Merge branch 'akpm' (patches from Andrew)

Merge updates from Andrew Morton:

 - a few misc things

 - ocfs2 updates

 - the v9fs maintainers have been missing for a long time. I've taken
   over v9fs patch slinging.

 - most of MM

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (116 commits)
  mm,oom_reaper: check for MMF_OOM_SKIP before complaining
  mm/ksm: fix interaction with THP
  mm/memblock.c: cast constant ULLONG_MAX to phys_addr_t
  headers: untangle kmemleak.h from mm.h
  include/linux/mmdebug.h: make VM_WARN* non-rvals
  mm/page_isolation.c: make start_isolate_page_range() fail if already isolated
  mm: change return type to vm_fault_t
  mm, oom: remove 3% bonus for CAP_SYS_ADMIN processes
  mm, page_alloc: wakeup kcompactd even if kswapd cannot free more memory
  kernel/fork.c: detect early free of a live mm
  mm: make counting of list_lru_one::nr_items lockless
  mm/swap_state.c: make bool enable_vma_readahead and swap_vma_readahead() static
  block_invalidatepage(): only release page if the full page was invalidated
  mm: kernel-doc: add missing parameter descriptions
  mm/swap.c: remove @cold parameter description for release_pages()
  mm/nommu: remove description of alloc_vm_area
  zram: drop max_zpage_size and use zs_huge_class_size()
  zsmalloc: introduce zs_huge_class_size()
  mm: fix races between swapoff and flush dcache
  fs/direct-io.c: minor cleanups in do_blockdev_direct_IO
  ...
diff --git a/.mailmap b/.mailmap
index dc42cfb..9795e6b 100644
--- a/.mailmap
+++ b/.mailmap
@@ -34,9 +34,9 @@
 Ben Gardner <bgardner@wabtec.com>
 Ben M Cahill <ben.m.cahill@intel.com>
 Björn Steinbrink <B.Steinbrink@gmx.de>
-Boris Brezillon <boris.brezillon@free-electrons.com>
-Boris Brezillon <boris.brezillon@free-electrons.com> <b.brezillon.dev@gmail.com>
-Boris Brezillon <boris.brezillon@free-electrons.com> <b.brezillon@overkiz.com>
+Boris Brezillon <boris.brezillon@bootlin.com> <boris.brezillon@free-electrons.com>
+Boris Brezillon <boris.brezillon@bootlin.com> <b.brezillon.dev@gmail.com>
+Boris Brezillon <boris.brezillon@bootlin.com> <b.brezillon@overkiz.com>
 Brian Avery <b.avery@hp.com>
 Brian King <brking@us.ibm.com>
 Christoph Hellwig <hch@lst.de>
@@ -128,6 +128,7 @@
 Michael Buesch <m@bues.ch>
 Michel Dänzer <michel@tungstengraphics.com>
 Miodrag Dinic <miodrag.dinic@mips.com> <miodrag.dinic@imgtec.com>
+Miquel Raynal <miquel.raynal@bootlin.com> <miquel.raynal@free-electrons.com>
 Mitesh shah <mshah@teja.com>
 Mohit Kumar <mohit.kumar@st.com> <mohit.kumar.dhaka@gmail.com>
 Morten Welinder <terra@gnome.org>
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-logitech-hidpp b/Documentation/ABI/testing/sysfs-driver-hid-logitech-hidpp
new file mode 100644
index 0000000..d8f831f
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-logitech-hidpp
@@ -0,0 +1,19 @@
+What:		/sys/bus/hid/drivers/logitech-hidpp-device/<dev>/range
+Date:		Jan, 2016
+KernelVersion:	4.6
+Contact:	linux-input@vger.kernel.org
+Description:
+		(RW) This attribute controls the amount of 'turn' permitted in
+		Logitech G920 wheel. Reading from the file shows the current
+		range of the steering wheel. Writing a value within the min and
+		max boundary sets the range of the wheel.
+
+What:		/sys/bus/hid/drivers/logitech-hidpp-device/<dev>/builtin_power_supply
+Date:		Apr, 2017
+KernelVersion:	4.12
+Contact:	linux-input@vger.kernel.org
+Description:
+		Presence of this file indicates that HID++ driver is capable of
+		handling battery properties in the kernel. This way, upower can
+		add a udev rule to decide whether or not it should use the
+		internal unifying support or the generic kernel one.
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-ntrig b/Documentation/ABI/testing/sysfs-driver-hid-ntrig
new file mode 100644
index 0000000..e574a56
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-ntrig
@@ -0,0 +1,70 @@
+What:		/sys/bus/hid/drivers/ntrig/<dev>/activate_slack
+Date:		May, 2010
+KernelVersion:	2.6.35
+Contact:	linux-input@vger.kernel.org
+Description:
+		(RW) Number of contact frames ignored before acknowledging the
+		start of activity (activating touch).
+
+
+What:		/sys/bus/hid/drivers/ntrig/<dev>/decativate_slack
+Date:		May, 2010
+KernelVersion:	2.6.35
+Contact:	linux-input@vger.kernel.org
+Description:
+		(RW) Number of empty (no contact) frames ignored before
+		acknowledging the end of activity (deactivating touch).
+
+		When the last finger is removed from the device, it sends a
+		number of empty frames. By holding off on deactivation for a few
+		frames false erroneous disconnects can be tolerated, where the
+		sensor may mistakenly not detect a finger that is still present.
+
+
+What:		/sys/bus/hid/drivers/ntrig/<dev>/activation_width
+What:		/sys/bus/hid/drivers/ntrig/<dev>/activation_height
+Date:		May, 2010
+KernelVersion:	2.6.35
+Contact:	linux-input@vger.kernel.org
+Description:
+		Threholds to override activation slack.
+
+		activation_width:	(RW) Width threshold to immediately
+					start processing touch events.
+
+		activation_height:	(RW) Height threshold to immediately
+					start processing touch events.
+
+
+What:		/sys/bus/hid/drivers/ntrig/<dev>/min_width
+What:		/sys/bus/hid/drivers/ntrig/<dev>/min_height
+Date:		May, 2010
+KernelVersion:	2.6.35
+Contact:	linux-input@vger.kernel.org
+Description:
+		Minimum size contact accepted.
+
+		min_width:	(RW) Minimum touch contact width to decide
+				activation and activity.
+
+		min_height:	(RW) Minimum touch contact height to decide
+				activation and activity.
+
+
+What:		/sys/bus/hid/drivers/ntrig/<dev>/sensor_physical_width
+What:		/sys/bus/hid/drivers/ntrig/<dev>/sensor_physical_height
+Date:		May, 2010
+KernelVersion:	2.6.35
+Contact:	linux-input@vger.kernel.org
+Description:
+		(RO) These are internal ranges not used for normal events but
+		useful for tuning.
+
+
+What:		/sys/bus/hid/drivers/ntrig/<dev>/sensor_logical_width
+What:		/sys/bus/hid/drivers/ntrig/<dev>/sensor_logical_height
+Date:		May, 2010
+KernelVersion:	2.6.35
+Contact:	linux-input@vger.kernel.org
+Description:
+		(RO) The range for positions reported during activity.
diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
new file mode 100644
index 0000000..016724e
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -0,0 +1,885 @@
+What:		/sys/bus/*/drivers/ufshcd/*/auto_hibern8
+Date:		March 2018
+Contact:	linux-scsi@vger.kernel.org
+Description:
+		This file contains the auto-hibernate idle timer setting of a
+		UFS host controller. A value of '0' means auto-hibernate is not
+		enabled. Otherwise the value is the number of microseconds of
+		idle time before the UFS host controller will autonomously put
+		the link into hibernate state. That will save power at the
+		expense of increased latency. Note that the hardware supports
+		10-bit values with a power-of-ten multiplier which allows a
+		maximum value of 102300000. Refer to the UFS Host Controller
+		Interface specification for more details.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device type. This is one of the UFS
+		device descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_class
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device class. This is one of the UFS
+		device descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_sub_class
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the UFS storage subclass. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/protocol
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the protocol supported by an UFS device.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_luns
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows number of logical units. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_wluns
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows number of well known logical units.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/boot_enable
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows value that indicates whether the device is
+		enabled for boot. This is one of the UFS device descriptor
+		parameters. The full information about the descriptor could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/descriptor_access_enable
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows value that indicates whether the device
+		descriptor could be read after partial initialization phase
+		of the boot sequence. This is one of the UFS device descriptor
+		parameters. The full information about the descriptor could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_power_mode
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows value that defines the power mode after
+		device initialization or hardware reset. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/high_priority_lun
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the high priority lun. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/secure_removal_type
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the secure removal type. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/support_security_lun
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the security lun is supported.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/bkops_termination_latency
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the background operations termination
+		latency. This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_active_icc_level
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the initial active ICC level. This is one
+		of the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/specification_version
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the specification version. This is one
+		of the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturing_date
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the manufacturing date in BCD format.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturer_id
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the manufacturee ID. This is one of the
+		UFS device descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtt_capability
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of outstanding RTTs
+		supported by the device. This is one of the UFS device
+		descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtc_update
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the frequency and method of the realtime
+		clock update. This is one of the UFS device descriptor
+		parameters. The full information about the descriptor
+		could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ufs_features
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows which features are supported by the device.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be
+		found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ffu_timeout
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the FFU timeout. This is one of the
+		UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/queue_depth
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device queue depth. This is one of the
+		UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_version
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device version. This is one of the
+		UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_secure_wpa
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows number of secure write protect areas
+		supported by the device. This is one of the UFS device
+		descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_max_data_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum amount of data that may be
+		written during the pre-soldering phase of the PSA flow.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_state_timeout
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the command maximum timeout for a change
+		in PSA state. This is one of the UFS device descriptor
+		parameters. The full information about the descriptor could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/unipro_version
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the MIPI UniPro version number in BCD format.
+		This is one of the UFS interconnect descriptor parameters.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/mphy_version
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the MIPI M-PHY version number in BCD format.
+		This is one of the UFS interconnect descriptor parameters.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/raw_device_capacity
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the total memory quantity available to
+		the user to configure the device logical units. This is one
+		of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_luns
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of logical units
+		supported by the UFS device. This is one of the UFS
+		geometry descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/segment_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the segment size. This is one of the UFS
+		geometry descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/allocation_unit_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the allocation unit size. This is one of
+		the UFS geometry descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/min_addressable_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the minimum addressable block size. This
+		is one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_read_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the optimal read block size. This is one
+		of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_write_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the optimal write block size. This is one
+		of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_in_buffer_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum data-in buffer size. This
+		is one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_out_buffer_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum data-out buffer size. This
+		is one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/rpmb_rw_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of RPMB frames allowed
+		in Security Protocol In/Out. This is one of the UFS geometry
+		descriptor parameters. The full information about the
+		descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/dyn_capacity_resource_policy
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the dynamic capacity resource policy. This
+		is one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/data_ordering
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows support for out-of-order data transfer.
+		This is one of the UFS geometry descriptor parameters.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_contexts
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows maximum available number of contexts which
+		are supported by the device. This is one of the UFS geometry
+		descriptor parameters. The full information about the
+		descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_unit_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows system data tag unit size. This is one of
+		the UFS geometry descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_resource_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows maximum storage area size allocated by
+		the device to handle system data by the tagging mechanism.
+		This is one of the UFS geometry descriptor parameters.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/secure_removal_types
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows supported secure removal types. This is
+		one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/memory_types
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows supported memory types. This is one of
+		the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_max_alloc_units
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of allocation units for
+		different memory types (system code, non persistent,
+		enhanced type 1-4). This is one of the UFS geometry
+		descriptor parameters. The full information about the
+		descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_capacity_adjustment_factor
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the memory capacity adjustment factor for
+		different memory types (system code, non persistent,
+		enhanced type 1-4). This is one of the UFS geometry
+		descriptor parameters. The full information about the
+		descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/health_descriptor/eol_info
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows preend of life information. This is one
+		of the UFS health descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_a
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows indication of the device life time
+		(method a). This is one of the UFS health descriptor
+		parameters. The full information about the descriptor
+		could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_b
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows indication of the device life time
+		(method b). This is one of the UFS health descriptor
+		parameters. The full information about the descriptor
+		could be found at UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/power_descriptor/active_icc_levels_vcc*
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows maximum VCC, VCCQ and VCCQ2 value for
+		active ICC levels from 0 to 15. This is one of the UFS
+		power descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/manufacturer_name
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a device manufactureer name string.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_name
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a product name string. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/oem_id
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a OEM ID string. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/serial_number
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a device serial number string. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_revision
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a product revision string. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/boot_lun_id
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows boot LUN information. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/lun_write_protect
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows LUN write protection status. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/lun_queue_depth
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows LUN queue depth. This is one of the UFS
+		unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/psa_sensitive
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows PSA sensitivity. This is one of the UFS
+		unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/lun_memory_type
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows LUN memory type. This is one of the UFS
+		unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/data_reliability
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file defines the device behavior when a power failure
+		occurs during a write operation. This is one of the UFS
+		unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/logical_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the size of addressable logical blocks
+		(calculated as an exponent with base 2). This is one of
+		the UFS unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/logical_block_count
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows total number of addressable logical blocks.
+		This is one of the UFS unit descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/erase_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the erase block size. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/provisioning_type
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the thin provisioning type. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/physical_memory_resourse_count
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the total physical memory resources. This is
+		one of the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/context_capabilities
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the context capabilities. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/large_unit_granularity
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the granularity of the LUN. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/device_init
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device init status. The full information
+		about the flag could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/permanent_wpe
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether permanent write protection is enabled.
+		The full information about the flag could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/power_on_wpe
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether write protection is enabled on all
+		logical units configured as power on write protected. The
+		full information about the flag could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/bkops_enable
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the device background operations are
+		enabled. The full information about the flag could be
+		found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/life_span_mode_enable
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the device life span mode is enabled.
+		The full information about the flag could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/phy_resource_removal
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether physical resource removal is enable.
+		The full information about the flag could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/busy_rtc
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the device is executing internal
+		operation related to real time clock. The full information
+		about the flag could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/disable_fw_update
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the device FW update is permanently
+		disabled. The full information about the flag could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/boot_lun_enabled
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the boot lun enabled UFS device attribute.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/current_power_mode
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the current power mode UFS device attribute.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/active_icc_level
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the active icc level UFS device attribute.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/ooo_data_enabled
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the out of order data transfer enabled UFS
+		device attribute. The full information about the attribute
+		could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/bkops_status
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the background operations status UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/purge_status
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the purge operation status UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/max_data_in_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum data size in a DATA IN
+		UPIU. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/max_data_out_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of bytes that can be
+		requested with a READY TO TRANSFER UPIU. The full information
+		about the attribute could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/reference_clock_frequency
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the reference clock frequency UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/configuration_descriptor_lock
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the configuration descriptor is locked.
+		The full information about the attribute could be found at
+		UFS specifications 2.1. The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/max_number_of_rtt
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the maximum current number of
+		outstanding RTTs in device that is allowed. The full
+		information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_control
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the exception event control UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_status
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the exception event status UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/ffu_status
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the ffu status UFS device attribute.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/psa_state
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file show the PSA feature status. The full information
+		about the attribute could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/psa_data_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the amount of data that the host plans to
+		load to all logical units in pre-soldering state.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/class/scsi_device/*/device/dyn_cap_needed
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the The amount of physical memory needed
+		to be removed from the physical memory resources pool of
+		the particular logical unit. The full information about
+		the attribute could be found at UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/rpm_lvl
+Date:		September 2014
+Contact:	Subhash Jadavani <subhashj@codeaurora.org>
+Description:	This entry could be used to set or show the UFS device
+		runtime power management level. The current driver
+		implementation supports 6 levels with next target states:
+		0 - an UFS device will stay active, an UIC link will
+		stay active
+		1 - an UFS device will stay active, an UIC link will
+		hibernate
+		2 - an UFS device will moved to sleep, an UIC link will
+		stay active
+		3 - an UFS device will moved to sleep, an UIC link will
+		hibernate
+		4 - an UFS device will be powered off, an UIC link will
+		hibernate
+		5 - an UFS device will be powered off, an UIC link will
+		be powered off
+
+What:		/sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state
+Date:		February 2018
+Contact:	Subhash Jadavani <subhashj@codeaurora.org>
+Description:	This entry shows the target power mode of an UFS device
+		for the chosen runtime power management level.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/rpm_target_link_state
+Date:		February 2018
+Contact:	Subhash Jadavani <subhashj@codeaurora.org>
+Description:	This entry shows the target state of an UFS UIC link
+		for the chosen runtime power management level.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/spm_lvl
+Date:		September 2014
+Contact:	Subhash Jadavani <subhashj@codeaurora.org>
+Description:	This entry could be used to set or show the UFS device
+		system power management level. The current driver
+		implementation supports 6 levels with next target states:
+		0 - an UFS device will stay active, an UIC link will
+		stay active
+		1 - an UFS device will stay active, an UIC link will
+		hibernate
+		2 - an UFS device will moved to sleep, an UIC link will
+		stay active
+		3 - an UFS device will moved to sleep, an UIC link will
+		hibernate
+		4 - an UFS device will be powered off, an UIC link will
+		hibernate
+		5 - an UFS device will be powered off, an UIC link will
+		be powered off
+
+What:		/sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state
+Date:		February 2018
+Contact:	Subhash Jadavani <subhashj@codeaurora.org>
+Description:	This entry shows the target power mode of an UFS device
+		for the chosen system power management level.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/spm_target_link_state
+Date:		February 2018
+Contact:	Subhash Jadavani <subhashj@codeaurora.org>
+Description:	This entry shows the target state of an UFS UIC link
+		for the chosen system power management level.
+		The file is read only.
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index d870b55..540553c 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -192,3 +192,14 @@
 Contact:	"Sheng Yong" <shengyong1@huawei.com>
 Description:
 		 Controls readahead inode block in readdir.
+
+What:		/sys/fs/f2fs/<disk>/extension_list
+Date:		Feburary 2018
+Contact:	"Chao Yu" <yuchao0@huawei.com>
+Description:
+		 Used to control configure extension list:
+		 - Query: cat /sys/fs/f2fs/<disk>/extension_list
+		 - Add: echo '[h/c]extension' > /sys/fs/f2fs/<disk>/extension_list
+		 - Del: echo '[h/c]!extension' > /sys/fs/f2fs/<disk>/extension_list
+		 - [h] means add/del hot file extension
+		 - [c] means add/del cold file extension
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 7993021..3c87a69 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4456,6 +4456,9 @@
 	usbhid.jspoll=
 			[USBHID] The interval which joysticks are to be polled at.
 
+	usbhid.kbpoll=
+			[USBHID] The interval which keyboards are to be polled at.
+
 	usb-storage.delay_use=
 			[UMS] The delay in seconds before a new device is
 			scanned for Logical Units (default 1).
diff --git a/Documentation/arm/Atmel/README b/Documentation/arm/Microchip/README
similarity index 64%
rename from Documentation/arm/Atmel/README
rename to Documentation/arm/Microchip/README
index afb13c1..a366f37 100644
--- a/Documentation/arm/Atmel/README
+++ b/Documentation/arm/Microchip/README
@@ -1,54 +1,54 @@
-ARM Atmel SoCs (aka AT91)
-=========================
+ARM Microchip SoCs (aka AT91)
+=============================
 
 
 Introduction
 ------------
-This document gives useful information about the ARM Atmel SoCs that are
+This document gives useful information about the ARM Microchip SoCs that are
 currently supported in Linux Mainline (you know, the one on kernel.org).
 
-It is important to note that the Atmel | SMART ARM-based MPU product line is
-historically named "AT91" or "at91" throughout the Linux kernel development
-process even if this product prefix has completely disappeared from the
-official Atmel product name. Anyway, files, directories, git trees,
+It is important to note that the Microchip (previously Atmel) ARM-based MPU
+product line is historically named "AT91" or "at91" throughout the Linux kernel
+development process even if this product prefix has completely disappeared from
+the official Microchip product name. Anyway, files, directories, git trees,
 git branches/tags and email subject always contain this "at91" sub-string.
 
 
 AT91 SoCs
 ---------
 Documentation and detailed datasheet for each product are available on
-the Atmel website: http://www.atmel.com.
+the Microchip website: http://www.microchip.com.
 
   Flavors:
     * ARM 920 based SoC
       - at91rm9200
         + Datasheet
-          http://www.atmel.com/Images/doc1768.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-1768-32-bit-ARM920T-Embedded-Microprocessor-AT91RM9200_Datasheet.pdf
 
     * ARM 926 based SoCs
       - at91sam9260
         + Datasheet
-          http://www.atmel.com/Images/doc6221.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6221-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9260_Datasheet.pdf
 
       - at91sam9xe
         + Datasheet
-          http://www.atmel.com/Images/Atmel-6254-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9XE_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6254-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9XE_Datasheet.pdf
 
       - at91sam9261
         + Datasheet
-          http://www.atmel.com/Images/doc6062.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6062-ARM926EJ-S-Microprocessor-SAM9261_Datasheet.pdf
 
       - at91sam9263
         + Datasheet
-          http://www.atmel.com/Images/Atmel_6249_32-bit-ARM926EJ-S-Microcontroller_SAM9263_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6249-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9263_Datasheet.pdf
 
       - at91sam9rl
         + Datasheet
-          http://www.atmel.com/Images/doc6289.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/doc6289.pdf
 
       - at91sam9g20
         + Datasheet
-          http://www.atmel.com/Images/doc6384.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/DS60001516A.pdf
 
       - at91sam9g45 family
         - at91sam9g45
@@ -56,7 +56,7 @@
         - at91sam9m10
         - at91sam9m11 (device superset)
         + Datasheet
-          http://www.atmel.com/Images/Atmel-6437-32-bit-ARM926-Embedded-Microprocessor-SAM9M11_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6437-32-bit-ARM926-Embedded-Microprocessor-SAM9M11_Datasheet.pdf
 
       - at91sam9x5 family (aka "The 5 series")
         - at91sam9g15
@@ -65,11 +65,11 @@
         - at91sam9x25
         - at91sam9x35
         + Datasheet (can be considered as covering the whole family)
-          http://www.atmel.com/Images/Atmel_11055_32-bit-ARM926EJ-S-Microcontroller_SAM9X35_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11055-32-bit-ARM926EJ-S-Microcontroller-SAM9X35_Datasheet.pdf
 
       - at91sam9n12
         + Datasheet
-          http://www.atmel.com/Images/Atmel_11063_32-bit-ARM926EJ-S-Microcontroller_SAM9N12CN11CN12_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/DS60001517A.pdf
 
     * ARM Cortex-A5 based SoCs
       - sama5d3 family
@@ -79,7 +79,7 @@
         - sama5d35
         - sama5d36 (device superset)
         + Datasheet
-          http://www.atmel.com/Images/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet.pdf
 
     * ARM Cortex-A5 + NEON based SoCs
       - sama5d4 family
@@ -88,7 +88,7 @@
         - sama5d43
         - sama5d44 (device superset)
         + Datasheet
-          http://www.atmel.com/Images/Atmel-11238-32-bit-Cortex-A5-Microcontroller-SAMA5D4_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/60001525A.pdf
 
       - sama5d2 family
         - sama5d21
@@ -99,7 +99,7 @@
         - sama5d27 (device superset)
         - sama5d28 (device superset + environmental monitors)
         + Datasheet
-          http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/DS60001476B.pdf
 
     * ARM Cortex-M7 MCUs
       - sams70 family
@@ -112,8 +112,6 @@
         - sams70q19
         - sams70q20
         - sams70q21
-        + Datasheet
-          http://www.atmel.com/Images/Atmel-11242-32-bit-Cortex-M7-Microcontroller-SAM-S70Q-SAM-S70N-SAM-S70J_Datasheet.pdf
 
       - samv70 family
         - samv70j19
@@ -122,8 +120,6 @@
         - samv70n20
         - samv70q19
         - samv70q20
-        + Datasheet
-          http://www.atmel.com/Images/Atmel-11297-32-bit-Cortex-M7-Microcontroller-SAM-V70Q-SAM-V70N-SAM-V70J_Datasheet.pdf
 
       - samv71 family
         - samv71j19
@@ -135,13 +131,15 @@
         - samv71q19
         - samv71q20
         - samv71q21
+
         + Datasheet
-          http://www.atmel.com/Images/Atmel-44003-32-bit-Cortex-M7-Microcontroller-SAM-V71Q-SAM-V71N-SAM-V71J_Datasheet.pdf
+          http://ww1.microchip.com/downloads/en/DeviceDoc/60001527A.pdf
+
 
 Linux kernel information
 ------------------------
 Linux kernel mach directory: arch/arm/mach-at91
-MAINTAINERS entry is: "ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES"
+MAINTAINERS entry is: "ARM/Microchip (AT91) SoC support"
 
 
 Device Tree for AT91 SoCs and boards
diff --git a/Documentation/arm/Samsung-S3C24XX/S3C2412.txt b/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
index f057876..dc1fd36 100644
--- a/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
+++ b/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
@@ -46,7 +46,7 @@
 ----
 
   The NAND hardware is similar to the S3C2440, and is supported by the
-  s3c2410 driver in the drivers/mtd/nand directory.
+  s3c2410 driver in the drivers/mtd/nand/raw directory.
 
 
 USB Host
diff --git a/Documentation/arm/stm32/overview.rst b/Documentation/arm/stm32/overview.rst
new file mode 100644
index 0000000..85cfc84
--- /dev/null
+++ b/Documentation/arm/stm32/overview.rst
@@ -0,0 +1,34 @@
+========================
+STM32 ARM Linux Overview
+========================
+
+Introduction
+------------
+
+The STMicroelectronics STM32 family of Cortex-A microprocessors (MPUs) and
+Cortex-M microcontrollers (MCUs) are supported by the 'STM32' platform of
+ARM Linux.
+
+Configuration
+-------------
+
+For MCUs, use the provided default configuration:
+        make stm32_defconfig
+For MPUs, use multi_v7 configuration:
+        make multi_v7_defconfig
+
+Layout
+------
+
+All the files for multiple machine families are located in the platform code
+contained in arch/arm/mach-stm32
+
+There is a generic board board-dt.c in the mach folder which support
+Flattened Device Tree, which means, it works with any compatible board with
+Device Trees.
+
+:Authors:
+
+- Maxime Coquelin <mcoquelin.stm32@gmail.com>
+- Ludovic Barre <ludovic.barre@st.com>
+- Gerald Baeza <gerald.baeza@st.com>
diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
deleted file mode 100644
index a03b035..0000000
--- a/Documentation/arm/stm32/overview.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-			STM32 ARM Linux Overview
-			========================
-
-Introduction
-------------
-
-  The STMicroelectronics family of Cortex-M based MCUs are supported by the
-  'STM32' platform of ARM Linux. Currently only the STM32F429 (Cortex-M4)
-  and STM32F746 (Cortex-M7) are supported.
-
-
-Configuration
--------------
-
-  A generic configuration is provided for STM32 family, and can be used as the
-  default by
-	make stm32_defconfig
-
-Layout
-------
-
-  All the files for multiple machine families are located in the platform code
-  contained in arch/arm/mach-stm32
-
-  There is a generic board board-dt.c in the mach folder which support
-  Flattened Device Tree, which means, it works with any compatible board with
-  Device Trees.
-
-
-Document Author
----------------
-
-  Maxime Coquelin <mcoquelin.stm32@gmail.com>
diff --git a/Documentation/arm/stm32/stm32f429-overview.rst b/Documentation/arm/stm32/stm32f429-overview.rst
new file mode 100644
index 0000000..18feda9
--- /dev/null
+++ b/Documentation/arm/stm32/stm32f429-overview.rst
@@ -0,0 +1,26 @@
+STM32F429 Overview
+==================
+
+Introduction
+------------
+
+The STM32F429 is a Cortex-M4 MCU aimed at various applications.
+It features:
+
+- ARM Cortex-M4 up to 180MHz with FPU
+- 2MB internal Flash Memory
+- External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND)
+- I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers
+- LCD controller & Camera interface
+- Cryptographic processor
+
+Resources
+---------
+
+Datasheet and reference manual are publicly available on ST website (STM32F429_).
+
+.. _STM32F429: http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013
+
+:Authors:
+
+Maxime Coquelin <mcoquelin.stm32@gmail.com>
diff --git a/Documentation/arm/stm32/stm32f429-overview.txt b/Documentation/arm/stm32/stm32f429-overview.txt
deleted file mode 100644
index 5206822..0000000
--- a/Documentation/arm/stm32/stm32f429-overview.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-			STM32F429 Overview
-			==================
-
-  Introduction
-  ------------
-	The STM32F429 is a Cortex-M4 MCU aimed at various applications.
-	It features:
-	- ARM Cortex-M4 up to 180MHz with FPU
-	- 2MB internal Flash Memory
-	- External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND)
-	- I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers
-	- LCD controller & Camera interface
-	- Cryptographic processor
-
-  Resources
-  ---------
-	Datasheet and reference manual are publicly available on ST website:
-	- http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013
-
-  Document Author
-  ---------------
-	Maxime Coquelin <mcoquelin.stm32@gmail.com>
diff --git a/Documentation/arm/stm32/stm32f746-overview.rst b/Documentation/arm/stm32/stm32f746-overview.rst
new file mode 100644
index 0000000..b5f4b6c
--- /dev/null
+++ b/Documentation/arm/stm32/stm32f746-overview.rst
@@ -0,0 +1,33 @@
+STM32F746 Overview
+==================
+
+Introduction
+------------
+
+The STM32F746 is a Cortex-M7 MCU aimed at various applications.
+It features:
+
+- Cortex-M7 core running up to @216MHz
+- 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
+- FMC controller to connect SDRAM, NOR and NAND memories
+- Dual mode QSPI
+- SD/MMC/SDIO support
+- Ethernet controller
+- USB OTFG FS & HS controllers
+- I2C, SPI, CAN busses support
+- Several 16 & 32 bits general purpose timers
+- Serial Audio interface
+- LCD controller
+- HDMI-CEC
+- SPDIFRX
+
+Resources
+---------
+
+Datasheet and reference manual are publicly available on ST website (STM32F746_).
+
+.. _STM32F746: http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html
+
+:Authors:
+
+Alexandre Torgue <alexandre.torgue@st.com>
diff --git a/Documentation/arm/stm32/stm32f746-overview.txt b/Documentation/arm/stm32/stm32f746-overview.txt
deleted file mode 100644
index cffd2b1c..0000000
--- a/Documentation/arm/stm32/stm32f746-overview.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-			STM32F746 Overview
-			==================
-
-  Introduction
-  ------------
-	The STM32F746 is a Cortex-M7 MCU aimed at various applications.
-	It features:
-	- Cortex-M7 core running up to @216MHz
-	- 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
-	- FMC controller to connect SDRAM, NOR and NAND memories
-	- Dual mode QSPI
-	- SD/MMC/SDIO support
-	- Ethernet controller
-	- USB OTFG FS & HS controllers
-	- I2C, SPI, CAN busses support
-	- Several 16 & 32 bits general purpose timers
-	- Serial Audio interface
-	- LCD controller
-	- HDMI-CEC
-	- SPDIFRX
-
-  Resources
-  ---------
-	Datasheet and reference manual are publicly available on ST website:
-	- http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html
-
-  Document Author
-  ---------------
-	Alexandre Torgue <alexandre.torgue@st.com>
-
-
-
-
-
diff --git a/Documentation/arm/stm32/stm32f769-overview.rst b/Documentation/arm/stm32/stm32f769-overview.rst
new file mode 100644
index 0000000..228656c
--- /dev/null
+++ b/Documentation/arm/stm32/stm32f769-overview.rst
@@ -0,0 +1,35 @@
+STM32F769 Overview
+==================
+
+Introduction
+------------
+
+The STM32F769 is a Cortex-M7 MCU aimed at various applications.
+It features:
+
+- Cortex-M7 core running up to @216MHz
+- 2MB internal flash, 512KBytes internal RAM (+4KB of backup SRAM)
+- FMC controller to connect SDRAM, NOR and NAND memories
+- Dual mode QSPI
+- SD/MMC/SDIO support*2
+- Ethernet controller
+- USB OTFG FS & HS controllers
+- I2C*4, SPI*6, CAN*3 busses support
+- Several 16 & 32 bits general purpose timers
+- Serial Audio interface*2
+- LCD controller
+- HDMI-CEC
+- DSI
+- SPDIFRX
+- MDIO salave interface
+
+Resources
+---------
+
+Datasheet and reference manual are publicly available on ST website (STM32F769_).
+
+.. _STM32F769: http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f7-series/stm32f7x9/stm32f769ni.html
+
+:Authors:
+
+Alexandre Torgue <alexandre.torgue@st.com>
diff --git a/Documentation/arm/stm32/stm32h743-overview.rst b/Documentation/arm/stm32/stm32h743-overview.rst
new file mode 100644
index 0000000..3458dc0
--- /dev/null
+++ b/Documentation/arm/stm32/stm32h743-overview.rst
@@ -0,0 +1,34 @@
+STM32H743 Overview
+==================
+
+Introduction
+------------
+
+The STM32H743 is a Cortex-M7 MCU aimed at various applications.
+It features:
+
+- Cortex-M7 core running up to @400MHz
+- 2MB internal flash, 1MBytes internal RAM
+- FMC controller to connect SDRAM, NOR and NAND memories
+- Dual mode QSPI
+- SD/MMC/SDIO support
+- Ethernet controller
+- USB OTFG FS & HS controllers
+- I2C, SPI, CAN busses support
+- Several 16 & 32 bits general purpose timers
+- Serial Audio interface
+- LCD controller
+- HDMI-CEC
+- SPDIFRX
+- DFSDM
+
+Resources
+---------
+
+Datasheet and reference manual are publicly available on ST website (STM32H743_).
+
+.. _STM32H743: http://www.st.com/en/microcontrollers/stm32h7x3.html?querycriteria=productId=LN2033
+
+:Authors:
+
+Alexandre Torgue <alexandre.torgue@st.com>
diff --git a/Documentation/arm/stm32/stm32h743-overview.txt b/Documentation/arm/stm32/stm32h743-overview.txt
deleted file mode 100644
index 3031cba..0000000
--- a/Documentation/arm/stm32/stm32h743-overview.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-			STM32H743 Overview
-			==================
-
-  Introduction
-  ------------
-	The STM32H743 is a Cortex-M7 MCU aimed at various applications.
-	It features:
-	- Cortex-M7 core running up to @400MHz
-	- 2MB internal flash, 1MBytes internal RAM
-	- FMC controller to connect SDRAM, NOR and NAND memories
-	- Dual mode QSPI
-	- SD/MMC/SDIO support
-	- Ethernet controller
-	- USB OTFG FS & HS controllers
-	- I2C, SPI, CAN busses support
-	- Several 16 & 32 bits general purpose timers
-	- Serial Audio interface
-	- LCD controller
-	- HDMI-CEC
-	- SPDIFRX
-	- DFSDM
-
-  Resources
-  ---------
-	Datasheet and reference manual are publicly available on ST website:
-	- http://www.st.com/en/microcontrollers/stm32h7x3.html?querycriteria=productId=LN2033
-
-  Document Author
-  ---------------
-	Alexandre Torgue <alexandre.torgue@st.com>
diff --git a/Documentation/arm/stm32/stm32mp157-overview.rst b/Documentation/arm/stm32/stm32mp157-overview.rst
new file mode 100644
index 0000000..62e176d
--- /dev/null
+++ b/Documentation/arm/stm32/stm32mp157-overview.rst
@@ -0,0 +1,19 @@
+STM32MP157 Overview
+===================
+
+Introduction
+------------
+
+The STM32MP157 is a Cortex-A MPU aimed at various applications.
+It features:
+
+- Dual core Cortex-A7 application core
+- 2D/3D image composition with GPU
+- Standard memories interface support
+- Standard connectivity, widely inherited from the STM32 MCU family
+- Comprehensive security support
+
+:Authors:
+
+- Ludovic Barre <ludovic.barre@st.com>
+- Gerald Baeza <gerald.baeza@st.com>
diff --git a/Documentation/cdrom/cdrom-standard.tex b/Documentation/cdrom/cdrom-standard.tex
index 8f85b0e..f7cd455 100644
--- a/Documentation/cdrom/cdrom-standard.tex
+++ b/Documentation/cdrom/cdrom-standard.tex
@@ -234,6 +234,7 @@
   &int& (* open)(struct\ cdrom_device_info *, int)\cr
   &void& (* release)(struct\ cdrom_device_info *);\cr 
   &int& (* drive_status)(struct\ cdrom_device_info *, int);\cr     
+  &unsigned\ int& (* check_events)(struct\ cdrom_device_info *, unsigned\ int, int);\cr
   &int& (* media_changed)(struct\ cdrom_device_info *, int);\cr 
   &int& (* tray_move)(struct\ cdrom_device_info *, int);\cr
   &int& (* lock_door)(struct\ cdrom_device_info *, int);\cr
@@ -245,10 +246,9 @@
   &int& (* reset)(struct\ cdrom_device_info *);\cr
   &int& (* audio_ioctl)(struct\ cdrom_device_info *, unsigned\ int, 
         void *{});\cr 
-  &int& (* dev_ioctl)(struct\ cdrom_device_info *, unsigned\ int, 
-        unsigned\ long);\cr
 \noalign{\medskip}
   &const\ int& capability;& capability flags \cr
+  &int& (* generic_packet)(struct\ cdrom_device_info *, struct\ packet_command *{});\cr
 \};\cr
 }
 $$
@@ -274,19 +274,32 @@
 \halign{$#$\ \hfil&$#$\ \hfil&\hbox to 10em{$#$\hss}&
   $/*$ \rm# $*/$\hfil\cr
 struct& cdrom_device_info\ \{ \hidewidth\cr
-  & struct\ cdrom_device_ops *& ops;& device operations for this major\cr
-  & struct\ cdrom_device_info *& next;& next device_info for this major\cr
+  & const\ struct\ cdrom_device_ops *& ops;& device operations for this major\cr
+  & struct\ list_head& list;& linked list of all device_info\cr
+  & struct\ gendisk *& disk;& matching block layer disk\cr
   & void *&  handle;& driver-dependent data\cr
 \noalign{\medskip}
-  & kdev_t&  dev;& device number (incorporates minor)\cr
   & int& mask;& mask of capability: disables them \cr
   & int& speed;& maximum speed for reading data \cr
   & int& capacity;& number of discs in a jukebox \cr
 \noalign{\medskip}
-  &int& options : 30;& options flags \cr
+  &unsigned\ int& options : 30;& options flags \cr
   &unsigned& mc_flags : 2;& media-change buffer flags \cr
+  &unsigned\ int& vfs_events;& cached events for vfs path\cr
+  &unsigned\ int& ioctl_events;& cached events for ioctl path\cr
   & int& use_count;& number of times device is opened\cr
   & char& name[20];& name of the device type\cr
+\noalign{\medskip}
+  &__u8& sanyo_slot : 2;& Sanyo 3-CD changer support\cr
+  &__u8& keeplocked : 1;& CDROM_LOCKDOOR status\cr
+  &__u8& reserved : 5;& not used yet\cr
+  & int& cdda_method;& see CDDA_* flags\cr
+  &__u8& last_sense;& saves last sense key\cr
+  &__u8& media_written;& dirty flag, DVD+RW bookkeeping\cr
+  &unsigned\ short& mmc3_profile;& current MMC3 profile\cr
+  & int& for_data;& unknown:TBD\cr
+  & int\ (* exit)\ (struct\ cdrom_device_info *);&& unknown:TBD\cr
+  & int& mrw_mode_page;& which MRW mode page is in use\cr
 \}\cr
 }$$
 Using this $struct$, a linked list of the registered minor devices is
@@ -298,9 +311,7 @@
 in $ops\to capability$, if a specific drive doesn't support a feature
 of the driver. The value $speed$ specifies the maximum head-rate of the
 drive, measured in units of normal audio speed (176\,kB/sec raw data or
-150\,kB/sec file system data). The value $n_discs$ should reflect the
-number of discs the drive can hold simultaneously, if it is designed
-as a juke-box, or otherwise~1. The parameters are declared $const$
+150\,kB/sec file system data).  The parameters are declared $const$
 because they describe properties of the drive, which don't change after
 registration.
 
@@ -1002,7 +1013,7 @@
 \cdrom-related code in the 2.1-kernel.  Thanks to Scott Snyder and
 Gerd Knorr, who were the first to implement this interface for SCSI
 and IDE-CD drivers and added many ideas for extension of the data
-structures relative to kernel~2.0.  Further thanks to Heiko Ei{\sz}feldt,
+structures relative to kernel~2.0.  Further thanks to Heiko Ei{\ss}feldt,
 Thomas Quinot, Jon Tombs, Ken Pizzini, Eberhard M\"onkeberg and Andrew
 Kroll, the \linux\ \cdrom\ device driver developers who were kind
 enough to give suggestions and criticisms during the writing. Finally
diff --git a/Documentation/device-mapper/verity.txt b/Documentation/device-mapper/verity.txt
index 89fd8f9..b3d2e4a 100644
--- a/Documentation/device-mapper/verity.txt
+++ b/Documentation/device-mapper/verity.txt
@@ -109,6 +109,17 @@
     This is the offset, in <data_block_size> blocks, from the start of the
     FEC device to the beginning of the encoding data.
 
+check_at_most_once
+    Verify data blocks only the first time they are read from the data device,
+    rather than every time.  This reduces the overhead of dm-verity so that it
+    can be used on systems that are memory and/or CPU constrained.  However, it
+    provides a reduced level of security because only offline tampering of the
+    data device's content will be detected, not online tampering.
+
+    Hash blocks are still verified each time they are read from the hash device,
+    since verification of hash blocks is less performance critical than data
+    blocks, and a hash block will not be verified any more after all the data
+    blocks it covers have been verified anyway.
 
 Theory of operation
 ===================
diff --git a/Documentation/devicetree/bindings/arm/arm,scmi.txt b/Documentation/devicetree/bindings/arm/arm,scmi.txt
new file mode 100644
index 0000000..5f3719a
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/arm,scmi.txt
@@ -0,0 +1,179 @@
+System Control and Management Interface (SCMI) Message Protocol
+----------------------------------------------------------
+
+The SCMI is intended to allow agents such as OSPM to manage various functions
+that are provided by the hardware platform it is running on, including power
+and performance functions.
+
+This binding is intended to define the interface the firmware implementing
+the SCMI as described in ARM document number ARM DUI 0922B ("ARM System Control
+and Management Interface Platform Design Document")[0] provide for OSPM in
+the device tree.
+
+Required properties:
+
+The scmi node with the following properties shall be under the /firmware/ node.
+
+- compatible : shall be "arm,scmi"
+- mboxes: List of phandle and mailbox channel specifiers. It should contain
+	  exactly one or two mailboxes, one for transmitting messages("tx")
+	  and another optional for receiving the notifications("rx") if
+	  supported.
+- shmem : List of phandle pointing to the shared memory(SHM) area as per
+	  generic mailbox client binding.
+- #address-cells : should be '1' if the device has sub-nodes, maps to
+	  protocol identifier for a given sub-node.
+- #size-cells : should be '0' as 'reg' property doesn't have any size
+	  associated with it.
+
+Optional properties:
+
+- mbox-names: shall be "tx" or "rx" depending on mboxes entries.
+
+See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details
+about the generic mailbox controller and client driver bindings.
+
+The mailbox is the only permitted method of calling the SCMI firmware.
+Mailbox doorbell is used as a mechanism to alert the presence of a
+messages and/or notification.
+
+Each protocol supported shall have a sub-node with corresponding compatible
+as described in the following sections. If the platform supports dedicated
+communication channel for a particular protocol, the 3 properties namely:
+mboxes, mbox-names and shmem shall be present in the sub-node corresponding
+to that protocol.
+
+Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol
+------------------------------------------------------------
+
+This binding uses the common clock binding[1].
+
+Required properties:
+- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI commands.
+
+Power domain bindings for the power domains based on SCMI Message Protocol
+------------------------------------------------------------
+
+This binding for the SCMI power domain providers uses the generic power
+domain binding[2].
+
+Required properties:
+ - #power-domain-cells : Should be 1. Contains the device or the power
+			 domain ID value used by SCMI commands.
+
+Sensor bindings for the sensors based on SCMI Message Protocol
+--------------------------------------------------------------
+SCMI provides an API to access the various sensors on the SoC.
+
+Required properties:
+- #thermal-sensor-cells: should be set to 1. This property follows the
+			 thermal device tree bindings[3].
+
+			 Valid cell values are raw identifiers (Sensor ID)
+			 as used by the firmware. Refer to  platform details
+			 for your implementation for the IDs to use.
+
+SRAM and Shared Memory for SCMI
+-------------------------------
+
+A small area of SRAM is reserved for SCMI communication between application
+processors and SCP.
+
+The properties should follow the generic mmio-sram description found in [4]
+
+Each sub-node represents the reserved area for SCMI.
+
+Required sub-node properties:
+- reg : The base offset and size of the reserved area with the SRAM
+- compatible : should be "arm,scmi-shmem" for Non-secure SRAM based
+	       shared memory
+
+[0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/power/power_domain.txt
+[3] Documentation/devicetree/bindings/thermal/thermal.txt
+[4] Documentation/devicetree/bindings/sram/sram.txt
+
+Example:
+
+sram@50000000 {
+	compatible = "mmio-sram";
+	reg = <0x0 0x50000000 0x0 0x10000>;
+
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0 0x0 0x50000000 0x10000>;
+
+	cpu_scp_lpri: scp-shmem@0 {
+		compatible = "arm,scmi-shmem";
+		reg = <0x0 0x200>;
+	};
+
+	cpu_scp_hpri: scp-shmem@200 {
+		compatible = "arm,scmi-shmem";
+		reg = <0x200 0x200>;
+	};
+};
+
+mailbox@40000000 {
+	....
+	#mbox-cells = <1>;
+	reg = <0x0 0x40000000 0x0 0x10000>;
+};
+
+firmware {
+
+	...
+
+	scmi {
+		compatible = "arm,scmi";
+		mboxes = <&mailbox 0 &mailbox 1>;
+		mbox-names = "tx", "rx";
+		shmem = <&cpu_scp_lpri &cpu_scp_hpri>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi_devpd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi_dvfs: protocol@13 {
+			reg = <0x13>;
+			#clock-cells = <1>;
+		};
+
+		scmi_clk: protocol@14 {
+			reg = <0x14>;
+			#clock-cells = <1>;
+		};
+
+		scmi_sensors0: protocol@15 {
+			reg = <0x15>;
+			#thermal-sensor-cells = <1>;
+		};
+	};
+};
+
+cpu@0 {
+	...
+	reg = <0 0>;
+	clocks = <&scmi_dvfs 0>;
+};
+
+hdlcd@7ff60000 {
+	...
+	reg = <0 0x7ff60000 0 0x1000>;
+	clocks = <&scmi_clk 4>;
+	power-domains = <&scmi_devpd 1>;
+};
+
+thermal-zones {
+	soc_thermal {
+		polling-delay-passive = <100>;
+		polling-delay = <1000>;
+					/* sensor ID */
+		thermal-sensors = <&scmi_sensors0 3>;
+		...
+	};
+};
diff --git a/Documentation/devicetree/bindings/arm/cpu-enable-method/nuvoton,npcm750-smp b/Documentation/devicetree/bindings/arm/cpu-enable-method/nuvoton,npcm750-smp
new file mode 100644
index 0000000..8e04330
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/cpu-enable-method/nuvoton,npcm750-smp
@@ -0,0 +1,42 @@
+=========================================================
+Secondary CPU enable-method "nuvoton,npcm750-smp" binding
+=========================================================
+
+To apply to all CPUs, a single "nuvoton,npcm750-smp" enable method should be
+defined in the "cpus" node.
+
+Enable method name:	"nuvoton,npcm750-smp"
+Compatible machines:	"nuvoton,npcm750"
+Compatible CPUs:	"arm,cortex-a9"
+Related properties:	(none)
+
+Note:
+This enable method needs valid nodes compatible with "arm,cortex-a9-scu" and
+"nuvoton,npcm750-gcr".
+
+Example:
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "nuvoton,npcm750-smp";
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			clocks = <&clk NPCM7XX_CLK_CPU>;
+			clock-names = "clk_cpu";
+			reg = <0>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			clocks = <&clk NPCM7XX_CLK_CPU>;
+			clock-names = "clk_cpu";
+			reg = <1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index f4a7770..29e1dc5 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -185,6 +185,7 @@
 			    "nvidia,tegra186-denver"
 			    "qcom,krait"
 			    "qcom,kryo"
+			    "qcom,kryo385"
 			    "qcom,scorpion"
 	- enable-method
 		Value type: <stringlist>
@@ -198,6 +199,7 @@
 			    "actions,s500-smp"
 			    "allwinner,sun6i-a31"
 			    "allwinner,sun8i-a23"
+			    "allwinner,sun9i-a80-smp"
 			    "amlogic,meson8-smp"
 			    "amlogic,meson8b-smp"
 			    "arm,realview-smp"
diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt
index 91d5178..7d21ab3 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek.txt
@@ -50,6 +50,15 @@
 - Reference board variant 1 for MT7622:
     Required root node properties:
       - compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622";
+- Reference board for MT7623a with eMMC:
+    Required root node properties:
+      - compatible = "mediatek,mt7623a-rfb-emmc", "mediatek,mt7623";
+- Reference board for MT7623a with NAND:
+    Required root node properties:
+      - compatible = "mediatek,mt7623a-rfb-nand", "mediatek,mt7623";
+- Reference board for MT7623n with eMMC:
+    Required root node properties:
+      - compatible = "mediatek,mt7623n-rfb-emmc", "mediatek,mt7623";
 - Reference  board for MT7623n with NAND:
     Required root node properties:
       - compatible = "mediatek,mt7623n-rfb-nand", "mediatek,mt7623";
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
index 6cc7840..8f5335b 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
@@ -9,6 +9,7 @@
 	- "mediatek,mt2701-ethsys", "syscon"
 	- "mediatek,mt7622-ethsys", "syscon"
 - #clock-cells: Must be 1
+- #reset-cells: Must be 1
 
 The ethsys controller uses the common clk binding from
 Documentation/devicetree/bindings/clock/clock-bindings.txt
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
index d5d5f12..7fe5dc6 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
@@ -8,6 +8,7 @@
 - compatible: Should be:
 	- "mediatek,mt7622-pciesys", "syscon"
 - #clock-cells: Must be 1
+- #reset-cells: Must be 1
 
 The PCIESYS controller uses the common clk binding from
 Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -19,4 +20,5 @@
 	compatible = "mediatek,mt7622-pciesys", "syscon";
 	reg = <0 0x1a100800 0 0x1000>;
 	#clock-cells = <1>;
+	#reset-cells = <1>;
 };
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
index 00760019..b8184da 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
@@ -8,6 +8,7 @@
 - compatible: Should be:
 	- "mediatek,mt7622-ssusbsys", "syscon"
 - #clock-cells: Must be 1
+- #reset-cells: Must be 1
 
 The SSUSBSYS controller uses the common clk binding from
 Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -19,4 +20,5 @@
 	compatible = "mediatek,mt7622-ssusbsys", "syscon";
 	reg = <0 0x1a000000 0 0x1000>;
 	#clock-cells = <1>;
+	#reset-cells = <1>;
 };
diff --git a/Documentation/devicetree/bindings/arm/npcm/npcm.txt b/Documentation/devicetree/bindings/arm/npcm/npcm.txt
new file mode 100644
index 0000000..2d87d9e
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/npcm/npcm.txt
@@ -0,0 +1,6 @@
+NPCM Platforms Device Tree Bindings
+-----------------------------------
+NPCM750 SoC
+Required root node properties:
+	- compatible = "nuvoton,npcm750";
+
diff --git a/Documentation/devicetree/bindings/arm/omap/ctrl.txt b/Documentation/devicetree/bindings/arm/omap/ctrl.txt
index ce8dabf..f35b779 100644
--- a/Documentation/devicetree/bindings/arm/omap/ctrl.txt
+++ b/Documentation/devicetree/bindings/arm/omap/ctrl.txt
@@ -25,6 +25,7 @@
 		"ti,omap4-scm-padconf-wkup"
 		"ti,omap5-scm-core"
 		"ti,omap5-scm-padconf-core"
+		"ti,omap5-scm-wkup-pad-conf"
 		"ti,dra7-scm-core"
 - reg:		Contains Control Module register address range
 		(base address and length)
diff --git a/Documentation/devicetree/bindings/arm/omap/mpu.txt b/Documentation/devicetree/bindings/arm/omap/mpu.txt
index 763695d..f301e63 100644
--- a/Documentation/devicetree/bindings/arm/omap/mpu.txt
+++ b/Documentation/devicetree/bindings/arm/omap/mpu.txt
@@ -13,6 +13,13 @@
 Optional properties:
 - sram:	Phandle to the ocmcram node
 
+am335x and am437x only:
+- pm-sram: Phandles to ocmcram nodes to be used for power management.
+	   First should be type 'protect-exec' for the driver to use to copy
+	   and run PM functions, second should be regular pool to be used for
+	   data region for code. See Documentation/devicetree/bindings/sram/sram.txt
+	   for more details.
+
 Examples:
 
 - For an OMAP5 SMP system:
@@ -36,3 +43,12 @@
     compatible = "ti,omap3-mpu";
     ti,hwmods = "mpu";
 };
+
+- For an AM335x system:
+
+mpu {
+	compatible = "ti,omap3-mpu";
+	ti,hwmods = "mpu";
+	pm-sram = <&pm_sram_code
+		   &pm_sram_data>;
+};
diff --git a/Documentation/devicetree/bindings/arm/qcom.txt b/Documentation/devicetree/bindings/arm/qcom.txt
index 0ed4d39..ee532e7 100644
--- a/Documentation/devicetree/bindings/arm/qcom.txt
+++ b/Documentation/devicetree/bindings/arm/qcom.txt
@@ -26,6 +26,7 @@
 	msm8996
 	mdm9615
 	ipq8074
+	sdm845
 
 The 'board' element must be one of the following strings:
 
diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
index 326d24b..1c1d62d 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.txt
+++ b/Documentation/devicetree/bindings/arm/rockchip.txt
@@ -50,6 +50,10 @@
     Required root node properties:
       - compatible = "firefly,firefly-rk3399", "rockchip,rk3399";
 
+- Firefly roc-rk3328-cc board:
+    Required root node properties:
+      - compatible = "firefly,roc-rk3328-cc", "rockchip,rk3328";
+
 - ChipSPARK PopMetal-RK3288 board:
     Required root node properties:
       - compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288";
@@ -181,10 +185,18 @@
     Required root node properties:
       - compatible = "rockchip,rk3399-evb", "rockchip,rk3399";
 
+- Rockchip RK3399 Sapphire board standalone:
+    Required root node properties:
+      - compatible = "rockchip,rk3399-sapphire", "rockchip,rk3399";
+
 - Rockchip RK3399 Sapphire Excavator board:
     Required root node properties:
       - compatible = "rockchip,rk3399-sapphire-excavator", "rockchip,rk3399";
 
+- Theobroma Systems RK3368-uQ7 Haikou Baseboard:
+    Required root node properties:
+      - compatible = "tsd,rk3368-uq7-haikou", "rockchip,rk3368";
+
 - Theobroma Systems RK3399-Q7 Haikou Baseboard:
     Required root node properties:
       - compatible = "tsd,rk3399-q7-haikou", "rockchip,rk3399";
diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
index 779f561..1668578 100644
--- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
@@ -43,6 +43,12 @@
 - interrupt-parent: a phandle indicating which interrupt controller
   this PMU signals interrupts to.
 
+
+Optional nodes:
+
+- nodes defining the restart and poweroff syscon children
+
+
 Example :
 pmu_system_controller: system-controller@10040000 {
 	compatible = "samsung,exynos5250-pmu", "syscon";
diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
index 469ac98..14510b2 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
@@ -9,7 +9,11 @@
 	- "samsung,smdkv310"	- for Exynos4210-based Samsung SMDKV310 eval board.
 	- "samsung,trats"	- for Exynos4210-based Tizen Reference board.
 	- "samsung,universal_c210" - for Exynos4210-based Samsung board.
+	- "samsung,i9300"          - for Exynos4412-based Samsung GT-I9300 board.
+	- "samsung,i9305"          - for Exynos4412-based Samsung GT-I9305 board.
+	- "samsung,midas"       - for Exynos4412-based Samsung Midas board.
 	- "samsung,smdk4412",	- for Exynos4412-based Samsung SMDK4412 eval board.
+	- "samsung,n710x"          - for Exynos4412-based Samsung GT-N7100/GT-N7105 board.
 	- "samsung,trats2"	- for Exynos4412-based Tizen Reference board.
 	- "samsung,smdk5250"	- for Exynos5250-based Samsung SMDK5250 eval board.
 	- "samsung,xyref5260"	- for Exynos5260-based Samsung board.
diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt
index 5c3af7e..d3d1df9 100644
--- a/Documentation/devicetree/bindings/arm/shmobile.txt
+++ b/Documentation/devicetree/bindings/arm/shmobile.txt
@@ -39,8 +39,12 @@
     compatible = "renesas,r8a7795"
   - R-Car M3-W (R8A77960)
     compatible = "renesas,r8a7796"
+  - R-Car M3-N (R8A77965)
+    compatible = "renesas,r8a77965"
   - R-Car V3M (R8A77970)
     compatible = "renesas,r8a77970"
+  - R-Car V3H (R8A77980)
+    compatible = "renesas,r8a77980"
   - R-Car D3 (R8A77995)
     compatible = "renesas,r8a77995"
 
@@ -52,11 +56,13 @@
   - APE6-EVM
     compatible = "renesas,ape6evm", "renesas,r8a73a4"
   - Atmark Techno Armadillo-800 EVA
-    compatible = "renesas,armadillo800eva"
+    compatible = "renesas,armadillo800eva", "renesas,r8a7740"
   - Blanche (RTP0RC7792SEB00010S)
     compatible = "renesas,blanche", "renesas,r8a7792"
   - BOCK-W
     compatible = "renesas,bockw", "renesas,r8a7778"
+  - Condor (RTP0RC77980SEB0010SS/RTP0RC77980SEB0010SA01)
+    compatible = "renesas,condor", "renesas,r8a77980"
   - Draak (RTP0RC77995SEB0010S)
     compatible = "renesas,draak", "renesas,r8a77995"
   - Eagle (RTP0RC77970SEB0010S)
@@ -102,19 +108,25 @@
     compatible = "renesas,salvator-x", "renesas,r8a7795"
   - Salvator-X (RTP0RC7796SIPB0011S)
     compatible = "renesas,salvator-x", "renesas,r8a7796"
+  - Salvator-X (RTP0RC7796SIPB0011S (M3N))
+    compatible = "renesas,salvator-x", "renesas,r8a77965"
   - Salvator-XS (Salvator-X 2nd version, RTP0RC7795SIPB0012S)
     compatible = "renesas,salvator-xs", "renesas,r8a7795"
   - Salvator-XS (Salvator-X 2nd version, RTP0RC7796SIPB0012S)
     compatible = "renesas,salvator-xs", "renesas,r8a7796"
+  - Salvator-XS (Salvator-X 2nd version, RTP0RC77965SIPB012S)
+    compatible = "renesas,salvator-xs", "renesas,r8a77965"
   - SILK (RTP0RC7794LCB00011S)
     compatible = "renesas,silk", "renesas,r8a7794"
   - SK-RZG1E (YR8A77450S000BE)
     compatible = "renesas,sk-rzg1e", "renesas,r8a7745"
   - SK-RZG1M (YR8A77430S000BE)
     compatible = "renesas,sk-rzg1m", "renesas,r8a7743"
-  - V3MSK
+  - Stout (ADAS Starterkit, Y-R-CAR-ADAS-SKH2-BOARD)
+    compatible = "renesas,stout", "renesas,r8a7790"
+  - V3MSK (Y-ASK-RCAR-V3M-WS10)
     compatible = "renesas,v3msk", "renesas,r8a77970"
-  - Wheat
+  - Wheat (RTP0RC7792ASKB0000JE)
     compatible = "renesas,wheat", "renesas,r8a7792"
 
 
diff --git a/Documentation/devicetree/bindings/arm/stm32.txt b/Documentation/devicetree/bindings/arm/stm32.txt
index 05762b0..6808ed9 100644
--- a/Documentation/devicetree/bindings/arm/stm32.txt
+++ b/Documentation/devicetree/bindings/arm/stm32.txt
@@ -7,3 +7,4 @@
   st,stm32f469
   st,stm32f746
   st,stm32h743
+  st,stm32mp157
diff --git a/Documentation/devicetree/bindings/arm/sunxi/smp-sram.txt b/Documentation/devicetree/bindings/arm/sunxi/smp-sram.txt
new file mode 100644
index 0000000..082e6a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunxi/smp-sram.txt
@@ -0,0 +1,44 @@
+Allwinner SRAM for smp bringup:
+------------------------------------------------
+
+Allwinner's A80 SoC uses part of the secure sram for hotplugging of the
+primary core (cpu0). Once the core gets powered up it checks if a magic
+value is set at a specific location. If it is then the BROM will jump
+to the software entry address, instead of executing a standard boot.
+
+Therefore a reserved section sub-node has to be added to the mmio-sram
+declaration.
+
+Note that this is separate from the Allwinner SRAM controller found in
+../../sram/sunxi-sram.txt. This SRAM is secure only and not mappable to
+any device.
+
+Also there are no "secure-only" properties. The implementation should
+check if this SRAM is usable first.
+
+Required sub-node properties:
+- compatible : depending on the SoC this should be one of:
+		"allwinner,sun9i-a80-smp-sram"
+
+The rest of the properties should follow the generic mmio-sram discription
+found in ../../misc/sram.txt
+
+Example:
+
+	sram_b: sram@20000 {
+		/* 256 KiB secure SRAM at 0x20000 */
+		compatible = "mmio-sram";
+		reg = <0x00020000 0x40000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x00020000 0x40000>;
+
+		smp-sram@1000 {
+			/*
+			 * This is checked by BROM to determine if
+			 * cpu0 should jump to SMP entry vector
+			 */
+			compatible = "allwinner,sun9i-a80-smp-sram";
+			reg = <0x1000 0x8>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/arm/tegra.txt b/Documentation/devicetree/bindings/arm/tegra.txt
index 7f1411b..32f62bb 100644
--- a/Documentation/devicetree/bindings/arm/tegra.txt
+++ b/Documentation/devicetree/bindings/arm/tegra.txt
@@ -9,6 +9,12 @@
 
   nvidia,tegra20
   nvidia,tegra30
+  nvidia,tegra114
+  nvidia,tegra124
+  nvidia,tegra132
+  nvidia,tegra210
+  nvidia,tegra186
+  nvidia,tegra194
 
 Boards
 -------------------------------------------
@@ -26,8 +32,18 @@
   nvidia,cardhu
   nvidia,cardhu-a02
   nvidia,cardhu-a04
+  nvidia,dalmore
   nvidia,harmony
+  nvidia,jetson-tk1
+  nvidia,norrin
+  nvidia,p2371-0000
+  nvidia,p2371-2180
+  nvidia,p2571
+  nvidia,p2771-0000
+  nvidia,p2972-0000
+  nvidia,roth
   nvidia,seaboard
+  nvidia,tn7
   nvidia,ventana
   toradex,apalis_t30
   toradex,apalis_t30-eval
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
index 078a58b..5a3bf7c 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
@@ -3,6 +3,7 @@
 Required properties:
 - compatible: Should contain one of the following:
   - "nvidia,tegra186-pmc": for Tegra186
+  - "nvidia,tegra194-pmc": for Tegra194
 - reg: Must contain an (offset, length) pair of the register set for each
   entry in reg-names.
 - reg-names: Must include the following entries:
@@ -10,6 +11,7 @@
   - "wake"
   - "aotag"
   - "scratch"
+  - "misc" (Only for Tegra194)
 
 Optional properties:
 - nvidia,invert-interrupt: If present, inverts the PMU interrupt signal.
diff --git a/Documentation/devicetree/bindings/arm/xilinx.txt b/Documentation/devicetree/bindings/arm/xilinx.txt
index 1f79953..b9043bc 100644
--- a/Documentation/devicetree/bindings/arm/xilinx.txt
+++ b/Documentation/devicetree/bindings/arm/xilinx.txt
@@ -5,3 +5,59 @@
 
 Required root node properties:
     - compatible = "xlnx,zynq-7000";
+
+Additional compatible strings:
+
+- Xilinx internal board cc108
+  "xlnx,zynq-cc108"
+
+- Xilinx internal board zc770 with different FMC cards
+  "xlnx,zynq-zc770-xm010"
+  "xlnx,zynq-zc770-xm011"
+  "xlnx,zynq-zc770-xm012"
+  "xlnx,zynq-zc770-xm013"
+
+- Digilent Zybo Z7 board
+  "digilent,zynq-zybo-z7"
+
+---------------------------------------------------------------
+
+Xilinx Zynq UltraScale+ MPSoC Platforms Device Tree Bindings
+
+Boards with ZynqMP SOC based on an ARM Cortex A53 processor
+shall have the following properties.
+
+Required root node properties:
+    - compatible = "xlnx,zynqmp";
+
+
+Additional compatible strings:
+
+- Xilinx internal board zc1232
+  "xlnx,zynqmp-zc1232-revA", "xlnx,zynqmp-zc1232"
+
+- Xilinx internal board zc1254
+  "xlnx,zynqmp-zc1254-revA", "xlnx,zynqmp-zc1254"
+
+- Xilinx internal board zc1275
+  "xlnx,zynqmp-zc1275-revA", "xlnx,zynqmp-zc1275"
+
+- Xilinx internal board zc1751
+  "xlnx,zynqmp-zc1751"
+
+- Xilinx 96boards compatible board zcu100
+  "xlnx,zynqmp-zcu100-revC", "xlnx,zynqmp-zcu100"
+
+- Xilinx evaluation board zcu102
+  "xlnx,zynqmp-zcu102-revA", "xlnx,zynqmp-zcu102"
+  "xlnx,zynqmp-zcu102-revB", "xlnx,zynqmp-zcu102"
+  "xlnx,zynqmp-zcu102-rev1.0", "xlnx,zynqmp-zcu102"
+
+- Xilinx evaluation board zcu104
+  "xlnx,zynqmp-zcu104-revA", "xlnx,zynqmp-zcu104"
+
+- Xilinx evaluation board zcu106
+  "xlnx,zynqmp-zcu106-revA", "xlnx,zynqmp-zcu106"
+
+- Xilinx evaluation board zcu111
+  "xlnx,zynqmp-zcu111-revA", "xlnx,zynqmp-zcu111"
diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
index 3e21eb8..c1e7062 100644
--- a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
+++ b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
@@ -73,7 +73,7 @@
 controllers with a simple-bus node since they are all connected to the same
 chip-select (CS4), in this example external address decoding is provided:
 
-gmi@70090000 {
+gmi@70009000 {
 	compatible = "nvidia,tegra20-gmi";
 	reg = <0x70009000 0x1000>;
 	#address-cells = <2>;
@@ -84,7 +84,6 @@
 	reset-names = "gmi";
 	ranges = <4 0 0xd0000000 0xfffffff>;
 
-
 	bus@4,0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -109,7 +108,7 @@
 Example with one SJA1000 CAN controller connected to the GMI bus
 on CS4:
 
-gmi@70090000 {
+gmi@70009000 {
 	compatible = "nvidia,tegra20-gmi";
 	reg = <0x70009000 0x1000>;
 	#address-cells = <2>;
@@ -120,7 +119,6 @@
 	reset-names = "gmi";
 	ranges = <4 0 0xd0000000 0xfffffff>;
 
-
 	can@4,0 {
 		reg = <4 0 0x100>;
 		nvidia,snor-mux-mode;
diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
index 76aec8a..3c1f3a2 100644
--- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
+++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
@@ -415,12 +415,27 @@
 	value type: <u32>
 	Definition: LP register offset. default it is 0x34.
 
+   - clocks
+      Usage: optional, required if SNVS LP RTC requires explicit
+          enablement of clocks
+      Value type: <prop_encoded-array>
+      Definition:  a clock specifier describing the clock required for
+          enabling and disabling SNVS LP RTC.
+
+   - clock-names
+      Usage: optional, required if SNVS LP RTC requires explicit
+          enablement of clocks
+      Value type: <string>
+      Definition: clock name string should be "snvs-rtc".
+
 EXAMPLE
 	sec_mon_rtc_lp@1 {
 		compatible = "fsl,sec-v4.0-mon-rtc-lp";
 		interrupts = <93 2>;
 		regmap = <&snvs>;
 		offset = <0x34>;
+		clocks = <&clks IMX7D_SNVS_CLK>;
+		clock-names = "snvs-rtc";
 	};
 
 =====================================================================
@@ -543,6 +558,8 @@
 			regmap = <&sec_mon>;
 			offset = <0x34>;
 			interrupts = <93 2>;
+			clocks = <&clks IMX7D_SNVS_CLK>;
+			clock-names = "snvs-rtc";
 		};
 
 		snvs-pwrkey@020cc000 {
diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
index baf9b34..b6a8cc0 100644
--- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
+++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
@@ -74,8 +74,8 @@
 
 bcm2835_i2s: i2s@7e203000 {
 	compatible = "brcm,bcm2835-i2s";
-	reg = <	0x7e203000 0x20>,
-	      < 0x7e101098 0x02>;
+	reg = <	0x7e203000 0x24>;
+	clocks = <&clocks BCM2835_CLOCK_PCM>;
 
 	dmas = <&dma 2>,
 	       <&dma 3>;
diff --git a/Documentation/devicetree/bindings/gpio/gpio-eic-sprd.txt b/Documentation/devicetree/bindings/gpio/gpio-eic-sprd.txt
new file mode 100644
index 0000000..93d98d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-eic-sprd.txt
@@ -0,0 +1,97 @@
+Spreadtrum EIC controller bindings
+
+The EIC is the abbreviation of external interrupt controller, which can
+be used only in input mode. The Spreadtrum platform has 2 EIC controllers,
+one is in digital chip, and another one is in PMIC. The digital chip EIC
+controller contains 4 sub-modules: EIC-debounce, EIC-latch, EIC-async and
+EIC-sync. But the PMIC EIC controller contains only one EIC-debounce sub-
+module.
+
+The EIC-debounce sub-module provides up to 8 source input signal
+connections. A debounce mechanism is used to capture the input signals'
+stable status (millisecond resolution) and a single-trigger mechanism
+is introduced into this sub-module to enhance the input event detection
+reliability. In addition, this sub-module's clock can be shut off
+automatically to reduce power dissipation. Moreover the debounce range
+is from 1ms to 4s with a step size of 1ms. The input signal will be
+ignored if it is asserted for less than 1 ms.
+
+The EIC-latch sub-module is used to latch some special power down signals
+and generate interrupts, since the EIC-latch does not depend on the APB
+clock to capture signals.
+
+The EIC-async sub-module uses a 32kHz clock to capture the short signals
+(microsecond resolution) to generate interrupts by level or edge trigger.
+
+The EIC-sync is similar with GPIO's input function, which is a synchronized
+signal input register. It can generate interrupts by level or edge trigger
+when detecting input signals.
+
+Required properties:
+- compatible: Should be one of the following:
+  "sprd,sc9860-eic-debounce",
+  "sprd,sc9860-eic-latch",
+  "sprd,sc9860-eic-async",
+  "sprd,sc9860-eic-sync",
+  "sprd,sc27xx-eic".
+- reg: Define the base and range of the I/O address space containing
+  the GPIO controller registers.
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be <2>. The first cell is the gpio number and
+  the second cell is used to specify optional parameters.
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells: Should be <2>. Specifies the number of cells needed
+  to encode interrupt source.
+- interrupts: Should be the port interrupt shared by all the gpios.
+
+Example:
+	eic_debounce: gpio@40210000 {
+		compatible = "sprd,sc9860-eic-debounce";
+		reg = <0 0x40210000 0 0x80>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	eic_latch: gpio@40210080 {
+		compatible = "sprd,sc9860-eic-latch";
+		reg = <0 0x40210080 0 0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	eic_async: gpio@402100a0 {
+		compatible = "sprd,sc9860-eic-async";
+		reg = <0 0x402100a0 0 0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	eic_sync: gpio@402100c0 {
+		compatible = "sprd,sc9860-eic-sync";
+		reg = <0 0x402100c0 0 0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pmic_eic: gpio@300 {
+		compatible = "sprd,sc27xx-eic";
+		reg = <0x300>;
+		interrupt-parent = <&sc2731_pmic>;
+		interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt b/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt
index 0d01587..d2a9376 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt
@@ -16,6 +16,8 @@
 	nxp,pca9574
 	nxp,pca9575
 	nxp,pca9698
+	nxp,pcal6524
+	nxp,pcal9555a
 	maxim,max7310
 	maxim,max7312
 	maxim,max7313
diff --git a/Documentation/devicetree/bindings/gpio/gpio-sprd.txt b/Documentation/devicetree/bindings/gpio/gpio-sprd.txt
new file mode 100644
index 0000000..eca97d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-sprd.txt
@@ -0,0 +1,28 @@
+Spreadtrum GPIO controller bindings
+
+The controller's registers are organized as sets of sixteen 16-bit
+registers with each set controlling a bank of up to 16 pins. A single
+interrupt is shared for all of the banks handled by the controller.
+
+Required properties:
+- compatible: Should be "sprd,sc9860-gpio".
+- reg: Define the base and range of the I/O address space containing
+the GPIO controller registers.
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be <2>. The first cell is the gpio number and
+the second cell is used to specify optional parameters.
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells: Should be <2>. Specifies the number of cells needed
+to encode interrupt source.
+- interrupts: Should be the port interrupt shared by all the gpios.
+
+Example:
+	ap_gpio: gpio@40280000 {
+		compatible = "sprd,sc9860-gpio";
+		reg = <0 0x40280000 0 0x1000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+	};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt b/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt
deleted file mode 100644
index 528f5ef..0000000
--- a/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-ImgTec TZ1090 PDC GPIO Controller
-
-Required properties:
-- compatible: Compatible property value should be "img,tz1090-pdc-gpio".
-
-- reg: Physical base address of the controller and length of memory mapped
-  region. This starts at and cover the SOC_GPIO_CONTROL registers.
-
-- gpio-controller: Specifies that the node is a gpio controller.
-
-- #gpio-cells: Should be 2. The syntax of the gpio specifier used by client
-  nodes should have the following values.
-     <[phandle of the gpio controller node]
-      [PDC gpio number]
-      [gpio flags]>
-
-  Values for gpio specifier:
-  - GPIO number: a value in the range 0 to 6.
-  - GPIO flags: bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
-    Only the following flags are supported:
-      GPIO_ACTIVE_HIGH
-      GPIO_ACTIVE_LOW
-
-Optional properties:
-- gpio-ranges: Mapping to pin controller pins (as described in
-  Documentation/devicetree/bindings/gpio/gpio.txt)
-
-- interrupts: Individual syswake interrupts (other GPIOs cannot interrupt)
-
-
-Example:
-
-	pdc_gpios: gpio-controller@2006500 {
-		gpio-controller;
-		#gpio-cells = <2>;
-
-		compatible = "img,tz1090-pdc-gpio";
-		reg = <0x02006500 0x100>;
-
-		interrupt-parent = <&pdc>;
-		interrupts =	<8  IRQ_TYPE_NONE>,	/* Syswake 0 */
-				<9  IRQ_TYPE_NONE>,	/* Syswake 1 */
-				<10 IRQ_TYPE_NONE>;	/* Syswake 2 */
-		gpio-ranges = <&pdc_pinctrl 0 0 7>;
-	};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt b/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
deleted file mode 100644
index b05a90e..0000000
--- a/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-ImgTec TZ1090 GPIO Controller
-
-Required properties:
-- compatible: Compatible property value should be "img,tz1090-gpio".
-
-- reg: Physical base address of the controller and length of memory mapped
-  region.
-
-- #address-cells: Should be 1 (for bank subnodes)
-
-- #size-cells: Should be 0 (for bank subnodes)
-
-- Each bank of GPIOs should have a subnode to represent it.
-
-  Bank subnode required properties:
-  - reg: Index of bank in the range 0 to 2.
-
-  - gpio-controller: Specifies that the node is a gpio controller.
-
-  - #gpio-cells: Should be 2. The syntax of the gpio specifier used by client
-    nodes should have the following values.
-       <[phandle of the gpio controller node]
-        [gpio number within the gpio bank]
-        [gpio flags]>
-
-    Values for gpio specifier:
-    - GPIO number: a value in the range 0 to 29.
-    - GPIO flags: bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
-      Only the following flags are supported:
-        GPIO_ACTIVE_HIGH
-        GPIO_ACTIVE_LOW
-
-  Bank subnode optional properties:
-  - gpio-ranges: Mapping to pin controller pins (as described in
-    Documentation/devicetree/bindings/gpio/gpio.txt)
-
-  - interrupts: Interrupt for the entire bank
-
-  - interrupt-controller: Specifies that the node is an interrupt controller
-
-  - #interrupt-cells: Should be 2. The syntax of the interrupt specifier used by
-    client nodes should have the following values.
-       <[phandle of the interurupt controller]
-        [gpio number within the gpio bank]
-        [irq flags]>
-
-    Values for irq specifier:
-    - GPIO number: a value in the range 0 to 29
-    - IRQ flags: value to describe edge and level triggering, as defined in
-      <dt-bindings/interrupt-controller/irq.h>. Only the following flags are
-      supported:
-        IRQ_TYPE_EDGE_RISING
-        IRQ_TYPE_EDGE_FALLING
-        IRQ_TYPE_EDGE_BOTH
-        IRQ_TYPE_LEVEL_HIGH
-        IRQ_TYPE_LEVEL_LOW
-
-
-
-Example:
-
-	gpios: gpio-controller@2005800 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "img,tz1090-gpio";
-		reg = <0x02005800 0x90>;
-
-		/* bank 0 with an interrupt */
-		gpios0: bank@0 {
-			#gpio-cells = <2>;
-			#interrupt-cells = <2>;
-			reg = <0>;
-			interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
-			gpio-controller;
-			gpio-ranges = <&pinctrl 0 0 30>;
-			interrupt-controller;
-		};
-
-		/* bank 2 without interrupt */
-		gpios2: bank@2 {
-			#gpio-cells = <2>;
-			reg = <2>;
-			gpio-controller;
-			gpio-ranges = <&pinctrl 0 60 30>;
-		};
-	};
-
-
diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index b5de08e..a7c31de 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -151,9 +151,9 @@
 first 18 GPIOs, at local offset 0 .. 17, are in use.
 
 If these GPIOs do not happen to be the first N GPIOs at offset 0...N-1, an
-additional bitmask is needed to specify which GPIOs are actually in use,
-and which are dummies. The bindings for this case has not yet been
-specified, but should be specified if/when such hardware appears.
+additional set of tuples is needed to specify which GPIOs are unusable, with
+the gpio-reserved-ranges binding. This property indicates the start and size
+of the GPIOs that can't be used.
 
 Optionally, a GPIO controller may have a "gpio-line-names" property. This is
 an array of strings defining the names of the GPIO lines going out of the
@@ -178,6 +178,7 @@
 	gpio-controller;
 	#gpio-cells = <2>;
 	ngpios = <18>;
+	gpio-reserved-ranges = <0 4>, <12 2>;
 	gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R",
 		"LED G", "LED B", "Col A", "Col B", "Col C", "Col D",
 		"Row A", "Row B", "Row C", "Row D", "NMI button",
diff --git a/Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt b/Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt
new file mode 100644
index 0000000..20fc72d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt
@@ -0,0 +1,27 @@
+Nintendo Wii (Hollywood) GPIO controller
+
+Required properties:
+- compatible: "nintendo,hollywood-gpio
+- reg: Physical base address and length of the controller's registers.
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be <2>. The first cell is the pin number and the
+  second cell is used to specify optional parameters:
+   - bit 0 specifies polarity (0 for normal, 1 for inverted).
+
+Optional properties:
+- ngpios: see Documentation/devicetree/bindings/gpio/gpio.txt
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells: Should be two.
+- interrupts: Interrupt specifier for the controller's Broadway (PowerPC)
+  interrupt.
+- interrupt-parent: phandle of the parent interrupt controller.
+
+Example:
+
+	GPIO: gpio@d8000c0 {
+		#gpio-cells = <2>;
+		compatible = "nintendo,hollywood-gpio";
+		reg = <0x0d8000c0 0x40>;
+		gpio-controller;
+		ngpios = <24>;
+	}
diff --git a/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
new file mode 100644
index 0000000..ce97265
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
@@ -0,0 +1,30 @@
+Raspberry Pi GPIO expander
+
+The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware. The
+firmware exposes a mailbox interface that allows the ARM core to control the
+GPIO lines on the expander.
+
+The Raspberry Pi GPIO expander node must be a child node of the Raspberry Pi
+firmware node.
+
+Required properties:
+
+- compatible : Should be "raspberrypi,firmware-gpio"
+- gpio-controller : Marks the device node as a gpio controller
+- #gpio-cells : Should be two.  The first cell is the pin number, and
+  the second cell is used to specify the gpio polarity:
+  0 = active high
+  1 = active low
+
+Example:
+
+firmware: firmware-rpi {
+	compatible = "raspberrypi,bcm2835-firmware";
+	mboxes = <&mailbox>;
+
+	expgpio: gpio {
+		 compatible = "raspberrypi,firmware-gpio";
+		 gpio-controller;
+		 #gpio-cells = <2>;
+	 };
+};
diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
index ad87654..c1f65d1 100644
--- a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
+++ b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
@@ -10,6 +10,7 @@
     * And, optionally, one of the vendor specific compatible:
       + allwinner,sun4i-a10-mali
       + allwinner,sun7i-a20-mali
+      + allwinner,sun8i-h3-mali
       + allwinner,sun50i-h5-mali
       + amlogic,meson-gxbb-mali
       + amlogic,meson-gxl-mali
diff --git a/Documentation/devicetree/bindings/input/gpio-keys.txt b/Documentation/devicetree/bindings/input/gpio-keys.txt
index a949404..996ce84 100644
--- a/Documentation/devicetree/bindings/input/gpio-keys.txt
+++ b/Documentation/devicetree/bindings/input/gpio-keys.txt
@@ -26,6 +26,14 @@
 	  If not specified defaults to 5.
 	- wakeup-source: Boolean, button can wake-up the system.
 			 (Legacy property supported: "gpio-key,wakeup")
+	- wakeup-event-action: Specifies whether the key should wake the
+	  system when asserted, when deasserted, or both. This property is
+	  only valid for keys that wake up the system (e.g., when the
+	  "wakeup-source" property is also provided).
+	  Supported values are defined in linux-event-codes.h:
+		EV_ACT_ASSERTED		- asserted
+		EV_ACT_DEASSERTED	- deasserted
+		EV_ACT_ANY		- both asserted and deasserted
 	- linux,can-disable: Boolean, indicates that button is connected
 	  to dedicated (not shared) interrupt which can be disabled to
 	  suppress events from the button.
diff --git a/Documentation/devicetree/bindings/input/zii,rave-sp-pwrbutton.txt b/Documentation/devicetree/bindings/input/zii,rave-sp-pwrbutton.txt
new file mode 100644
index 0000000..43ef770
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/zii,rave-sp-pwrbutton.txt
@@ -0,0 +1,22 @@
+Zodiac Inflight Innovations RAVE Supervisory Processor Power Button Bindings
+
+RAVE SP input device is a "MFD cell" device corresponding to power
+button functionality of RAVE Supervisory Processor. It is expected
+that its Device Tree node is specified as a child of the node
+corresponding to the parent RAVE SP device (as documented in
+Documentation/devicetree/bindings/mfd/zii,rave-sp.txt)
+
+Required properties:
+
+- compatible: Should be "zii,rave-sp-pwrbutton"
+
+Example:
+
+	rave-sp {
+		compatible = "zii,rave-sp-rdu1";
+		current-speed = <38400>;
+
+		pwrbutton {
+			compatible = "zii,rave-sp-pwrbutton";
+		};
+	}
diff --git a/Documentation/devicetree/bindings/mailbox/mailbox.txt b/Documentation/devicetree/bindings/mailbox/mailbox.txt
index be05b97..af8ecee 100644
--- a/Documentation/devicetree/bindings/mailbox/mailbox.txt
+++ b/Documentation/devicetree/bindings/mailbox/mailbox.txt
@@ -23,6 +23,11 @@
 
 Optional property:
 - mbox-names: List of identifier strings for each mailbox channel.
+- shmem : List of phandle pointing to the shared memory(SHM) area between the
+	  users of these mailboxes for IPC, one for each mailbox. This shared
+	  memory can be part of any memory reserved for the purpose of this
+	  communication between the mailbox client and the remote.
+
 
 Example:
 	pwr_cntrl: power {
@@ -30,3 +35,26 @@
 		mbox-names = "pwr-ctrl", "rpc";
 		mboxes = <&mailbox 0 &mailbox 1>;
 	};
+
+Example with shared memory(shmem):
+
+	sram: sram@50000000 {
+		compatible = "mmio-sram";
+		reg = <0x50000000 0x10000>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x50000000 0x10000>;
+
+		cl_shmem: shmem@0 {
+			compatible = "client-shmem";
+			reg = <0x0 0x200>;
+		};
+	};
+
+	client@2e000000 {
+		...
+		mboxes = <&mailbox 0>;
+		shmem = <&cl_shmem>;
+		..
+	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti/emif.txt b/Documentation/devicetree/bindings/memory-controllers/ti/emif.txt
index 621b41c..44d7146 100644
--- a/Documentation/devicetree/bindings/memory-controllers/ti/emif.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/ti/emif.txt
@@ -3,7 +3,9 @@
 EMIF - External Memory Interface - is an SDRAM controller used in
 TI SoCs. EMIF supports, based on the IP revision, one or more of
 DDR2/DDR3/LPDDR2 protocols. This binding describes a given instance
-of the EMIF IP and memory parts attached to it.
+of the EMIF IP and memory parts attached to it. Certain revisions
+of the EMIF controller also contain optional ECC support, which
+corrects one bit errors and detects two bit errors.
 
 Required properties:
 - compatible	: Should be of the form "ti,emif-<ip-rev>" where <ip-rev>
@@ -11,6 +13,8 @@
   compatible should be one of the following:
   	     "ti,emif-am3352"
 	     "ti,emif-am4372"
+	     "ti,emif-dra7xx"
+	     "ti,emif-keystone"
 
 - phy-type	: <u32> indicating the DDR phy type. Following are the
   allowed values
@@ -22,6 +26,7 @@
 - ti,hwmods	: For TI hwmods processing and omap device creation
   the value shall be "emif<n>" where <n> is the number of the EMIF
   instance with base 1.
+- interrupts	: interrupt used by the controller
 
 Required only for "ti,emif-am3352" and "ti,emif-am4372":
 - sram			: Phandles for generic sram driver nodes,
@@ -71,3 +76,9 @@
         sram = <&pm_sram_code
                 &pm_sram_data>;
 };
+
+emif1: emif@4c000000 {
+	compatible = "ti,emif-dra7xx";
+	reg = <0x4c000000 0x200>;
+	interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+};
diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
index 69aadee..34dd890 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
+++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
@@ -176,3 +176,24 @@
 	compatible = "aspeed,ast2500-lhc";
 	reg = <0x20 0x24 0x48 0x8>;
 };
+
+LPC reset control
+-----------------
+
+The UARTs present in the ASPEED SoC can have their resets tied to the reset
+state of the LPC bus. Some systems may chose to modify this configuration.
+
+Required properties:
+
+ - compatible:		"aspeed,ast2500-lpc-reset" or
+			"aspeed,ast2400-lpc-reset"
+ - reg:			offset and length of the IP in the LHC memory region
+ - #reset-controller	indicates the number of reset cells expected
+
+Example:
+
+lpc_reset: reset-controller@18 {
+        compatible = "aspeed,ast2500-lpc-reset";
+        reg = <0x18 0x4>;
+        #reset-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
index c655878..8ce49b2 100644
--- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
@@ -21,7 +21,7 @@
 	- "rockchip,rk3399-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3399
 
 Optional Properties:
-* clocks: from common clock binding: if ciu_drive and ciu_sample are
+* clocks: from common clock binding: if ciu-drive and ciu-sample are
   specified in clock-names, should contain handles to these clocks.
 
 * clock-names: Apart from the clock-names described in synopsys-dw-mshc.txt
@@ -29,7 +29,7 @@
   to control the clock phases, "ciu-sample" is required for tuning high-
   speed modes.
 
-* rockchip,default-sample-phase: The default phase to set ciu_sample at
+* rockchip,default-sample-phase: The default phase to set ciu-sample at
   probing, low speeds or in case where all phases work at tuning time.
   If not specified 0 deg will be used.
 
diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 63d4d626..483e9cf 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -39,3 +39,27 @@
 		....
 	};
 };
+
+Example showing the usage of two SPI NOR devices:
+
+&qspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi2>;
+	status = "okay";
+
+	flash0: n25q256a@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <0>;
+	};
+
+	flash1: n25q256a@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a", "jedec,spi-nor";
+		spi-max-frequency = <29000000>;
+		reg = <1>;
+	};
+};
diff --git a/Documentation/devicetree/bindings/mtd/marvell-nand.txt b/Documentation/devicetree/bindings/mtd/marvell-nand.txt
index c08fb47..e0c7907 100644
--- a/Documentation/devicetree/bindings/mtd/marvell-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/marvell-nand.txt
@@ -14,7 +14,10 @@
 - #address-cells: shall be set to 1. Encode the NAND CS.
 - #size-cells: shall be set to 0.
 - interrupts: shall define the NAND controller interrupt.
-- clocks: shall reference the NAND controller clock.
+- clocks: shall reference the NAND controller clocks, the second one is
+  is only needed for the Armada 7K/8K SoCs
+- clock-names: mandatory if there is a second clock, in this case there
+  should be one clock named "core" and another one named "reg"
 - marvell,system-controller: Set to retrieve the syscon node that handles
   NAND controller related registers (only required with the
   "marvell,armada-8k-nand[-controller]" compatibles).
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
index 4a0a48b..232fa12 100644
--- a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
+++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
@@ -41,6 +41,13 @@
 
  - erase-size : The chip's physical erase block size in bytes.
 
+ The device tree may optionally contain endianness property.
+ little-endian or big-endian : It Represents the endianness that should be used
+                               by the controller to  properly read/write data
+			       from/to the flash. If this property is missing,
+			       the endianness is chosen by the system
+			       (potentially based on extra configuration options).
+
 The device tree may optionally contain sub-nodes describing partitions of the
 address space. See partition.txt for more detail.
 
diff --git a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
deleted file mode 100644
index d4ee4da..0000000
--- a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-PXA3xx NAND DT bindings
-
-Required properties:
-
- - compatible:		Should be set to one of the following:
-			marvell,pxa3xx-nand
-			marvell,armada370-nand
-			marvell,armada-8k-nand
- - reg: 		The register base for the controller
- - interrupts:		The interrupt to map
- - #address-cells:	Set to <1> if the node includes partitions
- - marvell,system-controller: Set to retrieve the syscon node that handles
-			NAND controller related registers (only required
-			with marvell,armada-8k-nand compatible).
-
-Optional properties:
-
- - dmas:			dma data channel, see dma.txt binding doc
- - marvell,nand-enable-arbiter:	Set to enable the bus arbiter
- - marvell,nand-keep-config:	Set to keep the NAND controller config as set
-				by the bootloader
- - num-cs:			Number of chipselect lines to use
- - nand-on-flash-bbt: 		boolean to enable on flash bbt option if
-				not present false
- - nand-ecc-strength:           number of bits to correct per ECC step
- - nand-ecc-step-size:          number of data bytes covered by a single ECC step
-
-The following ECC strength and step size are currently supported:
-
- - nand-ecc-strength = <1>, nand-ecc-step-size = <512>
- - nand-ecc-strength = <4>, nand-ecc-step-size = <512>
- - nand-ecc-strength = <8>, nand-ecc-step-size = <512>
-
-Example:
-
-	nand0: nand@43100000 {
-		compatible = "marvell,pxa3xx-nand";
-		reg = <0x43100000 90>;
-		interrupts = <45>;
-		dmas = <&pdma 97 0>;
-		dma-names = "data";
-		#address-cells = <1>;
-
-		marvell,nand-enable-arbiter;
-		marvell,nand-keep-config;
-		num-cs = <1>;
-
-		/* partitions (optional) */
-	};
-
diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
index 5e13a5c..0734f03 100644
--- a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
@@ -24,8 +24,8 @@
 - allwinner,rb : shall contain the native Ready/Busy ids.
  or
 - rb-gpios : shall contain the gpios used as R/B pins.
-- nand-ecc-mode : one of the supported ECC modes ("hw", "hw_syndrome", "soft",
-  "soft_bch" or "none")
+- nand-ecc-mode : one of the supported ECC modes ("hw", "soft", "soft_bch" or
+		  "none")
 
 see Documentation/devicetree/bindings/mtd/nand.txt for generic bindings.
 
diff --git a/Documentation/devicetree/bindings/arm/ccn.txt b/Documentation/devicetree/bindings/perf/arm-ccn.txt
similarity index 100%
rename from Documentation/devicetree/bindings/arm/ccn.txt
rename to Documentation/devicetree/bindings/perf/arm-ccn.txt
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.txt b/Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.txt
index a9aa79f..1aa6f26 100644
--- a/Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.txt
@@ -21,7 +21,9 @@
    - timer: The timeout clock (clk_m). Present if phy_type == utmi.
    - utmi-pads: The clock needed to access the UTMI pad control registers.
      Present if phy_type == utmi.
-   - ulpi-link: The clock Tegra provides to the ULPI PHY (cdev2).
+   - ulpi-link: The clock Tegra provides to the ULPI PHY (usually pad DAP_MCLK2
+     with pad group aka "nvidia,pins" cdev2 and pin mux option config aka
+     "nvidia,function" pllp_out4).
      Present if phy_type == ulpi, and ULPI link mode is in use.
  - resets : Must contain an entry for each entry in reset-names.
    See ../reset/reset.txt for details.
diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt
index 2c46f30..9a06e1f 100644
--- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt
@@ -11,6 +11,7 @@
    "st,stm32f429-pinctrl"
    "st,stm32f469-pinctrl"
    "st,stm32f746-pinctrl"
+   "st,stm32f769-pinctrl"
    "st,stm32h743-pinctrl"
    "st,stm32mp157-pinctrl"
    "st,stm32mp157-z-pinctrl"
diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
index 8690f10..ab399e5 100644
--- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
+++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
@@ -17,7 +17,9 @@
       - "renesas,r8a7794-sysc" (R-Car E2)
       - "renesas,r8a7795-sysc" (R-Car H3)
       - "renesas,r8a7796-sysc" (R-Car M3-W)
+      - "renesas,r8a77965-sysc" (R-Car M3-N)
       - "renesas,r8a77970-sysc" (R-Car V3M)
+      - "renesas,r8a77980-sysc" (R-Car V3H)
       - "renesas,r8a77995-sysc" (R-Car D3)
   - reg: Address start and address range for the device.
   - #power-domain-cells: Must be 1.
diff --git a/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt b/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt
index 36afa32..a3dc4b9 100644
--- a/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt
+++ b/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt
@@ -152,14 +152,7 @@
 
 1.l) The General Purpose I/O (GPIO) controller node
 
-  Represents the dual access 32 GPIO controller interface.
-
-  Required properties:
-
-  - #gpio-cells : <2>
-  - compatible : should be "nintendo,hollywood-gpio"
-  - reg : should contain the IPC registers location and length
-  - gpio-controller
+  see Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt
 
 1.m) The control node
 
diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt
index a8014f3..294a0da 100644
--- a/Documentation/devicetree/bindings/reset/renesas,rst.txt
+++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt
@@ -26,7 +26,9 @@
 		  - "renesas,r8a7794-rst" (R-Car E2)
 		  - "renesas,r8a7795-rst" (R-Car H3)
 		  - "renesas,r8a7796-rst" (R-Car M3-W)
+		  - "renesas,r8a77965-rst" (R-Car M3-N)
 		  - "renesas,r8a77970-rst" (R-Car V3M)
+		  - "renesas,r8a77980-rst" (R-Car V3H)
 		  - "renesas,r8a77995-rst" (R-Car D3)
   - reg: Address start and address range for the device.
 
diff --git a/Documentation/devicetree/bindings/reset/st,stm32mp1-rcc.txt b/Documentation/devicetree/bindings/reset/st,stm32mp1-rcc.txt
new file mode 100644
index 0000000..b4edaf7
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/st,stm32mp1-rcc.txt
@@ -0,0 +1,6 @@
+STMicroelectronics STM32MP1 Peripheral Reset Controller
+=======================================================
+
+The RCC IP is both a reset and a clock controller.
+
+Please see Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.txt
diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
index df3bef7..8c6659e 100644
--- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
+++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
@@ -53,6 +53,13 @@
 Optional main node properties:
  - hip06-sas-v2-quirk-amt : when set, indicates that the v2 controller has the
 			    "am-max-transmissions" limitation.
+ - hisilicon,signal-attenuation : array of 3 32-bit values, containing de-emphasis,
+		preshoot, and boost attenuation readings for the board. They
+		are used to describe the signal attenuation of the board. These
+		values' range is 7600 to 12400, and used to represent -24dB to
+		24dB.
+		The formula is "y = (x-10000)/10000". For example, 10478
+		means 4.78dB.
 
 Example:
 	sas0: sas@c1000000 {
diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index 76bf45b..d6fe16f 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -21,6 +21,8 @@
 	- "mediatek,mt2712-scpsys"
 	- "mediatek,mt6797-scpsys"
 	- "mediatek,mt7622-scpsys"
+	- "mediatek,mt7623-scpsys", "mediatek,mt2701-scpsys": For MT7623 SoC
+	- "mediatek,mt7623a-scpsys": For MT7623A SoC
 	- "mediatek,mt8173-scpsys"
 - #power-domain-cells: Must be 1
 - reg: Address range of the SCPSYS unit
@@ -28,10 +30,11 @@
 - clock, clock-names: clocks according to the common clock binding.
                       These are clocks which hardware needs to be
                       enabled before enabling certain power domains.
-	Required clocks for MT2701: "mm", "mfg", "ethif"
+	Required clocks for MT2701 or MT7623: "mm", "mfg", "ethif"
 	Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", "vdec"
 	Required clocks for MT6797: "mm", "mfg", "vdec"
 	Required clocks for MT7622: "hif_sel"
+	Required clocks for MT7622A: "ethif"
 	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
 
 Optional properties:
diff --git a/Documentation/devicetree/bindings/sound/ak4458.txt b/Documentation/devicetree/bindings/sound/ak4458.txt
new file mode 100644
index 0000000..7839be7
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ak4458.txt
@@ -0,0 +1,23 @@
+AK4458 audio DAC
+
+This device supports I2C mode.
+
+Required properties:
+
+- compatible : "asahi-kasei,ak4458"
+- reg : The I2C address of the device for I2C
+
+Optional properties:
+- reset-gpios: A GPIO specifier for the power down & reset pin
+- mute-gpios: A GPIO specifier for the soft mute pin
+
+Example:
+
+&i2c {
+	ak4458: dac@10 {
+		compatible = "asahi-kasei,ak4458";
+		reg = <0x10>;
+		reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>
+		mute-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>
+	};
+};
diff --git a/Documentation/devicetree/bindings/sound/ak5558.txt b/Documentation/devicetree/bindings/sound/ak5558.txt
new file mode 100644
index 0000000..7d67ca6
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ak5558.txt
@@ -0,0 +1,22 @@
+AK5558 8 channel differential 32-bit delta-sigma ADC
+
+This device supports I2C mode only.
+
+Required properties:
+
+- compatible : "asahi-kasei,ak5558"
+- reg : The I2C address of the device.
+
+Optional properties:
+
+- reset-gpios: A GPIO specifier for the power down & reset pin.
+
+Example:
+
+&i2c {
+	ak5558: adc@10 {
+		compatible = "asahi-kasei,ak5558";
+		reg = <0x10>;
+		reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+	};
+};
diff --git a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt
index 65783de..7bb0362 100644
--- a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt
@@ -2,9 +2,8 @@
 
 Required properties:
 - compatible: "brcm,bcm2835-i2s"
-- reg: A list of base address and size entries:
-	* The first entry should cover the PCM registers
-	* The second entry should cover the PCM clock registers
+- reg: Should contain PCM registers location and length.
+- clocks: the (PCM) clock to use
 - dmas: List of DMA controller phandle and DMA request line ordered pairs.
 - dma-names: Identifier string for each DMA request line in the dmas property.
   These strings correspond 1:1 with the ordered pairs in dmas.
@@ -16,8 +15,8 @@
 
 bcm2835_i2s: i2s@7e203000 {
 	compatible = "brcm,bcm2835-i2s";
-	reg = <0x7e203000 0x20>,
-	      <0x7e101098 0x02>;
+	reg = <0x7e203000 0x24>;
+	clocks = <&clocks BCM2835_CLOCK_PCM>;
 
 	dmas = <&dma 2>,
 	       <&dma 3>;
diff --git a/Documentation/devicetree/bindings/sound/da7219.txt b/Documentation/devicetree/bindings/sound/da7219.txt
index 5b54d2d..c3df92d 100644
--- a/Documentation/devicetree/bindings/sound/da7219.txt
+++ b/Documentation/devicetree/bindings/sound/da7219.txt
@@ -25,6 +25,9 @@
   interrupt is to be used to wake system, otherwise "irq" should be used.
 - wakeup-source: Flag to indicate this device can wake system (suspend/resume).
 
+- #clock-cells :  Should be set to '<0>', only one clock source provided;
+- clock-output-names : Name given for DAI clocks output;
+
 - clocks : phandle and clock specifier for codec MCLK.
 - clock-names : Clock name string for 'clocks' attribute, should be "mclk".
 
@@ -83,6 +86,9 @@
 		VDDMIC-supply = <&reg_audio>;
 		VDDIO-supply = <&reg_audio>;
 
+		#clock-cells = <0>;
+		clock-output-names = "dai-clks";
+
 		clocks = <&clks 201>;
 		clock-names = "mclk";
 
diff --git a/Documentation/devicetree/bindings/sound/dmic.txt b/Documentation/devicetree/bindings/sound/dmic.txt
index f7bf656..e957b41 100644
--- a/Documentation/devicetree/bindings/sound/dmic.txt
+++ b/Documentation/devicetree/bindings/sound/dmic.txt
@@ -8,6 +8,7 @@
 Optional properties:
 	- dmicen-gpios: GPIO specifier for dmic to control start and stop
 	- num-channels: Number of microphones on this DAI
+	- wakeup-delay-ms: Delay (in ms) after enabling the DMIC
 
 Example node:
 
@@ -15,4 +16,5 @@
 		compatible = "dmic-codec";
 		dmicen-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>;
 		num-channels = <1>;
+		wakeup-delay-ms <50>;
 	};
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index f749e27..c60a573 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -28,7 +28,6 @@
  (compatible with CS4271 and CS4272)
 
  "fsl,imx-audio-wm8962"
- (compatible with Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt)
 
  "fsl,imx-audio-sgtl5000"
  (compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt)
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
deleted file mode 100644
index acea71b..0000000
--- a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-Freescale i.MX audio complex with WM8962 codec
-
-Required properties:
-
-  - compatible		: "fsl,imx-audio-wm8962"
-
-  - model		: The user-visible name of this sound complex
-
-  - ssi-controller	: The phandle of the i.MX SSI controller
-
-  - audio-codec		: The phandle of the WM8962 audio codec
-
-  - audio-routing	: A list of the connections between audio components.
-			  Each entry is a pair of strings, the first being the
-			  connection's sink, the second being the connection's
-			  source. Valid names could be power supplies, WM8962
-			  pins, and the jacks on the board:
-
-			  Power supplies:
-			   * Mic Bias
-
-			  Board connectors:
-			   * Mic Jack
-			   * Headphone Jack
-			   * Ext Spk
-
-  - mux-int-port	: The internal port of the i.MX audio muxer (AUDMUX)
-
-  - mux-ext-port	: The external port of the i.MX audio muxer
-
-Note: The AUDMUX port numbering should start at 1, which is consistent with
-hardware manual.
-
-Example:
-
-sound {
-	compatible = "fsl,imx6q-sabresd-wm8962",
-		     "fsl,imx-audio-wm8962";
-	model = "wm8962-audio";
-	ssi-controller = <&ssi2>;
-	audio-codec = <&codec>;
-		audio-routing =
-		"Headphone Jack", "HPOUTL",
-		"Headphone Jack", "HPOUTR",
-		"Ext Spk", "SPKOUTL",
-		"Ext Spk", "SPKOUTR",
-		"MICBIAS", "AMIC",
-		"IN3R", "MICBIAS",
-		"DMIC", "MICBIAS",
-		"DMICDAT", "DMIC";
-	mux-int-port = <2>;
-	mux-ext-port = <3>;
-};
diff --git a/Documentation/devicetree/bindings/sound/max98090.txt b/Documentation/devicetree/bindings/sound/max98090.txt
index 4e3be66..7e1bbd5 100644
--- a/Documentation/devicetree/bindings/sound/max98090.txt
+++ b/Documentation/devicetree/bindings/sound/max98090.txt
@@ -16,6 +16,8 @@
 
 - clock-names: Should be "mclk"
 
+- #sound-dai-cells : should be 0.
+
 - maxim,dmic-freq: Frequency at which to clock DMIC
 
 - maxim,micbias: Micbias voltage applies to the analog mic, valid voltages value are:
diff --git a/Documentation/devicetree/bindings/sound/maxim,max9759.txt b/Documentation/devicetree/bindings/sound/maxim,max9759.txt
new file mode 100644
index 0000000..737a996
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/maxim,max9759.txt
@@ -0,0 +1,18 @@
+Maxim MAX9759 Speaker Amplifier
+===============================
+
+Required properties:
+- compatible : "maxim,max9759"
+- shutdown-gpios : the gpio connected to the shutdown pin
+- mute-gpios : the gpio connected to the mute pin
+- gain-gpios : the 2 gpios connected to the g1 and g2 pins
+
+Example:
+
+max9759: analog-amplifier {
+	compatible = "maxim,max9759";
+	shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
+	mute-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+	gain-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>,
+		     <&gpio3 25 GPIO_ACTIVE_LOW>;
+};
diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
index 6df87b9..e2f7f49 100644
--- a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
+++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
@@ -53,7 +53,7 @@
 Example:
 
 	audsys: audio-subsystem@11220000 {
-		compatible = "mediatek,mt2701-audsys", "syscon", "simple-mfd";
+		compatible = "mediatek,mt2701-audsys", "syscon";
 		...
 
 		afe: audio-controller {
diff --git a/Documentation/devicetree/bindings/sound/pcm1789.txt b/Documentation/devicetree/bindings/sound/pcm1789.txt
new file mode 100644
index 0000000..3c74ed2
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/pcm1789.txt
@@ -0,0 +1,22 @@
+Texas Instruments pcm1789 DT bindings
+
+PCM1789 is a simple audio codec that can be connected via
+I2C or SPI. Currently, only I2C bus is supported.
+
+Required properties:
+
+ - compatible: "ti,pcm1789"
+
+Required properties on I2C:
+
+ - reg: the I2C address
+ - reset-gpios: GPIO to control the RESET pin
+
+Examples:
+
+	audio-codec@4c {
+		compatible = "ti,pcm1789";
+		reg = <0x4c>;
+		reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+		#sound-dai-cells = <0>;
+	};
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
index 5bed9a5..b86d790 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
+++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
@@ -351,6 +351,7 @@
 				    - "renesas,rcar_sound-r8a7793" (R-Car M2-N)
 				    - "renesas,rcar_sound-r8a7794" (R-Car E2)
 				    - "renesas,rcar_sound-r8a7795" (R-Car H3)
+				    - "renesas,rcar_sound-r8a7796" (R-Car M3-W)
 - reg				: Should contain the register physical address.
 				  required register is
 				   SRU/ADG/SSI      if generation1
diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3288-hdmi-analog.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3288-hdmi-analog.txt
index 2539e1d..e5430d1 100644
--- a/Documentation/devicetree/bindings/sound/rockchip,rk3288-hdmi-analog.txt
+++ b/Documentation/devicetree/bindings/sound/rockchip,rk3288-hdmi-analog.txt
@@ -22,7 +22,7 @@
 Example:
 
 sound {
-	compatible = "rockchip,rockchip-audio-es8388";
+	compatible = "rockchip,rk3288-hdmi-analog";
 	rockchip,model = "Analog audio output";
 	rockchip,i2s-controller = <&i2s>;
 	rockchip,audio-codec = <&es8388>;
diff --git a/Documentation/devicetree/bindings/sound/rohm,bd28623.txt b/Documentation/devicetree/bindings/sound/rohm,bd28623.txt
new file mode 100644
index 0000000..d84557c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rohm,bd28623.txt
@@ -0,0 +1,29 @@
+ROHM BD28623MUV Class D speaker amplifier for digital input
+
+This codec does not have any control buses such as I2C, it detect format and
+rate of I2S signal automatically. It has two signals that can be connected
+to GPIOs: reset and mute.
+
+Required properties:
+- compatible      : should be "rohm,bd28623"
+- #sound-dai-cells: should be 0.
+- VCCA-supply     : regulator phandle for the VCCA supply
+- VCCP1-supply    : regulator phandle for the VCCP1 supply
+- VCCP2-supply    : regulator phandle for the VCCP2 supply
+
+Optional properties:
+- reset-gpios     : GPIO specifier for the active low reset line
+- mute-gpios      : GPIO specifier for the active low mute line
+
+Example:
+
+	codec {
+		compatible = "rohm,bd28623";
+		#sound-dai-cells = <0>;
+
+		VCCA-supply = <&vcc_reg>;
+		VCCP1-supply = <&vcc_reg>;
+		VCCP2-supply = <&vcc_reg>;
+		reset-gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+		mute-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
+	};
diff --git a/Documentation/devicetree/bindings/sound/rt5651.txt b/Documentation/devicetree/bindings/sound/rt5651.txt
index 38752330..b852218 100644
--- a/Documentation/devicetree/bindings/sound/rt5651.txt
+++ b/Documentation/devicetree/bindings/sound/rt5651.txt
@@ -16,6 +16,23 @@
 - realtek,dmic-en
   Boolean. true if dmic is used.
 
+- realtek,jack-detect-source
+  u32. Valid values:
+  1: Use JD1_1 pin for jack-detect
+  2: Use JD1_2 pin for jack-detect
+  3: Use JD2 pin for jack-detect
+
+- realtek,over-current-threshold-microamp
+  u32, micbias over-current detection threshold in µA, valid values are
+  600, 1500 and 2000µA.
+
+- realtek,over-current-scale-factor
+  u32, micbias over-current detection scale-factor, valid values are:
+  0: Scale current by 0.5
+  1: Scale current by 0.75
+  2: Scale current by 1.0
+  3: Scale current by 1.5
+
 Pins on the device (for linking into audio routes) for RT5651:
 
   * DMIC L1
diff --git a/Documentation/devicetree/bindings/sound/rt5665.txt b/Documentation/devicetree/bindings/sound/rt5665.txt
index 419c892..8df1705 100644
--- a/Documentation/devicetree/bindings/sound/rt5665.txt
+++ b/Documentation/devicetree/bindings/sound/rt5665.txt
@@ -1,10 +1,10 @@
-RT5665/RT5666/RT5668 audio CODEC
+RT5665/RT5666 audio CODEC
 
 This device supports I2C only.
 
 Required properties:
 
-- compatible : One of "realtek,rt5665", "realtek,rt5666" or "realtek,rt5668".
+- compatible : One of "realtek,rt5665", "realtek,rt5666".
 
 - reg : The I2C address of the device.
 
diff --git a/Documentation/devicetree/bindings/sound/samsung,odroid.txt b/Documentation/devicetree/bindings/sound/samsung,odroid.txt
index 625b1b1..e9da220 100644
--- a/Documentation/devicetree/bindings/sound/samsung,odroid.txt
+++ b/Documentation/devicetree/bindings/sound/samsung,odroid.txt
@@ -2,8 +2,10 @@
 
 Required properties:
 
- - compatible - "samsung,odroidxu3-audio" - for Odroid XU3 board,
-		"samsung,odroidxu4-audio" - for Odroid XU4 board
+ - compatible - "hardkernel,odroid-xu3-audio" - for Odroid XU3 board,
+		"hardkernel,odroid-xu4-audio" - for Odroid XU4 board (deprecated),
+		"samsung,odroid-xu3-audio" - for Odroid XU3 board (deprecated),
+		"samsung,odroid-xu4-audio" - for Odroid XU4 board (deprecated)
  - model - the user-visible name of this sound complex
  - clocks - should contain entries matching clock names in the clock-names
     property
@@ -35,7 +37,7 @@
 Example:
 
 sound {
-	compatible = "samsung,odroidxu3-audio";
+	compatible = "hardkernel,odroid-xu3-audio";
 	model = "Odroid-XU3";
 	samsung,audio-routing =
 		"Headphone Jack", "HPL",
diff --git a/Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt b/Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt
index 94442e5..f5ccc12 100644
--- a/Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt
+++ b/Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt
@@ -4,9 +4,13 @@
 
  - compatible		 : "samsung,tm2-audio"
  - model		 : the user-visible name of this sound complex
- - audio-codec		 : the phandle of the wm5110 audio codec node,
-			   as described in ../mfd/arizona.txt
- - i2s-controller	 : the phandle of the I2S controller
+ - audio-codec		 : the first entry should be phandle of the wm5110 audio
+			   codec node, as described in ../mfd/arizona.txt;
+			   the second entry should be phandle of the HDMI
+			   transmitter node
+ - i2s-controller	 : the list of phandle and argument tuples pointing to
+			   I2S controllers, the first entry should be I2S0 and
+			   the second one I2S1
  - audio-amplifier	 : the phandle of the MAX98504 amplifier
  - samsung,audio-routing : a list of the connections between audio components;
 			   each entry is a pair of strings, the first being the
@@ -22,8 +26,8 @@
 
 sound {
 	compatible = "samsung,tm2-audio";
-	audio-codec = <&wm5110>;
-	i2s-controller = <&i2s0>;
+	audio-codec = <&wm5110>, <&hdmi>;
+	i2s-controller = <&i2s0 0>, <&i2s1 0>;
 	audio-amplifier = <&max98504>;
 	mic-bias-gpios = <&gpr3 2 0>;
 	model = "wm5110";
diff --git a/Documentation/devicetree/bindings/sound/samsung-i2s.txt b/Documentation/devicetree/bindings/sound/samsung-i2s.txt
index bf100cd..a88cb00 100644
--- a/Documentation/devicetree/bindings/sound/samsung-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/samsung-i2s.txt
@@ -7,7 +7,7 @@
    - samsung,s5pv210-i2s: for 8/16/24bit multichannel(5.1) I2S with
      secondary fifo, s/w reset control and internal mux for root clk src.
    - samsung,exynos5420-i2s: for 8/16/24bit multichannel(5.1) I2S for
-     playback, sterio channel capture, secondary fifo using internal
+     playback, stereo channel capture, secondary fifo using internal
      or external dma, s/w reset control, internal mux for root clk src
      and 7.1 channel TDM support for playback. TDM (Time division multiplexing)
      is to allow transfer of multiple channel audio data on single data line.
@@ -25,7 +25,7 @@
   These strings correspond 1:1 with the ordered pairs in dmas.
 - clocks: Handle to iis clock and RCLK source clk.
 - clock-names:
-  i2s0 uses some base clks from CMU and some are from audio subsystem internal
+  i2s0 uses some base clocks from CMU and some are from audio subsystem internal
   clock controller. The clock names for i2s0 should be "iis", "i2s_opclk0" and
   "i2s_opclk1" as shown in the example below.
   i2s1 and i2s2 uses clocks from CMU. The clock names for i2s1 and i2s2 should
@@ -36,9 +36,9 @@
 - #clock-cells: should be 1, this property must be present if the I2S device
   is a clock provider in terms of the common clock bindings, described in
   ../clock/clock-bindings.txt.
-- clock-output-names: from the common clock bindings, names of the CDCLK
-  I2S output clocks, suggested values are "i2s_cdclk0", "i2s_cdclk1",
-  "i2s_cdclk3" for the I2S0, I2S1, I2S2 devices recpectively.
+- clock-output-names (deprecated): from the common clock bindings, names of
+  the CDCLK I2S output clocks, suggested values are "i2s_cdclk0", "i2s_cdclk1",
+  "i2s_cdclk3" for the I2S0, I2S1, I2S2 devices respectively.
 
 There are following clocks available at the I2S device nodes:
  CLK_I2S_CDCLK    - the CDCLK (CODECLKO) gate clock,
@@ -49,9 +49,10 @@
 
 Refer to the SoC datasheet for availability of the above clocks.
 The CLK_I2S_RCLK_PSR and CLK_I2S_RCLK_SRC clocks are usually only available
-in the IIS Multi Audio Interface (I2S0).
-Note: Old DTs may not have the #clock-cells, clock-output-names properties
-and then not use the I2S node as a clock supplier.
+in the IIS Multi Audio Interface.
+
+Note: Old DTs may not have the #clock-cells property and then not use the I2S
+node as a clock supplier.
 
 Optional SoC Specific Properties:
 
@@ -59,6 +60,7 @@
   sub system(used in secondary sound source).
 - pinctrl-0: Should specify pin control groups used for this controller.
 - pinctrl-names: Should contain only one value - "default".
+- #sound-dai-cells: should be 1.
 
 
 Example:
@@ -74,9 +76,9 @@
 		<&clock_audss EXYNOS_I2S_BUS>,
 		<&clock_audss EXYNOS_SCLK_I2S>;
 	clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
-	#clock-cells;
-	clock-output-names = "i2s_cdclk0";
+	#clock-cells = <1>;
 	samsung,idma-addr = <0x03000000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2s0_bus>;
+	#sound-dai-cells = <1>;
 };
diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt
index 060cb4a..9a36c7e 100644
--- a/Documentation/devicetree/bindings/sound/sgtl5000.txt
+++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt
@@ -5,6 +5,8 @@
 
 - reg : the I2C address of the device
 
+- #sound-dai-cells: must be equal to 0
+
 - clocks : the clock provider of SYS_MCLK
 
 - VDDA-supply : the regulator provider of VDDA
@@ -40,6 +42,7 @@
 codec: sgtl5000@a {
 	compatible = "fsl,sgtl5000";
 	reg = <0x0a>;
+	#sound-dai-cells = <0>;
 	clocks = <&clks 150>;
 	micbias-resistor-k-ohms = <2>;
 	micbias-voltage-m-volts = <2250>;
diff --git a/Documentation/devicetree/bindings/sound/snow.txt b/Documentation/devicetree/bindings/sound/snow.txt
index 6df74f1..80fd9a8 100644
--- a/Documentation/devicetree/bindings/sound/snow.txt
+++ b/Documentation/devicetree/bindings/sound/snow.txt
@@ -5,8 +5,17 @@
 			"google,snow-audio-max98090" or
 			"google,snow-audio-max98091" or
 			"google,snow-audio-max98095"
-- samsung,i2s-controller: The phandle of the Samsung I2S controller
-- samsung,audio-codec: The phandle of the audio codec
+- samsung,i2s-controller (deprecated): The phandle of the Samsung I2S controller
+- samsung,audio-codec (deprecated): The phandle of the audio codec
+
+Required sub-nodes:
+
+ - 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
+    controller
+ - 'codec' subnode with a 'sound-dai' property containing list of phandles
+    to the CODEC nodes, first entry must be the phandle of the MAX98090,
+    MAX98091 or MAX98095 CODEC (exact device type is indicated by the compatible
+    string) and the second entry must be the phandle of the HDMI IP block node
 
 Optional:
 - samsung,model: The name of the sound-card
diff --git a/Documentation/devicetree/bindings/sound/st,stm32-sai.txt b/Documentation/devicetree/bindings/sound/st,stm32-sai.txt
index b1acc1a..f301cdf 100644
--- a/Documentation/devicetree/bindings/sound/st,stm32-sai.txt
+++ b/Documentation/devicetree/bindings/sound/st,stm32-sai.txt
@@ -45,6 +45,12 @@
 	This property sets SAI sub-block as slave of another SAI sub-block.
 	Must contain the phandle and index of the sai sub-block providing
 	the synchronization.
+  - st,iec60958: support S/PDIF IEC6958 protocol for playback
+	IEC60958 protocol is not available for capture.
+	By default, custom protocol is assumed, meaning that protocol is
+	configured according to protocol defined in related DAI link node,
+	such as i2s, left justified, right justified, dsp and pdm protocols.
+	Note: ac97 protocol is not supported by SAI driver
 
 The device node should contain one 'port' child node with one child 'endpoint'
 node, according to the bindings defined in Documentation/devicetree/bindings/
diff --git a/Documentation/devicetree/bindings/sound/tda7419.txt b/Documentation/devicetree/bindings/sound/tda7419.txt
new file mode 100644
index 0000000..6b85ec3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tda7419.txt
@@ -0,0 +1,38 @@
+TDA7419 audio processor
+
+This device supports I2C only.
+
+Required properties:
+
+- compatible : "st,tda7419"
+- reg : the I2C address of the device.
+- vdd-supply : a regulator spec for the common power supply (8-10V)
+
+Optional properties:
+
+- st,mute-gpios : a GPIO spec for the MUTE pin.
+
+Pins on the device (for linking into audio routes):
+
+  * SE3L
+  * SE3R
+  * SE2L
+  * SE2R
+  * SE1L
+  * SE1R
+  * DIFFL
+  * DIFFR
+  * MIX
+  * OUTLF
+  * OUTRF
+  * OUTLR
+  * OUTRR
+  * OUTSW
+
+Example:
+
+ap: tda7419@44 {
+	compatible = "st,tda7419";
+	reg = <0x44>;
+	vdd-supply = <&vdd_9v0_reg>;
+};
diff --git a/Documentation/devicetree/bindings/sound/uniphier,aio.txt b/Documentation/devicetree/bindings/sound/uniphier,aio.txt
new file mode 100644
index 0000000..4ce68ed
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/uniphier,aio.txt
@@ -0,0 +1,45 @@
+Socionext UniPhier SoC audio driver
+
+The Socionext UniPhier audio subsystem consists of I2S and S/PDIF blocks in
+the same register space.
+
+Required properties:
+- compatible      : should be one of the following:
+		    "socionext,uniphier-ld11-aio"
+		    "socionext,uniphier-ld20-aio"
+		    "socionext,uniphier-pxs2-aio"
+- reg             : offset and length of the register set for the device.
+- interrupts      : should contain I2S or S/PDIF interrupt.
+- pinctrl-names   : should be "default".
+- pinctrl-0       : defined I2S signal pins for an external codec chip.
+- clock-names     : should include following entries:
+                    "aio"
+- clocks          : a list of phandle, should contain an entry for each
+                    entry in clock-names.
+- reset-names     : should include following entries:
+                    "aio"
+- resets          : a list of phandle, should contain an entry for each
+                    entry in reset-names.
+- #sound-dai-cells: should be 1.
+
+Optional properties:
+- socionext,syscon: a phandle, should contain soc-glue.
+                    The soc-glue is used for changing mode of S/PDIF signal pin
+                    to Output from Hi-Z. This property is optional if you use
+                    I2S signal pins only.
+
+Example:
+	audio {
+		compatible = "socionext,uniphier-ld20-aio";
+		reg = <0x56000000 0x80000>;
+		interrupts = <0 144 4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_aout>;
+		clock-names = "aio";
+		clocks = <&sys_clk 40>;
+		reset-names = "aio";
+		resets = <&sys_rst 40>;
+		#sound-dai-cells = <1>;
+
+		socionext,syscon = <&sg>;
+	};
diff --git a/Documentation/devicetree/bindings/sound/wm8524.txt b/Documentation/devicetree/bindings/sound/wm8524.txt
index 20c6200..0f05535 100644
--- a/Documentation/devicetree/bindings/sound/wm8524.txt
+++ b/Documentation/devicetree/bindings/sound/wm8524.txt
@@ -10,7 +10,7 @@
 
 Example:
 
-codec: wm8524@0 {
+codec: wm8524 {
 	compatible = "wlf,wm8524";
 	wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
 };
diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt
index 2e3740f..763a280 100644
--- a/Documentation/devicetree/bindings/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/trivial-devices.txt
@@ -75,6 +75,18 @@
 maxim,max6625		9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
 mcube,mc3230		mCube 3-axis 8-bit digital accelerometer
 memsic,mxc6225		MEMSIC 2-axis 8-bit digital accelerometer
+microchip,mcp4017-502	Microchip 7-bit Single I2C Digital POT (5k)
+microchip,mcp4017-103	Microchip 7-bit Single I2C Digital POT (10k)
+microchip,mcp4017-503	Microchip 7-bit Single I2C Digital POT (50k)
+microchip,mcp4017-104	Microchip 7-bit Single I2C Digital POT (100k)
+microchip,mcp4018-502	Microchip 7-bit Single I2C Digital POT (5k)
+microchip,mcp4018-103	Microchip 7-bit Single I2C Digital POT (10k)
+microchip,mcp4018-503	Microchip 7-bit Single I2C Digital POT (50k)
+microchip,mcp4018-104	Microchip 7-bit Single I2C Digital POT (100k)
+microchip,mcp4019-502	Microchip 7-bit Single I2C Digital POT (5k)
+microchip,mcp4019-103	Microchip 7-bit Single I2C Digital POT (10k)
+microchip,mcp4019-503	Microchip 7-bit Single I2C Digital POT (50k)
+microchip,mcp4019-104	Microchip 7-bit Single I2C Digital POT (100k)
 microchip,mcp4531-502	Microchip 7-bit Single I2C Digital Potentiometer (5k)
 microchip,mcp4531-103	Microchip 7-bit Single I2C Digital Potentiometer (10k)
 microchip,mcp4531-503	Microchip 7-bit Single I2C Digital Potentiometer (50k)
diff --git a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
index 62dd5ba..04fc368 100644
--- a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
@@ -2,8 +2,10 @@
 
 Required properties:
 
-- compatible : should be either "allwinner,sun4i-a10-wdt" or
-               "allwinner,sun6i-a31-wdt"
+- compatible : should be one of
+	"allwinner,sun4i-a10-wdt"
+	"allwinner,sun6i-a31-wdt"
+	"allwinner,sun50i-a64-wdt","allwinner,sun6i-a31-wdt"
 - reg : Specifies base physical address and size of the registers.
 
 Example:
diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt
index 5175a24..a4feb6d 100644
--- a/Documentation/devicetree/overlay-notes.txt
+++ b/Documentation/devicetree/overlay-notes.txt
@@ -91,8 +91,8 @@
 return value is an error or a cookie identifying this overlay.
 
 2. Call of_overlay_remove() to remove and cleanup the overlay changeset
-previously created via the call to of_overlay_apply(). Removal of an overlay
-changeset that is stacked by another will not be permitted.
+previously created via the call to of_overlay_fdt_apply(). Removal of an
+overlay changeset that is stacked by another will not be permitted.
 
 Finally, if you need to remove all overlays in one-go, just call
 of_overlay_remove_all() which will remove every single one in the correct
diff --git a/Documentation/gpio/board.txt b/Documentation/driver-api/gpio/board.rst
similarity index 88%
rename from Documentation/gpio/board.txt
rename to Documentation/driver-api/gpio/board.rst
index 659bb19..25d62b2 100644
--- a/Documentation/gpio/board.txt
+++ b/Documentation/driver-api/gpio/board.rst
@@ -1,3 +1,4 @@
+=============
 GPIO Mappings
 =============
 
@@ -23,7 +24,7 @@
 
 GPIOs mappings are defined in the consumer device's node, in a property named
 <function>-gpios, where <function> is the function the driver will request
-through gpiod_get(). For example:
+through gpiod_get(). For example::
 
 	foo_device {
 		compatible = "acme,foo";
@@ -40,7 +41,7 @@
 newer bindings since it has been deprecated.
 
 This property will make GPIOs 15, 16 and 17 available to the driver under the
-"led" function, and GPIO 1 as the "power" GPIO:
+"led" function, and GPIO 1 as the "power" GPIO::
 
 	struct gpio_desc *red, *green, *blue, *power;
 
@@ -60,13 +61,13 @@
 
 Internally, the GPIO subsystem prefixes the GPIO suffix ("gpios" or "gpio")
 with the string passed in con_id to get the resulting string
-(snprintf(... "%s-%s", con_id, gpio_suffixes[]).
+(``snprintf(... "%s-%s", con_id, gpio_suffixes[]``).
 
 ACPI
 ----
 ACPI also supports function names for GPIOs in a similar fashion to DT.
 The above DT example can be converted to an equivalent ACPI description
-with the help of _DSD (Device Specific Data), introduced in ACPI 5.1:
+with the help of _DSD (Device Specific Data), introduced in ACPI 5.1::
 
 	Device (FOO) {
 		Name (_CRS, ResourceTemplate () {
@@ -105,12 +106,12 @@
 Platform Data
 -------------
 Finally, GPIOs can be bound to devices and functions using platform data. Board
-files that desire to do so need to include the following header:
+files that desire to do so need to include the following header::
 
 	#include <linux/gpio/machine.h>
 
 GPIOs are mapped by the means of tables of lookups, containing instances of the
-gpiod_lookup structure. Two macros are defined to help declaring such mappings:
+gpiod_lookup structure. Two macros are defined to help declaring such mappings::
 
 	GPIO_LOOKUP(chip_label, chip_hwnum, con_id, flags)
 	GPIO_LOOKUP_IDX(chip_label, chip_hwnum, con_id, idx, flags)
@@ -141,22 +142,24 @@
 make use of these GPIOs. It can be NULL, in which case it will be matched for
 calls to gpiod_get() with a NULL device.
 
-struct gpiod_lookup_table gpios_table = {
-	.dev_id = "foo.0",
-	.table = {
-		GPIO_LOOKUP_IDX("gpio.0", 15, "led", 0, GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP_IDX("gpio.0", 16, "led", 1, GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP_IDX("gpio.0", 17, "led", 2, GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP("gpio.0", 1, "power", GPIO_ACTIVE_LOW),
-		{ },
-	},
-};
+.. code-block:: c
 
-And the table can be added by the board code as follows:
+        struct gpiod_lookup_table gpios_table = {
+                .dev_id = "foo.0",
+                .table = {
+                        GPIO_LOOKUP_IDX("gpio.0", 15, "led", 0, GPIO_ACTIVE_HIGH),
+                        GPIO_LOOKUP_IDX("gpio.0", 16, "led", 1, GPIO_ACTIVE_HIGH),
+                        GPIO_LOOKUP_IDX("gpio.0", 17, "led", 2, GPIO_ACTIVE_HIGH),
+                        GPIO_LOOKUP("gpio.0", 1, "power", GPIO_ACTIVE_LOW),
+                        { },
+                },
+        };
+
+And the table can be added by the board code as follows::
 
 	gpiod_add_lookup_table(&gpios_table);
 
-The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
+The driver controlling "foo.0" will then be able to obtain its GPIOs as follows::
 
 	struct gpio_desc *red, *green, *blue, *power;
 
diff --git a/Documentation/gpio/consumer.txt b/Documentation/driver-api/gpio/consumer.rst
similarity index 88%
rename from Documentation/gpio/consumer.txt
rename to Documentation/driver-api/gpio/consumer.rst
index d53e5b5..c71a50d 100644
--- a/Documentation/gpio/consumer.txt
+++ b/Documentation/driver-api/gpio/consumer.rst
@@ -1,3 +1,4 @@
+==================================
 GPIO Descriptor Consumer Interface
 ==================================
 
@@ -30,10 +31,10 @@
   be met with console warnings that may be perceived as intimidating.
 
 All the functions that work with the descriptor-based GPIO interface are
-prefixed with gpiod_. The gpio_ prefix is used for the legacy interface. No
-other function in the kernel should use these prefixes. The use of the legacy
-functions is strongly discouraged, new code should use <linux/gpio/consumer.h>
-and descriptors exclusively.
+prefixed with ``gpiod_``. The ``gpio_`` prefix is used for the legacy
+interface. No other function in the kernel should use these prefixes. The use
+of the legacy functions is strongly discouraged, new code should use
+<linux/gpio/consumer.h> and descriptors exclusively.
 
 
 Obtaining and Disposing GPIOs
@@ -43,13 +44,13 @@
 non-forgeable handler that must be obtained through a call to one of the
 gpiod_get() functions. Like many other kernel subsystems, gpiod_get() takes the
 device that will use the GPIO and the function the requested GPIO is supposed to
-fulfill:
+fulfill::
 
 	struct gpio_desc *gpiod_get(struct device *dev, const char *con_id,
 				    enum gpiod_flags flags)
 
 If a function is implemented by using several GPIOs together (e.g. a simple LED
-device that displays digits), an additional index argument can be specified:
+device that displays digits), an additional index argument can be specified::
 
 	struct gpio_desc *gpiod_get_index(struct device *dev,
 					  const char *con_id, unsigned int idx,
@@ -84,7 +85,7 @@
 errors and an absence of GPIO for optional GPIO parameters. For the common
 pattern where a GPIO is optional, the gpiod_get_optional() and
 gpiod_get_index_optional() functions can be used. These functions return NULL
-instead of -ENOENT if no GPIO has been assigned to the requested function:
+instead of -ENOENT if no GPIO has been assigned to the requested function::
 
 	struct gpio_desc *gpiod_get_optional(struct device *dev,
 					     const char *con_id,
@@ -101,14 +102,14 @@
 -ENOSYS return codes.  System integrators should however be careful to enable
 gpiolib on systems that need it.
 
-For a function using multiple GPIOs all of those can be obtained with one call:
+For a function using multiple GPIOs all of those can be obtained with one call::
 
 	struct gpio_descs *gpiod_get_array(struct device *dev,
 					   const char *con_id,
 					   enum gpiod_flags flags)
 
 This function returns a struct gpio_descs which contains an array of
-descriptors:
+descriptors::
 
 	struct gpio_descs {
 		unsigned int ndescs;
@@ -116,13 +117,13 @@
 	}
 
 The following function returns NULL instead of -ENOENT if no GPIOs have been
-assigned to the requested function:
+assigned to the requested function::
 
 	struct gpio_descs *gpiod_get_array_optional(struct device *dev,
 						    const char *con_id,
 						    enum gpiod_flags flags)
 
-Device-managed variants of these functions are also defined:
+Device-managed variants of these functions are also defined::
 
 	struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id,
 					 enum gpiod_flags flags)
@@ -149,11 +150,11 @@
 							 const char *con_id,
 							 enum gpiod_flags flags)
 
-A GPIO descriptor can be disposed of using the gpiod_put() function:
+A GPIO descriptor can be disposed of using the gpiod_put() function::
 
 	void gpiod_put(struct gpio_desc *desc)
 
-For an array of GPIOs this function can be used:
+For an array of GPIOs this function can be used::
 
 	void gpiod_put_array(struct gpio_descs *descs)
 
@@ -161,7 +162,7 @@
 It is also not allowed to individually release descriptors (using gpiod_put())
 from an array acquired with gpiod_get_array().
 
-The device-managed variants are, unsurprisingly:
+The device-managed variants are, unsurprisingly::
 
 	void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
 
@@ -175,7 +176,7 @@
 -----------------
 The first thing a driver must do with a GPIO is setting its direction. If no
 direction-setting flags have been given to gpiod_get*(), this is done by
-invoking one of the gpiod_direction_*() functions:
+invoking one of the gpiod_direction_*() functions::
 
 	int gpiod_direction_input(struct gpio_desc *desc)
 	int gpiod_direction_output(struct gpio_desc *desc, int value)
@@ -189,7 +190,7 @@
 For output GPIOs, the value provided becomes the initial output value. This
 helps avoid signal glitching during system startup.
 
-A driver can also query the current direction of a GPIO:
+A driver can also query the current direction of a GPIO::
 
 	int gpiod_get_direction(const struct gpio_desc *desc)
 
@@ -206,7 +207,7 @@
 don't need to sleep, and can safely be done from inside hard (non-threaded) IRQ
 handlers and similar contexts.
 
-Use the following calls to access GPIOs from an atomic context:
+Use the following calls to access GPIOs from an atomic context::
 
 	int gpiod_get_value(const struct gpio_desc *desc);
 	void gpiod_set_value(struct gpio_desc *desc, int value);
@@ -231,11 +232,11 @@
 sleeping, which can't be done from inside IRQ handlers.
 
 Platforms that support this type of GPIO distinguish them from other GPIOs by
-returning nonzero from this call:
+returning nonzero from this call::
 
 	int gpiod_cansleep(const struct gpio_desc *desc)
 
-To access such GPIOs, a different set of accessors is defined:
+To access such GPIOs, a different set of accessors is defined::
 
 	int gpiod_get_value_cansleep(const struct gpio_desc *desc)
 	void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
@@ -271,23 +272,23 @@
 gpiod_set_(array)_value_xxx() passes "asserted" ("1"), the physical line level
 will be driven low.
 
-To summarize:
+To summarize::
 
-Function (example)                 line property          physical line
-gpiod_set_raw_value(desc, 0);      don't care             low
-gpiod_set_raw_value(desc, 1);      don't care             high
-gpiod_set_value(desc, 0);          default (active high)  low
-gpiod_set_value(desc, 1);          default (active high)  high
-gpiod_set_value(desc, 0);          active low             high
-gpiod_set_value(desc, 1);          active low             low
-gpiod_set_value(desc, 0);          default (active high)  low
-gpiod_set_value(desc, 1);          default (active high)  high
-gpiod_set_value(desc, 0);          open drain             low
-gpiod_set_value(desc, 1);          open drain             high impedance
-gpiod_set_value(desc, 0);          open source            high impedance
-gpiod_set_value(desc, 1);          open source            high
+  Function (example)                 line property          physical line
+  gpiod_set_raw_value(desc, 0);      don't care             low
+  gpiod_set_raw_value(desc, 1);      don't care             high
+  gpiod_set_value(desc, 0);          default (active high)  low
+  gpiod_set_value(desc, 1);          default (active high)  high
+  gpiod_set_value(desc, 0);          active low             high
+  gpiod_set_value(desc, 1);          active low             low
+  gpiod_set_value(desc, 0);          default (active high)  low
+  gpiod_set_value(desc, 1);          default (active high)  high
+  gpiod_set_value(desc, 0);          open drain             low
+  gpiod_set_value(desc, 1);          open drain             high impedance
+  gpiod_set_value(desc, 0);          open source            high impedance
+  gpiod_set_value(desc, 1);          open source            high
 
-It is possible to override these semantics using the *set_raw/'get_raw functions
+It is possible to override these semantics using the set_raw/get_raw functions
 but it should be avoided as much as possible, especially by system-agnostic drivers
 which should not need to care about the actual physical line level and worry about
 the logical value instead.
@@ -300,7 +301,7 @@
 line.
 
 The following set of calls ignore the active-low or open drain property of a GPIO and
-work on the raw line value:
+work on the raw line value::
 
 	int gpiod_get_raw_value(const struct gpio_desc *desc)
 	void gpiod_set_raw_value(struct gpio_desc *desc, int value)
@@ -308,7 +309,7 @@
 	void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value)
 	int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
 
-The active low state of a GPIO can also be queried using the following call:
+The active low state of a GPIO can also be queried using the following call::
 
 	int gpiod_is_active_low(const struct gpio_desc *desc)
 
@@ -318,7 +319,7 @@
 
 Access multiple GPIOs with a single function call
 -------------------------------------------------
-The following functions get or set the values of an array of GPIOs:
+The following functions get or set the values of an array of GPIOs::
 
 	int gpiod_get_array_value(unsigned int array_size,
 				  struct gpio_desc **desc_array,
@@ -361,7 +362,7 @@
 The descriptor array can be obtained using the gpiod_get_array() function
 or one of its variants. If the group of descriptors returned by that function
 matches the desired group of GPIOs, those GPIOs can be accessed by simply using
-the struct gpio_descs returned by gpiod_get_array():
+the struct gpio_descs returned by gpiod_get_array()::
 
 	struct gpio_descs *my_gpio_descs = gpiod_get_array(...);
 	gpiod_set_array_value(my_gpio_descs->ndescs, my_gpio_descs->desc,
@@ -384,7 +385,7 @@
 GPIOs mapped to IRQs
 --------------------
 GPIO lines can quite often be used as IRQs. You can get the IRQ number
-corresponding to a given GPIO using the following call:
+corresponding to a given GPIO using the following call::
 
 	int gpiod_to_irq(const struct gpio_desc *desc)
 
@@ -424,7 +425,7 @@
 Many kernel subsystems still handle GPIOs using the legacy integer-based
 interface. Although it is strongly encouraged to upgrade them to the safer
 descriptor-based API, the following two functions allow you to convert a GPIO
-descriptor into the GPIO integer namespace and vice-versa:
+descriptor into the GPIO integer namespace and vice-versa::
 
 	int desc_to_gpio(const struct gpio_desc *desc)
 	struct gpio_desc *gpio_to_desc(unsigned gpio)
diff --git a/Documentation/gpio/driver.txt b/Documentation/driver-api/gpio/driver.rst
similarity index 92%
rename from Documentation/gpio/driver.txt
rename to Documentation/driver-api/gpio/driver.rst
index 3392a0f..505ee90 100644
--- a/Documentation/gpio/driver.txt
+++ b/Documentation/driver-api/gpio/driver.rst
@@ -1,3 +1,4 @@
+================================
 GPIO Descriptor Driver Interface
 ================================
 
@@ -53,9 +54,9 @@
 
 The code implementing a gpio_chip should support multiple instances of the
 controller, possibly using the driver model. That code will configure each
-gpio_chip and issue gpiochip_add[_data]() or devm_gpiochip_add_data().
-Removing a GPIO controller should be rare; use [devm_]gpiochip_remove() when
-it is unavoidable.
+gpio_chip and issue ``gpiochip_add[_data]()`` or ``devm_gpiochip_add_data()``.
+Removing a GPIO controller should be rare; use ``[devm_]gpiochip_remove()``
+when it is unavoidable.
 
 Often a gpio_chip is part of an instance-specific structure with states not
 exposed by the GPIO interfaces, such as addressing, power management, and more.
@@ -115,7 +116,7 @@
 
 Open drain (CMOS) or open collector (TTL) means the line is not actively driven
 high: instead you provide the drain/collector as output, so when the transistor
-is not open, it will present a high-impedance (tristate) to the external rail.
+is not open, it will present a high-impedance (tristate) to the external rail::
 
 
    CMOS CONFIGURATION      TTL CONFIGURATION
@@ -148,19 +149,19 @@
 Integrated electronics often have an output driver stage in the form of a CMOS
 "totem-pole" with one N-MOS and one P-MOS transistor where one of them drives
 the line high and one of them drives the line low. This is called a push-pull
-output. The "totem-pole" looks like so:
+output. The "totem-pole" looks like so::
 
-                 VDD
-                  |
-        OD    ||--+
-     +--/ ---o||     P-MOS-FET
-     |        ||--+
-IN --+            +----- out
-     |        ||--+
-     +--/ ----||     N-MOS-FET
-        OS    ||--+
-                  |
-                 GND
+                     VDD
+                      |
+            OD    ||--+
+         +--/ ---o||     P-MOS-FET
+         |        ||--+
+    IN --+            +----- out
+         |        ||--+
+         +--/ ----||     N-MOS-FET
+            OS    ||--+
+                      |
+                     GND
 
 The desired output signal (e.g. coming directly from some GPIO output register)
 arrives at IN. The switches named "OD" and "OS" are normally closed, creating
@@ -219,8 +220,9 @@
 
 RT_FULL: a realtime compliant GPIO driver should not use spinlock_t or any
 sleepable APIs (like PM runtime) as part of its irq_chip implementation.
-- spinlock_t should be replaced with raw_spinlock_t [1].
-- If sleepable APIs have to be used, these can be done from the .irq_bus_lock()
+
+* spinlock_t should be replaced with raw_spinlock_t [1].
+* If sleepable APIs have to be used, these can be done from the .irq_bus_lock()
   and .irq_bus_unlock() callbacks, as these are the only slowpath callbacks
   on an irqchip. Create the callbacks if needed [2].
 
@@ -232,12 +234,12 @@
   system interrupt controller. This means that the GPIO irqchip handler will
   be called immediately from the parent irqchip, while holding the IRQs
   disabled. The GPIO irqchip will then end up calling something like this
-  sequence in its interrupt handler:
+  sequence in its interrupt handler::
 
-  static irqreturn_t foo_gpio_irq(int irq, void *data)
-      chained_irq_enter(...);
-      generic_handle_irq(...);
-      chained_irq_exit(...);
+    static irqreturn_t foo_gpio_irq(int irq, void *data)
+        chained_irq_enter(...);
+        generic_handle_irq(...);
+        chained_irq_exit(...);
 
   Chained GPIO irqchips typically can NOT set the .can_sleep flag on
   struct gpio_chip, as everything happens directly in the callbacks: no
@@ -252,7 +254,7 @@
   (for example, see [3]).
   Know W/A: The generic_handle_irq() is expected to be called with IRQ disabled,
   so the IRQ core will complain if it is called from an IRQ handler which is
-  forced to a thread. The "fake?" raw lock can be used to W/A this problem:
+  forced to a thread. The "fake?" raw lock can be used to W/A this problem::
 
 	raw_spinlock_t wa_lock;
 	static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
@@ -265,11 +267,11 @@
   but chained IRQ handlers are not used. Instead GPIO IRQs dispatching is
   performed by generic IRQ handler which is configured using request_irq().
   The GPIO irqchip will then end up calling something like this sequence in
-  its interrupt handler:
+  its interrupt handler::
 
-  static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)
-	for each detected GPIO IRQ
-		generic_handle_irq(...);
+    static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)
+        for each detected GPIO IRQ
+            generic_handle_irq(...);
 
   RT_FULL: Such kind of handlers will be forced threaded on -RT, as result IRQ
   core will complain that generic_handle_irq() is called with IRQ enabled and
@@ -282,11 +284,11 @@
   in a quick IRQ handler with IRQs disabled. Instead they need to spawn a
   thread and then mask the parent IRQ line until the interrupt is handled
   by the driver. The hallmark of this driver is to call something like
-  this in its interrupt handler:
+  this in its interrupt handler::
 
-  static irqreturn_t foo_gpio_irq(int irq, void *data)
-      ...
-      handle_nested_irq(irq);
+    static irqreturn_t foo_gpio_irq(int irq, void *data)
+        ...
+        handle_nested_irq(irq);
 
   The hallmark of threaded GPIO irqchips is that they set the .can_sleep
   flag on struct gpio_chip to true, indicating that this chip may sleep
@@ -359,12 +361,12 @@
 Locking IRQ usage
 -----------------
 Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
-to mark the GPIO as being used as an IRQ:
+to mark the GPIO as being used as an IRQ::
 
 	int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
 
 This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
-is released:
+is released::
 
 	void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
 
@@ -408,7 +410,7 @@
 descriptors through the gpiolib API. Using gpio_request() for this purpose
 does not help since it pins the module to the kernel forever (it calls
 try_module_get()). A GPIO driver can use the following functions instead
-to request and free descriptors without being pinned to the kernel forever.
+to request and free descriptors without being pinned to the kernel forever::
 
 	struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc,
 						    const char *label)
@@ -422,6 +424,6 @@
 count. Do not use the functions to request gpio descriptors not owned by the
 calling driver.
 
-[1] http://www.spinics.net/lists/linux-omap/msg120425.html
-[2] https://lkml.org/lkml/2015/9/25/494
-[3] https://lkml.org/lkml/2015/9/25/495
+* [1] http://www.spinics.net/lists/linux-omap/msg120425.html
+* [2] https://lkml.org/lkml/2015/9/25/494
+* [3] https://lkml.org/lkml/2015/9/25/495
diff --git a/Documentation/gpio/drivers-on-gpio.txt b/Documentation/driver-api/gpio/drivers-on-gpio.rst
similarity index 95%
rename from Documentation/gpio/drivers-on-gpio.txt
rename to Documentation/driver-api/gpio/drivers-on-gpio.rst
index a2ccbab..7da0c1d 100644
--- a/Documentation/gpio/drivers-on-gpio.txt
+++ b/Documentation/driver-api/gpio/drivers-on-gpio.rst
@@ -1,3 +1,4 @@
+============================
 Subsystem drivers using GPIO
 ============================
 
@@ -74,8 +75,8 @@
   it from 1-to-0-to-1. If that hardware does not receive its "ping"
   periodically, it will reset the system.
 
-- gpio-nand: drivers/mtd/nand/gpio.c is used to connect a NAND flash chip to
-  a set of simple GPIO lines: RDY, NCE, ALE, CLE, NWP. It interacts with the
+- gpio-nand: drivers/mtd/nand/raw/gpio.c is used to connect a NAND flash chip
+  to a set of simple GPIO lines: RDY, NCE, ALE, CLE, NWP. It interacts with the
   NAND flash MTD subsystem and provides chip access and partition parsing like
   any other NAND driving hardware.
 
diff --git a/Documentation/driver-api/gpio.rst b/Documentation/driver-api/gpio/index.rst
similarity index 73%
rename from Documentation/driver-api/gpio.rst
rename to Documentation/driver-api/gpio/index.rst
index 6dd4aa6..6a374de 100644
--- a/Documentation/driver-api/gpio.rst
+++ b/Documentation/driver-api/gpio/index.rst
@@ -2,6 +2,18 @@
 General Purpose Input/Output (GPIO)
 ===================================
 
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   intro
+   driver
+   consumer
+   board
+   drivers-on-gpio
+   legacy
+
 Core
 ====
 
@@ -11,15 +23,6 @@
 .. kernel-doc:: drivers/gpio/gpiolib.c
    :export:
 
-Legacy API
-==========
-
-The functions listed in this section are deprecated. The GPIO descriptor based
-API described above should be used in new code.
-
-.. kernel-doc:: drivers/gpio/gpiolib-legacy.c
-   :export:
-
 ACPI support
 ============
 
diff --git a/Documentation/gpio/gpio.txt b/Documentation/driver-api/gpio/intro.rst
similarity index 95%
rename from Documentation/gpio/gpio.txt
rename to Documentation/driver-api/gpio/intro.rst
index cd9b356..7459148 100644
--- a/Documentation/gpio/gpio.txt
+++ b/Documentation/driver-api/gpio/intro.rst
@@ -1,3 +1,8 @@
+============
+Introduction
+============
+
+
 GPIO Interfaces
 ===============
 
@@ -9,9 +14,9 @@
 ways to obtain and use GPIOs:
 
   - The descriptor-based interface is the preferred way to manipulate GPIOs,
-and is described by all the files in this directory excepted gpio-legacy.txt.
+    and is described by all the files in this directory excepted gpio-legacy.txt.
   - The legacy integer-based interface which is considered deprecated (but still
-usable for compatibility reasons) is documented in gpio-legacy.txt.
+    usable for compatibility reasons) is documented in gpio-legacy.txt.
 
 The remainder of this document applies to the new descriptor-based interface.
 gpio-legacy.txt contains the same information applied to the legacy
diff --git a/Documentation/gpio/gpio-legacy.txt b/Documentation/driver-api/gpio/legacy.rst
similarity index 95%
rename from Documentation/gpio/gpio-legacy.txt
rename to Documentation/driver-api/gpio/legacy.rst
index 8356d0e..5e9421e 100644
--- a/Documentation/gpio/gpio-legacy.txt
+++ b/Documentation/driver-api/gpio/legacy.rst
@@ -1,4 +1,6 @@
-GPIO Interfaces
+======================
+Legacy GPIO Interfaces
+======================
 
 This provides an overview of GPIO access conventions on Linux.
 
@@ -129,7 +131,7 @@
 the gpio_request() call; see later.
 
 One of the next things to do with a GPIO, often in board setup code when
-setting up a platform_device using the GPIO, is mark its direction:
+setting up a platform_device using the GPIO, is mark its direction::
 
 	/* set as input or output, returning 0 or negative errno */
 	int gpio_direction_input(unsigned gpio);
@@ -164,7 +166,7 @@
 (nonthreaded) IRQ handlers and similar contexts.
 
 Use the following calls to access such GPIOs,
-for which gpio_cansleep() will always return false (see below):
+for which gpio_cansleep() will always return false (see below)::
 
 	/* GPIO INPUT:  return zero or nonzero */
 	int gpio_get_value(unsigned gpio);
@@ -201,11 +203,11 @@
 
 Platforms that support this type of GPIO distinguish them from other GPIOs
 by returning nonzero from this call (which requires a valid GPIO number,
-which should have been previously allocated with gpio_request):
+which should have been previously allocated with gpio_request)::
 
 	int gpio_cansleep(unsigned gpio);
 
-To access such GPIOs, a different set of accessors is defined:
+To access such GPIOs, a different set of accessors is defined::
 
 	/* GPIO INPUT:  return zero or nonzero, might sleep */
 	int gpio_get_value_cansleep(unsigned gpio);
@@ -222,27 +224,27 @@
 on GPIOs that can't be accessed from hardIRQ handlers, these calls act
 the same as the spinlock-safe calls.
 
-  ** IN ADDITION ** calls to setup and configure such GPIOs must be made
+**IN ADDITION** calls to setup and configure such GPIOs must be made
 from contexts which may sleep, since they may need to access the GPIO
-controller chip too:  (These setup calls are usually made from board
-setup or driver probe/teardown code, so this is an easy constraint.)
+controller chip too  (These setup calls are usually made from board
+setup or driver probe/teardown code, so this is an easy constraint.)::
 
-	gpio_direction_input()
-	gpio_direction_output()
-	gpio_request()
+                gpio_direction_input()
+                gpio_direction_output()
+                gpio_request()
 
-## 	gpio_request_one()
-##	gpio_request_array()
-## 	gpio_free_array()
+        ## 	gpio_request_one()
+        ##	gpio_request_array()
+        ## 	gpio_free_array()
 
-	gpio_free()
-	gpio_set_debounce()
+                gpio_free()
+                gpio_set_debounce()
 
 
 
 Claiming and Releasing GPIOs
 ----------------------------
-To help catch system configuration errors, two calls are defined.
+To help catch system configuration errors, two calls are defined::
 
 	/* request GPIO, returning 0 or negative errno.
 	 * non-null labels may be useful for diagnostics.
@@ -296,7 +298,7 @@
 before you free it.
 
 Considering in most cases GPIOs are actually configured right after they
-are claimed, three additional calls are defined:
+are claimed, three additional calls are defined::
 
 	/* request a single GPIO, with initial configuration specified by
 	 * 'flags', identical to gpio_request() wrt other arguments and
@@ -347,7 +349,7 @@
 In the future, these flags can be extended to support more properties.
 
 Further more, to ease the claim/release of multiple GPIOs, 'struct gpio' is
-introduced to encapsulate all three fields as:
+introduced to encapsulate all three fields as::
 
 	struct gpio {
 		unsigned	gpio;
@@ -355,7 +357,7 @@
 		const char	*label;
 	};
 
-A typical example of usage:
+A typical example of usage::
 
 	static struct gpio leds_gpios[] = {
 		{ 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* default to ON */
@@ -380,7 +382,7 @@
 --------------------
 GPIO numbers are unsigned integers; so are IRQ numbers.  These make up
 two logically distinct namespaces (GPIO 0 need not use IRQ 0).  You can
-map between them using calls like:
+map between them using calls like::
 
 	/* map GPIO numbers to IRQ numbers */
 	int gpio_to_irq(unsigned gpio);
@@ -446,12 +448,12 @@
 subsystem, in the sense that the pins can be used by other functions
 together with an optional gpio feature. We have already covered the
 case where e.g. a GPIO controller need to reserve a pin or set the
-direction of a pin by calling any of:
+direction of a pin by calling any of::
 
-pinctrl_gpio_request()
-pinctrl_gpio_free()
-pinctrl_gpio_direction_input()
-pinctrl_gpio_direction_output()
+  pinctrl_gpio_request()
+  pinctrl_gpio_free()
+  pinctrl_gpio_direction_input()
+  pinctrl_gpio_direction_output()
 
 But how does the pin control subsystem cross-correlate the GPIO
 numbers (which are a global business) to a certain pin on a certain
@@ -565,7 +567,7 @@
 GPIOs through GPIO-lib and the code cannot be enabled by the user.
 
 Trivial implementations of those functions can directly use framework
-code, which always dispatches through the gpio_chip:
+code, which always dispatches through the gpio_chip::
 
   #define gpio_get_value	__gpio_get_value
   #define gpio_set_value	__gpio_set_value
@@ -731,7 +733,7 @@
 Exporting from Kernel code
 --------------------------
 Kernel code can explicitly manage exports of GPIOs which have already been
-requested using gpio_request():
+requested using gpio_request()::
 
 	/* export the GPIO to userspace */
 	int gpio_export(unsigned gpio, bool direction_may_change);
@@ -756,3 +758,13 @@
 symlinks from elsewhere in sysfs to the GPIO sysfs node.  Drivers can
 use this to provide the interface under their own device in sysfs with
 a descriptive name.
+
+
+API Reference
+=============
+
+The functions listed in this section are deprecated. The GPIO descriptor based
+API should be used in new code.
+
+.. kernel-doc:: drivers/gpio/gpiolib-legacy.c
+   :export:
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index e9b41b1..6d8352c 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -44,7 +44,7 @@
    uio-howto
    firmware/index
    pinctl
-   gpio
+   gpio/index
    misc_devices
    dmaengine/index
    slimbus
diff --git a/Documentation/driver-api/mtdnand.rst b/Documentation/driver-api/mtdnand.rst
index 2a5191b..dcd6359 100644
--- a/Documentation/driver-api/mtdnand.rst
+++ b/Documentation/driver-api/mtdnand.rst
@@ -967,10 +967,10 @@
 which is marked with an [XXX] identifier. See the chapter "Documentation
 hints" for an explanation.
 
-.. kernel-doc:: drivers/mtd/nand/nand_base.c
+.. kernel-doc:: drivers/mtd/nand/raw/nand_base.c
    :export:
 
-.. kernel-doc:: drivers/mtd/nand/nand_ecc.c
+.. kernel-doc:: drivers/mtd/nand/raw/nand_ecc.c
    :export:
 
 Internal Functions Provided
@@ -982,10 +982,10 @@
 for an explanation. The functions marked with [DEFAULT] might be
 relevant for a board driver developer.
 
-.. kernel-doc:: drivers/mtd/nand/nand_base.c
+.. kernel-doc:: drivers/mtd/nand/raw/nand_base.c
    :internal:
 
-.. kernel-doc:: drivers/mtd/nand/nand_bbt.c
+.. kernel-doc:: drivers/mtd/nand/raw/nand_bbt.c
    :internal:
 
 Credits
diff --git a/Documentation/driver-api/scsi.rst b/Documentation/driver-api/scsi.rst
index 3ae3379..31ad0fe 100644
--- a/Documentation/driver-api/scsi.rst
+++ b/Documentation/driver-api/scsi.rst
@@ -154,12 +154,6 @@
 .. kernel-doc:: drivers/scsi/scsi_lib_dma.c
    :export:
 
-drivers/scsi/scsi_module.c
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The file drivers/scsi/scsi_module.c contains legacy support for
-old-style host templates. It should never be used by any new driver.
-
 drivers/scsi/scsi_proc.c
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/Documentation/fault-injection/fault-injection.txt b/Documentation/fault-injection/fault-injection.txt
index de1dc35..4d1b7b4 100644
--- a/Documentation/fault-injection/fault-injection.txt
+++ b/Documentation/fault-injection/fault-injection.txt
@@ -36,6 +36,14 @@
   ALLOW_ERROR_INJECTION() macro, by setting debugfs entries
   under /sys/kernel/debug/fail_function. No boot option supported.
 
+o NVMe fault injection
+
+  inject NVMe status code and retry flag on devices permitted by setting
+  debugfs entries under /sys/kernel/debug/nvme*/fault_inject. The default
+  status code is NVME_SC_INVALID_OPCODE with no retry. The status code and
+  retry flag can be set via the debugfs.
+
+
 Configure fault-injection capabilities behavior
 -----------------------------------------------
 
diff --git a/Documentation/fault-injection/nvme-fault-injection.txt b/Documentation/fault-injection/nvme-fault-injection.txt
new file mode 100644
index 0000000..8fbf3bf
--- /dev/null
+++ b/Documentation/fault-injection/nvme-fault-injection.txt
@@ -0,0 +1,116 @@
+NVMe Fault Injection
+====================
+Linux's fault injection framework provides a systematic way to support
+error injection via debugfs in the /sys/kernel/debug directory. When
+enabled, the default NVME_SC_INVALID_OPCODE with no retry will be
+injected into the nvme_end_request. Users can change the default status
+code and no retry flag via the debugfs. The list of Generic Command
+Status can be found in include/linux/nvme.h
+
+Following examples show how to inject an error into the nvme.
+
+First, enable CONFIG_FAULT_INJECTION_DEBUG_FS kernel config,
+recompile the kernel. After booting up the kernel, do the
+following.
+
+Example 1: Inject default status code with no retry
+---------------------------------------------------
+
+mount /dev/nvme0n1 /mnt
+echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times
+echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability
+cp a.file /mnt
+
+Expected Result:
+
+cp: cannot stat ‘/mnt/a.file’: Input/output error
+
+Message from dmesg:
+
+FAULT_INJECTION: forcing a failure.
+name fault_inject, interval 1, probability 100, space 0, times 1
+CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.15.0-rc8+ #2
+Hardware name: innotek GmbH VirtualBox/VirtualBox,
+BIOS VirtualBox 12/01/2006
+Call Trace:
+  <IRQ>
+  dump_stack+0x5c/0x7d
+  should_fail+0x148/0x170
+  nvme_should_fail+0x2f/0x50 [nvme_core]
+  nvme_process_cq+0xe7/0x1d0 [nvme]
+  nvme_irq+0x1e/0x40 [nvme]
+  __handle_irq_event_percpu+0x3a/0x190
+  handle_irq_event_percpu+0x30/0x70
+  handle_irq_event+0x36/0x60
+  handle_fasteoi_irq+0x78/0x120
+  handle_irq+0xa7/0x130
+  ? tick_irq_enter+0xa8/0xc0
+  do_IRQ+0x43/0xc0
+  common_interrupt+0xa2/0xa2
+  </IRQ>
+RIP: 0010:native_safe_halt+0x2/0x10
+RSP: 0018:ffffffff82003e90 EFLAGS: 00000246 ORIG_RAX: ffffffffffffffdd
+RAX: ffffffff817a10c0 RBX: ffffffff82012480 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+RBP: 0000000000000000 R08: 000000008e38ce64 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff82012480
+R13: ffffffff82012480 R14: 0000000000000000 R15: 0000000000000000
+  ? __sched_text_end+0x4/0x4
+  default_idle+0x18/0xf0
+  do_idle+0x150/0x1d0
+  cpu_startup_entry+0x6f/0x80
+  start_kernel+0x4c4/0x4e4
+  ? set_init_arg+0x55/0x55
+  secondary_startup_64+0xa5/0xb0
+  print_req_error: I/O error, dev nvme0n1, sector 9240
+EXT4-fs error (device nvme0n1): ext4_find_entry:1436:
+inode #2: comm cp: reading directory lblock 0
+
+Example 2: Inject default status code with retry
+------------------------------------------------
+
+mount /dev/nvme0n1 /mnt
+echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times
+echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability
+echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/status
+echo 0 > /sys/kernel/debug/nvme0n1/fault_inject/dont_retry
+
+cp a.file /mnt
+
+Expected Result:
+
+command success without error
+
+Message from dmesg:
+
+FAULT_INJECTION: forcing a failure.
+name fault_inject, interval 1, probability 100, space 0, times 1
+CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.15.0-rc8+ #4
+Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+Call Trace:
+  <IRQ>
+  dump_stack+0x5c/0x7d
+  should_fail+0x148/0x170
+  nvme_should_fail+0x30/0x60 [nvme_core]
+  nvme_loop_queue_response+0x84/0x110 [nvme_loop]
+  nvmet_req_complete+0x11/0x40 [nvmet]
+  nvmet_bio_done+0x28/0x40 [nvmet]
+  blk_update_request+0xb0/0x310
+  blk_mq_end_request+0x18/0x60
+  flush_smp_call_function_queue+0x3d/0xf0
+  smp_call_function_single_interrupt+0x2c/0xc0
+  call_function_single_interrupt+0xa2/0xb0
+  </IRQ>
+RIP: 0010:native_safe_halt+0x2/0x10
+RSP: 0018:ffffc9000068bec0 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff04
+RAX: ffffffff817a10c0 RBX: ffff88011a3c9680 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+RBP: 0000000000000001 R08: 000000008e38c131 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000000 R12: ffff88011a3c9680
+R13: ffff88011a3c9680 R14: 0000000000000000 R15: 0000000000000000
+  ? __sched_text_end+0x4/0x4
+  default_idle+0x18/0xf0
+  do_idle+0x150/0x1d0
+  cpu_startup_entry+0x6f/0x80
+  start_secondary+0x187/0x1e0
+  secondary_startup_64+0xa5/0xb0
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
index 13c2ff0..12a147c 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -174,6 +174,23 @@
 offprjjquota           Turn off project journelled quota.
 quota                  Enable plain user disk quota accounting.
 noquota                Disable all plain disk quota option.
+whint_mode=%s          Control which write hints are passed down to block
+                       layer. This supports "off", "user-based", and
+                       "fs-based".  In "off" mode (default), f2fs does not pass
+                       down hints. In "user-based" mode, f2fs tries to pass
+                       down hints given by users. And in "fs-based" mode, f2fs
+                       passes down hints with its policy.
+alloc_mode=%s          Adjust block allocation policy, which supports "reuse"
+                       and "default".
+fsync_mode=%s          Control the policy of fsync. Currently supports "posix"
+                       and "strict". In "posix" mode, which is default, fsync
+                       will follow POSIX semantics and does a light operation
+                       to improve the filesystem performance. In "strict" mode,
+                       fsync will be heavy and behaves in line with xfs, ext4
+                       and btrfs, where xfstest generic/342 will pass, but the
+                       performance will regress.
+test_dummy_encryption  Enable dummy encryption, which provides a fake fscrypt
+                       context. The fake fscrypt context is used by xfstests.
 
 ================================================================================
 DEBUGFS ENTRIES
@@ -611,3 +628,63 @@
 In order to identify whether the data in the victim segment are valid or not,
 F2FS manages a bitmap. Each bit represents the validity of a block, and the
 bitmap is composed of a bit stream covering whole blocks in main area.
+
+Write-hint Policy
+-----------------
+
+1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET.
+
+2) whint_mode=user-based. F2FS tries to pass down hints given by
+users.
+
+User                  F2FS                     Block
+----                  ----                     -----
+                      META                     WRITE_LIFE_NOT_SET
+                      HOT_NODE                 "
+                      WARM_NODE                "
+                      COLD_NODE                "
+*ioctl(COLD)          COLD_DATA                WRITE_LIFE_EXTREME
+*extension list       "                        "
+
+-- buffered io
+WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
+WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
+WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
+WRITE_LIFE_NONE       "                        "
+WRITE_LIFE_MEDIUM     "                        "
+WRITE_LIFE_LONG       "                        "
+
+-- direct io
+WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
+WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
+WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
+WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
+WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
+WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
+
+3) whint_mode=fs-based. F2FS passes down hints with its policy.
+
+User                  F2FS                     Block
+----                  ----                     -----
+                      META                     WRITE_LIFE_MEDIUM;
+                      HOT_NODE                 WRITE_LIFE_NOT_SET
+                      WARM_NODE                "
+                      COLD_NODE                WRITE_LIFE_NONE
+ioctl(COLD)           COLD_DATA                WRITE_LIFE_EXTREME
+extension list        "                        "
+
+-- buffered io
+WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
+WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
+WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_LONG
+WRITE_LIFE_NONE       "                        "
+WRITE_LIFE_MEDIUM     "                        "
+WRITE_LIFE_LONG       "                        "
+
+-- direct io
+WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
+WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
+WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
+WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
+WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
+WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt
index d3d0e32..e2f2faf 100644
--- a/Documentation/filesystems/udf.txt
+++ b/Documentation/filesystems/udf.txt
@@ -36,18 +36,14 @@
 	iocharset=	Set the NLS character set
 
 The uid= and gid= options need a bit more explaining.  They will accept a
-decimal numeric value which will be used as the default ID for that mount.
-They will also accept the string "ignore" and "forget".  For files on the disk
-that are owned by nobody ( -1 ), they will instead look as if they are owned
-by the default ID.  The ignore option causes the default ID to override all
-IDs on the disk, not just -1.  The forget option causes all IDs to be written
-to disk as -1, so when the media is later remounted, they will appear to be
-owned by whatever default ID it is mounted with at that time.
+decimal numeric value and all inodes on that mount will then appear as
+belonging to that uid and gid.  Mount options also accept the string "forget".
+The forget option causes all IDs to be written to disk as -1 which is a way
+of UDF standard to indicate that IDs are not supported for these files .
 
-For typical desktop use of removable media, you should set the ID to that
-of the interactively logged on user, and also specify both the forget and
-ignore options.  This way the interactive user will always see the files
-on the disk as belonging to him.
+For typical desktop use of removable media, you should set the ID to that of
+the interactively logged on user, and also specify the forget option.  This way
+the interactive user will always see the files on the disk as belonging to him.
 
 The remaining are for debugging and disaster recovery:
 
@@ -57,16 +53,8 @@
 
 	session=	Set the CDROM session (default= last session)
 	anchor=		Override standard anchor location. (default= 256)
-	volume=		Override the VolumeDesc location. (unused)
-	partition=	Override the PartitionDesc location. (unused)
 	lastblock=	Set the last block of the filesystem/
 
-The following expect a offset from the partition root.
-
-	fileset=	Override the fileset block location. (unused)
-	rootdir=	Override the root directory location. (unused)
-			WARNING: overriding the rootdir to a non-directory may
-				yield highly unpredictable results.
 -------------------------------------------------------------------------------
 
 
diff --git a/Documentation/gpio/00-INDEX b/Documentation/gpio/00-INDEX
index 179beb2..17e19a6 100644
--- a/Documentation/gpio/00-INDEX
+++ b/Documentation/gpio/00-INDEX
@@ -1,17 +1,4 @@
 00-INDEX
 	- This file
-gpio.txt
-	- Introduction to GPIOs and their kernel interfaces
-consumer.txt
-	- How to obtain and use GPIOs in a driver
-driver.txt
-	- How to write a GPIO driver
-drivers-on-gpio.txt:
-	- Drivers in other subsystems that can use GPIO to provide more
-	  complex functionality.
-board.txt
-	- How to assign GPIOs to a consumer device and a function
 sysfs.txt
 	- Information about the GPIO sysfs interface
-gpio-legacy.txt
-	- Historical documentation of the deprecated GPIO integer interface
diff --git a/Documentation/gpio/sysfs.txt b/Documentation/gpio/sysfs.txt
index 6cdeab8..58eeab8 100644
--- a/Documentation/gpio/sysfs.txt
+++ b/Documentation/gpio/sysfs.txt
@@ -32,9 +32,8 @@
 GPIO drivers could be all that the system really needs.
 
 DO NOT ABUSE SYSFS TO CONTROL HARDWARE THAT HAS PROPER KERNEL DRIVERS.
-PLEASE READ THE DOCUMENT NAMED "drivers-on-gpio.txt" IN THIS DOCUMENTATION
-DIRECTORY TO AVOID REINVENTING KERNEL WHEELS IN USERSPACE. I MEAN IT.
-REALLY.
+PLEASE READ THE DOCUMENT AT Documentation/driver-api/gpio/drivers-on-gpio.rst
+TO AVOID REINVENTING KERNEL WHEELS IN USERSPACE. I MEAN IT. REALLY.
 
 Paths in Sysfs
 --------------
diff --git a/Documentation/input/devices/pxrc.rst b/Documentation/input/devices/pxrc.rst
new file mode 100644
index 0000000..ca11f64
--- /dev/null
+++ b/Documentation/input/devices/pxrc.rst
@@ -0,0 +1,57 @@
+=======================================================
+pxrc - PhoenixRC Flight Controller Adapter
+=======================================================
+
+:Author: Marcus Folkesson <marcus.folkesson@gmail.com>
+
+This driver let you use your own RC controller plugged into the
+adapter that comes with PhoenixRC [1]_ or other compatible adapters.
+
+The adapter supports 7 analog channels and 1 digital input switch.
+
+Notes
+=====
+
+Many RC controllers is able to configure which stick goes to which channel.
+This is also configurable in most simulators, so a matching is not necessary.
+
+The driver is generating the following input event for analog channels:
+
++---------+----------------+
+| Channel |      Event     |
++=========+================+
+|     1   |  ABS_X         |
++---------+----------------+
+|     2   |  ABS_Y         |
++---------+----------------+
+|     3   |  ABS_RX        |
++---------+----------------+
+|     4   |  ABS_RY        |
++---------+----------------+
+|     5   |  ABS_RUDDER    |
++---------+----------------+
+|     6   |  ABS_THROTTLE  |
++---------+----------------+
+|     7   |  ABS_MISC      |
++---------+----------------+
+
+The digital input switch is generated as an `BTN_A` event.
+
+Manual Testing
+==============
+
+To test this driver's functionality you may use `input-event` which is part of
+the `input layer utilities` suite [2]_.
+
+For example::
+
+    > modprobe pxrc
+    > input-events <devnr>
+
+To print all input events from input `devnr`.
+
+References
+==========
+
+.. [1] http://www.phoenix-sim.com/
+.. [2] https://www.kraxel.org/cgit/input/
diff --git a/Documentation/arm/CCN.txt b/Documentation/perf/arm-ccn.txt
similarity index 100%
rename from Documentation/arm/CCN.txt
rename to Documentation/perf/arm-ccn.txt
diff --git a/Documentation/scsi/ChangeLog.1992-1997 b/Documentation/scsi/ChangeLog.1992-1997
deleted file mode 100644
index 6faad7e..0000000
--- a/Documentation/scsi/ChangeLog.1992-1997
+++ /dev/null
@@ -1,2023 +0,0 @@
-Sat Jan 18 15:51:45 1997  Richard Henderson  <rth@tamu.edu>
-
-	* Don't play with usage_count directly, instead hand around
-	the module header and use the module macros.
-
-Fri May 17 00:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 2.0.3 Released.
-
-Tue Apr 16 21:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 1.3.2 Released.
-
-Sun Dec 31 23:26:00 1995  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 1.3.1 Released.
-
-Fri Nov 10 15:29:49 1995  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* Released new BusLogic driver.
-
-Wed Aug  9 22:37:04 1995  Andries Brouwer  <aeb@cwi.nl>
-
-	As a preparation for new device code, separated the various
-	functions the request->dev field had into the device proper,
-	request->rq_dev and a status field request->rq_status.
-
-	The 2nd argument of bios_param is now a kdev_t.
-
-Wed Jul 19 10:43:15 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-        * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all
-	attached devices.
-
-	* scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and
-	eata_dma_proc.c to produce some device info for /proc/scsi.
-
-	* eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done):
-	Changed handling of internal SCSI commands send to the HBA.
-
-
-Wed Jul 19 10:09:17 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.11 released.
-
-	* eata_dma.c (eata_queue)(eata_int_handler): Added code to do
-	command latency measurements if requested by root through
-	/proc/scsi interface.
-	Throughout Use HZ constant for time references.
-
-	* eata_pio.c: Use HZ constant for time references.
-
-	* aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD
-	to GNU style.
-
-	* scsi.h: Added READ_12 command opcode constant
-
-Wed Jul 19 09:25:30 1995  Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.10 released.
-
-	* scsi_proc.c (dispatch_scsi_info): Removed unused variable.
-
-Wed Jul 19 09:25:30 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.9 released.
-
-	* scsi.c Blacklist concept expanded to 'support' more device
-	deficiencies. blacklist[] renamed to device_list[]
-	(scan_scsis): Code cleanup.
-
-	* scsi_debug.c (scsi_debug_proc_info): Added support to control
-	device lockup simulation via /proc/scsi interface.
-
-
-Wed Jul 19 09:22:34 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.7 released.
-
-	* scsi_proc.c: Fixed a number of bugs in directory handling
-
-Wed Jul 19 09:18:28 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.5 released.
-
-	* Native wide, multichannel and /proc/scsi support now in official
-	kernel distribution.
-
-        * scsi.c/h, hosts.c/h et al reindented to increase readability
-	(especially on 80 column wide terminals).
-
-	* scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added
-	/proc/scsi/scsi which allows root to scan for hotplugged devices.
-
-	* scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi.
-	(scan_scsis): Added some 'spaghetti' code to allow scanning for
-	single devices.
-	
-
-Thu Jun 20 15:20:27 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-        * proc.c: Renamed to scsi_proc.c
-
-Mon Jun 12 20:32:45 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.0 released.
-
-Mon May 15 19:33:14 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* scsi.c: Added native multichannel and wide scsi support.
-
-	* proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries):
-	Updated /proc/scsi interface.
-
-Thu May  4 17:58:48 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* sd.c (requeue_sd_request): Zero out the scatterlist only if
-	scsi_malloc returned memory for it.
-
-	* eata_dma.c (register_HBA) (eata_queue): Add support for
-	large scatter/gather tables and set use_clustering accordingly
-
-	* hosts.c: Make use_clustering changeable in the Scsi_Host structure.
-
-Wed Apr 12 15:25:52 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.5 released.
-
-	* buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff).
-	Fixed interrupt routine to avoid races when handling multiple
-	complete commands per interrupt.  Seems to come up with faster
-	cards.
-
-	* eata_dma.c: Update to 2.3.5r. Modularize. Improved error handling
-        throughout and fixed bug interrupt routine which resulted in shifted
-        status bytes. Added blink LED state checks for ISA and EISA HBAs.
-        Memory management bug seems to have disappeared ==> increasing
-        C_P_L_CURRENT_MAX to 16 for now. Decreasing C_P_L_DIV to 3 for
-        performance reasons.
-
-	* scsi.c: If we get a FMK, EOM, or ILI when attempting to scan
-	the bus, assume that it was just noise on the bus, and ignore
-	the device.
-
-	* scsi.h: Update and add a bunch of missing commands which we
-	were never using.
-
-	* sd.c: Use restore_flags in do_sd_request - this may result in
-	latency conditions, but it gets rid of races and crashes.
-	Do not save flags again when searching for a second command to
-	queue.
-
-	* st.c: Use bytes, not STP->buffer->buffer_size when reading
-	from tape.
-
-
-Tue Apr  4 09:42:08 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.4 released.
-
-	* st.c: Fix typo - restoring wrong flags.
-
-Wed Mar 29 06:55:12 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.3 released.
-
-	* st.c: Perform some waiting operations with interrupts off.
-	Is this correct???
-
-Wed Mar 22 10:34:26 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.2 released.
-
-	* aha152x.c: Modularize.  Add support for PCMCIA.
-
-	* eata.c: Update to version 2.0.  Fixed bug preventing media
-	detection.  If scsi_register_host returns NULL, fail gracefully.
-
-	* scsi.c: Detect as NEC (for photo-cd purposes) for the 84
-	and 25 models as "NEC_OLDCDR".
-
-	* scsi.h: Add define for NEC_OLDCDR
-
-	* sr.c: Add handling for NEC_OLDCDR.  Treat as unknown.
-
-	* u14-34f.c: Update to version 2.0.  Fixed same bug as in
-	eata.c.
-
-
-Mon Mar  6 11:11:20 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.0 released.  Yeah!!!
-
-	* Minor spelling/punctuation changes throughout.  Nothing
-	substantive.
-
-Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.95 released.
-
-	* qlogic.c: Update to version 0.41.
-
-	* seagate.c: Change some message to be more descriptive about what
-	we detected.
-
-	* sr.c: spelling/whitespace changes.
-
-Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.94 released.
-
-Mon Feb 20 08:57:17 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.93 released.
-
-	* hosts.h: Change io_port to long int from short.
-
- 	* 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP,
- 	  NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output
- 	  fixed, should initialize correctly if left running, now loadable,
-  	  new memory allocation, extraneous diagnostic output suppressed,
- 	  splx() replaced with save/restore flags. [ Drew ]
-
-	* hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c,
-	sr_ioctl.c: Add special junk at end that Emacs will use for
-	formatting the file.
-
-	* qlogic.c: Update to v0.40a.  Improve parity handling.
-
-	* scsi.c: Add Hitachi DK312C to blacklist.  Change "};" to "}" in
-	many places.  Use scsi_init_malloc to get command block - may
-	need this to be dma compatible for some host adapters.
-	Restore interrupts after unregistering a host.
-
-	* sd.c: Use sti instead of restore flags - causes latency problems.
-
-	* seagate.c: Use controller_type to determine string used when
-	registering irq.
-
-	* sr.c: More photo-cd hacks to make sure we get the xa stuff right.
-	* sr.h, sr.c: Change is_xa to xa_flags field.
-
-	* st.c: Disable retries for write operations.
-
-Wed Feb 15 10:52:56 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.92 released.
-
-	* eata.c: Update to 1.17.
-
-	* eata_dma.c: Update to 2.31a. Add more support for /proc/scsi.
-        Continuing modularization. Less crashes because of the bug in the
-        memory management ==> increase C_P_L_CURRENT_MAX to 10
-        and decrease C_P_L_DIV to 4.
-
-	* hosts.c: If we remove last host registered, reuse host number.
-	When freeing memory from host being deregistered, free extra_bytes
-	too.
-
-	* scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt.
-	Change memory allocation to work around bugs in __get_dma_pages.
-	Do not free host if usage count is not zero (for modules).
-
-	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000.
-
-	* st.c: Allow for ST_EXTRA_DEVS in st data structures.
-
-	* u14-34f.c: Update to 1.17.
-
-Thu Feb  9 10:11:16 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.91 released.
-
-	* eata.c: Update to 1.16.  Use wish_block instead of host->block.
-
-	* hosts.c: Initialize wish_block to 0.
-
-	* hosts.h: Add wish_block.
-
-	* scsi.c: Use wish_block as indicator that the host should be added
-	to block list.
-
-	* sg.c: Add SG_EXTRA_DEVS to number of slots.
-
-	* u14-34f.c: Use wish_block.
-
-Tue Feb  7 11:46:04 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.90 released.
-
-	* eata.c: Change naming from eata_* to eata2x_*.  Now at vers 1.15.
-	Update interrupt handler to take pt_regs as arg.  Allow blocking
-	even if loaded as module.  Initialize target_time_out array.
-	Do not put sti(); in timing loop.
-
-	* hosts.c: Do not reuse host numbers.
-	Use scsi_make_blocked_list to generate blocking list.
-
-	* script_asm.pl:  Beats me.  Don't know perl.  Something to do with
-	phase index.
-
-	* scsi.c (scsi_make_blocked_list): New function - code copied from
-	hosts.c.
-
-	* scsi.c: Update code to disable photo CD for Toshiba cdroms.
-	Use just manufacturer name, not model number.
-
-	* sr.c: Fix setting density for Toshiba drives.
-
-	* u14-34f.c: Clear target_time_out array during reset.
-
-Wed Feb  1 09:20:45 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.89 released.
-
-	* Makefile, u14-34f.c: Modularize.
-
-	* Makefile, eata.c: Modularize.  Now version 1.14
-
-	* NCR5380.c: Update interrupt handler with new arglist.  Minor
-	cleanups.
-
-	* eata_dma.c: Begin to modularize.  Add hooks for /proc/scsi.
-	New version 2.3.0a. Add code in interrupt handler to allow
-        certain CDROM drivers to be detected which return a
-        CHECK_CONDITION during SCSI bus scan. Add opcode check to get
-        all DATA IN and DATA OUT phases right. Utilize HBA_interpret flag.
-	Improvements in HBA identification. Various other minor stuff.
-
-	* hosts.c: Initialize ->dma_channel and ->io_port when registering
-	a new host.
-
-	* qlogic.c: Modularize and add PCMCIA support.
-
-	* scsi.c: Add Hitachi to blacklist.
-
-	* scsi.c: Change default to no lun scan (too many problem devices).
-
-	* scsi.h: Define QUEUE_FULL condition.
-
-	* sd.c: Do not check for non-existent partition until after
-	new media check.
-
-	* sg.c: Undo previous change which was wrong.
-
-	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000.
-
-	* st.c: Patches from Kai - improve filemark handling.
-
-Tue Jan 31 17:32:12 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.88 released.
-
-	* Throughout - spelling/grammar fixups.
-
-	* scsi.c: Make sure that all buffers are 16 byte aligned - some
-	drivers (buslogic) need this.
-
-	* scsi.c (scan_scsis): Remove message printed.
-
-	* scsi.c (scsi_init): Move message here.
-
-Mon Jan 30 06:40:25 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.87 released.
-
-	* sr.c: Photo-cd related changes. (Gerd Knorr??).
-
-	* st.c: Changes from Kai related to EOM detection.
-
-Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.86 released.
-
-	* 53c7,8xx.h: Change SG size to 127.
-
-	* eata_dma: Update to version 2.10i. Remove bug in the registration
-        of multiple HBAs and channels. Minor other improvements and stylistic
-        changes.
-
-	* scsi.c: Test for Toshiba XM-3401TA and exclude from detection
-	as toshiba drive - photo cd does not work with this drive.
-
-	* sr.c:  Update photocd code.
-
-Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.85 released.
-
-	* st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c:
-	include linux/mm.h
-
-	* qlogic.c, buslogic.c, aha1542.c: Include linux/module.h.
-
-Sun Jan 22 22:08:46 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.84 released.
-
-	* Makefile: Support for loadable QLOGIC boards.
-
-	* aha152x.c: Update to version 1.8 from Juergen.
-
-	* eata_dma.c: Update from Michael Neuffer.
-        Remove hard limit of 2 commands per lun and make it better
-        configurable. Improvements in HBA identification.
-
-	* in2000.c: Fix biosparam to support large disks.
-
-	* qlogic.c: Minor changes (change sti -> restore_flags).
-
-Wed Jan 18 23:33:09 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.83 released.
-
-	* aha1542.c(aha1542_intr_handle): Use arguments handed down to find
-	which irq.
-
-	* buslogic.c: Likewise.
-
-	* eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards.
-
-	* scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK.
-
-	* sd.c: Fail if we are opening a non-existent partition.
-
-	* sr.c: Bump SR_TIMEOUT to 15000.
-	Do not probe for media size at boot time(hard on changers).
-	Flag device as needing sector size instead.
-
-	* sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl.
-
-	* ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args).
-
-Mon Jan 16 07:18:23 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.82 released.
-
-	Throughout.
-	- Change all interrupt handlers to accept new calling convention.
-	In particular, we now receive the irq number as one of the arguments.
-
-	* More minor spelling corrections in some of the new files.
-
-	* aha1542.c, buslogic.c: Clean up interrupt handler a little now
-	that we receive the irq as an arg.
-
-	* aha274x.c: s/snarf_region/request_region/
-
-	* eata.c: Update to version 1.12.   Fix some comments and display a
-	message if we cannot reserve the port addresses.
-
-	* u14-34f.c: Update to version 1.13.   Fix some comments and display a
-	message if we cannot reserve the port addresses.
-
-	* eata_dma.c: Define get_board_data function (send INQUIRY command).
-	Use to improve detection of variants of different DPT boards.  Change
-	version subnumber to "0g".
-
-	* fdomain.c:  Update to version 5.26.  Improve detection of some boards
-	repackaged by IBM.
-
-	* scsi.c (scsi_register_host): Change "name" to const char *.
-
-	* sr.c: Fix problem in set mode command for Toshiba drives.
-
-	* sr.c: Fix typo from patch 81.
-
-Fri Jan 13 12:54:46 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.81 released.  Codefreeze for 1.2 release announced.
-
-	Big changes here.
-
-	* eata_dma.*: New files from Michael Neuffer.
-	(neuffer@goofy.zdv.uni-mainz.de).  Should support
-	all eata/dpt cards.
-
-	* hosts.c, Makefile: Add eata_dma.
-
-	* README.st: Document MTEOM.
-
-	Patches from me (ERY) to finish support for low-level loadable scsi.
-	It now works, and is actually useful.
-
-	* Throughout - add new argument to scsi_init_malloc that takes an
-	additional parameter.  This is used as a priority to kmalloc,
-	and you can specify the GFP_DMA flag if you need DMA-able memory.
-
-	* Makefile: For source files that are loadable, always add name
-	to SCSI_SRCS.  Fill in modules: target.
-
-	* hosts.c:  Change next_host to next_scsi_host, and make global.
-	Print hosts after we have identified all of them.  Use info()
-	function if present, otherwise use name field.
-
-	* hosts.h: Change attach function to return int, not void.
-	Define number of device slots to allow for loadable devices.
-	Define tags to tell scsi module code what type of module we
-	are loading.
-
-	* scsi.c: Fix scan_scsis so that it can be run by a user process.
-	Do not use waiting loops - use up and down mechanism as long
-	as current != task[0].
-
-	* scsi.c(scan_scsis): Do not use stack variables for I/O - this
-	could be > 16Mb if we are loading a module at runtime (i.e. use
-	scsi_init_malloc to get some memory we know will be safe).
-
-	* scsi.c: Change dma freelist to be a set of pages.  This allows
-	us to dynamically adjust the size of the list by adding more pages
-	to the pagelist.  Fix scsi_malloc and scsi_free accordingly.
-
-	* scsi_module.c: Fix include.
-
-	* sd.c: Declare detach function.  Increment/decrement module usage
-	count as required.  Fix init functions to allow loaded devices.
-	Revalidate all new disks so we get the partition tables.  Define
-	detach function.
-
-	* sr.c: Likewise.
-
-	* sg.c: Declare detach function.  Allow attachment of devices on
-	loaded drivers.
-
-	* st.c: Declare detach function.  Increment/decrement module usage
-	count as required.
-
-Tue Jan 10 10:09:58 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.79 released.
-
-	Patch from some undetermined individual who needs to get a life :-).
-
-	* sr.c: Attacked by spelling bee...
-
-	Patches from Gerd Knorr:
-
-	* sr.c: make printk messages for photoCD a little more informative.
-
-	* sr_ioctl.c: Fix CDROMMULTISESSION_SYS ioctl.
-
-Mon Jan  9 10:01:37 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.78 released.
-
-	* Makefile: Add empty modules: target.
-
-	* Wheee.  Now change register_iomem to request_region.
-
-	* in2000.c: Bugfix - apparently this is the fix that we have
-	all been waiting for.  It fixes a problem whereby the driver
-	is not stable under heavy load.  Race condition and all that.
-	Patch from Peter Lu.
-
-Wed Jan  4 21:17:40 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.77 released.
-
-	* 53c7,8xx.c: Fix from Linus - emulate splx.
-
-	Throughout:
-
-		Change "snarf_region" with "register_iomem".
-
-	* scsi_module.c: New file.  Contains support for low-level loadable
-	  scsi drivers. [ERY].
-
-	* sd.c: More s/int/long/ changes.
-
-	* seagate.c: Explicitly include linux/config.h
-
-	* sg.c: Increment/decrement module usage count on open/close.
-
-	* sg.c: Be a bit more careful about the user not supplying enough
-	  information for a valid command.  Pass correct size down to
-	  scsi_do_cmd.
-
-	* sr.c:  More changes for Photo-CD.  This apparently breaks NEC drives.
-
-	* sr_ioctl.c:  Support CDROMMULTISESSION ioctl.
-
-
-Sun Jan  1 19:55:21 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.76 released.
-
-	* constants.c: Add type cast in switch statement.
-
-	* scsi.c (scsi_free): Change datatype of "offset" to long.
-	  (scsi_malloc): Change a few more variables to long.  Who
-	  did this and why was it important?  64 bit machines?
-
-
-	Lots of changes to use save_state/restore_state instead of cli/sti.
-	Files changed include:
-
-	* aha1542.c:
-	* aha1740.c:
-	* buslogic.c:
-	* in2000.c:
-	* scsi.c:
-	* scsi_debug.c:
-	* sd.c:
-	* sr.c:
-	* st.c:
-
-Wed Dec 28 16:38:29 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.75 released.
-
-	* buslogic.c: Spelling fix.
-
-	* scsi.c: Add HP C1790A and C2500A scanjet to blacklist.
-
-	* scsi.c: Spelling fixup.
-
-	* sd.c: Add support for sd_hardsizes (hard sector sizes).
-
-	* ultrastor.c: Use save_flags/restore_flags instead of cli/sti.
-
-Fri Dec 23 13:36:25 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.74 released.
-
-	* README.st: Update from Kai Makisara.
-
-	* eata.c: New version from Dario - version 1.11.
-	  use scsicam bios_param routine.  Add support for 2011
-	  and 2021 boards.
-
-	* hosts.c: Add support for blocking.  Linked list automatically
-	  generated when shpnt->block is set.
-
-	* scsi.c: Add sankyo & HP scanjet to blacklist.  Add support for
-	  kicking things loose when we deadlock.
-
-	* scsi.c: Recognize scanners and processors in scan_scsis.
-
-	* scsi_ioctl.h: Increase timeout to 9 seconds.
-
-	* st.c: New version from Kai - add better support for backspace.
-
-	* u14-34f.c: New version from Dario.  Supports blocking.
-
-Wed Dec 14 14:46:30 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.73 released.
-
-	* buslogic.c: Update from Dave Gentzel.  Version 1.14.
-	  Add module related stuff.   More fault tolerant if out of
-	  DMA memory.
-
-	* fdomain.c: New version from Rik Faith - version 5.22.  Add support
-	  for ISA-200S SCSI adapter.
-
-	* hosts.c: Spelling.
-
-	* qlogic.c: Update to version 0.38a.  Add more support for PCMCIA.
-
-	* scsi.c: Mask device type with 0x1f during scan_scsis.
-	  Add support for deadlocking, err, make that getting out of
-	  deadlock situations that are created when we allow the user
-	  to limit requests to one host adapter at a time.
-
-	* scsi.c: Bugfix - pass pid, not SCpnt as second arg to
-	  scsi_times_out.
-
-	* scsi.c: Restore interrupt state to previous value instead of using
-	  cli/sti pairs.
-
-	* scsi.c: Add a bunch of module stuff (all commented out for now).
-
-	* scsi.c: Clean up scsi_dump_status.
-
-Tue Dec  6 12:34:20 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.72 released.
-
-	* sg.c: Bugfix - always use sg_free, since we might have big buff.
-
-Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.71 released.
-
-	* sg.c: Clear buff field when not in use.  Only call scsi_free if
-	non-null.
-
-	* scsi.h: Call wake_up(&wait_for_request) when done with a
-	command.
-
-	* scsi.c (scsi_times_out): Pass pid down so that we can protect
-	against race conditions.
-
-	* scsi.c (scsi_abort): Zero timeout field if we get the
-	NOT_RUNNING message back from low-level driver.
-
-
-	* scsi.c (scsi_done): Restore cmd_len, use_sg here.
-
-	* scsi.c (request_sense): Not here.
-
-	* hosts.h: Add new forbidden_addr, forbidden_size fields.  Who
-	added these and why????
-
-	* hosts.c (scsi_mem_init): Mark pages as reserved if they fall in
-	the forbidden regions.  I am not sure - I think this is so that
-	we can deal with boards that do incomplete decoding of their
-	address lines for the bios chips, but I am not entirely sure.
-
-	* buslogic.c: Set forbidden_addr stuff if using a buggy board.
-
-	* aha1740.c: Test for NULL pointer in SCtmp.  This should not
-	occur, but a nice message is better than a kernel segfault.
-
-	* 53c7,8xx.c: Add new PCI chip ID for 815.
-
-Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.70 released.
-
-	* ChangeLog, st.c: Spelling.
-
-Tue Nov 29 18:48:42 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.69 released.
-
-	* u14-34f.h: Non-functional change.  [Dario].
-
-	* u14-34f.c: Use block field in Scsi_Host to prevent commands from
-	being queued to more than one host at the same time (used when
-	motherboard does not deal with multiple bus-masters very well).
-	Only when SINGLE_HOST_OPERATIONS is defined.
-	Use new cmd_per_lun field.  [Dario]
-
-	* eata.c: Likewise.
-
-	* st.c: More changes from Kai.  Add ready flag to indicate drive
-	status.
-
-	* README.st: Document this.
-
-	* sr.c: Bugfix (do not subtract CD_BLOCK_OFFSET) for photo-cd
-	code.
-
-	* sg.c: Bugfix - fix problem where opcode is not correctly set up.
-
-	* seagate.[c,h]: Use #defines to set driver name.
-
-	* scsi_ioctl.c: Zero buffer before executing command.
-
-	* scsi.c: Use new cmd_per_lun field in Scsi_Hosts as appropriate.
-	Add Sony CDU55S to blacklist.
-
-	* hosts.h: Add new cmd_per_lun field to Scsi_Hosts.
-
-	* hosts.c: Initialize cmd_per_lun in Scsi_Hosts from template.
-
-	* buslogic.c: Use cmd_per_lun field - initialize to different
-	values depending upon bus type (i.e. use 1 if ISA, so we do not
-	hog memory).  Use other patches which got lost from 1.1.68.
-
-	* aha1542.c: Spelling.
-
-Tue Nov 29 15:43:50 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.68 released.
-
-	Add support for 12 byte vendor specific commands in scsi-generics,
-	more (i.e. the last mandatory) low-level changes to support
-	loadable modules, plus a few other changes people have requested
-	lately.  Changes by me (ERY) unless otherwise noted.  Spelling
-	changes appear from some unknown corner of the universe.
-
-	* Throughout: Change COMMAND_SIZE() to use SCpnt->cmd_len.
-
-	* Throughout: Change info() low level function to take a Scsi_Host
-	pointer.  This way the info function can return specific
-	information about the host in question, if desired.
-
-	* All low-level drivers: Add NULL in initializer for the
-	usage_count field added to Scsi_Host_Template.
-
-	* aha152x.[c,h]: Remove redundant info() function.
-
-	* aha1542.[c,h]: Likewise.
-
-	* aha1740.[c,h]: Likewise.
-
-	* aha274x.[c,h]: Likewise.
-
-	* eata.[c,h]: Likewise.
-
-	* pas16.[c,h]: Likewise.
-
-	* scsi_debug.[c,h]: Likewise.
-
-	* t128.[c,h]: Likewise.
-
-	* u14-34f.[c,h]: Likewise.
-
-	* ultrastor.[c,h]: Likewise.
-
-	* wd7000.[c,h]: Likewise.
-
-	* aha1542.c: Add support for command line options with lilo to set
-	DMA parameters, I/O port.  From Matt Aarnio.
-
-	* buslogic.[c,h]: New version (1.13) from Dave Gentzel.
-
-	* hosts.h: Add new field to Scsi_Hosts "block" to allow blocking
-	all I/O to certain other cards.  Helps prevent problems with some
-	ISA motherboards.
-
-	* hosts.h: Add usage_count to Scsi_Host_Template.
-
-	* hosts.h: Add n_io_port to Scsi_Host (used when releasing module).
-
-	* hosts.c: Initialize block field.
-
-	* in2000.c: Remove "static" declarations from exported functions.
-
-	* in2000.h: Likewise.
-
-	* scsi.c: Correctly set cmd_len field as required.  Save and
-	change setting when doing a request_sense, restore when done.
-	Move abort timeout message.  Fix panic in request_queueable to
-	print correct function name.
-
-	* scsi.c: When incrementing usage count, walk block linked list
-	for host, and or in SCSI_HOST_BLOCK bit.  When decrementing usage
-	count to 0, clear this bit to allow usage to continue, wake up
-	processes waiting.
-
-
-	* scsi_ioctl.c: If we have an info() function, call it, otherwise
-	if we have a "name" field, use it, else do nothing.
-
-	* sd.c, sr.c: Clear cmd_len field prior to each command we
-	generate.
-
-	* sd.h: Add "has_part_table" bit to rscsi_disks.
-
-	* sg.[c,h]: Add support for vendor specific 12 byte commands (i.e.
-	override command length in COMMAND_SIZE).
-
-	* sr.c: Bugfix from Gerd in photocd code.
-
-	* sr.c: Bugfix in get_sectorsize - always use scsi_malloc buffer -
-	we cannot guarantee that the stack is < 16Mb.
-
-Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.67 released.
-
-	* sr.c: Change spelling of manufactor to manufacturer.
-
-	* scsi.h: Likewise.
-
-	* scsi.c: Likewise.
-
-	* qlogic.c: Spelling corrections.
-
-	* in2000.h: Spelling corrections.
-
-	* in2000.c: Update from Bill Earnest, change from
-	jshiffle@netcom.com.  Support new bios versions.
-
-	* README.qlogic: Spelling correction.
-
-Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.66 released.
-
-	* u14-34f.c: Spelling corrections.
-
-	* sr.[h,c]: Add support for multi-session CDs from Gerd Knorr.
-
-	* scsi.h: Add manufactor field for keeping track of device
-	manufacturer.
-
-	* scsi.c: More spelling corrections.
-
-	* qlogic.h, qlogic.c, README.qlogic: New driver from Tom Zerucha.
-
-	* in2000.c, in2000.h: New driver from Brad McLean/Bill Earnest.
-
-	* fdomain.c: Spelling correction.
-
-	* eata.c: Spelling correction.
-
-Fri Nov 18 15:22:44 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.65 released.
-
-	* eata.h: Update version string to 1.08.00.
-
-	* eata.c: Set sg_tablesize correctly for DPT PM2012 boards.
-
-	* aha274x.seq: Spell checking.
-
-	* README.st: Likewise.
-
-	* README.aha274x: Likewise.
-
-	* ChangeLog: Likewise.
-
-Tue Nov 15 15:35:08 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.64 released.
-
-	* u14-34f.h: Update version number to 1.10.01.
-
-	* u14-34f.c: Use Scsi_Host can_queue variable instead of one from template.
-
-	* eata.[c,h]: New driver for DPT boards from Dario Ballabio.
-
-	* buslogic.c: Use can_queue field.
-
-Wed Nov 30 12:09:09 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.63 released.
-
-	* sd.c: Give I/O error if we attempt 512 byte I/O to a disk with
-	1024 byte sectors.
-
-	* scsicam.c: Make sure we do read from whole disk (mask off
-	partition).
-
-	* scsi.c: Use can_queue in Scsi_Host structure.
-	Fix panic message about invalid host.
-
-	* hosts.c: Initialize can_queue from template.
-
-	* hosts.h: Add can_queue to Scsi_Host structure.
-
-	* aha1740.c: Print out warning about NULL ecbptr.
-
-Fri Nov  4 12:40:30 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.62 released.
-
-	* fdomain.c: Update to version 5.20. (From Rik Faith).  Support
-	BIOS version 3.5.
-
-	* st.h: Add ST_EOD symbol.
-
-	* st.c: Patches from Kai Makisara - support additional densities,
-	add support for MTFSS, MTBSS, MTWSM commands.
-
-	* README.st: Update to document new commands.
-
-	* scsi.c: Add Mediavision CDR-H93MV to blacklist.
-
-Sat Oct 29 20:57:36 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.60 released.
-
-	* u14-34f.[c,h]: New driver from Dario Ballabio.
-
-	* aic7770.c, aha274x_seq.h, aha274x.seq, aha274x.h, aha274x.c,
-	README.aha274x: New files, new driver from John Aycock.
-
-
-Tue Oct 11 08:47:39 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.54 released.
-
-	* Add third PCI chip id.  [Drew]
-
-	* buslogic.c: Set BUSLOGIC_CMDLUN back to 1 [Eric].
-
-	* ultrastor.c: Fix asm directives for new GCC.
-
-	* sr.c, sd.c: Use new end_scsi_request function.
-
-	* scsi.h(end_scsi_request): Return pointer to block if still
-	active, else return NULL if inactive.  Fixes race condition.
-
-Sun Oct  9 20:23:14 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.53 released.
-
-	* scsi.c: Do not allocate dma bounce buffers if we have exactly
-	16Mb.
-
-Fri Sep  9 05:35:30 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.51 released.
-
-	* aha152x.c: Add support for disabling the parity check.  Update
-	to version 1.4. [Juergen].
-
-	* seagate.c: Tweak debugging message.
-
-Wed Aug 31 10:15:55 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.50 released.
-
-	* aha152x.c: Add eb800 for Vtech Platinum SMP boards. [Juergen].
-
-	* scsi.c: Add Quantum PD1225S to blacklist.
-
-Fri Aug 26 09:38:45 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.49 released.
-
-	* sd.c: Fix bug when we were deleting the wrong entry if we
-	get an unsupported sector size device.
-
-	* sr.c: Another spelling patch.
-
-Thu Aug 25 09:15:27 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.48 released.
-
-	* Throughout: Use new semantics for request_dma, as appropriate.
-
-	* sr.c: Print correct device number.
-
-Sun Aug 21 17:49:23 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.47 released.
-
-	* NCR5380.c: Add support for LIMIT_TRANSFERSIZE.
-
-	* constants.h: Add prototype for print_Scsi_Cmnd.
-
-	* pas16.c: Some more minor tweaks.  Test for Mediavision board.
-	Allow for disks > 1Gb.  [Drew??]
-
-	* sr.c: Set SCpnt->transfersize.
-
-Tue Aug 16 17:29:35 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.46 released.
-
-	* Throughout: More spelling fixups.
-
-	* buslogic.c: Add a few more fixups from Dave.  Disk translation
-	mainly.
-
-	* pas16.c: Add a few patches (Drew?).
-
-
-Thu Aug 11 20:45:15 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.44 released.
-
-	* hosts.c: Add type casts for scsi_init_malloc.
-
-	* scsicam.c: Add type cast.
-
-Wed Aug 10 19:23:01 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.43 released.
-
-	* Throughout: Spelling cleanups. [??]
-
-	* aha152x.c, NCR53*.c, fdomain.c, g_NCR5380.c, pas16.c, seagate.c,
-	 t128.c: Use request_irq, not irqaction. [??]
-
-	* aha1542.c: Move test for shost before we start to use shost.
-
-	* aha1542.c, aha1740.c, ultrastor.c, wd7000.c: Use new
-	calling sequence for request_irq.
-
-	* buslogic.c: Update from Dave Gentzel.
-
-Tue Aug  9 09:32:59 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.42 released.
-
-	* NCR5380.c: Change NCR5380_print_status to static.
-
-	* seagate.c: A few more bugfixes.  Only Drew knows what they are
-	for.
-
-	* ultrastor.c: Tweak some __asm__ directives so that it works
-	with newer compilers. [??]
-
-Sat Aug  6 21:29:36 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.40 released.
-
-	* NCR5380.c: Return SCSI_RESET_WAKEUP from reset function.
-
-	* aha1542.c: Reset mailbox status after a bus device reset.
-
-	* constants.c: Fix typo (;;).
-
-	* g_NCR5380.c:
-	* pas16.c:  Correct usage of NCR5380_init.
-
-	* scsi.c: Remove redundant (and unused variables).
-
-	* sd.c: Use memset to clear all of rscsi_disks before we use it.
-
-	* sg.c: Ditto, except for scsi_generics.
-
-	* sr.c: Ditto, except for scsi_CDs.
-
-	* st.c: Initialize STp->device.
-
-	* seagate.c: Fix bug. [Drew]
-
-Thu Aug  4 08:47:27 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.39 released.
-
-	* Makefile: Fix typo in NCR53C7xx.
-
-	* st.c: Print correct number for device.
-
-Tue Aug  2 11:29:14 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.38 released.
-
-	Lots of changes in 1.1.38.  All from Drew unless otherwise noted.
-
-	* 53c7,8xx.c: New file from Drew.  PCI driver.
-
-	* 53c7,8xx.h: Likewise.
-
-	* 53c7,8xx.scr: Likewise.
-
-	* 53c8xx_d.h, 53c8xx_u.h, script_asm.pl: Likewise.
-
-	* scsicam.c: New file from Drew.  Read block 0 on the disk and
-	read the partition table.  Attempt to deduce the geometry from
-	the partition table if possible.  Only used by 53c[7,8]xx right
-	now, but could be used by any device for which we have no way
-	of identifying the geometry.
-
-	* sd.c: Use device letters instead of sd%d in a lot of messages.
-
-	* seagate.c: Fix bug that resulted in lockups with some devices.
-
-	* sr.c (sr_open): Return -EROFS, not -EACCES if we attempt to open
-	device for write.
-
-	* hosts.c, Makefile: Update for new driver.
-
-	* NCR5380.c, NCR5380.h, g_NCR5380.h: Update from Drew to support
-	53C400 chip.
-
-	* constants.c: Define CONST_CMND and CONST_MSG.  Other minor
-	cleanups along the way.  Improve handling of CONST_MSG.
-
-	* fdomain.c, fdomain.h: New version from Rik Faith.  Update to
-	5.18.  Should now support TMC-3260 PCI card with 18C30 chip.
-
-	* pas16.c: Update with new irq initialization.
-
-	* t128.c: Update with minor cleanups.
-
-	* scsi.c (scsi_pid): New variable - gives each command a unique
-	id. Add Quantum LPS5235S to blacklist.  Change in_scan to
-	in_scan_scsis and make global.
-
-	* scsi.h: Add some defines for extended message handling,
-	INITIATE/RELEASE_RECOVERY.  Add a few new fields to support sync
-	transfers.
-
-	* scsi_ioctl.h: Add ioctl to request synchronous transfers.
-
-
-Tue Jul 26 21:36:58 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.37 released.
-
-	* aha1542.c: Always call aha1542_mbenable, use new udelay
-	mechanism so we do not wait a long time if the board does not
-	implement this command.
-
-	* g_NCR5380.c: Remove #include <linux/config.h> and #if
-	defined(CONFIG_SCSI_*).
-
-	* seagate.c: Likewise.
-
-	Next round of changes to support loadable modules.  Getting closer
-	now, still not possible to do anything remotely usable.
-
-	hosts.c: Create a linked list of detected high level devices.
-	(scsi_register_device): New function to insert into this list.
-	(scsi_init): Call scsi_register_device for each of the known high
-	level drivers.
-
-	hosts.h: Add prototype for linked list header.  Add structure
-	definition for device template structure which defines the linked
-	list.
-
-	scsi.c: (scan_scsis): Use linked list instead of knowledge about
-	existing high level device drivers.
-	(scsi_dev_init): Use init functions for drivers on linked list
-	instead of explicit list to initialize and attach devices to high
-	level drivers.
-
-	scsi.h: Add new field "attached" to scsi_device - count of number
-	of high level devices attached.
-
-	sd.c, sr.c, sg.c, st.c: Adjust init/attach functions to use new
-	scheme.
-
-Sat Jul 23 13:03:17 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.35 released.
-
-	* ultrastor.c: Change constraint on asm() operand so that it works
-	with gcc 2.6.0.
-
-Thu Jul 21 10:37:39 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.33 released.
-
-	* sr.c(sr_open): Do not allow opens with write access.
-
-Mon Jul 18 09:51:22 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.31 released.
-
-	* sd.c: Increase SD_TIMEOUT from 300 to 600.
-
-	* sr.c: Remove stray task_struct* variable that was no longer
-	used.
-
-	* sr_ioctl.c: Fix typo in up() call.
-
-Sun Jul 17 16:25:29 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.30 released.
-
-	* scsi.c (scan_scsis): Fix detection of some Toshiba CDROM drives
-	that report themselves as disk drives.
-
-	* (Throughout): Use request.sem instead of request.waiting.
-	Should fix swap problem with fdomain.
-
-Thu Jul 14 10:51:42 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.29 released.
-
-	* scsi.c (scan_scsis): Add new devices to end of linked list, not
-	to the beginning.
-
-	* scsi.h (SCSI_SLEEP): Remove brain dead hack to try to save
-	the task state before sleeping.
-
-Sat Jul  9 15:01:03 1994  Eric Youngdale  (eric@esp22)
-
-	More changes to eventually support loadable modules.  Mainly
-	we want to use linked lists instead of arrays because it is easier
-	to dynamically add and remove things this way.
-
-	Quite a bit more work is needed before loadable modules are
-	possible (and usable) with scsi, but this is most of the grunge
-	work.
-
-	* Linux 1.1.28 released.
-
-	* scsi.c, scsi.h (allocate_device, request_queueable): Change
-	argument from index into scsi_devices to a pointer to the
-	Scsi_Device struct.
-
-	* Throughout: Change all calls to allocate_device,
-	request_queueable to use new calling sequence.
-
-	* Throughout: Use SCpnt->device instead of
-	scsi_devices[SCpnt->index].  Ugh - the pointer was there all along
-	- much cleaner this way.
-
-	* scsi.c (scsi_init_malloc, scsi_free_malloc): New functions -
-	allow us to pretend that we have a working malloc when we
-	initialize.  Use this instead of passing memory_start, memory_end
-	around all over the place.
-
-	* scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use
-	scsi_init_malloc, remove all arguments, no return value.
-
-	* scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd
-	structs.
-
-	* scsi.c (scsi_dev_init): Set up for scsi_init_malloc.
-	(scan_scsis): Get SDpnt from scsi_init_malloc, and refresh
-	when we discover a device.  Free pointer before returning.
-	Change scsi_devices into a linked list.
-
-	* scsi.c (scan_scsis): Change to only scan one host.
-	(scsi_dev_init): Loop over all detected hosts, and scan them.
-
-	* hosts.c  (scsi_init_free): Change so that  number of extra bytes
-	is stored in struct, and we do not have to pass it each time.
-
-	* hosts.h: Change Scsi_Host_Template struct to include "next" and
-	"release" functions.  Initialize to NULL in all low level
-	adapters.
-
-	* hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked
-	list scsi_hosts, linked together with the new "next" field.
-
-Wed Jul  6 05:45:02 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.25 released.
-
-	* aha152x.c: Changes from Juergen - cleanups and updates.
-
-	* sd.c, sr.c: Use new check_media_change and revalidate
-	file_operations fields.
-
-	* st.c, st.h: Add changes from Kai Makisara, dated Jun 22.
-
-	* hosts.h: Change SG_ALL back to 0xff.  Apparently soft error
-	in /dev/brain resulted in having this bumped up.
-	Change first parameter in bios_param function to be Disk * instead
-	of index into rscsi_disks.
-
-	* sd_ioctl.c: Pass pointer to rscsi_disks element instead of index
-	to array.
-
-	* sd.h: Add struct name "scsi_disk" to typedef for Scsi_Disk.
-
-	* scsi.c: Remove redundant Maxtor XT8760S from blacklist.
-	In scsi_reset, add printk when DEBUG defined.
-
-	* All low level drivers: Modify definitions of bios_param in
-	appropriate way.
-
-Thu Jun 16 10:31:59 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.20 released.
-
-	* scsi_ioctl.c: Only pass down the actual number of characters
-	required to scsi_do_cmd, not the one rounded up to a even number
-	of sectors.
-
-	* ultrastor.c: Changes from Caleb Epstein for 24f cards.  Support
-	larger SG lists.
-
-	* ultrastor.c: Changes from me - use scsi_register to register
-	host.  Add some consistency checking,
-
-Wed Jun  1 21:12:13 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.19 released.
-
-	* scsi.h: Add new return code for reset() function:
-	SCSI_RESET_PUNT.
-
-	* scsi.c: Make SCSI_RESET_PUNT the same as SCSI_RESET_WAKEUP for
-	now.
-
-	* aha1542.c: If the command responsible for the reset is not
-	pending, return SCSI_RESET_PUNT.
-
-	* aha1740.c, buslogic.c, wd7000.c, ultrastor.c: Return
-	SCSI_RESET_PUNT instead of SCSI_RESET_SNOOZE.
-
-Tue May 31 19:36:01 1994  Eric Youngdale  (eric@esp22)
-
-	* buslogic.c: Do not print out message about "must be Adaptec"
-	if we have detected a buslogic card.  Print out a warning message
-	if we are configuring for >16Mb, since the 445S at board level
-	D or earlier does not work right.  The "D" level board can be made
-	to work by flipping an undocumented switch, but this is too subtle.
-
-    Changes based upon patches in Yggdrasil distribution.
-
-	* sg.c, sg.h: Return sense data to user.
-
-	* aha1542.c, aha1740.c, buslogic.c: Do not panic if
-	sense buffer is wrong size.
-
-	* hosts.c: Test for ultrastor card before any of the others.
-
-	* scsi.c: Allow boot-time option for max_scsi_luns=? so that
-	buggy firmware has an easy work-around.
-
-Sun May 15 20:24:34 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.15 released.
-
-	Post-codefreeze thaw...
-
-	* buslogic.[c,h]: New driver from David Gentzel.
-
-	* hosts.h: Add use_clustering field to explicitly say whether
-	clustering should be used for devices attached to this host
-	adapter.  The buslogic board apparently supports large SG lists,
-	but it is apparently faster if sd.c condenses this into a smaller
-	list.
-
-	* sd.c: Use this field instead of heuristic.
-
-	* All host adapter include files: Add appropriate initializer for
-	use_clustering field.
-
-	* scsi.h: Add #defines for return codes for the abort and reset
-	functions.  There are now a specific set of return codes to fully
-	specify all of the possible things that the low-level adapter
-	could do.
-
-	* scsi.c: Act based upon return codes from abort/reset functions.
-
-	* All host adapter abort/reset functions: Return new return code.
-
-	* Add code in scsi.c to help debug timeouts.  Use #define
-	DEBUG_TIMEOUT to enable this.
-
-	* scsi.c: If the host->irq field is set, use
-	disable_irq/enable_irq before calling queuecommand if we
-	are not already in an interrupt.  Reduce races, and we
-	can be sloppier about cli/sti in the interrupt routines now
-	(reduce interrupt latency).
-
-	* constants.c: Fix some things to eliminate warnings.  Add some
-	sense descriptions that were omitted before.
-
-	* aha1542.c: Watch for SCRD from host adapter - if we see it, set
-	a flag.  Currently we only print out the number of pending
-	commands that might need to be restarted.
-
-	* aha1542.c (aha1542_abort): Look for lost interrupts, OGMB still
-	full, and attempt to recover.  Otherwise give up.
-
-	* aha1542.c (aha1542_reset): Try BUS DEVICE RESET, and then pass
-	DID_RESET back up to the upper level code for all commands running
-	on this target (even on different LUNs).
-
-Sat May  7 14:54:01 1994
-
-	* Linux 1.1.12 released.
-
-	* st.c, st.h: New version from Kai.  Supports boot time
-	specification of number of buffers.
-
-	* wd7000.[c,h]: Updated driver from John Boyd.  Now supports
-	more than one wd7000 board in machine at one time, among other things.
-
-Wed Apr 20 22:20:35 1994
-
-	* Linux 1.1.8 released.
-
-	* sd.c: Add a few type casts where scsi_malloc is called.
-
-Wed Apr 13 12:53:29 1994
-
-	* Linux 1.1.4 released.
-
-	* scsi.c: Clean up a few printks (use %p to print pointers).
-
-Wed Apr 13 11:33:02 1994
-
-	* Linux 1.1.3 released.
-
-	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
-	better).
-
-Fri Apr  8 08:57:19 1994
-
-	* Linux 1.1.2 released.
-
-	* Throughout: SCSI portion of cluster diffs added.
-
-Tue Apr  5 07:41:50 1994
-
-	* Linux 1.1 development tree initiated.
-
-	* The linux 1.0 development tree is now effectively frozen except
-	for obvious bugfixes.
-
-******************************************************************
-******************************************************************
-******************************************************************
-******************************************************************
-
-Sun Apr 17 00:17:39 1994
-
-	* Linux 1.0, patchlevel 9 released.
-
-	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
-	better).
-
-Thu Apr  7 08:36:20 1994
-
-	* Linux 1.0, patchlevel8 released.
-
-	* fdomain.c: Update to version 5.15 from 5.9.  Handles 3.4 bios.
-
-Sun Apr  3 14:43:03 1994
-
-	* Linux 1.0, patchlevel6 released.
-
-	* wd7000.c: Make stab at fixing race condition.
-
-Sat Mar 26 14:14:50 1994
-
-	* Linux 1.0, patchlevel5 released.
-
-	* aha152x.c, Makefile: Fix a few bugs (too much data message).
-	Add a few more bios signatures. (Patches from Juergen).
-
-	* aha1542.c: Fix race condition in aha1542_out.
-
-Mon Mar 21 16:36:20 1994
-
-	* Linux 1.0, patchlevel3 released.
-
-	* sd.c, st.c, sr.c, sg.c: Return -ENXIO, not -ENODEV if we attempt
-	to open a non-existent device.
-
-	* scsi.c: Add Chinon cdrom to blacklist.
-
-	* sr_ioctl.c: Check return status of verify_area.
-
-Sat Mar  6 16:06:19 1994
-
-	* Linux 1.0 released (technically a pre-release).
-
-	* scsi.c: Add IMS CDD521, Maxtor XT-8760S to blacklist.
-
-Tue Feb 15 10:58:20 1994
-
-        * pl15e released.
-
-        * aha1542.c: For 1542C, allow dynamic device scan with >1Gb turned
-	off.
-
-	* constants.c: Fix typo in definition of CONSTANTS.
-
-        * pl15d released.
-
-Fri Feb 11 10:10:16 1994
-
-        * pl15c released.
-
-	* scsi.c: Add Maxtor XT-3280 and Rodime RO3000S to blacklist.
-
-	* scsi.c: Allow tagged queueing for scsi 3 devices as well.
-	Some really old devices report a version number of 0.  Disallow
-	LUN != 0 for these.
-
-Thu Feb 10 09:48:57 1994
-
-        * pl15b released.
-
-Sun Feb  6 12:19:46 1994
-
-        * pl15a released.
-
-Fri Feb  4 09:02:17 1994
-
-        * scsi.c: Add Teac cdrom to blacklist.
-
-Thu Feb  3 14:16:43 1994
-
-	* pl15 released.
-
-Tue Feb  1 15:47:43 1994
-
-	* pl14w released.
-
-	* wd7000.c (wd_bases): Fix typo in last change.
-
-Mon Jan 24 17:37:23 1994
-
-	* pl14u released.
-
-	* aha1542.c: Support 1542CF/extended bios.  Different from 1542C
-
-	* wd7000.c: Allow bios at 0xd8000 as well.
-
-	* ultrastor.c: Do not truncate cylinders to 1024.
-
-	* fdomain.c: Update to version 5.9 (add new bios signature).
-
-	* NCR5380.c: Update from Drew - should work a lot better now.
-
-Sat Jan  8 15:13:10 1994
-
-	* pl14o released.
-
-	* sr_ioctl.c: Zero reserved field before trying to set audio volume.
-
-Wed Jan  5 13:21:10 1994
-
-	* pl14m released.
-
-	* fdomain.c: Update to version 5.8.  No functional difference???
-
-Tue Jan  4 14:26:13 1994
-
-	* pl14l released.
-
-	* ultrastor.c: Remove outl, inl functions (now provided elsewhere).
-
-Mon Jan  3 12:27:25 1994
-
-	* pl14k released.
-
-	* aha152x.c: Remove insw and outsw functions.
-
-	* fdomain.c: Ditto.
-
-Wed Dec 29 09:47:20 1993
-
-	* pl14i released.
-
-	* scsi.c: Support RECOVERED_ERROR for tape drives.
-
-	* st.c: Update of tape driver from Kai.
-
-Tue Dec 21 09:18:30 1993
-
-	* pl14g released.
-
-	* aha1542.[c,h]: Support extended BIOS stuff.
-
-	* scsi.c: Clean up messages about disks, so they are displayed as
-	sda, sdb, etc instead of sd0, sd1, etc.
-
-	* sr.c:  Force reread of capacity if disk was changed.
-	Clear buffer before asking for capacity/sectorsize (some drives
-	do not report this properly).  Set needs_sector_size flag if
-	drive did not return sensible sector size.
-
-Mon Dec 13 12:13:47 1993
-
-	* aha152x.c: Update to version .101 from Juergen.
-
-Mon Nov 29 03:03:00 1993
-
-        * linux 0.99.14 released.
-
-	* All scsi stuff moved from kernel/blk_drv/scsi to drivers/scsi.
-
-	* Throughout: Grammatical corrections to various comments.
-
-	* Makefile: fix so that we do not need to compile things we are
-	not going to use.
-
-	* NCR5380.c, NCR5380.h, g_NCR5380.c, g_NCR5380.h, pas16.c,
-	pas16.h, t128.c, t128.h:  New files from Drew.
-
-	* aha152x.c, aha152x.h: New files from Juergen Fischer.
-
-	* aha1542.c: Support for more than one 1542 in the machine
-	at the same time.  Make functions static that do not need
-	visibility.
-
-	* aha1740.c: Set NEEDS_JUMPSTART flag in reset function, so we
-	know to restart the command.  Change prototype of aha1740_reset
-	to take a command pointer.
-
-	* constants.c: Clean up a few things.
-
-	* fdomain.c: Update to version 5.6.  Move snarf_region.  Allow
-	board to be set at different SCSI ids.  Remove support for
-	reselection (did not work well).  Set JUMPSTART flag in reset
-	code.
-
-	* hosts.c: Support new low-level adapters.  Allow for more than
-	one adapter of a given type.
-
-	* hosts.h: Allow for more than one adapter of a given type.
-
-	* scsi.c:  Add scsi_device_types array, if NEEDS_JUMPSTART is set
-	after a low-level reset, start the command again.  Sort blacklist,
-	and add Maxtor MXT-1240S, XT-4170S, NEC CDROM 84, Seagate ST157N.
-
-	* scsi.h: Add constants for tagged queueing.
-
-	* Throughout: Use constants from major.h instead of hardcoded
-	numbers for major numbers.
-
-	* scsi_ioctl.c: Fix bug in buffer length in ioctl_command.  Use
-	verify_area in GET_IDLUN ioctl.  Add new ioctls for
-	TAGGED_QUEUE_ENABLE, DISABLE.  Only allow IOCTL_SEND_COMMAND by
-	superuser.
-
-	* sd.c: Only pay attention to UNIT_ATTENTION for removable disks.
-	Fix bug where sometimes portions of blocks would get lost
-	resulting in processes hanging.  Add messages when we spin up a
-	disk, and fix a bug in the timing.  Increase read-ahead for disks
-	that are on a scatter-gather capable host adapter.
-
-	* seagate.c: Fix so that some parameters can be set from the lilo
-	prompt.  Supply jumpstart flag if we are resetting and need the
-	command restarted.   Fix so that we return 1 if we detect a card
-	so that multiple card detection works correctly.  Add yet another
-	signature for FD cards (950).  Add another signature for ST0x.
-
-	* sg.c, sg.h: New files from Lawrence Foard for generic scsi
-	access.
-
-	* sr.c:  Add type casts for (void*) so that we can do pointer
-	arithmetic.  Works with GCC without this, but it is not strictly
-	correct.  Same bugfix as was in sd.c.  Increase read-ahead a la
-	disk driver.
-
-	* sr_ioctl.c: Use scsi_malloc buffer instead of buffer from stack
-	since we cannot guarantee that the stack is < 16Mb.
-
-	ultrastor.c: Update to support 24f properly (JFC's driver).
-
-	wd7000.c: Supply jumpstart flag for reset.  Do not round up
-	number of cylinders in biosparam function.
-
-Sat Sep  4 20:49:56 1993
-
-    * 0.99pl13 released.
-
-    * Throughout:  Use check_region/snarf_region for all low-level
-    drivers.
-
-    * aha1542.c: Do hard reset instead of soft (some ethercard probes
-    screw us up).
-
-    * scsi.c: Add new flag ASKED_FOR_SENSE so that we can tell if we are
-    in a loop whereby the device returns null sense data.
-
-    * sd.c: Add code to spin up a drive if it is not already spinning.
-    Do this one at a time to make it easier on power supplies.
-
-    * sd_ioctl.c: Use sync_dev instead of fsync_dev in BLKFLSBUF ioctl.
-
-    * seagate.c: Switch around DATA/CONTROL lines.
-
-    * st.c: Change sense to unsigned.
-
-Thu Aug  5 11:59:18 1993
-
-    * 0.99pl12 released.
-
-    * constants.c, constants.h: New files with ascii descriptions of
-    various conditions.
-
-    * Makefile: Do not try to count the number of low-level drivers,
-    just generate the list of .o files.
-
-    * aha1542.c: Replace 16 with sizeof(SCpnt->sense_buffer).  Add tests
-    for addresses > 16Mb, panic if we find one.
-
-    * aha1740.c: Ditto with sizeof().
-
-    * fdomain.c: Update to version 3.18.  Add new signature, register IRQ
-    with irqaction.  Use ID 7 for new board.  Be more intelligent about
-    obtaining the h/s/c numbers for biosparam.
-
-    * hosts.c: Do not depend upon Makefile generated count of the number
-    of low-level host adapters.
-
-    * scsi.c: Use array for scsi_command_size instead of a function.  Add
-    Texel cdrom and Maxtor XT-4380S to blacklist.  Allow compile time
-    option for no-multi lun scan.  Add semaphore for possible problems
-    with handshaking, assume device is faulty until we know it not to be
-    the case.  Add DEBUG_INIT symbol to dump info as we scan for devices.
-    Zero sense buffer so we can tell if we need to request it.  When
-    examining sense information, request sense if buffer is all zero.
-    If RESET, request sense information to see what to do next.
-
-    * scsi_debug.c: Change some constants to use symbols like INT_MAX.
-
-    * scsi_ioctl.c (kernel_scsi_ioctl): New function -for making ioctl
-    calls from kernel space.
-
-    * sd.c: Increase timeout to 300.  Use functions in constants.h to
-    display info.  Use scsi_malloc buffer for READ_CAPACITY, since
-    we cannot guarantee that a stack based buffer is < 16Mb.
-
-    * sd_ioctl.c: Add BLKFLSBUF ioctl.
-
-    * seagate.c: Add new compile time options for ARBITRATE,
-    SLOW_HANDSHAKE, and SLOW_RATE.  Update assembly loops for transferring
-    data.  Use kernel_scsi_ioctl to request mode page with geometry.
-
-    * sr.c: Use functions in constants.c to display messages.
-
-    * st.c: Support for variable block size.
-
-    * ultrastor.c: Do not use cache for tape drives.  Set
-    unchecked_isa_dma flag, even though this may not be needed (gets set
-    later).
-
-Sat Jul 17 18:32:44 1993
-
-    * 0.99pl11 released.  C++ compilable.
-
-    * Throughout: Add type casts all over the place, and use "ip" instead
-    of "info" in the various biosparam functions.
-
-    * Makefile: Compile seagate.c with C++ compiler.
-
-    * aha1542.c: Always set ccb pointer as this gets trashed somehow on
-    some systems.  Add a few type casts.  Update biosparam function a little.
-
-    * aha1740.c: Add a few type casts.
-
-    * fdomain.c: Update to version 3.17 from 3.6.  Now works with
-    TMC-18C50.
-
-    * scsi.c: Minor changes here and there with datatypes.  Save use_sg
-    when requesting sense information so that this can properly be
-    restored if we retry the command.  Set aside dma buffers assuming each
-    block is 1 page, not 1Kb minix block.
-
-    * scsi_ioctl.c: Add a few type casts.  Other minor changes.
-
-    * sd.c:  Correctly  free all scsi_malloc'd memory if we run out of
-    dma_pool. Store blocksize information for each partition.
-
-    * seagate.c: Minor cleanups here and there.
-
-    * sr.c: Set up blocksize array for all discs.  Fix bug in freeing
-    buffers if we run out of dma pool.
-
-Thu Jun  2 17:58:11 1993
-
-    * 0.99pl10 released.
-
-    * aha1542.c: Support for BT 445S (VL-bus board with no dma channel).
-
-    * fdomain.c: Upgrade to version 3.6. Preliminary support for TNC-18C50.
-
-    * scsi.c: First attempt to fix problem with old_use_sg.  Change
-    NOT_READY to a SUGGEST_ABORT.  Fix timeout race where time might
-    get decremented past zero.
-
-    * sd.c: Add block_fsync function to dispatch table.
-
-    * sr.c: Increase timeout to 500 from 250.  Add entry for sync in
-    dispatch table (supply NULL).  If we do not have a sectorsize,
-    try to get it in the sd_open function.  Add new function just to
-    obtain sectorsize.
-
-    * sr.h: Add needs_sector_size semaphore.
-
-    * st.c: Add NULL for fsync in dispatch table.
-
-    * wd7000.c: Allow another condition for power on that are normal
-    and do not require a panic.
-
-Thu Apr 22 23:10:11 1993
-
-    * 0.99pl9 released.
-
-    * aha1542.c: Use (void) instead of () in setup_mailboxes.
-
-    * scsi.c: Initialize transfersize and underflow fields in SCmd to 0.
-    Do not panic for unsupported message bytes.
-
-    * scsi.h: Allocate 12 bytes instead of 10 for commands.  Add
-    transfersize and underflow fields.
-
-    * scsi_ioctl.c: Further bugfix to ioctl_probe.
-
-    * sd.c: Use long instead of int for last parameter in sd_ioctl.
-    Initialize transfersize and underflow fields.
-
-    * sd_ioctl.c: Ditto for sd_ioctl(,,,,);
-
-    * seagate.c: New version from Drew.  Includes new signatures for FD
-    cards.  Support for 0ws jumper. Correctly initialize
-    scsi_hosts[hostnum].this_id.  Improved handing of
-    disconnect/reconnect, and support command linking.  Use
-    transfersize and underflow fields.  Support scatter-gather.
-
-    * sr.c, sr_ioctl.c: Use long instead of int for last parameter in sr_ioctl.
-    Use buffer and buflength in do_ioctl.  Patches from Chris Newbold for
-    scsi-2 audio commands.
-
-    * ultrastor.c: Comment out in_byte (compiler warning).
-
-    * wd7000.c: Change () to (void) in wd7000_enable_dma.
-
-Wed Mar 31 16:36:25 1993
-
-    * 0.99pl8 released.
-
-    * aha1542.c: Handle mailboxes better for 1542C.
-        Do not truncate number of cylinders at 1024 for biosparam call.
-
-    * aha1740.c: Fix a few minor bugs for multiple devices.
-        Same as above for biosparam.
-
-    * scsi.c: Add lockable semaphore for removable devices that can have
-    media removal prevented.  Add another signature for flopticals.
-    (allocate_device): Fix race condition.  Allow more space in dma pool
-    for blocksizes of up to 4Kb.
-
-    * scsi.h: Define COMMAND_SIZE.  Define a SCSI specific version of
-    INIT_REQUEST that can run with interrupts off.
-
-    * scsi_ioctl.c: Make ioctl_probe function more idiot-proof.  If
-    a removable device says ILLEGAL REQUEST to a door-locking command,
-    clear lockable flag.  Add SCSI_IOCTL_GET_IDLUN ioctl.  Do not attempt
-    to lock door for devices that do not have lockable semaphore set.
-
-    * sd.c: Fix race condition for multiple disks.  Use INIT_SCSI_REQUEST
-    instead of INIT_REQUEST.  Allow sector sizes of 1024 and 256.  For
-    removable disks that are not ready, mark them as having a media change
-    (some drives do not report this later).
-
-    * seagate.c: Use volatile keyword for memory-mapped register pointers.
-
-    * sr.c: Fix race condition, a la sd.c.  Increase the number of retries
-    to 1.  Use INIT_SCSI_REQUEST.  Allow 512 byte sector sizes.  Do a
-    read_capacity when we init the device so we know the size and
-    sectorsize.
-
-    * st.c: If ioctl not found in st.c, try scsi_ioctl for others.
-
-    * ultrastor.c: Do not truncate number of cylinders at 1024 for
-    biosparam call.
-
-    * wd7000.c: Ditto.
-    Throughout: Use COMMAND_SIZE macro to determine length of scsi
-    command.
-
-
-
-Sat Mar 13 17:31:29 1993
-
-    * 0.99pl7 released.
-
-    Throughout: Improve punctuation in some messages, and use new
-    verify_area syntax.
-
-    * aha1542.c: Handle unexpected interrupts better.
-
-    * scsi.c: Ditto.  Handle reset conditions a bit better, asking for
-    sense information and retrying if required.
-
-    * scsi_ioctl.c: Allow for 12 byte scsi commands.
-
-    * ultrastor.c: Update to use scatter-gather.
-
-Sat Feb 20 17:57:15 1993
-
-    * 0.99pl6 released.
-
-    * fdomain.c: Update to version 3.5.  Handle spurious interrupts
-    better.
-
-    * sd.c: Use register_blkdev function.
-
-    * sr.c: Ditto.
-
-    * st.c: Use register_chrdev function.
-
-    * wd7000.c: Undo previous change.
-
-Sat Feb  6 11:20:43 1993
-
-    * 0.99pl5 released.
-
-    * scsi.c: Fix bug in testing for UNIT_ATTENTION.
-
-    * wd7000.c: Check at more addresses for bios.  Fix bug in biosparam
-    (heads & sectors turned around).
-
-Wed Jan 20 18:13:59 1993
-
-    * 0.99pl4 released.
-
-    * scsi.c: Ignore leading spaces when looking for blacklisted devices.
-
-    * seagate.c: Add a few new signatures for FD cards.  Another patch
-    with SCint to fix race condition.  Use recursion_depth to keep track
-    of how many times we have been recursively called, and do not start
-    another command unless we are on the outer level.  Fixes bug
-    with Syquest cartridge drives (used to crash kernel), because
-    they do not disconnect with large data transfers.
-
-Tue Jan 12 14:33:36 1993
-
-    * 0.99pl3 released.
-
-    * fdomain.c: Update to version 3.3 (a few new signatures).
-
-    * scsi.c: Add CDU-541, Denon DRD-25X to blacklist.
-    (allocate_request, request_queueable): Init request.waiting to NULL if
-    non-buffer type of request.
-
-    * seagate.c:  Allow controller to be overridden with CONTROLLER symbol.
-    Set SCint=NULL when we are done, to remove race condition.
-
-    * st.c: Changes from Kai.
-
-Wed Dec 30 20:03:47 1992
-
-    * 0.99pl2 released.
-
-    * scsi.c: Blacklist back in.  Remove Newbury drive as other bugfix
-    eliminates need for it here.
-
-    * sd.c: Return ENODEV instead of EACCES if no such device available.
-    (sd_init) Init blkdev_fops earlier so that sd_open is available sooner.
-
-    * sr.c: Same as above for sd.c.
-
-    * st.c: Return ENODEV instead of ENXIO if no device.  Init chrdev_fops
-    sooner, so that it is always there even if no tapes.
-
-    * seagate.c (controller_type): New variable to keep track of ST0x or
-    FD.  Modify signatures list to indicate controller type, and init
-    controller_type once we find a match.
-
-    * wd7000.c (wd7000_set_sync): Remove redundant function.
-
-Sun Dec 20 16:26:24 1992
-
-    * 0.99pl1 released.
-
-    * scsi_ioctl.c: Bugfix - check dev->index, not dev->id against
-    NR_SCSI_DEVICES.
-
-    * sr_ioctl.c: Verify that device exists before allowing an ioctl.
-
-    * st.c: Patches from Kai - change timeout values, improve end of tape
-    handling.
-
-Sun Dec 13 18:15:23 1992
-
-    * 0.99 kernel released.  Baseline for this ChangeLog.
diff --git a/Documentation/scsi/Mylex.txt b/Documentation/scsi/Mylex.txt
deleted file mode 100644
index 3797f3e..0000000
--- a/Documentation/scsi/Mylex.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Please see the file README.BusLogic for information about Linux support for
-Mylex (formerly BusLogic) MultiMaster and FlashPoint SCSI Host Adapters.
-
-The Mylex DAC960 PCI RAID Controllers are now supported.  Please consult
-http://sourceforge.net/projects/dandelion for further information on the DAC960 driver.
diff --git a/Documentation/scsi/scsi-parameters.txt b/Documentation/scsi/scsi-parameters.txt
index 453d4b7..25a4b4c 100644
--- a/Documentation/scsi/scsi-parameters.txt
+++ b/Documentation/scsi/scsi-parameters.txt
@@ -34,11 +34,6 @@
 			See drivers/scsi/BusLogic.c, comment before function
 			BusLogic_ParseDriverOptions().
 
-	eata=		[HW,SCSI]
-
-	fdomain=	[HW,SCSI]
-			See header of drivers/scsi/fdomain.c.
-
 	gdth=		[HW,SCSI]
 			See header of drivers/scsi/gdth.c.
 
@@ -70,8 +65,6 @@
 	ncr53c400a=	[HW,SCSI]
 			See Documentation/scsi/g_NCR5380.txt.
 
-	ncr53c406a=	[HW,SCSI]
-
 	ncr53c8xx=	[HW,SCSI]
 
 	osst=		[HW,SCSI] SCSI Tape Driver
@@ -110,12 +103,5 @@
 	st=		[HW,SCSI] SCSI tape parameters (buffers, etc.)
 			See Documentation/scsi/st.txt.
 
-	sym53c416=	[HW,SCSI]
-			See header of drivers/scsi/sym53c416.c.
-
-	tmscsim=	[HW,SCSI]
-			See comment before function dc390_setup() in
-			drivers/scsi/tmscsim.c.
-
 	wd33c93=	[HW,SCSI]
 			See header of drivers/scsi/wd33c93.c.
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index 2c31d9e..177c031 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -114,9 +114,7 @@
 "static int xxx_slave_alloc(struct scsi_device * sdev) { /* code */ }"
 
 ** the scsi_host_alloc() function is a replacement for the rather vaguely
-named scsi_register() function in most situations. The scsi_register()
-and scsi_unregister() functions remain to support legacy LLDs that use
-the passive initialization model.
+named scsi_register() function in most situations.
 
 
 Hotplug initialization model
@@ -228,79 +226,6 @@
 struct scsi_device instances are freed after slave_destroy().
 
 
-Passive initialization model
-============================
-These older LLDs include a file called "scsi_module.c" [yes the ".c" is a
-little surprising] in their source code. For that file to work an
-instance of struct scsi_host_template with the name "driver_template"
-needs to be defined. Here is a typical code sequence used in this model:
-    static struct scsi_host_template driver_template = {
-        ...
-    };
-    #include "scsi_module.c"
-
-The scsi_module.c file contains two functions:
-  - init_this_scsi_driver() which is executed when the LLD is
-    initialized (i.e. boot time or module load time)
-  - exit_this_scsi_driver() which is executed when the LLD is shut
-    down (i.e. module unload time)
-Note: since these functions are tagged with __init and __exit qualifiers
-an LLD should not call them explicitly (since the kernel does that).
-
-Here is an example of an initialization sequence when two hosts are
-detected (so detect() returns 2) and the SCSI bus scan on each host
-finds 1 SCSI device (and a second device does not respond).
-
-LLD                      mid level                 LLD
-===----------------------=========-----------------===------
-init_this_scsi_driver() ----+
-                            |
-                         detect()  -----------------+
-                            |                       |
-                            |                scsi_register()
-                            |                scsi_register()
-                            |
-                      slave_alloc()
-                      slave_configure()  -->  scsi_change_queue_depth()
-                      slave_alloc()   ***
-                      slave_destroy() ***
-                            |
-                      slave_alloc()
-                      slave_configure()
-                      slave_alloc()   ***
-                      slave_destroy() ***
-------------------------------------------------------------
-
-The mid level invokes scsi_change_queue_depth() with "cmd_per_lun" for that
-host as the queue length. These settings can be overridden by a
-slave_configure() supplied by the LLD.
-
-*** For scsi devices that the mid level tries to scan but do not
-    respond, a slave_alloc(), slave_destroy() pair is called.
-
-Here is an LLD shutdown sequence:
-
-LLD                      mid level                 LLD
-===----------------------=========-----------------===------
-exit_this_scsi_driver() ----+
-                            |
-                     slave_destroy()
-                        release()   -->   scsi_unregister()
-                            |
-                     slave_destroy()
-                        release()   -->   scsi_unregister()
-------------------------------------------------------------
-
-An LLD need not define slave_destroy() (i.e. it is optional). 
-
-The shortcoming of the "passive initialization model" is that host
-registration and de-registration are (typically) tied to LLD initialization
-and shutdown. Once the LLD is initialized then a new host that appears
-(e.g. via hotplugging) cannot easily be added without a redundant
-driver shutdown and re-initialization. It may be possible to write an LLD
-that uses both initialization models.
-
-
 Reference Counting
 ==================
 The Scsi_Host structure has had reference counting infrastructure added.
@@ -738,7 +663,6 @@
 
 Summary:
    bios_param - fetch head, sector, cylinder info for a disk
-   detect - detects HBAs this driver wants to control
    eh_timed_out - notify the host that a command timer expired
    eh_abort_handler - abort given command
    eh_bus_reset_handler - issue SCSI bus reset
@@ -748,7 +672,6 @@
    ioctl - driver can respond to ioctls
    proc_info - supports /proc/scsi/{driver_name}/{host_no}
    queuecommand - queue scsi command, invoke 'done' on completion
-   release - release all resources associated with given host
    slave_alloc - prior to any commands being sent to a new device 
    slave_configure - driver fine tuning for given device after attach
    slave_destroy - given device is about to be shut down
@@ -785,28 +708,6 @@
 
 
 /**
- *      detect - detects HBAs this driver wants to control
- *      @shtp: host template for this driver.
- *
- *      Returns number of hosts this driver wants to control. 0 means no
- *      suitable hosts found.
- *
- *      Locks: none held
- *
- *      Calling context: process [invoked from init_this_scsi_driver()]
- *
- *      Notes: First function called from the SCSI mid level on this
- *      driver. Upper level drivers (e.g. sd) may not (yet) be present.
- *      For each host found, this method should call scsi_register() 
- *      [see hosts.c].
- *
- *      Defined in: LLD (required if "passive initialization mode" is used,
- *                       not invoked in "hotplug initialization mode")
- **/
-    int detect(struct scsi_host_template * shtp)
-
-
-/**
  *      eh_timed_out - The timer for the command has just fired
  *      @scp: identifies command timing out
  *
@@ -1074,27 +975,6 @@
 
 
 /**
- *      release - release all resources associated with given host
- *      @shp: host to be released.
- *
- *      Return value ignored (could soon be a function returning void).
- *
- *      Locks: none held
- *
- *      Calling context: process
- *
- *      Notes: Invoked from scsi_module.c's exit_this_scsi_driver().
- *      LLD's implementation of this function should call 
- *      scsi_unregister(shp) prior to returning.
- *      Only needed for old-style host templates.
- *
- *      Defined in: LLD (required in "passive initialization model",
- *                       should not be defined in hotplug model)
- **/
-    int release(struct Scsi_Host * shp)
-
-
-/**
  *      slave_alloc -   prior to any commands being sent to a new device 
  *                      (i.e. just prior to scan) this call is made
  *      @sdp: pointer to new device (about to be scanned)
diff --git a/Documentation/scsi/sd-parameters.txt b/Documentation/scsi/sd-parameters.txt
new file mode 100644
index 0000000..8e5af00
--- /dev/null
+++ b/Documentation/scsi/sd-parameters.txt
@@ -0,0 +1,22 @@
+Linux SCSI Disk Driver (sd) Parameters
+======================================
+
+cache_type (RW)
+---------------
+Enable/disable drive write & read cache.
+
+ cache_type string          | WCE RCD | Write cache | Read cache
+----------------------------+---------+-------------+------------
+ write through              | 0   0   | off         | on
+ none                       | 0   1   | off         | off
+ write back                 | 1   0   | on          | on
+ write back, no read (daft) | 1   1   | on          | off
+
+To set cache type to "write back" and save this setting to the drive:
+
+  # echo "write back" > cache_type
+
+To modify the caching mode without making the change persistent, prepend
+"temporary " to the cache type string. E.g.:
+
+  # echo "temporary write back" > cache_type
diff --git a/Documentation/scsi/tmscsim.txt b/Documentation/scsi/tmscsim.txt
deleted file mode 100644
index 0e0322b..0000000
--- a/Documentation/scsi/tmscsim.txt
+++ /dev/null
@@ -1,443 +0,0 @@
-The tmscsim driver
-==================
-
-1. Purpose and history
-2. Installation
-3. Features
-4. Configuration via /proc/scsi/tmscsim/?
-5. Configuration via boot/module params
-6. Potential improvements
-7. Bug reports, debugging and updates
-8. Acknowledgements
-9. Copyright
-
-
-1. Purpose and history
-----------------------
-The tmscsim driver supports PCI SCSI Host Adapters based on the AM53C974
-chip. AM53C974 based SCSI adapters include: 
- Tekram DC390, DC390T
- Dawicontrol 2974
- QLogic Fast! PCI Basic
- some on-board adapters
-(This is most probably not a complete list)
-
-It has originally written by C.L. Huang from the Tekram corp. to support the
-Tekram DC390(T) adapter. This is where the name comes from: tm = Tekram
-scsi = SCSI driver, m = AMD (?) as opposed to w for the DC390W/U/F
-(NCR53c8X5, X=2/7) driver. Yes, there was also a driver for the latter,
-tmscsiw, which supported DC390W/U/F adapters. It's not maintained any more,
-as the ncr53c8xx is perfectly supporting these adapters since some time.
-
-The driver first appeared in April 1996, exclusively supported the DC390 
-and has been enhanced since then in various steps. In May 1998 support for 
-general AM53C974 based adapters and some possibilities to configure it were
-added. The non-DC390 support works by assuming some values for the data
-normally taken from the DC390 EEPROM. See below (chapter 5) for details.
-
-When using the DC390, the configuration is still be done using the DC390
-BIOS setup. The DC390 EEPROM is read and used by the driver, any boot or
-module parameters (chapter 5) are ignored! However, you can change settings
-dynamically, as described in chapter 4. 
-
-For a more detailed description of the driver's history, see the first lines
-of tmscsim.c.
-The numbering scheme isn't consistent. The first versions went from 1.00 to
-1.12, then 1.20a to 1.20t. Finally I decided to use the ncr53c8xx scheme. So
-the next revisions will be 2.0a to 2.0X (stable), 2.1a to 2.1X (experimental),
-2.2a to 2.2X (stable, again) etc. (X = anything between a and z.) If I send
-fixes to people for testing, I create intermediate versions with a digit 
-appended, e.g. 2.0c3.
-
-
-2. Installation
----------------
-If you got any recent kernel with this driver and document included in
-linux/drivers/scsi, you basically have to do nothing special to use this
-driver. Of course you have to choose to compile SCSI support and DC390(T)
-support into your kernel or as module when configuring your kernel for
-compiling.
-NEW: You may as well compile this module outside your kernel, using the
-supplied Makefile.
-
- If you got an old kernel (pre 2.1.127, pre 2.0.37p1) with an old version of
- this driver: Get dc390-21125-20b.diff.gz or dc390-2036p21-20b1.diff.gz from
- my web page and apply the patch. Apply further patches to upgrade to the 
- latest version of the driver.
-
- If you want to do it manually, you should copy the files (dc390.h,
- tmscsim.h, tmscsim.c, scsiiom.c and README.tmscsim) from this directory to
- linux/drivers/scsi. You have to recompile your kernel/module of course.
-
- You should apply the three patches included in dc390-120-kernel.diff
- (Applying them: cd /usr/src; patch -p0 <~/dc390-120-kernel.diff)
- The patches are against 2.1.125, so you might have to manually resolve
- rejections when applying to another kernel version.
-
- The patches will update the kernel startup code to allow boot parameters to
- be passed to the driver, update the Documentation and finally offer you the
- possibility to omit the non-DC390 parts of the driver.
- (By selecting "Omit support for non DC390" you basically disable the
- emulation of a DC390 EEPROM for non DC390 adapters. This saves a few bytes
- of memory.)
-
-If you got a very old kernel without the tmscsim driver (pre 2.0.31)
-I recommend upgrading your kernel. However, if you don't want to, please
-contact me to get the appropriate patches.
-
-
-Upgrading a SCSI driver is always a delicate thing to do. The 2.0 driver has
-proven stable on many systems, but it's still a good idea to take some
-precautions. In an ideal world you would have a full backup of your disks.
-The world isn't ideal and most people don't have full backups (me neither).
-So take at least the following measures:
-* make your kernel remount the FS read-only on detecting an error:
-  tune2fs -e remount-ro /dev/sd??
-* have copies of your SCSI disk's partition tables on some safe location:
-  dd if=/dev/sda of=/mnt/floppy/sda bs=512 count=1
-  or just print it with:
-  fdisk -l | lpr
-* make sure you are able to boot Linux (e.g. from floppy disk using InitRD)
-  if your SCSI disk gets corrupted. You can use 
-  ftp://student.physik.uni-dortmund.de/pub/linux/kernel/bootdisk.gz
-
-One more warning: I used to overclock my PCI bus to 41.67 MHz. My Tekram
-DC390F (Sym53c875) accepted this as well as my Millennium. But the Am53C974
-produced errors and started to corrupt my disks. So don't do that! A 37.50
-MHz PCI bus works for me, though, but I don't recommend using higher clocks
-than the 33.33 MHz being in the PCI spec.
-
-
-3.Features
-----------
-- SCSI
- * Tagged command queueing
- * Sync speed up to 10 MHz
- * Disconnection
- * Multiple LUNs
-
-- General / Linux interface
- * Support for up to 4 AM53C974 adapters.
- * DC390 EEPROM usage or boot/module params
- * Information via cat /proc/scsi/tmscsim/?
- * Dynamically configurable by writing to /proc/scsi/tmscsim/?
- * Dynamic allocation of resources
- * SMP support: Locking on io_request lock (Linux 2.1/2.2) or adapter 
-    specific locks (Linux 2.5?)
- * Uniform source code for Linux-2.x.y
- * Support for dyn. addition/removal of devices via add/remove-single-device
-   (Try: echo "scsi add-single-device C B T U" >/proc/scsi/scsi 
-    C = Controller, B = Bus, T = Target SCSI ID, U = Unit SCSI LUN.) 
-    Use with care!
- * Try to use the partition table for the determination of the mapping
-
-
-4. Configuration via /proc/scsi/tmscsim/?
------------------------------------------
-First of all look at the output of /proc/scsi/tmscsim/? by typing
- cat /proc/scsi/tmscsim/?
-The "?" should be replaced by the SCSI host number. (The shell might do this
-for you.)
-You will see some info regarding the adapter and, at the end, a listing of
-the attached devices and their settings.
-
-Here's an example:
-garloff@kurt:/home/garloff > cat /proc/scsi/tmscsim/0
-Tekram DC390/AM53C974 PCI SCSI Host Adapter, Driver Version 2.0e7 2000-11-28
-SCSI Host Nr 1, AM53C974 Adapter Nr 0
-IOPortBase 0xb000, IRQ 10
-MaxID 8, MaxLUN 8, AdapterID 6, SelTimeout 250 ms, DelayReset 1 s
-TagMaxNum 16, Status 0x00, ACBFlag 0x00, GlitchEater 24 ns
-Statistics: Cmnds 1470165, Cmnds not sent directly 0, Out of SRB conds 0
-            Lost arbitrations 587,  Sel. connected 0, Connected: No
-Nr of attached devices: 4, Nr of DCBs: 4
-Map of attached LUNs: 01 00 00 03 01 00 00 00
-Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs MaxCmd
-00  00  00  Yes  Yes  Yes  Yes  Yes   100 ns    10.0 M      15      16
-01  03  00  Yes  Yes  Yes  Yes  No    100 ns    10.0 M      15      01
-02  03  01  Yes  Yes  Yes  Yes  No    100 ns    10.0 M      15      01
-03  04  00  Yes  Yes  Yes  Yes  No    100 ns    10.0 M      15      01
-
-Note that the settings MaxID and MaxLUN are not zero- but one-based, which
-means that a setting MaxLUN=4, will result in the support of LUNs 0..3. This
-is somehow inconvenient, but the way the mid-level SCSI code expects it to be.
-
-ACB and DCB are acronyms for Adapter Control Block and Device Control Block.
-These are data structures of the driver containing information about the
-adapter and the connected SCSI devices respectively.
-
-Idx is the device index (just a consecutive number for the driver), ID and
-LUN are the SCSI ID and LUN, Prty means Parity checking, Sync synchronous
-negotiation, DsCn Disconnection, SndS Send Start command on startup (not
-used by the driver) and TagQ Tagged Command Queueing. NegoPeriod and
-SyncSpeed are somehow redundant, because they are reciprocal values 
-(1 / 112 ns = 8.9 MHz). At least in theory. The driver is able to adjust the
-NegoPeriod more accurate (4ns) than the SyncSpeed (1 / 25ns). I don't know
-if certain devices will have problems with this discrepancy. Max. speed is
-10 MHz corresp. to a min. NegoPeriod of 100 ns. 
-(The driver allows slightly higher speeds if the devices (Ultra SCSI) accept
-it, but that's out of adapter spec, on your own risk and unlikely to improve
-performance. You're likely to crash your disks.) 
-SyncOffs is the offset used for synchronous negotiations; max. is 15. 
-The last values are only shown, if Sync is enabled. (NegoPeriod is still
-displayed in brackets to show the values which will be used after enabling
-Sync.)
-MaxCmd ist the number of commands (=tags) which can be processed at the same
-time by the device.
-
-If you want to change a setting, you can do that by writing to
-/proc/scsi/tmscsim/?. Basically you have to imitate the output of driver.
-(Don't use the brackets for NegoPeriod on Sync disabled devices.)
-You don't have to care about capitalisation. The driver will accept space,
-tab, comma, = and : as separators.
-
-There are three kinds of changes: 
-
-(1) Change driver settings: 
-    You type the names of the parameters and the params following it.
-    Example:
-     echo "MaxLUN=8 seltimeout 200" >/proc/scsi/tmscsim/0
-
-    Note that you can only change MaxID, MaxLUN, AdapterID, SelTimeOut,
-    TagMaxNum, ACBFlag, GlitchEater and DelayReset. Don't change ACBFlag
-    unless you want to see what happens, if the driver hangs.
-
-(2) Change device settings: You write a config line to the driver. The Nr
-    must match the ID and LUN given. If you give "-" as parameter, it is
-    ignored and the corresponding setting won't be changed. 
-    You can use "y" or "n" instead of "Yes" and "No" if you want to.
-    You don't need to specify a full line. The driver automatically performs
-    an INQUIRY on the device if necessary to check if it is capable to operate
-    with the given settings (Sync, TagQ).
-    Examples:
-     echo "0 0 0 y y y - y - 10 " >/proc/scsi/tmscsim/0
-     echo "3 5 0 y n y " >/proc/scsi/tmscsim/0
-
-    To give a short explanation of the first example: 
-    The first three numbers, "0 0 0" (Device index 0, SCSI ID 0, SCSI LUN 0),
-    select the device to which the following parameters apply. Note that it
-    would be sufficient to use the index or both SCSI ID and LUN, but I chose
-    to require all three to have a syntax similar to the output.
-    The following "y y y - y" enables Parity checking, enables Synchronous
-    transfers, Disconnection, leaves Send Start (not used) untouched and
-    enables Tagged Command Queueing for the selected device. The "-" skips
-    the Negotiation Period setting but the "10" sets the max sync. speed to
-    10 MHz. It's useless to specify both NegoPeriod and SyncSpeed as
-    discussed above. The values used in this example will result in maximum
-    performance.
-
-(3) Special commands: You can force a SCSI bus reset, an INQUIRY command, the
-    removal or the addition of a device's DCB and a SCSI register dump.
-    This is only used for debugging when you meet problems. The parameter of
-    the INQUIRY and REMOVE commands is the device index as shown by the
-    output of /proc/scsi/tmscsim/? in the device listing in the first column
-    (Idx). ADD takes the SCSI ID and LUN.
-    Examples:
-     echo "reset" >/proc/scsi/tmscsim/0
-     echo "inquiry 1" >/proc/scsi/tmscsim/0
-     echo "remove 2" >/proc/scsi/tmscsim/1
-     echo "add 2 3" >/proc/scsi/tmscsim/?
-     echo "dump" >/proc/scsi/tmscsim/0
-
-    Note that you will meet problems when you REMOVE a device's DCB with the
-    remove command if it contains partitions which are mounted. Only use it
-    after unmounting its partitions, telling the SCSI mid-level code to
-    remove it (scsi remove-single-device) and you really need a few bytes of
-    memory.
-    The ADD command allows you to configure a device before you tell the
-    mid-level code to try detection.
-
-
-I'd suggest reviewing the output of /proc/scsi/tmscsim/? after changing
-settings to see if everything changed as requested.
-
-
-5. Configuration via boot/module parameters
--------------------------------------------
-With the DC390, the driver reads its EEPROM settings and tries to use them.
-But you may want to override the settings prior to being able to change the
-driver configuration via /proc/scsi/tmscsim/?.
-If you do have another AM53C974 based adapter, that's even the only
-possibility to adjust settings before you are able to write to the
-/proc/scsi/tmscsim/? pseudo-file, e.g. if you want to use another 
-adapter ID than 7.  
-(BTW, the log message "DC390: No EEPROM found!" is normal without a DC390.)
-For this purpose, you can pass options to the driver before it is initialised
-by using kernel or module parameters. See lilo(8) or modprobe(1) manual
-pages on how to pass params to the kernel or a module.
-[NOTE: Formerly, it was not possible to override the EEPROM supplied
- settings of the DC390 with cmd line parameters. This has changed since
- 2.0e7]
-
-The syntax of the params is much shorter than the syntax of the /proc/...
-interface. This makes it a little bit more difficult to use. However, long
-parameter lines have the risk to be misinterpreted and the length of kernel
-parameters is limited.
-
-As the support for non-DC390 adapters works by simulating the values of the
-DC390 EEPROM, the settings are given in a DC390 BIOS' way.
-
-Here's the syntax:
-tmscsim=AdaptID,SpdIdx,DevMode,AdaptMode,TaggedCmnds,DelayReset
-
-Each of the parameters is a number, containing the described information:
-
-* AdaptID: The SCSI ID of the host adapter. Must be in the range 0..7
-  Default is 7.
-
-* SpdIdx: The index of the maximum speed as in the DC390 BIOS. The values
-  0..7 mean 10, 8.0, 6.7, 5.7, 5.0, 4.0, 3.1 and 2 MHz resp. Default is
-  0 (10.0 MHz).
-
-* DevMode is a bit mapped value describing the per-device features. It
-  applies to all devices. (Sync, Disc and TagQ will only apply, if the
-  device supports it.) The meaning of the bits (* = default):
-
-   Bit Val(hex) Val(dec)  Meaning
-   *0	 0x01	    1	  Parity check
-   *1	 0x02	    2	  Synchronous Negotiation
-   *2	 0x04	    4	  Disconnection
-   *3	 0x08	    8	  Send Start command on startup. (Not used)
-   *4	 0x10	   16	  Tagged Command Queueing
-
-  As usual, the desired value is obtained by adding the wanted values. If
-  you want to enable all values, e.g., you would use 31(0x1f). Default is 31.
-
-* AdaptMode is a bit mapped value describing the enabled adapter features.
-
-   Bit Val(hex) Val(dec)  Meaning
-   *0	 0x01	    1	  Support more than two drives. (Not used)
-   *1	 0x02	    2	  Use DOS compatible mapping for HDs greater than 1GB.
-   *2	 0x04	    4	  Reset SCSI Bus on startup.
-   *3	 0x08	    8	  Active Negation: Improves SCSI Bus noise immunity.
-    4	 0x10	   16	  Immediate return on BIOS seek command. (Not used)
- (*)5	 0x20	   32	  Check for LUNs >= 1.
-  
-* TaggedCmnds is a number indicating the maximum number of Tagged Commands.
-  It is the binary logarithm - 1 of the actual number. Max is 4 (32).
-   Value  Number of Tagged Commands
-     0		 2
-     1		 4
-     2		 8
-    *3		16
-     4		32
-
-* DelayReset is the time in seconds (minus 0.5s), the adapter waits, after a
-  bus reset. Default is 1 (corresp. to 1.5s).
-
-Example:
- modprobe tmscsim tmscsim=6,2,31
-would set the adapter ID to 6, max. speed to 6.7 MHz, enable all device
-features and leave the adapter features, the number of Tagged Commands
-and the Delay after a reset to the defaults.
-
-As you can see, you don't need to specify all of the six params.
-If you want values to be ignored (i.e. the EEprom settings or the defaults
-will be used), you may pass -2 (not 0!) at the corresponding position.
-
-The defaults (7,0,31,15,3,1) are aggressive to allow good performance. You
-can use tmscsim=7,0,31,63,4,0 for maximum performance, if your SCSI chain
-allows it. If you meet problems, you can use tmscsim=-1 which is a shortcut
-for tmscsim=7,4,9,15,2,10.
-
-
-6. Potential improvements
--------------------------
-Most of the intended work on the driver has been done. Here are a few ideas
-to further improve its usability:
-
-* Cleanly separate per-Target and per-LUN properties (DCB)
-* More intelligent abort() routine
-* Use new_eh code (Linux-2.1+)
-* Have the mid-level (ML) code (and not the driver) handle more of the
-  various conditions.
-* Command queueing in the driver: Eliminate Query list and use ML instead.
-* More user friendly boot/module param syntax
-
-Further investigation on these problems:
-
-* Driver hangs with sync readcdda (xcdroast) (most probably VIA PCI error)
-
-Known problems: 
-Please see http://www.garloff.de/kurt/linux/dc390/problems.html
-
-* Changing the parameters of multi-lun by the tmscsim/? interface will
-  cause problems, cause these settings are mostly per Target and not per LUN
-  and should be updated accordingly. To be fixed for 2.0d24.
-* CDRs (eg Yam CRW4416) not recognized, because some buggy devices don't 
-  recover from a SCSI reset in time. Use a higher delay or don't issue
-  a SCSI bus reset on driver initialization. See problems page.
-  For the CRW4416S, this seems to be solved with firmware 1.0g (reported by 
-  Jean-Yves Barbier).
-* TEAC CD-532S not being recognized. (Works with 1.11).
-* Scanners (eg. Astra UMAX 1220S) don't work: Disable Sync Negotiation.
-  If this does not help, try echo "INQUIRY t" >/proc/scsi/tmscsim/? (t
-  replaced by the dev index of your scanner). You may try to reset your SCSI
-  bus afterwards (echo "RESET" >/proc/scsi/tmscsim/?).
-  The problem seems to be solved as of 2.0d18, thanks to Andreas Rick.
-* If there is a valid partition table, the driver will use it for determining
-  the mapping. If there's none, a reasonable mapping (Symbios-like) will be
-  assumed. Other operating systems may not like this mapping, though
-  it's consistent with the BIOS' behaviour. Old DC390 drivers ignored the
-  partition table and used a H/S = 64/32 or 255/63 translation. So if you
-  want to be compatible to those, use this old mapping when creating
-  partition tables. Even worse, on bootup the DC390 might complain if other
-  mappings are found, so auto rebooting may fail.
-* In some situations, the driver will get stuck in an abort loop. This is a
-  bad interaction between the Mid-Layer of Linux' SCSI code and the driver.
-  Try to disable DsCn, if you meet this problem. Please contact me for
-  further debugging.
-
-
-7. Bug reports, debugging and updates
--------------------------------------
-Whenever you have problems with the driver, you are invited to ask the
-author for help. However, I'd suggest reading the docs and trying to solve
-the problem yourself, first. 
-If you find something, which you believe to be a bug, please report it to me. 
-Please append the output of /proc/scsi/scsi, /proc/scsi/tmscsim/? and
-maybe the DC390 log messages to the report. 
-
-Bug reports should be send to me (Kurt Garloff <dc390@garloff.de>) as well
-as to the linux-scsi list (<linux-scsi@vger.kernel.org>), as sometimes bugs
-are caused by the SCSI mid-level code.
-
-I will ask you for some more details and probably I will also ask you to
-enable some of the DEBUG options in the driver (tmscsim.c:DC390_DEBUGXXX
-defines). The driver will produce some data for the syslog facility then.
-Beware: If your syslog gets written to a SCSI disk connected to your
-AM53C974, the logging might produce log output again, and you might end
-having your box spending most of its time doing the logging.
-
-The latest version of the driver can be found at:
- http://www.garloff.de/kurt/linux/dc390/
- ftp://ftp.suse.com/pub/people/garloff/linux/dc390/
-
-
-8. Acknowledgements
--------------------
-Thanks to Linus Torvalds, Alan Cox, the FSF people, the XFree86 team and 
-all the others for the wonderful OS and software.
-Thanks to C.L. Huang and Philip Giang (Tekram) for the initial driver
-release and support.
-Thanks to Doug Ledford, Gérard Roudier for support with SCSI coding.
-Thanks to a lot of people (espec. Chiaki Ishikawa, Andreas Haumer, Hubert 
-Tonneau) for intensively testing the driver (and even risking data loss
-doing this during early revisions).
-Recently, SuSE GmbH, Nuernberg, FRG, has been paying me for the driver
-development and maintenance. Special thanks!
-
-
-9. Copyright
-------------
- This driver is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by   
- the Free Software Foundation; version 2 of the License.
- If you want to use any later version of the GNU GPL, you will probably
- be allowed to, but you have to ask me and Tekram <erich@tekram.com.tw>
- before.
-
--------------------------------------------------------------------------
-Written by Kurt Garloff <kurt@garloff.de> 1998/06/11
-Last updated 2000/11/28, driver revision 2.0e7
-$Id: README.tmscsim,v 2.25.2.7 2000/12/20 01:07:12 garloff Exp $
diff --git a/Documentation/x86/00-INDEX b/Documentation/x86/00-INDEX
index 6922644..3bb2ee3 100644
--- a/Documentation/x86/00-INDEX
+++ b/Documentation/x86/00-INDEX
@@ -2,14 +2,14 @@
 	- this file
 boot.txt
 	- List of boot protocol versions
-early-microcode.txt
-	- How to load microcode from an initrd-CPIO archive early to fix CPU issues.
 earlyprintk.txt
 	- Using earlyprintk with a USB2 debug port key.
 entry_64.txt
 	- Describe (some of the) kernel entry points for x86.
 exception-tables.txt
 	- why and how Linux kernel uses exception tables on x86
+microcode.txt
+	- How to load microcode from an initrd-CPIO archive early to fix CPU issues.
 mtrr.txt
 	- how to use x86 Memory Type Range Registers to increase performance
 pat.txt
diff --git a/MAINTAINERS b/MAINTAINERS
index 89fd804..881d328 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -843,13 +843,6 @@
 F:	sound/soc/codecs/ssm*
 F:	sound/soc/codecs/sigmadsp.*
 
-ANALOG DEVICES INC ASOC DRIVERS
-L:	adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
-L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
-W:	http://blackfin.uclinux.org/
-S:	Supported
-F:	sound/soc/blackfin/*
-
 ANALOG DEVICES INC DMA DRIVERS
 M:	Lars-Peter Clausen <lars@metafoo.de>
 W:	http://ez.analog.com/community/linux-device-drivers
@@ -1245,31 +1238,10 @@
 F:	drivers/*/*aspeed*
 
 ARM/ATMEL AT91 Clock Support
-M:	Boris Brezillon <boris.brezillon@free-electrons.com>
+M:	Boris Brezillon <boris.brezillon@bootlin.com>
 S:	Maintained
 F:	drivers/clk/at91
 
-ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
-M:	Nicolas Ferre <nicolas.ferre@microchip.com>
-M:	Alexandre Belloni <alexandre.belloni@bootlin.com>
-L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W:	http://www.linux4sam.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git
-S:	Supported
-N:	at91
-N:	atmel
-F:	arch/arm/mach-at91/
-F:	include/soc/at91/
-F:	arch/arm/boot/dts/at91*.dts
-F:	arch/arm/boot/dts/at91*.dtsi
-F:	arch/arm/boot/dts/sama*.dts
-F:	arch/arm/boot/dts/sama*.dtsi
-F:	arch/arm/include/debug/at91.S
-F:	drivers/memory/atmel*
-F:	drivers/watchdog/sama5d4_wdt.c
-X:	drivers/input/touchscreen/atmel_mxt_ts.c
-X:	drivers/net/wireless/atmel/
-
 ARM/CALXEDA HIGHBANK ARCHITECTURE
 M:	Rob Herring <robh@kernel.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1590,15 +1562,6 @@
 M:	Philipp Zabel <philipp.zabel@gmail.com>
 S:	Maintained
 
-ARM/Marvell Berlin SoC support
-M:	Jisheng Zhang <jszhang@marvell.com>
-M:	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
-L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:	Maintained
-F:	arch/arm/mach-berlin/
-F:	arch/arm/boot/dts/berlin*
-F:	arch/arm64/boot/dts/marvell/berlin*
-
 ARM/Marvell Dove/MV78xx0/Orion SOC support
 M:	Jason Cooper <jason@lakedaemon.net>
 M:	Andrew Lunn <andrew@lunn.ch>
@@ -1669,6 +1632,27 @@
 F:	arch/arm/mach-ks8695/
 S:	Odd Fixes
 
+ARM/Microchip (AT91) SoC support
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
+M:	Alexandre Belloni <alexandre.belloni@bootlin.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+W:	http://www.linux4sam.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git
+S:	Supported
+N:	at91
+N:	atmel
+F:	arch/arm/mach-at91/
+F:	include/soc/at91/
+F:	arch/arm/boot/dts/at91*.dts
+F:	arch/arm/boot/dts/at91*.dtsi
+F:	arch/arm/boot/dts/sama*.dts
+F:	arch/arm/boot/dts/sama*.dtsi
+F:	arch/arm/include/debug/at91.S
+F:	drivers/memory/atmel*
+F:	drivers/watchdog/sama5d4_wdt.c
+X:	drivers/input/touchscreen/atmel_mxt_ts.c
+X:	drivers/net/wireless/atmel/
+
 ARM/MIOA701 MACHINE SUPPORT
 M:	Robert Jarzmik <robert.jarzmik@free.fr>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1713,6 +1697,20 @@
 F:	Documentation/devicetree/bindings/arm/ux500/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
 
+ARM/NUVOTON NPCM ARCHITECTURE
+M:	Avi Fishman <avifishman70@gmail.com>
+M:	Tomer Maimon <tmaimon77@gmail.com>
+R:	Patrick Venture <venture@google.com>
+R:	Nancy Yuen <yuenn@google.com>
+R:	Brendan Higgins <brendanhiggins@google.com>
+L:	openbmc@lists.ozlabs.org (moderated for non-subscribers)
+S:	Supported
+F:	arch/arm/mach-npcm/
+F:	arch/arm/boot/dts/nuvoton-npcm*
+F:	include/dt-bindings/clock/nuvoton,npcm7xx-clks.h
+F:	drivers/*/*npcm*
+F:	Documentation/*/*npcm*
+
 ARM/NUVOTON W90X900 ARM ARCHITECTURE
 M:	Wan ZongShun <mcuos.com@gmail.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1723,7 +1721,7 @@
 F:	drivers/input/touchscreen/w90p910_ts.c
 F:	drivers/watchdog/nuc900_wdt.c
 F:	drivers/net/ethernet/nuvoton/w90p910_ether.c
-F:	drivers/mtd/nand/nuc900_nand.c
+F:	drivers/mtd/nand/raw/nuc900_nand.c
 F:	drivers/rtc/rtc-nuc900.c
 F:	drivers/spi/spi-nuc900.c
 F:	drivers/usb/host/ehci-w90x900.c
@@ -1876,7 +1874,6 @@
 S:	Maintained
 F:	arch/arm/boot/dts/s3c*
 F:	arch/arm/boot/dts/s5p*
-F:	arch/arm/boot/dts/samsung*
 F:	arch/arm/boot/dts/exynos*
 F:	arch/arm64/boot/dts/exynos/
 F:	arch/arm/plat-samsung/
@@ -1976,6 +1973,14 @@
 S:	Maintained
 F:	drivers/edac/altera_edac.
 
+ARM/SPREADTRUM SoC SUPPORT
+M:	Orson Zhai <orsonzhai@gmail.com>
+M:	Baolin Wang <baolin.wang@linaro.org>
+M:	Chunyan Zhang <zhang.lyra@gmail.com>
+S:	Maintained
+F:	arch/arm64/boot/dts/sprd
+N:	sprd
+
 ARM/STI ARCHITECTURE
 M:	Patrice Chotard <patrice.chotard@st.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2018,6 +2023,15 @@
 F:	arch/arm/mach-stm32/
 F:	drivers/clocksource/armv7m_systick.c
 
+ARM/Synaptics Berlin SoC support
+M:	Jisheng Zhang <Jisheng.Zhang@synaptics.com>
+M:	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	arch/arm/mach-berlin/
+F:	arch/arm/boot/dts/berlin*
+F:	arch/arm64/boot/dts/marvell/berlin*
+
 ARM/TANGO ARCHITECTURE
 M:	Marc Gonzalez <marc.w.gonzalez@free.fr>
 M:	Mans Rullgard <mans@mansr.com>
@@ -2653,6 +2667,7 @@
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:	Maintained
 F:	block/
+F:	drivers/block/
 F:	kernel/trace/blktrace.c
 F:	lib/sbitmap.c
 
@@ -2984,7 +2999,7 @@
 L:	linux-mtd@lists.infradead.org
 L:	bcm-kernel-feedback-list@broadcom.com
 S:	Maintained
-F:	drivers/mtd/nand/brcmnand/
+F:	drivers/mtd/nand/raw/brcmnand/
 
 BROADCOM STB DPFE DRIVER
 M:	Markus Mayer <mmayer@broadcom.com>
@@ -4076,7 +4091,7 @@
 M:	Masahiro Yamada <yamada.masahiro@socionext.com>
 L:	linux-mtd@lists.infradead.org
 S:	Supported
-F:	drivers/mtd/nand/denali*
+F:	drivers/mtd/nand/raw/denali*
 
 DESIGNWARE USB2 DRD IP DRIVER
 M:	Minas Harutyunyan <hminas@synopsys.com>
@@ -4293,6 +4308,7 @@
 S:	Maintained
 F:	drivers/dma/
 F:	include/linux/dmaengine.h
+F:	include/linux/of_dma.h
 F:	Documentation/devicetree/bindings/dma/
 F:	Documentation/driver-api/dmaengine/
 T:	git git://git.infradead.org/users/vkoul/slave-dma.git
@@ -4617,7 +4633,7 @@
 T:	git git://anongit.freedesktop.org/drm/drm-misc
 
 DRM DRIVERS FOR ATMEL HLCDC
-M:	Boris Brezillon <boris.brezillon@free-electrons.com>
+M:	Boris Brezillon <boris.brezillon@bootlin.com>
 L:	dri-devel@lists.freedesktop.org
 S:	Supported
 F:	drivers/gpu/drm/atmel-hlcdc/
@@ -4977,12 +4993,6 @@
 S:	Maintained
 F:	drivers/media/tuners/e4000*
 
-EATA ISA/EISA/PCI SCSI DRIVER
-M:	Dario Ballabio <ballabio_dario@emc.com>
-L:	linux-scsi@vger.kernel.org
-S:	Maintained
-F:	drivers/scsi/eata.c
-
 EC100 MEDIA DRIVER
 M:	Antti Palosaari <crope@iki.fi>
 L:	linux-media@vger.kernel.org
@@ -5620,7 +5630,7 @@
 M:	Han Xu <han.xu@nxp.com>
 L:	linux-mtd@lists.infradead.org
 S:	Maintained
-F:	drivers/mtd/nand/gpmi-nand/*
+F:	drivers/mtd/nand/raw/gpmi-nand/*
 
 FREESCALE I2C CPM DRIVER
 M:	Jochen Friedrich <jochen@scram.de>
@@ -5818,12 +5828,6 @@
 F:	tools/perf/bench/futex*
 F:	Documentation/*futex*
 
-FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
-M:	Rik Faith <faith@cs.unc.edu>
-L:	linux-scsi@vger.kernel.org
-S:	Odd Fixes (e.g., new signatures)
-F:	drivers/scsi/fdomain.*
-
 GCC PLUGINS
 M:	Kees Cook <keescook@chromium.org>
 R:	Emese Revfy <re.emese@gmail.com>
@@ -5984,7 +5988,7 @@
 F:	drivers/media/rc/gpio-ir-tx.c
 
 GPIO MOCKUP DRIVER
-M:	Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
+M:	Bamvor Jian Zhang <bamv2005@gmail.com>
 R:	Bartosz Golaszewski <brgl@bgdev.pl>
 L:	linux-gpio@vger.kernel.org
 S:	Maintained
@@ -5997,12 +6001,14 @@
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
 S:	Maintained
 F:	Documentation/devicetree/bindings/gpio/
+F:	Documentation/driver-api/gpio/
 F:	Documentation/gpio/
 F:	Documentation/ABI/testing/gpio-cdev
 F:	Documentation/ABI/obsolete/sysfs-gpio
 F:	drivers/gpio/
 F:	include/linux/gpio/
 F:	include/linux/gpio.h
+F:	include/linux/of_gpio.h
 F:	include/asm-generic/gpio.h
 F:	include/uapi/linux/gpio.h
 F:	tools/gpio/
@@ -6937,7 +6943,7 @@
 M:	Harvey Hunt <harveyhuntnexus@gmail.com>
 L:	linux-mtd@lists.infradead.org
 S:	Maintained
-F:	drivers/mtd/nand/jz4780_*
+F:	drivers/mtd/nand/raw/jz4780_*
 
 INOTIFY
 M:	Jan Kara <jack@suse.cz>
@@ -7312,6 +7318,7 @@
 F:	Documentation/devicetree/bindings/iommu/
 F:	drivers/iommu/
 F:	include/linux/iommu.h
+F:	include/linux/of_iommu.h
 F:	include/linux/iova.h
 
 IP MASQUERADING
@@ -8424,7 +8431,7 @@
 F:	Documentation/devicetree/bindings/display/armada/
 
 MARVELL CRYPTO DRIVER
-M:	Boris Brezillon <boris.brezillon@free-electrons.com>
+M:	Boris Brezillon <boris.brezillon@bootlin.com>
 M:	Arnaud Ebalard <arno@natisbad.org>
 F:	drivers/crypto/marvell/
 S:	Maintained
@@ -8483,10 +8490,10 @@
 F:	drivers/net/wireless/marvell/mwl8k.c
 
 MARVELL NAND CONTROLLER DRIVER
-M:	Miquel Raynal <miquel.raynal@free-electrons.com>
+M:	Miquel Raynal <miquel.raynal@bootlin.com>
 L:	linux-mtd@lists.infradead.org
 S:	Maintained
-F:	drivers/mtd/nand/marvell_nand.c
+F:	drivers/mtd/nand/raw/marvell_nand.c
 F:	Documentation/devicetree/bindings/mtd/marvell-nand.txt
 
 MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
@@ -9091,10 +9098,9 @@
 MEMORY TECHNOLOGY DEVICES (MTD)
 M:	David Woodhouse <dwmw2@infradead.org>
 M:	Brian Norris <computersforpeace@gmail.com>
-M:	Boris Brezillon <boris.brezillon@free-electrons.com>
+M:	Boris Brezillon <boris.brezillon@bootlin.com>
 M:	Marek Vasut <marek.vasut@gmail.com>
 M:	Richard Weinberger <richard@nod.at>
-M:	Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
 L:	linux-mtd@lists.infradead.org
 W:	http://www.linux-mtd.infradead.org/
 Q:	http://patchwork.ozlabs.org/project/linux-mtd/list/
@@ -9179,7 +9185,7 @@
 M:	Josh Wu <rainyfeeling@outlook.com>
 L:	linux-mtd@lists.infradead.org
 S:	Supported
-F:	drivers/mtd/nand/atmel/*
+F:	drivers/mtd/nand/raw/atmel/*
 F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
 
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
@@ -9511,7 +9517,7 @@
 F:	drivers/net/ethernet/myricom/myri10ge/
 
 NAND FLASH SUBSYSTEM
-M:	Boris Brezillon <boris.brezillon@free-electrons.com>
+M:	Boris Brezillon <boris.brezillon@bootlin.com>
 R:	Richard Weinberger <richard@nod.at>
 L:	linux-mtd@lists.infradead.org
 W:	http://www.linux-mtd.infradead.org/
@@ -10305,7 +10311,7 @@
 M:	Kyungmin Park <kyungmin.park@samsung.com>
 L:	linux-mtd@lists.infradead.org
 S:	Maintained
-F:	drivers/mtd/onenand/
+F:	drivers/mtd/nand/onenand/
 F:	include/linux/mtd/onenand*.h
 
 ONSTREAM SCSI TAPE DRIVER
@@ -10802,6 +10808,7 @@
 F:	drivers/pci/
 F:	include/asm-generic/pci*
 F:	include/linux/pci*
+F:	include/linux/of_pci.h
 F:	include/uapi/linux/pci*
 F:	lib/pci*
 F:	arch/x86/pci/
@@ -11430,12 +11437,6 @@
 F:	sound/arm/pxa*
 F:	sound/soc/pxa/
 
-PXA3xx NAND FLASH DRIVER
-M:	Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
-L:	linux-mtd@lists.infradead.org
-S:	Maintained
-F:	drivers/mtd/nand/pxa3xx_nand.c
-
 QAT DRIVER
 M:	Giovanni Cabiddu <giovanni.cabiddu@intel.com>
 L:	qat-linux@intel.com
@@ -11919,8 +11920,8 @@
 RICOH SMARTMEDIA/XD DRIVER
 M:	Maxim Levitsky <maximlevitsky@gmail.com>
 S:	Maintained
-F:	drivers/mtd/nand/r852.c
-F:	drivers/mtd/nand/r852.h
+F:	drivers/mtd/nand/raw/r852.c
+F:	drivers/mtd/nand/raw/r852.h
 
 RISC-V ARCHITECTURE
 M:	Palmer Dabbelt <palmer@sifive.com>
@@ -13116,7 +13117,6 @@
 F:	arch/arm/mach-spear/
 
 SPI NOR SUBSYSTEM
-M:	Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
 M:	Marek Vasut <marek.vasut@gmail.com>
 L:	linux-mtd@lists.infradead.org
 W:	http://www.linux-mtd.infradead.org/
@@ -13489,15 +13489,16 @@
 S:	Supported
 F:	drivers/mfd/syscon.c
 
-SYSTEM CONTROL & POWER INTERFACE (SCPI) Message Protocol drivers
+SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE (SCPI/SCMI) Message Protocol drivers
 M:	Sudeep Holla <sudeep.holla@arm.com>
 L:	linux-arm-kernel@lists.infradead.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/arm/arm,scpi.txt
-F:	drivers/clk/clk-scpi.c
-F:	drivers/cpufreq/scpi-cpufreq.c
+F:	Documentation/devicetree/bindings/arm/arm,sc[mp]i.txt
+F:	drivers/clk/clk-sc[mp]i.c
+F:	drivers/cpufreq/sc[mp]i-cpufreq.c
 F:	drivers/firmware/arm_scpi.c
-F:	include/linux/scpi_protocol.h
+F:	drivers/firmware/arm_scmi/
+F:	include/linux/sc[mp]i_protocol.h
 
 SYSTEM RESET/SHUTDOWN DRIVERS
 M:	Sebastian Reichel <sre@kernel.org>
@@ -14759,7 +14760,7 @@
 M:	Stefan Agner <stefan@agner.ch>
 L:	linux-mtd@lists.infradead.org
 S:	Supported
-F:	drivers/mtd/nand/vf610_nfc.c
+F:	drivers/mtd/nand/raw/vf610_nfc.c
 
 VFAT/FAT/MSDOS FILESYSTEM
 M:	OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index 6e9a0a9..783b2035 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -10,7 +10,6 @@
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/kdev_t.h>
-#include <linux/fs_struct.h>
 #include <linux/proc_fs.h>
 #include <linux/file.h>
 #include <linux/sched/mm.h>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7e3d535..1878083 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -709,8 +709,6 @@
 # Kconfigs may be included either alphabetically (according to the
 # plat- suffix) or along side the corresponding mach-* source.
 #
-source "arch/arm/mach-mvebu/Kconfig"
-
 source "arch/arm/mach-actions/Kconfig"
 
 source "arch/arm/mach-alpine/Kconfig"
@@ -719,6 +717,8 @@
 
 source "arch/arm/mach-asm9260/Kconfig"
 
+source "arch/arm/mach-aspeed/Kconfig"
+
 source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-axxia/Kconfig"
@@ -739,6 +739,9 @@
 
 source "arch/arm/mach-ep93xx/Kconfig"
 
+source "arch/arm/mach-exynos/Kconfig"
+source "arch/arm/plat-samsung/Kconfig"
+
 source "arch/arm/mach-footbridge/Kconfig"
 
 source "arch/arm/mach-gemini/Kconfig"
@@ -747,31 +750,33 @@
 
 source "arch/arm/mach-hisi/Kconfig"
 
+source "arch/arm/mach-imx/Kconfig"
+
 source "arch/arm/mach-integrator/Kconfig"
 
+source "arch/arm/mach-iop13xx/Kconfig"
+
 source "arch/arm/mach-iop32x/Kconfig"
 
 source "arch/arm/mach-iop33x/Kconfig"
 
-source "arch/arm/mach-iop13xx/Kconfig"
-
 source "arch/arm/mach-ixp4xx/Kconfig"
 
 source "arch/arm/mach-keystone/Kconfig"
 
 source "arch/arm/mach-ks8695/Kconfig"
 
+source "arch/arm/mach-mediatek/Kconfig"
+
 source "arch/arm/mach-meson/Kconfig"
 
+source "arch/arm/mach-mmp/Kconfig"
+
 source "arch/arm/mach-moxart/Kconfig"
 
-source "arch/arm/mach-aspeed/Kconfig"
-
 source "arch/arm/mach-mv78xx0/Kconfig"
 
-source "arch/arm/mach-imx/Kconfig"
-
-source "arch/arm/mach-mediatek/Kconfig"
+source "arch/arm/mach-mvebu/Kconfig"
 
 source "arch/arm/mach-mxs/Kconfig"
 
@@ -779,6 +784,8 @@
 
 source "arch/arm/mach-nomadik/Kconfig"
 
+source "arch/arm/mach-npcm/Kconfig"
+
 source "arch/arm/mach-nspire/Kconfig"
 
 source "arch/arm/plat-omap/Kconfig"
@@ -789,23 +796,31 @@
 
 source "arch/arm/mach-orion5x/Kconfig"
 
+source "arch/arm/mach-oxnas/Kconfig"
+
 source "arch/arm/mach-picoxcell/Kconfig"
 
+source "arch/arm/mach-prima2/Kconfig"
+
 source "arch/arm/mach-pxa/Kconfig"
 source "arch/arm/plat-pxa/Kconfig"
 
-source "arch/arm/mach-mmp/Kconfig"
-
-source "arch/arm/mach-oxnas/Kconfig"
-
 source "arch/arm/mach-qcom/Kconfig"
 
 source "arch/arm/mach-realview/Kconfig"
 
 source "arch/arm/mach-rockchip/Kconfig"
 
+source "arch/arm/mach-s3c24xx/Kconfig"
+
+source "arch/arm/mach-s3c64xx/Kconfig"
+
+source "arch/arm/mach-s5pv210/Kconfig"
+
 source "arch/arm/mach-sa1100/Kconfig"
 
+source "arch/arm/mach-shmobile/Kconfig"
+
 source "arch/arm/mach-socfpga/Kconfig"
 
 source "arch/arm/mach-spear/Kconfig"
@@ -814,21 +829,8 @@
 
 source "arch/arm/mach-stm32/Kconfig"
 
-source "arch/arm/mach-s3c24xx/Kconfig"
-
-source "arch/arm/mach-s3c64xx/Kconfig"
-
-source "arch/arm/mach-s5pv210/Kconfig"
-
-source "arch/arm/mach-exynos/Kconfig"
-source "arch/arm/plat-samsung/Kconfig"
-
-source "arch/arm/mach-shmobile/Kconfig"
-
 source "arch/arm/mach-sunxi/Kconfig"
 
-source "arch/arm/mach-prima2/Kconfig"
-
 source "arch/arm/mach-tango/Kconfig"
 
 source "arch/arm/mach-tegra/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index e83f516..e4e537f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -196,6 +196,7 @@
 machine-$(CONFIG_ARCH_MXS)		+= mxs
 machine-$(CONFIG_ARCH_NETX)		+= netx
 machine-$(CONFIG_ARCH_NOMADIK)		+= nomadik
+machine-$(CONFIG_ARCH_NPCM)		+= npcm
 machine-$(CONFIG_ARCH_NSPIRE)		+= nspire
 machine-$(CONFIG_ARCH_OXNAS)		+= oxnas
 machine-$(CONFIG_ARCH_OMAP1)		+= omap1
diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c
index 13c90ab..ade5079 100644
--- a/arch/arm/boot/compressed/string.c
+++ b/arch/arm/boot/compressed/string.c
@@ -121,6 +121,16 @@ char *strchr(const char *s, int c)
 	return (char *)s;
 }
 
+char *strrchr(const char *s, int c)
+{
+	const char *last = NULL;
+	do {
+		if (*s == (char)c)
+			last = s;
+	} while (*s++);
+	return (char *)last;
+}
+
 #undef memset
 
 void *memset(void *s, int c, size_t count)
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index ade7a38..7e24249 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -163,7 +163,10 @@
 	exynos4210-smdkv310.dtb \
 	exynos4210-trats.dtb \
 	exynos4210-universal_c210.dtb \
+	exynos4412-i9300.dtb \
+	exynos4412-i9305.dtb \
 	exynos4412-itop-elite.dtb \
+	exynos4412-n710x.dtb \
 	exynos4412-odroidu3.dtb \
 	exynos4412-odroidx.dtb \
 	exynos4412-odroidx2.dtb \
@@ -304,6 +307,8 @@
 dtb-$(CONFIG_ARCH_LPC32XX) += \
 	lpc3250-ea3250.dtb \
 	lpc3250-phy3250.dtb
+dtb-$(CONFIG_ARCH_NPCM7XX) += \
+	nuvoton-npcm750-evb.dtb
 dtb-$(CONFIG_MACH_MESON6) += \
 	meson6-atv1200.dtb
 dtb-$(CONFIG_MACH_MESON8) += \
@@ -396,6 +401,7 @@
 	imx6dl-icore-rqs.dtb \
 	imx6dl-nit6xlite.dtb \
 	imx6dl-nitrogen6x.dtb \
+	imx6dl-phytec-mira-rdk-nand.dtb \
 	imx6dl-phytec-pbab01.dtb \
 	imx6dl-rex-basic.dtb \
 	imx6dl-riotboard.dtb \
@@ -435,6 +441,7 @@
 	imx6q-dfi-fs700-m60.dtb \
 	imx6q-display5-tianma-tm070-1280x768.dtb \
 	imx6q-dmo-edmqmx6.dtb \
+	imx6q-dms-ba16.dtb \
 	imx6q-evi.dtb \
 	imx6q-gk802.dtb \
 	imx6q-gw51xx.dtb \
@@ -465,6 +472,8 @@
 	imx6q-nitrogen6_max.dtb \
 	imx6q-nitrogen6_som2.dtb \
 	imx6q-novena.dtb \
+	imx6q-phytec-mira-rdk-emmc.dtb \
+	imx6q-phytec-mira-rdk-nand.dtb \
 	imx6q-phytec-pbab01.dtb \
 	imx6q-pistachio.dtb \
 	imx6q-rex-pro.dtb \
@@ -494,6 +503,7 @@
 	imx6q-zii-rdu2.dtb \
 	imx6qp-nitrogen6_max.dtb \
 	imx6qp-nitrogen6_som2.dtb \
+	imx6qp-phytec-mira-rdk-nand.dtb \
 	imx6qp-sabreauto.dtb \
 	imx6qp-sabresd.dtb \
 	imx6qp-tx6qp-8037.dtb \
@@ -526,7 +536,9 @@
 	imx6ul-tx6ul-0010.dtb \
 	imx6ul-tx6ul-0011.dtb \
 	imx6ul-tx6ul-mainboard.dtb \
-	imx6ull-14x14-evk.dtb
+	imx6ull-14x14-evk.dtb \
+	imx6ull-colibri-eval-v3.dtb \
+	imx6ull-colibri-wifi-eval-v3.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
 	imx7d-cl-som-imx7.dtb \
 	imx7d-colibri-emmc-eval-v3.dtb \
@@ -673,6 +685,7 @@
 	am335x-lxm.dtb \
 	am335x-moxa-uc-8100-me-t.dtb \
 	am335x-nano.dtb \
+	am335x-pdu001.dtb \
 	am335x-pepper.dtb \
 	am335x-phycore-rdk.dtb \
 	am335x-shc.dtb \
@@ -752,6 +765,7 @@
 	qcom-msm8960-cdp.dtb \
 	qcom-msm8974-fairphone-fp2.dtb \
 	qcom-msm8974-lge-nexus5-hammerhead.dtb \
+	qcom-msm8974-samsung-klte.dtb \
 	qcom-msm8974-sony-xperia-castor.dtb \
 	qcom-msm8974-sony-xperia-honami.dtb \
 	qcom-mdm9615-wp8548-mangoh-green.dtb
@@ -784,6 +798,7 @@
 	r8a7778-bockw.dtb \
 	r8a7779-marzen.dtb \
 	r8a7790-lager.dtb \
+	r8a7790-stout.dtb \
 	r8a7791-koelsch.dtb \
 	r8a7791-porter.dtb \
 	r8a7792-blanche.dtb \
@@ -863,7 +878,7 @@
 	stih410-b2120.dtb \
 	stih410-b2260.dtb \
 	stih418-b2199.dtb
-dtb-$(CONFIG_ARCH_STM32)+= \
+dtb-$(CONFIG_ARCH_STM32) += \
 	stm32f429-disco.dtb \
 	stm32f469-disco.dtb \
 	stm32f746-disco.dtb \
@@ -871,7 +886,9 @@
 	stm32429i-eval.dtb \
 	stm32746g-eval.dtb \
 	stm32h743i-eval.dtb \
-	stm32h743i-disco.dtb
+	stm32h743i-disco.dtb \
+	stm32mp157c-ed1.dtb \
+	stm32mp157c-ev1.dtb
 dtb-$(CONFIG_MACH_SUN4I) += \
 	sun4i-a10-a1000.dtb \
 	sun4i-a10-ba10-tvbox.dtb \
@@ -942,6 +959,8 @@
 	sun7i-a20-m3.dtb \
 	sun7i-a20-mk808c.dtb \
 	sun7i-a20-olimex-som-evb.dtb \
+	sun7i-a20-olimex-som204-evb.dtb \
+	sun7i-a20-olimex-som204-evb-emmc.dtb \
 	sun7i-a20-olinuxino-lime.dtb \
 	sun7i-a20-olinuxino-lime2.dtb \
 	sun7i-a20-olinuxino-lime2-emmc.dtb \
@@ -974,6 +993,7 @@
 	sun8i-a83t-cubietruck-plus.dtb \
 	sun8i-a83t-tbs-a711.dtb \
 	sun8i-h2-plus-orangepi-r1.dtb \
+	sun8i-h2-plus-bananapi-m2-zero.dtb \
 	sun8i-h2-plus-orangepi-zero.dtb \
 	sun8i-h3-bananapi-m2-plus.dtb \
 	sun8i-h3-beelink-x2.dtb \
@@ -1022,6 +1042,7 @@
 	tegra114-tn7.dtb
 dtb-$(CONFIG_ARCH_TEGRA_124_SOC) += \
 	tegra124-apalis-eval.dtb \
+	tegra124-apalis-v1.2-eval.dtb \
 	tegra124-jetson-tk1.dtb \
 	tegra124-nyan-big.dtb \
 	tegra124-nyan-blaze.dtb \
@@ -1047,6 +1068,7 @@
 	uniphier-sld8-ref.dtb
 dtb-$(CONFIG_ARCH_VERSATILE) += \
 	versatile-ab.dtb \
+	versatile-ab-ib2.dtb \
 	versatile-pb.dtb
 dtb-$(CONFIG_ARCH_VEXPRESS) += \
 	vexpress-v2p-ca5s.dtb \
@@ -1062,12 +1084,18 @@
 	wm8750-apc8750.dtb \
 	wm8850-w70v2.dtb
 dtb-$(CONFIG_ARCH_ZYNQ) += \
+	zynq-cc108.dtb \
 	zynq-microzed.dtb \
 	zynq-parallella.dtb \
 	zynq-zc702.dtb \
 	zynq-zc706.dtb \
+	zynq-zc770-xm010.dtb \
+	zynq-zc770-xm011.dtb \
+	zynq-zc770-xm012.dtb \
+	zynq-zc770-xm013.dtb \
 	zynq-zed.dtb \
-	zynq-zybo.dtb
+	zynq-zybo.dtb \
+	zynq-zybo-z7.dtb
 dtb-$(CONFIG_MACH_ARMADA_370) += \
 	armada-370-db.dtb \
 	armada-370-dlink-dns327l.dtb \
@@ -1129,6 +1157,7 @@
 dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
 dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-ast2500-evb.dtb \
+	aspeed-bmc-arm-centriq2400-rep.dtb \
 	aspeed-bmc-opp-palmetto.dtb \
 	aspeed-bmc-opp-romulus.dtb \
 	aspeed-bmc-opp-witherspoon.dtb \
diff --git a/arch/arm/boot/dts/am335x-boneblue.dts b/arch/arm/boot/dts/am335x-boneblue.dts
index 3f2480d..58baee1 100644
--- a/arch/arm/boot/dts/am335x-boneblue.dts
+++ b/arch/arm/boot/dts/am335x-boneblue.dts
@@ -342,7 +342,7 @@
 	};
 
 	baseboard_eeprom: baseboard_eeprom@50 {
-		compatible = "at,24c256";
+		compatible = "atmel,24c256";
 		reg = <0x50>;
 
 		#address-cells = <1>;
diff --git a/arch/arm/boot/dts/am335x-pdu001.dts b/arch/arm/boot/dts/am335x-pdu001.dts
new file mode 100644
index 0000000..1ad530a
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-pdu001.dts
@@ -0,0 +1,595 @@
+/*
+ * pdu001.dts
+ *
+ * EETS GmbH PDU001 board device tree file
+ *
+ * Copyright (C) 2018 EETS GmbH - http://www.eets.ch/
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:  GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/leds/leds-pca9532.h>
+
+/ {
+	model = "EETS,PDU001";
+	compatible = "ti,am33xx";
+
+	chosen {
+		stdout-path = &uart3;
+	};
+
+	cpus {
+		cpu@0 {
+			cpu0-supply = <&vdd1_reg>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x10000000>; /* 256 MB */
+	};
+
+	vbat: fixedregulator@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vbat";
+		regulator-min-microvolt = <3600000>;
+		regulator-max-microvolt = <3600000>;
+		regulator-boot-on;
+	};
+
+	lis3_reg: fixedregulator@1 {
+		compatible = "regulator-fixed";
+		regulator-name = "lis3_reg";
+		regulator-boot-on;
+	};
+
+	panel {
+		compatible = "ti,tilcdc,panel";
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <&lcd_pins_s0>;
+		panel-info {
+			ac-bias           = <255>;
+			ac-bias-intrpt    = <0>;
+			dma-burst-sz      = <16>;
+			bpp               = <16>;
+			fdd               = <0x80>;
+			sync-edge         = <0>;
+			sync-ctrl         = <1>;
+			raster-order      = <0>;
+			fifo-th           = <0>;
+		};
+
+		display-timings {
+			240x320p16 {
+				clock-frequency = <6500000>;
+				hactive = <240>;
+				vactive = <320>;
+				hfront-porch = <6>;
+				hback-porch = <6>;
+				hsync-len = <1>;
+				vback-porch = <6>;
+				vfront-porch = <6>;
+				vsync-len = <1>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				pixelclk-active = <1>;
+				de-active = <0>;
+			};
+		};
+	};
+};
+
+&am33xx_pinmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&clkout2_pin>;
+
+	i2c0_pins: pinmux_i2c0_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c0_sda */
+			AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
+		>;
+	};
+
+	i2c1_pins: pinmux_i2c1_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE2)	/* spi0_d1.i2c1_sda */
+			AM33XX_IOPAD(0x95c, PIN_INPUT_PULLUP | MUX_MODE2)	/* spi0_cs0.i2c1_scl */
+		>;
+	};
+
+	i2c2_pins: pinmux_i2c2_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE2)	/* spi0_clk.i2c2_sda */
+			AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE2)	/* spi0_d0.i2c2_scl */
+		>;
+	};
+
+	spi1_pins: pinmux_spi1_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x990, PIN_OUTPUT | MUX_MODE3)		/* mcasp0_aclkx.spi1_sclk */
+			AM33XX_IOPAD(0x994, PIN_OUTPUT | MUX_MODE3)		/* mcasp0_fsx.spi1_d0 */
+			AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE3)	/* mcasp0_axr0.spi1_d1 */
+			AM33XX_IOPAD(0x99C, PIN_OUTPUT | MUX_MODE3)		/* mcasp0_ahclkr.spi1_cs0 */
+		>;
+	};
+
+	uart0_pins: pinmux_uart0_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x96C, PIN_OUTPUT | MUX_MODE7)		/* uart0_rtsn.gpio1_9 */
+			AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
+			AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* uart0_txd.uart0_txd */
+		>;
+	};
+
+	uart1_pins: pinmux_uart1_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart1_rxd.uart1_rxd */
+			AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* uart1_txd.uart1_txd */
+		>;
+	};
+
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x960, PIN_INPUT_PULLUP | MUX_MODE1)	/* spi0_cs1.uart3_rxd */
+			AM33XX_IOPAD(0x964, PIN_OUTPUT_PULLDOWN | MUX_MODE1)	/* ecap0_in_pwm0_out.uart3_txd */
+		>;
+	};
+
+	clkout2_pin: pinmux_clkout2_pin {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)	/* xdma_event_intr1.clkout2 */
+		>;
+	};
+
+	cpsw_default: cpsw_default {
+		pinctrl-single,pins = <
+			/* Port 1 (emac0) */
+			AM33XX_IOPAD(0x908, PIN_INPUT | MUX_MODE0)		/* mii1_col.mii1_col */
+			AM33XX_IOPAD(0x90C, PIN_INPUT | MUX_MODE0)		/* mii1_crs.mii1_crs */
+			AM33XX_IOPAD(0x910, PIN_INPUT | MUX_MODE0)		/* mii1_rxer.mii1_rxer */
+			AM33XX_IOPAD(0x914, PIN_OUTPUT | MUX_MODE0)		/* mii1_txen.mii1_txen */
+			AM33XX_IOPAD(0x918, PIN_INPUT | MUX_MODE0)		/* mii1_rxdv.mii1_rxdv */
+			AM33XX_IOPAD(0x91c, PIN_OUTPUT | MUX_MODE0)		/* mii1_txd3.mii1_txd3 */
+			AM33XX_IOPAD(0x920, PIN_OUTPUT | MUX_MODE0)		/* mii1_txd2.mii1_txd2 */
+			AM33XX_IOPAD(0x924, PIN_OUTPUT | MUX_MODE0)		/* mii1_txd1.mii1_txd1 */
+			AM33XX_IOPAD(0x928, PIN_OUTPUT | MUX_MODE0)		/* mii1_txd0.mii1_txd0 */
+			AM33XX_IOPAD(0x92c, PIN_INPUT | MUX_MODE0)		/* mii1_txclk.mii1_txclk */
+			AM33XX_IOPAD(0x930, PIN_INPUT | MUX_MODE0)		/* mii1_rxclk.mii1_rxclk */
+			AM33XX_IOPAD(0x934, PIN_INPUT | MUX_MODE0)		/* mii1_rxd3.mii1_rxd3 */
+			AM33XX_IOPAD(0x938, PIN_INPUT | MUX_MODE0)		/* mii1_rxd2.mii1_rxd2 */
+			AM33XX_IOPAD(0x93c, PIN_INPUT | MUX_MODE0)		/* mii1_rxd1.mii1_rxd1 */
+			AM33XX_IOPAD(0x940, PIN_INPUT | MUX_MODE0)		/* mii1_rxd0.mii1_rxd0 */
+
+			/* Port 2 (emac1) */
+			AM33XX_IOPAD(0x840, PIN_OUTPUT | MUX_MODE1)		/* mii2_txen.gpmc_a0 */
+			AM33XX_IOPAD(0x844, PIN_INPUT | MUX_MODE1)		/* mii2_rxdv.gpmc_a1 */
+			AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE1)		/* mii2_txd3.gpmc_a2 */
+			AM33XX_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE1)		/* mii2_txd2.gpmc_a3 */
+			AM33XX_IOPAD(0x850, PIN_OUTPUT | MUX_MODE1)		/* mii2_txd1.gpmc_a4 */
+			AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE1)		/* mii2_txd0.gpmc_a5 */
+			AM33XX_IOPAD(0x858, PIN_INPUT | MUX_MODE1)		/* mii2_txclk.gpmc_a6 */
+			AM33XX_IOPAD(0x85c, PIN_INPUT | MUX_MODE1)		/* mii2_rxclk.gpmc_a7 */
+			AM33XX_IOPAD(0x860, PIN_INPUT | MUX_MODE1)		/* mii2_rxd3.gpmc_a8 */
+			AM33XX_IOPAD(0x864, PIN_INPUT | MUX_MODE1)		/* mii2_rxd2.gpmc_a9 */
+			AM33XX_IOPAD(0x868, PIN_INPUT | MUX_MODE1)		/* mii2_rxd1.gpmc_a10 */
+			AM33XX_IOPAD(0x86C, PIN_INPUT | MUX_MODE1)		/* mii2_rxd0.gpmc_a11 */
+			AM33XX_IOPAD(0x870, PIN_INPUT | MUX_MODE1)		/* mii2_crs.gpmc_wait0 */
+			AM33XX_IOPAD(0x874, PIN_INPUT | MUX_MODE1)		/* mii2_rxer.gpmc_wpn */
+			AM33XX_IOPAD(0x878, PIN_INPUT | MUX_MODE1)		/* mii2_col.gpmc_ben1 */
+		>;
+	};
+
+	davinci_mdio_default: davinci_mdio_default {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
+			AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
+		>;
+	};
+
+	mmc1_pins: pinmux_mmc1_pins {
+		/* eMMC */
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat3 */
+			AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat2 */
+			AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat1 */
+			AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat0 */
+			AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_clk */
+			AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_cmd */
+		>;
+	};
+
+	mmc2_pins: pinmux_mmc2_pins {
+		/* SD cardcage */
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad3.mmc1_dat3 */
+			AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad2.mmc1_dat2 */
+			AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad1.mmc1_dat1 */
+			AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad0.mmc1_dat0 */
+			AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2)	/* gpmc_csn1.mmc1_clk */
+			AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2)	/* gpmc_csn2.mmc1_cmd */
+			/* card change signal for frontpanel SD cardcage */
+			AM33XX_IOPAD(0x890, PIN_INPUT | MUX_MODE7)		/* gpmc_advn_ale.gpio2_2 */
+		>;
+	};
+
+	lcd_pins_s0: lcd_pins_s0 {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)		/* lcd_data0.lcd_data0 */
+			AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)		/* lcd_data1.lcd_data1 */
+			AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)		/* lcd_data2.lcd_data2 */
+			AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)		/* lcd_data3.lcd_data3 */
+			AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)		/* lcd_data4.lcd_data4 */
+			AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)		/* lcd_data5.lcd_data5 */
+			AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)		/* lcd_data6.lcd_data6 */
+			AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)		/* lcd_data7.lcd_data7 */
+			AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)		/* lcd_data8.lcd_data8 */
+			AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)		/* lcd_data9.lcd_data9 */
+			AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)		/* lcd_data10.lcd_data10 */
+			AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)		/* lcd_data11.lcd_data11 */
+			AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)		/* lcd_data12.lcd_data12 */
+			AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)		/* lcd_data13.lcd_data13 */
+			AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)		/* lcd_data14.lcd_data14 */
+			AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)		/* lcd_data15.lcd_data15 */
+			AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0)		/* lcd_vsync.lcd_vsync */
+			AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0)		/* lcd_hsync.lcd_hsync */
+			AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0)		/* lcd_pclk.lcd_pclk */
+			AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0)		/* lcd_ac_bias_en.lcd_ac_bias_en */
+		>;
+	};
+
+	dcan0_pins: pinmux_dcan0_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x978, PIN_OUTPUT | MUX_MODE2)		/* uart1_ctsn.d_can0_tx */
+			AM33XX_IOPAD(0x97c, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* uart1_rtsn.d_can0_rx */
+		>;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+
+	rts-gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+	rs485-rts-active-high;
+	rs485-rts-delay = <0 0>;
+	linux,rs485-enabled-at-boot-time;
+
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tps: tps@2d {
+		reg = <0x2d>;
+	};
+
+	m2_eeprom: m2_eeprom@50 {
+		compatible = "atmel,24c256";
+		reg = <0x50>;
+		status = "okay";
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+
+	status = "okay";
+	clock-frequency = <100000>;
+
+	board_24aa025e48: board_24aa025e48@50 {
+		compatible = "atmel,24c02";
+		reg = <0x50>;
+	};
+
+	backplane_24aa025e48: backplane_24aa025e48@53 {
+		compatible = "atmel,24c02";
+		reg = <0x53>;
+	};
+
+	pca9532: pca9532@60 {
+		compatible = "nxp,pca9532";
+		reg = <0x60>;
+		psc0 = <0x97>;
+		pwm0 = <0x80>;
+		psc1 = <0x97>;
+		pwm1 = <0x10>;
+
+		run.red@0 {
+			type = <PCA9532_TYPE_LED>;
+		};
+		run.green@1 {
+			type = <PCA9532_TYPE_LED>;
+			default-state = "on";
+		};
+		s2.red@2 {
+			type = <PCA9532_TYPE_LED>;
+		};
+		s2.green@3 {
+			type = <PCA9532_TYPE_LED>;
+		};
+		s1.yellow@4 {
+			type = <PCA9532_TYPE_LED>;
+		};
+		s1.green@5 {
+			type = <PCA9532_TYPE_LED>;
+		};
+	};
+
+	pca9530: pca9530@61 {
+		compatible = "nxp,pca9530";
+		reg = <0x61>;
+
+		tft-panel@0 {
+			type = <PCA9532_TYPE_LED>;
+			linux,default-trigger = "backlight";
+			default-state = "on";
+		};
+	};
+
+	mcp79400: mcp79400@6f {
+		compatible = "microchip,mcp7940x";
+		reg = <0x6f>;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+
+	status = "okay";
+	clock-frequency = <100000>;
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_pins>;
+	ti,pindir-d0-out-d1-in;
+	status = "okay";
+
+	cfaf240320a032t {
+		compatible = "orisetech,otm3225a";
+		reg = <0>;
+		spi-max-frequency = <1000000>;
+		// SPI mode 3
+		spi-cpol;
+		spi-cpha;
+		status = "okay";
+	};
+};
+
+&usb {
+	status = "okay";
+};
+
+&usb_ctrl_mod {
+	status = "okay";
+};
+
+&usb0_phy {
+	status = "okay";
+};
+
+&usb1_phy {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
+
+&cppi41dma  {
+	status = "okay";
+};
+
+/*
+ * Disable soc's rtc as we have no VBAT for it. This makes the board
+ * rtc (Microchip MCP79400) the default rtc device 'rtc0'.
+ */
+&rtc {
+	status = "disabled";
+};
+
+&lcdc {
+	status = "okay";
+};
+
+&elm {
+	status = "okay";
+};
+
+#include "tps65910.dtsi"
+
+&tps {
+	vcc1-supply = <&vbat>;
+	vcc2-supply = <&vbat>;
+	vcc3-supply = <&vbat>;
+	vcc4-supply = <&vbat>;
+	vcc5-supply = <&vbat>;
+	vcc6-supply = <&vbat>;
+	vcc7-supply = <&vbat>;
+	vccio-supply = <&vbat>;
+
+	regulators {
+		vrtc_reg: regulator@0 {
+			regulator-name = "ldo_vrtc";
+			regulator-always-on;
+		};
+
+		vio_reg: regulator@1 {
+			regulator-name = "buck_vdd_ddr";
+			regulator-always-on;
+		};
+
+		vdd1_reg: regulator@2 {
+			/* VDD_MPU voltage limits */
+			regulator-name = "buck_vdd_mpu";
+			regulator-min-microvolt = <912500>;
+			regulator-max-microvolt = <1312500>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		vdd2_reg: regulator@3 {
+			/* VDD_CORE voltage limits */
+			regulator-name = "buck_vdd_core";
+			regulator-min-microvolt = <912500>;
+			regulator-max-microvolt = <1150000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		vdd3_reg: regulator@4 {
+			regulator-name = "boost_res";
+			regulator-always-on;
+		};
+
+		vdig1_reg: regulator@5 {
+			regulator-name = "ldo_vdig1";
+			regulator-always-on;
+		};
+
+		vdig2_reg: regulator@6 {
+			regulator-name = "ldo_vdig2";
+			regulator-always-on;
+		};
+
+		vpll_reg: regulator@7 {
+			regulator-name = "ldo_vpll";
+			regulator-always-on;
+		};
+
+		vdac_reg: regulator@8 {
+			regulator-name = "ldo_vdac";
+			regulator-always-on;
+		};
+
+		vaux1_reg: regulator@9 {
+			regulator-name = "ldo_vaux1";
+			regulator-always-on;
+		};
+
+		vaux2_reg: regulator@10 {
+			regulator-name = "ldo_vaux2";
+			regulator-always-on;
+		};
+
+		vaux33_reg: regulator@11 {
+			regulator-name = "ldo_vaux33";
+			regulator-always-on;
+		};
+
+		vmmc_reg: regulator@12 {
+			regulator-name = "ldo_vmmc";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		vbb_reg: regulator@13 {
+			regulator-name = "bat_vbb";
+		};
+	};
+};
+
+&mac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&cpsw_default>;
+	dual_emac;			/* no switch, two distinct MACs */
+	status = "okay";
+};
+
+&davinci_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&davinci_mdio_default>;
+	status = "okay";
+};
+
+&cpsw_emac0 {
+	phy_id = <&davinci_mdio>, <0>;
+	phy-mode = "mii";
+	dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+	phy_id = <&davinci_mdio>, <1>;
+	phy-mode = "mii";
+	dual_emac_res_vlan = <2>;
+};
+
+&tscadc {
+	status = "okay";
+	tsc {
+		ti,wires = <4>;
+		ti,x-plate-resistance = <200>;
+		ti,coordinate-readouts = <5>;
+		ti,wire-config = <0x01 0x10 0x22 0x33>;
+		ti,charge-delay = <0x400>;
+	};
+
+	adc {
+		ti,adc-channels = <4 5 6 7>;
+	};
+};
+
+&mmc1 {
+	status = "okay";
+	vmmc-supply = <&vmmc_reg>;
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	non-removable;
+};
+
+&mmc2 {
+	status = "okay";
+	vmmc-supply = <&vmmc_reg>;
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>;
+	cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+};
+
+&sham {
+	status = "okay";
+};
+
+&aes {
+	status = "okay";
+};
+
+&dcan0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&dcan0_pins>;
+};
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 628c77b..9cd62bc2 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -147,6 +147,8 @@
 		mpu {
 			compatible = "ti,omap3-mpu";
 			ti,hwmods = "mpu";
+			pm-sram = <&pm_sram_code
+				   &pm_sram_data>;
 		};
 	};
 
@@ -905,6 +907,21 @@
 		ocmcram: ocmcram@40300000 {
 			compatible = "mmio-sram";
 			reg = <0x40300000 0x10000>; /* 64k */
+			ranges = <0x0 0x40300000 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			pm_sram_code: pm-sram-code@0 {
+				compatible = "ti,sram";
+				reg = <0x0 0x1000>;
+				protect-exec;
+			};
+
+			pm_sram_data: pm-sram-data@1000 {
+				compatible = "ti,sram";
+				reg = <0x1000 0x1000>;
+				pool;
+			};
 		};
 
 		elm: elm@48080000 {
@@ -945,6 +962,10 @@
 			compatible = "ti,emif-am3352";
 			reg = <0x4c000000 0x1000000>;
 			ti,hwmods = "emif";
+			interrupts = <101>;
+			sram = <&pm_sram_code
+				&pm_sram_data>;
+			ti,no-idle;
 		};
 
 		gpmc: gpmc@50000000 {
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 964f3ef..f0cbd86 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -92,6 +92,16 @@
 		};
 	};
 
+	soc {
+		compatible = "ti,omap-infra";
+		mpu {
+			compatible = "ti,omap4-mpu";
+			ti,hwmods = "mpu";
+			pm-sram = <&pm_sram_code
+				   &pm_sram_data>;
+		};
+	};
+
 	gic: interrupt-controller@48241000 {
 		compatible = "arm,cortex-a9-gic";
 		interrupt-controller;
@@ -143,6 +153,7 @@
 		#size-cells = <1>;
 		ranges;
 		ti,hwmods = "l3_main";
+		ti,no-idle;
 		reg = <0x44000000 0x400000
 		       0x44800000 0x400000>;
 		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
@@ -237,6 +248,10 @@
 			compatible = "ti,emif-am4372";
 			reg = <0x4c000000 0x1000000>;
 			ti,hwmods = "emif";
+			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+			ti,no-idle;
+			sram = <&pm_sram_code
+				&pm_sram_data>;
 		};
 
 		edma: edma@49000000 {
@@ -1141,6 +1156,21 @@
 		ocmcram: ocmcram@40300000 {
 			compatible = "mmio-sram";
 			reg = <0x40300000 0x40000>; /* 256k */
+			ranges = <0x0 0x40300000 0x40000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			pm_sram_code: pm-sram-code@0 {
+				compatible = "ti,sram";
+				reg = <0x0 0x1000>;
+				protect-exec;
+			};
+
+			pm_sram_data: pm-sram-data@1000 {
+				compatible = "ti,sram";
+				reg = <0x1000 0x1000>;
+				pool;
+			};
 		};
 
 		dcan0: can@481cc000 {
diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
index c3b1a3f..8fe95cd 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -805,7 +805,7 @@
 };
 
 &usb1 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts
index 3fa3b22..4118802 100644
--- a/arch/arm/boot/dts/am437x-sk-evm.dts
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -600,7 +600,7 @@
 };
 
 &usb1 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&usb1_pins>;
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index 00c3d1d..a669418 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -856,7 +856,7 @@
 };
 
 &usb1 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts
index 6d3c837..a255514 100644
--- a/arch/arm/boot/dts/am571x-idk.dts
+++ b/arch/arm/boot/dts/am571x-idk.dts
@@ -10,8 +10,8 @@
 #include "dra72x.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
-#include "am57xx-idk-common.dtsi"
 #include "dra72x-mmc-iodelay.dtsi"
+#include "am57xx-idk-common.dtsi"
 
 / {
 	model = "TI AM5718 IDK";
diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts
index 9ab0af5..3a02ed7 100644
--- a/arch/arm/boot/dts/am572x-idk.dts
+++ b/arch/arm/boot/dts/am572x-idk.dts
@@ -9,9 +9,8 @@
 /dts-v1/;
 
 #include "dra74x.dtsi"
-#include "am572x-idk-common.dtsi"
-#include "am57xx-idk-common.dtsi"
 #include "dra74x-mmc-iodelay.dtsi"
+#include "am572x-idk-common.dtsi"
 
 / {
 	model = "TI AM5728 IDK";
diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi
index ab60035..6204a26 100644
--- a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi
+++ b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi
@@ -442,6 +442,7 @@
 	pinctrl-0 = <&mmc2_pins_default>;
 
 	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	bus-width = <8>;
 	ti,non-removable;
 	cap-mmc-dual-data-rate;
diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi
index 97aa8e6..43cdf52 100644
--- a/arch/arm/boot/dts/am57xx-idk-common.dtsi
+++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi
@@ -115,6 +115,17 @@
 			DRA7XX_CORE_IOPAD(0x37d4, MUX_MODE15 | PULL_UP)	/* dcan1_rx.off */
 		>;
 	};
+
+	mmc1_pins_default: mmc1_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mmc1_clk.clk */
+			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+		>;
+	};
 };
 
 &i2c1 {
@@ -410,6 +421,7 @@
 &mmc2 {
 	status = "okay";
 	vmmc-supply = <&v3_3d>;
+	vqmmc-supply = <&v3_3d>;
 	bus-width = <8>;
 	ti,non-removable;
 	max-frequency = <96000000>;
diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts
index b67a751..d7c8419 100644
--- a/arch/arm/boot/dts/animeo_ip.dts
+++ b/arch/arm/boot/dts/animeo_ip.dts
@@ -24,7 +24,7 @@
 	};
 
 	chosen {
-		linux,stdout-path = &usart2;
+		stdout-path = &usart2;
 	};
 
 	memory {
diff --git a/arch/arm/boot/dts/arm-realview-eb.dtsi b/arch/arm/boot/dts/arm-realview-eb.dtsi
index e2e9599..a917cf8 100644
--- a/arch/arm/boot/dts/arm-realview-eb.dtsi
+++ b/arch/arm/boot/dts/arm-realview-eb.dtsi
@@ -143,6 +143,43 @@
 		port1-otg;
 	};
 
+	bridge {
+		compatible = "ti,ths8134a", "ti,ths8134";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				vga_bridge_in: endpoint {
+					remote-endpoint = <&clcd_pads>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				vga_bridge_out: endpoint {
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	vga {
+		compatible = "vga-connector";
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_bridge_out>;
+			};
+		};
+	};
+
 	/* These peripherals are inside the FPGA */
 	fpga {
 		#address-cells = <1>;
@@ -409,36 +446,15 @@
 			interrupt-names = "combined";
 			clocks = <&oscclk0>, <&pclk>;
 			clock-names = "clcdclk", "apb_pclk";
+			/* 1024x768 16bpp @65MHz works fine */
+			max-memory-bandwidth = <95000000>;
 
 			port {
 				clcd_pads: endpoint {
-					remote-endpoint = <&clcd_panel>;
+					remote-endpoint = <&vga_bridge_in>;
 					arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
 				};
 			};
-
-			panel {
-				compatible = "panel-dpi";
-
-				port {
-					clcd_panel: endpoint {
-						remote-endpoint = <&clcd_pads>;
-					};
-				};
-
-				/* Standard 640x480 VGA timings */
-				panel-timing {
-					clock-frequency = <25175000>;
-					hactive = <640>;
-					hback-porch = <48>;
-					hfront-porch = <16>;
-					hsync-len = <96>;
-					vactive = <480>;
-					vback-porch = <33>;
-					vfront-porch = <10>;
-					vsync-len = <2>;
-				};
-			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/arm-realview-pb1176.dts b/arch/arm/boot/dts/arm-realview-pb1176.dts
index c789564..f935b72 100644
--- a/arch/arm/boot/dts/arm-realview-pb1176.dts
+++ b/arch/arm/boot/dts/arm-realview-pb1176.dts
@@ -161,6 +161,43 @@
 		port1-otg;
 	};
 
+	bridge {
+		compatible = "ti,ths8134a", "ti,ths8134";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				vga_bridge_in: endpoint {
+					remote-endpoint = <&clcd_pads>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				vga_bridge_out: endpoint {
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	vga {
+		compatible = "vga-connector";
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_bridge_out>;
+			};
+		};
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -403,36 +440,15 @@
 			interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&oscclk0>, <&pclk>;
 			clock-names = "clcdclk", "apb_pclk";
+			/* 1024x768 16bpp @65MHz works fine */
+			max-memory-bandwidth = <95000000>;
 
 			port {
 				clcd_pads: endpoint {
-					remote-endpoint = <&clcd_panel>;
+					remote-endpoint = <&vga_bridge_in>;
 					arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
 				};
 			};
-
-			panel {
-				compatible = "panel-dpi";
-
-				port {
-					clcd_panel: endpoint {
-						remote-endpoint = <&clcd_pads>;
-					};
-				};
-
-				/* Standard 640x480 VGA timings */
-				panel-timing {
-					clock-frequency = <25175000>;
-					hactive = <640>;
-					hback-porch = <48>;
-					hfront-porch = <16>;
-					hsync-len = <96>;
-					vactive = <480>;
-					vback-porch = <33>;
-					vfront-porch = <10>;
-					vsync-len = <2>;
-				};
-			};
 		};
 	};
 
@@ -564,7 +580,5 @@
 			clocks = <&pclk>;
 			clock-names = "apb_pclk";
 		};
-
-
 	};
 };
diff --git a/arch/arm/boot/dts/arm-realview-pb11mp.dts b/arch/arm/boot/dts/arm-realview-pb11mp.dts
index 3944765..3620328 100644
--- a/arch/arm/boot/dts/arm-realview-pb11mp.dts
+++ b/arch/arm/boot/dts/arm-realview-pb11mp.dts
@@ -242,6 +242,49 @@
 		bank-width = <4>;
 	};
 
+	bridge {
+		compatible = "ti,ths8134a", "ti,ths8134";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				vga_bridge_in: endpoint {
+					remote-endpoint = <&clcd_pads>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				vga_bridge_out: endpoint {
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	vga {
+		/*
+		 * This DDC I2C is connected directly to the DVI portions
+		 * of the connector, so it's not really working when the
+		 * monitor is connected to the VGA connector.
+		 */
+		compatible = "vga-connector";
+		ddc-i2c-bus = <&i2c1>;
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_bridge_out>;
+			};
+		};
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -575,6 +618,13 @@
 			clock-names = "apb_pclk";
 		};
 
+		i2c1: i2c@10016000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "arm,versatile-i2c";
+			reg = <0x10016000 0x1000>;
+		};
+
 		rtc: rtc@10017000 {
 			compatible = "arm,pl031", "arm,primecell";
 			reg = <0x10017000 0x1000>;
@@ -609,37 +659,15 @@
 			interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&oscclk4>, <&pclk>;
 			clock-names = "clcdclk", "apb_pclk";
-			max-memory-bandwidth = <130000000>; /* 16bpp @ 63.5MHz */
+			/* 1024x768 16bpp @65MHz works fine */
+			max-memory-bandwidth = <95000000>;
 
 			port {
 				clcd_pads: endpoint {
-					remote-endpoint = <&clcd_panel>;
+					remote-endpoint = <&vga_bridge_in>;
 					arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
 				};
 			};
-
-			panel {
-				compatible = "panel-dpi";
-
-				port {
-					clcd_panel: endpoint {
-						remote-endpoint = <&clcd_pads>;
-					};
-				};
-
-				/* Standard 640x480 VGA timings */
-				panel-timing {
-					clock-frequency = <25175000>;
-					hactive = <640>;
-					hback-porch = <48>;
-					hfront-porch = <16>;
-					hsync-len = <96>;
-					vactive = <480>;
-					vback-porch = <33>;
-					vfront-porch = <10>;
-					vsync-len = <2>;
-				};
-			};
 		};
 
 		/*
diff --git a/arch/arm/boot/dts/arm-realview-pbx.dtsi b/arch/arm/boot/dts/arm-realview-pbx.dtsi
index aeb49c4..10868ba 100644
--- a/arch/arm/boot/dts/arm-realview-pbx.dtsi
+++ b/arch/arm/boot/dts/arm-realview-pbx.dtsi
@@ -34,7 +34,8 @@
 		serial1 = &serial1;
 		serial2 = &serial2;
 		serial3 = &serial3;
-		i2c0 = &i2c;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
 	};
 
 	memory {
@@ -158,6 +159,49 @@
 		port1-otg;
 	};
 
+	bridge {
+		compatible = "ti,ths8134a", "ti,ths8134";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				vga_bridge_in: endpoint {
+					remote-endpoint = <&clcd_pads>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				vga_bridge_out: endpoint {
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	vga {
+		/*
+		 * This DDC I2C is connected directly to the DVI portions
+		 * of the connector, so it's not really working when the
+		 * monitor is connected to the VGA connector.
+		 */
+		compatible = "vga-connector";
+		ddc-i2c-bus = <&i2c1>;
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_bridge_out>;
+			};
+		};
+	};
+
 	soc: soc@0 {
 		compatible = "arm,realview-pbx-soc", "simple-bus";
 		#address-cells = <1>;
@@ -285,7 +329,7 @@
 					       <&timclk>;
 		};
 
-		i2c: i2c@10002000 {
+		i2c0: i2c@10002000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "arm,versatile-i2c";
@@ -396,7 +440,12 @@
 			clock-names = "apb_pclk";
 		};
 
-		/* DVI serial bus control is at 10016000 */
+		i2c1: i2c@10016000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "arm,versatile-i2c";
+			reg = <0x10016000 0x1000>;
+		};
 
 		rtc: rtc@10017000 {
 			compatible = "arm,pl031", "arm,primecell";
@@ -506,36 +555,15 @@
 			interrupt-names = "combined";
 			clocks = <&oscclk4>, <&pclk>;
 			clock-names = "clcdclk", "apb_pclk";
+			/* 1024x768 16bpp @65MHz works fine */
+			max-memory-bandwidth = <95000000>;
 
 			port {
 				clcd_pads: endpoint {
-					remote-endpoint = <&clcd_panel>;
+					remote-endpoint = <&vga_bridge_in>;
 					arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
 				};
 			};
-
-			panel {
-				compatible = "panel-dpi";
-
-				port {
-					clcd_panel: endpoint {
-						remote-endpoint = <&clcd_pads>;
-					};
-				};
-
-				/* Standard 640x480 VGA timings */
-				panel-timing {
-					clock-frequency = <25175000>;
-					hactive = <640>;
-					hback-porch = <48>;
-					hfront-porch = <16>;
-					hsync-len = <96>;
-					vactive = <480>;
-					vback-porch = <33>;
-					vfront-porch = <10>;
-					vsync-len = <2>;
-				};
-			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index c4eef732..afe4609 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada 370 evaluation board
  * (DB-88F6710-BP-DDR3)
@@ -8,44 +9,6 @@
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Note: this Device Tree assumes that the bootloader has remapped the
  * internal registers to 0xf1000000 (instead of the default
  * 0xd0000000). The 0xf1000000 is the default used by the recent,
diff --git a/arch/arm/boot/dts/armada-370-dlink-dns327l.dts b/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
index db7f3aa3..8e46f63 100644
--- a/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
+++ b/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for D-Link DNS-327L
  *
  * Copyright (C) 2015, Andrew Andrianov <andrew@ncrmnt.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /* Remaining unsolved:
diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
index 702f58c..996f31b 100644
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Globalscale Mirabox
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
index b1a96e9..5663480 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for NETGEAR ReadyNAS 102
  *
  * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
@@ -103,7 +66,7 @@
 
 				status = "okay";
 
-				isl12057: isl12057@68 {
+				isl12057: rtc@68 {
 					compatible = "isil,isl12057";
 					reg = <0x68>;
 					wakeup-source;
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
index d67e7aa..16d0307 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for NETGEAR ReadyNAS 104
  *
  * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
@@ -105,7 +68,7 @@
 
 				status = "okay";
 
-				isl12057: isl12057@68 {
+				isl12057: rtc@68 {
 					compatible = "isil,isl12057";
 					reg = <0x68>;
 					wakeup-source;
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
index c28afb2..cc2f774 100644
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada 370 Reference Design board
  * (RD-88F6710-A1)
@@ -6,44 +7,6 @@
  *
  *  Copyright (C) 2013 Florian Fainelli <florian@openwrt.org>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Note: this Device Tree assumes that the bootloader has remapped the
  * internal registers to 0xf1000000 (instead of the default
  * 0xd0000000). The 0xf1000000 is the default used by the recent,
diff --git a/arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts b/arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts
index fef0110..8dd242e 100644
--- a/arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts
+++ b/arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for Seagate NAS 2-Bay (Armada 370 SoC).
  *
  * Copyright (C) 2015 Seagate
  *
  * Author: Vincent Donnefort <vdonnefort@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /*
diff --git a/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts b/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts
index eb6af53..3cf70c7 100644
--- a/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts
+++ b/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for Seagate NAS 4-Bay (Armada 370 SoC).
  *
  * Copyright (C) 2015 Seagate
  *
  * Author: Vincent Donnefort <vdonnefort@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /*
diff --git a/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi b/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi
index e9a5b95..a5206db 100644
--- a/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi
+++ b/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree common file for the Seagate NAS 2 and 4-bay (Armada 370 SoC).
  *
  * Copyright (C) 2015 Seagate
  *
  * Author: Vincent Donnefort <vdonnefort@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /*
diff --git a/arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts b/arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts
index 3c91f98..5ee572d 100644
--- a/arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts
+++ b/arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for Seagate Personal Cloud NAS 2-Bay (Armada 370 SoC).
  *
  * Copyright (C) 2015 Seagate
  *
  * Author: Simon Guinot <simon.guinot@sequanux.org>
- *
- * 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.
  */
 
 /*
diff --git a/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts
index aad39e9..578b54b 100644
--- a/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts
+++ b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for Seagate Personal Cloud NAS (Armada 370 SoC).
  *
  * Copyright (C) 2015 Seagate
  *
  * Author: Simon Guinot <simon.guinot@sequanux.org>
- *
- * 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.
  */
 
 /*
diff --git a/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi
index d079a89..a624b23 100644
--- a/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi
+++ b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree common file for the Seagate Personal Cloud NAS 1 and 2-Bay
  * (Armada 370 SoC).
@@ -5,10 +6,6 @@
  * Copyright (C) 2015 Seagate
  *
  * Author: Simon Guinot <simon.guinot@sequanux.org>
- *
- * 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.
  */
 
 /*
diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
index 9504081..64f2ce2 100644
--- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts
+++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Synology DS213j
  *
  * Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Note: this Device Tree assumes that the bootloader has remapped the
  * internal registers to 0xf1000000 (instead of the old 0xd0000000).
  * The 0xf1000000 is the default used by the recent, DT-capable, U-Boot
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 09495e8..11fc327 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 370 and Armada XP SoC
  *
@@ -8,44 +9,6 @@
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  * Ben Dooks <ben.dooks@codethink.co.uk>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * This file contains the definitions that are common to the Armada
  * 370 and Armada XP SoC.
  */
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index b1cf5a2..46e6d3e 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 370 family SoC
  *
@@ -7,44 +8,6 @@
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Contains definitions specific to the Armada 370 SoC that are not
  * common to all Armada SoCs.
  */
diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts
index bcdbb8b..e4ecd7e 100644
--- a/arch/arm/boot/dts/armada-375-db.dts
+++ b/arch/arm/boot/dts/armada-375-db.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada 375 evaluation board
  * (DB-88F6720)
@@ -6,44 +7,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
index 2cb1bcd..53ead6f 100644
--- a/arch/arm/boot/dts/armada-375.dtsi
+++ b/arch/arm/boot/dts/armada-375.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 375 family SoC
  *
@@ -5,44 +6,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi
index 132596f..cff1269 100644
--- a/arch/arm/boot/dts/armada-380.dtsi
+++ b/arch/arm/boot/dts/armada-380.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 380 SoC.
  *
@@ -6,44 +7,6 @@
  * Lior Amsalem <alior@marvell.com>
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "armada-38x.dtsi"
diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts
index 678aa02..d294f24 100644
--- a/arch/arm/boot/dts/armada-385-db-ap.dts
+++ b/arch/arm/boot/dts/armada-385-db-ap.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for Marvell Armada 385 Access Point Development board
  * (DB-88F6820-AP)
@@ -5,38 +6,6 @@
  *  Copyright (C) 2014 Marvell
  *
  * Nadav Haklai <nadavh@marvell.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-385-linksys-caiman.dts b/arch/arm/boot/dts/armada-385-linksys-caiman.dts
index ee669ae..1f30993 100644
--- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts
+++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts
@@ -1,40 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree include for the Linksys WRT1200AC (Caiman)
  *
  * Copyright (C) 2015 Imre Kaloz <kaloz@openwrt.org>
- *
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-385-linksys-cobra.dts b/arch/arm/boot/dts/armada-385-linksys-cobra.dts
index 5169ca8..bc34802 100644
--- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts
+++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts
@@ -1,40 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for the Linksys WRT1900ACv2 (Cobra)
  *
  * Copyright (C) 2015 Imre Kaloz <kaloz@openwrt.org>
- *
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-385-linksys-rango.dts b/arch/arm/boot/dts/armada-385-linksys-rango.dts
index da8a0f3..5b745a0 100644
--- a/arch/arm/boot/dts/armada-385-linksys-rango.dts
+++ b/arch/arm/boot/dts/armada-385-linksys-rango.dts
@@ -1,40 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for the Linksys WRT3200ACM (Rango)
  *
  * Copyright (C) 2016 Imre Kaloz <kaloz@openwrt.org>
- *
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-385-linksys-shelby.dts b/arch/arm/boot/dts/armada-385-linksys-shelby.dts
index 94aa35b..44f5aeb 100644
--- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts
+++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts
@@ -1,40 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for the Linksys WRT1900ACS (Shelby)
  *
  * Copyright (C) 2015 Imre Kaloz <kaloz@openwrt.org>
- *
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi
index 434dc9a..4a0d736 100644
--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
@@ -1,40 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree include file for Armada 385 based Linksys boards
  *
  * Copyright (C) 2015 Imre Kaloz <kaloz@openwrt.org>
- *
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/gpio/gpio.h>
@@ -282,3 +250,8 @@
 	status = "okay";
 	usb-phy = <&usb3_1_phy>;
 };
+
+&rtc {
+	/* No crystal connected to the internal RTC */
+	status = "disabled";
+};
diff --git a/arch/arm/boot/dts/armada-385-synology-ds116.dts b/arch/arm/boot/dts/armada-385-synology-ds116.dts
index 0a3552e..6782ce4 100644
--- a/arch/arm/boot/dts/armada-385-synology-ds116.dts
+++ b/arch/arm/boot/dts/armada-385-synology-ds116.dts
@@ -1,39 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for Synology DS116 NAS
  *
  * Copyright (C) 2017 Willy Tarreau <w@1wt.eu>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
index 06831e1..768b6c5 100644
--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
+++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
@@ -1,43 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for the Turris Omnia
  *
  * Copyright (C) 2016 Uwe Kleine-König <uwe@kleine-koenig.org>
  * Copyright (C) 2016 Tomas Hlavacek <tmshlvkc@gmail.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Schematic available at https://www.turris.cz/doc/_media/rtrom01-schema.pdf
  */
 
diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
index 74863af..f0022d1 100644
--- a/arch/arm/boot/dts/armada-385.dtsi
+++ b/arch/arm/boot/dts/armada-385.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 385 SoC.
  *
@@ -6,44 +7,6 @@
  * Lior Amsalem <alior@marvell.com>
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "armada-38x.dtsi"
diff --git a/arch/arm/boot/dts/armada-388-clearfog-base.dts b/arch/arm/boot/dts/armada-388-clearfog-base.dts
index 22ed07fc..50ed4ae 100644
--- a/arch/arm/boot/dts/armada-388-clearfog-base.dts
+++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for SolidRun Clearfog Base revision A1 rev 2.0 (88F6828)
  *
@@ -7,43 +8,6 @@
  * the A1 rev 2.0 of the board, which does not represent final
  * production board.  Things will change, don't expect this file to
  * remain compatible info the future.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-388-clearfog-pro.dts b/arch/arm/boot/dts/armada-388-clearfog-pro.dts
index bd85870..24e4b5a 100644
--- a/arch/arm/boot/dts/armada-388-clearfog-pro.dts
+++ b/arch/arm/boot/dts/armada-388-clearfog-pro.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for SolidRun Clearfog Pro revision A1 rev 2.0 (88F6828)
  *
@@ -7,43 +8,6 @@
  * the A1 rev 2.0 of the board, which does not represent final
  * production board.  Things will change, don't expect this file to
  * remain compatible info the future.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 #include "armada-388-clearfog.dts"
 
diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts
index ee7b008..5fd0f6f 100644
--- a/arch/arm/boot/dts/armada-388-clearfog.dts
+++ b/arch/arm/boot/dts/armada-388-clearfog.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for SolidRun Clearfog Pro revision A1 rev 2.0 (88F6828)
  *
@@ -7,43 +8,6 @@
  * the A1 rev 2.0 of the board, which does not represent final
  * production board.  Things will change, don't expect this file to
  * remain compatible info the future.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-388-clearfog.dtsi b/arch/arm/boot/dts/armada-388-clearfog.dtsi
index 68acfc9..0d9dfdf 100644
--- a/arch/arm/boot/dts/armada-388-clearfog.dtsi
+++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree include file for SolidRun Clearfog 88F6828 based boards
  *
@@ -7,43 +8,6 @@
  * the A1 rev 2.0 of the board, which does not represent final
  * production board.  Things will change, don't expect this file to
  * remain compatible info the future.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file 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.
- *
- * Or, alternatively
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "armada-388.dtsi"
@@ -117,6 +81,16 @@
 			};
 		};
 	};
+
+	sfp: sfp {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c1>;
+		los-gpio = <&expander0 12 GPIO_ACTIVE_HIGH>;
+		mod-def0-gpio = <&expander0 15 GPIO_ACTIVE_LOW>;
+		tx-disable-gpio = <&expander0 14 GPIO_ACTIVE_HIGH>;
+		tx-fault-gpio = <&expander0 13 GPIO_ACTIVE_HIGH>;
+		maximum-power-milliwatt = <2000>;
+	};
 };
 
 &eth1 {
@@ -133,18 +107,14 @@
 	bm,pool-long = <3>;
 	bm,pool-short = <1>;
 	buffer-manager = <&bm>;
+	managed = "in-band-status";
 	phy-mode = "sgmii";
+	sfp = <&sfp>;
 	status = "okay";
-
-	fixed-link {
-		speed = <1000>;
-		full-duplex;
-	};
 };
 
 &i2c0 {
-	/* Is there anything on this? */
-	clock-frequency = <100000>;
+	clock-frequency = <400000>;
 	pinctrl-0 = <&i2c0_pins>;
 	pinctrl-names = "default";
 	status = "okay";
@@ -209,43 +179,13 @@
 			output-low;
 			line-name = "m.2 devslp";
 		};
-		sfp_los {
-			/* SFP loss of signal */
-			gpio-hog;
-			gpios = <12 GPIO_ACTIVE_HIGH>;
-			input;
-			line-name = "sfp-los";
-		};
-		sfp_tx_fault {
-			/* SFP laser fault */
-			gpio-hog;
-			gpios = <13 GPIO_ACTIVE_HIGH>;
-			input;
-			line-name = "sfp-tx-fault";
-		};
-		sfp_tx_disable {
-			/* SFP transmit disable */
-			gpio-hog;
-			gpios = <14 GPIO_ACTIVE_HIGH>;
-			output-low;
-			line-name = "sfp-tx-disable";
-		};
-		sfp_mod_def0 {
-			/* SFP module present */
-			gpio-hog;
-			gpios = <15 GPIO_ACTIVE_LOW>;
-			input;
-			line-name = "sfp-mod-def0";
-		};
 	};
 
-	/* The MCP3021 is 100kHz clock only */
+	/* The MCP3021 supports standard and fast modes */
 	mikrobus_adc: mcp3021@4c {
 		compatible = "microchip,mcp3021";
 		reg = <0x4c>;
 	};
-
-	/* Also something at 0x64 */
 };
 
 &i2c1 {
diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts
index a4ec1fa..05250d4 100644
--- a/arch/arm/boot/dts/armada-388-db.dts
+++ b/arch/arm/boot/dts/armada-388-db.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada 388 evaluation board
  * (DB-88F6820)
@@ -5,44 +6,6 @@
  *  Copyright (C) 2014 Marvell
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts
index 51b4ee6..9d87325 100644
--- a/arch/arm/boot/dts/armada-388-gp.dts
+++ b/arch/arm/boot/dts/armada-388-gp.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for Marvell Armada 385 development board
  * (RD-88F6820-GP)
@@ -5,38 +6,6 @@
  * Copyright (C) 2014 Marvell
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-388-rd.dts b/arch/arm/boot/dts/armada-388-rd.dts
index 9cc3ca0..328a4d6 100644
--- a/arch/arm/boot/dts/armada-388-rd.dts
+++ b/arch/arm/boot/dts/armada-388-rd.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada 388 Reference Design board
  * (RD-88F6820-AP)
@@ -6,44 +7,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-388.dtsi b/arch/arm/boot/dts/armada-388.dtsi
index 1c0d151..f3a020f 100644
--- a/arch/arm/boot/dts/armada-388.dtsi
+++ b/arch/arm/boot/dts/armada-388.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 388 SoC.
  *
@@ -5,39 +6,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
- *
  * The main difference with the Armada 385 is that the 388 can handle two more
  * SATA ports. So we can reuse the dtsi of the Armada 385, override the pinctrl
  * property and the name of the SoC, and add the second SATA host which control
diff --git a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
index 9b508a8..2d1cea1 100644
--- a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
+++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for SolidRun Armada 38x Microsom
  *
@@ -7,43 +8,6 @@
  * the A1 rev 2.0 of the board, which does not represent final
  * production board.  Things will change, don't expect this file to
  * remain compatible info the future.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index a6cc568..4cc09e4 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 38x family of SoCs.
  *
@@ -6,44 +7,6 @@
  * Lior Amsalem <alior@marvell.com>
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "skeleton.dtsi"
diff --git a/arch/arm/boot/dts/armada-390-db.dts b/arch/arm/boot/dts/armada-390-db.dts
index c718a52..1b2362e 100644
--- a/arch/arm/boot/dts/armada-390-db.dts
+++ b/arch/arm/boot/dts/armada-390-db.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada 390 Development Board
  * (DB-88F6920)
@@ -5,44 +6,6 @@
  * Copyright (C) 2016 Marvell
  *
  * Grzegorz Jaszczyk <jaz@semihalf.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-390.dtsi b/arch/arm/boot/dts/armada-390.dtsi
index 0d8a54a..aa2057d 100644
--- a/arch/arm/boot/dts/armada-390.dtsi
+++ b/arch/arm/boot/dts/armada-390.dtsi
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 390 SoC.
  *
  * Copyright (C) 2015 Marvell
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "armada-39x.dtsi"
diff --git a/arch/arm/boot/dts/armada-395-gp.dts b/arch/arm/boot/dts/armada-395-gp.dts
index ef491b5..2a9de19 100644
--- a/arch/arm/boot/dts/armada-395-gp.dts
+++ b/arch/arm/boot/dts/armada-395-gp.dts
@@ -1,41 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for Marvell Armada 395 GP board
  *
  * Copyright (C) 2016 Marvell
  *
  * Grzegorz Jaszczyk <jaz@semihalf.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-395.dtsi b/arch/arm/boot/dts/armada-395.dtsi
index bf7e433..e18a7d9 100644
--- a/arch/arm/boot/dts/armada-395.dtsi
+++ b/arch/arm/boot/dts/armada-395.dtsi
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 395 SoC.
  *
  * Copyright (C) 2016 Marvell
  *
  * Grzegorz Jaszczyk <jaz@semihalf.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "armada-39x.dtsi"
diff --git a/arch/arm/boot/dts/armada-398-db.dts b/arch/arm/boot/dts/armada-398-db.dts
index f0e0379..2337f24 100644
--- a/arch/arm/boot/dts/armada-398-db.dts
+++ b/arch/arm/boot/dts/armada-398-db.dts
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 398 Development Board
  *
  * Copyright (C) 2015 Marvell
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-398.dtsi b/arch/arm/boot/dts/armada-398.dtsi
index 1f4e113..c5ac893 100644
--- a/arch/arm/boot/dts/armada-398.dtsi
+++ b/arch/arm/boot/dts/armada-398.dtsi
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 398 SoC.
  *
  * Copyright (C) 2015 Marvell
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "armada-395.dtsi"
diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi
index 5218bd2..c1737c0 100644
--- a/arch/arm/boot/dts/armada-39x.dtsi
+++ b/arch/arm/boot/dts/armada-39x.dtsi
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 39x family of SoCs.
  *
  * Copyright (C) 2015 Marvell
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "skeleton.dtsi"
diff --git a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi
index bdd4c7a..a5da44f 100644
--- a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi
+++ b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell 98dx3236 family SoC
  *
  * Copyright (C) 2016 Allied Telesis Labs
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Contains definitions specific to the 98dx3236 SoC that are not
  * common to all Armada XP SoCs.
  */
diff --git a/arch/arm/boot/dts/armada-xp-98dx3336.dtsi b/arch/arm/boot/dts/armada-xp-98dx3336.dtsi
index a0d81bd..2f5fc67 100644
--- a/arch/arm/boot/dts/armada-xp-98dx3336.dtsi
+++ b/arch/arm/boot/dts/armada-xp-98dx3336.dtsi
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell 98dx3336 family SoC
  *
  * Copyright (C) 2016 Allied Telesis Labs
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Contains definitions specific to the 98dx3236 SoC that are not
  * common to all Armada XP SoCs.
  */
diff --git a/arch/arm/boot/dts/armada-xp-98dx4251.dtsi b/arch/arm/boot/dts/armada-xp-98dx4251.dtsi
index bc9f824..7a9e883 100644
--- a/arch/arm/boot/dts/armada-xp-98dx4251.dtsi
+++ b/arch/arm/boot/dts/armada-xp-98dx4251.dtsi
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell 98dx4521 family SoC
  *
  * Copyright (C) 2016 Allied Telesis Labs
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Contains definitions specific to the 98dx4521 SoC that are not
  * common to all Armada XP SoCs.
  */
diff --git a/arch/arm/boot/dts/armada-xp-axpwifiap.dts b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
index d0c6a01..606fd34 100644
--- a/arch/arm/boot/dts/armada-xp-axpwifiap.dts
+++ b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell RD-AXPWiFiAP.
  *
@@ -9,44 +10,6 @@
  * Copyright (C) 2013 Marvell
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-db-dxbc2.dts b/arch/arm/boot/dts/armada-xp-db-dxbc2.dts
index 1b1ff17..4c64923f 100644
--- a/arch/arm/boot/dts/armada-xp-db-dxbc2.dts
+++ b/arch/arm/boot/dts/armada-xp-db-dxbc2.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for DB-DXBC2 board
  *
@@ -5,44 +6,6 @@
  *
  * Based on armada-xp-db.dts
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Note: this Device Tree assumes that the bootloader has remapped the
  * internal registers to 0xf1000000 (instead of the default
  * 0xd0000000). The 0xf1000000 is the default used by the recent,
diff --git a/arch/arm/boot/dts/armada-xp-db-xc3-24g4xg.dts b/arch/arm/boot/dts/armada-xp-db-xc3-24g4xg.dts
index 06fce35..a0ebb52 100644
--- a/arch/arm/boot/dts/armada-xp-db-xc3-24g4xg.dts
+++ b/arch/arm/boot/dts/armada-xp-db-xc3-24g4xg.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for DB-XC3-24G4XG board
  *
@@ -5,44 +6,6 @@
  *
  * Based on armada-xp-db.dts
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Note: this Device Tree assumes that the bootloader has remapped the
  * internal registers to 0xf1000000 (instead of the default
  * 0xd0000000). The 0xf1000000 is the default used by the recent,
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index 065282c..73d3f5c 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada XP evaluation board
  * (DB-78460-BP)
@@ -8,43 +9,6 @@
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
   *
  * Note: this Device Tree assumes that the bootloader has remapped the
  * internal registers to 0xf1000000 (instead of the default
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index ac9eab8..c143556 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada XP development board
  * (DB-MV784MP-GP)
@@ -8,44 +9,6 @@
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Note: this Device Tree assumes that the bootloader has remapped the
  * internal registers to 0xf1000000 (instead of the default
  * 0xd0000000). The 0xf1000000 is the default used by the recent,
diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
index ce0afba1..def62e9 100644
--- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
+++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Lenovo Iomega ix4-300d
  *
  * Copyright (C) 2014, Benoit Masson <yahoo@perenite.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
index 6d705f5..f8b60d9 100644
--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Device Tree file for the Linksys WRT1900AC (Mamba).
  *
@@ -13,38 +14,6 @@
  *     Copyright (C) 2013 Marvell
  *
  *     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts
index 977f6b3..1395cea 100644
--- a/arch/arm/boot/dts/armada-xp-matrix.dts
+++ b/arch/arm/boot/dts/armada-xp-matrix.dts
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada XP Matrix board
  *
  * Copyright (C) 2013 Marvell
  *
  * Lior Amsalem <alior@marvell.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
index 129738f..8558bf6 100644
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada XP family SoC
  *
@@ -5,44 +6,6 @@
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Contains definitions specific to the Armada XP MV78230 SoC that are not
  * common to all Armada XP SoCs.
  */
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
index e58d597..2d85fe8 100644
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada XP family SoC
  *
@@ -5,44 +6,6 @@
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Contains definitions specific to the Armada XP MV78260 SoC that are not
  * common to all Armada XP SoCs.
  */
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
index a5c961c..230a3fd 100644
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada XP family SoC
  *
@@ -5,44 +6,6 @@
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Contains definitions specific to the Armada XP MV78460 SoC that are not
  * common to all Armada XP SoCs.
  */
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
index 40c6fe2..c350b1c 100644
--- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
+++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for NETGEAR ReadyNAS 2120
  *
  * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
@@ -115,7 +78,7 @@
 					reg = <0x4c>;
 				};
 
-				isl12057: isl12057@68 {
+				isl12057: rtc@68 {
 					compatible = "isil,isl12057";
 					reg = <0x68>;
 					wakeup-source;
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
index 66b7813..0efcc16 100644
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for OpenBlocks AX3-4 board
  *
  * Copyright (C) 2012 Marvell
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-synology-ds414.dts b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
index d7228a5..809e821 100644
--- a/arch/arm/boot/dts/armada-xp-synology-ds414.dts
+++ b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Synology DS414
  *
  * Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Note: this Device Tree assumes that the bootloader has remapped the
  * internal registers to 0xf1000000 (instead of the old 0xd0000000).
  * The 0xf1000000 is the default used by the recent, DT-capable, U-Boot
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index fa1e881..ee15c77 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada XP family SoC
  *
@@ -8,44 +9,6 @@
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  * Ben Dooks <ben.dooks@codethink.co.uk>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * Contains definitions specific to the Armada XP SoC that are not
  * common to all Armada SoCs.
  */
diff --git a/arch/arm/boot/dts/artpec6-devboard.dts b/arch/arm/boot/dts/artpec6-devboard.dts
index 9dfe845..d20d953 100644
--- a/arch/arm/boot/dts/artpec6-devboard.dts
+++ b/arch/arm/boot/dts/artpec6-devboard.dts
@@ -26,7 +26,7 @@
 
 	memory {
 		device_type = "memory";
-		reg = <0x0 0x10000000>;
+		reg = <0x0 0x40000000>;
 	};
 };
 
@@ -59,6 +59,7 @@
 	mdio {
 		#address-cells = <0x1>;
 		#size-cells = <0x0>;
+		compatible = "snps,dwmac-mdio";
 		phy1: phy@0 {
 			compatible = "ethernet-phy-ieee802.3-c22";
 			device_type = "ethernet-phy";
diff --git a/arch/arm/boot/dts/artpec6.dtsi b/arch/arm/boot/dts/artpec6.dtsi
index 2ed1177..3e4115c 100644
--- a/arch/arm/boot/dts/artpec6.dtsi
+++ b/arch/arm/boot/dts/artpec6.dtsi
@@ -41,6 +41,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/dma/nbpfaxi.h>
 #include <dt-bindings/clock/axis,artpec6-clkctrl.h>
 #include "skeleton.dtsi"
 
@@ -98,7 +99,7 @@
 		clock-frequency = <125000000>;
 	};
 
-	clkctrl: clkctrl@0xf8000000 {
+	clkctrl: clkctrl@f8000000 {
 		#clock-cells = <1>;
 		compatible = "axis,artpec6-clkctrl";
 		reg = <0xf8000000 0x48>;
@@ -153,6 +154,10 @@
 		interrupt-affinity = <&cpu0>, <&cpu1>;
 	};
 
+	/*
+	 * Both pci nodes cannot be enabled at the same time,
+	 * leave the unwanted node as disabled.
+	 */
 	pcie: pcie@f8050000 {
 		compatible = "axis,artpec6-pcie", "snps,dw-pcie";
 		reg = <0xf8050000 0x2000
@@ -180,28 +185,146 @@
 		status = "disabled";
 	};
 
+	pcie_ep: pcie_ep@f8050000 {
+		compatible = "axis,artpec6-pcie-ep", "snps,dw-pcie";
+		reg = <0xf8050000 0x2000
+		       0xf8051000 0x2000
+		       0xf8040000 0x1000
+		       0xc0000000 0x20000000>;
+		reg-names = "dbi", "dbi2", "phy", "addr_space";
+		num-ib-windows = <6>;
+		num-ob-windows = <2>;
+		num-lanes = <2>;
+		axis,syscon-pcie = <&syscon>;
+		status = "disabled";
+	};
+
+	pinctrl: pinctrl@f801d000 {
+		compatible = "axis,artpec6-pinctrl";
+		reg = <0xf801d000 0x400>;
+
+		pinctrl_uart0: uart0grp {
+			function = "uart0";
+			groups = "uart0grp2";
+			bias-pull-up;
+		};
+		pinctrl_uart1: uart1grp {
+			function = "uart1";
+			groups = "uart1grp0";
+			bias-pull-up;
+		};
+		pinctrl_uart2: uart2grp {
+			function = "uart2";
+			groups = "uart2grp1";
+			bias-pull-up;
+		};
+		pinctrl_uart3: uart3grp {
+			function = "uart3";
+			groups = "uart3grp0";
+			bias-pull-up;
+		};
+	};
+
 	amba@0 {
 		compatible = "simple-bus";
 		#address-cells = <0x1>;
 		#size-cells = <0x1>;
 		ranges;
-		dma-ranges = <0x80000000 0x00000000 0x40000000>;
-		dma-coherent;
+		dma-ranges;
+
+		crypto@f4264000 {
+			compatible = "axis,artpec6-crypto";
+			reg = <0xf4264000 0x4000>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		dma0: dma@f8019000 {
+			compatible = "renesas,nbpfaxi64dmac8b16";
+			reg = <0xf8019000 0x400>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* error */
+				     <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch12",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&clkctrl ARTPEC6_CLK_DMA_ACLK>;
+			#dma-cells = <2>;
+			dma-channels = <8>;
+			dma-requests = <8>;
+		};
+		dma1: dma@f8019400 {
+			compatible = "renesas,nbpfaxi64dmac8b16";
+			reg = <0xf8019400 0x400>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* error */
+				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch12",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&clkctrl ARTPEC6_CLK_DMA_ACLK>;
+			#dma-cells = <2>;
+			dma-channels = <8>;
+			dma-requests = <8>;
+		};
 
 		ethernet: ethernet@f8010000 {
-			clock-names = "phy_ref_clk", "apb_pclk";
-			clocks = <&eth_phy_ref_clk>,
-				<&clkctrl ARTPEC6_CLK_ETH_ACLK>;
-			compatible = "snps,dwc-qos-ethernet-4.10";
-			interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "stmmaceth", "ptp_ref";
+			clocks = <&clkctrl ARTPEC6_CLK_ETH_ACLK>,
+				<&clkctrl ARTPEC6_CLK_PTP_REF>;
+			compatible = "snps,dwmac-4.10a", "snps,dwmac";
+			interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq", "eth_lpi";
 			reg = <0xf8010000 0x4000>;
 
-			snps,write-requests = <2>;
-			snps,read-requests = <16>;
+			snps,axi-config = <&stmmac_axi_setup>;
+			snps,mtl-rx-config = <&mtl_rx_setup>;
+			snps,mtl-tx-config = <&mtl_tx_setup>;
+
 			snps,txpbl = <8>;
 			snps,rxpbl = <2>;
+			snps,aal;
+			snps,tso;
 
 			status = "disabled";
+
+			stmmac_axi_setup: stmmac-axi-config {
+				snps,wr_osr_lmt = <1>;
+				snps,rd_osr_lmt = <15>;
+				/* If FB is disabled, the AXI master chooses
+				 * a burst length of any value less than the
+				 * maximum enabled burst length
+				 * (all lesser burst length enables are redundant).
+				 */
+				snps,blen = <0 0 0 0 16 0 0>;
+			};
+
+			mtl_rx_setup: rx-queues-config {
+				snps,rx-queues-to-use = <1>;
+				queue0 {};
+			};
+
+			mtl_tx_setup: tx-queues-config {
+				snps,tx-queues-to-use = <2>;
+				queue0 {};
+				queue1 {};
+			};
 		};
 
 		uart0: serial@f8036000 {
@@ -211,6 +334,11 @@
 			clocks = <&clkctrl ARTPEC6_CLK_UART_REFCLK>,
 				<&clkctrl ARTPEC6_CLK_UART_PCLK>;
 			clock-names = "uart_clk", "apb_pclk";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart0>;
+			dmas = <&dma0 4 (NBPF_SLAVE_RQ_HIGH | NBPF_SLAVE_RQ_LEVEL)>,
+			       <&dma0 5 (NBPF_SLAVE_RQ_HIGH | NBPF_SLAVE_RQ_LEVEL)>;
+			dma-names = "rx", "tx";
 			status = "disabled";
 		};
 		uart1: serial@f8037000 {
@@ -220,6 +348,11 @@
 			clocks = <&clkctrl ARTPEC6_CLK_UART_REFCLK>,
 				<&clkctrl ARTPEC6_CLK_UART_PCLK>;
 			clock-names = "uart_clk", "apb_pclk";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart1>;
+			dmas = <&dma0 6 (NBPF_SLAVE_RQ_HIGH | NBPF_SLAVE_RQ_LEVEL)>,
+			       <&dma0 7 (NBPF_SLAVE_RQ_HIGH | NBPF_SLAVE_RQ_LEVEL)>;
+			dma-names = "rx", "tx";
 			status = "disabled";
 		};
 		uart2: serial@f8038000 {
@@ -229,6 +362,11 @@
 			clocks = <&clkctrl ARTPEC6_CLK_UART_REFCLK>,
 				<&clkctrl ARTPEC6_CLK_UART_PCLK>;
 			clock-names = "uart_clk", "apb_pclk";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart2>;
+			dmas = <&dma1 0 (NBPF_SLAVE_RQ_HIGH | NBPF_SLAVE_RQ_LEVEL)>,
+			       <&dma1 1 (NBPF_SLAVE_RQ_HIGH | NBPF_SLAVE_RQ_LEVEL)>;
+			dma-names = "rx", "tx";
 			status = "disabled";
 		};
 		uart3: serial@f8039000 {
@@ -238,6 +376,11 @@
 			clocks = <&clkctrl ARTPEC6_CLK_UART_REFCLK>,
 				<&clkctrl ARTPEC6_CLK_UART_PCLK>;
 			clock-names = "uart_clk", "apb_pclk";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart3>;
+			dmas = <&dma1 2 (NBPF_SLAVE_RQ_HIGH | NBPF_SLAVE_RQ_LEVEL)>,
+			       <&dma1 3 (NBPF_SLAVE_RQ_HIGH | NBPF_SLAVE_RQ_LEVEL)>;
+			dma-names = "rx", "tx";
 			status = "disabled";
 		};
 	};
diff --git a/arch/arm/boot/dts/aspeed-bmc-arm-centriq2400-rep.dts b/arch/arm/boot/dts/aspeed-bmc-arm-centriq2400-rep.dts
new file mode 100644
index 0000000..df12276
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-arm-centriq2400-rep.dts
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+	model = "Qualcomm Centriq 2400  REP AST2520";
+	compatible = "qualcomm,centriq2400-rep-bmc", "aspeed,ast2500";
+
+	chosen {
+		stdout-path = &uart5;
+		bootargs = "console=ttyS4,115200 earlyprintk";
+	};
+
+	memory {
+		reg = <0x80000000 0x40000000>;
+	};
+
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
+                        <&adc 4>, <&adc 5>, <&adc 6>, <&adc 8>;
+	};
+
+	iio-hwmon-battery {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 7>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		uid_led {
+			label = "UID_LED";
+			gpios = <&gpio ASPEED_GPIO(Q, 5) GPIO_ACTIVE_LOW>;
+		};
+
+		ras_error_led {
+			label = "RAS_ERROR_LED";
+			gpios = <&gpio ASPEED_GPIO(F, 6) GPIO_ACTIVE_LOW>;
+		};
+
+		system_fault {
+			label = "System_fault";
+			gpios = <&gpio ASPEED_GPIO(A, 1) GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&fmc {
+	status = "okay";
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "bmc";
+#include "openbmc-flash-layout.dtsi"
+	};
+};
+
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+	flash@0 {
+		status = "okay";
+	};
+};
+
+&spi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi2ck_default
+			&pinctrl_spi2miso_default
+			&pinctrl_spi2mosi_default
+			&pinctrl_spi2cs0_default>;
+};
+
+&uart3 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_txd3_default &pinctrl_rxd3_default>;
+	current-speed = <115200>;
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&mac0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+};
+
+&i2c0 {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+
+	tmp421@1e {
+		compatible = "ti,tmp421";
+		reg = <0x1e>;
+	};
+	tmp421@2a {
+		compatible = "ti,tmp421";
+		reg = <0x2a>;
+	};
+	tmp421@4e {
+		compatible = "ti,tmp421";
+		reg = <0x4e>;
+	};
+	tmp421@1c {
+		compatible = "ti,tmp421";
+		reg = <0x1c>;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+};
+
+&i2c4 {
+	status = "okay";
+};
+
+&i2c5 {
+	status = "okay";
+};
+
+&i2c6 {
+	status = "okay";
+
+	tmp421@1d {
+		compatible = "ti,tmp421";
+		reg = <0x1d>;
+	};
+	tmp421@1f {
+		compatible = "ti,tmp421";
+		reg = <0x1f>;
+	};
+	tmp421@4d {
+		compatible = "ti,tmp421";
+		reg = <0x4d>;
+	};
+	tmp421@4f {
+		compatible = "ti,tmp421";
+		reg = <0x4f>;
+	};
+	nvt210@4c {
+		compatible = "nvt210";
+		reg = <0x4c>;
+	};
+	eeprom@50 {
+		compatible = "atmel,24c128";
+		reg = <0x50>;
+		pagesize = <128>;
+	};
+};
+
+&i2c7 {
+	status = "okay";
+};
+
+&i2c8 {
+	status = "okay";
+
+	pca9641@70 {
+		compatible = "nxp,pca9641";
+		reg = <0x70>;
+		i2c-arb {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			tmp421@1d {
+				compatible = "tmp421";
+				reg = <0x1d>;
+			};
+			adm1278@12 {
+				compatible = "adi,adm1278";
+				reg = <0x12>;
+				Rsense = <500>;
+			};
+			eeprom@50 {
+				compatible = "atmel,24c02";
+				reg = <0x50>;
+			};
+			ds1100@58 {
+				compatible = "ds1100";
+				reg = <0x58>;
+			};
+		};
+	};
+};
+
+&i2c9 {
+	status = "okay";
+};
+
+&vuart {
+	status = "okay";
+};
+
+&gfx {
+	status = "okay";
+};
+
+&pinctrl {
+	aspeed,external-nodes = <&gfx &lhc>;
+};
+
+&gpio {
+	pin_gpio_c7 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(C, 7) GPIO_ACTIVE_HIGH>;
+		output;
+		line-name = "BIOS_SPI_MUX_S";
+	};
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
index 4379d09..c7084a8 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
@@ -2,6 +2,7 @@
 /dts-v1/;
 
 #include "aspeed-g4.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
 
 / {
 	model = "Palmetto BMC";
@@ -26,6 +27,32 @@
 			reg = <0x5f000000 0x01000000>; /* 16M */
 		};
 	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		heartbeat {
+			gpios = <&gpio ASPEED_GPIO(R, 4) GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			gpios = <&gpio ASPEED_GPIO(R, 5) GPIO_ACTIVE_LOW>;
+		};
+
+		identify {
+			gpios = <&gpio ASPEED_GPIO(A, 2) GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		checkstop {
+			label = "checkstop";
+			gpios = <&gpio ASPEED_GPIO(P, 5) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(P, 5)>;
+		};
+	};
 };
 
 &fmc {
@@ -40,6 +67,9 @@
 
 &spi {
 	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1debug_default>;
+
 	flash@0 {
 		status = "okay";
 		m25p,fast-read;
@@ -47,6 +77,29 @@
 	};
 };
 
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flbusy_default &pinctrl_flwp_default
+
+			&pinctrl_vgahs_default &pinctrl_vgavs_default
+			&pinctrl_ddcclk_default &pinctrl_ddcdat_default>;
+};
+
+&uart1 {
+	/* Rear RS-232 connector */
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_txd1_default
+			&pinctrl_rxd1_default
+			&pinctrl_nrts1_default
+			&pinctrl_ndtr1_default
+			&pinctrl_ndsr1_default
+			&pinctrl_ncts1_default
+			&pinctrl_ndcd1_default
+			&pinctrl_nri1_default>;
+};
+
 &uart5 {
 	status = "okay";
 };
@@ -111,3 +164,156 @@
 &vuart {
 	status = "okay";
 };
+
+&ibt {
+	status = "okay";
+};
+
+&gpio {
+	pin_func_mode0 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(C, 4) GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "func_mode0";
+	};
+
+	pin_func_mode1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(C, 5)  GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "func_mode1";
+	};
+
+	pin_func_mode2 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(C, 6) GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "func_mode2";
+	};
+
+	pin_gpio_a0 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(A, 0) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "BMC_FAN_RESERVED_N";
+	};
+
+	pin_gpio_a1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(A, 1) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "APSS_WDT_N";
+	};
+
+	pin_gpio_b1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(B, 1) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "APSS_BOOT_MODE";
+	};
+
+	pin_gpio_b2 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "APSS_RESET_N";
+	};
+
+	pin_gpio_b7 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(B, 7) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "SPIVID_STBY_RESET_N";
+	};
+
+	pin_gpio_d1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(D, 1) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "BMC_POWER_UP";
+	};
+
+	pin_gpio_f1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(F, 1) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "BMC_BATTERY_TEST";
+	};
+
+	pin_gpio_f4 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(F, 4) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "AST_HW_FAULT_N";
+	};
+
+	pin_gpio_f5 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(F, 5) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "AST_SYS_FAULT_N";
+	};
+
+	pin_gpio_f7 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(F, 7) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "BMC_FULL_SPEED_N";
+	};
+
+	pin_gpio_g3 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(G, 3) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "BMC_FAN_ERROR_N";
+	};
+
+	pin_gpio_g4 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(G, 4) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "BMC_WDT_RST1_P";
+	};
+
+	pin_gpio_g5 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(G, 5) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "BMC_WDT_RST2_P";
+	};
+
+	pin_gpio_h0 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 0) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "PE_SLOT_TEST_EN_N";
+	};
+
+	pin_gpio_h1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "BMC_RTCRST_N";
+	};
+
+	pin_gpio_h2 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "SYS_PWROK_BMC";
+	};
+
+	pin_gpio_h6 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 6) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "SCM1_FSI0_DATA_EN";
+	};
+
+	pin_gpio_h7 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 7) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "BMC_TPM_INT_N";
+	};
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts
index 623b6ab..51bc6a2 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts
@@ -184,9 +184,9 @@
 &i2c12 {
 	status = "okay";
 
-	max31785@52 {
-		compatible = "maxim,max31785";
-		reg = <0x52>;
+	w83773g@4c {
+		compatible = "nuvoton,w83773g";
+		reg = <0x4c>;
 	};
 };
 
@@ -203,6 +203,12 @@
 		output-low;
 		line-name = "nic_func_mode1";
 	};
+	seq_cont {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(S, 7) GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "seq_cont";
+	};
 };
 
 &vuart {
@@ -257,3 +263,7 @@
 		aspeed,fan-tach-ch = /bits/ 8 <0x0e>;
 	};
 };
+
+&ibt {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts b/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
index 5f9049d..7056231 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
@@ -546,3 +546,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_wdtrst1_default>;
 };
+
+&ibt {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts b/arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts
index c881484..ebe726a 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts
@@ -424,3 +424,7 @@
 		aspeed,fan-tach-ch = /bits/ 8 <0x03>;
 	};
 };
+
+&ibt {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index ae2b8c9..518d2bc 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -167,6 +167,7 @@
 				reg-shift = <2>;
 				interrupts = <9>;
 				clocks = <&syscon ASPEED_CLK_GATE_UART1CLK>;
+				resets = <&lpc_reset 4>;
 				no-loopback-test;
 				status = "disabled";
 			};
@@ -238,6 +239,7 @@
 					lpc_ctrl: lpc-ctrl@0 {
 						compatible = "aspeed,ast2400-lpc-ctrl";
 						reg = <0x0 0x80>;
+						clocks = <&syscon ASPEED_CLK_GATE_LCLK>;
 						status = "disabled";
 					};
 
@@ -252,6 +254,19 @@
 						compatible = "aspeed,ast2400-lhc";
 						reg = <0x20 0x24 0x48 0x8>;
 					};
+
+					lpc_reset: reset-controller@18 {
+						compatible = "aspeed,ast2400-lpc-reset";
+						reg = <0x18 0x4>;
+						#reset-cells = <1>;
+					};
+
+					ibt: ibt@c0  {
+						compatible = "aspeed,ast2400-ibt-bmc";
+						reg = <0xc0 0x18>;
+						interrupts = <8>;
+						status = "disabled";
+					};
 				};
 			};
 
@@ -261,6 +276,7 @@
 				reg-shift = <2>;
 				interrupts = <32>;
 				clocks = <&syscon ASPEED_CLK_GATE_UART2CLK>;
+				resets = <&lpc_reset 5>;
 				no-loopback-test;
 				status = "disabled";
 			};
@@ -271,6 +287,7 @@
 				reg-shift = <2>;
 				interrupts = <33>;
 				clocks = <&syscon ASPEED_CLK_GATE_UART3CLK>;
+				resets = <&lpc_reset 6>;
 				no-loopback-test;
 				status = "disabled";
 			};
@@ -281,6 +298,7 @@
 				reg-shift = <2>;
 				interrupts = <34>;
 				clocks = <&syscon ASPEED_CLK_GATE_UART4CLK>;
+				resets = <&lpc_reset 7>;
 				no-loopback-test;
 				status = "disabled";
 			};
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 2477ebc..f991771 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -210,6 +210,7 @@
 				reg-shift = <2>;
 				interrupts = <9>;
 				clocks = <&syscon ASPEED_CLK_GATE_UART1CLK>;
+				resets = <&lpc_reset 4>;
 				no-loopback-test;
 				status = "disabled";
 			};
@@ -269,7 +270,7 @@
 
 				#address-cells = <1>;
 				#size-cells = <1>;
-				ranges = <0 0x1e789000 0x1000>;
+				ranges = <0x0 0x1e789000 0x1000>;
 
 				lpc_bmc: lpc-bmc@0 {
 					compatible = "aspeed,ast2500-lpc-bmc";
@@ -279,16 +280,16 @@
 				lpc_host: lpc-host@80 {
 					compatible = "aspeed,ast2500-lpc-host", "simple-mfd", "syscon";
 					reg = <0x80 0x1e0>;
+					reg-io-width = <4>;
 
 					#address-cells = <1>;
 					#size-cells = <1>;
-					ranges = <0 0x80 0x1e0>;
-
-					reg-io-width = <4>;
+					ranges = <0x0 0x80 0x1e0>;
 
 					lpc_ctrl: lpc-ctrl@0 {
 						compatible = "aspeed,ast2500-lpc-ctrl";
 						reg = <0x0 0x80>;
+						clocks = <&syscon ASPEED_CLK_GATE_LCLK>;
 						status = "disabled";
 					};
 
@@ -303,6 +304,19 @@
 						compatible = "aspeed,ast2500-lhc";
 						reg = <0x20 0x24 0x48 0x8>;
 					};
+
+					lpc_reset: reset-controller@18 {
+						compatible = "aspeed,ast2500-lpc-reset";
+						reg = <0x18 0x4>;
+						#reset-cells = <1>;
+					};
+
+					ibt: ibt@c0 {
+						compatible = "aspeed,ast2500-ibt-bmc";
+						reg = <0xc0 0x18>;
+						interrupts = <8>;
+						status = "disabled";
+					};
 				};
 			};
 
@@ -312,6 +326,7 @@
 				reg-shift = <2>;
 				interrupts = <32>;
 				clocks = <&syscon ASPEED_CLK_GATE_UART2CLK>;
+				resets = <&lpc_reset 5>;
 				no-loopback-test;
 				status = "disabled";
 			};
@@ -322,6 +337,7 @@
 				reg-shift = <2>;
 				interrupts = <33>;
 				clocks = <&syscon ASPEED_CLK_GATE_UART3CLK>;
+				resets = <&lpc_reset 6>;
 				no-loopback-test;
 				status = "disabled";
 			};
@@ -332,6 +348,7 @@
 				reg-shift = <2>;
 				interrupts = <34>;
 				clocks = <&syscon ASPEED_CLK_GATE_UART4CLK>;
+				resets = <&lpc_reset 7>;
 				no-loopback-test;
 				status = "disabled";
 			};
diff --git a/arch/arm/boot/dts/at91-nattis-2-natte-2.dts b/arch/arm/boot/dts/at91-nattis-2-natte-2.dts
index 3ea1d26..af9f384 100644
--- a/arch/arm/boot/dts/at91-nattis-2-natte-2.dts
+++ b/arch/arm/boot/dts/at91-nattis-2-natte-2.dts
@@ -109,7 +109,32 @@
 
 		port {
 			panel_input: endpoint {
-				remote-endpoint = <&hlcdc_panel_output>;
+				remote-endpoint = <&lvds_encoder_output>;
+			};
+		};
+	};
+
+	lvds-encoder {
+		compatible = "lvds-encoder";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				lvds_encoder_input: endpoint {
+					remote-endpoint = <&hlcdc_output>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				lvds_encoder_output: endpoint {
+					remote-endpoint = <&panel_input>;
+				};
 			};
 		};
 	};
@@ -146,7 +171,7 @@
 	};
 
 	eeprom@50 {
-		compatible = "nxp,24c02";
+		compatible = "nxp,se97b", "atmel,24c02";
 		reg = <0x50>;
 		pagesize = <16>;
 	};
@@ -176,8 +201,8 @@
 			     &pinctrl_lcd_hipow0>;
 
 		port@0 {
-			hlcdc_panel_output: endpoint {
-				remote-endpoint = <&panel_input>;
+			hlcdc_output: endpoint {
+				remote-endpoint = <&lvds_encoder_input>;
 			};
 		};
 	};
@@ -216,29 +241,34 @@
 			reg = <0x0 0x40000>;
 		};
 
-		bootloader@40000 {
-			label = "bootloader";
-			reg = <0x40000 0x80000>;
+		barebox@40000 {
+			label = "barebox";
+			reg = <0x40000 0x60000>;
 		};
 
-		bootloaderenv@c0000 {
-			label = "bootloader env";
-			reg = <0xc0000 0xc0000>;
+		bareboxenv@c0000 {
+			label = "bareboxenv";
+			reg = <0xc0000 0x40000>;
 		};
 
-		dtb@180000 {
-			label = "device tree";
-			reg = <0x180000 0x80000>;
+		bareboxenv2@100000 {
+			label = "bareboxenv2";
+			reg = <0x100000 0x40000>;
+		};
+
+		oftree@180000 {
+			label = "oftree";
+			reg = <0x180000 0x20000>;
 		};
 
 		kernel@200000 {
 			label = "kernel";
-			reg = <0x200000 0x600000>;
+			reg = <0x200000 0x500000>;
 		};
 
 		rootfs@800000 {
 			label = "rootfs";
-			reg = <0x800000 0x0f800000>;
+			reg = <0x800000 0x1f800000>;
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
index e603a26..b10dccd 100644
--- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
@@ -230,7 +230,7 @@
 				status = "okay";
 
 				at24@50 {
-					compatible = "24c02";
+					compatible = "atmel,24c02";
 					reg = <0x50>;
 					pagesize = <8>;
 				};
diff --git a/arch/arm/boot/dts/at91-tse850-3.dts b/arch/arm/boot/dts/at91-tse850-3.dts
index 9b82cc8..2fbec69 100644
--- a/arch/arm/boot/dts/at91-tse850-3.dts
+++ b/arch/arm/boot/dts/at91-tse850-3.dts
@@ -234,6 +234,7 @@
 		compatible = "ti,pcm5142";
 
 		reg = <0x4c>;
+		#sound-dai-cells = <0>;
 
 		AVDD-supply = <&reg_3v3>;
 		DVDD-supply = <&reg_3v3>;
@@ -246,7 +247,7 @@
 	};
 
 	eeprom@50 {
-		compatible = "nxp,24c02", "atmel,24c02";
+		compatible = "nxp,se97b", "atmel,24c02";
 		reg = <0x50>;
 		pagesize = <16>;
 	};
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index ba61893a..2ad69a7 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -493,8 +493,8 @@
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA17 periph A */
-							 AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA18 periph A */
+							<AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_uart0_cts: uart0_cts-0 {
@@ -511,8 +511,8 @@
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB20 periph A with pullup */
-							 AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB21 periph A */
+							<AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_uart1_rts: uart1_rts-0 {
@@ -545,8 +545,8 @@
 				uart2 {
 					pinctrl_uart2: uart2-0 {
 						atmel,pins =
-							<AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA22 periph A */
-							 AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA23 periph A with pullup */
+							<AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+							 AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
 					};
 
 					pinctrl_uart2_rts: uart2_rts-0 {
@@ -563,8 +563,8 @@
 				uart3 {
 					pinctrl_uart3: uart3-0 {
 						atmel,pins =
-							<AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA5 periph B with pullup */
-							 AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA6 periph B */
+							<AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_NONE
+							 AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_uart3_rts: uart3_rts-0 {
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index 655f06c..9118e29 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -434,8 +434,8 @@
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB4 periph A */
-							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB5 periph A */
+							<AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
@@ -468,8 +468,8 @@
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB6 periph A with pullup */
-							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB7 periph A */
+							<AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
@@ -486,8 +486,8 @@
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB8 periph A with pullup */
-							 AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB9 periph A */
+							<AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
@@ -504,8 +504,8 @@
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB10 periph A with pullup */
-							 AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB11 periph A */
+							<AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart3_rts: usart3_rts-0 {
@@ -522,16 +522,16 @@
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA31 periph B with pullup */
-							 AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA30 periph B */
+							<AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_NONE
+							 AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
 					};
 				};
 
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB12 periph A with pullup */
-							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB13 periph A */
+							<AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 				};
 
diff --git a/arch/arm/boot/dts/at91sam9260ek.dts b/arch/arm/boot/dts/at91sam9260ek.dts
index e16c706..d2b865f 100644
--- a/arch/arm/boot/dts/at91sam9260ek.dts
+++ b/arch/arm/boot/dts/at91sam9260ek.dts
@@ -201,7 +201,7 @@
 		status = "okay";
 
 		24c512@50 {
-			compatible = "24c512";
+			compatible = "atmel,24c512";
 			reg = <0x50>;
 		};
 	};
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
index ddfc63b..53c63d0 100644
--- a/arch/arm/boot/dts/at91sam9261.dtsi
+++ b/arch/arm/boot/dts/at91sam9261.dtsi
@@ -328,8 +328,8 @@
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
-							<AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+							<AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+							<AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
@@ -346,8 +346,8 @@
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
-							<AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+							<AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+							<AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
@@ -364,8 +364,8 @@
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
-							<AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+							<AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+							<AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index f240567..87fb066 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -437,8 +437,8 @@
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA26 periph A with pullup */
-							 AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA27 periph A */
+							<AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
@@ -455,8 +455,8 @@
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD0 periph A with pullup */
-							 AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD1 periph A */
+							<AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
@@ -473,8 +473,8 @@
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD2 periph A with pullup */
-							 AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD3 periph A */
+							<AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts
index e9a7c70..727096f 100644
--- a/arch/arm/boot/dts/at91sam9263ek.dts
+++ b/arch/arm/boot/dts/at91sam9263ek.dts
@@ -250,7 +250,7 @@
 		status = "okay";
 
 		24c512@50 {
-			compatible = "24c512";
+			compatible = "atmel,24c512";
 			reg = <0x50>;
 			pagesize = <128>;
 		};
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
index 50561b7..71df3ad 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -211,7 +211,7 @@
 		status = "okay";
 
 		24c512@50 {
-			compatible = "24c512";
+			compatible = "atmel,24c512";
 			reg = <0x50>;
 		};
 
diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi b/arch/arm/boot/dts/at91sam9g25.dtsi
index a7da0dd..0898213 100644
--- a/arch/arm/boot/dts/at91sam9g25.dtsi
+++ b/arch/arm/boot/dts/at91sam9g25.dtsi
@@ -21,7 +21,7 @@
 				atmel,mux-mask = <
 				      /*    A         B          C     */
 				       0xffffffff 0xffe0399f 0xc000001c  /* pioA */
-				       0x0007ffff 0x8000fe3f 0x00000000  /* pioB */
+				       0x0007ffff 0x00047e3f 0x00000000  /* pioB */
 				       0x80000000 0x07c0ffff 0xb83fffff  /* pioC */
 				       0x003fffff 0x003f8000 0x00000000  /* pioD */
 				      >;
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 3a30eec..1ee25a4 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -555,8 +555,8 @@
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB19 periph A with pullup */
-							 AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB18 periph A */
+							<AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
@@ -573,8 +573,8 @@
 				uart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB4 periph A with pullup */
-							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB5 periph A */
+							<AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
@@ -591,8 +591,8 @@
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB6 periph A with pullup */
-							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB7 periph A */
+							<AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
@@ -609,8 +609,8 @@
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB9 periph A with pullup */
-							 AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB8 periph A */
+							<AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart3_rts: usart3_rts-0 {
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 4b62f4f..37cb81f 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -641,8 +641,8 @@
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<AT91_PIOC 16 AT91_PERIPH_C AT91_PINCTRL_PULL_UP	/* PC17 periph C with pullup */
-							 AT91_PIOC 17 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PC16 periph C */
+							<AT91_PIOC 16 AT91_PERIPH_C AT91_PINCTRL_NONE
+							 AT91_PIOC 17 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>;
 					};
 				};
 
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
index 3cae687..bd001cc 100644
--- a/arch/arm/boot/dts/at91sam9rl.dtsi
+++ b/arch/arm/boot/dts/at91sam9rl.dtsi
@@ -1,7 +1,8 @@
 /*
  * at91sam9rl.dtsi - Device Tree Include file for AT91SAM9RL family SoC
  *
- *  Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *  Copyright (C) 2014 Microchip
+ *  Alexandre Belloni <alexandre.belloni@free-electrons.com>
  *
  * Licensed under GPLv2 or later.
  */
@@ -719,8 +720,8 @@
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
-							<AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+							<AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+							<AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
@@ -742,8 +743,8 @@
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
-							<AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+							<AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+							<AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
@@ -765,8 +766,8 @@
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
-							<AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+							<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+							<AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart3_rts: usart3_rts-0 {
diff --git a/arch/arm/boot/dts/at91sam9rlek.dts b/arch/arm/boot/dts/at91sam9rlek.dts
index 4bde9f2..27d8a1f 100644
--- a/arch/arm/boot/dts/at91sam9rlek.dts
+++ b/arch/arm/boot/dts/at91sam9rlek.dts
@@ -1,7 +1,8 @@
 /*
  * at91sam9rlek.dts - Device Tree file for Atmel at91sam9rl reference board
  *
- *  Copyright (C) 2014  Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *  Copyright (C) 2014 Microchip
+ *  Alexandre Belloni <alexandre.belloni@free-electrons.com>
  *
  * Licensed under GPLv2 only
  */
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index fee4fe5..a3c3c31 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -520,8 +520,8 @@
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA0 periph A with pullup */
-							 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA1 periph A */
+							<AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
@@ -543,8 +543,8 @@
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA5 periph A with pullup */
-							 AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA6 periph A */
+							<AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
@@ -566,8 +566,8 @@
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA7 periph A with pullup */
-							 AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA8 periph A */
+							<AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE
+							 AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
diff --git a/arch/arm/boot/dts/at91sam9x5_usart3.dtsi b/arch/arm/boot/dts/at91sam9x5_usart3.dtsi
index 43bb5b5..a32d12b 100644
--- a/arch/arm/boot/dts/at91sam9x5_usart3.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5_usart3.dtsi
@@ -21,8 +21,8 @@
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PC22 periph B with pullup */
-							 AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;		/* PC23 periph B */
+							<AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE
+							 AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
 					};
 
 					pinctrl_usart3_rts: usart3_rts-0 {
diff --git a/arch/arm/boot/dts/atlas7-evb.dts b/arch/arm/boot/dts/atlas7-evb.dts
index 1e9cd1a..900e03b 100644
--- a/arch/arm/boot/dts/atlas7-evb.dts
+++ b/arch/arm/boot/dts/atlas7-evb.dts
@@ -73,7 +73,7 @@
 		btm {
 			uart6: uart@11000000 {
 				status = "okay";
-				sirf,uart-has-rtscts;
+				uart-has-rtscts;
 			};
 		};
 
diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
index 897103e..0d9ff12 100644
--- a/arch/arm/boot/dts/axp209.dtsi
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -58,6 +58,11 @@
 		status = "disabled";
 	};
 
+	axp_adc: adc {
+		compatible = "x-powers,axp209-adc";
+		#io-channel-cells = <1>;
+	};
+
 	axp_gpio: gpio {
 		compatible = "x-powers,axp209-gpio";
 		gpio-controller;
diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
index 87fb08e..65a07a6 100644
--- a/arch/arm/boot/dts/axp22x.dtsi
+++ b/arch/arm/boot/dts/axp22x.dtsi
@@ -57,6 +57,11 @@
 		status = "disabled";
 	};
 
+	axp_adc: adc {
+		compatible = "x-powers,axp221-adc";
+		#io-channel-cells = <1>;
+	};
+
 	battery_power_supply: battery-power-supply {
 		compatible = "x-powers,axp221-battery-power-supply";
 		status = "disabled";
diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi
index fd55b89..043c717 100644
--- a/arch/arm/boot/dts/axp81x.dtsi
+++ b/arch/arm/boot/dts/axp81x.dtsi
@@ -48,7 +48,12 @@
 	interrupt-controller;
 	#interrupt-cells = <1>;
 
-	axp_gpio: axp-gpio {
+	axp_adc: adc {
+		compatible = "x-powers,axp813-adc";
+		#io-channel-cells = <1>;
+	};
+
+	axp_gpio: gpio {
 		compatible = "x-powers,axp813-gpio";
 		gpio-controller;
 		#gpio-cells = <2>;
@@ -64,6 +69,11 @@
 		};
 	};
 
+	battery_power_supply: battery-power-supply {
+		compatible = "x-powers,axp813-battery-power-supply";
+		status = "disabled";
+	};
+
 	regulators {
 		/* Default work frequency for buck regulators */
 		x-powers,dcdc-freq = <3000>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
index b8565fc..b7f79f1 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
@@ -12,7 +12,7 @@
 /dts-v1/;
 #include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
-#include "bcm283x-rpi-usb-host.dtsi"
+#include "bcm283x-rpi-usb-otg.dtsi"
 
 / {
 	compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
@@ -131,6 +131,18 @@
 
 &uart0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&uart0_gpio14>;
+	pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>;
+	status = "okay";
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		max-speed = <2000000>;
+		shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_gpio14>;
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 593f58d..6c3cfaa 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -18,7 +18,9 @@
 
 	soc {
 		firmware: firmware {
-			compatible = "raspberrypi,bcm2835-firmware";
+			compatible = "raspberrypi,bcm2835-firmware", "simple-bus";
+			#address-cells = <0>;
+			#size-cells = <0>;
 			mboxes = <&mailbox>;
 		};
 
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
index 3e4ed7c..0b31d99 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
@@ -25,6 +25,23 @@
 	};
 };
 
+&firmware {
+	expgpio: gpio {
+		compatible = "raspberrypi,firmware-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "BT_ON",
+				  "WL_ON",
+				  "STATUS_LED",
+				  "LAN_RUN",
+				  "HPD_N",
+				  "CAM_GPIO0",
+				  "CAM_GPIO1",
+				  "PWR_LOW_N";
+		status = "okay";
+	};
+};
+
 /* uart0 communicates with the BT module */
 &uart0 {
 	pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 9d293de..ac00e73 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -223,6 +223,7 @@
 			gpclk2_gpio43: gpclk2_gpio43 {
 				brcm,pins = <43>;
 				brcm,function = <BCM2835_FSEL_ALT0>;
+				brcm,pull = <BCM2835_PUD_OFF>;
 			};
 
 			i2c0_gpio0: i2c0_gpio0 {
@@ -252,7 +253,7 @@
 
 			jtag_gpio4: jtag_gpio4 {
 				brcm,pins = <4 5 6 12 13>;
-				brcm,function = <BCM2835_FSEL_ALT4>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
 			};
 			jtag_gpio22: jtag_gpio22 {
 				brcm,pins = <22 23 24 25 26 27>;
@@ -335,10 +336,12 @@
 			uart0_ctsrts_gpio30: uart0_ctsrts_gpio30 {
 				brcm,pins = <30 31>;
 				brcm,function = <BCM2835_FSEL_ALT3>;
+				brcm,pull = <BCM2835_PUD_UP BCM2835_PUD_OFF>;
 			};
 			uart0_gpio32: uart0_gpio32 {
 				brcm,pins = <32 33>;
 				brcm,function = <BCM2835_FSEL_ALT3>;
+				brcm,pull = <BCM2835_PUD_OFF BCM2835_PUD_UP>;
 			};
 			uart0_gpio36: uart0_gpio36 {
 				brcm,pins = <36 37>;
@@ -397,8 +400,8 @@
 
 		i2s: i2s@7e203000 {
 			compatible = "brcm,bcm2835-i2s";
-			reg = <0x7e203000 0x20>,
-			      <0x7e101098 0x02>;
+			reg = <0x7e203000 0x24>;
+			clocks = <&clocks BCM2835_CLOCK_PCM>;
 
 			dmas = <&dma 2>,
 			       <&dma 3>;
@@ -438,6 +441,17 @@
 			interrupts = <2 14>; /* pwa1 */
 		};
 
+		dpi: dpi@7e208000 {
+			compatible = "brcm,bcm2835-dpi";
+			reg = <0x7e208000 0x8c>;
+			clocks = <&clocks BCM2835_CLOCK_VPU>,
+				 <&clocks BCM2835_CLOCK_DPI>;
+			clock-names = "core", "pixel";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		dsi0: dsi@7e209000 {
 			compatible = "brcm,bcm2835-dsi0";
 			reg = <0x7e209000 0x78>;
diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
index 8bef642..87ea6ba 100644
--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
@@ -35,6 +35,74 @@
 		       0x88000000 0x08000000>;
 	};
 
+	spi {
+		compatible = "spi-gpio";
+		num-chipselects = <1>;
+		gpio-sck = <&chipcommon 7 0>;
+		gpio-mosi = <&chipcommon 4 0>;
+		cs-gpios = <&chipcommon 6 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		hc595: gpio_spi@0 {
+			compatible = "fairchild,74hc595";
+			reg = <0>;
+			registers-number = <1>;
+			spi-max-frequency = <100000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "bcm53xx:green:usb";
+			gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		power0 {
+			label = "bcm53xx:green:power";
+			gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "default-on";
+		};
+
+		power1 {
+			label = "bcm53xx:red:power";
+			gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		router0 {
+			label = "bcm53xx:green:router";
+			gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "default-on";
+		};
+
+		router1 {
+			label = "bcm53xx:amber:router";
+			gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
+		};
+
+		wan {
+			label = "bcm53xx:green:wan";
+			gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "default-on";
+		};
+
+		wireless0 {
+			label = "bcm53xx:green:wireless";
+			gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
+		};
+
+		wireless1 {
+			label = "bcm53xx:amber:wireless";
+			gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
 	gpio-keys {
 		compatible = "gpio-keys";
 		#address-cells = <1>;
diff --git a/arch/arm/boot/dts/bcm958622hr.dts b/arch/arm/boot/dts/bcm958622hr.dts
index fd8b8c6..ecd05e2 100644
--- a/arch/arm/boot/dts/bcm958622hr.dts
+++ b/arch/arm/boot/dts/bcm958622hr.dts
@@ -204,10 +204,10 @@
 			reg = <4>;
 		};
 
-		port@5 {
-			ethernet = <&amac0>;
+		port@8 {
+			ethernet = <&amac2>;
 			label = "cpu";
-			reg = <5>;
+			reg = <8>;
 			fixed-link {
 				speed = <1000>;
 				full-duplex;
diff --git a/arch/arm/boot/dts/bcm958623hr.dts b/arch/arm/boot/dts/bcm958623hr.dts
index b8bde13..f5e85b3 100644
--- a/arch/arm/boot/dts/bcm958623hr.dts
+++ b/arch/arm/boot/dts/bcm958623hr.dts
@@ -208,10 +208,10 @@
 			reg = <4>;
 		};
 
-		port@5 {
-			ethernet = <&amac0>;
+		port@8 {
+			ethernet = <&amac2>;
 			label = "cpu";
-			reg = <5>;
+			reg = <8>;
 			fixed-link {
 				speed = <1000>;
 				full-duplex;
diff --git a/arch/arm/boot/dts/bcm958625hr.dts b/arch/arm/boot/dts/bcm958625hr.dts
index f0e2008..ea3fc19 100644
--- a/arch/arm/boot/dts/bcm958625hr.dts
+++ b/arch/arm/boot/dts/bcm958625hr.dts
@@ -210,10 +210,10 @@
 			reg = <4>;
 		};
 
-		port@5 {
-			ethernet = <&amac0>;
+		port@8 {
+			ethernet = <&amac2>;
 			label = "cpu";
-			reg = <5>;
+			reg = <8>;
 			fixed-link {
 				speed = <1000>;
 				full-duplex;
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
index 2cf2392..3ea5f73 100644
--- a/arch/arm/boot/dts/bcm958625k.dts
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -245,10 +245,10 @@
 			reg = <4>;
 		};
 
-		port@5 {
-			ethernet = <&amac0>;
+		port@8 {
+			ethernet = <&amac2>;
 			label = "cpu";
-			reg = <5>;
+			reg = <8>;
 			fixed-link {
 				speed = <1000>;
 				full-duplex;
diff --git a/arch/arm/boot/dts/bcm988312hr.dts b/arch/arm/boot/dts/bcm988312hr.dts
index bce251a..ea9a080 100644
--- a/arch/arm/boot/dts/bcm988312hr.dts
+++ b/arch/arm/boot/dts/bcm988312hr.dts
@@ -216,10 +216,10 @@
 			reg = <4>;
 		};
 
-		port@5 {
-			ethernet = <&amac0>;
+		port@8 {
+			ethernet = <&amac2>;
 			label = "cpu";
-			reg = <5>;
+			reg = <8>;
 			fixed-link {
 				speed = <1000>;
 				full-duplex;
diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index c755079..3962fa4 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -15,11 +15,16 @@
 	compatible = "ti,da850-evm", "ti,da850";
 	model = "DA850/AM1808/OMAP-L138 EVM";
 
+	chosen {
+		stdout-path = &serial2;
+	};
+
 	aliases {
 		serial0 = &serial0;
 		serial1 = &serial1;
 		serial2 = &serial2;
 		ethernet0 = &eth0;
+		spi0 = &spi1;
 	};
 
 	soc@1c00000 {
diff --git a/arch/arm/boot/dts/da850-lego-ev3.dts b/arch/arm/boot/dts/da850-lego-ev3.dts
index 81942ae..1ffd877 100644
--- a/arch/arm/boot/dts/da850-lego-ev3.dts
+++ b/arch/arm/boot/dts/da850-lego-ev3.dts
@@ -184,6 +184,23 @@
 		io-channel-names = "voltage", "current";
 		rechargeable-gpios = <&gpio 136 GPIO_ACTIVE_LOW>;
 	};
+
+	/* ARM local RAM */
+	memory@ffff0000 {
+		compatible = "syscon", "simple-mfd";
+		reg = <0xffff0000 0x2000>; /* 8k */
+
+		/*
+		 * The I2C bootloader looks for this magic value to either
+		 * boot normally or boot into a firmware update mode.
+		 */
+		reboot-mode {
+			compatible = "syscon-reboot-mode";
+			offset = <0x1ffc>;
+			mode-normal = <0x00000000>;
+			mode-loader = <0x5555aaaa>;
+		};
+	};
 };
 
 &pmx_core {
@@ -293,7 +310,7 @@
 	 * EEPROM contains the first stage bootloader, HW ID and Bluetooth MAC.
 	 */
 	eeprom@50 {
-		compatible = "microchip,24c128";
+		compatible = "microchip,24c128", "atmel,24c128";
 		pagesize = <64>;
 		read-only;
 		reg = <0x50>;
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index a7385c3..f1425b0 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -87,33 +87,6 @@
 			DRA7XX_CORE_IOPAD(0x3818, MUX_MODE15 | PULL_UP)	/* wakeup0.off */
 		>;
 	};
-
-	mmc1_pins_default: mmc1_pins_default {
-		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14)	/* mmc1sdcd.gpio219 */
-			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
-			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
-			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
-			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
-			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
-			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
-		>;
-	};
-
-	mmc2_pins_default: mmc2_pins_default {
-		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
-			DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
-			DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
-			DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
-			DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
-			DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
-			DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
-			DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
-			DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
-			DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
-		>;
-	};
 };
 
 &i2c1 {
@@ -350,6 +323,7 @@
 &mmc2 {
 	status = "okay";
 	vmmc-supply = <&evm_1v8_sw>;
+	vqmmc-supply = <&evm_1v8_sw>;
 	bus-width = <8>;
 	pinctrl-names = "default", "hs", "ddr_1_8v-rev11", "ddr_1_8v", "hs200_1_8v-rev11", "hs200_1_8v";
 	pinctrl-0 = <&mmc2_pins_default>;
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index e4a420f..f4ddd86 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -92,8 +92,6 @@
 			clock-latency = <300000>; /* From omap-cpufreq driver */
 
 			/* cooling options */
-			cooling-min-level = <0>;
-			cooling-max-level = <2>;
 			#cooling-cells = <2>; /* min followed by max */
 
 			vbb-supply = <&abb_mpu>;
diff --git a/arch/arm/boot/dts/dra71-evm.dts b/arch/arm/boot/dts/dra71-evm.dts
index 41c9132..ebc4bba 100644
--- a/arch/arm/boot/dts/dra71-evm.dts
+++ b/arch/arm/boot/dts/dra71-evm.dts
@@ -24,13 +24,13 @@
 
 		regulator-name = "vddshv8";
 		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <3000000>;
+		regulator-max-microvolt = <3300000>;
 		regulator-boot-on;
 		vin-supply = <&evm_5v0>;
 
 		gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>;
 		states = <1800000 0x0
-			  3000000 0x1>;
+			  3300000 0x1>;
 	};
 
 	evm_1v8_sw: fixedregulator-evm_1v8 {
@@ -50,6 +50,19 @@
 	};
 };
 
+&dra7_pmx_core {
+	mmc1_pins_default: mmc1_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mmc1_clk.clk */
+			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+		>;
+	};
+};
+
 &i2c1 {
 	status = "okay";
 	clock-frequency = <400000>;
diff --git a/arch/arm/boot/dts/dra76-evm.dts b/arch/arm/boot/dts/dra76-evm.dts
index c4fe7f8..2deb964 100644
--- a/arch/arm/boot/dts/dra76-evm.dts
+++ b/arch/arm/boot/dts/dra76-evm.dts
@@ -9,6 +9,7 @@
 
 #include "dra76x.dtsi"
 #include "dra7-evm-common.dtsi"
+#include "dra76x-mmc-iodelay.dtsi"
 #include <dt-bindings/net/ti-dp83867.h>
 
 / {
@@ -100,46 +101,6 @@
 	};
 };
 
-&dra7_pmx_core {
-	mmc1_pins_default: mmc1_pins_default {
-		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14)	/* mmc1sdcd.gpio219 */
-			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
-			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
-			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
-			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
-			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
-			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
-		>;
-	};
-
-	mmc1_pins_sdr12: pinmux_mmc1_sdr12_pins {
-		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc1_clk.clk */
-			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc1_cmd.cmd */
-			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc1_dat0.dat0 */
-			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc1_dat1.dat1 */
-			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc1_dat2.dat2 */
-			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc1_dat3.dat3 */
-		>;
-	};
-
-	mmc2_pins_default: mmc2_pins_default {
-		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
-			DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
-			DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
-			DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
-			DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
-			DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
-			DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
-			DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
-			DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
-			DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
-		>;
-	};
-};
-
 &i2c1 {
 	status = "okay";
 	clock-frequency = <400000>;
@@ -353,16 +314,21 @@
 	 * is always hardwired.
 	 */
 	cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>;
-	pinctrl-names = "default";
+	pinctrl-names = "default", "hs";
 	pinctrl-0 = <&mmc1_pins_default>;
+	pinctrl-1 = <&mmc1_pins_hs>;
 };
 
 &mmc2 {
 	status = "okay";
 	vmmc-supply = <&vio_1v8>;
+	vqmmc-supply = <&vio_1v8>;
 	bus-width = <8>;
-	pinctrl-names = "default";
+	pinctrl-names = "default", "hs", "ddr_1_8v", "hs200_1_8v";
 	pinctrl-0 = <&mmc2_pins_default>;
+	pinctrl-1 = <&mmc2_pins_default>;
+	pinctrl-2 = <&mmc2_pins_default>;
+	pinctrl-3 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_conf>;
 };
 
 /* No RTC on this device */
diff --git a/arch/arm/boot/dts/dra76x-mmc-iodelay.dtsi b/arch/arm/boot/dts/dra76x-mmc-iodelay.dtsi
new file mode 100644
index 0000000..baba7b0
--- /dev/null
+++ b/arch/arm/boot/dts/dra76x-mmc-iodelay.dtsi
@@ -0,0 +1,285 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Texas Instruments
+// MMC IOdelay values for TI's DRA76x and AM576x SoCs.
+// Author: Sekhar Nori <nsekhar@ti.com>
+
+/*
+ * Rules for modifying this file:
+ * a) Update of this file should typically correspond to a datamanual revision.
+ *    Datamanual revision that was used should be updated in comment below.
+ *    If there is no update to datamanual, do not update the values. If you
+ *    need to use values different from that recommended by the datamanual
+ *    for your design, then you should consider adding values to the device-
+ *    -tree file for your board directly.
+ * b) We keep the mode names as close to the datamanual as possible. So
+ *    if the manual calls a mode, DDR50, or DDR or DDR 1.8v or DDR 3.3v,
+ *    we follow that in code too.
+ * c) If the values change between multiple revisions of silicon, we add
+ *    a revision tag to both the new and old entry. Use 'rev11' for PG 1.1,
+ *    'rev20' for PG 2.0 and so on.
+ * d) The node name and node label should be the exact same string. This is
+ *    to curb naming creativity and achieve consistency.
+ *
+ * Datamanual Revisions:
+ *
+ * DRA76x Silicon Revision 1.0: SPRS993A, Revised July 2017
+ *
+ */
+
+&dra7_pmx_core {
+	mmc1_pins_default: mmc1_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+		>;
+	};
+
+	mmc1_pins_hs: mmc1_pins_hs {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_clk.clk */
+			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_cmd.cmd */
+			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat0.dat0 */
+			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat1.dat1 */
+			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat2.dat2 */
+			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat3.dat3 */
+		>;
+	};
+
+	mmc1_pins_sdr50: mmc1_pins_sdr50 {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0)	/* mmc1_clk.clk */
+			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0)	/* mmc1_cmd.cmd */
+			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0)	/* mmc1_dat0.dat0 */
+			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0)	/* mmc1_dat1.dat1 */
+			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0)	/* mmc1_dat2.dat2 */
+			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0)	/* mmc1_dat3.dat3 */
+		>;
+	};
+
+	mmc1_pins_ddr50: mmc1_pins_ddr50 {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)	/* mmc1_clk.clk */
+			DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)	/* mmc1_cmd.cmd */
+			DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)	/* mmc1_dat0.dat0 */
+			DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)	/* mmc1_dat1.dat1 */
+			DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)	/* mmc1_dat2.dat2 */
+			DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)	/* mmc1_dat3.dat3 */
+		>;
+	};
+
+	mmc2_pins_default: mmc2_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+			DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+			DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+			DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+			DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+			DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+			DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+			DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+			DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+			DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
+		>;
+	};
+
+	mmc2_pins_hs200: mmc2_pins_hs200 {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+			DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+			DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+			DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+			DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+			DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+			DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+			DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+			DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+			DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
+		>;
+	};
+
+	mmc3_pins_default: mmc3_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
+			DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
+			DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
+			DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
+			DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
+			DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
+		>;
+	};
+
+	mmc4_pins_hs: mmc4_pins_hs {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */
+			DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */
+			DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */
+			DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */
+			DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */
+			DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */
+		>;
+	};
+};
+
+&dra7_iodelay_core {
+
+	/* Corresponds to MMC1_DDR_MANUAL1 in datamanual */
+	mmc1_iodelay_ddr_conf: mmc1_iodelay_ddr_conf {
+		pinctrl-pin-array = <
+			0x618 A_DELAY_PS(489) G_DELAY_PS(0)	/* CFG_MMC1_CLK_IN */
+			0x624 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_CMD_IN */
+			0x630 A_DELAY_PS(374) G_DELAY_PS(0)	/* CFG_MMC1_DAT0_IN */
+			0x63c A_DELAY_PS(31) G_DELAY_PS(0)	/* CFG_MMC1_DAT1_IN */
+			0x648 A_DELAY_PS(56) G_DELAY_PS(0)	/* CFG_MMC1_DAT2_IN */
+			0x654 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT3_IN */
+			0x620 A_DELAY_PS(1355) G_DELAY_PS(0)	/* CFG_MMC1_CLK_OUT */
+			0x628 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_CMD_OEN */
+			0x62c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_CMD_OUT */
+			0x634 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT0_OEN */
+			0x638 A_DELAY_PS(0) G_DELAY_PS(4)	/* CFG_MMC1_DAT0_OUT */
+			0x640 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT1_OEN */
+			0x644 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT1_OUT */
+			0x64c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT2_OEN */
+			0x650 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT2_OUT */
+			0x658 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT3_OEN */
+			0x65c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT3_OUT */
+		>;
+	};
+
+	/* Corresponds to MMC1_SDR104_MANUAL1 in datamanual */
+	mmc1_iodelay_sdr104_conf: mmc1_iodelay_sdr104_conf {
+		pinctrl-pin-array = <
+			0x620 A_DELAY_PS(892) G_DELAY_PS(0)	/* CFG_MMC1_CLK_OUT */
+			0x628 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_CMD_OEN */
+			0x62c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_CMD_OUT */
+			0x634 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT0_OEN */
+			0x638 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT0_OUT */
+			0x640 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT1_OEN */
+			0x644 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT1_OUT */
+			0x64c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT2_OEN */
+			0x650 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT2_OUT */
+			0x658 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT3_OEN */
+			0x65c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC1_DAT3_OUT */
+		>;
+	};
+
+	/* Corresponds to MMC2_HS200_MANUAL1 in datamanual */
+	mmc2_iodelay_hs200_conf: mmc2_iodelay_hs200_conf {
+		pinctrl-pin-array = <
+			0x190 A_DELAY_PS(384) G_DELAY_PS(0)       /* CFG_GPMC_A19_OEN */
+			0x194 A_DELAY_PS(0) G_DELAY_PS(174)       /* CFG_GPMC_A19_OUT */
+			0x1a8 A_DELAY_PS(410) G_DELAY_PS(0)       /* CFG_GPMC_A20_OEN */
+			0x1ac A_DELAY_PS(85) G_DELAY_PS(0)        /* CFG_GPMC_A20_OUT */
+			0x1b4 A_DELAY_PS(468) G_DELAY_PS(0)       /* CFG_GPMC_A21_OEN */
+			0x1b8 A_DELAY_PS(139) G_DELAY_PS(0)       /* CFG_GPMC_A21_OUT */
+			0x1c0 A_DELAY_PS(676) G_DELAY_PS(0)       /* CFG_GPMC_A22_OEN */
+			0x1c4 A_DELAY_PS(69) G_DELAY_PS(0)        /* CFG_GPMC_A22_OUT */
+			0x1d0 A_DELAY_PS(1062) G_DELAY_PS(154)	  /* CFG_GPMC_A23_OUT */
+			0x1d8 A_DELAY_PS(640) G_DELAY_PS(0)       /* CFG_GPMC_A24_OEN */
+			0x1dc A_DELAY_PS(0) G_DELAY_PS(0)         /* CFG_GPMC_A24_OUT */
+			0x1e4 A_DELAY_PS(356) G_DELAY_PS(0)       /* CFG_GPMC_A25_OEN */
+			0x1e8 A_DELAY_PS(0) G_DELAY_PS(0)         /* CFG_GPMC_A25_OUT */
+			0x1f0 A_DELAY_PS(579) G_DELAY_PS(0)       /* CFG_GPMC_A26_OEN */
+			0x1f4 A_DELAY_PS(0) G_DELAY_PS(0)         /* CFG_GPMC_A26_OUT */
+			0x1fc A_DELAY_PS(435) G_DELAY_PS(0)       /* CFG_GPMC_A27_OEN */
+			0x200 A_DELAY_PS(36) G_DELAY_PS(0)        /* CFG_GPMC_A27_OUT */
+			0x364 A_DELAY_PS(759) G_DELAY_PS(0)       /* CFG_GPMC_CS1_OEN */
+			0x368 A_DELAY_PS(72) G_DELAY_PS(0)        /* CFG_GPMC_CS1_OUT */
+	      >;
+	};
+
+	/* Corresponds to MMC3_MANUAL1 in datamanual */
+	mmc3_iodelay_manual1_conf: mmc3_iodelay_manual1_conf {
+		pinctrl-pin-array = <
+			0x678 A_DELAY_PS(0) G_DELAY_PS(386)	/* CFG_MMC3_CLK_IN */
+			0x680 A_DELAY_PS(605) G_DELAY_PS(0)	/* CFG_MMC3_CLK_OUT */
+			0x684 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_CMD_IN */
+			0x688 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_CMD_OEN */
+			0x68c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_CMD_OUT */
+			0x690 A_DELAY_PS(171) G_DELAY_PS(0)	/* CFG_MMC3_DAT0_IN */
+			0x694 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT0_OEN */
+			0x698 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT0_OUT */
+			0x69c A_DELAY_PS(221) G_DELAY_PS(0)	/* CFG_MMC3_DAT1_IN */
+			0x6a0 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT1_OEN */
+			0x6a4 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT1_OUT */
+			0x6a8 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT2_IN */
+			0x6ac A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT2_OEN */
+			0x6b0 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT2_OUT */
+			0x6b4 A_DELAY_PS(474) G_DELAY_PS(0)	/* CFG_MMC3_DAT3_IN */
+			0x6b8 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT3_OEN */
+			0x6bc A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT3_OUT */
+		>;
+	};
+
+	/* Corresponds to MMC3_MANUAL2 in datamanual */
+	mmc3_iodelay_sdr50_conf: mmc3_iodelay_sdr50_conf {
+		pinctrl-pin-array = <
+			0x678 A_DELAY_PS(852) G_DELAY_PS(0)	/* CFG_MMC3_CLK_IN */
+			0x680 A_DELAY_PS(94) G_DELAY_PS(0)	/* CFG_MMC3_CLK_OUT */
+			0x684 A_DELAY_PS(122) G_DELAY_PS(0)	/* CFG_MMC3_CMD_IN */
+			0x688 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_CMD_OEN */
+			0x68c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_CMD_OUT */
+			0x690 A_DELAY_PS(91) G_DELAY_PS(0)	/* CFG_MMC3_DAT0_IN */
+			0x694 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT0_OEN */
+			0x698 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT0_OUT */
+			0x69c A_DELAY_PS(57) G_DELAY_PS(0)	/* CFG_MMC3_DAT1_IN */
+			0x6a0 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT1_OEN */
+			0x6a4 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT1_OUT */
+			0x6a8 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT2_IN */
+			0x6ac A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT2_OEN */
+			0x6b0 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT2_OUT */
+			0x6b4 A_DELAY_PS(375) G_DELAY_PS(0)	/* CFG_MMC3_DAT3_IN */
+			0x6b8 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT3_OEN */
+			0x6bc A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_MMC3_DAT3_OUT */
+		>;
+	};
+
+	/* Corresponds to MMC4_MANUAL1 in datamanual */
+	mmc4_iodelay_manual1_conf: mmc4_iodelay_manual1_conf {
+		pinctrl-pin-array = <
+			0x840 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART1_CTSN_IN */
+			0x848 A_DELAY_PS(1147) G_DELAY_PS(0)	/* CFG_UART1_CTSN_OUT */
+			0x84c A_DELAY_PS(1834) G_DELAY_PS(0)	/* CFG_UART1_RTSN_IN */
+			0x850 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART1_RTSN_OEN */
+			0x854 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART1_RTSN_OUT */
+			0x870 A_DELAY_PS(2165) G_DELAY_PS(0)	/* CFG_UART2_CTSN_IN */
+			0x874 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_CTSN_OEN */
+			0x878 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_CTSN_OUT */
+			0x87c A_DELAY_PS(1929) G_DELAY_PS(64)	/* CFG_UART2_RTSN_IN */
+			0x880 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_RTSN_OEN */
+			0x884 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_RTSN_OUT */
+			0x888 A_DELAY_PS(1935) G_DELAY_PS(128)	/* CFG_UART2_RXD_IN */
+			0x88c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_RXD_OEN */
+			0x890 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_RXD_OUT */
+			0x894 A_DELAY_PS(2172) G_DELAY_PS(44)	/* CFG_UART2_TXD_IN */
+			0x898 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_TXD_OEN */
+			0x89c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_TXD_OUT */
+		>;
+	};
+
+	/* Corresponds to MMC4_DS_MANUAL1 in datamanual */
+	mmc4_iodelay_default_conf: mmc4_iodelay_default_conf {
+		pinctrl-pin-array = <
+			0x840 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART1_CTSN_IN */
+			0x848 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART1_CTSN_OUT */
+			0x84c A_DELAY_PS(307) G_DELAY_PS(0)	/* CFG_UART1_RTSN_IN */
+			0x850 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART1_RTSN_OEN */
+			0x854 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART1_RTSN_OUT */
+			0x870 A_DELAY_PS(785) G_DELAY_PS(0)	/* CFG_UART2_CTSN_IN */
+			0x874 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_CTSN_OEN */
+			0x878 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_CTSN_OUT */
+			0x87c A_DELAY_PS(613) G_DELAY_PS(0)	/* CFG_UART2_RTSN_IN */
+			0x880 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_RTSN_OEN */
+			0x884 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_RTSN_OUT */
+			0x888 A_DELAY_PS(683) G_DELAY_PS(0)	/* CFG_UART2_RXD_IN */
+			0x88c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_RXD_OEN */
+			0x890 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_RXD_OUT */
+			0x894 A_DELAY_PS(835) G_DELAY_PS(0)	/* CFG_UART2_TXD_IN */
+			0x898 A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_TXD_OEN */
+			0x89c A_DELAY_PS(0) G_DELAY_PS(0)	/* CFG_UART2_TXD_OUT */
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/emev2-kzm9d.dts b/arch/arm/boot/dts/emev2-kzm9d.dts
index 60d0a73..c238407 100644
--- a/arch/arm/boot/dts/emev2-kzm9d.dts
+++ b/arch/arm/boot/dts/emev2-kzm9d.dts
@@ -38,28 +38,28 @@
 		#size-cells = <0>;
 
 		one {
-			debounce_interval = <50>;
+			debounce-interval = <50>;
 			wakeup-source;
 			label = "DSW2-1";
 			linux,code = <KEY_1>;
 			gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
 		};
 		two {
-			debounce_interval = <50>;
+			debounce-interval = <50>;
 			wakeup-source;
 			label = "DSW2-2";
 			linux,code = <KEY_2>;
 			gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
 		};
 		three {
-			debounce_interval = <50>;
+			debounce-interval = <50>;
 			wakeup-source;
 			label = "DSW2-3";
 			linux,code = <KEY_3>;
 			gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
 		};
 		four {
-			debounce_interval = <50>;
+			debounce-interval = <50>;
 			wakeup-source;
 			label = "DSW2-4";
 			linux,code = <KEY_4>;
diff --git a/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi b/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi
index 25186ac..1dbf3bb 100644
--- a/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi
+++ b/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Samsung's Exynos SoC MFC (Video Codec) reserved memory common definition.
  *
  * Copyright (c) 2016 Samsung Electronics Co., Ltd
- *
- * 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.
  */
 
 / {
diff --git a/arch/arm/boot/dts/exynos-syscon-restart.dtsi b/arch/arm/boot/dts/exynos-syscon-restart.dtsi
index 09a2040..4b3dd05 100644
--- a/arch/arm/boot/dts/exynos-syscon-restart.dtsi
+++ b/arch/arm/boot/dts/exynos-syscon-restart.dtsi
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Samsung's Exynos SoC syscon reboot/poweroff nodes common definition.
- *
- * 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.
  */
 
 / {
diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi
index 0aa577f..620b50c 100644
--- a/arch/arm/boot/dts/exynos3250-artik5.dtsi
+++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi
@@ -245,6 +245,7 @@
 				regulator-name = "VLDO23_1.8V";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
 			};
 
 			ldo24_reg: LDO24 {
@@ -316,6 +317,41 @@
 	status = "okay";
 };
 
+&mshc_1 {
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	disable-wp;
+	non-removable;
+	keep-power-in-suspend;
+	fifo-depth = <0x40>;
+	vqmmc-supply = <&ldo11_reg>;
+	/*
+	 * Voltage negotiation is broken for the SDIO periph so we
+	 * can't actually set the voltage here.
+	 * vmmc-supply = <&ldo23_reg>;
+	 */
+	card-detect-delay = <500>;
+	clock-frequency = <100000000>;
+	max-frequency = <100000000>;
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-sdr-timing = <0 1>;
+	samsung,dw-mshc-ddr-timing = <1 2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd1_cmd &sd1_clk &sd1_bus1 &sd1_bus4 &wlanen>;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&pinctrl_1 {
+	wlanen: wlanen {
+		samsung,pins = "gpx2-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV3>;
+		samsung,pin-val = <1>;
+	};
+};
+
 &rtc {
 	clocks = <&cmu CLK_RTC>, <&s2mps14_osc S2MPS11_CLK_AP>;
 	clock-names = "rtc", "rtc_src";
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index b8fb94f..0a5f989 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -161,34 +161,39 @@
 			syscon = <&pmu_system_controller>;
 		};
 
-		pd_cam: cam-power-domain@10023c00 {
+		pd_cam: power-domain@10023c00 {
 			compatible = "samsung,exynos4210-pd";
 			reg = <0x10023C00 0x20>;
 			#power-domain-cells = <0>;
+			label = "CAM";
 		};
 
-		pd_mfc: mfc-power-domain@10023c40 {
+		pd_mfc: power-domain@10023c40 {
 			compatible = "samsung,exynos4210-pd";
 			reg = <0x10023C40 0x20>;
 			#power-domain-cells = <0>;
+			label = "MFC";
 		};
 
-		pd_g3d: g3d-power-domain@10023c60 {
+		pd_g3d: power-domain@10023c60 {
 			compatible = "samsung,exynos4210-pd";
 			reg = <0x10023C60 0x20>;
 			#power-domain-cells = <0>;
+			label = "G3D";
 		};
 
-		pd_lcd0: lcd0-power-domain@10023c80 {
+		pd_lcd0: power-domain@10023c80 {
 			compatible = "samsung,exynos4210-pd";
 			reg = <0x10023C80 0x20>;
 			#power-domain-cells = <0>;
+			label = "LCD0";
 		};
 
-		pd_isp: isp-power-domain@10023ca0 {
+		pd_isp: power-domain@10023ca0 {
 			compatible = "samsung,exynos4210-pd";
 			reg = <0x10023CA0 0x20>;
 			#power-domain-cells = <0>;
+			label = "ISP";
 		};
 
 		cmu: clock-controller@10030000 {
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 6d59cc8..909a9f2 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -52,961 +52,976 @@
 		serial3 = &serial_3;
 	};
 
-	clock_audss: clock-controller@3810000 {
-		compatible = "samsung,exynos4210-audss-clock";
-		reg = <0x03810000 0x0C>;
-		#clock-cells = <1>;
-		clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>,
-			 <&clock CLK_SCLK_AUDIO0>, <&clock CLK_SCLK_AUDIO0>;
-		clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
-	};
-
-	i2s0: i2s@3830000 {
-		compatible = "samsung,s5pv210-i2s";
-		reg = <0x03830000 0x100>;
-		clocks = <&clock_audss EXYNOS_I2S_BUS>,
-			 <&clock_audss EXYNOS_DOUT_AUD_BUS>,
-			 <&clock_audss EXYNOS_SCLK_I2S>;
-		clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
-		#clock-cells = <1>;
-		clock-output-names = "i2s_cdclk0";
-		dmas = <&pdma0 12>, <&pdma0 11>, <&pdma0 10>;
-		dma-names = "tx", "rx", "tx-sec";
-		samsung,idma-addr = <0x03000000>;
-		#sound-dai-cells = <1>;
-		status = "disabled";
-	};
-
-	chipid@10000000 {
-		compatible = "samsung,exynos4210-chipid";
-		reg = <0x10000000 0x100>;
-	};
-
-	scu: snoop-control-unit@10500000 {
-		compatible = "arm,cortex-a9-scu";
-		reg = <0x10500000 0x2000>;
-	};
-
-	memory-controller@12570000 {
-		compatible = "samsung,exynos4210-srom";
-		reg = <0x12570000 0x14>;
-	};
-
-	mipi_phy: video-phy {
-		compatible = "samsung,s5pv210-mipi-video-phy";
-		#phy-cells = <1>;
-		syscon = <&pmu_system_controller>;
-	};
-
-	pd_mfc: mfc-power-domain@10023c40 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023C40 0x20>;
-		#power-domain-cells = <0>;
-		label = "MFC";
-	};
-
-	pd_g3d: g3d-power-domain@10023c60 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023C60 0x20>;
-		#power-domain-cells = <0>;
-		label = "G3D";
-	};
-
-	pd_lcd0: lcd0-power-domain@10023c80 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023C80 0x20>;
-		#power-domain-cells = <0>;
-		label = "LCD0";
-	};
-
-	pd_tv: tv-power-domain@10023c20 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023C20 0x20>;
-		#power-domain-cells = <0>;
-		power-domains = <&pd_lcd0>;
-		label = "TV";
-	};
-
-	pd_cam: cam-power-domain@10023c00 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023C00 0x20>;
-		#power-domain-cells = <0>;
-		label = "CAM";
-	};
-
-	pd_gps: gps-power-domain@10023ce0 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023CE0 0x20>;
-		#power-domain-cells = <0>;
-		label = "GPS";
-	};
-
-	pd_gps_alive: gps-alive-power-domain@10023d00 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023D00 0x20>;
-		#power-domain-cells = <0>;
-		label = "GPS alive";
-	};
-
-	gic: interrupt-controller@10490000 {
-		compatible = "arm,cortex-a9-gic";
-		#interrupt-cells = <3>;
-		interrupt-controller;
-		reg = <0x10490000 0x10000>, <0x10480000 0x10000>;
-	};
-
-	combiner: interrupt-controller@10440000 {
-		compatible = "samsung,exynos4210-combiner";
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		reg = <0x10440000 0x1000>;
-	};
-
-	pmu {
-		compatible = "arm,cortex-a9-pmu";
-		interrupt-parent = <&combiner>;
-		interrupts = <2 2>, <3 2>;
-	};
-
-	sys_reg: syscon@10010000 {
-		compatible = "samsung,exynos4-sysreg", "syscon";
-		reg = <0x10010000 0x400>;
-	};
-
-	pmu_system_controller: system-controller@10020000 {
-		compatible = "samsung,exynos4210-pmu", "syscon";
-		reg = <0x10020000 0x4000>;
-		interrupt-controller;
-		#interrupt-cells = <3>;
-		interrupt-parent = <&gic>;
-	};
-
-	dsi_0: dsi@11c80000 {
-		compatible = "samsung,exynos4210-mipi-dsi";
-		reg = <0x11C80000 0x10000>;
-		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-		power-domains = <&pd_lcd0>;
-		phys = <&mipi_phy 1>;
-		phy-names = "dsim";
-		clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
-		clock-names = "bus_clk", "sclk_mipi";
-		status = "disabled";
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-
-	camera {
-		compatible = "samsung,fimc", "simple-bus";
-		status = "disabled";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		#clock-cells = <1>;
-		clock-output-names = "cam_a_clkout", "cam_b_clkout";
-		ranges;
-
-		fimc_0: fimc@11800000 {
-			compatible = "samsung,exynos4210-fimc";
-			reg = <0x11800000 0x1000>;
-			interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_FIMC0>, <&clock CLK_SCLK_FIMC0>;
-			clock-names = "fimc", "sclk_fimc";
-			power-domains = <&pd_cam>;
-			samsung,sysreg = <&sys_reg>;
-			iommus = <&sysmmu_fimc0>;
-			status = "disabled";
-		};
-
-		fimc_1: fimc@11810000 {
-			compatible = "samsung,exynos4210-fimc";
-			reg = <0x11810000 0x1000>;
-			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_FIMC1>, <&clock CLK_SCLK_FIMC1>;
-			clock-names = "fimc", "sclk_fimc";
-			power-domains = <&pd_cam>;
-			samsung,sysreg = <&sys_reg>;
-			iommus = <&sysmmu_fimc1>;
-			status = "disabled";
-		};
-
-		fimc_2: fimc@11820000 {
-			compatible = "samsung,exynos4210-fimc";
-			reg = <0x11820000 0x1000>;
-			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_FIMC2>, <&clock CLK_SCLK_FIMC2>;
-			clock-names = "fimc", "sclk_fimc";
-			power-domains = <&pd_cam>;
-			samsung,sysreg = <&sys_reg>;
-			iommus = <&sysmmu_fimc2>;
-			status = "disabled";
-		};
-
-		fimc_3: fimc@11830000 {
-			compatible = "samsung,exynos4210-fimc";
-			reg = <0x11830000 0x1000>;
-			interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_FIMC3>, <&clock CLK_SCLK_FIMC3>;
-			clock-names = "fimc", "sclk_fimc";
-			power-domains = <&pd_cam>;
-			samsung,sysreg = <&sys_reg>;
-			iommus = <&sysmmu_fimc3>;
-			status = "disabled";
-		};
-
-		csis_0: csis@11880000 {
-			compatible = "samsung,exynos4210-csis";
-			reg = <0x11880000 0x4000>;
-			interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_CSIS0>, <&clock CLK_SCLK_CSIS0>;
-			clock-names = "csis", "sclk_csis";
-			bus-width = <4>;
-			power-domains = <&pd_cam>;
-			phys = <&mipi_phy 0>;
-			phy-names = "csis";
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		csis_1: csis@11890000 {
-			compatible = "samsung,exynos4210-csis";
-			reg = <0x11890000 0x4000>;
-			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_CSIS1>, <&clock CLK_SCLK_CSIS1>;
-			clock-names = "csis", "sclk_csis";
-			bus-width = <2>;
-			power-domains = <&pd_cam>;
-			phys = <&mipi_phy 2>;
-			phy-names = "csis";
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-	};
-
-	rtc: rtc@10070000 {
-		compatible = "samsung,s3c6410-rtc";
-		reg = <0x10070000 0x100>;
-		interrupt-parent = <&pmu_system_controller>;
-		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_RTC>;
-		clock-names = "rtc";
-		status = "disabled";
-	};
-
-	keypad: keypad@100a0000 {
-		compatible = "samsung,s5pv210-keypad";
-		reg = <0x100A0000 0x100>;
-		interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_KEYIF>;
-		clock-names = "keypad";
-		status = "disabled";
-	};
-
-	sdhci_0: sdhci@12510000 {
-		compatible = "samsung,exynos4210-sdhci";
-		reg = <0x12510000 0x100>;
-		interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
-		clock-names = "hsmmc", "mmc_busclk.2";
-		status = "disabled";
-	};
-
-	sdhci_1: sdhci@12520000 {
-		compatible = "samsung,exynos4210-sdhci";
-		reg = <0x12520000 0x100>;
-		interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_SDMMC1>, <&clock CLK_SCLK_MMC1>;
-		clock-names = "hsmmc", "mmc_busclk.2";
-		status = "disabled";
-	};
-
-	sdhci_2: sdhci@12530000 {
-		compatible = "samsung,exynos4210-sdhci";
-		reg = <0x12530000 0x100>;
-		interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_SDMMC2>, <&clock CLK_SCLK_MMC2>;
-		clock-names = "hsmmc", "mmc_busclk.2";
-		status = "disabled";
-	};
-
-	sdhci_3: sdhci@12540000 {
-		compatible = "samsung,exynos4210-sdhci";
-		reg = <0x12540000 0x100>;
-		interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_SDMMC3>, <&clock CLK_SCLK_MMC3>;
-		clock-names = "hsmmc", "mmc_busclk.2";
-		status = "disabled";
-	};
-
-	exynos_usbphy: exynos-usbphy@125b0000 {
-		compatible = "samsung,exynos4210-usb2-phy";
-		reg = <0x125B0000 0x100>;
-		samsung,pmureg-phandle = <&pmu_system_controller>;
-		clocks = <&clock CLK_USB_DEVICE>, <&clock CLK_XUSBXTI>;
-		clock-names = "phy", "ref";
-		#phy-cells = <1>;
-		status = "disabled";
-	};
-
-	hsotg: hsotg@12480000 {
-		compatible = "samsung,s3c6400-hsotg";
-		reg = <0x12480000 0x20000>;
-		interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_USB_DEVICE>;
-		clock-names = "otg";
-		phys = <&exynos_usbphy 0>;
-		phy-names = "usb2-phy";
-		status = "disabled";
-	};
-
-	ehci: ehci@12580000 {
-		compatible = "samsung,exynos4210-ehci";
-		reg = <0x12580000 0x100>;
-		interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_USB_HOST>;
-		clock-names = "usbhost";
-		status = "disabled";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		port@0 {
-			reg = <0>;
-			phys = <&exynos_usbphy 1>;
-			status = "disabled";
-		};
-		port@1 {
-			reg = <1>;
-			phys = <&exynos_usbphy 2>;
-			status = "disabled";
-		};
-		port@2 {
-			reg = <2>;
-			phys = <&exynos_usbphy 3>;
-			status = "disabled";
-		};
-	};
-
-	ohci: ohci@12590000 {
-		compatible = "samsung,exynos4210-ohci";
-		reg = <0x12590000 0x100>;
-		interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_USB_HOST>;
-		clock-names = "usbhost";
-		status = "disabled";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		port@0 {
-			reg = <0>;
-			phys = <&exynos_usbphy 1>;
-			status = "disabled";
-		};
-	};
-
-	i2s1: i2s@13960000 {
-		compatible = "samsung,s3c6410-i2s";
-		reg = <0x13960000 0x100>;
-		clocks = <&clock CLK_I2S1>;
-		clock-names = "iis";
-		#clock-cells = <1>;
-		clock-output-names = "i2s_cdclk1";
-		dmas = <&pdma1 12>, <&pdma1 11>;
-		dma-names = "tx", "rx";
-		#sound-dai-cells = <1>;
-		status = "disabled";
-	};
-
-	i2s2: i2s@13970000 {
-		compatible = "samsung,s3c6410-i2s";
-		reg = <0x13970000 0x100>;
-		clocks = <&clock CLK_I2S2>;
-		clock-names = "iis";
-		#clock-cells = <1>;
-		clock-output-names = "i2s_cdclk2";
-		dmas = <&pdma0 14>, <&pdma0 13>;
-		dma-names = "tx", "rx";
-		#sound-dai-cells = <1>;
-		status = "disabled";
-	};
-
-	mfc: codec@13400000 {
-		compatible = "samsung,mfc-v5";
-		reg = <0x13400000 0x10000>;
-		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
-		power-domains = <&pd_mfc>;
-		clocks = <&clock CLK_MFC>, <&clock CLK_SCLK_MFC>;
-		clock-names = "mfc", "sclk_mfc";
-		iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
-		iommu-names = "left", "right";
-	};
-
-	serial_0: serial@13800000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13800000 0x100>;
-		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
-		clock-names = "uart", "clk_uart_baud0";
-		dmas = <&pdma0 15>, <&pdma0 16>;
-		dma-names = "rx", "tx";
-		status = "disabled";
-	};
-
-	serial_1: serial@13810000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13810000 0x100>;
-		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
-		clock-names = "uart", "clk_uart_baud0";
-		dmas = <&pdma1 15>, <&pdma1 16>;
-		dma-names = "rx", "tx";
-		status = "disabled";
-	};
-
-	serial_2: serial@13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-		dmas = <&pdma0 17>, <&pdma0 18>;
-		dma-names = "rx", "tx";
-		status = "disabled";
-	};
-
-	serial_3: serial@13830000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13830000 0x100>;
-		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
-		clock-names = "uart", "clk_uart_baud0";
-		dmas = <&pdma1 17>, <&pdma1 18>;
-		dma-names = "rx", "tx";
-		status = "disabled";
-	};
-
-	i2c_0: i2c@13860000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-i2c";
-		reg = <0x13860000 0x100>;
-		interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C0>;
-		clock-names = "i2c";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2c0_bus>;
-		status = "disabled";
-	};
-
-	i2c_1: i2c@13870000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-i2c";
-		reg = <0x13870000 0x100>;
-		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C1>;
-		clock-names = "i2c";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2c1_bus>;
-		status = "disabled";
-	};
-
-	i2c_2: i2c@13880000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-i2c";
-		reg = <0x13880000 0x100>;
-		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C2>;
-		clock-names = "i2c";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2c2_bus>;
-		status = "disabled";
-	};
-
-	i2c_3: i2c@13890000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-i2c";
-		reg = <0x13890000 0x100>;
-		interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C3>;
-		clock-names = "i2c";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2c3_bus>;
-		status = "disabled";
-	};
-
-	i2c_4: i2c@138a0000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-i2c";
-		reg = <0x138A0000 0x100>;
-		interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C4>;
-		clock-names = "i2c";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2c4_bus>;
-		status = "disabled";
-	};
-
-	i2c_5: i2c@138b0000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-i2c";
-		reg = <0x138B0000 0x100>;
-		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C5>;
-		clock-names = "i2c";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2c5_bus>;
-		status = "disabled";
-	};
-
-	i2c_6: i2c@138c0000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-i2c";
-		reg = <0x138C0000 0x100>;
-		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C6>;
-		clock-names = "i2c";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2c6_bus>;
-		status = "disabled";
-	};
-
-	i2c_7: i2c@138d0000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-i2c";
-		reg = <0x138D0000 0x100>;
-		interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C7>;
-		clock-names = "i2c";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2c7_bus>;
-		status = "disabled";
-	};
-
-	i2c_8: i2c@138e0000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "samsung,s3c2440-hdmiphy-i2c";
-		reg = <0x138E0000 0x100>;
-		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_I2C_HDMI>;
-		clock-names = "i2c";
-		status = "disabled";
-
-		hdmi_i2c_phy: hdmiphy@38 {
-			compatible = "exynos4210-hdmiphy";
-			reg = <0x38>;
-		};
-	};
-
-	spi_0: spi@13920000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x13920000 0x100>;
-		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
-		dmas = <&pdma0 7>, <&pdma0 6>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
-		clock-names = "spi", "spi_busclk0";
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi0_bus>;
-		status = "disabled";
-	};
-
-	spi_1: spi@13930000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x13930000 0x100>;
-		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
-		dmas = <&pdma1 7>, <&pdma1 6>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
-		clock-names = "spi", "spi_busclk0";
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi1_bus>;
-		status = "disabled";
-	};
-
-	spi_2: spi@13940000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x13940000 0x100>;
-		interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-		dmas = <&pdma0 9>, <&pdma0 8>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
-		clock-names = "spi", "spi_busclk0";
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi2_bus>;
-		status = "disabled";
-	};
-
-	pwm: pwm@139d0000 {
-		compatible = "samsung,exynos4210-pwm";
-		reg = <0x139D0000 0x1000>;
-		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_PWM>;
-		clock-names = "timers";
-		#pwm-cells = <3>;
-		status = "disabled";
-	};
-
-	amba {
-		#address-cells = <1>;
-		#size-cells = <1>;
+	soc: soc {
 		compatible = "simple-bus";
-		interrupt-parent = <&gic>;
+		#address-cells = <1>;
+		#size-cells = <1>;
 		ranges;
 
-		pdma0: pdma@12680000 {
-			compatible = "arm,pl330", "arm,primecell";
-			reg = <0x12680000 0x1000>;
-			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_PDMA0>;
-			clock-names = "apb_pclk";
-			#dma-cells = <1>;
-			#dma-channels = <8>;
-			#dma-requests = <32>;
+		clock_audss: clock-controller@3810000 {
+			compatible = "samsung,exynos4210-audss-clock";
+			reg = <0x03810000 0x0C>;
+			#clock-cells = <1>;
+			clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>,
+				 <&clock CLK_SCLK_AUDIO0>,
+				 <&clock CLK_SCLK_AUDIO0>;
+			clock-names = "pll_ref", "pll_in", "sclk_audio",
+				      "sclk_pcm_in";
 		};
 
-		pdma1: pdma@12690000 {
-			compatible = "arm,pl330", "arm,primecell";
-			reg = <0x12690000 0x1000>;
-			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_PDMA1>;
-			clock-names = "apb_pclk";
-			#dma-cells = <1>;
-			#dma-channels = <8>;
-			#dma-requests = <32>;
+		i2s0: i2s@3830000 {
+			compatible = "samsung,s5pv210-i2s";
+			reg = <0x03830000 0x100>;
+			clocks = <&clock_audss EXYNOS_I2S_BUS>,
+				 <&clock_audss EXYNOS_DOUT_AUD_BUS>,
+				 <&clock_audss EXYNOS_SCLK_I2S>;
+			clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+			#clock-cells = <1>;
+			clock-output-names = "i2s_cdclk0";
+			dmas = <&pdma0 12>, <&pdma0 11>, <&pdma0 10>;
+			dma-names = "tx", "rx", "tx-sec";
+			samsung,idma-addr = <0x03000000>;
+			#sound-dai-cells = <1>;
+			status = "disabled";
 		};
 
-		mdma1: mdma@12850000 {
-			compatible = "arm,pl330", "arm,primecell";
-			reg = <0x12850000 0x1000>;
-			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clock CLK_MDMA>;
-			clock-names = "apb_pclk";
-			#dma-cells = <1>;
-			#dma-channels = <8>;
-			#dma-requests = <1>;
+		chipid@10000000 {
+			compatible = "samsung,exynos4210-chipid";
+			reg = <0x10000000 0x100>;
 		};
-	};
 
-	fimd: fimd@11c00000 {
-		compatible = "samsung,exynos4210-fimd";
-		interrupt-parent = <&combiner>;
-		reg = <0x11c00000 0x20000>;
-		interrupt-names = "fifo", "vsync", "lcd_sys";
-		interrupts = <11 0>, <11 1>, <11 2>;
-		clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
-		clock-names = "sclk_fimd", "fimd";
-		power-domains = <&pd_lcd0>;
-		iommus = <&sysmmu_fimd0>;
-		samsung,sysreg = <&sys_reg>;
-		status = "disabled";
-	};
+		scu: snoop-control-unit@10500000 {
+			compatible = "arm,cortex-a9-scu";
+			reg = <0x10500000 0x2000>;
+		};
 
-	tmu: tmu@100c0000 {
-		#include "exynos4412-tmu-sensor-conf.dtsi"
-	};
+		memory-controller@12570000 {
+			compatible = "samsung,exynos4210-srom";
+			reg = <0x12570000 0x14>;
+		};
 
-	jpeg_codec: jpeg-codec@11840000 {
-		compatible = "samsung,exynos4210-jpeg";
-		reg = <0x11840000 0x1000>;
-		interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_JPEG>;
-		clock-names = "jpeg";
-		power-domains = <&pd_cam>;
-		iommus = <&sysmmu_jpeg>;
-	};
+		mipi_phy: video-phy {
+			compatible = "samsung,s5pv210-mipi-video-phy";
+			#phy-cells = <1>;
+			syscon = <&pmu_system_controller>;
+		};
 
-	rotator: rotator@12810000 {
-		compatible = "samsung,exynos4210-rotator";
-		reg = <0x12810000 0x64>;
-		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_ROTATOR>;
-		clock-names = "rotator";
-		iommus = <&sysmmu_rotator>;
-	};
+		pd_mfc: mfc-power-domain@10023c40 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023C40 0x20>;
+			#power-domain-cells = <0>;
+			label = "MFC";
+		};
 
-	hdmi: hdmi@12d00000 {
-		compatible = "samsung,exynos4210-hdmi";
-		reg = <0x12D00000 0x70000>;
-		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
-		clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy",
-			"mout_hdmi";
-		clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
-			<&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
-			<&clock CLK_MOUT_HDMI>;
-		phy = <&hdmi_i2c_phy>;
-		power-domains = <&pd_tv>;
-		samsung,syscon-phandle = <&pmu_system_controller>;
-		#sound-dai-cells = <0>;
-		status = "disabled";
-	};
+		pd_g3d: g3d-power-domain@10023c60 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023C60 0x20>;
+			#power-domain-cells = <0>;
+			label = "G3D";
+		};
 
-	hdmicec: cec@100b0000 {
-		compatible = "samsung,s5p-cec";
-		reg = <0x100B0000 0x200>;
-		interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_HDMI_CEC>;
-		clock-names = "hdmicec";
-		samsung,syscon-phandle = <&pmu_system_controller>;
-		hdmi-phandle = <&hdmi>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&hdmi_cec>;
-		status = "disabled";
-	};
+		pd_lcd0: lcd0-power-domain@10023c80 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023C80 0x20>;
+			#power-domain-cells = <0>;
+			label = "LCD0";
+		};
 
-	mixer: mixer@12c10000 {
-		compatible = "samsung,exynos4210-mixer";
-		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
-		reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
-		power-domains = <&pd_tv>;
-		iommus = <&sysmmu_tv>;
-		status = "disabled";
-	};
+		pd_tv: tv-power-domain@10023c20 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023C20 0x20>;
+			#power-domain-cells = <0>;
+			power-domains = <&pd_lcd0>;
+			label = "TV";
+		};
 
-	ppmu_dmc0: ppmu_dmc0@106a0000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x106a0000 0x2000>;
-		clocks = <&clock CLK_PPMUDMC0>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+		pd_cam: cam-power-domain@10023c00 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023C00 0x20>;
+			#power-domain-cells = <0>;
+			label = "CAM";
+		};
 
-	ppmu_dmc1: ppmu_dmc1@106b0000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x106b0000 0x2000>;
-		clocks = <&clock CLK_PPMUDMC1>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+		pd_gps: gps-power-domain@10023ce0 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023CE0 0x20>;
+			#power-domain-cells = <0>;
+			label = "GPS";
+		};
 
-	ppmu_cpu: ppmu_cpu@106c0000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x106c0000 0x2000>;
-		clocks = <&clock CLK_PPMUCPU>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+		pd_gps_alive: gps-alive-power-domain@10023d00 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023D00 0x20>;
+			#power-domain-cells = <0>;
+			label = "GPS alive";
+		};
 
-	ppmu_acp: ppmu_acp@10ae0000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x106e0000 0x2000>;
-		status = "disabled";
-	};
+		gic: interrupt-controller@10490000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x10490000 0x10000>, <0x10480000 0x10000>;
+		};
 
-	ppmu_rightbus: ppmu_rightbus@112a0000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x112a0000 0x2000>;
-		clocks = <&clock CLK_PPMURIGHT>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+		combiner: interrupt-controller@10440000 {
+			compatible = "samsung,exynos4210-combiner";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0x10440000 0x1000>;
+		};
 
-	ppmu_leftbus: ppmu_leftbus0@116a0000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x116a0000 0x2000>;
-		clocks = <&clock CLK_PPMULEFT>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+		pmu: pmu {
+			compatible = "arm,cortex-a9-pmu";
+			interrupt-parent = <&combiner>;
+			interrupts = <2 2>, <3 2>;
+		};
 
-	ppmu_camif: ppmu_camif@11ac0000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x11ac0000 0x2000>;
-		clocks = <&clock CLK_PPMUCAMIF>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+		sys_reg: syscon@10010000 {
+			compatible = "samsung,exynos4-sysreg", "syscon";
+			reg = <0x10010000 0x400>;
+		};
 
-	ppmu_lcd0: ppmu_lcd0@11e40000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x11e40000 0x2000>;
-		clocks = <&clock CLK_PPMULCD0>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+		pmu_system_controller: system-controller@10020000 {
+			compatible = "samsung,exynos4210-pmu", "syscon";
+			reg = <0x10020000 0x4000>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
+		};
 
-	ppmu_fsys: ppmu_g3d@12630000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x12630000 0x2000>;
-		status = "disabled";
-	};
+		dsi_0: dsi@11c80000 {
+			compatible = "samsung,exynos4210-mipi-dsi";
+			reg = <0x11C80000 0x10000>;
+			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&pd_lcd0>;
+			phys = <&mipi_phy 1>;
+			phy-names = "dsim";
+			clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
+			clock-names = "bus_clk", "sclk_mipi";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
 
-	ppmu_image: ppmu_image@12aa0000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x12aa0000 0x2000>;
-		clocks = <&clock CLK_PPMUIMAGE>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+		camera: camera {
+			compatible = "samsung,fimc", "simple-bus";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			#clock-cells = <1>;
+			clock-output-names = "cam_a_clkout", "cam_b_clkout";
+			ranges;
 
-	ppmu_tv: ppmu_tv@12e40000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x12e40000 0x2000>;
-		clocks = <&clock CLK_PPMUTV>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+			fimc_0: fimc@11800000 {
+				compatible = "samsung,exynos4210-fimc";
+				reg = <0x11800000 0x1000>;
+				interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_FIMC0>,
+					 <&clock CLK_SCLK_FIMC0>;
+				clock-names = "fimc", "sclk_fimc";
+				power-domains = <&pd_cam>;
+				samsung,sysreg = <&sys_reg>;
+				iommus = <&sysmmu_fimc0>;
+				status = "disabled";
+			};
 
-	ppmu_g3d: ppmu_g3d@13220000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x13220000 0x2000>;
-		clocks = <&clock CLK_PPMUG3D>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+			fimc_1: fimc@11810000 {
+				compatible = "samsung,exynos4210-fimc";
+				reg = <0x11810000 0x1000>;
+				interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_FIMC1>,
+					 <&clock CLK_SCLK_FIMC1>;
+				clock-names = "fimc", "sclk_fimc";
+				power-domains = <&pd_cam>;
+				samsung,sysreg = <&sys_reg>;
+				iommus = <&sysmmu_fimc1>;
+				status = "disabled";
+			};
 
-	ppmu_mfc_left: ppmu_mfc_left@13660000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x13660000 0x2000>;
-		clocks = <&clock CLK_PPMUMFC_L>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+			fimc_2: fimc@11820000 {
+				compatible = "samsung,exynos4210-fimc";
+				reg = <0x11820000 0x1000>;
+				interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_FIMC2>,
+					 <&clock CLK_SCLK_FIMC2>;
+				clock-names = "fimc", "sclk_fimc";
+				power-domains = <&pd_cam>;
+				samsung,sysreg = <&sys_reg>;
+				iommus = <&sysmmu_fimc2>;
+				status = "disabled";
+			};
 
-	ppmu_mfc_right: ppmu_mfc_right@13670000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x13670000 0x2000>;
-		clocks = <&clock CLK_PPMUMFC_R>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
+			fimc_3: fimc@11830000 {
+				compatible = "samsung,exynos4210-fimc";
+				reg = <0x11830000 0x1000>;
+				interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_FIMC3>,
+					 <&clock CLK_SCLK_FIMC3>;
+				clock-names = "fimc", "sclk_fimc";
+				power-domains = <&pd_cam>;
+				samsung,sysreg = <&sys_reg>;
+				iommus = <&sysmmu_fimc3>;
+				status = "disabled";
+			};
 
-	sysmmu_mfc_l: sysmmu@13620000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x13620000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <5 5>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
-		power-domains = <&pd_mfc>;
-		#iommu-cells = <0>;
-	};
+			csis_0: csis@11880000 {
+				compatible = "samsung,exynos4210-csis";
+				reg = <0x11880000 0x4000>;
+				interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_CSIS0>,
+					 <&clock CLK_SCLK_CSIS0>;
+				clock-names = "csis", "sclk_csis";
+				bus-width = <4>;
+				power-domains = <&pd_cam>;
+				phys = <&mipi_phy 0>;
+				phy-names = "csis";
+				status = "disabled";
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
 
-	sysmmu_mfc_r: sysmmu@13630000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x13630000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <5 6>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
-		power-domains = <&pd_mfc>;
-		#iommu-cells = <0>;
-	};
+			csis_1: csis@11890000 {
+				compatible = "samsung,exynos4210-csis";
+				reg = <0x11890000 0x4000>;
+				interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_CSIS1>,
+					 <&clock CLK_SCLK_CSIS1>;
+				clock-names = "csis", "sclk_csis";
+				bus-width = <2>;
+				power-domains = <&pd_cam>;
+				phys = <&mipi_phy 2>;
+				phy-names = "csis";
+				status = "disabled";
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
 
-	sysmmu_tv: sysmmu@12e20000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x12E20000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <5 4>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_TV>, <&clock CLK_MIXER>;
-		power-domains = <&pd_tv>;
-		#iommu-cells = <0>;
-	};
+		rtc: rtc@10070000 {
+			compatible = "samsung,s3c6410-rtc";
+			reg = <0x10070000 0x100>;
+			interrupt-parent = <&pmu_system_controller>;
+			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_RTC>;
+			clock-names = "rtc";
+			status = "disabled";
+		};
 
-	sysmmu_fimc0: sysmmu@11a20000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x11A20000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <4 2>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_FIMC0>, <&clock CLK_FIMC0>;
-		power-domains = <&pd_cam>;
-		#iommu-cells = <0>;
-	};
+		keypad: keypad@100a0000 {
+			compatible = "samsung,s5pv210-keypad";
+			reg = <0x100A0000 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_KEYIF>;
+			clock-names = "keypad";
+			status = "disabled";
+		};
 
-	sysmmu_fimc1: sysmmu@11a30000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x11A30000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <4 3>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_FIMC1>, <&clock CLK_FIMC1>;
-		power-domains = <&pd_cam>;
-		#iommu-cells = <0>;
-	};
+		sdhci_0: sdhci@12510000 {
+			compatible = "samsung,exynos4210-sdhci";
+			reg = <0x12510000 0x100>;
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
+			clock-names = "hsmmc", "mmc_busclk.2";
+			status = "disabled";
+		};
 
-	sysmmu_fimc2: sysmmu@11a40000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x11A40000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <4 4>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_FIMC2>, <&clock CLK_FIMC2>;
-		power-domains = <&pd_cam>;
-		#iommu-cells = <0>;
-	};
+		sdhci_1: sdhci@12520000 {
+			compatible = "samsung,exynos4210-sdhci";
+			reg = <0x12520000 0x100>;
+			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_SDMMC1>, <&clock CLK_SCLK_MMC1>;
+			clock-names = "hsmmc", "mmc_busclk.2";
+			status = "disabled";
+		};
 
-	sysmmu_fimc3: sysmmu@11a50000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x11A50000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <4 5>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_FIMC3>, <&clock CLK_FIMC3>;
-		power-domains = <&pd_cam>;
-		#iommu-cells = <0>;
-	};
+		sdhci_2: sdhci@12530000 {
+			compatible = "samsung,exynos4210-sdhci";
+			reg = <0x12530000 0x100>;
+			interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_SDMMC2>, <&clock CLK_SCLK_MMC2>;
+			clock-names = "hsmmc", "mmc_busclk.2";
+			status = "disabled";
+		};
 
-	sysmmu_jpeg: sysmmu@11a60000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x11A60000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <4 6>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
-		power-domains = <&pd_cam>;
-		#iommu-cells = <0>;
-	};
+		sdhci_3: sdhci@12540000 {
+			compatible = "samsung,exynos4210-sdhci";
+			reg = <0x12540000 0x100>;
+			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_SDMMC3>, <&clock CLK_SCLK_MMC3>;
+			clock-names = "hsmmc", "mmc_busclk.2";
+			status = "disabled";
+		};
 
-	sysmmu_rotator: sysmmu@12a30000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x12A30000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <5 0>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
-		#iommu-cells = <0>;
-	};
+		exynos_usbphy: exynos-usbphy@125b0000 {
+			compatible = "samsung,exynos4210-usb2-phy";
+			reg = <0x125B0000 0x100>;
+			samsung,pmureg-phandle = <&pmu_system_controller>;
+			clocks = <&clock CLK_USB_DEVICE>, <&clock CLK_XUSBXTI>;
+			clock-names = "phy", "ref";
+			#phy-cells = <1>;
+			status = "disabled";
+		};
 
-	sysmmu_fimd0: sysmmu@11e20000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x11E20000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <5 2>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_FIMD0>, <&clock CLK_FIMD0>;
-		power-domains = <&pd_lcd0>;
-		#iommu-cells = <0>;
-	};
+		hsotg: hsotg@12480000 {
+			compatible = "samsung,s3c6400-hsotg";
+			reg = <0x12480000 0x20000>;
+			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_USB_DEVICE>;
+			clock-names = "otg";
+			phys = <&exynos_usbphy 0>;
+			phy-names = "usb2-phy";
+			status = "disabled";
+		};
 
-	sss: sss@10830000 {
-		compatible = "samsung,exynos4210-secss";
-		reg = <0x10830000 0x300>;
-		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_SSS>;
-		clock-names = "secss";
-	};
+		ehci: ehci@12580000 {
+			compatible = "samsung,exynos4210-ehci";
+			reg = <0x12580000 0x100>;
+			interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_USB_HOST>;
+			clock-names = "usbhost";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				phys = <&exynos_usbphy 1>;
+				status = "disabled";
+			};
+			port@1 {
+				reg = <1>;
+				phys = <&exynos_usbphy 2>;
+				status = "disabled";
+			};
+			port@2 {
+				reg = <2>;
+				phys = <&exynos_usbphy 3>;
+				status = "disabled";
+			};
+		};
 
-	prng: rng@10830400 {
-		compatible = "samsung,exynos4-rng";
-		reg = <0x10830400 0x200>;
-		clocks = <&clock CLK_SSS>;
-		clock-names = "secss";
+		ohci: ohci@12590000 {
+			compatible = "samsung,exynos4210-ohci";
+			reg = <0x12590000 0x100>;
+			interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_USB_HOST>;
+			clock-names = "usbhost";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				phys = <&exynos_usbphy 1>;
+				status = "disabled";
+			};
+		};
+
+		i2s1: i2s@13960000 {
+			compatible = "samsung,s3c6410-i2s";
+			reg = <0x13960000 0x100>;
+			clocks = <&clock CLK_I2S1>;
+			clock-names = "iis";
+			#clock-cells = <1>;
+			clock-output-names = "i2s_cdclk1";
+			dmas = <&pdma1 12>, <&pdma1 11>;
+			dma-names = "tx", "rx";
+			#sound-dai-cells = <1>;
+			status = "disabled";
+		};
+
+		i2s2: i2s@13970000 {
+			compatible = "samsung,s3c6410-i2s";
+			reg = <0x13970000 0x100>;
+			clocks = <&clock CLK_I2S2>;
+			clock-names = "iis";
+			#clock-cells = <1>;
+			clock-output-names = "i2s_cdclk2";
+			dmas = <&pdma0 14>, <&pdma0 13>;
+			dma-names = "tx", "rx";
+			#sound-dai-cells = <1>;
+			status = "disabled";
+		};
+
+		mfc: codec@13400000 {
+			compatible = "samsung,mfc-v5";
+			reg = <0x13400000 0x10000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&pd_mfc>;
+			clocks = <&clock CLK_MFC>, <&clock CLK_SCLK_MFC>;
+			clock-names = "mfc", "sclk_mfc";
+			iommus = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+			iommu-names = "left", "right";
+		};
+
+		serial_0: serial@13800000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x13800000 0x100>;
+			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
+			clock-names = "uart", "clk_uart_baud0";
+			dmas = <&pdma0 15>, <&pdma0 16>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		serial_1: serial@13810000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x13810000 0x100>;
+			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
+			clock-names = "uart", "clk_uart_baud0";
+			dmas = <&pdma1 15>, <&pdma1 16>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		serial_2: serial@13820000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x13820000 0x100>;
+			interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
+			clock-names = "uart", "clk_uart_baud0";
+			dmas = <&pdma0 17>, <&pdma0 18>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		serial_3: serial@13830000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x13830000 0x100>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
+			clock-names = "uart", "clk_uart_baud0";
+			dmas = <&pdma1 17>, <&pdma1 18>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		i2c_0: i2c@13860000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13860000 0x100>;
+			interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C0>;
+			clock-names = "i2c";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_bus>;
+			status = "disabled";
+		};
+
+		i2c_1: i2c@13870000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13870000 0x100>;
+			interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C1>;
+			clock-names = "i2c";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c1_bus>;
+			status = "disabled";
+		};
+
+		i2c_2: i2c@13880000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13880000 0x100>;
+			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C2>;
+			clock-names = "i2c";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c2_bus>;
+			status = "disabled";
+		};
+
+		i2c_3: i2c@13890000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13890000 0x100>;
+			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C3>;
+			clock-names = "i2c";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c3_bus>;
+			status = "disabled";
+		};
+
+		i2c_4: i2c@138a0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x138A0000 0x100>;
+			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C4>;
+			clock-names = "i2c";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c4_bus>;
+			status = "disabled";
+		};
+
+		i2c_5: i2c@138b0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x138B0000 0x100>;
+			interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C5>;
+			clock-names = "i2c";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c5_bus>;
+			status = "disabled";
+		};
+
+		i2c_6: i2c@138c0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x138C0000 0x100>;
+			interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C6>;
+			clock-names = "i2c";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c6_bus>;
+			status = "disabled";
+		};
+
+		i2c_7: i2c@138d0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x138D0000 0x100>;
+			interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C7>;
+			clock-names = "i2c";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c7_bus>;
+			status = "disabled";
+		};
+
+		i2c_8: i2c@138e0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "samsung,s3c2440-hdmiphy-i2c";
+			reg = <0x138E0000 0x100>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_I2C_HDMI>;
+			clock-names = "i2c";
+			status = "disabled";
+
+			hdmi_i2c_phy: hdmiphy@38 {
+				compatible = "exynos4210-hdmiphy";
+				reg = <0x38>;
+			};
+		};
+
+		spi_0: spi@13920000 {
+			compatible = "samsung,exynos4210-spi";
+			reg = <0x13920000 0x100>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma0 7>, <&pdma0 6>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
+			clock-names = "spi", "spi_busclk0";
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi0_bus>;
+			status = "disabled";
+		};
+
+		spi_1: spi@13930000 {
+			compatible = "samsung,exynos4210-spi";
+			reg = <0x13930000 0x100>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 7>, <&pdma1 6>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
+			clock-names = "spi", "spi_busclk0";
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi1_bus>;
+			status = "disabled";
+		};
+
+		spi_2: spi@13940000 {
+			compatible = "samsung,exynos4210-spi";
+			reg = <0x13940000 0x100>;
+			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma0 9>, <&pdma0 8>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
+			clock-names = "spi", "spi_busclk0";
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi2_bus>;
+			status = "disabled";
+		};
+
+		pwm: pwm@139d0000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x139D0000 0x1000>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_PWM>;
+			clock-names = "timers";
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
+		amba {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			interrupt-parent = <&gic>;
+			ranges;
+
+			pdma0: pdma@12680000 {
+				compatible = "arm,pl330", "arm,primecell";
+				reg = <0x12680000 0x1000>;
+				interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_PDMA0>;
+				clock-names = "apb_pclk";
+				#dma-cells = <1>;
+				#dma-channels = <8>;
+				#dma-requests = <32>;
+			};
+
+			pdma1: pdma@12690000 {
+				compatible = "arm,pl330", "arm,primecell";
+				reg = <0x12690000 0x1000>;
+				interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_PDMA1>;
+				clock-names = "apb_pclk";
+				#dma-cells = <1>;
+				#dma-channels = <8>;
+				#dma-requests = <32>;
+			};
+
+			mdma1: mdma@12850000 {
+				compatible = "arm,pl330", "arm,primecell";
+				reg = <0x12850000 0x1000>;
+				interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clock CLK_MDMA>;
+				clock-names = "apb_pclk";
+				#dma-cells = <1>;
+				#dma-channels = <8>;
+				#dma-requests = <1>;
+			};
+		};
+
+		fimd: fimd@11c00000 {
+			compatible = "samsung,exynos4210-fimd";
+			interrupt-parent = <&combiner>;
+			reg = <0x11c00000 0x20000>;
+			interrupt-names = "fifo", "vsync", "lcd_sys";
+			interrupts = <11 0>, <11 1>, <11 2>;
+			clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
+			clock-names = "sclk_fimd", "fimd";
+			power-domains = <&pd_lcd0>;
+			iommus = <&sysmmu_fimd0>;
+			samsung,sysreg = <&sys_reg>;
+			status = "disabled";
+		};
+
+		tmu: tmu@100c0000 {
+			interrupt-parent = <&combiner>;
+			reg = <0x100C0000 0x100>;
+			interrupts = <2 4>;
+			status = "disabled";
+			#include "exynos4412-tmu-sensor-conf.dtsi"
+		};
+
+		jpeg_codec: jpeg-codec@11840000 {
+			compatible = "samsung,exynos4210-jpeg";
+			reg = <0x11840000 0x1000>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_JPEG>;
+			clock-names = "jpeg";
+			power-domains = <&pd_cam>;
+			iommus = <&sysmmu_jpeg>;
+		};
+
+		rotator: rotator@12810000 {
+			compatible = "samsung,exynos4210-rotator";
+			reg = <0x12810000 0x64>;
+			interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_ROTATOR>;
+			clock-names = "rotator";
+			iommus = <&sysmmu_rotator>;
+		};
+
+		hdmi: hdmi@12d00000 {
+			compatible = "samsung,exynos4210-hdmi";
+			reg = <0x12D00000 0x70000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
+				      "sclk_hdmiphy", "mout_hdmi";
+			clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
+				 <&clock CLK_SCLK_PIXEL>,
+				 <&clock CLK_SCLK_HDMIPHY>,
+				 <&clock CLK_MOUT_HDMI>;
+			phy = <&hdmi_i2c_phy>;
+			power-domains = <&pd_tv>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			#sound-dai-cells = <0>;
+			status = "disabled";
+		};
+
+		hdmicec: cec@100b0000 {
+			compatible = "samsung,s5p-cec";
+			reg = <0x100B0000 0x200>;
+			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_HDMI_CEC>;
+			clock-names = "hdmicec";
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			hdmi-phandle = <&hdmi>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hdmi_cec>;
+			status = "disabled";
+		};
+
+		mixer: mixer@12c10000 {
+			compatible = "samsung,exynos4210-mixer";
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+			reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
+			power-domains = <&pd_tv>;
+			iommus = <&sysmmu_tv>;
+			status = "disabled";
+		};
+
+		ppmu_dmc0: ppmu_dmc0@106a0000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x106a0000 0x2000>;
+			clocks = <&clock CLK_PPMUDMC0>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_dmc1: ppmu_dmc1@106b0000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x106b0000 0x2000>;
+			clocks = <&clock CLK_PPMUDMC1>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_cpu: ppmu_cpu@106c0000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x106c0000 0x2000>;
+			clocks = <&clock CLK_PPMUCPU>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_rightbus: ppmu_rightbus@112a0000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x112a0000 0x2000>;
+			clocks = <&clock CLK_PPMURIGHT>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_leftbus: ppmu_leftbus0@116a0000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x116a0000 0x2000>;
+			clocks = <&clock CLK_PPMULEFT>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_camif: ppmu_camif@11ac0000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x11ac0000 0x2000>;
+			clocks = <&clock CLK_PPMUCAMIF>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_lcd0: ppmu_lcd0@11e40000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x11e40000 0x2000>;
+			clocks = <&clock CLK_PPMULCD0>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_fsys: ppmu_g3d@12630000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x12630000 0x2000>;
+			status = "disabled";
+		};
+
+		ppmu_image: ppmu_image@12aa0000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x12aa0000 0x2000>;
+			clocks = <&clock CLK_PPMUIMAGE>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_tv: ppmu_tv@12e40000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x12e40000 0x2000>;
+			clocks = <&clock CLK_PPMUTV>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_g3d: ppmu_g3d@13220000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x13220000 0x2000>;
+			clocks = <&clock CLK_PPMUG3D>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_mfc_left: ppmu_mfc_left@13660000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x13660000 0x2000>;
+			clocks = <&clock CLK_PPMUMFC_L>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		ppmu_mfc_right: ppmu_mfc_right@13670000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x13670000 0x2000>;
+			clocks = <&clock CLK_PPMUMFC_R>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		sysmmu_mfc_l: sysmmu@13620000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x13620000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <5 5>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_MFCL>, <&clock CLK_MFC>;
+			power-domains = <&pd_mfc>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_mfc_r: sysmmu@13630000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x13630000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <5 6>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_MFCR>, <&clock CLK_MFC>;
+			power-domains = <&pd_mfc>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_tv: sysmmu@12e20000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x12E20000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <5 4>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_TV>, <&clock CLK_MIXER>;
+			power-domains = <&pd_tv>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc0: sysmmu@11a20000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11A20000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <4 2>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_FIMC0>, <&clock CLK_FIMC0>;
+			power-domains = <&pd_cam>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc1: sysmmu@11a30000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11A30000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <4 3>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_FIMC1>, <&clock CLK_FIMC1>;
+			power-domains = <&pd_cam>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc2: sysmmu@11a40000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11A40000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <4 4>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_FIMC2>, <&clock CLK_FIMC2>;
+			power-domains = <&pd_cam>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc3: sysmmu@11a50000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11A50000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <4 5>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_FIMC3>, <&clock CLK_FIMC3>;
+			power-domains = <&pd_cam>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_jpeg: sysmmu@11a60000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11A60000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <4 6>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_JPEG>, <&clock CLK_JPEG>;
+			power-domains = <&pd_cam>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_rotator: sysmmu@12a30000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x12A30000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <5 0>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_ROTATOR>,
+				 <&clock CLK_ROTATOR>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimd0: sysmmu@11e20000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x11E20000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <5 2>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_FIMD0>, <&clock CLK_FIMD0>;
+			power-domains = <&pd_lcd0>;
+			#iommu-cells = <0>;
+		};
+
+		sss: sss@10830000 {
+			compatible = "samsung,exynos4210-secss";
+			reg = <0x10830000 0x300>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_SSS>;
+			clock-names = "secss";
+		};
+
+		prng: rng@10830400 {
+			compatible = "samsung,exynos4-rng";
+			reg = <0x10830400 0x200>;
+			clocks = <&clock CLK_SSS>;
+			clock-names = "secss";
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index dbe6c05..520c593 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -13,853 +13,851 @@
 
 #include <dt-bindings/pinctrl/samsung.h>
 
-/ {
-	pinctrl@11400000 {
-		gpa0: gpa0 {
-			gpio-controller;
-			#gpio-cells = <2>;
+&pinctrl_0 {
+	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>;
-		};
-
-		gpe0: gpe0 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
-
-		gpe1: gpe1 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
-
-		gpe2: gpe2 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
-
-		gpe3: gpe3 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
-
-		gpe4: gpe4 {
-			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>;
-		};
-
-		uart0_data: uart0-data {
-			samsung,pins = "gpa0-0", "gpa0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart0_fctl: uart0-fctl {
-			samsung,pins = "gpa0-2", "gpa0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart1_data: uart1-data {
-			samsung,pins = "gpa0-4", "gpa0-5";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart1_fctl: uart1-fctl {
-			samsung,pins = "gpa0-6", "gpa0-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c2_bus: i2c2-bus {
-			samsung,pins = "gpa0-6", "gpa0-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart2_data: uart2-data {
-			samsung,pins = "gpa1-0", "gpa1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart2_fctl: uart2-fctl {
-			samsung,pins = "gpa1-2", "gpa1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart_audio_a: uart-audio-a {
-			samsung,pins = "gpa1-0", "gpa1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c3_bus: i2c3-bus {
-			samsung,pins = "gpa1-2", "gpa1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart3_data: uart3-data {
-			samsung,pins = "gpa1-4", "gpa1-5";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart_audio_b: uart-audio-b {
-			samsung,pins = "gpa1-4", "gpa1-5";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		spi0_bus: spi0-bus {
-			samsung,pins = "gpb-0", "gpb-2", "gpb-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c4_bus: i2c4-bus {
-			samsung,pins = "gpb-2", "gpb-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		spi1_bus: spi1-bus {
-			samsung,pins = "gpb-4", "gpb-6", "gpb-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c5_bus: i2c5-bus {
-			samsung,pins = "gpb-6", "gpb-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2s1_bus: i2s1-bus {
-			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
-					"gpc0-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pcm1_bus: pcm1-bus {
-			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
-					"gpc0-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		ac97_bus: ac97-bus {
-			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
-					"gpc0-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2s2_bus: i2s2-bus {
-			samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
-					"gpc1-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pcm2_bus: pcm2-bus {
-			samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
-					"gpc1-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		spdif_bus: spdif-bus {
-			samsung,pins = "gpc1-0", "gpc1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c6_bus: i2c6-bus {
-			samsung,pins = "gpc1-3", "gpc1-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		spi2_bus: spi2-bus {
-			samsung,pins = "gpc1-1", "gpc1-2", "gpc1-3", "gpc1-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c7_bus: i2c7-bus {
-			samsung,pins = "gpd0-2", "gpd0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c0_bus: i2c0-bus {
-			samsung,pins = "gpd1-0", "gpd1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c1_bus: i2c1-bus {
-			samsung,pins = "gpd1-2", "gpd1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pwm0_out: pwm0-out {
-			samsung,pins = "gpd0-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pwm1_out: pwm1-out {
-			samsung,pins = "gpd0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pwm2_out: pwm2-out {
-			samsung,pins = "gpd0-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pwm3_out: pwm3-out {
-			samsung,pins = "gpd0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		lcd_ctrl: lcd-ctrl {
-			samsung,pins = "gpd0-0", "gpd0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		lcd_sync: lcd-sync {
-			samsung,pins = "gpf0-0", "gpf0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		lcd_en: lcd-en {
-			samsung,pins = "gpe3-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		lcd_clk: lcd-clk {
-			samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
 	};
 
-	pinctrl@11000000 {
-		gpj0: gpj0 {
-			gpio-controller;
-			#gpio-cells = <2>;
+	gpa1: gpa1 {
+		gpio-controller;
+		#gpio-cells = <2>;
 
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
-
-		gpj1: gpj1 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
-
-		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>;
-		};
-
-		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 = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-			#interrupt-cells = <2>;
-		};
-
-		gpx1: gpx1 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			interrupt-parent = <&gic>;
-			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-			#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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_cmd: sd0-cmd {
-			samsung,pins = "gpk0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_cd: sd0-cd {
-			samsung,pins = "gpk0-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_bus1: sd0-bus-width1 {
-			samsung,pins = "gpk0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_bus4: sd0-bus-width4 {
-			samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_bus8: sd0-bus-width8 {
-			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_clk: sd4-clk {
-			samsung,pins = "gpk0-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_cmd: sd4-cmd {
-			samsung,pins = "gpk0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_cd: sd4-cd {
-			samsung,pins = "gpk0-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_bus1: sd4-bus-width1 {
-			samsung,pins = "gpk0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_bus4: sd4-bus-width4 {
-			samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_bus8: sd4-bus-width8 {
-			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_clk: sd1-clk {
-			samsung,pins = "gpk1-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_cmd: sd1-cmd {
-			samsung,pins = "gpk1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_cd: sd1-cd {
-			samsung,pins = "gpk1-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_bus1: sd1-bus-width1 {
-			samsung,pins = "gpk1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_bus4: sd1-bus-width4 {
-			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_clk: sd2-clk {
-			samsung,pins = "gpk2-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_cmd: sd2-cmd {
-			samsung,pins = "gpk2-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_cd: sd2-cd {
-			samsung,pins = "gpk2-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_bus1: sd2-bus-width1 {
-			samsung,pins = "gpk2-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_bus4: sd2-bus-width4 {
-			samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_bus8: sd2-bus-width8 {
-			samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_clk: sd3-clk {
-			samsung,pins = "gpk3-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_cmd: sd3-cmd {
-			samsung,pins = "gpk3-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_cd: sd3-cd {
-			samsung,pins = "gpk3-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_bus1: sd3-bus-width1 {
-			samsung,pins = "gpk3-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_bus4: sd3-bus-width4 {
-			samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		eint0: ext-int0 {
-			samsung,pins = "gpx0-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint8: ext-int8 {
-			samsung,pins = "gpx1-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint15: ext-int15 {
-			samsung,pins = "gpx1-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint16: ext-int16 {
-			samsung,pins = "gpx2-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint31: ext-int31 {
-			samsung,pins = "gpx3-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		cam_port_a_io: cam-port-a-io {
-			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-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		cam_port_a_clk_active: cam-port-a-clk-active {
-			samsung,pins = "gpj1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		cam_port_a_clk_idle: cam-port-a-clk-idle {
-			samsung,pins = "gpj1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		hdmi_cec: hdmi-cec {
-			samsung,pins = "gpx3-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
 	};
 
-	pinctrl@3860000 {
-		gpz: gpz {
-			gpio-controller;
-			#gpio-cells = <2>;
-		};
+	gpb: gpb {
+		gpio-controller;
+		#gpio-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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
 
-		pcm0_bus: pcm0-bus {
-			samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
-					"gpz-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
+	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>;
+	};
+
+	gpe0: gpe0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpe1: gpe1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpe2: gpe2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpe3: gpe3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpe4: gpe4 {
+		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>;
+	};
+
+	uart0_data: uart0-data {
+		samsung,pins = "gpa0-0", "gpa0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart0_fctl: uart0-fctl {
+		samsung,pins = "gpa0-2", "gpa0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_data: uart1-data {
+		samsung,pins = "gpa0-4", "gpa0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_fctl: uart1-fctl {
+		samsung,pins = "gpa0-6", "gpa0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c2_bus: i2c2-bus {
+		samsung,pins = "gpa0-6", "gpa0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart2_data: uart2-data {
+		samsung,pins = "gpa1-0", "gpa1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart2_fctl: uart2-fctl {
+		samsung,pins = "gpa1-2", "gpa1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart_audio_a: uart-audio-a {
+		samsung,pins = "gpa1-0", "gpa1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c3_bus: i2c3-bus {
+		samsung,pins = "gpa1-2", "gpa1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart3_data: uart3-data {
+		samsung,pins = "gpa1-4", "gpa1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart_audio_b: uart-audio-b {
+		samsung,pins = "gpa1-4", "gpa1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi0_bus: spi0-bus {
+		samsung,pins = "gpb-0", "gpb-2", "gpb-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c4_bus: i2c4-bus {
+		samsung,pins = "gpb-2", "gpb-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi1_bus: spi1-bus {
+		samsung,pins = "gpb-4", "gpb-6", "gpb-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c5_bus: i2c5-bus {
+		samsung,pins = "gpb-6", "gpb-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2s1_bus: i2s1-bus {
+		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+				"gpc0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pcm1_bus: pcm1-bus {
+		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+				"gpc0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	ac97_bus: ac97-bus {
+		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+				"gpc0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2s2_bus: i2s2-bus {
+		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+				"gpc1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pcm2_bus: pcm2-bus {
+		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+				"gpc1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spdif_bus: spdif-bus {
+		samsung,pins = "gpc1-0", "gpc1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c6_bus: i2c6-bus {
+		samsung,pins = "gpc1-3", "gpc1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi2_bus: spi2-bus {
+		samsung,pins = "gpc1-1", "gpc1-2", "gpc1-3", "gpc1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c7_bus: i2c7-bus {
+		samsung,pins = "gpd0-2", "gpd0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c0_bus: i2c0-bus {
+		samsung,pins = "gpd1-0", "gpd1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c1_bus: i2c1-bus {
+		samsung,pins = "gpd1-2", "gpd1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pwm0_out: pwm0-out {
+		samsung,pins = "gpd0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pwm1_out: pwm1-out {
+		samsung,pins = "gpd0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pwm2_out: pwm2-out {
+		samsung,pins = "gpd0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pwm3_out: pwm3-out {
+		samsung,pins = "gpd0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	lcd_ctrl: lcd-ctrl {
+		samsung,pins = "gpd0-0", "gpd0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	lcd_sync: lcd-sync {
+		samsung,pins = "gpf0-0", "gpf0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	lcd_en: lcd-en {
+		samsung,pins = "gpe3-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	lcd_clk: lcd-clk {
+		samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_1 {
+	gpj0: gpj0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpj1: gpj1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	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>;
+	};
+
+	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 = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+		#interrupt-cells = <2>;
+	};
+
+	gpx1: gpx1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		#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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_cmd: sd0-cmd {
+		samsung,pins = "gpk0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_cd: sd0-cd {
+		samsung,pins = "gpk0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_bus1: sd0-bus-width1 {
+		samsung,pins = "gpk0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_bus4: sd0-bus-width4 {
+		samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_bus8: sd0-bus-width8 {
+		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_clk: sd4-clk {
+		samsung,pins = "gpk0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_cmd: sd4-cmd {
+		samsung,pins = "gpk0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_cd: sd4-cd {
+		samsung,pins = "gpk0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_bus1: sd4-bus-width1 {
+		samsung,pins = "gpk0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_bus4: sd4-bus-width4 {
+		samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_bus8: sd4-bus-width8 {
+		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_clk: sd1-clk {
+		samsung,pins = "gpk1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_cmd: sd1-cmd {
+		samsung,pins = "gpk1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_cd: sd1-cd {
+		samsung,pins = "gpk1-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_bus1: sd1-bus-width1 {
+		samsung,pins = "gpk1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_bus4: sd1-bus-width4 {
+		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_clk: sd2-clk {
+		samsung,pins = "gpk2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_cmd: sd2-cmd {
+		samsung,pins = "gpk2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_cd: sd2-cd {
+		samsung,pins = "gpk2-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_bus1: sd2-bus-width1 {
+		samsung,pins = "gpk2-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_bus4: sd2-bus-width4 {
+		samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_bus8: sd2-bus-width8 {
+		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_clk: sd3-clk {
+		samsung,pins = "gpk3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_cmd: sd3-cmd {
+		samsung,pins = "gpk3-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_cd: sd3-cd {
+		samsung,pins = "gpk3-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_bus1: sd3-bus-width1 {
+		samsung,pins = "gpk3-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_bus4: sd3-bus-width4 {
+		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	eint0: ext-int0 {
+		samsung,pins = "gpx0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint8: ext-int8 {
+		samsung,pins = "gpx1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint15: ext-int15 {
+		samsung,pins = "gpx1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint16: ext-int16 {
+		samsung,pins = "gpx2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint31: ext-int31 {
+		samsung,pins = "gpx3-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	cam_port_a_io: cam-port-a-io {
+		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-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	cam_port_a_clk_active: cam-port-a-clk-active {
+		samsung,pins = "gpj1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	cam_port_a_clk_idle: cam-port-a-clk-idle {
+		samsung,pins = "gpj1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hdmi_cec: hdmi-cec {
+		samsung,pins = "gpx3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_2 {
+	gpz: gpz {
+		gpio-controller;
+		#gpio-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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pcm0_bus: pcm0-bus {
+		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+				"gpz-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 };
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index aaade17..eaeeb4f 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -148,43 +148,12 @@
 		};
 	};
 
-	camera {
-		pinctrl-names = "default";
-		pinctrl-0 = <>;
-		status = "okay";
+};
 
-		fimc_0: fimc@11800000 {
-			status = "okay";
-			assigned-clocks = <&clock CLK_MOUT_FIMC0>,
-					<&clock CLK_SCLK_FIMC0>;
-			assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
-			assigned-clock-rates = <0>, <160000000>;
-		};
-
-		fimc_1: fimc@11810000 {
-			status = "okay";
-			assigned-clocks = <&clock CLK_MOUT_FIMC1>,
-					<&clock CLK_SCLK_FIMC1>;
-			assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
-			assigned-clock-rates = <0>, <160000000>;
-		};
-
-		fimc_2: fimc@11820000 {
-			status = "okay";
-			assigned-clocks = <&clock CLK_MOUT_FIMC2>,
-					<&clock CLK_SCLK_FIMC2>;
-			assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
-			assigned-clock-rates = <0>, <160000000>;
-		};
-
-		fimc_3: fimc@11830000 {
-			status = "okay";
-			assigned-clocks = <&clock CLK_MOUT_FIMC3>,
-					<&clock CLK_SCLK_FIMC3>;
-			assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
-			assigned-clock-rates = <0>, <160000000>;
-		};
-	};
+&camera {
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	status = "okay";
 };
 
 &cpu0 {
@@ -234,6 +203,38 @@
 	vbus-supply = <&safe1_sreg>;
 };
 
+&fimc_0 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC0>,
+			  <&clock CLK_SCLK_FIMC0>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_1 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC1>,
+			  <&clock CLK_SCLK_FIMC1>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_2 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC2>,
+			  <&clock CLK_SCLK_FIMC2>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+		assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_3 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC3>,
+			  <&clock CLK_SCLK_FIMC3>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
 &fimd {
 	status = "okay";
 };
@@ -275,6 +276,7 @@
 
 	max8997_pmic@66 {
 		compatible = "maxim,max8997-pmic";
+		interrupts-extended = <&gpx0 7 0>, <&gpx2 3 0>;
 
 		reg = <0x66>;
 		interrupt-parent = <&gpx0>;
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 21fff7c..4e6ff97 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -28,24 +28,6 @@
 		stdout-path = &serial_2;
 	};
 
-	sysram@2020000 {
-		smp-sysram@0 {
-			status = "disabled";
-		};
-
-		smp-sysram@5000 {
-			compatible = "samsung,exynos4210-sysram";
-			reg = <0x5000 0x1000>;
-		};
-
-		smp-sysram@1f000 {
-			status = "disabled";
-		};
-	};
-
-	mct@10050000 {
-		compatible = "none";
-	};
 
 	fixed-rate-clocks {
 		xxti {
@@ -173,45 +155,6 @@
 		};
 	};
 
-	camera {
-		status = "okay";
-
-		pinctrl-names = "default";
-		pinctrl-0 = <>;
-
-		fimc_0: fimc@11800000 {
-			status = "okay";
-			assigned-clocks = <&clock CLK_MOUT_FIMC0>,
-					<&clock CLK_SCLK_FIMC0>;
-			assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
-			assigned-clock-rates = <0>, <160000000>;
-		};
-
-		fimc_1: fimc@11810000 {
-			status = "okay";
-			assigned-clocks = <&clock CLK_MOUT_FIMC1>,
-					<&clock CLK_SCLK_FIMC1>;
-			assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
-			assigned-clock-rates = <0>, <160000000>;
-		};
-
-		fimc_2: fimc@11820000 {
-			status = "okay";
-			assigned-clocks = <&clock CLK_MOUT_FIMC2>,
-					<&clock CLK_SCLK_FIMC2>;
-			assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
-			assigned-clock-rates = <0>, <160000000>;
-		};
-
-		fimc_3: fimc@11830000 {
-			status = "okay";
-			assigned-clocks = <&clock CLK_MOUT_FIMC3>,
-					<&clock CLK_SCLK_FIMC3>;
-			assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
-			assigned-clock-rates = <0>, <160000000>;
-		};
-	};
-
 	hdmi_en: voltage-regulator-hdmi-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "HDMI_5V";
@@ -234,6 +177,13 @@
 	};
 };
 
+&camera {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
 &cpu0 {
 	cpu0-supply = <&vdd_arm_reg>;
 };
@@ -250,6 +200,38 @@
 	vbus-supply = <&safeout1_reg>;
 };
 
+&fimc_0 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC0>,
+			  <&clock CLK_SCLK_FIMC0>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_1 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC1>,
+			  <&clock CLK_SCLK_FIMC1>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_2 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC2>,
+			  <&clock CLK_SCLK_FIMC2>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_3 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC3>,
+			  <&clock CLK_SCLK_FIMC3>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
 &fimd {
 	pinctrl-0 = <&lcd_clk>, <&lcd_data24>;
 	pinctrl-names = "default";
@@ -501,6 +483,10 @@
 	status = "okay";
 };
 
+&mct {
+	compatible = "none";
+};
+
 &mdma1 {
 	reg = <0x12840000 0x1000>;
 };
@@ -579,3 +565,18 @@
 	/delete-property/dmas;
 	/delete-property/dma-names;
 };
+
+&sysram {
+	smp-sysram@0 {
+		status = "disabled";
+	};
+
+	smp-sysram@5000 {
+		compatible = "samsung,exynos4210-sysram";
+		reg = <0x5000 0x1000>;
+	};
+
+	smp-sysram@1f000 {
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index cc978cf..88fb47c 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -17,7 +17,6 @@
  */
 
 #include "exynos4.dtsi"
-#include "exynos4210-pinctrl.dtsi"
 #include "exynos4-cpu-thermal.dtsi"
 
 / {
@@ -49,8 +48,6 @@
 				400000	975000
 				200000	950000
 			>;
-			cooling-min-level = <4>;
-			cooling-max-level = <2>;
 			#cooling-cells = <2>; /* min followed by max */
 		};
 
@@ -61,108 +58,304 @@
 		};
 	};
 
-	sysram: sysram@2020000 {
-		compatible = "mmio-sram";
-		reg = <0x02020000 0x20000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0x02020000 0x20000>;
+	soc: soc {
+		sysram: sysram@2020000 {
+			compatible = "mmio-sram";
+			reg = <0x02020000 0x20000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x02020000 0x20000>;
 
-		smp-sysram@0 {
-			compatible = "samsung,exynos4210-sysram";
-			reg = <0x0 0x1000>;
+			smp-sysram@0 {
+				compatible = "samsung,exynos4210-sysram";
+				reg = <0x0 0x1000>;
+			};
+
+			smp-sysram@1f000 {
+				compatible = "samsung,exynos4210-sysram-ns";
+				reg = <0x1f000 0x1000>;
+			};
 		};
 
-		smp-sysram@1f000 {
-			compatible = "samsung,exynos4210-sysram-ns";
-			reg = <0x1f000 0x1000>;
+		pd_lcd1: lcd1-power-domain@10023ca0 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023CA0 0x20>;
+			#power-domain-cells = <0>;
+			label = "LCD1";
 		};
-	};
 
-	pd_lcd1: lcd1-power-domain@10023ca0 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023CA0 0x20>;
-		#power-domain-cells = <0>;
-		label = "LCD1";
-	};
+		l2c: l2-cache-controller@10502000 {
+			compatible = "arm,pl310-cache";
+			reg = <0x10502000 0x1000>;
+			cache-unified;
+			cache-level = <2>;
+			arm,tag-latency = <2 2 1>;
+			arm,data-latency = <2 2 1>;
+		};
 
-	l2c: l2-cache-controller@10502000 {
-		compatible = "arm,pl310-cache";
-		reg = <0x10502000 0x1000>;
-		cache-unified;
-		cache-level = <2>;
-		arm,tag-latency = <2 2 1>;
-		arm,data-latency = <2 2 1>;
-	};
+		mct: mct@10050000 {
+			compatible = "samsung,exynos4210-mct";
+			reg = <0x10050000 0x800>;
+			interrupt-parent = <&mct_map>;
+			interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
+			clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
+			clock-names = "fin_pll", "mct";
 
-	mct: mct@10050000 {
-		compatible = "samsung,exynos4210-mct";
-		reg = <0x10050000 0x800>;
-		interrupt-parent = <&mct_map>;
-		interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
-		clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
-		clock-names = "fin_pll", "mct";
-
-		mct_map: mct-map {
-			#interrupt-cells = <1>;
-			#address-cells = <0>;
-			#size-cells = <0>;
-			interrupt-map = <0 &gic 0 57 IRQ_TYPE_LEVEL_HIGH>,
+			mct_map: mct-map {
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map =
+					<0 &gic 0 57 IRQ_TYPE_LEVEL_HIGH>,
 					<1 &gic 0 69 IRQ_TYPE_LEVEL_HIGH>,
 					<2 &combiner 12 6>,
 					<3 &combiner 12 7>,
 					<4 &gic 0 42 IRQ_TYPE_LEVEL_HIGH>,
 					<5 &gic 0 48 IRQ_TYPE_LEVEL_HIGH>;
+			};
 		};
-	};
 
-	watchdog: watchdog@10060000 {
-		compatible = "samsung,s3c6410-wdt";
-		reg = <0x10060000 0x100>;
-		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_WDT>;
-		clock-names = "watchdog";
-	};
-
-	clock: clock-controller@10030000 {
-		compatible = "samsung,exynos4210-clock";
-		reg = <0x10030000 0x20000>;
-		#clock-cells = <1>;
-	};
-
-	pinctrl_0: pinctrl@11400000 {
-		compatible = "samsung,exynos4210-pinctrl";
-		reg = <0x11400000 0x1000>;
-		interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
-	};
-
-	pinctrl_1: pinctrl@11000000 {
-		compatible = "samsung,exynos4210-pinctrl";
-		reg = <0x11000000 0x1000>;
-		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
-
-		wakup_eint: wakeup-interrupt-controller {
-			compatible = "samsung,exynos4210-wakeup-eint";
-			interrupt-parent = <&gic>;
-			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		watchdog: watchdog@10060000 {
+			compatible = "samsung,s3c6410-wdt";
+			reg = <0x10060000 0x100>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_WDT>;
+			clock-names = "watchdog";
 		};
-	};
 
-	pinctrl_2: pinctrl@3860000 {
-		compatible = "samsung,exynos4210-pinctrl";
-		reg = <0x03860000 0x1000>;
-	};
+		clock: clock-controller@10030000 {
+			compatible = "samsung,exynos4210-clock";
+			reg = <0x10030000 0x20000>;
+			#clock-cells = <1>;
+		};
 
-	tmu: tmu@100c0000 {
-		compatible = "samsung,exynos4210-tmu";
-		interrupt-parent = <&combiner>;
-		reg = <0x100C0000 0x100>;
-		interrupts = <2 4>;
-		clocks = <&clock CLK_TMU_APBIF>;
-		clock-names = "tmu_apbif";
-		samsung,tmu_gain = <15>;
-		samsung,tmu_reference_voltage = <7>;
-		status = "disabled";
+		pinctrl_0: pinctrl@11400000 {
+			compatible = "samsung,exynos4210-pinctrl";
+			reg = <0x11400000 0x1000>;
+			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_1: pinctrl@11000000 {
+			compatible = "samsung,exynos4210-pinctrl";
+			reg = <0x11000000 0x1000>;
+			interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+
+			wakup_eint: wakeup-interrupt-controller {
+				compatible = "samsung,exynos4210-wakeup-eint";
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
+		pinctrl_2: pinctrl@3860000 {
+			compatible = "samsung,exynos4210-pinctrl";
+			reg = <0x03860000 0x1000>;
+		};
+
+		g2d: g2d@12800000 {
+			compatible = "samsung,s5pv210-g2d";
+			reg = <0x12800000 0x1000>;
+			interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
+			clock-names = "sclk_fimg2d", "fimg2d";
+			power-domains = <&pd_lcd0>;
+			iommus = <&sysmmu_g2d>;
+		};
+
+		ppmu_acp: ppmu_acp@10ae0000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x10ae0000 0x2000>;
+			status = "disabled";
+		};
+
+		ppmu_lcd1: ppmu_lcd1@12240000 {
+			compatible = "samsung,exynos-ppmu";
+			reg = <0x12240000 0x2000>;
+			clocks = <&clock CLK_PPMULCD1>;
+			clock-names = "ppmu";
+			status = "disabled";
+		};
+
+		sysmmu_g2d: sysmmu@12a20000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x12A20000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <4 7>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+			power-domains = <&pd_lcd0>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimd1: sysmmu@12220000 {
+			compatible = "samsung,exynos-sysmmu";
+			interrupt-parent = <&combiner>;
+			reg = <0x12220000 0x1000>;
+			interrupts = <5 3>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_FIMD1>, <&clock CLK_FIMD1>;
+			power-domains = <&pd_lcd1>;
+			#iommu-cells = <0>;
+		};
+
+		bus_dmc: bus_dmc {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_DMC>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_dmc_opp_table>;
+			status = "disabled";
+		};
+
+		bus_acp: bus_acp {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_ACP>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_acp_opp_table>;
+			status = "disabled";
+		};
+
+		bus_peri: bus_peri {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_ACLK100>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_peri_opp_table>;
+			status = "disabled";
+		};
+
+		bus_fsys: bus_fsys {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_ACLK133>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_fsys_opp_table>;
+			status = "disabled";
+		};
+
+		bus_display: bus_display {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_ACLK160>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_display_opp_table>;
+			status = "disabled";
+		};
+
+		bus_lcd0: bus_lcd0 {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_ACLK200>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_leftbus: bus_leftbus {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_GDL>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_rightbus: bus_rightbus {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_GDR>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_mfc: bus_mfc {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_SCLK_MFC>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
+		};
+
+		bus_dmc_opp_table: opp_table1 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+				opp-microvolt = <1025000>;
+			};
+			opp-267000000 {
+				opp-hz = /bits/ 64 <267000000>;
+				opp-microvolt = <1050000>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				opp-microvolt = <1150000>;
+			};
+		};
+
+		bus_acp_opp_table: opp_table2 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+			};
+			opp-160000000 {
+				opp-hz = /bits/ 64 <160000000>;
+			};
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+			};
+		};
+
+		bus_peri_opp_table: opp_table3 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-5000000 {
+				opp-hz = /bits/ 64 <5000000>;
+			};
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+		};
+
+		bus_fsys_opp_table: opp_table4 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-10000000 {
+				opp-hz = /bits/ 64 <10000000>;
+			};
+			opp-134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+			};
+		};
+
+		bus_display_opp_table: opp_table5 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+			opp-134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+			};
+			opp-160000000 {
+				opp-hz = /bits/ 64 <160000000>;
+			};
+		};
+
+		bus_leftbus_opp_table: opp_table6 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+			opp-160000000 {
+				opp-hz = /bits/ 64 <160000000>;
+			};
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+			};
+		};
 	};
 
 	thermal-zones {
@@ -172,262 +365,30 @@
 			thermal-sensors = <&tmu 0>;
 
 			trips {
-			      cpu_alert0: cpu-alert-0 {
-				      temperature = <85000>; /* millicelsius */
-			      };
-			      cpu_alert1: cpu-alert-1 {
-				      temperature = <100000>; /* millicelsius */
-			      };
-			      cpu_alert2: cpu-alert-2 {
-				      temperature = <110000>; /* millicelsius */
-			      };
+				cpu_alert0: cpu-alert-0 {
+				temperature = <85000>; /* millicelsius */
+				};
+				cpu_alert1: cpu-alert-1 {
+				temperature = <100000>; /* millicelsius */
+				};
+				cpu_alert2: cpu-alert-2 {
+				temperature = <110000>; /* millicelsius */
+				};
 			};
 		};
 	};
-
-	g2d: g2d@12800000 {
-		compatible = "samsung,s5pv210-g2d";
-		reg = <0x12800000 0x1000>;
-		interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
-		clock-names = "sclk_fimg2d", "fimg2d";
-		power-domains = <&pd_lcd0>;
-		iommus = <&sysmmu_g2d>;
-	};
-
-	camera {
-		clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
-			 <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
-		clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
-
-		fimc_0: fimc@11800000 {
-			samsung,pix-limits = <4224 8192 1920 4224>;
-			samsung,mainscaler-ext;
-			samsung,cam-if;
-		};
-
-		fimc_1: fimc@11810000 {
-			samsung,pix-limits = <4224 8192 1920 4224>;
-			samsung,mainscaler-ext;
-			samsung,cam-if;
-		};
-
-		fimc_2: fimc@11820000 {
-			samsung,pix-limits = <4224 8192 1920 4224>;
-			samsung,mainscaler-ext;
-			samsung,lcd-wb;
-		};
-
-		fimc_3: fimc@11830000 {
-			samsung,pix-limits = <1920 8192 1366 1920>;
-			samsung,rotators = <0>;
-			samsung,mainscaler-ext;
-			samsung,lcd-wb;
-		};
-	};
-
-	mixer: mixer@12c10000 {
-		clock-names = "mixer", "hdmi", "sclk_hdmi", "vp", "mout_mixer",
-			"sclk_mixer";
-		clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
-			<&clock CLK_SCLK_HDMI>, <&clock CLK_VP>,
-			<&clock CLK_MOUT_MIXER>, <&clock CLK_SCLK_MIXER>;
-	};
-
-	ppmu_lcd1: ppmu_lcd1@12240000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x12240000 0x2000>;
-		clocks = <&clock CLK_PPMULCD1>;
-		clock-names = "ppmu";
-		status = "disabled";
-	};
-
-	sysmmu_g2d: sysmmu@12a20000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x12A20000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <4 7>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
-		power-domains = <&pd_lcd0>;
-		#iommu-cells = <0>;
-	};
-
-	sysmmu_fimd1: sysmmu@12220000 {
-		compatible = "samsung,exynos-sysmmu";
-		interrupt-parent = <&combiner>;
-		reg = <0x12220000 0x1000>;
-		interrupts = <5 3>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_FIMD1>, <&clock CLK_FIMD1>;
-		power-domains = <&pd_lcd1>;
-		#iommu-cells = <0>;
-	};
-
-	bus_dmc: bus_dmc {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_DMC>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_dmc_opp_table>;
-		status = "disabled";
-	};
-
-	bus_acp: bus_acp {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_ACP>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_acp_opp_table>;
-		status = "disabled";
-	};
-
-	bus_peri: bus_peri {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_ACLK100>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_peri_opp_table>;
-		status = "disabled";
-	};
-
-	bus_fsys: bus_fsys {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_ACLK133>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_fsys_opp_table>;
-		status = "disabled";
-	};
-
-	bus_display: bus_display {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_ACLK160>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_display_opp_table>;
-		status = "disabled";
-	};
-
-	bus_lcd0: bus_lcd0 {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_ACLK200>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_leftbus_opp_table>;
-		status = "disabled";
-	};
-
-	bus_leftbus: bus_leftbus {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_GDL>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_leftbus_opp_table>;
-		status = "disabled";
-	};
-
-	bus_rightbus: bus_rightbus {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_GDR>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_leftbus_opp_table>;
-		status = "disabled";
-	};
-
-	bus_mfc: bus_mfc {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_SCLK_MFC>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_leftbus_opp_table>;
-		status = "disabled";
-	};
-
-	bus_dmc_opp_table: opp_table1 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-134000000 {
-			opp-hz = /bits/ 64 <134000000>;
-			opp-microvolt = <1025000>;
-		};
-		opp-267000000 {
-			opp-hz = /bits/ 64 <267000000>;
-			opp-microvolt = <1050000>;
-		};
-		opp-400000000 {
-			opp-hz = /bits/ 64 <400000000>;
-			opp-microvolt = <1150000>;
-		};
-	};
-
-	bus_acp_opp_table: opp_table2 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-134000000 {
-			opp-hz = /bits/ 64 <134000000>;
-		};
-		opp-160000000 {
-			opp-hz = /bits/ 64 <160000000>;
-		};
-		opp-200000000 {
-			opp-hz = /bits/ 64 <200000000>;
-		};
-	};
-
-	bus_peri_opp_table: opp_table3 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-5000000 {
-			opp-hz = /bits/ 64 <5000000>;
-		};
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
-		};
-	};
-
-	bus_fsys_opp_table: opp_table4 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-10000000 {
-			opp-hz = /bits/ 64 <10000000>;
-		};
-		opp-134000000 {
-			opp-hz = /bits/ 64 <134000000>;
-		};
-	};
-
-	bus_display_opp_table: opp_table5 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
-		};
-		opp-134000000 {
-			opp-hz = /bits/ 64 <134000000>;
-		};
-		opp-160000000 {
-			opp-hz = /bits/ 64 <160000000>;
-		};
-	};
-
-	bus_leftbus_opp_table: opp_table6 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
-		};
-		opp-160000000 {
-			opp-hz = /bits/ 64 <160000000>;
-		};
-		opp-200000000 {
-			opp-hz = /bits/ 64 <200000000>;
-		};
-	};
 };
 
 &gic {
 	cpu-offset = <0x8000>;
 };
 
+&camera {
+	clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
+		 <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
+	clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
+};
+
 &combiner {
 	samsung,combiner-nr = <16>;
 	interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
@@ -448,10 +409,43 @@
 		     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 };
 
+&fimc_0 {
+	samsung,pix-limits = <4224 8192 1920 4224>;
+	samsung,mainscaler-ext;
+	samsung,cam-if;
+};
+
+&fimc_1 {
+	samsung,pix-limits = <4224 8192 1920 4224>;
+	samsung,mainscaler-ext;
+	samsung,cam-if;
+};
+
+&fimc_2 {
+	samsung,pix-limits = <4224 8192 1920 4224>;
+	samsung,mainscaler-ext;
+	samsung,lcd-wb;
+};
+
+&fimc_3 {
+	samsung,pix-limits = <1920 8192 1366 1920>;
+	samsung,rotators = <0>;
+	samsung,mainscaler-ext;
+	samsung,lcd-wb;
+};
+
 &mdma1 {
 	power-domains = <&pd_lcd0>;
 };
 
+&mixer {
+	clock-names = "mixer", "hdmi", "sclk_hdmi", "vp", "mout_mixer",
+		      "sclk_mixer";
+	clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+		 <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>,
+		 <&clock CLK_MOUT_MIXER>, <&clock CLK_SCLK_MIXER>;
+};
+
 &pmu_system_controller {
 	clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
 			"clkout4", "clkout8", "clkout9";
@@ -468,3 +462,13 @@
 &sysmmu_rotator {
 	power-domains = <&pd_lcd0>;
 };
+
+&tmu {
+	compatible = "samsung,exynos4210-tmu";
+	clocks = <&clock CLK_TMU_APBIF>;
+	clock-names = "tmu_apbif";
+	samsung,tmu_gain = <15>;
+	samsung,tmu_reference_voltage = <7>;
+};
+
+#include "exynos4210-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
new file mode 100644
index 0000000..ee8e1f4
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos4412 based Galaxy S3 board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ */
+
+/dts-v1/;
+#include "exynos4412-midas.dtsi"
+
+/ {
+	aliases {
+		i2c9 = &i2c_ak8975;
+		i2c10 = &i2c_cm36651;
+	};
+
+	regulators {
+		lcd_vdd3_reg: voltage-regulator-2 {
+			compatible = "regulator-fixed";
+			regulator-name = "LCD_VDD_2.2V";
+			regulator-min-microvolt = <2200000>;
+			regulator-max-microvolt = <2200000>;
+			gpio = <&gpc0 1 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+
+		ps_als_reg: voltage-regulator-5 {
+			compatible = "regulator-fixed";
+			regulator-name = "LED_A_3.0V";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			gpio = <&gpj0 5 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+	};
+
+	i2c_ak8975: i2c-gpio-0 {
+		compatible = "i2c-gpio";
+		gpios = <&gpy2 4 GPIO_ACTIVE_HIGH>, <&gpy2 5 GPIO_ACTIVE_HIGH>;
+		i2c-gpio,delay-us = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+
+		ak8975@c {
+			compatible = "asahi-kasei,ak8975";
+			reg = <0x0c>;
+			gpios = <&gpj0 7 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	i2c_cm36651: i2c-gpio-2 {
+		compatible = "i2c-gpio";
+		gpios = <&gpf0 0 GPIO_ACTIVE_LOW>, <&gpf0 1 GPIO_ACTIVE_LOW>;
+		i2c-gpio,delay-us = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cm36651@18 {
+			compatible = "capella,cm36651";
+			reg = <0x18>;
+			interrupt-parent = <&gpx0>;
+			interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+			vled-supply = <&ps_als_reg>;
+		};
+	};
+};
+
+&buck9_reg {
+	maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
+};
+
+&cam_af_reg {
+	gpio = <&gpm0 4 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&cam_io_reg {
+	gpio = <&gpm0 2 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&dsi_0 {
+	status = "okay";
+
+	panel@0 {
+		compatible = "samsung,s6e8aa0";
+		reg = <0>;
+		vdd3-supply = <&lcd_vdd3_reg>;
+		vci-supply = <&ldo25_reg>;
+		reset-gpios = <&gpf2 1 GPIO_ACTIVE_HIGH>;
+		power-on-delay= <50>;
+		reset-delay = <100>;
+		init-delay = <100>;
+		flip-horizontal;
+		flip-vertical;
+		panel-width-mm = <58>;
+		panel-height-mm = <103>;
+
+		display-timings {
+			timing-0 {
+				clock-frequency = <57153600>;
+				hactive = <720>;
+				vactive = <1280>;
+				hfront-porch = <5>;
+				hback-porch = <5>;
+				hsync-len = <5>;
+				vfront-porch = <13>;
+				vback-porch = <1>;
+				vsync-len = <2>;
+			};
+		};
+	};
+};
+
+&i2c_3 {
+	mms114-touchscreen@48 {
+		compatible = "melfas,mms114";
+		reg = <0x48>;
+		interrupt-parent = <&gpm2>;
+		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+		x-size = <720>;
+		y-size = <1280>;
+		avdd-supply = <&ldo23_reg>;
+		vdd-supply = <&ldo24_reg>;
+	};
+};
+
+&ldo25_reg {
+	regulator-name = "LCD_VCC_3.3V";
+	regulator-min-microvolt = <2800000>;
+	regulator-max-microvolt = <2800000>;
+};
+
+&s5c73m3 {
+	standby-gpios = <&gpm0 1 GPIO_ACTIVE_LOW>;   /* ISP_STANDBY */
+	vdda-supply = <&ldo17_reg>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/exynos4412-i9300.dts b/arch/arm/boot/dts/exynos4412-i9300.dts
new file mode 100644
index 0000000..f8125a9
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-i9300.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos4412 based M0 (GT-I9300) board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ */
+
+/dts-v1/;
+#include "exynos4412-galaxy-s3.dtsi"
+
+/ {
+	model = "Samsung Galaxy S3 (GT-I9300) based on Exynos4412";
+	compatible = "samsung,i9300", "samsung,midas", "samsung,exynos4412", "samsung,exynos4";
+
+	/* bootargs are passed in by bootloader */
+
+	memory@40000000 {
+		device_type = "memory";
+		reg =  <0x40000000 0x40000000>;
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4412-i9305.dts b/arch/arm/boot/dts/exynos4412-i9305.dts
new file mode 100644
index 0000000..54a2a55
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-i9305.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "exynos4412-galaxy-s3.dtsi"
+
+/ {
+	model = "Samsung Galaxy S3 (GT-I9305) based on Exynos4412";
+	compatible = "samsung,i9305", "samsung,midas", "samsung,exynos4412", "samsung,exynos4";
+
+	/* bootargs are passed in by bootloader */
+
+	memory@40000000 {
+		device_type = "memory";
+		reg =  <0x40000000 0x80000000>;
+	};
+};
+
+&i2c0_bus {
+	/* SCL and SDA pins are swapped */
+	samsung,pins = "gpd1-1", "gpd1-0";
+};
diff --git a/arch/arm/boot/dts/exynos4412-itop-elite.dts b/arch/arm/boot/dts/exynos4412-itop-elite.dts
index a4cd493..0dedeba 100644
--- a/arch/arm/boot/dts/exynos4412-itop-elite.dts
+++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts
@@ -116,14 +116,6 @@
 		compatible = "pwm-beeper";
 		pwms = <&pwm 0 4000000 PWM_POLARITY_INVERTED>;
 	};
-
-	camera: camera {
-		pinctrl-0 = <&cam_port_a_clk_active>;
-		pinctrl-names = "default";
-		status = "okay";
-		assigned-clocks = <&clock CLK_MOUT_CAM0>;
-		assigned-clock-parents = <&clock CLK_XUSBXTI>;
-	};
 };
 
 &adc {
@@ -131,6 +123,14 @@
 	status = "okay";
 };
 
+&camera {
+	pinctrl-0 = <&cam_port_a_clk_active>;
+	pinctrl-names = "default";
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_CAM0>;
+	assigned-clock-parents = <&clock CLK_XUSBXTI>;
+};
+
 &clock_audss {
 	assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>,
 			<&clock_audss EXYNOS_MOUT_I2S>,
diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi
new file mode 100644
index 0000000..76f2b30
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-midas.dtsi
@@ -0,0 +1,1308 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos4412 based Trats 2 board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Device tree source file for Samsung's Trats 2 board which is based on
+ * Samsung's Exynos4412 SoC.
+ */
+
+/dts-v1/;
+#include "exynos4412.dtsi"
+#include "exynos4412-ppmu-common.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/maxim,max77686.h>
+#include <dt-bindings/pinctrl/samsung.h>
+
+/ {
+	compatible = "samsung,midas", "samsung,exynos4412", "samsung,exynos4";
+
+	aliases {
+		i2c11 = &i2c_max77693;
+		i2c12 = &i2c_max77693_fuel;
+	};
+
+	chosen {
+		stdout-path = &serial_2;
+	};
+
+	firmware@204f000 {
+		compatible = "samsung,secure-firmware";
+		reg = <0x0204F000 0x1000>;
+	};
+
+	fixed-rate-clocks {
+		xxti {
+			compatible = "samsung,clock-xxti", "fixed-clock";
+			clock-frequency = <0>;
+		};
+
+		xusbxti {
+			compatible = "samsung,clock-xusbxti", "fixed-clock";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cam_io_reg: voltage-regulator-1 {
+			compatible = "regulator-fixed";
+			regulator-name = "CAM_SENSOR_A";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			enable-active-high;
+			status = "disabled";
+		};
+
+		cam_af_reg: voltage-regulator-3 {
+			compatible = "regulator-fixed";
+			regulator-name = "CAM_AF";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			enable-active-high;
+			status = "disabled";
+		};
+
+		vsil12: voltage-regulator-6 {
+			compatible = "regulator-fixed";
+			regulator-name = "VSIL_1.2V";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			gpio = <&gpl0 4 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+			vin-supply = <&buck7_reg>;
+		};
+
+		vcc33mhl: voltage-regulator-7 {
+			compatible = "regulator-fixed";
+			regulator-name = "VCC_3.3_MHL";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpl0 4 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+
+		vcc18mhl: voltage-regulator-8 {
+			compatible = "regulator-fixed";
+			regulator-name = "VCC_1.8_MHL";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			gpio = <&gpl0 4 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		key-down {
+			gpios = <&gpx3 3 GPIO_ACTIVE_LOW>;
+			linux,code = <114>;
+			label = "volume down";
+			debounce-interval = <10>;
+		};
+
+		key-up {
+			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
+			linux,code = <115>;
+			label = "volume up";
+			debounce-interval = <10>;
+		};
+
+		key-power {
+			gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
+			linux,code = <116>;
+			label = "power";
+			debounce-interval = <10>;
+			wakeup-source;
+		};
+
+		key-ok {
+			gpios = <&gpx0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <139>;
+			label = "ok";
+			debounce-interval = <10>;
+			wakeup-source;
+		};
+	};
+
+	i2c_max77693: i2c-gpio-1 {
+		compatible = "i2c-gpio";
+		gpios = <&gpm2 0 GPIO_ACTIVE_HIGH>, <&gpm2 1 GPIO_ACTIVE_HIGH>;
+		i2c-gpio,delay-us = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+
+		max77693@66 {
+			compatible = "maxim,max77693";
+			interrupt-parent = <&gpx1>;
+			interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+			reg = <0x66>;
+
+			regulators {
+				esafeout1_reg: ESAFEOUT1 {
+					regulator-name = "ESAFEOUT1";
+				};
+				esafeout2_reg: ESAFEOUT2 {
+					regulator-name = "ESAFEOUT2";
+				};
+				charger_reg: CHARGER {
+					regulator-name = "CHARGER";
+					regulator-min-microamp = <60000>;
+					regulator-max-microamp = <2580000>;
+				};
+			};
+
+			max77693_haptic {
+				compatible = "maxim,max77693-haptic";
+				haptic-supply = <&ldo26_reg>;
+				pwms = <&pwm 0 38022 0>;
+			};
+
+			charger {
+				compatible = "maxim,max77693-charger";
+
+				maxim,constant-microvolt = <4350000>;
+				maxim,min-system-microvolt = <3600000>;
+				maxim,thermal-regulation-celsius = <100>;
+				maxim,battery-overcurrent-microamp = <3500000>;
+				maxim,charge-input-threshold-microvolt = <4300000>;
+			};
+		};
+	};
+
+	i2c_max77693_fuel: i2c-gpio-3 {
+		compatible = "i2c-gpio";
+		gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>, <&gpf1 4 GPIO_ACTIVE_HIGH>;
+		i2c-gpio,delay-us = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+
+		max77693-fuel-gauge@36 {
+			compatible = "maxim,max17047";
+			interrupt-parent = <&gpx2>;
+			interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+			reg = <0x36>;
+
+			maxim,over-heat-temp = <700>;
+			maxim,over-volt = <4500>;
+		};
+	};
+
+	i2c-mhl {
+		compatible = "i2c-gpio";
+		gpios = <&gpf0 4 GPIO_ACTIVE_HIGH>, <&gpf0 6 GPIO_ACTIVE_HIGH>;
+		i2c-gpio,delay-us = <100>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pinctrl-0 = <&i2c_mhl_bus>;
+		pinctrl-names = "default";
+		status = "okay";
+
+		sii9234: hdmi-bridge@39 {
+			compatible = "sil,sii9234";
+			avcc33-supply = <&vcc33mhl>;
+			iovcc18-supply = <&vcc18mhl>;
+			avcc12-supply = <&vsil12>;
+			cvcc12-supply = <&vsil12>;
+			reset-gpios = <&gpf3 4 GPIO_ACTIVE_LOW>;
+			interrupt-parent = <&gpf3>;
+			interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+			reg = <0x39>;
+
+			port {
+				mhl_to_hdmi: endpoint {
+					remote-endpoint = <&hdmi_to_mhl>;
+				};
+			};
+		};
+	};
+
+	wlan_pwrseq: sdhci3-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpj0 0 GPIO_ACTIVE_LOW>;
+		clocks = <&max77686 MAX77686_CLK_PMIC>;
+		clock-names = "ext_clock";
+	};
+
+	sound {
+		compatible = "samsung,trats2-audio";
+		samsung,i2s-controller = <&i2s0>;
+		samsung,model = "Trats2";
+		samsung,audio-codec = <&wm1811>;
+		samsung,audio-routing =
+			"SPK", "SPKOUTLN",
+			"SPK", "SPKOUTLP",
+			"SPK", "SPKOUTRN",
+			"SPK", "SPKOUTRP";
+	};
+
+	thermistor-ap {
+		compatible = "murata,ncp15wb473";
+		pullup-uv = <1800000>;	 /* VCC_1.8V_AP */
+		pullup-ohm = <100000>;	 /* 100K */
+		pulldown-ohm = <100000>; /* 100K */
+		io-channels = <&adc 1>;  /* AP temperature */
+	};
+
+	thermistor-battery {
+		compatible = "murata,ncp15wb473";
+		pullup-uv = <1800000>;	 /* VCC_1.8V_AP */
+		pullup-ohm = <100000>;	 /* 100K */
+		pulldown-ohm = <100000>; /* 100K */
+		io-channels = <&adc 2>;  /* Battery temperature */
+	};
+
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			cooling-maps {
+				map0 {
+				     /* Corresponds to 800MHz at freq_table */
+				     cooling-device = <&cpu0 7 7>;
+				};
+				map1 {
+				     /* Corresponds to 200MHz at freq_table */
+				     cooling-device = <&cpu0 13 13>;
+			       };
+		       };
+		};
+	};
+};
+
+&adc {
+	vdd-supply = <&ldo3_reg>;
+	status = "okay";
+};
+
+&bus_dmc {
+	devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
+	vdd-supply = <&buck1_reg>;
+	status = "okay";
+};
+
+&bus_acp {
+	devfreq = <&bus_dmc>;
+	status = "okay";
+};
+
+&bus_c2c {
+	devfreq = <&bus_dmc>;
+	status = "okay";
+};
+
+&bus_leftbus {
+	devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
+	vdd-supply = <&buck3_reg>;
+	status = "okay";
+};
+
+&bus_rightbus {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_display {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_fsys {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_peri {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&bus_mfc {
+	devfreq = <&bus_leftbus>;
+	status = "okay";
+};
+
+&camera {
+	pinctrl-0 = <&cam_port_a_clk_active &cam_port_b_clk_active>;
+	pinctrl-names = "default";
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_CAM0>,
+		<&clock CLK_MOUT_CAM1>;
+	assigned-clock-parents = <&clock CLK_XUSBXTI>,
+		<&clock CLK_XUSBXTI>;
+};
+
+&cpu0 {
+	cpu0-supply = <&buck2_reg>;
+};
+
+&csis_0 {
+	status = "okay";
+	vddcore-supply = <&ldo8_reg>;
+	vddio-supply = <&ldo10_reg>;
+	assigned-clocks = <&clock CLK_MOUT_CSIS0>,
+			<&clock CLK_SCLK_CSIS0>;
+	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+	assigned-clock-rates = <0>, <176000000>;
+
+	/* Camera C (3) MIPI CSI-2 (CSIS0) */
+	port@3 {
+		reg = <3>;
+		csis0_ep: endpoint {
+			remote-endpoint = <&s5c73m3_ep>;
+			data-lanes = <1 2 3 4>;
+			samsung,csis-hs-settle = <12>;
+		};
+	};
+};
+
+&csis_1 {
+	status = "okay";
+	vddcore-supply = <&ldo8_reg>;
+	vddio-supply = <&ldo10_reg>;
+	assigned-clocks = <&clock CLK_MOUT_CSIS1>,
+			<&clock CLK_SCLK_CSIS1>;
+	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+	assigned-clock-rates = <0>, <176000000>;
+
+	/* Camera D (4) MIPI CSI-2 (CSIS1) */
+	port@4 {
+		reg = <4>;
+		csis1_ep: endpoint {
+			remote-endpoint = <&is_s5k6a3_ep>;
+			data-lanes = <1>;
+			samsung,csis-hs-settle = <18>;
+			samsung,csis-wclk;
+		};
+	};
+};
+
+&dsi_0 {
+	vddcore-supply = <&ldo8_reg>;
+	vddio-supply = <&ldo10_reg>;
+	samsung,burst-clock-frequency = <500000000>;
+	samsung,esc-clock-frequency = <20000000>;
+	samsung,pll-clock-frequency = <24000000>;
+};
+
+&exynos_usbphy {
+	vbus-supply = <&esafeout1_reg>;
+	status = "okay";
+};
+
+&fimc_0 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC0>,
+			<&clock CLK_SCLK_FIMC0>;
+	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+	assigned-clock-rates = <0>, <176000000>;
+};
+
+&fimc_1 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC1>,
+			<&clock CLK_SCLK_FIMC1>;
+	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+	assigned-clock-rates = <0>, <176000000>;
+};
+
+&fimc_2 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC2>,
+			<&clock CLK_SCLK_FIMC2>;
+	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+	assigned-clock-rates = <0>, <176000000>;
+};
+
+&fimc_3 {
+	status = "okay";
+	assigned-clocks = <&clock CLK_MOUT_FIMC3>,
+			<&clock CLK_SCLK_FIMC3>;
+	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+	assigned-clock-rates = <0>, <176000000>;
+};
+
+&fimc_is {
+	pinctrl-0 = <&fimc_is_uart>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	};
+
+&fimc_lite_0 {
+	status = "okay";
+};
+
+&fimc_lite_1 {
+	status = "okay";
+};
+
+&fimd {
+	status = "okay";
+};
+
+&hdmi {
+	hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&hdmi_hpd>;
+	vdd-supply = <&ldo3_reg>;
+	vdd_osc-supply = <&ldo4_reg>;
+	vdd_pll-supply = <&ldo3_reg>;
+	ddc = <&i2c_5>;
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@1 {
+			reg = <1>;
+			hdmi_to_mhl: endpoint {
+				remote-endpoint = <&mhl_to_hdmi>;
+			};
+		};
+	};
+};
+
+&hsotg {
+	vusb_d-supply = <&ldo15_reg>;
+	vusb_a-supply = <&ldo12_reg>;
+	dr_mode = "peripheral";
+	status = "okay";
+};
+
+&i2c_0 {
+	samsung,i2c-sda-delay = <100>;
+	samsung,i2c-slave-addr = <0x10>;
+	samsung,i2c-max-bus-freq = <400000>;
+	pinctrl-0 = <&i2c0_bus>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	s5c73m3: s5c73m3@3c {
+		compatible = "samsung,s5c73m3";
+		reg = <0x3c>;
+		xshutdown-gpios = <&gpf1 3 GPIO_ACTIVE_LOW>; /* ISP_RESET */
+		vdd-int-supply = <&buck9_reg>;
+		vddio-cis-supply = <&ldo9_reg>;
+		vddio-host-supply = <&ldo18_reg>;
+		vdd-af-supply = <&cam_af_reg>;
+		vdd-reg-supply = <&cam_io_reg>;
+		clock-frequency = <24000000>;
+		/* CAM_A_CLKOUT */
+		clocks = <&camera 0>;
+		clock-names = "cis_extclk";
+		status = "disabled";
+		port {
+			s5c73m3_ep: endpoint {
+				remote-endpoint = <&csis0_ep>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+&i2c1_isp {
+	pinctrl-0 = <&fimc_is_i2c1>;
+	pinctrl-names = "default";
+
+	s5k6a3@10 {
+		compatible = "samsung,s5k6a3";
+		reg = <0x10>;
+		svdda-supply = <&cam_io_reg>;
+		svddio-supply = <&ldo19_reg>;
+		afvdd-supply = <&ldo19_reg>;
+		clock-frequency = <24000000>;
+		/* CAM_B_CLKOUT */
+		clocks = <&camera 1>;
+		clock-names = "extclk";
+		samsung,camclk-out = <1>;
+		gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>;
+
+		port {
+			is_s5k6a3_ep: endpoint {
+				remote-endpoint = <&csis1_ep>;
+				data-lanes = <1>;
+			};
+		};
+	};
+};
+
+&i2c_3 {
+	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";
+};
+
+&i2c_4 {
+	samsung,i2c-sda-delay = <100>;
+	samsung,i2c-slave-addr = <0x10>;
+	samsung,i2c-max-bus-freq = <100000>;
+	pinctrl-0 = <&i2c4_bus>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	wm1811: wm1811@1a {
+		compatible = "wlf,wm1811";
+		reg = <0x1a>;
+		clocks = <&pmu_system_controller 0>;
+		clock-names = "MCLK1";
+		DCVDD-supply = <&ldo3_reg>;
+		DBVDD1-supply = <&ldo3_reg>;
+		wlf,ldo1ena = <&gpj0 4 0>;
+	};
+};
+
+&i2c_5 {
+	status = "okay";
+};
+
+&i2c_7 {
+	samsung,i2c-sda-delay = <100>;
+	samsung,i2c-slave-addr = <0x10>;
+	samsung,i2c-max-bus-freq = <100000>;
+	pinctrl-0 = <&i2c7_bus>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	max77686: max77686_pmic@9 {
+		compatible = "maxim,max77686";
+		interrupt-parent = <&gpx0>;
+		interrupts = <7 IRQ_TYPE_NONE>;
+		reg = <0x09>;
+		#clock-cells = <1>;
+
+		voltage-regulators {
+			ldo1_reg: LDO1 {
+				regulator-name = "VALIVE_1.0V_AP";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+			};
+
+			ldo2_reg: LDO2 {
+				regulator-name = "VM1M2_1.2V_AP";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo3_reg: LDO3 {
+				regulator-name = "VCC_1.8V_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			ldo4_reg: LDO4 {
+				regulator-name = "VCC_2.8V_AP";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+			};
+
+			ldo5_reg: LDO5 {
+				regulator-name = "VCC_1.8V_IO";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			ldo6_reg: LDO6 {
+				regulator-name = "VMPLL_1.0V_AP";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo7_reg: LDO7 {
+				regulator-name = "VPLL_1.0V_AP";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo8_reg: LDO8 {
+				regulator-name = "VMIPI_1.0V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo9_reg: LDO9 {
+				regulator-name = "CAM_ISP_MIPI_1.2V";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+			};
+
+			ldo10_reg: LDO10 {
+				regulator-name = "VMIPI_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo11_reg: LDO11 {
+				regulator-name = "VABB1_1.95V";
+				regulator-min-microvolt = <1950000>;
+				regulator-max-microvolt = <1950000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo12_reg: LDO12 {
+				regulator-name = "VUOTG_3.0V";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo13_reg: LDO13 {
+				regulator-name = "NFC_AVDD_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo14_reg: LDO14 {
+				regulator-name = "VABB2_1.95V";
+				regulator-min-microvolt = <1950000>;
+				regulator-max-microvolt = <1950000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo15_reg: LDO15 {
+				regulator-name = "VHSIC_1.0V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo16_reg: LDO16 {
+				regulator-name = "VHSIC_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo17_reg: LDO17 {
+				regulator-name = "CAM_SENSOR_CORE_1.2V";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+			};
+
+			ldo18_reg: LDO18 {
+				regulator-name = "CAM_ISP_SEN_IO_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo19_reg: LDO19 {
+				regulator-name = "VT_CAM_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo20_reg: LDO20 {
+				regulator-name = "VDDQ_PRE_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo21_reg: LDO21 {
+				regulator-name = "VTF_2.8V";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				maxim,ena-gpios = <&gpy2 0 GPIO_ACTIVE_HIGH>;
+			};
+
+			ldo22_reg: LDO22 {
+				regulator-name = "VMEM_VDD_2.8V";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				maxim,ena-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
+			};
+
+			ldo23_reg: LDO23 {
+				regulator-name = "TSP_AVDD_3.3V";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo24_reg: LDO24 {
+				regulator-name = "TSP_VDD_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo25_reg: LDO25 {
+				regulator-name = "LDO25";
+			};
+
+			ldo26_reg: LDO26 {
+				regulator-name = "MOTOR_VCC_3.0V";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+			};
+
+			buck1_reg: BUCK1 {
+				regulator-name = "vdd_mif";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck2_reg: BUCK2 {
+				regulator-name = "vdd_arm";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			buck3_reg: BUCK3 {
+				regulator-name = "vdd_int";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <1150000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck4_reg: BUCK4 {
+				regulator-name = "vdd_g3d";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <1150000>;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck5_reg: BUCK5 {
+				regulator-name = "VMEM_1.2V_AP";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+
+			buck6_reg: BUCK6 {
+				regulator-name = "VCC_SUB_1.35V";
+				regulator-min-microvolt = <1350000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+			};
+
+			buck7_reg: BUCK7 {
+				regulator-name = "VCC_SUB_2.0V";
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+				regulator-always-on;
+			};
+
+			buck8_reg: BUCK8 {
+				regulator-name = "VMEM_VDDF_3.0V";
+				regulator-min-microvolt = <2850000>;
+				regulator-max-microvolt = <2850000>;
+				maxim,ena-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
+			};
+
+			buck9_reg: BUCK9 {
+				regulator-name = "CAM_ISP_CORE_1.2V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1200000>;
+			};
+		};
+	};
+};
+
+&i2c_8 {
+	status = "okay";
+};
+
+&i2s0 {
+	pinctrl-0 = <&i2s0_bus>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&mixer {
+	status = "okay";
+};
+
+&mshc_0 {
+	broken-cd;
+	non-removable;
+	card-detect-delay = <200>;
+	vmmc-supply = <&ldo22_reg>;
+	clock-frequency = <400000000>;
+	samsung,dw-mshc-ciu-div = <0>;
+	samsung,dw-mshc-sdr-timing = <2 3>;
+	samsung,dw-mshc-ddr-timing = <1 2>;
+	pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+	pinctrl-names = "default";
+	status = "okay";
+	bus-width = <8>;
+	cap-mmc-highspeed;
+};
+
+&pmu_system_controller {
+	assigned-clocks = <&pmu_system_controller 0>;
+	assigned-clock-parents =  <&clock CLK_XUSBXTI>;
+};
+
+&pinctrl_0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sleep0>;
+
+	mhl_int: mhl-int {
+		samsung,pins = "gpf3-5";
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	i2c_mhl_bus: i2c-mhl-bus {
+		samsung,pins = "gpf0-4", "gpf0-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	sleep0: sleep-states {
+		PIN_SLP(gpa0-0, INPUT, NONE);
+		PIN_SLP(gpa0-1, OUT0, NONE);
+		PIN_SLP(gpa0-2, INPUT, NONE);
+		PIN_SLP(gpa0-3, INPUT, UP);
+		PIN_SLP(gpa0-4, INPUT, NONE);
+		PIN_SLP(gpa0-5, INPUT, DOWN);
+		PIN_SLP(gpa0-6, INPUT, DOWN);
+		PIN_SLP(gpa0-7, INPUT, UP);
+
+		PIN_SLP(gpa1-0, INPUT, DOWN);
+		PIN_SLP(gpa1-1, INPUT, DOWN);
+		PIN_SLP(gpa1-2, INPUT, DOWN);
+		PIN_SLP(gpa1-3, INPUT, DOWN);
+		PIN_SLP(gpa1-4, INPUT, DOWN);
+		PIN_SLP(gpa1-5, INPUT, DOWN);
+
+		PIN_SLP(gpb-0, INPUT, NONE);
+		PIN_SLP(gpb-1, INPUT, NONE);
+		PIN_SLP(gpb-2, INPUT, NONE);
+		PIN_SLP(gpb-3, INPUT, NONE);
+		PIN_SLP(gpb-4, INPUT, DOWN);
+		PIN_SLP(gpb-5, INPUT, UP);
+		PIN_SLP(gpb-6, INPUT, DOWN);
+		PIN_SLP(gpb-7, INPUT, DOWN);
+
+		PIN_SLP(gpc0-0, INPUT, DOWN);
+		PIN_SLP(gpc0-1, INPUT, DOWN);
+		PIN_SLP(gpc0-2, INPUT, DOWN);
+		PIN_SLP(gpc0-3, INPUT, DOWN);
+		PIN_SLP(gpc0-4, INPUT, DOWN);
+
+		PIN_SLP(gpc1-0, INPUT, NONE);
+		PIN_SLP(gpc1-1, PREV, NONE);
+		PIN_SLP(gpc1-2, INPUT, NONE);
+		PIN_SLP(gpc1-3, INPUT, NONE);
+		PIN_SLP(gpc1-4, INPUT, NONE);
+
+		PIN_SLP(gpd0-0, INPUT, DOWN);
+		PIN_SLP(gpd0-1, INPUT, DOWN);
+		PIN_SLP(gpd0-2, INPUT, NONE);
+		PIN_SLP(gpd0-3, INPUT, NONE);
+
+		PIN_SLP(gpd1-0, INPUT, DOWN);
+		PIN_SLP(gpd1-1, INPUT, DOWN);
+		PIN_SLP(gpd1-2, INPUT, NONE);
+		PIN_SLP(gpd1-3, INPUT, NONE);
+
+		PIN_SLP(gpf0-0, INPUT, NONE);
+		PIN_SLP(gpf0-1, INPUT, NONE);
+		PIN_SLP(gpf0-2, INPUT, DOWN);
+		PIN_SLP(gpf0-3, INPUT, DOWN);
+		PIN_SLP(gpf0-4, INPUT, NONE);
+		PIN_SLP(gpf0-5, INPUT, DOWN);
+		PIN_SLP(gpf0-6, INPUT, NONE);
+		PIN_SLP(gpf0-7, INPUT, DOWN);
+
+		PIN_SLP(gpf1-0, INPUT, DOWN);
+		PIN_SLP(gpf1-1, INPUT, DOWN);
+		PIN_SLP(gpf1-2, INPUT, DOWN);
+		PIN_SLP(gpf1-3, INPUT, DOWN);
+		PIN_SLP(gpf1-4, INPUT, NONE);
+		PIN_SLP(gpf1-5, INPUT, NONE);
+		PIN_SLP(gpf1-6, INPUT, DOWN);
+		PIN_SLP(gpf1-7, PREV, NONE);
+
+		PIN_SLP(gpf2-0, PREV, NONE);
+		PIN_SLP(gpf2-1, INPUT, DOWN);
+		PIN_SLP(gpf2-2, INPUT, DOWN);
+		PIN_SLP(gpf2-3, INPUT, DOWN);
+		PIN_SLP(gpf2-4, INPUT, DOWN);
+		PIN_SLP(gpf2-5, INPUT, DOWN);
+		PIN_SLP(gpf2-6, INPUT, NONE);
+		PIN_SLP(gpf2-7, INPUT, NONE);
+
+		PIN_SLP(gpf3-0, INPUT, NONE);
+		PIN_SLP(gpf3-1, PREV, NONE);
+		PIN_SLP(gpf3-2, PREV, NONE);
+		PIN_SLP(gpf3-3, PREV, NONE);
+		PIN_SLP(gpf3-4, OUT1, NONE);
+		PIN_SLP(gpf3-5, INPUT, DOWN);
+
+		PIN_SLP(gpj0-0, PREV, NONE);
+		PIN_SLP(gpj0-1, PREV, NONE);
+		PIN_SLP(gpj0-2, PREV, NONE);
+		PIN_SLP(gpj0-3, INPUT, DOWN);
+		PIN_SLP(gpj0-4, PREV, NONE);
+		PIN_SLP(gpj0-5, PREV, NONE);
+		PIN_SLP(gpj0-6, INPUT, DOWN);
+		PIN_SLP(gpj0-7, INPUT, DOWN);
+
+		PIN_SLP(gpj1-0, INPUT, DOWN);
+		PIN_SLP(gpj1-1, PREV, NONE);
+		PIN_SLP(gpj1-2, PREV, NONE);
+		PIN_SLP(gpj1-3, INPUT, DOWN);
+		PIN_SLP(gpj1-4, INPUT, DOWN);
+	};
+};
+
+&pinctrl_1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sleep1>;
+
+	hdmi_hpd: hdmi-hpd {
+		samsung,pins = "gpx3-7";
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	sleep1: sleep-states {
+		PIN_SLP(gpk0-0, PREV, NONE);
+		PIN_SLP(gpk0-1, PREV, NONE);
+		PIN_SLP(gpk0-2, OUT0, NONE);
+		PIN_SLP(gpk0-3, PREV, NONE);
+		PIN_SLP(gpk0-4, PREV, NONE);
+		PIN_SLP(gpk0-5, PREV, NONE);
+		PIN_SLP(gpk0-6, PREV, NONE);
+
+		PIN_SLP(gpk1-0, INPUT, DOWN);
+		PIN_SLP(gpk1-1, INPUT, DOWN);
+		PIN_SLP(gpk1-2, INPUT, DOWN);
+		PIN_SLP(gpk1-3, PREV, NONE);
+		PIN_SLP(gpk1-4, PREV, NONE);
+		PIN_SLP(gpk1-5, PREV, NONE);
+		PIN_SLP(gpk1-6, PREV, NONE);
+
+		PIN_SLP(gpk2-0, INPUT, DOWN);
+		PIN_SLP(gpk2-1, INPUT, DOWN);
+		PIN_SLP(gpk2-2, INPUT, DOWN);
+		PIN_SLP(gpk2-3, INPUT, DOWN);
+		PIN_SLP(gpk2-4, INPUT, DOWN);
+		PIN_SLP(gpk2-5, INPUT, DOWN);
+		PIN_SLP(gpk2-6, INPUT, DOWN);
+
+		PIN_SLP(gpk3-0, OUT0, NONE);
+		PIN_SLP(gpk3-1, INPUT, NONE);
+		PIN_SLP(gpk3-2, INPUT, DOWN);
+		PIN_SLP(gpk3-3, INPUT, NONE);
+		PIN_SLP(gpk3-4, INPUT, NONE);
+		PIN_SLP(gpk3-5, INPUT, NONE);
+		PIN_SLP(gpk3-6, INPUT, NONE);
+
+		PIN_SLP(gpl0-0, INPUT, DOWN);
+		PIN_SLP(gpl0-1, INPUT, DOWN);
+		PIN_SLP(gpl0-2, INPUT, DOWN);
+		PIN_SLP(gpl0-3, INPUT, DOWN);
+		PIN_SLP(gpl0-4, PREV, NONE);
+		PIN_SLP(gpl0-6, PREV, NONE);
+
+		PIN_SLP(gpl1-0, INPUT, DOWN);
+		PIN_SLP(gpl1-1, INPUT, DOWN);
+		PIN_SLP(gpl2-0, INPUT, DOWN);
+		PIN_SLP(gpl2-1, INPUT, DOWN);
+		PIN_SLP(gpl2-2, INPUT, DOWN);
+		PIN_SLP(gpl2-3, INPUT, DOWN);
+		PIN_SLP(gpl2-4, INPUT, DOWN);
+		PIN_SLP(gpl2-5, INPUT, DOWN);
+		PIN_SLP(gpl2-6, PREV, NONE);
+		PIN_SLP(gpl2-7, INPUT, DOWN);
+
+		PIN_SLP(gpm0-0, INPUT, DOWN);
+		PIN_SLP(gpm0-1, INPUT, DOWN);
+		PIN_SLP(gpm0-2, INPUT, DOWN);
+		PIN_SLP(gpm0-3, INPUT, DOWN);
+		PIN_SLP(gpm0-4, INPUT, DOWN);
+		PIN_SLP(gpm0-5, INPUT, DOWN);
+		PIN_SLP(gpm0-6, INPUT, DOWN);
+		PIN_SLP(gpm0-7, INPUT, DOWN);
+
+		PIN_SLP(gpm1-0, INPUT, DOWN);
+		PIN_SLP(gpm1-1, INPUT, DOWN);
+		PIN_SLP(gpm1-2, INPUT, NONE);
+		PIN_SLP(gpm1-3, INPUT, NONE);
+		PIN_SLP(gpm1-4, INPUT, NONE);
+		PIN_SLP(gpm1-5, INPUT, NONE);
+		PIN_SLP(gpm1-6, INPUT, DOWN);
+
+		PIN_SLP(gpm2-0, INPUT, NONE);
+		PIN_SLP(gpm2-1, INPUT, NONE);
+		PIN_SLP(gpm2-2, INPUT, DOWN);
+		PIN_SLP(gpm2-3, INPUT, DOWN);
+		PIN_SLP(gpm2-4, INPUT, DOWN);
+
+		PIN_SLP(gpm3-0, PREV, NONE);
+		PIN_SLP(gpm3-1, PREV, NONE);
+		PIN_SLP(gpm3-2, PREV, NONE);
+		PIN_SLP(gpm3-3, OUT1, NONE);
+		PIN_SLP(gpm3-4, INPUT, DOWN);
+		PIN_SLP(gpm3-5, INPUT, DOWN);
+		PIN_SLP(gpm3-6, INPUT, DOWN);
+		PIN_SLP(gpm3-7, INPUT, DOWN);
+
+		PIN_SLP(gpm4-0, INPUT, DOWN);
+		PIN_SLP(gpm4-1, INPUT, DOWN);
+		PIN_SLP(gpm4-2, INPUT, DOWN);
+		PIN_SLP(gpm4-3, INPUT, DOWN);
+		PIN_SLP(gpm4-4, INPUT, DOWN);
+		PIN_SLP(gpm4-5, INPUT, DOWN);
+		PIN_SLP(gpm4-6, INPUT, DOWN);
+		PIN_SLP(gpm4-7, INPUT, DOWN);
+
+		PIN_SLP(gpy0-0, INPUT, DOWN);
+		PIN_SLP(gpy0-1, INPUT, DOWN);
+		PIN_SLP(gpy0-2, INPUT, DOWN);
+		PIN_SLP(gpy0-3, INPUT, DOWN);
+		PIN_SLP(gpy0-4, INPUT, DOWN);
+		PIN_SLP(gpy0-5, INPUT, DOWN);
+
+		PIN_SLP(gpy1-0, INPUT, DOWN);
+		PIN_SLP(gpy1-1, INPUT, DOWN);
+		PIN_SLP(gpy1-2, INPUT, DOWN);
+		PIN_SLP(gpy1-3, INPUT, DOWN);
+
+		PIN_SLP(gpy2-0, PREV, NONE);
+		PIN_SLP(gpy2-1, INPUT, DOWN);
+		PIN_SLP(gpy2-2, INPUT, NONE);
+		PIN_SLP(gpy2-3, INPUT, NONE);
+		PIN_SLP(gpy2-4, INPUT, NONE);
+		PIN_SLP(gpy2-5, INPUT, NONE);
+
+		PIN_SLP(gpy3-0, INPUT, DOWN);
+		PIN_SLP(gpy3-1, INPUT, DOWN);
+		PIN_SLP(gpy3-2, INPUT, DOWN);
+		PIN_SLP(gpy3-3, INPUT, DOWN);
+		PIN_SLP(gpy3-4, INPUT, DOWN);
+		PIN_SLP(gpy3-5, INPUT, DOWN);
+		PIN_SLP(gpy3-6, INPUT, DOWN);
+		PIN_SLP(gpy3-7, INPUT, DOWN);
+
+		PIN_SLP(gpy4-0, INPUT, DOWN);
+		PIN_SLP(gpy4-1, INPUT, DOWN);
+		PIN_SLP(gpy4-2, INPUT, DOWN);
+		PIN_SLP(gpy4-3, INPUT, DOWN);
+		PIN_SLP(gpy4-4, INPUT, DOWN);
+		PIN_SLP(gpy4-5, INPUT, DOWN);
+		PIN_SLP(gpy4-6, INPUT, DOWN);
+		PIN_SLP(gpy4-7, INPUT, DOWN);
+
+		PIN_SLP(gpy5-0, INPUT, DOWN);
+		PIN_SLP(gpy5-1, INPUT, DOWN);
+		PIN_SLP(gpy5-2, INPUT, DOWN);
+		PIN_SLP(gpy5-3, INPUT, DOWN);
+		PIN_SLP(gpy5-4, INPUT, DOWN);
+		PIN_SLP(gpy5-5, INPUT, DOWN);
+		PIN_SLP(gpy5-6, INPUT, DOWN);
+		PIN_SLP(gpy5-7, INPUT, DOWN);
+
+		PIN_SLP(gpy6-0, INPUT, DOWN);
+		PIN_SLP(gpy6-1, INPUT, DOWN);
+		PIN_SLP(gpy6-2, INPUT, DOWN);
+		PIN_SLP(gpy6-3, INPUT, DOWN);
+		PIN_SLP(gpy6-4, INPUT, DOWN);
+		PIN_SLP(gpy6-5, INPUT, DOWN);
+		PIN_SLP(gpy6-6, INPUT, DOWN);
+		PIN_SLP(gpy6-7, INPUT, DOWN);
+	};
+};
+
+&pinctrl_2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sleep2>;
+
+	sleep2: sleep-states {
+		PIN_SLP(gpz-0, INPUT, DOWN);
+		PIN_SLP(gpz-1, INPUT, DOWN);
+		PIN_SLP(gpz-2, INPUT, DOWN);
+		PIN_SLP(gpz-3, INPUT, DOWN);
+		PIN_SLP(gpz-4, INPUT, DOWN);
+		PIN_SLP(gpz-5, INPUT, DOWN);
+		PIN_SLP(gpz-6, INPUT, DOWN);
+	};
+};
+
+&pinctrl_3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sleep3>;
+
+	sleep3: sleep-states {
+		PIN_SLP(gpv0-0, INPUT, DOWN);
+		PIN_SLP(gpv0-1, INPUT, DOWN);
+		PIN_SLP(gpv0-2, INPUT, DOWN);
+		PIN_SLP(gpv0-3, INPUT, DOWN);
+		PIN_SLP(gpv0-4, INPUT, DOWN);
+		PIN_SLP(gpv0-5, INPUT, DOWN);
+		PIN_SLP(gpv0-6, INPUT, DOWN);
+		PIN_SLP(gpv0-7, INPUT, DOWN);
+
+		PIN_SLP(gpv1-0, INPUT, DOWN);
+		PIN_SLP(gpv1-1, INPUT, DOWN);
+		PIN_SLP(gpv1-2, INPUT, DOWN);
+		PIN_SLP(gpv1-3, INPUT, DOWN);
+		PIN_SLP(gpv1-4, INPUT, DOWN);
+		PIN_SLP(gpv1-5, INPUT, DOWN);
+		PIN_SLP(gpv1-6, INPUT, DOWN);
+		PIN_SLP(gpv1-7, INPUT, DOWN);
+
+		PIN_SLP(gpv2-0, INPUT, DOWN);
+		PIN_SLP(gpv2-1, INPUT, DOWN);
+		PIN_SLP(gpv2-2, INPUT, DOWN);
+		PIN_SLP(gpv2-3, INPUT, DOWN);
+		PIN_SLP(gpv2-4, INPUT, DOWN);
+		PIN_SLP(gpv2-5, INPUT, DOWN);
+		PIN_SLP(gpv2-6, INPUT, DOWN);
+		PIN_SLP(gpv2-7, INPUT, DOWN);
+
+		PIN_SLP(gpv3-0, INPUT, DOWN);
+		PIN_SLP(gpv3-1, INPUT, DOWN);
+		PIN_SLP(gpv3-2, INPUT, DOWN);
+		PIN_SLP(gpv3-3, INPUT, DOWN);
+		PIN_SLP(gpv3-4, INPUT, DOWN);
+		PIN_SLP(gpv3-5, INPUT, DOWN);
+		PIN_SLP(gpv3-6, INPUT, DOWN);
+		PIN_SLP(gpv3-7, INPUT, DOWN);
+
+		PIN_SLP(gpv4-0, INPUT, DOWN);
+	};
+};
+
+&pwm {
+	pinctrl-0 = <&pwm0_out>;
+	pinctrl-names = "default";
+	samsung,pwm-outputs = <0>;
+	status = "okay";
+};
+
+&rtc {
+	status = "okay";
+	clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>;
+	clock-names = "rtc", "rtc_src";
+};
+
+&sdhci_2 {
+	bus-width = <4>;
+	cd-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
+	pinctrl-names = "default";
+	vmmc-supply = <&ldo21_reg>;
+	status = "okay";
+};
+
+&sdhci_3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	non-removable;
+	bus-width = <4>;
+
+	mmc-pwrseq = <&wlan_pwrseq>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>;
+	status = "okay";
+
+	brcmf: wifi@1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+		interrupt-parent = <&gpx2>;
+		interrupts = <5 IRQ_TYPE_NONE>;
+		interrupt-names = "host-wake";
+	};
+};
+
+&serial_0 {
+	status = "okay";
+};
+
+&serial_1 {
+	status = "okay";
+};
+
+&serial_2 {
+	status = "okay";
+};
+
+&serial_3 {
+	status = "okay";
+};
+
+&spi_1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_bus>;
+	cs-gpios = <&gpb 5 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+
+	s5c73m3_spi: s5c73m3@0 {
+		compatible = "samsung,s5c73m3";
+		spi-max-frequency = <50000000>;
+		reg = <0>;
+		controller-data {
+			samsung,spi-feedback-delay = <2>;
+		};
+	};
+};
+
+&tmu {
+	vtmu-supply = <&ldo10_reg>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/exynos4412-n710x.dts b/arch/arm/boot/dts/exynos4412-n710x.dts
new file mode 100644
index 0000000..eb402a0
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-n710x.dts
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "exynos4412-midas.dtsi"
+
+/ {
+	compatible = "samsung,n710x", "samsung,midas", "samsung,exynos4412", "samsung,exynos4";
+	model = "Samsung Galaxy Note 2 (GT-N7100, GT-N7105) based on Exynos4412";
+
+	memory@40000000 {
+		device_type = "memory";
+		reg =  <0x40000000 0x80000000>;
+	};
+
+	/* bootargs are passed in by bootloader */
+
+	regulators {
+		cam_vdda_reg: voltage-regulator-9 {
+			compatible = "regulator-fixed";
+			regulator-name = "CAM_SENSOR_CORE_1.2V";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			gpio = <&gpm4 1 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+	};
+};
+
+&buck9_reg {
+	maxim,ena-gpios = <&gpm1 0 GPIO_ACTIVE_HIGH>;
+};
+
+&cam_af_reg {
+	gpio = <&gpm1 1 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&cam_io_reg {
+	gpio = <&gpm0 7 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&i2c_3 {
+	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";
+
+	mms152-touchscreen@48 {
+		compatible = "melfas,mms152";
+		reg = <0x48>;
+		interrupt-parent = <&gpm2>;
+		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+		x-size = <720>;
+		y-size = <1280>;
+		avdd-supply = <&ldo23_reg>;
+		vdd-supply = <&ldo24_reg>;
+	};
+};
+
+&ldo13_reg {
+	regulator-name = "VCC_1.8V_LCD";
+	regulator-always-on;
+};
+
+&ldo25_reg {
+	regulator-name = "VCI_3.0V_LCD";
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+};
+
+&s5c73m3 {
+	standby-gpios = <&gpm0 6 GPIO_ACTIVE_LOW>;   /* ISP_STANDBY */
+	vdda-supply = <&cam_vdda_reg>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 556ea78..d7ad07f 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -61,12 +61,6 @@
 		reset-gpios = <&gpk1 2 GPIO_ACTIVE_LOW>;
 	};
 
-	camera {
-		status = "okay";
-		pinctrl-names = "default";
-		pinctrl-0 = <>;
-	};
-
 	fixed-rate-clocks {
 		xxti {
 			compatible = "samsung,clock-xxti";
@@ -142,6 +136,12 @@
 	status = "okay";
 };
 
+&camera {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
 &clock_audss {
 	assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>,
 			<&clock_audss EXYNOS_MOUT_I2S>,
diff --git a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
index e8dd5f2d..d7d5fdc 100644
--- a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
@@ -18,964 +18,962 @@
 		samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_ ##_pull>;	\
 	}
 
-/ {
-	pinctrl_0: pinctrl@11400000 {
-		gpa0: gpa0 {
-			gpio-controller;
-			#gpio-cells = <2>;
+&pinctrl_0 {
+	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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart0_fctl: uart0-fctl {
-			samsung,pins = "gpa0-2", "gpa0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart1_data: uart1-data {
-			samsung,pins = "gpa0-4", "gpa0-5";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart1_fctl: uart1-fctl {
-			samsung,pins = "gpa0-6", "gpa0-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c2_bus: i2c2-bus {
-			samsung,pins = "gpa0-6", "gpa0-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart2_data: uart2-data {
-			samsung,pins = "gpa1-0", "gpa1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart2_fctl: uart2-fctl {
-			samsung,pins = "gpa1-2", "gpa1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart_audio_a: uart-audio-a {
-			samsung,pins = "gpa1-0", "gpa1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c3_bus: i2c3-bus {
-			samsung,pins = "gpa1-2", "gpa1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart3_data: uart3-data {
-			samsung,pins = "gpa1-4", "gpa1-5";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart_audio_b: uart-audio-b {
-			samsung,pins = "gpa1-4", "gpa1-5";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		spi0_bus: spi0-bus {
-			samsung,pins = "gpb-0", "gpb-2", "gpb-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c4_bus: i2c4-bus {
-			samsung,pins = "gpb-0", "gpb-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		spi1_bus: spi1-bus {
-			samsung,pins = "gpb-4", "gpb-6", "gpb-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c5_bus: i2c5-bus {
-			samsung,pins = "gpb-2", "gpb-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2s1_bus: i2s1-bus {
-			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
-					"gpc0-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pcm1_bus: pcm1-bus {
-			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
-					"gpc0-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		ac97_bus: ac97-bus {
-			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
-					"gpc0-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2s2_bus: i2s2-bus {
-			samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
-					"gpc1-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pcm2_bus: pcm2-bus {
-			samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
-					"gpc1-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		spdif_bus: spdif-bus {
-			samsung,pins = "gpc1-0", "gpc1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c6_bus: i2c6-bus {
-			samsung,pins = "gpc1-3", "gpc1-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		spi2_bus: spi2-bus {
-			samsung,pins = "gpc1-1", "gpc1-3", "gpc1-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pwm0_out: pwm0-out {
-			samsung,pins = "gpd0-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pwm1_out: pwm1-out {
-			samsung,pins = "gpd0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		lcd_ctrl: lcd-ctrl {
-			samsung,pins = "gpd0-0", "gpd0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c7_bus: i2c7-bus {
-			samsung,pins = "gpd0-2", "gpd0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pwm2_out: pwm2-out {
-			samsung,pins = "gpd0-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pwm3_out: pwm3-out {
-			samsung,pins = "gpd0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c0_bus: i2c0-bus {
-			samsung,pins = "gpd1-0", "gpd1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		mipi0_clk: mipi0-clk {
-			samsung,pins = "gpd1-0", "gpd1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c1_bus: i2c1-bus {
-			samsung,pins = "gpd1-2", "gpd1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		mipi1_clk: mipi1-clk {
-			samsung,pins = "gpd1-2", "gpd1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		lcd_clk: lcd-clk {
-			samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		lcd_ldi: lcd-ldi {
-			samsung,pins = "gpf3-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		cam_port_a_io: cam-port-a-io {
-			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-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		cam_port_a_clk_active: cam-port-a-clk-active {
-			samsung,pins = "gpj1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		cam_port_a_clk_idle: cam-port-a-clk-idle {
-			samsung,pins = "gpj1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
 	};
 
-	pinctrl_1: pinctrl@11000000 {
-		gpk0: gpk0 {
-			gpio-controller;
-			#gpio-cells = <2>;
+	gpa1: gpa1 {
+		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 = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-			#interrupt-cells = <2>;
-		};
-
-		gpx1: gpx1 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			interrupt-parent = <&gic>;
-			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-			#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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_cmd: sd0-cmd {
-			samsung,pins = "gpk0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_cd: sd0-cd {
-			samsung,pins = "gpk0-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_bus1: sd0-bus-width1 {
-			samsung,pins = "gpk0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_bus4: sd0-bus-width4 {
-			samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd0_bus8: sd0-bus-width8 {
-			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_clk: sd4-clk {
-			samsung,pins = "gpk0-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_cmd: sd4-cmd {
-			samsung,pins = "gpk0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_cd: sd4-cd {
-			samsung,pins = "gpk0-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_bus1: sd4-bus-width1 {
-			samsung,pins = "gpk0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_bus4: sd4-bus-width4 {
-			samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd4_bus8: sd4-bus-width8 {
-			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_clk: sd1-clk {
-			samsung,pins = "gpk1-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_cmd: sd1-cmd {
-			samsung,pins = "gpk1-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_cd: sd1-cd {
-			samsung,pins = "gpk1-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_bus1: sd1-bus-width1 {
-			samsung,pins = "gpk1-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd1_bus4: sd1-bus-width4 {
-			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_clk: sd2-clk {
-			samsung,pins = "gpk2-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_cmd: sd2-cmd {
-			samsung,pins = "gpk2-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_cd: sd2-cd {
-			samsung,pins = "gpk2-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_bus1: sd2-bus-width1 {
-			samsung,pins = "gpk2-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_bus4: sd2-bus-width4 {
-			samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd2_bus8: sd2-bus-width8 {
-			samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_clk: sd3-clk {
-			samsung,pins = "gpk3-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_cmd: sd3-cmd {
-			samsung,pins = "gpk3-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_cd: sd3-cd {
-			samsung,pins = "gpk3-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_bus1: sd3-bus-width1 {
-			samsung,pins = "gpk3-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		sd3_bus4: sd3-bus-width4 {
-			samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		cam_port_b_io: cam-port-b-io {
-			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";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		cam_port_b_clk_active: cam-port-b-clk-active {
-			samsung,pins = "gpm2-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-		};
-
-		cam_port_b_clk_idle: cam-port-b-clk-idle {
-			samsung,pins = "gpm2-2";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint0: ext-int0 {
-			samsung,pins = "gpx0-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint8: ext-int8 {
-			samsung,pins = "gpx1-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint15: ext-int15 {
-			samsung,pins = "gpx1-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint16: ext-int16 {
-			samsung,pins = "gpx2-0";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		eint31: ext-int31 {
-			samsung,pins = "gpx3-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		fimc_is_i2c0: fimc-is-i2c0 {
-			samsung,pins = "gpm4-0", "gpm4-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		fimc_is_i2c1: fimc-is-i2c1 {
-			samsung,pins = "gpm4-2", "gpm4-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		fimc_is_uart: fimc-is-uart {
-			samsung,pins = "gpm3-5", "gpm3-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		hdmi_cec: hdmi-cec {
-			samsung,pins = "gpx3-6";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
 	};
 
-	pinctrl_2: pinctrl@3860000 {
-		gpz: gpz {
-			gpio-controller;
-			#gpio-cells = <2>;
+	gpb: gpb {
+		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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		pcm0_bus: pcm0-bus {
-			samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
-					"gpz-4";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
 	};
 
-	pinctrl_3: pinctrl@106e0000 {
-		gpv0: gpv0 {
-			gpio-controller;
-			#gpio-cells = <2>;
+	gpc0: gpc0 {
+		gpio-controller;
+		#gpio-cells = <2>;
 
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
 
-		gpv1: gpv1 {
-			gpio-controller;
-			#gpio-cells = <2>;
+	gpc1: gpc1 {
+		gpio-controller;
+		#gpio-cells = <2>;
 
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
 
-		gpv2: gpv2 {
-			gpio-controller;
-			#gpio-cells = <2>;
+	gpd0: gpd0 {
+		gpio-controller;
+		#gpio-cells = <2>;
 
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
 
-		gpv3: gpv3 {
-			gpio-controller;
-			#gpio-cells = <2>;
+	gpd1: gpd1 {
+		gpio-controller;
+		#gpio-cells = <2>;
 
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
 
-		gpv4: gpv4 {
-			gpio-controller;
-			#gpio-cells = <2>;
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
 
-			interrupt-controller;
-			#interrupt-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 = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart0_fctl: uart0-fctl {
+		samsung,pins = "gpa0-2", "gpa0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_data: uart1-data {
+		samsung,pins = "gpa0-4", "gpa0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_fctl: uart1-fctl {
+		samsung,pins = "gpa0-6", "gpa0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c2_bus: i2c2-bus {
+		samsung,pins = "gpa0-6", "gpa0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart2_data: uart2-data {
+		samsung,pins = "gpa1-0", "gpa1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart2_fctl: uart2-fctl {
+		samsung,pins = "gpa1-2", "gpa1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart_audio_a: uart-audio-a {
+		samsung,pins = "gpa1-0", "gpa1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c3_bus: i2c3-bus {
+		samsung,pins = "gpa1-2", "gpa1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart3_data: uart3-data {
+		samsung,pins = "gpa1-4", "gpa1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart_audio_b: uart-audio-b {
+		samsung,pins = "gpa1-4", "gpa1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi0_bus: spi0-bus {
+		samsung,pins = "gpb-0", "gpb-2", "gpb-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c4_bus: i2c4-bus {
+		samsung,pins = "gpb-0", "gpb-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi1_bus: spi1-bus {
+		samsung,pins = "gpb-4", "gpb-6", "gpb-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c5_bus: i2c5-bus {
+		samsung,pins = "gpb-2", "gpb-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2s1_bus: i2s1-bus {
+		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+				"gpc0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pcm1_bus: pcm1-bus {
+		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+				"gpc0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	ac97_bus: ac97-bus {
+		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+				"gpc0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2s2_bus: i2s2-bus {
+		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+				"gpc1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pcm2_bus: pcm2-bus {
+		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+				"gpc1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spdif_bus: spdif-bus {
+		samsung,pins = "gpc1-0", "gpc1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c6_bus: i2c6-bus {
+		samsung,pins = "gpc1-3", "gpc1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi2_bus: spi2-bus {
+		samsung,pins = "gpc1-1", "gpc1-3", "gpc1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pwm0_out: pwm0-out {
+		samsung,pins = "gpd0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pwm1_out: pwm1-out {
+		samsung,pins = "gpd0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	lcd_ctrl: lcd-ctrl {
+		samsung,pins = "gpd0-0", "gpd0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c7_bus: i2c7-bus {
+		samsung,pins = "gpd0-2", "gpd0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pwm2_out: pwm2-out {
+		samsung,pins = "gpd0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pwm3_out: pwm3-out {
+		samsung,pins = "gpd0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c0_bus: i2c0-bus {
+		samsung,pins = "gpd1-0", "gpd1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	mipi0_clk: mipi0-clk {
+		samsung,pins = "gpd1-0", "gpd1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	i2c1_bus: i2c1-bus {
+		samsung,pins = "gpd1-2", "gpd1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	mipi1_clk: mipi1-clk {
+		samsung,pins = "gpd1-2", "gpd1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	lcd_clk: lcd-clk {
+		samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	lcd_ldi: lcd-ldi {
+		samsung,pins = "gpf3-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	cam_port_a_io: cam-port-a-io {
+		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-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	cam_port_a_clk_active: cam-port-a-clk-active {
+		samsung,pins = "gpj1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	cam_port_a_clk_idle: cam-port-a-clk-idle {
+		samsung,pins = "gpj1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_1 {
+	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 = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+		#interrupt-cells = <2>;
+	};
+
+	gpx1: gpx1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		#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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_cmd: sd0-cmd {
+		samsung,pins = "gpk0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_cd: sd0-cd {
+		samsung,pins = "gpk0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_bus1: sd0-bus-width1 {
+		samsung,pins = "gpk0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_bus4: sd0-bus-width4 {
+		samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd0_bus8: sd0-bus-width8 {
+		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_clk: sd4-clk {
+		samsung,pins = "gpk0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_cmd: sd4-cmd {
+		samsung,pins = "gpk0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_cd: sd4-cd {
+		samsung,pins = "gpk0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_bus1: sd4-bus-width1 {
+		samsung,pins = "gpk0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_bus4: sd4-bus-width4 {
+		samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd4_bus8: sd4-bus-width8 {
+		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_clk: sd1-clk {
+		samsung,pins = "gpk1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_cmd: sd1-cmd {
+		samsung,pins = "gpk1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_cd: sd1-cd {
+		samsung,pins = "gpk1-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_bus1: sd1-bus-width1 {
+		samsung,pins = "gpk1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd1_bus4: sd1-bus-width4 {
+		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_clk: sd2-clk {
+		samsung,pins = "gpk2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_cmd: sd2-cmd {
+		samsung,pins = "gpk2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_cd: sd2-cd {
+		samsung,pins = "gpk2-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_bus1: sd2-bus-width1 {
+		samsung,pins = "gpk2-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_bus4: sd2-bus-width4 {
+		samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd2_bus8: sd2-bus-width8 {
+		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_clk: sd3-clk {
+		samsung,pins = "gpk3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_cmd: sd3-cmd {
+		samsung,pins = "gpk3-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_cd: sd3-cd {
+		samsung,pins = "gpk3-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_bus1: sd3-bus-width1 {
+		samsung,pins = "gpk3-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	sd3_bus4: sd3-bus-width4 {
+		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	cam_port_b_io: cam-port-b-io {
+		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";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	cam_port_b_clk_active: cam-port-b-clk-active {
+		samsung,pins = "gpm2-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+	};
+
+	cam_port_b_clk_idle: cam-port-b-clk-idle {
+		samsung,pins = "gpm2-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint0: ext-int0 {
+		samsung,pins = "gpx0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint8: ext-int8 {
+		samsung,pins = "gpx1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint15: ext-int15 {
+		samsung,pins = "gpx1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint16: ext-int16 {
+		samsung,pins = "gpx2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	eint31: ext-int31 {
+		samsung,pins = "gpx3-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	fimc_is_i2c0: fimc-is-i2c0 {
+		samsung,pins = "gpm4-0", "gpm4-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	fimc_is_i2c1: fimc-is-i2c1 {
+		samsung,pins = "gpm4-2", "gpm4-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	fimc_is_uart: fimc-is-uart {
+		samsung,pins = "gpm3-5", "gpm3-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hdmi_cec: hdmi-cec {
+		samsung,pins = "gpx3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_2 {
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	pcm0_bus: pcm0-bus {
+		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+				"gpz-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_3 {
+	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 = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 };
diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts
index 5504398..01f37b5 100644
--- a/arch/arm/boot/dts/exynos4412-tiny4412.dts
+++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * FriendlyARM's Exynos4412 based TINY4412 board device tree source
  *
@@ -5,11 +6,7 @@
  *
  * Device tree source file for FriendlyARM's TINY4412 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"
diff --git a/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
index e3f7934..489b58c 100644
--- a/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
+++ b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device tree sources for Exynos4412 TMU sensor configuration
  *
  * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <dt-bindings/thermal/thermal_exynos.h>
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index f285790..327ee98 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Samsung's Exynos4412 based Trats 2 board device tree source
  *
@@ -6,30 +7,14 @@
  *
  * Device tree source file for Samsung's Trats 2 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"
-#include "exynos4412-ppmu-common.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/clock/maxim,max77686.h>
-#include <dt-bindings/pinctrl/samsung.h>
+#include "exynos4412-galaxy-s3.dtsi"
 
 / {
 	model = "Samsung Trats 2 based on Exynos4412";
-	compatible = "samsung,trats2", "samsung,exynos4412", "samsung,exynos4";
-
-	aliases {
-		i2c9 = &i2c_ak8975;
-		i2c10 = &i2c_cm36651;
-		i2c11 = &i2c_max77693;
-		i2c12 = &i2c_max77693_fuel;
-	};
+	compatible = "samsung,trats2", "samsung,midas", "samsung,exynos4412", "samsung,exynos4";
 
 	memory@40000000 {
 		device_type = "memory";
@@ -38,1378 +23,5 @@
 
 	chosen {
 		bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
-		stdout-path = &serial_2;
 	};
-
-	firmware@204f000 {
-		compatible = "samsung,secure-firmware";
-		reg = <0x0204F000 0x1000>;
-	};
-
-	fixed-rate-clocks {
-		xxti {
-			compatible = "samsung,clock-xxti", "fixed-clock";
-			clock-frequency = <0>;
-		};
-
-		xusbxti {
-			compatible = "samsung,clock-xusbxti", "fixed-clock";
-			clock-frequency = <24000000>;
-		};
-	};
-
-	regulators {
-		compatible = "simple-bus";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		cam_io_reg: voltage-regulator-1 {
-			compatible = "regulator-fixed";
-			regulator-name = "CAM_SENSOR_A";
-			regulator-min-microvolt = <2800000>;
-			regulator-max-microvolt = <2800000>;
-			gpio = <&gpm0 2 GPIO_ACTIVE_HIGH>;
-			enable-active-high;
-		};
-
-		lcd_vdd3_reg: voltage-regulator-2 {
-			compatible = "regulator-fixed";
-			regulator-name = "LCD_VDD_2.2V";
-			regulator-min-microvolt = <2200000>;
-			regulator-max-microvolt = <2200000>;
-			gpio = <&gpc0 1 GPIO_ACTIVE_HIGH>;
-			enable-active-high;
-		};
-
-		cam_af_reg: voltage-regulator-3 {
-			compatible = "regulator-fixed";
-			regulator-name = "CAM_AF";
-			regulator-min-microvolt = <2800000>;
-			regulator-max-microvolt = <2800000>;
-			gpio = <&gpm0 4 GPIO_ACTIVE_HIGH>;
-			enable-active-high;
-		};
-
-		ps_als_reg: voltage-regulator-5 {
-			compatible = "regulator-fixed";
-			regulator-name = "LED_A_3.0V";
-			regulator-min-microvolt = <3000000>;
-			regulator-max-microvolt = <3000000>;
-			gpio = <&gpj0 5 GPIO_ACTIVE_HIGH>;
-			enable-active-high;
-		};
-
-		vsil12: voltage-regulator-6 {
-			compatible = "regulator-fixed";
-			regulator-name = "VSIL_1.2V";
-			regulator-min-microvolt = <1200000>;
-			regulator-max-microvolt = <1200000>;
-			gpio = <&gpl0 4 GPIO_ACTIVE_HIGH>;
-			enable-active-high;
-			vin-supply = <&buck7_reg>;
-		};
-
-		vcc33mhl: voltage-regulator-7 {
-			compatible = "regulator-fixed";
-			regulator-name = "VCC_3.3_MHL";
-			regulator-min-microvolt = <3300000>;
-			regulator-max-microvolt = <3300000>;
-			gpio = <&gpl0 4 GPIO_ACTIVE_HIGH>;
-			enable-active-high;
-		};
-
-		vcc18mhl: voltage-regulator-8 {
-			compatible = "regulator-fixed";
-			regulator-name = "VCC_1.8_MHL";
-			regulator-min-microvolt = <1800000>;
-			regulator-max-microvolt = <1800000>;
-			gpio = <&gpl0 4 GPIO_ACTIVE_HIGH>;
-			enable-active-high;
-		};
-	};
-
-	gpio-keys {
-		compatible = "gpio-keys";
-
-		key-down {
-			gpios = <&gpx3 3 GPIO_ACTIVE_LOW>;
-			linux,code = <114>;
-			label = "volume down";
-			debounce-interval = <10>;
-		};
-
-		key-up {
-			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
-			linux,code = <115>;
-			label = "volume up";
-			debounce-interval = <10>;
-		};
-
-		key-power {
-			gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
-			linux,code = <116>;
-			label = "power";
-			debounce-interval = <10>;
-			wakeup-source;
-		};
-
-		key-ok {
-			gpios = <&gpx0 1 GPIO_ACTIVE_LOW>;
-			linux,code = <139>;
-			label = "ok";
-			debounce-inteval = <10>;
-			wakeup-source;
-		};
-	};
-
-	i2c_max77693: i2c-gpio-1 {
-		compatible = "i2c-gpio";
-		gpios = <&gpm2 0 GPIO_ACTIVE_HIGH>, <&gpm2 1 GPIO_ACTIVE_HIGH>;
-		i2c-gpio,delay-us = <2>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "okay";
-
-		max77693@66 {
-			compatible = "maxim,max77693";
-			interrupt-parent = <&gpx1>;
-			interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
-			reg = <0x66>;
-
-			regulators {
-				esafeout1_reg: ESAFEOUT1 {
-					regulator-name = "ESAFEOUT1";
-				};
-				esafeout2_reg: ESAFEOUT2 {
-					regulator-name = "ESAFEOUT2";
-				};
-				charger_reg: CHARGER {
-					regulator-name = "CHARGER";
-					regulator-min-microamp = <60000>;
-					regulator-max-microamp = <2580000>;
-				};
-			};
-
-			max77693_haptic {
-				compatible = "maxim,max77693-haptic";
-				haptic-supply = <&ldo26_reg>;
-				pwms = <&pwm 0 38022 0>;
-			};
-
-			charger {
-				compatible = "maxim,max77693-charger";
-
-				maxim,constant-microvolt = <4350000>;
-				maxim,min-system-microvolt = <3600000>;
-				maxim,thermal-regulation-celsius = <100>;
-				maxim,battery-overcurrent-microamp = <3500000>;
-				maxim,charge-input-threshold-microvolt = <4300000>;
-			};
-		};
-	};
-
-	i2c_max77693_fuel: i2c-gpio-3 {
-		compatible = "i2c-gpio";
-		gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>, <&gpf1 4 GPIO_ACTIVE_HIGH>;
-		i2c-gpio,delay-us = <2>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "okay";
-
-		max77693-fuel-gauge@36 {
-			compatible = "maxim,max17047";
-			interrupt-parent = <&gpx2>;
-			interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
-			reg = <0x36>;
-
-			maxim,over-heat-temp = <700>;
-			maxim,over-volt = <4500>;
-		};
-	};
-
-	i2c_ak8975: i2c-gpio-0 {
-		compatible = "i2c-gpio";
-		gpios = <&gpy2 4 GPIO_ACTIVE_HIGH>, <&gpy2 5 GPIO_ACTIVE_HIGH>;
-		i2c-gpio,delay-us = <2>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "okay";
-
-		ak8975@c {
-			compatible = "asahi-kasei,ak8975";
-			reg = <0x0c>;
-			gpios = <&gpj0 7 GPIO_ACTIVE_HIGH>;
-		};
-	};
-
-	i2c_cm36651: i2c-gpio-2 {
-		compatible = "i2c-gpio";
-		gpios = <&gpf0 0 GPIO_ACTIVE_LOW>, <&gpf0 1 GPIO_ACTIVE_LOW>;
-		i2c-gpio,delay-us = <2>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		cm36651@18 {
-			compatible = "capella,cm36651";
-			reg = <0x18>;
-			interrupt-parent = <&gpx0>;
-			interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
-			vled-supply = <&ps_als_reg>;
-		};
-	};
-
-	i2c-mhl {
-		compatible = "i2c-gpio";
-		gpios = <&gpf0 4 GPIO_ACTIVE_HIGH>, <&gpf0 6 GPIO_ACTIVE_HIGH>;
-		i2c-gpio,delay-us = <100>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		pinctrl-0 = <&i2c_mhl_bus>;
-		pinctrl-names = "default";
-		status = "okay";
-
-		sii9234: hdmi-bridge@39 {
-			compatible = "sil,sii9234";
-			avcc33-supply = <&vcc33mhl>;
-			iovcc18-supply = <&vcc18mhl>;
-			avcc12-supply = <&vsil12>;
-			cvcc12-supply = <&vsil12>;
-			reset-gpios = <&gpf3 4 GPIO_ACTIVE_LOW>;
-			interrupt-parent = <&gpf3>;
-			interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
-			reg = <0x39>;
-
-			port {
-				mhl_to_hdmi: endpoint {
-					remote-endpoint = <&hdmi_to_mhl>;
-				};
-			};
-		};
-	};
-
-	camera: camera {
-		pinctrl-0 = <&cam_port_a_clk_active &cam_port_b_clk_active>;
-		pinctrl-names = "default";
-		status = "okay";
-		assigned-clocks = <&clock CLK_MOUT_CAM0>,
-				  <&clock CLK_MOUT_CAM1>;
-		assigned-clock-parents = <&clock CLK_XUSBXTI>,
-					 <&clock CLK_XUSBXTI>;
-
-
-	};
-
-	wlan_pwrseq: sdhci3-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&gpj0 0 GPIO_ACTIVE_LOW>;
-		clocks = <&max77686 MAX77686_CLK_PMIC>;
-		clock-names = "ext_clock";
-	};
-
-	sound {
-		compatible = "samsung,trats2-audio";
-		samsung,i2s-controller = <&i2s0>;
-		samsung,model = "Trats2";
-		samsung,audio-codec = <&wm1811>;
-		samsung,audio-routing =
-			"SPK", "SPKOUTLN",
-			"SPK", "SPKOUTLP",
-			"SPK", "SPKOUTRN",
-			"SPK", "SPKOUTRP";
-	};
-
-	thermistor-ap {
-		compatible = "murata,ncp15wb473";
-		pullup-uv = <1800000>;	 /* VCC_1.8V_AP */
-		pullup-ohm = <100000>;	 /* 100K */
-		pulldown-ohm = <100000>; /* 100K */
-		io-channels = <&adc 1>;  /* AP temperature */
-	};
-
-	thermistor-battery {
-		compatible = "murata,ncp15wb473";
-		pullup-uv = <1800000>;	 /* VCC_1.8V_AP */
-		pullup-ohm = <100000>;	 /* 100K */
-		pulldown-ohm = <100000>; /* 100K */
-		io-channels = <&adc 2>;  /* Battery temperature */
-	};
-
-	thermal-zones {
-		cpu_thermal: cpu-thermal {
-			cooling-maps {
-				map0 {
-				     /* Corresponds to 800MHz at freq_table */
-				     cooling-device = <&cpu0 7 7>;
-				};
-				map1 {
-				     /* Corresponds to 200MHz at freq_table */
-				     cooling-device = <&cpu0 13 13>;
-			       };
-		       };
-		};
-	};
-};
-
-&adc {
-	vdd-supply = <&ldo3_reg>;
-	status = "okay";
-};
-
-&bus_dmc {
-	devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
-	vdd-supply = <&buck1_reg>;
-	status = "okay";
-};
-
-&bus_acp {
-	devfreq = <&bus_dmc>;
-	status = "okay";
-};
-
-&bus_c2c {
-	devfreq = <&bus_dmc>;
-	status = "okay";
-};
-
-&bus_leftbus {
-	devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
-	vdd-supply = <&buck3_reg>;
-	status = "okay";
-};
-
-&bus_rightbus {
-	devfreq = <&bus_leftbus>;
-	status = "okay";
-};
-
-&bus_display {
-	devfreq = <&bus_leftbus>;
-	status = "okay";
-};
-
-&bus_fsys {
-	devfreq = <&bus_leftbus>;
-	status = "okay";
-};
-
-&bus_peri {
-	devfreq = <&bus_leftbus>;
-	status = "okay";
-};
-
-&bus_mfc {
-	devfreq = <&bus_leftbus>;
-	status = "okay";
-};
-
-&cpu0 {
-	cpu0-supply = <&buck2_reg>;
-};
-
-&csis_0 {
-	status = "okay";
-	vddcore-supply = <&ldo8_reg>;
-	vddio-supply = <&ldo10_reg>;
-	assigned-clocks = <&clock CLK_MOUT_CSIS0>,
-			<&clock CLK_SCLK_CSIS0>;
-	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
-	assigned-clock-rates = <0>, <176000000>;
-
-	/* Camera C (3) MIPI CSI-2 (CSIS0) */
-	port@3 {
-		reg = <3>;
-		csis0_ep: endpoint {
-			remote-endpoint = <&s5c73m3_ep>;
-			data-lanes = <1 2 3 4>;
-			samsung,csis-hs-settle = <12>;
-		};
-	};
-};
-
-&csis_1 {
-	status = "okay";
-	vddcore-supply = <&ldo8_reg>;
-	vddio-supply = <&ldo10_reg>;
-	assigned-clocks = <&clock CLK_MOUT_CSIS1>,
-			<&clock CLK_SCLK_CSIS1>;
-	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
-	assigned-clock-rates = <0>, <176000000>;
-
-	/* Camera D (4) MIPI CSI-2 (CSIS1) */
-	port@4 {
-		reg = <4>;
-		csis1_ep: endpoint {
-			remote-endpoint = <&is_s5k6a3_ep>;
-			data-lanes = <1>;
-			samsung,csis-hs-settle = <18>;
-			samsung,csis-wclk;
-		};
-	};
-};
-
-&dsi_0 {
-	vddcore-supply = <&ldo8_reg>;
-	vddio-supply = <&ldo10_reg>;
-	samsung,burst-clock-frequency = <500000000>;
-	samsung,esc-clock-frequency = <20000000>;
-	samsung,pll-clock-frequency = <24000000>;
-	status = "okay";
-
-	panel@0 {
-		compatible = "samsung,s6e8aa0";
-		reg = <0>;
-		vdd3-supply = <&lcd_vdd3_reg>;
-		vci-supply = <&ldo25_reg>;
-		reset-gpios = <&gpf2 1 GPIO_ACTIVE_HIGH>;
-		power-on-delay= <50>;
-		reset-delay = <100>;
-		init-delay = <100>;
-		flip-horizontal;
-		flip-vertical;
-		panel-width-mm = <58>;
-		panel-height-mm = <103>;
-
-		display-timings {
-			timing-0 {
-				clock-frequency = <57153600>;
-				hactive = <720>;
-				vactive = <1280>;
-				hfront-porch = <5>;
-				hback-porch = <5>;
-				hsync-len = <5>;
-				vfront-porch = <13>;
-				vback-porch = <1>;
-				vsync-len = <2>;
-			};
-		};
-	};
-};
-
-&exynos_usbphy {
-	vbus-supply = <&esafeout1_reg>;
-	status = "okay";
-};
-
-&fimc_0 {
-	status = "okay";
-	assigned-clocks = <&clock CLK_MOUT_FIMC0>,
-			<&clock CLK_SCLK_FIMC0>;
-	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
-	assigned-clock-rates = <0>, <176000000>;
-};
-
-&fimc_1 {
-	status = "okay";
-	assigned-clocks = <&clock CLK_MOUT_FIMC1>,
-			<&clock CLK_SCLK_FIMC1>;
-	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
-	assigned-clock-rates = <0>, <176000000>;
-};
-
-&fimc_2 {
-	status = "okay";
-	assigned-clocks = <&clock CLK_MOUT_FIMC2>,
-			<&clock CLK_SCLK_FIMC2>;
-	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
-	assigned-clock-rates = <0>, <176000000>;
-};
-
-&fimc_3 {
-	status = "okay";
-	assigned-clocks = <&clock CLK_MOUT_FIMC3>,
-			<&clock CLK_SCLK_FIMC3>;
-	assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
-	assigned-clock-rates = <0>, <176000000>;
-};
-
-&fimc_is {
-	pinctrl-0 = <&fimc_is_uart>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	i2c1_isp: i2c-isp@12140000 {
-		pinctrl-0 = <&fimc_is_i2c1>;
-		pinctrl-names = "default";
-
-		s5k6a3@10 {
-			compatible = "samsung,s5k6a3";
-			reg = <0x10>;
-			svdda-supply = <&cam_io_reg>;
-			svddio-supply = <&ldo19_reg>;
-			afvdd-supply = <&ldo19_reg>;
-			clock-frequency = <24000000>;
-			/* CAM_B_CLKOUT */
-			clocks = <&camera 1>;
-			clock-names = "extclk";
-			samsung,camclk-out = <1>;
-			gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>;
-
-			port {
-				is_s5k6a3_ep: endpoint {
-					remote-endpoint = <&csis1_ep>;
-					data-lanes = <1>;
-				};
-			};
-		};
-	};
-};
-
-&fimc_lite_0 {
-	status = "okay";
-};
-
-&fimc_lite_1 {
-	status = "okay";
-};
-
-&fimd {
-	status = "okay";
-};
-
-&hdmi {
-	hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&hdmi_hpd>;
-	vdd-supply = <&ldo3_reg>;
-	vdd_osc-supply = <&ldo4_reg>;
-	vdd_pll-supply = <&ldo3_reg>;
-	ddc = <&i2c_5>;
-	status = "okay";
-
-	ports {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		port@1 {
-			reg = <1>;
-			hdmi_to_mhl: endpoint {
-				remote-endpoint = <&mhl_to_hdmi>;
-			};
-		};
-	};
-};
-
-&hsotg {
-	vusb_d-supply = <&ldo15_reg>;
-	vusb_a-supply = <&ldo12_reg>;
-	dr_mode = "peripheral";
-	status = "okay";
-};
-
-&i2c_0 {
-	samsung,i2c-sda-delay = <100>;
-	samsung,i2c-slave-addr = <0x10>;
-	samsung,i2c-max-bus-freq = <400000>;
-	pinctrl-0 = <&i2c0_bus>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	s5c73m3@3c {
-		compatible = "samsung,s5c73m3";
-		reg = <0x3c>;
-		standby-gpios = <&gpm0 1 GPIO_ACTIVE_LOW>;   /* ISP_STANDBY */
-		xshutdown-gpios = <&gpf1 3 GPIO_ACTIVE_LOW>; /* ISP_RESET */
-		vdd-int-supply = <&buck9_reg>;
-		vddio-cis-supply = <&ldo9_reg>;
-		vdda-supply = <&ldo17_reg>;
-		vddio-host-supply = <&ldo18_reg>;
-		vdd-af-supply = <&cam_af_reg>;
-		vdd-reg-supply = <&cam_io_reg>;
-		clock-frequency = <24000000>;
-		/* CAM_A_CLKOUT */
-		clocks = <&camera 0>;
-		clock-names = "cis_extclk";
-		port {
-			s5c73m3_ep: endpoint {
-				remote-endpoint = <&csis0_ep>;
-				data-lanes = <1 2 3 4>;
-			};
-		};
-	};
-};
-
-&i2c_3 {
-	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 = <&gpm2>;
-		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
-		x-size = <720>;
-		y-size = <1280>;
-		avdd-supply = <&ldo23_reg>;
-		vdd-supply = <&ldo24_reg>;
-	};
-};
-
-&i2c_4 {
-	samsung,i2c-sda-delay = <100>;
-	samsung,i2c-slave-addr = <0x10>;
-	samsung,i2c-max-bus-freq = <100000>;
-	pinctrl-0 = <&i2c4_bus>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	wm1811: wm1811@1a {
-		compatible = "wlf,wm1811";
-		reg = <0x1a>;
-		clocks = <&pmu_system_controller 0>;
-		clock-names = "MCLK1";
-		DCVDD-supply = <&ldo3_reg>;
-		DBVDD1-supply = <&ldo3_reg>;
-		wlf,ldo1ena = <&gpj0 4 0>;
-	};
-};
-
-&i2c_5 {
-	status = "okay";
-};
-
-&i2c_7 {
-	samsung,i2c-sda-delay = <100>;
-	samsung,i2c-slave-addr = <0x10>;
-	samsung,i2c-max-bus-freq = <100000>;
-	pinctrl-0 = <&i2c7_bus>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	max77686: max77686_pmic@9 {
-		compatible = "maxim,max77686";
-		interrupt-parent = <&gpx0>;
-		interrupts = <7 IRQ_TYPE_NONE>;
-		reg = <0x09>;
-		#clock-cells = <1>;
-
-		voltage-regulators {
-			ldo1_reg: LDO1 {
-				regulator-name = "VALIVE_1.0V_AP";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-always-on;
-			};
-
-			ldo2_reg: LDO2 {
-				regulator-name = "VM1M2_1.2V_AP";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-on-in-suspend;
-				};
-			};
-
-			ldo3_reg: LDO3 {
-				regulator-name = "VCC_1.8V_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-always-on;
-			};
-
-			ldo4_reg: LDO4 {
-				regulator-name = "VCC_2.8V_AP";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-				regulator-always-on;
-			};
-
-			ldo5_reg: LDO5 {
-				regulator-name = "VCC_1.8V_IO";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-always-on;
-			};
-
-			ldo6_reg: LDO6 {
-				regulator-name = "VMPLL_1.0V_AP";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-on-in-suspend;
-				};
-			};
-
-			ldo7_reg: LDO7 {
-				regulator-name = "VPLL_1.0V_AP";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-on-in-suspend;
-				};
-			};
-
-			ldo8_reg: LDO8 {
-				regulator-name = "VMIPI_1.0V";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo9_reg: LDO9 {
-				regulator-name = "CAM_ISP_MIPI_1.2V";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-			};
-
-			ldo10_reg: LDO10 {
-				regulator-name = "VMIPI_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo11_reg: LDO11 {
-				regulator-name = "VABB1_1.95V";
-				regulator-min-microvolt = <1950000>;
-				regulator-max-microvolt = <1950000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo12_reg: LDO12 {
-				regulator-name = "VUOTG_3.0V";
-				regulator-min-microvolt = <3000000>;
-				regulator-max-microvolt = <3000000>;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo13_reg: LDO13 {
-				regulator-name = "NFC_AVDD_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo14_reg: LDO14 {
-				regulator-name = "VABB2_1.95V";
-				regulator-min-microvolt = <1950000>;
-				regulator-max-microvolt = <1950000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo15_reg: LDO15 {
-				regulator-name = "VHSIC_1.0V";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-state-mem {
-					regulator-on-in-suspend;
-				};
-			};
-
-			ldo16_reg: LDO16 {
-				regulator-name = "VHSIC_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-state-mem {
-					regulator-on-in-suspend;
-				};
-			};
-
-			ldo17_reg: LDO17 {
-				regulator-name = "CAM_SENSOR_CORE_1.2V";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-			};
-
-			ldo18_reg: LDO18 {
-				regulator-name = "CAM_ISP_SEN_IO_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo19_reg: LDO19 {
-				regulator-name = "VT_CAM_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo20_reg: LDO20 {
-				regulator-name = "VDDQ_PRE_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo21_reg: LDO21 {
-				regulator-name = "VTF_2.8V";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-				maxim,ena-gpios = <&gpy2 0 GPIO_ACTIVE_HIGH>;
-			};
-
-			ldo22_reg: LDO22 {
-				regulator-name = "VMEM_VDD_2.8V";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-				maxim,ena-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
-			};
-
-			ldo23_reg: LDO23 {
-				regulator-name = "TSP_AVDD_3.3V";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-			};
-
-			ldo24_reg: LDO24 {
-				regulator-name = "TSP_VDD_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo25_reg: LDO25 {
-				regulator-name = "LCD_VCC_3.3V";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-			};
-
-			ldo26_reg: LDO26 {
-				regulator-name = "MOTOR_VCC_3.0V";
-				regulator-min-microvolt = <3000000>;
-				regulator-max-microvolt = <3000000>;
-			};
-
-			buck1_reg: BUCK1 {
-				regulator-name = "vdd_mif";
-				regulator-min-microvolt = <850000>;
-				regulator-max-microvolt = <1100000>;
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck2_reg: BUCK2 {
-				regulator-name = "vdd_arm";
-				regulator-min-microvolt = <850000>;
-				regulator-max-microvolt = <1500000>;
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-state-mem {
-					regulator-on-in-suspend;
-				};
-			};
-
-			buck3_reg: BUCK3 {
-				regulator-name = "vdd_int";
-				regulator-min-microvolt = <850000>;
-				regulator-max-microvolt = <1150000>;
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck4_reg: BUCK4 {
-				regulator-name = "vdd_g3d";
-				regulator-min-microvolt = <850000>;
-				regulator-max-microvolt = <1150000>;
-				regulator-boot-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck5_reg: BUCK5 {
-				regulator-name = "VMEM_1.2V_AP";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-				regulator-always-on;
-			};
-
-			buck6_reg: BUCK6 {
-				regulator-name = "VCC_SUB_1.35V";
-				regulator-min-microvolt = <1350000>;
-				regulator-max-microvolt = <1350000>;
-				regulator-always-on;
-			};
-
-			buck7_reg: BUCK7 {
-				regulator-name = "VCC_SUB_2.0V";
-				regulator-min-microvolt = <2000000>;
-				regulator-max-microvolt = <2000000>;
-				regulator-always-on;
-			};
-
-			buck8_reg: BUCK8 {
-				regulator-name = "VMEM_VDDF_3.0V";
-				regulator-min-microvolt = <2850000>;
-				regulator-max-microvolt = <2850000>;
-				maxim,ena-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
-			};
-
-			buck9_reg: BUCK9 {
-				regulator-name = "CAM_ISP_CORE_1.2V";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1200000>;
-				maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
-			};
-		};
-	};
-};
-
-&i2c_8 {
-	status = "okay";
-};
-
-&i2s0 {
-	pinctrl-0 = <&i2s0_bus>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&mixer {
-	status = "okay";
-};
-
-&mshc_0 {
-	broken-cd;
-	non-removable;
-	card-detect-delay = <200>;
-	vmmc-supply = <&ldo22_reg>;
-	clock-frequency = <400000000>;
-	samsung,dw-mshc-ciu-div = <0>;
-	samsung,dw-mshc-sdr-timing = <2 3>;
-	samsung,dw-mshc-ddr-timing = <1 2>;
-	pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
-	pinctrl-names = "default";
-	status = "okay";
-	bus-width = <8>;
-	cap-mmc-highspeed;
-};
-
-&pmu_system_controller {
-	assigned-clocks = <&pmu_system_controller 0>;
-	assigned-clock-parents =  <&clock CLK_XUSBXTI>;
-};
-
-&pinctrl_0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&sleep0>;
-
-	mhl_int: mhl-int {
-		samsung,pins = "gpf3-5";
-		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-	};
-
-	i2c_mhl_bus: i2c-mhl-bus {
-		samsung,pins = "gpf0-4", "gpf0-6";
-		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
-		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-	};
-
-	sleep0: sleep-states {
-		PIN_SLP(gpa0-0, INPUT, NONE);
-		PIN_SLP(gpa0-1, OUT0, NONE);
-		PIN_SLP(gpa0-2, INPUT, NONE);
-		PIN_SLP(gpa0-3, INPUT, UP);
-		PIN_SLP(gpa0-4, INPUT, NONE);
-		PIN_SLP(gpa0-5, INPUT, DOWN);
-		PIN_SLP(gpa0-6, INPUT, DOWN);
-		PIN_SLP(gpa0-7, INPUT, UP);
-
-		PIN_SLP(gpa1-0, INPUT, DOWN);
-		PIN_SLP(gpa1-1, INPUT, DOWN);
-		PIN_SLP(gpa1-2, INPUT, DOWN);
-		PIN_SLP(gpa1-3, INPUT, DOWN);
-		PIN_SLP(gpa1-4, INPUT, DOWN);
-		PIN_SLP(gpa1-5, INPUT, DOWN);
-
-		PIN_SLP(gpb-0, INPUT, NONE);
-		PIN_SLP(gpb-1, INPUT, NONE);
-		PIN_SLP(gpb-2, INPUT, NONE);
-		PIN_SLP(gpb-3, INPUT, NONE);
-		PIN_SLP(gpb-4, INPUT, DOWN);
-		PIN_SLP(gpb-5, INPUT, UP);
-		PIN_SLP(gpb-6, INPUT, DOWN);
-		PIN_SLP(gpb-7, INPUT, DOWN);
-
-		PIN_SLP(gpc0-0, INPUT, DOWN);
-		PIN_SLP(gpc0-1, INPUT, DOWN);
-		PIN_SLP(gpc0-2, INPUT, DOWN);
-		PIN_SLP(gpc0-3, INPUT, DOWN);
-		PIN_SLP(gpc0-4, INPUT, DOWN);
-
-		PIN_SLP(gpc1-0, INPUT, NONE);
-		PIN_SLP(gpc1-1, PREV, NONE);
-		PIN_SLP(gpc1-2, INPUT, NONE);
-		PIN_SLP(gpc1-3, INPUT, NONE);
-		PIN_SLP(gpc1-4, INPUT, NONE);
-
-		PIN_SLP(gpd0-0, INPUT, DOWN);
-		PIN_SLP(gpd0-1, INPUT, DOWN);
-		PIN_SLP(gpd0-2, INPUT, NONE);
-		PIN_SLP(gpd0-3, INPUT, NONE);
-
-		PIN_SLP(gpd1-0, INPUT, DOWN);
-		PIN_SLP(gpd1-1, INPUT, DOWN);
-		PIN_SLP(gpd1-2, INPUT, NONE);
-		PIN_SLP(gpd1-3, INPUT, NONE);
-
-		PIN_SLP(gpf0-0, INPUT, NONE);
-		PIN_SLP(gpf0-1, INPUT, NONE);
-		PIN_SLP(gpf0-2, INPUT, DOWN);
-		PIN_SLP(gpf0-3, INPUT, DOWN);
-		PIN_SLP(gpf0-4, INPUT, NONE);
-		PIN_SLP(gpf0-5, INPUT, DOWN);
-		PIN_SLP(gpf0-6, INPUT, NONE);
-		PIN_SLP(gpf0-7, INPUT, DOWN);
-
-		PIN_SLP(gpf1-0, INPUT, DOWN);
-		PIN_SLP(gpf1-1, INPUT, DOWN);
-		PIN_SLP(gpf1-2, INPUT, DOWN);
-		PIN_SLP(gpf1-3, INPUT, DOWN);
-		PIN_SLP(gpf1-4, INPUT, NONE);
-		PIN_SLP(gpf1-5, INPUT, NONE);
-		PIN_SLP(gpf1-6, INPUT, DOWN);
-		PIN_SLP(gpf1-7, PREV, NONE);
-
-		PIN_SLP(gpf2-0, PREV, NONE);
-		PIN_SLP(gpf2-1, INPUT, DOWN);
-		PIN_SLP(gpf2-2, INPUT, DOWN);
-		PIN_SLP(gpf2-3, INPUT, DOWN);
-		PIN_SLP(gpf2-4, INPUT, DOWN);
-		PIN_SLP(gpf2-5, INPUT, DOWN);
-		PIN_SLP(gpf2-6, INPUT, NONE);
-		PIN_SLP(gpf2-7, INPUT, NONE);
-
-		PIN_SLP(gpf3-0, INPUT, NONE);
-		PIN_SLP(gpf3-1, PREV, NONE);
-		PIN_SLP(gpf3-2, PREV, NONE);
-		PIN_SLP(gpf3-3, PREV, NONE);
-		PIN_SLP(gpf3-4, OUT1, NONE);
-		PIN_SLP(gpf3-5, INPUT, DOWN);
-
-		PIN_SLP(gpj0-0, PREV, NONE);
-		PIN_SLP(gpj0-1, PREV, NONE);
-		PIN_SLP(gpj0-2, PREV, NONE);
-		PIN_SLP(gpj0-3, INPUT, DOWN);
-		PIN_SLP(gpj0-4, PREV, NONE);
-		PIN_SLP(gpj0-5, PREV, NONE);
-		PIN_SLP(gpj0-6, INPUT, DOWN);
-		PIN_SLP(gpj0-7, INPUT, DOWN);
-
-		PIN_SLP(gpj1-0, INPUT, DOWN);
-		PIN_SLP(gpj1-1, PREV, NONE);
-		PIN_SLP(gpj1-2, PREV, NONE);
-		PIN_SLP(gpj1-3, INPUT, DOWN);
-		PIN_SLP(gpj1-4, INPUT, DOWN);
-	};
-};
-
-&pinctrl_1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&sleep1>;
-
-	hdmi_hpd: hdmi-hpd {
-		samsung,pins = "gpx3-7";
-		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
-	};
-
-	sleep1: sleep-states {
-		PIN_SLP(gpk0-0, PREV, NONE);
-		PIN_SLP(gpk0-1, PREV, NONE);
-		PIN_SLP(gpk0-2, OUT0, NONE);
-		PIN_SLP(gpk0-3, PREV, NONE);
-		PIN_SLP(gpk0-4, PREV, NONE);
-		PIN_SLP(gpk0-5, PREV, NONE);
-		PIN_SLP(gpk0-6, PREV, NONE);
-
-		PIN_SLP(gpk1-0, INPUT, DOWN);
-		PIN_SLP(gpk1-1, INPUT, DOWN);
-		PIN_SLP(gpk1-2, INPUT, DOWN);
-		PIN_SLP(gpk1-3, PREV, NONE);
-		PIN_SLP(gpk1-4, PREV, NONE);
-		PIN_SLP(gpk1-5, PREV, NONE);
-		PIN_SLP(gpk1-6, PREV, NONE);
-
-		PIN_SLP(gpk2-0, INPUT, DOWN);
-		PIN_SLP(gpk2-1, INPUT, DOWN);
-		PIN_SLP(gpk2-2, INPUT, DOWN);
-		PIN_SLP(gpk2-3, INPUT, DOWN);
-		PIN_SLP(gpk2-4, INPUT, DOWN);
-		PIN_SLP(gpk2-5, INPUT, DOWN);
-		PIN_SLP(gpk2-6, INPUT, DOWN);
-
-		PIN_SLP(gpk3-0, OUT0, NONE);
-		PIN_SLP(gpk3-1, INPUT, NONE);
-		PIN_SLP(gpk3-2, INPUT, DOWN);
-		PIN_SLP(gpk3-3, INPUT, NONE);
-		PIN_SLP(gpk3-4, INPUT, NONE);
-		PIN_SLP(gpk3-5, INPUT, NONE);
-		PIN_SLP(gpk3-6, INPUT, NONE);
-
-		PIN_SLP(gpl0-0, INPUT, DOWN);
-		PIN_SLP(gpl0-1, INPUT, DOWN);
-		PIN_SLP(gpl0-2, INPUT, DOWN);
-		PIN_SLP(gpl0-3, INPUT, DOWN);
-		PIN_SLP(gpl0-4, PREV, NONE);
-		PIN_SLP(gpl0-6, PREV, NONE);
-
-		PIN_SLP(gpl1-0, INPUT, DOWN);
-		PIN_SLP(gpl1-1, INPUT, DOWN);
-		PIN_SLP(gpl2-0, INPUT, DOWN);
-		PIN_SLP(gpl2-1, INPUT, DOWN);
-		PIN_SLP(gpl2-2, INPUT, DOWN);
-		PIN_SLP(gpl2-3, INPUT, DOWN);
-		PIN_SLP(gpl2-4, INPUT, DOWN);
-		PIN_SLP(gpl2-5, INPUT, DOWN);
-		PIN_SLP(gpl2-6, PREV, NONE);
-		PIN_SLP(gpl2-7, INPUT, DOWN);
-
-		PIN_SLP(gpm0-0, INPUT, DOWN);
-		PIN_SLP(gpm0-1, INPUT, DOWN);
-		PIN_SLP(gpm0-2, INPUT, DOWN);
-		PIN_SLP(gpm0-3, INPUT, DOWN);
-		PIN_SLP(gpm0-4, INPUT, DOWN);
-		PIN_SLP(gpm0-5, INPUT, DOWN);
-		PIN_SLP(gpm0-6, INPUT, DOWN);
-		PIN_SLP(gpm0-7, INPUT, DOWN);
-
-		PIN_SLP(gpm1-0, INPUT, DOWN);
-		PIN_SLP(gpm1-1, INPUT, DOWN);
-		PIN_SLP(gpm1-2, INPUT, NONE);
-		PIN_SLP(gpm1-3, INPUT, NONE);
-		PIN_SLP(gpm1-4, INPUT, NONE);
-		PIN_SLP(gpm1-5, INPUT, NONE);
-		PIN_SLP(gpm1-6, INPUT, DOWN);
-
-		PIN_SLP(gpm2-0, INPUT, NONE);
-		PIN_SLP(gpm2-1, INPUT, NONE);
-		PIN_SLP(gpm2-2, INPUT, DOWN);
-		PIN_SLP(gpm2-3, INPUT, DOWN);
-		PIN_SLP(gpm2-4, INPUT, DOWN);
-
-		PIN_SLP(gpm3-0, PREV, NONE);
-		PIN_SLP(gpm3-1, PREV, NONE);
-		PIN_SLP(gpm3-2, PREV, NONE);
-		PIN_SLP(gpm3-3, OUT1, NONE);
-		PIN_SLP(gpm3-4, INPUT, DOWN);
-		PIN_SLP(gpm3-5, INPUT, DOWN);
-		PIN_SLP(gpm3-6, INPUT, DOWN);
-		PIN_SLP(gpm3-7, INPUT, DOWN);
-
-		PIN_SLP(gpm4-0, INPUT, DOWN);
-		PIN_SLP(gpm4-1, INPUT, DOWN);
-		PIN_SLP(gpm4-2, INPUT, DOWN);
-		PIN_SLP(gpm4-3, INPUT, DOWN);
-		PIN_SLP(gpm4-4, INPUT, DOWN);
-		PIN_SLP(gpm4-5, INPUT, DOWN);
-		PIN_SLP(gpm4-6, INPUT, DOWN);
-		PIN_SLP(gpm4-7, INPUT, DOWN);
-
-		PIN_SLP(gpy0-0, INPUT, DOWN);
-		PIN_SLP(gpy0-1, INPUT, DOWN);
-		PIN_SLP(gpy0-2, INPUT, DOWN);
-		PIN_SLP(gpy0-3, INPUT, DOWN);
-		PIN_SLP(gpy0-4, INPUT, DOWN);
-		PIN_SLP(gpy0-5, INPUT, DOWN);
-
-		PIN_SLP(gpy1-0, INPUT, DOWN);
-		PIN_SLP(gpy1-1, INPUT, DOWN);
-		PIN_SLP(gpy1-2, INPUT, DOWN);
-		PIN_SLP(gpy1-3, INPUT, DOWN);
-
-		PIN_SLP(gpy2-0, PREV, NONE);
-		PIN_SLP(gpy2-1, INPUT, DOWN);
-		PIN_SLP(gpy2-2, INPUT, NONE);
-		PIN_SLP(gpy2-3, INPUT, NONE);
-		PIN_SLP(gpy2-4, INPUT, NONE);
-		PIN_SLP(gpy2-5, INPUT, NONE);
-
-		PIN_SLP(gpy3-0, INPUT, DOWN);
-		PIN_SLP(gpy3-1, INPUT, DOWN);
-		PIN_SLP(gpy3-2, INPUT, DOWN);
-		PIN_SLP(gpy3-3, INPUT, DOWN);
-		PIN_SLP(gpy3-4, INPUT, DOWN);
-		PIN_SLP(gpy3-5, INPUT, DOWN);
-		PIN_SLP(gpy3-6, INPUT, DOWN);
-		PIN_SLP(gpy3-7, INPUT, DOWN);
-
-		PIN_SLP(gpy4-0, INPUT, DOWN);
-		PIN_SLP(gpy4-1, INPUT, DOWN);
-		PIN_SLP(gpy4-2, INPUT, DOWN);
-		PIN_SLP(gpy4-3, INPUT, DOWN);
-		PIN_SLP(gpy4-4, INPUT, DOWN);
-		PIN_SLP(gpy4-5, INPUT, DOWN);
-		PIN_SLP(gpy4-6, INPUT, DOWN);
-		PIN_SLP(gpy4-7, INPUT, DOWN);
-
-		PIN_SLP(gpy5-0, INPUT, DOWN);
-		PIN_SLP(gpy5-1, INPUT, DOWN);
-		PIN_SLP(gpy5-2, INPUT, DOWN);
-		PIN_SLP(gpy5-3, INPUT, DOWN);
-		PIN_SLP(gpy5-4, INPUT, DOWN);
-		PIN_SLP(gpy5-5, INPUT, DOWN);
-		PIN_SLP(gpy5-6, INPUT, DOWN);
-		PIN_SLP(gpy5-7, INPUT, DOWN);
-
-		PIN_SLP(gpy6-0, INPUT, DOWN);
-		PIN_SLP(gpy6-1, INPUT, DOWN);
-		PIN_SLP(gpy6-2, INPUT, DOWN);
-		PIN_SLP(gpy6-3, INPUT, DOWN);
-		PIN_SLP(gpy6-4, INPUT, DOWN);
-		PIN_SLP(gpy6-5, INPUT, DOWN);
-		PIN_SLP(gpy6-6, INPUT, DOWN);
-		PIN_SLP(gpy6-7, INPUT, DOWN);
-	};
-};
-
-&pinctrl_2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&sleep2>;
-
-	sleep2: sleep-states {
-		PIN_SLP(gpz-0, INPUT, DOWN);
-		PIN_SLP(gpz-1, INPUT, DOWN);
-		PIN_SLP(gpz-2, INPUT, DOWN);
-		PIN_SLP(gpz-3, INPUT, DOWN);
-		PIN_SLP(gpz-4, INPUT, DOWN);
-		PIN_SLP(gpz-5, INPUT, DOWN);
-		PIN_SLP(gpz-6, INPUT, DOWN);
-	};
-};
-
-&pinctrl_3 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&sleep3>;
-
-	sleep3: sleep-states {
-		PIN_SLP(gpv0-0, INPUT, DOWN);
-		PIN_SLP(gpv0-1, INPUT, DOWN);
-		PIN_SLP(gpv0-2, INPUT, DOWN);
-		PIN_SLP(gpv0-3, INPUT, DOWN);
-		PIN_SLP(gpv0-4, INPUT, DOWN);
-		PIN_SLP(gpv0-5, INPUT, DOWN);
-		PIN_SLP(gpv0-6, INPUT, DOWN);
-		PIN_SLP(gpv0-7, INPUT, DOWN);
-
-		PIN_SLP(gpv1-0, INPUT, DOWN);
-		PIN_SLP(gpv1-1, INPUT, DOWN);
-		PIN_SLP(gpv1-2, INPUT, DOWN);
-		PIN_SLP(gpv1-3, INPUT, DOWN);
-		PIN_SLP(gpv1-4, INPUT, DOWN);
-		PIN_SLP(gpv1-5, INPUT, DOWN);
-		PIN_SLP(gpv1-6, INPUT, DOWN);
-		PIN_SLP(gpv1-7, INPUT, DOWN);
-
-		PIN_SLP(gpv2-0, INPUT, DOWN);
-		PIN_SLP(gpv2-1, INPUT, DOWN);
-		PIN_SLP(gpv2-2, INPUT, DOWN);
-		PIN_SLP(gpv2-3, INPUT, DOWN);
-		PIN_SLP(gpv2-4, INPUT, DOWN);
-		PIN_SLP(gpv2-5, INPUT, DOWN);
-		PIN_SLP(gpv2-6, INPUT, DOWN);
-		PIN_SLP(gpv2-7, INPUT, DOWN);
-
-		PIN_SLP(gpv3-0, INPUT, DOWN);
-		PIN_SLP(gpv3-1, INPUT, DOWN);
-		PIN_SLP(gpv3-2, INPUT, DOWN);
-		PIN_SLP(gpv3-3, INPUT, DOWN);
-		PIN_SLP(gpv3-4, INPUT, DOWN);
-		PIN_SLP(gpv3-5, INPUT, DOWN);
-		PIN_SLP(gpv3-6, INPUT, DOWN);
-		PIN_SLP(gpv3-7, INPUT, DOWN);
-
-		PIN_SLP(gpv4-0, INPUT, DOWN);
-	};
-};
-
-&pwm {
-	pinctrl-0 = <&pwm0_out>;
-	pinctrl-names = "default";
-	samsung,pwm-outputs = <0>;
-	status = "okay";
-};
-
-&rtc {
-	status = "okay";
-	clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>;
-	clock-names = "rtc", "rtc_src";
-};
-
-&sdhci_2 {
-	bus-width = <4>;
-	cd-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
-	cd-inverted;
-	pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
-	pinctrl-names = "default";
-	vmmc-supply = <&ldo21_reg>;
-	status = "okay";
-};
-
-&sdhci_3 {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	non-removable;
-	bus-width = <4>;
-
-	mmc-pwrseq = <&wlan_pwrseq>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>;
-	status = "okay";
-
-	brcmf: wifi@1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-		interrupt-parent = <&gpx2>;
-		interrupts = <5 IRQ_TYPE_NONE>;
-		interrupt-names = "host-wake";
-	};
-};
-
-&serial_0 {
-	status = "okay";
-};
-
-&serial_1 {
-	status = "okay";
-};
-
-&serial_2 {
-	status = "okay";
-};
-
-&serial_3 {
-	status = "okay";
-};
-
-&spi_1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&spi1_bus>;
-	cs-gpios = <&gpb 5 GPIO_ACTIVE_HIGH>;
-	status = "okay";
-
-	s5c73m3_spi: s5c73m3@0 {
-		compatible = "samsung,s5c73m3";
-		spi-max-frequency = <50000000>;
-		reg = <0>;
-		controller-data {
-			samsung,spi-feedback-delay = <2>;
-		};
-	};
-};
-
-&tmu {
-	vtmu-supply = <&ldo10_reg>;
-	status = "okay";
 };
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index e4ad2fc..2ae1ab6 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -15,7 +15,7 @@
  */
 
 #include "exynos4.dtsi"
-#include "exynos4412-pinctrl.dtsi"
+
 #include "exynos4-cpu-thermal.dtsi"
 
 / {
@@ -42,8 +42,6 @@
 			clocks = <&clock CLK_ARM_CLK>;
 			clock-names = "cpu";
 			operating-points-v2 = <&cpu0_opp_table>;
-			cooling-min-level = <13>;
-			cooling-max-level = <7>;
 			#cooling-cells = <2>; /* min followed by max */
 		};
 
@@ -147,463 +145,410 @@
 		};
 	};
 
-	sysram@2020000 {
-		compatible = "mmio-sram";
-		reg = <0x02020000 0x40000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0x02020000 0x40000>;
 
-		smp-sysram@0 {
-			compatible = "samsung,exynos4210-sysram";
-			reg = <0x0 0x1000>;
+	soc: soc {
+
+		pinctrl_0: pinctrl@11400000 {
+			compatible = "samsung,exynos4x12-pinctrl";
+			reg = <0x11400000 0x1000>;
+			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		smp-sysram@2f000 {
-			compatible = "samsung,exynos4210-sysram-ns";
-			reg = <0x2f000 0x1000>;
+		pinctrl_1: pinctrl@11000000 {
+			compatible = "samsung,exynos4x12-pinctrl";
+			reg = <0x11000000 0x1000>;
+			interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+
+			wakup_eint: wakeup-interrupt-controller {
+				compatible = "samsung,exynos4210-wakeup-eint";
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			};
 		};
-	};
 
-	pd_isp: isp-power-domain@10023ca0 {
-		compatible = "samsung,exynos4210-pd";
-		reg = <0x10023CA0 0x20>;
-		#power-domain-cells = <0>;
-		label = "ISP";
-	};
+		pinctrl_2: pinctrl@3860000 {
+			compatible = "samsung,exynos4x12-pinctrl";
+			reg = <0x03860000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <10 0>;
+		};
 
-	l2c: l2-cache-controller@10502000 {
-		compatible = "arm,pl310-cache";
-		reg = <0x10502000 0x1000>;
-		cache-unified;
-		cache-level = <2>;
-		arm,tag-latency = <2 2 1>;
-		arm,data-latency = <3 2 1>;
-		arm,double-linefill = <1>;
-		arm,double-linefill-incr = <0>;
-		arm,double-linefill-wrap = <1>;
-		arm,prefetch-drop = <1>;
-		arm,prefetch-offset = <7>;
-	};
+		pinctrl_3: pinctrl@106e0000 {
+			compatible = "samsung,exynos4x12-pinctrl";
+			reg = <0x106E0000 0x1000>;
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+		};
 
-	clock: clock-controller@10030000 {
-		compatible = "samsung,exynos4412-clock";
-		reg = <0x10030000 0x18000>;
-		#clock-cells = <1>;
-	};
+		sysram@2020000 {
+			compatible = "mmio-sram";
+			reg = <0x02020000 0x40000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x02020000 0x40000>;
 
-	isp_clock: clock-controller@10048000 {
-		compatible = "samsung,exynos4412-isp-clock";
-		reg = <0x10048000 0x1000>;
-		#clock-cells = <1>;
-		power-domains = <&pd_isp>;
-		clocks = <&clock CLK_ACLK200>, <&clock CLK_ACLK400_MCUISP>;
-		clock-names = "aclk200", "aclk400_mcuisp";
-	};
+			smp-sysram@0 {
+				compatible = "samsung,exynos4210-sysram";
+				reg = <0x0 0x1000>;
+			};
 
-	mct@10050000 {
-		compatible = "samsung,exynos4412-mct";
-		reg = <0x10050000 0x800>;
-		interrupt-parent = <&mct_map>;
-		interrupts = <0>, <1>, <2>, <3>, <4>;
-		clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
-		clock-names = "fin_pll", "mct";
+			smp-sysram@2f000 {
+				compatible = "samsung,exynos4210-sysram-ns";
+				reg = <0x2f000 0x1000>;
+			};
+		};
 
-		mct_map: mct-map {
-			#interrupt-cells = <1>;
-			#address-cells = <0>;
-			#size-cells = <0>;
-			interrupt-map = <0 &gic 0 57 IRQ_TYPE_LEVEL_HIGH>,
+		pd_isp: isp-power-domain@10023ca0 {
+			compatible = "samsung,exynos4210-pd";
+			reg = <0x10023CA0 0x20>;
+			#power-domain-cells = <0>;
+			label = "ISP";
+		};
+
+		l2c: l2-cache-controller@10502000 {
+			compatible = "arm,pl310-cache";
+			reg = <0x10502000 0x1000>;
+			cache-unified;
+			cache-level = <2>;
+			arm,tag-latency = <2 2 1>;
+			arm,data-latency = <3 2 1>;
+			arm,double-linefill = <1>;
+			arm,double-linefill-incr = <0>;
+			arm,double-linefill-wrap = <1>;
+			arm,prefetch-drop = <1>;
+			arm,prefetch-offset = <7>;
+		};
+
+		clock: clock-controller@10030000 {
+			compatible = "samsung,exynos4412-clock";
+			reg = <0x10030000 0x18000>;
+			#clock-cells = <1>;
+		};
+
+		isp_clock: clock-controller@10048000 {
+			compatible = "samsung,exynos4412-isp-clock";
+			reg = <0x10048000 0x1000>;
+			#clock-cells = <1>;
+			power-domains = <&pd_isp>;
+			clocks = <&clock CLK_ACLK200>,
+				 <&clock CLK_ACLK400_MCUISP>;
+			clock-names = "aclk200", "aclk400_mcuisp";
+		};
+
+		mct@10050000 {
+			compatible = "samsung,exynos4412-mct";
+			reg = <0x10050000 0x800>;
+			interrupt-parent = <&mct_map>;
+			interrupts = <0>, <1>, <2>, <3>, <4>;
+			clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
+			clock-names = "fin_pll", "mct";
+
+			mct_map: mct-map {
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map =
+					<0 &gic 0 57 IRQ_TYPE_LEVEL_HIGH>,
 					<1 &combiner 12 5>,
 					<2 &combiner 12 6>,
 					<3 &combiner 12 7>,
 					<4 &gic 1 12 IRQ_TYPE_LEVEL_HIGH>;
+			};
 		};
-	};
 
-	watchdog: watchdog@10060000 {
-		compatible = "samsung,exynos5250-wdt";
-		reg = <0x10060000 0x100>;
-		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_WDT>;
-		clock-names = "watchdog";
-		samsung,syscon-phandle = <&pmu_system_controller>;
-	};
+		watchdog: watchdog@10060000 {
+			compatible = "samsung,exynos5250-wdt";
+			reg = <0x10060000 0x100>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_WDT>;
+			clock-names = "watchdog";
+			samsung,syscon-phandle = <&pmu_system_controller>;
+		};
 
-	adc: adc@126c0000 {
-		compatible = "samsung,exynos-adc-v1";
-		reg = <0x126C0000 0x100>;
-		interrupt-parent = <&combiner>;
-		interrupts = <10 3>;
-		clocks = <&clock CLK_TSADC>;
-		clock-names = "adc";
-		#io-channel-cells = <1>;
-		io-channel-ranges;
-		samsung,syscon-phandle = <&pmu_system_controller>;
-		status = "disabled";
-	};
-
-	g2d: g2d@10800000 {
-		compatible = "samsung,exynos4212-g2d";
-		reg = <0x10800000 0x1000>;
-		interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
-		clock-names = "sclk_fimg2d", "fimg2d";
-		iommus = <&sysmmu_g2d>;
-	};
-
-	camera {
-		clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
-			 <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
-		clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
-
-		/* fimc_[0-3] are configured outside, under phandles */
-		fimc_lite_0: fimc-lite@12390000 {
-			compatible = "samsung,exynos4212-fimc-lite";
-			reg = <0x12390000 0x1000>;
-			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
-			power-domains = <&pd_isp>;
-			clocks = <&isp_clock CLK_ISP_FIMC_LITE0>;
-			clock-names = "flite";
-			iommus = <&sysmmu_fimc_lite0>;
+		adc: adc@126c0000 {
+			compatible = "samsung,exynos-adc-v1";
+			reg = <0x126C0000 0x100>;
+			interrupt-parent = <&combiner>;
+			interrupts = <10 3>;
+			clocks = <&clock CLK_TSADC>;
+			clock-names = "adc";
+			#io-channel-cells = <1>;
+			io-channel-ranges;
+			samsung,syscon-phandle = <&pmu_system_controller>;
 			status = "disabled";
 		};
 
-		fimc_lite_1: fimc-lite@123a0000 {
-			compatible = "samsung,exynos4212-fimc-lite";
-			reg = <0x123A0000 0x1000>;
-			interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
-			power-domains = <&pd_isp>;
-			clocks = <&isp_clock CLK_ISP_FIMC_LITE1>;
-			clock-names = "flite";
-			iommus = <&sysmmu_fimc_lite1>;
-			status = "disabled";
+		g2d: g2d@10800000 {
+			compatible = "samsung,exynos4212-g2d";
+			reg = <0x10800000 0x1000>;
+			interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
+			clock-names = "sclk_fimg2d", "fimg2d";
+			iommus = <&sysmmu_g2d>;
 		};
 
-		fimc_is: fimc-is@12000000 {
-			compatible = "samsung,exynos4212-fimc-is";
-			reg = <0x12000000 0x260000>;
-			interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
-			power-domains = <&pd_isp>;
-			clocks = <&isp_clock CLK_ISP_FIMC_LITE0>,
-				 <&isp_clock CLK_ISP_FIMC_LITE1>,
-				 <&isp_clock CLK_ISP_PPMUISPX>,
-				 <&isp_clock CLK_ISP_PPMUISPMX>,
-				 <&isp_clock CLK_ISP_FIMC_ISP>,
-				 <&isp_clock CLK_ISP_FIMC_DRC>,
-				 <&isp_clock CLK_ISP_FIMC_FD>,
-				 <&isp_clock CLK_ISP_MCUISP>,
-				 <&isp_clock CLK_ISP_GICISP>,
-				 <&isp_clock CLK_ISP_MCUCTL_ISP>,
-				 <&isp_clock CLK_ISP_PWM_ISP>,
-				 <&isp_clock CLK_ISP_DIV_ISP0>,
-				 <&isp_clock CLK_ISP_DIV_ISP1>,
-				 <&isp_clock CLK_ISP_DIV_MCUISP0>,
-				 <&isp_clock CLK_ISP_DIV_MCUISP1>,
-				 <&clock CLK_MOUT_MPLL_USER_T>,
-				 <&clock CLK_ACLK200>,
-				 <&clock CLK_ACLK400_MCUISP>,
-				 <&clock CLK_DIV_ACLK200>,
-				 <&clock CLK_DIV_ACLK400_MCUISP>,
-				 <&clock CLK_UART_ISP_SCLK>;
-			clock-names = "lite0", "lite1", "ppmuispx",
-				      "ppmuispmx", "isp",
-				      "drc", "fd", "mcuisp",
-				      "gicisp", "mcuctl_isp", "pwm_isp",
-				      "ispdiv0", "ispdiv1", "mcuispdiv0",
-				      "mcuispdiv1", "mpll", "aclk200",
-				      "aclk400mcuisp", "div_aclk200",
-				      "div_aclk400mcuisp", "uart";
-			iommus = <&sysmmu_fimc_isp>, <&sysmmu_fimc_drc>,
-				 <&sysmmu_fimc_fd>, <&sysmmu_fimc_mcuctl>;
-			iommu-names = "isp", "drc", "fd", "mcuctl";
+		mshc_0: mmc@12550000 {
+			compatible = "samsung,exynos4412-dw-mshc";
+			reg = <0x12550000 0x1000>;
+			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges;
+			#size-cells = <0>;
+			fifo-depth = <0x80>;
+			clocks = <&clock CLK_SDMMC4>, <&clock CLK_SCLK_MMC4>;
+			clock-names = "biu", "ciu";
 			status = "disabled";
+		};
 
-			pmu@10020000 {
-				reg = <0x10020000 0x3000>;
+		sysmmu_g2d: sysmmu@10A40000{
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x10A40000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <4 7>;
+			clock-names = "sysmmu", "master";
+			clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc_isp: sysmmu@12260000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x12260000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <16 2>;
+			power-domains = <&pd_isp>;
+			clock-names = "sysmmu";
+			clocks = <&isp_clock CLK_ISP_SMMU_ISP>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc_drc: sysmmu@12270000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x12270000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <16 3>;
+			power-domains = <&pd_isp>;
+			clock-names = "sysmmu";
+			clocks = <&isp_clock CLK_ISP_SMMU_DRC>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc_fd: sysmmu@122a0000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x122A0000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <16 4>;
+			power-domains = <&pd_isp>;
+			clock-names = "sysmmu";
+			clocks = <&isp_clock CLK_ISP_SMMU_FD>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc_mcuctl: sysmmu@122b0000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x122B0000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <16 5>;
+			power-domains = <&pd_isp>;
+			clock-names = "sysmmu";
+			clocks = <&isp_clock CLK_ISP_SMMU_ISPCX>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc_lite0: sysmmu@123b0000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x123B0000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <16 0>;
+			power-domains = <&pd_isp>;
+			clock-names = "sysmmu", "master";
+			clocks = <&isp_clock CLK_ISP_SMMU_LITE0>,
+				 <&isp_clock CLK_ISP_FIMC_LITE0>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_fimc_lite1: sysmmu@123c0000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x123C0000 0x1000>;
+			interrupt-parent = <&combiner>;
+			interrupts = <16 1>;
+			power-domains = <&pd_isp>;
+			clock-names = "sysmmu", "master";
+			clocks = <&isp_clock CLK_ISP_SMMU_LITE1>,
+				 <&isp_clock CLK_ISP_FIMC_LITE1>;
+			#iommu-cells = <0>;
+		};
+
+		bus_dmc: bus_dmc {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_DMC>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_dmc_opp_table>;
+			status = "disabled";
+		};
+
+		bus_acp: bus_acp {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_ACP>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_acp_opp_table>;
+			status = "disabled";
+		};
+
+		bus_c2c: bus_c2c {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_C2C>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_dmc_opp_table>;
+			status = "disabled";
+		};
+
+		bus_dmc_opp_table: opp_table1 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+				opp-microvolt = <900000>;
 			};
-
-			i2c1_isp: i2c-isp@12140000 {
-				compatible = "samsung,exynos4212-i2c-isp";
-				reg = <0x12140000 0x100>;
-				clocks = <&isp_clock CLK_ISP_I2C1_ISP>;
-				clock-names = "i2c_isp";
-				#address-cells = <1>;
-				#size-cells = <0>;
+			opp-134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+				opp-microvolt = <900000>;
+			};
+			opp-160000000 {
+				opp-hz = /bits/ 64 <160000000>;
+				opp-microvolt = <900000>;
+			};
+			opp-267000000 {
+				opp-hz = /bits/ 64 <267000000>;
+				opp-microvolt = <950000>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				opp-microvolt = <1050000>;
 			};
 		};
-	};
 
-	mshc_0: mmc@12550000 {
-		compatible = "samsung,exynos4412-dw-mshc";
-		reg = <0x12550000 0x1000>;
-		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		fifo-depth = <0x80>;
-		clocks = <&clock CLK_SDMMC4>, <&clock CLK_SCLK_MMC4>;
-		clock-names = "biu", "ciu";
-		status = "disabled";
-	};
+		bus_acp_opp_table: opp_table2 {
+			compatible = "operating-points-v2";
+			opp-shared;
 
-	sysmmu_g2d: sysmmu@10A40000{
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x10A40000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <4 7>;
-		clock-names = "sysmmu", "master";
-		clocks = <&clock CLK_SMMU_G2D>, <&clock CLK_G2D>;
-		#iommu-cells = <0>;
-	};
-
-	sysmmu_fimc_isp: sysmmu@12260000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x12260000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <16 2>;
-		power-domains = <&pd_isp>;
-		clock-names = "sysmmu";
-		clocks = <&isp_clock CLK_ISP_SMMU_ISP>;
-		#iommu-cells = <0>;
-	};
-
-	sysmmu_fimc_drc: sysmmu@12270000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x12270000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <16 3>;
-		power-domains = <&pd_isp>;
-		clock-names = "sysmmu";
-		clocks = <&isp_clock CLK_ISP_SMMU_DRC>;
-		#iommu-cells = <0>;
-	};
-
-	sysmmu_fimc_fd: sysmmu@122a0000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x122A0000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <16 4>;
-		power-domains = <&pd_isp>;
-		clock-names = "sysmmu";
-		clocks = <&isp_clock CLK_ISP_SMMU_FD>;
-		#iommu-cells = <0>;
-	};
-
-	sysmmu_fimc_mcuctl: sysmmu@122b0000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x122B0000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <16 5>;
-		power-domains = <&pd_isp>;
-		clock-names = "sysmmu";
-		clocks = <&isp_clock CLK_ISP_SMMU_ISPCX>;
-		#iommu-cells = <0>;
-	};
-
-	sysmmu_fimc_lite0: sysmmu@123b0000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x123B0000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <16 0>;
-		power-domains = <&pd_isp>;
-		clock-names = "sysmmu", "master";
-		clocks = <&isp_clock CLK_ISP_SMMU_LITE0>,
-			 <&isp_clock CLK_ISP_FIMC_LITE0>;
-		#iommu-cells = <0>;
-	};
-
-	sysmmu_fimc_lite1: sysmmu@123c0000 {
-		compatible = "samsung,exynos-sysmmu";
-		reg = <0x123C0000 0x1000>;
-		interrupt-parent = <&combiner>;
-		interrupts = <16 1>;
-		power-domains = <&pd_isp>;
-		clock-names = "sysmmu", "master";
-		clocks = <&isp_clock CLK_ISP_SMMU_LITE1>,
-			 <&isp_clock CLK_ISP_FIMC_LITE1>;
-		#iommu-cells = <0>;
-	};
-
-	bus_dmc: bus_dmc {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_DMC>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_dmc_opp_table>;
-		status = "disabled";
-	};
-
-	bus_acp: bus_acp {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_ACP>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_acp_opp_table>;
-		status = "disabled";
-	};
-
-	bus_c2c: bus_c2c {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_C2C>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_dmc_opp_table>;
-		status = "disabled";
-	};
-
-	bus_dmc_opp_table: opp_table1 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
-			opp-microvolt = <900000>;
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+			opp-134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+			};
+			opp-160000000 {
+				opp-hz = /bits/ 64 <160000000>;
+			};
+			opp-267000000 {
+				opp-hz = /bits/ 64 <267000000>;
+			};
 		};
-		opp-134000000 {
-			opp-hz = /bits/ 64 <134000000>;
-			opp-microvolt = <900000>;
-		};
-		opp-160000000 {
-			opp-hz = /bits/ 64 <160000000>;
-			opp-microvolt = <900000>;
-		};
-		opp-267000000 {
-			opp-hz = /bits/ 64 <267000000>;
-			opp-microvolt = <950000>;
-		};
-		opp-400000000 {
-			opp-hz = /bits/ 64 <400000000>;
-			opp-microvolt = <1050000>;
-		};
-	};
 
-	bus_acp_opp_table: opp_table2 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
+		bus_leftbus: bus_leftbus {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_GDL>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
 		};
-		opp-134000000 {
-			opp-hz = /bits/ 64 <134000000>;
+
+		bus_rightbus: bus_rightbus {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_DIV_GDR>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
 		};
-		opp-160000000 {
-			opp-hz = /bits/ 64 <160000000>;
+
+		bus_display: bus_display {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_ACLK160>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_display_opp_table>;
+			status = "disabled";
 		};
-		opp-267000000 {
-			opp-hz = /bits/ 64 <267000000>;
+
+		bus_fsys: bus_fsys {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_ACLK133>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_fsys_opp_table>;
+			status = "disabled";
 		};
-	};
 
-	bus_leftbus: bus_leftbus {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_GDL>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_leftbus_opp_table>;
-		status = "disabled";
-	};
-
-	bus_rightbus: bus_rightbus {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_DIV_GDR>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_leftbus_opp_table>;
-		status = "disabled";
-	};
-
-	bus_display: bus_display {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_ACLK160>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_display_opp_table>;
-		status = "disabled";
-	};
-
-	bus_fsys: bus_fsys {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_ACLK133>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_fsys_opp_table>;
-		status = "disabled";
-	};
-
-	bus_peri: bus_peri {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_ACLK100>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_peri_opp_table>;
-		status = "disabled";
-	};
-
-	bus_mfc: bus_mfc {
-		compatible = "samsung,exynos-bus";
-		clocks = <&clock CLK_SCLK_MFC>;
-		clock-names = "bus";
-		operating-points-v2 = <&bus_leftbus_opp_table>;
-		status = "disabled";
-	};
-
-	bus_leftbus_opp_table: opp_table3 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
-			opp-microvolt = <900000>;
+		bus_peri: bus_peri {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_ACLK100>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_peri_opp_table>;
+			status = "disabled";
 		};
-		opp-134000000 {
-			opp-hz = /bits/ 64 <134000000>;
-			opp-microvolt = <925000>;
-		};
-		opp-160000000 {
-			opp-hz = /bits/ 64 <160000000>;
-			opp-microvolt = <950000>;
-		};
-		opp-200000000 {
-			opp-hz = /bits/ 64 <200000000>;
-			opp-microvolt = <1000000>;
-		};
-	};
 
-	bus_display_opp_table: opp_table4 {
-		compatible = "operating-points-v2";
-		opp-shared;
-
-		opp-160000000 {
-			opp-hz = /bits/ 64 <160000000>;
+		bus_mfc: bus_mfc {
+			compatible = "samsung,exynos-bus";
+			clocks = <&clock CLK_SCLK_MFC>;
+			clock-names = "bus";
+			operating-points-v2 = <&bus_leftbus_opp_table>;
+			status = "disabled";
 		};
-		opp-200000000 {
-			opp-hz = /bits/ 64 <200000000>;
-		};
-	};
 
-	bus_fsys_opp_table: opp_table5 {
-		compatible = "operating-points-v2";
-		opp-shared;
+		bus_leftbus_opp_table: opp_table3 {
+			compatible = "operating-points-v2";
+			opp-shared;
 
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+				opp-microvolt = <900000>;
+			};
+			opp-134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+				opp-microvolt = <925000>;
+			};
+			opp-160000000 {
+				opp-hz = /bits/ 64 <160000000>;
+				opp-microvolt = <950000>;
+			};
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				opp-microvolt = <1000000>;
+			};
 		};
-		opp-134000000 {
-			opp-hz = /bits/ 64 <134000000>;
-		};
-	};
 
-	bus_peri_opp_table: opp_table6 {
-		compatible = "operating-points-v2";
-		opp-shared;
+		bus_display_opp_table: opp_table4 {
+			compatible = "operating-points-v2";
+			opp-shared;
 
-		opp-50000000 {
-			opp-hz = /bits/ 64 <50000000>;
+			opp-160000000 {
+				opp-hz = /bits/ 64 <160000000>;
+			};
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+			};
 		};
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
-		};
-	};
 
-	pmu {
-		interrupts = <2 2>, <3 2>, <18 2>, <19 2>;
+		bus_fsys_opp_table: opp_table5 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+			opp-134000000 {
+				opp-hz = /bits/ 64 <134000000>;
+			};
+		};
+
+		bus_peri_opp_table: opp_table6 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-50000000 {
+				opp-hz = /bits/ 64 <50000000>;
+			};
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+		};
 	};
 };
 
@@ -631,6 +576,92 @@
 		     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
 };
 
+&camera {
+	clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
+		 <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
+	clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
+
+	/* fimc_[0-3] are configured outside, under phandles */
+	fimc_lite_0: fimc-lite@12390000 {
+		compatible = "samsung,exynos4212-fimc-lite";
+		reg = <0x12390000 0x1000>;
+		interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&pd_isp>;
+		clocks = <&isp_clock CLK_ISP_FIMC_LITE0>;
+		clock-names = "flite";
+		iommus = <&sysmmu_fimc_lite0>;
+		status = "disabled";
+	};
+
+	fimc_lite_1: fimc-lite@123a0000 {
+		compatible = "samsung,exynos4212-fimc-lite";
+		reg = <0x123A0000 0x1000>;
+		interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&pd_isp>;
+		clocks = <&isp_clock CLK_ISP_FIMC_LITE1>;
+		clock-names = "flite";
+		iommus = <&sysmmu_fimc_lite1>;
+		status = "disabled";
+	};
+
+	fimc_is: fimc-is@12000000 {
+		compatible = "samsung,exynos4212-fimc-is";
+		reg = <0x12000000 0x260000>;
+		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&pd_isp>;
+		clocks = <&isp_clock CLK_ISP_FIMC_LITE0>,
+			 <&isp_clock CLK_ISP_FIMC_LITE1>,
+			 <&isp_clock CLK_ISP_PPMUISPX>,
+			 <&isp_clock CLK_ISP_PPMUISPMX>,
+			 <&isp_clock CLK_ISP_FIMC_ISP>,
+			 <&isp_clock CLK_ISP_FIMC_DRC>,
+			 <&isp_clock CLK_ISP_FIMC_FD>,
+			 <&isp_clock CLK_ISP_MCUISP>,
+			 <&isp_clock CLK_ISP_GICISP>,
+			 <&isp_clock CLK_ISP_MCUCTL_ISP>,
+			 <&isp_clock CLK_ISP_PWM_ISP>,
+			 <&isp_clock CLK_ISP_DIV_ISP0>,
+			 <&isp_clock CLK_ISP_DIV_ISP1>,
+			 <&isp_clock CLK_ISP_DIV_MCUISP0>,
+			 <&isp_clock CLK_ISP_DIV_MCUISP1>,
+			 <&clock CLK_MOUT_MPLL_USER_T>,
+			 <&clock CLK_ACLK200>,
+			 <&clock CLK_ACLK400_MCUISP>,
+			 <&clock CLK_DIV_ACLK200>,
+			 <&clock CLK_DIV_ACLK400_MCUISP>,
+			 <&clock CLK_UART_ISP_SCLK>;
+		clock-names = "lite0", "lite1", "ppmuispx",
+			      "ppmuispmx", "isp",
+			      "drc", "fd", "mcuisp",
+			      "gicisp", "mcuctl_isp", "pwm_isp",
+			      "ispdiv0", "ispdiv1", "mcuispdiv0",
+			      "mcuispdiv1", "mpll", "aclk200",
+			      "aclk400mcuisp", "div_aclk200",
+			      "div_aclk400mcuisp", "uart";
+		iommus = <&sysmmu_fimc_isp>, <&sysmmu_fimc_drc>,
+			 <&sysmmu_fimc_fd>, <&sysmmu_fimc_mcuctl>;
+		iommu-names = "isp", "drc", "fd", "mcuctl";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		status = "disabled";
+
+		pmu@10020000 {
+			reg = <0x10020000 0x3000>;
+		};
+
+		i2c1_isp: i2c-isp@12140000 {
+			compatible = "samsung,exynos4212-i2c-isp";
+			reg = <0x12140000 0x100>;
+			clocks = <&isp_clock CLK_ISP_I2C1_ISP>;
+			clock-names = "i2c_isp";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
 &exynos_usbphy {
 	compatible = "samsung,exynos4x12-usb2-phy";
 	samsung,sysreg-phandle = <&sys_reg>;
@@ -693,35 +724,8 @@
 		 <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>;
 };
 
-&pinctrl_0 {
-	compatible = "samsung,exynos4x12-pinctrl";
-	reg = <0x11400000 0x1000>;
-	interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
-};
-
-&pinctrl_1 {
-	compatible = "samsung,exynos4x12-pinctrl";
-	reg = <0x11000000 0x1000>;
-	interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
-
-	wakup_eint: wakeup-interrupt-controller {
-		compatible = "samsung,exynos4210-wakeup-eint";
-		interrupt-parent = <&gic>;
-		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-	};
-};
-
-&pinctrl_2 {
-	compatible = "samsung,exynos4x12-pinctrl";
-	reg = <0x03860000 0x1000>;
-	interrupt-parent = <&combiner>;
-	interrupts = <10 0>;
-};
-
-&pinctrl_3 {
-	compatible = "samsung,exynos4x12-pinctrl";
-	reg = <0x106E0000 0x1000>;
-	interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+&pmu {
+	interrupts = <2 2>, <3 2>, <18 2>, <19 2>;
 };
 
 &pmu_system_controller {
@@ -743,3 +747,5 @@
 	clock-names = "tmu_apbif";
 	status = "disabled";
 };
+
+#include "exynos4412-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
index 59cf1b2..fd9226d 100644
--- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi
+++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
@@ -9,6 +9,7 @@
 #include <dt-bindings/clock/maxim,max77686.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/input/input.h>
+#include <dt-bindings/sound/samsung-i2s.h>
 #include "exynos5250.dtsi"
 
 / {
@@ -225,6 +226,16 @@
 	};
 };
 
+&clock {
+	assigned-clocks = <&clock CLK_FOUT_EPLL>;
+	assigned-clock-rates = <49152000>;
+};
+
+&clock_audss {
+	assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>;
+	assigned-clock-parents = <&clock CLK_FOUT_EPLL>;
+};
+
 &cpu0 {
 	cpu0-supply = <&buck2_reg>;
 };
@@ -513,6 +524,8 @@
 };
 
 &i2s0 {
+	assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>;
+	assigned-clock-parents = <&clock_audss EXYNOS_I2S_BUS>;
 	status = "okay";
 };
 
@@ -649,6 +662,11 @@
 	};
 };
 
+&pmu_system_controller {
+	assigned-clocks = <&pmu_system_controller 0>;
+	assigned-clock-parents = <&clock CLK_FIN_PLL>;
+};
+
 &rtc {
 	status = "okay";
 	clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>;
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index 4827cb5..75fdc5e 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -18,6 +18,14 @@
 
 		samsung,model = "Snow-I2S-MAX98095";
 		samsung,audio-codec = <&max98095>;
+
+		cpu {
+			sound-dai = <&i2s0 0>;
+		};
+
+		codec {
+			sound-dai = <&max98095 0>, <&hdmi>;
+		};
 	};
 };
 
@@ -27,6 +35,9 @@
 		reg = <0x11>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&max98095_en>;
+		clocks = <&pmu_system_controller 0>;
+		clock-names = "mclk";
+		#sound-dai-cells = <1>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 56626d1..45283a6 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -77,8 +77,6 @@
 				 300000  937500
 				 200000  925000
 			>;
-			cooling-min-level = <15>;
-			cooling-max-level = <9>;
 			#cooling-cells = <2>; /* min followed by max */
 		};
 		cpu@1 {
@@ -500,6 +498,8 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2s0_bus>;
 			power-domains = <&pd_mau>;
+			#clock-cells = <1>;
+			#sound-dai-cells = <1>;
 		};
 
 		i2s1: i2s@12d60000 {
@@ -514,6 +514,7 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2s1_bus>;
 			power-domains = <&pd_mau>;
+			#sound-dai-cells = <1>;
 		};
 
 		i2s2: i2s@12d70000 {
@@ -528,6 +529,7 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2s2_bus>;
 			power-domains = <&pd_mau>;
+			#sound-dai-cells = <1>;
 		};
 
 		usb_dwc3 {
@@ -655,7 +657,7 @@
 			power-domains = <&pd_gsc>;
 			clocks = <&clock CLK_GSCL0>;
 			clock-names = "gscl";
-			iommu = <&sysmmu_gsc0>;
+			iommus = <&sysmmu_gsc0>;
 		};
 
 		gsc_1:  gsc@13e10000 {
@@ -665,7 +667,7 @@
 			power-domains = <&pd_gsc>;
 			clocks = <&clock CLK_GSCL1>;
 			clock-names = "gscl";
-			iommu = <&sysmmu_gsc1>;
+			iommus = <&sysmmu_gsc1>;
 		};
 
 		gsc_2:  gsc@13e20000 {
@@ -675,7 +677,7 @@
 			power-domains = <&pd_gsc>;
 			clocks = <&clock CLK_GSCL2>;
 			clock-names = "gscl";
-			iommu = <&sysmmu_gsc2>;
+			iommus = <&sysmmu_gsc2>;
 		};
 
 		gsc_3:  gsc@13e30000 {
@@ -685,7 +687,7 @@
 			power-domains = <&pd_gsc>;
 			clocks = <&clock CLK_GSCL3>;
 			clock-names = "gscl";
-			iommu = <&sysmmu_gsc3>;
+			iommus = <&sysmmu_gsc3>;
 		};
 
 		hdmi: hdmi@14530000 {
@@ -700,6 +702,7 @@
 					"sclk_hdmiphy", "mout_hdmi";
 			samsung,syscon-phandle = <&pmu_system_controller>;
 			phy = <&hdmiphy>;
+			#sound-dai-cells = <0>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/exynos5260-xyref5260.dts b/arch/arm/boot/dts/exynos5260-xyref5260.dts
index 442eb03..fa19c59 100644
--- a/arch/arm/boot/dts/exynos5260-xyref5260.dts
+++ b/arch/arm/boot/dts/exynos5260-xyref5260.dts
@@ -65,7 +65,6 @@
 &mmc_0 {
 	status = "okay";
 	broken-cd;
-	bypass-smu;
 	cap-mmc-highspeed;
 	supports-hs200-mode; /* 200 MHz */
 	card-detect-delay = <200>;
diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi
index 1886aa0..55509c6 100644
--- a/arch/arm/boot/dts/exynos5410.dtsi
+++ b/arch/arm/boot/dts/exynos5410.dtsi
@@ -11,7 +11,6 @@
  */
 
 #include "exynos54xx.dtsi"
-#include "exynos-syscon-restart.dtsi"
 #include <dt-bindings/clock/exynos5410.h>
 #include <dt-bindings/clock/exynos-audss-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -197,9 +196,9 @@
 			interrupt-parent = <&gic>;
 			ranges;
 
-			pdma0: pdma@12680000 {
+			pdma0: pdma@121a0000 {
 				compatible = "arm,pl330", "arm,primecell";
-				reg = <0x121A0000 0x1000>;
+				reg = <0x121a0000 0x1000>;
 				interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clock CLK_PDMA0>;
 				clock-names = "apb_pclk";
@@ -208,9 +207,9 @@
 				#dma-requests = <32>;
 			};
 
-			pdma1: pdma@12690000 {
+			pdma1: pdma@121b0000 {
 				compatible = "arm,pl330", "arm,primecell";
-				reg = <0x121B0000 0x1000>;
+				reg = <0x121b0000 0x1000>;
 				interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clock CLK_PDMA1>;
 				clock-names = "apb_pclk";
diff --git a/arch/arm/boot/dts/exynos5420-cpus.dtsi b/arch/arm/boot/dts/exynos5420-cpus.dtsi
index 123f0ce..a8e4494 100644
--- a/arch/arm/boot/dts/exynos5420-cpus.dtsi
+++ b/arch/arm/boot/dts/exynos5420-cpus.dtsi
@@ -30,8 +30,6 @@
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
 			operating-points-v2 = <&cluster_a15_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <11>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <1024>;
 		};
@@ -43,8 +41,6 @@
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
 			operating-points-v2 = <&cluster_a15_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <11>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <1024>;
 		};
@@ -56,8 +52,6 @@
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
 			operating-points-v2 = <&cluster_a15_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <11>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <1024>;
 		};
@@ -69,8 +63,6 @@
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
 			operating-points-v2 = <&cluster_a15_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <11>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <1024>;
 		};
@@ -83,8 +75,6 @@
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
 			operating-points-v2 = <&cluster_a7_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <7>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <539>;
 		};
@@ -96,8 +86,6 @@
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
 			operating-points-v2 = <&cluster_a7_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <7>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <539>;
 		};
@@ -109,8 +97,6 @@
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
 			operating-points-v2 = <&cluster_a7_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <7>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <539>;
 		};
@@ -122,8 +108,6 @@
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
 			operating-points-v2 = <&cluster_a7_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <7>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <539>;
 		};
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 5a76ed7..244f009 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -11,6 +11,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/clock/maxim,max77802.h>
 #include <dt-bindings/regulator/maxim,max77802.h>
+#include <dt-bindings/sound/samsung-i2s.h>
 #include "exynos5420.dtsi"
 #include "exynos5420-cpus.dtsi"
 
@@ -86,6 +87,14 @@
 		samsung,model = "Peach-Pit-I2S-MAX98090";
 		samsung,i2s-controller = <&i2s0>;
 		samsung,audio-codec = <&max98090>;
+
+		cpu {
+			sound-dai = <&i2s0 0>;
+		};
+
+		codec {
+			sound-dai = <&max98090>, <&hdmi>;
+		};
 	};
 
 	usb300_vbus_reg: regulator-usb300 {
@@ -142,6 +151,11 @@
 	vdd-supply = <&ldo9_reg>;
 };
 
+&clock_audss {
+	assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>;
+	assigned-clock-parents = <&clock CLK_FOUT_EPLL>;
+};
+
 &cpu0 {
 	cpu-supply = <&buck2_reg>;
 };
@@ -606,6 +620,7 @@
 		pinctrl-0 = <&max98090_irq>;
 		clocks = <&pmu_system_controller 0>;
 		clock-names = "mclk";
+		#sound-dai-cells = <0>;
 	};
 
 	light-sensor@44 {
@@ -690,6 +705,8 @@
 };
 
 &i2s0 {
+	assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>;
+	assigned-clock-parents = <&clock_audss EXYNOS_I2S_BUS>;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos5422-cpus.dtsi b/arch/arm/boot/dts/exynos5422-cpus.dtsi
index c593809..7c130a0 100644
--- a/arch/arm/boot/dts/exynos5422-cpus.dtsi
+++ b/arch/arm/boot/dts/exynos5422-cpus.dtsi
@@ -29,8 +29,6 @@
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
 			operating-points-v2 = <&cluster_a7_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <11>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <539>;
 		};
@@ -42,8 +40,6 @@
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
 			operating-points-v2 = <&cluster_a7_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <11>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <539>;
 		};
@@ -55,8 +51,6 @@
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
 			operating-points-v2 = <&cluster_a7_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <11>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <539>;
 		};
@@ -68,8 +62,6 @@
 			clock-frequency = <1000000000>;
 			cci-control-port = <&cci_control0>;
 			operating-points-v2 = <&cluster_a7_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <11>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <539>;
 		};
@@ -82,8 +74,6 @@
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
 			operating-points-v2 = <&cluster_a15_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <15>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <1024>;
 		};
@@ -95,8 +85,6 @@
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
 			operating-points-v2 = <&cluster_a15_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <15>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <1024>;
 		};
@@ -108,8 +96,6 @@
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
 			operating-points-v2 = <&cluster_a15_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <15>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <1024>;
 		};
@@ -121,8 +107,6 @@
 			clock-frequency = <1800000000>;
 			cci-control-port = <&cci_control1>;
 			operating-points-v2 = <&cluster_a15_opp_table>;
-			cooling-min-level = <0>;
-			cooling-max-level = <15>;
 			#cooling-cells = <2>; /* min followed by max */
 			capacity-dmips-mhz = <1024>;
 		};
diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi
index fce9e26..f3abecc4 100644
--- a/arch/arm/boot/dts/exynos5440.dtsi
+++ b/arch/arm/boot/dts/exynos5440.dtsi
@@ -26,24 +26,6 @@
 		tmuctrl2 = &tmuctrl_2;
 	};
 
-	clock: clock-controller@160000 {
-		compatible = "samsung,exynos5440-clock";
-		reg = <0x160000 0x1000>;
-		#clock-cells = <1>;
-	};
-
-	gic: interrupt-controller@2e0000 {
-		compatible = "arm,cortex-a15-gic";
-		#interrupt-cells = <3>;
-		interrupt-controller;
-		reg =	<0x2E1000 0x1000>,
-			<0x2E2000 0x2000>,
-			<0x2E4000 0x2000>,
-			<0x2E6000 0x2000>;
-		interrupts = <GIC_PPI 9
-				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-	};
-
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -70,182 +52,290 @@
 		};
 	};
 
-	arm-pmu {
-		compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu";
-		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
-	};
-
-	timer {
-		compatible = "arm,cortex-a15-timer",
-			     "arm,armv7-timer";
-		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
-		clock-frequency = <50000000>;
-	};
-
-	cpufreq@160000 {
-		compatible = "samsung,exynos5440-cpufreq";
-		reg = <0x160000 0x1000>;
-		interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
-		operating-points = <
-				/* KHz	  uV */
-				1500000 1100000
-				1400000 1075000
-				1300000 1050000
-				1200000 1025000
-				1100000 1000000
-				1000000 975000
-				900000  950000
-				800000  925000
-		>;
-	};
-
-	serial_0: serial@b0000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0xB0000 0x1000>;
-		interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
-
-	serial_1: serial@c0000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0xC0000 0x1000>;
-		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
-
-	spi_0: spi@d0000 {
-		compatible = "samsung,exynos5440-spi";
-		reg = <0xD0000 0x100>;
-		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		samsung,spi-src-clk = <0>;
-		num-cs = <1>;
-		clocks = <&clock CLK_B_125>, <&clock CLK_SPI_BAUD>;
-		clock-names = "spi", "spi_busclk0";
-	};
-
-	pin_ctrl: pinctrl@e0000 {
-		compatible = "samsung,exynos5440-pinctrl";
-		reg = <0xE0000 0x1000>;
-		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		#gpio-cells = <2>;
-
-		fan: fan {
-			samsung,exynos5440-pin-function = <1>;
-		};
-
-		hdd_led0: hdd_led0 {
-			samsung,exynos5440-pin-function = <2>;
-		};
-
-		hdd_led1: hdd_led1 {
-			samsung,exynos5440-pin-function = <3>;
-		};
-
-		uart1: uart1 {
-			samsung,exynos5440-pin-function = <4>;
-		};
-	};
-
-	i2c@f0000 {
-		compatible = "samsung,exynos5440-i2c";
-		reg = <0xF0000 0x1000>;
-		interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&clock CLK_B_125>;
-		clock-names = "i2c";
-	};
-
-	i2c@100000 {
-		compatible = "samsung,exynos5440-i2c";
-		reg = <0x100000 0x1000>;
-		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&clock CLK_B_125>;
-		clock-names = "i2c";
-	};
-
-	watchdog@110000 {
-		compatible = "samsung,s3c6410-wdt";
-		reg = <0x110000 0x1000>;
-		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_B_125>;
-		clock-names = "watchdog";
-	};
-
-	gmac: ethernet@230000 {
-		compatible = "snps,dwmac-3.70a", "snps,dwmac";
-		reg = <0x00230000 0x8000>;
-		interrupt-parent = <&gic>;
-		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "macirq";
-		phy-mode = "sgmii";
-		clocks = <&clock CLK_GMAC0>;
-		clock-names = "stmmaceth";
-	};
-
-	amba {
+	soc: soc {
+		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "simple-bus";
-		interrupt-parent = <&gic>;
 		ranges;
-	};
 
-	rtc@130000 {
-		compatible = "samsung,s3c6410-rtc";
-		reg = <0x130000 0x1000>;
-		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_B_125>;
-		clock-names = "rtc";
-	};
+		clock: clock-controller@160000 {
+			compatible = "samsung,exynos5440-clock";
+			reg = <0x160000 0x1000>;
+			#clock-cells = <1>;
+		};
 
-	tmuctrl_0: tmuctrl@160118 {
-		compatible = "samsung,exynos5440-tmu";
-		reg = <0x160118 0x230>, <0x160368 0x10>;
-		interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_B_125>;
-		clock-names = "tmu_apbif";
-		#include "exynos5440-tmu-sensor-conf.dtsi"
-	};
+		gic: interrupt-controller@2e0000 {
+			compatible = "arm,cortex-a15-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg =	<0x2E1000 0x1000>,
+				<0x2E2000 0x2000>,
+				<0x2E4000 0x2000>,
+				<0x2E6000 0x2000>;
+			interrupts = <GIC_PPI 9
+					(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		};
 
-	tmuctrl_1: tmuctrl@16011c {
-		compatible = "samsung,exynos5440-tmu";
-		reg = <0x16011C 0x230>, <0x160368 0x10>;
-		interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_B_125>;
-		clock-names = "tmu_apbif";
-		#include "exynos5440-tmu-sensor-conf.dtsi"
-	};
 
-	tmuctrl_2: tmuctrl@160120 {
-		compatible = "samsung,exynos5440-tmu";
-		reg = <0x160120 0x230>, <0x160368 0x10>;
-		interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_B_125>;
-		clock-names = "tmu_apbif";
-		#include "exynos5440-tmu-sensor-conf.dtsi"
+		arm-pmu {
+			compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu";
+			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		timer {
+			compatible = "arm,cortex-a15-timer",
+				     "arm,armv7-timer";
+			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+			clock-frequency = <50000000>;
+		};
+
+		cpufreq@160000 {
+			compatible = "samsung,exynos5440-cpufreq";
+			reg = <0x160000 0x1000>;
+			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+			operating-points = <
+					/* KHz	  uV */
+					1500000 1100000
+					1400000 1075000
+					1300000 1050000
+					1200000 1025000
+					1100000 1000000
+					1000000 975000
+					900000  950000
+					800000  925000
+			>;
+		};
+
+		serial_0: serial@b0000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0xB0000 0x1000>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
+			clock-names = "uart", "clk_uart_baud0";
+		};
+
+		serial_1: serial@c0000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0xC0000 0x1000>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
+			clock-names = "uart", "clk_uart_baud0";
+		};
+
+		spi_0: spi@d0000 {
+			compatible = "samsung,exynos5440-spi";
+			reg = <0xD0000 0x100>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			samsung,spi-src-clk = <0>;
+			num-cs = <1>;
+			clocks = <&clock CLK_B_125>, <&clock CLK_SPI_BAUD>;
+			clock-names = "spi", "spi_busclk0";
+		};
+
+		pin_ctrl: pinctrl@e0000 {
+			compatible = "samsung,exynos5440-pinctrl";
+			reg = <0xE0000 0x1000>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			#gpio-cells = <2>;
+
+			fan: fan {
+				samsung,exynos5440-pin-function = <1>;
+			};
+
+			hdd_led0: hdd_led0 {
+				samsung,exynos5440-pin-function = <2>;
+			};
+
+			hdd_led1: hdd_led1 {
+				samsung,exynos5440-pin-function = <3>;
+			};
+
+			uart1: uart1 {
+				samsung,exynos5440-pin-function = <4>;
+			};
+		};
+
+		i2c@f0000 {
+			compatible = "samsung,exynos5440-i2c";
+			reg = <0xF0000 0x1000>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock CLK_B_125>;
+			clock-names = "i2c";
+		};
+
+		i2c@100000 {
+			compatible = "samsung,exynos5440-i2c";
+			reg = <0x100000 0x1000>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock CLK_B_125>;
+			clock-names = "i2c";
+		};
+
+		watchdog@110000 {
+			compatible = "samsung,s3c6410-wdt";
+			reg = <0x110000 0x1000>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_B_125>;
+			clock-names = "watchdog";
+		};
+
+		gmac: ethernet@230000 {
+			compatible = "snps,dwmac-3.70a", "snps,dwmac";
+			reg = <0x00230000 0x8000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+			phy-mode = "sgmii";
+			clocks = <&clock CLK_GMAC0>;
+			clock-names = "stmmaceth";
+		};
+
+		amba {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			interrupt-parent = <&gic>;
+			ranges;
+		};
+
+		rtc@130000 {
+			compatible = "samsung,s3c6410-rtc";
+			reg = <0x130000 0x1000>;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_B_125>;
+			clock-names = "rtc";
+		};
+
+		tmuctrl_0: tmuctrl@160118 {
+			compatible = "samsung,exynos5440-tmu";
+			reg = <0x160118 0x230>, <0x160368 0x10>;
+			interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_B_125>;
+			clock-names = "tmu_apbif";
+			#include "exynos5440-tmu-sensor-conf.dtsi"
+		};
+
+		tmuctrl_1: tmuctrl@16011c {
+			compatible = "samsung,exynos5440-tmu";
+			reg = <0x16011C 0x230>, <0x160368 0x10>;
+			interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_B_125>;
+			clock-names = "tmu_apbif";
+			#include "exynos5440-tmu-sensor-conf.dtsi"
+		};
+
+		tmuctrl_2: tmuctrl@160120 {
+			compatible = "samsung,exynos5440-tmu";
+			reg = <0x160120 0x230>, <0x160368 0x10>;
+			interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_B_125>;
+			clock-names = "tmu_apbif";
+			#include "exynos5440-tmu-sensor-conf.dtsi"
+		};
+
+		sata@210000 {
+			compatible = "snps,exynos5440-ahci";
+			reg = <0x210000 0x10000>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_SATA>;
+			clock-names = "sata";
+		};
+
+		ohci@220000 {
+			compatible = "samsung,exynos5440-ohci";
+			reg = <0x220000 0x1000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_USB>;
+			clock-names = "usbhost";
+		};
+
+		ehci@221000 {
+			compatible = "samsung,exynos5440-ehci";
+			reg = <0x221000 0x1000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_USB>;
+			clock-names = "usbhost";
+		};
+
+		pcie_phy0: pcie-phy@270000 {
+			#phy-cells = <0>;
+			compatible = "samsung,exynos5440-pcie-phy";
+			reg = <0x270000 0x1000>, <0x271000 0x40>;
+		};
+
+		pcie_phy1: pcie-phy@272000 {
+			#phy-cells = <0>;
+			compatible = "samsung,exynos5440-pcie-phy";
+			reg = <0x272000 0x1000>, <0x271040 0x40>;
+		};
+
+		pcie_0: pcie@290000 {
+			compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+			reg = <0x290000 0x1000>, <0x40000000 0x1000>;
+			reg-names = "elbi", "config";
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_PR0_250_O>, <&clock CLK_PB0_250_O>;
+			clock-names = "pcie", "pcie_bus";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			phys = <&pcie_phy0>;
+			ranges = <0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
+				  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
+			bus-range = <0x00 0xff>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0x0 0 &gic 53>;
+			num-lanes = <4>;
+			status = "disabled";
+		};
+
+		pcie_1: pcie@2a0000 {
+			compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+			reg = <0x2a0000 0x1000>, <0x60000000 0x1000>;
+			reg-names = "elbi", "config";
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock CLK_PR1_250_O>, <&clock CLK_PB0_250_O>;
+			clock-names = "pcie", "pcie_bus";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			phys = <&pcie_phy1>;
+			ranges = <0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
+				  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
+			bus-range = <0x00 0xff>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0x0 0 &gic 56>;
+			num-lanes = <4>;
+			status = "disabled";
+		};
 	};
 
 	thermal-zones {
@@ -262,86 +352,4 @@
 		       #include "exynos5440-trip-points.dtsi"
 		};
 	};
-
-	sata@210000 {
-		compatible = "snps,exynos5440-ahci";
-		reg = <0x210000 0x10000>;
-		interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_SATA>;
-		clock-names = "sata";
-	};
-
-	ohci@220000 {
-		compatible = "samsung,exynos5440-ohci";
-		reg = <0x220000 0x1000>;
-		interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_USB>;
-		clock-names = "usbhost";
-	};
-
-	ehci@221000 {
-		compatible = "samsung,exynos5440-ehci";
-		reg = <0x221000 0x1000>;
-		interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_USB>;
-		clock-names = "usbhost";
-	};
-
-	pcie_phy0: pcie-phy@270000 {
-		#phy-cells = <0>;
-		compatible = "samsung,exynos5440-pcie-phy";
-		reg = <0x270000 0x1000>, <0x271000 0x40>;
-	};
-
-	pcie_phy1: pcie-phy@272000 {
-		#phy-cells = <0>;
-		compatible = "samsung,exynos5440-pcie-phy";
-		reg = <0x272000 0x1000>, <0x271040 0x40>;
-	};
-
-	pcie_0: pcie@290000 {
-		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-		reg = <0x290000 0x1000>, <0x40000000 0x1000>;
-		reg-names = "elbi", "config";
-		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_PR0_250_O>, <&clock CLK_PB0_250_O>;
-		clock-names = "pcie", "pcie_bus";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		phys = <&pcie_phy0>;
-		ranges = <0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
-		bus-range = <0x00 0xff>;
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 53>;
-		num-lanes = <4>;
-		status = "disabled";
-	};
-
-	pcie_1: pcie@2a0000 {
-		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-		reg = <0x2a0000 0x1000>, <0x60000000 0x1000>;
-		reg-names = "elbi", "config";
-		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clock CLK_PR1_250_O>, <&clock CLK_PB0_250_O>;
-		clock-names = "pcie", "pcie_bus";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		phys = <&pcie_phy1>;
-		ranges = <0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
-		bus-range = <0x00 0xff>;
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 56>;
-		num-lanes = <4>;
-		status = "disabled";
-	};
 };
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 0029ec2..2f8df92 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Google Peach Pi Rev 10+ board device tree source
  *
  * Copyright (c) 2014 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/;
@@ -14,6 +11,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/clock/maxim,max77802.h>
 #include <dt-bindings/regulator/maxim,max77802.h>
+#include <dt-bindings/sound/samsung-i2s.h>
 #include "exynos5800.dtsi"
 #include "exynos5420-cpus.dtsi"
 
@@ -89,6 +87,14 @@
 		samsung,model = "Peach-Pi-I2S-MAX98091";
 		samsung,i2s-controller = <&i2s0>;
 		samsung,audio-codec = <&max98091>;
+
+		cpu {
+			sound-dai = <&i2s0 0>;
+		};
+
+		codec {
+			sound-dai = <&max98091>, <&hdmi>;
+		};
 	};
 
 	usb300_vbus_reg: regulator-usb300 {
@@ -145,6 +151,11 @@
 	vdd-supply = <&ldo9_reg>;
 };
 
+&clock_audss {
+	assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>;
+	assigned-clock-parents = <&clock CLK_FOUT_EPLL>;
+};
+
 &cpu0 {
 	cpu-supply = <&buck2_reg>;
 };
@@ -609,6 +620,7 @@
 		pinctrl-0 = <&max98091_irq>;
 		clocks = <&pmu_system_controller 0>;
 		clock-names = "mclk";
+		#sound-dai-cells = <0>;
 	};
 
 	light-sensor@44 {
@@ -661,6 +673,8 @@
 };
 
 &i2s0 {
+	assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>;
+	assigned-clock-parents = <&clock_audss EXYNOS_I2S_BUS>;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
index 9ddb6ba..57d3b31 100644
--- a/arch/arm/boot/dts/exynos5800.dtsi
+++ b/arch/arm/boot/dts/exynos5800.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SAMSUNG EXYNOS5800 SoC device tree source
  *
@@ -7,10 +8,6 @@
  * SAMSUNG EXYNOS5800 SoC device nodes are listed in this file.
  * EXYNOS5800 based board files can include this file and provide
  * values for board specfic bindings.
- *
- * 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 "exynos5420.dtsi"
diff --git a/arch/arm/boot/dts/gemini-dlink-dns-313.dts b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
index da8bb9d..403364a 100644
--- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts
+++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
@@ -78,8 +78,6 @@
 		gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>,
 			<&gpio0 12 GPIO_ACTIVE_HIGH>;
 		gpio-fan,speed-map = <0 0>, <3000 1>, <6000 2>;
-		cooling-min-level = <0>;
-		cooling-max-level = <2>;
 		#cooling-cells = <2>;
 	};
 
diff --git a/arch/arm/boot/dts/imx1-ads.dts b/arch/arm/boot/dts/imx1-ads.dts
index 5ea28ee..6354e4c 100644
--- a/arch/arm/boot/dts/imx1-ads.dts
+++ b/arch/arm/boot/dts/imx1-ads.dts
@@ -20,7 +20,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@8000000 {
 		reg = <0x08000000 0x04000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx1-apf9328.dts b/arch/arm/boot/dts/imx1-apf9328.dts
index e8b4b52c..11515c0 100644
--- a/arch/arm/boot/dts/imx1-apf9328.dts
+++ b/arch/arm/boot/dts/imx1-apf9328.dts
@@ -20,7 +20,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@8000000 {
 		reg = <0x08000000 0x00800000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx1.dtsi b/arch/arm/boot/dts/imx1.dtsi
index 20f6565..f7b9edf 100644
--- a/arch/arm/boot/dts/imx1.dtsi
+++ b/arch/arm/boot/dts/imx1.dtsi
@@ -25,7 +25,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		gpio0 = &gpio1;
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
index 57e2997..9d92ece82 100644
--- a/arch/arm/boot/dts/imx23-evk.dts
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -16,7 +16,7 @@
 	model = "Freescale i.MX23 Evaluation Kit";
 	compatible = "fsl,imx23-evk", "fsl,imx23";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx23-olinuxino.dts b/arch/arm/boot/dts/imx23-olinuxino.dts
index a8b1c53..e935177 100644
--- a/arch/arm/boot/dts/imx23-olinuxino.dts
+++ b/arch/arm/boot/dts/imx23-olinuxino.dts
@@ -19,7 +19,7 @@
 	model = "i.MX23 Olinuxino Low Cost Board";
 	compatible = "olimex,imx23-olinuxino", "fsl,imx23";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x04000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx23-sansa.dts b/arch/arm/boot/dts/imx23-sansa.dts
index 221fd55..67de786 100644
--- a/arch/arm/boot/dts/imx23-sansa.dts
+++ b/arch/arm/boot/dts/imx23-sansa.dts
@@ -49,7 +49,7 @@
 	model = "SanDisk Sansa Fuze+";
 	compatible = "sandisk,sansa_fuze_plus", "fsl,imx23";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x04000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx23-stmp378x_devb.dts b/arch/arm/boot/dts/imx23-stmp378x_devb.dts
index 455169e..95c7b91 100644
--- a/arch/arm/boot/dts/imx23-stmp378x_devb.dts
+++ b/arch/arm/boot/dts/imx23-stmp378x_devb.dts
@@ -16,7 +16,7 @@
 	model = "Freescale STMP378x Development Board";
 	compatible = "fsl,stmp378x-devb", "fsl,imx23";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x04000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx23-xfi3.dts b/arch/arm/boot/dts/imx23-xfi3.dts
index 025cf94..9616e50 100644
--- a/arch/arm/boot/dts/imx23-xfi3.dts
+++ b/arch/arm/boot/dts/imx23-xfi3.dts
@@ -48,7 +48,7 @@
 	model = "Creative ZEN X-Fi3";
 	compatible = "creative,x-fi3", "fsl,imx23";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x04000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 10d57f9..cb0a3fe 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -23,7 +23,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		gpio0 = &gpio0;
@@ -222,7 +222,8 @@
 					fsl,pull-up = <MXS_PULL_DISABLE>;
 				};
 
-				gpmi_pins_fixup: gpmi-pins-fixup {
+				gpmi_pins_fixup: gpmi-pins-fixup@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX23_PAD_GPMI_WPN__GPMI_WPN
 						MX23_PAD_GPMI_WRN__GPMI_WRN
@@ -266,7 +267,8 @@
 					fsl,pull-up = <MXS_PULL_ENABLE>;
 				};
 
-				mmc0_pins_fixup: mmc0-pins-fixup {
+				mmc0_pins_fixup: mmc0-pins-fixup@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX23_PAD_SSP1_DETECT__SSP1_DETECT
 						MX23_PAD_SSP1_SCK__SSP1_SCK
diff --git a/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi b/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi
index d6f2764..e316fe0 100644
--- a/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi
+++ b/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi
@@ -17,7 +17,7 @@
 	model = "Eukrea CPUIMX25";
 	compatible = "eukrea,cpuimx25", "fsl,imx25";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x4000000>; /* 64M */
 	};
 };
diff --git a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts
index 0f05372..6273a1f 100644
--- a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts
+++ b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts
@@ -88,12 +88,12 @@
 
 		pinctrl_esdhc1: esdhc1grp {
 			fsl,pins = <
-				MX25_PAD_SD1_CMD__SD1_CMD		0x400000c0
-				MX25_PAD_SD1_CLK__SD1_CLK		0x400000c0
-				MX25_PAD_SD1_DATA0__SD1_DATA0		0x400000c0
-				MX25_PAD_SD1_DATA1__SD1_DATA1		0x400000c0
-				MX25_PAD_SD1_DATA2__SD1_DATA2		0x400000c0
-				MX25_PAD_SD1_DATA3__SD1_DATA3		0x400000c0
+				MX25_PAD_SD1_CMD__ESDHC1_CMD		0x400000c0
+				MX25_PAD_SD1_CLK__ESDHC1_CLK		0x400000c0
+				MX25_PAD_SD1_DATA0__ESDHC1_DAT0		0x400000c0
+				MX25_PAD_SD1_DATA1__ESDHC1_DAT1		0x400000c0
+				MX25_PAD_SD1_DATA2__ESDHC1_DAT2		0x400000c0
+				MX25_PAD_SD1_DATA3__ESDHC1_DAT3		0x400000c0
 			>;
 		};
 
diff --git a/arch/arm/boot/dts/imx25-karo-tx25.dts b/arch/arm/boot/dts/imx25-karo-tx25.dts
index 30a62d4..5cb6967 100644
--- a/arch/arm/boot/dts/imx25-karo-tx25.dts
+++ b/arch/arm/boot/dts/imx25-karo-tx25.dts
@@ -36,7 +36,7 @@
 		};
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x02000000 0x90000000 0x02000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx25-pdk.dts b/arch/arm/boot/dts/imx25-pdk.dts
index 2d15ce7..7f9bd05 100644
--- a/arch/arm/boot/dts/imx25-pdk.dts
+++ b/arch/arm/boot/dts/imx25-pdk.dts
@@ -18,7 +18,7 @@
 	model = "Freescale i.MX25 Product Development Kit";
 	compatible = "fsl,imx25-pdk", "fsl,imx25";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x4000000>;
 	};
 
@@ -165,12 +165,12 @@
 
 		pinctrl_esdhc1: esdhc1grp {
 			fsl,pins = <
-				MX25_PAD_SD1_CMD__SD1_CMD		0x80000000
-				MX25_PAD_SD1_CLK__SD1_CLK		0x80000000
-				MX25_PAD_SD1_DATA0__SD1_DATA0		0x80000000
-				MX25_PAD_SD1_DATA1__SD1_DATA1		0x80000000
-				MX25_PAD_SD1_DATA2__SD1_DATA2		0x80000000
-				MX25_PAD_SD1_DATA3__SD1_DATA3		0x80000000
+				MX25_PAD_SD1_CMD__ESDHC1_CMD		0x80000000
+				MX25_PAD_SD1_CLK__ESDHC1_CLK		0x80000000
+				MX25_PAD_SD1_DATA0__ESDHC1_DAT0		0x80000000
+				MX25_PAD_SD1_DATA1__ESDHC1_DAT1		0x80000000
+				MX25_PAD_SD1_DATA2__ESDHC1_DAT2		0x80000000
+				MX25_PAD_SD1_DATA3__ESDHC1_DAT3		0x80000000
 				MX25_PAD_A14__GPIO_2_0			0x80000000
 				MX25_PAD_A15__GPIO_2_1			0x80000000
 			>;
diff --git a/arch/arm/boot/dts/imx25-pinfunc.h b/arch/arm/boot/dts/imx25-pinfunc.h
index 6c63dca..a480706 100644
--- a/arch/arm/boot/dts/imx25-pinfunc.h
+++ b/arch/arm/boot/dts/imx25-pinfunc.h
@@ -151,21 +151,21 @@
 #define MX25_PAD_D15__D15			0x088 0x280 0x000 0x00 0x000
 #define MX25_PAD_D15__LD16			0x088 0x280 0x000 0x01 0x000
 #define MX25_PAD_D15__GPIO_4_5			0x088 0x280 0x000 0x05 0x000
-#define MX25_PAD_D15__SDHC1_DAT7		0x088 0x280 0x4d8 0x06 0x000
+#define MX25_PAD_D15__ESDHC1_DAT7		0x088 0x280 0x4d8 0x06 0x000
 
 #define MX25_PAD_D14__D14			0x08c 0x284 0x000 0x00 0x000
 #define MX25_PAD_D14__LD17			0x08c 0x284 0x000 0x01 0x000
 #define MX25_PAD_D14__GPIO_4_6			0x08c 0x284 0x000 0x05 0x000
-#define MX25_PAD_D14__SDHC1_DAT6		0x08c 0x284 0x4d4 0x06 0x000
+#define MX25_PAD_D14__ESDHC1_DAT6		0x08c 0x284 0x4d4 0x06 0x000
 
 #define MX25_PAD_D13__D13			0x090 0x288 0x000 0x00 0x000
 #define MX25_PAD_D13__LD18			0x090 0x288 0x000 0x01 0x000
 #define MX25_PAD_D13__GPIO_4_7			0x090 0x288 0x000 0x05 0x000
-#define MX25_PAD_D13__SDHC1_DAT5		0x090 0x288 0x4d0 0x06 0x000
+#define MX25_PAD_D13__ESDHC1_DAT5		0x090 0x288 0x4d0 0x06 0x000
 
 #define MX25_PAD_D12__D12			0x094 0x28c 0x000 0x00 0x000
 #define MX25_PAD_D12__GPIO_4_8			0x094 0x28c 0x000 0x05 0x000
-#define MX25_PAD_D12__SDHC1_DAT4		0x094 0x28c 0x4cc 0x06 0x000
+#define MX25_PAD_D12__ESDHC1_DAT4		0x094 0x28c 0x4cc 0x06 0x000
 
 #define MX25_PAD_D11__D11			0x098 0x290 0x000 0x00 0x000
 #define MX25_PAD_D11__GPIO_4_9			0x098 0x290 0x000 0x05 0x000
@@ -236,12 +236,13 @@
 #define MX25_PAD_LD8__LD8			0x0e8 0x2e0 0x000 0x00 0x000
 #define MX25_PAD_LD8__UART4_RXD			0x0e8 0x2e0 0x570 0x02 0x000
 #define MX25_PAD_LD8__FEC_TX_ERR		0x0e8 0x2e0 0x000 0x05 0x000
-#define MX25_PAD_LD8__SDHC2_CMD			0x0e8 0x2e0 0x4e0 0x06 0x000
+/* SION must be set; see the comment for MX25_PAD_SD1_CMD__ESDHC1_CMD. */
+#define MX25_PAD_LD8__ESDHC2_CMD		0x0e8 0x2e0 0x4e0 0x16 0x000
 
 #define MX25_PAD_LD9__LD9			0x0ec 0x2e4 0x000 0x00 0x000
 #define MX25_PAD_LD9__UART4_TXD			0x0ec 0x2e4 0x000 0x02 0x000
 #define MX25_PAD_LD9__FEC_COL			0x0ec 0x2e4 0x504 0x05 0x001
-#define MX25_PAD_LD9__SDHC2_CLK			0x0ec 0x2e4 0x4dc 0x06 0x000
+#define MX25_PAD_LD9__ESDHC2_CLK		0x0ec 0x2e4 0x4dc 0x06 0x000
 
 #define MX25_PAD_LD10__LD10			0x0f0 0x2e8 0x000 0x00 0x000
 #define MX25_PAD_LD10__UART4_RTS		0x0f0 0x2e8 0x56c 0x02 0x000
@@ -250,7 +251,7 @@
 #define MX25_PAD_LD11__LD11			0x0f4 0x2ec 0x000 0x00 0x000
 #define MX25_PAD_LD11__UART4_CTS		0x0f4 0x2ec 0x000 0x02 0x000
 #define MX25_PAD_LD11__FEC_RDATA2		0x0f4 0x2ec 0x50c 0x05 0x001
-#define MX25_PAD_LD11__SDHC2_DAT1		0x0f4 0x2ec 0x4e8 0x06 0x000
+#define MX25_PAD_LD11__ESDHC2_DAT1		0x0f4 0x2ec 0x4e8 0x06 0x000
 
 #define MX25_PAD_LD12__LD12			0x0f8 0x2f0 0x000 0x00 0x000
 #define MX25_PAD_LD12__CSPI2_MOSI		0x0f8 0x2f0 0x4a0 0x02 0x000
@@ -316,12 +317,13 @@
 #define MX25_PAD_CSI_D5__CSPI3_RDY		0x12c 0x324 0x000 0x07 0x000
 
 #define MX25_PAD_CSI_D6__CSI_D6			0x130 0x328 0x000 0x00 0x000
-#define MX25_PAD_CSI_D6__SDHC2_CMD		0x130 0x328 0x4e0 0x02 0x001
+/* SION must be set; see the comment for MX25_PAD_SD1_CMD__ESDHC1_CMD. */
+#define MX25_PAD_CSI_D6__ESDHC2_CMD		0x130 0x328 0x4e0 0x12 0x001
 #define MX25_PAD_CSI_D6__SIM1_PD0		0x130 0x328 0x000 0x04 0x000
 #define MX25_PAD_CSI_D6__GPIO_1_31		0x130 0x328 0x000 0x05 0x000
 
 #define MX25_PAD_CSI_D7__CSI_D7			0x134 0x32c 0x000 0x00 0x000
-#define MX25_PAD_CSI_D7__SDHC2_DAT_CLK		0x134 0x32C 0x4dc 0x02 0x001
+#define MX25_PAD_CSI_D7__ESDHC2_CLK		0x134 0x32C 0x4dc 0x02 0x001
 #define MX25_PAD_CSI_D7__GPIO_1_6		0x134 0x32c 0x000 0x05 0x000
 
 #define MX25_PAD_CSI_D8__CSI_D8			0x138 0x330 0x000 0x00 0x000
@@ -336,22 +338,22 @@
 
 #define MX25_PAD_CSI_MCLK__CSI_MCLK		0x140 0x338 0x000 0x00 0x000
 #define MX25_PAD_CSI_MCLK__AUD6_TXD		0x140 0x338 0x000 0x01 0x000
-#define MX25_PAD_CSI_MCLK__SDHC2_DAT0		0x140 0x338 0x4e4 0x02 0x001
+#define MX25_PAD_CSI_MCLK__ESDHC2_DAT0		0x140 0x338 0x4e4 0x02 0x001
 #define MX25_PAD_CSI_MCLK__GPIO_1_8		0x140 0x338 0x000 0x05 0x000
 
 #define MX25_PAD_CSI_VSYNC__CSI_VSYNC		0x144 0x33c 0x000 0x00 0x000
 #define MX25_PAD_CSI_VSYNC__AUD6_RXD		0x144 0x33c 0x000 0x01 0x000
-#define MX25_PAD_CSI_VSYNC__SDHC2_DAT1		0x144 0x33c 0x4e8 0x02 0x001
+#define MX25_PAD_CSI_VSYNC__ESDHC2_DAT1		0x144 0x33c 0x4e8 0x02 0x001
 #define MX25_PAD_CSI_VSYNC__GPIO_1_9		0x144 0x33c 0x000 0x05 0x000
 
 #define MX25_PAD_CSI_HSYNC__CSI_HSYNC		0x148 0x340 0x000 0x00 0x000
 #define MX25_PAD_CSI_HSYNC__AUD6_TXC		0x148 0x340 0x000 0x01 0x000
-#define MX25_PAD_CSI_HSYNC__SDHC2_DAT2		0x148 0x340 0x4ec 0x02 0x001
+#define MX25_PAD_CSI_HSYNC__ESDHC2_DAT2		0x148 0x340 0x4ec 0x02 0x001
 #define MX25_PAD_CSI_HSYNC__GPIO_1_10		0x148 0x340 0x000 0x05 0x000
 
 #define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK		0x14c 0x344 0x000 0x00 0x000
 #define MX25_PAD_CSI_PIXCLK__AUD6_TXFS		0x14c 0x344 0x000 0x01 0x000
-#define MX25_PAD_CSI_PIXCLK__SDHC2_DAT3		0x14c 0x344 0x4f0 0x02 0x001
+#define MX25_PAD_CSI_PIXCLK__ESDHC2_DAT3	0x14c 0x344 0x4f0 0x02 0x001
 #define MX25_PAD_CSI_PIXCLK__GPIO_1_11		0x14c 0x344 0x000 0x05 0x000
 
 #define MX25_PAD_I2C1_CLK__I2C1_CLK		0x150 0x348 0x000 0x00 0x000
@@ -419,37 +421,37 @@
 #define MX25_PAD_UART2_CTS__GPIO_4_29		0x18c 0x384 0x000 0x05 0x000
 
 /*
- * Removing the SION bit from MX25_PAD_SD1_CMD__SD1_CMD breaks detecting an SD
+ * Removing the SION bit from MX25_PAD_*__ESDHCn_CMD breaks detecting an SD
  * card. According to the i.MX25 reference manual (e.g. Figure 23-2 in IMX25RM
  * Rev. 2 from 01/2011) this pin is bidirectional. So it seems to be a silicon
- * bug that configuring the SD1_CMD function doesn't enable the input path for
- * this pin.
+ * bug that configuring the ESDHCn_CMD function doesn't enable the input path
+ * for this pin.
  * This might have side effects for other hardware units that are connected to
  * that pin and use the respective function as input.
  */
-#define MX25_PAD_SD1_CMD__SD1_CMD		0x190 0x388 0x000 0x10 0x000
+#define MX25_PAD_SD1_CMD__ESDHC1_CMD		0x190 0x388 0x000 0x10 0x000
 #define MX25_PAD_SD1_CMD__CSPI2_MOSI		0x190 0x388 0x4a0 0x01 0x001
 #define MX25_PAD_SD1_CMD__FEC_RDATA2		0x190 0x388 0x50c 0x02 0x002
 #define MX25_PAD_SD1_CMD__GPIO_2_23		0x190 0x388 0x000 0x05 0x000
 
-#define MX25_PAD_SD1_CLK__SD1_CLK		0x194 0x38c 0x000 0x00 0x000
+#define MX25_PAD_SD1_CLK__ESDHC1_CLK		0x194 0x38c 0x000 0x00 0x000
 #define MX25_PAD_SD1_CLK__CSPI2_MISO		0x194 0x38c 0x49c 0x01 0x001
 #define MX25_PAD_SD1_CLK__FEC_RDATA3		0x194 0x38c 0x510 0x02 0x002
 #define MX25_PAD_SD1_CLK__GPIO_2_24		0x194 0x38c 0x000 0x05 0x000
 
-#define MX25_PAD_SD1_DATA0__SD1_DATA0		0x198 0x390 0x000 0x00 0x000
+#define MX25_PAD_SD1_DATA0__ESDHC1_DAT0		0x198 0x390 0x000 0x00 0x000
 #define MX25_PAD_SD1_DATA0__CSPI2_SCLK		0x198 0x390 0x494 0x01 0x001
 #define MX25_PAD_SD1_DATA0__GPIO_2_25		0x198 0x390 0x000 0x05 0x000
 
-#define MX25_PAD_SD1_DATA1__SD1_DATA1		0x19c 0x394 0x000 0x00 0x000
+#define MX25_PAD_SD1_DATA1__ESDHC1_DAT1		0x19c 0x394 0x000 0x00 0x000
 #define MX25_PAD_SD1_DATA1__AUD7_RXD		0x19c 0x394 0x478 0x03 0x000
 #define MX25_PAD_SD1_DATA1__GPIO_2_26		0x19c 0x394 0x000 0x05 0x000
 
-#define MX25_PAD_SD1_DATA2__SD1_DATA2		0x1a0 0x398 0x000 0x00 0x000
+#define MX25_PAD_SD1_DATA2__ESDHC1_DAT2		0x1a0 0x398 0x000 0x00 0x000
 #define MX25_PAD_SD1_DATA2__FEC_RX_CLK		0x1a0 0x398 0x514 0x02 0x002
 #define MX25_PAD_SD1_DATA2__GPIO_2_27		0x1a0 0x398 0x000 0x05 0x000
 
-#define MX25_PAD_SD1_DATA3__SD1_DATA3		0x1a4 0x39c 0x000 0x00 0x000
+#define MX25_PAD_SD1_DATA3__ESDHC1_DAT3		0x1a4 0x39c 0x000 0x00 0x000
 #define MX25_PAD_SD1_DATA3__FEC_CRS		0x1a4 0x39c 0x508 0x02 0x002
 #define MX25_PAD_SD1_DATA3__GPIO_2_28		0x1a4 0x39c 0x000 0x05 0x000
 
@@ -496,6 +498,8 @@
 #define MX25_PAD_KPP_COL3__GPIO_3_4		0x1c4 0x3bc 0x000 0x05 0x000
 
 #define MX25_PAD_FEC_MDC__FEC_MDC		0x1c8 0x3c0 0x000 0x00 0x000
+/* SION must be set; see the comment for MX25_PAD_SD1_CMD__ESDHC1_CMD. */
+#define MX25_PAD_FEC_MDC__ESDHC2_CMD		0x1c8 0x3c0 0x4e0 0x11 0x002
 #define MX25_PAD_FEC_MDC__AUD4_TXD		0x1c8 0x3c0 0x464 0x02 0x001
 #define MX25_PAD_FEC_MDC__GPIO_3_5		0x1c8 0x3c0 0x000 0x05 0x000
 
@@ -601,4 +605,28 @@
 #define MX25_PAD_BOOT_MODE1__BOOT_MODE1		0x228 0x000 0x000 0x00 0x000
 #define MX25_PAD_BOOT_MODE1__GPIO_4_31		0x228 0x000 0x000 0x05 0x000
 
+/*
+ * Compatibility defines for out-of-tree users. You should update if you make
+ * use of one of them.
+ */
+#define MX25_PAD_D15__SDHC1_DAT7		MX25_PAD_D15__ESDHC1_DAT7
+#define MX25_PAD_D14__SDHC1_DAT6		MX25_PAD_D14__ESDHC1_DAT6
+#define MX25_PAD_D13__SDHC1_DAT5		MX25_PAD_D13__ESDHC1_DAT5
+#define MX25_PAD_D12__SDHC1_DAT4		MX25_PAD_D12__ESDHC1_DAT4
+#define MX25_PAD_LD8__SDHC2_CMD			MX25_PAD_LD8__ESDHC2_CMD
+#define MX25_PAD_LD9__SDHC2_CLK			MX25_PAD_LD9__ESDHC2_CLK
+#define MX25_PAD_LD11__SDHC2_DAT1		MX25_PAD_LD11__ESDHC2_DAT1
+#define MX25_PAD_CSI_D6__SDHC2_CMD		MX25_PAD_CSI_D6__ESDHC2_CMD
+#define MX25_PAD_CSI_D7__SDHC2_DAT_CLK		MX25_PAD_CSI_D7__ESDHC2_CLK
+#define MX25_PAD_CSI_MCLK__SDHC2_DAT0		MX25_PAD_CSI_MCLK__ESDHC2_DAT0
+#define MX25_PAD_CSI_VSYNC__SDHC2_DAT1		MX25_PAD_CSI_VSYNC__ESDHC2_DAT1
+#define MX25_PAD_CSI_HSYNC__SDHC2_DAT2		MX25_PAD_CSI_HSYNC__ESDHC2_DAT2
+#define MX25_PAD_CSI_PIXCLK__SDHC2_DAT3		MX25_PAD_CSI_PIXCLK__ESDHC2_DAT3
+#define MX25_PAD_SD1_CMD__SD1_CMD		MX25_PAD_SD1_CMD__ESDHC1_CMD
+#define MX25_PAD_SD1_CLK__SD1_CLK		MX25_PAD_SD1_CLK__ESDHC1_CLK
+#define MX25_PAD_SD1_DATA0__SD1_DATA0		MX25_PAD_SD1_DATA0__ESDHC1_DAT0
+#define MX25_PAD_SD1_DATA1__SD1_DATA1		MX25_PAD_SD1_DATA1__ESDHC1_DAT1
+#define MX25_PAD_SD1_DATA2__SD1_DATA2		MX25_PAD_SD1_DATA2__ESDHC1_DAT2
+#define MX25_PAD_SD1_DATA3__SD1_DATA3		MX25_PAD_SD1_DATA3__ESDHC1_DAT3
+
 #endif /* __DTS_IMX25_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
index 9445f8e..cf70df2 100644
--- a/arch/arm/boot/dts/imx25.dtsi
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -22,7 +22,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec;
@@ -269,6 +269,7 @@
 				dmas = <&sdma 24 1 0>,
 				       <&sdma 25 1 0>;
 				dma-names = "rx", "tx";
+				fsl,fifo-depth = <15>;
 				status = "disabled";
 			};
 
@@ -329,6 +330,7 @@
 				dmas = <&sdma 28 1 0>,
 				       <&sdma 29 1 0>;
 				dma-names = "rx", "tx";
+				fsl,fifo-depth = <15>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx27-apf27.dts b/arch/arm/boot/dts/imx27-apf27.dts
index 73aae4f..66941cd 100644
--- a/arch/arm/boot/dts/imx27-apf27.dts
+++ b/arch/arm/boot/dts/imx27-apf27.dts
@@ -19,7 +19,7 @@
 	model = "Armadeus Systems APF27 module";
 	compatible = "armadeus,imx27-apf27", "fsl,imx27";
 
-	memory {
+	memory@a0000000 {
 		reg = <0xa0000000 0x04000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi b/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi
index 2cf896c..9c455dc 100644
--- a/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi
+++ b/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi
@@ -16,21 +16,14 @@
 	model = "Eukrea CPUIMX27";
 	compatible = "eukrea,cpuimx27", "fsl,imx27";
 
-	memory {
+	memory@a0000000 {
 		reg = <0xa0000000 0x04000000>;
 	};
 
-	clocks {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "simple-bus";
-
-		clk14745600: clock@0 {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <14745600>;
-			reg = <0>;
-		};
+	clk14745600: clk-uart {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <14745600>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts b/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts
index f565357..15145e7 100644
--- a/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts
+++ b/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts
@@ -84,7 +84,7 @@
 	cs-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
 	status = "okay";
 
-	ads7846 {
+	ads7846@0 {
 		compatible = "ti,ads7846";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_touch>;
diff --git a/arch/arm/boot/dts/imx27-pdk.dts b/arch/arm/boot/dts/imx27-pdk.dts
index 2a140c8..924b90c 100644
--- a/arch/arm/boot/dts/imx27-pdk.dts
+++ b/arch/arm/boot/dts/imx27-pdk.dts
@@ -16,7 +16,7 @@
 	model = "Freescale i.MX27 Product Development Kit";
 	compatible = "fsl,imx27-pdk", "fsl,imx27";
 
-	memory {
+	memory@a0000000 {
 		reg = <0xa0000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
index 0b8490b..cbad7c8 100644
--- a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
+++ b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
@@ -17,7 +17,7 @@
 	model = "Phytec pca100";
 	compatible = "phytec,imx27-pca100", "fsl,imx27";
 
-	memory {
+	memory@a0000000 {
 		reg = <0xa0000000 0x08000000>; /* 128MB */
 	};
 };
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
index c9095b7..ec466b4 100644
--- a/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
+++ b/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
@@ -16,7 +16,7 @@
 	model = "Phytec pcm038";
 	compatible = "phytec,imx27-pcm038", "fsl,imx27";
 
-	memory {
+	memory@a0000000 {
 		reg = <0xa0000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
index 15d85f1..6585b00 100644
--- a/arch/arm/boot/dts/imx27.dtsi
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -26,7 +26,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec;
diff --git a/arch/arm/boot/dts/imx28-apf28.dts b/arch/arm/boot/dts/imx28-apf28.dts
index 070e59c..bab7834 100644
--- a/arch/arm/boot/dts/imx28-apf28.dts
+++ b/arch/arm/boot/dts/imx28-apf28.dts
@@ -16,7 +16,7 @@
 	model = "Armadeus Systems APF28 module";
 	compatible = "armadeus,imx28-apf28", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-apx4devkit.dts b/arch/arm/boot/dts/imx28-apx4devkit.dts
index ae07834..96faa53 100644
--- a/arch/arm/boot/dts/imx28-apx4devkit.dts
+++ b/arch/arm/boot/dts/imx28-apx4devkit.dts
@@ -6,7 +6,7 @@
 	model = "Bluegiga APX4 Development Kit";
 	compatible = "bluegiga,apx4devkit", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x04000000>;
 	};
 
@@ -82,7 +82,8 @@
 					fsl,pull-up = <MXS_PULL_ENABLE>;
 				};
 
-				mmc2_sck_cfg_apx4: mmc2-sck-cfg-apx4 {
+				mmc2_sck_cfg_apx4: mmc2-sck-cfg-apx4@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX28_PAD_SSP0_DATA7__SSP2_SCK
 					>;
@@ -146,6 +147,7 @@
 				sgtl5000: codec@a {
 					compatible = "fsl,sgtl5000";
 					reg = <0x0a>;
+					#sound-dai-cells = <0>;
 					VDDA-supply = <&reg_3p3v>;
 					VDDIO-supply = <&reg_3p3v>;
 					clocks = <&saif0>;
diff --git a/arch/arm/boot/dts/imx28-cfa10036.dts b/arch/arm/boot/dts/imx28-cfa10036.dts
index 570aa33..e54f5ab 100644
--- a/arch/arm/boot/dts/imx28-cfa10036.dts
+++ b/arch/arm/boot/dts/imx28-cfa10036.dts
@@ -16,7 +16,7 @@
 	model = "Crystalfontz CFA-10036 Board";
 	compatible = "crystalfontz,cfa10036", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-cfa10049.dts b/arch/arm/boot/dts/imx28-cfa10049.dts
index 4cd52d5..60e5c7f 100644
--- a/arch/arm/boot/dts/imx28-cfa10049.dts
+++ b/arch/arm/boot/dts/imx28-cfa10049.dts
@@ -19,6 +19,71 @@
 	model = "Crystalfontz CFA-10049 Board";
 	compatible = "crystalfontz,cfa10049", "crystalfontz,cfa10036", "fsl,imx28";
 
+	i2cmux {
+		compatible = "i2c-mux-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2cmux_pins_cfa10049>;
+		mux-gpios = <&gpio1 22 0 &gpio1 23 0>;
+		i2c-parent = <&i2c1>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			adc0: nau7802@2a {
+				compatible = "nuvoton,nau7802";
+				reg = <0x2a>;
+				nuvoton,vldo = <3000>;
+			};
+		};
+
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			adc1: nau7802@2a {
+				compatible = "nuvoton,nau7802";
+				reg = <0x2a>;
+				nuvoton,vldo = <3000>;
+			};
+		};
+
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+
+				adc2: nau7802@2a {
+				compatible = "nuvoton,nau7802";
+				reg = <0x2a>;
+				nuvoton,vldo = <3000>;
+			};
+		};
+
+		i2c@3 {
+			reg = <3>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pca9555: pca9555@20 {
+				compatible = "nxp,pca9555";
+				pinctrl-names = "default";
+				pinctrl-0 = <&pca_pins_cfa10049>;
+				interrupt-parent = <&gpio2>;
+				interrupts = <19 0x2>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x20>;
+			};
+		};
+	};
+
 	apb@80000000 {
 		apbh@80000000 {
 			pinctrl@80018000 {
@@ -219,71 +284,6 @@
 				status = "okay";
 			};
 
-			i2cmux {
-				compatible = "i2c-mux-gpio";
-				#address-cells = <1>;
-				#size-cells = <0>;
-				pinctrl-names = "default";
-				pinctrl-0 = <&i2cmux_pins_cfa10049>;
-				mux-gpios = <&gpio1 22 0 &gpio1 23 0>;
-				i2c-parent = <&i2c1>;
-
-				i2c@0 {
-					#address-cells = <1>;
-					#size-cells = <0>;
-					reg = <0>;
-
-					adc0: nau7802@2a {
-						compatible = "nuvoton,nau7802";
-						reg = <0x2a>;
-						nuvoton,vldo = <3000>;
-					};
-				};
-
-				i2c@1 {
-					#address-cells = <1>;
-					#size-cells = <0>;
-					reg = <1>;
-
-					adc1: nau7802@2a {
-						compatible = "nuvoton,nau7802";
-						reg = <0x2a>;
-						nuvoton,vldo = <3000>;
-					};
-				};
-
-				i2c@2 {
-					#address-cells = <1>;
-					#size-cells = <0>;
-					reg = <2>;
-
-					adc2: nau7802@2a {
-						compatible = "nuvoton,nau7802";
-						reg = <0x2a>;
-						nuvoton,vldo = <3000>;
-					};
-				};
-
-				i2c@3 {
-					reg = <3>;
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					pca9555: pca9555@20 {
-						compatible = "nxp,pca9555";
-						pinctrl-names = "default";
-						pinctrl-0 = <&pca_pins_cfa10049>;
-						interrupt-parent = <&gpio2>;
-						interrupts = <19 0x2>;
-						gpio-controller;
-						#gpio-cells = <2>;
-						interrupt-controller;
-						#interrupt-cells = <2>;
-						reg = <0x20>;
-					};
-				};
-			};
-
 			usbphy1: usbphy@8007e000 {
 				status = "okay";
 			};
diff --git a/arch/arm/boot/dts/imx28-duckbill-2-485.dts b/arch/arm/boot/dts/imx28-duckbill-2-485.dts
index bd3fd47..97084e4 100644
--- a/arch/arm/boot/dts/imx28-duckbill-2-485.dts
+++ b/arch/arm/boot/dts/imx28-duckbill-2-485.dts
@@ -19,7 +19,7 @@
 	model = "I2SE Duckbill 2 485";
 	compatible = "i2se,duckbill-2-485", "i2se,duckbill-2", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-duckbill-2-enocean.dts b/arch/arm/boot/dts/imx28-duckbill-2-enocean.dts
index 4450047..7f8d40a 100644
--- a/arch/arm/boot/dts/imx28-duckbill-2-enocean.dts
+++ b/arch/arm/boot/dts/imx28-duckbill-2-enocean.dts
@@ -20,7 +20,7 @@
 	model = "I2SE Duckbill 2 EnOcean";
 	compatible = "i2se,duckbill-2-enocean", "i2se,duckbill-2", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-duckbill-2-spi.dts b/arch/arm/boot/dts/imx28-duckbill-2-spi.dts
index 927732e..13e7b13 100644
--- a/arch/arm/boot/dts/imx28-duckbill-2-spi.dts
+++ b/arch/arm/boot/dts/imx28-duckbill-2-spi.dts
@@ -23,7 +23,7 @@
 		ethernet1 = &qca7000;
 	};
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-duckbill-2.dts b/arch/arm/boot/dts/imx28-duckbill-2.dts
index 7fa3d75..88556c9 100644
--- a/arch/arm/boot/dts/imx28-duckbill-2.dts
+++ b/arch/arm/boot/dts/imx28-duckbill-2.dts
@@ -19,7 +19,7 @@
 	model = "I2SE Duckbill 2";
 	compatible = "i2se,duckbill-2", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-duckbill.dts b/arch/arm/boot/dts/imx28-duckbill.dts
index 3e4385d..f286bfe 100644
--- a/arch/arm/boot/dts/imx28-duckbill.dts
+++ b/arch/arm/boot/dts/imx28-duckbill.dts
@@ -18,7 +18,7 @@
 	model = "I2SE Duckbill";
 	compatible = "i2se,duckbill", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts b/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts
index 7c1572c..b70f334 100644
--- a/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts
+++ b/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts
@@ -23,7 +23,7 @@
 	model = "Eukrea Electromatique MBMX283LC";
 	compatible = "eukrea,mbmx283lc", "eukrea,mbmx28lc", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x04000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts b/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts
index b61fd61..65efb78 100644
--- a/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts
+++ b/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts
@@ -22,7 +22,7 @@
 	model = "Eukrea Electromatique MBMX287LC";
 	compatible = "eukrea,mbmx287lc", "eukrea,mbmx283lc", "eukrea,mbmx28lc", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi
index 49ab408..ff1328c 100644
--- a/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi
+++ b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi
@@ -151,6 +151,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		VDDA-supply = <&reg_3p3v>;
 		VDDIO-supply = <&reg_3p3v>;
 		clocks = <&saif0>;
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
index 7f5b804..b0d3965 100644
--- a/arch/arm/boot/dts/imx28-evk.dts
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -16,7 +16,7 @@
 	model = "Freescale i.MX28 Evaluation Kit";
 	compatible = "fsl,imx28-evk", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
@@ -197,6 +197,7 @@
 				sgtl5000: codec@a {
 					compatible = "fsl,sgtl5000";
 					reg = <0x0a>;
+					#sound-dai-cells = <0>;
 					VDDA-supply = <&reg_3p3v>;
 					VDDIO-supply = <&reg_3p3v>;
 					clocks = <&saif0>;
diff --git a/arch/arm/boot/dts/imx28-m28.dtsi b/arch/arm/boot/dts/imx28-m28.dtsi
index a69856e..0ec415e 100644
--- a/arch/arm/boot/dts/imx28-m28.dtsi
+++ b/arch/arm/boot/dts/imx28-m28.dtsi
@@ -15,7 +15,7 @@
 	model = "Aries/DENX M28";
 	compatible = "aries,m28", "denx,m28", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-m28cu3.dts b/arch/arm/boot/dts/imx28-m28cu3.dts
index 9d6c8fe..3bb5ffc 100644
--- a/arch/arm/boot/dts/imx28-m28cu3.dts
+++ b/arch/arm/boot/dts/imx28-m28cu3.dts
@@ -16,7 +16,7 @@
 	model = "MSR M28CU3";
 	compatible = "msr,m28cu3", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-m28evk.dts b/arch/arm/boot/dts/imx28-m28evk.dts
index 22aa025..7d97a0c 100644
--- a/arch/arm/boot/dts/imx28-m28evk.dts
+++ b/arch/arm/boot/dts/imx28-m28evk.dts
@@ -140,6 +140,7 @@
 				sgtl5000: codec@a {
 					compatible = "fsl,sgtl5000";
 					reg = <0x0a>;
+					#sound-dai-cells = <0>;
 					VDDA-supply = <&reg_3p3v>;
 					VDDIO-supply = <&reg_3p3v>;
 					clocks = <&saif0>;
diff --git a/arch/arm/boot/dts/imx28-sps1.dts b/arch/arm/boot/dts/imx28-sps1.dts
index 0ce3cb8..2393e839 100644
--- a/arch/arm/boot/dts/imx28-sps1.dts
+++ b/arch/arm/boot/dts/imx28-sps1.dts
@@ -16,7 +16,7 @@
 	model = "SchulerControl GmbH, SC SPS 1";
 	compatible = "schulercontrol,imx28-sps1", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x08000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx28-ts4600.dts b/arch/arm/boot/dts/imx28-ts4600.dts
index 1e391c9..f8a09a8 100644
--- a/arch/arm/boot/dts/imx28-ts4600.dts
+++ b/arch/arm/boot/dts/imx28-ts4600.dts
@@ -19,7 +19,7 @@
 	model = "Technologic Systems i.MX28 TS-4600";
 	compatible = "technologic,imx28-ts4600", "fsl,imx28";
 
-	memory {
+	memory@40000000 {
 		reg = <0x40000000 0x10000000>;   /* 256MB */
 	};
 
diff --git a/arch/arm/boot/dts/imx28-tx28.dts b/arch/arm/boot/dts/imx28-tx28.dts
index 152621e..6871863 100644
--- a/arch/arm/boot/dts/imx28-tx28.dts
+++ b/arch/arm/boot/dts/imx28-tx28.dts
@@ -65,8 +65,8 @@
 		usbotg = &usb0;
 	};
 
-	memory {
-		reg = <0 0>; /* will be filled in by U-Boot */
+	memory@40000000 {
+		reg = <0x40000000 0>; /* will be filled in by U-Boot */
 	};
 
 	onewire {
@@ -531,7 +531,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_edt_ft5x06_pins: tx28-edt-ft5x06-pins {
+	tx28_edt_ft5x06_pins: tx28-edt-ft5x06-pins@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_SSP0_DATA6__GPIO_2_6 /* RESET */
 			MX28_PAD_SSP0_DATA5__GPIO_2_5 /* IRQ */
@@ -542,7 +543,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_flexcan_xcvr_pins: tx28-flexcan-xcvr-pins {
+	tx28_flexcan_xcvr_pins: tx28-flexcan-xcvr-pins@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_LCD_D00__GPIO_1_0
 		>;
@@ -551,7 +553,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_lcdif_23bit_pins: tx28-lcdif-23bit {
+	tx28_lcdif_23bit_pins: tx28-lcdif-23bit@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			/* LCD_D00 may be used as Flexcan Transceiver Enable on STK5-V5 */
 			MX28_PAD_LCD_D01__LCD_D1
@@ -583,7 +586,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_lcdif_ctrl_pins: tx28-lcdif-ctrl {
+	tx28_lcdif_ctrl_pins: tx28-lcdif-ctrl@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_LCD_ENABLE__GPIO_1_31 /* Enable */
 			MX28_PAD_LCD_RESET__GPIO_3_30  /* Reset */
@@ -593,7 +597,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_mac0_pins_gpio: tx28-mac0-gpio-pins {
+	tx28_mac0_pins_gpio: tx28-mac0-gpio-pins@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_ENET0_MDC__GPIO_4_0
 			MX28_PAD_ENET0_MDIO__GPIO_4_1
@@ -610,7 +615,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_pca9554_pins: tx28-pca9554-pins {
+	tx28_pca9554_pins: tx28-pca9554-pins@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_PWM3__GPIO_3_28
 		>;
@@ -619,7 +625,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_spi_gpio_pins: spi-gpiogrp {
+	tx28_spi_gpio_pins: spi-gpiogrp@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_AUART2_RX__GPIO_3_8
 			MX28_PAD_AUART2_TX__GPIO_3_9
@@ -633,7 +640,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_tsc2007_pins: tx28-tsc2007-pins {
+	tx28_tsc2007_pins: tx28-tsc2007-pins@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_SAIF0_MCLK__GPIO_3_20 /* TSC2007 IRQ */
 		>;
@@ -643,7 +651,8 @@
 	};
 
 
-	tx28_usbphy0_pins: tx28-usbphy0-pins {
+	tx28_usbphy0_pins: tx28-usbphy0-pins@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_GPMI_CE2N__GPIO_0_18 /* USBOTG_VBUSEN */
 			MX28_PAD_GPMI_CE3N__GPIO_0_19 /* USBOTH_OC */
@@ -653,7 +662,8 @@
 		fsl,pull-up = <MXS_PULL_DISABLE>;
 	};
 
-	tx28_usbphy1_pins: tx28-usbphy1-pins {
+	tx28_usbphy1_pins: tx28-usbphy1-pins@0 {
+		reg = <0>;
 		fsl,pinmux-ids = <
 			MX28_PAD_SPDIF__GPIO_3_27 /* USBH_VBUSEN */
 			MX28_PAD_JTAG_RTCK__GPIO_4_20 /* USBH_OC */
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index e52e05c..9ad8d35 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -24,7 +24,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &mac0;
@@ -283,7 +283,8 @@
 					fsl,pull-up = <MXS_PULL_DISABLE>;
 				};
 
-				gpmi_status_cfg: gpmi-status-cfg {
+				gpmi_status_cfg: gpmi-status-cfg@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX28_PAD_GPMI_RDN__GPMI_RDN
 						MX28_PAD_GPMI_WRN__GPMI_WRN
@@ -527,14 +528,16 @@
 					fsl,pull-up = <MXS_PULL_ENABLE>;
 				};
 
-				mmc0_cd_cfg: mmc0-cd-cfg {
+				mmc0_cd_cfg: mmc0-cd-cfg@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
 					>;
 					fsl,pull-up = <MXS_PULL_DISABLE>;
 				};
 
-				mmc0_sck_cfg: mmc0-sck-cfg {
+				mmc0_sck_cfg: mmc0-sck-cfg@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX28_PAD_SSP0_SCK__SSP0_SCK
 					>;
@@ -558,14 +561,16 @@
 					fsl,pull-up = <MXS_PULL_ENABLE>;
 				};
 
-				mmc1_cd_cfg: mmc1-cd-cfg {
+				mmc1_cd_cfg: mmc1-cd-cfg@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT
 					>;
 					fsl,pull-up = <MXS_PULL_DISABLE>;
 				};
 
-				mmc1_sck_cfg: mmc1-sck-cfg {
+				mmc1_sck_cfg: mmc1-sck-cfg@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX28_PAD_GPMI_WRN__SSP1_SCK
 					>;
@@ -606,7 +611,8 @@
 					fsl,pull-up = <MXS_PULL_ENABLE>;
 				};
 
-				mmc2_cd_cfg: mmc2-cd-cfg {
+				mmc2_cd_cfg: mmc2-cd-cfg@0 {
+					reg = <0>;
 					fsl,pinmux-ids = <
 						MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
 					>;
diff --git a/arch/arm/boot/dts/imx31-bug.dts b/arch/arm/boot/dts/imx31-bug.dts
index ae6cebb..6ee4ff8 100644
--- a/arch/arm/boot/dts/imx31-bug.dts
+++ b/arch/arm/boot/dts/imx31-bug.dts
@@ -16,7 +16,7 @@
 	model = "Buglabs i.MX31 Bug 1.x";
 	compatible = "buglabs,imx31-bug", "fsl,imx31";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x8000000>; /* 128M */
 	};
 };
diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi
index a720314..ebc3f2d 100644
--- a/arch/arm/boot/dts/imx31.dtsi
+++ b/arch/arm/boot/dts/imx31.dtsi
@@ -19,7 +19,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		serial0 = &uart1;
diff --git a/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi b/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi
index 9c2b715..ba39d93 100644
--- a/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi
+++ b/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi
@@ -17,7 +17,7 @@
 	model = "Eukrea CPUIMX35";
 	compatible = "eukrea,cpuimx35", "fsl,imx35";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x8000000>; /* 128M */
 	};
 };
diff --git a/arch/arm/boot/dts/imx35-pdk.dts b/arch/arm/boot/dts/imx35-pdk.dts
index 9bb628f..646b125 100644
--- a/arch/arm/boot/dts/imx35-pdk.dts
+++ b/arch/arm/boot/dts/imx35-pdk.dts
@@ -17,7 +17,7 @@
 	model = "Freescale i.MX35 Product Development Kit";
 	compatible = "fsl,imx35-pdk", "fsl,imx35";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x8000000>,
 		      <0x90000000 0x8000000>;
 	};
diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi
index e08c0c1..bf343195 100644
--- a/arch/arm/boot/dts/imx35.dtsi
+++ b/arch/arm/boot/dts/imx35.dtsi
@@ -20,7 +20,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec;
diff --git a/arch/arm/boot/dts/imx50-evk.dts b/arch/arm/boot/dts/imx50-evk.dts
index 98b5faa..23f1833 100644
--- a/arch/arm/boot/dts/imx50-evk.dts
+++ b/arch/arm/boot/dts/imx50-evk.dts
@@ -18,7 +18,7 @@
 	model = "Freescale i.MX50 Evaluation Kit";
 	compatible = "fsl,imx50-evk", "fsl,imx50";
 
-	memory {
+	memory@70000000 {
 		reg = <0x70000000 0x80000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
index 35955e6..7954e79 100644
--- a/arch/arm/boot/dts/imx50.dtsi
+++ b/arch/arm/boot/dts/imx50.dtsi
@@ -25,7 +25,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec;
diff --git a/arch/arm/boot/dts/imx51-apf51.dts b/arch/arm/boot/dts/imx51-apf51.dts
index c83ac16..79d8003 100644
--- a/arch/arm/boot/dts/imx51-apf51.dts
+++ b/arch/arm/boot/dts/imx51-apf51.dts
@@ -21,7 +21,7 @@
 	model = "Armadeus Systems APF51 module";
 	compatible = "armadeus,imx51-apf51", "fsl,imx51";
 
-	memory {
+	memory@90000000 {
 		reg = <0x90000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
index 4ac5ab6..cf7a196 100644
--- a/arch/arm/boot/dts/imx51-babbage.dts
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -21,7 +21,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@90000000 {
 		reg = <0x90000000 0x20000000>;
 	};
 
@@ -369,6 +369,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		clocks = <&clk_audio>;
 		VDDA-supply = <&vdig_reg>;
 		VDDIO-supply = <&vvideo_reg>;
diff --git a/arch/arm/boot/dts/imx51-digi-connectcore-jsk.dts b/arch/arm/boot/dts/imx51-digi-connectcore-jsk.dts
index 1db517d..2967a74 100644
--- a/arch/arm/boot/dts/imx51-digi-connectcore-jsk.dts
+++ b/arch/arm/boot/dts/imx51-digi-connectcore-jsk.dts
@@ -17,7 +17,7 @@
 		     "digi,connectcore-ccxmx51-som", "fsl,imx51";
 
 	chosen {
-		linux,stdout-path = &uart1;
+		stdout-path = &uart1;
 	};
 };
 
diff --git a/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi b/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi
index b821066..5761a66 100644
--- a/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi
+++ b/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi
@@ -16,7 +16,7 @@
 	model = "Digi ConnectCore CC(W)-MX51";
 	compatible = "digi,connectcore-ccxmx51-som", "fsl,imx51";
 
-	memory {
+	memory@90000000 {
 		reg = <0x90000000 0x08000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi b/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
index 6316426..f8902a3 100644
--- a/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
+++ b/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
@@ -22,7 +22,7 @@
 	model = "Eukrea CPUIMX51";
 	compatible = "eukrea,cpuimx51", "fsl,imx51";
 
-	memory {
+	memory@90000000 {
 		reg = <0x90000000 0x10000000>; /* 256M */
 	};
 };
diff --git a/arch/arm/boot/dts/imx51-ts4800.dts b/arch/arm/boot/dts/imx51-ts4800.dts
index f59b02b..39eb067 100644
--- a/arch/arm/boot/dts/imx51-ts4800.dts
+++ b/arch/arm/boot/dts/imx51-ts4800.dts
@@ -17,7 +17,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@90000000 {
 		reg = <0x90000000 0x10000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 5306b78..0c99ac0 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -51,6 +51,11 @@
 		stdout-path = &uart1;
 	};
 
+	/* Will be filled by the bootloader */
+	memory@90000000 {
+		reg = <0x90000000 0>;
+	};
+
 	aliases {
 		mdio-gpio0 = &mdio_gpio;
 		rtc0 = &ds1341;
@@ -568,6 +573,15 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart3>;
 	status = "okay";
+
+	rave-sp {
+		compatible = "zii,rave-sp-rdu1";
+		current-speed = <38400>;
+
+		watchdog {
+			compatible = "zii,rave-sp-watchdog";
+		};
+	};
 };
 
 &usbh1 {
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 00d30bd..5d390a6 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -26,7 +26,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec;
diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts
index 4486bc4..80fc007 100644
--- a/arch/arm/boot/dts/imx53-ard.dts
+++ b/arch/arm/boot/dts/imx53-ard.dts
@@ -17,7 +17,7 @@
 	model = "Freescale i.MX53 Automotive Reference Design Board";
 	compatible = "fsl,imx53-ard", "fsl,imx53";
 
-	memory {
+	memory@70000000 {
 		reg = <0x70000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx53-cx9020.dts b/arch/arm/boot/dts/imx53-cx9020.dts
index 5e67e43..cf70ebc 100644
--- a/arch/arm/boot/dts/imx53-cx9020.dts
+++ b/arch/arm/boot/dts/imx53-cx9020.dts
@@ -21,7 +21,7 @@
 		stdout-path = &uart2;
 	};
 
-	memory {
+	memory@70000000 {
 		reg = <0x70000000 0x20000000>,
 		      <0xb0000000 0x20000000>;
 	};
diff --git a/arch/arm/boot/dts/imx53-m53.dtsi b/arch/arm/boot/dts/imx53-m53.dtsi
index 7ce69c6..3da6dd5 100644
--- a/arch/arm/boot/dts/imx53-m53.dtsi
+++ b/arch/arm/boot/dts/imx53-m53.dtsi
@@ -15,7 +15,7 @@
 	model = "Aries/DENX M53";
 	compatible = "aries,imx53-m53", "denx,imx53-m53", "fsl,imx53";
 
-	memory {
+	memory@70000000 {
 		reg = <0x70000000 0x20000000>,
 		      <0xb0000000 0x20000000>;
 	};
diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts
index e485257..3935fe6 100644
--- a/arch/arm/boot/dts/imx53-m53evk.dts
+++ b/arch/arm/boot/dts/imx53-m53evk.dts
@@ -153,6 +153,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		VDDA-supply = <&reg_3p2v>;
 		VDDIO-supply = <&reg_3p2v>;
 		clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
diff --git a/arch/arm/boot/dts/imx53-ppd.dts b/arch/arm/boot/dts/imx53-ppd.dts
index cce9594..d5628af 100644
--- a/arch/arm/boot/dts/imx53-ppd.dts
+++ b/arch/arm/boot/dts/imx53-ppd.dts
@@ -132,6 +132,14 @@
 		enable-active-high;
 	};
 
+	reg_tsiref: regulator-tsiref {
+		compatible = "regulator-fixed";
+		regulator-name = "tsiref";
+		regulator-min-microvolt = <2500000>;
+		regulator-max-microvolt = <2500000>;
+		regulator-always-on;
+	};
+
 	pwm_bl: backlight {
 		compatible = "pwm-backlight";
 		pwms = <&pwm2 0 50000>;
@@ -294,6 +302,8 @@
 		interrupt-parent = <&gpio3>;
 		interrupts = <12 0x8>;
 		spi-max-frequency = <1000000>;
+		dlg,tsi-as-adc;
+		tsiref-supply = <&reg_tsiref>;
 
 		regulators {
 			buck1_reg: buck1 {
@@ -436,6 +446,7 @@
 			sgtl5000: codec@a {
 				compatible = "fsl,sgtl5000";
 				reg = <0xa>;
+				#sound-dai-cells = <0>;
 				VDDA-supply = <&reg_sgtl5k>;
 				VDDIO-supply = <&reg_sgtl5k>;
 				clocks = <&cko2_11M>;
@@ -525,6 +536,7 @@
 
 	touchscreen@4b {
 		compatible = "atmel,maxtouch";
+		reset-gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
 		reg = <0x4b>;
 		interrupt-parent = <&gpio5>;
 		interrupts = <4 0x8>;
diff --git a/arch/arm/boot/dts/imx53-qsb-common.dtsi b/arch/arm/boot/dts/imx53-qsb-common.dtsi
index 41a2e2a..485a69d 100644
--- a/arch/arm/boot/dts/imx53-qsb-common.dtsi
+++ b/arch/arm/boot/dts/imx53-qsb-common.dtsi
@@ -17,7 +17,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@70000000 {
 		reg = <0x70000000 0x20000000>,
 		      <0xb0000000 0x20000000>;
 	};
@@ -317,6 +317,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		VDDA-supply = <&reg_3p2v>;
 		VDDIO-supply = <&reg_3p2v>;
 		clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts
index 51f4a42..fd03012 100644
--- a/arch/arm/boot/dts/imx53-smd.dts
+++ b/arch/arm/boot/dts/imx53-smd.dts
@@ -17,7 +17,7 @@
 	model = "Freescale i.MX53 Smart Mobile Reference Design Board";
 	compatible = "fsl,imx53-smd", "fsl,imx53";
 
-	memory {
+	memory@70000000 {
 		reg = <0x70000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx53-tqma53.dtsi b/arch/arm/boot/dts/imx53-tqma53.dtsi
index eecdc1c..a72b898 100644
--- a/arch/arm/boot/dts/imx53-tqma53.dtsi
+++ b/arch/arm/boot/dts/imx53-tqma53.dtsi
@@ -16,7 +16,7 @@
 	model = "TQ TQMa53";
 	compatible = "tq,tqma53", "fsl,imx53";
 
-	memory {
+	memory@70000000 {
 		reg = <0x70000000 0x40000000>; /* Up to 1GiB */
 	};
 
diff --git a/arch/arm/boot/dts/imx53-tx53-x03x.dts b/arch/arm/boot/dts/imx53-tx53-x03x.dts
index fe15c95..af8ec5e 100644
--- a/arch/arm/boot/dts/imx53-tx53-x03x.dts
+++ b/arch/arm/boot/dts/imx53-tx53-x03x.dts
@@ -230,6 +230,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		VDDA-supply = <&reg_2v5>;
 		VDDIO-supply = <&reg_3v3>;
 		clocks = <&mclk>;
diff --git a/arch/arm/boot/dts/imx53-tx53-x13x.dts b/arch/arm/boot/dts/imx53-tx53-x13x.dts
index f2b2ad3..6cdf208 100644
--- a/arch/arm/boot/dts/imx53-tx53-x13x.dts
+++ b/arch/arm/boot/dts/imx53-tx53-x13x.dts
@@ -131,6 +131,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		VDDA-supply = <&reg_2v5>;
 		VDDIO-supply = <&reg_3v3>;
 		clocks = <&mclk>;
diff --git a/arch/arm/boot/dts/imx53-tx53.dtsi b/arch/arm/boot/dts/imx53-tx53.dtsi
index a22e461..69a2af7 100644
--- a/arch/arm/boot/dts/imx53-tx53.dtsi
+++ b/arch/arm/boot/dts/imx53-tx53.dtsi
@@ -49,6 +49,11 @@
 	model = "Ka-Ro electronics TX53 module";
 	compatible = "karo,tx53", "fsl,imx53";
 
+	/* Will be filled by the bootloader */
+	memory@70000000 {
+		reg = <0x70000000 0>;
+	};
+
 	aliases {
 		can0 = &can2; /* Make the can interface indices consistent with TX28/TX48 modules */
 		can1 = &can1;
diff --git a/arch/arm/boot/dts/imx53-usbarmory.dts b/arch/arm/boot/dts/imx53-usbarmory.dts
index 6782d7f..f6268d0 100644
--- a/arch/arm/boot/dts/imx53-usbarmory.dts
+++ b/arch/arm/boot/dts/imx53-usbarmory.dts
@@ -57,7 +57,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@70000000 {
 		reg = <0x70000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx53-voipac-bsb.dts b/arch/arm/boot/dts/imx53-voipac-bsb.dts
index 25c78f1..9570537 100644
--- a/arch/arm/boot/dts/imx53-voipac-bsb.dts
+++ b/arch/arm/boot/dts/imx53-voipac-bsb.dts
@@ -133,6 +133,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		VDDA-supply = <&reg_3p3v>;
 		VDDIO-supply = <&reg_3p3v>;
 		clocks = <&clks 150>;
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 1040251..7d647d0 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -26,7 +26,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec;
diff --git a/arch/arm/boot/dts/imx6dl-apf6dev.dts b/arch/arm/boot/dts/imx6dl-apf6dev.dts
index df26e54..4a7f86d 100644
--- a/arch/arm/boot/dts/imx6dl-apf6dev.dts
+++ b/arch/arm/boot/dts/imx6dl-apf6dev.dts
@@ -54,7 +54,7 @@
 	model = "Armadeus APF6 Solo Module on APF6Dev Board";
 	compatible = "armadeus,imx6dl-apf6dev", "armadeus,imx6dl-apf6", "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6dl-aristainetos2_4.dts b/arch/arm/boot/dts/imx6dl-aristainetos2_4.dts
index 5f0d196..7128c76 100644
--- a/arch/arm/boot/dts/imx6dl-aristainetos2_4.dts
+++ b/arch/arm/boot/dts/imx6dl-aristainetos2_4.dts
@@ -48,7 +48,7 @@
 	model = "aristainetos2 i.MX6 Dual Lite Board 4";
 	compatible = "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6dl-aristainetos2_7.dts b/arch/arm/boot/dts/imx6dl-aristainetos2_7.dts
index 805b131..240f366 100644
--- a/arch/arm/boot/dts/imx6dl-aristainetos2_7.dts
+++ b/arch/arm/boot/dts/imx6dl-aristainetos2_7.dts
@@ -48,7 +48,7 @@
 	model = "aristainetos2 i.MX6 Dual Lite Board 7";
 	compatible = "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts
index 3c9f4af..ad77336 100644
--- a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts
+++ b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts
@@ -27,7 +27,7 @@
 		status = "okay";
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_7.dts b/arch/arm/boot/dts/imx6dl-aristainetos_7.dts
index 96cd835..64ed84e 100644
--- a/arch/arm/boot/dts/imx6dl-aristainetos_7.dts
+++ b/arch/arm/boot/dts/imx6dl-aristainetos_7.dts
@@ -16,7 +16,7 @@
 	model = "aristainetos i.MX6 Dual Lite Board 7";
 	compatible = "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
index dcf9206..ea184d1 100644
--- a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -53,6 +53,11 @@
 	compatible = "toradex,colibri_imx6dl-eval-v3", "toradex,colibri_imx6dl",
 		     "fsl,imx6dl";
 
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
+
 	aliases {
 		i2c0 = &i2c2;
 		i2c1 = &i2c3;
@@ -63,6 +68,10 @@
 		rtc1 = &snvs_rtc;
 	};
 
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
 	clocks {
 		/* Fixed crystal dedicated to mcp251x */
 		clk16m: clk@1 {
diff --git a/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts b/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
index 994f96a..89384cb 100644
--- a/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
+++ b/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
@@ -20,4 +20,9 @@
 / {
 	model = "DFI FS700-M60-6DL i.MX6dl Q7 Board";
 	compatible = "dfi,fs700-m60-6dl", "dfi,fs700e-m60", "fsl,imx6dl";
+
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
 };
diff --git a/arch/arm/boot/dts/imx6dl-phytec-mira-rdk-nand.dts b/arch/arm/boot/dts/imx6dl-phytec-mira-rdk-nand.dts
new file mode 100644
index 0000000..9f7f9f9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-phytec-mira-rdk-nand.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
+
+/ {
+	model = "PHYTEC phyBOARD-Mira DualLite/Solo Carrier-Board with NAND";
+	compatible = "phytec,imx6dl-pbac06-nand", "phytec,imx6dl-pbac06",
+		     "phytec,imx6qdl-pcm058", "fsl,imx6dl";
+
+	chosen {
+		stdout-path = &uart2;
+	};
+};
+
+&ethphy {
+	max-speed = <100>;
+};
+
+&fec {
+	status = "okay";
+};
+
+&gpmi {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c_rtc {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
+&usbotg {
+	status = "okay";
+};
+
+&usdhc1 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi
index 964bc2a..7d98889 100644
--- a/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi
+++ b/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi
@@ -16,7 +16,7 @@
 	model = "Phytec phyFLEX-i.MX6 DualLite/Solo";
 	compatible = "phytec,imx6dl-pfla02", "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6dl-rex-basic.dts b/arch/arm/boot/dts/imx6dl-rex-basic.dts
index c3a14a4..3fb7f4e 100644
--- a/arch/arm/boot/dts/imx6dl-rex-basic.dts
+++ b/arch/arm/boot/dts/imx6dl-rex-basic.dts
@@ -16,7 +16,7 @@
 	model = "Rex Basic i.MX6 Dual Lite Board";
 	compatible = "rex,imx6dl-rex-basic", "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts
index 23e1082..2e98c92 100644
--- a/arch/arm/boot/dts/imx6dl-riotboard.dts
+++ b/arch/arm/boot/dts/imx6dl-riotboard.dts
@@ -15,7 +15,7 @@
 	model = "RIoTboard i.MX6S";
 	compatible = "riot,imx6s-riotboard", "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6dl-ts4900.dts b/arch/arm/boot/dts/imx6dl-ts4900.dts
index 6ea0b78..cc01a7a 100644
--- a/arch/arm/boot/dts/imx6dl-ts4900.dts
+++ b/arch/arm/boot/dts/imx6dl-ts4900.dts
@@ -46,4 +46,9 @@
 / {
 	model = "Technologic Systems i.MX6 Solo/DualLite TS-4900 (Default Device Tree)";
 	compatible = "technologic,imx6dl-ts4900", "fsl,imx6dl";
+
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
 };
diff --git a/arch/arm/boot/dts/imx6dl-ts7970.dts b/arch/arm/boot/dts/imx6dl-ts7970.dts
index d104daf..82435d5 100644
--- a/arch/arm/boot/dts/imx6dl-ts7970.dts
+++ b/arch/arm/boot/dts/imx6dl-ts7970.dts
@@ -47,4 +47,9 @@
 / {
 	model = "Technologic Systems i.MX6 Solo/DualLite TS-7970 (Default Device Tree)";
 	compatible = "technologic,imx6dl-ts7970", "fsl,imx6dl";
+
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
 };
diff --git a/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts b/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts
index 8c314ee..5727fa4 100644
--- a/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts
+++ b/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts
@@ -16,7 +16,7 @@
 	model = "Wandboard i.MX6 Dual Lite Board rev B1";
 	compatible = "wand,imx6dl-wandboard", "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6dl-wandboard-revd1.dts b/arch/arm/boot/dts/imx6dl-wandboard-revd1.dts
index aa4d4fa..a72c07d 100644
--- a/arch/arm/boot/dts/imx6dl-wandboard-revd1.dts
+++ b/arch/arm/boot/dts/imx6dl-wandboard-revd1.dts
@@ -16,7 +16,7 @@
 	model = "Wandboard i.MX6 Dual Lite Board revD1";
 	compatible = "wand,imx6dl-wandboard", "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6dl-wandboard.dts b/arch/arm/boot/dts/imx6dl-wandboard.dts
index bbb6167..a09f274 100644
--- a/arch/arm/boot/dts/imx6dl-wandboard.dts
+++ b/arch/arm/boot/dts/imx6dl-wandboard.dts
@@ -16,7 +16,7 @@
 	model = "Wandboard i.MX6 Dual Lite Board";
 	compatible = "wand,imx6dl-wandboard", "fsl,imx6dl";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
index c01674f..558bce8 100644
--- a/arch/arm/boot/dts/imx6dl.dtsi
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -80,11 +80,6 @@
 				reg = <0x020f4000 0x4000>;
 				interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
 			};
-
-			lcdif: lcdif@20f8000 {
-				reg = <0x020f8000 0x4000>;
-				interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
-			};
 		};
 
 		aips2: aips-bus@2100000 {
@@ -109,11 +104,6 @@
 		compatible = "fsl,imx-display-subsystem";
 		ports = <&ipu1_di0>, <&ipu1_di1>;
 	};
-
-	gpu-subsystem {
-		compatible = "fsl,imx-gpu-subsystem";
-		cores = <&gpu_2d>, <&gpu_3d>;
-	};
 };
 
 &gpio1 {
diff --git a/arch/arm/boot/dts/imx6q-apf6dev.dts b/arch/arm/boot/dts/imx6q-apf6dev.dts
index 4e4de82..5e72f81 100644
--- a/arch/arm/boot/dts/imx6q-apf6dev.dts
+++ b/arch/arm/boot/dts/imx6q-apf6dev.dts
@@ -54,7 +54,7 @@
 	model = "Armadeus APF6 Quad / Dual Module on APF6Dev Board";
 	compatible = "armadeus,imx6q-apf6dev", "armadeus,imx6q-apf6", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts
index 4989d0b..953a5b5 100644
--- a/arch/arm/boot/dts/imx6q-arm2.dts
+++ b/arch/arm/boot/dts/imx6q-arm2.dts
@@ -18,7 +18,7 @@
 	model = "Freescale i.MX6 Quad Armadillo2 Board";
 	compatible = "fsl,imx6q-arm2", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-ba16.dtsi b/arch/arm/boot/dts/imx6q-ba16.dtsi
index 5fcb037..bf4bdb3 100644
--- a/arch/arm/boot/dts/imx6q-ba16.dtsi
+++ b/arch/arm/boot/dts/imx6q-ba16.dtsi
@@ -46,7 +46,7 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi
index 916ea94..990e411 100644
--- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi
+++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi
@@ -353,6 +353,14 @@
 	};
 };
 
+&pmu {
+	secure-reg-access;
+};
+
+&usdhc2 {
+	status = "disabled";
+};
+
 &usdhc4 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usdhc4>;
diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts
index bc7587c..65ef4ca 100644
--- a/arch/arm/boot/dts/imx6q-cm-fx6.dts
+++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts
@@ -50,7 +50,7 @@
 	model = "CompuLab CM-FX6";
 	compatible = "compulab,cm-fx6", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts b/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
index fd0ad9a..ad12d76 100644
--- a/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
+++ b/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
@@ -20,4 +20,9 @@
 / {
 	model = "DFI FS700-M60-6QD i.MX6qd Q7 Board";
 	compatible = "dfi,fs700-m60-6qd", "dfi,fs700e-m60", "fsl,imx6q";
+
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
 };
diff --git a/arch/arm/boot/dts/imx6q-display5.dtsi b/arch/arm/boot/dts/imx6q-display5.dtsi
index 09085fd..85232c7 100644
--- a/arch/arm/boot/dts/imx6q-display5.dtsi
+++ b/arch/arm/boot/dts/imx6q-display5.dtsi
@@ -47,7 +47,7 @@
 	model = "Liebherr (LWN) display5 i.MX6 Quad Board";
 	compatible = "lwn,display5", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
index f0316ea..b3c6a4a 100644
--- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
+++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
@@ -29,7 +29,7 @@
 		stmpe-i2c1 = &stmpe2;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-dms-ba16.dts b/arch/arm/boot/dts/imx6q-dms-ba16.dts
new file mode 100644
index 0000000..57761f3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-dms-ba16.dts
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "imx6q-ba16.dtsi"
+
+/ {
+	model = "Advantech DMS-BA16";
+	compatible = "advantech,imx6q-dms-ba16", "advantech,imx6q-ba16", "fsl,imx6q";
+
+	reg_usb_otg_vbus: regulator-usbotgvbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_otg_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usbotgvbus>;
+		gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	sys_mclk: clock-sys-mclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <22000000>;
+	};
+
+	sound {
+		compatible = "fsl,imx6q-ba16-sgtl5000",
+			     "fsl,imx-audio-sgtl5000";
+		model = "imx6q-ba16-sgtl5000";
+		ssi-controller = <&ssi1>;
+		audio-codec = <&sgtl5000>;
+		audio-routing =
+			"MIC_IN", "Mic Jack",
+			"Mic Jack", "Mic Bias",
+			"Headphone Jack", "HP_OUT";
+		mux-int-port = <1>;
+		mux-ext-port = <4>;
+	};
+};
+
+&ecspi5 {
+	cs-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi5>;
+	status = "okay";
+
+	m25_eeprom: m25p80@0 {
+		compatible = "atmel,at25256B", "atmel,at25";
+		spi-max-frequency = <20000000>;
+		size = <0x8000>;
+		pagesize = <64>;
+		reg = <0>;
+		address-width = <16>;
+	};
+};
+
+&iomuxc {
+	pinctrl_i2c1_gpio: i2c1gpiogrp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26        0x1b0b0
+			MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27        0x1b0b0
+		>;
+	};
+
+	pinctrl_i2c2_gpio: i2c2gpiogrp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x1b0b0
+			MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x1b0b0
+		>;
+	};
+
+	pinctrl_i2c3_gpio: i2c3gpiogrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_3__GPIO1_IO03   0x1b0b0
+			MX6QDL_PAD_GPIO_6__GPIO1_IO06   0x1b0b0
+		>;
+	};
+
+	pinctrl_usbotgvbus: usbotgvbusgrp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
+			MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x000b0
+		>;
+	};
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	sgtl5000: codec@a {
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		clocks = <&sys_mclk>;
+		lrclk-strength = <0x3>;
+		VDDA-supply = <&reg_1p8v>;
+		VDDIO-supply = <&reg_3p3v>;
+	};
+};
+
+&pwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm2>;
+	status = "okay";
+};
+
+&sata {
+	fsl,no-spread-spectrum;
+	fsl,transmit-atten-16ths = <12>;
+	fsl,transmit-boost-mdB = <3330>;
+	fsl,transmit-level-mV = <1133>;
+	fsl,receive-dpll-mode = <1>;
+	status = "okay";
+};
+
+&usbotg {
+	vbus-supply = <&reg_usb_otg_vbus>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg>;
+	dr_mode = "otg";
+	disable-over-current;
+	status = "okay";
+};
+
+&usdhc4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	bus-width = <8>;
+	cd-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
+	no-1-8-v;
+	keep-power-in-suspend;
+	wakeup-source;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts
index e0aea78..fcd257b 100644
--- a/arch/arm/boot/dts/imx6q-evi.dts
+++ b/arch/arm/boot/dts/imx6q-evi.dts
@@ -50,7 +50,7 @@
 	model = "Uniwest Evi";
 	compatible = "uniwest,imx6q-evi", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-gk802.dts b/arch/arm/boot/dts/imx6q-gk802.dts
index b715deb..0be3756 100644
--- a/arch/arm/boot/dts/imx6q-gk802.dts
+++ b/arch/arm/boot/dts/imx6q-gk802.dts
@@ -18,7 +18,7 @@
 		stdout-path = &uart4;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts
index 29adaa7c..a8f70b4 100644
--- a/arch/arm/boot/dts/imx6q-gw5400-a.dts
+++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts
@@ -60,7 +60,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-h100.dts b/arch/arm/boot/dts/imx6q-h100.dts
index 8a2ea6c..714e09e0 100644
--- a/arch/arm/boot/dts/imx6q-h100.dts
+++ b/arch/arm/boot/dts/imx6q-h100.dts
@@ -49,6 +49,11 @@
 	model = "Auvidea H100";
 	compatible = "auvidea,h100", "fsl,imx6q";
 
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
+
 	aliases {
 		rtc0 = &rtc;
 		rtc1 = &snvs_rtc;
@@ -161,7 +166,7 @@
 	status = "okay";
 
 	eeprom: 24c02@51 {
-		compatible = "microchip,24c02", "at24";
+		compatible = "microchip,24c02", "atmel,24c02";
 		reg = <0x51>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-marsboard.dts b/arch/arm/boot/dts/imx6q-marsboard.dts
index 432291b..dd763f2 100644
--- a/arch/arm/boot/dts/imx6q-marsboard.dts
+++ b/arch/arm/boot/dts/imx6q-marsboard.dts
@@ -47,7 +47,7 @@
 	model = "Embest MarS Board i.MX6Dual";
 	compatible = "embest,imx6q-marsboard", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-mccmon6.dts b/arch/arm/boot/dts/imx6q-mccmon6.dts
index cab36f4..b7e9f38 100644
--- a/arch/arm/boot/dts/imx6q-mccmon6.dts
+++ b/arch/arm/boot/dts/imx6q-mccmon6.dts
@@ -19,7 +19,7 @@
 	model = "Liebherr (LWN) monitor6 i.MX6 Quad Board";
 	compatible = "lwn,mccmon6", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-novena.dts b/arch/arm/boot/dts/imx6q-novena.dts
index 7d7dc59..52f3937 100644
--- a/arch/arm/boot/dts/imx6q-novena.dts
+++ b/arch/arm/boot/dts/imx6q-novena.dts
@@ -55,6 +55,11 @@
 	model = "Kosagi Novena Dual/Quad";
 	compatible = "kosagi,imx6q-novena", "fsl,imx6q";
 
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
+
 	chosen {
 		stdout-path = &uart2;
 	};
diff --git a/arch/arm/boot/dts/imx6q-phytec-mira-rdk-emmc.dts b/arch/arm/boot/dts/imx6q-phytec-mira-rdk-emmc.dts
new file mode 100644
index 0000000..2e70ea5
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-phytec-mira-rdk-emmc.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
+
+/ {
+	model = "PHYTEC phyBOARD-Mira Quad Carrier-Board with eMMC";
+	compatible = "phytec,imx6q-pbac06-emmc", "phytec,imx6q-pbac06",
+		     "phytec,imx6qdl-pcm058", "fsl,imx6q";
+
+	chosen {
+		stdout-path = &uart2;
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&fec {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c_rtc {
+	status = "okay";
+};
+
+&m25p80 {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
+&usbotg {
+	status = "okay";
+};
+
+&usdhc1 {
+	status = "okay";
+};
+
+&usdhc4 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-phytec-mira-rdk-nand.dts b/arch/arm/boot/dts/imx6q-phytec-mira-rdk-nand.dts
new file mode 100644
index 0000000..65d2e48
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-phytec-mira-rdk-nand.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
+
+/ {
+	model = "PHYTEC phyBOARD-Mira Quad Carrier-Board with NAND";
+	compatible = "phytec,imx6q-pbac06-nand", "phytec,imx6q-pbac06",
+		     "phytec,imx6qdl-pcm058", "fsl,imx6q";
+
+	chosen {
+		stdout-path = &uart2;
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&fec {
+	status = "okay";
+};
+
+&gpmi {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c_rtc {
+	status = "okay";
+};
+
+&m25p80 {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
+&usbotg {
+	status = "okay";
+};
+
+&usdhc1 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
index cd20d0a..fad858c 100644
--- a/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
+++ b/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
@@ -16,7 +16,7 @@
 	model = "Phytec phyFLEX-i.MX6 Quad";
 	compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6q-pistachio.dts b/arch/arm/boot/dts/imx6q-pistachio.dts
index 1effb58..bd57b3b 100644
--- a/arch/arm/boot/dts/imx6q-pistachio.dts
+++ b/arch/arm/boot/dts/imx6q-pistachio.dts
@@ -56,7 +56,7 @@
 		stdout-path = &uart4;
 	};
 
-	memory: memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-rex-pro.dts b/arch/arm/boot/dts/imx6q-rex-pro.dts
index 90ea61a..d6cae73 100644
--- a/arch/arm/boot/dts/imx6q-rex-pro.dts
+++ b/arch/arm/boot/dts/imx6q-rex-pro.dts
@@ -16,7 +16,7 @@
 	model = "Rex Pro i.MX6 Quad Board";
 	compatible = "rex,imx6q-rex-pro", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6q-sbc6x.dts b/arch/arm/boot/dts/imx6q-sbc6x.dts
index 2557330..b7aa2f0 100644
--- a/arch/arm/boot/dts/imx6q-sbc6x.dts
+++ b/arch/arm/boot/dts/imx6q-sbc6x.dts
@@ -12,7 +12,7 @@
 	model = "MicroSys sbc6x board";
 	compatible = "microsys,sbc6x", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6q-tbs2910.dts b/arch/arm/boot/dts/imx6q-tbs2910.dts
index a3cd7af..505cba7 100644
--- a/arch/arm/boot/dts/imx6q-tbs2910.dts
+++ b/arch/arm/boot/dts/imx6q-tbs2910.dts
@@ -59,7 +59,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6q-ts4900.dts b/arch/arm/boot/dts/imx6q-ts4900.dts
index fab76f8..e655107 100644
--- a/arch/arm/boot/dts/imx6q-ts4900.dts
+++ b/arch/arm/boot/dts/imx6q-ts4900.dts
@@ -46,6 +46,11 @@
 / {
 	model = "Technologic Systems i.MX6 Quad TS-4900 (Default Device Tree)";
 	compatible = "technologic,imx6q-ts4900", "fsl,imx6q";
+
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
 };
 
 &sata {
diff --git a/arch/arm/boot/dts/imx6q-ts7970.dts b/arch/arm/boot/dts/imx6q-ts7970.dts
index f19e189..c615ac4 100644
--- a/arch/arm/boot/dts/imx6q-ts7970.dts
+++ b/arch/arm/boot/dts/imx6q-ts7970.dts
@@ -47,6 +47,11 @@
 / {
 	model = "Technologic Systems i.MX6 Quad TS-7970 (Default Device Tree)";
 	compatible = "technologic,imx6q-ts7970", "fsl,imx6q";
+
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
 };
 
 &sata {
diff --git a/arch/arm/boot/dts/imx6q-wandboard-revb1.dts b/arch/arm/boot/dts/imx6q-wandboard-revb1.dts
index 9207d80..b763352 100644
--- a/arch/arm/boot/dts/imx6q-wandboard-revb1.dts
+++ b/arch/arm/boot/dts/imx6q-wandboard-revb1.dts
@@ -16,7 +16,7 @@
 	model = "Wandboard i.MX6 Quad Board rev B1";
 	compatible = "wand,imx6q-wandboard", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6q-wandboard-revd1.dts b/arch/arm/boot/dts/imx6q-wandboard-revd1.dts
index e87ddb1..8691fab 100644
--- a/arch/arm/boot/dts/imx6q-wandboard-revd1.dts
+++ b/arch/arm/boot/dts/imx6q-wandboard-revd1.dts
@@ -16,7 +16,7 @@
 	model = "Wandboard i.MX6 Quad Board revD1";
 	compatible = "wand,imx6q-wandboard", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6q-wandboard.dts b/arch/arm/boot/dts/imx6q-wandboard.dts
index 4a8a6ee..2a3d98c 100644
--- a/arch/arm/boot/dts/imx6q-wandboard.dts
+++ b/arch/arm/boot/dts/imx6q-wandboard.dts
@@ -16,7 +16,7 @@
 	model = "Wandboard i.MX6 Quad Board";
 	compatible = "wand,imx6q-wandboard", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6q-zii-rdu2.dts b/arch/arm/boot/dts/imx6q-zii-rdu2.dts
index 6be8a1e..7da6dde 100644
--- a/arch/arm/boot/dts/imx6q-zii-rdu2.dts
+++ b/arch/arm/boot/dts/imx6q-zii-rdu2.dts
@@ -47,4 +47,9 @@
 / {
 	model = "ZII RDU2 Board";
 	compatible = "zii,imx6q-zii-rdu2", "fsl,imx6q";
+
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
 };
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index bc581aa..ae7b3f1 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -215,11 +215,6 @@
 		compatible = "fsl,imx-display-subsystem";
 		ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>;
 	};
-
-	gpu-subsystem {
-		compatible = "fsl,imx-gpu-subsystem";
-		cores = <&gpu_2d>, <&gpu_3d>, <&gpu_vg>;
-	};
 };
 
 &gpio1 {
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 4e776e0..8206683 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -47,6 +47,11 @@
 	model = "Toradex Apalis iMX6Q/D Module";
 	compatible = "toradex,apalis_imx6q", "fsl,imx6q";
 
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
+
 	backlight: backlight {
 		compatible = "pwm-backlight";
 		pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
index d1cfdc2..9332a31 100644
--- a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
@@ -42,6 +42,11 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
+
 	ir_recv: ir-receiver {
 		compatible = "gpio-ir-receiver";
 		gpios = <&gpio3 9 1>;
diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
index dea8fc4..17a7b9c 100644
--- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
@@ -44,7 +44,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
index 363a443..b804468 100644
--- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
@@ -59,7 +59,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
index c75385c..629908f 100644
--- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
@@ -59,7 +59,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
index eab75f3..a1a6fb5 100644
--- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
@@ -59,7 +59,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw551x.dtsi b/arch/arm/boot/dts/imx6qdl-gw551x.dtsi
index 30d4662..4e21b38 100644
--- a/arch/arm/boot/dts/imx6qdl-gw551x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw551x.dtsi
@@ -74,7 +74,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
index c67c106..81dae5b 100644
--- a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
@@ -51,7 +51,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi
index 1a0faa1..c5d95e8 100644
--- a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi
@@ -80,7 +80,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
index d894dde..b5986ef 100644
--- a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
@@ -288,6 +288,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		clocks = <&clks IMX6QDL_CLK_CKO>;
 		VDDA-supply = <&reg_1p8v>;
 		VDDIO-supply = <&reg_3p3v>;
diff --git a/arch/arm/boot/dts/imx6qdl-gw5903.dtsi b/arch/arm/boot/dts/imx6qdl-gw5903.dtsi
index 4444251..3681322 100644
--- a/arch/arm/boot/dts/imx6qdl-gw5903.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw5903.dtsi
@@ -83,7 +83,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw5904.dtsi b/arch/arm/boot/dts/imx6qdl-gw5904.dtsi
index fd4b68b..58124ad 100644
--- a/arch/arm/boot/dts/imx6qdl-gw5904.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw5904.dtsi
@@ -93,7 +93,7 @@
 		};
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
index 9258323..7e20b47 100644
--- a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
@@ -40,6 +40,11 @@
  */
 
 / {
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
+
 	chosen {
 		stdout-path = &uart1;
 	};
@@ -239,10 +244,9 @@
 
 		pinctrl_hummingboard_usbotg_id: hummingboard-usbotg-id {
 			/*
-			 * Similar to pinctrl_usbotg_2, but we want it
-			 * pulled down for a fixed host connection.
+			 * We want it pulled down for a fixed host connection.
 			 */
-			fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
+			fsl,pins = <MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x13059>;
 		};
 
 		pinctrl_hummingboard_usbotg_vbus: hummingboard-usbotg-vbus {
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
index dffbc92..98241ac 100644
--- a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
@@ -40,6 +40,11 @@
  */
 
 / {
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
+
 	chosen {
 		stdout-path = &uart1;
 	};
@@ -191,6 +196,7 @@
 	sgtl5000: codec@a {
 		clocks = <&clks IMX6QDL_CLK_CKO>;
 		compatible = "fsl,sgtl5000";
+		#sound-dai-cells = <0>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_hummingboard2_sgtl5000>;
 		reg = <0x0a>;
@@ -409,8 +415,7 @@
 
 		pinctrl_hummingboard2_usbotg_id: hummingboard2-usbotg-id {
 			/*
-			 * Similar to pinctrl_usbotg_2, but we want it
-			 * pulled down for a fixed host connection.
+			 * We want it pulled down for a fixed host connection.
 			 */
 			fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
 		};
diff --git a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi
index b6220d6..acc3b11f 100644
--- a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi
@@ -44,7 +44,7 @@
 #include <dt-bindings/sound/fsl-imx-audmux.h>
 
 / {
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
@@ -200,7 +200,11 @@
 	status = "okay";
 
 	mdio {
-		eth_phy: ethernet-phy {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		eth_phy: ethernet-phy@0 {
+			reg = <0x0>;
 			rxc-skew-ps = <1140>;
 			txc-skew-ps = <1140>;
 			txen-skew-ps = <600>;
diff --git a/arch/arm/boot/dts/imx6qdl-icore.dtsi b/arch/arm/boot/dts/imx6qdl-icore.dtsi
index a1b469c..b3a463a 100644
--- a/arch/arm/boot/dts/imx6qdl-icore.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-icore.dtsi
@@ -45,7 +45,7 @@
 #include <dt-bindings/sound/fsl-imx-audmux.h>
 
 / {
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
index 4cc4e23..aab088f 100644
--- a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
@@ -46,7 +46,7 @@
 		stdout-path = &uart2;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
index fd05f7c..87ca6ea 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
@@ -46,7 +46,7 @@
 		stdout-path = &uart2;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0xF0000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
index 40942d6..f5b763d 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
@@ -46,7 +46,7 @@
 		stdout-path = &uart2;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index 919b6b7..596866b 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -48,7 +48,7 @@
 		stdout-path = &uart2;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-mira.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-mira.dtsi
new file mode 100644
index 0000000..9ebd438
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-phytec-mira.dtsi
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+
+/ {
+	aliases {
+		rtc0 = &i2c_rtc;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <7>;
+		power-supply = <&reg_backlight>;
+		pwms = <&pwm1 0 5000000>;
+		status = "okay";
+	};
+
+	gpio_leds: leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpioleds>;
+		status = "disabled";
+
+		red {
+			label = "phyboard-mira:red";
+			gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>;
+		};
+
+		green {
+			label = "phyboard-mira:green";
+			gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>;
+		};
+
+		blue {
+			label = "phyboard-mira:blue";
+			gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+		};
+	};
+
+	reg_backlight: regulator-backlight {
+		compatible = "regulator-fixed";
+		regulator-name = "backlight_3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	reg_en_switch: regulator-en-switch {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_en_switch>;
+		regulator-name = "Enable Switch";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio3 4 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+	};
+
+	reg_flexcan1: regulator-flexcan1 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flexcan1_en>;
+		regulator-name = "flexcan1-reg";
+		regulator-min-microvolt = <1500000>;
+		regulator-max-microvolt = <1500000>;
+		gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	reg_panel: regulator-panel {
+		compatible = "regulator-fixed";
+		regulator-name = "panel-power-supply";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-always-on;
+	};
+
+	reg_pcie: regulator-pcie {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pcie_reg>;
+		regulator-name = "mPCIe_1V5";
+		regulator-min-microvolt = <1500000>;
+		regulator-max-microvolt = <1500000>;
+		gpio = <&gpio3 0 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	reg_usb_h1_vbus: usb-h1-vbus {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usbh1_vbus>;
+		regulator-name = "usb_h1_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio2 18 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	reg_usbotg_vbus: usbotg-vbus {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usbotg_vbus>;
+		regulator-name = "usb_otg_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	panel {
+		compatible = "auo,g104sn02";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_panel_en>;
+		power-supply = <&reg_panel>;
+		enable-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+		backlight = <&backlight>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&lvds0_out>;
+			};
+		};
+	};
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan1>;
+	xceiver-supply = <&reg_flexcan1>;
+	status = "disabled";
+};
+
+&hdmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hdmicec>;
+	ddc-i2c-bus = <&i2c2>;
+	status = "disabled";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	clock-frequency = <400000>;
+	status = "disabled";
+
+	stmpe: touchctrl@44 {
+		compatible = "st,stmpe811";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_stmpe>;
+		reg = <0x44>;
+		interrupt-parent = <&gpio7>;
+		interrupts = <12 IRQ_TYPE_NONE>;
+		status = "disabled";
+
+		stmpe_touchscreen {
+			compatible = "st,stmpe-ts";
+			st,sample-time = <4>;
+			st,mod-12b = <1>;
+			st,ref-sel = <0>;
+			st,adc-freq = <1>;
+			st,ave-ctrl = <1>;
+			st,touch-det-delay = <2>;
+			st,settling = <2>;
+			st,fraction-z = <7>;
+			st,i-drive = <1>;
+		};
+	};
+
+	i2c_rtc: rtc@68 {
+		compatible = "microcrystal,rv4162";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_rtc_int>;
+		reg = <0x68>;
+		interrupt-parent = <&gpio7>;
+		interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	clock-frequency = <100000>;
+	status = "disabled";
+};
+
+&ldb {
+	status = "okay";
+
+	lvds-channel@0 {
+		fsl,data-mapping = "spwg";
+		fsl,data-width = <24>;
+		status = "disabled";
+
+		port@4 {
+			reg = <4>;
+
+			lvds0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+};
+
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie>;
+	reset-gpio = <&gpio2 25 GPIO_ACTIVE_LOW>;
+	vpcie-supply = <&reg_pcie>;
+	status = "disabled";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3>;
+	uart-has-rtscts;
+	status = "disabled";
+};
+
+&usbh1 {
+	vbus-supply = <&reg_usb_h1_vbus>;
+	disable-over-current;
+	status = "disabled";
+};
+
+&usbotg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg>;
+	vbus-supply = <&reg_usbotg_vbus>;
+	disable-over-current;
+	status = "disabled";
+};
+
+&usdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	cd-gpios = <&gpio6 31 GPIO_ACTIVE_LOW>;
+	no-1-8-v;
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl_panel_en: panelen1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_EB0__GPIO2_IO28		0xb0b1
+		>;
+	};
+
+	pinctrl_en_switch: enswitchgrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_DA4__GPIO3_IO04		0xb0b1
+		>;
+	};
+
+	pinctrl_flexcan1: flexcan1grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_7__FLEXCAN1_TX		0x1b0b0
+			MX6QDL_PAD_GPIO_8__FLEXCAN1_RX		0x1b0b0
+		>;
+	};
+
+	pinctrl_flexcan1_en: flexcan1engrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_A18__GPIO2_IO20		0xb0b1
+		>;
+	};
+
+	pinctrl_gpioleds: gpioledsgrp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22	0x1b0b0
+			MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23	0x1b0b0
+			MX6QDL_PAD_CSI0_DAT6__GPIO5_IO24	0x1b0b0
+		>;
+	};
+
+	pinctrl_hdmicec: hdmicecgrp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE	0x1f8b0
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA		0x4001b8b1
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL		0x4001b8b1
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D21__I2C1_SCL		0x4001b8b1
+			MX6QDL_PAD_EIM_D28__I2C1_SDA		0x4001b8b1
+		>;
+	};
+
+	pinctrl_pcie: pciegrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_OE__GPIO2_IO25		0xb0b1
+		>;
+	};
+
+	pinctrl_pcie_reg: pciereggrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_DA0__GPIO3_IO00		0xb0b1
+		>;
+	};
+
+	pinctrl_pwm1: pwm1grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_9__PWM1_OUT		0x1b0b1
+		>;
+	};
+
+	pinctrl_rtc_int: rtcintgrp {
+		fsl,pins = <
+			MX6QDL_PAD_SD3_RST__GPIO7_IO08		0x1b0b0
+		>;
+	};
+
+	pinctrl_stmpe: stmpegrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x1b0b0
+		>;
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D26__UART2_TX_DATA	0x1b0b1
+			MX6QDL_PAD_EIM_D27__UART2_RX_DATA	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart3: uart3grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_EB3__UART3_CTS_B		0x1b0b1
+			MX6QDL_PAD_EIM_D23__UART3_RTS_B		0x1b0b1
+			MX6QDL_PAD_EIM_D24__UART3_TX_DATA	0x1b0b1
+			MX6QDL_PAD_EIM_D25__UART3_RX_DATA	0x1b0b1
+		>;
+	};
+
+	pinctrl_usbh1_vbus: usbh1vbusgrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_A20__GPIO2_IO18		0xb0b1
+		>;
+	};
+
+	pinctrl_usbotg: usbotggrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_1__USB_OTG_ID		0x17059
+		>;
+	};
+
+	pinctrl_usbotg_vbus: usbotgvbusgrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_A19__GPIO2_IO19		0xb0b1
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_CMD__SD1_CMD		0x170f9
+			MX6QDL_PAD_SD1_CLK__SD1_CLK		0x100f9
+			MX6QDL_PAD_SD1_DAT0__SD1_DATA0		0x170f9
+			MX6QDL_PAD_SD1_DAT1__SD1_DATA1		0x170f9
+			MX6QDL_PAD_SD1_DAT2__SD1_DATA2		0x170f9
+			MX6QDL_PAD_SD1_DAT3__SD1_DATA3		0x170f9
+			MX6QDL_PAD_EIM_BCLK__GPIO6_IO31		0xb0b1  /* CD */
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
index 585b4f6..7ba317a 100644
--- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
@@ -13,7 +13,7 @@
 
 / {
 	chosen {
-		linux,stdout-path = &uart4;
+		stdout-path = &uart4;
 	};
 
 	regulators {
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
index d81b007..c58f344 100644
--- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
@@ -15,7 +15,7 @@
 	model = "Phytec phyFLEX-i.MX6 Quad";
 	compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi
new file mode 100644
index 0000000..6486df3
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	aliases {
+		rtc1 = &da9062_rtc;
+		rtc2 = &snvs_rtc;
+	};
+
+	/*
+	 * Set the minimum memory size here and
+	 * let the bootloader set the real size.
+	 */
+	memory@10000000 {
+		device_type = "memory";
+		reg = <0x10000000 0x8000000>;
+	};
+
+	gpio_leds_som: somleds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpioleds_som>;
+
+		som-led-green {
+			label = "phycore:green";
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+};
+
+&ecspi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1>;
+	cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	m25p80: flash@0 {
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		status = "disabled";
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet>;
+	phy-handle = <&ethphy>;
+	phy-mode = "rgmii";
+	phy-supply = <&vdd_eth_io>;
+	phy-reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+	status = "disabled";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy: ethernet-phy@3 {
+			reg = <3>;
+			txc-skew-ps = <1680>;
+			rxc-skew-ps = <1860>;
+		};
+	};
+};
+
+&gpmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpmi_nand>;
+	nand-on-flash-bbt;
+	status = "disabled";
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	eeprom@50 {
+		compatible = "atmel,24c32";
+		reg = <0x50>;
+	};
+
+	pmic@58 {
+		compatible = "dlg,da9062";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pmic>;
+		reg = <0x58>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+
+		da9062_rtc: rtc {
+			compatible = "dlg,da9062-rtc";
+		};
+
+		watchdog {
+			compatible = "dlg,da9062-watchdog";
+		};
+
+		regulators {
+			vdd_arm: buck1 {
+				regulator-name = "vdd_arm";
+				regulator-min-microvolt = <730000>;
+				regulator-max-microvolt = <1380000>;
+				regulator-always-on;
+			};
+
+			vdd_soc: buck2 {
+				regulator-name = "vdd_soc";
+				regulator-min-microvolt = <730000>;
+				regulator-max-microvolt = <1380000>;
+				regulator-always-on;
+			};
+
+			vdd_ddr3_1p5: buck3 {
+				regulator-name = "vdd_ddr3";
+				regulator-min-microvolt = <1500000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+			};
+
+			vdd_eth_1p2: buck4 {
+				regulator-name = "vdd_eth";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+
+			vdd_snvs: ldo1 {
+				regulator-name = "vdd_snvs";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+			};
+
+			vdd_high: ldo2 {
+				regulator-name = "vdd_high";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+			};
+
+			vdd_eth_io: ldo3 {
+				regulator-name = "vdd_eth_io";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+			};
+
+			vdd_emmc_1p8: ldo4 {
+				regulator-name = "vdd_emmc";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+		};
+	};
+};
+
+&reg_arm {
+	vin-supply = <&vdd_arm>;
+};
+
+&reg_pu {
+	vin-supply = <&vdd_soc>;
+};
+
+&reg_soc {
+	vin-supply = <&vdd_soc>;
+};
+
+&snvs_poweroff {
+	status = "okay";
+};
+
+&usdhc4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	bus-width = <8>;
+	non-removable;
+	vmmc-supply = <&vdd_emmc_1p8>;
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl_enet: enetgrp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
+			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
+			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x1b0b0
+			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x1b0b0
+			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x1b0b0
+			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x1b0b0
+			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x1b0b0
+			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x1b0b0
+			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x1b0b0
+			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
+			MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
+			MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
+			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
+			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
+			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
+			MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN	0x1b0b0
+			MX6QDL_PAD_SD2_DAT1__GPIO1_IO14		0x1b0b0
+		>;
+	};
+
+	pinctrl_gpioleds_som: gpioledssomgrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_4__GPIO1_IO04		0x1b0b0
+		>;
+	};
+
+	pinctrl_gpmi_nand: gpminandgrp {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CLE__NAND_CLE		0xb0b1
+			MX6QDL_PAD_NANDF_ALE__NAND_ALE		0xb0b1
+			MX6QDL_PAD_NANDF_WP_B__NAND_WP_B	0xb0b1
+			MX6QDL_PAD_NANDF_RB0__NAND_READY_B	0xb000
+			MX6QDL_PAD_NANDF_CS0__NAND_CE0_B	0xb0b1
+			MX6QDL_PAD_NANDF_CS1__NAND_CE1_B	0xb0b1
+			MX6QDL_PAD_NANDF_CS2__NAND_CE2_B	0xb0b1
+			MX6QDL_PAD_NANDF_CS3__NAND_CE3_B	0xb0b1
+			MX6QDL_PAD_SD4_CMD__NAND_RE_B		0xb0b1
+			MX6QDL_PAD_SD4_CLK__NAND_WE_B		0xb0b1
+			MX6QDL_PAD_NANDF_D0__NAND_DATA00	0xb0b1
+			MX6QDL_PAD_NANDF_D1__NAND_DATA01	0xb0b1
+			MX6QDL_PAD_NANDF_D2__NAND_DATA02	0xb0b1
+			MX6QDL_PAD_NANDF_D3__NAND_DATA03	0xb0b1
+			MX6QDL_PAD_NANDF_D4__NAND_DATA04	0xb0b1
+			MX6QDL_PAD_NANDF_D5__NAND_DATA05	0xb0b1
+			MX6QDL_PAD_NANDF_D6__NAND_DATA06	0xb0b1
+			MX6QDL_PAD_NANDF_D7__NAND_DATA07	0xb0b1
+			MX6QDL_PAD_SD4_DAT0__NAND_DQS		0x00b1
+		>;
+	};
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_6__I2C3_SDA		0x4001b8b1
+			MX6QDL_PAD_GPIO_5__I2C3_SCL		0x4001b8b1
+		>;
+	};
+
+	pinctrl_ecspi1: ecspi1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D16__ECSPI1_SCLK		0x100b1
+			MX6QDL_PAD_EIM_D17__ECSPI1_MISO		0x100b1
+			MX6QDL_PAD_EIM_D18__ECSPI1_MOSI		0x100b1
+			MX6QDL_PAD_EIM_D19__GPIO3_IO19		0x1b0b0
+		>;
+	};
+
+	pinctrl_pmic: pmicgrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_2__GPIO1_IO02		0x1b0b0
+		>;
+	};
+
+	pinctrl_usdhc4: usdhc4grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_CMD__SD4_CMD		0x17059
+			MX6QDL_PAD_SD4_CLK__SD4_CLK		0x10059
+			MX6QDL_PAD_SD4_DAT0__SD4_DATA0		0x17059
+			MX6QDL_PAD_SD4_DAT1__SD4_DATA1		0x17059
+			MX6QDL_PAD_SD4_DAT2__SD4_DATA2		0x17059
+			MX6QDL_PAD_SD4_DAT3__SD4_DATA3		0x17059
+			MX6QDL_PAD_SD4_DAT4__SD4_DATA4		0x17059
+			MX6QDL_PAD_SD4_DAT5__SD4_DATA5		0x17059
+			MX6QDL_PAD_SD4_DAT6__SD4_DATA6		0x17059
+			MX6QDL_PAD_SD4_DAT7__SD4_DATA7		0x17059
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6qdl-rex.dtsi b/arch/arm/boot/dts/imx6qdl-rex.dtsi
index 6e9549f..039e3b8 100644
--- a/arch/arm/boot/dts/imx6qdl-rex.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-rex.dtsi
@@ -137,7 +137,7 @@
 	status = "okay";
 
 	eeprom@57 {
-		compatible = "at,24c02";
+		compatible = "atmel,24c02";
 		reg = <0x57>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
index 82d6ccb..54b0139 100644
--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
@@ -13,7 +13,7 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index 35de7ad..18b6505 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -49,7 +49,7 @@
 		stdout-path = &uart2;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index 0a50705..f019f99 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -19,7 +19,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-tx6.dtsi b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
index 6abb66c..f015e2d 100644
--- a/arch/arm/boot/dts/imx6qdl-tx6.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
@@ -61,8 +61,8 @@
 		sdhc1 = &usdhc2;
 	};
 
-	memory {
-		reg = <0 0>; /* will be filled by U-Boot */
+	memory@10000000 {
+		reg = <0x10000000 0>; /* will be filled by U-Boot */
 	};
 
 	clocks {
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
index 4161b7d..9063879 100644
--- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
@@ -35,7 +35,7 @@
 		pinctrl-names = "default";
 	};
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-var-dart.dtsi b/arch/arm/boot/dts/imx6qdl-var-dart.dtsi
index 421d6f5..38080c1 100644
--- a/arch/arm/boot/dts/imx6qdl-var-dart.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-var-dart.dtsi
@@ -10,7 +10,7 @@
 #include <dt-bindings/sound/fsl-imx-audmux.h>
 
 / {
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
index 72f52fc..911f7f0 100644
--- a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
@@ -305,6 +305,15 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart4>;
 	status = "okay";
+
+	rave-sp {
+		compatible = "zii,rave-sp-rdu2";
+		current-speed = <1000000>;
+
+		watchdog {
+			compatible = "zii,rave-sp-watchdog";
+		};
+	};
 };
 
 &ecspi1 {
@@ -498,7 +507,7 @@
 	};
 
 	eeprom@54 {
-		compatible = "at,24c128";
+		compatible = "atmel,24c128";
 		reg = <0x54>;
 	};
 
@@ -602,6 +611,8 @@
 	wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
 	vmmc-supply = <&reg_3p3v_sd>;
 	vqmmc-supply = <&reg_3p3v>;
+	no-1-8-v;
+	no-sdio;
 	status = "okay";
 };
 
@@ -613,6 +624,8 @@
 	wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
 	vmmc-supply = <&reg_3p3v_sd>;
 	vqmmc-supply = <&reg_3p3v>;
+	no-1-8-v;
+	no-sdio;
 	status = "okay";
 };
 
@@ -622,7 +635,10 @@
 	bus-width = <8>;
 	vmmc-supply = <&reg_3p3v>;
 	vqmmc-supply = <&reg_3p3v>;
+	no-1-8-v;
 	non-removable;
+	no-sdio;
+	no-sd;
 	status = "okay";
 };
 
@@ -805,6 +821,10 @@
 	};
 };
 
+&wdog1 {
+	status = "disabled";
+};
+
 &iomuxc {
 	pinctrl_accel: accelgrp {
 		fsl,pins = <
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 59ff866..c003e62 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -23,7 +23,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec;
@@ -143,7 +143,7 @@
 		};
 	};
 
-	pmu {
+	pmu: pmu {
 		compatible = "arm,cortex-a9-pmu";
 		interrupt-parent = <&gpc>;
 		interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/imx6qp-phytec-mira-rdk-nand.dts b/arch/arm/boot/dts/imx6qp-phytec-mira-rdk-nand.dts
new file mode 100644
index 0000000..f27d7ab
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qp-phytec-mira-rdk-nand.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Enrico Scholz <enrico.scholz@sigma-chemnitz.de>
+ */
+
+/dts-v1/;
+#include "imx6qp.dtsi"
+#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
+
+/ {
+	model = "PHYTEC phyBOARD-Mira QuadPlus Carrier-Board with NAND";
+	compatible = "phytec,imx6qp-pbac06-nand", "phytec,imx6qp-pbac06",
+		     "phytec,imx6qdl-pcm058", "fsl,imx6qp";
+
+	chosen {
+		stdout-path = &uart2;
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&fec {
+	status = "okay";
+};
+
+&gpmi {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c_rtc {
+	status = "okay";
+};
+
+&m25p80 {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
+&usbotg {
+	status = "okay";
+};
+
+&usdhc1 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qp-wandboard-revd1.dts b/arch/arm/boot/dts/imx6qp-wandboard-revd1.dts
index f7badd8..907ba0c 100644
--- a/arch/arm/boot/dts/imx6qp-wandboard-revd1.dts
+++ b/arch/arm/boot/dts/imx6qp-wandboard-revd1.dts
@@ -16,7 +16,7 @@
 	model = "Wandboard i.MX6 QuadPlus Board revD1";
 	compatible = "wand,imx6qp-wandboard", "fsl,imx6qp";
 
-	memory {
+	memory@10000000 {
 		reg = <0x10000000 0x80000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6qp-zii-rdu2.dts b/arch/arm/boot/dts/imx6qp-zii-rdu2.dts
index 547a766..de5b50d 100644
--- a/arch/arm/boot/dts/imx6qp-zii-rdu2.dts
+++ b/arch/arm/boot/dts/imx6qp-zii-rdu2.dts
@@ -47,4 +47,9 @@
 / {
 	model = "ZII RDU2+ Board";
 	compatible = "zii,imx6qp-zii-rdu2", "fsl,imx6qp";
+
+	/* Will be filled by the bootloader */
+	memory@10000000 {
+		reg = <0x10000000 0>;
+	};
 };
diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts
index 2844ab5..37e792f 100644
--- a/arch/arm/boot/dts/imx6sl-evk.dts
+++ b/arch/arm/boot/dts/imx6sl-evk.dts
@@ -16,7 +16,7 @@
 	model = "Freescale i.MX6 SoloLite EVK Board";
 	compatible = "fsl,imx6sl-evk", "fsl,imx6sl";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6sl-warp.dts b/arch/arm/boot/dts/imx6sl-warp.dts
index 72c7745..404e602 100644
--- a/arch/arm/boot/dts/imx6sl-warp.dts
+++ b/arch/arm/boot/dts/imx6sl-warp.dts
@@ -54,7 +54,7 @@
 	model = "WaRP Board";
 	compatible = "warp,imx6sl-warp", "fsl,imx6sl";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index ae8df3c..ab6a7e2 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -21,7 +21,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec;
diff --git a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts
index f9d40ee..b58f770 100644
--- a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts
+++ b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts
@@ -52,7 +52,7 @@
 		t_lcd = &t_lcd;
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
index 240a286..72da5ac 100644
--- a/arch/arm/boot/dts/imx6sx-sabreauto.dts
+++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
@@ -14,7 +14,7 @@
 	model = "Freescale i.MX6 SoloX Sabre Auto Board";
 	compatible = "fsl,imx6sx-sabreauto", "fsl,imx6sx";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi
index d35aa85..f8f3187 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi
@@ -20,7 +20,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts b/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts
index 4d8c652..252175b 100644
--- a/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts
+++ b/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts
@@ -20,7 +20,7 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo-basic.dts b/arch/arm/boot/dts/imx6sx-udoo-neo-basic.dts
index 0c1fc1a..40ccdf4 100644
--- a/arch/arm/boot/dts/imx6sx-udoo-neo-basic.dts
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo-basic.dts
@@ -48,7 +48,7 @@
 	model = "UDOO Neo Basic";
 	compatible = "udoo,neobasic", "fsl,imx6sx";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo-extended.dts b/arch/arm/boot/dts/imx6sx-udoo-neo-extended.dts
index 5d6c227..42bfc8f 100644
--- a/arch/arm/boot/dts/imx6sx-udoo-neo-extended.dts
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo-extended.dts
@@ -48,7 +48,7 @@
 	model = "UDOO Neo Extended";
 	compatible = "udoo,neoextended", "fsl,imx6sx";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo-full.dts b/arch/arm/boot/dts/imx6sx-udoo-neo-full.dts
index 653ceb2..c84c877 100644
--- a/arch/arm/boot/dts/imx6sx-udoo-neo-full.dts
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo-full.dts
@@ -48,7 +48,7 @@
 	model = "UDOO Neo Full";
 	compatible = "udoo,neofull", "fsl,imx6sx";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index fd78793..49c7205 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -22,7 +22,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		can0 = &flexcan1;
@@ -188,6 +188,7 @@
 				 <&clks IMX6SX_CLK_GPU>,
 				 <&clks IMX6SX_CLK_GPU>;
 			clock-names = "bus", "core", "shader";
+			power-domains = <&pd_pu>;
 		};
 
 		dma_apbh: dma-apbh@1804000 {
@@ -767,6 +768,18 @@
 					#address-cells = <1>;
 					#size-cells = <0>;
 
+					power-domain@0 {
+						reg = <0>;
+						#power-domain-cells = <0>;
+					};
+
+					pd_pu: power-domain@1 {
+						reg = <1>;
+						#power-domain-cells = <0>;
+						power-supply = <&reg_soc>;
+						clocks = <&clks IMX6SX_CLK_GPU>;
+					};
+
 					pd_pci: power-domain@3 {
 						reg = <3>;
 						#power-domain-cells = <0>;
@@ -1355,9 +1368,4 @@
 			status = "disabled";
 		};
 	};
-
-	gpu-subsystem {
-		compatible = "fsl,imx-gpu-subsystem";
-		cores = <&gpu>;
-	};
 };
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
index 18fdb08..6d720b2 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
@@ -9,487 +9,9 @@
 /dts-v1/;
 
 #include "imx6ul.dtsi"
+#include "imx6ul-14x14-evk.dtsi"
 
 / {
 	model = "Freescale i.MX6 UltraLite 14x14 EVK Board";
 	compatible = "fsl,imx6ul-14x14-evk", "fsl,imx6ul";
-
-	chosen {
-		stdout-path = &uart1;
-	};
-
-	memory {
-		reg = <0x80000000 0x20000000>;
-	};
-
-	backlight_display: backlight-display {
-		compatible = "pwm-backlight";
-		pwms = <&pwm1 0 5000000>;
-		brightness-levels = <0 4 8 16 32 64 128 255>;
-		default-brightness-level = <6>;
-		status = "okay";
-	};
-
-
-	reg_sd1_vmmc: regulator-sd1-vmmc {
-		compatible = "regulator-fixed";
-		regulator-name = "VSD_3V3";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	sound {
-		compatible = "simple-audio-card";
-		simple-audio-card,name = "mx6ul-wm8960";
-		simple-audio-card,format = "i2s";
-		simple-audio-card,bitclock-master = <&dailink_master>;
-		simple-audio-card,frame-master = <&dailink_master>;
-		simple-audio-card,widgets =
-			"Microphone", "Mic Jack",
-			"Line", "Line In",
-			"Line", "Line Out",
-			"Speaker", "Speaker",
-			"Headphone", "Headphone Jack";
-		simple-audio-card,routing =
-			"Headphone Jack", "HP_L",
-			"Headphone Jack", "HP_R",
-			"Speaker", "SPK_LP",
-			"Speaker", "SPK_LN",
-			"Speaker", "SPK_RP",
-			"Speaker", "SPK_RN",
-			"LINPUT1", "Mic Jack",
-			"LINPUT3", "Mic Jack",
-			"RINPUT1", "Mic Jack",
-			"RINPUT2", "Mic Jack";
-
-		simple-audio-card,cpu {
-			sound-dai = <&sai2>;
-		};
-
-		dailink_master: simple-audio-card,codec {
-			sound-dai = <&codec>;
-			clocks = <&clks IMX6UL_CLK_SAI2>;
-		};
-	};
-
-	panel {
-		compatible = "innolux,at043tn24";
-		backlight = <&backlight_display>;
-
-		port {
-			panel_in: endpoint {
-				remote-endpoint = <&display_out>;
-			};
-		};
-	};
-};
-
-&clks {
-	assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
-	assigned-clock-rates = <786432000>;
-};
-
-&i2c2 {
-	clock_frequency = <100000>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_i2c2>;
-	status = "okay";
-
-	codec: wm8960@1a {
-		#sound-dai-cells = <0>;
-		compatible = "wlf,wm8960";
-		reg = <0x1a>;
-		wlf,shared-lrclk;
-	};
-};
-
-&fec1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_enet1>;
-	phy-mode = "rmii";
-	phy-handle = <&ethphy0>;
-	status = "okay";
-};
-
-&fec2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_enet2>;
-	phy-mode = "rmii";
-	phy-handle = <&ethphy1>;
-	status = "okay";
-
-	mdio {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		ethphy0: ethernet-phy@2 {
-			reg = <2>;
-			micrel,led-mode = <1>;
-			clocks = <&clks IMX6UL_CLK_ENET_REF>;
-			clock-names = "rmii-ref";
-		};
-
-		ethphy1: ethernet-phy@1 {
-			reg = <1>;
-			micrel,led-mode = <1>;
-			clocks = <&clks IMX6UL_CLK_ENET2_REF>;
-			clock-names = "rmii-ref";
-		};
-	};
-};
-
-
-&lcdif {
-	assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
-	assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_lcdif_dat
-		     &pinctrl_lcdif_ctrl>;
-	status = "okay";
-
-	port {
-		display_out: endpoint {
-			remote-endpoint = <&panel_in>;
-		};
-	};
-};
-
-&pwm1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_pwm1>;
-	status = "okay";
-};
-
-&qspi {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_qspi>;
-	status = "okay";
-
-	flash0: n25q256a@0 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		compatible = "micron,n25q256a";
-		spi-max-frequency = <29000000>;
-		reg = <0>;
-	};
-};
-
-&sai2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_sai2>;
-	assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
-			  <&clks IMX6UL_CLK_SAI2>;
-	assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
-	assigned-clock-rates = <0>, <12288000>;
-	fsl,sai-mclk-direction-output;
-	status = "okay";
-};
-
-&snvs_poweroff {
-	status = "okay";
-};
-
-&tsc {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
-	measure-delay-time = <0xffff>;
-	pre-charge-time = <0xfff>;
-	status = "okay";
-};
-
-&uart1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart1>;
-	status = "okay";
-};
-
-&uart2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart2>;
-	uart-has-rtscts;
-	status = "okay";
-};
-
-&usbotg1 {
-	dr_mode = "otg";
-	status = "okay";
-};
-
-&usbotg2 {
-	dr_mode = "host";
-	disable-over-current;
-	status = "okay";
-};
-
-&usbphy1 {
-	fsl,tx-d-cal = <106>;
-};
-
-&usbphy2 {
-	fsl,tx-d-cal = <106>;
-};
-
-&usdhc1 {
-	pinctrl-names = "default", "state_100mhz", "state_200mhz";
-	pinctrl-0 = <&pinctrl_usdhc1>;
-	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
-	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
-	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
-	keep-power-in-suspend;
-	wakeup-source;
-	vmmc-supply = <&reg_sd1_vmmc>;
-	status = "okay";
-};
-
-&usdhc2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usdhc2>;
-	no-1-8-v;
-	keep-power-in-suspend;
-	wakeup-source;
-	status = "okay";
-};
-
-&wdog1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_wdog>;
-	fsl,ext-reset-output;
-};
-
-&iomuxc {
-	pinctrl-names = "default";
-
-	pinctrl_csi1: csi1grp {
-		fsl,pins = <
-			MX6UL_PAD_CSI_MCLK__CSI_MCLK		0x1b088
-			MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK	0x1b088
-			MX6UL_PAD_CSI_VSYNC__CSI_VSYNC		0x1b088
-			MX6UL_PAD_CSI_HSYNC__CSI_HSYNC		0x1b088
-			MX6UL_PAD_CSI_DATA00__CSI_DATA02	0x1b088
-			MX6UL_PAD_CSI_DATA01__CSI_DATA03	0x1b088
-			MX6UL_PAD_CSI_DATA02__CSI_DATA04	0x1b088
-			MX6UL_PAD_CSI_DATA03__CSI_DATA05	0x1b088
-			MX6UL_PAD_CSI_DATA04__CSI_DATA06	0x1b088
-			MX6UL_PAD_CSI_DATA05__CSI_DATA07	0x1b088
-			MX6UL_PAD_CSI_DATA06__CSI_DATA08	0x1b088
-			MX6UL_PAD_CSI_DATA07__CSI_DATA09	0x1b088
-		>;
-	};
-
-	pinctrl_enet1: enet1grp {
-		fsl,pins = <
-			MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN	0x1b0b0
-			MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER	0x1b0b0
-			MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00	0x1b0b0
-			MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01	0x1b0b0
-			MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN	0x1b0b0
-			MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00	0x1b0b0
-			MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01	0x1b0b0
-			MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1	0x4001b031
-		>;
-	};
-
-	pinctrl_enet2: enet2grp {
-		fsl,pins = <
-			MX6UL_PAD_GPIO1_IO07__ENET2_MDC		0x1b0b0
-			MX6UL_PAD_GPIO1_IO06__ENET2_MDIO	0x1b0b0
-			MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN	0x1b0b0
-			MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER	0x1b0b0
-			MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00	0x1b0b0
-			MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01	0x1b0b0
-			MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN	0x1b0b0
-			MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00	0x1b0b0
-			MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01	0x1b0b0
-			MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2	0x4001b031
-		>;
-	};
-
-	pinctrl_flexcan1: flexcan1grp{
-		fsl,pins = <
-			MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX	0x1b020
-			MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX	0x1b020
-		>;
-	};
-
-	pinctrl_flexcan2: flexcan2grp{
-		fsl,pins = <
-			MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX	0x1b020
-			MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX	0x1b020
-		>;
-	};
-
-	pinctrl_i2c1: i2c1grp {
-		fsl,pins = <
-			MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
-			MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
-		>;
-	};
-
-	pinctrl_i2c2: i2c2grp {
-		fsl,pins = <
-			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
-			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
-		>;
-	};
-
-	pinctrl_lcdif_dat: lcdifdatgrp {
-		fsl,pins = <
-			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x79
-			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x79
-			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x79
-			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x79
-			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x79
-			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x79
-			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x79
-			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x79
-			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x79
-			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x79
-			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x79
-			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x79
-			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x79
-			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x79
-			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x79
-			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x79
-			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x79
-			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x79
-			MX6UL_PAD_LCD_DATA18__LCDIF_DATA18  0x79
-			MX6UL_PAD_LCD_DATA19__LCDIF_DATA19  0x79
-			MX6UL_PAD_LCD_DATA20__LCDIF_DATA20  0x79
-			MX6UL_PAD_LCD_DATA21__LCDIF_DATA21  0x79
-			MX6UL_PAD_LCD_DATA22__LCDIF_DATA22  0x79
-			MX6UL_PAD_LCD_DATA23__LCDIF_DATA23  0x79
-		>;
-	};
-
-	pinctrl_lcdif_ctrl: lcdifctrlgrp {
-		fsl,pins = <
-			MX6UL_PAD_LCD_CLK__LCDIF_CLK	    0x79
-			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x79
-			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x79
-			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x79
-			/* used for lcd reset */
-			MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09  0x79
-		>;
-	};
-
-	pinctrl_qspi: qspigrp {
-		fsl,pins = <
-			MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK	0x70a1
-			MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00	0x70a1
-			MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01	0x70a1
-			MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02	0x70a1
-			MX6UL_PAD_NAND_CLE__QSPI_A_DATA03	0x70a1
-			MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B	0x70a1
-		>;
-	};
-
-	pinctrl_sai2: sai2grp {
-		fsl,pins = <
-			MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK	0x17088
-			MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC	0x17088
-			MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA	0x11088
-			MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA	0x11088
-			MX6UL_PAD_JTAG_TMS__SAI2_MCLK		0x17088
-			MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04	0x17059
-		>;
-	};
-
-	pinctrl_pwm1: pwm1grp {
-		fsl,pins = <
-			MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
-		>;
-	};
-
-	pinctrl_sim2: sim2grp {
-		fsl,pins = <
-			MX6UL_PAD_CSI_DATA03__SIM2_PORT1_PD		0xb808
-			MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK		0x31
-			MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B		0xb808
-			MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN		0xb808
-			MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD		0xb809
-			MX6UL_PAD_CSI_DATA02__GPIO4_IO23		0x3008
-		>;
-	};
-
-	pinctrl_tsc: tscgrp {
-		fsl,pins = <
-			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01		0xb0
-			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0xb0
-			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0xb0
-			MX6UL_PAD_GPIO1_IO04__GPIO1_IO04		0xb0
-		>;
-	};
-
-	pinctrl_uart1: uart1grp {
-		fsl,pins = <
-			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
-			MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
-		>;
-	};
-
-	pinctrl_uart2: uart2grp {
-		fsl,pins = <
-			MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX	0x1b0b1
-			MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX	0x1b0b1
-			MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS	0x1b0b1
-			MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS	0x1b0b1
-		>;
-	};
-
-	pinctrl_usdhc1: usdhc1grp {
-		fsl,pins = <
-			MX6UL_PAD_SD1_CMD__USDHC1_CMD     	0x17059
-			MX6UL_PAD_SD1_CLK__USDHC1_CLK     	0x10059
-			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 	0x17059
-			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 	0x17059
-			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 	0x17059
-			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 	0x17059
-			MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x17059 /* SD1 CD */
-			MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT    0x17059 /* SD1 VSELECT */
-			MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */
-		>;
-	};
-
-	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
-		fsl,pins = <
-			MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170b9
-			MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100b9
-			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
-			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
-			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
-			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
-
-		>;
-	};
-
-	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
-		fsl,pins = <
-			MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170f9
-			MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100f9
-			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
-			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
-			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
-			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
-		>;
-	};
-
-	pinctrl_usdhc2: usdhc2grp {
-		fsl,pins = <
-			MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x17059
-			MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059
-			MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
-			MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
-			MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
-			MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
-		>;
-	};
-
-	pinctrl_wdog: wdoggrp {
-		fsl,pins = <
-			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
-		>;
-	};
 };
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
new file mode 100644
index 0000000..32a0723
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+	chosen {
+		stdout-path = &uart1;
+	};
+
+	memory@80000000 {
+		reg = <0x80000000 0x20000000>;
+	};
+
+	backlight_display: backlight-display {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		status = "okay";
+	};
+
+
+	reg_sd1_vmmc: regulator-sd1-vmmc {
+		compatible = "regulator-fixed";
+		regulator-name = "VSD_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "mx6ul-wm8960";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink_master>;
+		simple-audio-card,frame-master = <&dailink_master>;
+		simple-audio-card,widgets =
+			"Microphone", "Mic Jack",
+			"Line", "Line In",
+			"Line", "Line Out",
+			"Speaker", "Speaker",
+			"Headphone", "Headphone Jack";
+		simple-audio-card,routing =
+			"Headphone Jack", "HP_L",
+			"Headphone Jack", "HP_R",
+			"Speaker", "SPK_LP",
+			"Speaker", "SPK_LN",
+			"Speaker", "SPK_RP",
+			"Speaker", "SPK_RN",
+			"LINPUT1", "Mic Jack",
+			"LINPUT3", "Mic Jack",
+			"RINPUT1", "Mic Jack",
+			"RINPUT2", "Mic Jack";
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai2>;
+		};
+
+		dailink_master: simple-audio-card,codec {
+			sound-dai = <&codec>;
+			clocks = <&clks IMX6UL_CLK_SAI2>;
+		};
+	};
+
+	panel {
+		compatible = "innolux,at043tn24";
+		backlight = <&backlight_display>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display_out>;
+			};
+		};
+	};
+};
+
+&clks {
+	assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+	assigned-clock-rates = <786432000>;
+};
+
+&i2c2 {
+	clock_frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "okay";
+
+	codec: wm8960@1a {
+		#sound-dai-cells = <0>;
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+		wlf,shared-lrclk;
+	};
+};
+
+&fec1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet1>;
+	phy-mode = "rmii";
+	phy-handle = <&ethphy0>;
+	status = "okay";
+};
+
+&fec2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet2>;
+	phy-mode = "rmii";
+	phy-handle = <&ethphy1>;
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy@2 {
+			reg = <2>;
+			micrel,led-mode = <1>;
+			clocks = <&clks IMX6UL_CLK_ENET_REF>;
+			clock-names = "rmii-ref";
+		};
+
+		ethphy1: ethernet-phy@1 {
+			reg = <1>;
+			micrel,led-mode = <1>;
+			clocks = <&clks IMX6UL_CLK_ENET2_REF>;
+			clock-names = "rmii-ref";
+		};
+	};
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	mag3110@e {
+		compatible = "fsl,mag3110";
+		reg = <0x0e>;
+	};
+};
+
+&lcdif {
+	assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lcdif_dat
+		     &pinctrl_lcdif_ctrl>;
+	status = "okay";
+
+	port {
+		display_out: endpoint {
+			remote-endpoint = <&panel_in>;
+		};
+	};
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	status = "okay";
+};
+
+&qspi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi>;
+	status = "okay";
+
+	flash0: n25q256a@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,n25q256a";
+		spi-max-frequency = <29000000>;
+		reg = <0>;
+	};
+};
+
+&sai2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai2>;
+	assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+			  <&clks IMX6UL_CLK_SAI2>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+	assigned-clock-rates = <0>, <12288000>;
+	fsl,sai-mclk-direction-output;
+	status = "okay";
+};
+
+&snvs_poweroff {
+	status = "okay";
+};
+
+&tsc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_tsc>;
+	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	measure-delay-time = <0xffff>;
+	pre-charge-time = <0xfff>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&usbotg1 {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbotg2 {
+	dr_mode = "host";
+	disable-over-current;
+	status = "okay";
+};
+
+&usbphy1 {
+	fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+	fsl,tx-d-cal = <106>;
+};
+
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+	keep-power-in-suspend;
+	wakeup-source;
+	vmmc-supply = <&reg_sd1_vmmc>;
+	status = "okay";
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	no-1-8-v;
+	keep-power-in-suspend;
+	wakeup-source;
+	status = "okay";
+};
+
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	fsl,ext-reset-output;
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+
+	pinctrl_csi1: csi1grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_MCLK__CSI_MCLK		0x1b088
+			MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK	0x1b088
+			MX6UL_PAD_CSI_VSYNC__CSI_VSYNC		0x1b088
+			MX6UL_PAD_CSI_HSYNC__CSI_HSYNC		0x1b088
+			MX6UL_PAD_CSI_DATA00__CSI_DATA02	0x1b088
+			MX6UL_PAD_CSI_DATA01__CSI_DATA03	0x1b088
+			MX6UL_PAD_CSI_DATA02__CSI_DATA04	0x1b088
+			MX6UL_PAD_CSI_DATA03__CSI_DATA05	0x1b088
+			MX6UL_PAD_CSI_DATA04__CSI_DATA06	0x1b088
+			MX6UL_PAD_CSI_DATA05__CSI_DATA07	0x1b088
+			MX6UL_PAD_CSI_DATA06__CSI_DATA08	0x1b088
+			MX6UL_PAD_CSI_DATA07__CSI_DATA09	0x1b088
+		>;
+	};
+
+	pinctrl_enet1: enet1grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN	0x1b0b0
+			MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER	0x1b0b0
+			MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00	0x1b0b0
+			MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01	0x1b0b0
+			MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN	0x1b0b0
+			MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00	0x1b0b0
+			MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01	0x1b0b0
+			MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1	0x4001b031
+		>;
+	};
+
+	pinctrl_enet2: enet2grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO07__ENET2_MDC		0x1b0b0
+			MX6UL_PAD_GPIO1_IO06__ENET2_MDIO	0x1b0b0
+			MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN	0x1b0b0
+			MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER	0x1b0b0
+			MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00	0x1b0b0
+			MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01	0x1b0b0
+			MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN	0x1b0b0
+			MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00	0x1b0b0
+			MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01	0x1b0b0
+			MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2	0x4001b031
+		>;
+	};
+
+	pinctrl_flexcan1: flexcan1grp{
+		fsl,pins = <
+			MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX	0x1b020
+			MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX	0x1b020
+		>;
+	};
+
+	pinctrl_flexcan2: flexcan2grp{
+		fsl,pins = <
+			MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX	0x1b020
+			MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX	0x1b020
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
+			MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
+			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
+		>;
+	};
+
+	pinctrl_lcdif_dat: lcdifdatgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x79
+			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x79
+			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x79
+			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x79
+			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x79
+			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x79
+			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x79
+			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x79
+			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x79
+			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x79
+			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x79
+			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x79
+			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x79
+			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x79
+			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x79
+			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x79
+			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x79
+			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x79
+			MX6UL_PAD_LCD_DATA18__LCDIF_DATA18  0x79
+			MX6UL_PAD_LCD_DATA19__LCDIF_DATA19  0x79
+			MX6UL_PAD_LCD_DATA20__LCDIF_DATA20  0x79
+			MX6UL_PAD_LCD_DATA21__LCDIF_DATA21  0x79
+			MX6UL_PAD_LCD_DATA22__LCDIF_DATA22  0x79
+			MX6UL_PAD_LCD_DATA23__LCDIF_DATA23  0x79
+		>;
+	};
+
+	pinctrl_lcdif_ctrl: lcdifctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_CLK__LCDIF_CLK	    0x79
+			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x79
+			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x79
+			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x79
+			/* used for lcd reset */
+			MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09  0x79
+		>;
+	};
+
+	pinctrl_qspi: qspigrp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK	0x70a1
+			MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00	0x70a1
+			MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01	0x70a1
+			MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02	0x70a1
+			MX6UL_PAD_NAND_CLE__QSPI_A_DATA03	0x70a1
+			MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B	0x70a1
+		>;
+	};
+
+	pinctrl_sai2: sai2grp {
+		fsl,pins = <
+			MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK	0x17088
+			MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC	0x17088
+			MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA	0x11088
+			MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA	0x11088
+			MX6UL_PAD_JTAG_TMS__SAI2_MCLK		0x17088
+			MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04	0x17059
+		>;
+	};
+
+	pinctrl_pwm1: pwm1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
+		>;
+	};
+
+	pinctrl_sim2: sim2grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_DATA03__SIM2_PORT1_PD		0xb808
+			MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK		0x31
+			MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B		0xb808
+			MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN		0xb808
+			MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD		0xb809
+			MX6UL_PAD_CSI_DATA02__GPIO4_IO23		0x3008
+		>;
+	};
+
+	pinctrl_tsc: tscgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01		0xb0
+			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0xb0
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0xb0
+			MX6UL_PAD_GPIO1_IO04__GPIO1_IO04		0xb0
+		>;
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+			MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+		>;
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX	0x1b0b1
+			MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX	0x1b0b1
+			MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS	0x1b0b1
+			MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS	0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD     	0x17059
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK     	0x10059
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 	0x17059
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 	0x17059
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 	0x17059
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 	0x17059
+			MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x17059 /* SD1 CD */
+			MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT    0x17059 /* SD1 VSELECT */
+			MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170b9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100b9
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
+
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170f9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100f9
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
+		>;
+	};
+
+	pinctrl_usdhc2: usdhc2grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x17059
+			MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059
+			MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+			MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+			MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+			MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+		>;
+	};
+
+	pinctrl_wdog: wdoggrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6ul-geam.dts b/arch/arm/boot/dts/imx6ul-geam.dts
index 571eea7..d81d20f 100644
--- a/arch/arm/boot/dts/imx6ul-geam.dts
+++ b/arch/arm/boot/dts/imx6ul-geam.dts
@@ -50,7 +50,7 @@
 	model = "Engicam GEAM6UL Starter Kit";
 	compatible = "engicam,imx6ul-geam", "fsl,imx6ul";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x08000000>;
 	};
 
@@ -181,6 +181,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		clocks = <&clks IMX6UL_CLK_OSC>;
 		clock-names = "mclk";
 		VDDA-supply = <&reg_3p3v>;
diff --git a/arch/arm/boot/dts/imx6ul-isiot.dtsi b/arch/arm/boot/dts/imx6ul-isiot.dtsi
index 950fb28..921e12c 100644
--- a/arch/arm/boot/dts/imx6ul-isiot.dtsi
+++ b/arch/arm/boot/dts/imx6ul-isiot.dtsi
@@ -45,7 +45,7 @@
 #include "imx6ul.dtsi"
 
 / {
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 
@@ -142,6 +142,7 @@
 	sgtl5000: codec@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		#sound-dai-cells = <0>;
 		clocks = <&clks IMX6UL_CLK_OSC>;
 		clock-names = "mclk";
 		VDDA-supply = <&reg_3p3v>;
diff --git a/arch/arm/boot/dts/imx6ul-litesom.dtsi b/arch/arm/boot/dts/imx6ul-litesom.dtsi
index 039721d..8f775f6 100644
--- a/arch/arm/boot/dts/imx6ul-litesom.dtsi
+++ b/arch/arm/boot/dts/imx6ul-litesom.dtsi
@@ -47,7 +47,7 @@
 	model = "Grinn i.MX6UL liteSOM";
 	compatible = "grinn,imx6ul-litesom", "fsl,imx6ul";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6ul-opos6ul.dtsi b/arch/arm/boot/dts/imx6ul-opos6ul.dtsi
index aec5ccc..a031bee 100644
--- a/arch/arm/boot/dts/imx6ul-opos6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul-opos6ul.dtsi
@@ -48,7 +48,7 @@
 #include "imx6ul.dtsi"
 
 / {
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0>; /* will be filled by U-Boot */
 	};
 
diff --git a/arch/arm/boot/dts/imx6ul-pico-hobbit.dts b/arch/arm/boot/dts/imx6ul-pico-hobbit.dts
index 3bf26eb..47682b8 100644
--- a/arch/arm/boot/dts/imx6ul-pico-hobbit.dts
+++ b/arch/arm/boot/dts/imx6ul-pico-hobbit.dts
@@ -51,7 +51,7 @@
 	model = "Technexion Pico i.MX6UL Board";
 	compatible = "technexion,imx6ul-pico-hobbit", "fsl,imx6ul";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x10000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx6ul-pinfunc.h b/arch/arm/boot/dts/imx6ul-pinfunc.h
index 0034eeb..7b9a4dc 100644
--- a/arch/arm/boot/dts/imx6ul-pinfunc.h
+++ b/arch/arm/boot/dts/imx6ul-pinfunc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright 2014 - 2015 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -34,14 +34,14 @@
 #define MX6UL_PAD_JTAG_MOD__ENET1_REF_CLK_25M		0x0044 0x02d0 0x0000 3 0
 #define MX6UL_PAD_JTAG_MOD__CCM_PMIC_RDY		0x0044 0x02d0 0x04c0 4 0
 #define MX6UL_PAD_JTAG_MOD__GPIO1_IO10			0x0044 0x02d0 0x0000 5 0
-#define MX6UL_PAD_JTAG_MOD__SDMA_EXT_EVENT00		0x0044 0x02d0 0x0000 6 0
+#define MX6UL_PAD_JTAG_MOD__SDMA_EXT_EVENT00		0x0044 0x02d0 0x0610 6 0
 #define MX6UL_PAD_JTAG_TMS__SJC_TMS			0x0048 0x02d4 0x0000 0 0
 #define MX6UL_PAD_JTAG_TMS__GPT2_CAPTURE1		0x0048 0x02d4 0x0598 1 0
-#define MX6UL_PAD_JTAG_TMS__SAI2_MCLK			0x0048 0x02d4 0x0000 2 0
+#define MX6UL_PAD_JTAG_TMS__SAI2_MCLK			0x0048 0x02d4 0x05f0 2 0
 #define MX6UL_PAD_JTAG_TMS__CCM_CLKO1			0x0048 0x02d4 0x0000 3 0
 #define MX6UL_PAD_JTAG_TMS__CCM_WAIT			0x0048 0x02d4 0x0000 4 0
 #define MX6UL_PAD_JTAG_TMS__GPIO1_IO11			0x0048 0x02d4 0x0000 5 0
-#define MX6UL_PAD_JTAG_TMS__SDMA_EXT_EVENT01		0x0048 0x02d4 0x0000 6 0
+#define MX6UL_PAD_JTAG_TMS__SDMA_EXT_EVENT01		0x0048 0x02d4 0x0614 6 0
 #define MX6UL_PAD_JTAG_TMS__EPIT1_OUT			0x0048 0x02d4 0x0000 8 0
 #define MX6UL_PAD_JTAG_TDO__SJC_TDO			0x004c 0x02d8 0x0000 0 0
 #define MX6UL_PAD_JTAG_TDO__GPT2_CAPTURE2		0x004c 0x02d8 0x059c 1 0
@@ -63,12 +63,14 @@
 #define MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA		0x0054 0x02e0 0x05f4 2 0
 #define MX6UL_PAD_JTAG_TCK__PWM7_OUT			0x0054 0x02e0 0x0000 4 0
 #define MX6UL_PAD_JTAG_TCK__GPIO1_IO14			0x0054 0x02e0 0x0000 5 0
+#define MX6UL_PAD_JTAG_TCK__OSC32K_32K_OUT			0x0054 0x02e0 0x0000 6 0
 #define MX6UL_PAD_JTAG_TCK__SIM2_POWER_FAIL		0x0054 0x02e0 0x0000 8 0
 #define MX6UL_PAD_JTAG_TRST_B__SJC_TRSTB		0x0058 0x02e4 0x0000 0 0
 #define MX6UL_PAD_JTAG_TRST_B__GPT2_COMPARE3		0x0058 0x02e4 0x0000 1 0
 #define MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA		0x0058 0x02e4 0x0000 2 0
 #define MX6UL_PAD_JTAG_TRST_B__PWM8_OUT			0x0058 0x02e4 0x0000 4 0
 #define MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15		0x0058 0x02e4 0x0000 5 0
+#define MX6UL_PAD_JTAG_TRST_B__REF_CLK_24M		0x0058 0x02e4 0x0000 6 0
 #define MX6UL_PAD_JTAG_TRST_B__CAAM_RNG_OSC_OBS		0x0058 0x02e4 0x0000 8 0
 #define MX6UL_PAD_GPIO1_IO00__I2C2_SCL			0x005c 0x02e8 0x05ac 0 1
 #define MX6UL_PAD_GPIO1_IO00__GPT1_CAPTURE1		0x005c 0x02e8 0x058c 1 0
@@ -94,22 +96,24 @@
 #define MX6UL_PAD_GPIO1_IO02__ENET1_REF_CLK_25M		0x0064 0x02f0 0x0000 3 0
 #define MX6UL_PAD_GPIO1_IO02__USDHC1_WP			0x0064 0x02f0 0x066c 4 0
 #define MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0x0064 0x02f0 0x0000 5 0
-#define MX6UL_PAD_GPIO1_IO02__SDMA_EXT_EVENT00		0x0064 0x02f0 0x0000 6 0
+#define MX6UL_PAD_GPIO1_IO02__SDMA_EXT_EVENT00		0x0064 0x02f0 0x0610 6 1
 #define MX6UL_PAD_GPIO1_IO02__SRC_ANY_PU_RESET		0x0064 0x02f0 0x0000 7 0
 #define MX6UL_PAD_GPIO1_IO02__UART1_DCE_TX		0x0064 0x02f0 0x0000 8 0
 #define MX6UL_PAD_GPIO1_IO02__UART1_DTE_RX		0x0064 0x02f0 0x0624 8 0
 #define MX6UL_PAD_GPIO1_IO03__I2C1_SDA			0x0068 0x02f4 0x05a8 0 1
 #define MX6UL_PAD_GPIO1_IO03__GPT1_COMPARE3		0x0068 0x02f4 0x0000 1 0
 #define MX6UL_PAD_GPIO1_IO03__USB_OTG2_OC		0x0068 0x02f4 0x0660 2 0
+#define MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT		0x0068 0x02f4 0x0000 3 0
 #define MX6UL_PAD_GPIO1_IO03__USDHC1_CD_B		0x0068 0x02f4 0x0668 4 0
 #define MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0x0068 0x02f4 0x0000 5 0
-#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_eXT_CLK		0x0068 0x02f4 0x0000 6 0
+#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_EXT_CLK		0x0068 0x02f4 0x0000 6 0
 #define MX6UL_PAD_GPIO1_IO03__SRC_TESTER_ACK		0x0068 0x02f4 0x0000 7 0
-#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX		0x0068 0x02f4 0x0000 8 0
 #define MX6UL_PAD_GPIO1_IO03__UART1_DCE_RX		0x0068 0x02f4 0x0624 8 1
+#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX		0x0068 0x02f4 0x0000 8 0
 #define MX6UL_PAD_GPIO1_IO04__ENET1_REF_CLK1		0x006c 0x02f8 0x0574 0 1
 #define MX6UL_PAD_GPIO1_IO04__PWM3_OUT			0x006c 0x02f8 0x0000 1 0
 #define MX6UL_PAD_GPIO1_IO04__USB_OTG1_PWR		0x006c 0x02f8 0x0000 2 0
+#define MX6UL_PAD_GPIO1_IO04__REF_CLK_24M		0x006c 0x02f8 0x0000 3 0
 #define MX6UL_PAD_GPIO1_IO04__USDHC1_RESET_B		0x006c 0x02f8 0x0000 4 0
 #define MX6UL_PAD_GPIO1_IO04__GPIO1_IO04		0x006c 0x02f8 0x0000 5 0
 #define MX6UL_PAD_GPIO1_IO04__ENET2_1588_EVENT0_IN	0x006c 0x02f8 0x0000 6 0
@@ -200,7 +204,7 @@
 #define MX6UL_PAD_UART2_TX_DATA__CSI_DATA06		0x0094 0x0320 0x04dc 3 0
 #define MX6UL_PAD_UART2_TX_DATA__GPT1_CAPTURE1		0x0094 0x0320 0x058c 4 1
 #define MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20		0x0094 0x0320 0x0000 5 0
-#define MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0		0x0094 0x0320 0x0000 8 0
+#define MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0		0x0094 0x0320 0x0560 8 0
 #define MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX		0x0098 0x0324 0x062c 0 1
 #define MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX		0x0098 0x0324 0x0000 0 0
 #define MX6UL_PAD_UART2_RX_DATA__ENET1_TDATA03		0x0098 0x0324 0x0000 1 0
@@ -232,7 +236,7 @@
 #define MX6UL_PAD_UART3_TX_DATA__UART3_DTE_RX		0x00a4 0x0330 0x0634 0 0
 #define MX6UL_PAD_UART3_TX_DATA__ENET2_RDATA02		0x00a4 0x0330 0x0000 1 0
 #define MX6UL_PAD_UART3_TX_DATA__SIM1_PORT0_PD		0x00a4 0x0330 0x0000 2 0
-#define MX6UL_PAD_UART3_TX_DATA__CSI_DATA01		0x00a4 0x0330 0x0000 3 0
+#define MX6UL_PAD_UART3_TX_DATA__CSI_DATA01		0x00a4 0x0330 0x04d4 3 0
 #define MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS		0x00a4 0x0330 0x0000 4 0
 #define MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS		0x00a4 0x0330 0x0628 4 2
 #define MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24		0x00a4 0x0330 0x0000 5 0
@@ -242,7 +246,7 @@
 #define MX6UL_PAD_UART3_RX_DATA__UART3_DTE_TX		0x00a8 0x0334 0x0000 0 0
 #define MX6UL_PAD_UART3_RX_DATA__ENET2_RDATA03		0x00a8 0x0334 0x0000 1 0
 #define MX6UL_PAD_UART3_RX_DATA__SIM2_PORT0_PD		0x00a8 0x0334 0x0000 2 0
-#define MX6UL_PAD_UART3_RX_DATA__CSI_DATA00		0x00a8 0x0334 0x0000 3 0
+#define MX6UL_PAD_UART3_RX_DATA__CSI_DATA00		0x00a8 0x0334 0x04d0 3 0
 #define MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS		0x00a8 0x0334 0x0628 4 3
 #define MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS		0x00a8 0x0334 0x0000 4 0
 #define MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25		0x00a8 0x0334 0x0000 5 0
@@ -251,7 +255,7 @@
 #define MX6UL_PAD_UART3_CTS_B__UART3_DTE_RTS		0x00ac 0x0338 0x0630 0 0
 #define MX6UL_PAD_UART3_CTS_B__ENET2_RX_CLK		0x00ac 0x0338 0x0000 1 0
 #define MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX		0x00ac 0x0338 0x0000 2 0
-#define MX6UL_PAD_UART3_CTS_B__CSI_DATA10		0x00ac 0x0338 0x0000 3 0
+#define MX6UL_PAD_UART3_CTS_B__CSI_DATA10		0x00ac 0x0338 0x04ec 3 0
 #define MX6UL_PAD_UART3_CTS_B__ENET1_1588_EVENT1_IN	0x00ac 0x0338 0x0000 4 0
 #define MX6UL_PAD_UART3_CTS_B__GPIO1_IO26		0x00ac 0x0338 0x0000 5 0
 #define MX6UL_PAD_UART3_CTS_B__EPIT2_OUT		0x00ac 0x0338 0x0000 8 0
@@ -259,7 +263,7 @@
 #define MX6UL_PAD_UART3_RTS_B__UART3_DTE_CTS		0x00b0 0x033c 0x0000 0 0
 #define MX6UL_PAD_UART3_RTS_B__ENET2_TX_ER		0x00b0 0x033c 0x0000 1 0
 #define MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX		0x00b0 0x033c 0x0584 2 0
-#define MX6UL_PAD_UART3_RTS_B__CSI_DATA11		0x00b0 0x033c 0x0000 3 0
+#define MX6UL_PAD_UART3_RTS_B__CSI_DATA11		0x00b0 0x033c 0x04f0 3 0
 #define MX6UL_PAD_UART3_RTS_B__ENET1_1588_EVENT1_OUT	0x00b0 0x033c 0x0000 4 0
 #define MX6UL_PAD_UART3_RTS_B__GPIO1_IO27		0x00b0 0x033c 0x0000 5 0
 #define MX6UL_PAD_UART3_RTS_B__WDOG1_WDOG_B		0x00b0 0x033c 0x0000 8 0
@@ -267,7 +271,7 @@
 #define MX6UL_PAD_UART4_TX_DATA__UART4_DTE_RX		0x00b4 0x0340 0x063c 0 0
 #define MX6UL_PAD_UART4_TX_DATA__ENET2_TDATA02		0x00b4 0x0340 0x0000 1 0
 #define MX6UL_PAD_UART4_TX_DATA__I2C1_SCL		0x00b4 0x0340 0x05a4 2 1
-#define MX6UL_PAD_UART4_TX_DATA__CSI_DATA12		0x00b4 0x0340 0x0000 3 0
+#define MX6UL_PAD_UART4_TX_DATA__CSI_DATA12		0x00b4 0x0340 0x04f4 3 0
 #define MX6UL_PAD_UART4_TX_DATA__CSU_CSU_ALARM_AUT02	0x00b4 0x0340 0x0000 4 0
 #define MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28		0x00b4 0x0340 0x0000 5 0
 #define MX6UL_PAD_UART4_TX_DATA__ECSPI2_SCLK		0x00b4 0x0340 0x0544 8 1
@@ -275,23 +279,23 @@
 #define MX6UL_PAD_UART4_RX_DATA__UART4_DTE_TX		0x00b8 0x0344 0x0000 0 0
 #define MX6UL_PAD_UART4_RX_DATA__ENET2_TDATA03		0x00b8 0x0344 0x0000 1 0
 #define MX6UL_PAD_UART4_RX_DATA__I2C1_SDA		0x00b8 0x0344 0x05a8 2 2
-#define MX6UL_PAD_UART4_RX_DATA__CSI_DATA13		0x00b8 0x0344 0x0000 3 0
+#define MX6UL_PAD_UART4_RX_DATA__CSI_DATA13		0x00b8 0x0344 0x04f8 3 0
 #define MX6UL_PAD_UART4_RX_DATA__CSU_CSU_ALARM_AUT01	0x00b8 0x0344 0x0000 4 0
 #define MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29		0x00b8 0x0344 0x0000 5 0
-#define MX6UL_PAD_UART4_RX_DATA__ECSPI2_SS0		0x00b8 0x0344 0x0000 8 0
+#define MX6UL_PAD_UART4_RX_DATA__ECSPI2_SS0		0x00b8 0x0344 0x0550 8 1
 #define MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30		0x00bc 0x0348 0x0000 5 0
 #define MX6UL_PAD_UART5_TX_DATA__ECSPI2_MOSI		0x00bc 0x0348 0x054c 8 0
 #define MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX		0x00bc 0x0348 0x0000 0 0
 #define MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX		0x00bc 0x0348 0x0644 0 4
 #define MX6UL_PAD_UART5_TX_DATA__ENET2_CRS		0x00bc 0x0348 0x0000 1 0
 #define MX6UL_PAD_UART5_TX_DATA__I2C2_SCL		0x00bc 0x0348 0x05ac 2 2
-#define MX6UL_PAD_UART5_TX_DATA__CSI_DATA14		0x00bc 0x0348 0x0000 3 0
+#define MX6UL_PAD_UART5_TX_DATA__CSI_DATA14		0x00bc 0x0348 0x04fc 3 0
 #define MX6UL_PAD_UART5_TX_DATA__CSU_CSU_ALARM_AUT00	0x00bc 0x0348 0x0000 4 0
 #define MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX		0x00c0 0x034c 0x0644 0 5
 #define MX6UL_PAD_UART5_RX_DATA__UART5_DTE_TX		0x00c0 0x034c 0x0000 0 0
 #define MX6UL_PAD_UART5_RX_DATA__ENET2_COL		0x00c0 0x034c 0x0000 1 0
 #define MX6UL_PAD_UART5_RX_DATA__I2C2_SDA		0x00c0 0x034c 0x05b0 2 2
-#define MX6UL_PAD_UART5_RX_DATA__CSI_DATA15		0x00c0 0x034c 0x0000 3 0
+#define MX6UL_PAD_UART5_RX_DATA__CSI_DATA15		0x00c0 0x034c 0x0500 3 0
 #define MX6UL_PAD_UART5_RX_DATA__CSU_CSU_INT_DEB	0x00c0 0x034c 0x0000 4 0
 #define MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31		0x00c0 0x034c 0x0000 5 0
 #define MX6UL_PAD_UART5_RX_DATA__ECSPI2_MISO		0x00c0 0x034c 0x0548 8 1
@@ -299,59 +303,61 @@
 #define MX6UL_PAD_ENET1_RX_DATA0__UART4_DCE_RTS		0x00c4 0x0350 0x0638 1 0
 #define MX6UL_PAD_ENET1_RX_DATA0__UART4_DTE_CTS		0x00c4 0x0350 0x0000 1 0
 #define MX6UL_PAD_ENET1_RX_DATA0__PWM1_OUT		0x00c4 0x0350 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_DATA0__CSI_DATA16		0x00c4 0x0350 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_DATA0__CSI_DATA16		0x00c4 0x0350 0x0504 3 0
 #define MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX		0x00c4 0x0350 0x0000 4 0
 #define MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00		0x00c4 0x0350 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_DATA0__KPP_ROW00		0x00c4 0x0350 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_DATA0__KPP_ROW00		0x00c4 0x0350 0x05d0 6 0
 #define MX6UL_PAD_ENET1_RX_DATA0__USDHC1_LCTL		0x00c4 0x0350 0x0000 8 0
 #define MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01		0x00c8 0x0354 0x0000 0 0
 #define MX6UL_PAD_ENET1_RX_DATA1__UART4_DCE_CTS		0x00c8 0x0354 0x0000 1 0
 #define MX6UL_PAD_ENET1_RX_DATA1__UART4_DTE_RTS		0x00c8 0x0354 0x0638 1 1
 #define MX6UL_PAD_ENET1_RX_DATA1__PWM2_OUT		0x00c8 0x0354 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_DATA1__CSI_DATA17		0x00c8 0x0354 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_DATA1__CSI_DATA17		0x00c8 0x0354 0x0508 3 0
 #define MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX		0x00c8 0x0354 0x0584 4 1
 #define MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01		0x00c8 0x0354 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_DATA1__KPP_COL00		0x00c8 0x0354 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_DATA1__KPP_COL00		0x00c8 0x0354 0x05c4 6 0
 #define MX6UL_PAD_ENET1_RX_DATA1__USDHC2_LCTL		0x00c8 0x0354 0x0000 8 0
 #define MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN		0x00cc 0x0358 0x0000 0 0
 #define MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS		0x00cc 0x0358 0x0640 1 3
 #define MX6UL_PAD_ENET1_RX_EN__UART5_DTE_CTS		0x00cc 0x0358 0x0000 1 0
-#define MX6UL_PAD_ENET1_RX_EN__CSI_DATA18		0x00cc 0x0358 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_EN__OSC32K_32K_OUT		0x00cc 0x0358 0x0000 2 0
+#define MX6UL_PAD_ENET1_RX_EN__CSI_DATA18		0x00cc 0x0358 0x050c 3 0
 #define MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX		0x00cc 0x0358 0x0000 4 0
 #define MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02		0x00cc 0x0358 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_EN__KPP_ROW01		0x00cc 0x0358 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_EN__KPP_ROW01		0x00cc 0x0358 0x05d4 6 0
 #define MX6UL_PAD_ENET1_RX_EN__USDHC1_VSELECT		0x00cc 0x0358 0x0000 8 0
 #define MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00		0x00d0 0x035c 0x0000 0 0
 #define MX6UL_PAD_ENET1_TX_DATA0__UART5_DCE_CTS		0x00d0 0x035c 0x0000 1 0
 #define MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS		0x00d0 0x035c 0x0640 1 4
-#define MX6UL_PAD_ENET1_TX_DATA0__CSI_DATA19		0x00d0 0x035c 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_DATA0__REF_CLK_24M		0x00d0 0x035c 0x0000 2 0
+#define MX6UL_PAD_ENET1_TX_DATA0__CSI_DATA19		0x00d0 0x035c 0x0510 3 0
 #define MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX		0x00d0 0x035c 0x0588 4 1
 #define MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03		0x00d0 0x035c 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_DATA0__KPP_COL01		0x00d0 0x035c 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_DATA0__KPP_COL01		0x00d0 0x035c 0x05c8 6 0
 #define MX6UL_PAD_ENET1_TX_DATA0__USDHC2_VSELECT	0x00d0 0x035c 0x0000 8 0
 #define MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01		0x00d4 0x0360 0x0000 0 0
 #define MX6UL_PAD_ENET1_TX_DATA1__UART6_DCE_CTS		0x00d4 0x0360 0x0000 1 0
 #define MX6UL_PAD_ENET1_TX_DATA1__UART6_DTE_RTS		0x00d4 0x0360 0x0648 1 2
 #define MX6UL_PAD_ENET1_TX_DATA1__PWM5_OUT		0x00d4 0x0360 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_DATA1__CSI_DATA20		0x00d4 0x0360 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_DATA1__CSI_DATA20		0x00d4 0x0360 0x0514 3 0
 #define MX6UL_PAD_ENET1_TX_DATA1__ENET2_MDIO		0x00d4 0x0360 0x0580 4 1
 #define MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04		0x00d4 0x0360 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_DATA1__KPP_ROW02		0x00d4 0x0360 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_DATA1__KPP_ROW02		0x00d4 0x0360 0x05d8 6 0
 #define MX6UL_PAD_ENET1_TX_DATA1__WDOG1_WDOG_RST_B_DEB	0x00d4 0x0360 0x0000 8 0
 #define MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN		0x00d8 0x0364 0x0000 0 0
 #define MX6UL_PAD_ENET1_TX_EN__UART6_DCE_RTS		0x00d8 0x0364 0x0648 1 3
 #define MX6UL_PAD_ENET1_TX_EN__UART6_DTE_CTS		0x00d8 0x0364 0x0000 1 0
 #define MX6UL_PAD_ENET1_TX_EN__PWM6_OUT			0x00d8 0x0364 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_EN__CSI_DATA21		0x00d8 0x0364 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_EN__CSI_DATA21		0x00d8 0x0364 0x0518 3 0
 #define MX6UL_PAD_ENET1_TX_EN__ENET2_MDC		0x00d8 0x0364 0x0000 4 0
 #define MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05		0x00d8 0x0364 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_EN__KPP_COL02		0x00d8 0x0364 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_EN__KPP_COL02		0x00d8 0x0364 0x05cc 6 0
 #define MX6UL_PAD_ENET1_TX_EN__WDOG2_WDOG_RST_B_DEB	0x00d8 0x0364 0x0000 8 0
 #define MX6UL_PAD_ENET1_TX_CLK__ENET1_TX_CLK		0x00dc 0x0368 0x0000 0 0
 #define MX6UL_PAD_ENET1_TX_CLK__UART7_DCE_CTS		0x00dc 0x0368 0x0000 1 0
 #define MX6UL_PAD_ENET1_TX_CLK__UART7_DTE_RTS		0x00dc 0x0368 0x0650 1 0
 #define MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT		0x00dc 0x0368 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_CLK__CSI_DATA22		0x00dc 0x0368 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_CLK__CSI_DATA22		0x00dc 0x0368 0x051c 3 0
 #define MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1		0x00dc 0x0368 0x0574 4 2
 #define MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06		0x00dc 0x0368 0x0000 5 0
 #define MX6UL_PAD_ENET1_TX_CLK__KPP_ROW03		0x00dc 0x0368 0x0000 6 0
@@ -360,7 +366,7 @@
 #define MX6UL_PAD_ENET1_RX_ER__UART7_DCE_RTS		0x00e0 0x036c 0x0650 1 1
 #define MX6UL_PAD_ENET1_RX_ER__UART7_DTE_CTS		0x00e0 0x036c 0x0000 1 0
 #define MX6UL_PAD_ENET1_RX_ER__PWM8_OUT			0x00e0 0x036c 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_ER__CSI_DATA23		0x00e0 0x036c 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_ER__CSI_DATA23		0x00e0 0x036c 0x0520 3 0
 #define MX6UL_PAD_ENET1_RX_ER__EIM_CRE			0x00e0 0x036c 0x0000 4 0
 #define MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07		0x00e0 0x036c 0x0000 5 0
 #define MX6UL_PAD_ENET1_RX_ER__KPP_COL03		0x00e0 0x036c 0x0000 6 0
@@ -377,7 +383,7 @@
 #define MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01		0x00e8 0x0374 0x0000 0 0
 #define MX6UL_PAD_ENET2_RX_DATA1__UART6_DCE_RX		0x00e8 0x0374 0x064c 1 2
 #define MX6UL_PAD_ENET2_RX_DATA1__UART6_DTE_TX		0x00e8 0x0374 0x0000 1 0
-#define MX6UL_PAD_ENET2_RX_DATA1__SIM1_PORT0_cLK	0x00e8 0x0374 0x0000 2 0
+#define MX6UL_PAD_ENET2_RX_DATA1__SIM1_PORT0_CLK	0x00e8 0x0374 0x0000 2 0
 #define MX6UL_PAD_ENET2_RX_DATA1__I2C3_SDA		0x00e8 0x0374 0x05b8 3 1
 #define MX6UL_PAD_ENET2_RX_DATA1__ENET1_MDC		0x00e8 0x0374 0x0000 4 0
 #define MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09		0x00e8 0x0374 0x0000 5 0
@@ -400,6 +406,7 @@
 #define MX6UL_PAD_ENET2_TX_DATA0__EIM_EB_B02		0x00f0 0x037c 0x0000 4 0
 #define MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11		0x00f0 0x037c 0x0000 5 0
 #define MX6UL_PAD_ENET2_TX_DATA0__KPP_COL05		0x00f0 0x037c 0x0000 6 0
+#define MX6UL_PAD_ENET2_TX_DATA0__REF_CLK_24M		0x00f0 0x037c 0x0000 8 0
 #define MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01		0x00f4 0x0380 0x0000 0 0
 #define MX6UL_PAD_ENET2_TX_DATA1__UART8_DCE_TX		0x00f4 0x0380 0x0000 1 0
 #define MX6UL_PAD_ENET2_TX_DATA1__UART8_DTE_RX		0x00f4 0x0380 0x065c 1 0
@@ -412,7 +419,7 @@
 #define MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN		0x00f8 0x0384 0x0000 0 0
 #define MX6UL_PAD_ENET2_TX_EN__UART8_DCE_RX		0x00f8 0x0384 0x065c 1 1
 #define MX6UL_PAD_ENET2_TX_EN__UART8_DTE_TX		0x00f8 0x0384 0x0000 1 0
-#define MX6UL_PAD_ENET2_TX_EN__SIM2_PORT0_cLK		0x00f8 0x0384 0x0000 2 0
+#define MX6UL_PAD_ENET2_TX_EN__SIM2_PORT0_CLK		0x00f8 0x0384 0x0000 2 0
 #define MX6UL_PAD_ENET2_TX_EN__ECSPI4_MOSI		0x00f8 0x0384 0x056c 3 0
 #define MX6UL_PAD_ENET2_TX_EN__EIM_ACLK_FREERUN		0x00f8 0x0384 0x0000 4 0
 #define MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13		0x00f8 0x0384 0x0000 5 0
@@ -431,7 +438,7 @@
 #define MX6UL_PAD_ENET2_RX_ER__UART8_DCE_RTS		0x0100 0x038c 0x0658 1 1
 #define MX6UL_PAD_ENET2_RX_ER__UART8_DTE_CTS		0x0100 0x038c 0x0000 1 0
 #define MX6UL_PAD_ENET2_RX_ER__SIM2_PORT0_SVEN		0x0100 0x038c 0x0000 2 0
-#define MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0		0x0100 0x038c 0x0000 3 0
+#define MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0		0x0100 0x038c 0x0570 3 0
 #define MX6UL_PAD_ENET2_RX_ER__EIM_ADDR25		0x0100 0x038c 0x0000 4 0
 #define MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15		0x0100 0x038c 0x0000 5 0
 #define MX6UL_PAD_ENET2_RX_ER__KPP_COL07		0x0100 0x038c 0x0000 6 0
@@ -440,7 +447,7 @@
 #define MX6UL_PAD_LCD_CLK__LCDIF_WR_RWN			0x0104 0x0390 0x0000 1 0
 #define MX6UL_PAD_LCD_CLK__UART4_DCE_TX			0x0104 0x0390 0x0000 2 0
 #define MX6UL_PAD_LCD_CLK__UART4_DTE_RX			0x0104 0x0390 0x063c 2 2
-#define MX6UL_PAD_LCD_CLK__SAI3_MCLK			0x0104 0x0390 0x0000 3 0
+#define MX6UL_PAD_LCD_CLK__SAI3_MCLK			0x0104 0x0390 0x0600 3 0
 #define MX6UL_PAD_LCD_CLK__EIM_CS2_B			0x0104 0x0390 0x0000 4 0
 #define MX6UL_PAD_LCD_CLK__GPIO3_IO00			0x0104 0x0390 0x0000 5 0
 #define MX6UL_PAD_LCD_CLK__WDOG1_WDOG_RST_B_DEB		0x0104 0x0390 0x0000 8 0
@@ -464,7 +471,7 @@
 #define MX6UL_PAD_LCD_VSYNC__LCDIF_BUSY			0x0110 0x039c 0x05dc 1 1
 #define MX6UL_PAD_LCD_VSYNC__UART4_DCE_RTS		0x0110 0x039c 0x0638 2 3
 #define MX6UL_PAD_LCD_VSYNC__UART4_DTE_CTS		0x0110 0x039c 0x0000 2 0
-#define MX6UL_PAD_LCD_VSYNC__SAI3_RX_DATA		0x0110 0x039c 0x0000 3 0
+#define MX6UL_PAD_LCD_VSYNC__SAI3_RX_DATA		0x0110 0x039c 0x0604 3 0
 #define MX6UL_PAD_LCD_VSYNC__WDOG2_WDOG_B		0x0110 0x039c 0x0000 4 0
 #define MX6UL_PAD_LCD_VSYNC__GPIO3_IO03			0x0110 0x039c 0x0000 5 0
 #define MX6UL_PAD_LCD_VSYNC__ECSPI2_SS2			0x0110 0x039c 0x0000 8 0
@@ -477,13 +484,15 @@
 #define MX6UL_PAD_LCD_RESET__ECSPI2_SS3			0x0114 0x03a0 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA00__LCDIF_DATA00		0x0118 0x03a4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA00__PWM1_OUT			0x0118 0x03a4 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA00__CA7_MX6UL_TRACE0		0x0118 0x03a4 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA00__ENET1_1588_EVENT2_IN	0x0118 0x03a4 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA00__I2C3_SDA			0x0118 0x03a4 0x05b8 4 2
 #define MX6UL_PAD_LCD_DATA00__GPIO3_IO05		0x0118 0x03a4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA00__SRC_BT_CFG00		0x0118 0x03a4 0x0000 6 0
-#define MX6UL_PAD_LCD_DATA00__SAI1_MCLK			0x0118 0x03a4 0x0000 8 0
+#define MX6UL_PAD_LCD_DATA00__SAI1_MCLK			0x0118 0x03a4 0x05e0 8 1
 #define MX6UL_PAD_LCD_DATA01__LCDIF_DATA01		0x011c 0x03a8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA01__PWM2_OUT			0x011c 0x03a8 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA01__CA7_MX6UL_TRACE1		0x011c 0x03a8 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA01__ENET1_1588_EVENT2_OUT	0x011c 0x03a8 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA01__I2C3_SCL			0x011c 0x03a8 0x05b4 4 2
 #define MX6UL_PAD_LCD_DATA01__GPIO3_IO06		0x011c 0x03a8 0x0000 5 0
@@ -491,6 +500,7 @@
 #define MX6UL_PAD_LCD_DATA01__SAI1_TX_SYNC		0x011c 0x03a8 0x05ec 8 0
 #define MX6UL_PAD_LCD_DATA02__LCDIF_DATA02		0x0120 0x03ac 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA02__PWM3_OUT			0x0120 0x03ac 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA02__CA7_MX6UL_TRACE2		0x0120 0x03ac 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA02__ENET1_1588_EVENT3_IN	0x0120 0x03ac 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA02__I2C4_SDA			0x0120 0x03ac 0x05c0 4 2
 #define MX6UL_PAD_LCD_DATA02__GPIO3_IO07		0x0120 0x03ac 0x0000 5 0
@@ -498,14 +508,16 @@
 #define MX6UL_PAD_LCD_DATA02__SAI1_TX_BCLK		0x0120 0x03ac 0x05e8 8 0
 #define MX6UL_PAD_LCD_DATA03__LCDIF_DATA03		0x0124 0x03b0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA03__PWM4_OUT			0x0124 0x03b0 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA03__CA7_MX6UL_TRACE3		0x0124 0x03b0 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA03__ENET1_1588_EVENT3_OUT	0x0124 0x03b0 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA03__I2C4_SCL			0x0124 0x03b0 0x05bc 4 2
 #define MX6UL_PAD_LCD_DATA03__GPIO3_IO08		0x0124 0x03b0 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA03__SRC_BT_CFG03		0x0124 0x03b0 0x0000 6 0
-#define MX6UL_PAD_LCD_DATA03__SAI1_RX_DATA		0x0124 0x03b0 0x0000 8 0
+#define MX6UL_PAD_LCD_DATA03__SAI1_RX_DATA		0x0124 0x03b0 0x05e4 8 0
 #define MX6UL_PAD_LCD_DATA04__LCDIF_DATA04		0x0128 0x03b4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA04__UART8_DCE_CTS		0x0128 0x03b4 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA04__UART8_DTE_RTS		0x0128 0x03b4 0x0658 1 2
+#define MX6UL_PAD_LCD_DATA04__CA7_MX6UL_TRACE4		0x0128 0x03b4 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA04__ENET2_1588_EVENT2_IN	0x0128 0x03b4 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA04__SPDIF_SR_CLK		0x0128 0x03b4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA04__GPIO3_IO09		0x0128 0x03b4 0x0000 5 0
@@ -514,6 +526,7 @@
 #define MX6UL_PAD_LCD_DATA05__LCDIF_DATA05		0x012c 0x03b8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA05__UART8_DCE_RTS		0x012c 0x03b8 0x0658 1 3
 #define MX6UL_PAD_LCD_DATA05__UART8_DTE_CTS		0x012c 0x03b8 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA05__CA7_MX6UL_TRACE5		0x012c 0x03b8 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA05__ENET2_1588_EVENT2_OUT	0x012c 0x03b8 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA05__SPDIF_OUT			0x012c 0x03b8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA05__GPIO3_IO10		0x012c 0x03b8 0x0000 5 0
@@ -522,6 +535,7 @@
 #define MX6UL_PAD_LCD_DATA06__LCDIF_DATA06		0x0130 0x03bc 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA06__UART7_DCE_CTS		0x0130 0x03bc 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA06__UART7_DTE_RTS		0x0130 0x03bc 0x0650 1 2
+#define MX6UL_PAD_LCD_DATA06__CA7_MX6UL_TRACE6		0x0130 0x03bc 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA06__ENET2_1588_EVENT3_IN	0x0130 0x03bc 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA06__SPDIF_LOCK		0x0130 0x03bc 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA06__GPIO3_IO11		0x0130 0x03bc 0x0000 5 0
@@ -530,6 +544,7 @@
 #define MX6UL_PAD_LCD_DATA07__LCDIF_DATA07		0x0134 0x03c0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA07__UART7_DCE_RTS		0x0134 0x03c0 0x0650 1 3
 #define MX6UL_PAD_LCD_DATA07__UART7_DTE_CTS		0x0134 0x03c0 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA07__CA7_MX6UL_TRACE7		0x0134 0x03c0 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA07__ENET2_1588_EVENT3_OUT	0x0134 0x03c0 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA07__SPDIF_EXT_CLK		0x0134 0x03c0 0x061c 4 0
 #define MX6UL_PAD_LCD_DATA07__GPIO3_IO12		0x0134 0x03c0 0x0000 5 0
@@ -537,56 +552,64 @@
 #define MX6UL_PAD_LCD_DATA07__ECSPI1_SS3		0x0134 0x03c0 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA08__LCDIF_DATA08		0x0138 0x03c4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA08__SPDIF_IN			0x0138 0x03c4 0x0618 1 2
-#define MX6UL_PAD_LCD_DATA08__CSI_DATA16		0x0138 0x03c4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA08__CA7_MX6UL_TRACE8		0x0138 0x03c4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA08__CSI_DATA16		0x0138 0x03c4 0x0504 3 1
 #define MX6UL_PAD_LCD_DATA08__EIM_DATA00		0x0138 0x03c4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA08__GPIO3_IO13		0x0138 0x03c4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA08__SRC_BT_CFG08		0x0138 0x03c4 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA08__FLEXCAN1_TX		0x0138 0x03c4 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA09__LCDIF_DATA09		0x013c 0x03c8 0x0000 0 0
-#define MX6UL_PAD_LCD_DATA09__SAI3_MCLK			0x013c 0x03c8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA09__CSI_DATA17		0x013c 0x03c8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA09__SAI3_MCLK			0x013c 0x03c8 0x0600 1 1
+#define MX6UL_PAD_LCD_DATA09__CA7_MX6UL_TRACE9		0x013c 0x03c8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA09__CSI_DATA17		0x013c 0x03c8 0x0508 3 1
 #define MX6UL_PAD_LCD_DATA09__EIM_DATA01		0x013c 0x03c8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA09__GPIO3_IO14		0x013c 0x03c8 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA09__SRC_BT_CFG09		0x013c 0x03c8 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA09__FLEXCAN1_RX		0x013c 0x03c8 0x0584 8 2
 #define MX6UL_PAD_LCD_DATA10__LCDIF_DATA10		0x0140 0x03cc 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA10__SAI3_RX_SYNC		0x0140 0x03cc 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA10__CSI_DATA18		0x0140 0x03cc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA10__CA7_MX6UL_TRACE10		0x0140 0x03cc 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA10__CSI_DATA18		0x0140 0x03cc 0x050c 3 1
 #define MX6UL_PAD_LCD_DATA10__EIM_DATA02		0x0140 0x03cc 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA10__GPIO3_IO15		0x0140 0x03cc 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA10__SRC_BT_CFG10		0x0140 0x03cc 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA10__FLEXCAN2_TX		0x0140 0x03cc 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA11__LCDIF_DATA11		0x0144 0x03d0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA11__SAI3_RX_BCLK		0x0144 0x03d0 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA11__CSI_DATA19		0x0144 0x03d0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA11__CA7_MX6UL_TRACE11		0x0144 0x03d0 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA11__CSI_DATA19		0x0144 0x03d0 0x0510 3 1
 #define MX6UL_PAD_LCD_DATA11__EIM_DATA03		0x0144 0x03d0 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA11__GPIO3_IO16		0x0144 0x03d0 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA11__SRC_BT_CFG11		0x0144 0x03d0 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA11__FLEXCAN2_RX		0x0144 0x03d0 0x0588 8 2
 #define MX6UL_PAD_LCD_DATA12__LCDIF_DATA12		0x0148 0x03d4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA12__SAI3_TX_SYNC		0x0148 0x03d4 0x060c 1 1
-#define MX6UL_PAD_LCD_DATA12__CSI_DATA20		0x0148 0x03d4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA12__CA7_MX6UL_TRACE12		0x0148 0x03d4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA12__CSI_DATA20		0x0148 0x03d4 0x0514 3 1
 #define MX6UL_PAD_LCD_DATA12__EIM_DATA04		0x0148 0x03d4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA12__GPIO3_IO17		0x0148 0x03d4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA12__SRC_BT_CFG12		0x0148 0x03d4 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA12__ECSPI1_RDY		0x0148 0x03d4 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA13__LCDIF_DATA13		0x014c 0x03d8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA13__SAI3_TX_BCLK		0x014c 0x03d8 0x0608 1 1
-#define MX6UL_PAD_LCD_DATA13__CSI_DATA21		0x014c 0x03d8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA13__CA7_MX6UL_TRACE13		0x014c 0x03d8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA13__CSI_DATA21		0x014c 0x03d8 0x0518 3 1
 #define MX6UL_PAD_LCD_DATA13__EIM_DATA05		0x014c 0x03d8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA13__GPIO3_IO18		0x014c 0x03d8 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA13__SRC_BT_CFG13		0x014c 0x03d8 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA13__USDHC2_RESET_B		0x014c 0x03d8 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA14__LCDIF_DATA14		0x0150 0x03dc 0x0000 0 0
-#define MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA		0x0150 0x03dc 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA14__CSI_DATA22		0x0150 0x03dc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA		0x0150 0x03dc 0x0604 1 1
+#define MX6UL_PAD_LCD_DATA14__CA7_MX6UL_TRACE14		0x0150 0x03dc 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA14__CSI_DATA22		0x0150 0x03dc 0x051c 3 1
 #define MX6UL_PAD_LCD_DATA14__EIM_DATA06		0x0150 0x03dc 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA14__GPIO3_IO19		0x0150 0x03dc 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA14__SRC_BT_CFG14		0x0150 0x03dc 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA14__USDHC2_DATA4		0x0150 0x03dc 0x068c 8 0
 #define MX6UL_PAD_LCD_DATA15__LCDIF_DATA15		0x0154 0x03e0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA15__SAI3_TX_DATA		0x0154 0x03e0 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA15__CSI_DATA23		0x0154 0x03e0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA15__CA7_MX6UL_TRACE15		0x0154 0x03e0 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA15__CSI_DATA23		0x0154 0x03e0 0x0520 3 1
 #define MX6UL_PAD_LCD_DATA15__EIM_DATA07		0x0154 0x03e0 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA15__GPIO3_IO20		0x0154 0x03e0 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA15__SRC_BT_CFG15		0x0154 0x03e0 0x0000 6 0
@@ -594,7 +617,8 @@
 #define MX6UL_PAD_LCD_DATA16__LCDIF_DATA16		0x0158 0x03e4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA16__UART7_DCE_TX		0x0158 0x03e4 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA16__UART7_DTE_RX		0x0158 0x03e4 0x0654 1 2
-#define MX6UL_PAD_LCD_DATA16__CSI_DATA01		0x0158 0x03e4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA16__CA7_MX6UL_TRACE_CLK	0x0158 0x03e4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA16__CSI_DATA01		0x0158 0x03e4 0x04d4 3 1
 #define MX6UL_PAD_LCD_DATA16__EIM_DATA08		0x0158 0x03e4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA16__GPIO3_IO21		0x0158 0x03e4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA16__SRC_BT_CFG24		0x0158 0x03e4 0x0000 6 0
@@ -602,7 +626,8 @@
 #define MX6UL_PAD_LCD_DATA17__LCDIF_DATA17		0x015c 0x03e8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA17__UART7_DCE_RX		0x015c 0x03e8 0x0654 1 3
 #define MX6UL_PAD_LCD_DATA17__UART7_DTE_TX		0x015c 0x03e8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA17__CSI_DATA00		0x015c 0x03e8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA17__CA7_MX6UL_TRACE_CTL	0x015c 0x03e8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA17__CSI_DATA00		0x015c 0x03e8 0x04d0 3 1
 #define MX6UL_PAD_LCD_DATA17__EIM_DATA09		0x015c 0x03e8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA17__GPIO3_IO22		0x015c 0x03e8 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA17__SRC_BT_CFG25		0x015c 0x03e8 0x0000 6 0
@@ -610,7 +635,7 @@
 #define MX6UL_PAD_LCD_DATA18__LCDIF_DATA18		0x0160 0x03ec 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA18__PWM5_OUT			0x0160 0x03ec 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA18__CA7_MX6UL_EVENTO		0x0160 0x03ec 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA18__CSI_DATA10		0x0160 0x03ec 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA18__CSI_DATA10		0x0160 0x03ec 0x04ec 3 1
 #define MX6UL_PAD_LCD_DATA18__EIM_DATA10		0x0160 0x03ec 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA18__GPIO3_IO23		0x0160 0x03ec 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA18__SRC_BT_CFG26		0x0160 0x03ec 0x0000 6 0
@@ -622,7 +647,7 @@
 #define MX6UL_PAD_LCD_DATA19__LCDIF_DATA19		0x0164 0x03f0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA19__PWM6_OUT			0x0164 0x03f0 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA19__WDOG1_WDOG_ANY		0x0164 0x03f0 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA19__CSI_DATA11		0x0164 0x03f0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA19__CSI_DATA11		0x0164 0x03f0 0x04f0 3 1
 #define MX6UL_PAD_LCD_DATA20__EIM_DATA12		0x0168 0x03f4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA20__GPIO3_IO25		0x0168 0x03f4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA20__SRC_BT_CFG28		0x0168 0x03f4 0x0000 6 0
@@ -631,12 +656,12 @@
 #define MX6UL_PAD_LCD_DATA20__UART8_DCE_TX		0x0168 0x03f4 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA20__UART8_DTE_RX		0x0168 0x03f4 0x065c 1 2
 #define MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK		0x0168 0x03f4 0x0534 2 0
-#define MX6UL_PAD_LCD_DATA20__CSI_DATA12		0x0168 0x03f4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA20__CSI_DATA12		0x0168 0x03f4 0x04f4 3 1
 #define MX6UL_PAD_LCD_DATA21__LCDIF_DATA21		0x016c 0x03f8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA21__UART8_DCE_RX		0x016c 0x03f8 0x065c 1 3
 #define MX6UL_PAD_LCD_DATA21__UART8_DTE_TX		0x016c 0x03f8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA21__ECSPI1_SS0		0x016c 0x03f8 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA21__CSI_DATA13		0x016c 0x03f8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA21__ECSPI1_SS0		0x016c 0x03f8 0x0540 2 0
+#define MX6UL_PAD_LCD_DATA21__CSI_DATA13		0x016c 0x03f8 0x04f8 3 1
 #define MX6UL_PAD_LCD_DATA21__EIM_DATA13		0x016c 0x03f8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA21__GPIO3_IO26		0x016c 0x03f8 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA21__SRC_BT_CFG29		0x016c 0x03f8 0x0000 6 0
@@ -644,7 +669,7 @@
 #define MX6UL_PAD_LCD_DATA22__LCDIF_DATA22		0x0170 0x03fc 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA22__MQS_RIGHT			0x0170 0x03fc 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI		0x0170 0x03fc 0x053c 2 0
-#define MX6UL_PAD_LCD_DATA22__CSI_DATA14		0x0170 0x03fc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA22__CSI_DATA14		0x0170 0x03fc 0x04fc 3 1
 #define MX6UL_PAD_LCD_DATA22__EIM_DATA14		0x0170 0x03fc 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA22__GPIO3_IO27		0x0170 0x03fc 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA22__SRC_BT_CFG30		0x0170 0x03fc 0x0000 6 0
@@ -652,7 +677,7 @@
 #define MX6UL_PAD_LCD_DATA23__LCDIF_DATA23		0x0174 0x0400 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA23__MQS_LEFT			0x0174 0x0400 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA23__ECSPI1_MISO		0x0174 0x0400 0x0538 2 0
-#define MX6UL_PAD_LCD_DATA23__CSI_DATA15		0x0174 0x0400 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA23__CSI_DATA15		0x0174 0x0400 0x0500 3 1
 #define MX6UL_PAD_LCD_DATA23__EIM_DATA15		0x0174 0x0400 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA23__GPIO3_IO28		0x0174 0x0400 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA23__SRC_BT_CFG31		0x0174 0x0400 0x0000 6 0
@@ -660,42 +685,42 @@
 #define MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B		0x0178 0x0404 0x0000 0 0
 #define MX6UL_PAD_NAND_RE_B__USDHC2_CLK			0x0178 0x0404 0x0670 1 2
 #define MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK		0x0178 0x0404 0x0000 2 0
-#define MX6UL_PAD_NAND_RE_B__KPP_ROW00			0x0178 0x0404 0x0000 3 0
+#define MX6UL_PAD_NAND_RE_B__KPP_ROW00			0x0178 0x0404 0x05d0 3 1
 #define MX6UL_PAD_NAND_RE_B__EIM_EB_B00			0x0178 0x0404 0x0000 4 0
 #define MX6UL_PAD_NAND_RE_B__GPIO4_IO00			0x0178 0x0404 0x0000 5 0
 #define MX6UL_PAD_NAND_RE_B__ECSPI3_SS2			0x0178 0x0404 0x0000 8 0
 #define MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B		0x017c 0x0408 0x0000 0 0
 #define MX6UL_PAD_NAND_WE_B__USDHC2_CMD			0x017c 0x0408 0x0678 1 2
 #define MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B		0x017c 0x0408 0x0000 2 0
-#define MX6UL_PAD_NAND_WE_B__KPP_COL00			0x017c 0x0408 0x0000 3 0
+#define MX6UL_PAD_NAND_WE_B__KPP_COL00			0x017c 0x0408 0x05c4 3 1
 #define MX6UL_PAD_NAND_WE_B__EIM_EB_B01			0x017c 0x0408 0x0000 4 0
 #define MX6UL_PAD_NAND_WE_B__GPIO4_IO01			0x017c 0x0408 0x0000 5 0
 #define MX6UL_PAD_NAND_WE_B__ECSPI3_SS3			0x017c 0x0408 0x0000 8 0
 #define MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00		0x0180 0x040c 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA00__USDHC2_DATA0		0x0180 0x040c 0x067c 1 2
 #define MX6UL_PAD_NAND_DATA00__QSPI_B_SS1_B		0x0180 0x040c 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA00__KPP_ROW01		0x0180 0x040c 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA00__KPP_ROW01		0x0180 0x040c 0x05d4 3 1
 #define MX6UL_PAD_NAND_DATA00__EIM_AD08			0x0180 0x040c 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA00__GPIO4_IO02		0x0180 0x040c 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA00__ECSPI4_RDY		0x0180 0x040c 0x0000 8 0
 #define MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01		0x0184 0x0410 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA01__USDHC2_DATA1		0x0184 0x0410 0x0680 1 2
 #define MX6UL_PAD_NAND_DATA01__QSPI_B_DQS		0x0184 0x0410 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA01__KPP_COL01		0x0184 0x0410 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA01__KPP_COL01		0x0184 0x0410 0x05c8 3 1
 #define MX6UL_PAD_NAND_DATA01__EIM_AD09			0x0184 0x0410 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA01__GPIO4_IO03		0x0184 0x0410 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA01__ECSPI4_SS1		0x0184 0x0410 0x0000 8 0
 #define MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02		0x0188 0x0414 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA02__USDHC2_DATA2		0x0188 0x0414 0x0684 1 1
 #define MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00		0x0188 0x0414 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA02__KPP_ROW02		0x0188 0x0414 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA02__KPP_ROW02		0x0188 0x0414 0x05d8 3 1
 #define MX6UL_PAD_NAND_DATA02__EIM_AD10			0x0188 0x0414 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA02__GPIO4_IO04		0x0188 0x0414 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA02__ECSPI4_SS2		0x0188 0x0414 0x0000 8 0
 #define MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03		0x018c 0x0418 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA03__USDHC2_DATA3		0x018c 0x0418 0x0688 1 2
 #define MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01		0x018c 0x0418 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA03__KPP_COL02		0x018c 0x0418 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA03__KPP_COL02		0x018c 0x0418 0x05cc 3 1
 #define MX6UL_PAD_NAND_DATA03__EIM_AD11			0x018c 0x0418 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA03__GPIO4_IO05		0x018c 0x0418 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA03__ECSPI4_SS3		0x018c 0x0418 0x0000 8 0
@@ -726,7 +751,7 @@
 #define MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07		0x019c 0x0428 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA07__USDHC2_DATA7		0x019c 0x0428 0x0698 1 1
 #define MX6UL_PAD_NAND_DATA07__QSPI_A_SS1_B		0x019c 0x0428 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA07__ECSPI4_SS0		0x019c 0x0428 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA07__ECSPI4_SS0		0x019c 0x0428 0x0570 3 1
 #define MX6UL_PAD_NAND_DATA07__EIM_AD15			0x019c 0x0428 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA07__GPIO4_IO09		0x019c 0x0428 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS		0x019c 0x0428 0x0628 8 5
@@ -748,7 +773,7 @@
 #define MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B		0x01a8 0x0434 0x0000 0 0
 #define MX6UL_PAD_NAND_READY_B__USDHC1_DATA4		0x01a8 0x0434 0x0000 1 0
 #define MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00		0x01a8 0x0434 0x0000 2 0
-#define MX6UL_PAD_NAND_READY_B__ECSPI3_SS0		0x01a8 0x0434 0x0000 3 0
+#define MX6UL_PAD_NAND_READY_B__ECSPI3_SS0		0x01a8 0x0434 0x0560 3 1
 #define MX6UL_PAD_NAND_READY_B__EIM_CS1_B		0x01a8 0x0434 0x0000 4 0
 #define MX6UL_PAD_NAND_READY_B__GPIO4_IO12		0x01a8 0x0434 0x0000 5 0
 #define MX6UL_PAD_NAND_READY_B__UART3_DCE_TX		0x01a8 0x0434 0x0000 8 0
@@ -783,7 +808,7 @@
 #define MX6UL_PAD_NAND_DQS__PWM5_OUT			0x01b8 0x0444 0x0000 3 0
 #define MX6UL_PAD_NAND_DQS__EIM_WAIT			0x01b8 0x0444 0x0000 4 0
 #define MX6UL_PAD_NAND_DQS__GPIO4_IO16			0x01b8 0x0444 0x0000 5 0
-#define MX6UL_PAD_NAND_DQS__SDMA_EXT_EVENT01		0x01b8 0x0444 0x0000 6 0
+#define MX6UL_PAD_NAND_DQS__SDMA_EXT_EVENT01		0x01b8 0x0444 0x0614 6 1
 #define MX6UL_PAD_NAND_DQS__SPDIF_EXT_CLK		0x01b8 0x0444 0x061c 8 1
 #define MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x01bc 0x0448 0x0000 0 0
 #define MX6UL_PAD_SD1_CMD__GPT2_COMPARE1		0x01bc 0x0448 0x0000 1 0
@@ -791,11 +816,11 @@
 #define MX6UL_PAD_SD1_CMD__SPDIF_OUT			0x01bc 0x0448 0x0000 3 0
 #define MX6UL_PAD_SD1_CMD__EIM_ADDR19			0x01bc 0x0448 0x0000 4 0
 #define MX6UL_PAD_SD1_CMD__GPIO2_IO16			0x01bc 0x0448 0x0000 5 0
-#define MX6UL_PAD_SD1_CMD__SDMA_EXT_EVENT00		0x01bc 0x0448 0x0000 6 0
+#define MX6UL_PAD_SD1_CMD__SDMA_EXT_EVENT00		0x01bc 0x0448 0x0610 6 2
 #define MX6UL_PAD_SD1_CMD__USB_OTG1_PWR			0x01bc 0x0448 0x0000 8 0
 #define MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x01c0 0x044c 0x0000 0 0
 #define MX6UL_PAD_SD1_CLK__GPT2_COMPARE2		0x01c0 0x044c 0x0000 1 0
-#define MX6UL_PAD_SD1_CLK__SAI2_MCLK			0x01c0 0x044c 0x0000 2 0
+#define MX6UL_PAD_SD1_CLK__SAI2_MCLK			0x01c0 0x044c 0x05f0 2 1
 #define MX6UL_PAD_SD1_CLK__SPDIF_IN			0x01c0 0x044c 0x0618 3 3
 #define MX6UL_PAD_SD1_CLK__EIM_ADDR20			0x01c0 0x044c 0x0000 4 0
 #define MX6UL_PAD_SD1_CLK__GPIO2_IO17			0x01c0 0x044c 0x0000 5 0
@@ -878,10 +903,10 @@
 #define MX6UL_PAD_CSI_DATA01__CSI_DATA03		0x01e8 0x0474 0x04c8 0 0
 #define MX6UL_PAD_CSI_DATA01__USDHC2_DATA1		0x01e8 0x0474 0x0680 1 0
 #define MX6UL_PAD_CSI_DATA01__SIM1_PORT1_SVEN		0x01e8 0x0474 0x0000 2 0
-#define MX6UL_PAD_CSI_DATA01__ECSPI2_SS0		0x01e8 0x0474 0x0000 3 0
+#define MX6UL_PAD_CSI_DATA01__ECSPI2_SS0		0x01e8 0x0474 0x0550 3 0
 #define MX6UL_PAD_CSI_DATA01__EIM_AD01			0x01e8 0x0474 0x0000 4 0
 #define MX6UL_PAD_CSI_DATA01__GPIO4_IO22		0x01e8 0x0474 0x0000 5 0
-#define MX6UL_PAD_CSI_DATA01__SAI1_MCLK			0x01e8 0x0474 0x0000 6 0
+#define MX6UL_PAD_CSI_DATA01__SAI1_MCLK			0x01e8 0x0474 0x05e0 6 0
 #define MX6UL_PAD_CSI_DATA01__UART5_DCE_RX		0x01e8 0x0474 0x0644 8 1
 #define MX6UL_PAD_CSI_DATA01__UART5_DTE_TX		0x01e8 0x0474 0x0000 8 0
 #define MX6UL_PAD_CSI_DATA02__CSI_DATA04		0x01ec 0x0478 0x04d8 0 1
@@ -913,7 +938,7 @@
 #define MX6UL_PAD_CSI_DATA05__CSI_DATA07		0x01f8 0x0484 0x04e0 0 1
 #define MX6UL_PAD_CSI_DATA05__USDHC2_DATA5		0x01f8 0x0484 0x0690 1 2
 #define MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B		0x01f8 0x0484 0x0000 2 0
-#define MX6UL_PAD_CSI_DATA05__ECSPI1_SS0		0x01f8 0x0484 0x0000 3 0
+#define MX6UL_PAD_CSI_DATA05__ECSPI1_SS0		0x01f8 0x0484 0x0540 3 1
 #define MX6UL_PAD_CSI_DATA05__EIM_AD05			0x01f8 0x0484 0x0000 4 0
 #define MX6UL_PAD_CSI_DATA05__GPIO4_IO26		0x01f8 0x0484 0x0000 5 0
 #define MX6UL_PAD_CSI_DATA05__SAI1_TX_BCLK		0x01f8 0x0484 0x05e8 6 1
@@ -924,7 +949,7 @@
 #define MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI		0x01fc 0x0488 0x053c 3 1
 #define MX6UL_PAD_CSI_DATA06__EIM_AD06			0x01fc 0x0488 0x0000 4 0
 #define MX6UL_PAD_CSI_DATA06__GPIO4_IO27		0x01fc 0x0488 0x0000 5 0
-#define MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA		0x01fc 0x0488 0x0000 6 0
+#define MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA		0x01fc 0x0488 0x05e4 6 1
 #define MX6UL_PAD_CSI_DATA06__USDHC1_RESET_B		0x01fc 0x0488 0x0000 8 0
 #define MX6UL_PAD_CSI_DATA07__CSI_DATA09		0x0200 0x048c 0x04e8 0 1
 #define MX6UL_PAD_CSI_DATA07__USDHC2_DATA7		0x0200 0x048c 0x0698 1 2
diff --git a/arch/arm/boot/dts/imx6ul-tx6ul.dtsi b/arch/arm/boot/dts/imx6ul-tx6ul.dtsi
index 65111f98..f678d18 100644
--- a/arch/arm/boot/dts/imx6ul-tx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul-tx6ul.dtsi
@@ -70,8 +70,8 @@
 		stdout-path = &uart1;
 	};
 
-	memory {
-		reg = <0 0>; /* will be filled by U-Boot */
+	memory@80000000 {
+		reg = <0x80000000 0>; /* will be filled by U-Boot */
 	};
 
 	clocks {
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 5d6c3ba..1241972 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -22,7 +22,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		ethernet0 = &fec1;
@@ -86,15 +86,10 @@
 				 <&clks IMX6UL_CA7_SECONDARY_SEL>,
 				 <&clks IMX6UL_CLK_STEP>,
 				 <&clks IMX6UL_CLK_PLL1_SW>,
-				 <&clks IMX6UL_CLK_PLL1_SYS>,
-				 <&clks IMX6UL_PLL1_BYPASS>,
-				 <&clks IMX6UL_CLK_PLL1>,
-				 <&clks IMX6UL_PLL1_BYPASS_SRC>,
-				 <&clks IMX6UL_CLK_OSC>;
+				 <&clks IMX6UL_CLK_PLL1_SYS>;
 			clock-names = "arm", "pll2_bus",  "pll2_pfd2_396m",
 				      "secondary_sel", "step", "pll1_sw",
-				      "pll1_sys", "pll1_bypass", "pll1",
-				      "pll1_bypass_src", "osc";
+				      "pll1_sys";
 			arm-supply = <&reg_arm>;
 			soc-supply = <&reg_soc>;
 		};
@@ -102,14 +97,26 @@
 
 	intc: interrupt-controller@a01000 {
 		compatible = "arm,gic-400", "arm,cortex-a7-gic";
+		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		#interrupt-cells = <3>;
 		interrupt-controller;
+		interrupt-parent = <&intc>;
 		reg = <0x00a01000 0x1000>,
 		      <0x00a02000 0x2000>,
 		      <0x00a04000 0x2000>,
 		      <0x00a06000 0x2000>;
 	};
 
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+		interrupt-parent = <&intc>;
+		status = "disabled";
+	};
+
 	ckil: clock-cli {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
@@ -924,6 +931,14 @@
 				status = "disabled";
 			};
 
+			wdog3: wdog@21e4000 {
+				compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt";
+				reg = <0x021e4000 0x4000>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6UL_CLK_WDOG3>;
+				status = "disabled";
+			};
+
 			uart2: serial@21e8000 {
 				compatible = "fsl,imx6ul-uart",
 					     "fsl,imx6q-uart";
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk.dts b/arch/arm/boot/dts/imx6ull-14x14-evk.dts
index 4741871..30ef603 100644
--- a/arch/arm/boot/dts/imx6ull-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk.dts
@@ -39,7 +39,10 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "imx6ul-14x14-evk.dts"
+/dts-v1/;
+
+#include "imx6ull.dtsi"
+#include "imx6ul-14x14-evk.dtsi"
 
 / {
 	model = "Freescale i.MX6 UlltraLite 14x14 EVK Board";
diff --git a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dts
new file mode 100644
index 0000000..08669a1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018 Toradex AG
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-nonwifi.dtsi"
+#include "imx6ull-colibri-eval-v3.dtsi"
+
+/ {
+	model = "Toradex Colibri iMX6ULL 256MB on Colibri Evaluation Board V3";
+	compatible = "toradex,colibri-imx6ull-eval", "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
new file mode 100644
index 0000000..006690e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2017 Toradex AG
+ */
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	/* fixed crystal dedicated to mcp2515 */
+	clk16m: clk16m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <16000000>;
+	};
+
+	panel: panel {
+		compatible = "edt,et057090dhu";
+		backlight = <&bl>;
+		power-supply = <&reg_3v3>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&lcdif_out>;
+			};
+		};
+	};
+
+	reg_3v3: regulator-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_5v0: regulator-5v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	reg_usbh_vbus: regulator-usbh-vbus {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usbh_reg>;
+		regulator-name = "VCC_USB[1-4]";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		vin-supply = <&reg_5v0>;
+	};
+};
+
+&adc1 {
+	status = "okay";
+};
+
+&bl {
+	brightness-levels = <0 4 8 16 32 64 128 255>;
+	default-brightness-level = <6>;
+	power-supply = <&reg_3v3>;
+	pwms = <&pwm4 0 5000000 1>;
+	status = "okay";
+};
+
+&ecspi1 {
+	status = "okay";
+
+	mcp2515: can@0 {
+		compatible = "microchip,mcp2515";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can_int>;
+		reg = <0>;
+		clocks = <&clk16m>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+		spi-max-frequency = <10000000>;
+		vdd-supply = <&reg_3v3>;
+		xceiver-supply = <&reg_5v0>;
+		status = "okay";
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	/* M41T0M6 real time clock on carrier board */
+	m41t0m6: rtc@68 {
+		compatible = "st,m41t0";
+		reg = <0x68>;
+	};
+};
+
+&lcdif {
+	status = "okay";
+
+	port {
+		lcdif_out: endpoint {
+			remote-endpoint = <&panel_in>;
+		};
+	};
+};
+
+/* PWM <A> */
+&pwm4 {
+	status = "okay";
+};
+
+/* PWM <B> */
+&pwm5 {
+	status = "okay";
+};
+
+/* PWM <C> */
+&pwm6 {
+	status = "okay";
+};
+
+/* PWM <D> */
+&pwm7 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&usbotg1 {
+	status = "okay";
+};
+
+&usbotg2 {
+	vbus-supply = <&reg_usbh_vbus>;
+	status = "okay";
+};
+
+&usdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_snvs_usdhc1_cd>;
+	no-1-8-v;
+	cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	wakeup-source;
+	keep-power-in-suspend;
+	vmmc-supply = <&reg_3v3>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
new file mode 100644
index 0000000..10ab469
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018 Toradex AG
+ */
+
+#include "imx6ull-colibri.dtsi"
+
+/ {
+	memory@80000000 {
+		reg = <0x80000000 0x10000000>;
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
+		&pinctrl_gpio4 &pinctrl_gpio5 &pinctrl_gpio6>;
+};
+
+&iomuxc_snvs {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_snvs_gpio1 &pinctrl_snvs_gpio2 &pinctrl_snvs_gpio3>;
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi-eval-v3.dts b/arch/arm/boot/dts/imx6ull-colibri-wifi-eval-v3.dts
new file mode 100644
index 0000000..df72ce1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-wifi-eval-v3.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018 Toradex AG
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-wifi.dtsi"
+#include "imx6ull-colibri-eval-v3.dtsi"
+
+/ {
+	model = "Toradex Colibri iMX6ULL 512MB on Colibri Evaluation Board V3";
+	compatible = "toradex,colibri-imx6ull-wifi-eval", "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
new file mode 100644
index 0000000..3dffbcd
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018 Toradex AG
+ */
+
+#include "imx6ull-colibri.dtsi"
+
+/ {
+	memory@80000000 {
+		reg = <0x80000000 0x20000000>;
+	};
+
+	wifi_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_snvs_wifi_pdn>;
+		reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&cpu0 {
+	clock-frequency = <792000000>;
+	operating-points = <
+		/* kHz	uV */
+		792000  1225000
+		528000	1175000
+		396000	1025000
+		198000	950000
+	>;
+	fsl,soc-operating-points = <
+		/* KHz	uV */
+		792000  1175000
+		528000	1175000
+		396000	1175000
+		198000	1175000
+	>;
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
+		&pinctrl_gpio4 &pinctrl_gpio5>;
+
+};
+
+&iomuxc_snvs {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_snvs_gpio1 &pinctrl_snvs_gpio2>;
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	assigned-clocks = <&clks IMX6UL_CLK_USDHC2_SEL>, <&clks IMX6UL_CLK_USDHC2>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
+	assigned-clock-rates = <0>, <198000000>;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	no-1-8-v;
+	non-removable;
+	vmmc-supply = <&reg_module_3v3>;
+	wakeup-source;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi b/arch/arm/boot/dts/imx6ull-colibri.dtsi
new file mode 100644
index 0000000..6c63a73
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi
@@ -0,0 +1,553 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2018 Toradex AG
+ */
+
+#include "imx6ull.dtsi"
+
+/ {
+	aliases {
+		ethernet0 = &fec2;
+		ethernet1 = &fec1;
+	};
+
+	bl: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_bl_on>;
+		enable-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+		status = "disabled";
+	};
+
+	reg_module_3v3: regulator-module-3v3 {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-name = "+V3.3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_module_3v3_avdd: regulator-module-3v3-avdd {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-name = "+V3.3_AVDD_AUDIO";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_sd1_vmmc: regulator-sd1-vmmc {
+		compatible = "regulator-gpio";
+		gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_snvs_reg_sd>;
+		regulator-always-on;
+		regulator-name = "+V3.3_1.8_SD";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		states = <1800000 0x1 3300000 0x0>;
+		vin-supply = <&reg_module_3v3>;
+	};
+};
+
+&adc1 {
+	num-channels = <10>;
+	vref-supply = <&reg_module_3v3_avdd>;
+};
+
+/* Colibri SPI */
+&ecspi1 {
+	cs-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
+};
+
+&fec2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet2>;
+	phy-mode = "rmii";
+	phy-handle = <&ethphy1>;
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy1: ethernet-phy@2 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			max-speed = <100>;
+			reg = <2>;
+		};
+	};
+};
+
+&gpmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpmi_nand>;
+	nand-on-flash-bbt;
+	nand-ecc-mode = "hw";
+	nand-ecc-strength = <8>;
+	nand-ecc-step-size = <512>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	sda-gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
+	scl-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	pinctrl-1 = <&pinctrl_i2c2_gpio>;
+	sda-gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
+	scl-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	ad7879@2c {
+		compatible = "adi,ad7879-1";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_snvs_ad7879_int>;
+		reg = <0x2c>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+		touchscreen-max-pressure = <4096>;
+		adi,resistance-plate-x = <120>;
+		adi,first-conversion-delay = /bits/ 8 <3>;
+		adi,acquisition-time = /bits/ 8 <1>;
+		adi,median-filter-size = /bits/ 8 <2>;
+		adi,averaging = /bits/ 8 <1>;
+		adi,conversion-interval = /bits/ 8 <255>;
+	};
+};
+
+&lcdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lcdif_dat
+		     &pinctrl_lcdif_ctrl>;
+};
+
+&pwm4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm4>;
+	#pwm-cells = <3>;
+};
+
+&pwm5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm5>;
+	#pwm-cells = <3>;
+};
+
+&pwm6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm6>;
+	#pwm-cells = <3>;
+};
+
+&pwm7 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm7>;
+	#pwm-cells = <3>;
+};
+
+&sdma {
+	status = "okay";
+};
+
+&snvs_pwrkey {
+	status = "disabled";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_ctrl1>;
+	uart-has-rtscts;
+	fsl,dte-mode;
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	uart-has-rtscts;
+	fsl,dte-mode;
+};
+
+&uart5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5>;
+	fsl,dte-mode;
+};
+
+&usbotg1 {
+	dr_mode = "otg";
+	srp-disable;
+	hnp-disable;
+	adp-disable;
+};
+
+&usbotg2 {
+	dr_mode = "host";
+};
+
+&usdhc1 {
+	assigned-clocks = <&clks IMX6UL_CLK_USDHC1_SEL>, <&clks IMX6UL_CLK_USDHC1>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
+	assigned-clock-rates = <0>, <198000000>;
+};
+
+&iomuxc {
+	pinctrl_can_int: canint-grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04	0X14 /* SODIMM 73 */
+		>;
+	};
+
+	pinctrl_enet2: enet2-grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO06__ENET2_MDIO	0x1b0b0
+			MX6UL_PAD_GPIO1_IO07__ENET2_MDC		0x1b0b0
+			MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00	0x1b0b0
+			MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01	0x1b0b0
+			MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN	0x1b0b0
+			MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER	0x1b0b0
+			MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2	0x4001b031
+			MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00	0x1b0b0
+			MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01	0x1b0b0
+			MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN	0x1b0b0
+		>;
+	};
+
+	pinctrl_ecspi1_cs: ecspi1-cs-grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA21__GPIO3_IO26	0x000a0
+		>;
+	};
+
+	pinctrl_ecspi1: ecspi1-grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK	0x000a0
+			MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI	0x000a0
+			MX6UL_PAD_LCD_DATA23__ECSPI1_MISO	0x100a0
+		>;
+	};
+
+	pinctrl_flexcan2: flexcan2-grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX	0x1b020
+			MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX	0x1b020
+		>;
+	};
+
+	pinctrl_gpio_bl_on: gpio-bl-on-grp {
+		fsl,pins = <
+			MX6UL_PAD_JTAG_TMS__GPIO1_IO11		0x000a0
+		>;
+	};
+
+	pinctrl_gpio1: gpio1-grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00	0x74 /* SODIMM 55 */
+			MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01	0x74 /* SODIMM 63 */
+			MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25	0X14 /* SODIMM 77 */
+			MX6UL_PAD_JTAG_TCK__GPIO1_IO14		0x14 /* SODIMM 99 */
+			MX6UL_PAD_NAND_CE1_B__GPIO4_IO14	0x14 /* SODIMM 133 */
+			MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24	0x14 /* SODIMM 135 */
+			MX6UL_PAD_UART3_CTS_B__GPIO1_IO26	0x14 /* SODIMM 100 */
+			MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15	0x14 /* SODIMM 102 */
+			MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07	0x14 /* SODIMM 104 */
+			MX6UL_PAD_UART3_RTS_B__GPIO1_IO27	0x14 /* SODIMM 186 */
+		>;
+	};
+
+	pinctrl_gpio2: gpio2-grp { /* Camera */
+		fsl,pins = <
+			MX6UL_PAD_CSI_DATA04__GPIO4_IO25	0x74 /* SODIMM 69 */
+			MX6UL_PAD_CSI_MCLK__GPIO4_IO17		0x14 /* SODIMM 75 */
+			MX6UL_PAD_CSI_DATA06__GPIO4_IO27	0x14 /* SODIMM 85 */
+			MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18	0x14 /* SODIMM 96 */
+			MX6UL_PAD_CSI_DATA05__GPIO4_IO26	0x14 /* SODIMM 98 */
+		>;
+	};
+
+	pinctrl_gpio3: gpio3-grp { /* CAN2 */
+		fsl,pins = <
+			MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02	0x14 /* SODIMM 178 */
+			MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03	0x14 /* SODIMM 188 */
+		>;
+	};
+
+	pinctrl_gpio4: gpio4-grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_DATA07__GPIO4_IO28	0x74 /* SODIMM 65 */
+		>;
+	};
+
+	pinctrl_gpio5: gpio5-grp { /* ATMEL MXT TOUCH */
+		fsl,pins = <
+			MX6UL_PAD_JTAG_MOD__GPIO1_IO10		0x74 /* SODIMM 106 */
+		>;
+	};
+
+	pinctrl_gpio6: gpio6-grp { /* Wifi pins */
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03	0x14 /* SODIMM 89 */
+			MX6UL_PAD_CSI_DATA02__GPIO4_IO23	0x14 /* SODIMM 79 */
+			MX6UL_PAD_CSI_VSYNC__GPIO4_IO19		0x14 /* SODIMM 81 */
+			MX6UL_PAD_CSI_DATA03__GPIO4_IO24	0x14 /* SODIMM 97 */
+			MX6UL_PAD_CSI_DATA00__GPIO4_IO21	0x14 /* SODIMM 101 */
+			MX6UL_PAD_CSI_DATA01__GPIO4_IO22	0x14 /* SODIMM 103 */
+			MX6UL_PAD_CSI_HSYNC__GPIO4_IO20		0x14 /* SODIMM 94 */
+		>;
+	};
+
+	pinctrl_gpmi_nand: gpmi-nand-grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00	0x100a9
+			MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01	0x100a9
+			MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02	0x100a9
+			MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03	0x100a9
+			MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04	0x100a9
+			MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05	0x100a9
+			MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06	0x100a9
+			MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07	0x100a9
+			MX6UL_PAD_NAND_CLE__RAWNAND_CLE		0x100a9
+			MX6UL_PAD_NAND_ALE__RAWNAND_ALE		0x100a9
+			MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B	0x100a9
+			MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B	0x100a9
+			MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B	0x100a9
+			MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B	0x100a9
+		>;
+	};
+
+	pinctrl_i2c1: i2c1-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
+			MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
+		>;
+	};
+
+	pinctrl_i2c1_gpio: i2c1-gpio-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x4001b8b0
+			MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x4001b8b0
+		>;
+	};
+
+	pinctrl_i2c2: i2c2-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
+			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
+		>;
+	};
+
+	pinctrl_i2c2_gpio: i2c2-gpio-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x4001b8b0
+			MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x4001b8b0
+		>;
+	};
+
+	pinctrl_lcdif_dat: lcdif-dat-grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x00079
+			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x00079
+			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x00079
+			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x00079
+			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x00079
+			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x00079
+			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x00079
+			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x00079
+			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x00079
+			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x00079
+			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x00079
+			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x00079
+			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x00079
+			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x00079
+			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x00079
+			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x00079
+			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x00079
+			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x00079
+		>;
+	};
+
+	pinctrl_lcdif_ctrl: lcdif-ctrl-grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_CLK__LCDIF_CLK	    0x00079
+			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x00079
+			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x00079
+			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x00079
+		>;
+	};
+
+	pinctrl_pwm4: pwm4-grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_WP_B__PWM4_OUT	0x00079
+		>;
+	};
+
+	pinctrl_pwm5: pwm5-grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_DQS__PWM5_OUT	0x00079
+		>;
+	};
+
+	pinctrl_pwm6: pwm6-grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_EN__PWM6_OUT	0x00079
+		>;
+	};
+
+	pinctrl_pwm7: pwm7-grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT	0x00079
+		>;
+	};
+
+	pinctrl_uart1: uart1-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX	0x1b0b1
+			MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX	0x1b0b1
+			MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS	0x1b0b1
+			MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart1_ctrl1: uart1-ctrl1-grp { /* Additional DTR, DCD */
+		fsl,pins = <
+			MX6UL_PAD_JTAG_TDI__GPIO1_IO13		0x1b0b1 /* DCD */
+			MX6UL_PAD_LCD_DATA18__GPIO3_IO23	0x1b0b1 /* DSR */
+			MX6UL_PAD_JTAG_TDO__GPIO1_IO12		0x1b0b1 /* DTR */
+			MX6UL_PAD_LCD_DATA19__GPIO3_IO24        0x1b0b1 /* RI */
+		>;
+	};
+
+	pinctrl_uart2: uart2-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX	0x1b0b1
+			MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX	0x1b0b1
+			MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS	0x1b0b1
+			MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS	0x1b0b1
+		>;
+	};
+	pinctrl_uart5: uart5-grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX	0x1b0b1
+			MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX	0x1b0b1
+		>;
+	};
+
+	pinctrl_usbh_reg: gpio-usbh-reg {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02	0x1b0b1 /* SODIMM 129 USBH PEN */
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x17059
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x10059
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x17059
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x17059
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x17059
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x17059
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1-100mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x170b9
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x100b9
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x170b9
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x170b9
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x170b9
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x170b9
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1-200mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x170f9
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x100f9
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x170b9
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x170b9
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x170b9
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x170b9
+		>;
+	};
+
+	pinctrl_usdhc2: usdhc2-grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_DATA00__USDHC2_DATA0	0x17059
+			MX6UL_PAD_CSI_DATA01__USDHC2_DATA1	0x17059
+			MX6UL_PAD_CSI_DATA02__USDHC2_DATA2	0x17059
+			MX6UL_PAD_CSI_DATA03__USDHC2_DATA3	0x17059
+			MX6UL_PAD_CSI_HSYNC__USDHC2_CMD		0x17059
+			MX6UL_PAD_CSI_VSYNC__USDHC2_CLK		0x17059
+
+			MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT	0x14
+		>;
+	};
+};
+
+&iomuxc_snvs {
+	pinctrl_snvs_gpio1: snvs-gpio1-grp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06	0x14 /* SODIMM 93 */
+			MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03	0x14 /* SODIMM 95 */
+			MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10	0x74 /* SODIMM 105 */
+			MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05	0x14 /* SODIMM 131 USBH OC */
+			MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08	0x74 /* SODIMM 138 */
+		>;
+	};
+
+	pinctrl_snvs_gpio2: snvs-gpio2-grp { /* ATMEL MXT TOUCH */
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04	0x74 /* SODIMM 107 */
+		>;
+	};
+
+	pinctrl_snvs_gpio3: snvs-gpio3-grp { /* Wifi pins */
+		fsl,pins = <
+			MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11	0x14 /* SODIMM 127 */
+		>;
+	};
+
+	pinctrl_snvs_ad7879_int: snvs-ad7879-int-grp { /* TOUCH Interrupt */
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07	0x1b0b0
+		>;
+	};
+
+	pinctrl_snvs_reg_sd: snvs-reg-sd-grp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09	0x4001b8b0
+		>;
+	};
+
+	pinctrl_snvs_usbc_det: snvs-usbc-det-grp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02	0x1b0b0
+		>;
+	};
+
+	pinctrl_snvs_gpiokeys: snvs-gpiokeys-grp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01	0x130b0
+		>;
+	};
+
+	pinctrl_snvs_usdhc1_cd: snvs-usdhc1-cd-grp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00	0x1b0b0 /* CD */
+		>;
+	};
+
+	pinctrl_snvs_wifi_pdn: snvs-wifi-pdn-grp {
+		fsl,pins = <
+			MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11	0x14
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h b/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h
new file mode 100644
index 0000000..f6fb678
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2017 NXP
+ */
+
+#ifndef __DTS_IMX6ULL_PINFUNC_SNVS_H
+#define __DTS_IMX6ULL_PINFUNC_SNVS_H
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10                          0x0000 0x0044 0x0000 0x5 0x0
+#define MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11                          0x0004 0x0048 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00                        0x0008 0x004C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01                        0x000C 0x0050 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02                        0x0010 0x0054 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03                        0x0014 0x0058 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04                        0x0018 0x005C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05                        0x001C 0x0060 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06                        0x0020 0x0064 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07                        0x0024 0x0068 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08                        0x0028 0x006C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09                        0x002C 0x0070 0x0000 0x5 0x0
+
+#endif /* __DTS_IMX6ULL_PINFUNC_SNVS_H */
diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
index 0c18291..571ddd7 100644
--- a/arch/arm/boot/dts/imx6ull.dtsi
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -41,3 +41,35 @@
 
 #include "imx6ul.dtsi"
 #include "imx6ull-pinfunc.h"
+#include "imx6ull-pinfunc-snvs.h"
+
+/* Delete UART8 in AIPS-1 (i.MX6UL specific) */
+/delete-node/ &uart8;
+
+/ {
+	soc {
+		aips3: aips-bus@2200000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x02200000 0x100000>;
+			ranges;
+
+			iomuxc_snvs: iomuxc-snvs@2290000 {
+				compatible = "fsl,imx6ull-iomuxc-snvs";
+				reg = <0x02290000 0x4000>;
+			};
+
+			uart8: serial@2288000 {
+				compatible = "fsl,imx6ul-uart",
+					     "fsl,imx6q-uart";
+				reg = <0x02288000 0x4000>;
+				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6UL_CLK_UART8_IPG>,
+					 <&clks IMX6UL_CLK_UART8_SERIAL>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index ae45af1..7f64568 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -18,7 +18,7 @@
 	model = "CompuLab CL-SOM-iMX7";
 	compatible = "compulab,cl-som-imx7", "fsl,imx7d";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x10000000>; /* 256 MB - minimal configuration */
 	};
 
@@ -213,37 +213,37 @@
 &iomuxc {
 	pinctrl_enet1: enet1grp {
 		fsl,pins = <
-			MX7D_PAD_SD2_CD_B__ENET1_MDIO			0x3
-			MX7D_PAD_SD2_WP__ENET1_MDC			0x3
-			MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC	0x1
-			MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0	0x1
-			MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1	0x1
-			MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2	0x1
-			MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3	0x1
-			MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL	0x1
-			MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC	0x1
-			MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0	0x1
-			MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1	0x1
-			MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2	0x1
-			MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3	0x1
-			MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL	0x1
+			MX7D_PAD_SD2_CD_B__ENET1_MDIO			0x30
+			MX7D_PAD_SD2_WP__ENET1_MDC			0x30
+			MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC	0x11
+			MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0	0x11
+			MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1	0x11
+			MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2	0x11
+			MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3	0x11
+			MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL	0x11
+			MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC	0x11
+			MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0	0x11
+			MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1	0x11
+			MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2	0x11
+			MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3	0x11
+			MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL	0x11
 		>;
 	};
 
 	pinctrl_enet2: enet2grp {
 		fsl,pins = <
-			MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC		0x1
-			MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0		0x1
-			MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1		0x1
-			MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2		0x1
-			MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3		0x1
-			MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL		0x1
-			MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC		0x1
-			MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0		0x1
-			MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1		0x1
-			MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2		0x1
-			MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3		0x1
-			MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL		0x1
+			MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC		0x11
+			MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0		0x11
+			MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1		0x11
+			MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2		0x11
+			MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3		0x11
+			MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL		0x11
+			MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC		0x11
+			MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0		0x11
+			MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1		0x11
+			MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2		0x11
+			MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3		0x11
+			MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL		0x11
 		>;
 	};
 
diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
index 9b63b9c..04d24ee 100644
--- a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
+++ b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
@@ -7,7 +7,7 @@
 #include "imx7-colibri.dtsi"
 
 / {
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx7d-colibri.dtsi b/arch/arm/boot/dts/imx7d-colibri.dtsi
index 6f2bb70..d9f8fb6 100644
--- a/arch/arm/boot/dts/imx7d-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7d-colibri.dtsi
@@ -44,7 +44,7 @@
 #include "imx7-colibri.dtsi"
 
 / {
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx7d-nitrogen7.dts b/arch/arm/boot/dts/imx7d-nitrogen7.dts
index 2b05898..52167298 100644
--- a/arch/arm/boot/dts/imx7d-nitrogen7.dts
+++ b/arch/arm/boot/dts/imx7d-nitrogen7.dts
@@ -53,7 +53,7 @@
 		t_lcd = &t_lcd;
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx7d-pico.dtsi b/arch/arm/boot/dts/imx7d-pico.dtsi
index e307462..21973eb 100644
--- a/arch/arm/boot/dts/imx7d-pico.dtsi
+++ b/arch/arm/boot/dts/imx7d-pico.dtsi
@@ -48,7 +48,7 @@
 	model = "Technexion Pico i.MX7D Board";
 	compatible = "technexion,imx7d-pico", "fsl,imx7d";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x80000000>;
 	};
 
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index e7d2db8..5d6a08b 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -48,7 +48,7 @@
 	model = "Freescale i.MX7 SabreSD Board";
 	compatible = "fsl,imx7d-sdb", "fsl,imx7d";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x80000000>;
 	};
 
@@ -336,6 +336,11 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c2>;
 	status = "okay";
+
+	mpl3115@60 {
+		compatible = "fsl,mpl3115";
+		reg = <0x60>;
+	};
 };
 
 &i2c3 {
diff --git a/arch/arm/boot/dts/imx7s-colibri.dtsi b/arch/arm/boot/dts/imx7s-colibri.dtsi
index b810134..fe8344c 100644
--- a/arch/arm/boot/dts/imx7s-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7s-colibri.dtsi
@@ -44,7 +44,7 @@
 #include "imx7-colibri.dtsi"
 
 / {
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x10000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx7s-warp.dts b/arch/arm/boot/dts/imx7s-warp.dts
index 9bdf121..8a30b14 100644
--- a/arch/arm/boot/dts/imx7s-warp.dts
+++ b/arch/arm/boot/dts/imx7s-warp.dts
@@ -50,7 +50,7 @@
 	model = "Warp i.MX7 Board";
 	compatible = "warp,imx7s-warp", "fsl,imx7s";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 
@@ -271,6 +271,15 @@
 	status = "okay";
 };
 
+&uart6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart6>;
+	assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>;
+	assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
+	fsl,dte-mode;
+	status = "okay";
+};
+
 &usbotg1 {
 	dr_mode = "peripheral";
 	status = "okay";
@@ -379,6 +388,13 @@
 		>;
 	};
 
+	pinctrl_uart6: uart6grp {
+		fsl,pins = <
+			MX7D_PAD_ECSPI1_MOSI__UART6_DTE_RX	0x79
+			MX7D_PAD_ECSPI1_SCLK__UART6_DTE_TX	0x79
+		>;
+	};
+
 	pinctrl_usdhc1: usdhc1grp {
 		fsl,pins = <
 			MX7D_PAD_SD1_CMD__SD1_CMD	0x59
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 9aa2bb9..4d42335 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -58,7 +58,7 @@
 	 * Also for U-Boot there must be a pre-existing /memory node.
 	 */
 	chosen {};
-	memory { device_type = "memory"; reg = <0 0>; };
+	memory { device_type = "memory"; };
 
 	aliases {
 		gpio0 = &gpio1;
@@ -130,6 +130,12 @@
 		#phy-cells = <0>;
 	};
 
+	pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupt-parent = <&gpc>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>;
+	};
 
 	replicator {
 		/*
@@ -499,6 +505,14 @@
 				status = "disabled";
 			};
 
+			kpp: kpp@30320000 {
+				compatible = "fsl,imx7d-kpp", "fsl,imx21-kpp";
+				reg = <0x30320000 0x10000>;
+				interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_KPP_ROOT_CLK>;
+				status = "disabled";
+			};
+
 			iomuxc: iomuxc@30330000 {
 				compatible = "fsl,imx7d-iomuxc";
 				reg = <0x30330000 0x10000>;
@@ -511,9 +525,29 @@
 			};
 
 			ocotp: ocotp-ctrl@30350000 {
+				#address-cells = <1>;
+				#size-cells = <1>;
 				compatible = "fsl,imx7d-ocotp", "syscon";
 				reg = <0x30350000 0x10000>;
 				clocks = <&clks IMX7D_OCOTP_CLK>;
+
+				tempmon_calib: calib@3c {
+					reg = <0x3c 0x4>;
+				};
+
+				tempmon_temp_grade: temp-grade@10 {
+					reg = <0x10 0x4>;
+				};
+			};
+
+			tempmon: tempmon {
+				compatible = "fsl,imx7d-tempmon";
+				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+				fsl,tempmon =<&anatop>;
+				nvmem-cells = <&tempmon_calib>,
+					<&tempmon_temp_grade>;
+				nvmem-cell-names = "calib", "temp_grade";
+				clocks = <&clks IMX7D_PLL_SYS_MAIN_CLK>;
 			};
 
 			anatop: anatop@30360000 {
@@ -551,6 +585,8 @@
 					offset = <0x34>;
 					interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
 						     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_SNVS_CLK>;
+					clock-names = "snvs-rtc";
 				};
 
 				snvs_poweroff: snvs-poweroff {
@@ -708,118 +744,156 @@
 			reg = <0x30800000 0x400000>;
 			ranges;
 
-			ecspi1: ecspi@30820000 {
+			spba-bus@30800000 {
+				compatible = "fsl,spba-bus", "simple-bus";
 				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
-				reg = <0x30820000 0x10000>;
-				interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>,
-					<&clks IMX7D_ECSPI1_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
+				#size-cells = <1>;
+				reg = <0x30800000 0x100000>;
+				ranges;
+
+				ecspi1: ecspi@30820000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
+					reg = <0x30820000 0x10000>;
+					interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>,
+						<&clks IMX7D_ECSPI1_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				ecspi2: ecspi@30830000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
+					reg = <0x30830000 0x10000>;
+					interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>,
+						<&clks IMX7D_ECSPI2_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				ecspi3: ecspi@30840000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
+					reg = <0x30840000 0x10000>;
+					interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>,
+						<&clks IMX7D_ECSPI3_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				uart1: serial@30860000 {
+					compatible = "fsl,imx7d-uart",
+						     "fsl,imx6q-uart";
+					reg = <0x30860000 0x10000>;
+					interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_UART1_ROOT_CLK>,
+						<&clks IMX7D_UART1_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				uart2: serial@30890000 {
+					compatible = "fsl,imx7d-uart",
+						     "fsl,imx6q-uart";
+					reg = <0x30890000 0x10000>;
+					interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_UART2_ROOT_CLK>,
+						<&clks IMX7D_UART2_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				uart3: serial@30880000 {
+					compatible = "fsl,imx7d-uart",
+						     "fsl,imx6q-uart";
+					reg = <0x30880000 0x10000>;
+					interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_UART3_ROOT_CLK>,
+						<&clks IMX7D_UART3_ROOT_CLK>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				sai1: sai@308a0000 {
+					#sound-dai-cells = <0>;
+					compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
+					reg = <0x308a0000 0x10000>;
+					interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_SAI1_IPG_CLK>,
+						 <&clks IMX7D_SAI1_ROOT_CLK>,
+						 <&clks IMX7D_CLK_DUMMY>,
+						 <&clks IMX7D_CLK_DUMMY>;
+					clock-names = "bus", "mclk1", "mclk2", "mclk3";
+					dma-names = "rx", "tx";
+					dmas = <&sdma 8 24 0>, <&sdma 9 24 0>;
+					status = "disabled";
+				};
+
+				sai2: sai@308b0000 {
+					#sound-dai-cells = <0>;
+					compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
+					reg = <0x308b0000 0x10000>;
+					interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_SAI2_IPG_CLK>,
+						 <&clks IMX7D_SAI2_ROOT_CLK>,
+						 <&clks IMX7D_CLK_DUMMY>,
+						 <&clks IMX7D_CLK_DUMMY>;
+					clock-names = "bus", "mclk1", "mclk2", "mclk3";
+					dma-names = "rx", "tx";
+					dmas = <&sdma 10 24 0>, <&sdma 11 24 0>;
+					status = "disabled";
+				};
+
+				sai3: sai@308c0000 {
+					#sound-dai-cells = <0>;
+					compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
+					reg = <0x308c0000 0x10000>;
+					interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&clks IMX7D_SAI3_IPG_CLK>,
+						 <&clks IMX7D_SAI3_ROOT_CLK>,
+						 <&clks IMX7D_CLK_DUMMY>,
+						 <&clks IMX7D_CLK_DUMMY>;
+					clock-names = "bus", "mclk1", "mclk2", "mclk3";
+					dma-names = "rx", "tx";
+					dmas = <&sdma 12 24 0>, <&sdma 13 24 0>;
+					status = "disabled";
+				};
 			};
 
-			ecspi2: ecspi@30830000 {
+			crypto: caam@30900000 {
+				compatible = "fsl,sec-v4.0";
 				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
-				reg = <0x30830000 0x10000>;
-				interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>,
-					<&clks IMX7D_ECSPI2_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				#size-cells = <1>;
+				reg = <0x30900000 0x40000>;
+				ranges = <0 0x30900000 0x40000>;
+				interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_CAAM_CLK>,
+					 <&clks IMX7D_AHB_CHANNEL_ROOT_CLK>;
+				clock-names = "ipg", "aclk";
 
-			ecspi3: ecspi@30840000 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
-				reg = <0x30840000 0x10000>;
-				interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>,
-					<&clks IMX7D_ECSPI3_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				sec_jr0: jr0@1000 {
+					compatible = "fsl,sec-v4.0-job-ring";
+					reg = <0x1000 0x1000>;
+					interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+				};
 
-			uart1: serial@30860000 {
-				compatible = "fsl,imx7d-uart",
-					     "fsl,imx6q-uart";
-				reg = <0x30860000 0x10000>;
-				interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_UART1_ROOT_CLK>,
-					<&clks IMX7D_UART1_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
+				sec_jr1: jr1@2000 {
+					compatible = "fsl,sec-v4.0-job-ring";
+					reg = <0x2000 0x1000>;
+					interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+				};
 
-			uart2: serial@30890000 {
-				compatible = "fsl,imx7d-uart",
-					     "fsl,imx6q-uart";
-				reg = <0x30890000 0x10000>;
-				interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_UART2_ROOT_CLK>,
-					<&clks IMX7D_UART2_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
-
-			uart3: serial@30880000 {
-				compatible = "fsl,imx7d-uart",
-					     "fsl,imx6q-uart";
-				reg = <0x30880000 0x10000>;
-				interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_UART3_ROOT_CLK>,
-					<&clks IMX7D_UART3_ROOT_CLK>;
-				clock-names = "ipg", "per";
-				status = "disabled";
-			};
-
-			sai1: sai@308a0000 {
-				#sound-dai-cells = <0>;
-				compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
-				reg = <0x308a0000 0x10000>;
-				interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_SAI1_IPG_CLK>,
-					 <&clks IMX7D_SAI1_ROOT_CLK>,
-					 <&clks IMX7D_CLK_DUMMY>,
-					 <&clks IMX7D_CLK_DUMMY>;
-				clock-names = "bus", "mclk1", "mclk2", "mclk3";
-				dma-names = "rx", "tx";
-				dmas = <&sdma 8 24 0>, <&sdma 9 24 0>;
-				status = "disabled";
-			};
-
-			sai2: sai@308b0000 {
-				#sound-dai-cells = <0>;
-				compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
-				reg = <0x308b0000 0x10000>;
-				interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_SAI2_IPG_CLK>,
-					 <&clks IMX7D_SAI2_ROOT_CLK>,
-					 <&clks IMX7D_CLK_DUMMY>,
-					 <&clks IMX7D_CLK_DUMMY>;
-				clock-names = "bus", "mclk1", "mclk2", "mclk3";
-				dma-names = "rx", "tx";
-				dmas = <&sdma 10 24 0>, <&sdma 11 24 0>;
-				status = "disabled";
-			};
-
-			sai3: sai@308c0000 {
-				#sound-dai-cells = <0>;
-				compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
-				reg = <0x308c0000 0x10000>;
-				interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clks IMX7D_SAI3_IPG_CLK>,
-					 <&clks IMX7D_SAI3_ROOT_CLK>,
-					 <&clks IMX7D_CLK_DUMMY>,
-					 <&clks IMX7D_CLK_DUMMY>;
-				clock-names = "bus", "mclk1", "mclk2", "mclk3";
-				dma-names = "rx", "tx";
-				dmas = <&sdma 12 24 0>, <&sdma 13 24 0>;
-				status = "disabled";
+				sec_jr2: jr1@3000 {
+					compatible = "fsl,sec-v4.0-job-ring";
+					reg = <0x3000 0x1000>;
+					interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+				};
 			};
 
 			flexcan1: can@30a00000 {
diff --git a/arch/arm/boot/dts/keystone-k2e-clocks.dtsi b/arch/arm/boot/dts/keystone-k2e-clocks.dtsi
index 5e0e7d2..f759215 100644
--- a/arch/arm/boot/dts/keystone-k2e-clocks.dtsi
+++ b/arch/arm/boot/dts/keystone-k2e-clocks.dtsi
@@ -42,7 +42,7 @@
 		domain-id = <0>;
 	};
 
-	clkhyperlink0: clkhyperlink02350030 {
+	clkhyperlink0: clkhyperlink0@2350030 {
 		#clock-cells = <0>;
 		compatible = "ti,keystone,psc-clock";
 		clocks = <&chipclk12>;
diff --git a/arch/arm/boot/dts/keystone-k2e.dtsi b/arch/arm/boot/dts/keystone-k2e.dtsi
index 0bcd3f8..085e732 100644
--- a/arch/arm/boot/dts/keystone-k2e.dtsi
+++ b/arch/arm/boot/dts/keystone-k2e.dtsi
@@ -109,11 +109,14 @@
 			};
 		};
 
-		dspgpio0: keystone_dsp_gpio@2620240 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x240>;
+		devctrl: device-state-control@2620000 {
+			dspgpio0: keystone_dsp_gpio@240 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x240 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x240>;
+			};
 		};
 
 		dsp0: dsp@10800000 {
diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi
index fd06171..da78c00 100644
--- a/arch/arm/boot/dts/keystone-k2g.dtsi
+++ b/arch/arm/boot/dts/keystone-k2g.dtsi
@@ -69,6 +69,24 @@
 		interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
 	};
 
+	usbphy {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "simple-bus";
+
+		usb0_phy: usb-phy@0 {
+			compatible = "usb-nop-xceiv";
+			reg = <0>;
+			status = "disabled";
+		};
+
+		usb1_phy: usb-phy@1 {
+			compatible = "usb-nop-xceiv";
+			reg = <1>;
+			status = "disabled";
+		};
+	};
+
 	soc0: soc@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -97,8 +115,28 @@
 		};
 
 		devctrl: device-state-control@2620000 {
-			compatible = "ti,keystone-devctrl", "syscon";
+			compatible = "ti,keystone-devctrl", "syscon", "simple-mfd";
 			reg = <0x02620000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x02620000 0x1000>;
+
+			kirq0: keystone_irq@2a0 {
+				compatible = "ti,keystone-irq";
+				reg = <0x2a0 0x10>;
+				interrupts = <GIC_SPI 1 IRQ_TYPE_EDGE_RISING>;
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				ti,syscon-dev = <&devctrl 0x2a0>;
+			};
+
+			dspgpio0: keystone_dsp_gpio@240 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x240 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x240>;
+			};
 		};
 
 		uart0: serial@2530c00 {
@@ -113,7 +151,7 @@
 			status = "disabled";
 		};
 
-		uart1: serial@02531000 {
+		uart1: serial@2531000 {
 			compatible = "ti,da830-uart", "ns16550a";
 			current-speed = <115200>;
 			reg-shift = <2>;
@@ -125,7 +163,7 @@
 			status = "disabled";
 		};
 
-		uart2: serial@02531400 {
+		uart2: serial@2531400 {
 			compatible = "ti,da830-uart", "ns16550a";
 			current-speed = <115200>;
 			reg-shift = <2>;
@@ -188,21 +226,6 @@
 			status = "disabled";
 		};
 
-		kirq0: keystone_irq@26202a0 {
-			compatible = "ti,keystone-irq";
-			interrupts = <GIC_SPI 1 IRQ_TYPE_EDGE_RISING>;
-			interrupt-controller;
-			#interrupt-cells = <1>;
-			ti,syscon-dev = <&devctrl 0x2a0>;
-		};
-
-		dspgpio0: keystone_dsp_gpio@2620240 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x240>;
-		};
-
 		dsp0: dsp@10800000 {
 			compatible = "ti,k2g-dsp";
 			reg = <0x10800000 0x00100000>,
@@ -460,11 +483,6 @@
 			status = "disabled";
 		};
 
-		usb0_phy: usb-phy@0 {
-			compatible = "usb-nop-xceiv";
-			status = "disabled";
-		};
-
 		keystone_usb0: keystone-dwc3@2680000 {
 			compatible = "ti,keystone-dwc3";
 			#address-cells = <1>;
@@ -488,11 +506,6 @@
 			};
 		};
 
-		usb1_phy: usb-phy@1 {
-			compatible = "usb-nop-xceiv";
-			status = "disabled";
-		};
-
 		keystone_usb1: keystone-dwc3@2580000 {
 			compatible = "ti,keystone-dwc3";
 			#address-cells = <1>;
@@ -583,5 +596,18 @@
 			power-domains = <&k2g_pds 0x0013>;
 			clocks = <&k2g_clks 0x0013 0>;
 		};
+
+		wdt: wdt@02250000 {
+			compatible = "ti,keystone-wdt", "ti,davinci-wdt";
+			reg = <0x02250000 0x80>;
+			power-domains = <&k2g_pds 0x22>;
+			clocks = <&k2g_clks 0x22 0>;
+		};
+
+		emif: emif@21010000 {
+			compatible = "ti,emif-keystone";
+			reg = <0x21010000 0x200>;
+			interrupts = <GIC_SPI 123 IRQ_TYPE_EDGE_RISING>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/keystone-k2hk.dtsi b/arch/arm/boot/dts/keystone-k2hk.dtsi
index ed59474..ca0f198 100644
--- a/arch/arm/boot/dts/keystone-k2hk.dtsi
+++ b/arch/arm/boot/dts/keystone-k2hk.dtsi
@@ -87,60 +87,70 @@
 			};
 		};
 
-		dspgpio0: keystone_dsp_gpio@2620240 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x240>;
-		};
+		devctrl: device-state-control@2620000 {
+			dspgpio0: keystone_dsp_gpio@240 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x240 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x240>;
+			};
 
-		dspgpio1: keystone_dsp_gpio@2620244 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x244>;
-		};
+			dspgpio1: keystone_dsp_gpio@244 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x244 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x244>;
+			};
 
-		dspgpio2: keystone_dsp_gpio@2620248 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x248>;
-		};
+			dspgpio2: keystone_dsp_gpio@248 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x248 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x248>;
+			};
 
-		dspgpio3: keystone_dsp_gpio@262024c {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x24c>;
-		};
+			dspgpio3: keystone_dsp_gpio@24c {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x24c 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x24c>;
+			};
 
-		dspgpio4: keystone_dsp_gpio@2620250 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x250>;
-		};
+			dspgpio4: keystone_dsp_gpio@250 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x250 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x250>;
+			};
 
-		dspgpio5: keystone_dsp_gpio@2620254 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x254>;
-		};
+			dspgpio5: keystone_dsp_gpio@254 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x254 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x254>;
+			};
 
-		dspgpio6: keystone_dsp_gpio@2620258 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x258>;
-		};
+			dspgpio6: keystone_dsp_gpio@258 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x258 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x258>;
+			};
 
-		dspgpio7: keystone_dsp_gpio@262025c {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x25c>;
+			dspgpio7: keystone_dsp_gpio@25c {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x25c 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x25c>;
+			};
 		};
 
 		dsp0: dsp@10800000 {
diff --git a/arch/arm/boot/dts/keystone-k2l.dtsi b/arch/arm/boot/dts/keystone-k2l.dtsi
index b61a830..374c801 100644
--- a/arch/arm/boot/dts/keystone-k2l.dtsi
+++ b/arch/arm/boot/dts/keystone-k2l.dtsi
@@ -289,32 +289,38 @@
 			clocks = <&clkosr>;
 		};
 
-		dspgpio0: keystone_dsp_gpio@2620240 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x240>;
-		};
+		devctrl: device-state-control@2620000 {
+			dspgpio0: keystone_dsp_gpio@240 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x240 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x240>;
+			};
 
-		dspgpio1: keystone_dsp_gpio@2620244 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x244>;
-		};
+			dspgpio1: keystone_dsp_gpio@244 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x244 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x244>;
+			};
 
-		dspgpio2: keystone_dsp_gpio@2620248 {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x248>;
-		};
+			dspgpio2: keystone_dsp_gpio@248 {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x248 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x248>;
+			};
 
-		dspgpio3: keystone_dsp_gpio@262024c {
-			compatible = "ti,keystone-dsp-gpio";
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio,syscon-dev = <&devctrl 0x24c>;
+			dspgpio3: keystone_dsp_gpio@24c {
+				compatible = "ti,keystone-dsp-gpio";
+				reg = <0x24c 0x4>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio,syscon-dev = <&devctrl 0x24c>;
+			};
 		};
 
 		dsp0: dsp@10800000 {
diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index 93ea5c6..c298675 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -87,15 +87,28 @@
 		};
 
 		devctrl: device-state-control@2620000 {
-			compatible = "ti,keystone-devctrl", "syscon";
+			compatible = "ti,keystone-devctrl", "syscon", "simple-mfd";
 			reg = <0x02620000 0x1000>;
-		};
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x02620000 0x1000>;
 
-		rstctrl: reset-controller {
-			compatible = "ti,keystone-reset";
-			ti,syscon-pll = <&pllctrl 0xe4>;
-			ti,syscon-dev = <&devctrl 0x328>;
-			ti,wdt-list = <0>;
+			kirq0: keystone_irq@2a0 {
+				compatible = "ti,keystone-irq";
+				reg = <0x2a0 0x4>;
+				interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				ti,syscon-dev = <&devctrl 0x2a0>;
+			};
+
+			rstctrl: reset-controller@328 {
+				compatible = "ti,keystone-reset";
+				reg = <0x328 0x10>;
+				ti,syscon-pll = <&pllctrl 0xe4>;
+				ti,syscon-dev = <&devctrl 0x328>;
+				ti,wdt-list = <0>;
+			};
 		};
 
 		/include/ "keystone-clocks.dtsi"
@@ -282,14 +295,6 @@
 				  1 0 0x21000A00 0x00000100>;
 		};
 
-		kirq0: keystone_irq@26202a0 {
-			compatible = "ti,keystone-irq";
-			interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
-			interrupt-controller;
-			#interrupt-cells = <1>;
-			ti,syscon-dev = <&devctrl 0x2a0>;
-		};
-
 		pcie0: pcie@21800000 {
 			compatible = "ti,keystone-pcie", "snps,dw-pcie";
 			clocks = <&clkpcie>;
@@ -338,5 +343,12 @@
 					<GIC_SPI 29 IRQ_TYPE_EDGE_RISING>;
 			};
 		};
+
+		emif: emif@21010000 {
+			compatible = "ti,emif-keystone";
+			reg = <0x21010000 0x200>;
+			interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+			interrupt-parent = <&gic>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/kirkwood-b3.dts b/arch/arm/boot/dts/kirkwood-b3.dts
index d091ecb..17f48f8 100644
--- a/arch/arm/boot/dts/kirkwood-b3.dts
+++ b/arch/arm/boot/dts/kirkwood-b3.dts
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Device Tree file for Excito Bubba B3
  *
  * Copyright (C) 2013, Andrew Lunn <andrew@lunn.ch>
  *
- * This program is free software; you can redistribute 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.
  *
  * Note: This requires a new'ish version of u-boot, which disables the
  * L2 cache. If your B3 silently fails to boot, u-boot is probably too
diff --git a/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts b/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
index f16a73e..07fbfca 100644
--- a/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
+++ b/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Device Tree file for Seagate Blackarmor NAS220
  *
  * Copyright (C) 2014 Evgeni Dobrev <evgeni@studio-punkt.com>
- *
- * Licensed under GPLv2 or later.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-d2net.dts b/arch/arm/boot/dts/kirkwood-d2net.dts
index e1c25c3..bd3b266 100644
--- a/arch/arm/boot/dts/kirkwood-d2net.dts
+++ b/arch/arm/boot/dts/kirkwood-d2net.dts
@@ -1,11 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for d2 Network v2
  *
  * Copyright (C) 2014 Simon Guinot <simon.guinot@sequanux.org>
  *
- * 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.
 */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-db-88f6281.dts b/arch/arm/boot/dts/kirkwood-db-88f6281.dts
index aee6f02..2adb17c 100644
--- a/arch/arm/boot/dts/kirkwood-db-88f6281.dts
+++ b/arch/arm/boot/dts/kirkwood-db-88f6281.dts
@@ -1,12 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell DB-88F6281-BP Development Board Setup
  *
  * Saeed Bishara <saeed@marvell.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-db-88f6282.dts b/arch/arm/boot/dts/kirkwood-db-88f6282.dts
index e8b23e1..f84a485 100644
--- a/arch/arm/boot/dts/kirkwood-db-88f6282.dts
+++ b/arch/arm/boot/dts/kirkwood-db-88f6282.dts
@@ -1,12 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell DB-88F6282-BP Development Board Setup
  *
  * Saeed Bishara <saeed@marvell.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-db.dtsi b/arch/arm/boot/dts/kirkwood-db.dtsi
index 812df69..6fe2e31 100644
--- a/arch/arm/boot/dts/kirkwood-db.dtsi
+++ b/arch/arm/boot/dts/kirkwood-db.dtsi
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell DB-{88F6281,88F6282}-BP Development Board Setup
  *
  * Saeed Bishara <saeed@marvell.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- *
  * This file contains the definitions that are common between the 6281
  * and 6282 variants of the Marvell Kirkwood Development Board.
  */
diff --git a/arch/arm/boot/dts/kirkwood-dir665.dts b/arch/arm/boot/dts/kirkwood-dir665.dts
index 4d2b15d..31ceacd 100644
--- a/arch/arm/boot/dts/kirkwood-dir665.dts
+++ b/arch/arm/boot/dts/kirkwood-dir665.dts
@@ -1,9 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2014 Claudio Leite <leitec@staticky.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds109.dts b/arch/arm/boot/dts/kirkwood-ds109.dts
index d4bcc1c..29982e7 100644
--- a/arch/arm/boot/dts/kirkwood-ds109.dts
+++ b/arch/arm/boot/dts/kirkwood-ds109.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds110jv10.dts b/arch/arm/boot/dts/kirkwood-ds110jv10.dts
index 95bf83b..d68c616 100644
--- a/arch/arm/boot/dts/kirkwood-ds110jv10.dts
+++ b/arch/arm/boot/dts/kirkwood-ds110jv10.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds111.dts b/arch/arm/boot/dts/kirkwood-ds111.dts
index a85a466..e1420cb 100644
--- a/arch/arm/boot/dts/kirkwood-ds111.dts
+++ b/arch/arm/boot/dts/kirkwood-ds111.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds112.dts b/arch/arm/boot/dts/kirkwood-ds112.dts
index 6cef4bd..f48609e 100644
--- a/arch/arm/boot/dts/kirkwood-ds112.dts
+++ b/arch/arm/boot/dts/kirkwood-ds112.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds209.dts b/arch/arm/boot/dts/kirkwood-ds209.dts
index 6d25093..f41fe95 100644
--- a/arch/arm/boot/dts/kirkwood-ds209.dts
+++ b/arch/arm/boot/dts/kirkwood-ds209.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds210.dts b/arch/arm/boot/dts/kirkwood-ds210.dts
index 2f1933e..729f959 100644
--- a/arch/arm/boot/dts/kirkwood-ds210.dts
+++ b/arch/arm/boot/dts/kirkwood-ds210.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds212.dts b/arch/arm/boot/dts/kirkwood-ds212.dts
index 7f32e7a..416bab5 100644
--- a/arch/arm/boot/dts/kirkwood-ds212.dts
+++ b/arch/arm/boot/dts/kirkwood-ds212.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds212j.dts b/arch/arm/boot/dts/kirkwood-ds212j.dts
index f5c4213..14cf4d8 100644
--- a/arch/arm/boot/dts/kirkwood-ds212j.dts
+++ b/arch/arm/boot/dts/kirkwood-ds212j.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds409.dts b/arch/arm/boot/dts/kirkwood-ds409.dts
index e80a962e..a8650f9 100644
--- a/arch/arm/boot/dts/kirkwood-ds409.dts
+++ b/arch/arm/boot/dts/kirkwood-ds409.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds409slim.dts b/arch/arm/boot/dts/kirkwood-ds409slim.dts
index cae5af4..27a1d84 100644
--- a/arch/arm/boot/dts/kirkwood-ds409slim.dts
+++ b/arch/arm/boot/dts/kirkwood-ds409slim.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds411.dts b/arch/arm/boot/dts/kirkwood-ds411.dts
index 72e5830..86907be 100644
--- a/arch/arm/boot/dts/kirkwood-ds411.dts
+++ b/arch/arm/boot/dts/kirkwood-ds411.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds411j.dts b/arch/arm/boot/dts/kirkwood-ds411j.dts
index 3348e33..bb3200d 100644
--- a/arch/arm/boot/dts/kirkwood-ds411j.dts
+++ b/arch/arm/boot/dts/kirkwood-ds411j.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ds411slim.dts b/arch/arm/boot/dts/kirkwood-ds411slim.dts
index aaaf31b..9c5364a 100644
--- a/arch/arm/boot/dts/kirkwood-ds411slim.dts
+++ b/arch/arm/boot/dts/kirkwood-ds411slim.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-laplug.dts b/arch/arm/boot/dts/kirkwood-laplug.dts
index 1b0f070..6158214 100644
--- a/arch/arm/boot/dts/kirkwood-laplug.dts
+++ b/arch/arm/boot/dts/kirkwood-laplug.dts
@@ -1,9 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2013 Maxime Hadjinlian <maxime.hadjinlian@gmail.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi b/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi
index b9125e5..377b6e9 100644
--- a/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi
+++ b/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree common file for kirkwood-6282 based Buffalo Linkstation
  *
  * Copyright (C) 2015, 2016
  * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "kirkwood.dtsi"
diff --git a/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi b/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi
index 29d9295..ba629e0 100644
--- a/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi
+++ b/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree common file for kirkwood-6281 based 2-Bay Buffalo Linkstation
  *
  * Copyright (C) 2015, 2016
  * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "kirkwood.dtsi"
diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts
index 9cc0520..8bb3810 100644
--- a/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts
+++ b/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Buffalo Linkstation LS-QVL
  *
@@ -6,44 +7,6 @@
  * Based on kirkwood-linkstation-lswvl.dts,
  * Copyright (C) 2015, 2016
  * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts
index ff37e76..3f2a0bf 100644
--- a/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts
+++ b/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Buffalo Linkstation LS-VL
  *
  * Copyright (C) 2015, 2016
  * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts
index f602c05..c42d0da 100644
--- a/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts
+++ b/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Buffalo Linkstation LS-WSXL
  *
  * Copyright (C) 2015, 2016
  * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts
index ef8fc1a..e0f62ad 100644
--- a/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts
+++ b/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Buffalo Linkstation LS-WVL
  *
  * Copyright (C) 2015, 2016
  * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts
index ce41d55..c6024b5 100644
--- a/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts
+++ b/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Buffalo Linkstation LS-WXL
  *
  * Copyright (C) 2015, 2016
  * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-linkstation.dtsi b/arch/arm/boot/dts/kirkwood-linkstation.dtsi
index b459042..407d6d8 100644
--- a/arch/arm/boot/dts/kirkwood-linkstation.dtsi
+++ b/arch/arm/boot/dts/kirkwood-linkstation.dtsi
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree common file for kirkwood based Buffalo Linkstation
  *
  * Copyright (C) 2015, 2016
  * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 / {
diff --git a/arch/arm/boot/dts/kirkwood-linksys-viper.dts b/arch/arm/boot/dts/kirkwood-linksys-viper.dts
index f21a50d..a7d659b 100644
--- a/arch/arm/boot/dts/kirkwood-linksys-viper.dts
+++ b/arch/arm/boot/dts/kirkwood-linksys-viper.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * kirkwood-viper.dts - Device Tree file for Linksys viper (E4200v2 / EA4500)
  *
@@ -6,9 +7,6 @@
  * (c) 2014 Luka Perkov <luka@openwrt.org>
  * (c) 2014 Randy C. Will <randall.will@gmail.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
index 327023a..86d5329 100644
--- a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
+++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell 88F6281 GTW GE Board
  *
  * Lennert Buytenhek <buytenh@marvell.com>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- *
  * This file contains the definitions that are common between the 6281
  * and 6282 variants of the Marvell Kirkwood Development Board.
  */
diff --git a/arch/arm/boot/dts/kirkwood-nas2big.dts b/arch/arm/boot/dts/kirkwood-nas2big.dts
index f53bcac..6a2934b 100644
--- a/arch/arm/boot/dts/kirkwood-nas2big.dts
+++ b/arch/arm/boot/dts/kirkwood-nas2big.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for LaCie 2Big NAS
  *
@@ -5,9 +6,6 @@
  *
  * Author: Simon Guinot <simon.guinot@sequanux.org>
  *
- * 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.
 */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-net2big.dts b/arch/arm/boot/dts/kirkwood-net2big.dts
index 13a4477..3e3ac28 100644
--- a/arch/arm/boot/dts/kirkwood-net2big.dts
+++ b/arch/arm/boot/dts/kirkwood-net2big.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for LaCie 2Big Network v2
  *
@@ -8,9 +9,6 @@
  * Based on netxbig_v2-setup.c,
  * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
 */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-net5big.dts b/arch/arm/boot/dts/kirkwood-net5big.dts
index d2d44df..cba8a2b 100644
--- a/arch/arm/boot/dts/kirkwood-net5big.dts
+++ b/arch/arm/boot/dts/kirkwood-net5big.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for LaCie 5Big Network v2
  *
@@ -8,9 +9,6 @@
  * Based on netxbig_v2-setup.c,
  * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
 */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
index c0413b6..cb564c3 100644
--- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
+++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Device Tree file for NETGEAR ReadyNAS Duo v2
  *
  * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts
index 2bfc6cf..8cc8550 100644
--- a/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts
+++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Device Tree file for NETGEAR ReadyNAS NV+ v2
  *
  * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-netxbig.dtsi b/arch/arm/boot/dts/kirkwood-netxbig.dtsi
index 52b58fe..b573702 100644
--- a/arch/arm/boot/dts/kirkwood-netxbig.dtsi
+++ b/arch/arm/boot/dts/kirkwood-netxbig.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree common file for LaCie 2Big and 5Big Network v2
  *
@@ -8,9 +9,6 @@
  * Based on netxbig_v2-setup.c,
  * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
 */
 
 #include <dt-bindings/leds/leds-netxbig.h>
diff --git a/arch/arm/boot/dts/kirkwood-nsa320.dts b/arch/arm/boot/dts/kirkwood-nsa320.dts
index 6ab104b..b69b096 100644
--- a/arch/arm/boot/dts/kirkwood-nsa320.dts
+++ b/arch/arm/boot/dts/kirkwood-nsa320.dts
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /* Device tree file for the Zyxel NSA 320 NAS box.
  *
  * Copyright (c) 2014, Adam Baker <linux@baker-net.org.uk>
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
  *
  * Based upon the board setup file created by Peter Schildmann */
 
diff --git a/arch/arm/boot/dts/kirkwood-nsa325.dts b/arch/arm/boot/dts/kirkwood-nsa325.dts
index 36c6481..6f8085d 100644
--- a/arch/arm/boot/dts/kirkwood-nsa325.dts
+++ b/arch/arm/boot/dts/kirkwood-nsa325.dts
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /* Device tree file for the Zyxel NSA 325 NAS box.
  *
  * Copyright (c) 2015, Hans Ulli Kroll <ulli.kroll@googlemail.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.
  *
  * Based upon the board setup file created by Peter Schildmann
  */
diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts
index 27cc913..946f0f4 100644
--- a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts
+++ b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for OpenBlocks A7 board
  *
@@ -5,9 +6,6 @@
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-openrd-base.dts b/arch/arm/boot/dts/kirkwood-openrd-base.dts
index 8af5899..094191e 100644
--- a/arch/arm/boot/dts/kirkwood-openrd-base.dts
+++ b/arch/arm/boot/dts/kirkwood-openrd-base.dts
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell OpenRD Base Board Description
  *
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
- *
  * This file contains the definitions that are specific to OpenRD
  * base variant of the Marvell Kirkwood Development Board.
  */
diff --git a/arch/arm/boot/dts/kirkwood-openrd-client.dts b/arch/arm/boot/dts/kirkwood-openrd-client.dts
index 96ff59d..d4e0b81 100644
--- a/arch/arm/boot/dts/kirkwood-openrd-client.dts
+++ b/arch/arm/boot/dts/kirkwood-openrd-client.dts
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell OpenRD Client Board Description
  *
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
- *
  * This file contains the definitions that are specific to OpenRD
  * client variant of the Marvell Kirkwood Development Board.
  */
diff --git a/arch/arm/boot/dts/kirkwood-openrd-ultimate.dts b/arch/arm/boot/dts/kirkwood-openrd-ultimate.dts
index 9f12f8b..888e133 100644
--- a/arch/arm/boot/dts/kirkwood-openrd-ultimate.dts
+++ b/arch/arm/boot/dts/kirkwood-openrd-ultimate.dts
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell OpenRD Ultimate Board Description
  *
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
- *
  * This file contains the definitions that are specific to OpenRD
  * ultimate variant of the Marvell Kirkwood Development Board.
  */
diff --git a/arch/arm/boot/dts/kirkwood-openrd.dtsi b/arch/arm/boot/dts/kirkwood-openrd.dtsi
index 7175511..47f03c6 100644
--- a/arch/arm/boot/dts/kirkwood-openrd.dtsi
+++ b/arch/arm/boot/dts/kirkwood-openrd.dtsi
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell OpenRD (Base|Client|Ultimate) Board Description
  *
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
- *
  * This file contains the definitions that are common between the three
  * variants of the Marvell Kirkwood Development Board.
  */
diff --git a/arch/arm/boot/dts/kirkwood-pogo_e02.dts b/arch/arm/boot/dts/kirkwood-pogo_e02.dts
index a190080..f9e95e5 100644
--- a/arch/arm/boot/dts/kirkwood-pogo_e02.dts
+++ b/arch/arm/boot/dts/kirkwood-pogo_e02.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * kirkwood-pogo_e02.dts - Device tree file for Pogoplug E02
  *
@@ -7,9 +8,6 @@
  *  Arch Linux ARM by Oleg Rakhmanov <moonman.ca@gmail.com>
  *  OpenWrt by Felix Kaechele <heffer@fedoraproject.org>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
index 5ce220a..5aa4669 100644
--- a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
+++ b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
@@ -35,7 +35,7 @@
 		pinctrl-names = "default";
 
 		eject {
-			debounce_interval = <50>;
+			debounce-interval = <50>;
 			wakeup-source;
 			linux,code = <KEY_EJECTCD>;
 			label = "Eject Button";
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6192.dts b/arch/arm/boot/dts/kirkwood-rd88f6192.dts
index b8af907..712d604 100644
--- a/arch/arm/boot/dts/kirkwood-rd88f6192.dts
+++ b/arch/arm/boot/dts/kirkwood-rd88f6192.dts
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell RD88F6192 Board descrition
  *
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
- *
  * This file contains the definitions that are common between the three
  * variants of the Marvell Kirkwood Development Board.
  */
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281-a.dts b/arch/arm/boot/dts/kirkwood-rd88f6281-a.dts
index 9ec5a65..5da1635 100644
--- a/arch/arm/boot/dts/kirkwood-rd88f6281-a.dts
+++ b/arch/arm/boot/dts/kirkwood-rd88f6281-a.dts
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell RD88F6181 A Board descrition
  *
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
- *
  * This file contains the definitions for the board with the A0 or
  * higher stepping of the SoC. The ethernet switch does not have a
  * "wan" port.
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts b/arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts
index 6a4a65e..a9fee2c 100644
--- a/arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts
+++ b/arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell RD88F6181 Z0 stepping descrition
  *
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
- *
  * This file contains the definitions for the board using the Z0
  * stepping of the SoC. The ethernet switch has a "wan" port.
 */
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
index 91f5da5..0f22f0e 100644
--- a/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
+++ b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell RD88F6181 Common Board descrition
  *
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
- *
  * This file contains the definitions that are common between the two
  * variants of the Marvell Kirkwood Development Board.
  */
diff --git a/arch/arm/boot/dts/kirkwood-rs212.dts b/arch/arm/boot/dts/kirkwood-rs212.dts
index 2c722ec..c51cea8 100644
--- a/arch/arm/boot/dts/kirkwood-rs212.dts
+++ b/arch/arm/boot/dts/kirkwood-rs212.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-rs409.dts b/arch/arm/boot/dts/kirkwood-rs409.dts
index 921ca49..43673b03 100644
--- a/arch/arm/boot/dts/kirkwood-rs409.dts
+++ b/arch/arm/boot/dts/kirkwood-rs409.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-rs411.dts b/arch/arm/boot/dts/kirkwood-rs411.dts
index 02852b0..41fa63c 100644
--- a/arch/arm/boot/dts/kirkwood-rs411.dts
+++ b/arch/arm/boot/dts/kirkwood-rs411.dts
@@ -1,10 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
index 7196c7f..0a698d3 100644
--- a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
+++ b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * kirkwood-sheevaplug-common.dtsi - Common parts for Sheevaplugs
  *
  * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
- *
- * Licensed under GPLv2
  */
 
 #include "kirkwood.dtsi"
diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts b/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts
index e2b4ea4..ae8f493 100644
--- a/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts
+++ b/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * kirkwood-sheevaplug-esata.dts - Device tree file for eSATA Sheevaplug
  *
  * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
- *
- * Licensed under GPLv2
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug.dts b/arch/arm/boot/dts/kirkwood-sheevaplug.dts
index 82f6abf..c73cc90 100644
--- a/arch/arm/boot/dts/kirkwood-sheevaplug.dts
+++ b/arch/arm/boot/dts/kirkwood-sheevaplug.dts
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * kirkwood-sheevaplug.dts - Device tree file for Sheevaplug
  *
  * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
- *
- * Licensed under GPLv2
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-synology.dtsi b/arch/arm/boot/dts/kirkwood-synology.dtsi
index 210d21a..c97ed29 100644
--- a/arch/arm/boot/dts/kirkwood-synology.dtsi
+++ b/arch/arm/boot/dts/kirkwood-synology.dtsi
@@ -1,12 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Nodes for Marvell 628x Synology devices
  *
  * Andrew Lunn <andrew@lunn.ch>
  * Ben Peddell <klightspeed@killerwolves.net>
  *
- * 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.
  */
 
 / {
diff --git a/arch/arm/boot/dts/kirkwood-t5325.dts b/arch/arm/boot/dts/kirkwood-t5325.dts
index 3500f473..fe63b3a 100644
--- a/arch/arm/boot/dts/kirkwood-t5325.dts
+++ b/arch/arm/boot/dts/kirkwood-t5325.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree file for HP t5325 Thin Client"
  *
@@ -6,9 +7,6 @@
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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.
 */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ts419-6281.dts b/arch/arm/boot/dts/kirkwood-ts419-6281.dts
index aa22aa8..4a42ebc 100644
--- a/arch/arm/boot/dts/kirkwood-ts419-6281.dts
+++ b/arch/arm/boot/dts/kirkwood-ts419-6281.dts
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Device Tree file for QNAP TS41X with 6281 SoC
  *
  * Copyright (C) 2013, Andrew Lunn <andrew@lunn.ch>
- *
- * This program is free software; you can redistribute 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ts419-6282.dts b/arch/arm/boot/dts/kirkwood-ts419-6282.dts
index e3e71f4..be772e1 100644
--- a/arch/arm/boot/dts/kirkwood-ts419-6282.dts
+++ b/arch/arm/boot/dts/kirkwood-ts419-6282.dts
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Device Tree file for QNAP TS41X with 6282 SoC
  *
  * Copyright (C) 2013, Andrew Lunn <andrew@lunn.ch>
- *
- * This program is free software; you can redistribute 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.
  */
 
 /dts-v1/;
diff --git a/arch/arm/boot/dts/kirkwood-ts419.dtsi b/arch/arm/boot/dts/kirkwood-ts419.dtsi
index 02bd537..7172368 100644
--- a/arch/arm/boot/dts/kirkwood-ts419.dtsi
+++ b/arch/arm/boot/dts/kirkwood-ts419.dtsi
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Device Tree include file for QNAP TS41X
  *
  * Copyright (C) 2013, Andrew Lunn <andrew@lunn.ch>
- *
- * This program is free software; you can redistribute 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.
  */
 
 / {
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index eb2bf74..81c7eda 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -382,7 +382,7 @@
 
 		audio0: audio-controller@a0000 {
 			compatible = "marvell,kirkwood-audio";
-			#sound-dai-cells = <1>;
+			#sound-dai-cells = <0>;
 			reg = <0xa0000 0x2210>;
 			interrupts = <24>;
 			clocks = <&gate_clk 9>;
diff --git a/arch/arm/boot/dts/logicpd-som-lv.dtsi b/arch/arm/boot/dts/logicpd-som-lv.dtsi
index a30ee9f..b47cac2 100644
--- a/arch/arm/boot/dts/logicpd-som-lv.dtsi
+++ b/arch/arm/boot/dts/logicpd-som-lv.dtsi
@@ -88,10 +88,14 @@
 };
 
 &i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
 	clock-frequency = <400000>;
 };
 
 &i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_pins>;
 	clock-frequency = <400000>;
 };
 
@@ -213,6 +217,18 @@
 			OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4)	/* sys_boot1.gpio_3 */
 		>;
 	};
+	i2c2_pins: pinmux_i2c2_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0)	/* i2c2_scl */
+			OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0)	/* i2c2_sda */
+		>;
+	};
+	i2c3_pins: pinmux_i2c3_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0)	/* i2c3_scl */
+			OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0)	/* i2c3_sda */
+		>;
+	};
 };
 
 &omap3_pmx_core2 {
diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
index 4791544..3e174e4 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
@@ -83,10 +83,14 @@
 };
 
 &i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
 	clock-frequency = <400000>;
 };
 
 &i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_pins>;
 	clock-frequency = <400000>;
 	at24@50 {
 		compatible = "atmel,24c64";
@@ -144,6 +148,18 @@
 			OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0)        /* i2c1_sda.i2c1_sda */
 		>;
 	};
+	i2c2_pins: pinmux_i2c2_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0)	/* i2c2_scl */
+			OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0)	/* i2c2_sda */
+		>;
+	};
+	i2c3_pins: pinmux_i2c3_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0)	/* i2c3_scl */
+			OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0)	/* i2c3_sda */
+		>;
+	};
 };
 
 &uart2 {
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c31dad9..fbd2897 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -788,5 +788,21 @@
 			clock-names = "ipg", "per";
 			big-endian;
 		};
+
+		ocram1: sram@10000000 {
+			compatible = "mmio-sram";
+			reg = <0x0 0x10000000 0x0 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x0 0x10000000 0x10000>;
+		};
+
+		ocram2: sram@10010000 {
+			compatible = "mmio-sram";
+			reg = <0x0 0x10010000 0x0 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x0 0x10010000 0x10000>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi
index d2e3eea..dcc9292 100644
--- a/arch/arm/boot/dts/meson8.dtsi
+++ b/arch/arm/boot/dts/meson8.dtsi
@@ -46,6 +46,7 @@
 #include <dt-bindings/clock/meson8b-clkc.h>
 #include <dt-bindings/gpio/meson8-gpio.h>
 #include <dt-bindings/reset/amlogic,meson8b-clkc-reset.h>
+#include <dt-bindings/reset/amlogic,meson8b-reset.h>
 #include "meson.dtsi"
 
 / {
@@ -187,6 +188,12 @@
 		reg = <0x8000 0x4>, <0x4000 0x460>;
 	};
 
+	reset: reset-controller@4404 {
+		compatible = "amlogic,meson8b-reset";
+		reg = <0x4404 0x9c>;
+		#reset-cells = <1>;
+	};
+
 	analog_top: analog-top@81a8 {
 		compatible = "amlogic,meson8-analog-top", "syscon";
 		reg = <0x81a8 0x14>;
@@ -383,10 +390,12 @@
 	compatible = "amlogic,meson8-usb2-phy", "amlogic,meson-mx-usb2-phy";
 	clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB0>;
 	clock-names = "usb_general", "usb";
+	resets = <&reset RESET_USB_OTG>;
 };
 
 &usb1_phy {
 	compatible = "amlogic,meson8-usb2-phy", "amlogic,meson-mx-usb2-phy";
 	clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB1>;
 	clock-names = "usb_general", "usb";
+	resets = <&reset RESET_USB_OTG>;
 };
diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts
index 9ff6ca4..3a5603d 100644
--- a/arch/arm/boot/dts/meson8b-odroidc1.dts
+++ b/arch/arm/boot/dts/meson8b-odroidc1.dts
@@ -54,6 +54,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		mmc0 = &sd_card_slot;
 	};
 
 	memory {
@@ -69,6 +70,37 @@
 			default-state = "off";
 		};
 	};
+
+	tflash_vdd: regulator-tflash_vdd {
+		/*
+		 * signal name from schematics: TFLASH_VDD_EN
+		 */
+		compatible = "regulator-fixed";
+
+		regulator-name = "TFLASH_VDD";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpio = <&gpio GPIOY_12 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	tf_io: gpio-regulator-tf_io {
+		compatible = "regulator-gpio";
+
+		regulator-name = "TF_IO";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+
+		/*
+		 * signal name from schematics: TF_3V3N_1V8_EN
+		 */
+		gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
+		gpios-states = <0>;
+
+		states = <3300000 0
+			  1800000 1>;
+	};
 };
 
 &uart_AO {
@@ -99,3 +131,59 @@
 &usb1 {
 	status = "okay";
 };
+
+&sdio {
+	status = "okay";
+
+	pinctrl-0 = <&sd_b_pins>;
+	pinctrl-names = "default";
+
+	/* SD card */
+	sd_card_slot: slot@1 {
+		compatible = "mmc-slot";
+		reg = <1>;
+		status = "okay";
+
+		bus-width = <4>;
+		no-sdio;
+		cap-mmc-highspeed;
+		cap-sd-highspeed;
+		disable-wp;
+
+		cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+		cd-inverted;
+
+		vmmc-supply = <&tflash_vdd>;
+		vqmmc-supply = <&tf_io>;
+	};
+};
+
+&ethmac {
+	status = "okay";
+
+	snps,reset-gpio = <&gpio GPIOH_4 GPIO_ACTIVE_HIGH>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 30000>;
+
+	pinctrl-0 = <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+
+	phy-mode = "rgmii";
+	phy-handle = <&eth_phy>;
+	amlogic,tx-delay-ns = <4>;
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* Realtek RTL8211F (0x001cc916) */
+		eth_phy: ethernet-phy@0 {
+			reg = <0>;
+			eee-broken-1000t;
+			interrupt-parent = <&gpio_intc>;
+			/* GPIOH_3 */
+			interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi
index 7cd03ed..553b821 100644
--- a/arch/arm/boot/dts/meson8b.dtsi
+++ b/arch/arm/boot/dts/meson8b.dtsi
@@ -152,7 +152,7 @@
 
 	reset: reset-controller@4404 {
 		compatible = "amlogic,meson8b-reset";
-		reg = <0x4404 0x20>;
+		reg = <0x4404 0x9c>;
 		#reset-cells = <1>;
 	};
 
@@ -183,7 +183,36 @@
 			reg-names = "mux", "pull", "pull-enable", "gpio";
 			gpio-controller;
 			#gpio-cells = <2>;
-			gpio-ranges = <&pinctrl_cbus 0 0 130>;
+			gpio-ranges = <&pinctrl_cbus 0 0 83>;
+		};
+
+		eth_rgmii_pins: eth-rgmii {
+			mux {
+				groups = "eth_tx_clk",
+					 "eth_tx_en",
+					 "eth_txd1_0",
+					 "eth_txd1_1",
+					 "eth_txd0_0",
+					 "eth_txd0_1",
+					 "eth_rx_clk",
+					 "eth_rx_dv",
+					 "eth_rxd1",
+					 "eth_rxd0",
+					 "eth_mdio_en",
+					 "eth_mdc",
+					 "eth_ref_clk",
+					 "eth_txd2",
+					 "eth_txd3";
+				function = "ethernet";
+			};
+		};
+
+		sd_b_pins: sd-b {
+			mux {
+				groups = "sd_d0_b", "sd_d1_b", "sd_d2_b",
+					"sd_d3_b", "sd_clk_b", "sd_cmd_b";
+				function = "sd_b";
+			};
 		};
 	};
 };
@@ -203,8 +232,18 @@
 };
 
 &ethmac {
-	clocks = <&clkc CLKID_ETH>;
-	clock-names = "stmmaceth";
+	compatible = "amlogic,meson8b-dwmac", "snps,dwmac-3.70a", "snps,dwmac";
+
+	reg = <0xc9410000 0x10000
+	       0xc1108140 0x4>;
+
+	clocks = <&clkc CLKID_ETH>,
+		 <&clkc CLKID_MPLL2>,
+		 <&clkc CLKID_MPLL2>;
+	clock-names = "stmmaceth", "clkin0", "clkin1";
+
+	resets = <&reset RESET_ETHERNET>;
+	reset-names = "stmmaceth";
 };
 
 &gpio_intc {
@@ -219,6 +258,18 @@
 	clock-names = "core";
 };
 
+&i2c_AO {
+	clocks = <&clkc CLKID_CLK81>;
+};
+
+&i2c_A {
+	clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_B {
+	clocks = <&clkc CLKID_I2C>;
+};
+
 &L2 {
 	arm,data-latency = <3 3 3>;
 	arm,tag-latency = <2 2 2>;
diff --git a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi
index 4d61e5b..ddc7a7b 100644
--- a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi
+++ b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi
@@ -68,6 +68,19 @@
 			};
 		};
 
+		cpcap_audio: audio-codec {
+			#sound-dai-cells = <1>;
+
+			port@0 {
+				cpcap_audio_codec0: endpoint {
+				};
+			};
+			port@1 {
+				cpcap_audio_codec1: endpoint {
+				};
+			};
+		};
+
 		cpcap_rtc: rtc {
 			compatible = "motorola,cpcap-rtc";
 
diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index 8e7c654..e10c034 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -28,7 +28,7 @@
 	compatible = "mediatek,mt7623";
 	interrupt-parent = <&sysirq>;
 
-	cpu_opp_table: opp_table {
+	cpu_opp_table: opp-table {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -94,6 +94,9 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x1>;
+			clocks = <&infracfg CLK_INFRA_CPUSEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
 			operating-points-v2 = <&cpu_opp_table>;
 			clock-frequency = <1300000000>;
 		};
@@ -102,6 +105,9 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x2>;
+			clocks = <&infracfg CLK_INFRA_CPUSEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
 			operating-points-v2 = <&cpu_opp_table>;
 			clock-frequency = <1300000000>;
 		};
@@ -110,6 +116,9 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x3>;
+			clocks = <&infracfg CLK_INFRA_CPUSEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
 			operating-points-v2 = <&cpu_opp_table>;
 			clock-frequency = <1300000000>;
 		};
@@ -136,32 +145,32 @@
 	};
 
 	thermal-zones {
-			cpu_thermal: cpu_thermal {
+			cpu_thermal: cpu-thermal {
 				polling-delay-passive = <1000>;
 				polling-delay = <1000>;
 
 				thermal-sensors = <&thermal 0>;
 
 				trips {
-					cpu_passive: cpu_passive {
+					cpu_passive: cpu-passive {
 						temperature = <47000>;
 						hysteresis = <2000>;
 						type = "passive";
 					};
 
-					cpu_active: cpu_active {
+					cpu_active: cpu-active {
 						temperature = <67000>;
 						hysteresis = <2000>;
 						type = "active";
 					};
 
-					cpu_hot: cpu_hot {
+					cpu_hot: cpu-hot {
 						temperature = <87000>;
 						hysteresis = <2000>;
 						type = "hot";
 					};
 
-					cpu_crit {
+					cpu-crit {
 						temperature = <107000>;
 						hysteresis = <2000>;
 						type = "critical";
@@ -668,6 +677,111 @@
 		#reset-cells = <1>;
 	};
 
+	pcie: pcie@1a140000 {
+		compatible = "mediatek,mt7623-pcie";
+		device_type = "pci";
+		reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */
+		      <0 0x1a142000 0 0x1000>, /* Port0 registers */
+		      <0 0x1a143000 0 0x1000>, /* Port1 registers */
+		      <0 0x1a144000 0 0x1000>; /* Port2 registers */
+		reg-names = "subsys", "port0", "port1", "port2";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xf800 0 0 0>;
+		interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>,
+				<0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>,
+				<0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
+			 <&hifsys CLK_HIFSYS_PCIE0>,
+			 <&hifsys CLK_HIFSYS_PCIE1>,
+			 <&hifsys CLK_HIFSYS_PCIE2>;
+		clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2";
+		resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>,
+			 <&hifsys MT2701_HIFSYS_PCIE1_RST>,
+			 <&hifsys MT2701_HIFSYS_PCIE2_RST>;
+		reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2";
+		phys = <&pcie0_port PHY_TYPE_PCIE>,
+		       <&pcie1_port PHY_TYPE_PCIE>,
+		       <&u3port1 PHY_TYPE_PCIE>;
+		phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2";
+		power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>;
+		bus-range = <0x00 0xff>;
+		status = "disabled";
+		ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000
+			  0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>;
+
+		pcie@0,0 {
+			reg = <0x0000 0 0 0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>;
+			ranges;
+			num-lanes = <1>;
+			status = "disabled";
+		};
+
+		pcie@1,0 {
+			reg = <0x0800 0 0 0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>;
+			ranges;
+			num-lanes = <1>;
+			status = "disabled";
+		};
+
+		pcie@2,0 {
+			reg = <0x1000 0 0 0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
+			ranges;
+			num-lanes = <1>;
+			status = "disabled";
+		};
+	};
+
+	pcie0_phy: pcie-phy@1a149000 {
+		compatible = "mediatek,generic-tphy-v1";
+		reg = <0 0x1a149000 0 0x0700>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		pcie0_port: pcie-phy@1a149900 {
+			reg = <0 0x1a149900 0 0x0700>;
+			clocks = <&clk26m>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+	};
+
+	pcie1_phy: pcie-phy@1a14a000 {
+		compatible = "mediatek,generic-tphy-v1";
+		reg = <0 0x1a14a000 0 0x0700>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		pcie1_port: pcie-phy@1a14a900 {
+			reg = <0 0x1a14a900 0 0x0700>;
+			clocks = <&clk26m>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+	};
+
 	usb1: usb@1a1c0000 {
 		compatible = "mediatek,mt7623-xhci",
 			     "mediatek,mt8173-xhci";
diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
index 7bf5aa2..bbf56f8 100644
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -39,7 +39,34 @@
 		};
 	};
 
-	gpio_keys {
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_5v: regulator-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	gpio-keys {
 		compatible = "gpio-keys";
 		pinctrl-names = "default";
 		pinctrl-0 = <&key_pins_a>;
@@ -120,7 +147,6 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0>;
-			pinctrl-names = "default";
 			reset-gpios = <&pio 33 0>;
 			core-supply = <&mt6323_vpa_reg>;
 			io-supply = <&mt6323_vemc3v3_reg>;
@@ -191,8 +217,8 @@
 	bus-width = <8>;
 	max-frequency = <50000000>;
 	cap-mmc-highspeed;
-	vmmc-supply = <&mt6323_vemc3v3_reg>;
-	vqmmc-supply = <&mt6323_vio18_reg>;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_1p8v>;
 	non-removable;
 };
 
@@ -205,20 +231,42 @@
 	max-frequency = <50000000>;
 	cap-sd-highspeed;
 	cd-gpios = <&pio 261 GPIO_ACTIVE_LOW>;
-	vmmc-supply = <&mt6323_vmch_reg>;
-	vqmmc-supply = <&mt6323_vio18_reg>;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+};
+
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_default>;
+	status = "okay";
+
+	pcie@0,0 {
+		status = "okay";
+	};
+
+	pcie@1,0 {
+		status = "okay";
+	};
+};
+
+&pcie0_phy {
+	status = "okay";
+};
+
+&pcie1_phy {
+	status = "okay";
 };
 
 &pio {
 	cir_pins_a:cir@0 {
-		pins_cir {
+		pins-cir {
 			pinmux = <MT7623_PIN_46_IR_FUNC_IR>;
 			bias-disable;
 		};
 	};
 
 	i2c0_pins_a: i2c@0 {
-		pins_i2c0 {
+		pins-i2c0 {
 			pinmux = <MT7623_PIN_75_SDA0_FUNC_SDA0>,
 				 <MT7623_PIN_76_SCL0_FUNC_SCL0>;
 			bias-disable;
@@ -226,7 +274,7 @@
 	};
 
 	i2c1_pins_a: i2c@1 {
-		pin_i2c1 {
+		pin-i2c1 {
 			pinmux = <MT7623_PIN_57_SDA1_FUNC_SDA1>,
 				 <MT7623_PIN_58_SCL1_FUNC_SCL1>;
 			bias-disable;
@@ -234,7 +282,7 @@
 	};
 
 	i2s0_pins_a: i2s@0 {
-		pin_i2s0 {
+		pin-i2s0 {
 			pinmux = <MT7623_PIN_49_I2S0_DATA_FUNC_I2S0_DATA>,
 				 <MT7623_PIN_72_I2S0_DATA_IN_FUNC_I2S0_DATA_IN>,
 				 <MT7623_PIN_73_I2S0_LRCK_FUNC_I2S0_LRCK>,
@@ -246,7 +294,7 @@
 	};
 
 	i2s1_pins_a: i2s@1 {
-		pin_i2s1 {
+		pin-i2s1 {
 			pinmux = <MT7623_PIN_33_I2S1_DATA_FUNC_I2S1_DATA>,
 				 <MT7623_PIN_34_I2S1_DATA_IN_FUNC_I2S1_DATA_IN>,
 				 <MT7623_PIN_35_I2S1_BCK_FUNC_I2S1_BCK>,
@@ -258,7 +306,7 @@
 	};
 
 	key_pins_a: keys@0 {
-		pins_keys {
+		pins-keys {
 			pinmux = <MT7623_PIN_256_GPIO256_FUNC_GPIO256>,
 				 <MT7623_PIN_257_GPIO257_FUNC_GPIO257> ;
 			input-enable;
@@ -266,7 +314,7 @@
 	};
 
 	led_pins_a: leds@0 {
-		pins_leds {
+		pins-leds {
 			pinmux = <MT7623_PIN_239_EXT_SDIO0_FUNC_GPIO239>,
 				 <MT7623_PIN_240_EXT_XCS_FUNC_GPIO240>,
 				 <MT7623_PIN_241_EXT_SCK_FUNC_GPIO241>;
@@ -274,7 +322,7 @@
 	};
 
 	mmc0_pins_default: mmc0default {
-		pins_cmd_dat {
+		pins-cmd-dat {
 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>,
 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>,
 				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>,
@@ -288,19 +336,19 @@
 			bias-pull-up;
 		};
 
-		pins_clk {
+		pins-clk {
 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>;
 			bias-pull-down;
 		};
 
-		pins_rst {
+		pins-rst {
 			pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>;
 			bias-pull-up;
 		};
 	};
 
 	mmc0_pins_uhs: mmc0 {
-		pins_cmd_dat {
+		pins-cmd-dat {
 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>,
 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>,
 				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>,
@@ -315,20 +363,20 @@
 			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
 		};
 
-		pins_clk {
+		pins-clk {
 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>;
 			drive-strength = <MTK_DRIVE_2mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
 		};
 
-		pins_rst {
+		pins-rst {
 			pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>;
 			bias-pull-up;
 		};
 	};
 
 	mmc1_pins_default: mmc1default {
-		pins_cmd_dat {
+		pins-cmd-dat {
 			pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>,
 				 <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>,
 				 <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>,
@@ -339,26 +387,26 @@
 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
 		};
 
-		pins_clk {
+		pins-clk {
 			pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>;
 			bias-pull-down;
 			drive-strength = <MTK_DRIVE_4mA>;
 		};
 
-		pins_wp {
+		pins-wp {
 			pinmux = <MT7623_PIN_29_EINT7_FUNC_MSDC1_WP>;
 			input-enable;
 			bias-pull-up;
 		};
 
-		pins_insert {
+		pins-insert {
 			pinmux = <MT7623_PIN_261_MSDC1_INS_FUNC_GPIO261>;
 			bias-pull-up;
 		};
 	};
 
 	mmc1_pins_uhs: mmc1 {
-		pins_cmd_dat {
+		pins-cmd-dat {
 			pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>,
 				 <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>,
 				 <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>,
@@ -369,15 +417,23 @@
 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
 		};
 
-		pins_clk {
+		pins-clk {
 			pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>;
 			drive-strength = <MTK_DRIVE_4mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
 		};
 	};
 
+	pcie_default: pcie_pin_default {
+		pins_cmd_dat {
+			pinmux = <MT7623_PIN_208_AUD_EXT_CK1_FUNC_PCIE0_PERST_N>,
+				 <MT7623_PIN_209_AUD_EXT_CK2_FUNC_PCIE1_PERST_N>;
+			bias-disable;
+		};
+	};
+
 	pwm_pins_a: pwm@0 {
-		pins_pwm {
+		pins-pwm {
 			pinmux = <MT7623_PIN_203_PWM0_FUNC_PWM0>,
 				 <MT7623_PIN_204_PWM1_FUNC_PWM1>,
 				 <MT7623_PIN_205_PWM2_FUNC_PWM2>,
@@ -387,7 +443,7 @@
 	};
 
 	spi0_pins_a: spi@0 {
-		pins_spi {
+		pins-spi {
 			pinmux = <MT7623_PIN_53_SPI0_CSN_FUNC_SPI0_CS>,
 				<MT7623_PIN_54_SPI0_CK_FUNC_SPI0_CK>,
 				<MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MI>,
@@ -397,18 +453,25 @@
 	};
 
 	uart0_pins_a: uart@0 {
-		pins_dat {
+		pins-dat {
 			pinmux = <MT7623_PIN_79_URXD0_FUNC_URXD0>,
 				 <MT7623_PIN_80_UTXD0_FUNC_UTXD0>;
 		};
 	};
 
 	uart1_pins_a: uart@1 {
-		pins_dat {
+		pins-dat {
 			pinmux = <MT7623_PIN_81_URXD1_FUNC_URXD1>,
 				 <MT7623_PIN_82_UTXD1_FUNC_UTXD1>;
 		};
 	};
+
+	uart2_pins_a: uart@2 {
+		pins-dat {
+			pinmux = <MT7623_PIN_14_GPIO14_FUNC_URXD2>,
+				 <MT7623_PIN_15_GPIO15_FUNC_UTXD2>;
+		};
+	};
 };
 
 &pwm {
@@ -454,26 +517,30 @@
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
-	status = "disabled";
+	status = "okay";
 };
 
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart1_pins_a>;
-	status = "disabled";
+	status = "okay";
 };
 
 &uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins_a>;
 	status = "okay";
 };
 
 &usb1 {
-	vusb33-supply = <&mt6323_vusb_reg>;
+	vusb33-supply = <&reg_3p3v>;
+	vbus-supply = <&reg_5v>;
 	status = "okay";
 };
 
 &usb2 {
-	vusb33-supply = <&mt6323_vusb_reg>;
+	vusb33-supply = <&reg_3p3v>;
+	vbus-supply = <&reg_5v>;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/mt7623n-rfb-nand.dts b/arch/arm/boot/dts/mt7623n-rfb-nand.dts
index e66de86..f729c71 100644
--- a/arch/arm/boot/dts/mt7623n-rfb-nand.dts
+++ b/arch/arm/boot/dts/mt7623n-rfb-nand.dts
@@ -81,13 +81,13 @@
 
 &pio {
 	nand_pins_default: nanddefault {
-		pins_ale {
+		pins-ale {
 			pinmux = <MT7623_PIN_116_MSDC0_CMD_FUNC_NALE>;
 			drive-strength = <MTK_DRIVE_8mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
 		};
 
-		pins_dat {
+		pins-dat {
 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_NLD7>,
 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_NLD6>,
 				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_NLD4>,
@@ -102,7 +102,7 @@
 			bias-pull-up;
 		};
 
-		pins_we {
+		pins-we {
 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_NWEB>;
 			drive-strength = <MTK_DRIVE_8mA>;
 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
diff --git a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
new file mode 100644
index 0000000..d2d0761
--- /dev/null
+++ b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Nuvoton Technology tomer.maimon@nuvoton.com
+// Copyright 2018 Google, Inc.
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	/* external reference clock */
+	clk_refclk: clk_refclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+		clock-output-names = "refclk";
+	};
+
+	/* external reference clock for cpu. float in normal operation */
+	clk_sysbypck: clk_sysbypck {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <800000000>;
+		clock-output-names = "sysbypck";
+	};
+
+	/* external reference clock for MC. float in normal operation */
+	clk_mcbypck: clk_mcbypck {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <800000000>;
+		clock-output-names = "mcbypck";
+	};
+
+	 /* external clock signal rg1refck, supplied by the phy */
+	clk_rg1refck: clk_rg1refck {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+		clock-output-names = "clk_rg1refck";
+	};
+
+	 /* external clock signal rg2refck, supplied by the phy */
+	clk_rg2refck: clk_rg2refck {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+		clock-output-names = "clk_rg2refck";
+	};
+
+	clk_xin: clk_xin {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+		clock-output-names = "clk_xin";
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		ranges = <0x0 0xf0000000 0x00900000>;
+
+		gcr: gcr@800000 {
+			compatible = "nuvoton,npcm750-gcr", "syscon",
+				"simple-mfd";
+			reg = <0x800000 0x1000>;
+		};
+
+		scu: scu@3fe000 {
+			compatible = "arm,cortex-a9-scu";
+			reg = <0x3fe000 0x1000>;
+		};
+
+		l2: cache-controller@3fc000 {
+			compatible = "arm,pl310-cache";
+			reg = <0x3fc000 0x1000>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			cache-unified;
+			cache-level = <2>;
+			clocks = <&clk 10>;
+			arm,shared-override;
+		};
+
+		gic: interrupt-controller@3ff000 {
+			compatible = "arm,cortex-a9-gic";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x3ff000 0x1000>,
+				<0x3fe100 0x100>;
+		};
+	};
+
+	ahb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		ranges;
+
+		clk: clock-controller@f0801000 {
+			compatible = "nuvoton,npcm750-clk", "syscon";
+			#clock-cells = <1>;
+			clock-controller;
+			reg = <0xf0801000 0x1000>;
+			clock-names = "refclk", "sysbypck", "mcbypck";
+			clocks = <&clk_refclk>, <&clk_sysbypck>, <&clk_mcbypck>;
+		};
+
+		apb {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			interrupt-parent = <&gic>;
+			ranges = <0x0 0xf0000000 0x00300000>;
+
+			timer0: timer@8000 {
+				compatible = "nuvoton,npcm750-timer";
+				interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x8000 0x50>;
+				clocks = <&clk 5>;
+			};
+
+			watchdog0: watchdog@801C {
+				compatible = "nuvoton,npcm750-wdt";
+				interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x801C 0x4>;
+				status = "disabled";
+				clocks = <&clk 5>;
+			};
+
+			watchdog1: watchdog@901C {
+				compatible = "nuvoton,npcm750-wdt";
+				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x901C 0x4>;
+				status = "disabled";
+				clocks = <&clk 5>;
+			};
+
+			watchdog2: watchdog@a01C {
+				compatible = "nuvoton,npcm750-wdt";
+				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0xa01C 0x4>;
+				status = "disabled";
+				clocks = <&clk 5>;
+			};
+
+			serial0: serial@1000 {
+				compatible = "nuvoton,npcm750-uart";
+				reg = <0x1000 0x1000>;
+				clocks = <&clk 6>;
+				interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial1: serial@2000 {
+				compatible = "nuvoton,npcm750-uart";
+				reg = <0x2000 0x1000>;
+				clocks = <&clk 6>;
+				interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial2: serial@3000 {
+				compatible = "nuvoton,npcm750-uart";
+				reg = <0x3000 0x1000>;
+				clocks = <&clk 6>;
+				interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial3: serial@4000 {
+				compatible = "nuvoton,npcm750-uart";
+				reg = <0x4000 0x1000>;
+				clocks = <&clk 6>;
+				interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
new file mode 100644
index 0000000..15f744f
--- /dev/null
+++ b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Nuvoton Technology tomer.maimon@nuvoton.com
+// Copyright 2018 Google, Inc.
+
+/dts-v1/;
+#include "nuvoton-npcm750.dtsi"
+
+/ {
+	model = "Nuvoton npcm750 Development Board (Device Tree)";
+	compatible = "nuvoton,npcm750";
+
+	chosen {
+		stdout-path = &serial3;
+	};
+
+	memory {
+		reg = <0 0x40000000>;
+	};
+};
+
+&watchdog1 {
+	status = "okay";
+};
+
+&serial0 {
+	status = "okay";
+};
+
+&serial1 {
+	status = "okay";
+};
+
+&serial2 {
+	status = "okay";
+};
+
+&serial3 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/nuvoton-npcm750.dtsi b/arch/arm/boot/dts/nuvoton-npcm750.dtsi
new file mode 100644
index 0000000..6ac3405
--- /dev/null
+++ b/arch/arm/boot/dts/nuvoton-npcm750.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Nuvoton Technology tomer.maimon@nuvoton.com
+// Copyright 2018 Google, Inc.
+
+#include "nuvoton-common-npcm7xx.dtsi"
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "nuvoton,npcm750-smp";
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			clocks = <&clk 0>;
+			clock-names = "clk_cpu";
+			reg = <0>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			clocks = <&clk 0>;
+			clock-names = "clk_cpu";
+			reg = <1>;
+			next-level-cache = <&l2>;
+		};
+	};
+	soc {
+		timer@3fe600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x3fe600 0x20>;
+			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&clk 5>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts
index e44d93f..ded5fcf 100644
--- a/arch/arm/boot/dts/omap3-n9.dts
+++ b/arch/arm/boot/dts/omap3-n9.dts
@@ -39,6 +39,13 @@
 	};
 };
 
+&i2c3 {
+	ak8975@0f {
+		compatible = "asahi-kasei,ak8975";
+		reg = <0x0f>;
+	};
+};
+
 &isp {
 	vdd-csiphy1-supply = <&vaux2>;
 	vdd-csiphy2-supply = <&vaux2>;
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index a005802..4043ecb 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -557,6 +557,7 @@
 			dma-names = "tx", "rx";
 			clocks = <&mcbsp4_fck>;
 			clock-names = "fck";
+			#sound-dai-cells = <0>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts
index b21084d..bdf73cb 100644
--- a/arch/arm/boot/dts/omap4-droid4-xt894.dts
+++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts
@@ -70,8 +70,30 @@
 		regulator-always-on;
 	};
 
-	/* HS USB Host PHY on PORT 1 */
-	hsusb1_phy: hsusb1_phy {
+	/* FS USB Host PHY on port 1 for mdm6600 */
+	fsusb1_phy: usb-phy@1 {
+		compatible = "motorola,mapphone-mdm6600";
+		pinctrl-0 = <&usb_mdm6600_pins>;
+		pinctrl-names = "default";
+		enable-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>;     /* gpio_95 */
+		power-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>;	/* gpio_54 */
+		reset-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>;	/* gpio_49 */
+		/* mode: gpio_148 gpio_149 */
+		motorola,mode-gpios = <&gpio5 20 GPIO_ACTIVE_HIGH>,
+				      <&gpio5 21 GPIO_ACTIVE_HIGH>;
+		/* cmd: gpio_103 gpio_104 gpio_142 */
+		motorola,cmd-gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>,
+				     <&gpio4 8 GPIO_ACTIVE_HIGH>,
+				     <&gpio5 14 GPIO_ACTIVE_HIGH>;
+		/* status: gpio_52 gpio_53 gpio_55 */
+		motorola,status-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>,
+					<&gpio2 21 GPIO_ACTIVE_HIGH>,
+					<&gpio2 23 GPIO_ACTIVE_HIGH>;
+		#phy-cells = <0>;
+	};
+
+	/* HS USB host TLL nop-phy on port 2 for w3glte */
+	hsusb2_phy: usb-phy@2 {
 		compatible = "usb-nop-xceiv";
 		#phy-cells = <0>;
 	};
@@ -117,6 +139,26 @@
 
 		};
 	};
+
+	soundcard {
+		compatible = "audio-graph-card";
+		label = "Droid 4 Audio";
+
+		simple-graph-card,widgets =
+			"Speaker", "Earpiece",
+			"Speaker", "Loudspeaker",
+			"Headphone", "Headphone Jack",
+			"Microphone", "Internal Mic";
+
+		simple-graph-card,routing =
+			"Earpiece", "EP",
+			"Loudspeaker", "SPKR",
+			"Headphone Jack", "HSL",
+			"Headphone Jack", "HSR",
+			"MICR", "Internal Mic";
+
+		dais = <&mcbsp2_port>, <&mcbsp3_port>;
+	};
 };
 
 &dss {
@@ -124,13 +166,6 @@
 };
 
 &gpio6 {
-	touchscreen_reset {
-		gpio-hog;
-		gpios = <13 0>;
-		output-high;
-		line-name = "touchscreen-reset";
-	};
-
 	pwm8: dmtimer-pwm-8 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&vibrator_direction_pin>;
@@ -362,22 +397,18 @@
 	};
 };
 
-/*
- * REVISIT: Add gpio173 reset pin handling to the driver, see gpio-hog above.
- * If the GPIO reset is used, we probably need to have /lib/firmware/maxtouch.fw
- * available. See "mxt-app" and "droid4-touchscreen-firmware" tools for more
- * information.
- */
 &i2c2 {
-	tsp@4a {
+	touchscreen@4a {
 		compatible = "atmel,maxtouch";
 		reg = <0x4a>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&touchscreen_pins>;
 
+		reset-gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>; /* gpio173 */
+
 		/* gpio_183 with sys_nirq2 pad as wakeup */
-		interrupts-extended = <&gpio6 23 IRQ_TYPE_EDGE_FALLING
-				       &omap4_pmx_core 0x160>;
+		interrupts-extended = <&gpio6 23 IRQ_TYPE_EDGE_FALLING>,
+				      <&omap4_pmx_core 0x160>;
 		interrupt-names = "irq", "wakeup";
 		wakeup-source;
 	};
@@ -435,6 +466,7 @@
 
 	touchscreen_pins: pinmux_touchscreen_pins {
 		pinctrl-single,pins = <
+		OMAP4_IOPAD(0x180, PIN_OUTPUT | MUX_MODE3)
 		OMAP4_IOPAD(0x1a0, PIN_INPUT_PULLUP | MUX_MODE3)
 		>;
 	};
@@ -445,6 +477,43 @@
 		>;
 	};
 
+	usb_mdm6600_pins: pinmux_usb_mdm6600_pins {
+		pinctrl-single,pins = <
+		/* enable 0x4a1000d8 usbb1_ulpitll_dat7.gpio_95 ag16 */
+		OMAP4_IOPAD(0x0d8, PIN_INPUT | MUX_MODE3)
+
+		/* power 0x4a10007c gpmc_nwp.gpio_54 c25 */
+		OMAP4_IOPAD(0x07c, PIN_OUTPUT | MUX_MODE3)
+
+		/* reset 0x4a100072 gpmc_a25.gpio_49 d20 */
+		OMAP4_IOPAD(0x072, PIN_OUTPUT | MUX_MODE3)
+
+		/* mode0/bpwake 0x4a10014e sdmmc5_dat1.gpio_148 af4 */
+		OMAP4_IOPAD(0x14e, PIN_OUTPUT | MUX_MODE3)
+
+		/* mode1/apwake 0x4a100150 sdmmc5_dat2.gpio_149 ag3 */
+		OMAP4_IOPAD(0x150, PIN_OFF_OUTPUT_LOW | PIN_INPUT | MUX_MODE3)
+
+		/* status0 0x4a10007e gpmc_clk.gpio_55 b22 */
+		OMAP4_IOPAD(0x07e, PIN_INPUT | MUX_MODE3)
+
+		/* status1 0x4a10007a gpmc_ncs3.gpio_53 c22 */
+		OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3)
+
+		/* status2 0x4a100078 gpmc_ncs2.gpio_52 d21 */
+		OMAP4_IOPAD(0x078, PIN_INPUT | MUX_MODE3)
+
+		/* cmd0 0x4a100094 gpmc_ncs6.gpio_103 c24 */
+		OMAP4_IOPAD(0x094, PIN_OUTPUT | MUX_MODE3)
+
+		/* cmd1 0x4a100096 gpmc_ncs7.gpio_104 d24 */
+		OMAP4_IOPAD(0x096, PIN_OUTPUT | MUX_MODE3)
+
+		/* cmd2 0x4a100142 uart3_rts_sd.gpio_142 f28 */
+		OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE3)
+		>;
+	};
+
 	usb_ulpi_pins: pinmux_usb_ulpi_pins {
 		pinctrl-single,pins = <
 		OMAP4_IOPAD(0x196, MUX_MODE7)
@@ -484,6 +553,28 @@
 		>;
 	};
 
+	/*
+	 * Note that the v3.0.8 stock userspace dynamically remuxes uart1
+	 * rts pin probably for PM purposes to PIN_INPUT_PULLUP | MUX_MODE7
+	 * when not used. If needed, we can add rts pin remux later based
+	 * on power measurements.
+	 */
+	uart1_pins: pinmux_uart1_pins {
+		pinctrl-single,pins = <
+		/* 0x4a10013c mcspi1_cs2.uart1_cts ag23 */
+		OMAP4_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE1)
+
+		/* 0x4a10013e mcspi1_cs3.uart1_rts ah23 */
+		OMAP4_IOPAD(0x13e, MUX_MODE1)
+
+		/* 0x4a100140 uart3_cts_rctx.uart1_tx f27 */
+		OMAP4_IOPAD(0x140, PIN_OUTPUT | MUX_MODE1)
+
+		/* 0x4a1001ca dpm_emu14.uart1_rx aa3 */
+		OMAP4_IOPAD(0x1ca, PIN_INPUT_PULLUP | MUX_MODE2)
+		>;
+	};
+
 	/* uart3_tx_irtx and uart3_rx_irrx */
 	uart3_pins: pinmux_uart3_pins {
 		pinctrl-single,pins = <
@@ -512,6 +603,24 @@
 		OMAP4_IOPAD(0x112, PIN_OUTPUT_PULLUP | MUX_MODE5)	/* uart4_rts */
 		>;
 	};
+
+	mcbsp2_pins: pinmux_mcbsp2_pins {
+		pinctrl-single,pins = <
+		OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0)	/* abe_mcbsp2_clkx */
+		OMAP4_IOPAD(0x0f8, PIN_INPUT | MUX_MODE0)	/* abe_mcbsp2_dr */
+		OMAP4_IOPAD(0x0fa, PIN_OUTPUT | MUX_MODE0)	/* abe_mcbsp2_dx */
+		OMAP4_IOPAD(0x0fc, PIN_INPUT | MUX_MODE0)	/* abe_mcbsp2_fsx */
+		>;
+	};
+
+	mcbsp3_pins: pinmux_mcbsp3_pins {
+		pinctrl-single,pins = <
+		OMAP4_IOPAD(0x106, PIN_INPUT | MUX_MODE1)	/* abe_mcbsp3_dr */
+		OMAP4_IOPAD(0x108, PIN_OUTPUT | MUX_MODE1)	/* abe_mcbsp3_dx */
+		OMAP4_IOPAD(0x10a, PIN_INPUT | MUX_MODE1)	/* abe_mcbsp3_clkx */
+		OMAP4_IOPAD(0x10c, PIN_INPUT | MUX_MODE1)	/* abe_mcbsp3_fsx */
+		>;
+	};
 };
 
 &omap4_pmx_wkup {
@@ -535,6 +644,17 @@
 	};
 };
 
+/*
+ * As uart1 is wired to mdm6600 with rts and cts, we can use the cts pin for
+ * uart1 wakeirq.
+ */
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	interrupts-extended = <&wakeupgen GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH
+			       &omap4_pmx_core 0xfc>;
+};
+
 &uart3 {
 	interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
 			       &omap4_pmx_core 0x17c>;
@@ -551,8 +671,13 @@
 	};
 };
 
+&usbhsohci {
+	phys = <&fsusb1_phy>;
+	phy-names = "usb";
+};
+
 &usbhsehci {
-	phys = <&hsusb1_phy>;
+	phys = <&hsusb2_phy>;
 };
 
 &usbhshost {
@@ -597,3 +722,43 @@
 				  "0", "0", "1";
 	};
 };
+
+&mcbsp2 {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcbsp2_pins>;
+	status = "okay";
+
+	mcbsp2_port: port {
+		cpu_dai2: endpoint {
+			dai-format = "i2s";
+			remote-endpoint = <&cpcap_audio_codec0>;
+			frame-master = <&cpcap_audio_codec0>;
+			bitclock-master = <&cpcap_audio_codec0>;
+		};
+	};
+};
+
+&mcbsp3 {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcbsp3_pins>;
+	status = "okay";
+
+	mcbsp3_port: port {
+		cpu_dai3: endpoint {
+			dai-format = "dsp_a";
+			frame-master = <&cpcap_audio_codec1>;
+			bitclock-master = <&cpcap_audio_codec1>;
+			remote-endpoint = <&cpcap_audio_codec1>;
+		};
+	};
+};
+
+&cpcap_audio_codec0 {
+	remote-endpoint = <&cpu_dai2>;
+};
+
+&cpcap_audio_codec1 {
+	remote-endpoint = <&cpu_dai3>;
+};
diff --git a/arch/arm/boot/dts/omap443x.dtsi b/arch/arm/boot/dts/omap443x.dtsi
index 03c8ad9..cbcdcb4 100644
--- a/arch/arm/boot/dts/omap443x.dtsi
+++ b/arch/arm/boot/dts/omap443x.dtsi
@@ -24,8 +24,6 @@
 			clock-latency = <300000>; /* From legacy driver */
 
 			/* cooling options */
-			cooling-min-level = <0>;
-			cooling-max-level = <3>;
 			#cooling-cells = <2>; /* min followed by max */
 		};
 	};
diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi
index c43f2a2..ad97493 100644
--- a/arch/arm/boot/dts/omap4460.dtsi
+++ b/arch/arm/boot/dts/omap4460.dtsi
@@ -22,8 +22,6 @@
 			clock-latency = <300000>; /* From legacy driver */
 
 			/* cooling options */
-			cooling-min-level = <0>;
-			cooling-max-level = <2>;
 			#cooling-cells = <2>; /* min followed by max */
 		};
 	};
diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi
index 1b20838..3b22445 100644
--- a/arch/arm/boot/dts/omap5-board-common.dtsi
+++ b/arch/arm/boot/dts/omap5-board-common.dtsi
@@ -659,8 +659,8 @@
 		v2v1-supply = <&smps9_reg>;
 		enable-active-high;
 
-		clocks = <&clk32kgaudio>;
-		clock-names = "clk32k";
+		clocks = <&clk32kgaudio>, <&fref_xtal_ck>;
+		clock-names = "clk32k", "mclk";
 	};
 };
 
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 35d4298..732b61a 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -55,8 +55,6 @@
 			clock-latency = <300000>; /* From omap-cpufreq driver */
 
 			/* cooling options */
-			cooling-min-level = <0>;
-			cooling-max-level = <2>;
 			#cooling-cells = <2>; /* min followed by max */
 		};
 		cpu@1 {
@@ -289,6 +287,28 @@
 				pinctrl-single,register-width = <16>;
 				pinctrl-single,function-mask = <0x7fff>;
 			};
+
+			omap5_scm_wkup_pad_conf: omap5_scm_wkup_pad_conf@cda0 {
+				compatible = "ti,omap5-scm-wkup-pad-conf",
+					     "simple-bus";
+				reg = <0xcda0 0x60>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0xcda0 0x60>;
+
+				scm_wkup_pad_conf: scm_conf@0 {
+					compatible = "syscon", "simple-bus";
+					reg = <0x0 0x60>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					ranges = <0 0x0 0x60>;
+
+					scm_wkup_pad_conf_clocks: clocks@0 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+					};
+				};
+			};
 		};
 
 		ocmcram: ocmcram@40300000 {
diff --git a/arch/arm/boot/dts/omap54xx-clocks.dtsi b/arch/arm/boot/dts/omap54xx-clocks.dtsi
index 9619a74..ecc5573 100644
--- a/arch/arm/boot/dts/omap54xx-clocks.dtsi
+++ b/arch/arm/boot/dts/omap54xx-clocks.dtsi
@@ -1179,3 +1179,13 @@
 		};
 	};
 };
+
+&scm_wkup_pad_conf_clocks {
+	fref_xtal_ck: fref_xtal_ck {
+		#clock-cells = <0>;
+		compatible = "ti,gate-clock";
+		clocks = <&sys_clkin>;
+		ti,bit-shift = <28>;
+		reg = <0x14>;
+	};
+};
diff --git a/arch/arm/boot/dts/orion5x-lacie-d2-network.dts b/arch/arm/boot/dts/orion5x-lacie-d2-network.dts
index c701e8d..8c2449d 100644
--- a/arch/arm/boot/dts/orion5x-lacie-d2-network.dts
+++ b/arch/arm/boot/dts/orion5x-lacie-d2-network.dts
@@ -24,7 +24,7 @@
 
 	chosen {
 		bootargs = "console=ttyS0,115200n8 earlyprintk";
-		linux,stdout-path = &uart0;
+		stdout-path = &uart0;
 	};
 
 	soc {
diff --git a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
index 89ff404..b545d0f 100644
--- a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
+++ b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
@@ -30,7 +30,7 @@
 
 	chosen {
 		bootargs = "console=ttyS0,115200n8 earlyprintk";
-		linux,stdout-path = &uart0;
+		stdout-path = &uart0;
 	};
 
 	soc {
diff --git a/arch/arm/boot/dts/orion5x-linkstation.dtsi b/arch/arm/boot/dts/orion5x-linkstation.dtsi
index e9991c8..ebd93df 100644
--- a/arch/arm/boot/dts/orion5x-linkstation.dtsi
+++ b/arch/arm/boot/dts/orion5x-linkstation.dtsi
@@ -48,7 +48,7 @@
 / {
 	chosen {
 		bootargs = "console=ttyS0,115200n8 earlyprintk";
-		linux,stdout-path = &uart0;
+		stdout-path = &uart0;
 	};
 
 	soc {
diff --git a/arch/arm/boot/dts/orion5x-lswsgl.dts b/arch/arm/boot/dts/orion5x-lswsgl.dts
index ea966ec..0d97ded 100644
--- a/arch/arm/boot/dts/orion5x-lswsgl.dts
+++ b/arch/arm/boot/dts/orion5x-lswsgl.dts
@@ -60,7 +60,7 @@
 
 	chosen {
 		bootargs = "console=ttyS0,115200 earlyprintk";
-		linux,stdout-path = &uart0;
+		stdout-path = &uart0;
 	};
 
 	soc {
diff --git a/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts b/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts
index ff34849..0324cb5 100644
--- a/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts
+++ b/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts
@@ -24,7 +24,7 @@
 
 	chosen {
 		bootargs = "console=ttyS0,115200n8 earlyprintk";
-		linux,stdout-path = &uart0;
+		stdout-path = &uart0;
 	};
 
 	soc {
diff --git a/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts b/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts
index 6fb0525..d1817af 100644
--- a/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts
+++ b/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts
@@ -21,7 +21,7 @@
 
 	chosen {
 		bootargs = "console=ttyS0,115200n8 earlyprintk";
-		linux,stdout-path = &uart0;
+		stdout-path = &uart0;
 	};
 
 	soc {
diff --git a/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts b/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts
index 1297414..0c97293 100644
--- a/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts
+++ b/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts
@@ -23,7 +23,7 @@
 	};
 
 	chosen {
-		linux,stdout-path = &uart0;
+		stdout-path = &uart0;
 	};
 
 	clocks {
diff --git a/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts b/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts
index 9e317a4..86f2671 100644
--- a/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts
+++ b/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts
@@ -23,7 +23,7 @@
 	};
 
 	chosen {
-		linux,stdout-path = &uart0;
+		stdout-path = &uart0;
 	};
 
 	clocks {
diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi
index 55c75b6..982d1a6 100644
--- a/arch/arm/boot/dts/pxa3xx.dtsi
+++ b/arch/arm/boot/dts/pxa3xx.dtsi
@@ -117,15 +117,15 @@
 			status = "disabled";
 		};
 
-		nand0: nand@43100000 {
-			compatible = "marvell,pxa3xx-nand";
+		nand_controller: nand-controller@43100000 {
+			compatible = "marvell,pxa3xx-nand-controller";
 			reg = <0x43100000 90>;
 			interrupts = <45>;
 			clocks = <&clks CLK_NAND>;
 			dmas = <&pdma 97 3>;
 			dma-names = "data";
 			#address-cells = <1>;
-			#size-cells = <1>;	
+			#size-cells = <0>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
index b818ebc..209eb21 100644
--- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
@@ -133,7 +133,7 @@
 				clock-frequency = <200000>;
 
 				eeprom@50 {
-					compatible = "24c02";
+					compatible = "atmel,24c02";
 					reg = <0x50>;
 					pagesize = <32>;
 				};
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 3ca96e3..5341a39 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -316,6 +316,23 @@
 		};
 	};
 
+
+	/*
+	 * These channels from the ADC are simply hardware monitors.
+	 * That is why the ADC is referred to as "HKADC" - HouseKeeping
+	 * ADC.
+	 */
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&xoadc 0x00 0x01>, /* Battery */
+			    <&xoadc 0x00 0x02>, /* DC in (charger) */
+			    <&xoadc 0x00 0x04>, /* VPH the main system voltage */
+			    <&xoadc 0x00 0x0b>, /* Die temperature */
+			    <&xoadc 0x00 0x0c>, /* Reference voltage 1.25V */
+			    <&xoadc 0x00 0x0d>, /* Reference voltage 0.625V */
+			    <&xoadc 0x00 0x0e>; /* Charger temperature */
+	};
+
 	soc: soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -770,6 +787,52 @@
 					debounce = <15625>;
 					pull-up;
 				};
+
+				xoadc: xoadc@197 {
+					compatible = "qcom,pm8921-adc";
+					reg = <197>;
+					interrupts-extended = <&pmicintc 78 IRQ_TYPE_EDGE_RISING>;
+					#address-cells = <2>;
+					#size-cells = <0>;
+					#io-channel-cells = <2>;
+
+					vcoin: adc-channel@00 {
+						reg = <0x00 0x00>;
+					};
+					vbat: adc-channel@01 {
+						reg = <0x00 0x01>;
+					};
+					dcin: adc-channel@02 {
+						reg = <0x00 0x02>;
+					};
+					vph_pwr: adc-channel@04 {
+						reg = <0x00 0x04>;
+					};
+					batt_therm: adc-channel@08 {
+						reg = <0x00 0x08>;
+					};
+					batt_id: adc-channel@09 {
+						reg = <0x00 0x09>;
+					};
+					usb_vbus: adc-channel@0a {
+						reg = <0x00 0x0a>;
+					};
+					die_temp: adc-channel@0b {
+						reg = <0x00 0x0b>;
+					};
+					ref_625mv: adc-channel@0c {
+						reg = <0x00 0x0c>;
+					};
+					ref_1250mv: adc-channel@0d {
+						reg = <0x00 0x0d>;
+					};
+					chg_temp: adc-channel@0e {
+						reg = <0x00 0x0e>;
+					};
+					ref_muxoff: adc-channel@0f {
+						reg = <0x00 0x0f>;
+					};
+				};
 			};
 		};
 
diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
new file mode 100644
index 0000000..eaa1001
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro.dtsi"
+#include "qcom-pm8841.dtsi"
+#include "qcom-pm8941.dtsi"
+
+/ {
+	model = "Samsung Galaxy S5";
+	compatible = "samsung,klte", "qcom,msm8974";
+
+	aliases {
+		serial0 = &blsp1_uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&soc {
+	serial@f991e000 {
+		status = "ok";
+	};
+
+};
diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
index e87f2c9..701b396 100644
--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
@@ -491,7 +491,7 @@
 		pinctrl-0 = <&i2c8_pins>;
 
 		synaptics@2c {
-			compatible = "syna,rmi-i2c";
+			compatible = "syna,rmi4-i2c";
 			reg = <0x2c>;
 
 			interrupt-parent = <&msmgpio>;
@@ -506,6 +506,8 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&ts_int_pin>;
 
+			syna,startup-delay-ms = <10>;
+
 			rmi-f01@1 {
 				reg = <0x1>;
 				syna,nosleep = <1>;
diff --git a/arch/arm/boot/dts/r8a7743-iwg20m.dtsi b/arch/arm/boot/dts/r8a7743-iwg20m.dtsi
index 75a8ca5..1d3e950 100644
--- a/arch/arm/boot/dts/r8a7743-iwg20m.dtsi
+++ b/arch/arm/boot/dts/r8a7743-iwg20m.dtsi
@@ -34,6 +34,10 @@
 	};
 };
 
+&cmt0 {
+	status = "okay";
+};
+
 &extal_clk {
 	clock-frequency = <20000000>;
 };
diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi
index 0b74c6c..1d9073b 100644
--- a/arch/arm/boot/dts/r8a7743.dtsi
+++ b/arch/arm/boot/dts/r8a7743.dtsi
@@ -141,29 +141,6 @@
 		#size-cells = <2>;
 		ranges;
 
-		apmu@e6152000 {
-			compatible = "renesas,r8a7743-apmu", "renesas,apmu";
-			reg = <0 0xe6152000 0 0x188>;
-			cpus = <&cpu0 &cpu1>;
-		};
-
-		gic: interrupt-controller@f1001000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			#address-cells = <0>;
-			interrupt-controller;
-			reg = <0 0xf1001000 0 0x1000>,
-			      <0 0xf1002000 0 0x2000>,
-			      <0 0xf1004000 0 0x2000>,
-			      <0 0xf1006000 0 0x2000>;
-			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
-						 IRQ_TYPE_LEVEL_HIGH)>;
-			clocks = <&cpg CPG_MOD 408>;
-			clock-names = "clk";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 408>;
-		};
-
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a7743",
 				     "renesas,rcar-gen2-gpio";
@@ -284,6 +261,48 @@
 			resets = <&cpg 904>;
 		};
 
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a7743";
+			reg = <0 0xe6060000 0 0x250>;
+		};
+
+		tpu: pwm@e60f0000 {
+			compatible = "renesas,tpu-r8a7743", "renesas,tpu";
+			reg = <0 0xe60f0000 0 0x148>;
+			clocks = <&cpg CPG_MOD 304>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 304>;
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7743-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&usb_extal_clk>;
+			clock-names = "extal", "usb_extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		apmu@e6152000 {
+			compatible = "renesas,r8a7743-apmu", "renesas,apmu";
+			reg = <0 0xe6152000 0 0x188>;
+			cpus = <&cpu0 &cpu1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7743-rst";
+			reg = <0 0xe6160000 0 0x100>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7743-sysc";
+			reg = <0 0xe6180000 0 0x200>;
+			#power-domain-cells = <1>;
+		};
+
 		irqc: interrupt-controller@e61c0000 {
 			compatible = "renesas,irqc-r8a7743", "renesas,irqc";
 			#interrupt-cells = <2>;
@@ -316,227 +335,89 @@
 			#thermal-sensor-cells = <0>;
 		};
 
-		cmt0: timer@ffca0000 {
-			compatible = "renesas,r8a7743-cmt0",
-				     "renesas,rcar-gen2-cmt0";
-			reg = <0 0xffca0000 0 0x1004>;
-			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 124>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 124>;
+		ipmmu_sy0: mmu@e6280000 {
+			compatible = "renesas,ipmmu-r8a7743",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6280000 0 0x1000>;
+			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
 			status = "disabled";
 		};
 
-		cmt1: timer@e6130000 {
-			compatible = "renesas,r8a7743-cmt1",
-				     "renesas,rcar-gen2-cmt1";
-			reg = <0 0xe6130000 0 0x1004>;
-			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 329>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 329>;
+		ipmmu_sy1: mmu@e6290000 {
+			compatible = "renesas,ipmmu-r8a7743",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6290000 0 0x1000>;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
 			status = "disabled";
 		};
 
-		cpg: clock-controller@e6150000 {
-			compatible = "renesas,r8a7743-cpg-mssr";
-			reg = <0 0xe6150000 0 0x1000>;
-			clocks = <&extal_clk>, <&usb_extal_clk>;
-			clock-names = "extal", "usb_extal";
-			#clock-cells = <2>;
-			#power-domain-cells = <0>;
-			#reset-cells = <1>;
+		ipmmu_ds: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a7743",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6740000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
 		};
 
-		prr: chipid@ff000044 {
-			compatible = "renesas,prr";
-			reg = <0 0xff000044 0 4>;
+		ipmmu_mp: mmu@ec680000 {
+			compatible = "renesas,ipmmu-r8a7743",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xec680000 0 0x1000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
 		};
 
-		rst: reset-controller@e6160000 {
-			compatible = "renesas,r8a7743-rst";
-			reg = <0 0xe6160000 0 0x100>;
+		ipmmu_mx: mmu@fe951000 {
+			compatible = "renesas,ipmmu-r8a7743",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xfe951000 0 0x1000>;
+			interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
 		};
 
-		sysc: system-controller@e6180000 {
-			compatible = "renesas,r8a7743-sysc";
-			reg = <0 0xe6180000 0 0x200>;
-			#power-domain-cells = <1>;
+		ipmmu_gp: mmu@e62a0000 {
+			compatible = "renesas,ipmmu-r8a7743",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe62a0000 0 0x1000>;
+			interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
 		};
 
-		pfc: pin-controller@e6060000 {
-			compatible = "renesas,pfc-r8a7743";
-			reg = <0 0xe6060000 0 0x250>;
+		icram0:	sram@e63a0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63a0000 0 0x12000>;
 		};
 
-		dmac0: dma-controller@e6700000 {
-			compatible = "renesas,dmac-r8a7743",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe6700000 0 0x20000>;
-			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14";
-			clocks = <&cpg CPG_MOD 219>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 219>;
-			#dma-cells = <1>;
-			dma-channels = <15>;
+		icram1:	sram@e63c0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63c0000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0xe63c0000 0x1000>;
+
+			smp-sram@0 {
+				compatible = "renesas,smp-sram";
+				reg = <0 0x10>;
+			};
 		};
 
-		dmac1: dma-controller@e6720000 {
-			compatible = "renesas,dmac-r8a7743",
-				     "renesas,rcar-dmac";
-			reg = <0 0xe6720000 0 0x20000>;
-			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14";
-			clocks = <&cpg CPG_MOD 218>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 218>;
-			#dma-cells = <1>;
-			dma-channels = <15>;
+		icram2:	sram@e6300000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe6300000 0 0x40000>;
 		};
 
-		audma0: dma-controller@ec700000 {
-			compatible = "renesas,dmac-r8a7743",
-				     "renesas,rcar-dmac";
-			reg = <0 0xec700000 0 0x10000>;
-			interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					  "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7",
-					  "ch8", "ch9", "ch10", "ch11",
-					  "ch12";
-			clocks = <&cpg CPG_MOD 502>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 502>;
-			#dma-cells = <1>;
-			dma-channels = <13>;
-		};
-
-		audma1: dma-controller@ec720000 {
-			compatible = "renesas,dmac-r8a7743",
-				     "renesas,rcar-dmac";
-			reg = <0 0xec720000 0 0x10000>;
-			interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					  "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7",
-					  "ch8", "ch9", "ch10", "ch11",
-					  "ch12";
-			clocks = <&cpg CPG_MOD 501>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 501>;
-			#dma-cells = <1>;
-			dma-channels = <13>;
-		};
-
-		usb_dmac0: dma-controller@e65a0000 {
-			compatible = "renesas,r8a7743-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe65a0000 0 0x100>;
-			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 330>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 330>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
-		};
-
-		usb_dmac1: dma-controller@e65b0000 {
-			compatible = "renesas,r8a7743-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe65b0000 0 0x100>;
-			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 331>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 331>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
-		};
-
-		/* The memory map in the User's Manual maps the cores to bus
-		 *  numbers
+		/* The memory map in the User's Manual maps the cores to
+		 * bus numbers
 		 */
 		i2c0: i2c@e6508000 {
 			#address-cells = <1>;
@@ -675,6 +556,168 @@
 			status = "disabled";
 		};
 
+		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a7743",
+				     "renesas,rcar-gen2-usbhs";
+			reg = <0 0xe6590000 0 0x100>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>;
+			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+			       <&usb_dmac1 0>, <&usb_dmac1 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			renesas,buswait = <4>;
+			phys = <&usb0 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		usbphy: usb-phy@e6590100 {
+			compatible = "renesas,usb-phy-r8a7743",
+				     "renesas,rcar-gen2-usb-phy";
+			reg = <0 0xe6590100 0 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cpg CPG_MOD 704>;
+			clock-names = "usbhs";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			status = "disabled";
+
+			usb0: usb-channel@0 {
+				reg = <0>;
+				#phy-cells = <1>;
+			};
+			usb2: usb-channel@2 {
+				reg = <2>;
+				#phy-cells = <1>;
+			};
+		};
+
+		usb_dmac0: dma-controller@e65a0000 {
+			compatible = "renesas,r8a7743-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65a0000 0 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 330>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 330>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb_dmac1: dma-controller@e65b0000 {
+			compatible = "renesas,r8a7743-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65b0000 0 0x100>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 331>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 331>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a7743",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x20000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 219>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		dmac1: dma-controller@e6720000 {
+			compatible = "renesas,dmac-r8a7743",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6720000 0 0x20000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a7743",
+				     "renesas,etheravb-rcar-gen2";
+			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		qspi: spi@e6b10000 {
+			compatible = "renesas,qspi-r8a7743", "renesas,qspi";
+			reg = <0 0xe6b10000 0 0x2c>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 917>;
+			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
+			       <&dmac1 0x17>, <&dmac1 0x18>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			num-cs = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			resets = <&cpg 917>;
+			status = "disabled";
+		};
+
 		scifa0: serial@e6c40000 {
 			compatible = "renesas,scifa-r8a7743",
 				     "renesas,rcar-gen2-scifa", "renesas,scifa";
@@ -954,88 +997,6 @@
 			status = "disabled";
 		};
 
-		icram2:	sram@e6300000 {
-			compatible = "mmio-sram";
-			reg = <0 0xe6300000 0 0x40000>;
-		};
-
-		icram0:	sram@e63a0000 {
-			compatible = "mmio-sram";
-			reg = <0 0xe63a0000 0 0x12000>;
-		};
-
-		icram1:	sram@e63c0000 {
-			compatible = "mmio-sram";
-			reg = <0 0xe63c0000 0 0x1000>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges = <0 0 0xe63c0000 0x1000>;
-
-			smp-sram@0 {
-				compatible = "renesas,smp-sram";
-				reg = <0 0x10>;
-			};
-		};
-
-		ether: ethernet@ee700000 {
-			compatible = "renesas,ether-r8a7743",
-				     "renesas,rcar-gen2-ether";
-			reg = <0 0xee700000 0 0x400>;
-			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 813>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 813>;
-			phy-mode = "rmii";
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		avb: ethernet@e6800000 {
-			compatible = "renesas,etheravb-r8a7743",
-				     "renesas,etheravb-rcar-gen2";
-			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
-			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 812>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 812>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		mmcif0: mmc@ee200000 {
-			compatible = "renesas,mmcif-r8a7743",
-				     "renesas,sh-mmcif";
-			reg = <0 0xee200000 0 0x80>;
-			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 315>;
-			dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
-			       <&dmac1 0xd1>, <&dmac1 0xd2>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 315>;
-			reg-io-width = <4>;
-			max-frequency = <97500000>;
-			status = "disabled";
-		};
-
-		qspi: spi@e6b10000 {
-			compatible = "renesas,qspi-r8a7743", "renesas,qspi";
-			reg = <0 0xe6b10000 0 0x2c>;
-			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 917>;
-			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
-			       <&dmac1 0x17>, <&dmac1 0x18>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			num-cs = <1>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			resets = <&cpg 917>;
-			status = "disabled";
-		};
-
 		msiof0: spi@e6e20000 {
 			compatible = "renesas,msiof-r8a7743",
 				     "renesas,rcar-gen2-msiof";
@@ -1084,26 +1045,6 @@
 			status = "disabled";
 		};
 
-		/*
-		 * pci1 and xhci share the same phy, therefore only one of them
-		 * can be active at any one time. If both of them are enabled,
-		 * a race condition will determine who'll control the phy.
-		 * A firmware file is needed by the xhci driver in order for
-		 * USB 3.0 to work properly.
-		 */
-		xhci: usb@ee000000 {
-			compatible = "renesas,xhci-r8a7743",
-				     "renesas,rcar-gen2-xhci";
-			reg = <0 0xee000000 0 0xc00>;
-			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 328>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 328>;
-			phys = <&usb2 1>;
-			phy-names = "usb";
-			status = "disabled";
-		};
-
 		pwm0: pwm@e6e30000 {
 			compatible = "renesas,pwm-r8a7743", "renesas,pwm-rcar";
 			reg = <0 0xe6e30000 0 0x8>;
@@ -1174,100 +1115,34 @@
 			status = "disabled";
 		};
 
-		tpu: pwm@e60f0000 {
-			compatible = "renesas,tpu-r8a7743", "renesas,tpu";
-			reg = <0 0xe60f0000 0 0x148>;
-			clocks = <&cpg CPG_MOD 304>;
+		can0: can@e6e80000 {
+			compatible = "renesas,can-r8a7743",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e80000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>,
+				 <&cpg CPG_CORE R8A7743_CLK_RCAN>,
+				 <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
 			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 304>;
-			#pwm-cells = <3>;
+			resets = <&cpg 916>;
 			status = "disabled";
 		};
 
-		sdhi0: sd@ee100000 {
-			compatible = "renesas,sdhi-r8a7743",
-				     "renesas,rcar-gen2-sdhi";
-			reg = <0 0xee100000 0 0x328>;
-			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 314>;
-			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
-			       <&dmac1 0xcd>, <&dmac1 0xce>;
-			dma-names = "tx", "rx", "tx", "rx";
-			max-frequency = <195000000>;
+		can1: can@e6e88000 {
+			compatible = "renesas,can-r8a7743",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e88000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>,
+				 <&cpg CPG_CORE R8A7743_CLK_RCAN>,
+				 <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
 			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 314>;
+			resets = <&cpg 915>;
 			status = "disabled";
 		};
 
-		sdhi1: sd@ee140000 {
-			compatible = "renesas,sdhi-r8a7743",
-				     "renesas,rcar-gen2-sdhi";
-			reg = <0 0xee140000 0 0x100>;
-			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 312>;
-			dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
-			       <&dmac1 0xc1>, <&dmac1 0xc2>;
-			dma-names = "tx", "rx", "tx", "rx";
-			max-frequency = <97500000>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 312>;
-			status = "disabled";
-		};
-
-		sdhi2: sd@ee160000 {
-			compatible = "renesas,sdhi-r8a7743",
-				     "renesas,rcar-gen2-sdhi";
-			reg = <0 0xee160000 0 0x100>;
-			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 311>;
-			dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
-			       <&dmac1 0xd3>, <&dmac1 0xd4>;
-			dma-names = "tx", "rx", "tx", "rx";
-			max-frequency = <97500000>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 311>;
-			status = "disabled";
-		};
-
-		hsusb: usb@e6590000 {
-			compatible = "renesas,usbhs-r8a7743",
-				     "renesas,rcar-gen2-usbhs";
-			reg = <0 0xe6590000 0 0x100>;
-			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 704>;
-			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
-			       <&usb_dmac1 0>, <&usb_dmac1 1>;
-			dma-names = "ch0", "ch1", "ch2", "ch3";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 704>;
-			renesas,buswait = <4>;
-			phys = <&usb0 1>;
-			phy-names = "usb";
-			status = "disabled";
-		};
-
-		usbphy: usb-phy@e6590100 {
-			compatible = "renesas,usb-phy-r8a7743",
-				     "renesas,rcar-gen2-usb-phy";
-			reg = <0 0xe6590100 0 0x100>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			clocks = <&cpg CPG_MOD 704>;
-			clock-names = "usbhs";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 704>;
-			status = "disabled";
-
-			usb0: usb-channel@0 {
-				reg = <0>;
-				#phy-cells = <1>;
-			};
-			usb2: usb-channel@2 {
-				reg = <2>;
-				#phy-cells = <1>;
-			};
-		};
-
 		vin0: video@e6ef0000 {
 			compatible = "renesas,vin-r8a7743",
 				     "renesas,rcar-gen2-vin";
@@ -1301,162 +1176,6 @@
 			status = "disabled";
 		};
 
-		du: display@feb00000 {
-			compatible = "renesas,du-r8a7743";
-			reg = <0 0xfeb00000 0 0x40000>,
-			      <0 0xfeb90000 0 0x1c>;
-			reg-names = "du", "lvds.0";
-			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 724>,
-				 <&cpg CPG_MOD 723>,
-				 <&cpg CPG_MOD 726>;
-			clock-names = "du.0", "du.1", "lvds.0";
-			status = "disabled";
-
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				port@0 {
-					reg = <0>;
-					du_out_rgb: endpoint {
-					};
-				};
-				port@1 {
-					reg = <1>;
-					du_out_lvds0: endpoint {
-					};
-				};
-			};
-		};
-
-		can0: can@e6e80000 {
-			compatible = "renesas,can-r8a7743",
-				     "renesas,rcar-gen2-can";
-			reg = <0 0xe6e80000 0 0x1000>;
-			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 916>,
-				 <&cpg CPG_CORE R8A7743_CLK_RCAN>,
-				 <&can_clk>;
-			clock-names = "clkp1", "clkp2", "can_clk";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 916>;
-			status = "disabled";
-		};
-
-		can1: can@e6e88000 {
-			compatible = "renesas,can-r8a7743",
-				     "renesas,rcar-gen2-can";
-			reg = <0 0xe6e88000 0 0x1000>;
-			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 915>,
-				 <&cpg CPG_CORE R8A7743_CLK_RCAN>,
-				 <&can_clk>;
-			clock-names = "clkp1", "clkp2", "can_clk";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 915>;
-			status = "disabled";
-		};
-
-		pci0: pci@ee090000 {
-			compatible = "renesas,pci-r8a7743",
-				     "renesas,pci-rcar-gen2";
-			device_type = "pci";
-			reg = <0 0xee090000 0 0xc00>,
-			      <0 0xee080000 0 0x1100>;
-			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
-			status = "disabled";
-
-			bus-range = <0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
-			#interrupt-cells = <1>;
-			ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-			interrupt-map-mask = <0xff00 0 0 0x7>;
-			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-					 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-					 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-
-			usb@1,0 {
-				reg = <0x800 0 0 0 0>;
-				phys = <&usb0 0>;
-				phy-names = "usb";
-			};
-
-			usb@2,0 {
-				reg = <0x1000 0 0 0 0>;
-				phys = <&usb0 0>;
-				phy-names = "usb";
-			};
-		};
-
-		pci1: pci@ee0d0000 {
-			compatible = "renesas,pci-r8a7743",
-				     "renesas,pci-rcar-gen2";
-			device_type = "pci";
-			reg = <0 0xee0d0000 0 0xc00>,
-			      <0 0xee0c0000 0 0x1100>;
-			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
-			status = "disabled";
-
-			bus-range = <1 1>;
-			#address-cells = <3>;
-			#size-cells = <2>;
-			#interrupt-cells = <1>;
-			ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-			interrupt-map-mask = <0xff00 0 0 0x7>;
-			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-					 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-					 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-
-			usb@1,0 {
-				reg = <0x10800 0 0 0 0>;
-				phys = <&usb2 0>;
-				phy-names = "usb";
-			};
-
-			usb@2,0 {
-				reg = <0x11000 0 0 0 0>;
-				phys = <&usb2 0>;
-				phy-names = "usb";
-			};
-		};
-
-		pciec: pcie@fe000000 {
-			compatible = "renesas,pcie-r8a7743",
-				     "renesas,pcie-rcar-gen2";
-			reg = <0 0xfe000000 0 0x80000>;
-			#address-cells = <3>;
-			#size-cells = <2>;
-			bus-range = <0x00 0xff>;
-			device_type = "pci";
-			ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
-				  0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
-				  0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
-				  0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
-			/* Map all possible DDR as inbound ranges */
-			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
-				      0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
-			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
-			#interrupt-cells = <1>;
-			interrupt-map-mask = <0 0 0 0>;
-			interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
-			clock-names = "pcie", "pcie_bus";
-			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
-			resets = <&cpg 319>;
-			status = "disabled";
-		};
-
 		rcar_sound: sound@ec500000 {
 			/*
 			 * #sound-dai-cells is required
@@ -1641,6 +1360,369 @@
 				};
 			};
 		};
+
+		audma0: dma-controller@ec700000 {
+			compatible = "renesas,dmac-r8a7743",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec700000 0 0x10000>;
+			interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 502>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 502>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		audma1: dma-controller@ec720000 {
+			compatible = "renesas,dmac-r8a7743",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec720000 0 0x10000>;
+			interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 501>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 501>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		/*
+		 * pci1 and xhci share the same phy, therefore only one of them
+		 * can be active at any one time. If both of them are enabled,
+		 * a race condition will determine who'll control the phy.
+		 * A firmware file is needed by the xhci driver in order for
+		 * USB 3.0 to work properly.
+		 */
+		xhci: usb@ee000000 {
+			compatible = "renesas,xhci-r8a7743",
+				     "renesas,rcar-gen2-xhci";
+			reg = <0 0xee000000 0 0xc00>;
+			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			phys = <&usb2 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		pci0: pci@ee090000 {
+			compatible = "renesas,pci-r8a7743",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee090000 0 0xc00>,
+			      <0 0xee080000 0 0x1100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x800 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x1000 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
+			};
+		};
+
+		pci1: pci@ee0d0000 {
+			compatible = "renesas,pci-r8a7743",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee0d0000 0 0xc00>,
+			      <0 0xee0c0000 0 0x1100>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <1 1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x10800 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x11000 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+		};
+
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7743",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee100000 0 0x328>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
+			       <&dmac1 0xcd>, <&dmac1 0xce>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <195000000>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		sdhi1: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a7743",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee140000 0 0x100>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
+			       <&dmac1 0xc1>, <&dmac1 0xc2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi2: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a7743",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee160000 0 0x100>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
+			       <&dmac1 0xd3>, <&dmac1 0xd4>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		mmcif0: mmc@ee200000 {
+			compatible = "renesas,mmcif-r8a7743",
+				     "renesas,sh-mmcif";
+			reg = <0 0xee200000 0 0x80>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 315>;
+			dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
+			       <&dmac1 0xd1>, <&dmac1 0xd2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 315>;
+			reg-io-width = <4>;
+			max-frequency = <97500000>;
+			status = "disabled";
+		};
+
+		ether: ethernet@ee700000 {
+			compatible = "renesas,ether-r8a7743",
+				     "renesas,rcar-gen2-ether";
+			reg = <0 0xee700000 0 0x400>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 813>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 813>;
+			phy-mode = "rmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>, <0 0xf1002000 0 0x2000>,
+			      <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
+		pciec: pcie@fe000000 {
+			compatible = "renesas,pcie-r8a7743",
+				     "renesas,pcie-rcar-gen2";
+			reg = <0 0xfe000000 0 0x80000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+				  0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+				  0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+				  0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
+				      0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 319>;
+			status = "disabled";
+		};
+
+		vsp@fe928000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe928000 0 0x8000>;
+			interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 131>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 131>;
+		};
+
+		vsp@fe930000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe930000 0 0x8000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 128>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 128>;
+		};
+
+		vsp@fe938000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe938000 0 0x8000>;
+			interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 127>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 127>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a7743";
+			reg = <0 0xfeb00000 0 0x40000>,
+			      <0 0xfeb90000 0 0x1c>;
+			reg-names = "du", "lvds.0";
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>,
+				 <&cpg CPG_MOD 723>,
+				 <&cpg CPG_MOD 726>;
+			clock-names = "du.0", "du.1", "lvds.0";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+				port@1 {
+					reg = <1>;
+					du_out_lvds0: endpoint {
+					};
+				};
+			};
+		};
+
+		prr: chipid@ff000044 {
+			compatible = "renesas,prr";
+			reg = <0 0xff000044 0 4>;
+		};
+
+		cmt0: timer@ffca0000 {
+			compatible = "renesas,r8a7743-cmt0",
+				     "renesas,rcar-gen2-cmt0";
+			reg = <0 0xffca0000 0 0x1004>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 124>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 124>;
+			status = "disabled";
+		};
+
+		cmt1: timer@e6130000 {
+			compatible = "renesas,r8a7743-cmt1",
+				     "renesas,rcar-gen2-cmt1";
+			reg = <0 0xe6130000 0 0x1004>;
+			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 329>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			resets = <&cpg 329>;
+			status = "disabled";
+		};
 	};
 
 	thermal-zones {
diff --git a/arch/arm/boot/dts/r8a7745-iwg22m.dtsi b/arch/arm/boot/dts/r8a7745-iwg22m.dtsi
index ed9a8cf..8d0a392b 100644
--- a/arch/arm/boot/dts/r8a7745-iwg22m.dtsi
+++ b/arch/arm/boot/dts/r8a7745-iwg22m.dtsi
@@ -29,6 +29,10 @@
 	};
 };
 
+&cmt0 {
+	status = "okay";
+};
+
 &extal_clk {
 	clock-frequency = <20000000>;
 };
diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi
index ae918e9..dd49a8b 100644
--- a/arch/arm/boot/dts/r8a7745.dtsi
+++ b/arch/arm/boot/dts/r8a7745.dtsi
@@ -121,29 +121,6 @@
 		#size-cells = <2>;
 		ranges;
 
-		apmu@e6151000 {
-			compatible = "renesas,r8a7745-apmu", "renesas,apmu";
-			reg = <0 0xe6151000 0 0x188>;
-			cpus = <&cpu0 &cpu1>;
-		};
-
-		gic: interrupt-controller@f1001000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			#address-cells = <0>;
-			interrupt-controller;
-			reg = <0 0xf1001000 0 0x1000>,
-			      <0 0xf1002000 0 0x2000>,
-			      <0 0xf1004000 0 0x2000>,
-			      <0 0xf1006000 0 0x2000>;
-			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
-						 IRQ_TYPE_LEVEL_HIGH)>;
-			clocks = <&cpg CPG_MOD 408>;
-			clock-names = "clk";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 408>;
-		};
-
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a7745",
 				     "renesas,rcar-gen2-gpio";
@@ -249,6 +226,48 @@
 			resets = <&cpg 905>;
 		};
 
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a7745";
+			reg = <0 0xe6060000 0 0x11c>;
+		};
+
+		tpu: pwm@e60f0000 {
+			compatible = "renesas,tpu-r8a7745", "renesas,tpu";
+			reg = <0 0xe60f0000 0 0x148>;
+			clocks = <&cpg CPG_MOD 304>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 304>;
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7745-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&usb_extal_clk>;
+			clock-names = "extal", "usb_extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		apmu@e6151000 {
+			compatible = "renesas,r8a7745-apmu", "renesas,apmu";
+			reg = <0 0xe6151000 0 0x188>;
+			cpus = <&cpu0 &cpu1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7745-rst";
+			reg = <0 0xe6160000 0 0x100>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7745-sysc";
+			reg = <0 0xe6180000 0 0x200>;
+			#power-domain-cells = <1>;
+		};
+
 		irqc: interrupt-controller@e61c0000 {
 			compatible = "renesas,irqc-r8a7745", "renesas,irqc";
 			#interrupt-cells = <2>;
@@ -269,67 +288,269 @@
 			resets = <&cpg 407>;
 		};
 
-		cmt0: timer@ffca0000 {
-			compatible = "renesas,r8a7745-cmt0",
-				     "renesas,rcar-gen2-cmt0";
-			reg = <0 0xffca0000 0 0x1004>;
-			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 124>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 124>;
+		ipmmu_sy0: mmu@e6280000 {
+			compatible = "renesas,ipmmu-r8a7745",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6280000 0 0x1000>;
+			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
 			status = "disabled";
 		};
 
-		cmt1: timer@e6130000 {
-			compatible = "renesas,r8a7745-cmt1",
-				     "renesas,rcar-gen2-cmt1";
-			reg = <0 0xe6130000 0 0x1004>;
-			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 329>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 329>;
+		ipmmu_sy1: mmu@e6290000 {
+			compatible = "renesas,ipmmu-r8a7745",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6290000 0 0x1000>;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
 			status = "disabled";
 		};
 
-		cpg: clock-controller@e6150000 {
-			compatible = "renesas,r8a7745-cpg-mssr";
-			reg = <0 0xe6150000 0 0x1000>;
-			clocks = <&extal_clk>, <&usb_extal_clk>;
-			clock-names = "extal", "usb_extal";
-			#clock-cells = <2>;
-			#power-domain-cells = <0>;
-			#reset-cells = <1>;
+		ipmmu_ds: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a7745",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6740000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
 		};
 
-		prr: chipid@ff000044 {
-			compatible = "renesas,prr";
-			reg = <0 0xff000044 0 4>;
+		ipmmu_mp: mmu@ec680000 {
+			compatible = "renesas,ipmmu-r8a7745",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xec680000 0 0x1000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
 		};
 
-		rst: reset-controller@e6160000 {
-			compatible = "renesas,r8a7745-rst";
-			reg = <0 0xe6160000 0 0x100>;
+		ipmmu_mx: mmu@fe951000 {
+			compatible = "renesas,ipmmu-r8a7745",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xfe951000 0 0x1000>;
+			interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
 		};
 
-		sysc: system-controller@e6180000 {
-			compatible = "renesas,r8a7745-sysc";
-			reg = <0 0xe6180000 0 0x200>;
-			#power-domain-cells = <1>;
+		ipmmu_gp: mmu@e62a0000 {
+			compatible = "renesas,ipmmu-r8a7745",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe62a0000 0 0x1000>;
+			interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
 		};
 
-		pfc: pin-controller@e6060000 {
-			compatible = "renesas,pfc-r8a7745";
-			reg = <0 0xe6060000 0 0x11c>;
+		icram0:	sram@e63a0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63a0000 0 0x12000>;
+		};
+
+		icram1:	sram@e63c0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63c0000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0xe63c0000 0x1000>;
+
+			smp-sram@0 {
+				compatible = "renesas,smp-sram";
+				reg = <0 0x10>;
+			};
+		};
+
+		icram2:	sram@e6300000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe6300000 0 0x40000>;
+		};
+		i2c0: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7745",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6518000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7745",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6518000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6530000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7745",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6530000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e6540000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7745",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6540000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e6520000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7745",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6520000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@e6528000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7745",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6528000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 925>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 925>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		iic0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7745",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6500000 0 0x425>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>;
+			dmas = <&dmac0 0x61>, <&dmac0 0x62>,
+			       <&dmac1 0x61>, <&dmac1 0x62>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			status = "disabled";
+		};
+
+		iic1: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7745",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6510000 0 0x425>;
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 323>;
+			dmas = <&dmac0 0x65>, <&dmac0 0x66>,
+			       <&dmac1 0x65>, <&dmac1 0x66>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 323>;
+			status = "disabled";
+		};
+
+		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a7745",
+				     "renesas,rcar-gen2-usbhs";
+			reg = <0 0xe6590000 0 0x100>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>;
+			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+			       <&usb_dmac1 0>, <&usb_dmac1 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			renesas,buswait = <4>;
+			phys = <&usb0 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		usbphy: usb-phy@e6590100 {
+			compatible = "renesas,usb-phy-r8a7745",
+				     "renesas,rcar-gen2-usb-phy";
+			reg = <0 0xe6590100 0 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cpg CPG_MOD 704>;
+			clock-names = "usbhs";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			status = "disabled";
+
+			usb0: usb-channel@0 {
+				reg = <0>;
+				#phy-cells = <1>;
+			};
+			usb2: usb-channel@2 {
+				reg = <2>;
+				#phy-cells = <1>;
+			};
+		};
+
+		usb_dmac0: dma-controller@e65a0000 {
+			compatible = "renesas,r8a7745-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65a0000 0 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 330>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 330>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb_dmac1: dma-controller@e65b0000 {
+			compatible = "renesas,r8a7745-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65b0000 0 0x100>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 331>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 331>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
 		};
 
 		dmac0: dma-controller@e6700000 {
@@ -353,10 +574,10 @@
 				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
 				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14";
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
 			clocks = <&cpg CPG_MOD 219>;
 			clock-names = "fck";
 			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
@@ -386,10 +607,10 @@
 				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
 				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "error",
-					"ch0", "ch1", "ch2", "ch3",
-					"ch4", "ch5", "ch6", "ch7",
-					"ch8", "ch9", "ch10", "ch11",
-					"ch12", "ch13", "ch14";
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
 			clocks = <&cpg CPG_MOD 218>;
 			clock-names = "fck";
 			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
@@ -398,63 +619,33 @@
 			dma-channels = <15>;
 		};
 
-		audma0: dma-controller@ec700000 {
-			compatible = "renesas,dmac-r8a7745",
-				     "renesas,rcar-dmac";
-			reg = <0 0xec700000 0 0x10000>;
-			interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "error",
-					  "ch0", "ch1", "ch2", "ch3",
-					  "ch4", "ch5", "ch6", "ch7",
-					  "ch8", "ch9", "ch10", "ch11",
-					  "ch12";
-			clocks = <&cpg CPG_MOD 502>;
-			clock-names = "fck";
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a7745",
+				     "renesas,etheravb-rcar-gen2";
+			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 812>;
 			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 502>;
-			#dma-cells = <1>;
-			dma-channels = <13>;
+			resets = <&cpg 812>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
 		};
 
-		usb_dmac0: dma-controller@e65a0000 {
-			compatible = "renesas,r8a7745-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe65a0000 0 0x100>;
-			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 330>;
+		qspi: spi@e6b10000 {
+			compatible = "renesas,qspi-r8a7745", "renesas,qspi";
+			reg = <0 0xe6b10000 0 0x2c>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 917>;
+			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
+			       <&dmac1 0x17>, <&dmac1 0x18>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 330>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
-		};
-
-		usb_dmac1: dma-controller@e65b0000 {
-			compatible = "renesas,r8a7745-usb-dmac",
-				     "renesas,usb-dmac";
-			reg = <0 0xe65b0000 0 0x100>;
-			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
-				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "ch0", "ch1";
-			clocks = <&cpg CPG_MOD 331>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 331>;
-			#dma-cells = <1>;
-			dma-channels = <2>;
+			num-cs = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			resets = <&cpg 917>;
+			status = "disabled";
 		};
 
 		scifa0: serial@e6c40000 {
@@ -736,255 +927,6 @@
 			status = "disabled";
 		};
 
-		icram2:	sram@e6300000 {
-			compatible = "mmio-sram";
-			reg = <0 0xe6300000 0 0x40000>;
-		};
-
-		icram0:	sram@e63a0000 {
-			compatible = "mmio-sram";
-			reg = <0 0xe63a0000 0 0x12000>;
-		};
-
-		icram1:	sram@e63c0000 {
-			compatible = "mmio-sram";
-			reg = <0 0xe63c0000 0 0x1000>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges = <0 0 0xe63c0000 0x1000>;
-
-			smp-sram@0 {
-				compatible = "renesas,smp-sram";
-				reg = <0 0x10>;
-			};
-		};
-
-		ether: ethernet@ee700000 {
-			compatible = "renesas,ether-r8a7745",
-				     "renesas,rcar-gen2-ether";
-			reg = <0 0xee700000 0 0x400>;
-			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 813>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 813>;
-			phy-mode = "rmii";
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		avb: ethernet@e6800000 {
-			compatible = "renesas,etheravb-r8a7745",
-				     "renesas,etheravb-rcar-gen2";
-			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
-			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 812>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 812>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		i2c0: i2c@e6508000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7745",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6508000 0 0x40>;
-			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 931>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 931>;
-			i2c-scl-internal-delay-ns = <6>;
-			status = "disabled";
-		};
-
-		i2c1: i2c@e6518000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7745",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6518000 0 0x40>;
-			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 930>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 930>;
-			i2c-scl-internal-delay-ns = <6>;
-			status = "disabled";
-		};
-
-		i2c2: i2c@e6530000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7745",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6530000 0 0x40>;
-			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 929>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 929>;
-			i2c-scl-internal-delay-ns = <6>;
-			status = "disabled";
-		};
-
-		i2c3: i2c@e6540000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7745",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6540000 0 0x40>;
-			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 928>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 928>;
-			i2c-scl-internal-delay-ns = <6>;
-			status = "disabled";
-		};
-
-		i2c4: i2c@e6520000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7745",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6520000 0 0x40>;
-			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 927>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 927>;
-			i2c-scl-internal-delay-ns = <6>;
-			status = "disabled";
-		};
-
-		i2c5: i2c@e6528000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,i2c-r8a7745",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6528000 0 0x40>;
-			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 925>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 925>;
-			i2c-scl-internal-delay-ns = <6>;
-			status = "disabled";
-		};
-
-		iic0: i2c@e6500000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,iic-r8a7745",
-				     "renesas,rcar-gen2-iic",
-				     "renesas,rmobile-iic";
-			reg = <0 0xe6500000 0 0x425>;
-			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 318>;
-			dmas = <&dmac0 0x61>, <&dmac0 0x62>,
-			       <&dmac1 0x61>, <&dmac1 0x62>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 318>;
-			status = "disabled";
-		};
-
-		iic1: i2c@e6510000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "renesas,iic-r8a7745",
-				     "renesas,rcar-gen2-iic",
-				     "renesas,rmobile-iic";
-			reg = <0 0xe6510000 0 0x425>;
-			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 323>;
-			dmas = <&dmac0 0x65>, <&dmac0 0x66>,
-			       <&dmac1 0x65>, <&dmac1 0x66>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 323>;
-			status = "disabled";
-		};
-
-		mmcif0: mmc@ee200000 {
-			compatible = "renesas,mmcif-r8a7745",
-				     "renesas,sh-mmcif";
-			reg = <0 0xee200000 0 0x80>;
-			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 315>;
-			dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
-			       <&dmac1 0xd1>, <&dmac1 0xd2>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 315>;
-			reg-io-width = <4>;
-			max-frequency = <97500000>;
-			status = "disabled";
-		};
-
-		qspi: spi@e6b10000 {
-			compatible = "renesas,qspi-r8a7745", "renesas,qspi";
-			reg = <0 0xe6b10000 0 0x2c>;
-			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 917>;
-			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
-			       <&dmac1 0x17>, <&dmac1 0x18>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			num-cs = <1>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			resets = <&cpg 917>;
-			status = "disabled";
-		};
-
-		vin0: video@e6ef0000 {
-			compatible = "renesas,vin-r8a7745",
-				     "renesas,rcar-gen2-vin";
-			reg = <0 0xe6ef0000 0 0x1000>;
-			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 811>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 811>;
-			status = "disabled";
-		};
-
-		vin1: video@e6ef1000 {
-			compatible = "renesas,vin-r8a7745",
-				     "renesas,rcar-gen2-vin";
-			reg = <0 0xe6ef1000 0 0x1000>;
-			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 810>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 810>;
-			status = "disabled";
-		};
-
-		du: display@feb00000 {
-			compatible = "renesas,du-r8a7745";
-			reg = <0 0xfeb00000 0 0x40000>;
-			reg-names = "du";
-			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>;
-			clock-names = "du.0", "du.1";
-			status = "disabled";
-
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				port@0 {
-					reg = <0>;
-					du_out_rgb0: endpoint {
-					};
-				};
-				port@1 {
-					reg = <1>;
-					du_out_rgb1: endpoint {
-					};
-				};
-			};
-		};
-
 		msiof0: spi@e6e20000 {
 			compatible = "renesas,msiof-r8a7745",
 				     "renesas,rcar-gen2-msiof";
@@ -1103,170 +1045,6 @@
 			status = "disabled";
 		};
 
-		tpu: pwm@e60f0000 {
-			compatible = "renesas,tpu-r8a7745", "renesas,tpu";
-			reg = <0 0xe60f0000 0 0x148>;
-			clocks = <&cpg CPG_MOD 304>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 304>;
-			#pwm-cells = <3>;
-			status = "disabled";
-		};
-
-		sdhi0: sd@ee100000 {
-			compatible = "renesas,sdhi-r8a7745",
-				     "renesas,rcar-gen2-sdhi";
-			reg = <0 0xee100000 0 0x328>;
-			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 314>;
-			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
-			       <&dmac1 0xcd>, <&dmac1 0xce>;
-			dma-names = "tx", "rx", "tx", "rx";
-			max-frequency = <195000000>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 314>;
-			status = "disabled";
-		};
-
-		sdhi1: sd@ee140000 {
-			compatible = "renesas,sdhi-r8a7745",
-				     "renesas,rcar-gen2-sdhi";
-			reg = <0 0xee140000 0 0x100>;
-			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 312>;
-			dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
-			       <&dmac1 0xc1>, <&dmac1 0xc2>;
-			dma-names = "tx", "rx", "tx", "rx";
-			max-frequency = <97500000>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 312>;
-			status = "disabled";
-		};
-
-		sdhi2: sd@ee160000 {
-			compatible = "renesas,sdhi-r8a7745",
-				     "renesas,rcar-gen2-sdhi";
-			reg = <0 0xee160000 0 0x100>;
-			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 311>;
-			dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
-			       <&dmac1 0xd3>, <&dmac1 0xd4>;
-			dma-names = "tx", "rx", "tx", "rx";
-			max-frequency = <97500000>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 311>;
-			status = "disabled";
-		};
-
-		pci0: pci@ee090000 {
-			compatible = "renesas,pci-r8a7745",
-				     "renesas,pci-rcar-gen2";
-			device_type = "pci";
-			reg = <0 0xee090000 0 0xc00>,
-			      <0 0xee080000 0 0x1100>;
-			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
-			status = "disabled";
-
-			bus-range = <0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
-			#interrupt-cells = <1>;
-			ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-			interrupt-map-mask = <0xff00 0 0 0x7>;
-			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-					 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-					 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-
-			usb@1,0 {
-				reg = <0x800 0 0 0 0>;
-				phys = <&usb0 0>;
-				phy-names = "usb";
-			};
-
-			usb@2,0 {
-				reg = <0x1000 0 0 0 0>;
-				phys = <&usb0 0>;
-				phy-names = "usb";
-			};
-		};
-
-		pci1: pci@ee0d0000 {
-			compatible = "renesas,pci-r8a7745",
-				     "renesas,pci-rcar-gen2";
-			device_type = "pci";
-			reg = <0 0xee0d0000 0 0xc00>,
-			      <0 0xee0c0000 0 0x1100>;
-			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 703>;
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 703>;
-			status = "disabled";
-
-			bus-range = <1 1>;
-			#address-cells = <3>;
-			#size-cells = <2>;
-			#interrupt-cells = <1>;
-			ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-			interrupt-map-mask = <0xff00 0 0 0x7>;
-			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-					 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-					 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-
-			usb@1,0 {
-				reg = <0x10800 0 0 0 0>;
-				phys = <&usb2 0>;
-				phy-names = "usb";
-			};
-
-			usb@2,0 {
-				reg = <0x11000 0 0 0 0>;
-				phys = <&usb2 0>;
-				phy-names = "usb";
-			};
-		};
-
-		hsusb: usb@e6590000 {
-			compatible = "renesas,usbhs-r8a7745",
-				     "renesas,rcar-gen2-usbhs";
-			reg = <0 0xe6590000 0 0x100>;
-			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 704>;
-			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
-			       <&usb_dmac1 0>, <&usb_dmac1 1>;
-			dma-names = "ch0", "ch1", "ch2", "ch3";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 704>;
-			renesas,buswait = <4>;
-			phys = <&usb0 1>;
-			phy-names = "usb";
-			status = "disabled";
-		};
-
-		usbphy: usb-phy@e6590100 {
-			compatible = "renesas,usb-phy-r8a7745",
-				     "renesas,rcar-gen2-usb-phy";
-			reg = <0 0xe6590100 0 0x100>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			clocks = <&cpg CPG_MOD 704>;
-			clock-names = "usbhs";
-			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
-			resets = <&cpg 704>;
-			status = "disabled";
-
-			usb0: usb-channel@0 {
-				reg = <0>;
-				#phy-cells = <1>;
-			};
-			usb2: usb-channel@2 {
-				reg = <2>;
-				#phy-cells = <1>;
-			};
-		};
-
 		can0: can@e6e80000 {
 			compatible = "renesas,can-r8a7745",
 				     "renesas,rcar-gen2-can";
@@ -1295,6 +1073,28 @@
 			status = "disabled";
 		};
 
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a7745",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 811>;
+			status = "disabled";
+		};
+
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a7745",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 810>;
+			status = "disabled";
+		};
+
 		rcar_sound: sound@ec500000 {
 			/*
 			 * #sound-dai-cells is required
@@ -1474,6 +1274,278 @@
 				};
 			};
 		};
+
+		audma0: dma-controller@ec700000 {
+			compatible = "renesas,dmac-r8a7745",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec700000 0 0x10000>;
+			interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 502>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 502>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		pci0: pci@ee090000 {
+			compatible = "renesas,pci-r8a7745",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee090000 0 0xc00>,
+			      <0 0xee080000 0 0x1100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x800 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x1000 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
+			};
+		};
+
+		pci1: pci@ee0d0000 {
+			compatible = "renesas,pci-r8a7745",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee0d0000 0 0xc00>,
+			      <0 0xee0c0000 0 0x1100>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <1 1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x10800 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x11000 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+		};
+
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7745",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee100000 0 0x328>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
+			       <&dmac1 0xcd>, <&dmac1 0xce>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <195000000>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		sdhi1: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a7745",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee140000 0 0x100>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
+			       <&dmac1 0xc1>, <&dmac1 0xc2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi2: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a7745",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee160000 0 0x100>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
+			       <&dmac1 0xd3>, <&dmac1 0xd4>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		mmcif0: mmc@ee200000 {
+			compatible = "renesas,mmcif-r8a7745",
+				     "renesas,sh-mmcif";
+			reg = <0 0xee200000 0 0x80>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 315>;
+			dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
+			       <&dmac1 0xd1>, <&dmac1 0xd2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 315>;
+			reg-io-width = <4>;
+			max-frequency = <97500000>;
+			status = "disabled";
+		};
+
+		ether: ethernet@ee700000 {
+			compatible = "renesas,ether-r8a7745",
+				     "renesas,rcar-gen2-ether";
+			reg = <0 0xee700000 0 0x400>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 813>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 813>;
+			phy-mode = "rmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>, <0 0xf1002000 0 0x2000>,
+			      <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
+		vsp@fe928000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe928000 0 0x8000>;
+			interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 131>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 131>;
+		};
+
+		vsp@fe930000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe930000 0 0x8000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 128>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 128>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a7745";
+			reg = <0 0xfeb00000 0 0x40000>;
+			reg-names = "du";
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>;
+			clock-names = "du.0", "du.1";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb0: endpoint {
+					};
+				};
+				port@1 {
+					reg = <1>;
+					du_out_rgb1: endpoint {
+					};
+				};
+			};
+		};
+
+		prr: chipid@ff000044 {
+			compatible = "renesas,prr";
+			reg = <0 0xff000044 0 4>;
+		};
+
+		cmt0: timer@ffca0000 {
+			compatible = "renesas,r8a7745-cmt0",
+				     "renesas,rcar-gen2-cmt0";
+			reg = <0 0xffca0000 0 0x1004>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 124>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 124>;
+			status = "disabled";
+		};
+
+		cmt1: timer@e6130000 {
+			compatible = "renesas,r8a7745-cmt1",
+				     "renesas,rcar-gen2-cmt1";
+			reg = <0 0xe6130000 0 0x1004>;
+			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 329>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			resets = <&cpg 329>;
+			status = "disabled";
+		};
 	};
 
 	timer {
diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts
index 9412a86..4b9006b 100644
--- a/arch/arm/boot/dts/r8a7779-marzen.dts
+++ b/arch/arm/boot/dts/r8a7779-marzen.dts
@@ -42,6 +42,19 @@
 		regulator-always-on;
 	};
 
+	vccq_sdhi0: regulator-vccq-sdhi0 {
+		compatible = "regulator-gpio";
+
+		regulator-name = "SDHI0 VccQ";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+		gpios-states = <1>;
+		states = <3300000 1
+			  1800000 0>;
+	};
+
 	ethernet@18000000 {
 		compatible = "smsc,lan9220", "smsc,lan9115";
 		reg = <0x18000000 0x100>;
@@ -243,6 +256,7 @@
 	pinctrl-names = "default";
 
 	vmmc-supply = <&fixedregulator3v3>;
+	vqmmc-supply = <&vccq_sdhi0>;
 	bus-width = <4>;
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index f2ea632..063fdb6 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -51,8 +51,11 @@
 		serial0 = &scif0;
 		serial1 = &scifa1;
 		i2c8 = &gpioi2c1;
+		i2c9 = &gpioi2c2;
 		i2c10 = &i2cexio0;
 		i2c11 = &i2cexio1;
+		i2c12 = &i2chdmi;
+		i2c13 = &i2cpwr;
 	};
 
 	chosen {
@@ -244,6 +247,12 @@
 		};
 	};
 
+	cec_clock: cec-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+	};
+
 	hdmi-out {
 		compatible = "hdmi-connector";
 		type = "a";
@@ -272,8 +281,18 @@
 		#size-cells = <0>;
 		compatible = "i2c-gpio";
 		status = "disabled";
-		sda-gpios = <&gpio1 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		scl-gpios = <&gpio1 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio1 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		i2c-gpio,delay-us = <5>;
+	};
+
+	gpioi2c2: i2c-9 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		scl-gpios = <&gpio5 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio5 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <5>;
 	};
 
@@ -308,6 +327,138 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 	};
+
+        /*
+         * IIC2 and I2C2 may be switched using pinmux.
+         * A fallback to GPIO is also provided.
+         */
+	i2chdmi: i2c-12 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&iic2>, <&i2c2>, <&gpioi2c2>;
+		i2c-bus-name = "i2c-hdmi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ak4643: codec@12 {
+			compatible = "asahi-kasei,ak4643";
+			#sound-dai-cells = <0>;
+			reg = <0x12>;
+		};
+
+		composite-in@20 {
+			compatible = "adi,adv7180";
+			reg = <0x20>;
+			remote = <&vin1>;
+
+			port {
+				adv7180: endpoint {
+					bus-width = <8>;
+					remote-endpoint = <&vin1ep0>;
+				};
+			};
+		};
+
+		hdmi@39 {
+			compatible = "adi,adv7511w";
+			reg = <0x39>;
+			interrupt-parent = <&gpio1>;
+			interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&cec_clock>;
+			clock-names = "cec";
+
+			adi,input-depth = <8>;
+			adi,input-colorspace = "rgb";
+			adi,input-clock = "1x";
+			adi,input-style = <1>;
+			adi,input-justification = "evenly";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7511_in: endpoint {
+						remote-endpoint = <&du_out_lvds0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					adv7511_out: endpoint {
+						remote-endpoint = <&hdmi_con_out>;
+					};
+				};
+			};
+		};
+
+		hdmi-in@4c {
+			compatible = "adi,adv7612";
+			reg = <0x4c>;
+			interrupt-parent = <&gpio1>;
+			interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+			default-input = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7612_in: endpoint {
+						remote-endpoint = <&hdmi_con_in>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					adv7612_out: endpoint {
+						remote-endpoint = <&vin0ep2>;
+					};
+				};
+			};
+		};
+	};
+
+	/*
+	 * IIC3 and I2C3 may be switched using pinmux.
+	 * IIC3/I2C3 does not appear to support fallback to GPIO.
+	 */
+	i2cpwr: i2c-13 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&iic3>, <&i2c3>;
+		i2c-bus-name = "i2c-pwr";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmic@58 {
+			compatible = "dlg,da9063";
+			reg = <0x58>;
+			interrupt-parent = <&irqc0>;
+			interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+			interrupt-controller;
+
+			rtc {
+				compatible = "dlg,da9063-rtc";
+			};
+
+			wdt {
+				compatible = "dlg,da9063-watchdog";
+			};
+		};
+
+		vdd_dvfs: regulator@68 {
+			compatible = "dlg,da9210";
+			reg = <0x68>;
+			interrupt-parent = <&irqc0>;
+			interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+	};
 };
 
 &du {
@@ -437,11 +588,21 @@
 		function = "iic1";
 	};
 
+	i2c2_pins: i2c2 {
+		groups = "i2c2";
+		function = "i2c2";
+	};
+
 	iic2_pins: iic2 {
 		groups = "iic2";
 		function = "iic2";
 	};
 
+	i2c3_pins: i2c3 {
+		groups = "i2c3";
+		function = "i2c3";
+	};
+
 	iic3_pins: iic3 {
 		groups = "iic3";
 		function = "iic3";
@@ -643,124 +804,28 @@
 	pinctrl-names = "i2c-exio1";
 };
 
-&iic2	{
-	status = "okay";
-	pinctrl-0 = <&iic2_pins>;
-	pinctrl-names = "default";
+&i2c2	{
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-names = "i2c-hdmi";
 
 	clock-frequency = <100000>;
-
-	ak4643: codec@12 {
-		compatible = "asahi-kasei,ak4643";
-		#sound-dai-cells = <0>;
-		reg = <0x12>;
-	};
-
-	composite-in@20 {
-		compatible = "adi,adv7180";
-		reg = <0x20>;
-		remote = <&vin1>;
-
-		port {
-			adv7180: endpoint {
-				bus-width = <8>;
-				remote-endpoint = <&vin1ep0>;
-			};
-		};
-	};
-
-	hdmi@39 {
-		compatible = "adi,adv7511w";
-		reg = <0x39>;
-		interrupt-parent = <&gpio1>;
-		interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
-
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-		adi,input-style = <1>;
-		adi,input-justification = "evenly";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7511_in: endpoint {
-					remote-endpoint = <&du_out_lvds0>;
-				};
-			};
-
-			port@1 {
-				reg = <1>;
-				adv7511_out: endpoint {
-					remote-endpoint = <&hdmi_con_out>;
-				};
-			};
-		};
-	};
-
-	hdmi-in@4c {
-		compatible = "adi,adv7612";
-		reg = <0x4c>;
-		interrupt-parent = <&gpio1>;
-		interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
-		default-input = <0>;
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7612_in: endpoint {
-					remote-endpoint = <&hdmi_con_in>;
-				};
-			};
-
-			port@2 {
-				reg = <2>;
-				adv7612_out: endpoint {
-					remote-endpoint = <&vin0ep2>;
-				};
-			};
-		};
-	};
 };
 
-&iic3 {
-	pinctrl-names = "default";
+&iic2	{
+	pinctrl-0 = <&iic2_pins>;
+	pinctrl-names = "i2c-hdmi";
+
+	clock-frequency = <100000>;
+};
+
+&i2c3	{
+	pinctrl-0 = <&i2c3_pins>;
+	pinctrl-names = "i2c-pwr";
+};
+
+&iic3	{
 	pinctrl-0 = <&iic3_pins>;
-	status = "okay";
-
-	pmic@58 {
-		compatible = "dlg,da9063";
-		reg = <0x58>;
-		interrupt-parent = <&irqc0>;
-		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
-		interrupt-controller;
-
-		rtc {
-			compatible = "dlg,da9063-rtc";
-		};
-
-		wdt {
-			compatible = "dlg,da9063-watchdog";
-		};
-	};
-
-	vdd_dvfs: regulator@68 {
-		compatible = "dlg,da9210";
-		reg = <0x68>;
-		interrupt-parent = <&irqc0>;
-		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
-
-		regulator-min-microvolt = <1000000>;
-		regulator-max-microvolt = <1000000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
+	pinctrl-names = "i2c-pwr";
 };
 
 &pci0 {
diff --git a/arch/arm/boot/dts/r8a7790-stout.dts b/arch/arm/boot/dts/r8a7790-stout.dts
new file mode 100644
index 0000000..a13a92c
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7790-stout.dts
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Stout board
+ *
+ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
+ */
+
+/dts-v1/;
+#include "r8a7790.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Stout";
+	compatible = "renesas,stout", "renesas,r8a7790";
+
+	aliases {
+		serial0 = &scifa0;
+	};
+
+	chosen {
+		bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x40000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		led1 {
+			gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+		};
+		led2 {
+			gpios = <&gpio4 23 GPIO_ACTIVE_LOW>;
+		};
+		led3 {
+			gpios = <&gpio5 17 GPIO_ACTIVE_LOW>;
+		};
+		led5 {
+			gpios = <&gpio4 24 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	fixedregulator3v3: regulator-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vcc_sdhi0: regulator-vcc-sdhi0 {
+		compatible = "regulator-fixed";
+
+		regulator-name = "SDHI0 Vcc";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpio = <&gpio5 24 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	hdmi-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_out: endpoint {
+				remote-endpoint = <&adv7511_out>;
+			};
+		};
+	};
+
+	osc1_clk: osc1-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <148500000>;
+	};
+
+	osc4_clk: osc4-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+	};
+};
+
+&du {
+	pinctrl-0 = <&du_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 722>,
+		 <&cpg CPG_MOD 726>, <&cpg CPG_MOD 725>,
+		 <&osc1_clk>;
+	clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1", "dclkin.0";
+
+	ports {
+		port@0 {
+			endpoint {
+				remote-endpoint = <&adv7511_in>;
+			};
+		};
+		port@1 {
+			lvds_connector0: endpoint {
+			};
+		};
+		port@2 {
+			lvds_connector1: endpoint {
+			};
+		};
+	};
+};
+
+&extal_clk {
+	clock-frequency = <20000000>;
+};
+
+&pfc {
+
+	pinctrl-0 = <&scif_clk_pins>;
+	pinctrl-names = "default";
+
+	du_pins: du {
+		groups = "du_rgb888", "du_sync_1", "du_clk_out_0";
+		function = "du";
+	};
+
+	scifa0_pins: scifa0 {
+		groups = "scifa0_data_b";
+		function = "scifa0";
+	};
+
+	scif_clk_pins: scif_clk {
+		groups = "scif_clk";
+		function = "scif_clk";
+	};
+
+	ether_pins: ether {
+		groups = "eth_link", "eth_mdio", "eth_rmii";
+		function = "eth";
+	};
+
+	phy1_pins: phy1 {
+		groups = "intc_irq1";
+		function = "intc";
+	};
+
+	sdhi0_pins: sd0 {
+		groups = "sdhi0_data4", "sdhi0_ctrl";
+		function = "sdhi0";
+		power-source = <3300>;
+	};
+
+	qspi_pins: qspi {
+		groups = "qspi_ctrl", "qspi_data4";
+		function = "qspi";
+	};
+
+	iic2_pins: iic2 {
+		groups = "iic2_b";
+		function = "iic2";
+	};
+
+	iic3_pins: iic3 {
+		groups = "iic3";
+		function = "iic3";
+	};
+
+	usb0_pins: usb0 {
+		groups = "usb0";
+		function = "usb0";
+	};
+};
+
+&ether {
+	pinctrl-0 = <&ether_pins &phy1_pins>;
+	pinctrl-names = "default";
+
+	phy-handle = <&phy1>;
+	renesas,ether-link-active-low;
+	status = "okay";
+
+	phy1: ethernet-phy@1 {
+		reg = <1>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+		micrel,led-mode = <1>;
+	};
+};
+
+&cmt0 {
+	status = "okay";
+};
+
+&qspi {
+	pinctrl-0 = <&qspi_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+
+	flash: flash@0 {
+		compatible = "spansion,s25fl512s", "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <30000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		spi-cpha;
+		spi-cpol;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "loader";
+				reg = <0x00000000 0x00080000>;
+				read-only;
+			};
+			partition@80000 {
+				label = "uboot";
+				reg = <0x00080000 0x00040000>;
+				read-only;
+			};
+			partition@c0000 {
+				label = "uboot-env";
+				reg = <0x000c0000 0x00040000>;
+				read-only;
+			};
+			partition@100000 {
+				label = "flash";
+				reg = <0x00100000 0x03f00000>;
+			};
+		};
+	};
+};
+
+&scifa0 {
+	pinctrl-0 = <&scifa0_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+};
+
+&scif_clk {
+	clock-frequency = <14745600>;
+};
+
+&sdhi0 {
+	pinctrl-0 = <&sdhi0_pins>;
+	pinctrl-names = "default";
+
+	vmmc-supply = <&vcc_sdhi0>;
+	cd-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&cpu0 {
+	cpu0-supply = <&vdd_dvfs>;
+};
+
+&iic2	{
+	status = "okay";
+	pinctrl-0 = <&iic2_pins>;
+	pinctrl-names = "default";
+
+	clock-frequency = <100000>;
+
+	hdmi@39 {
+		compatible = "adi,adv7511w";
+		reg = <0x39>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&osc4_clk>;
+		clock-names = "cec";
+
+		adi,input-depth = <8>;
+		adi,input-colorspace = "rgb";
+		adi,input-clock = "1x";
+		adi,input-style = <1>;
+		adi,input-justification = "evenly";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7511_in: endpoint {
+					remote-endpoint = <&du_out_rgb>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				adv7511_out: endpoint {
+					remote-endpoint = <&hdmi_con_out>;
+				};
+			};
+		};
+	};
+};
+
+&iic3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&iic3_pins>;
+	status = "okay";
+
+	pmic@58 {
+		compatible = "dlg,da9063";
+		reg = <0x58>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+
+		rtc {
+			compatible = "dlg,da9063-rtc";
+		};
+
+		wdt {
+			compatible = "dlg,da9063-watchdog";
+		};
+	};
+
+	vdd_dvfs: regulator@68 {
+		compatible = "dlg,da9210";
+		reg = <0x68>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <1000000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vdd: regulator@70 {
+		compatible = "dlg,da9210";
+		reg = <0x70>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <1000000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&pci0 {
+	status = "okay";
+	pinctrl-0 = <&usb0_pins>;
+	pinctrl-names = "default";
+};
+
+&usbphy {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index ed9a685..e4367ce 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -17,7 +17,6 @@
 
 / {
 	compatible = "renesas,r8a7790";
-	interrupt-parent = <&gic>;
 	#address-cells = <2>;
 	#size-cells = <2>;
 
@@ -41,6 +40,35 @@
 		vin3 = &vin3;
 	};
 
+	/*
+	 * The external audio clocks are configured as 0 Hz fixed frequency
+	 * clocks by default.
+	 * Boards that provide audio clocks should override them.
+	 */
+	audio_clk_a: audio_clk_a {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+	audio_clk_b: audio_clk_b {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+	audio_clk_c: audio_clk_c {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External CAN clock */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board. */
+		clock-frequency = <0>;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -159,983 +187,6 @@
 		};
 	};
 
-	thermal-zones {
-		cpu_thermal: cpu-thermal {
-			polling-delay-passive	= <0>;
-			polling-delay		= <0>;
-
-			thermal-sensors = <&thermal>;
-
-			trips {
-				cpu-crit {
-					temperature	= <95000>;
-					hysteresis	= <0>;
-					type		= "critical";
-				};
-			};
-			cooling-maps {
-			};
-		};
-	};
-
-	apmu@e6151000 {
-		compatible = "renesas,r8a7790-apmu", "renesas,apmu";
-		reg = <0 0xe6151000 0 0x188>;
-		cpus = <&cpu4 &cpu5 &cpu6 &cpu7>;
-	};
-
-	apmu@e6152000 {
-		compatible = "renesas,r8a7790-apmu", "renesas,apmu";
-		reg = <0 0xe6152000 0 0x188>;
-		cpus = <&cpu0 &cpu1 &cpu2 &cpu3>;
-	};
-
-	gic: interrupt-controller@f1001000 {
-		compatible = "arm,gic-400";
-		#interrupt-cells = <3>;
-		#address-cells = <0>;
-		interrupt-controller;
-		reg = <0 0xf1001000 0 0x1000>,
-			<0 0xf1002000 0 0x2000>,
-			<0 0xf1004000 0 0x2000>,
-			<0 0xf1006000 0 0x2000>;
-		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-		clocks = <&cpg CPG_MOD 408>;
-		clock-names = "clk";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 408>;
-	};
-
-	gpio0: gpio@e6050000 {
-		compatible = "renesas,gpio-r8a7790", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6050000 0 0x50>;
-		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 0 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 912>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 912>;
-	};
-
-	gpio1: gpio@e6051000 {
-		compatible = "renesas,gpio-r8a7790", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6051000 0 0x50>;
-		interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 32 30>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 911>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 911>;
-	};
-
-	gpio2: gpio@e6052000 {
-		compatible = "renesas,gpio-r8a7790", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6052000 0 0x50>;
-		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 64 30>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 910>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 910>;
-	};
-
-	gpio3: gpio@e6053000 {
-		compatible = "renesas,gpio-r8a7790", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6053000 0 0x50>;
-		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 96 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 909>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 909>;
-	};
-
-	gpio4: gpio@e6054000 {
-		compatible = "renesas,gpio-r8a7790", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6054000 0 0x50>;
-		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 128 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 908>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 908>;
-	};
-
-	gpio5: gpio@e6055000 {
-		compatible = "renesas,gpio-r8a7790", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055000 0 0x50>;
-		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 160 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 907>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 907>;
-	};
-
-	thermal: thermal@e61f0000 {
-		compatible =	"renesas,thermal-r8a7790",
-				"renesas,rcar-gen2-thermal",
-				"renesas,rcar-thermal";
-		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
-		interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 522>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 522>;
-		#thermal-sensor-cells = <0>;
-	};
-
-	timer {
-		compatible = "arm,armv7-timer";
-		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
-	};
-
-	cmt0: timer@ffca0000 {
-		compatible = "renesas,r8a7790-cmt0", "renesas,rcar-gen2-cmt0";
-		reg = <0 0xffca0000 0 0x1004>;
-		interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 124>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 124>;
-
-		status = "disabled";
-	};
-
-	cmt1: timer@e6130000 {
-		compatible = "renesas,r8a7790-cmt1", "renesas,rcar-gen2-cmt1";
-		reg = <0 0xe6130000 0 0x1004>;
-		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 329>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 329>;
-
-		status = "disabled";
-	};
-
-	irqc0: interrupt-controller@e61c0000 {
-		compatible = "renesas,irqc-r8a7790", "renesas,irqc";
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		reg = <0 0xe61c0000 0 0x200>;
-		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 407>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 407>;
-	};
-
-	dmac0: dma-controller@e6700000 {
-		compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
-		reg = <0 0xe6700000 0 0x20000>;
-		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12", "ch13", "ch14";
-		clocks = <&cpg CPG_MOD 219>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 219>;
-		#dma-cells = <1>;
-		dma-channels = <15>;
-	};
-
-	dmac1: dma-controller@e6720000 {
-		compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
-		reg = <0 0xe6720000 0 0x20000>;
-		interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12", "ch13", "ch14";
-		clocks = <&cpg CPG_MOD 218>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 218>;
-		#dma-cells = <1>;
-		dma-channels = <15>;
-	};
-
-	audma0: dma-controller@ec700000 {
-		compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
-		reg = <0 0xec700000 0 0x10000>;
-		interrupts =	<GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12";
-		clocks = <&cpg CPG_MOD 502>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 502>;
-		#dma-cells = <1>;
-		dma-channels = <13>;
-	};
-
-	audma1: dma-controller@ec720000 {
-		compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
-		reg = <0 0xec720000 0 0x10000>;
-		interrupts =	<GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12";
-		clocks = <&cpg CPG_MOD 501>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 501>;
-		#dma-cells = <1>;
-		dma-channels = <13>;
-	};
-
-	usb_dmac0: dma-controller@e65a0000 {
-		compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac";
-		reg = <0 0xe65a0000 0 0x100>;
-		interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "ch0", "ch1";
-		clocks = <&cpg CPG_MOD 330>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 330>;
-		#dma-cells = <1>;
-		dma-channels = <2>;
-	};
-
-	usb_dmac1: dma-controller@e65b0000 {
-		compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac";
-		reg = <0 0xe65b0000 0 0x100>;
-		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "ch0", "ch1";
-		clocks = <&cpg CPG_MOD 331>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 331>;
-		#dma-cells = <1>;
-		dma-channels = <2>;
-	};
-
-	i2c0: i2c@e6508000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7790", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6508000 0 0x40>;
-		interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 931>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 931>;
-		i2c-scl-internal-delay-ns = <110>;
-		status = "disabled";
-	};
-
-	i2c1: i2c@e6518000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7790", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6518000 0 0x40>;
-		interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 930>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 930>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c2: i2c@e6530000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7790", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6530000 0 0x40>;
-		interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 929>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 929>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c3: i2c@e6540000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7790", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6540000 0 0x40>;
-		interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 928>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 928>;
-		i2c-scl-internal-delay-ns = <110>;
-		status = "disabled";
-	};
-
-	iic0: i2c@e6500000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6500000 0 0x425>;
-		interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 318>;
-		dmas = <&dmac0 0x61>, <&dmac0 0x62>,
-		       <&dmac1 0x61>, <&dmac1 0x62>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 318>;
-		status = "disabled";
-	};
-
-	iic1: i2c@e6510000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6510000 0 0x425>;
-		interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 323>;
-		dmas = <&dmac0 0x65>, <&dmac0 0x66>,
-		       <&dmac1 0x65>, <&dmac1 0x66>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 323>;
-		status = "disabled";
-	};
-
-	iic2: i2c@e6520000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6520000 0 0x425>;
-		interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 300>;
-		dmas = <&dmac0 0x69>, <&dmac0 0x6a>,
-		       <&dmac1 0x69>, <&dmac1 0x6a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 300>;
-		status = "disabled";
-	};
-
-	iic3: i2c@e60b0000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe60b0000 0 0x425>;
-		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 926>;
-		dmas = <&dmac0 0x77>, <&dmac0 0x78>,
-		       <&dmac1 0x77>, <&dmac1 0x78>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 926>;
-		status = "disabled";
-	};
-
-	mmcif0: mmc@ee200000 {
-		compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
-		reg = <0 0xee200000 0 0x80>;
-		interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 315>;
-		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
-		       <&dmac1 0xd1>, <&dmac1 0xd2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 315>;
-		reg-io-width = <4>;
-		status = "disabled";
-		max-frequency = <97500000>;
-	};
-
-	mmcif1: mmc@ee220000 {
-		compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
-		reg = <0 0xee220000 0 0x80>;
-		interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 305>;
-		dmas = <&dmac0 0xe1>, <&dmac0 0xe2>,
-		       <&dmac1 0xe1>, <&dmac1 0xe2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 305>;
-		reg-io-width = <4>;
-		status = "disabled";
-		max-frequency = <97500000>;
-	};
-
-	pfc: pin-controller@e6060000 {
-		compatible = "renesas,pfc-r8a7790";
-		reg = <0 0xe6060000 0 0x250>;
-	};
-
-	sdhi0: sd@ee100000 {
-		compatible = "renesas,sdhi-r8a7790",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee100000 0 0x328>;
-		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 314>;
-		dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
-		       <&dmac1 0xcd>, <&dmac1 0xce>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <195000000>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 314>;
-		status = "disabled";
-	};
-
-	sdhi1: sd@ee120000 {
-		compatible = "renesas,sdhi-r8a7790",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee120000 0 0x328>;
-		interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 313>;
-		dmas = <&dmac0 0xc9>, <&dmac0 0xca>,
-		       <&dmac1 0xc9>, <&dmac1 0xca>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <195000000>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 313>;
-		status = "disabled";
-	};
-
-	sdhi2: sd@ee140000 {
-		compatible = "renesas,sdhi-r8a7790",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee140000 0 0x100>;
-		interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 312>;
-		dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
-		       <&dmac1 0xc1>, <&dmac1 0xc2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <97500000>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 312>;
-		status = "disabled";
-	};
-
-	sdhi3: sd@ee160000 {
-		compatible = "renesas,sdhi-r8a7790",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee160000 0 0x100>;
-		interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 311>;
-		dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
-		       <&dmac1 0xd3>, <&dmac1 0xd4>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <97500000>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 311>;
-		status = "disabled";
-	};
-
-	scifa0: serial@e6c40000 {
-		compatible = "renesas,scifa-r8a7790",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c40000 0 64>;
-		interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 204>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x21>, <&dmac0 0x22>,
-		       <&dmac1 0x21>, <&dmac1 0x22>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 204>;
-		status = "disabled";
-	};
-
-	scifa1: serial@e6c50000 {
-		compatible = "renesas,scifa-r8a7790",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c50000 0 64>;
-		interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 203>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x25>, <&dmac0 0x26>,
-		       <&dmac1 0x25>, <&dmac1 0x26>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 203>;
-		status = "disabled";
-	};
-
-	scifa2: serial@e6c60000 {
-		compatible = "renesas,scifa-r8a7790",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c60000 0 64>;
-		interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 202>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x27>, <&dmac0 0x28>,
-		       <&dmac1 0x27>, <&dmac1 0x28>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 202>;
-		status = "disabled";
-	};
-
-	scifb0: serial@e6c20000 {
-		compatible = "renesas,scifb-r8a7790",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6c20000 0 0x100>;
-		interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 206>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
-		       <&dmac1 0x3d>, <&dmac1 0x3e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 206>;
-		status = "disabled";
-	};
-
-	scifb1: serial@e6c30000 {
-		compatible = "renesas,scifb-r8a7790",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6c30000 0 0x100>;
-		interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 207>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
-		       <&dmac1 0x19>, <&dmac1 0x1a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 207>;
-		status = "disabled";
-	};
-
-	scifb2: serial@e6ce0000 {
-		compatible = "renesas,scifb-r8a7790",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6ce0000 0 0x100>;
-		interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 216>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
-		       <&dmac1 0x1d>, <&dmac1 0x1e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 216>;
-		status = "disabled";
-	};
-
-	scif0: serial@e6e60000 {
-		compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e60000 0 64>;
-		interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 721>, <&cpg CPG_CORE R8A7790_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
-		       <&dmac1 0x29>, <&dmac1 0x2a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 721>;
-		status = "disabled";
-	};
-
-	scif1: serial@e6e68000 {
-		compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e68000 0 64>;
-		interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 720>, <&cpg CPG_CORE R8A7790_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
-		       <&dmac1 0x2d>, <&dmac1 0x2e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 720>;
-		status = "disabled";
-	};
-
-	scif2: serial@e6e56000 {
-		compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e56000 0 64>;
-		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 310>, <&cpg CPG_CORE R8A7790_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
-		       <&dmac1 0x2b>, <&dmac1 0x2c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 310>;
-		status = "disabled";
-	};
-
-	hscif0: serial@e62c0000 {
-		compatible = "renesas,hscif-r8a7790",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62c0000 0 96>;
-		interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 717>, <&cpg CPG_CORE R8A7790_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
-		       <&dmac1 0x39>, <&dmac1 0x3a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 717>;
-		status = "disabled";
-	};
-
-	hscif1: serial@e62c8000 {
-		compatible = "renesas,hscif-r8a7790",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62c8000 0 96>;
-		interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 716>, <&cpg CPG_CORE R8A7790_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
-		       <&dmac1 0x4d>, <&dmac1 0x4e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 716>;
-		status = "disabled";
-	};
-
-	icram0:	sram@e63a0000 {
-		compatible = "mmio-sram";
-		reg = <0 0xe63a0000 0 0x12000>;
-	};
-
-	icram1:	sram@e63c0000 {
-		compatible = "mmio-sram";
-		reg = <0 0xe63c0000 0 0x1000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0 0xe63c0000 0x1000>;
-
-		smp-sram@0 {
-			compatible = "renesas,smp-sram";
-			reg = <0 0x10>;
-		};
-	};
-
-	ether: ethernet@ee700000 {
-		compatible = "renesas,ether-r8a7790",
-			     "renesas,rcar-gen2-ether";
-		reg = <0 0xee700000 0 0x400>;
-		interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 813>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 813>;
-		phy-mode = "rmii";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	avb: ethernet@e6800000 {
-		compatible = "renesas,etheravb-r8a7790",
-			     "renesas,etheravb-rcar-gen2";
-		reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
-		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 812>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 812>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	sata0: sata@ee300000 {
-		compatible = "renesas,sata-r8a7790", "renesas,rcar-gen2-sata";
-		reg = <0 0xee300000 0 0x2000>;
-		interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 815>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 815>;
-		status = "disabled";
-	};
-
-	sata1: sata@ee500000 {
-		compatible = "renesas,sata-r8a7790", "renesas,rcar-gen2-sata";
-		reg = <0 0xee500000 0 0x2000>;
-		interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 814>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 814>;
-		status = "disabled";
-	};
-
-	hsusb: usb@e6590000 {
-		compatible = "renesas,usbhs-r8a7790", "renesas,rcar-gen2-usbhs";
-		reg = <0 0xe6590000 0 0x100>;
-		interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 704>;
-		dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
-		       <&usb_dmac1 0>, <&usb_dmac1 1>;
-		dma-names = "ch0", "ch1", "ch2", "ch3";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 704>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
-		status = "disabled";
-	};
-
-	usbphy: usb-phy@e6590100 {
-		compatible = "renesas,usb-phy-r8a7790",
-			     "renesas,rcar-gen2-usb-phy";
-		reg = <0 0xe6590100 0 0x100>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&cpg CPG_MOD 704>;
-		clock-names = "usbhs";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 704>;
-		status = "disabled";
-
-		usb0: usb-channel@0 {
-			reg = <0>;
-			#phy-cells = <1>;
-		};
-		usb2: usb-channel@2 {
-			reg = <2>;
-			#phy-cells = <1>;
-		};
-	};
-
-	vin0: video@e6ef0000 {
-		compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef0000 0 0x1000>;
-		interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 811>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 811>;
-		status = "disabled";
-	};
-
-	vin1: video@e6ef1000 {
-		compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef1000 0 0x1000>;
-		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 810>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 810>;
-		status = "disabled";
-	};
-
-	vin2: video@e6ef2000 {
-		compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef2000 0 0x1000>;
-		interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 809>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 809>;
-		status = "disabled";
-	};
-
-	vin3: video@e6ef3000 {
-		compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef3000 0 0x1000>;
-		interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 808>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 808>;
-		status = "disabled";
-	};
-
-	vsp@fe920000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe920000 0 0x8000>;
-		interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 130>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 130>;
-	};
-
-	vsp@fe928000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe928000 0 0x8000>;
-		interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 131>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 131>;
-	};
-
-	vsp@fe930000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe930000 0 0x8000>;
-		interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 128>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 128>;
-	};
-
-	vsp@fe938000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe938000 0 0x8000>;
-		interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 127>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 127>;
-	};
-
-	du: display@feb00000 {
-		compatible = "renesas,du-r8a7790";
-		reg = <0 0xfeb00000 0 0x70000>,
-		      <0 0xfeb90000 0 0x1c>,
-		      <0 0xfeb94000 0 0x1c>;
-		reg-names = "du", "lvds.0", "lvds.1";
-		interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>,
-			 <&cpg CPG_MOD 722>, <&cpg CPG_MOD 726>,
-			 <&cpg CPG_MOD 725>;
-		clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1";
-		status = "disabled";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				du_out_rgb: endpoint {
-				};
-			};
-			port@1 {
-				reg = <1>;
-				du_out_lvds0: endpoint {
-				};
-			};
-			port@2 {
-				reg = <2>;
-				du_out_lvds1: endpoint {
-				};
-			};
-		};
-	};
-
-	can0: can@e6e80000 {
-		compatible = "renesas,can-r8a7790", "renesas,rcar-gen2-can";
-		reg = <0 0xe6e80000 0 0x1000>;
-		interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 916>, <&cpg CPG_CORE R8A7790_CLK_RCAN>,
-			 <&can_clk>;
-		clock-names = "clkp1", "clkp2", "can_clk";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 916>;
-		status = "disabled";
-	};
-
-	can1: can@e6e88000 {
-		compatible = "renesas,can-r8a7790", "renesas,rcar-gen2-can";
-		reg = <0 0xe6e88000 0 0x1000>;
-		interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 915>, <&cpg CPG_CORE R8A7790_CLK_RCAN>,
-			 <&can_clk>;
-		clock-names = "clkp1", "clkp2", "can_clk";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 915>;
-		status = "disabled";
-	};
-
-	jpu: jpeg-codec@fe980000 {
-		compatible = "renesas,jpu-r8a7790", "renesas,rcar-gen2-jpu";
-		reg = <0 0xfe980000 0 0x10300>;
-		interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 106>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 106>;
-	};
-
 	/* External root clock */
 	extal_clk: extal {
 		compatible = "fixed-clock";
@@ -1151,27 +202,6 @@
 		clock-frequency = <0>;
 	};
 
-	/*
-	 * The external audio clocks are configured as 0 Hz fixed frequency
-	 * clocks by default.
-	 * Boards that provide audio clocks should override them.
-	 */
-	audio_clk_a: audio_clk_a {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-	audio_clk_b: audio_clk_b {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-	audio_clk_c: audio_clk_c {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
 	/* External SCIF clock */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -1180,489 +210,1530 @@
 		clock-frequency = <0>;
 	};
 
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gpio0: gpio@e6050000 {
+			compatible = "renesas,gpio-r8a7790",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6050000 0 0x50>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 0 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 912>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 912>;
+		};
+
+		gpio1: gpio@e6051000 {
+			compatible = "renesas,gpio-r8a7790",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6051000 0 0x50>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 32 30>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 911>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 911>;
+		};
+
+		gpio2: gpio@e6052000 {
+			compatible = "renesas,gpio-r8a7790",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6052000 0 0x50>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 64 30>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 910>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 910>;
+		};
+
+		gpio3: gpio@e6053000 {
+			compatible = "renesas,gpio-r8a7790",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6053000 0 0x50>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 96 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 909>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 909>;
+		};
+
+		gpio4: gpio@e6054000 {
+			compatible = "renesas,gpio-r8a7790",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6054000 0 0x50>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 128 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 908>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 908>;
+		};
+
+		gpio5: gpio@e6055000 {
+			compatible = "renesas,gpio-r8a7790",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055000 0 0x50>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 160 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 907>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 907>;
+		};
+
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a7790";
+			reg = <0 0xe6060000 0 0x250>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7790-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&usb_extal_clk>;
+			clock-names = "extal", "usb_extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		apmu@e6151000 {
+			compatible = "renesas,r8a7790-apmu", "renesas,apmu";
+			reg = <0 0xe6151000 0 0x188>;
+			cpus = <&cpu4 &cpu5 &cpu6 &cpu7>;
+		};
+
+		apmu@e6152000 {
+			compatible = "renesas,r8a7790-apmu", "renesas,apmu";
+			reg = <0 0xe6152000 0 0x188>;
+			cpus = <&cpu0 &cpu1 &cpu2 &cpu3>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7790-rst";
+			reg = <0 0xe6160000 0 0x0100>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7790-sysc";
+			reg = <0 0xe6180000 0 0x0200>;
+			#power-domain-cells = <1>;
+		};
+
+		irqc0: interrupt-controller@e61c0000 {
+			compatible = "renesas,irqc-r8a7790", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 407>;
+		};
+
+		thermal: thermal@e61f0000 {
+			compatible = "renesas,thermal-r8a7790",
+				     "renesas,rcar-gen2-thermal",
+				     "renesas,rcar-thermal";
+			reg = <0 0xe61f0000 0 0x10>, <0 0xe61f0100 0 0x38>;
+			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 522>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 522>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		ipmmu_sy0: mmu@e6280000 {
+			compatible = "renesas,ipmmu-r8a7790",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6280000 0 0x1000>;
+			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_sy1: mmu@e6290000 {
+			compatible = "renesas,ipmmu-r8a7790",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6290000 0 0x1000>;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_ds: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a7790",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6740000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_mp: mmu@ec680000 {
+			compatible = "renesas,ipmmu-r8a7790",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xec680000 0 0x1000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_mx: mmu@fe951000 {
+			compatible = "renesas,ipmmu-r8a7790",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xfe951000 0 0x1000>;
+			interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a7790",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xffc80000 0 0x1000>;
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		icram0:	sram@e63a0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63a0000 0 0x12000>;
+		};
+
+		icram1:	sram@e63c0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63c0000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0xe63c0000 0x1000>;
+
+			smp-sram@0 {
+				compatible = "renesas,smp-sram";
+				reg = <0 0x10>;
+			};
+		};
+
+		i2c0: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7790",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6518000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7790",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6518000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6530000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7790",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6530000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e6540000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7790",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6540000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		iic0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7790",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6500000 0 0x425>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>;
+			dmas = <&dmac0 0x61>, <&dmac0 0x62>,
+			       <&dmac1 0x61>, <&dmac1 0x62>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			status = "disabled";
+		};
+
+		iic1: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7790",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6510000 0 0x425>;
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 323>;
+			dmas = <&dmac0 0x65>, <&dmac0 0x66>,
+			       <&dmac1 0x65>, <&dmac1 0x66>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 323>;
+			status = "disabled";
+		};
+
+		iic2: i2c@e6520000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7790",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6520000 0 0x425>;
+			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 300>;
+			dmas = <&dmac0 0x69>, <&dmac0 0x6a>,
+			       <&dmac1 0x69>, <&dmac1 0x6a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 300>;
+			status = "disabled";
+		};
+
+		iic3: i2c@e60b0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7790",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe60b0000 0 0x425>;
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 926>;
+			dmas = <&dmac0 0x77>, <&dmac0 0x78>,
+			       <&dmac1 0x77>, <&dmac1 0x78>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 926>;
+			status = "disabled";
+		};
+
+		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a7790",
+				     "renesas,rcar-gen2-usbhs";
+			reg = <0 0xe6590000 0 0x100>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>;
+			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+			       <&usb_dmac1 0>, <&usb_dmac1 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			renesas,buswait = <4>;
+			phys = <&usb0 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		usbphy: usb-phy@e6590100 {
+			compatible = "renesas,usb-phy-r8a7790",
+				     "renesas,rcar-gen2-usb-phy";
+			reg = <0 0xe6590100 0 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cpg CPG_MOD 704>;
+			clock-names = "usbhs";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			status = "disabled";
+
+			usb0: usb-channel@0 {
+				reg = <0>;
+				#phy-cells = <1>;
+			};
+			usb2: usb-channel@2 {
+				reg = <2>;
+				#phy-cells = <1>;
+			};
+		};
+
+		usb_dmac0: dma-controller@e65a0000 {
+			compatible = "renesas,r8a7790-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65a0000 0 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 330>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 330>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb_dmac1: dma-controller@e65b0000 {
+			compatible = "renesas,r8a7790-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65b0000 0 0x100>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 331>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 331>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a7790",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x20000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 219>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		dmac1: dma-controller@e6720000 {
+			compatible = "renesas,dmac-r8a7790",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6720000 0 0x20000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a7790",
+				     "renesas,etheravb-rcar-gen2";
+			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		qspi: spi@e6b10000 {
+			compatible = "renesas,qspi-r8a7790", "renesas,qspi";
+			reg = <0 0xe6b10000 0 0x2c>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 917>;
+			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
+			       <&dmac1 0x17>, <&dmac1 0x18>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+			num-cs = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		scifa0: serial@e6c40000 {
+			compatible = "renesas,scifa-r8a7790",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x21>, <&dmac0 0x22>,
+			       <&dmac1 0x21>, <&dmac1 0x22>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scifa1: serial@e6c50000 {
+			compatible = "renesas,scifa-r8a7790",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x25>, <&dmac0 0x26>,
+			       <&dmac1 0x25>, <&dmac1 0x26>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		scifa2: serial@e6c60000 {
+			compatible = "renesas,scifa-r8a7790",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c60000 0 64>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x27>, <&dmac0 0x28>,
+			       <&dmac1 0x27>, <&dmac1 0x28>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 202>;
+			status = "disabled";
+		};
+
+		scifb0: serial@e6c20000 {
+			compatible = "renesas,scifb-r8a7790",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c20000 0 0x100>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
+			       <&dmac1 0x3d>, <&dmac1 0x3e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 206>;
+			status = "disabled";
+		};
+
+		scifb1: serial@e6c30000 {
+			compatible = "renesas,scifb-r8a7790",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c30000 0 0x100>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
+			       <&dmac1 0x19>, <&dmac1 0x1a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 207>;
+			status = "disabled";
+		};
+
+		scifb2: serial@e6ce0000 {
+			compatible = "renesas,scifb-r8a7790",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6ce0000 0 0x100>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 216>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
+			       <&dmac1 0x1d>, <&dmac1 0x1e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 216>;
+			status = "disabled";
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a7790",
+				     "renesas,rcar-gen2-scif",
+				     "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 721>,
+				 <&cpg CPG_CORE R8A7790_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
+			       <&dmac1 0x29>, <&dmac1 0x2a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 721>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a7790",
+				     "renesas,rcar-gen2-scif",
+				     "renesas,scif";
+			reg = <0 0xe6e68000 0 64>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 720>,
+				 <&cpg CPG_CORE R8A7790_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
+			       <&dmac1 0x2d>, <&dmac1 0x2e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 720>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e56000 {
+			compatible = "renesas,scif-r8a7790",
+				     "renesas,rcar-gen2-scif",
+				     "renesas,scif";
+			reg = <0 0xe6e56000 0 64>;
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 310>,
+				 <&cpg CPG_CORE R8A7790_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
+			       <&dmac1 0x2b>, <&dmac1 0x2c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 310>;
+			status = "disabled";
+		};
+
+		hscif0: serial@e62c0000 {
+			compatible = "renesas,hscif-r8a7790",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c0000 0 96>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 717>,
+				 <&cpg CPG_CORE R8A7790_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
+			       <&dmac1 0x39>, <&dmac1 0x3a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 717>;
+			status = "disabled";
+		};
+
+		hscif1: serial@e62c8000 {
+			compatible = "renesas,hscif-r8a7790",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c8000 0 96>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>,
+				 <&cpg CPG_CORE R8A7790_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
+			       <&dmac1 0x4d>, <&dmac1 0x4e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 716>;
+			status = "disabled";
+		};
+
+		msiof0: spi@e6e20000 {
+			compatible = "renesas,msiof-r8a7790",
+				     "renesas,rcar-gen2-msiof";
+			reg = <0 0xe6e20000 0 0x0064>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 0>;
+			dmas = <&dmac0 0x51>, <&dmac0 0x52>,
+			       <&dmac1 0x51>, <&dmac1 0x52>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof1: spi@e6e10000 {
+			compatible = "renesas,msiof-r8a7790",
+				     "renesas,rcar-gen2-msiof";
+			reg = <0 0xe6e10000 0 0x0064>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 208>;
+			dmas = <&dmac0 0x55>, <&dmac0 0x56>,
+			       <&dmac1 0x55>, <&dmac1 0x56>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 208>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof2: spi@e6e00000 {
+			compatible = "renesas,msiof-r8a7790",
+				     "renesas,rcar-gen2-msiof";
+			reg = <0 0xe6e00000 0 0x0064>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 205>;
+			dmas = <&dmac0 0x41>, <&dmac0 0x42>,
+			       <&dmac1 0x41>, <&dmac1 0x42>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 205>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof3: spi@e6c90000 {
+			compatible = "renesas,msiof-r8a7790",
+				     "renesas,rcar-gen2-msiof";
+			reg = <0 0xe6c90000 0 0x0064>;
+			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 215>;
+			dmas = <&dmac0 0x45>, <&dmac0 0x46>,
+			       <&dmac1 0x45>, <&dmac1 0x46>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 215>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		can0: can@e6e80000 {
+			compatible = "renesas,can-r8a7790",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e80000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>,
+				 <&cpg CPG_CORE R8A7790_CLK_RCAN>, <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+			status = "disabled";
+		};
+
+		can1: can@e6e88000 {
+			compatible = "renesas,can-r8a7790",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e88000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>,
+				 <&cpg CPG_CORE R8A7790_CLK_RCAN>, <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 915>;
+			status = "disabled";
+		};
+
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a7790",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 811>;
+			status = "disabled";
+		};
+
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a7790",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 810>;
+			status = "disabled";
+		};
+
+		vin2: video@e6ef2000 {
+			compatible = "renesas,vin-r8a7790",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef2000 0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 809>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 809>;
+			status = "disabled";
+		};
+
+		vin3: video@e6ef3000 {
+			compatible = "renesas,vin-r8a7790",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef3000 0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 808>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 808>;
+			status = "disabled";
+		};
+
+		rcar_sound: sound@ec500000 {
+			/*
+			 * #sound-dai-cells is required
+			 *
+			 * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
+			 * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
+			 */
+			compatible = "renesas,rcar_sound-r8a7790",
+				     "renesas,rcar_sound-gen2";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
+			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+			clocks = <&cpg CPG_MOD 1005>,
+				 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+				 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+				 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+				 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+				 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+				 <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+				 <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+				 <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+				 <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+				 <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+				 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
+				 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
+				 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+				 <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>,
+				 <&cpg CPG_CORE R8A7790_CLK_M2>;
+			clock-names = "ssi-all",
+				      "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+				      "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+				      "ssi.1", "ssi.0",
+				      "src.9", "src.8", "src.7", "src.6",
+				      "src.5", "src.4", "src.3", "src.2",
+				      "src.1", "src.0",
+				      "ctu.0", "ctu.1",
+				      "mix.0", "mix.1",
+				      "dvc.0", "dvc.1",
+				      "clk_a", "clk_b", "clk_c", "clk_i";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 1005>,
+				 <&cpg 1006>, <&cpg 1007>,
+				 <&cpg 1008>, <&cpg 1009>,
+				 <&cpg 1010>, <&cpg 1011>,
+				 <&cpg 1012>, <&cpg 1013>,
+				 <&cpg 1014>, <&cpg 1015>;
+			reset-names = "ssi-all",
+				      "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+				      "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+				      "ssi.1", "ssi.0";
+
+			status = "disabled";
+
+			rcar_sound,dvc {
+				dvc0: dvc-0 {
+					dmas = <&audma1 0xbc>;
+					dma-names = "tx";
+				};
+				dvc1: dvc-1 {
+					dmas = <&audma1 0xbe>;
+					dma-names = "tx";
+				};
+			};
+
+			rcar_sound,mix {
+				mix0: mix-0 { };
+				mix1: mix-1 { };
+			};
+
+			rcar_sound,ctu {
+				ctu00: ctu-0 { };
+				ctu01: ctu-1 { };
+				ctu02: ctu-2 { };
+				ctu03: ctu-3 { };
+				ctu10: ctu-4 { };
+				ctu11: ctu-5 { };
+				ctu12: ctu-6 { };
+				ctu13: ctu-7 { };
+			};
+
+			rcar_sound,src {
+				src0: src-0 {
+					interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x85>, <&audma1 0x9a>;
+					dma-names = "rx", "tx";
+				};
+				src1: src-1 {
+					interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x87>, <&audma1 0x9c>;
+					dma-names = "rx", "tx";
+				};
+				src2: src-2 {
+					interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x89>, <&audma1 0x9e>;
+					dma-names = "rx", "tx";
+				};
+				src3: src-3 {
+					interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+					dma-names = "rx", "tx";
+				};
+				src4: src-4 {
+					interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+					dma-names = "rx", "tx";
+				};
+				src5: src-5 {
+					interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+					dma-names = "rx", "tx";
+				};
+				src6: src-6 {
+					interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x91>, <&audma1 0xb4>;
+					dma-names = "rx", "tx";
+				};
+				src7: src-7 {
+					interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x93>, <&audma1 0xb6>;
+					dma-names = "rx", "tx";
+				};
+				src8: src-8 {
+					interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x95>, <&audma1 0xb8>;
+					dma-names = "rx", "tx";
+				};
+				src9: src-9 {
+					interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x97>, <&audma1 0xba>;
+					dma-names = "rx", "tx";
+				};
+			};
+
+			rcar_sound,ssi {
+				ssi0: ssi-0 {
+					interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x01>, <&audma1 0x02>,
+					       <&audma0 0x15>, <&audma1 0x16>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi1: ssi-1 {
+					 interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x03>, <&audma1 0x04>,
+					       <&audma0 0x49>, <&audma1 0x4a>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi2: ssi-2 {
+					interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x05>, <&audma1 0x06>,
+					       <&audma0 0x63>, <&audma1 0x64>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi3: ssi-3 {
+					interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x07>, <&audma1 0x08>,
+					       <&audma0 0x6f>, <&audma1 0x70>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi4: ssi-4 {
+					interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x09>, <&audma1 0x0a>,
+					       <&audma0 0x71>, <&audma1 0x72>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi5: ssi-5 {
+					interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0b>, <&audma1 0x0c>,
+					       <&audma0 0x73>, <&audma1 0x74>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi6: ssi-6 {
+					interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0d>, <&audma1 0x0e>,
+					       <&audma0 0x75>, <&audma1 0x76>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi7: ssi-7 {
+					interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0f>, <&audma1 0x10>,
+					       <&audma0 0x79>, <&audma1 0x7a>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi8: ssi-8 {
+					interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x11>, <&audma1 0x12>,
+					       <&audma0 0x7b>, <&audma1 0x7c>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi9: ssi-9 {
+					interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x13>, <&audma1 0x14>,
+					       <&audma0 0x7d>, <&audma1 0x7e>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+			};
+		};
+
+		audma0: dma-controller@ec700000 {
+			compatible = "renesas,dmac-r8a7790",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec700000 0 0x10000>;
+			interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 502>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 502>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		audma1: dma-controller@ec720000 {
+			compatible = "renesas,dmac-r8a7790",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec720000 0 0x10000>;
+			interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 501>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 501>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		xhci: usb@ee000000 {
+			compatible = "renesas,xhci-r8a7790",
+				     "renesas,rcar-gen2-xhci";
+			reg = <0 0xee000000 0 0xc00>;
+			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			phys = <&usb2 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		pci0: pci@ee090000 {
+			compatible = "renesas,pci-r8a7790",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee090000 0 0xc00>,
+			      <0 0xee080000 0 0x1100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x800 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x1000 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
+			};
+		};
+
+		pci1: pci@ee0b0000 {
+			compatible = "renesas,pci-r8a7790",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee0b0000 0 0xc00>,
+			      <0 0xee0a0000 0 0x1100>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <1 1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee0a0000 0 0xee0a0000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pci2: pci@ee0d0000 {
+			compatible = "renesas,pci-r8a7790",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			reg = <0 0xee0d0000 0 0xc00>,
+			      <0 0xee0c0000 0 0x1100>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+
+			bus-range = <2 2>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x20800 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x21000 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+		};
+
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7790",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee100000 0 0x328>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
+			       <&dmac1 0xcd>, <&dmac1 0xce>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <195000000>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		sdhi1: sd@ee120000 {
+			compatible = "renesas,sdhi-r8a7790",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee120000 0 0x328>;
+			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 313>;
+			dmas = <&dmac0 0xc9>, <&dmac0 0xca>,
+			       <&dmac1 0xc9>, <&dmac1 0xca>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <195000000>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 313>;
+			status = "disabled";
+		};
+
+		sdhi2: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a7790",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee140000 0 0x100>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
+			       <&dmac1 0xc1>, <&dmac1 0xc2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi3: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a7790",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee160000 0 0x100>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
+			       <&dmac1 0xd3>, <&dmac1 0xd4>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		mmcif0: mmc@ee200000 {
+			compatible = "renesas,mmcif-r8a7790",
+				     "renesas,sh-mmcif";
+			reg = <0 0xee200000 0 0x80>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 315>;
+			dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
+			       <&dmac1 0xd1>, <&dmac1 0xd2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 315>;
+			reg-io-width = <4>;
+			status = "disabled";
+			max-frequency = <97500000>;
+		};
+
+		mmcif1: mmc@ee220000 {
+			compatible = "renesas,mmcif-r8a7790",
+				     "renesas,sh-mmcif";
+			reg = <0 0xee220000 0 0x80>;
+			interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 305>;
+			dmas = <&dmac0 0xe1>, <&dmac0 0xe2>,
+			       <&dmac1 0xe1>, <&dmac1 0xe2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 305>;
+			reg-io-width = <4>;
+			status = "disabled";
+			max-frequency = <97500000>;
+		};
+
+		sata0: sata@ee300000 {
+			compatible = "renesas,sata-r8a7790",
+				     "renesas,rcar-gen2-sata";
+			reg = <0 0xee300000 0 0x2000>;
+			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 815>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 815>;
+			status = "disabled";
+		};
+
+		sata1: sata@ee500000 {
+			compatible = "renesas,sata-r8a7790",
+				     "renesas,rcar-gen2-sata";
+			reg = <0 0xee500000 0 0x2000>;
+			interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 814>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 814>;
+			status = "disabled";
+		};
+
+		ether: ethernet@ee700000 {
+			compatible = "renesas,ether-r8a7790",
+				     "renesas,rcar-gen2-ether";
+			reg = <0 0xee700000 0 0x400>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 813>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 813>;
+			phy-mode = "rmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>, <0 0xf1002000 0 0x2000>,
+			      <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
+		pciec: pcie@fe000000 {
+			compatible = "renesas,pcie-r8a7790",
+				     "renesas,pcie-rcar-gen2";
+			reg = <0 0xfe000000 0 0x80000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+				  0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+				  0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+				  0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
+				      0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 319>;
+			status = "disabled";
+		};
+
+		vsp@fe920000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe920000 0 0x8000>;
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 130>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 130>;
+		};
+
+		vsp@fe928000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe928000 0 0x8000>;
+			interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 131>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 131>;
+		};
+
+		vsp@fe930000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe930000 0 0x8000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 128>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 128>;
+		};
+
+		vsp@fe938000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe938000 0 0x8000>;
+			interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 127>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 127>;
+		};
+
+		jpu: jpeg-codec@fe980000 {
+			compatible = "renesas,jpu-r8a7790",
+				     "renesas,rcar-gen2-jpu";
+			reg = <0 0xfe980000 0 0x10300>;
+			interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 106>;
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 106>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a7790";
+			reg = <0 0xfeb00000 0 0x70000>,
+			      <0 0xfeb90000 0 0x1c>,
+			      <0 0xfeb94000 0 0x1c>;
+			reg-names = "du", "lvds.0", "lvds.1";
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>,
+				 <&cpg CPG_MOD 722>, <&cpg CPG_MOD 726>,
+				 <&cpg CPG_MOD 725>;
+			clock-names = "du.0", "du.1", "du.2", "lvds.0",
+				      "lvds.1";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+				port@1 {
+					reg = <1>;
+					du_out_lvds0: endpoint {
+					};
+				};
+				port@2 {
+					reg = <2>;
+					du_out_lvds1: endpoint {
+					};
+				};
+			};
+		};
+
+		prr: chipid@ff000044 {
+			compatible = "renesas,prr";
+			reg = <0 0xff000044 0 4>;
+		};
+
+		cmt0: timer@ffca0000 {
+			compatible = "renesas,r8a7790-cmt0",
+				     "renesas,rcar-gen2-cmt0";
+			reg = <0 0xffca0000 0 0x1004>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 124>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 124>;
+
+			status = "disabled";
+		};
+
+		cmt1: timer@e6130000 {
+			compatible = "renesas,r8a7790-cmt1",
+				     "renesas,rcar-gen2-cmt1";
+			reg = <0 0xe6130000 0 0x1004>;
+			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 329>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+			resets = <&cpg 329>;
+
+			status = "disabled";
+		};
+	};
+
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&thermal>;
+
+			trips {
+				cpu-crit {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+			cooling-maps {
+			};
+		};
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
 	/* External USB clock - can be overridden by the board */
 	usb_extal_clk: usb_extal {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <48000000>;
 	};
-
-	/* External CAN clock */
-	can_clk: can {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		/* This value must be overridden by the board. */
-		clock-frequency = <0>;
-	};
-
-	cpg: clock-controller@e6150000 {
-		compatible = "renesas,r8a7790-cpg-mssr";
-		reg = <0 0xe6150000 0 0x1000>;
-		clocks = <&extal_clk>, <&usb_extal_clk>;
-		clock-names = "extal", "usb_extal";
-		#clock-cells = <2>;
-		#power-domain-cells = <0>;
-		#reset-cells = <1>;
-	};
-
-	prr: chipid@ff000044 {
-		compatible = "renesas,prr";
-		reg = <0 0xff000044 0 4>;
-	};
-
-	rst: reset-controller@e6160000 {
-		compatible = "renesas,r8a7790-rst";
-		reg = <0 0xe6160000 0 0x0100>;
-	};
-
-	sysc: system-controller@e6180000 {
-		compatible = "renesas,r8a7790-sysc";
-		reg = <0 0xe6180000 0 0x0200>;
-		#power-domain-cells = <1>;
-	};
-
-	qspi: spi@e6b10000 {
-		compatible = "renesas,qspi-r8a7790", "renesas,qspi";
-		reg = <0 0xe6b10000 0 0x2c>;
-		interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 917>;
-		dmas = <&dmac0 0x17>, <&dmac0 0x18>,
-		       <&dmac1 0x17>, <&dmac1 0x18>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 917>;
-		num-cs = <1>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	msiof0: spi@e6e20000 {
-		compatible = "renesas,msiof-r8a7790",
-			     "renesas,rcar-gen2-msiof";
-		reg = <0 0xe6e20000 0 0x0064>;
-		interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 0>;
-		dmas = <&dmac0 0x51>, <&dmac0 0x52>,
-		       <&dmac1 0x51>, <&dmac1 0x52>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 0>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	msiof1: spi@e6e10000 {
-		compatible = "renesas,msiof-r8a7790",
-			     "renesas,rcar-gen2-msiof";
-		reg = <0 0xe6e10000 0 0x0064>;
-		interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 208>;
-		dmas = <&dmac0 0x55>, <&dmac0 0x56>,
-		       <&dmac1 0x55>, <&dmac1 0x56>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 208>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	msiof2: spi@e6e00000 {
-		compatible = "renesas,msiof-r8a7790",
-			     "renesas,rcar-gen2-msiof";
-		reg = <0 0xe6e00000 0 0x0064>;
-		interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 205>;
-		dmas = <&dmac0 0x41>, <&dmac0 0x42>,
-		       <&dmac1 0x41>, <&dmac1 0x42>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 205>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	msiof3: spi@e6c90000 {
-		compatible = "renesas,msiof-r8a7790",
-			     "renesas,rcar-gen2-msiof";
-		reg = <0 0xe6c90000 0 0x0064>;
-		interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 215>;
-		dmas = <&dmac0 0x45>, <&dmac0 0x46>,
-		       <&dmac1 0x45>, <&dmac1 0x46>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 215>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	xhci: usb@ee000000 {
-		compatible = "renesas,xhci-r8a7790", "renesas,rcar-gen2-xhci";
-		reg = <0 0xee000000 0 0xc00>;
-		interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 328>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 328>;
-		phys = <&usb2 1>;
-		phy-names = "usb";
-		status = "disabled";
-	};
-
-	pci0: pci@ee090000 {
-		compatible = "renesas,pci-r8a7790", "renesas,pci-rcar-gen2";
-		device_type = "pci";
-		reg = <0 0xee090000 0 0xc00>,
-		      <0 0xee080000 0 0x1100>;
-		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 703>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 703>;
-		status = "disabled";
-
-		bus-range = <0 0>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		#interrupt-cells = <1>;
-		ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-		interrupt-map-mask = <0xff00 0 0 0x7>;
-		interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-				 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-				 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-
-		usb@1,0 {
-			reg = <0x800 0 0 0 0>;
-			phys = <&usb0 0>;
-			phy-names = "usb";
-		};
-
-		usb@2,0 {
-			reg = <0x1000 0 0 0 0>;
-			phys = <&usb0 0>;
-			phy-names = "usb";
-		};
-	};
-
-	pci1: pci@ee0b0000 {
-		compatible = "renesas,pci-r8a7790", "renesas,pci-rcar-gen2";
-		device_type = "pci";
-		reg = <0 0xee0b0000 0 0xc00>,
-		      <0 0xee0a0000 0 0x1100>;
-		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 703>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 703>;
-		status = "disabled";
-
-		bus-range = <1 1>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		#interrupt-cells = <1>;
-		ranges = <0x02000000 0 0xee0a0000 0 0xee0a0000 0 0x00010000>;
-		interrupt-map-mask = <0xff00 0 0 0x7>;
-		interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
-				 0x0800 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
-				 0x1000 0 0 2 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-	};
-
-	pci2: pci@ee0d0000 {
-		compatible = "renesas,pci-r8a7790", "renesas,pci-rcar-gen2";
-		device_type = "pci";
-		clocks = <&cpg CPG_MOD 703>;
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 703>;
-		reg = <0 0xee0d0000 0 0xc00>,
-		      <0 0xee0c0000 0 0x1100>;
-		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-		status = "disabled";
-
-		bus-range = <2 2>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		#interrupt-cells = <1>;
-		ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-		interrupt-map-mask = <0xff00 0 0 0x7>;
-		interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-				 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-				 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-
-		usb@1,0 {
-			reg = <0x20800 0 0 0 0>;
-			phys = <&usb2 0>;
-			phy-names = "usb";
-		};
-
-		usb@2,0 {
-			reg = <0x21000 0 0 0 0>;
-			phys = <&usb2 0>;
-			phy-names = "usb";
-		};
-	};
-
-	pciec: pcie@fe000000 {
-		compatible = "renesas,pcie-r8a7790", "renesas,pcie-rcar-gen2";
-		reg = <0 0xfe000000 0 0x80000>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		bus-range = <0x00 0xff>;
-		device_type = "pci";
-		ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
-			  0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
-			  0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
-			  0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
-		/* Map all possible DDR as inbound ranges */
-		dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
-			      0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>;
-		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
-		clock-names = "pcie", "pcie_bus";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 319>;
-		status = "disabled";
-	};
-
-	rcar_sound: sound@ec500000 {
-		/*
-		 * #sound-dai-cells is required
-		 *
-		 * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
-		 * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
-		 */
-		compatible =  "renesas,rcar_sound-r8a7790", "renesas,rcar_sound-gen2";
-		reg =	<0 0xec500000 0 0x1000>, /* SCU */
-			<0 0xec5a0000 0 0x100>,  /* ADG */
-			<0 0xec540000 0 0x1000>, /* SSIU */
-			<0 0xec541000 0 0x280>,  /* SSI */
-			<0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
-		reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
-
-		clocks = <&cpg CPG_MOD 1005>,
-			 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
-			 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
-			 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
-			 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
-			 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
-			 <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
-			 <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
-			 <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
-			 <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
-			 <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
-			 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
-			 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
-			 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
-			 <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>,
-			 <&cpg CPG_CORE R8A7790_CLK_M2>;
-		clock-names = "ssi-all",
-				"ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
-				"ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0",
-				"src.9", "src.8", "src.7", "src.6", "src.5",
-				"src.4", "src.3", "src.2", "src.1", "src.0",
-				"ctu.0", "ctu.1",
-				"mix.0", "mix.1",
-				"dvc.0", "dvc.1",
-				"clk_a", "clk_b", "clk_c", "clk_i";
-		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-		resets = <&cpg 1005>,
-			 <&cpg 1006>, <&cpg 1007>, <&cpg 1008>, <&cpg 1009>,
-			 <&cpg 1010>, <&cpg 1011>, <&cpg 1012>, <&cpg 1013>,
-			 <&cpg 1014>, <&cpg 1015>;
-		reset-names = "ssi-all",
-			      "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
-			      "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0";
-
-		status = "disabled";
-
-		rcar_sound,dvc {
-			dvc0: dvc-0 {
-				dmas = <&audma1 0xbc>;
-				dma-names = "tx";
-			};
-			dvc1: dvc-1 {
-				dmas = <&audma1 0xbe>;
-				dma-names = "tx";
-			};
-		};
-
-		rcar_sound,mix {
-			mix0: mix-0 { };
-			mix1: mix-1 { };
-		};
-
-		rcar_sound,ctu {
-			ctu00: ctu-0 { };
-			ctu01: ctu-1 { };
-			ctu02: ctu-2 { };
-			ctu03: ctu-3 { };
-			ctu10: ctu-4 { };
-			ctu11: ctu-5 { };
-			ctu12: ctu-6 { };
-			ctu13: ctu-7 { };
-		};
-
-		rcar_sound,src {
-			src0: src-0 {
-				interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x85>, <&audma1 0x9a>;
-				dma-names = "rx", "tx";
-			};
-			src1: src-1 {
-				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x87>, <&audma1 0x9c>;
-				dma-names = "rx", "tx";
-			};
-			src2: src-2 {
-				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x89>, <&audma1 0x9e>;
-				dma-names = "rx", "tx";
-			};
-			src3: src-3 {
-				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8b>, <&audma1 0xa0>;
-				dma-names = "rx", "tx";
-			};
-			src4: src-4 {
-				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8d>, <&audma1 0xb0>;
-				dma-names = "rx", "tx";
-			};
-			src5: src-5 {
-				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8f>, <&audma1 0xb2>;
-				dma-names = "rx", "tx";
-			};
-			src6: src-6 {
-				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x91>, <&audma1 0xb4>;
-				dma-names = "rx", "tx";
-			};
-			src7: src-7 {
-				interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x93>, <&audma1 0xb6>;
-				dma-names = "rx", "tx";
-			};
-			src8: src-8 {
-				interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x95>, <&audma1 0xb8>;
-				dma-names = "rx", "tx";
-			};
-			src9: src-9 {
-				interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x97>, <&audma1 0xba>;
-				dma-names = "rx", "tx";
-			};
-		};
-
-		rcar_sound,ssi {
-			ssi0: ssi-0 {
-				interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi1: ssi-1 {
-				 interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi2: ssi-2 {
-				interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi3: ssi-3 {
-				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi4: ssi-4 {
-				interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi5: ssi-5 {
-				interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi6: ssi-6 {
-				interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi7: ssi-7 {
-				interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi8: ssi-8 {
-				interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi9: ssi-9 {
-				interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-		};
-	};
-
-	ipmmu_sy0: mmu@e6280000 {
-		compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6280000 0 0x1000>;
-		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_sy1: mmu@e6290000 {
-		compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6290000 0 0x1000>;
-		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_ds: mmu@e6740000 {
-		compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6740000 0 0x1000>;
-		interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_mp: mmu@ec680000 {
-		compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
-		reg = <0 0xec680000 0 0x1000>;
-		interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_mx: mmu@fe951000 {
-		compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
-		reg = <0 0xfe951000 0 0x1000>;
-		interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_rt: mmu@ffc80000 {
-		compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
-		reg = <0 0xffc80000 0 0x1000>;
-		interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
 };
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index a50924d..f40321a 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -51,7 +51,11 @@
 		serial0 = &scif0;
 		serial1 = &scif1;
 		i2c9 = &gpioi2c1;
+		i2c10 = &gpioi2c2;
+		i2c11 = &gpioi2c4;
 		i2c12 = &i2cexio1;
+		i2c13 = &i2chdmi;
+		i2c14 = &i2cexio4;
 	};
 
 	chosen {
@@ -312,8 +316,28 @@
 		#size-cells = <0>;
 		compatible = "i2c-gpio";
 		status = "disabled";
-		sda-gpios = <&gpio7 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		scl-gpios = <&gpio7 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio7 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		i2c-gpio,delay-us = <5>;
+	};
+
+	gpioi2c2: i2c-10 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		scl-gpios = <&gpio2 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio2 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		i2c-gpio,delay-us = <5>;
+	};
+
+	gpioi2c4: i2c-11 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		scl-gpios = <&gpio7 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio7 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <5>;
 	};
 
@@ -328,6 +352,115 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 	};
+
+	/*
+	 * A fallback to GPIO is provided for I2C2.
+	 */
+	i2chdmi: i2c-13 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&i2c2>, <&gpioi2c2>;
+		i2c-bus-name = "i2c-hdmi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ak4643: codec@12 {
+			compatible = "asahi-kasei,ak4643";
+			#sound-dai-cells = <0>;
+			reg = <0x12>;
+		};
+
+		composite-in@20 {
+			compatible = "adi,adv7180";
+			reg = <0x20>;
+			remote = <&vin1>;
+
+			port {
+				adv7180: endpoint {
+					bus-width = <8>;
+					remote-endpoint = <&vin1ep>;
+				};
+			};
+		};
+
+		hdmi@39 {
+			compatible = "adi,adv7511w";
+			reg = <0x39>;
+			interrupt-parent = <&gpio3>;
+			interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&cec_clock>;
+			clock-names = "cec";
+
+			adi,input-depth = <8>;
+			adi,input-colorspace = "rgb";
+			adi,input-clock = "1x";
+			adi,input-style = <1>;
+			adi,input-justification = "evenly";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7511_in: endpoint {
+						remote-endpoint = <&du_out_rgb>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					adv7511_out: endpoint {
+						remote-endpoint = <&hdmi_con_out>;
+					};
+				};
+			};
+		};
+
+		hdmi-in@4c {
+			compatible = "adi,adv7612";
+			reg = <0x4c>;
+			interrupt-parent = <&gpio4>;
+			interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+			default-input = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7612_in: endpoint {
+						remote-endpoint = <&hdmi_con_in>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					adv7612_out: endpoint {
+						remote-endpoint = <&vin0ep2>;
+					};
+				};
+			};
+		};
+
+		eeprom@50 {
+			compatible = "renesas,r1ex24002", "atmel,24c02";
+			reg = <0x50>;
+			pagesize = <16>;
+		};
+	};
+
+	/*
+	 * I2C4 is routed to EXIO connector E, pins 37 (SCL) + 39 (SDA).
+	 * A fallback to GPIO is provided.
+	 */
+	i2cexio4: i2c-14 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&i2c4>, <&gpioi2c4>;
+		i2c-bus-name = "i2c-exio4";
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
 };
 
 &du {
@@ -371,6 +504,11 @@
 		function = "i2c2";
 	};
 
+	i2c4_pins: i2c4 {
+		groups = "i2c4_c";
+		function = "i2c4";
+	};
+
 	du_pins: du {
 		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
 		function = "du";
@@ -621,96 +759,14 @@
 
 &i2c2 {
 	pinctrl-0 = <&i2c2_pins>;
-	pinctrl-names = "default";
+	pinctrl-names = "i2c-hdmi";
 
-	status = "okay";
 	clock-frequency = <100000>;
+};
 
-	ak4643: codec@12 {
-		compatible = "asahi-kasei,ak4643";
-		#sound-dai-cells = <0>;
-		reg = <0x12>;
-	};
-
-	composite-in@20 {
-		compatible = "adi,adv7180";
-		reg = <0x20>;
-		remote = <&vin1>;
-
-		port {
-			adv7180: endpoint {
-				bus-width = <8>;
-				remote-endpoint = <&vin1ep>;
-			};
-		};
-	};
-
-	hdmi@39 {
-		compatible = "adi,adv7511w";
-		reg = <0x39>;
-		interrupt-parent = <&gpio3>;
-		interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&cec_clock>;
-		clock-names = "cec";
-
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-		adi,input-style = <1>;
-		adi,input-justification = "evenly";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7511_in: endpoint {
-					remote-endpoint = <&du_out_rgb>;
-				};
-			};
-
-			port@1 {
-				reg = <1>;
-				adv7511_out: endpoint {
-					remote-endpoint = <&hdmi_con_out>;
-				};
-			};
-		};
-	};
-
-	hdmi-in@4c {
-		compatible = "adi,adv7612";
-		reg = <0x4c>;
-		interrupt-parent = <&gpio4>;
-		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
-		default-input = <0>;
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7612_in: endpoint {
-					remote-endpoint = <&hdmi_con_in>;
-				};
-			};
-
-			port@2 {
-				reg = <2>;
-				adv7612_out: endpoint {
-					remote-endpoint = <&vin0ep2>;
-				};
-			};
-		};
-	};
-
-	eeprom@50 {
-		compatible = "renesas,r1ex24002", "atmel,24c02";
-		reg = <0x50>;
-		pagesize = <16>;
-	};
+&i2c4 {
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-names = "i2c-exio4";
 };
 
 &i2c6 {
diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts
index eb37495..c14e6fe 100644
--- a/arch/arm/boot/dts/r8a7791-porter.dts
+++ b/arch/arm/boot/dts/r8a7791-porter.dts
@@ -29,6 +29,8 @@
 
 	aliases {
 		serial0 = &scif0;
+		i2c9 = &gpioi2c2;
+		i2c10 = &i2chdmi;
 	};
 
 	chosen {
@@ -135,6 +137,78 @@
 			clocks = <&x14_clk>;
 		};
 	};
+
+	gpioi2c2: i2c-9 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		scl-gpios = <&gpio2 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio2 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		i2c-gpio,delay-us = <5>;
+	};
+
+	/*
+	 * A fallback to GPIO is provided for I2C2.
+	 */
+	i2chdmi: i2c-10 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&i2c2>, <&gpioi2c2>;
+		i2c-bus-name = "i2c-hdmi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ak4642: codec@12 {
+			compatible = "asahi-kasei,ak4642";
+			#sound-dai-cells = <0>;
+			reg = <0x12>;
+		};
+
+		composite-in@20 {
+			compatible = "adi,adv7180";
+			reg = <0x20>;
+			remote = <&vin0>;
+
+			port {
+				adv7180: endpoint {
+					bus-width = <8>;
+					remote-endpoint = <&vin0ep>;
+				};
+			};
+		};
+
+		hdmi@39 {
+			compatible = "adi,adv7511w";
+			reg = <0x39>;
+			interrupt-parent = <&gpio3>;
+			interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+
+			adi,input-depth = <8>;
+			adi,input-colorspace = "rgb";
+			adi,input-clock = "1x";
+			adi,input-style = <1>;
+			adi,input-justification = "evenly";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7511_in: endpoint {
+						remote-endpoint = <&du_out_rgb>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					adv7511_out: endpoint {
+						remote-endpoint = <&hdmi_con>;
+					};
+				};
+			};
+		};
+	};
 };
 
 &extal_clk {
@@ -296,61 +370,9 @@
 
 &i2c2 {
 	pinctrl-0 = <&i2c2_pins>;
-	pinctrl-names = "default";
+	pinctrl-names = "i2c-hdmi";
 
-	status = "okay";
 	clock-frequency = <400000>;
-
-	ak4642: codec@12 {
-		compatible = "asahi-kasei,ak4642";
-		#sound-dai-cells = <0>;
-		reg = <0x12>;
-	};
-
-	composite-in@20 {
-		compatible = "adi,adv7180";
-		reg = <0x20>;
-		remote = <&vin0>;
-
-		port {
-			adv7180: endpoint {
-				bus-width = <8>;
-				remote-endpoint = <&vin0ep>;
-			};
-		};
-	};
-
-	hdmi@39 {
-		compatible = "adi,adv7511w";
-		reg = <0x39>;
-		interrupt-parent = <&gpio3>;
-		interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
-
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-		adi,input-style = <1>;
-		adi,input-justification = "evenly";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7511_in: endpoint {
-					remote-endpoint = <&du_out_rgb>;
-				};
-			};
-
-			port@1 {
-				reg = <1>;
-				adv7511_out: endpoint {
-					remote-endpoint = <&hdmi_con>;
-				};
-			};
-		};
-	};
 };
 
 &sata0 {
@@ -425,7 +447,7 @@
 		      "dclkin.0", "dclkin.1";
 
 	ports {
-		port@1 {
+		port@0 {
 			endpoint {
 				remote-endpoint = <&adv7511_in>;
 			};
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 008a260..f11dab7 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -17,7 +17,6 @@
 
 / {
 	compatible = "renesas,r8a7791";
-	interrupt-parent = <&gic>;
 	#address-cells = <2>;
 	#size-cells = <2>;
 
@@ -40,6 +39,35 @@
 		vin2 = &vin2;
 	};
 
+	/*
+	 * The external audio clocks are configured as 0 Hz fixed frequency
+	 * clocks by default.
+	 * Boards that provide audio clocks should override them.
+	 */
+	audio_clk_a: audio_clk_a {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+	audio_clk_b: audio_clk_b {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+	audio_clk_c: audio_clk_c {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External CAN clock */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board. */
+		clock-frequency = <0>;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -83,1087 +111,6 @@
 		};
 	};
 
-	thermal-zones {
-		cpu_thermal: cpu-thermal {
-			polling-delay-passive	= <0>;
-			polling-delay		= <0>;
-
-			thermal-sensors = <&thermal>;
-
-			trips {
-				cpu-crit {
-					temperature	= <95000>;
-					hysteresis	= <0>;
-					type		= "critical";
-				};
-			};
-			cooling-maps {
-			};
-		};
-	};
-
-	apmu@e6152000 {
-		compatible = "renesas,r8a7791-apmu", "renesas,apmu";
-		reg = <0 0xe6152000 0 0x188>;
-		cpus = <&cpu0 &cpu1>;
-	};
-
-	gic: interrupt-controller@f1001000 {
-		compatible = "arm,gic-400";
-		#interrupt-cells = <3>;
-		#address-cells = <0>;
-		interrupt-controller;
-		reg = <0 0xf1001000 0 0x1000>,
-			<0 0xf1002000 0 0x2000>,
-			<0 0xf1004000 0 0x2000>,
-			<0 0xf1006000 0 0x2000>;
-		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
-		clocks = <&cpg CPG_MOD 408>;
-		clock-names = "clk";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 408>;
-	};
-
-	gpio0: gpio@e6050000 {
-		compatible = "renesas,gpio-r8a7791", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6050000 0 0x50>;
-		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 0 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 912>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 912>;
-	};
-
-	gpio1: gpio@e6051000 {
-		compatible = "renesas,gpio-r8a7791", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6051000 0 0x50>;
-		interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 32 26>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 911>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 911>;
-	};
-
-	gpio2: gpio@e6052000 {
-		compatible = "renesas,gpio-r8a7791", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6052000 0 0x50>;
-		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 64 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 910>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 910>;
-	};
-
-	gpio3: gpio@e6053000 {
-		compatible = "renesas,gpio-r8a7791", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6053000 0 0x50>;
-		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 96 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 909>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 909>;
-	};
-
-	gpio4: gpio@e6054000 {
-		compatible = "renesas,gpio-r8a7791", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6054000 0 0x50>;
-		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 128 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 908>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 908>;
-	};
-
-	gpio5: gpio@e6055000 {
-		compatible = "renesas,gpio-r8a7791", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055000 0 0x50>;
-		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 160 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 907>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 907>;
-	};
-
-	gpio6: gpio@e6055400 {
-		compatible = "renesas,gpio-r8a7791", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055400 0 0x50>;
-		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 192 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 905>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 905>;
-	};
-
-	gpio7: gpio@e6055800 {
-		compatible = "renesas,gpio-r8a7791", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055800 0 0x50>;
-		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 224 26>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 904>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 904>;
-	};
-
-	thermal: thermal@e61f0000 {
-		compatible =	"renesas,thermal-r8a7791",
-				"renesas,rcar-gen2-thermal",
-				"renesas,rcar-thermal";
-		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
-		interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 522>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 522>;
-		#thermal-sensor-cells = <0>;
-	};
-
-	timer {
-		compatible = "arm,armv7-timer";
-		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
-	};
-
-	cmt0: timer@ffca0000 {
-		compatible = "renesas,r8a7791-cmt0", "renesas,rcar-gen2-cmt0";
-		reg = <0 0xffca0000 0 0x1004>;
-		interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 124>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 124>;
-
-		status = "disabled";
-	};
-
-	cmt1: timer@e6130000 {
-		compatible = "renesas,r8a7791-cmt1", "renesas,rcar-gen2-cmt1";
-		reg = <0 0xe6130000 0 0x1004>;
-		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 329>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 329>;
-
-		status = "disabled";
-	};
-
-	irqc0: interrupt-controller@e61c0000 {
-		compatible = "renesas,irqc-r8a7791", "renesas,irqc";
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		reg = <0 0xe61c0000 0 0x200>;
-		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 407>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 407>;
-	};
-
-	dmac0: dma-controller@e6700000 {
-		compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
-		reg = <0 0xe6700000 0 0x20000>;
-		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12", "ch13", "ch14";
-		clocks = <&cpg CPG_MOD 219>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 219>;
-		#dma-cells = <1>;
-		dma-channels = <15>;
-	};
-
-	dmac1: dma-controller@e6720000 {
-		compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
-		reg = <0 0xe6720000 0 0x20000>;
-		interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12", "ch13", "ch14";
-		clocks = <&cpg CPG_MOD 218>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 218>;
-		#dma-cells = <1>;
-		dma-channels = <15>;
-	};
-
-	audma0: dma-controller@ec700000 {
-		compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
-		reg = <0 0xec700000 0 0x10000>;
-		interrupts =	<GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12";
-		clocks = <&cpg CPG_MOD 502>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 502>;
-		#dma-cells = <1>;
-		dma-channels = <13>;
-	};
-
-	audma1: dma-controller@ec720000 {
-		compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
-		reg = <0 0xec720000 0 0x10000>;
-		interrupts =	<GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12";
-		clocks = <&cpg CPG_MOD 501>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 501>;
-		#dma-cells = <1>;
-		dma-channels = <13>;
-	};
-
-	usb_dmac0: dma-controller@e65a0000 {
-		compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac";
-		reg = <0 0xe65a0000 0 0x100>;
-		interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "ch0", "ch1";
-		clocks = <&cpg CPG_MOD 330>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 330>;
-		#dma-cells = <1>;
-		dma-channels = <2>;
-	};
-
-	usb_dmac1: dma-controller@e65b0000 {
-		compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac";
-		reg = <0 0xe65b0000 0 0x100>;
-		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "ch0", "ch1";
-		clocks = <&cpg CPG_MOD 331>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 331>;
-		#dma-cells = <1>;
-		dma-channels = <2>;
-	};
-
-	/* The memory map in the User's Manual maps the cores to bus numbers */
-	i2c0: i2c@e6508000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6508000 0 0x40>;
-		interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 931>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 931>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c1: i2c@e6518000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6518000 0 0x40>;
-		interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 930>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 930>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c2: i2c@e6530000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6530000 0 0x40>;
-		interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 929>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 929>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c3: i2c@e6540000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6540000 0 0x40>;
-		interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 928>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 928>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c4: i2c@e6520000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6520000 0 0x40>;
-		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 927>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 927>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c5: i2c@e6528000 {
-		/* doesn't need pinmux */
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6528000 0 0x40>;
-		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 925>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 925>;
-		i2c-scl-internal-delay-ns = <110>;
-		status = "disabled";
-	};
-
-	i2c6: i2c@e60b0000 {
-		/* doesn't need pinmux */
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7791", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe60b0000 0 0x425>;
-		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 926>;
-		dmas = <&dmac0 0x77>, <&dmac0 0x78>,
-		       <&dmac1 0x77>, <&dmac1 0x78>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 926>;
-		status = "disabled";
-	};
-
-	i2c7: i2c@e6500000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7791", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6500000 0 0x425>;
-		interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 318>;
-		dmas = <&dmac0 0x61>, <&dmac0 0x62>,
-		       <&dmac1 0x61>, <&dmac1 0x62>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 318>;
-		status = "disabled";
-	};
-
-	i2c8: i2c@e6510000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7791", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6510000 0 0x425>;
-		interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 323>;
-		dmas = <&dmac0 0x65>, <&dmac0 0x66>,
-		       <&dmac1 0x65>, <&dmac1 0x66>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 323>;
-		status = "disabled";
-	};
-
-	pfc: pin-controller@e6060000 {
-		compatible = "renesas,pfc-r8a7791";
-		reg = <0 0xe6060000 0 0x250>;
-	};
-
-	mmcif0: mmc@ee200000 {
-		compatible = "renesas,mmcif-r8a7791", "renesas,sh-mmcif";
-		reg = <0 0xee200000 0 0x80>;
-		interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 315>;
-		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
-		       <&dmac1 0xd1>, <&dmac1 0xd2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 315>;
-		reg-io-width = <4>;
-		status = "disabled";
-		max-frequency = <97500000>;
-	};
-
-	sdhi0: sd@ee100000 {
-		compatible = "renesas,sdhi-r8a7791",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee100000 0 0x328>;
-		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 314>;
-		dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
-		       <&dmac1 0xcd>, <&dmac1 0xce>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <195000000>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 314>;
-		status = "disabled";
-	};
-
-	sdhi1: sd@ee140000 {
-		compatible = "renesas,sdhi-r8a7791",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee140000 0 0x100>;
-		interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 312>;
-		dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
-		       <&dmac1 0xc1>, <&dmac1 0xc2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <97500000>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 312>;
-		status = "disabled";
-	};
-
-	sdhi2: sd@ee160000 {
-		compatible = "renesas,sdhi-r8a7791",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee160000 0 0x100>;
-		interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 311>;
-		dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
-		       <&dmac1 0xd3>, <&dmac1 0xd4>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <97500000>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 311>;
-		status = "disabled";
-	};
-
-	scifa0: serial@e6c40000 {
-		compatible = "renesas,scifa-r8a7791",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c40000 0 64>;
-		interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 204>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x21>, <&dmac0 0x22>,
-		       <&dmac1 0x21>, <&dmac1 0x22>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 204>;
-		status = "disabled";
-	};
-
-	scifa1: serial@e6c50000 {
-		compatible = "renesas,scifa-r8a7791",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c50000 0 64>;
-		interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 203>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x25>, <&dmac0 0x26>,
-		       <&dmac1 0x25>, <&dmac1 0x26>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 203>;
-		status = "disabled";
-	};
-
-	scifa2: serial@e6c60000 {
-		compatible = "renesas,scifa-r8a7791",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c60000 0 64>;
-		interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 202>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x27>, <&dmac0 0x28>,
-		       <&dmac1 0x27>, <&dmac1 0x28>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 202>;
-		status = "disabled";
-	};
-
-	scifa3: serial@e6c70000 {
-		compatible = "renesas,scifa-r8a7791",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c70000 0 64>;
-		interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1106>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
-		       <&dmac1 0x1b>, <&dmac1 0x1c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 1106>;
-		status = "disabled";
-	};
-
-	scifa4: serial@e6c78000 {
-		compatible = "renesas,scifa-r8a7791",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c78000 0 64>;
-		interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1107>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
-		       <&dmac1 0x1f>, <&dmac1 0x20>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 1107>;
-		status = "disabled";
-	};
-
-	scifa5: serial@e6c80000 {
-		compatible = "renesas,scifa-r8a7791",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c80000 0 64>;
-		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1108>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x23>, <&dmac0 0x24>,
-		       <&dmac1 0x23>, <&dmac1 0x24>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 1108>;
-		status = "disabled";
-	};
-
-	scifb0: serial@e6c20000 {
-		compatible = "renesas,scifb-r8a7791",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6c20000 0 0x100>;
-		interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 206>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
-		       <&dmac1 0x3d>, <&dmac1 0x3e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 206>;
-		status = "disabled";
-	};
-
-	scifb1: serial@e6c30000 {
-		compatible = "renesas,scifb-r8a7791",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6c30000 0 0x100>;
-		interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 207>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
-		       <&dmac1 0x19>, <&dmac1 0x1a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 207>;
-		status = "disabled";
-	};
-
-	scifb2: serial@e6ce0000 {
-		compatible = "renesas,scifb-r8a7791",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6ce0000 0 0x100>;
-		interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 216>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
-		       <&dmac1 0x1d>, <&dmac1 0x1e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 216>;
-		status = "disabled";
-	};
-
-	scif0: serial@e6e60000 {
-		compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e60000 0 64>;
-		interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 721>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
-		       <&dmac1 0x29>, <&dmac1 0x2a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 721>;
-		status = "disabled";
-	};
-
-	scif1: serial@e6e68000 {
-		compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e68000 0 64>;
-		interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 720>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
-		       <&dmac1 0x2d>, <&dmac1 0x2e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 720>;
-		status = "disabled";
-	};
-
-	adc: adc@e6e54000 {
-		compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc";
-		reg = <0 0xe6e54000 0 64>;
-		clocks = <&cpg CPG_MOD 901>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 901>;
-		status = "disabled";
-	};
-
-	scif2: serial@e6e58000 {
-		compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e58000 0 64>;
-		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 719>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
-		       <&dmac1 0x2b>, <&dmac1 0x2c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 719>;
-		status = "disabled";
-	};
-
-	scif3: serial@e6ea8000 {
-		compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ea8000 0 64>;
-		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 718>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
-		       <&dmac1 0x2f>, <&dmac1 0x30>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 718>;
-		status = "disabled";
-	};
-
-	scif4: serial@e6ee0000 {
-		compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ee0000 0 64>;
-		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 715>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
-		       <&dmac1 0xfb>, <&dmac1 0xfc>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 715>;
-		status = "disabled";
-	};
-
-	scif5: serial@e6ee8000 {
-		compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ee8000 0 64>;
-		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 714>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
-		       <&dmac1 0xfd>, <&dmac1 0xfe>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 714>;
-		status = "disabled";
-	};
-
-	hscif0: serial@e62c0000 {
-		compatible = "renesas,hscif-r8a7791",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62c0000 0 96>;
-		interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 717>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
-		       <&dmac1 0x39>, <&dmac1 0x3a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 717>;
-		status = "disabled";
-	};
-
-	hscif1: serial@e62c8000 {
-		compatible = "renesas,hscif-r8a7791",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62c8000 0 96>;
-		interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 716>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
-		       <&dmac1 0x4d>, <&dmac1 0x4e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 716>;
-		status = "disabled";
-	};
-
-	hscif2: serial@e62d0000 {
-		compatible = "renesas,hscif-r8a7791",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62d0000 0 96>;
-		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 713>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
-		       <&dmac1 0x3b>, <&dmac1 0x3c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 713>;
-		status = "disabled";
-	};
-
-	icram0:	sram@e63a0000 {
-		compatible = "mmio-sram";
-		reg = <0 0xe63a0000 0 0x12000>;
-	};
-
-	icram1:	sram@e63c0000 {
-		compatible = "mmio-sram";
-		reg = <0 0xe63c0000 0 0x1000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0 0xe63c0000 0x1000>;
-
-		smp-sram@0 {
-			compatible = "renesas,smp-sram";
-			reg = <0 0x10>;
-		};
-	};
-
-	ether: ethernet@ee700000 {
-		compatible = "renesas,ether-r8a7791",
-			     "renesas,rcar-gen2-ether";
-		reg = <0 0xee700000 0 0x400>;
-		interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 813>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 813>;
-		phy-mode = "rmii";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	avb: ethernet@e6800000 {
-		compatible = "renesas,etheravb-r8a7791",
-			     "renesas,etheravb-rcar-gen2";
-		reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
-		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 812>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 812>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	sata0: sata@ee300000 {
-		compatible = "renesas,sata-r8a7791", "renesas,rcar-gen2-sata";
-		reg = <0 0xee300000 0 0x2000>;
-		interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 815>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 815>;
-		status = "disabled";
-	};
-
-	sata1: sata@ee500000 {
-		compatible = "renesas,sata-r8a7791", "renesas,rcar-gen2-sata";
-		reg = <0 0xee500000 0 0x2000>;
-		interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 814>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 814>;
-		status = "disabled";
-	};
-
-	hsusb: usb@e6590000 {
-		compatible = "renesas,usbhs-r8a7791", "renesas,rcar-gen2-usbhs";
-		reg = <0 0xe6590000 0 0x100>;
-		interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 704>;
-		dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
-		       <&usb_dmac1 0>, <&usb_dmac1 1>;
-		dma-names = "ch0", "ch1", "ch2", "ch3";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 704>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
-		status = "disabled";
-	};
-
-	usbphy: usb-phy@e6590100 {
-		compatible = "renesas,usb-phy-r8a7791",
-			     "renesas,rcar-gen2-usb-phy";
-		reg = <0 0xe6590100 0 0x100>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&cpg CPG_MOD 704>;
-		clock-names = "usbhs";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 704>;
-		status = "disabled";
-
-		usb0: usb-channel@0 {
-			reg = <0>;
-			#phy-cells = <1>;
-		};
-		usb2: usb-channel@2 {
-			reg = <2>;
-			#phy-cells = <1>;
-		};
-	};
-
-	vin0: video@e6ef0000 {
-		compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef0000 0 0x1000>;
-		interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 811>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 811>;
-		status = "disabled";
-	};
-
-	vin1: video@e6ef1000 {
-		compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef1000 0 0x1000>;
-		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 810>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 810>;
-		status = "disabled";
-	};
-
-	vin2: video@e6ef2000 {
-		compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef2000 0 0x1000>;
-		interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 809>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 809>;
-		status = "disabled";
-	};
-
-	vsp@fe928000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe928000 0 0x8000>;
-		interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 131>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 131>;
-	};
-
-	vsp@fe930000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe930000 0 0x8000>;
-		interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 128>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 128>;
-	};
-
-	vsp@fe938000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe938000 0 0x8000>;
-		interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 127>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 127>;
-	};
-
-	du: display@feb00000 {
-		compatible = "renesas,du-r8a7791";
-		reg = <0 0xfeb00000 0 0x40000>,
-		      <0 0xfeb90000 0 0x1c>;
-		reg-names = "du", "lvds.0";
-		interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 724>,
-			 <&cpg CPG_MOD 723>,
-			 <&cpg CPG_MOD 726>;
-		clock-names = "du.0", "du.1", "lvds.0";
-		status = "disabled";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				du_out_rgb: endpoint {
-				};
-			};
-			port@1 {
-				reg = <1>;
-				du_out_lvds0: endpoint {
-				};
-			};
-		};
-	};
-
-	can0: can@e6e80000 {
-		compatible = "renesas,can-r8a7791", "renesas,rcar-gen2-can";
-		reg = <0 0xe6e80000 0 0x1000>;
-		interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 916>, <&cpg CPG_CORE R8A7791_CLK_RCAN>,
-			 <&can_clk>;
-		clock-names = "clkp1", "clkp2", "can_clk";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 916>;
-		status = "disabled";
-	};
-
-	can1: can@e6e88000 {
-		compatible = "renesas,can-r8a7791", "renesas,rcar-gen2-can";
-		reg = <0 0xe6e88000 0 0x1000>;
-		interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 915>, <&cpg CPG_CORE R8A7791_CLK_RCAN>,
-			 <&can_clk>;
-		clock-names = "clkp1", "clkp2", "can_clk";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 915>;
-		status = "disabled";
-	};
-
-	jpu: jpeg-codec@fe980000 {
-		compatible = "renesas,jpu-r8a7791", "renesas,rcar-gen2-jpu";
-		reg = <0 0xfe980000 0 0x10300>;
-		interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 106>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 106>;
-	};
-
 	/* External root clock */
 	extal_clk: extal {
 		compatible = "fixed-clock";
@@ -1172,27 +119,6 @@
 		clock-frequency = <0>;
 	};
 
-	/*
-	 * The external audio clocks are configured as 0 Hz fixed frequency
-	 * clocks by default.
-	 * Boards that provide audio clocks should override them.
-	 */
-	audio_clk_a: audio_clk_a {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-	audio_clk_b: audio_clk_b {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-	audio_clk_c: audio_clk_c {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
 	/* External PCIe clock - can be overridden by the board */
 	pcie_bus_clk: pcie_bus {
 		compatible = "fixed-clock";
@@ -1208,460 +134,1604 @@
 		clock-frequency = <0>;
 	};
 
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gpio0: gpio@e6050000 {
+			compatible = "renesas,gpio-r8a7791",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6050000 0 0x50>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 0 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 912>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 912>;
+		};
+
+		gpio1: gpio@e6051000 {
+			compatible = "renesas,gpio-r8a7791",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6051000 0 0x50>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 32 26>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 911>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 911>;
+		};
+
+		gpio2: gpio@e6052000 {
+			compatible = "renesas,gpio-r8a7791",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6052000 0 0x50>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 64 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 910>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 910>;
+		};
+
+		gpio3: gpio@e6053000 {
+			compatible = "renesas,gpio-r8a7791",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6053000 0 0x50>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 96 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 909>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 909>;
+		};
+
+		gpio4: gpio@e6054000 {
+			compatible = "renesas,gpio-r8a7791",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6054000 0 0x50>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 128 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 908>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 908>;
+		};
+
+		gpio5: gpio@e6055000 {
+			compatible = "renesas,gpio-r8a7791",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055000 0 0x50>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 160 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 907>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 907>;
+		};
+
+		gpio6: gpio@e6055400 {
+			compatible = "renesas,gpio-r8a7791",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055400 0 0x50>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 192 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 905>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 905>;
+		};
+
+		gpio7: gpio@e6055800 {
+			compatible = "renesas,gpio-r8a7791",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055800 0 0x50>;
+			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 224 26>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 904>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 904>;
+		};
+
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a7791";
+			reg = <0 0xe6060000 0 0x250>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7791-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&usb_extal_clk>;
+			clock-names = "extal", "usb_extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		apmu@e6152000 {
+			compatible = "renesas,r8a7791-apmu", "renesas,apmu";
+			reg = <0 0xe6152000 0 0x188>;
+			cpus = <&cpu0 &cpu1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7791-rst";
+			reg = <0 0xe6160000 0 0x0100>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7791-sysc";
+			reg = <0 0xe6180000 0 0x0200>;
+			#power-domain-cells = <1>;
+		};
+
+		irqc0: interrupt-controller@e61c0000 {
+			compatible = "renesas,irqc-r8a7791", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 407>;
+		};
+
+		thermal: thermal@e61f0000 {
+			compatible = "renesas,thermal-r8a7791",
+				     "renesas,rcar-gen2-thermal",
+				     "renesas,rcar-thermal";
+			reg = <0 0xe61f0000 0 0x10>, <0 0xe61f0100 0 0x38>;
+			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 522>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 522>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		ipmmu_sy0: mmu@e6280000 {
+			compatible = "renesas,ipmmu-r8a7791",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6280000 0 0x1000>;
+			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_sy1: mmu@e6290000 {
+			compatible = "renesas,ipmmu-r8a7791",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6290000 0 0x1000>;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_ds: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a7791",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6740000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_mp: mmu@ec680000 {
+			compatible = "renesas,ipmmu-r8a7791",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xec680000 0 0x1000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_mx: mmu@fe951000 {
+			compatible = "renesas,ipmmu-r8a7791",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xfe951000 0 0x1000>;
+			interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a7791",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xffc80000 0 0x1000>;
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_gp: mmu@e62a0000 {
+			compatible = "renesas,ipmmu-r8a7791",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe62a0000 0 0x1000>;
+			interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		icram0:	sram@e63a0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63a0000 0 0x12000>;
+		};
+
+		icram1:	sram@e63c0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63c0000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0xe63c0000 0x1000>;
+
+			smp-sram@0 {
+				compatible = "renesas,smp-sram";
+				reg = <0 0x10>;
+			};
+		};
+
+		/* The memory map in the User's Manual maps the cores to
+		 * bus numbers
+		 */
+		i2c0: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7791",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6518000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7791",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6518000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6530000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7791",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6530000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e6540000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7791",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6540000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e6520000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7791",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6520000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@e6528000 {
+			/* doesn't need pinmux */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7791",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6528000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 925>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 925>;
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c6: i2c@e60b0000 {
+			/* doesn't need pinmux */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7791",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe60b0000 0 0x425>;
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 926>;
+			dmas = <&dmac0 0x77>, <&dmac0 0x78>,
+			       <&dmac1 0x77>, <&dmac1 0x78>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 926>;
+			status = "disabled";
+		};
+
+		i2c7: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7791",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6500000 0 0x425>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>;
+			dmas = <&dmac0 0x61>, <&dmac0 0x62>,
+			       <&dmac1 0x61>, <&dmac1 0x62>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			status = "disabled";
+		};
+
+		i2c8: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7791",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6510000 0 0x425>;
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 323>;
+			dmas = <&dmac0 0x65>, <&dmac0 0x66>,
+			       <&dmac1 0x65>, <&dmac1 0x66>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 323>;
+			status = "disabled";
+		};
+
+		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a7791",
+				     "renesas,rcar-gen2-usbhs";
+			reg = <0 0xe6590000 0 0x100>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>;
+			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+			       <&usb_dmac1 0>, <&usb_dmac1 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			renesas,buswait = <4>;
+			phys = <&usb0 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		usbphy: usb-phy@e6590100 {
+			compatible = "renesas,usb-phy-r8a7791",
+				     "renesas,rcar-gen2-usb-phy";
+			reg = <0 0xe6590100 0 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cpg CPG_MOD 704>;
+			clock-names = "usbhs";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			status = "disabled";
+
+			usb0: usb-channel@0 {
+				reg = <0>;
+				#phy-cells = <1>;
+			};
+			usb2: usb-channel@2 {
+				reg = <2>;
+				#phy-cells = <1>;
+			};
+		};
+
+		usb_dmac0: dma-controller@e65a0000 {
+			compatible = "renesas,r8a7791-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65a0000 0 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 330>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 330>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb_dmac1: dma-controller@e65b0000 {
+			compatible = "renesas,r8a7791-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65b0000 0 0x100>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 331>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 331>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a7791",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x20000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 219>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		dmac1: dma-controller@e6720000 {
+			compatible = "renesas,dmac-r8a7791",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6720000 0 0x20000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a7791",
+				     "renesas,etheravb-rcar-gen2";
+			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		qspi: spi@e6b10000 {
+			compatible = "renesas,qspi-r8a7791", "renesas,qspi";
+			reg = <0 0xe6b10000 0 0x2c>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 917>;
+			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
+			       <&dmac1 0x17>, <&dmac1 0x18>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+			num-cs = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		scifa0: serial@e6c40000 {
+			compatible = "renesas,scifa-r8a7791",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x21>, <&dmac0 0x22>,
+			       <&dmac1 0x21>, <&dmac1 0x22>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scifa1: serial@e6c50000 {
+			compatible = "renesas,scifa-r8a7791",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x25>, <&dmac0 0x26>,
+			       <&dmac1 0x25>, <&dmac1 0x26>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		scifa2: serial@e6c60000 {
+			compatible = "renesas,scifa-r8a7791",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c60000 0 64>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x27>, <&dmac0 0x28>,
+			       <&dmac1 0x27>, <&dmac1 0x28>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 202>;
+			status = "disabled";
+		};
+
+		scifa3: serial@e6c70000 {
+			compatible = "renesas,scifa-r8a7791",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c70000 0 64>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1106>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
+			       <&dmac1 0x1b>, <&dmac1 0x1c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 1106>;
+			status = "disabled";
+		};
+
+		scifa4: serial@e6c78000 {
+			compatible = "renesas,scifa-r8a7791",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c78000 0 64>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1107>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
+			       <&dmac1 0x1f>, <&dmac1 0x20>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 1107>;
+			status = "disabled";
+		};
+
+		scifa5: serial@e6c80000 {
+			compatible = "renesas,scifa-r8a7791",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c80000 0 64>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1108>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x23>, <&dmac0 0x24>,
+			       <&dmac1 0x23>, <&dmac1 0x24>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 1108>;
+			status = "disabled";
+		};
+
+		scifb0: serial@e6c20000 {
+			compatible = "renesas,scifb-r8a7791",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c20000 0 0x100>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
+			       <&dmac1 0x3d>, <&dmac1 0x3e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 206>;
+			status = "disabled";
+		};
+
+		scifb1: serial@e6c30000 {
+			compatible = "renesas,scifb-r8a7791",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c30000 0 0x100>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
+			       <&dmac1 0x19>, <&dmac1 0x1a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 207>;
+			status = "disabled";
+		};
+
+		scifb2: serial@e6ce0000 {
+			compatible = "renesas,scifb-r8a7791",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6ce0000 0 0x100>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 216>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
+			       <&dmac1 0x1d>, <&dmac1 0x1e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 216>;
+			status = "disabled";
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a7791",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 721>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
+			       <&dmac1 0x29>, <&dmac1 0x2a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 721>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a7791",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e68000 0 64>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 720>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
+			       <&dmac1 0x2d>, <&dmac1 0x2e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 720>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e58000 {
+			compatible = "renesas,scif-r8a7791",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e58000 0 64>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 719>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
+			       <&dmac1 0x2b>, <&dmac1 0x2c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 719>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6ea8000 {
+			compatible = "renesas,scif-r8a7791",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ea8000 0 64>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 718>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
+			       <&dmac1 0x2f>, <&dmac1 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 718>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6ee0000 {
+			compatible = "renesas,scif-r8a7791",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee0000 0 64>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 715>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
+			       <&dmac1 0xfb>, <&dmac1 0xfc>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 715>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6ee8000 {
+			compatible = "renesas,scif-r8a7791",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee8000 0 64>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 714>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
+			       <&dmac1 0xfd>, <&dmac1 0xfe>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 714>;
+			status = "disabled";
+		};
+
+		hscif0: serial@e62c0000 {
+			compatible = "renesas,hscif-r8a7791",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c0000 0 96>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 717>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
+			       <&dmac1 0x39>, <&dmac1 0x3a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 717>;
+			status = "disabled";
+		};
+
+		hscif1: serial@e62c8000 {
+			compatible = "renesas,hscif-r8a7791",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c8000 0 96>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
+			       <&dmac1 0x4d>, <&dmac1 0x4e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 716>;
+			status = "disabled";
+		};
+
+		hscif2: serial@e62d0000 {
+			compatible = "renesas,hscif-r8a7791",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62d0000 0 96>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 713>, <&cpg CPG_CORE R8A7791_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
+			       <&dmac1 0x3b>, <&dmac1 0x3c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 713>;
+			status = "disabled";
+		};
+
+		msiof0: spi@e6e20000 {
+			compatible = "renesas,msiof-r8a7791",
+				     "renesas,rcar-gen2-msiof";
+			reg = <0 0xe6e20000 0 0x0064>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 000>;
+			dmas = <&dmac0 0x51>, <&dmac0 0x52>,
+			       <&dmac1 0x51>, <&dmac1 0x52>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof1: spi@e6e10000 {
+			compatible = "renesas,msiof-r8a7791",
+				     "renesas,rcar-gen2-msiof";
+			reg = <0 0xe6e10000 0 0x0064>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 208>;
+			dmas = <&dmac0 0x55>, <&dmac0 0x56>,
+			       <&dmac1 0x55>, <&dmac1 0x56>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 208>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		msiof2: spi@e6e00000 {
+			compatible = "renesas,msiof-r8a7791",
+				     "renesas,rcar-gen2-msiof";
+			reg = <0 0xe6e00000 0 0x0064>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 205>;
+			dmas = <&dmac0 0x41>, <&dmac0 0x42>,
+			       <&dmac1 0x41>, <&dmac1 0x42>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 205>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		adc: adc@e6e54000 {
+			compatible = "renesas,r8a7791-gyroadc",
+				     "renesas,rcar-gyroadc";
+			reg = <0 0xe6e54000 0 64>;
+			clocks = <&cpg CPG_MOD 901>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 901>;
+			status = "disabled";
+		};
+
+		can0: can@e6e80000 {
+			compatible = "renesas,can-r8a7791",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e80000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>,
+				 <&cpg CPG_CORE R8A7791_CLK_RCAN>, <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+			status = "disabled";
+		};
+
+		can1: can@e6e88000 {
+			compatible = "renesas,can-r8a7791",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e88000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>,
+				 <&cpg CPG_CORE R8A7791_CLK_RCAN>, <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 915>;
+			status = "disabled";
+		};
+
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a7791",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 811>;
+			status = "disabled";
+		};
+
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a7791",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 810>;
+			status = "disabled";
+		};
+
+		vin2: video@e6ef2000 {
+			compatible = "renesas,vin-r8a7791",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef2000 0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 809>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 809>;
+			status = "disabled";
+		};
+
+		rcar_sound: sound@ec500000 {
+			/*
+			 * #sound-dai-cells is required
+			 *
+			 * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
+			 * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
+			 */
+			compatible = "renesas,rcar_sound-r8a7791",
+				     "renesas,rcar_sound-gen2";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
+			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+			clocks = <&cpg CPG_MOD 1005>,
+				 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+				 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+				 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+				 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+				 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+				 <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+				 <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+				 <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+				 <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+				 <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+				 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
+				 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
+				 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+				 <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>,
+				 <&cpg CPG_CORE R8A7791_CLK_M2>;
+			clock-names = "ssi-all",
+				      "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+				      "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+				      "ssi.1", "ssi.0", "src.9", "src.8",
+				      "src.7", "src.6", "src.5", "src.4",
+				      "src.3", "src.2", "src.1", "src.0",
+				      "ctu.0", "ctu.1",
+				      "mix.0", "mix.1",
+				      "dvc.0", "dvc.1",
+				      "clk_a", "clk_b", "clk_c", "clk_i";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 1005>,
+				 <&cpg 1006>, <&cpg 1007>,
+				 <&cpg 1008>, <&cpg 1009>,
+				 <&cpg 1010>, <&cpg 1011>,
+				 <&cpg 1012>, <&cpg 1013>,
+				 <&cpg 1014>, <&cpg 1015>;
+			reset-names = "ssi-all",
+				      "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+				      "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+				      "ssi.1", "ssi.0";
+
+			status = "disabled";
+
+			rcar_sound,dvc {
+				dvc0: dvc-0 {
+					dmas = <&audma1 0xbc>;
+					dma-names = "tx";
+				};
+				dvc1: dvc-1 {
+					dmas = <&audma1 0xbe>;
+					dma-names = "tx";
+				};
+			};
+
+			rcar_sound,mix {
+				mix0: mix-0 { };
+				mix1: mix-1 { };
+			};
+
+			rcar_sound,ctu {
+				ctu00: ctu-0 { };
+				ctu01: ctu-1 { };
+				ctu02: ctu-2 { };
+				ctu03: ctu-3 { };
+				ctu10: ctu-4 { };
+				ctu11: ctu-5 { };
+				ctu12: ctu-6 { };
+				ctu13: ctu-7 { };
+			};
+
+			rcar_sound,src {
+				src0: src-0 {
+					interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x85>, <&audma1 0x9a>;
+					dma-names = "rx", "tx";
+				};
+				src1: src-1 {
+					interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x87>, <&audma1 0x9c>;
+					dma-names = "rx", "tx";
+				};
+				src2: src-2 {
+					interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x89>, <&audma1 0x9e>;
+					dma-names = "rx", "tx";
+				};
+				src3: src-3 {
+					interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+					dma-names = "rx", "tx";
+				};
+				src4: src-4 {
+					interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+					dma-names = "rx", "tx";
+				};
+				src5: src-5 {
+					interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+					dma-names = "rx", "tx";
+				};
+				src6: src-6 {
+					interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x91>, <&audma1 0xb4>;
+					dma-names = "rx", "tx";
+				};
+				src7: src-7 {
+					interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x93>, <&audma1 0xb6>;
+					dma-names = "rx", "tx";
+				};
+				src8: src-8 {
+					interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x95>, <&audma1 0xb8>;
+					dma-names = "rx", "tx";
+				};
+				src9: src-9 {
+					interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x97>, <&audma1 0xba>;
+					dma-names = "rx", "tx";
+				};
+			};
+
+			rcar_sound,ssi {
+				ssi0: ssi-0 {
+					interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x01>, <&audma1 0x02>,
+					       <&audma0 0x15>, <&audma1 0x16>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi1: ssi-1 {
+					 interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x03>, <&audma1 0x04>,
+					       <&audma0 0x49>, <&audma1 0x4a>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi2: ssi-2 {
+					interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x05>, <&audma1 0x06>,
+					       <&audma0 0x63>, <&audma1 0x64>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi3: ssi-3 {
+					interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x07>, <&audma1 0x08>,
+					       <&audma0 0x6f>, <&audma1 0x70>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi4: ssi-4 {
+					interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x09>, <&audma1 0x0a>,
+					       <&audma0 0x71>, <&audma1 0x72>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi5: ssi-5 {
+					interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0b>, <&audma1 0x0c>,
+					       <&audma0 0x73>, <&audma1 0x74>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi6: ssi-6 {
+					interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0d>, <&audma1 0x0e>,
+					       <&audma0 0x75>, <&audma1 0x76>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi7: ssi-7 {
+					interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0f>, <&audma1 0x10>,
+					       <&audma0 0x79>, <&audma1 0x7a>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi8: ssi-8 {
+					interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x11>, <&audma1 0x12>,
+					       <&audma0 0x7b>, <&audma1 0x7c>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi9: ssi-9 {
+					interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x13>, <&audma1 0x14>,
+					       <&audma0 0x7d>, <&audma1 0x7e>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+			};
+		};
+
+		audma0: dma-controller@ec700000 {
+			compatible = "renesas,dmac-r8a7791",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec700000 0 0x10000>;
+			interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 502>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 502>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		audma1: dma-controller@ec720000 {
+			compatible = "renesas,dmac-r8a7791",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec720000 0 0x10000>;
+			interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 501>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 501>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		xhci: usb@ee000000 {
+			compatible = "renesas,xhci-r8a7791",
+				     "renesas,rcar-gen2-xhci";
+			reg = <0 0xee000000 0 0xc00>;
+			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			phys = <&usb2 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		pci0: pci@ee090000 {
+			compatible = "renesas,pci-r8a7791",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee090000 0 0xc00>,
+			      <0 0xee080000 0 0x1100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x800 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x1000 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
+			};
+		};
+
+		pci1: pci@ee0d0000 {
+			compatible = "renesas,pci-r8a7791",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee0d0000 0 0xc00>,
+			      <0 0xee0c0000 0 0x1100>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <1 1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x10800 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x11000 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+		};
+
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7791",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee100000 0 0x328>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
+			       <&dmac1 0xcd>, <&dmac1 0xce>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <195000000>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		sdhi1: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a7791",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee140000 0 0x100>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
+			       <&dmac1 0xc1>, <&dmac1 0xc2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi2: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a7791",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee160000 0 0x100>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
+			       <&dmac1 0xd3>, <&dmac1 0xd4>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		mmcif0: mmc@ee200000 {
+			compatible = "renesas,mmcif-r8a7791",
+				     "renesas,sh-mmcif";
+			reg = <0 0xee200000 0 0x80>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 315>;
+			dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
+			       <&dmac1 0xd1>, <&dmac1 0xd2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 315>;
+			reg-io-width = <4>;
+			status = "disabled";
+			max-frequency = <97500000>;
+		};
+
+		sata0: sata@ee300000 {
+			compatible = "renesas,sata-r8a7791",
+				     "renesas,rcar-gen2-sata";
+			reg = <0 0xee300000 0 0x2000>;
+			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 815>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 815>;
+			status = "disabled";
+		};
+
+		sata1: sata@ee500000 {
+			compatible = "renesas,sata-r8a7791",
+				     "renesas,rcar-gen2-sata";
+			reg = <0 0xee500000 0 0x2000>;
+			interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 814>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 814>;
+			status = "disabled";
+		};
+
+		ether: ethernet@ee700000 {
+			compatible = "renesas,ether-r8a7791",
+				     "renesas,rcar-gen2-ether";
+			reg = <0 0xee700000 0 0x400>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 813>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 813>;
+			phy-mode = "rmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>, <0 0xf1002000 0 0x2000>,
+			      <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
+		pciec: pcie@fe000000 {
+			compatible = "renesas,pcie-r8a7791",
+				     "renesas,pcie-rcar-gen2";
+			reg = <0 0xfe000000 0 0x80000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+				  0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+				  0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+				  0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
+				      0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 319>;
+			status = "disabled";
+		};
+
+		vsp@fe928000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe928000 0 0x8000>;
+			interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 131>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 131>;
+		};
+
+		vsp@fe930000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe930000 0 0x8000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 128>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 128>;
+		};
+
+		vsp@fe938000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe938000 0 0x8000>;
+			interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 127>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 127>;
+		};
+
+		jpu: jpeg-codec@fe980000 {
+			compatible = "renesas,jpu-r8a7791",
+				     "renesas,rcar-gen2-jpu";
+			reg = <0 0xfe980000 0 0x10300>;
+			interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 106>;
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 106>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a7791";
+			reg = <0 0xfeb00000 0 0x40000>,
+			      <0 0xfeb90000 0 0x1c>;
+			reg-names = "du", "lvds.0";
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>,
+				 <&cpg CPG_MOD 723>,
+				 <&cpg CPG_MOD 726>;
+			clock-names = "du.0", "du.1", "lvds.0";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+				port@1 {
+					reg = <1>;
+					du_out_lvds0: endpoint {
+					};
+				};
+			};
+		};
+
+		prr: chipid@ff000044 {
+			compatible = "renesas,prr";
+			reg = <0 0xff000044 0 4>;
+		};
+
+		cmt0: timer@ffca0000 {
+			compatible = "renesas,r8a7791-cmt0",
+				     "renesas,rcar-gen2-cmt0";
+			reg = <0 0xffca0000 0 0x1004>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 124>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 124>;
+
+			status = "disabled";
+		};
+
+		cmt1: timer@e6130000 {
+			compatible = "renesas,r8a7791-cmt1",
+				     "renesas,rcar-gen2-cmt1";
+			reg = <0 0xe6130000 0 0x1004>;
+			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 329>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+			resets = <&cpg 329>;
+
+			status = "disabled";
+		};
+	};
+
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&thermal>;
+
+			trips {
+				cpu-crit {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+			cooling-maps {
+			};
+		};
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
 	/* External USB clock - can be overridden by the board */
 	usb_extal_clk: usb_extal {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <48000000>;
 	};
-
-	/* External CAN clock */
-	can_clk: can {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		/* This value must be overridden by the board. */
-		clock-frequency = <0>;
-	};
-
-	cpg: clock-controller@e6150000 {
-		compatible = "renesas,r8a7791-cpg-mssr";
-		reg = <0 0xe6150000 0 0x1000>;
-		clocks = <&extal_clk>, <&usb_extal_clk>;
-		clock-names = "extal", "usb_extal";
-		#clock-cells = <2>;
-		#power-domain-cells = <0>;
-		#reset-cells = <1>;
-	};
-
-	rst: reset-controller@e6160000 {
-		compatible = "renesas,r8a7791-rst";
-		reg = <0 0xe6160000 0 0x0100>;
-	};
-
-	prr: chipid@ff000044 {
-		compatible = "renesas,prr";
-		reg = <0 0xff000044 0 4>;
-	};
-
-	sysc: system-controller@e6180000 {
-		compatible = "renesas,r8a7791-sysc";
-		reg = <0 0xe6180000 0 0x0200>;
-		#power-domain-cells = <1>;
-	};
-
-	qspi: spi@e6b10000 {
-		compatible = "renesas,qspi-r8a7791", "renesas,qspi";
-		reg = <0 0xe6b10000 0 0x2c>;
-		interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 917>;
-		dmas = <&dmac0 0x17>, <&dmac0 0x18>,
-		       <&dmac1 0x17>, <&dmac1 0x18>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 917>;
-		num-cs = <1>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	msiof0: spi@e6e20000 {
-		compatible = "renesas,msiof-r8a7791",
-			     "renesas,rcar-gen2-msiof";
-		reg = <0 0xe6e20000 0 0x0064>;
-		interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 000>;
-		dmas = <&dmac0 0x51>, <&dmac0 0x52>,
-		       <&dmac1 0x51>, <&dmac1 0x52>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 0>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	msiof1: spi@e6e10000 {
-		compatible = "renesas,msiof-r8a7791",
-			     "renesas,rcar-gen2-msiof";
-		reg = <0 0xe6e10000 0 0x0064>;
-		interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 208>;
-		dmas = <&dmac0 0x55>, <&dmac0 0x56>,
-		       <&dmac1 0x55>, <&dmac1 0x56>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 208>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	msiof2: spi@e6e00000 {
-		compatible = "renesas,msiof-r8a7791",
-			     "renesas,rcar-gen2-msiof";
-		reg = <0 0xe6e00000 0 0x0064>;
-		interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 205>;
-		dmas = <&dmac0 0x41>, <&dmac0 0x42>,
-		       <&dmac1 0x41>, <&dmac1 0x42>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 205>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	xhci: usb@ee000000 {
-		compatible = "renesas,xhci-r8a7791", "renesas,rcar-gen2-xhci";
-		reg = <0 0xee000000 0 0xc00>;
-		interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 328>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 328>;
-		phys = <&usb2 1>;
-		phy-names = "usb";
-		status = "disabled";
-	};
-
-	pci0: pci@ee090000 {
-		compatible = "renesas,pci-r8a7791", "renesas,pci-rcar-gen2";
-		device_type = "pci";
-		reg = <0 0xee090000 0 0xc00>,
-		      <0 0xee080000 0 0x1100>;
-		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 703>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 703>;
-		status = "disabled";
-
-		bus-range = <0 0>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		#interrupt-cells = <1>;
-		ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-		interrupt-map-mask = <0xff00 0 0 0x7>;
-		interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-				 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-				 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-
-		usb@1,0 {
-			reg = <0x800 0 0 0 0>;
-			phys = <&usb0 0>;
-			phy-names = "usb";
-		};
-
-		usb@2,0 {
-			reg = <0x1000 0 0 0 0>;
-			phys = <&usb0 0>;
-			phy-names = "usb";
-		};
-	};
-
-	pci1: pci@ee0d0000 {
-		compatible = "renesas,pci-r8a7791", "renesas,pci-rcar-gen2";
-		device_type = "pci";
-		reg = <0 0xee0d0000 0 0xc00>,
-		      <0 0xee0c0000 0 0x1100>;
-		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 703>;
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 703>;
-		status = "disabled";
-
-		bus-range = <1 1>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		#interrupt-cells = <1>;
-		ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-		interrupt-map-mask = <0xff00 0 0 0x7>;
-		interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-				 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-				 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-
-		usb@1,0 {
-			reg = <0x10800 0 0 0 0>;
-			phys = <&usb2 0>;
-			phy-names = "usb";
-		};
-
-		usb@2,0 {
-			reg = <0x11000 0 0 0 0>;
-			phys = <&usb2 0>;
-			phy-names = "usb";
-		};
-	};
-
-	pciec: pcie@fe000000 {
-		compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2";
-		reg = <0 0xfe000000 0 0x80000>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		bus-range = <0x00 0xff>;
-		device_type = "pci";
-		ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
-			  0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
-			  0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
-			  0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
-		/* Map all possible DDR as inbound ranges */
-		dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
-			      0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
-		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
-		clock-names = "pcie", "pcie_bus";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 319>;
-		status = "disabled";
-	};
-
-	ipmmu_sy0: mmu@e6280000 {
-		compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6280000 0 0x1000>;
-		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_sy1: mmu@e6290000 {
-		compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6290000 0 0x1000>;
-		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_ds: mmu@e6740000 {
-		compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6740000 0 0x1000>;
-		interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_mp: mmu@ec680000 {
-		compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
-		reg = <0 0xec680000 0 0x1000>;
-		interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_mx: mmu@fe951000 {
-		compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
-		reg = <0 0xfe951000 0 0x1000>;
-		interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_rt: mmu@ffc80000 {
-		compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
-		reg = <0 0xffc80000 0 0x1000>;
-		interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	ipmmu_gp: mmu@e62a0000 {
-		compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
-		reg = <0 0xe62a0000 0 0x1000>;
-		interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
-
-	rcar_sound: sound@ec500000 {
-		/*
-		 * #sound-dai-cells is required
-		 *
-		 * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
-		 * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
-		 */
-		compatible =  "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2";
-		reg =	<0 0xec500000 0 0x1000>, /* SCU */
-			<0 0xec5a0000 0 0x100>,  /* ADG */
-			<0 0xec540000 0 0x1000>, /* SSIU */
-			<0 0xec541000 0 0x280>,  /* SSI */
-			<0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
-		reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
-
-		clocks = <&cpg CPG_MOD 1005>,
-			 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
-			 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
-			 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
-			 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
-			 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
-			 <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
-			 <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
-			 <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
-			 <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
-			 <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
-			 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
-			 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
-			 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
-			 <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>,
-			 <&cpg CPG_CORE R8A7791_CLK_M2>;
-		clock-names = "ssi-all",
-				"ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
-				"ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0",
-				"src.9", "src.8", "src.7", "src.6", "src.5",
-				"src.4", "src.3", "src.2", "src.1", "src.0",
-				"ctu.0", "ctu.1",
-				"mix.0", "mix.1",
-				"dvc.0", "dvc.1",
-				"clk_a", "clk_b", "clk_c", "clk_i";
-		power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
-		resets = <&cpg 1005>,
-			 <&cpg 1006>, <&cpg 1007>, <&cpg 1008>, <&cpg 1009>,
-			 <&cpg 1010>, <&cpg 1011>, <&cpg 1012>, <&cpg 1013>,
-			 <&cpg 1014>, <&cpg 1015>;
-		reset-names = "ssi-all",
-			      "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
-			      "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0";
-
-		status = "disabled";
-
-		rcar_sound,dvc {
-			dvc0: dvc-0 {
-				dmas = <&audma1 0xbc>;
-				dma-names = "tx";
-			};
-			dvc1: dvc-1 {
-				dmas = <&audma1 0xbe>;
-				dma-names = "tx";
-			};
-		};
-
-		rcar_sound,mix {
-			mix0: mix-0 { };
-			mix1: mix-1 { };
-		};
-
-		rcar_sound,ctu {
-			ctu00: ctu-0 { };
-			ctu01: ctu-1 { };
-			ctu02: ctu-2 { };
-			ctu03: ctu-3 { };
-			ctu10: ctu-4 { };
-			ctu11: ctu-5 { };
-			ctu12: ctu-6 { };
-			ctu13: ctu-7 { };
-		};
-
-		rcar_sound,src {
-			src0: src-0 {
-				interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x85>, <&audma1 0x9a>;
-				dma-names = "rx", "tx";
-			};
-			src1: src-1 {
-				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x87>, <&audma1 0x9c>;
-				dma-names = "rx", "tx";
-			};
-			src2: src-2 {
-				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x89>, <&audma1 0x9e>;
-				dma-names = "rx", "tx";
-			};
-			src3: src-3 {
-				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8b>, <&audma1 0xa0>;
-				dma-names = "rx", "tx";
-			};
-			src4: src-4 {
-				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8d>, <&audma1 0xb0>;
-				dma-names = "rx", "tx";
-			};
-			src5: src-5 {
-				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8f>, <&audma1 0xb2>;
-				dma-names = "rx", "tx";
-			};
-			src6: src-6 {
-				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x91>, <&audma1 0xb4>;
-				dma-names = "rx", "tx";
-			};
-			src7: src-7 {
-				interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x93>, <&audma1 0xb6>;
-				dma-names = "rx", "tx";
-			};
-			src8: src-8 {
-				interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x95>, <&audma1 0xb8>;
-				dma-names = "rx", "tx";
-			};
-			src9: src-9 {
-				interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x97>, <&audma1 0xba>;
-				dma-names = "rx", "tx";
-			};
-		};
-
-		rcar_sound,ssi {
-			ssi0: ssi-0 {
-				interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi1: ssi-1 {
-				 interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi2: ssi-2 {
-				interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi3: ssi-3 {
-				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi4: ssi-4 {
-				interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi5: ssi-5 {
-				interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi6: ssi-6 {
-				interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi7: ssi-7 {
-				interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi8: ssi-8 {
-				interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi9: ssi-9 {
-				interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-		};
-	};
 };
diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi
index 3be15a1..268987f 100644
--- a/arch/arm/boot/dts/r8a7792.dtsi
+++ b/arch/arm/boot/dts/r8a7792.dtsi
@@ -101,63 +101,6 @@
 		#size-cells = <2>;
 		ranges;
 
-		apmu@e6152000 {
-			compatible = "renesas,r8a7792-apmu", "renesas,apmu";
-			reg = <0 0xe6152000 0 0x188>;
-			cpus = <&cpu0 &cpu1>;
-		};
-
-		gic: interrupt-controller@f1001000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			interrupt-controller;
-			reg = <0 0xf1001000 0 0x1000>,
-			      <0 0xf1002000 0 0x2000>,
-			      <0 0xf1004000 0 0x2000>,
-			      <0 0xf1006000 0 0x2000>;
-			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
-				      IRQ_TYPE_LEVEL_HIGH)>;
-			clocks = <&cpg CPG_MOD 408>;
-			clock-names = "clk";
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 408>;
-		};
-
-		irqc: interrupt-controller@e61c0000 {
-			compatible = "renesas,irqc-r8a7792", "renesas,irqc";
-			#interrupt-cells = <2>;
-			interrupt-controller;
-			reg = <0 0xe61c0000 0 0x200>;
-			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 407>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 407>;
-		};
-
-		rst: reset-controller@e6160000 {
-			compatible = "renesas,r8a7792-rst";
-			reg = <0 0xe6160000 0 0x0100>;
-		};
-
-		prr: chipid@ff000044 {
-			compatible = "renesas,prr";
-			reg = <0 0xff000044 0 4>;
-		};
-
-		sysc: system-controller@e6180000 {
-			compatible = "renesas,r8a7792-sysc";
-			reg = <0 0xe6180000 0 0x0200>;
-			#power-domain-cells = <1>;
-		};
-
-		pfc: pin-controller@e6060000 {
-			compatible = "renesas,pfc-r8a7792";
-			reg = <0 0xe6060000 0 0x144>;
-		};
-
 		gpio0: gpio@e6050000 {
 			compatible = "renesas,gpio-r8a7792",
 				     "renesas,rcar-gen2-gpio";
@@ -338,6 +281,155 @@
 			resets = <&cpg 913>;
 		};
 
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a7792";
+			reg = <0 0xe6060000 0 0x144>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7792-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>;
+			clock-names = "extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		apmu@e6152000 {
+			compatible = "renesas,r8a7792-apmu", "renesas,apmu";
+			reg = <0 0xe6152000 0 0x188>;
+			cpus = <&cpu0 &cpu1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7792-rst";
+			reg = <0 0xe6160000 0 0x0100>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7792-sysc";
+			reg = <0 0xe6180000 0 0x0200>;
+			#power-domain-cells = <1>;
+		};
+
+		irqc: interrupt-controller@e61c0000 {
+			compatible = "renesas,irqc-r8a7792", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 407>;
+		};
+
+		icram0:	sram@e63a0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63a0000 0 0x12000>;
+		};
+
+		icram1:	sram@e63c0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63c0000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0xe63c0000 0x1000>;
+
+			smp-sram@0 {
+				compatible = "renesas,smp-sram";
+				reg = <0 0x10>;
+			};
+		};
+
+		/* I2C doesn't need pinmux */
+		i2c0: i2c@e6508000 {
+			compatible = "renesas,i2c-r8a7792",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6518000 {
+			compatible = "renesas,i2c-r8a7792",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6518000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6530000 {
+			compatible = "renesas,i2c-r8a7792",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6530000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e6540000 {
+			compatible = "renesas,i2c-r8a7792",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6540000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e6520000 {
+			compatible = "renesas,i2c-r8a7792",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6520000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@e6528000 {
+			compatible = "renesas,i2c-r8a7792",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6528000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 925>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 925>;
+			i2c-scl-internal-delay-ns = <110>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		dmac0: dma-controller@e6700000 {
 			compatible = "renesas,dmac-r8a7792",
 				     "renesas,rcar-dmac";
@@ -404,6 +496,35 @@
 			dma-channels = <15>;
 		};
 
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a7792",
+				     "renesas,etheravb-rcar-gen2";
+			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		qspi: spi@e6b10000 {
+			compatible = "renesas,qspi-r8a7792", "renesas,qspi";
+			reg = <0 0xe6b10000 0 0x2c>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 917>;
+			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
+			       <&dmac1 0x17>, <&dmac1 0x18>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+			num-cs = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		scif0: serial@e6e60000 {
 			compatible = "renesas,scif-r8a7792",
 				     "renesas,rcar-gen2-scif", "renesas,scif";
@@ -500,162 +621,6 @@
 			status = "disabled";
 		};
 
-		icram0:	sram@e63a0000 {
-			compatible = "mmio-sram";
-			reg = <0 0xe63a0000 0 0x12000>;
-		};
-
-		icram1:	sram@e63c0000 {
-			compatible = "mmio-sram";
-			reg = <0 0xe63c0000 0 0x1000>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges = <0 0 0xe63c0000 0x1000>;
-
-			smp-sram@0 {
-				compatible = "renesas,smp-sram";
-				reg = <0 0x10>;
-			};
-		};
-
-		sdhi0: sd@ee100000 {
-			compatible = "renesas,sdhi-r8a7792",
-				     "renesas,rcar-gen2-sdhi";
-			reg = <0 0xee100000 0 0x328>;
-			interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
-			       <&dmac1 0xcd>, <&dmac1 0xce>;
-			dma-names = "tx", "rx", "tx", "rx";
-			clocks = <&cpg CPG_MOD 314>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 314>;
-			status = "disabled";
-		};
-
-		jpu: jpeg-codec@fe980000 {
-			compatible = "renesas,jpu-r8a7792",
-				     "renesas,rcar-gen2-jpu";
-			reg = <0 0xfe980000 0 0x10300>;
-			interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 106>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 106>;
-		};
-
-		avb: ethernet@e6800000 {
-			compatible = "renesas,etheravb-r8a7792",
-				     "renesas,etheravb-rcar-gen2";
-			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
-			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 812>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 812>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		/* I2C doesn't need pinmux */
-		i2c0: i2c@e6508000 {
-			compatible = "renesas,i2c-r8a7792",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6508000 0 0x40>;
-			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 931>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 931>;
-			i2c-scl-internal-delay-ns = <6>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		i2c1: i2c@e6518000 {
-			compatible = "renesas,i2c-r8a7792",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6518000 0 0x40>;
-			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 930>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 930>;
-			i2c-scl-internal-delay-ns = <6>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		i2c2: i2c@e6530000 {
-			compatible = "renesas,i2c-r8a7792",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6530000 0 0x40>;
-			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 929>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 929>;
-			i2c-scl-internal-delay-ns = <6>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		i2c3: i2c@e6540000 {
-			compatible = "renesas,i2c-r8a7792",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6540000 0 0x40>;
-			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 928>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 928>;
-			i2c-scl-internal-delay-ns = <6>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		i2c4: i2c@e6520000 {
-			compatible = "renesas,i2c-r8a7792",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6520000 0 0x40>;
-			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 927>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 927>;
-			i2c-scl-internal-delay-ns = <6>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		i2c5: i2c@e6528000 {
-			compatible = "renesas,i2c-r8a7792",
-				     "renesas,rcar-gen2-i2c";
-			reg = <0 0xe6528000 0 0x40>;
-			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 925>;
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 925>;
-			i2c-scl-internal-delay-ns = <110>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
-		qspi: spi@e6b10000 {
-			compatible = "renesas,qspi-r8a7792", "renesas,qspi";
-			reg = <0 0xe6b10000 0 0x2c>;
-			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 917>;
-			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
-			       <&dmac1 0x17>, <&dmac1 0x18>;
-			dma-names = "tx", "rx", "tx", "rx";
-			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
-			resets = <&cpg 917>;
-			num-cs = <1>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
 		msiof0: spi@e6e20000 {
 			compatible = "renesas,msiof-r8a7792",
 				     "renesas,rcar-gen2-msiof";
@@ -688,34 +653,6 @@
 			status = "disabled";
 		};
 
-		du: display@feb00000 {
-			compatible = "renesas,du-r8a7792";
-			reg = <0 0xfeb00000 0 0x40000>;
-			reg-names = "du";
-			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 724>,
-				 <&cpg CPG_MOD 723>;
-			clock-names = "du.0", "du.1";
-			status = "disabled";
-
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				port@0 {
-					reg = <0>;
-					du_out_rgb0: endpoint {
-					};
-				};
-				port@1 {
-					reg = <1>;
-					du_out_rgb1: endpoint {
-					};
-				};
-			};
-		};
-
 		can0: can@e6e80000 {
 			compatible = "renesas,can-r8a7792",
 				     "renesas,rcar-gen2-can";
@@ -808,6 +745,36 @@
 			status = "disabled";
 		};
 
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7792",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee100000 0 0x328>;
+			interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
+			       <&dmac1 0xcd>, <&dmac1 0xce>;
+			dma-names = "tx", "rx", "tx", "rx";
+			clocks = <&cpg CPG_MOD 314>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>,
+			      <0 0xf1002000 0 0x2000>,
+			      <0 0xf1004000 0 0x2000>,
+			      <0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
+				      IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
 		vsp@fe928000 {
 			compatible = "renesas,vsp1";
 			reg = <0 0xfe928000 0 0x8000>;
@@ -835,14 +802,47 @@
 			resets = <&cpg 127>;
 		};
 
-		cpg: clock-controller@e6150000 {
-			compatible = "renesas,r8a7792-cpg-mssr";
-			reg = <0 0xe6150000 0 0x1000>;
-			clocks = <&extal_clk>;
-			clock-names = "extal";
-			#clock-cells = <2>;
-			#power-domain-cells = <0>;
-			#reset-cells = <1>;
+		jpu: jpeg-codec@fe980000 {
+			compatible = "renesas,jpu-r8a7792",
+				     "renesas,rcar-gen2-jpu";
+			reg = <0 0xfe980000 0 0x10300>;
+			interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 106>;
+			power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+			resets = <&cpg 106>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a7792";
+			reg = <0 0xfeb00000 0 0x40000>;
+			reg-names = "du";
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>,
+				 <&cpg CPG_MOD 723>;
+			clock-names = "du.0", "du.1";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb0: endpoint {
+					};
+				};
+				port@1 {
+					reg = <1>;
+					du_out_rgb1: endpoint {
+					};
+				};
+			};
+		};
+
+		prr: chipid@ff000044 {
+			compatible = "renesas,prr";
+			reg = <0 0xff000044 0 4>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts
index 51b3ffa..9ed6961 100644
--- a/arch/arm/boot/dts/r8a7793-gose.dts
+++ b/arch/arm/boot/dts/r8a7793-gose.dts
@@ -48,6 +48,10 @@
 	aliases {
 		serial0 = &scif0;
 		serial1 = &scif1;
+		i2c9 = &gpioi2c2;
+		i2c10 = &gpioi2c4;
+		i2c11 = &i2chdmi;
+		i2c12 = &i2cexio4;
 	};
 
 	chosen {
@@ -296,6 +300,146 @@
 		#clock-cells = <0>;
 		clock-frequency = <148500000>;
 	};
+
+	gpioi2c2: i2c-9 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		scl-gpios = <&gpio2 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio2 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		i2c-gpio,delay-us = <5>;
+	};
+
+	gpioi2c4: i2c-10 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		scl-gpios = <&gpio7 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio7 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		i2c-gpio,delay-us = <5>;
+	};
+
+	/*
+	 * A fallback to GPIO is provided for I2C2.
+	 */
+	i2chdmi: i2c-11 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&i2c2>, <&gpioi2c2>;
+		i2c-bus-name = "i2c-hdmi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ak4643: codec@12 {
+			compatible = "asahi-kasei,ak4643";
+			#sound-dai-cells = <0>;
+			reg = <0x12>;
+		};
+
+		composite-in@20 {
+			compatible = "adi,adv7180cp";
+			reg = <0x20>;
+			remote = <&vin1>;
+
+			port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7180_in: endpoint {
+						remote-endpoint = <&composite_con_in>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					adv7180_out: endpoint {
+						bus-width = <8>;
+						remote-endpoint = <&vin1ep>;
+					};
+				};
+			};
+		};
+
+		hdmi@39 {
+			compatible = "adi,adv7511w";
+			reg = <0x39>;
+			interrupt-parent = <&gpio3>;
+			interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+
+			adi,input-depth = <8>;
+			adi,input-colorspace = "rgb";
+			adi,input-clock = "1x";
+			adi,input-style = <1>;
+			adi,input-justification = "evenly";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7511_in: endpoint {
+						remote-endpoint = <&du_out_rgb>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					adv7511_out: endpoint {
+						remote-endpoint = <&hdmi_con_out>;
+					};
+				};
+			};
+		};
+
+		hdmi-in@4c {
+			compatible = "adi,adv7612";
+			reg = <0x4c>;
+			interrupt-parent = <&gpio4>;
+			interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+			default-input = <0>;
+
+			port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7612_in: endpoint {
+						remote-endpoint = <&hdmi_con_in>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					adv7612_out: endpoint {
+						remote-endpoint = <&vin0ep2>;
+					};
+				};
+			};
+		};
+
+		eeprom@50 {
+			compatible = "renesas,r1ex24002", "atmel,24c02";
+			reg = <0x50>;
+			pagesize = <16>;
+		};
+	};
+
+	/*
+	 * I2C4 is routed to EXIO connector E, pins 37 (SCL) + 39 (SDA).
+	 * A fallback to GPIO is provided.
+	 */
+	i2cexio4: i2c-12 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&i2c4>, <&gpioi2c4>;
+		i2c-bus-name = "i2c-exio4";
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
 };
 
 &du {
@@ -334,6 +478,11 @@
 		function = "i2c2";
 	};
 
+	i2c4_pins: i2c4 {
+		groups = "i2c4_c";
+		function = "i2c4";
+	};
+
 	du_pins: du {
 		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
 		function = "du";
@@ -544,107 +693,11 @@
 
 &i2c2 {
 	pinctrl-0 = <&i2c2_pins>;
-	pinctrl-names = "default";
+	pinctrl-names = "i2c-hdmi";
 
 	status = "okay";
 	clock-frequency = <100000>;
 
-	ak4643: codec@12 {
-		compatible = "asahi-kasei,ak4643";
-		#sound-dai-cells = <0>;
-		reg = <0x12>;
-	};
-
-	composite-in@20 {
-		compatible = "adi,adv7180cp";
-		reg = <0x20>;
-		remote = <&vin1>;
-
-		port {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7180_in: endpoint {
-					remote-endpoint = <&composite_con_in>;
-				};
-			};
-
-			port@3 {
-				reg = <3>;
-				adv7180_out: endpoint {
-					bus-width = <8>;
-					remote-endpoint = <&vin1ep>;
-				};
-			};
-		};
-	};
-
-	hdmi@39 {
-		compatible = "adi,adv7511w";
-		reg = <0x39>;
-		interrupt-parent = <&gpio3>;
-		interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
-
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-		adi,input-style = <1>;
-		adi,input-justification = "evenly";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7511_in: endpoint {
-					remote-endpoint = <&du_out_rgb>;
-				};
-			};
-
-			port@1 {
-				reg = <1>;
-				adv7511_out: endpoint {
-					remote-endpoint = <&hdmi_con_out>;
-				};
-			};
-		};
-	};
-
-	hdmi-in@4c {
-		compatible = "adi,adv7612";
-		reg = <0x4c>;
-		interrupt-parent = <&gpio4>;
-		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
-		default-input = <0>;
-
-		port {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7612_in: endpoint {
-					remote-endpoint = <&hdmi_con_in>;
-				};
-			};
-
-			port@2 {
-				reg = <2>;
-				adv7612_out: endpoint {
-					remote-endpoint = <&vin0ep2>;
-				};
-			};
-		};
-	};
-
-	eeprom@50 {
-		compatible = "renesas,r1ex24002", "atmel,24c02";
-		reg = <0x50>;
-		pagesize = <16>;
-	};
 };
 
 &i2c6 {
@@ -668,6 +721,11 @@
 	};
 };
 
+&i2c4 {
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-names = "i2c-exio4";
+};
+
 &rcar_sound {
 	pinctrl-0 = <&sound_pins &sound_clk_pins>;
 	pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi
index 039b225..f9c5a55 100644
--- a/arch/arm/boot/dts/r8a7793.dtsi
+++ b/arch/arm/boot/dts/r8a7793.dtsi
@@ -15,7 +15,6 @@
 
 / {
 	compatible = "renesas,r8a7793";
-	interrupt-parent = <&gic>;
 	#address-cells = <2>;
 	#size-cells = <2>;
 
@@ -32,6 +31,35 @@
 		spi0 = &qspi;
 	};
 
+	/*
+	 * The external audio clocks are configured as 0 Hz fixed frequency
+	 * clocks by default.
+	 * Boards that provide audio clocks should override them.
+	 */
+	audio_clk_a: audio_clk_a {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+	audio_clk_b: audio_clk_b {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+	audio_clk_c: audio_clk_c {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External CAN clock */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board. */
+		clock-frequency = <0>;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -74,960 +102,6 @@
 		};
 	};
 
-	apmu@e6152000 {
-		compatible = "renesas,r8a7793-apmu", "renesas,apmu";
-		reg = <0 0xe6152000 0 0x188>;
-		cpus = <&cpu0 &cpu1>;
-	};
-
-	thermal-zones {
-		cpu_thermal: cpu-thermal {
-			polling-delay-passive	= <0>;
-			polling-delay		= <0>;
-
-			thermal-sensors = <&thermal>;
-
-			trips {
-				cpu-crit {
-					temperature	= <95000>;
-					hysteresis	= <0>;
-					type		= "critical";
-				};
-			};
-			cooling-maps {
-			};
-		};
-	};
-
-	gic: interrupt-controller@f1001000 {
-		compatible = "arm,gic-400";
-		#interrupt-cells = <3>;
-		#address-cells = <0>;
-		interrupt-controller;
-		reg = <0 0xf1001000 0 0x1000>,
-			<0 0xf1002000 0 0x2000>,
-			<0 0xf1004000 0 0x2000>,
-			<0 0xf1006000 0 0x2000>;
-		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
-		clocks = <&cpg CPG_MOD 408>;
-		clock-names = "clk";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 408>;
-	};
-
-	gpio0: gpio@e6050000 {
-		compatible = "renesas,gpio-r8a7793", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6050000 0 0x50>;
-		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 0 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 912>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 912>;
-	};
-
-	gpio1: gpio@e6051000 {
-		compatible = "renesas,gpio-r8a7793", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6051000 0 0x50>;
-		interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 32 26>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 911>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 911>;
-	};
-
-	gpio2: gpio@e6052000 {
-		compatible = "renesas,gpio-r8a7793", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6052000 0 0x50>;
-		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 64 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 910>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 910>;
-	};
-
-	gpio3: gpio@e6053000 {
-		compatible = "renesas,gpio-r8a7793", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6053000 0 0x50>;
-		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 96 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 909>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 909>;
-	};
-
-	gpio4: gpio@e6054000 {
-		compatible = "renesas,gpio-r8a7793", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6054000 0 0x50>;
-		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 128 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 908>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 908>;
-	};
-
-	gpio5: gpio@e6055000 {
-		compatible = "renesas,gpio-r8a7793", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055000 0 0x50>;
-		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 160 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 907>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 907>;
-	};
-
-	gpio6: gpio@e6055400 {
-		compatible = "renesas,gpio-r8a7793", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055400 0 0x50>;
-		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 192 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 905>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 905>;
-	};
-
-	gpio7: gpio@e6055800 {
-		compatible = "renesas,gpio-r8a7793", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055800 0 0x50>;
-		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 224 26>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 904>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 904>;
-	};
-
-	thermal: thermal@e61f0000 {
-		compatible =	"renesas,thermal-r8a7793",
-				"renesas,rcar-gen2-thermal",
-				"renesas,rcar-thermal";
-		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
-		interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 522>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 522>;
-		#thermal-sensor-cells = <0>;
-	};
-
-	timer {
-		compatible = "arm,armv7-timer";
-		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
-	};
-
-	cmt0: timer@ffca0000 {
-		compatible = "renesas,r8a7793-cmt0", "renesas,rcar-gen2-cmt0";
-		reg = <0 0xffca0000 0 0x1004>;
-		interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 124>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 124>;
-
-		status = "disabled";
-	};
-
-	cmt1: timer@e6130000 {
-		compatible = "renesas,r8a7793-cmt1", "renesas,rcar-gen2-cmt1";
-		reg = <0 0xe6130000 0 0x1004>;
-		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 329>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 329>;
-
-		status = "disabled";
-	};
-
-	irqc0: interrupt-controller@e61c0000 {
-		compatible = "renesas,irqc-r8a7793", "renesas,irqc";
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		reg = <0 0xe61c0000 0 0x200>;
-		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 407>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 407>;
-	};
-
-	dmac0: dma-controller@e6700000 {
-		compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac";
-		reg = <0 0xe6700000 0 0x20000>;
-		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12", "ch13", "ch14";
-		clocks = <&cpg CPG_MOD 219>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 219>;
-		#dma-cells = <1>;
-		dma-channels = <15>;
-	};
-
-	dmac1: dma-controller@e6720000 {
-		compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac";
-		reg = <0 0xe6720000 0 0x20000>;
-		interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12", "ch13", "ch14";
-		clocks = <&cpg CPG_MOD 218>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 218>;
-		#dma-cells = <1>;
-		dma-channels = <15>;
-	};
-
-	audma0: dma-controller@ec700000 {
-		compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac";
-		reg = <0 0xec700000 0 0x10000>;
-		interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12";
-		clocks = <&cpg CPG_MOD 502>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 502>;
-		#dma-cells = <1>;
-		dma-channels = <13>;
-	};
-
-	audma1: dma-controller@ec720000 {
-		compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac";
-		reg = <0 0xec720000 0 0x10000>;
-		interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12";
-		clocks = <&cpg CPG_MOD 501>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 501>;
-		#dma-cells = <1>;
-		dma-channels = <13>;
-	};
-
-	/* The memory map in the User's Manual maps the cores to bus numbers */
-	i2c0: i2c@e6508000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7793", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6508000 0 0x40>;
-		interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 931>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 931>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c1: i2c@e6518000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7793", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6518000 0 0x40>;
-		interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 930>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 930>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c2: i2c@e6530000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7793", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6530000 0 0x40>;
-		interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 929>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 929>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c3: i2c@e6540000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7793", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6540000 0 0x40>;
-		interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 928>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 928>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c4: i2c@e6520000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7793", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6520000 0 0x40>;
-		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 927>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 927>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c5: i2c@e6528000 {
-		/* doesn't need pinmux */
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,i2c-r8a7793", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6528000 0 0x40>;
-		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 925>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 925>;
-		i2c-scl-internal-delay-ns = <110>;
-		status = "disabled";
-	};
-
-	i2c6: i2c@e60b0000 {
-		/* doesn't need pinmux */
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7793", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe60b0000 0 0x425>;
-		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 926>;
-		dmas = <&dmac0 0x77>, <&dmac0 0x78>,
-		       <&dmac1 0x77>, <&dmac1 0x78>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 926>;
-		status = "disabled";
-	};
-
-	i2c7: i2c@e6500000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7793", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6500000 0 0x425>;
-		interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 318>;
-		dmas = <&dmac0 0x61>, <&dmac0 0x62>,
-		       <&dmac1 0x61>, <&dmac1 0x62>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 318>;
-		status = "disabled";
-	};
-
-	i2c8: i2c@e6510000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "renesas,iic-r8a7793", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6510000 0 0x425>;
-		interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 323>;
-		dmas = <&dmac0 0x65>, <&dmac0 0x66>,
-		       <&dmac1 0x65>, <&dmac1 0x66>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 323>;
-		status = "disabled";
-	};
-
-	pfc: pin-controller@e6060000 {
-		compatible = "renesas,pfc-r8a7793";
-		reg = <0 0xe6060000 0 0x250>;
-	};
-
-	sdhi0: sd@ee100000 {
-		compatible = "renesas,sdhi-r8a7793",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee100000 0 0x328>;
-		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 314>;
-		dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
-		       <&dmac1 0xcd>, <&dmac1 0xce>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <195000000>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 314>;
-		status = "disabled";
-	};
-
-	sdhi1: sd@ee140000 {
-		compatible = "renesas,sdhi-r8a7793",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee140000 0 0x100>;
-		interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 312>;
-		dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
-		       <&dmac1 0xc1>, <&dmac1 0xc2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <97500000>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 312>;
-		status = "disabled";
-	};
-
-	sdhi2: sd@ee160000 {
-		compatible = "renesas,sdhi-r8a7793",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee160000 0 0x100>;
-		interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 311>;
-		dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
-		       <&dmac1 0xd3>, <&dmac1 0xd4>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <97500000>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 311>;
-		status = "disabled";
-	};
-
-	mmcif0: mmc@ee200000 {
-		compatible = "renesas,mmcif-r8a7793", "renesas,sh-mmcif";
-		reg = <0 0xee200000 0 0x80>;
-		interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 315>;
-		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
-		       <&dmac1 0xd1>, <&dmac1 0xd2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 315>;
-		reg-io-width = <4>;
-		status = "disabled";
-		max-frequency = <97500000>;
-	};
-
-	scifa0: serial@e6c40000 {
-		compatible = "renesas,scifa-r8a7793",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c40000 0 64>;
-		interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 204>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x21>, <&dmac0 0x22>,
-		       <&dmac1 0x21>, <&dmac1 0x22>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 204>;
-		status = "disabled";
-	};
-
-	scifa1: serial@e6c50000 {
-		compatible = "renesas,scifa-r8a7793",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c50000 0 64>;
-		interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 203>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x25>, <&dmac0 0x26>,
-		       <&dmac1 0x25>, <&dmac1 0x26>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 203>;
-		status = "disabled";
-	};
-
-	scifa2: serial@e6c60000 {
-		compatible = "renesas,scifa-r8a7793",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c60000 0 64>;
-		interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 202>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x27>, <&dmac0 0x28>,
-		       <&dmac1 0x27>, <&dmac1 0x28>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 202>;
-		status = "disabled";
-	};
-
-	scifa3: serial@e6c70000 {
-		compatible = "renesas,scifa-r8a7793",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c70000 0 64>;
-		interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1106>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
-		       <&dmac1 0x1b>, <&dmac1 0x1c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 1106>;
-		status = "disabled";
-	};
-
-	scifa4: serial@e6c78000 {
-		compatible = "renesas,scifa-r8a7793",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c78000 0 64>;
-		interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1107>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
-		       <&dmac1 0x1f>, <&dmac1 0x20>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 1107>;
-		status = "disabled";
-	};
-
-	scifa5: serial@e6c80000 {
-		compatible = "renesas,scifa-r8a7793",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c80000 0 64>;
-		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1108>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x23>, <&dmac0 0x24>,
-		       <&dmac1 0x23>, <&dmac1 0x24>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 1108>;
-		status = "disabled";
-	};
-
-	scifb0: serial@e6c20000 {
-		compatible = "renesas,scifb-r8a7793",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6c20000 0 0x100>;
-		interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 206>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
-		       <&dmac1 0x3d>, <&dmac1 0x3e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 206>;
-		status = "disabled";
-	};
-
-	scifb1: serial@e6c30000 {
-		compatible = "renesas,scifb-r8a7793",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6c30000 0 0x100>;
-		interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 207>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
-		       <&dmac1 0x19>, <&dmac1 0x1a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 207>;
-		status = "disabled";
-	};
-
-	scifb2: serial@e6ce0000 {
-		compatible = "renesas,scifb-r8a7793",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6ce0000 0 0x100>;
-		interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 216>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
-		       <&dmac1 0x1d>, <&dmac1 0x1e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 216>;
-		status = "disabled";
-	};
-
-	scif0: serial@e6e60000 {
-		compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e60000 0 64>;
-		interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 721>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
-		       <&dmac1 0x29>, <&dmac1 0x2a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 721>;
-		status = "disabled";
-	};
-
-	scif1: serial@e6e68000 {
-		compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e68000 0 64>;
-		interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 720>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
-		       <&dmac1 0x2d>, <&dmac1 0x2e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 720>;
-		status = "disabled";
-	};
-
-	scif2: serial@e6e58000 {
-		compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e58000 0 64>;
-		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 719>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
-		       <&dmac1 0x2b>, <&dmac1 0x2c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 719>;
-		status = "disabled";
-	};
-
-	scif3: serial@e6ea8000 {
-		compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ea8000 0 64>;
-		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 718>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
-		       <&dmac1 0x2f>, <&dmac1 0x30>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 718>;
-		status = "disabled";
-	};
-
-	scif4: serial@e6ee0000 {
-		compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ee0000 0 64>;
-		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 715>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
-		       <&dmac1 0xfb>, <&dmac1 0xfc>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 715>;
-		status = "disabled";
-	};
-
-	scif5: serial@e6ee8000 {
-		compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ee8000 0 64>;
-		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 714>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
-		       <&dmac1 0xfd>, <&dmac1 0xfe>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 714>;
-		status = "disabled";
-	};
-
-	hscif0: serial@e62c0000 {
-		compatible = "renesas,hscif-r8a7793",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62c0000 0 96>;
-		interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 717>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
-		       <&dmac1 0x39>, <&dmac1 0x3a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 717>;
-		status = "disabled";
-	};
-
-	hscif1: serial@e62c8000 {
-		compatible = "renesas,hscif-r8a7793",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62c8000 0 96>;
-		interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 716>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
-		       <&dmac1 0x4d>, <&dmac1 0x4e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 716>;
-		status = "disabled";
-	};
-
-	hscif2: serial@e62d0000 {
-		compatible = "renesas,hscif-r8a7793",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62d0000 0 96>;
-		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 713>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
-		       <&dmac1 0x3b>, <&dmac1 0x3c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 713>;
-		status = "disabled";
-	};
-
-	icram0:	sram@e63a0000 {
-		compatible = "mmio-sram";
-		reg = <0 0xe63a0000 0 0x12000>;
-	};
-
-	icram1:	sram@e63c0000 {
-		compatible = "mmio-sram";
-		reg = <0 0xe63c0000 0 0x1000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0 0xe63c0000 0x1000>;
-
-		smp-sram@0 {
-			compatible = "renesas,smp-sram";
-			reg = <0 0x10>;
-		};
-	};
-
-	ether: ethernet@ee700000 {
-		compatible = "renesas,ether-r8a7793",
-			     "renesas,rcar-gen2-ether";
-		reg = <0 0xee700000 0 0x400>;
-		interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 813>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 813>;
-		phy-mode = "rmii";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	vin0: video@e6ef0000 {
-		compatible = "renesas,vin-r8a7793", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef0000 0 0x1000>;
-		interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 811>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 811>;
-		status = "disabled";
-	};
-
-	vin1: video@e6ef1000 {
-		compatible = "renesas,vin-r8a7793", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef1000 0 0x1000>;
-		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 810>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 810>;
-		status = "disabled";
-	};
-
-	vin2: video@e6ef2000 {
-		compatible = "renesas,vin-r8a7793", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef2000 0 0x1000>;
-		interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 809>;
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 809>;
-		status = "disabled";
-	};
-
-	qspi: spi@e6b10000 {
-		compatible = "renesas,qspi-r8a7793", "renesas,qspi";
-		reg = <0 0xe6b10000 0 0x2c>;
-		interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 917>;
-		dmas = <&dmac0 0x17>, <&dmac0 0x18>,
-		       <&dmac1 0x17>, <&dmac1 0x18>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 917>;
-		num-cs = <1>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	du: display@feb00000 {
-		compatible = "renesas,du-r8a7793";
-		reg = <0 0xfeb00000 0 0x40000>,
-		      <0 0xfeb90000 0 0x1c>;
-		reg-names = "du", "lvds.0";
-		interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 724>,
-			 <&cpg CPG_MOD 723>,
-			 <&cpg CPG_MOD 726>;
-		clock-names = "du.0", "du.1", "lvds.0";
-		status = "disabled";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				du_out_rgb: endpoint {
-				};
-			};
-			port@1 {
-				reg = <1>;
-				du_out_lvds0: endpoint {
-				};
-			};
-		};
-	};
-
-	can0: can@e6e80000 {
-		compatible = "renesas,can-r8a7793", "renesas,rcar-gen2-can";
-		reg = <0 0xe6e80000 0 0x1000>;
-		interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 916>, <&cpg CPG_CORE R8A7793_CLK_RCAN>,
-			 <&can_clk>;
-		clock-names = "clkp1", "clkp2", "can_clk";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 916>;
-		status = "disabled";
-	};
-
-	can1: can@e6e88000 {
-		compatible = "renesas,can-r8a7793", "renesas,rcar-gen2-can";
-		reg = <0 0xe6e88000 0 0x1000>;
-		interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 915>, <&cpg CPG_CORE R8A7793_CLK_RCAN>,
-			 <&can_clk>;
-		clock-names = "clkp1", "clkp2", "can_clk";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 915>;
-		status = "disabled";
-	};
-
 	/* External root clock */
 	extal_clk: extal {
 		compatible = "fixed-clock";
@@ -1036,42 +110,6 @@
 		clock-frequency = <0>;
 	};
 
-	/*
-	 * The external audio clocks are configured as 0 Hz fixed frequency
-	 * clocks by default.
-	 * Boards that provide audio clocks should override them.
-	 */
-	audio_clk_a: audio_clk_a {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-	audio_clk_b: audio_clk_b {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-	audio_clk_c: audio_clk_c {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-
-	/* External USB clock - can be overridden by the board */
-	usb_extal_clk: usb_extal {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <48000000>;
-	};
-
-	/* External CAN clock */
-	can_clk: can {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		/* This value must be overridden by the board. */
-		clock-frequency = <0>;
-	};
-
 	/* External SCIF clock */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -1080,255 +118,1279 @@
 		clock-frequency = <0>;
 	};
 
-	/* Special CPG clocks */
-	cpg: clock-controller@e6150000 {
-		compatible = "renesas,r8a7793-cpg-mssr";
-		reg = <0 0xe6150000 0 0x1000>;
-		clocks = <&extal_clk>, <&usb_extal_clk>;
-		clock-names = "extal", "usb_extal";
-		#clock-cells = <2>;
-		#power-domain-cells = <0>;
-		#reset-cells = <1>;
-	};
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
 
-	rst: reset-controller@e6160000 {
-		compatible = "renesas,r8a7793-rst";
-		reg = <0 0xe6160000 0 0x0100>;
-	};
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
 
-	prr: chipid@ff000044 {
-		compatible = "renesas,prr";
-		reg = <0 0xff000044 0 4>;
-	};
+		gpio0: gpio@e6050000 {
+			compatible = "renesas,gpio-r8a7793",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6050000 0 0x50>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 0 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 912>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 912>;
+		};
 
-	sysc: system-controller@e6180000 {
-		compatible = "renesas,r8a7793-sysc";
-		reg = <0 0xe6180000 0 0x0200>;
-		#power-domain-cells = <1>;
-	};
+		gpio1: gpio@e6051000 {
+			compatible = "renesas,gpio-r8a7793",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6051000 0 0x50>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 32 26>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 911>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 911>;
+		};
 
-	ipmmu_sy0: mmu@e6280000 {
-		compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6280000 0 0x1000>;
-		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio2: gpio@e6052000 {
+			compatible = "renesas,gpio-r8a7793",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6052000 0 0x50>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 64 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 910>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 910>;
+		};
 
-	ipmmu_sy1: mmu@e6290000 {
-		compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6290000 0 0x1000>;
-		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio3: gpio@e6053000 {
+			compatible = "renesas,gpio-r8a7793",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6053000 0 0x50>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 96 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 909>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 909>;
+		};
 
-	ipmmu_ds: mmu@e6740000 {
-		compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6740000 0 0x1000>;
-		interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio4: gpio@e6054000 {
+			compatible = "renesas,gpio-r8a7793",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6054000 0 0x50>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 128 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 908>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 908>;
+		};
 
-	ipmmu_mp: mmu@ec680000 {
-		compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
-		reg = <0 0xec680000 0 0x1000>;
-		interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio5: gpio@e6055000 {
+			compatible = "renesas,gpio-r8a7793",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055000 0 0x50>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 160 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 907>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 907>;
+		};
 
-	ipmmu_mx: mmu@fe951000 {
-		compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
-		reg = <0 0xfe951000 0 0x1000>;
-		interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio6: gpio@e6055400 {
+			compatible = "renesas,gpio-r8a7793",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055400 0 0x50>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 192 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 905>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 905>;
+		};
 
-	ipmmu_rt: mmu@ffc80000 {
-		compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
-		reg = <0 0xffc80000 0 0x1000>;
-		interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio7: gpio@e6055800 {
+			compatible = "renesas,gpio-r8a7793",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055800 0 0x50>;
+			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 224 26>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 904>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 904>;
+		};
 
-	ipmmu_gp: mmu@e62a0000 {
-		compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
-		reg = <0 0xe62a0000 0 0x1000>;
-		interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a7793";
+			reg = <0 0xe6060000 0 0x250>;
+		};
 
-	rcar_sound: sound@ec500000 {
-		/*
-		 * #sound-dai-cells is required
-		 *
-		 * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
-		 * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
+		/* Special CPG clocks */
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7793-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&usb_extal_clk>;
+			clock-names = "extal", "usb_extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		apmu@e6152000 {
+			compatible = "renesas,r8a7793-apmu", "renesas,apmu";
+			reg = <0 0xe6152000 0 0x188>;
+			cpus = <&cpu0 &cpu1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7793-rst";
+			reg = <0 0xe6160000 0 0x0100>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7793-sysc";
+			reg = <0 0xe6180000 0 0x0200>;
+			#power-domain-cells = <1>;
+		};
+
+		irqc0: interrupt-controller@e61c0000 {
+			compatible = "renesas,irqc-r8a7793", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 407>;
+		};
+
+		thermal: thermal@e61f0000 {
+			compatible = "renesas,thermal-r8a7793",
+				     "renesas,rcar-gen2-thermal",
+				     "renesas,rcar-thermal";
+			reg = <0 0xe61f0000 0 0x10>, <0 0xe61f0100 0 0x38>;
+			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 522>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 522>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		ipmmu_sy0: mmu@e6280000 {
+			compatible = "renesas,ipmmu-r8a7793",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6280000 0 0x1000>;
+			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_sy1: mmu@e6290000 {
+			compatible = "renesas,ipmmu-r8a7793",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6290000 0 0x1000>;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_ds: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a7793",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6740000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_mp: mmu@ec680000 {
+			compatible = "renesas,ipmmu-r8a7793",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xec680000 0 0x1000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_mx: mmu@fe951000 {
+			compatible = "renesas,ipmmu-r8a7793",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xfe951000 0 0x1000>;
+			interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_rt: mmu@ffc80000 {
+			compatible = "renesas,ipmmu-r8a7793",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xffc80000 0 0x1000>;
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_gp: mmu@e62a0000 {
+			compatible = "renesas,ipmmu-r8a7793",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe62a0000 0 0x1000>;
+			interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		icram0:	sram@e63a0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63a0000 0 0x12000>;
+		};
+
+		icram1:	sram@e63c0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63c0000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0xe63c0000 0x1000>;
+
+			smp-sram@0 {
+				compatible = "renesas,smp-sram";
+				reg = <0 0x10>;
+			};
+		};
+
+		/* The memory map in the User's Manual maps the cores to
+		 * bus numbers
 		 */
-		compatible =  "renesas,rcar_sound-r8a7793", "renesas,rcar_sound-gen2";
-		reg =	<0 0xec500000 0 0x1000>, /* SCU */
-			<0 0xec5a0000 0 0x100>,  /* ADG */
-			<0 0xec540000 0 0x1000>, /* SSIU */
-			<0 0xec541000 0 0x280>,  /* SSI */
-			<0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
-		reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+		i2c0: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7793",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
 
-		clocks = <&cpg CPG_MOD 1005>,
-			 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
-			 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
-			 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
-			 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
-			 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
-			 <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
-			 <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
-			 <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
-			 <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
-			 <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
-			 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
-			 <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>,
-			 <&cpg CPG_CORE R8A7793_CLK_M2>;
-		clock-names = "ssi-all",
-				"ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
-				"ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0",
-				"src.9", "src.8", "src.7", "src.6", "src.5",
-				"src.4", "src.3", "src.2", "src.1", "src.0",
-				"dvc.0", "dvc.1",
-				"clk_a", "clk_b", "clk_c", "clk_i";
-		power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
-		resets = <&cpg 1005>,
-			 <&cpg 1006>, <&cpg 1007>, <&cpg 1008>, <&cpg 1009>,
-			 <&cpg 1010>, <&cpg 1011>, <&cpg 1012>, <&cpg 1013>,
-			 <&cpg 1014>, <&cpg 1015>;
-		reset-names = "ssi-all",
-			      "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
-			      "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0";
+		i2c1: i2c@e6518000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7793",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6518000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
 
-		status = "disabled";
+		i2c2: i2c@e6530000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7793",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6530000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
 
-		rcar_sound,dvc {
-			dvc0: dvc-0 {
-				dmas = <&audma1 0xbc>;
-				dma-names = "tx";
+		i2c3: i2c@e6540000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7793",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6540000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e6520000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7793",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6520000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@e6528000 {
+			/* doesn't need pinmux */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a7793",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6528000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 925>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 925>;
+			i2c-scl-internal-delay-ns = <110>;
+			status = "disabled";
+		};
+
+		i2c6: i2c@e60b0000 {
+			/* doesn't need pinmux */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7793",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe60b0000 0 0x425>;
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 926>;
+			dmas = <&dmac0 0x77>, <&dmac0 0x78>,
+			       <&dmac1 0x77>, <&dmac1 0x78>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 926>;
+			status = "disabled";
+		};
+
+		i2c7: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7793",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6500000 0 0x425>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>;
+			dmas = <&dmac0 0x61>, <&dmac0 0x62>,
+			       <&dmac1 0x61>, <&dmac1 0x62>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			status = "disabled";
+		};
+
+		i2c8: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a7793",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6510000 0 0x425>;
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 323>;
+			dmas = <&dmac0 0x65>, <&dmac0 0x66>,
+			       <&dmac1 0x65>, <&dmac1 0x66>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 323>;
+			status = "disabled";
+		};
+
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a7793",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x20000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 219>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		dmac1: dma-controller@e6720000 {
+			compatible = "renesas,dmac-r8a7793",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6720000 0 0x20000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		qspi: spi@e6b10000 {
+			compatible = "renesas,qspi-r8a7793", "renesas,qspi";
+			reg = <0 0xe6b10000 0 0x2c>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 917>;
+			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
+			       <&dmac1 0x17>, <&dmac1 0x18>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+			num-cs = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		scifa0: serial@e6c40000 {
+			compatible = "renesas,scifa-r8a7793",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x21>, <&dmac0 0x22>,
+			       <&dmac1 0x21>, <&dmac1 0x22>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scifa1: serial@e6c50000 {
+			compatible = "renesas,scifa-r8a7793",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x25>, <&dmac0 0x26>,
+			       <&dmac1 0x25>, <&dmac1 0x26>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		scifa2: serial@e6c60000 {
+			compatible = "renesas,scifa-r8a7793",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c60000 0 64>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x27>, <&dmac0 0x28>,
+			       <&dmac1 0x27>, <&dmac1 0x28>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 202>;
+			status = "disabled";
+		};
+
+		scifa3: serial@e6c70000 {
+			compatible = "renesas,scifa-r8a7793",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c70000 0 64>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1106>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
+			       <&dmac1 0x1b>, <&dmac1 0x1c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 1106>;
+			status = "disabled";
+		};
+
+		scifa4: serial@e6c78000 {
+			compatible = "renesas,scifa-r8a7793",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c78000 0 64>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1107>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
+			       <&dmac1 0x1f>, <&dmac1 0x20>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 1107>;
+			status = "disabled";
+		};
+
+		scifa5: serial@e6c80000 {
+			compatible = "renesas,scifa-r8a7793",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c80000 0 64>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1108>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x23>, <&dmac0 0x24>,
+			       <&dmac1 0x23>, <&dmac1 0x24>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 1108>;
+			status = "disabled";
+		};
+
+		scifb0: serial@e6c20000 {
+			compatible = "renesas,scifb-r8a7793",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c20000 0 0x100>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
+			       <&dmac1 0x3d>, <&dmac1 0x3e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 206>;
+			status = "disabled";
+		};
+
+		scifb1: serial@e6c30000 {
+			compatible = "renesas,scifb-r8a7793",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c30000 0 0x100>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
+			       <&dmac1 0x19>, <&dmac1 0x1a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 207>;
+			status = "disabled";
+		};
+
+		scifb2: serial@e6ce0000 {
+			compatible = "renesas,scifb-r8a7793",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6ce0000 0 0x100>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 216>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
+			       <&dmac1 0x1d>, <&dmac1 0x1e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 216>;
+			status = "disabled";
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a7793",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 721>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
+			       <&dmac1 0x29>, <&dmac1 0x2a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 721>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a7793",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e68000 0 64>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 720>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
+			       <&dmac1 0x2d>, <&dmac1 0x2e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 720>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e58000 {
+			compatible = "renesas,scif-r8a7793",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e58000 0 64>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 719>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
+			       <&dmac1 0x2b>, <&dmac1 0x2c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 719>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6ea8000 {
+			compatible = "renesas,scif-r8a7793",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ea8000 0 64>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 718>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
+			       <&dmac1 0x2f>, <&dmac1 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 718>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6ee0000 {
+			compatible = "renesas,scif-r8a7793",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee0000 0 64>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 715>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
+			       <&dmac1 0xfb>, <&dmac1 0xfc>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 715>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6ee8000 {
+			compatible = "renesas,scif-r8a7793",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee8000 0 64>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 714>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
+			       <&dmac1 0xfd>, <&dmac1 0xfe>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 714>;
+			status = "disabled";
+		};
+
+		hscif0: serial@e62c0000 {
+			compatible = "renesas,hscif-r8a7793",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c0000 0 96>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 717>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
+			       <&dmac1 0x39>, <&dmac1 0x3a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 717>;
+			status = "disabled";
+		};
+
+		hscif1: serial@e62c8000 {
+			compatible = "renesas,hscif-r8a7793",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c8000 0 96>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
+			       <&dmac1 0x4d>, <&dmac1 0x4e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 716>;
+			status = "disabled";
+		};
+
+		hscif2: serial@e62d0000 {
+			compatible = "renesas,hscif-r8a7793",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62d0000 0 96>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 713>, <&cpg CPG_CORE R8A7793_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
+			       <&dmac1 0x3b>, <&dmac1 0x3c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 713>;
+			status = "disabled";
+		};
+
+		can0: can@e6e80000 {
+			compatible = "renesas,can-r8a7793",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e80000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>, <&cpg CPG_CORE R8A7793_CLK_RCAN>,
+				 <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+			status = "disabled";
+		};
+
+		can1: can@e6e88000 {
+			compatible = "renesas,can-r8a7793",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e88000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>, <&cpg CPG_CORE R8A7793_CLK_RCAN>,
+				 <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 915>;
+			status = "disabled";
+		};
+
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a7793",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 811>;
+			status = "disabled";
+		};
+
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a7793",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 810>;
+			status = "disabled";
+		};
+
+		vin2: video@e6ef2000 {
+			compatible = "renesas,vin-r8a7793",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef2000 0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 809>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 809>;
+			status = "disabled";
+		};
+
+		rcar_sound: sound@ec500000 {
+			/*
+			 * #sound-dai-cells is required
+			 *
+			 * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
+			 * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
+			 */
+			compatible = "renesas,rcar_sound-r8a7793",
+				     "renesas,rcar_sound-gen2";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
+			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+			clocks = <&cpg CPG_MOD 1005>,
+				 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+				 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+				 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+				 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+				 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+				 <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+				 <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+				 <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+				 <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+				 <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+				 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+				 <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>,
+				 <&cpg CPG_CORE R8A7793_CLK_M2>;
+			clock-names = "ssi-all",
+				      "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+				      "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+				      "ssi.1", "ssi.0",
+				      "src.9", "src.8", "src.7", "src.6",
+				      "src.5", "src.4", "src.3", "src.2",
+				      "src.1", "src.0",
+				      "dvc.0", "dvc.1",
+				      "clk_a", "clk_b", "clk_c", "clk_i";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 1005>,
+				 <&cpg 1006>, <&cpg 1007>,
+				 <&cpg 1008>, <&cpg 1009>,
+				 <&cpg 1010>, <&cpg 1011>,
+				 <&cpg 1012>, <&cpg 1013>,
+				 <&cpg 1014>, <&cpg 1015>;
+			reset-names = "ssi-all",
+				      "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+				      "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+				      "ssi.1", "ssi.0";
+
+			status = "disabled";
+
+			rcar_sound,dvc {
+				dvc0: dvc-0 {
+					dmas = <&audma1 0xbc>;
+					dma-names = "tx";
+				};
+				dvc1: dvc-1 {
+					dmas = <&audma1 0xbe>;
+					dma-names = "tx";
+				};
 			};
-			dvc1: dvc-1 {
-				dmas = <&audma1 0xbe>;
-				dma-names = "tx";
+
+			rcar_sound,src {
+				src0: src-0 {
+					interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x85>, <&audma1 0x9a>;
+					dma-names = "rx", "tx";
+				};
+				src1: src-1 {
+					interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x87>, <&audma1 0x9c>;
+					dma-names = "rx", "tx";
+				};
+				src2: src-2 {
+					interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x89>, <&audma1 0x9e>;
+					dma-names = "rx", "tx";
+				};
+				src3: src-3 {
+					interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+					dma-names = "rx", "tx";
+				};
+				src4: src-4 {
+					interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+					dma-names = "rx", "tx";
+				};
+				src5: src-5 {
+					interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+					dma-names = "rx", "tx";
+				};
+				src6: src-6 {
+					interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x91>, <&audma1 0xb4>;
+					dma-names = "rx", "tx";
+				};
+				src7: src-7 {
+					interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x93>, <&audma1 0xb6>;
+					dma-names = "rx", "tx";
+				};
+				src8: src-8 {
+					interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x95>, <&audma1 0xb8>;
+					dma-names = "rx", "tx";
+				};
+				src9: src-9 {
+					interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x97>, <&audma1 0xba>;
+					dma-names = "rx", "tx";
+				};
+			};
+
+			rcar_sound,ssi {
+				ssi0: ssi-0 {
+					interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x01>, <&audma1 0x02>,
+					       <&audma0 0x15>, <&audma1 0x16>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi1: ssi-1 {
+					 interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x03>, <&audma1 0x04>,
+					       <&audma0 0x49>, <&audma1 0x4a>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi2: ssi-2 {
+					interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x05>, <&audma1 0x06>,
+					       <&audma0 0x63>, <&audma1 0x64>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi3: ssi-3 {
+					interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x07>, <&audma1 0x08>,
+					       <&audma0 0x6f>, <&audma1 0x70>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi4: ssi-4 {
+					interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x09>, <&audma1 0x0a>,
+					       <&audma0 0x71>, <&audma1 0x72>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi5: ssi-5 {
+					interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0b>, <&audma1 0x0c>,
+					       <&audma0 0x73>, <&audma1 0x74>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi6: ssi-6 {
+					interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0d>, <&audma1 0x0e>,
+					       <&audma0 0x75>, <&audma1 0x76>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi7: ssi-7 {
+					interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0f>, <&audma1 0x10>,
+					       <&audma0 0x79>, <&audma1 0x7a>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi8: ssi-8 {
+					interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x11>, <&audma1 0x12>,
+					       <&audma0 0x7b>, <&audma1 0x7c>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi9: ssi-9 {
+					interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x13>, <&audma1 0x14>,
+					       <&audma0 0x7d>, <&audma1 0x7e>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
 			};
 		};
 
-		rcar_sound,src {
-			src0: src-0 {
-				interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x85>, <&audma1 0x9a>;
-				dma-names = "rx", "tx";
-			};
-			src1: src-1 {
-				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x87>, <&audma1 0x9c>;
-				dma-names = "rx", "tx";
-			};
-			src2: src-2 {
-				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x89>, <&audma1 0x9e>;
-				dma-names = "rx", "tx";
-			};
-			src3: src-3 {
-				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8b>, <&audma1 0xa0>;
-				dma-names = "rx", "tx";
-			};
-			src4: src-4 {
-				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8d>, <&audma1 0xb0>;
-				dma-names = "rx", "tx";
-			};
-			src5: src-5 {
-				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8f>, <&audma1 0xb2>;
-				dma-names = "rx", "tx";
-			};
-			src6: src-6 {
-				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x91>, <&audma1 0xb4>;
-				dma-names = "rx", "tx";
-			};
-			src7: src-7 {
-				interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x93>, <&audma1 0xb6>;
-				dma-names = "rx", "tx";
-			};
-			src8: src-8 {
-				interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x95>, <&audma1 0xb8>;
-				dma-names = "rx", "tx";
-			};
-			src9: src-9 {
-				interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x97>, <&audma1 0xba>;
-				dma-names = "rx", "tx";
+		audma0: dma-controller@ec700000 {
+			compatible = "renesas,dmac-r8a7793",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec700000 0 0x10000>;
+			interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 502>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 502>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		audma1: dma-controller@ec720000 {
+			compatible = "renesas,dmac-r8a7793",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec720000 0 0x10000>;
+			interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 501>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 501>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7793",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee100000 0 0x328>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
+			       <&dmac1 0xcd>, <&dmac1 0xce>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <195000000>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		sdhi1: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a7793",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee140000 0 0x100>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
+			       <&dmac1 0xc1>, <&dmac1 0xc2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi2: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a7793",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee160000 0 0x100>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
+			       <&dmac1 0xd3>, <&dmac1 0xd4>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		mmcif0: mmc@ee200000 {
+			compatible = "renesas,mmcif-r8a7793",
+				     "renesas,sh-mmcif";
+			reg = <0 0xee200000 0 0x80>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 315>;
+			dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
+			       <&dmac1 0xd1>, <&dmac1 0xd2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 315>;
+			reg-io-width = <4>;
+			status = "disabled";
+			max-frequency = <97500000>;
+		};
+
+		ether: ethernet@ee700000 {
+			compatible = "renesas,ether-r8a7793",
+				     "renesas,rcar-gen2-ether";
+			reg = <0 0xee700000 0 0x400>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 813>;
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 813>;
+			phy-mode = "rmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>,
+				<0 0xf1002000 0 0x2000>,
+				<0 0xf1004000 0 0x2000>,
+				<0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a7793";
+			reg = <0 0xfeb00000 0 0x40000>,
+			      <0 0xfeb90000 0 0x1c>;
+			reg-names = "du", "lvds.0";
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>,
+				 <&cpg CPG_MOD 723>,
+				 <&cpg CPG_MOD 726>;
+			clock-names = "du.0", "du.1", "lvds.0";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+				port@1 {
+					reg = <1>;
+					du_out_lvds0: endpoint {
+					};
+				};
 			};
 		};
 
-		rcar_sound,ssi {
-			ssi0: ssi-0 {
-				interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
-				dma-names = "rx", "tx", "rxu", "txu";
+		prr: chipid@ff000044 {
+			compatible = "renesas,prr";
+			reg = <0 0xff000044 0 4>;
+		};
+
+		cmt0: timer@ffca0000 {
+			compatible = "renesas,r8a7793-cmt0",
+				     "renesas,rcar-gen2-cmt0";
+			reg = <0 0xffca0000 0 0x1004>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 124>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 124>;
+
+			status = "disabled";
+		};
+
+		cmt1: timer@e6130000 {
+			compatible = "renesas,r8a7793-cmt1",
+				     "renesas,rcar-gen2-cmt1";
+			reg = <0 0xe6130000 0 0x1004>;
+			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 329>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+			resets = <&cpg 329>;
+
+			status = "disabled";
+		};
+	};
+
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&thermal>;
+
+			trips {
+				cpu-crit {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
 			};
-			ssi1: ssi-1 {
-				 interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi2: ssi-2 {
-				interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi3: ssi-3 {
-				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi4: ssi-4 {
-				interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi5: ssi-5 {
-				interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi6: ssi-6 {
-				interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi7: ssi-7 {
-				interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi8: ssi-8 {
-				interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi9: ssi-9 {
-				interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;
-				dma-names = "rx", "tx", "rxu", "txu";
+			cooling-maps {
 			};
 		};
 	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	/* External USB clock - can be overridden by the board */
+	usb_extal_clk: usb_extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
+	};
 };
diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
index 60c6515..26a8834 100644
--- a/arch/arm/boot/dts/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/r8a7794-alt.dts
@@ -18,7 +18,9 @@
 
 	aliases {
 		serial0 = &scif2;
+		i2c9 = &gpioi2c1;
 		i2c10 = &gpioi2c4;
+		i2c11 = &i2chdmi;
 		i2c12 = &i2cexio4;
 	};
 
@@ -138,17 +140,50 @@
 		clock-frequency = <148500000>;
 	};
 
+	gpioi2c1: i2c-9 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		scl-gpios = <&gpio4 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio4 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	};
+
 	gpioi2c4: i2c-10 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "i2c-gpio";
 		status = "disabled";
-		sda-gpios = <&gpio4 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		scl-gpios = <&gpio4 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio4 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <5>;
 	};
 
 	/*
+	 * A fallback to GPIO is provided for I2C1.
+	 */
+	i2chdmi: i2c-11 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&i2c1>, <&gpioi2c1>;
+		i2c-bus-name = "i2c-hdmi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		composite-in@20 {
+			compatible = "adi,adv7180";
+			reg = <0x20>;
+			remote = <&vin0>;
+
+			port {
+				adv7180: endpoint {
+					bus-width = <8>;
+					remote-endpoint = <&vin0ep>;
+				};
+			};
+		};
+	};
+
+	/*
 	 * I2C4 is routed to EXIO connector B, pins 73 (SCL) + 74 (SDA).
 	 * A fallback to GPIO is provided.
 	 */
@@ -324,23 +359,9 @@
 
 &i2c1 {
 	pinctrl-0 = <&i2c1_pins>;
-	pinctrl-names = "default";
+	pinctrl-names = "i2c-hdmi";
 
-	status = "okay";
 	clock-frequency = <400000>;
-
-	composite-in@20 {
-		compatible = "adi,adv7180";
-		reg = <0x20>;
-		remote = <&vin0>;
-
-		port {
-			adv7180: endpoint {
-				bus-width = <8>;
-				remote-endpoint = <&vin0ep>;
-			};
-		};
-	};
 };
 
 &i2c4 {
diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts
index edfad0e..351cb3b 100644
--- a/arch/arm/boot/dts/r8a7794-silk.dts
+++ b/arch/arm/boot/dts/r8a7794-silk.dts
@@ -24,6 +24,7 @@
 /dts-v1/;
 #include "r8a7794.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
 	model = "SILK";
@@ -31,6 +32,8 @@
 
 	aliases {
 		serial0 = &scif2;
+		i2c9 = &gpioi2c1;
+		i2c10 = &i2chdmi;
 	};
 
 	chosen {
@@ -43,6 +46,60 @@
 		reg = <0 0x40000000 0 0x40000000>;
 	};
 
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		key-3 {
+			gpios = <&gpio5 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_3>;
+			label = "SW3";
+			wakeup-source;
+			debounce-interval = <20>;
+		};
+		key-4 {
+			gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_4>;
+			label = "SW4";
+			wakeup-source;
+			debounce-interval = <20>;
+		};
+		key-6 {
+			gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_6>;
+			label = "SW6";
+			wakeup-source;
+			debounce-interval = <20>;
+		};
+		key-a {
+			gpios = <&gpio3 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_A>;
+			label = "SW12-1";
+			wakeup-source;
+			debounce-interval = <20>;
+		};
+		key-b {
+			gpios = <&gpio3 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_B>;
+			label = "SW12-2";
+			wakeup-source;
+			debounce-interval = <20>;
+		};
+		key-c {
+			gpios = <&gpio3 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_C>;
+			label = "SW12-3";
+			wakeup-source;
+			debounce-interval = <20>;
+		};
+		key-d {
+			gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_D>;
+			label = "SW12-4";
+			wakeup-source;
+			debounce-interval = <20>;
+		};
+	};
+
 	d3_3v: regulator-d3-3v {
 		compatible = "regulator-fixed";
 		regulator-name = "D3.3V";
@@ -153,6 +210,84 @@
 			clocks = <&x9_clk>;
 		};
 	};
+
+	gpioi2c1: i2c-9 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		scl-gpios = <&gpio4 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		sda-gpios = <&gpio4 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		i2c-gpio,delay-us = <5>;
+	};
+
+	/*
+	 * A fallback to GPIO is provided for I2C1.
+	 */
+	i2chdmi: i2c-10 {
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&i2c1>, <&gpioi2c1>;
+		i2c-bus-name = "i2c-hdmi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ak4643: codec@12 {
+			compatible = "asahi-kasei,ak4643";
+			#sound-dai-cells = <0>;
+			reg = <0x12>;
+		};
+
+		composite-in@20 {
+			compatible = "adi,adv7180";
+			reg = <0x20>;
+			remote = <&vin0>;
+
+			port {
+				adv7180: endpoint {
+					bus-width = <8>;
+					remote-endpoint = <&vin0ep>;
+				};
+			};
+		};
+
+		hdmi@39 {
+			compatible = "adi,adv7511w";
+			reg = <0x39>;
+			interrupt-parent = <&gpio5>;
+			interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
+
+			adi,input-depth = <8>;
+			adi,input-colorspace = "rgb";
+			adi,input-clock = "1x";
+			adi,input-style = <1>;
+			adi,input-justification = "evenly";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7511_in: endpoint {
+						remote-endpoint = <&du_out_rgb0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					adv7511_out: endpoint {
+						remote-endpoint = <&hdmi_con>;
+					};
+				};
+			};
+		};
+
+		eeprom@50 {
+			compatible = "renesas,r1ex24002", "atmel,24c02";
+			reg = <0x50>;
+			pagesize = <16>;
+		};
+	};
 };
 
 &extal_clk {
@@ -268,61 +403,9 @@
 
 &i2c1 {
 	pinctrl-0 = <&i2c1_pins>;
-	pinctrl-names = "default";
+	pinctrl-names = "i2c-hdmi";
 
-	status = "okay";
 	clock-frequency = <400000>;
-
-	ak4643: codec@12 {
-		compatible = "asahi-kasei,ak4643";
-		#sound-dai-cells = <0>;
-		reg = <0x12>;
-	};
-
-	composite-in@20 {
-		compatible = "adi,adv7180";
-		reg = <0x20>;
-		remote = <&vin0>;
-
-		port {
-			adv7180: endpoint {
-				bus-width = <8>;
-				remote-endpoint = <&vin0ep>;
-			};
-		};
-	};
-
-	hdmi@39 {
-		compatible = "adi,adv7511w";
-		reg = <0x39>;
-		interrupt-parent = <&gpio5>;
-		interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
-
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-		adi,input-style = <1>;
-		adi,input-justification = "evenly";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				adv7511_in: endpoint {
-					remote-endpoint = <&du_out_rgb0>;
-				};
-			};
-
-			port@1 {
-				reg = <1>;
-				adv7511_out: endpoint {
-					remote-endpoint = <&hdmi_con>;
-				};
-			};
-		};
-	};
 };
 
 &mmcif0 {
diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 106b4e1..d588efa 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -16,7 +16,6 @@
 
 / {
 	compatible = "renesas,r8a7794";
-	interrupt-parent = <&gic>;
 	#address-cells = <2>;
 	#size-cells = <2>;
 
@@ -34,6 +33,35 @@
 		vin1 = &vin1;
 	};
 
+	/*
+	 * The external audio clocks are configured as 0 Hz fixed frequency
+	 * clocks by default.
+	 * Boards that provide audio clocks should override them.
+	 */
+	audio_clka: audio_clka {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+	audio_clkb: audio_clkb {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+	audio_clkc: audio_clkc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External CAN clock */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board. */
+		clock-frequency = <0>;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -67,986 +95,6 @@
 		};
 	};
 
-	apmu@e6151000 {
-		compatible = "renesas,r8a7794-apmu", "renesas,apmu";
-		reg = <0 0xe6151000 0 0x188>;
-		cpus = <&cpu0 &cpu1>;
-	};
-
-	gic: interrupt-controller@f1001000 {
-		compatible = "arm,gic-400";
-		#interrupt-cells = <3>;
-		#address-cells = <0>;
-		interrupt-controller;
-		reg = <0 0xf1001000 0 0x1000>,
-			<0 0xf1002000 0 0x2000>,
-			<0 0xf1004000 0 0x2000>,
-			<0 0xf1006000 0 0x2000>;
-		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
-		clocks = <&cpg CPG_MOD 408>;
-		clock-names = "clk";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 408>;
-	};
-
-	gpio0: gpio@e6050000 {
-		compatible = "renesas,gpio-r8a7794", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6050000 0 0x50>;
-		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 0 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 912>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 912>;
-	};
-
-	gpio1: gpio@e6051000 {
-		compatible = "renesas,gpio-r8a7794", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6051000 0 0x50>;
-		interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 32 26>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 911>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 911>;
-	};
-
-	gpio2: gpio@e6052000 {
-		compatible = "renesas,gpio-r8a7794", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6052000 0 0x50>;
-		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 64 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 910>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 910>;
-	};
-
-	gpio3: gpio@e6053000 {
-		compatible = "renesas,gpio-r8a7794", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6053000 0 0x50>;
-		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 96 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 909>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 909>;
-	};
-
-	gpio4: gpio@e6054000 {
-		compatible = "renesas,gpio-r8a7794", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6054000 0 0x50>;
-		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 128 32>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 908>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 908>;
-	};
-
-	gpio5: gpio@e6055000 {
-		compatible = "renesas,gpio-r8a7794", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055000 0 0x50>;
-		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 160 28>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 907>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 907>;
-	};
-
-	gpio6: gpio@e6055400 {
-		compatible = "renesas,gpio-r8a7794", "renesas,rcar-gen2-gpio";
-		reg = <0 0xe6055400 0 0x50>;
-		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-ranges = <&pfc 0 192 26>;
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		clocks = <&cpg CPG_MOD 905>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 905>;
-	};
-
-	cmt0: timer@ffca0000 {
-		compatible = "renesas,r8a7794-cmt0", "renesas,rcar-gen2-cmt0";
-		reg = <0 0xffca0000 0 0x1004>;
-		interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 124>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 124>;
-
-		status = "disabled";
-	};
-
-	cmt1: timer@e6130000 {
-		compatible = "renesas,r8a7794-cmt1", "renesas,rcar-gen2-cmt1";
-		reg = <0 0xe6130000 0 0x1004>;
-		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 329>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 329>;
-
-		status = "disabled";
-	};
-
-	timer {
-		compatible = "arm,armv7-timer";
-		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
-	};
-
-	irqc0: interrupt-controller@e61c0000 {
-		compatible = "renesas,irqc-r8a7794", "renesas,irqc";
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		reg = <0 0xe61c0000 0 0x200>;
-		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 407>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 407>;
-	};
-
-	pfc: pin-controller@e6060000 {
-		compatible = "renesas,pfc-r8a7794";
-		reg = <0 0xe6060000 0 0x11c>;
-	};
-
-	dmac0: dma-controller@e6700000 {
-		compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac";
-		reg = <0 0xe6700000 0 0x20000>;
-		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12", "ch13", "ch14";
-		clocks = <&cpg CPG_MOD 219>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 219>;
-		#dma-cells = <1>;
-		dma-channels = <15>;
-	};
-
-	dmac1: dma-controller@e6720000 {
-		compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac";
-		reg = <0 0xe6720000 0 0x20000>;
-		interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
-			      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				"ch0", "ch1", "ch2", "ch3",
-				"ch4", "ch5", "ch6", "ch7",
-				"ch8", "ch9", "ch10", "ch11",
-				"ch12", "ch13", "ch14";
-		clocks = <&cpg CPG_MOD 218>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 218>;
-		#dma-cells = <1>;
-		dma-channels = <15>;
-	};
-
-	audma0: dma-controller@ec700000 {
-		compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac";
-		reg = <0 0xec700000 0 0x10000>;
-		interrupts =	<GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
-				 GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error",
-				  "ch0", "ch1", "ch2", "ch3", "ch4", "ch5",
-				  "ch6", "ch7", "ch8", "ch9", "ch10", "ch11",
-				  "ch12";
-		clocks = <&cpg CPG_MOD 502>;
-		clock-names = "fck";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 502>;
-		#dma-cells = <1>;
-		dma-channels = <13>;
-	};
-
-	scifa0: serial@e6c40000 {
-		compatible = "renesas,scifa-r8a7794",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c40000 0 64>;
-		interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 204>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x21>, <&dmac0 0x22>,
-		       <&dmac1 0x21>, <&dmac1 0x22>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 204>;
-		status = "disabled";
-	};
-
-	scifa1: serial@e6c50000 {
-		compatible = "renesas,scifa-r8a7794",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c50000 0 64>;
-		interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 203>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x25>, <&dmac0 0x26>,
-		       <&dmac1 0x25>, <&dmac1 0x26>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 203>;
-		status = "disabled";
-	};
-
-	scifa2: serial@e6c60000 {
-		compatible = "renesas,scifa-r8a7794",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c60000 0 64>;
-		interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 202>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x27>, <&dmac0 0x28>,
-		       <&dmac1 0x27>, <&dmac1 0x28>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 202>;
-		status = "disabled";
-	};
-
-	scifa3: serial@e6c70000 {
-		compatible = "renesas,scifa-r8a7794",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c70000 0 64>;
-		interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1106>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
-		       <&dmac1 0x1b>, <&dmac1 0x1c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 1106>;
-		status = "disabled";
-	};
-
-	scifa4: serial@e6c78000 {
-		compatible = "renesas,scifa-r8a7794",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c78000 0 64>;
-		interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1107>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
-		       <&dmac1 0x1f>, <&dmac1 0x20>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 1107>;
-		status = "disabled";
-	};
-
-	scifa5: serial@e6c80000 {
-		compatible = "renesas,scifa-r8a7794",
-			     "renesas,rcar-gen2-scifa", "renesas,scifa";
-		reg = <0 0xe6c80000 0 64>;
-		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 1108>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x23>, <&dmac0 0x24>,
-		       <&dmac1 0x23>, <&dmac1 0x24>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 1108>;
-		status = "disabled";
-	};
-
-	scifb0: serial@e6c20000 {
-		compatible = "renesas,scifb-r8a7794",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6c20000 0 0x100>;
-		interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 206>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
-		       <&dmac1 0x3d>, <&dmac1 0x3e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 206>;
-		status = "disabled";
-	};
-
-	scifb1: serial@e6c30000 {
-		compatible = "renesas,scifb-r8a7794",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6c30000 0 0x100>;
-		interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 207>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
-		       <&dmac1 0x19>, <&dmac1 0x1a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 207>;
-		status = "disabled";
-	};
-
-	scifb2: serial@e6ce0000 {
-		compatible = "renesas,scifb-r8a7794",
-			     "renesas,rcar-gen2-scifb", "renesas,scifb";
-		reg = <0 0xe6ce0000 0 0x100>;
-		interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 216>;
-		clock-names = "fck";
-		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
-		       <&dmac1 0x1d>, <&dmac1 0x1e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 216>;
-		status = "disabled";
-	};
-
-	scif0: serial@e6e60000 {
-		compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e60000 0 64>;
-		interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 721>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
-		       <&dmac1 0x29>, <&dmac1 0x2a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 721>;
-		status = "disabled";
-	};
-
-	scif1: serial@e6e68000 {
-		compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e68000 0 64>;
-		interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 720>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
-		       <&dmac1 0x2d>, <&dmac1 0x2e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 720>;
-		status = "disabled";
-	};
-
-	scif2: serial@e6e58000 {
-		compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6e58000 0 64>;
-		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 719>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
-		       <&dmac1 0x2b>, <&dmac1 0x2c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 719>;
-		status = "disabled";
-	};
-
-	scif3: serial@e6ea8000 {
-		compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ea8000 0 64>;
-		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 718>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
-		       <&dmac1 0x2f>, <&dmac1 0x30>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 718>;
-		status = "disabled";
-	};
-
-	scif4: serial@e6ee0000 {
-		compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ee0000 0 64>;
-		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 715>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
-		       <&dmac1 0xfb>, <&dmac1 0xfc>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 715>;
-		status = "disabled";
-	};
-
-	scif5: serial@e6ee8000 {
-		compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif",
-			     "renesas,scif";
-		reg = <0 0xe6ee8000 0 64>;
-		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 714>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
-		       <&dmac1 0xfd>, <&dmac1 0xfe>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 714>;
-		status = "disabled";
-	};
-
-	hscif0: serial@e62c0000 {
-		compatible = "renesas,hscif-r8a7794",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62c0000 0 96>;
-		interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 717>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
-		       <&dmac1 0x39>, <&dmac1 0x3a>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 717>;
-		status = "disabled";
-	};
-
-	hscif1: serial@e62c8000 {
-		compatible = "renesas,hscif-r8a7794",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62c8000 0 96>;
-		interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 716>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
-		       <&dmac1 0x4d>, <&dmac1 0x4e>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 716>;
-		status = "disabled";
-	};
-
-	hscif2: serial@e62d0000 {
-		compatible = "renesas,hscif-r8a7794",
-			     "renesas,rcar-gen2-hscif", "renesas,hscif";
-		reg = <0 0xe62d0000 0 96>;
-		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 713>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
-			 <&scif_clk>;
-		clock-names = "fck", "brg_int", "scif_clk";
-		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
-		       <&dmac1 0x3b>, <&dmac1 0x3c>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 713>;
-		status = "disabled";
-	};
-
-	icram0:	sram@e63a0000 {
-		compatible = "mmio-sram";
-		reg = <0 0xe63a0000 0 0x12000>;
-	};
-
-	icram1:	sram@e63c0000 {
-		compatible = "mmio-sram";
-		reg = <0 0xe63c0000 0 0x1000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0 0xe63c0000 0x1000>;
-
-		smp-sram@0 {
-			compatible = "renesas,smp-sram";
-			reg = <0 0x10>;
-		};
-	};
-
-	ether: ethernet@ee700000 {
-		compatible = "renesas,ether-r8a7794",
-			     "renesas,rcar-gen2-ether";
-		reg = <0 0xee700000 0 0x400>;
-		interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 813>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 813>;
-		phy-mode = "rmii";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	avb: ethernet@e6800000 {
-		compatible = "renesas,etheravb-r8a7794",
-			     "renesas,etheravb-rcar-gen2";
-		reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
-		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 812>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 812>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	/* The memory map in the User's Manual maps the cores to bus numbers */
-	i2c0: i2c@e6508000 {
-		compatible = "renesas,i2c-r8a7794", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6508000 0 0x40>;
-		interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 931>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 931>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c1: i2c@e6518000 {
-		compatible = "renesas,i2c-r8a7794", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6518000 0 0x40>;
-		interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 930>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 930>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c2: i2c@e6530000 {
-		compatible = "renesas,i2c-r8a7794", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6530000 0 0x40>;
-		interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 929>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 929>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c3: i2c@e6540000 {
-		compatible = "renesas,i2c-r8a7794", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6540000 0 0x40>;
-		interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 928>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 928>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c4: i2c@e6520000 {
-		compatible = "renesas,i2c-r8a7794", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6520000 0 0x40>;
-		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 927>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 927>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c5: i2c@e6528000 {
-		compatible = "renesas,i2c-r8a7794", "renesas,rcar-gen2-i2c";
-		reg = <0 0xe6528000 0 0x40>;
-		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 925>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 925>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		i2c-scl-internal-delay-ns = <6>;
-		status = "disabled";
-	};
-
-	i2c6: i2c@e6500000 {
-		compatible = "renesas,iic-r8a7794", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6500000 0 0x425>;
-		interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 318>;
-		dmas = <&dmac0 0x61>, <&dmac0 0x62>,
-		       <&dmac1 0x61>, <&dmac1 0x62>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 318>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	i2c7: i2c@e6510000 {
-		compatible = "renesas,iic-r8a7794", "renesas,rcar-gen2-iic",
-			     "renesas,rmobile-iic";
-		reg = <0 0xe6510000 0 0x425>;
-		interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 323>;
-		dmas = <&dmac0 0x65>, <&dmac0 0x66>,
-		       <&dmac1 0x65>, <&dmac1 0x66>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 323>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	mmcif0: mmc@ee200000 {
-		compatible = "renesas,mmcif-r8a7794", "renesas,sh-mmcif";
-		reg = <0 0xee200000 0 0x80>;
-		interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 315>;
-		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
-		       <&dmac1 0xd1>, <&dmac1 0xd2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 315>;
-		reg-io-width = <4>;
-		status = "disabled";
-	};
-
-	sdhi0: sd@ee100000 {
-		compatible = "renesas,sdhi-r8a7794",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee100000 0 0x328>;
-		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 314>;
-		dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
-		       <&dmac1 0xcd>, <&dmac1 0xce>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <195000000>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 314>;
-		status = "disabled";
-	};
-
-	sdhi1: sd@ee140000 {
-		compatible = "renesas,sdhi-r8a7794",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee140000 0 0x100>;
-		interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 312>;
-		dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
-		       <&dmac1 0xc1>, <&dmac1 0xc2>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <97500000>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 312>;
-		status = "disabled";
-	};
-
-	sdhi2: sd@ee160000 {
-		compatible = "renesas,sdhi-r8a7794",
-			     "renesas,rcar-gen2-sdhi";
-		reg = <0 0xee160000 0 0x100>;
-		interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 311>;
-		dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
-		       <&dmac1 0xd3>, <&dmac1 0xd4>;
-		dma-names = "tx", "rx", "tx", "rx";
-		max-frequency = <97500000>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 311>;
-		status = "disabled";
-	};
-
-	qspi: spi@e6b10000 {
-		compatible = "renesas,qspi-r8a7794", "renesas,qspi";
-		reg = <0 0xe6b10000 0 0x2c>;
-		interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 917>;
-		dmas = <&dmac0 0x17>, <&dmac0 0x18>,
-		       <&dmac1 0x17>, <&dmac1 0x18>;
-		dma-names = "tx", "rx", "tx", "rx";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 917>;
-		num-cs = <1>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "disabled";
-	};
-
-	vin0: video@e6ef0000 {
-		compatible = "renesas,vin-r8a7794", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef0000 0 0x1000>;
-		interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 811>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 811>;
-		status = "disabled";
-	};
-
-	vin1: video@e6ef1000 {
-		compatible = "renesas,vin-r8a7794", "renesas,rcar-gen2-vin";
-		reg = <0 0xe6ef1000 0 0x1000>;
-		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 810>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 810>;
-		status = "disabled";
-	};
-
-	pci0: pci@ee090000 {
-		compatible = "renesas,pci-r8a7794", "renesas,pci-rcar-gen2";
-		device_type = "pci";
-		reg = <0 0xee090000 0 0xc00>,
-		      <0 0xee080000 0 0x1100>;
-		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 703>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 703>;
-		status = "disabled";
-
-		bus-range = <0 0>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		#interrupt-cells = <1>;
-		ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-		interrupt-map-mask = <0xff00 0 0 0x7>;
-		interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-				 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-				 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-
-		usb@1,0 {
-			reg = <0x800 0 0 0 0>;
-			phys = <&usb0 0>;
-			phy-names = "usb";
-		};
-
-		usb@2,0 {
-			reg = <0x1000 0 0 0 0>;
-			phys = <&usb0 0>;
-			phy-names = "usb";
-		};
-	};
-
-	pci1: pci@ee0d0000 {
-		compatible = "renesas,pci-r8a7794", "renesas,pci-rcar-gen2";
-		device_type = "pci";
-		reg = <0 0xee0d0000 0 0xc00>,
-		      <0 0xee0c0000 0 0x1100>;
-		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 703>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 703>;
-		status = "disabled";
-
-		bus-range = <1 1>;
-		#address-cells = <3>;
-		#size-cells = <2>;
-		#interrupt-cells = <1>;
-		ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-		interrupt-map-mask = <0xff00 0 0 0x7>;
-		interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-				 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-				 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-
-		usb@1,0 {
-			reg = <0x10800 0 0 0 0>;
-			phys = <&usb2 0>;
-			phy-names = "usb";
-		};
-
-		usb@2,0 {
-			reg = <0x11000 0 0 0 0>;
-			phys = <&usb2 0>;
-			phy-names = "usb";
-		};
-	};
-
-	hsusb: usb@e6590000 {
-		compatible = "renesas,usbhs-r8a7794", "renesas,rcar-gen2-usbhs";
-		reg = <0 0xe6590000 0 0x100>;
-		interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 704>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 704>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
-		status = "disabled";
-	};
-
-	usbphy: usb-phy@e6590100 {
-		compatible = "renesas,usb-phy-r8a7794",
-			     "renesas,rcar-gen2-usb-phy";
-		reg = <0 0xe6590100 0 0x100>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&cpg CPG_MOD 704>;
-		clock-names = "usbhs";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 704>;
-		status = "disabled";
-
-		usb0: usb-channel@0 {
-			reg = <0>;
-			#phy-cells = <1>;
-		};
-		usb2: usb-channel@2 {
-			reg = <2>;
-			#phy-cells = <1>;
-		};
-	};
-
-	vsp@fe928000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe928000 0 0x8000>;
-		interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 131>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 131>;
-	};
-
-	vsp@fe930000 {
-		compatible = "renesas,vsp1";
-		reg = <0 0xfe930000 0 0x8000>;
-		interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 128>;
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 128>;
-	};
-
-	du: display@feb00000 {
-		compatible = "renesas,du-r8a7794";
-		reg = <0 0xfeb00000 0 0x40000>;
-		reg-names = "du";
-		interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>;
-		clock-names = "du.0", "du.1";
-		status = "disabled";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				du_out_rgb0: endpoint {
-				};
-			};
-			port@1 {
-				reg = <1>;
-				du_out_rgb1: endpoint {
-				};
-			};
-		};
-	};
-
-	can0: can@e6e80000 {
-		compatible = "renesas,can-r8a7794", "renesas,rcar-gen2-can";
-		reg = <0 0xe6e80000 0 0x1000>;
-		interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 916>, <&cpg CPG_CORE R8A7794_CLK_RCAN>,
-			 <&can_clk>;
-		clock-names = "clkp1", "clkp2", "can_clk";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 916>;
-		status = "disabled";
-	};
-
-	can1: can@e6e88000 {
-		compatible = "renesas,can-r8a7794", "renesas,rcar-gen2-can";
-		reg = <0 0xe6e88000 0 0x1000>;
-		interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cpg CPG_MOD 915>, <&cpg CPG_CORE R8A7794_CLK_RCAN>,
-			 <&can_clk>;
-		clock-names = "clkp1", "clkp2", "can_clk";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 915>;
-		status = "disabled";
-	};
-
 	/* External root clock */
 	extal_clk: extal {
 		compatible = "fixed-clock";
@@ -1055,21 +103,6 @@
 		clock-frequency = <0>;
 	};
 
-	/* External USB clock - can be overridden by the board */
-	usb_extal_clk: usb_extal {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <48000000>;
-	};
-
-	/* External CAN clock */
-	can_clk: can {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		/* This value must be overridden by the board. */
-		clock-frequency = <0>;
-	};
-
 	/* External SCIF clock */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -1078,279 +111,1297 @@
 		clock-frequency = <0>;
 	};
 
-	/*
-	 * The external audio clocks are configured  as 0 Hz fixed
-	 * frequency clocks by default.  Boards that provide audio
-	 * clocks should override them.
-	 */
-	audio_clka: audio_clka {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-	audio_clkb: audio_clkb {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
-	audio_clkc: audio_clkc {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
-	};
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
 
-	cpg: clock-controller@e6150000 {
-		compatible = "renesas,r8a7794-cpg-mssr";
-		reg = <0 0xe6150000 0 0x1000>;
-		clocks = <&extal_clk>, <&usb_extal_clk>;
-		clock-names = "extal", "usb_extal";
-		#clock-cells = <2>;
-		#power-domain-cells = <0>;
-		#reset-cells = <1>;
-	};
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
 
-	rst: reset-controller@e6160000 {
-		compatible = "renesas,r8a7794-rst";
-		reg = <0 0xe6160000 0 0x0100>;
-	};
+		gpio0: gpio@e6050000 {
+			compatible = "renesas,gpio-r8a7794",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6050000 0 0x50>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 0 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 912>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 912>;
+		};
 
-	prr: chipid@ff000044 {
-		compatible = "renesas,prr";
-		reg = <0 0xff000044 0 4>;
-	};
+		gpio1: gpio@e6051000 {
+			compatible = "renesas,gpio-r8a7794",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6051000 0 0x50>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 32 26>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 911>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 911>;
+		};
 
-	sysc: system-controller@e6180000 {
-		compatible = "renesas,r8a7794-sysc";
-		reg = <0 0xe6180000 0 0x0200>;
-		#power-domain-cells = <1>;
-	};
+		gpio2: gpio@e6052000 {
+			compatible = "renesas,gpio-r8a7794",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6052000 0 0x50>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 64 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 910>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 910>;
+		};
 
-	ipmmu_sy0: mmu@e6280000 {
-		compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6280000 0 0x1000>;
-		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio3: gpio@e6053000 {
+			compatible = "renesas,gpio-r8a7794",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6053000 0 0x50>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 96 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 909>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 909>;
+		};
 
-	ipmmu_sy1: mmu@e6290000 {
-		compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6290000 0 0x1000>;
-		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio4: gpio@e6054000 {
+			compatible = "renesas,gpio-r8a7794",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6054000 0 0x50>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 128 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 908>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 908>;
+		};
 
-	ipmmu_ds: mmu@e6740000 {
-		compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
-		reg = <0 0xe6740000 0 0x1000>;
-		interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio5: gpio@e6055000 {
+			compatible = "renesas,gpio-r8a7794",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055000 0 0x50>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 160 28>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 907>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 907>;
+		};
 
-	ipmmu_mp: mmu@ec680000 {
-		compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
-		reg = <0 0xec680000 0 0x1000>;
-		interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		gpio6: gpio@e6055400 {
+			compatible = "renesas,gpio-r8a7794",
+				     "renesas,rcar-gen2-gpio";
+			reg = <0 0xe6055400 0 0x50>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 192 26>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 905>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 905>;
+		};
 
-	ipmmu_mx: mmu@fe951000 {
-		compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
-		reg = <0 0xfe951000 0 0x1000>;
-		interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a7794";
+			reg = <0 0xe6060000 0 0x11c>;
+		};
 
-	ipmmu_gp: mmu@e62a0000 {
-		compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
-		reg = <0 0xe62a0000 0 0x1000>;
-		interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
-		#iommu-cells = <1>;
-		status = "disabled";
-	};
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7794-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&usb_extal_clk>;
+			clock-names = "extal", "usb_extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
 
-	rcar_sound: sound@ec500000 {
-		/*
-		 * #sound-dai-cells is required
-		 *
-		 * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
-		 * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
+		apmu@e6151000 {
+			compatible = "renesas,r8a7794-apmu", "renesas,apmu";
+			reg = <0 0xe6151000 0 0x188>;
+			cpus = <&cpu0 &cpu1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7794-rst";
+			reg = <0 0xe6160000 0 0x0100>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7794-sysc";
+			reg = <0 0xe6180000 0 0x0200>;
+			#power-domain-cells = <1>;
+		};
+
+		irqc0: interrupt-controller@e61c0000 {
+			compatible = "renesas,irqc-r8a7794", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 407>;
+		};
+
+		ipmmu_sy0: mmu@e6280000 {
+			compatible = "renesas,ipmmu-r8a7794",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6280000 0 0x1000>;
+			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_sy1: mmu@e6290000 {
+			compatible = "renesas,ipmmu-r8a7794",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6290000 0 0x1000>;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_ds: mmu@e6740000 {
+			compatible = "renesas,ipmmu-r8a7794",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe6740000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_mp: mmu@ec680000 {
+			compatible = "renesas,ipmmu-r8a7794",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xec680000 0 0x1000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_mx: mmu@fe951000 {
+			compatible = "renesas,ipmmu-r8a7794",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xfe951000 0 0x1000>;
+			interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		ipmmu_gp: mmu@e62a0000 {
+			compatible = "renesas,ipmmu-r8a7794",
+				     "renesas,ipmmu-vmsa";
+			reg = <0 0xe62a0000 0 0x1000>;
+			interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
+		icram0:	sram@e63a0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63a0000 0 0x12000>;
+		};
+
+		icram1:	sram@e63c0000 {
+			compatible = "mmio-sram";
+			reg = <0 0xe63c0000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0xe63c0000 0x1000>;
+
+			smp-sram@0 {
+				compatible = "renesas,smp-sram";
+				reg = <0 0x10>;
+			};
+		};
+
+		/* The memory map in the User's Manual maps the cores to
+		 * bus numbers
 		 */
-		compatible = "renesas,rcar_sound-r8a7794",
-			     "renesas,rcar_sound-gen2";
-		reg =	<0 0xec500000 0 0x1000>, /* SCU */
-			<0 0xec5a0000 0 0x100>,  /* ADG */
-			<0 0xec540000 0 0x1000>, /* SSIU */
-			<0 0xec541000 0 0x280>,  /* SSI */
-			<0 0xec740000 0 0x200>;  /* Audio DMAC peri peri */
-		reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+		i2c0: i2c@e6508000 {
+			compatible = "renesas,i2c-r8a7794",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
 
-		clocks = <&cpg CPG_MOD 1005>,
-			 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
-			 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
-			 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
-			 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
-			 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
-			 <&cpg CPG_MOD 1025>, <&cpg CPG_MOD 1026>,
-			 <&cpg CPG_MOD 1027>, <&cpg CPG_MOD 1028>,
-			 <&cpg CPG_MOD 1029>, <&cpg CPG_MOD 1030>,
-			 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
-			 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
-			 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
-			 <&audio_clka>, <&audio_clkb>, <&audio_clkc>,
-			 <&cpg CPG_CORE R8A7794_CLK_M2>;
-		clock-names = "ssi-all",
-			      "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
-			      "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0",
-			      "src.6", "src.5", "src.4", "src.3", "src.2",
-			      "src.1",
-			      "ctu.0", "ctu.1",
-			      "mix.0", "mix.1",
-			      "dvc.0", "dvc.1",
-			      "clk_a", "clk_b", "clk_c", "clk_i";
-		power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
-		resets = <&cpg 1005>,
-			 <&cpg 1006>, <&cpg 1007>, <&cpg 1008>, <&cpg 1009>,
-			 <&cpg 1010>, <&cpg 1011>, <&cpg 1012>, <&cpg 1013>,
-			 <&cpg 1014>, <&cpg 1015>;
-		reset-names = "ssi-all",
-			      "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5",
-			      "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0";
+		i2c1: i2c@e6518000 {
+			compatible = "renesas,i2c-r8a7794",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6518000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
 
-		status = "disabled";
+		i2c2: i2c@e6530000 {
+			compatible = "renesas,i2c-r8a7794",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6530000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
 
-		rcar_sound,dvc {
-			dvc0: dvc-0 {
-				dmas = <&audma0 0xbc>;
-				dma-names = "tx";
+		i2c3: i2c@e6540000 {
+			compatible = "renesas,i2c-r8a7794",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6540000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e6520000 {
+			compatible = "renesas,i2c-r8a7794",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6520000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c5: i2c@e6528000 {
+			compatible = "renesas,i2c-r8a7794",
+				     "renesas,rcar-gen2-i2c";
+			reg = <0 0xe6528000 0 0x40>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 925>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 925>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c6: i2c@e6500000 {
+			compatible = "renesas,iic-r8a7794",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6500000 0 0x425>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>;
+			dmas = <&dmac0 0x61>, <&dmac0 0x62>,
+			       <&dmac1 0x61>, <&dmac1 0x62>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c7: i2c@e6510000 {
+			compatible = "renesas,iic-r8a7794",
+				     "renesas,rcar-gen2-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe6510000 0 0x425>;
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 323>;
+			dmas = <&dmac0 0x65>, <&dmac0 0x66>,
+			       <&dmac1 0x65>, <&dmac1 0x66>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 323>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a7794",
+				     "renesas,rcar-gen2-usbhs";
+			reg = <0 0xe6590000 0 0x100>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			renesas,buswait = <4>;
+			phys = <&usb0 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		usbphy: usb-phy@e6590100 {
+			compatible = "renesas,usb-phy-r8a7794",
+				     "renesas,rcar-gen2-usb-phy";
+			reg = <0 0xe6590100 0 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cpg CPG_MOD 704>;
+			clock-names = "usbhs";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 704>;
+			status = "disabled";
+
+			usb0: usb-channel@0 {
+				reg = <0>;
+				#phy-cells = <1>;
 			};
-			dvc1: dvc-1 {
-				dmas = <&audma0 0xbe>;
-				dma-names = "tx";
+			usb2: usb-channel@2 {
+				reg = <2>;
+				#phy-cells = <1>;
 			};
 		};
 
-		rcar_sound,mix {
-			mix0: mix-0 { };
-			mix1: mix-1 { };
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a7794",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x20000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 219>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
 		};
 
-		rcar_sound,ctu {
-			ctu00: ctu-0 { };
-			ctu01: ctu-1 { };
-			ctu02: ctu-2 { };
-			ctu03: ctu-3 { };
-			ctu10: ctu-4 { };
-			ctu11: ctu-5 { };
-			ctu12: ctu-6 { };
-			ctu13: ctu-7 { };
+		dmac1: dma-controller@e6720000 {
+			compatible = "renesas,dmac-r8a7794",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6720000 0 0x20000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
 		};
 
-		rcar_sound,src {
-			src-0 {
-				status = "disabled";
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a7794",
+				     "renesas,etheravb-rcar-gen2";
+			reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 812>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		qspi: spi@e6b10000 {
+			compatible = "renesas,qspi-r8a7794", "renesas,qspi";
+			reg = <0 0xe6b10000 0 0x2c>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 917>;
+			dmas = <&dmac0 0x17>, <&dmac0 0x18>,
+			       <&dmac1 0x17>, <&dmac1 0x18>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+			num-cs = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		scifa0: serial@e6c40000 {
+			compatible = "renesas,scifa-r8a7794",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x21>, <&dmac0 0x22>,
+			       <&dmac1 0x21>, <&dmac1 0x22>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scifa1: serial@e6c50000 {
+			compatible = "renesas,scifa-r8a7794",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x25>, <&dmac0 0x26>,
+			       <&dmac1 0x25>, <&dmac1 0x26>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		scifa2: serial@e6c60000 {
+			compatible = "renesas,scifa-r8a7794",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c60000 0 64>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x27>, <&dmac0 0x28>,
+			       <&dmac1 0x27>, <&dmac1 0x28>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 202>;
+			status = "disabled";
+		};
+
+		scifa3: serial@e6c70000 {
+			compatible = "renesas,scifa-r8a7794",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c70000 0 64>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1106>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
+			       <&dmac1 0x1b>, <&dmac1 0x1c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 1106>;
+			status = "disabled";
+		};
+
+		scifa4: serial@e6c78000 {
+			compatible = "renesas,scifa-r8a7794",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c78000 0 64>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1107>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
+			       <&dmac1 0x1f>, <&dmac1 0x20>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 1107>;
+			status = "disabled";
+		};
+
+		scifa5: serial@e6c80000 {
+			compatible = "renesas,scifa-r8a7794",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c80000 0 64>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1108>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x23>, <&dmac0 0x24>,
+			       <&dmac1 0x23>, <&dmac1 0x24>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 1108>;
+			status = "disabled";
+		};
+
+		scifb0: serial@e6c20000 {
+			compatible = "renesas,scifb-r8a7794",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c20000 0 0x100>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
+			       <&dmac1 0x3d>, <&dmac1 0x3e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 206>;
+			status = "disabled";
+		};
+
+		scifb1: serial@e6c30000 {
+			compatible = "renesas,scifb-r8a7794",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c30000 0 0x100>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
+			       <&dmac1 0x19>, <&dmac1 0x1a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 207>;
+			status = "disabled";
+		};
+
+		scifb2: serial@e6ce0000 {
+			compatible = "renesas,scifb-r8a7794",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6ce0000 0 0x100>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 216>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
+			       <&dmac1 0x1d>, <&dmac1 0x1e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 216>;
+			status = "disabled";
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a7794",
+				     "renesas,rcar-gen2-scif",
+				     "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 721>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
+			       <&dmac1 0x29>, <&dmac1 0x2a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 721>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a7794",
+				     "renesas,rcar-gen2-scif",
+				     "renesas,scif";
+			reg = <0 0xe6e68000 0 64>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 720>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
+			       <&dmac1 0x2d>, <&dmac1 0x2e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 720>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e58000 {
+			compatible = "renesas,scif-r8a7794",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e58000 0 64>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 719>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
+			       <&dmac1 0x2b>, <&dmac1 0x2c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 719>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6ea8000 {
+			compatible = "renesas,scif-r8a7794",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ea8000 0 64>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 718>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
+			       <&dmac1 0x2f>, <&dmac1 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 718>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6ee0000 {
+			compatible = "renesas,scif-r8a7794",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee0000 0 64>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 715>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
+			       <&dmac1 0xfb>, <&dmac1 0xfc>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 715>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6ee8000 {
+			compatible = "renesas,scif-r8a7794",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee8000 0 64>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 714>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
+			       <&dmac1 0xfd>, <&dmac1 0xfe>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 714>;
+			status = "disabled";
+		};
+
+		hscif0: serial@e62c0000 {
+			compatible = "renesas,hscif-r8a7794",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c0000 0 96>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 717>,
+				 <&cpg CPG_CORE R8A7794_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
+			       <&dmac1 0x39>, <&dmac1 0x3a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 717>;
+			status = "disabled";
+		};
+
+		hscif1: serial@e62c8000 {
+			compatible = "renesas,hscif-r8a7794",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c8000 0 96>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>,
+				 <&cpg CPG_CORE R8A7794_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
+			       <&dmac1 0x4d>, <&dmac1 0x4e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 716>;
+			status = "disabled";
+		};
+
+		hscif2: serial@e62d0000 {
+			compatible = "renesas,hscif-r8a7794",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62d0000 0 96>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 713>, <&cpg CPG_CORE R8A7794_CLK_ZS>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
+			       <&dmac1 0x3b>, <&dmac1 0x3c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 713>;
+			status = "disabled";
+		};
+
+		can0: can@e6e80000 {
+			compatible = "renesas,can-r8a7794",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e80000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>, <&cpg CPG_CORE R8A7794_CLK_RCAN>,
+				 <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+			status = "disabled";
+		};
+
+		can1: can@e6e88000 {
+			compatible = "renesas,can-r8a7794",
+				     "renesas,rcar-gen2-can";
+			reg = <0 0xe6e88000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>, <&cpg CPG_CORE R8A7794_CLK_RCAN>,
+				 <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 915>;
+			status = "disabled";
+		};
+
+		vin0: video@e6ef0000 {
+			compatible = "renesas,vin-r8a7794",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef0000 0 0x1000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 811>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 811>;
+			status = "disabled";
+		};
+
+		vin1: video@e6ef1000 {
+			compatible = "renesas,vin-r8a7794",
+				     "renesas,rcar-gen2-vin";
+			reg = <0 0xe6ef1000 0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 810>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 810>;
+			status = "disabled";
+		};
+
+		rcar_sound: sound@ec500000 {
+			/*
+			 * #sound-dai-cells is required
+			 *
+			 * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
+			 * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
+			 */
+			compatible = "renesas,rcar_sound-r8a7794",
+				     "renesas,rcar_sound-gen2";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri */
+			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+			clocks = <&cpg CPG_MOD 1005>,
+				 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+				 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+				 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+				 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+				 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+				 <&cpg CPG_MOD 1025>, <&cpg CPG_MOD 1026>,
+				 <&cpg CPG_MOD 1027>, <&cpg CPG_MOD 1028>,
+				 <&cpg CPG_MOD 1029>, <&cpg CPG_MOD 1030>,
+				 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
+				 <&cpg CPG_MOD 1021>, <&cpg CPG_MOD 1020>,
+				 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+				 <&audio_clka>, <&audio_clkb>, <&audio_clkc>,
+				 <&cpg CPG_CORE R8A7794_CLK_M2>;
+			clock-names = "ssi-all",
+				      "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+				      "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+				      "ssi.1", "ssi.0",
+				      "src.6", "src.5", "src.4", "src.3",
+				      "src.2", "src.1",
+				      "ctu.0", "ctu.1",
+				      "mix.0", "mix.1",
+				      "dvc.0", "dvc.1",
+				      "clk_a", "clk_b", "clk_c", "clk_i";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 1005>,
+				 <&cpg 1006>, <&cpg 1007>,
+				 <&cpg 1008>, <&cpg 1009>,
+				 <&cpg 1010>, <&cpg 1011>,
+				 <&cpg 1012>, <&cpg 1013>,
+				 <&cpg 1014>, <&cpg 1015>;
+			reset-names = "ssi-all",
+				      "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+				      "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+				      "ssi.1", "ssi.0";
+
+			status = "disabled";
+
+			rcar_sound,dvc {
+				dvc0: dvc-0 {
+					dmas = <&audma0 0xbc>;
+					dma-names = "tx";
+				};
+				dvc1: dvc-1 {
+					dmas = <&audma0 0xbe>;
+					dma-names = "tx";
+				};
 			};
-			src1: src-1 {
-				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x87>, <&audma0 0x9c>;
-				dma-names = "rx", "tx";
+
+			rcar_sound,mix {
+				mix0: mix-0 { };
+				mix1: mix-1 { };
 			};
-			src2: src-2 {
-				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x89>, <&audma0 0x9e>;
-				dma-names = "rx", "tx";
+
+			rcar_sound,ctu {
+				ctu00: ctu-0 { };
+				ctu01: ctu-1 { };
+				ctu02: ctu-2 { };
+				ctu03: ctu-3 { };
+				ctu10: ctu-4 { };
+				ctu11: ctu-5 { };
+				ctu12: ctu-6 { };
+				ctu13: ctu-7 { };
 			};
-			src3: src-3 {
-				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8b>, <&audma0 0xa0>;
-				dma-names = "rx", "tx";
+
+			rcar_sound,src {
+				src-0 {
+					status = "disabled";
+				};
+				src1: src-1 {
+					interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x87>, <&audma0 0x9c>;
+					dma-names = "rx", "tx";
+				};
+				src2: src-2 {
+					interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x89>, <&audma0 0x9e>;
+					dma-names = "rx", "tx";
+				};
+				src3: src-3 {
+					interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8b>, <&audma0 0xa0>;
+					dma-names = "rx", "tx";
+				};
+				src4: src-4 {
+					interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8d>, <&audma0 0xb0>;
+					dma-names = "rx", "tx";
+				};
+				src5: src-5 {
+					interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x8f>, <&audma0 0xb2>;
+					dma-names = "rx", "tx";
+				};
+				src6: src-6 {
+					interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x91>, <&audma0 0xb4>;
+					dma-names = "rx", "tx";
+				};
 			};
-			src4: src-4 {
-				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8d>, <&audma0 0xb0>;
-				dma-names = "rx", "tx";
-			};
-			src5: src-5 {
-				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x8f>, <&audma0 0xb2>;
-				dma-names = "rx", "tx";
-			};
-			src6: src-6 {
-				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x91>, <&audma0 0xb4>;
-				dma-names = "rx", "tx";
+
+			rcar_sound,ssi {
+				ssi0: ssi-0 {
+					interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x01>, <&audma0 0x02>,
+					       <&audma0 0x15>, <&audma0 0x16>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi1: ssi-1 {
+					interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x03>, <&audma0 0x04>,
+					       <&audma0 0x49>, <&audma0 0x4a>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi2: ssi-2 {
+					interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x05>, <&audma0 0x06>,
+					       <&audma0 0x63>, <&audma0 0x64>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi3: ssi-3 {
+					interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x07>, <&audma0 0x08>,
+					       <&audma0 0x6f>, <&audma0 0x70>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi4: ssi-4 {
+					interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x09>, <&audma0 0x0a>,
+					       <&audma0 0x71>, <&audma0 0x72>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi5: ssi-5 {
+					interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0b>, <&audma0 0x0c>,
+					       <&audma0 0x73>, <&audma0 0x74>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi6: ssi-6 {
+					interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0d>, <&audma0 0x0e>,
+					       <&audma0 0x75>, <&audma0 0x76>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi7: ssi-7 {
+					interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x0f>, <&audma0 0x10>,
+					       <&audma0 0x79>, <&audma0 0x7a>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi8: ssi-8 {
+					interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x11>, <&audma0 0x12>,
+					       <&audma0 0x7b>, <&audma0 0x7c>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
+				ssi9: ssi-9 {
+					interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&audma0 0x13>, <&audma0 0x14>,
+					       <&audma0 0x7d>, <&audma0 0x7e>;
+					dma-names = "rx", "tx", "rxu", "txu";
+				};
 			};
 		};
 
-		rcar_sound,ssi {
-			ssi0: ssi-0 {
-				interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x01>, <&audma0 0x02>,
-				       <&audma0 0x15>, <&audma0 0x16>;
-				dma-names = "rx", "tx", "rxu", "txu";
+		audma0: dma-controller@ec700000 {
+			compatible = "renesas,dmac-r8a7794",
+				     "renesas,rcar-dmac";
+			reg = <0 0xec700000 0 0x10000>;
+			interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3", "ch4",
+					  "ch5", "ch6", "ch7", "ch8", "ch9",
+					  "ch10", "ch11",
+					  "ch12";
+			clocks = <&cpg CPG_MOD 502>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 502>;
+			#dma-cells = <1>;
+			dma-channels = <13>;
+		};
+
+		pci0: pci@ee090000 {
+			compatible = "renesas,pci-r8a7794",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee090000 0 0xc00>,
+			      <0 0xee080000 0 0x1100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x800 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
 			};
-			ssi1: ssi-1 {
-				interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x03>, <&audma0 0x04>,
-				       <&audma0 0x49>, <&audma0 0x4a>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi2: ssi-2 {
-				interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x05>, <&audma0 0x06>,
-				       <&audma0 0x63>, <&audma0 0x64>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi3: ssi-3 {
-				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x07>, <&audma0 0x08>,
-				       <&audma0 0x6f>, <&audma0 0x70>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi4: ssi-4 {
-				interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x09>, <&audma0 0x0a>,
-				       <&audma0 0x71>, <&audma0 0x72>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi5: ssi-5 {
-				interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0b>, <&audma0 0x0c>,
-				       <&audma0 0x73>, <&audma0 0x74>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi6: ssi-6 {
-				interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0d>, <&audma0 0x0e>,
-				       <&audma0 0x75>, <&audma0 0x76>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi7: ssi-7 {
-				interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x0f>, <&audma0 0x10>,
-				       <&audma0 0x79>, <&audma0 0x7a>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi8: ssi-8 {
-				interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x11>, <&audma0 0x12>,
-				       <&audma0 0x7b>, <&audma0 0x7c>;
-				dma-names = "rx", "tx", "rxu", "txu";
-			};
-			ssi9: ssi-9 {
-				interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
-				dmas = <&audma0 0x13>, <&audma0 0x14>,
-				       <&audma0 0x7d>, <&audma0 0x7e>;
-				dma-names = "rx", "tx", "rxu", "txu";
+
+			usb@2,0 {
+				reg = <0x1000 0 0 0 0>;
+				phys = <&usb0 0>;
+				phy-names = "usb";
 			};
 		};
+
+		pci1: pci@ee0d0000 {
+			compatible = "renesas,pci-r8a7794",
+				     "renesas,pci-rcar-gen2";
+			device_type = "pci";
+			reg = <0 0xee0d0000 0 0xc00>,
+			      <0 0xee0c0000 0 0x1100>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 703>;
+			status = "disabled";
+
+			bus-range = <1 1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
+			interrupt-map-mask = <0xff00 0 0 0x7>;
+			interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
+					 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+
+			usb@1,0 {
+				reg = <0x10800 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+
+			usb@2,0 {
+				reg = <0x11000 0 0 0 0>;
+				phys = <&usb2 0>;
+				phy-names = "usb";
+			};
+		};
+
+		sdhi0: sd@ee100000 {
+			compatible = "renesas,sdhi-r8a7794",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee100000 0 0x328>;
+			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 314>;
+			dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
+			       <&dmac1 0xcd>, <&dmac1 0xce>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <195000000>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 314>;
+			status = "disabled";
+		};
+
+		sdhi1: sd@ee140000 {
+			compatible = "renesas,sdhi-r8a7794",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee140000 0 0x100>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 312>;
+			dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
+			       <&dmac1 0xc1>, <&dmac1 0xc2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 312>;
+			status = "disabled";
+		};
+
+		sdhi2: sd@ee160000 {
+			compatible = "renesas,sdhi-r8a7794",
+				     "renesas,rcar-gen2-sdhi";
+			reg = <0 0xee160000 0 0x100>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 311>;
+			dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
+			       <&dmac1 0xd3>, <&dmac1 0xd4>;
+			dma-names = "tx", "rx", "tx", "rx";
+			max-frequency = <97500000>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 311>;
+			status = "disabled";
+		};
+
+		mmcif0: mmc@ee200000 {
+			compatible = "renesas,mmcif-r8a7794",
+				     "renesas,sh-mmcif";
+			reg = <0 0xee200000 0 0x80>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 315>;
+			dmas = <&dmac0 0xd1>, <&dmac0 0xd2>,
+			       <&dmac1 0xd1>, <&dmac1 0xd2>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 315>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		ether: ethernet@ee700000 {
+			compatible = "renesas,ether-r8a7794",
+				     "renesas,rcar-gen2-ether";
+			reg = <0 0xee700000 0 0x400>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 813>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 813>;
+			phy-mode = "rmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>,
+			      <0 0xf1002000 0 0x2000>,
+			      <0 0xf1004000 0 0x2000>,
+			      <0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 408>;
+		};
+
+		vsp@fe928000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe928000 0 0x8000>;
+			interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 131>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 131>;
+		};
+
+		vsp@fe930000 {
+			compatible = "renesas,vsp1";
+			reg = <0 0xfe930000 0 0x8000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 128>;
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 128>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a7794";
+			reg = <0 0xfeb00000 0 0x40000>;
+			reg-names = "du";
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>;
+			clock-names = "du.0", "du.1";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb0: endpoint {
+					};
+				};
+				port@1 {
+					reg = <1>;
+					du_out_rgb1: endpoint {
+					};
+				};
+			};
+		};
+
+		prr: chipid@ff000044 {
+			compatible = "renesas,prr";
+			reg = <0 0xff000044 0 4>;
+		};
+
+		cmt0: timer@ffca0000 {
+			compatible = "renesas,r8a7794-cmt0",
+				     "renesas,rcar-gen2-cmt0";
+			reg = <0 0xffca0000 0 0x1004>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 124>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 124>;
+
+			status = "disabled";
+		};
+
+		cmt1: timer@e6130000 {
+			compatible = "renesas,r8a7794-cmt1",
+				     "renesas,rcar-gen2-cmt1";
+			reg = <0 0xe6130000 0 0x1004>;
+			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 329>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+			resets = <&cpg 329>;
+
+			status = "disabled";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	/* External USB clock - can be overridden by the board */
+	usb_extal_clk: usb_extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 341deaf..df1e478 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -233,7 +233,7 @@
 	};
 
 	grf: syscon@11000000 {
-		compatible = "syscon", "simple-mfd";
+		compatible = "rockchip,rk3228-grf", "syscon", "simple-mfd";
 		reg = <0x11000000 0x1000>;
 		#address-cells = <1>;
 		#size-cells = <1>;
diff --git a/arch/arm/boot/dts/rk3288-phycore-rdk.dts b/arch/arm/boot/dts/rk3288-phycore-rdk.dts
index 1241cbc..985743f 100644
--- a/arch/arm/boot/dts/rk3288-phycore-rdk.dts
+++ b/arch/arm/boot/dts/rk3288-phycore-rdk.dts
@@ -265,7 +265,11 @@
 	disable-wp;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
-	vmmc-supply = <&vdd_io_sd>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vdd_sd>;
 	vqmmc-supply = <&vdd_io_sd>;
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/rk3288-phycore-som.dtsi b/arch/arm/boot/dts/rk3288-phycore-som.dtsi
index 5eae477..f13bcb1 100644
--- a/arch/arm/boot/dts/rk3288-phycore-som.dtsi
+++ b/arch/arm/boot/dts/rk3288-phycore-som.dtsi
@@ -336,11 +336,10 @@
 				regulator-name = "vdd_io_sd";
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-min-microvolt = <3300000>;
+				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
 				regulator-state-mem {
-					regulator-on-in-suspend;
-					regulator-suspend-microvolt = <3300000>;
+					regulator-off-in-suspend;
 				};
 			};
 		};
diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
index b9c471f..51f36a1 100644
--- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi
+++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
@@ -280,6 +280,10 @@
 	};
 };
 
+&saradc {
+	vref-supply = <&vcc_18>;
+};
+
 &tsadc {
 	rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
 	rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts
index 0e084b8..8ccc89d 100644
--- a/arch/arm/boot/dts/rk3288-rock2-square.dts
+++ b/arch/arm/boot/dts/rk3288-rock2-square.dts
@@ -39,6 +39,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/input/input.h>
 #include "rk3288-rock2-som.dtsi"
 
 / {
@@ -49,6 +50,32 @@
 		stdout-path = "serial2:115200n8";
 	};
 
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+
+		button-recovery {
+			label = "Recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		power {
+			gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+			label = "GPIO Power";
+			linux,code = <KEY_POWER>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pwr_key>;
+			wakeup-source;
+		};
+	};
+
 	gpio-leds {
 		compatible = "gpio-leds";
 
@@ -220,6 +247,12 @@
 		};
 	};
 
+	keys {
+		pwr_key: pwr-key {
+			rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
 	pmic {
 		pmic_int: pmic-int {
 			rockchip,pins = <0 4 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -261,6 +294,10 @@
 	};
 };
 
+&saradc {
+	status = "okay";
+};
+
 &spdif {
 	status = "okay";
 };
@@ -284,3 +321,7 @@
 &usb_host1 {
 	status = "okay";
 };
+
+&usb_otg {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
index d752a31..be48711 100644
--- a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
@@ -92,7 +92,6 @@
 			248 249 250 251 252 253 254 255>;
 		default-brightness-level = <128>;
 		enable-gpios = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>;
-		backlight-boot-off;
 		pinctrl-names = "default";
 		pinctrl-0 = <&bl_en>;
 		pwms = <&pwm0 0 1000000 0>;
diff --git a/arch/arm/boot/dts/rk3288-vyasa.dts b/arch/arm/boot/dts/rk3288-vyasa.dts
index 9842a00..14c896bf 100644
--- a/arch/arm/boot/dts/rk3288-vyasa.dts
+++ b/arch/arm/boot/dts/rk3288-vyasa.dts
@@ -155,6 +155,17 @@
 	cpu0-supply = <&vdd_cpu>;
 };
 
+&emmc {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	disable-wp;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>;
+	vmmc-supply = <&vcc_io>;
+	status = "okay";
+};
+
 &gmac {
 	assigned-clocks = <&cru SCLK_MAC>;
 	assigned-clock-parents = <&ext_gmac>;
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index b9c05b5..eae5e1e 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -861,24 +861,24 @@
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE	/* conflicts with PWMFI2, ISI_D8 */
-							 AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* conflicts with ISI_PCK */
+							<AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* conflicts with PWMFI2, ISI_D8 */
+							 AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* conflicts with ISI_PCK */
 					};
 				};
 
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE	/* conflicts with TWD0, ISI_VSYNC */
-							 AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* conflicts with TWCK0, ISI_HSYNC */
+							<AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* conflicts with TWD0, ISI_VSYNC */
+							 AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* conflicts with TWCK0, ISI_HSYNC */
 					};
 				};
 
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD17 periph A */
-							 AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PD18 periph A with pullup */
+							<AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+							 AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;
 					};
 
 					pinctrl_usart0_rts_cts: usart0_rts_cts-0 {
@@ -891,8 +891,8 @@
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB28 periph A */
-							 AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PB29 periph A with pullup */
+							<AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+							 AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
 					};
 
 					pinctrl_usart1_rts_cts: usart1_rts_cts-0 {
@@ -905,8 +905,8 @@
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<AT91_PIOE 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PE25 periph B, conflicts with A25 */
-							 AT91_PIOE 26 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PE26 periph B with pullup, conflicts NCS0 */
+							<AT91_PIOE 25 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* conflicts with A25 */
+							 AT91_PIOE 26 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* conflicts NCS0 */
 					};
 
 					pinctrl_usart2_rts_cts: usart2_rts_cts-0 {
@@ -919,8 +919,8 @@
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<AT91_PIOE 18 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PE18 periph B, conflicts with A18 */
-							 AT91_PIOE 19 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PE19 periph B with pullup, conflicts with A19 */
+							<AT91_PIOE 18 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* conflicts with A18 */
+							 AT91_PIOE 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* conflicts with A19 */
 					};
 
 					pinctrl_usart3_rts_cts: usart3_rts_cts-0 {
diff --git a/arch/arm/boot/dts/sama5d34ek.dts b/arch/arm/boot/dts/sama5d34ek.dts
index c8b8449..15d5c46 100644
--- a/arch/arm/boot/dts/sama5d34ek.dts
+++ b/arch/arm/boot/dts/sama5d34ek.dts
@@ -38,7 +38,7 @@
 				status = "okay";
 
 				24c256@50 {
-					compatible = "24c256";
+					compatible = "atmel,24c256";
 					reg = <0x50>;
 					pagesize = <64>;
 				};
diff --git a/arch/arm/boot/dts/sama5d3_uart.dtsi b/arch/arm/boot/dts/sama5d3_uart.dtsi
index 186377d..f599f8a 100644
--- a/arch/arm/boot/dts/sama5d3_uart.dtsi
+++ b/arch/arm/boot/dts/sama5d3_uart.dtsi
@@ -23,16 +23,16 @@
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC29 periph A, conflicts with PWMFI2, ISI_D8 */
-							 AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PC30 periph A with pullup, conflicts with ISI_PCK */
+							<AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* conflicts with PWMFI2, ISI_D8 */
+							 AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* conflicts with ISI_PCK */
 					};
 				};
 
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA30 periph B, conflicts with TWD0, ISI_VSYNC */
-							 AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA31 periph B with pullup, conflicts with TWCK0, ISI_HSYNC */
+							<AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* conflicts with TWD0, ISI_VSYNC */
+							 AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* conflicts with TWCK0, ISI_HSYNC */
 					};
 				};
 			};
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index 373b362..0cf9bed 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -1379,7 +1379,7 @@
 			pinctrl@fc06a000 {
 				#address-cells = <1>;
 				#size-cells = <1>;
-				compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+				compatible = "atmel,sama5d3-pinctrl", "atmel,at91sam9x5-pinctrl", "simple-bus";
 				ranges = <0xfc068000 0xfc068000 0x100
 					  0xfc06a000 0xfc06a000 0x4000>;
 				/* WARNING: revisit as pin spec has changed */
@@ -1926,8 +1926,8 @@
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<AT91_PIOE 29 AT91_PERIPH_B AT91_PINCTRL_NONE		/* RXD */
-							 AT91_PIOE 30 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* TXD */
+							<AT91_PIOE 29 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* RXD */
+							 AT91_PIOE 30 AT91_PERIPH_B AT91_PINCTRL_NONE		/* TXD */
 							>;
 					};
 				};
@@ -1935,8 +1935,8 @@
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<AT91_PIOC 25 AT91_PERIPH_C AT91_PINCTRL_NONE		/* RXD */
-							 AT91_PIOC 26 AT91_PERIPH_C AT91_PINCTRL_PULL_UP	/* TXD */
+							<AT91_PIOC 25 AT91_PERIPH_C AT91_PINCTRL_PULL_UP	/* RXD */
+							 AT91_PIOC 26 AT91_PERIPH_C AT91_PINCTRL_NONE		/* TXD */
 							>;
 					};
 				};
@@ -1944,8 +1944,8 @@
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE		/* RXD */
-							 AT91_PIOD 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* TXD */
+							<AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* RXD */
+							 AT91_PIOD 13 AT91_PERIPH_A AT91_PINCTRL_NONE		/* TXD */
 							>;
 					};
 					pinctrl_usart0_rts: usart0_rts-0 {
@@ -1959,8 +1959,8 @@
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE		/* RXD */
-							 AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* TXD */
+							<AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* RXD */
+							 AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE		/* TXD */
 							>;
 					};
 					pinctrl_usart1_rts: usart1_rts-0 {
@@ -1974,8 +1974,8 @@
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE		/* RXD - conflicts with G0_CRS, ISI_HSYNC */
-							 AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP		/* TXD - conflicts with G0_COL, PCK2 */
+							<AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP		/* RXD - conflicts with G0_CRS, ISI_HSYNC */
+							 AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_NONE		/* TXD - conflicts with G0_COL, PCK2 */
 							>;
 					};
 					pinctrl_usart2_rts: usart2_rts-0 {
@@ -1989,8 +1989,8 @@
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<AT91_PIOE 16 AT91_PERIPH_B AT91_PINCTRL_NONE		/* RXD */
-							 AT91_PIOE 17 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* TXD */
+							<AT91_PIOE 16 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* RXD */
+							 AT91_PIOE 17 AT91_PERIPH_B AT91_PINCTRL_NONE		/* TXD */
 							>;
 					};
 				};
@@ -1998,8 +1998,8 @@
 				usart4 {
 					pinctrl_usart4: usart4-0 {
 						atmel,pins =
-							<AT91_PIOE 26 AT91_PERIPH_B AT91_PINCTRL_NONE		/* RXD */
-							 AT91_PIOE 27 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* TXD */
+							<AT91_PIOE 26 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* RXD */
+							 AT91_PIOE 27 AT91_PERIPH_B AT91_PINCTRL_NONE		/* TXD */
 							>;
 					};
 					pinctrl_usart4_rts: usart4_rts-0 {
diff --git a/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi b/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi
deleted file mode 100644
index dbdda36..0000000
--- a/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi
+++ /dev/null
@@ -1,68 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Timings and Geometry for Samsung K3PE0E000B memory part
- */
-
-/ {
-	samsung_K3PE0E000B: lpddr2 {
-		compatible	= "Samsung,K3PE0E000B","jedec,lpddr2-s4";
-		density		= <4096>;
-		io-width	= <32>;
-
-		tRPab-min-tck	= <3>;
-		tRCD-min-tck	= <3>;
-		tWR-min-tck	= <3>;
-		tRASmin-min-tck	= <3>;
-		tRRD-min-tck	= <2>;
-		tWTR-min-tck	= <2>;
-		tXP-min-tck	= <2>;
-		tRTP-min-tck	= <2>;
-		tCKE-min-tck	= <3>;
-		tCKESR-min-tck	= <3>;
-		tFAW-min-tck	= <8>;
-
-		timings_samsung_K3PE0E000B_533MHz: lpddr2-timings@0 {
-			compatible	= "jedec,lpddr2-timings";
-			min-freq	= <10000000>;
-			max-freq	= <533333333>;
-			tRPab		= <21000>;
-			tRCD		= <18000>;
-			tWR		= <15000>;
-			tRAS-min	= <42000>;
-			tRRD		= <10000>;
-			tWTR		= <7500>;
-			tXP		= <7500>;
-			tRTP		= <7500>;
-			tCKESR		= <15000>;
-			tDQSCK-max	= <5500>;
-			tFAW		= <50000>;
-			tZQCS		= <90000>;
-			tZQCL		= <360000>;
-			tZQinit		= <1000000>;
-			tRAS-max-ns	= <70000>;
-			tDQSCK-max-derated = <6000>;
-		};
-
-		timings_samsung_K3PE0E000B_266MHz: lpddr2-timings@1 {
-			compatible	= "jedec,lpddr2-timings";
-			min-freq	= <10000000>;
-			max-freq	= <266666666>;
-			tRPab		= <21000>;
-			tRCD		= <18000>;
-			tWR		= <15000>;
-			tRAS-min	= <42000>;
-			tRRD		= <10000>;
-			tWTR		= <7500>;
-			tXP		= <7500>;
-			tRTP		= <7500>;
-			tCKESR		= <15000>;
-			tDQSCK-max	= <5500>;
-			tFAW		= <50000>;
-			tZQCS		= <90000>;
-			tZQCL		= <360000>;
-			tZQinit		= <1000000>;
-			tRAS-max-ns	= <70000>;
-			tDQSCK-max-derated = <6000>;
-		};
-	};
-};
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index c42ca70..486d4e7 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -831,7 +831,7 @@
 		timer@fffec600 {
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0xfffec600 0x100>;
-			interrupts = <1 13 0xf04>;
+			interrupts = <1 13 0xf01>;
 			clocks = <&mpu_periph_clk>;
 		};
 
diff --git a/arch/arm/boot/dts/stih407-b2120.dts b/arch/arm/boot/dts/stih407-b2120.dts
index a7a0f76..62ce1ce 100644
--- a/arch/arm/boot/dts/stih407-b2120.dts
+++ b/arch/arm/boot/dts/stih407-b2120.dts
@@ -15,10 +15,10 @@
 
 	chosen {
 		bootargs = "clk_ignore_unused";
-		linux,stdout-path = &sbc_serial0;
+		stdout-path = &sbc_serial0;
 	};
 
-	memory {
+	memory@40000000 {
 		device_type = "memory";
 		reg = <0x40000000 0x80000000>;
 	};
diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
index d0a24d9..ea78334 100644
--- a/arch/arm/boot/dts/stih407-clock.dtsi
+++ b/arch/arm/boot/dts/stih407-clock.dtsi
@@ -7,33 +7,27 @@
  */
 #include <dt-bindings/clock/stih407-clks.h>
 / {
+	/*
+	 * Fixed 30MHz oscillator inputs to SoC
+	 */
+	clk_sysin: clk-sysin {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <30000000>;
+	};
+
+	clk_tmdsout_hdmi: clk-tmdsout-hdmi {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <0>;
+	};
+
 	clocks {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
 
 		/*
-		 * Fixed 30MHz oscillator inputs to SoC
-		 */
-		clk_sysin: clk-sysin {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <30000000>;
-		};
-
-		/*
-		 * ARM Peripheral clock for timers
-		 */
-		arm_periph_clk: clk-m-a9-periphs {
-			#clock-cells = <0>;
-			compatible = "fixed-factor-clock";
-
-			clocks = <&clk_m_a9>;
-			clock-div = <2>;
-			clock-mult = <1>;
-		};
-
-		/*
 		 * A9 PLL.
 		 */
 		clockgen-a9@92b0000 {
@@ -62,32 +56,19 @@
 				 <&clockgen_a9_pll 0>,
 				 <&clk_s_c0_flexgen 13>,
 				 <&clk_m_a9_ext2f_div2>;
-		};
 
-		/*
-		 * ARM Peripheral clock for timers
-		 */
-		clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
-			#clock-cells = <0>;
-			compatible = "fixed-factor-clock";
 
-			clocks = <&clk_s_c0_flexgen 13>;
+			/*
+			 * ARM Peripheral clock for timers
+			 */
+			arm_periph_clk: clk-m-a9-periphs {
+				#clock-cells = <0>;
+				compatible = "fixed-factor-clock";
 
-			clock-output-names = "clk-m-a9-ext2f-div2";
-
-			clock-div = <2>;
-			clock-mult = <1>;
-		};
-
-		/*
-		 * Bootloader initialized system infrastructure clock for
-		 * serial devices.
-		 */
-		clk_ext2f_a9: clockgen-c0@13 {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <200000000>;
-			clock-output-names = "clk-s-icn-reg-0";
+				clocks = <&clk_m_a9>;
+				clock-div = <2>;
+				clock-mult = <1>;
+			};
 		};
 
 		clockgen-a@90ff000 {
@@ -204,6 +185,21 @@
 						 <CLK_EXT2F_A9>,
 						 <CLK_ICN_LMI>,
 						 <CLK_ICN_SBC>;
+
+				/*
+				 * ARM Peripheral clock for timers
+				 */
+				clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
+					#clock-cells = <0>;
+					compatible = "fixed-factor-clock";
+
+					clocks = <&clk_s_c0_flexgen 13>;
+
+					clock-output-names = "clk-m-a9-ext2f-div2";
+
+					clock-div = <2>;
+					clock-mult = <1>;
+				};
 			};
 		};
 
@@ -254,13 +250,7 @@
 					     "clk-s-d2-fs0-ch3";
 		};
 
-		clk_tmdsout_hdmi: clk-tmdsout-hdmi {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <0>;
-		};
-
-		clockgen-d2@x9106000 {
+		clockgen-d2@9106000 {
 			compatible = "st,clkgen-c32";
 			reg = <0x9106000 0x1000>;
 
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index cf37569..f7362c3 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -92,7 +92,7 @@
 		clocks = <&arm_periph_clk>;
 	};
 
-	l2: cache-controller {
+	l2: cache-controller@8762000 {
 		compatible = "arm,pl310-cache";
 		reg = <0x08762000 0x1000>;
 		arm,data-latency = <3 3 3>;
@@ -125,24 +125,28 @@
 		ranges;
 		compatible = "simple-bus";
 
-		restart {
+		restart: restart-controller@0 {
 			compatible = "st,stih407-restart";
+			reg = <0 0>;
 			st,syscfg = <&syscfg_sbc_reg>;
 			status = "okay";
 		};
 
-		powerdown: powerdown-controller {
+		powerdown: powerdown-controller@0 {
 			compatible = "st,stih407-powerdown";
+			reg = <0 0>;
 			#reset-cells = <1>;
 		};
 
-		softreset: softreset-controller {
+		softreset: softreset-controller@0 {
 			compatible = "st,stih407-softreset";
+			reg = <0 0>;
 			#reset-cells = <1>;
 		};
 
-		picophyreset: picophyreset-controller {
+		picophyreset: picophyreset-controller@0 {
 			compatible = "st,stih407-picophyreset";
+			reg = <0 0>;
 			#reset-cells = <1>;
 		};
 
@@ -174,6 +178,13 @@
 		syscfg_core: core-syscfg@92b0000 {
 			compatible = "st,stih407-core-syscfg", "syscon";
 			reg = <0x92b0000 0x1000>;
+
+			sti_sasg_codec: sti-sasg-codec {
+				compatible = "st,stih407-sas-codec";
+				#sound-dai-cells = <1>;
+				status = "disabled";
+				st,syscfg = <&syscfg_core>;
+			};
 		};
 
 		syscfg_lpm: lpm-syscfg@94b5100 {
@@ -181,8 +192,9 @@
 			reg = <0x94b5100 0x1000>;
 		};
 
-		irq-syscfg {
+		irq-syscfg@0 {
 			compatible    = "st,stih407-irq-syscfg";
+			reg = <0 0>;
 			st,syscfg     = <&syscfg_core>;
 			st,irq-device = <ST_IRQ_SYSCFG_PMU_0>,
 					<ST_IRQ_SYSCFG_PMU_1>;
@@ -380,8 +392,9 @@
 			status = "disabled";
 		};
 
-		usb2_picophy0: phy1 {
+		usb2_picophy0: phy1@0 {
 			compatible = "st,stih407-usb2-phy";
+			reg = <0 0>;
 			#phy-cells = <0>;
 			st,syscfg = <&syscfg_core 0x100 0xf4>;
 			resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
@@ -389,12 +402,13 @@
 			reset-names = "global", "port";
 		};
 
-		miphy28lp_phy: miphy28lp@9b22000 {
+		miphy28lp_phy: miphy28lp@0 {
 			compatible = "st,miphy28lp-phy";
 			st,syscfg = <&syscfg_core>;
 			#address-cells	= <1>;
 			#size-cells	= <1>;
 			ranges;
+			reg = <0 0>;
 
 			phy_port0: port@9b22000 {
 				reg = <0x9b22000 0xff>,
@@ -805,6 +819,7 @@
 
 		st231_gp0: st231-gp0@0 {
 			compatible	= "st,st231-rproc";
+			reg		= <0 0>;
 			memory-region	= <&gp0_reserved>;
 			resets		= <&softreset STIH407_ST231_GP0_SOFTRESET>;
 			reset-names	= "sw_reset";
@@ -818,6 +833,7 @@
 
 		st231_delta: st231-delta@0 {
 			compatible	= "st,st231-rproc";
+			reg		= <0 0>;
 			memory-region	= <&delta_reserved>;
 			resets		= <&softreset STIH407_ST231_DMU_SOFTRESET>;
 			reset-names	= "sw_reset";
@@ -885,13 +901,6 @@
 			status = "disabled";
 		};
 
-		sti_sasg_codec: sti-sasg-codec {
-			compatible = "st,stih407-sas-codec";
-			#sound-dai-cells = <1>;
-			status = "disabled";
-			st,syscfg = <&syscfg_core>;
-		};
-
 		sti_uni_player0: sti-uni-player@8d80000 {
 			compatible = "st,stih407-uni-player-hdmi";
 			#sound-dai-cells = <0>;
@@ -980,8 +989,9 @@
 			status = "disabled";
 		};
 
-		delta0 {
+		delta0@0 {
 			compatible = "st,st-delta";
+			reg = <0 0>;
 			clock-names = "delta",
 				      "delta-st231",
 				      "delta-flash-promip";
diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index a290900..53c6888 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -45,7 +45,7 @@
 	};
 
 	soc {
-		pin-controller-sbc {
+		pin-controller-sbc@961f080 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "st,stih407-sbc-pinctrl";
@@ -369,7 +369,7 @@
 			};
 		};
 
-		pin-controller-front0 {
+		pin-controller-front0@920f080 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "st,stih407-front-pinctrl";
@@ -929,7 +929,7 @@
 			};
 		};
 
-		pin-controller-front1 {
+		pin-controller-front1@921f080 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "st,stih407-front-pinctrl";
@@ -962,7 +962,7 @@
 			};
 		};
 
-		pin-controller-rear {
+		pin-controller-rear@922f080 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "st,stih407-rear-pinctrl";
@@ -1157,7 +1157,7 @@
 			};
 		};
 
-		pin-controller-flash {
+		pin-controller-flash@923f080 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "st,stih407-flash-pinctrl";
diff --git a/arch/arm/boot/dts/stih407.dtsi b/arch/arm/boot/dts/stih407.dtsi
index 11fdecd..57efc87 100644
--- a/arch/arm/boot/dts/stih407.dtsi
+++ b/arch/arm/boot/dts/stih407.dtsi
@@ -11,11 +11,11 @@
 #include <dt-bindings/gpio/gpio.h>
 / {
 	soc {
-		sti-display-subsystem {
+		sti-display-subsystem@0 {
 			compatible = "st,sti-display-subsystem";
 			#address-cells = <1>;
 			#size-cells = <1>;
-
+			reg = <0 0>;
 			assigned-clocks	= <&clk_s_d2_quadfs 0>,
 					  <&clk_s_d2_quadfs 1>,
 					  <&clk_s_c0_pll1 0>,
@@ -107,6 +107,7 @@
 				compatible = "st,stih407-hdmi";
 				reg = <0x8d04000 0x1000>;
 				reg-names = "hdmi-reg";
+				#sound-dai-cells = <0>;
 				interrupts = <GIC_SPI 106 IRQ_TYPE_NONE>;
 				interrupt-names	= "irq";
 				clock-names = "pix",
diff --git a/arch/arm/boot/dts/stih410-b2120.dts b/arch/arm/boot/dts/stih410-b2120.dts
index 6c6b4cc..2a5a980 100644
--- a/arch/arm/boot/dts/stih410-b2120.dts
+++ b/arch/arm/boot/dts/stih410-b2120.dts
@@ -15,10 +15,10 @@
 
 	chosen {
 		bootargs = "clk_ignore_unused";
-		linux,stdout-path = &sbc_serial0;
+		stdout-path = &sbc_serial0;
 	};
 
-	memory {
+	memory@40000000 {
 		device_type = "memory";
 		reg = <0x40000000 0x80000000>;
 	};
@@ -37,11 +37,11 @@
 			sd-uhs-ddr50;
 		};
 
-		usb2_picophy1: phy2 {
+		usb2_picophy1: phy2@0 {
 			status = "okay";
 		};
 
-		usb2_picophy2: phy3 {
+		usb2_picophy2: phy3@0 {
 			status = "okay";
 		};
 
@@ -61,7 +61,7 @@
 			status = "okay";
 		};
 
-		sti-display-subsystem {
+		sti-display-subsystem@0 {
 			sti-hda@8d02000 {
 				status = "okay";
 			};
diff --git a/arch/arm/boot/dts/stih410-b2260.dts b/arch/arm/boot/dts/stih410-b2260.dts
index 50d3675..155caa8 100644
--- a/arch/arm/boot/dts/stih410-b2260.dts
+++ b/arch/arm/boot/dts/stih410-b2260.dts
@@ -16,10 +16,10 @@
 
 	chosen {
 		bootargs = "clk_ignore_unused";
-		linux,stdout-path = &uart1;
+		stdout-path = &uart1;
 	};
 
-	memory {
+	memory@40000000 {
 		device_type = "memory";
 		reg = <0x40000000 0x40000000>;
 	};
@@ -29,36 +29,54 @@
 		ethernet0 = &ethernet0;
 	};
 
-	soc {
-
-		leds {
-			compatible = "gpio-leds";
-			user_green_1 {
-				label = "User_green_1";
-				gpios = <&pio1 3 GPIO_ACTIVE_LOW>;
-				linux,default-trigger = "heartbeat";
-				default-state = "off";
-			};
-
-			user_green_2 {
-				label = "User_green_2";
-				gpios = <&pio4 1 GPIO_ACTIVE_LOW>;
-				default-state = "off";
-			};
-
-			user_green_3 {
-				label = "User_green_3";
-				gpios = <&pio2 1 GPIO_ACTIVE_LOW>;
-				default-state = "off";
-			};
-
-			user_green_4 {
-				label = "User_green_4";
-				gpios = <&pio2 5 GPIO_ACTIVE_LOW>;
-				default-state = "off";
-			};
+	leds {
+		compatible = "gpio-leds";
+		user_green_1 {
+			label = "User_green_1";
+			gpios = <&pio1 3 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
 		};
 
+		user_green_2 {
+			label = "User_green_2";
+			gpios = <&pio4 1 GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+
+		user_green_3 {
+			label = "User_green_3";
+			gpios = <&pio2 1 GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+
+		user_green_4 {
+			label = "User_green_4";
+			gpios = <&pio2 5 GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+	};
+
+	sound: sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "STI-B2260";
+		status = "okay";
+
+		simple-audio-card,dai-link0 {
+			/* DAC */
+			format = "i2s";
+			mclk-fs = <128>;
+			cpu {
+				sound-dai = <&sti_uni_player0>;
+			};
+
+			codec {
+				sound-dai = <&sti_hdmi>;
+			};
+		};
+	};
+
+	soc {
 		/* Low speed expansion connector */
 		uart0: serial@9830000 {
 			label = "LS-UART0";
@@ -128,11 +146,11 @@
 			status = "okay";
 		};
 
-		usb2_picophy1: phy2 {
+		usb2_picophy1: phy2@0 {
 			status = "okay";
 		};
 
-		usb2_picophy2: phy3 {
+		usb2_picophy2: phy3@0 {
 			status = "okay";
 		};
 
@@ -182,26 +200,7 @@
 			status = "okay";
 		};
 
-		sound {
-			compatible = "simple-audio-card";
-			simple-audio-card,name = "STI-B2260";
-			status = "okay";
-
-			simple-audio-card,dai-link@0 {
-				/* DAC */
-				format = "i2s";
-				mclk-fs = <128>;
-				cpu {
-					sound-dai = <&sti_uni_player0>;
-				};
-
-				codec {
-					sound-dai = <&sti_hdmi>;
-				};
-			};
-		};
-
-		miphy28lp_phy: miphy28lp@9b22000 {
+		miphy28lp_phy: miphy28lp@0 {
 
 			phy_port1: port@9b2a000 {
 				st,osc-force-ext;
diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
index fde5df1..5f11d09 100644
--- a/arch/arm/boot/dts/stih410-clock.dtsi
+++ b/arch/arm/boot/dts/stih410-clock.dtsi
@@ -7,6 +7,22 @@
  */
 #include <dt-bindings/clock/stih410-clks.h>
 / {
+	/*
+	 * Fixed 30MHz oscillator inputs to SoC
+	 */
+	clk_sysin: clk-sysin {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <30000000>;
+		clock-output-names = "CLK_SYSIN";
+	};
+
+	clk_tmdsout_hdmi: clk-tmdsout-hdmi {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <0>;
+	};
+
 	clocks {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -15,27 +31,6 @@
 		compatible = "st,stih410-clk", "simple-bus";
 
 		/*
-		 * Fixed 30MHz oscillator inputs to SoC
-		 */
-		clk_sysin: clk-sysin {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <30000000>;
-			clock-output-names = "CLK_SYSIN";
-		};
-
-		/*
-		 * ARM Peripheral clock for timers
-		 */
-		arm_periph_clk: clk-m-a9-periphs {
-			#clock-cells = <0>;
-			compatible = "fixed-factor-clock";
-			clocks = <&clk_m_a9>;
-			clock-div = <2>;
-			clock-mult = <1>;
-		};
-
-		/*
 		 * A9 PLL.
 		 */
 		clockgen-a9@92b0000 {
@@ -64,32 +59,16 @@
 				 <&clockgen_a9_pll 0>,
 				 <&clk_s_c0_flexgen 13>,
 				 <&clk_m_a9_ext2f_div2>;
-		};
-
-		/*
-		 * ARM Peripheral clock for timers
-		 */
-		clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
-			#clock-cells = <0>;
-			compatible = "fixed-factor-clock";
-
-			clocks = <&clk_s_c0_flexgen 13>;
-
-			clock-output-names = "clk-m-a9-ext2f-div2";
-
-			clock-div = <2>;
-			clock-mult = <1>;
-		};
-
-		/*
-		 * Bootloader initialized system infrastructure clock for
-		 * serial devices.
-		 */
-		clk_ext2f_a9: clockgen-c0@13 {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <200000000>;
-			clock-output-names = "clk-s-icn-reg-0";
+			/*
+			 * ARM Peripheral clock for timers
+			 */
+			arm_periph_clk: clk-m-a9-periphs {
+				#clock-cells = <0>;
+				compatible = "fixed-factor-clock";
+				clocks = <&clk_m_a9>;
+				clock-div = <2>;
+				clock-mult = <1>;
+			};
 		};
 
 		clockgen-a@90ff000 {
@@ -214,6 +193,21 @@
 						 <CLK_EXT2F_A9>,
 						 <CLK_ICN_LMI>,
 						 <CLK_ICN_SBC>;
+
+				/*
+				 * ARM Peripheral clock for timers
+				 */
+				clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
+					#clock-cells = <0>;
+					compatible = "fixed-factor-clock";
+
+					clocks = <&clk_s_c0_flexgen 13>;
+
+					clock-output-names = "clk-m-a9-ext2f-div2";
+
+					clock-div = <2>;
+					clock-mult = <1>;
+				};
 			};
 		};
 
@@ -266,13 +260,7 @@
 					     "clk-s-d2-fs0-ch3";
 		};
 
-		clk_tmdsout_hdmi: clk-tmdsout-hdmi {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <0>;
-		};
-
-		clockgen-d2@x9106000 {
+		clockgen-d2@9106000 {
 			compatible = "st,clkgen-c32";
 			reg = <0x9106000 0x1000>;
 
diff --git a/arch/arm/boot/dts/stih410-pinctrl.dtsi b/arch/arm/boot/dts/stih410-pinctrl.dtsi
index b3e9dfc..5ae1fd6 100644
--- a/arch/arm/boot/dts/stih410-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih410-pinctrl.dtsi
@@ -10,7 +10,7 @@
 / {
 
 	soc {
-		pin-controller-rear {
+		pin-controller-rear@922f080 {
 
 			usb0 {
 				pinctrl_usb0: usb2-0 {
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index 68b5ff9..3313005 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -16,8 +16,9 @@
 	};
 
 	soc {
-		usb2_picophy1: phy2 {
+		usb2_picophy1: phy2@0 {
 			compatible = "st,stih407-usb2-phy";
+			reg = <0 0>;
 			#phy-cells = <0>;
 			st,syscfg = <&syscfg_core 0xf8 0xf4>;
 			resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
@@ -27,8 +28,9 @@
 			status = "disabled";
 		};
 
-		usb2_picophy2: phy3 {
+		usb2_picophy2: phy3@0 {
 			compatible = "st,stih407-usb2-phy";
+			reg = <0 0>;
 			#phy-cells = <0>;
 			st,syscfg = <&syscfg_core 0xfc 0xf4>;
 			resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
@@ -102,11 +104,12 @@
 			status = "disabled";
 		};
 
-		sti-display-subsystem {
+		sti-display-subsystem@0 {
 			compatible = "st,sti-display-subsystem";
 			#address-cells = <1>;
 			#size-cells = <1>;
 
+			reg = <0 0>;
 			assigned-clocks	= <&clk_s_d2_quadfs 0>,
 					  <&clk_s_d2_quadfs 1>,
 					  <&clk_s_c0_pll1 0>,
@@ -198,6 +201,7 @@
 				compatible = "st,stih407-hdmi";
 				reg = <0x8d04000 0x1000>;
 				reg-names = "hdmi-reg";
+				#sound-dai-cells = <0>;
 				interrupts = <GIC_SPI 106 IRQ_TYPE_NONE>;
 				interrupt-names	= "irq";
 				clock-names = "pix",
@@ -235,7 +239,7 @@
 					 <&clk_s_d2_quadfs 1>;
 			};
 
-			sti-hqvdp@9c000000 {
+			sti-hqvdp@9c00000 {
 				compatible = "st,stih407-hqvdp";
 				reg = <0x9C00000 0x100000>;
 				clock-names = "hqvdp", "pix_main";
@@ -273,7 +277,7 @@
 			interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
 		};
 
-		delta0 {
+		delta0@0 {
 			compatible = "st,st-delta";
 			clock-names = "delta",
 				      "delta-st231",
diff --git a/arch/arm/boot/dts/stih418-b2199.dts b/arch/arm/boot/dts/stih418-b2199.dts
index 7f5f325..cd0d719 100644
--- a/arch/arm/boot/dts/stih418-b2199.dts
+++ b/arch/arm/boot/dts/stih418-b2199.dts
@@ -15,10 +15,10 @@
 
 	chosen {
 		bootargs = "clk_ignore_unused";
-		linux,stdout-path = &sbc_serial0;
+		stdout-path = &sbc_serial0;
 	};
 
-	memory {
+	memory@40000000 {
 		device_type = "memory";
 		reg = <0x40000000 0xc0000000>;
 	};
@@ -28,24 +28,24 @@
 		ethernet0 = &ethernet0;
 	};
 
+	leds {
+		compatible = "gpio-leds";
+		red {
+			label = "Front Panel LED";
+			gpios = <&pio4 1 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+		green {
+			gpios = <&pio1 3 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
 	soc {
 		sbc_serial0: serial@9530000 {
 			status = "okay";
 		};
 
-		leds {
-			compatible = "gpio-leds";
-			red {
-				label = "Front Panel LED";
-				gpios = <&pio4 1 GPIO_ACTIVE_HIGH>;
-				linux,default-trigger = "heartbeat";
-			};
-			green {
-				gpios = <&pio1 3 GPIO_ACTIVE_HIGH>;
-				default-state = "off";
-			};
-		};
-
 		i2c@9842000 {
 			status = "okay";
 		};
@@ -88,7 +88,7 @@
 			non-removable;
 		};
 
-		miphy28lp_phy: miphy28lp@9b22000 {
+		miphy28lp_phy: miphy28lp@0 {
 
 			phy_port0: port@9b22000 {
 				st,osc-rdy;
diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
index 9a157c1..13fb8db 100644
--- a/arch/arm/boot/dts/stih418-clock.dtsi
+++ b/arch/arm/boot/dts/stih418-clock.dtsi
@@ -7,6 +7,22 @@
  */
 #include <dt-bindings/clock/stih418-clks.h>
 / {
+	/*
+	 * Fixed 30MHz oscillator inputs to SoC
+	 */
+	clk_sysin: clk-sysin {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <30000000>;
+		clock-output-names = "CLK_SYSIN";
+	};
+
+	clk_tmdsout_hdmi: clk-tmdsout-hdmi {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <0>;
+	};
+
 	clocks {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -15,27 +31,6 @@
 		compatible = "st,stih418-clk", "simple-bus";
 
 		/*
-		 * Fixed 30MHz oscillator inputs to SoC
-		 */
-		clk_sysin: clk-sysin {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <30000000>;
-			clock-output-names = "CLK_SYSIN";
-		};
-
-		/*
-		 * ARM Peripheral clock for timers
-		 */
-		arm_periph_clk: clk-m-a9-periphs {
-			#clock-cells = <0>;
-			compatible = "fixed-factor-clock";
-			clocks = <&clk_m_a9>;
-			clock-div = <2>;
-			clock-mult = <1>;
-		};
-
-		/*
 		 * A9 PLL.
 		 */
 		clockgen-a9@92b0000 {
@@ -64,32 +59,17 @@
 				 <&clockgen_a9_pll 0>,
 				 <&clk_s_c0_flexgen 13>,
 				 <&clk_m_a9_ext2f_div2>;
-		};
 
-		/*
-		 * ARM Peripheral clock for timers
-		 */
-		clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
-			#clock-cells = <0>;
-			compatible = "fixed-factor-clock";
-
-			clocks = <&clk_s_c0_flexgen 13>;
-
-			clock-output-names = "clk-m-a9-ext2f-div2";
-
-			clock-div = <2>;
-			clock-mult = <1>;
-		};
-
-		/*
-		 * Bootloader initialized system infrastructure clock for
-		 * serial devices.
-		 */
-		clk_ext2f_a9: clockgen-c0@13 {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <200000000>;
-			clock-output-names = "clk-s-icn-reg-0";
+			/*
+			 * ARM Peripheral clock for timers
+			 */
+			arm_periph_clk: clk-m-a9-periphs {
+				#clock-cells = <0>;
+				compatible = "fixed-factor-clock";
+				clocks = <&clk_m_a9>;
+				clock-div = <2>;
+				clock-mult = <1>;
+			};
 		};
 
 		clockgen-a@90ff000 {
@@ -207,6 +187,21 @@
 						     "clk-proc-mixer",
 						     "clk-proc-sc",
 						     "clk-avsp-hevc";
+
+				/*
+				 * ARM Peripheral clock for timers
+				 */
+				clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
+					#clock-cells = <0>;
+					compatible = "fixed-factor-clock";
+
+					clocks = <&clk_s_c0_flexgen 13>;
+
+					clock-output-names = "clk-m-a9-ext2f-div2";
+
+					clock-div = <2>;
+					clock-mult = <1>;
+				};
 			};
 		};
 
@@ -259,13 +254,7 @@
 					     "clk-s-d2-fs0-ch3";
 		};
 
-		clk_tmdsout_hdmi: clk-tmdsout-hdmi {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <0>;
-		};
-
-		clockgen-d2@x9106000 {
+		clockgen-d2@9106000 {
 			compatible = "st,clkgen-c32";
 			reg = <0x9106000 0x1000>;
 
diff --git a/arch/arm/boot/dts/stih418.dtsi b/arch/arm/boot/dts/stih418.dtsi
index e6525ab..0efb3cd 100644
--- a/arch/arm/boot/dts/stih418.dtsi
+++ b/arch/arm/boot/dts/stih418.dtsi
@@ -30,8 +30,9 @@
 	};
 
 	soc {
-		usb2_picophy1: phy2 {
+		usb2_picophy1: phy2@0 {
 			compatible = "st,stih407-usb2-phy";
+			reg = <0 0>;
 			#phy-cells = <0>;
 			st,syscfg = <&syscfg_core 0xf8 0xf4>;
 			resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
@@ -39,8 +40,9 @@
 			reset-names = "global", "port";
 		};
 
-		usb2_picophy2: phy3 {
+		usb2_picophy2: phy3@0 {
 			compatible = "st,stih407-usb2-phy";
+			reg = <0 0>;
 			#phy-cells = <0>;
 			st,syscfg = <&syscfg_core 0xfc 0xf4>;
 			resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index 7f80c2c..c67edb1 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -10,24 +10,70 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/media/c8sectpfe.h>
 / {
+	leds {
+		compatible = "gpio-leds";
+		red {
+			label = "Front Panel LED";
+			gpios = <&pio4 1 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+		green {
+			gpios = <&pio1 3 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	sound: sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "STI-B2120";
+		status = "okay";
+
+		simple-audio-card,dai-link0 {
+			/* HDMI */
+			format = "i2s";
+			mclk-fs = <128>;
+			cpu {
+				sound-dai = <&sti_uni_player0>;
+			};
+
+			codec {
+				sound-dai = <&sti_hdmi>;
+			};
+		};
+
+		simple-audio-card,dai-link1 {
+			/* DAC */
+			format = "i2s";
+			mclk-fs = <256>;
+			frame-inversion = <1>;
+			cpu {
+				sound-dai = <&sti_uni_player2>;
+			};
+
+			codec {
+				sound-dai = <&sti_sasg_codec 1>;
+			};
+		};
+
+		simple-audio-card,dai-link2 {
+			/* SPDIF */
+			format = "left_j";
+			mclk-fs = <128>;
+			cpu {
+				sound-dai = <&sti_uni_player3>;
+			};
+
+			codec {
+				sound-dai = <&sti_sasg_codec 0>;
+			};
+		};
+	};
+
 	soc {
 		sbc_serial0: serial@9530000 {
 			status = "okay";
 		};
 
-		leds {
-			compatible = "gpio-leds";
-			red {
-				label = "Front Panel LED";
-				gpios = <&pio4 1 GPIO_ACTIVE_HIGH>;
-				linux,default-trigger = "heartbeat";
-			};
-			green {
-				gpios = <&pio1 3 GPIO_ACTIVE_HIGH>;
-				default-state = "off";
-			};
-		};
-
 		pwm0: pwm@9810000 {
 			status = "okay";
 		};
@@ -80,7 +126,7 @@
 			st,i2c-min-sda-pulse-width-us = <5>;
 		};
 
-		miphy28lp_phy: miphy28lp@9b22000 {
+		miphy28lp_phy: miphy28lp@0 {
 
 			phy_port0: port@9b22000 {
 				st,osc-rdy;
@@ -126,7 +172,7 @@
 			clock-names	= "c8sectpfe";
 
 			/* tsin0 is TSA on NIMA */
-			tsin0: port@0 {
+			tsin0: port {
 				tsin-num	= <0>;
 				serial-not-parallel;
 				i2c-bus		= <&ssc2>;
@@ -147,53 +193,11 @@
 			status = "okay";
 		};
 
-		sti_sasg_codec: sti-sasg-codec {
-			status = "okay";
-			pinctrl-names = "default";
-			pinctrl-0 = <&pinctrl_spdif_out>;
-		};
-
-		sound {
-			compatible = "simple-audio-card";
-			simple-audio-card,name = "STI-B2120";
-			status = "okay";
-
-			simple-audio-card,dai-link@0 {
-				/* HDMI */
-				format = "i2s";
-				mclk-fs = <128>;
-				cpu {
-					sound-dai = <&sti_uni_player0>;
-				};
-
-				codec {
-					sound-dai = <&sti_hdmi>;
-				};
-			};
-			simple-audio-card,dai-link@1 {
-				/* DAC */
-				format = "i2s";
-				mclk-fs = <256>;
-				frame-inversion = <1>;
-				cpu {
-					sound-dai = <&sti_uni_player2>;
-				};
-
-				codec {
-					sound-dai = <&sti_sasg_codec 1>;
-				};
-			};
-			simple-audio-card,dai-link@2 {
-				/* SPDIF */
-				format = "left_j";
-				mclk-fs = <128>;
-				cpu {
-					sound-dai = <&sti_uni_player3>;
-				};
-
-				codec {
-					sound-dai = <&sti_sasg_codec 0>;
-				};
+		syscfg_core: core-syscfg@92b0000 {
+			sti_sasg_codec: sti-sasg-codec {
+				status = "okay";
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_spdif_out>;
 			};
 		};
 	};
diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index 293ecb9..7eb786a 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -144,6 +144,13 @@
 			};
 		};
 	};
+
+	mmc_vcard: mmc_vcard {
+		compatible = "regulator-fixed";
+		regulator-name = "mmc_vcard";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &adc {
@@ -254,6 +261,18 @@
 	status = "okay";
 };
 
+&sdio {
+	status = "okay";
+	vmmc-supply = <&mmc_vcard>;
+	cd-gpios = <&stmpegpio 15 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	pinctrl-names = "default", "opendrain";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_pins_od>;
+	bus-width = <4>;
+	max-frequency = <12500000>;
+};
+
 &timers1 {
 	status = "okay";
 
diff --git a/arch/arm/boot/dts/stm32746g-eval.dts b/arch/arm/boot/dts/stm32746g-eval.dts
index 2d4e717..8c081ea 100644
--- a/arch/arm/boot/dts/stm32746g-eval.dts
+++ b/arch/arm/boot/dts/stm32746g-eval.dts
@@ -42,6 +42,7 @@
 
 /dts-v1/;
 #include "stm32f746.dtsi"
+#include "stm32f746-pinctrl.dtsi"
 #include <dt-bindings/input/input.h>
 
 / {
@@ -90,6 +91,13 @@
 		clocks = <&rcc 0 STM32F7_AHB1_CLOCK(OTGHSULPI)>;
 		clock-names = "main_clk";
 	};
+
+	mmc_vcard: mmc_vcard {
+		compatible = "regulator-fixed";
+		regulator-name = "mmc_vcard";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &clk_hse {
@@ -112,6 +120,16 @@
 	status = "okay";
 };
 
+&sdio1 {
+	status = "okay";
+	vmmc-supply = <&mmc_vcard>;
+	broken-cd;
+	pinctrl-names = "default", "opendrain";
+	pinctrl-0 = <&sdio_pins_a>;
+	pinctrl-1 = <&sdio_pins_od_a>;
+	bus-width = <4>;
+};
+
 &usart1 {
 	pinctrl-0 = <&usart1_pins_a>;
 	pinctrl-names = "default";
@@ -119,7 +137,7 @@
 };
 
 &usbotg_hs {
-	dr_mode = "host";
+	dr_mode = "otg";
 	phys = <&usbotg_hs_phy>;
 	phy-names = "usb2-phy";
 	pinctrl-0 = <&usbotg_hs_pins_a>;
diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
index ae94d86..3520289 100644
--- a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
@@ -338,6 +338,37 @@
 					slew-rate = <3>;
 				};
 			};
+
+			sdio_pins: sdio_pins@0 {
+				pins {
+					pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDIO_D0 */
+						 <STM32_PINMUX('C', 9, AF12)>, /* SDIO_D1 */
+						 <STM32_PINMUX('C', 10, AF12)>, /* SDIO_D2 */
+						 <STM32_PINMUX('C', 11, AF12)>, /* SDIO_D3 */
+						 <STM32_PINMUX('C', 12, AF12)>, /* SDIO_CK */
+						 <STM32_PINMUX('D', 2, AF12)>; /* SDIO_CMD */
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+			};
+
+			sdio_pins_od: sdio_pins_od@0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDIO_D0 */
+						 <STM32_PINMUX('C', 9, AF12)>, /* SDIO_D1 */
+						 <STM32_PINMUX('C', 10, AF12)>, /* SDIO_D2 */
+						 <STM32_PINMUX('C', 11, AF12)>, /* SDIO_D3 */
+						 <STM32_PINMUX('C', 12, AF12)>; /* SDIO_CK */
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+
+				pins2 {
+					pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDIO_CMD */
+					drive-open-drain;
+					slew-rate = <2>;
+				};
+			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 10099df..ede77e0 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -511,6 +511,17 @@
 			};
 		};
 
+		sdio: sdio@40012c00 {
+			compatible = "arm,pl180", "arm,primecell";
+			arm,primecell-periphid = <0x00880180>;
+			reg = <0x40012c00 0x400>;
+			clocks = <&rcc 0 STM32F4_APB2_CLOCK(SDIO)>;
+			clock-names = "apb_pclk";
+			interrupts = <49>;
+			max-frequency = <48000000>;
+			status = "disabled";
+		};
+
 		syscfg: system-config@40013800 {
 			compatible = "syscon";
 			reg = <0x40013800 0x400>;
diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
index c18acbe..2f76726 100644
--- a/arch/arm/boot/dts/stm32f469-disco.dts
+++ b/arch/arm/boot/dts/stm32f469-disco.dts
@@ -48,6 +48,8 @@
 /dts-v1/;
 #include "stm32f429.dtsi"
 #include "stm32f469-pinctrl.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
 	model = "STMicroelectronics STM32F469i-DISCO board";
@@ -66,10 +68,46 @@
 		serial0 = &usart3;
 	};
 
+	mmc_vcard: mmc_vcard {
+		compatible = "regulator-fixed";
+		regulator-name = "mmc_vcard";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
 	soc {
 		dma-ranges = <0xc0000000 0x0 0x10000000>;
 	};
 
+	leds {
+		compatible = "gpio-leds";
+		green {
+			gpios = <&gpiog 6 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "heartbeat";
+		};
+		orange {
+			gpios = <&gpiod 4 GPIO_ACTIVE_LOW>;
+		};
+		red {
+			gpios = <&gpiod 5 GPIO_ACTIVE_LOW>;
+		};
+		blue {
+			gpios = <&gpiok 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		autorepeat;
+		button@0 {
+			label = "User";
+			linux,code = <KEY_WAKEUP>;
+			gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
 	/* This turns on vbus for otg for host mode (dwc2) */
 	vcc5v_otg: vcc5v-otg-regulator {
 		compatible = "regulator-fixed";
@@ -120,6 +158,18 @@
 	};
 };
 
+&sdio {
+	status = "okay";
+	vmmc-supply = <&mmc_vcard>;
+	cd-gpios = <&gpiog 2 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	broken-cd;
+	pinctrl-names = "default", "opendrain";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_pins_od>;
+	bus-width = <4>;
+};
+
 &usart3 {
 	pinctrl-0 = <&usart3_pins_a>;
 	pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/stm32f7-pinctrl.dtsi b/arch/arm/boot/dts/stm32f7-pinctrl.dtsi
new file mode 100644
index 0000000..9314128
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f7-pinctrl.dtsi
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Alexandre Torgue  <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+#include <dt-bindings/mfd/stm32f7-rcc.h>
+
+/ {
+	soc {
+		pinctrl: pin-controller {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x40020000 0x3000>;
+			interrupt-parent = <&exti>;
+			st,syscfg = <&syscfg 0x8>;
+			pins-are-numbered;
+
+			gpioa: gpio@40020000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x0 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOA)>;
+				st,bank-name = "GPIOA";
+			};
+
+			gpiob: gpio@40020400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x400 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOB)>;
+				st,bank-name = "GPIOB";
+			};
+
+			gpioc: gpio@40020800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x800 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOC)>;
+				st,bank-name = "GPIOC";
+			};
+
+			gpiod: gpio@40020c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0xc00 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOD)>;
+				st,bank-name = "GPIOD";
+			};
+
+			gpioe: gpio@40021000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x1000 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOE)>;
+				st,bank-name = "GPIOE";
+			};
+
+			gpiof: gpio@40021400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x1400 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOF)>;
+				st,bank-name = "GPIOF";
+			};
+
+			gpiog: gpio@40021800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x1800 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOG)>;
+				st,bank-name = "GPIOG";
+			};
+
+			gpioh: gpio@40021c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x1c00 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOH)>;
+				st,bank-name = "GPIOH";
+			};
+
+			gpioi: gpio@40022000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x2000 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOI)>;
+				st,bank-name = "GPIOI";
+			};
+
+			gpioj: gpio@40022400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x2400 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOJ)>;
+				st,bank-name = "GPIOJ";
+			};
+
+			gpiok: gpio@40022800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x2800 0x400>;
+				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOK)>;
+				st,bank-name = "GPIOK";
+			};
+
+			cec_pins_a: cec@0 {
+				pins {
+					pinmux = <STM32_PINMUX('A', 15, AF4)>; /* HDMI CEC */
+					slew-rate = <0>;
+					drive-open-drain;
+					bias-disable;
+				};
+			};
+
+			usart1_pins_a: usart1@0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('A', 9, AF7)>; /* USART1_TX */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('A', 10, AF7)>; /* USART1_RX */
+					bias-disable;
+				};
+			};
+
+			usart1_pins_b: usart1@1 {
+				pins1 {
+					pinmux = <STM32_PINMUX('A', 9, AF7)>; /* USART1_TX */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 7, AF7)>; /* USART1_RX */
+					bias-disable;
+				};
+			};
+
+			i2c1_pins_b: i2c1@0 {
+				pins {
+					pinmux = <STM32_PINMUX('B', 9, AF4)>, /* I2C1 SDA */
+						 <STM32_PINMUX('B', 8, AF4)>; /* I2C1 SCL */
+					bias-disable;
+					drive-open-drain;
+					slew-rate = <0>;
+				};
+			};
+
+			usbotg_hs_pins_a: usbotg-hs@0 {
+				pins {
+					pinmux = <STM32_PINMUX('H', 4, AF10)>, /* OTG_HS_ULPI_NXT */
+						 <STM32_PINMUX('I', 11, AF10)>, /* OTG_HS_ULPI_DIR */
+						 <STM32_PINMUX('C', 0, AF10)>, /* OTG_HS_ULPI_STP */
+						 <STM32_PINMUX('A', 5, AF10)>, /* OTG_HS_ULPI_CK */
+						 <STM32_PINMUX('A', 3, AF10)>, /* OTG_HS_ULPI_D0 */
+						 <STM32_PINMUX('B', 0, AF10)>, /* OTG_HS_ULPI_D1 */
+						 <STM32_PINMUX('B', 1, AF10)>, /* OTG_HS_ULPI_D2 */
+						 <STM32_PINMUX('B', 10, AF10)>, /* OTG_HS_ULPI_D3 */
+						 <STM32_PINMUX('B', 11, AF10)>, /* OTG_HS_ULPI_D4 */
+						 <STM32_PINMUX('B', 12, AF10)>, /* OTG_HS_ULPI_D5 */
+						 <STM32_PINMUX('B', 13, AF10)>, /* OTG_HS_ULPI_D6 */
+						 <STM32_PINMUX('B', 5, AF10)>; /* OTG_HS_ULPI_D7 */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+			};
+
+			usbotg_hs_pins_b: usbotg-hs@1 {
+				pins {
+					pinmux = <STM32_PINMUX('H', 4, AF10)>, /* OTG_HS_ULPI_NXT */
+						 <STM32_PINMUX('C', 2, AF10)>, /* OTG_HS_ULPI_DIR */
+						 <STM32_PINMUX('C', 0, AF10)>, /* OTG_HS_ULPI_STP */
+						 <STM32_PINMUX('A', 5, AF10)>, /* OTG_HS_ULPI_CK */
+						 <STM32_PINMUX('A', 3, AF10)>, /* OTG_HS_ULPI_D0 */
+						 <STM32_PINMUX('B', 0, AF10)>, /* OTG_HS_ULPI_D1 */
+						 <STM32_PINMUX('B', 1, AF10)>, /* OTG_HS_ULPI_D2 */
+						 <STM32_PINMUX('B', 10, AF10)>, /* OTG_HS_ULPI_D3 */
+						 <STM32_PINMUX('B', 11, AF10)>, /* OTG_HS_ULPI_D4 */
+						 <STM32_PINMUX('B', 12, AF10)>, /* OTG_HS_ULPI_D5 */
+						 <STM32_PINMUX('B', 13, AF10)>, /* OTG_HS_ULPI_D6 */
+						 <STM32_PINMUX('B', 5, AF10)>; /* OTG_HS_ULPI_D7 */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+			};
+
+			usbotg_fs_pins_a: usbotg-fs@0 {
+				pins {
+					pinmux = <STM32_PINMUX('A', 10, AF10)>, /* OTG_FS_ID */
+						 <STM32_PINMUX('A', 11, AF10)>, /* OTG_FS_DM */
+						 <STM32_PINMUX('A', 12, AF10)>; /* OTG_FS_DP */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+			};
+
+			sdio_pins_a: sdio_pins_a@0 {
+				pins {
+					pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1 D0 */
+						 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1 D1 */
+						 <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1 D2 */
+						 <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1 D3 */
+						 <STM32_PINMUX('C', 12, AF12)>, /* SDMMC1 CLK */
+						 <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1 CMD */
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+			};
+
+			sdio_pins_od_a: sdio_pins_od_a@0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1 D0 */
+						 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1 D1 */
+						 <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1 D2 */
+						 <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1 D3 */
+						 <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1 CLK */
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+
+				pins2 {
+					pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1 CMD */
+					drive-open-drain;
+					slew-rate = <2>;
+				};
+			};
+
+			sdio_pins_b: sdio_pins_b@0 {
+				pins {
+					pinmux = <STM32_PINMUX('G', 9, AF11)>, /* SDMMC2 D0 */
+						 <STM32_PINMUX('G', 10, AF11)>, /* SDMMC2 D1 */
+						 <STM32_PINMUX('B', 3, AF10)>, /* SDMMC2 D2 */
+						 <STM32_PINMUX('B', 4, AF10)>, /* SDMMC2 D3 */
+						 <STM32_PINMUX('D', 6, AF11)>, /* SDMMC2 CLK */
+						 <STM32_PINMUX('D', 7, AF11)>; /* SDMMC2 CMD */
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+			};
+
+			sdio_pins_od_b: sdio_pins_od_b@0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('G', 9, AF11)>, /* SDMMC2 D0 */
+						 <STM32_PINMUX('G', 10, AF11)>, /* SDMMC2 D1 */
+						 <STM32_PINMUX('B', 3, AF10)>, /* SDMMC2 D2 */
+						 <STM32_PINMUX('B', 4, AF10)>, /* SDMMC2 D3 */
+						 <STM32_PINMUX('D', 6, AF11)>; /* SDMMC2 CLK */
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+
+				pins2 {
+					pinmux = <STM32_PINMUX('D', 7, AF11)>; /* SDMMC2 CMD */
+					drive-open-drain;
+					slew-rate = <2>;
+				};
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stm32f746-disco.dts b/arch/arm/boot/dts/stm32f746-disco.dts
index 4d85dba..be94c6a 100644
--- a/arch/arm/boot/dts/stm32f746-disco.dts
+++ b/arch/arm/boot/dts/stm32f746-disco.dts
@@ -42,7 +42,9 @@
 
 /dts-v1/;
 #include "stm32f746.dtsi"
+#include "stm32f746-pinctrl.dtsi"
 #include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "STMicroelectronics STM32F746-DISCO board";
@@ -75,12 +77,30 @@
 		regulator-name = "vcc5_host1";
 		regulator-always-on;
 	};
+
+	mmc_vcard: mmc_vcard {
+		compatible = "regulator-fixed";
+		regulator-name = "mmc_vcard";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &clk_hse {
 	clock-frequency = <25000000>;
 };
 
+&sdio1 {
+	status = "okay";
+	vmmc-supply = <&mmc_vcard>;
+	cd-gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	pinctrl-names = "default", "opendrain";
+	pinctrl-0 = <&sdio_pins_a>;
+	pinctrl-1 = <&sdio_pins_od_a>;
+	bus-width = <4>;
+};
+
 &usart1 {
 	pinctrl-0 = <&usart1_pins_b>;
 	pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/stm32f746-pinctrl.dtsi b/arch/arm/boot/dts/stm32f746-pinctrl.dtsi
new file mode 100644
index 0000000..fcfd2ac
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f746-pinctrl.dtsi
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Alexandre Torgue  <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include "stm32f7-pinctrl.dtsi"
+
+&pinctrl{
+	compatible = "st,stm32f746-pinctrl";
+};
diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
index 5f66d15..4be2ee5 100644
--- a/arch/arm/boot/dts/stm32f746.dtsi
+++ b/arch/arm/boot/dts/stm32f746.dtsi
@@ -42,7 +42,6 @@
 
 #include "skeleton.dtsi"
 #include "armv7-m.dtsi"
-#include <dt-bindings/pinctrl/stm32-pinfunc.h>
 #include <dt-bindings/clock/stm32fx-clock.h>
 #include <dt-bindings/mfd/stm32f7-rcc.h>
 
@@ -429,6 +428,28 @@
 			status = "disabled";
 		};
 
+		sdio2: sdio2@40011c00 {
+			compatible = "arm,pl180", "arm,primecell";
+			arm,primecell-periphid = <0x00880180>;
+			reg = <0x40011c00 0x400>;
+			clocks = <&rcc 0 STM32F7_APB2_CLOCK(SDMMC2)>;
+			clock-names = "apb_pclk";
+			interrupts = <103>;
+			max-frequency = <48000000>;
+			status = "disabled";
+		};
+
+		sdio1: sdio1@40012c00 {
+			compatible = "arm,pl180", "arm,primecell";
+			arm,primecell-periphid = <0x00880180>;
+			reg = <0x40012c00 0x400>;
+			clocks = <&rcc 0 STM32F7_APB2_CLOCK(SDMMC1)>;
+			clock-names = "apb_pclk";
+			interrupts = <49>;
+			max-frequency = <48000000>;
+			status = "disabled";
+		};
+
 		syscfg: system-config@40013800 {
 			compatible = "syscon";
 			reg = <0x40013800 0x400>;
@@ -498,222 +519,6 @@
 			reg = <0x40007000 0x400>;
 		};
 
-		pin-controller {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "st,stm32f746-pinctrl";
-			ranges = <0 0x40020000 0x3000>;
-			interrupt-parent = <&exti>;
-			st,syscfg = <&syscfg 0x8>;
-			pins-are-numbered;
-
-			gpioa: gpio@40020000 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x0 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOA)>;
-				st,bank-name = "GPIOA";
-			};
-
-			gpiob: gpio@40020400 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x400 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOB)>;
-				st,bank-name = "GPIOB";
-			};
-
-			gpioc: gpio@40020800 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x800 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOC)>;
-				st,bank-name = "GPIOC";
-			};
-
-			gpiod: gpio@40020c00 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0xc00 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOD)>;
-				st,bank-name = "GPIOD";
-			};
-
-			gpioe: gpio@40021000 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x1000 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOE)>;
-				st,bank-name = "GPIOE";
-			};
-
-			gpiof: gpio@40021400 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x1400 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOF)>;
-				st,bank-name = "GPIOF";
-			};
-
-			gpiog: gpio@40021800 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x1800 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOG)>;
-				st,bank-name = "GPIOG";
-			};
-
-			gpioh: gpio@40021c00 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x1c00 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOH)>;
-				st,bank-name = "GPIOH";
-			};
-
-			gpioi: gpio@40022000 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x2000 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOI)>;
-				st,bank-name = "GPIOI";
-			};
-
-			gpioj: gpio@40022400 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x2400 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOJ)>;
-				st,bank-name = "GPIOJ";
-			};
-
-			gpiok: gpio@40022800 {
-				gpio-controller;
-				#gpio-cells = <2>;
-				interrupt-controller;
-				#interrupt-cells = <2>;
-				reg = <0x2800 0x400>;
-				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOK)>;
-				st,bank-name = "GPIOK";
-			};
-
-			cec_pins_a: cec@0 {
-				pins {
-					pinmux = <STM32_PINMUX('A', 15, AF4)>; /* HDMI CEC */
-					slew-rate = <0>;
-					drive-open-drain;
-					bias-disable;
-				};
-			};
-
-			usart1_pins_a: usart1@0 {
-				pins1 {
-					pinmux = <STM32_PINMUX('A', 9, AF7)>; /* USART1_TX */
-					bias-disable;
-					drive-push-pull;
-					slew-rate = <0>;
-				};
-				pins2 {
-					pinmux = <STM32_PINMUX('A', 10, AF7)>; /* USART1_RX */
-					bias-disable;
-				};
-			};
-
-			usart1_pins_b: usart1@1 {
-				pins1 {
-					pinmux = <STM32_PINMUX('A', 9, AF7)>; /* USART1_TX */
-					bias-disable;
-					drive-push-pull;
-					slew-rate = <0>;
-				};
-				pins2 {
-					pinmux = <STM32_PINMUX('B', 7, AF7)>; /* USART1_RX */
-					bias-disable;
-				};
-			};
-
-			i2c1_pins_b: i2c1@0 {
-				pins {
-					pinmux = <STM32_PINMUX('B', 9, AF4)>, /* I2C1 SDA */
-						 <STM32_PINMUX('B', 8, AF4)>; /* I2C1 SCL */
-					bias-disable;
-					drive-open-drain;
-					slew-rate = <0>;
-				};
-			};
-
-			usbotg_hs_pins_a: usbotg-hs@0 {
-				pins {
-					pinmux = <STM32_PINMUX('H', 4, AF10)>, /* OTG_HS_ULPI_NXT */
-						 <STM32_PINMUX('I', 11, AF10)>, /* OTG_HS_ULPI_DIR */
-						 <STM32_PINMUX('C', 0, AF10)>, /* OTG_HS_ULPI_STP */
-						 <STM32_PINMUX('A', 5, AF10)>, /* OTG_HS_ULPI_CK */
-						 <STM32_PINMUX('A', 3, AF10)>, /* OTG_HS_ULPI_D0 */
-						 <STM32_PINMUX('B', 0, AF10)>, /* OTG_HS_ULPI_D1 */
-						 <STM32_PINMUX('B', 1, AF10)>, /* OTG_HS_ULPI_D2 */
-						 <STM32_PINMUX('B', 10, AF10)>, /* OTG_HS_ULPI_D3 */
-						 <STM32_PINMUX('B', 11, AF10)>, /* OTG_HS_ULPI_D4 */
-						 <STM32_PINMUX('B', 12, AF10)>, /* OTG_HS_ULPI_D5 */
-						 <STM32_PINMUX('B', 13, AF10)>, /* OTG_HS_ULPI_D6 */
-						 <STM32_PINMUX('B', 5, AF10)>; /* OTG_HS_ULPI_D7 */
-					bias-disable;
-					drive-push-pull;
-					slew-rate = <2>;
-				};
-			};
-
-			usbotg_hs_pins_b: usbotg-hs@1 {
-				pins {
-					pinmux = <STM32_PINMUX('H', 4, AF10)>, /* OTG_HS_ULPI_NXT */
-						 <STM32_PINMUX('C', 2, AF10)>, /* OTG_HS_ULPI_DIR */
-						 <STM32_PINMUX('C', 0, AF10)>, /* OTG_HS_ULPI_STP */
-						 <STM32_PINMUX('A', 5, AF10)>, /* OTG_HS_ULPI_CK */
-						 <STM32_PINMUX('A', 3, AF10)>, /* OTG_HS_ULPI_D0 */
-						 <STM32_PINMUX('B', 0, AF10)>, /* OTG_HS_ULPI_D1 */
-						 <STM32_PINMUX('B', 1, AF10)>, /* OTG_HS_ULPI_D2 */
-						 <STM32_PINMUX('B', 10, AF10)>, /* OTG_HS_ULPI_D3 */
-						 <STM32_PINMUX('B', 11, AF10)>, /* OTG_HS_ULPI_D4 */
-						 <STM32_PINMUX('B', 12, AF10)>, /* OTG_HS_ULPI_D5 */
-						 <STM32_PINMUX('B', 13, AF10)>, /* OTG_HS_ULPI_D6 */
-						 <STM32_PINMUX('B', 5, AF10)>; /* OTG_HS_ULPI_D7 */
-					bias-disable;
-					drive-push-pull;
-					slew-rate = <2>;
-				};
-			};
-
-			usbotg_fs_pins_a: usbotg-fs@0 {
-				pins {
-					pinmux = <STM32_PINMUX('A', 10, AF10)>, /* OTG_FS_ID */
-						 <STM32_PINMUX('A', 11, AF10)>, /* OTG_FS_DM */
-						 <STM32_PINMUX('A', 12, AF10)>; /* OTG_FS_DP */
-					bias-disable;
-					drive-push-pull;
-					slew-rate = <2>;
-				};
-			};
-		};
-
 		crc: crc@40023000 {
 			compatible = "st,stm32f7-crc";
 			reg = <0x40023000 0x400>;
@@ -771,6 +576,9 @@
 			interrupts = <77>;
 			clocks = <&rcc 0 STM32F7_AHB1_CLOCK(OTGHS)>;
 			clock-names = "otg";
+			g-rx-fifo-size = <256>;
+			g-np-tx-fifo-size = <32>;
+			g-tx-fifo-size = <128 128 64 64 64 64 32 32>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/stm32f769-disco.dts b/arch/arm/boot/dts/stm32f769-disco.dts
index 4463ca1..2241eec 100644
--- a/arch/arm/boot/dts/stm32f769-disco.dts
+++ b/arch/arm/boot/dts/stm32f769-disco.dts
@@ -42,11 +42,13 @@
 
 /dts-v1/;
 #include "stm32f746.dtsi"
+#include "stm32f769-pinctrl.dtsi"
 #include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "STMicroelectronics STM32F769-DISCO board";
-	compatible = "st,stm32f769-disco", "st,stm32f7";
+	compatible = "st,stm32f769-disco", "st,stm32f769";
 
 	chosen {
 		bootargs = "root=/dev/ram";
@@ -61,6 +63,42 @@
 		serial0 = &usart1;
 	};
 
+	leds {
+		compatible = "gpio-leds";
+		green {
+			gpios = <&gpioj 5 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+		red {
+			gpios = <&gpioj 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		autorepeat;
+		button@0 {
+			label = "User";
+			linux,code = <KEY_HOME>;
+			gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	usbotg_hs_phy: usb-phy {
+		#phy-cells = <0>;
+		compatible = "usb-nop-xceiv";
+		clocks = <&rcc 0 STM32F7_AHB1_CLOCK(OTGHSULPI)>;
+		clock-names = "main_clk";
+	};
+
+	mmc_vcard: mmc_vcard {
+		compatible = "regulator-fixed";
+		regulator-name = "mmc_vcard";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &cec {
@@ -73,8 +111,33 @@
 	clock-frequency = <25000000>;
 };
 
+&rtc {
+	status = "okay";
+};
+
+&sdio2 {
+	status = "okay";
+	vmmc-supply = <&mmc_vcard>;
+	cd-gpios = <&gpioi 15 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	broken-cd;
+	pinctrl-names = "default", "opendrain";
+	pinctrl-0 = <&sdio_pins_b>;
+	pinctrl-1 = <&sdio_pins_od_b>;
+	bus-width = <4>;
+};
+
 &usart1 {
 	pinctrl-0 = <&usart1_pins_a>;
 	pinctrl-names = "default";
 	status = "okay";
 };
+
+&usbotg_hs {
+	dr_mode = "otg";
+	phys = <&usbotg_hs_phy>;
+	phy-names = "usb2-phy";
+	pinctrl-0 = <&usbotg_hs_pins_a>;
+	pinctrl-names = "default";
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32f769-pinctrl.dtsi b/arch/arm/boot/dts/stm32f769-pinctrl.dtsi
new file mode 100644
index 0000000..31005dd
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f769-pinctrl.dtsi
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Alexandre Torgue  <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include "stm32f7-pinctrl.dtsi"
+
+&pinctrl{
+	compatible = "st,stm32f769-pinctrl";
+};
diff --git a/arch/arm/boot/dts/stm32h743-pinctrl.dtsi b/arch/arm/boot/dts/stm32h743-pinctrl.dtsi
index 65c1cd0..0f15dfb 100644
--- a/arch/arm/boot/dts/stm32h743-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32h743-pinctrl.dtsi
@@ -49,6 +49,8 @@
 			#size-cells = <1>;
 			compatible = "st,stm32h743-pinctrl";
 			ranges = <0 0x58020000 0x3000>;
+			interrupt-parent = <&exti>;
+			st,syscfg = <&syscfg 0x8>;
 			pins-are-numbered;
 
 			gpioa: gpio@58020000 {
@@ -57,6 +59,8 @@
 				reg = <0x0 0x400>;
 				clocks = <&rcc GPIOA_CK>;
 				st,bank-name = "GPIOA";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpiob: gpio@58020400 {
@@ -65,6 +69,8 @@
 				reg = <0x400 0x400>;
 				clocks = <&rcc GPIOB_CK>;
 				st,bank-name = "GPIOB";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpioc: gpio@58020800 {
@@ -73,6 +79,8 @@
 				reg = <0x800 0x400>;
 				clocks = <&rcc GPIOC_CK>;
 				st,bank-name = "GPIOC";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpiod: gpio@58020c00 {
@@ -81,6 +89,8 @@
 				reg = <0xc00 0x400>;
 				clocks = <&rcc GPIOD_CK>;
 				st,bank-name = "GPIOD";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpioe: gpio@58021000 {
@@ -89,6 +99,8 @@
 				reg = <0x1000 0x400>;
 				clocks = <&rcc GPIOE_CK>;
 				st,bank-name = "GPIOE";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpiof: gpio@58021400 {
@@ -97,6 +109,8 @@
 				reg = <0x1400 0x400>;
 				clocks = <&rcc GPIOF_CK>;
 				st,bank-name = "GPIOF";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpiog: gpio@58021800 {
@@ -105,6 +119,8 @@
 				reg = <0x1800 0x400>;
 				clocks = <&rcc GPIOG_CK>;
 				st,bank-name = "GPIOG";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpioh: gpio@58021c00 {
@@ -113,6 +129,8 @@
 				reg = <0x1c00 0x400>;
 				clocks = <&rcc GPIOH_CK>;
 				st,bank-name = "GPIOH";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpioi: gpio@58022000 {
@@ -121,6 +139,8 @@
 				reg = <0x2000 0x400>;
 				clocks = <&rcc GPIOI_CK>;
 				st,bank-name = "GPIOI";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpioj: gpio@58022400 {
@@ -129,6 +149,8 @@
 				reg = <0x2400 0x400>;
 				clocks = <&rcc GPIOJ_CK>;
 				st,bank-name = "GPIOJ";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			gpiok: gpio@58022800 {
@@ -137,6 +159,8 @@
 				reg = <0x2800 0x400>;
 				clocks = <&rcc GPIOK_CK>;
 				st,bank-name = "GPIOK";
+				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 
 			usart1_pins: usart1@0 {
@@ -164,6 +188,26 @@
 					bias-disable;
 				};
 			};
+
+			usbotg_hs_pins_a: usbotg-hs@0 {
+				pins {
+					pinmux = <STM32_PINMUX('H', 4, AF10)>,	/* ULPI_NXT */
+							 <STM32_PINMUX('I', 11, AF10)>, /* ULPI_DIR> */
+							 <STM32_PINMUX('C', 0, AF10)>,	/* ULPI_STP> */
+							 <STM32_PINMUX('A', 5, AF10)>,	/* ULPI_CK> */
+							 <STM32_PINMUX('A', 3, AF10)>,	/* ULPI_D0> */
+							 <STM32_PINMUX('B', 0, AF10)>,	/* ULPI_D1> */
+							 <STM32_PINMUX('B', 1, AF10)>,	/* ULPI_D2> */
+							 <STM32_PINMUX('B', 10, AF10)>, /* ULPI_D3> */
+							 <STM32_PINMUX('B', 11, AF10)>, /* ULPI_D4> */
+							 <STM32_PINMUX('B', 12, AF10)>, /* ULPI_D5> */
+							 <STM32_PINMUX('B', 13, AF10)>, /* ULPI_D6> */
+							 <STM32_PINMUX('B', 5, AF10)>;	/* ULPI_D7> */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/stm32h743.dtsi b/arch/arm/boot/dts/stm32h743.dtsi
index bbfcbac..2bb103e 100644
--- a/arch/arm/boot/dts/stm32h743.dtsi
+++ b/arch/arm/boot/dts/stm32h743.dtsi
@@ -44,6 +44,7 @@
 #include "armv7-m.dtsi"
 #include <dt-bindings/clock/stm32h7-clks.h>
 #include <dt-bindings/mfd/stm32h7-rcc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	clocks {
@@ -100,6 +101,27 @@
 			};
 		};
 
+		spi2: spi@40003800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32h7-spi";
+			reg = <0x40003800 0x400>;
+			interrupts = <36>;
+			clocks = <&rcc SPI2_CK>;
+			status = "disabled";
+
+		};
+
+		spi3: spi@40003c00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32h7-spi";
+			reg = <0x40003c00 0x400>;
+			interrupts = <51>;
+			clocks = <&rcc SPI3_CK>;
+			status = "disabled";
+		};
+
 		usart2: serial@40004400 {
 			compatible = "st,stm32f7-uart";
 			reg = <0x40004400 0x400>;
@@ -140,6 +162,36 @@
 			clocks = <&rcc USART1_CK>;
 		};
 
+		spi1: spi@40013000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32h7-spi";
+			reg = <0x40013000 0x400>;
+			interrupts = <35>;
+			clocks = <&rcc SPI1_CK>;
+			status = "disabled";
+		};
+
+		spi4: spi@40013400 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32h7-spi";
+			reg = <0x40013400 0x400>;
+			interrupts = <84>;
+			clocks = <&rcc SPI4_CK>;
+			status = "disabled";
+		};
+
+		spi5: spi@40015000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32h7-spi";
+			reg = <0x40015000 0x400>;
+			interrupts = <85>;
+			clocks = <&rcc SPI5_CK>;
+			status = "disabled";
+		};
+
 		dma1: dma@40020000 {
 			compatible = "st,stm32-dma";
 			reg = <0x40020000 0x400>;
@@ -217,6 +269,27 @@
 			};
 		};
 
+		usbotg_hs: usb@40040000 {
+			compatible = "st,stm32f7-hsotg";
+			reg = <0x40040000 0x40000>;
+			interrupts = <77>;
+			clocks = <&rcc USB1OTG_CK>;
+			clock-names = "otg";
+			g-rx-fifo-size = <256>;
+			g-np-tx-fifo-size = <32>;
+			g-tx-fifo-size = <128 128 64 64 64 64 32 32>;
+			status = "disabled";
+		};
+
+		usbotg_fs: usb@40080000 {
+			compatible = "st,stm32f4x9-fsotg";
+			reg = <0x40080000 0x40000>;
+			interrupts = <101>;
+			clocks = <&rcc USB2OTG_CK>;
+			clock-names = "otg";
+			status = "disabled";
+		};
+
 		mdma1: dma@52000000 {
 			compatible = "st,stm32h7-mdma";
 			reg = <0x52000000 0x1000>;
@@ -227,6 +300,29 @@
 			dma-requests = <32>;
 		};
 
+		exti: interrupt-controller@58000000 {
+			compatible = "st,stm32h7-exti";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			reg = <0x58000000 0x400>;
+			interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <62>, <76>;
+		};
+
+		syscfg: system-config@58000400 {
+			compatible = "syscon";
+			reg = <0x58000400 0x400>;
+		};
+
+		spi6: spi@58001400 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32h7-spi";
+			reg = <0x58001400 0x400>;
+			interrupts = <86>;
+			clocks = <&rcc SPI6_CK>;
+			status = "disabled";
+		};
+
 		lptimer2: timer@58002400 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -304,7 +400,7 @@
 			};
 		};
 
-		vrefbuf: regulator@58003C00 {
+		vrefbuf: regulator@58003c00 {
 			compatible = "st,stm32-vrefbuf";
 			reg = <0x58003C00 0x8>;
 			clocks = <&rcc VREF_CK>;
@@ -313,6 +409,20 @@
 			status = "disabled";
 		};
 
+		rtc: rtc@58004000 {
+			compatible = "st,stm32h7-rtc";
+			reg = <0x58004000 0x400>;
+			clocks = <&rcc RTCAPB_CK>, <&rcc RTC_CK>;
+			clock-names = "pclk", "rtc_ck";
+			assigned-clocks = <&rcc RTC_CK>;
+			assigned-clock-parents = <&rcc LSE_CK>;
+			interrupt-parent = <&exti>;
+			interrupts = <17 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "alarm";
+			st,syscfg = <&pwrcfg>;
+			status = "disabled";
+		};
+
 		rcc: reset-clock-controller@58024400 {
 			compatible = "st,stm32h743-rcc", "st,stm32-rcc";
 			reg = <0x58024400 0x400>;
diff --git a/arch/arm/boot/dts/stm32h743i-disco.dts b/arch/arm/boot/dts/stm32h743i-disco.dts
index 79e841d..45e088c 100644
--- a/arch/arm/boot/dts/stm32h743i-disco.dts
+++ b/arch/arm/boot/dts/stm32h743i-disco.dts
@@ -63,7 +63,7 @@
 };
 
 &clk_hse {
-	clock-frequency = <125000000>;
+	clock-frequency = <25000000>;
 };
 
 &usart2 {
diff --git a/arch/arm/boot/dts/stm32h743i-eval.dts b/arch/arm/boot/dts/stm32h743i-eval.dts
index 9f0e72c..c7187e1 100644
--- a/arch/arm/boot/dts/stm32h743i-eval.dts
+++ b/arch/arm/boot/dts/stm32h743i-eval.dts
@@ -68,6 +68,14 @@
 		regulator-max-microvolt = <3300000>;
 		regulator-always-on;
 	};
+
+	usbotg_hs_phy: usb-phy {
+		#phy-cells = <0>;
+		compatible = "usb-nop-xceiv";
+		clocks = <&rcc USB1ULPI_CK>;
+		clock-names = "main_clk";
+	};
+
 };
 
 &adc_12 {
@@ -84,9 +92,21 @@
 	clock-frequency = <25000000>;
 };
 
+&rtc {
+	status = "okay";
+};
+
 &usart1 {
 	pinctrl-0 = <&usart1_pins>;
 	pinctrl-names = "default";
 	status = "okay";
 };
 
+&usbotg_hs {
+	pinctrl-0 = <&usbotg_hs_pins_a>;
+	pinctrl-names = "default";
+	phys = <&usbotg_hs_phy>;
+	phy-names = "usb2-phy";
+	dr_mode = "otg";
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
new file mode 100644
index 0000000..c0743305
--- /dev/null
+++ b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+
+/ {
+	soc {
+		pinctrl: pin-controller {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "st,stm32mp157-pinctrl";
+			ranges = <0 0x50002000 0xa400>;
+			pins-are-numbered;
+
+			gpioa: gpio@50002000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x0 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOA";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 0 16>;
+			};
+
+			gpiob: gpio@50003000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x1000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOB";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 16 16>;
+			};
+
+			gpioc: gpio@50004000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x2000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOC";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 32 16>;
+			};
+
+			gpiod: gpio@50005000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x3000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOD";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 48 16>;
+			};
+
+			gpioe: gpio@50006000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x4000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOE";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 64 16>;
+			};
+
+			gpiof: gpio@50007000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x5000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOF";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 80 16>;
+			};
+
+			gpiog: gpio@50008000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x6000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOG";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 96 16>;
+			};
+
+			gpioh: gpio@50009000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x7000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOH";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 112 16>;
+			};
+
+			gpioi: gpio@5000a000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x8000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOI";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 128 16>;
+			};
+
+			gpioj: gpio@5000b000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x9000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOJ";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 144 16>;
+			};
+
+			gpiok: gpio@5000c000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0xa000 0x400>;
+				clocks = <&clk_pll3_p>;
+				st,bank-name = "GPIOK";
+				ngpios = <8>;
+				gpio-ranges = <&pinctrl 0 160 8>;
+			};
+
+			uart4_pins_a: uart4@0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+					bias-disable;
+				};
+			};
+		};
+
+		pinctrl_z: pin-controller-z {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "st,stm32mp157-z-pinctrl";
+			ranges = <0 0x54004000 0x400>;
+			pins-are-numbered;
+			status = "disabled";
+
+			gpioz: gpio@54004000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0 0x400>;
+				clocks = <&clk_pll2_p>;
+				st,bank-name = "GPIOZ";
+				st,bank-ioport = <11>;
+				ngpios = <8>;
+				gpio-ranges = <&pinctrl_z 0 400 8>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stm32mp157c-ed1.dts b/arch/arm/boot/dts/stm32mp157c-ed1.dts
new file mode 100644
index 0000000..9f90337a
--- /dev/null
+++ b/arch/arm/boot/dts/stm32mp157c-ed1.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+/dts-v1/;
+
+#include "stm32mp157c.dtsi"
+#include "stm32mp157-pinctrl.dtsi"
+
+/ {
+	model = "STMicroelectronics STM32MP157C eval daughter";
+	compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		reg = <0xC0000000 0x40000000>;
+	};
+
+	aliases {
+		serial0 = &uart4;
+	};
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins_a>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts b/arch/arm/boot/dts/stm32mp157c-ev1.dts
new file mode 100644
index 0000000..57e6dbc
--- /dev/null
+++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+/dts-v1/;
+
+#include "stm32mp157c-ed1.dts"
+
+/ {
+	model = "STMicroelectronics STM32MP157C eval daughter on eval mother";
+	compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		serial0 = &uart4;
+	};
+};
diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi b/arch/arm/boot/dts/stm32mp157c.dtsi
new file mode 100644
index 0000000..9e17e42
--- /dev/null
+++ b/arch/arm/boot/dts/stm32mp157c.dtsi
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <0>;
+		};
+
+		cpu1: cpu@1 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <1>;
+		};
+	};
+
+	psci {
+		compatible = "arm,psci";
+		method = "smc";
+		cpu_off = <0x84000002>;
+		cpu_on = <0x84000003>;
+	};
+
+	aliases {
+		gpio0 = &gpioa;
+		gpio1 = &gpiob;
+		gpio2 = &gpioc;
+		gpio3 = &gpiod;
+		gpio4 = &gpioe;
+		gpio5 = &gpiof;
+		gpio6 = &gpiog;
+		gpio7 = &gpioh;
+		gpio8 = &gpioi;
+		gpio9 = &gpioj;
+		gpio10 = &gpiok;
+	};
+
+	intc: interrupt-controller@a0021000 {
+		compatible = "arm,cortex-a7-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0xa0021000 0x1000>,
+		      <0xa0022000 0x2000>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+		interrupt-parent = <&intc>;
+	};
+
+	clocks {
+		clk_hse: clk-hse {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+		};
+
+		clk_pll_per: clk-pll-per {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <64000000>;
+		};
+
+		clk_hsi: clk-hsi {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <64000000>;
+		};
+
+		clk_lse: clk-lse {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+		};
+
+		clk_lsi: clk-lsi {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32000>;
+		};
+
+		clk_csi: clk-csi {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <4000000>;
+		};
+
+		clk_pclk1: clk-pclk1 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <86000000>;
+		};
+
+		clk_pll3_p: clk-pll3_p {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <172000000>;
+		};
+
+		clk_pll2_p: clk-pll2_p {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <264000000>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+
+		usart2: serial@4000e000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x4000e000 0x400>;
+			interrupts = <GIC_SPI 38 IRQ_TYPE_NONE>;
+			clocks = <&clk_pclk1>;
+			status = "disabled";
+		};
+
+		usart3: serial@4000f000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x4000f000 0x400>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_NONE>;
+			clocks = <&clk_pclk1>;
+			status = "disabled";
+		};
+
+		uart4: serial@40010000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x40010000 0x400>;
+			interrupts = <GIC_SPI 52 IRQ_TYPE_NONE>;
+			clocks = <&clk_pclk1>;
+			status = "disabled";
+		};
+
+		uart5: serial@40011000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x40011000 0x400>;
+			interrupts = <GIC_SPI 53 IRQ_TYPE_NONE>;
+			clocks = <&clk_pclk1>;
+			status = "disabled";
+		};
+
+		uart7: serial@40018000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x40018000 0x400>;
+			interrupts = <GIC_SPI 82 IRQ_TYPE_NONE>;
+			clocks = <&clk_pclk1>;
+			status = "disabled";
+		};
+
+		uart8: serial@40019000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x40019000 0x400>;
+			interrupts = <GIC_SPI 83 IRQ_TYPE_NONE>;
+			clocks = <&clk_pclk1>;
+			status = "disabled";
+		};
+
+		usart6: serial@44003000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x44003000 0x400>;
+			interrupts = <GIC_SPI 71 IRQ_TYPE_NONE>;
+			clocks = <&clk_pclk1>;
+			status = "disabled";
+		};
+
+		usart1: serial@5c000000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x5c000000 0x400>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_NONE>;
+			clocks = <&clk_pclk1>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
index 09e9095..6c254ec 100644
--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -164,8 +164,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts b/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
index 39ba4cc..38a2c41 100644
--- a/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
+++ b/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
@@ -106,8 +106,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
index dfc88ae..cf7b392 100644
--- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
@@ -123,8 +123,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 1982c8c..197a1f2 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -162,8 +162,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts b/arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts
index 147cbc5..896e27a 100644
--- a/arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts
+++ b/arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts
@@ -150,8 +150,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts b/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
index 41ca8bd..ea7a59d 100644
--- a/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
+++ b/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
@@ -141,8 +141,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH01 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH01 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
index f33e42d..cc988cc 100644
--- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts
+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
@@ -106,8 +106,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts
index 35c57d0..f63767c 100644
--- a/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts
+++ b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts
@@ -78,8 +78,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-inet1.dts b/arch/arm/boot/dts/sun4i-a10-inet1.dts
index 9482e83..26d0c1d 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet1.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet1.dts
@@ -152,8 +152,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index 4b5c91c..5d09652 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -142,8 +142,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts
index 13224f5..221acd10 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts
@@ -300,8 +300,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts
index d22bd79..80ecd78 100644
--- a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts
+++ b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts
@@ -106,8 +106,7 @@
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
index 879141c..247fa27 100644
--- a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
+++ b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
@@ -133,8 +133,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-marsboard.dts b/arch/arm/boot/dts/sun4i-a10-marsboard.dts
index 435c551..0dbf695 100644
--- a/arch/arm/boot/dts/sun4i-a10-marsboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-marsboard.dts
@@ -132,8 +132,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
index 1b639e5..f9d74e2 100644
--- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
@@ -96,8 +96,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-mk802.dts b/arch/arm/boot/dts/sun4i-a10-mk802.dts
index 7198b34..059fe9c 100644
--- a/arch/arm/boot/dts/sun4i-a10-mk802.dts
+++ b/arch/arm/boot/dts/sun4i-a10-mk802.dts
@@ -56,12 +56,27 @@
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
 };
 
 &codec {
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -70,11 +85,20 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-mk802ii.dts b/arch/arm/boot/dts/sun4i-a10-mk802ii.dts
index e460da2..17dcdf0 100644
--- a/arch/arm/boot/dts/sun4i-a10-mk802ii.dts
+++ b/arch/arm/boot/dts/sun4i-a10-mk802ii.dts
@@ -82,8 +82,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
index 49247fb..b74a614 100644
--- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
@@ -97,7 +97,6 @@
 		864000  1300000
 		624000  1250000
 		>;
-	cooling-max-level = <2>;
 };
 
 &de {
@@ -165,8 +164,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
index 6e14054..b97a0f2 100644
--- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts
+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
@@ -140,8 +140,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts b/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts
index 5081303..84b25be 100644
--- a/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts
+++ b/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts
@@ -138,8 +138,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 4f2f2eea..77e8436 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -123,8 +123,6 @@
 				624000	1250000
 				>;
 			#cooling-cells = <2>;
-			cooling-min-level = <0>;
-			cooling-max-level = <3>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts b/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts
index d2dee8d..39504d7 100644
--- a/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts
@@ -93,8 +93,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_t003>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
-	cd-inverted;
+	cd-gpios = <&pio 6 1 GPIO_ACTIVE_LOW>; /* PG1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts b/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts
index 16f839d..8d4fb93 100644
--- a/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts
@@ -104,8 +104,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_t004>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
-	cd-inverted;
+	cd-gpios = <&pio 6 1 GPIO_ACTIVE_LOW>; /* PG1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a10s-mk802.dts b/arch/arm/boot/dts/sun5i-a10s-mk802.dts
index 020aa9d..dd7fd5c 100644
--- a/arch/arm/boot/dts/sun5i-a10s-mk802.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-mk802.dts
@@ -92,8 +92,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_mk802>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
-	cd-inverted;
+	cd-gpios = <&pio 6 1 GPIO_ACTIVE_LOW>; /* PG1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index da95118..2c902ed 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -201,8 +201,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino_micro>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
-	cd-inverted;
+	cd-gpios = <&pio 6 1 GPIO_ACTIVE_LOW>; /* PG1 */
 	status = "okay";
 };
 
@@ -211,8 +210,7 @@
 	pinctrl-0 = <&mmc1_pins_a>, <&mmc1_cd_pin_olinuxino_micro>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
-	cd-inverted;
+	cd-gpios = <&pio 6 13 GPIO_ACTIVE_LOW>; /* PG13 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts b/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts
index 262b366..034853d1 100644
--- a/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts
@@ -80,8 +80,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_r7>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
-	cd-inverted;
+	cd-gpios = <&pio 6 1 GPIO_ACTIVE_LOW>; /* PG1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts b/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts
index 5482be1..3f68ef5 100644
--- a/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts
@@ -130,8 +130,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_wobo_i5>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
-	cd-inverted;
+	cd-gpios = <&pio 1 3 GPIO_ACTIVE_LOW>; /* PB3 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts b/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts
index 3dbb0d7..378214d 100644
--- a/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts
+++ b/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts
@@ -125,8 +125,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_d709>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
-	cd-inverted;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
index 584fa57..7ee0c3f 100644
--- a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
+++ b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
@@ -120,8 +120,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_h702>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
-	cd-inverted;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
index 3a831ea..aa4b34f 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
@@ -99,8 +99,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxinom>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
-	cd-inverted;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index 4b9af42..437ad91 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -194,8 +194,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
-	cd-inverted;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 4e830f5..b1d8277 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -116,8 +116,6 @@
 		432000	1200000
 		>;
 	#cooling-cells = <2>;
-	cooling-min-level = <0>;
-	cooling-max-level = <5>;
 };
 
 &pio {
diff --git a/arch/arm/boot/dts/sun5i-gr8-evb.dts b/arch/arm/boot/dts/sun5i-gr8-evb.dts
index 558c16a..5f0adc0 100644
--- a/arch/arm/boot/dts/sun5i-gr8-evb.dts
+++ b/arch/arm/boot/dts/sun5i-gr8-evb.dts
@@ -236,8 +236,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gr8_evb>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
-	cd-inverted;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
index 49229b3..8acbaab 100644
--- a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
@@ -127,8 +127,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_vcc3v0>;
 	bus-width = <4>;
-	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
-	cd-inverted;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-a31-colombus.dts b/arch/arm/boot/dts/sun6i-a31-colombus.dts
index 85eff03..939c497 100644
--- a/arch/arm/boot/dts/sun6i-a31-colombus.dts
+++ b/arch/arm/boot/dts/sun6i-a31-colombus.dts
@@ -117,8 +117,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_colombus>;
 	vmmc-supply = <&reg_vcc3v0>;
 	bus-width = <4>;
-	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
-	cd-inverted;
+	cd-gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index 19e382a..ce4f9e9 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -218,8 +218,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_hummingbird>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
-	cd-inverted;
+	cd-gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-a31-i7.dts b/arch/arm/boot/dts/sun6i-a31-i7.dts
index 010a84c..d659be9 100644
--- a/arch/arm/boot/dts/sun6i-a31-i7.dts
+++ b/arch/arm/boot/dts/sun6i-a31-i7.dts
@@ -58,6 +58,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -93,6 +104,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -113,6 +128,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -124,8 +149,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_i7>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
-	cd-inverted;
+	cd-gpios = <&pio 7 22 GPIO_ACTIVE_LOW>; /* PH22 */
 	status = "okay";
 };
 
@@ -161,6 +185,10 @@
 	status = "okay";
 };
 
+&tcon0 {
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun6i-a31-m9.dts b/arch/arm/boot/dts/sun6i-a31-m9.dts
index 50605fd..9698f6d 100644
--- a/arch/arm/boot/dts/sun6i-a31-m9.dts
+++ b/arch/arm/boot/dts/sun6i-a31-m9.dts
@@ -107,8 +107,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_m9>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
-	cd-inverted;
+	cd-gpios = <&pio 7 22 GPIO_ACTIVE_LOW>; /* PH22 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts b/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
index 5219556..bb14b17 100644
--- a/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
+++ b/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
@@ -107,8 +107,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_m9>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
-	cd-inverted;
+	cd-gpios = <&pio 7 22 GPIO_ACTIVE_LOW>; /* PH22 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 72d3fe4..c729925 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -113,8 +113,6 @@
 				480000	1000000
 				>;
 			#cooling-cells = <2>;
-			cooling-min-level = <0>;
-			cooling-max-level = <3>;
 		};
 
 		cpu@1 {
diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
index 0cdb38a..4cb9664 100644
--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
@@ -151,8 +151,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_primo81>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
-	cd-inverted;
+	cd-gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
index 2984764..da0ccf5 100644
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
@@ -167,8 +167,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_sina31s>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */
-	cd-inverted;
+	cd-gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
index b2758dd..b8b79c0 100644
--- a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
@@ -120,8 +120,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bpi_m2>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */
-	cd-inverted;
+	cd-gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
index f3edf9c..aab6c17 100644
--- a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
@@ -102,8 +102,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bs1078v2>;
 	vmmc-supply = <&reg_vcc3v0>;
 	bus-width = <4>;
-	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
-	cd-inverted;
+	cd-gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
index 3cc4046..4e72e4f 100644
--- a/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
@@ -69,8 +69,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_e708_q1>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
-	cd-inverted;
+	cd-gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
index 4ed3162..763cb03 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
@@ -184,8 +184,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bpi_m1p>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
-	cd-inverted;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
index 88a1c23..70dfc4a 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
@@ -63,6 +63,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -109,6 +120,10 @@
 		>;
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -130,6 +145,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins_a>;
@@ -159,8 +184,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bananapi>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
-	cd-inverted;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapro.dts b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
index e7af1b7..0898eb6 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
@@ -158,8 +158,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bananapro>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
-	cd-inverted;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 39f43e4..942ac9d 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -165,8 +165,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 8c9bedc..5649161 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -206,8 +206,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
index 6e6264c..1f0e5ec 100644
--- a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
+++ b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
@@ -163,8 +163,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v0>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
index 5580997..2e3f2f2 100644
--- a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
+++ b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
@@ -160,8 +160,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts b/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts
index 794e761..926fa19 100644
--- a/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts
+++ b/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts
@@ -107,8 +107,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 8 5 GPIO_ACTIVE_HIGH>; /* PI5 */
-	cd-inverted;
+	cd-gpios = <&pio 8 5 GPIO_ACTIVE_LOW>; /* PI5 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts
index 8a8a6db..1b05ba4 100644
--- a/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts
+++ b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts
@@ -124,8 +124,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts
index 442f3c7..b1ab7c1 100644
--- a/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts
+++ b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts
@@ -227,8 +227,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_lamobo_r1>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
-	cd-inverted;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-m3.dts b/arch/arm/boot/dts/sun7i-a20-m3.dts
index 43c9478..e91a209 100644
--- a/arch/arm/boot/dts/sun7i-a20-m3.dts
+++ b/arch/arm/boot/dts/sun7i-a20-m3.dts
@@ -120,8 +120,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-mk808c.dts b/arch/arm/boot/dts/sun7i-a20-mk808c.dts
index f741309..6109f79 100644
--- a/arch/arm/boot/dts/sun7i-a20-mk808c.dts
+++ b/arch/arm/boot/dts/sun7i-a20-mk808c.dts
@@ -66,12 +66,27 @@
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
 };
 
 &codec {
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -80,6 +95,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+	remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins_a>;
@@ -112,8 +137,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v0>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
index 64c8ef9..f080f82 100644
--- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
@@ -61,6 +61,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -79,6 +90,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -107,6 +122,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins_a>;
@@ -190,8 +215,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
@@ -200,8 +224,7 @@
 	pinctrl-0 = <&mmc3_pins_a>, <&mmc3_cd_pin_olimex_som_evb>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 0 GPIO_ACTIVE_HIGH>; /* PH0 */
-	cd-inverted;
+	cd-gpios = <&pio 7 0 GPIO_ACTIVE_LOW>; /* PH0 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som204-evb-emmc.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som204-evb-emmc.dts
new file mode 100644
index 0000000..c56620a
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olimex-som204-evb-emmc.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree Source for A20-SOM204-EVB-eMMC Board
+ *
+ * Copyright (C) 2018 Olimex Ltd.
+ *   Author: Stefan Mavrodiev <stefan@olimex.com>
+ */
+
+/dts-v1/;
+#include "sun7i-a20-olimex-som204-evb.dts"
+
+/ {
+	model = "Olimex A20-SOM204-EVB-eMMC";
+	compatible = "olimex,a20-olimex-som204-evb-emmc", "allwinner,sun7i-a20";
+
+	mmc2_pwrseq: mmc2_pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&pio 2 16 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins_a>;
+	vmmc-supply = <&reg_vcc3v3>;
+	mmc-pwrseq = <&mmc2_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	emmc: emmc@0 {
+		reg = <0>;
+		compatible = "mmc-card";
+		broken-hpi;
+	};
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som204-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som204-evb.dts
new file mode 100644
index 0000000..eae8e26
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olimex-som204-evb.dts
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree Source for A20-SOM204-EVB Board
+ *
+ * Copyright (C) 2018 Olimex Ltd.
+ *   Author: Stefan Mavrodiev <stefan@olimex.com>
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+	model = "Olimex A20-SOM204-EVB";
+	compatible = "olimex,a20-olimex-som204-evb", "allwinner,sun7i-a20";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart4;
+		serial2 = &uart7;
+		spi0 = &spi1;
+		spi1 = &spi2;
+		ethernet1 = &rtl8723bs;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		stat {
+			label = "a20-som204-evb:green:stat";
+			gpios = <&pio 8 0 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		led1 {
+			label = "a20-som204-evb:green:led1";
+			gpios = <&pio 8 10 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		led2 {
+			label = "a20-som204-evb:yellow:led2";
+			gpios = <&pio 8 11 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	rtl_pwrseq: rtl_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&pio 6 9 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&ahci {
+	target-supply = <&reg_ahci_5v>;
+	status = "okay";
+};
+
+&can0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&can0_pins_a>;
+	status = "okay";
+};
+
+&codec {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&de {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_pins_rgmii_a>;
+	phy = <&phy3>;
+	phy-mode = "rgmii";
+	phy-supply = <&reg_vcc3v3>;
+
+	snps,reset-gpio = <&pio 0 17 GPIO_ACTIVE_HIGH>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 1000000>;
+	status = "okay";
+
+	phy3: ethernet-phy@3 {
+		reg = <3>;
+	};
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+
+	axp209: pmic@34 {
+		reg = <0x34>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+/* Exposed to UEXT1 */
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+
+	eeprom: eeprom@50 {
+		compatible = "atmel,24c16";
+		reg = <0x50>;
+		pagesize = <16>;
+	};
+};
+
+/* Exposed to UEXT2 */
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins_a>;
+	status = "okay";
+};
+
+&ir0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ir0_rx_pins_a>;
+	status = "okay";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	status = "okay";
+};
+
+&mmc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc3_pins_a>;
+	vmmc-supply = <&reg_vcc3v3>;
+	mmc-pwrseq = <&rtl_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	rtl8723bs: sdio_wifi@1 {
+		reg = <1>;
+	};
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&pio {
+	bt_uart_pins: bt_uart_pins@0 {
+		pins = "PG6", "PG7", "PG8";
+		function = "uart3";
+	};
+};
+
+#include "axp209.dtsi"
+
+&ac_power_supply {
+	status = "okay";
+};
+
+&battery_power_supply {
+	status = "okay";
+};
+
+&reg_ahci_5v {
+	gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-always-on;
+	regulator-min-microvolt = <1300000>;
+	regulator-max-microvolt = <1300000>;
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_ldo4 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-pg";
+};
+
+&reg_usb0_vbus {
+	gpio = <&pio 2 17 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&reg_usb1_vbus {
+	status = "okay";
+};
+
+&reg_usb2_vbus {
+	status = "okay";
+};
+
+/* Exposed to UEXT1 */
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_pins_a>,
+		    <&spi1_cs0_pins_a>;
+	status = "okay";
+};
+
+/* Exposed to UEXT2 */
+&spi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2_pins_a>,
+		    <&spi2_cs0_pins_a>;
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+/* Used for RTL8723BS bluetooth */
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&bt_uart_pins>;
+	status = "okay";
+};
+
+/* Exposed to UEXT1 */
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins_a>;
+	status = "okay";
+};
+
+/* Exposed to UEXT2 */
+&uart7 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart7_pins_a>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usb_power_supply {
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	usb0_vbus_power-supply = <&usb_power_supply>;
+	usb0_vbus-supply = <&reg_usb0_vbus>;
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	usb2_vbus-supply = <&reg_usb2_vbus>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
index edf9c3c..d20fd03 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
@@ -158,8 +158,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
index ba25018..b828677 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
@@ -159,8 +159,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index dffbaa2..866d230 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -226,8 +226,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
@@ -236,8 +235,7 @@
 	pinctrl-0 = <&mmc3_pins_a>, <&mmc3_cd_pin_olinuxinom>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
-	cd-inverted;
+	cd-gpios = <&pio 7 11 GPIO_ACTIVE_LOW>; /* PH11 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts b/arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
index 7af4c8f..f5c7178 100644
--- a/arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
+++ b/arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
@@ -61,6 +61,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -98,6 +109,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -119,6 +134,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins_a>;
@@ -144,8 +169,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_orangepi>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
-	cd-inverted;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
 	status = "okay";
 };
 
@@ -154,8 +178,7 @@
 	pinctrl-0 = <&mmc3_pins_a>, <&mmc3_cd_pin_orangepi>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
-	cd-inverted;
+	cd-gpios = <&pio 7 11 GPIO_ACTIVE_LOW>; /* PH11 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-orangepi.dts b/arch/arm/boot/dts/sun7i-a20-orangepi.dts
index 0a8d4a0..7a4244e 100644
--- a/arch/arm/boot/dts/sun7i-a20-orangepi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-orangepi.dts
@@ -135,8 +135,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_orangepi>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
-	cd-inverted;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
index fb591f3..bfca960 100644
--- a/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
@@ -158,8 +158,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
index 777152a..c576f10 100644
--- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
@@ -159,8 +159,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts b/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts
index f8d0aaf..8202c87 100644
--- a/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts
+++ b/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts
@@ -154,8 +154,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
index 7f8405a..ff5c108 100644
--- a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
+++ b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
@@ -123,8 +123,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
-	cd-inverted;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index bd0cd32..e529e4f 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -47,7 +47,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/thermal/thermal.h>
 #include <dt-bindings/dma/sun4i-a10.h>
-#include <dt-bindings/clock/sun4i-a10-ccu.h>
+#include <dt-bindings/clock/sun7i-a20-ccu.h>
 #include <dt-bindings/reset/sun4i-a10-ccu.h>
 
 / {
@@ -116,8 +116,6 @@
 				144000	1000000
 				>;
 			#cooling-cells = <2>;
-			cooling-min-level = <0>;
-			cooling-max-level = <6>;
 		};
 
 		cpu@1 {
@@ -1217,6 +1215,31 @@
 			#size-cells = <0>;
 		};
 
+		mali: gpu@1c40000 {
+			compatible = "allwinner,sun7i-a20-mali", "arm,mali-400";
+			reg = <0x01c40000 0x10000>;
+			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "gp",
+					  "gpmmu",
+					  "pp0",
+					  "ppmmu0",
+					  "pp1",
+					  "ppmmu1",
+					  "pmu";
+			clocks = <&ccu CLK_AHB_GPU>, <&ccu CLK_GPU>;
+			clock-names = "bus", "core";
+			resets = <&ccu RST_GPU>;
+
+			assigned-clocks = <&ccu CLK_GPU>;
+			assigned-clock-rates = <384000000>;
+		};
+
 		gmac: ethernet@1c50000 {
 			compatible = "allwinner,sun7i-a20-gmac";
 			reg = <0x01c50000 0x10000>;
diff --git a/arch/arm/boot/dts/sun8i-a23-evb.dts b/arch/arm/boot/dts/sun8i-a23-evb.dts
index 87289a6..8a93697 100644
--- a/arch/arm/boot/dts/sun8i-a23-evb.dts
+++ b/arch/arm/boot/dts/sun8i-a23-evb.dts
@@ -107,8 +107,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_evb>;
 	vmmc-supply = <&reg_vcc3v0>;
 	bus-width = <4>;
-	cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
-	cd-inverted;
+	cd-gpios = <&pio 1 4 GPIO_ACTIVE_LOW>; /* PB4 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
index be9a6b8..a1a1eb6 100644
--- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
+++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
@@ -43,7 +43,6 @@
 
 /dts-v1/;
 #include "sun8i-a33.dtsi"
-#include "sunxi-common-regulators.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
@@ -62,8 +61,6 @@
 
 	leds {
 		compatible = "gpio-leds";
-		pinctrl-names = "default";
-		pinctrl-0 = <&led_pin_olinuxino>;
 
 		green {
 			label = "a33-olinuxino:green:usr";
@@ -72,17 +69,24 @@
 	};
 };
 
+&codec {
+	status = "okay";
+};
+
+&dai {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
 
 &mmc0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino>;
+	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
-	cd-inverted;
+	cd-gpios = <&pio 1 4 GPIO_ACTIVE_LOW>; /* PB4 */
 	status = "okay";
 };
 
@@ -90,23 +94,6 @@
 	status = "okay";
 };
 
-&pio {
-	led_pin_olinuxino: led_pins@0 {
-		pins = "PB7";
-		function = "gpio_out";
-	};
-
-	mmc0_cd_pin_olinuxino: mmc0_cd_pin@0 {
-		pins = "PB4";
-		function = "gpio_in";
-	};
-
-	usb0_id_detect_pin: usb0_id_detect_pin@0 {
-		pins = "PB3";
-		function = "gpio_in";
-	};
-};
-
 &r_rsb {
 	status = "okay";
 
@@ -122,6 +109,14 @@
 
 #include "axp223.dtsi"
 
+&ac_power_supply {
+	status = "okay";
+};
+
+&battery_power_supply {
+	status = "okay";
+};
+
 &reg_aldo1 {
 	regulator-always-on;
 	regulator-min-microvolt = <3300000>;
@@ -195,6 +190,21 @@
 	vcc-lcd-supply = <&reg_dc1sw>;
 };
 
+&sound {
+	/* Board level jack widgets */
+	simple-audio-card,widgets = "Microphone", "Microphone Jack",
+				    "Headphone", "Headphone Jack";
+	/* Board level routing. First 2 routes copied from SoC level */
+	simple-audio-card,routing =
+		"Left DAC", "AIF1 Slot 0 Left",
+		"Right DAC", "AIF1 Slot 0 Right",
+		"HP", "HPCOM",
+		"Headphone Jack", "HP",
+		"MIC1", "Microphone Jack",
+		"Microphone Jack", "MBIAS";
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_b>;
@@ -211,8 +221,6 @@
 };
 
 &usbphy {
-	pinctrl-names = "default";
-	pinctrl-0 = <&usb0_id_detect_pin>;
 	usb0_id_det-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
 	usb0_vbus_power-supply = <&usb_power_supply>;
 	usb0_vbus-supply = <&reg_drivevbus>;
diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index 433cf2a..541acb4 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -144,8 +144,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_sina33>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
-	cd-inverted;
+	cd-gpios = <&pio 1 4 GPIO_ACTIVE_LOW>; /* PB4 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi
index 50eb84f..a21f2ed 100644
--- a/arch/arm/boot/dts/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a33.dtsi
@@ -289,7 +289,6 @@
 			clock-names = "ahb", "mod",
 				      "ram";
 			resets = <&ccu RST_BUS_DE_FE>;
-			status = "disabled";
 
 			ports {
 				#address-cells = <1>;
diff --git a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts
index 5091cec..36eceba 100644
--- a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts
@@ -87,9 +87,8 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	bus-width = <4>;
-	cd-inverted;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
index 6550bf0..3b579d7 100644
--- a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
@@ -60,6 +60,31 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		blue {
+			label = "bananapi-m3:blue:usr";
+			gpios = <&axp_gpio 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		green {
+			label = "bananapi-m3:green:usr";
+			gpios = <&axp_gpio 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
 	reg_usb1_vbus: reg-usb1-vbus {
 		compatible = "regulator-fixed";
 		regulator-name = "usb1-vbus";
@@ -82,6 +107,10 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	/* Terminus Tech FE 1.1s 4-port USB 2.0 hub here */
 	status = "okay";
@@ -100,6 +129,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &mdio {
 	rgmii_phy: ethernet-phy@1 {
 		compatible = "ethernet-phy-ieee802.3-c22";
@@ -112,8 +151,7 @@
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
index 6da08cd..88decb07 100644
--- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
@@ -176,8 +176,7 @@
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
index 511fca4..1537ce1 100644
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
@@ -128,6 +128,14 @@
 	};
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu100 {
+	cpu-supply = <&reg_dcdc3>;
+};
+
 &de {
 	status = "okay";
 };
@@ -231,6 +239,10 @@
 
 #include "axp81x.dtsi"
 
+&battery_power_supply {
+	status = "okay";
+};
+
 &reg_aldo1 {
 	regulator-min-microvolt = <1800000>;
 	regulator-max-microvolt = <1800000>;
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 7f4955a..5683076 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -60,51 +60,63 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		cpu@0 {
+		cpu0: cpu@0 {
+			clocks = <&ccu CLK_C0CPUX>;
+			clock-names = "cpu";
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			operating-points-v2 = <&cpu0_opp_table>;
 			reg = <0>;
 		};
 
 		cpu@1 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			operating-points-v2 = <&cpu0_opp_table>;
 			reg = <1>;
 		};
 
 		cpu@2 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			operating-points-v2 = <&cpu0_opp_table>;
 			reg = <2>;
 		};
 
 		cpu@3 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			operating-points-v2 = <&cpu0_opp_table>;
 			reg = <3>;
 		};
 
-		cpu@100 {
+		cpu100: cpu@100 {
+			clocks = <&ccu CLK_C1CPUX>;
+			clock-names = "cpu";
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			operating-points-v2 = <&cpu1_opp_table>;
 			reg = <0x100>;
 		};
 
 		cpu@101 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			operating-points-v2 = <&cpu1_opp_table>;
 			reg = <0x101>;
 		};
 
 		cpu@102 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			operating-points-v2 = <&cpu1_opp_table>;
 			reg = <0x102>;
 		};
 
 		cpu@103 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			operating-points-v2 = <&cpu1_opp_table>;
 			reg = <0x103>;
 		};
 	};
@@ -155,7 +167,7 @@
 
 	de: display-engine {
 		compatible = "allwinner,sun8i-a83t-display-engine";
-		allwinner,pipelines = <&mixer0>;
+		allwinner,pipelines = <&mixer0>, <&mixer1>;
 		status = "disabled";
 	};
 
@@ -164,6 +176,112 @@
 		device_type = "memory";
 	};
 
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-720000000 {
+			opp-hz = /bits/ 64 <720000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-864000000 {
+			opp-hz = /bits/ 64 <864000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-912000000 {
+			opp-hz = /bits/ 64 <912000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-1008000000 {
+			opp-hz = /bits/ 64 <1008000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-1128000000 {
+			opp-hz = /bits/ 64 <1128000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+	};
+
+	cpu1_opp_table: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-720000000 {
+			opp-hz = /bits/ 64 <720000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-864000000 {
+			opp-hz = /bits/ 64 <864000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-912000000 {
+			opp-hz = /bits/ 64 <912000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-1008000000 {
+			opp-hz = /bits/ 64 <1008000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-1128000000 {
+			opp-hz = /bits/ 64 <1128000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <840000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -208,6 +326,29 @@
 			};
 		};
 
+		mixer1: mixer@1200000 {
+			compatible = "allwinner,sun8i-a83t-de2-mixer-1";
+			reg = <0x01200000 0x100000>;
+			clocks = <&display_clocks CLK_BUS_MIXER1>,
+				 <&display_clocks CLK_MIXER1>;
+			clock-names = "bus",
+				      "mod";
+			resets = <&display_clocks RST_WB>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				mixer1_out: port@1 {
+					reg = <1>;
+
+					mixer1_out_tcon1: endpoint {
+						remote-endpoint = <&tcon1_in_mixer1>;
+					};
+				};
+			};
+		};
+
 		syscon: syscon@1c00000 {
 			compatible = "allwinner,sun8i-a83t-system-controller",
 				"syscon";
@@ -256,6 +397,40 @@
 			};
 		};
 
+		tcon1: lcd-controller@1c0d000 {
+			compatible = "allwinner,sun8i-a83t-tcon-tv";
+			reg = <0x01c0d000 0x1000>;
+			interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON1>, <&ccu CLK_TCON1>;
+			clock-names = "ahb", "tcon-ch1";
+			resets = <&ccu RST_BUS_TCON1>;
+			reset-names = "lcd";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon1_in: port@0 {
+					reg = <0>;
+
+					tcon1_in_mixer1: endpoint {
+						remote-endpoint = <&mixer1_out_tcon1>;
+					};
+				};
+
+				tcon1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon1_out_hdmi: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&hdmi_in_tcon1>;
+					};
+				};
+			};
+		};
+
 		mmc0: mmc@1c0f000 {
 			compatible = "allwinner,sun8i-a83t-mmc",
 				     "allwinner,sun7i-a20-mmc";
@@ -427,6 +602,11 @@
 				drive-strength = <40>;
 			};
 
+			hdmi_pins: hdmi-pins {
+				pins = "PH6", "PH7", "PH8";
+				function = "hdmi";
+			};
+
 			i2c0_pins: i2c0-pins {
 				pins = "PH0", "PH1";
 				function = "i2c0";
@@ -685,6 +865,50 @@
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
+		hdmi: hdmi@1ee0000 {
+			compatible = "allwinner,sun8i-a83t-dw-hdmi";
+			reg = <0x01ee0000 0x10000>;
+			reg-io-width = <1>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>,
+				 <&ccu CLK_HDMI>;
+			clock-names = "iahb", "isfr", "tmds";
+			resets = <&ccu RST_BUS_HDMI1>;
+			reset-names = "ctrl";
+			phys = <&hdmi_phy>;
+			phy-names = "hdmi-phy";
+			pinctrl-names = "default";
+			pinctrl-0 = <&hdmi_pins>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				hdmi_in: port@0 {
+					reg = <0>;
+
+					hdmi_in_tcon1: endpoint {
+						remote-endpoint = <&tcon1_out_hdmi>;
+					};
+				};
+
+				hdmi_out: port@1 {
+					reg = <1>;
+				};
+			};
+		};
+
+		hdmi_phy: hdmi-phy@1ef0000 {
+			compatible = "allwinner,sun8i-a83t-hdmi-phy";
+			reg = <0x01ef0000 0x10000>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>;
+			clock-names = "bus", "mod";
+			resets = <&ccu RST_BUS_HDMI0>;
+			reset-names = "phy";
+			#phy-cells = <0>;
+		};
+
 		r_intc: interrupt-controller@1f00c00 {
 			compatible = "allwinner,sun8i-a83t-r-intc",
 				     "allwinner,sun6i-a31-r-intc";
diff --git a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts
new file mode 100644
index 0000000..7d01f93
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
+ *
+ * Based on sun8i-h3-bananapi-m2-plus.dts, which is:
+ *   Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Banana Pi BPI-M2-Zero";
+	compatible = "sinovoip,bpi-m2-zero", "allwinner,sun8i-h2-plus";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+
+		pwr_led {
+			label = "bananapi-m2-zero:red:pwr";
+			gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
+			default-state = "on";
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+
+		sw4 {
+			label = "power";
+			linux,code = <BTN_0>;
+			gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+	};
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	/*
+	 * On the production batch of this board the card detect GPIO is
+	 * high active (card inserted), although on the early samples it's
+	 * low active.
+	 */
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+	status = "okay";
+};
+
+&mmc1 {
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	brcmf: wifi@1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+		interrupt-parent = <&pio>;
+		interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 / EINT10 */
+		interrupt-names = "host-wake";
+	};
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
+	/*
+	 * There're two micro-USB connectors, one is power-only and another is
+	 * OTG. The Vbus of these two connectors are connected together, so
+	 * the external USB device will be powered just by the power input
+	 * from the power-only USB port.
+	 */
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-r1.dts b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-r1.dts
index 112f09c..3356f42 100644
--- a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-r1.dts
+++ b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-r1.dts
@@ -68,6 +68,14 @@
 	};
 };
 
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "mxicy,mx25l12805d", "jedec,spi-nor";
+	};
+};
+
 &ohci1 {
 	/*
 	 * RTL8152B USB-Ethernet adapter is connected to USB1,
diff --git a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
index 6713d0f..0bc031fe 100644
--- a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
+++ b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
@@ -112,18 +112,13 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc_wifi>;
 	mmc-pwrseq = <&wifi_pwrseq>;
 	bus-width = <4>;
@@ -139,10 +134,6 @@
 	};
 };
 
-&mmc1_pins_a {
-	bias-pull-up;
-};
-
 &ohci0 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts
index f1c3f1c..30540dc 100644
--- a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts
+++ b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts
@@ -61,6 +61,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -100,6 +111,10 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -129,6 +144,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -136,18 +161,13 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	vqmmc-supply = <&reg_vcc3v3>;
 	mmc-pwrseq = <&wifi_pwrseq>;
diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
index 10da56e..cf1f970 100644
--- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
+++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
@@ -61,6 +61,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -100,6 +111,10 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -108,6 +123,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -115,18 +140,13 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
 	non-removable;
diff --git a/arch/arm/boot/dts/sun8i-h3-libretech-all-h3-cc.dts b/arch/arm/boot/dts/sun8i-h3-libretech-all-h3-cc.dts
index d406571..b20a710 100644
--- a/arch/arm/boot/dts/sun8i-h3-libretech-all-h3-cc.dts
+++ b/arch/arm/boot/dts/sun8i-h3-libretech-all-h3-cc.dts
@@ -23,6 +23,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -120,6 +131,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -143,6 +158,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -150,12 +175,9 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc_io>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts
index a6e6191..65cba10 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts
@@ -101,8 +101,6 @@
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	vqmmc-supply = <&reg_vcc3v3>;
 	mmc-pwrseq = <&wifi_pwrseq>;
@@ -119,6 +117,16 @@
 	};
 };
 
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_8bit_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
 &ohci1 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts
index c77fbca..9412668 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts
@@ -49,6 +49,21 @@
 	aliases {
 		ethernet0 = &emac;
 	};
+
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+};
+
+&de {
+	status = "okay";
 };
 
 &ehci1 {
@@ -66,6 +81,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
index 03ff6f8..6246d3e 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
@@ -72,18 +72,37 @@
 			gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>; /* PA10 */
 		};
 	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+	};
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
+&mmc1 {
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	brcmf: bcrmf@1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+		interrupt-parent = <&pio>;
+		interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 / EINT10 */
+		interrupt-names = "host-wake";
+	};
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi
index 7646e33..f110ee3 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi
@@ -95,10 +95,7 @@
 
 &mmc0 {
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
-	cd-inverted;
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
 	status = "okay";
 	vmmc-supply = <&reg_vcc3v3>;
 };
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
index b20be95b..f1fc6bd 100644
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts
@@ -62,6 +62,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -114,6 +125,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci1 {
 	status = "okay";
 };
@@ -125,6 +140,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -132,18 +157,13 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	mmc-pwrseq = <&wifi_pwrseq>;
 	bus-width = <4>;
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-lite.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-lite.dts
index a70a1da..476ae8e 100644
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-lite.dts
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-lite.dts
@@ -61,6 +61,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -91,6 +102,10 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci1 {
 	status = "okay";
 };
@@ -99,6 +114,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -106,18 +131,13 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
 	non-removable;
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts
index 82e5d28..3328fe5 100644
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts
@@ -60,6 +60,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -90,6 +101,10 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -102,16 +117,22 @@
 	phy-handle = <&int_mii_phy>;
 	phy-mode = "mii";
 	allwinner,leds-active-low;
+};
+
+&hdmi {
 	status = "okay";
 };
 
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts
index a10281b..71fb732 100644
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts
@@ -59,8 +59,6 @@
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
 	non-removable;
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
index d22546d..cea4d64 100644
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
@@ -60,6 +60,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -98,6 +109,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -121,6 +136,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -128,12 +153,9 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 8495dee..10da8ed 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -79,6 +79,33 @@
 			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
+
+	soc {
+		mali: gpu@1c40000 {
+			compatible = "allwinner,sun8i-h3-mali", "arm,mali-400";
+			reg = <0x01c40000 0x10000>;
+			interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "gp",
+					  "gpmmu",
+					  "pp0",
+					  "ppmmu0",
+					  "pp1",
+					  "ppmmu1",
+					  "pmu";
+			clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>;
+			clock-names = "bus", "core";
+			resets = <&ccu RST_BUS_GPU>;
+
+			assigned-clocks = <&ccu CLK_GPU>;
+			assigned-clock-rates = <384000000>;
+		};
+	};
 };
 
 &ccu {
diff --git a/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
index eaf0966..0dbdb29 100644
--- a/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
+++ b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
@@ -150,8 +150,7 @@
 	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
-	cd-inverted;
+	cd-gpios = <&pio 1 4 GPIO_ACTIVE_LOW>; /* PB4 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
index 8c5efe2..27d9ccd 100644
--- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
+++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
@@ -164,8 +164,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>; /* PH13 */
-	cd-inverted;
+	cd-gpios = <&pio 7 13 GPIO_ACTIVE_LOW>; /* PH13 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
index d6bd158..880096c7 100644
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -85,8 +85,7 @@
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
-	cd-inverted;
+	cd-gpios = <&pio 1 4 GPIO_ACTIVE_LOW>; /* PB4 */
 	status = "okay";
 };
 
@@ -125,6 +124,14 @@
 
 #include "axp223.dtsi"
 
+&ac_power_supply {
+	status = "okay";
+};
+
+&battery_power_supply {
+	status = "okay";
+};
+
 &reg_aldo1 {
 	regulator-always-on;
 	regulator-min-microvolt = <3000000>;
diff --git a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts
index fe16fc0..a26d72c 100644
--- a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts
+++ b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts
@@ -150,8 +150,7 @@
 &mmc0 {
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>; /* PH13 */
-	cd-inverted;
+	cd-gpios = <&pio 7 13 GPIO_ACTIVE_LOW>; /* PH13 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
index 4024639..85da85f 100644
--- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
+++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
@@ -74,6 +74,52 @@
 		};
 	};
 
+	vga-connector {
+		compatible = "vga-connector";
+		label = "vga";
+		ddc-i2c-bus = <&i2c3>;
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_dac_out>;
+			};
+		};
+	};
+
+	vga-dac {
+		compatible = "corpro,gm7123", "adi,adv7123", "dumb-vga-dac";
+		vdd-supply = <&reg_dcdc1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+
+				vga_dac_in: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&tcon0_out_vga>;
+				};
+			};
+
+			port@1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+
+				vga_dac_out: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
 	wifi_pwrseq: wifi-pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		clocks = <&ac100_rtc 1>;
@@ -83,13 +129,22 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_pins>;
+	status = "okay";
+};
+
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 18 GPIO_ACTIVE_HIGH>; /* PH18 */
-	cd-inverted;
+	cd-gpios = <&pio 7 18 GPIO_ACTIVE_LOW>; /* PH18 */
 	status = "okay";
 };
 
@@ -403,6 +458,18 @@
 
 #include "axp809.dtsi"
 
+&tcon0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd0_rgb888_pins>;
+};
+
+&tcon0_out {
+	tcon0_out_vga: endpoint@0 {
+		reg = <0>;
+		remote-endpoint = <&vga_dac_in>;
+	};
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_ph_pins>;
diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index a9b807b..58a199b 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -125,8 +125,7 @@
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
-	cd-gpios = <&pio 7 18 GPIO_ACTIVE_HIGH>; /* PH8 */
-	cd-inverted;
+	cd-gpios = <&pio 7 18 GPIO_ACTIVE_LOW>; /* PH8 */
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 90eac0b..25591d6 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -63,48 +63,72 @@
 		cpu0: cpu@0 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			cci-control-port = <&cci_control0>;
+			clock-frequency = <12000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x0>;
 		};
 
 		cpu1: cpu@1 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			cci-control-port = <&cci_control0>;
+			clock-frequency = <12000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x1>;
 		};
 
 		cpu2: cpu@2 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			cci-control-port = <&cci_control0>;
+			clock-frequency = <12000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x2>;
 		};
 
 		cpu3: cpu@3 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
+			cci-control-port = <&cci_control0>;
+			clock-frequency = <12000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x3>;
 		};
 
 		cpu4: cpu@100 {
 			compatible = "arm,cortex-a15";
 			device_type = "cpu";
+			cci-control-port = <&cci_control1>;
+			clock-frequency = <18000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x100>;
 		};
 
 		cpu5: cpu@101 {
 			compatible = "arm,cortex-a15";
 			device_type = "cpu";
+			cci-control-port = <&cci_control1>;
+			clock-frequency = <18000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x101>;
 		};
 
 		cpu6: cpu@102 {
 			compatible = "arm,cortex-a15";
 			device_type = "cpu";
+			cci-control-port = <&cci_control1>;
+			clock-frequency = <18000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x102>;
 		};
 
 		cpu7: cpu@103 {
 			compatible = "arm,cortex-a15";
 			device_type = "cpu";
+			cci-control-port = <&cci_control1>;
+			clock-frequency = <18000000>;
+			enable-method = "allwinner,sun9i-a80-smp";
 			reg = <0x103>;
 		};
 	};
@@ -224,6 +248,12 @@
 		};
 	};
 
+	de: display-engine {
+		compatible = "allwinner,sun9i-a80-display-engine";
+		allwinner,pipelines = <&fe0>, <&fe1>;
+		status = "disabled";
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -234,6 +264,25 @@
 		 */
 		ranges = <0 0 0 0x20000000>;
 
+		sram_b: sram@20000 {
+			/* 256 KiB secure SRAM at 0x20000 */
+			compatible = "mmio-sram";
+			reg = <0x00020000 0x40000>;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x00020000 0x40000>;
+
+			smp-sram@1000 {
+				/*
+				 * This is checked by BROM to determine if
+				 * cpu0 should jump to SMP entry vector
+				 */
+				compatible = "allwinner,sun9i-a80-smp-sram";
+				reg = <0x1000 0x8>;
+			};
+		};
+
 		ehci0: usb@a00000 {
 			compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
 			reg = <0x00a00000 0x100>;
@@ -347,6 +396,11 @@
 			#reset-cells = <1>;
 		};
 
+		cpucfg@1700000 {
+			compatible = "allwinner,sun9i-a80-cpucfg";
+			reg = <0x01700000 0x100>;
+		};
+
 		mmc0: mmc@1c0f000 {
 			compatible = "allwinner,sun9i-a80-mmc";
 			reg = <0x01c0f000 0x1000>;
@@ -431,6 +485,36 @@
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
+		cci: cci@1c90000 {
+			compatible = "arm,cci-400";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x01c90000 0x1000>;
+			ranges = <0x0 0x01c90000 0x10000>;
+
+			cci_control0: slave-if@4000 {
+				compatible = "arm,cci-400-ctrl-if";
+				interface-type = "ace";
+				reg = <0x4000 0x1000>;
+			};
+
+			cci_control1: slave-if@5000 {
+				compatible = "arm,cci-400-ctrl-if";
+				interface-type = "ace";
+				reg = <0x5000 0x1000>;
+			};
+
+			pmu@9000 {
+				 compatible = "arm,cci-400-pmu,r1";
+				 reg = <0x9000 0x5000>;
+				 interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					      <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					      <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					      <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					      <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
 		de_clocks: clock@3000000 {
 			compatible = "allwinner,sun9i-a80-de-clks";
 			reg = <0x03000000 0x30>;
@@ -445,6 +529,381 @@
 			#reset-cells = <1>;
 		};
 
+		fe0: display-frontend@3100000 {
+			compatible = "allwinner,sun9i-a80-display-frontend";
+			reg = <0x03100000 0x40000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_FE0>, <&de_clocks CLK_FE0>,
+				 <&de_clocks CLK_DRAM_FE0>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_clocks RST_FE0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				fe0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					fe0_out_deu0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&deu0_in_fe0>;
+					};
+				};
+			};
+		};
+
+		fe1: display-frontend@3140000 {
+			compatible = "allwinner,sun9i-a80-display-frontend";
+			reg = <0x03140000 0x40000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_FE1>, <&de_clocks CLK_FE1>,
+				 <&de_clocks CLK_DRAM_FE1>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_clocks RST_FE0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				fe1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					fe1_out_deu1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&deu1_in_fe1>;
+					};
+				};
+			};
+		};
+
+		be0: display-backend@3200000 {
+			compatible = "allwinner,sun9i-a80-display-backend";
+			reg = <0x03200000 0x40000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_BE0>, <&de_clocks CLK_BE0>,
+				 <&de_clocks CLK_DRAM_BE0>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_clocks RST_BE0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				be0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					be0_in_deu0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&deu0_out_be0>;
+					};
+
+					be0_in_deu1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&deu1_out_be0>;
+					};
+				};
+
+				be0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					be0_out_drc0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&drc0_in_be0>;
+					};
+				};
+			};
+		};
+
+		be1: display-backend@3240000 {
+			compatible = "allwinner,sun9i-a80-display-backend";
+			reg = <0x03240000 0x40000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_BE1>, <&de_clocks CLK_BE1>,
+				 <&de_clocks CLK_DRAM_BE1>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_clocks RST_BE1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				be1_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					be1_in_deu0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&deu0_out_be1>;
+					};
+
+					be1_in_deu1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&deu1_out_be1>;
+					};
+				};
+
+				be1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					be1_out_drc1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&drc1_in_be1>;
+					};
+				};
+			};
+		};
+
+		deu0: deu@3300000 {
+			compatible = "allwinner,sun9i-a80-deu";
+			reg = <0x03300000 0x40000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_DEU0>,
+				 <&de_clocks CLK_IEP_DEU0>,
+				 <&de_clocks CLK_DRAM_DEU0>;
+			clock-names = "ahb",
+				      "mod",
+				      "ram";
+			resets = <&de_clocks RST_DEU0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				deu0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					deu0_in_fe0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&fe0_out_deu0>;
+					};
+				};
+
+				deu0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					deu0_out_be0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be0_in_deu0>;
+					};
+
+					deu0_out_be1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&be1_in_deu0>;
+					};
+				};
+			};
+		};
+
+		deu1: deu@3340000 {
+			compatible = "allwinner,sun9i-a80-deu";
+			reg = <0x03340000 0x40000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_DEU1>,
+				 <&de_clocks CLK_IEP_DEU1>,
+				 <&de_clocks CLK_DRAM_DEU1>;
+			clock-names = "ahb",
+				      "mod",
+				      "ram";
+			resets = <&de_clocks RST_DEU1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				deu1_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					deu1_in_fe1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&fe1_out_deu1>;
+					};
+				};
+
+				deu1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					deu1_out_be0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be0_in_deu1>;
+					};
+
+					deu1_out_be1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&be1_in_deu1>;
+					};
+				};
+			};
+		};
+
+		drc0: drc@3400000 {
+			compatible = "allwinner,sun9i-a80-drc";
+			reg = <0x03400000 0x40000>;
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_DRC0>,
+				 <&de_clocks CLK_IEP_DRC0>,
+				 <&de_clocks CLK_DRAM_DRC0>;
+			clock-names = "ahb",
+				      "mod",
+				      "ram";
+			resets = <&de_clocks RST_DRC0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				drc0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					drc0_in_be0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be0_out_drc0>;
+					};
+				};
+
+				drc0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					drc0_out_tcon0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon0_in_drc0>;
+					};
+				};
+			};
+		};
+
+		drc1: drc@3440000 {
+			compatible = "allwinner,sun9i-a80-drc";
+			reg = <0x03440000 0x40000>;
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&de_clocks CLK_BUS_DRC1>,
+				 <&de_clocks CLK_IEP_DRC1>,
+				 <&de_clocks CLK_DRAM_DRC1>;
+			clock-names = "ahb",
+				      "mod",
+				      "ram";
+			resets = <&de_clocks RST_DRC1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				drc1_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					drc1_in_be1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be1_out_drc1>;
+					};
+				};
+
+				drc1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					drc1_out_tcon1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon1_in_drc1>;
+					};
+				};
+			};
+		};
+
+		tcon0: lcd-controller@3c00000 {
+			compatible = "allwinner,sun9i-a80-tcon-lcd";
+			reg = <0x03c00000 0x10000>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_LCD0>, <&ccu CLK_LCD0>;
+			clock-names = "ahb", "tcon-ch0";
+			resets = <&ccu RST_BUS_LCD0>, <&ccu RST_BUS_EDP>;
+			reset-names = "lcd", "edp";
+			clock-output-names = "tcon0-pixel-clock";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon0_in_drc0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&drc0_out_tcon0>;
+					};
+				};
+
+				tcon0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+			};
+		};
+
+		tcon1: lcd-controller@3c10000 {
+			compatible = "allwinner,sun9i-a80-tcon-tv";
+			reg = <0x03c10000 0x10000>;
+			interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_LCD1>, <&ccu CLK_LCD1>;
+			clock-names = "ahb", "tcon-ch1";
+			resets = <&ccu RST_BUS_LCD1>, <&ccu RST_BUS_EDP>;
+			reset-names = "lcd", "edp";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon1_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon1_in_drc1: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&drc1_out_tcon1>;
+					};
+				};
+
+				tcon1_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+			};
+		};
+
 		ccu: clock@6000000 {
 			compatible = "allwinner,sun9i-a80-ccu";
 			reg = <0x06000000 0x800>;
@@ -494,6 +953,17 @@
 				function = "i2c3";
 			};
 
+			lcd0_rgb888_pins: lcd0-rgb888-pins {
+				pins = "PD0", "PD1", "PD2", "PD3",
+				       "PD4", "PD5", "PD6", "PD7",
+				       "PD8", "PD9", "PD10", "PD11",
+				       "PD12", "PD13", "PD14", "PD15",
+				       "PD16", "PD17", "PD18", "PD19",
+				       "PD20", "PD21", "PD22", "PD23",
+				       "PD24", "PD25", "PD26", "PD27";
+				function = "lcd0";
+			};
+
 			mmc0_pins: mmc0-pins {
 				pins = "PF0", "PF1" ,"PF2", "PF3",
 				       "PF4", "PF5";
@@ -658,6 +1128,11 @@
 			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		prcm@8001400 {
+			compatible = "allwinner,sun9i-a80-prcm";
+			reg = <0x08001400 0x200>;
+		};
+
 		apbs_rst: reset@80014b0 {
 			reg = <0x080014b0 0x4>;
 			compatible = "allwinner,sun6i-a31-clock-reset";
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 7a83b15..1be1a02d6 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -105,6 +105,12 @@
 		};
 	};
 
+	de: display-engine {
+		compatible = "allwinner,sun8i-h3-display-engine";
+		allwinner,pipelines = <&mixer0>;
+		status = "disabled";
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -123,6 +129,29 @@
 			#reset-cells = <1>;
 		};
 
+		mixer0: mixer@1100000 {
+			compatible = "allwinner,sun8i-h3-de2-mixer-0";
+			reg = <0x01100000 0x100000>;
+			clocks = <&display_clocks CLK_BUS_MIXER0>,
+				 <&display_clocks CLK_MIXER0>;
+			clock-names = "bus",
+				      "mod";
+			resets = <&display_clocks RST_MIXER0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				mixer0_out: port@1 {
+					reg = <1>;
+
+					mixer0_out_tcon0: endpoint {
+						remote-endpoint = <&tcon0_in_mixer0>;
+					};
+				};
+			};
+		};
+
 		syscon: syscon@1c00000 {
 			compatible = "allwinner,sun8i-h3-system-controller",
 				"syscon";
@@ -138,9 +167,46 @@
 			#dma-cells = <1>;
 		};
 
+		tcon0: lcd-controller@1c0c000 {
+			compatible = "allwinner,sun8i-h3-tcon-tv",
+				     "allwinner,sun8i-a83t-tcon-tv";
+			reg = <0x01c0c000 0x1000>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>;
+			clock-names = "ahb", "tcon-ch1";
+			resets = <&ccu RST_BUS_TCON0>;
+			reset-names = "lcd";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon0_in: port@0 {
+					reg = <0>;
+
+					tcon0_in_mixer0: endpoint {
+						remote-endpoint = <&mixer0_out_tcon0>;
+					};
+				};
+
+				tcon0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon0_out_hdmi: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&hdmi_in_tcon0>;
+					};
+				};
+			};
+		};
+
 		mmc0: mmc@1c0f000 {
 			/* compatible and clocks are in per SoC .dtsi file */
 			reg = <0x01c0f000 0x1000>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc0_pins>;
 			resets = <&ccu RST_BUS_MMC0>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
@@ -152,6 +218,8 @@
 		mmc1: mmc@1c10000 {
 			/* compatible and clocks are in per SoC .dtsi file */
 			reg = <0x01c10000 0x1000>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc1_pins>;
 			resets = <&ccu RST_BUS_MMC1>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
@@ -348,7 +416,7 @@
 				function = "i2c2";
 			};
 
-			mmc0_pins_a: mmc0 {
+			mmc0_pins: mmc0 {
 				pins = "PF0", "PF1", "PF2", "PF3",
 				       "PF4", "PF5";
 				function = "mmc0";
@@ -356,13 +424,7 @@
 				bias-pull-up;
 			};
 
-			mmc0_cd_pin: mmc0_cd_pin {
-				pins = "PF6";
-				function = "gpio_in";
-				bias-pull-up;
-			};
-
-			mmc1_pins_a: mmc1 {
+			mmc1_pins: mmc1 {
 				pins = "PG0", "PG1", "PG2", "PG3",
 				       "PG4", "PG5";
 				function = "mmc1";
@@ -684,6 +746,50 @@
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
+		hdmi: hdmi@1ee0000 {
+			compatible = "allwinner,sun8i-h3-dw-hdmi",
+				     "allwinner,sun8i-a83t-dw-hdmi";
+			reg = <0x01ee0000 0x10000>;
+			reg-io-width = <1>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_DDC>,
+				 <&ccu CLK_HDMI>;
+			clock-names = "iahb", "isfr", "tmds";
+			resets = <&ccu RST_BUS_HDMI1>;
+			reset-names = "ctrl";
+			phys = <&hdmi_phy>;
+			phy-names = "hdmi-phy";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				hdmi_in: port@0 {
+					reg = <0>;
+
+					hdmi_in_tcon0: endpoint {
+						remote-endpoint = <&tcon0_out_hdmi>;
+					};
+				};
+
+				hdmi_out: port@1 {
+					reg = <1>;
+				};
+			};
+		};
+
+		hdmi_phy: hdmi-phy@1ef0000 {
+			compatible = "allwinner,sun8i-h3-hdmi-phy";
+			reg = <0x01ef0000 0x10000>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_DDC>,
+				 <&ccu 6>;
+			clock-names = "bus", "mod", "pll-0";
+			resets = <&ccu RST_BUS_HDMI0>;
+			reset-names = "phy";
+			#phy-cells = <0>;
+		};
+
 		rtc: rtc@1f00000 {
 			compatible = "allwinner,sun6i-a31-rtc";
 			reg = <0x01f00000 0x54>;
diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts
index acd6cf5..eafff16 100644
--- a/arch/arm/boot/dts/tegra114-dalmore.dts
+++ b/arch/arm/boot/dts/tegra114-dalmore.dts
@@ -780,7 +780,7 @@
 			compatible = "realtek,rt5640";
 			reg = <0x1c>;
 			interrupt-parent = <&gpio>;
-			interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
+			interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_EDGE_FALLING>;
 			realtek,ldo1-en-gpios =
 				<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
 		};
diff --git a/arch/arm/boot/dts/tegra124-apalis-eval.dts b/arch/arm/boot/dts/tegra124-apalis-eval.dts
index ecffcd1..a6ad759 100644
--- a/arch/arm/boot/dts/tegra124-apalis-eval.dts
+++ b/arch/arm/boot/dts/tegra124-apalis-eval.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Toradex AG
+ * Copyright 2016-2018 Toradex AG
  *
  * This file is dual-licensed: you can use it either under the terms
  * of the GPL or the X11 license, at your option. Note that this dual
@@ -105,7 +105,7 @@
 	 */
 	i2c@7000c000 {
 		status = "okay";
-		clock-frequency = <100000>;
+		clock-frequency = <400000>;
 
 		pcie-switch@58 {
 			compatible = "plx,pex8605";
@@ -114,7 +114,7 @@
 
 		/* M41T0M6 real time clock on carrier board */
 		rtc@68 {
-			compatible = "st,m41t00";
+			compatible = "st,m41t0";
 			reg = <0x68>;
 		};
 	};
@@ -124,7 +124,6 @@
 	 */
 	hdmi_ddc: i2c@7000c400 {
 		status = "okay";
-		clock-frequency = <100000>;
 	};
 
 	/*
@@ -133,7 +132,7 @@
 	 */
 	i2c@7000c500 {
 		status = "okay";
-		clock-frequency = <100000>;
+		clock-frequency = <400000>;
 	};
 
 	/* I2C4 (DDC): unused */
@@ -226,9 +225,7 @@
 
 	backlight: backlight {
 		compatible = "pwm-backlight";
-
-		/* BKL1_PWM */
-		pwms = <&pwm 3 5000000>;
+		pwms = <&pwm 3 5000000>; /* BKL1_PWM */
 		brightness-levels = <255 231 223 207 191 159 127 0>;
 		default-brightness-level = <6>;
 		/* BKL1_ON */
@@ -276,3 +273,13 @@
 		vin-supply = <&reg_5v0>;
 	};
 };
+
+&gpio {
+	/* Apalis GPIO7 MXM3 pin 15 PLX PEX 8605 PCIe Switch Reset */
+	pex_perst_n {
+		gpio-hog;
+		gpios = <TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "PEX_PERST_N";
+	};
+};
diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts
new file mode 100644
index 0000000..8a8d5fa
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2016-2018 Toradex AG
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra124-apalis-v1.2.dtsi"
+
+/ {
+	model = "Toradex Apalis TK1 on Apalis Evaluation Board";
+	compatible = "toradex,apalis-tk1-v1.2-eval", "toradex,apalis-tk1-eval",
+		     "toradex,apalis-tk1", "nvidia,tegra124";
+
+	aliases {
+		rtc0 = "/i2c@7000c000/rtc@68";
+		rtc1 = "/i2c@7000d000/pmic@40";
+		rtc2 = "/rtc@7000e000";
+		serial0 = &uarta;
+		serial1 = &uartb;
+		serial2 = &uartc;
+		serial3 = &uartd;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	pcie@1003000 {
+		pci@1,0 {
+			status = "okay";
+		};
+	};
+
+	host1x@50000000 {
+		hdmi@54280000 {
+			status = "okay";
+		};
+	};
+
+	/* Apalis UART1 */
+	serial@70006000 {
+		status = "okay";
+	};
+
+	/* Apalis UART2 */
+	serial@70006040 {
+		status = "okay";
+	};
+
+	/* Apalis UART3 */
+	serial@70006200 {
+		status = "okay";
+	};
+
+	/* Apalis UART4 */
+	serial@70006300 {
+		status = "okay";
+	};
+
+	pwm@7000a000 {
+		status = "okay";
+	};
+
+	/*
+	 * GEN1_I2C: I2C1_SDA/SCL on MXM3 pin 209/211 (e.g. RTC on carrier
+	 * board)
+	 */
+	i2c@7000c000 {
+		status = "okay";
+		clock-frequency = <400000>;
+
+		pcie-switch@58 {
+			compatible = "plx,pex8605";
+			reg = <0x58>;
+		};
+
+		/* M41T0M6 real time clock on carrier board */
+		rtc@68 {
+			compatible = "st,m41t0";
+			reg = <0x68>;
+		};
+	};
+
+	/* GEN2_I2C: unused */
+
+	/*
+	 * CAM_I2C: I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor
+	 * on carrier board)
+	 */
+	i2c@7000c500 {
+		status = "okay";
+		clock-frequency = <400000>;
+	};
+
+	/*
+	 * I2C4 (DDC): I2C4_SDA/SCL (DDC) on MXM3 pin 205/207
+	 * (e.g. display EDID)
+	 */
+	hdmi_ddc: i2c@7000c700 {
+		status = "okay";
+	};
+
+	/* SPI1: Apalis SPI1 */
+	spi@7000d400 {
+		status = "okay";
+		spi-max-frequency = <50000000>;
+
+		spidev0: spidev@0 {
+			compatible = "spidev";
+			reg = <0>;
+			spi-max-frequency = <50000000>;
+		};
+	};
+
+	/* SPI4: Apalis SPI2 */
+	spi@7000da00 {
+		status = "okay";
+		spi-max-frequency = <50000000>;
+
+		spidev1: spidev@0 {
+			compatible = "spidev";
+			reg = <0>;
+			spi-max-frequency = <50000000>;
+		};
+	};
+
+	/* Apalis Serial ATA */
+	sata@70020000 {
+		status = "okay";
+	};
+
+	hda@70030000 {
+		status = "okay";
+	};
+
+	usb@70090000 {
+		status = "okay";
+	};
+
+	/* Apalis MMC1 */
+	sdhci@700b0000 {
+		status = "okay";
+		/* MMC1_CD# */
+		cd-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_LOW>;
+		bus-width = <4>;
+		vqmmc-supply = <&vddio_sdmmc1>;
+	};
+
+	/* Apalis SD1 */
+	sdhci@700b0400 {
+		status = "okay";
+		/* SD1_CD# */
+		cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+		bus-width = <4>;
+		vqmmc-supply = <&vddio_sdmmc3>;
+	};
+
+	/* EHCI instance 0: USB1_DP/N -> USBO1_DP/N */
+	usb@7d000000 {
+		status = "okay";
+		dr_mode = "otg";
+	};
+
+	usb-phy@7d000000 {
+		status = "okay";
+		vbus-supply = <&reg_usbo1_vbus>;
+	};
+
+	/* EHCI instance 1: USB2_DP/N -> USBH2_DP/N */
+	usb@7d004000 {
+		status = "okay";
+	};
+
+	usb-phy@7d004000 {
+		status = "okay";
+		vbus-supply = <&reg_usbh_vbus>;
+	};
+
+	/* EHCI instance 2: USB3_DP/N -> USBH4_DP/N */
+	usb@7d008000 {
+		status = "okay";
+	};
+
+	usb-phy@7d008000 {
+		status = "okay";
+		vbus-supply = <&reg_usbh_vbus>;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 3 5000000>; /* BKL1_PWM */
+		brightness-levels = <255 231 223 207 191 159 127 0>;
+		default-brightness-level = <6>;
+		/* BKL1_ON */
+		enable-gpios = <&gpio TEGRA_GPIO(BB, 5) GPIO_ACTIVE_HIGH>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		wakeup {
+			label = "WAKE1_MICO";
+			gpios = <&gpio TEGRA_GPIO(DD, 3) GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WAKEUP>;
+			debounce-interval = <10>;
+			wakeup-source;
+		};
+	};
+
+	reg_5v0: regulator-5v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "5V_SW";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	/* USBO1_EN */
+	reg_usbo1_vbus: regulator-usbo1-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_USBO1";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		vin-supply = <&reg_5v0>;
+	};
+
+	/* USBH_EN */
+	reg_usbh_vbus: regulator-usbh-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_USBH(2A|2C|2D|3|4)";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio TEGRA_GPIO(T, 6) GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		vin-supply = <&reg_5v0>;
+	};
+};
+
+&gpio {
+	/* Apalis GPIO7 MXM3 pin 15 PLX PEX 8605 PCIe Switch Reset */
+	pex_perst_n {
+		gpio-hog;
+		gpios = <TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "PEX_PERST_N";
+	};
+};
diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
new file mode 100644
index 0000000..bb67edb
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
@@ -0,0 +1,2052 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2016-2018 Toradex AG
+ */
+
+#include "tegra124.dtsi"
+#include "tegra124-apalis-emc.dtsi"
+
+/*
+ * Toradex Apalis TK1 Module Device Tree
+ * Compatible for Revisions 2GB: V1.2A
+ */
+/ {
+	model = "Toradex Apalis TK1";
+	compatible = "toradex,apalis-tk1-v1.2", "toradex,apalis-tk1",
+		     "nvidia,tegra124";
+
+	memory {
+		reg = <0x0 0x80000000 0x0 0x80000000>;
+	};
+
+	pcie@1003000 {
+		status = "okay";
+		avddio-pex-supply = <&vdd_1v05>;
+		avdd-pex-pll-supply = <&vdd_1v05>;
+		avdd-pll-erefe-supply = <&avdd_1v05>;
+		dvddio-pex-supply = <&vdd_1v05>;
+		hvdd-pex-pll-e-supply = <&reg_3v3>;
+		hvdd-pex-supply = <&reg_3v3>;
+		vddio-pex-ctl-supply = <&reg_3v3>;
+
+		/* Apalis PCIe (additional lane Apalis type specific) */
+		pci@1,0 {
+			/* PCIE1_RX/TX and TS_DIFF1/2 */
+			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>,
+			       <&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>;
+			phy-names = "pcie-0", "pcie-1";
+		};
+
+		/* I210 Gigabit Ethernet Controller (On-module) */
+		pci@2,0 {
+			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>;
+			phy-names = "pcie-0";
+			status = "okay";
+		};
+	};
+
+	host1x@50000000 {
+		hdmi@54280000 {
+			pll-supply = <&reg_1v05_avdd_hdmi_pll>;
+			vdd-supply = <&reg_3v3_avdd_hdmi>;
+			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+			nvidia,hpd-gpio =
+				<&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	gpu@0,57000000 {
+		/*
+		 * Node left disabled on purpose - the bootloader will enable
+		 * it after having set the VPR up
+		 */
+		vdd-supply = <&vdd_gpu>;
+	};
+
+	pinmux: pinmux@70000868 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinmux {
+			/* Analogue Audio (On-module) */
+			dap3_fs_pp0 {
+				nvidia,pins = "dap3_fs_pp0";
+				nvidia,function = "i2s2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap3_din_pp1 {
+				nvidia,pins = "dap3_din_pp1";
+				nvidia,function = "i2s2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			dap3_dout_pp2 {
+				nvidia,pins = "dap3_dout_pp2";
+				nvidia,function = "i2s2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap3_sclk_pp3 {
+				nvidia,pins = "dap3_sclk_pp3";
+				nvidia,function = "i2s2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap_mclk1_pw4 {
+				nvidia,pins = "dap_mclk1_pw4";
+				nvidia,function = "extperiph1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis BKL1_ON */
+			pbb5 {
+				nvidia,pins = "pbb5";
+				nvidia,function = "vgp5";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis BKL1_PWM */
+			pu6 {
+				nvidia,pins = "pu6";
+				nvidia,function = "pwm3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis CAM1_MCLK */
+			cam_mclk_pcc0 {
+				nvidia,pins = "cam_mclk_pcc0";
+				nvidia,function = "vi_alt3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis Digital Audio */
+			dap2_fs_pa2 {
+				nvidia,pins = "dap2_fs_pa2";
+				nvidia,function = "hda";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			dap2_sclk_pa3 {
+				nvidia,pins = "dap2_sclk_pa3";
+				nvidia,function = "hda";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			dap2_din_pa4 {
+				nvidia,pins = "dap2_din_pa4";
+				nvidia,function = "hda";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			dap2_dout_pa5 {
+				nvidia,pins = "dap2_dout_pa5";
+				nvidia,function = "hda";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pbb3 { /* DAP1_RESET */
+				nvidia,pins = "pbb3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			clk3_out_pee0 {
+				nvidia,pins = "clk3_out_pee0";
+				nvidia,function = "extperiph3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis GPIO */
+			usb_vbus_en0_pn4 {
+				nvidia,pins = "usb_vbus_en0_pn4";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+			};
+			usb_vbus_en1_pn5 {
+				nvidia,pins = "usb_vbus_en1_pn5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+			};
+			pex_l0_rst_n_pdd1 {
+				nvidia,pins = "pex_l0_rst_n_pdd1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			pex_l0_clkreq_n_pdd2 {
+				nvidia,pins = "pex_l0_clkreq_n_pdd2";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			pex_l1_rst_n_pdd5 {
+				nvidia,pins = "pex_l1_rst_n_pdd5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			pex_l1_clkreq_n_pdd6 {
+				nvidia,pins = "pex_l1_clkreq_n_pdd6";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			dp_hpd_pff0 {
+				nvidia,pins = "dp_hpd_pff0";
+				nvidia,function = "dp";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			pff2 {
+				nvidia,pins = "pff2";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			owr { /* PEX_L1_CLKREQ_N multiplexed GPIO6 */
+				nvidia,pins = "owr";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+				nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis HDMI1_CEC */
+			hdmi_cec_pee3 {
+				nvidia,pins = "hdmi_cec_pee3";
+				nvidia,function = "cec";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis HDMI1_HPD */
+			hdmi_int_pn7 {
+				nvidia,pins = "hdmi_int_pn7";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis I2C1 */
+			gen1_i2c_scl_pc4 {
+				nvidia,pins = "gen1_i2c_scl_pc4";
+				nvidia,function = "i2c1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+			};
+			gen1_i2c_sda_pc5 {
+				nvidia,pins = "gen1_i2c_sda_pc5";
+				nvidia,function = "i2c1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis I2C3 (CAM) */
+			cam_i2c_scl_pbb1 {
+				nvidia,pins = "cam_i2c_scl_pbb1";
+				nvidia,function = "i2c3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+			};
+			cam_i2c_sda_pbb2 {
+				nvidia,pins = "cam_i2c_sda_pbb2";
+				nvidia,function = "i2c3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis I2C4 (DDC) */
+			ddc_scl_pv4 {
+				nvidia,pins = "ddc_scl_pv4";
+				nvidia,function = "i2c4";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
+			};
+			ddc_sda_pv5 {
+				nvidia,pins = "ddc_sda_pv5";
+				nvidia,function = "i2c4";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis MMC1 */
+			sdmmc1_cd_n_pv3 { /* CD# GPIO */
+				nvidia,pins = "sdmmc1_wp_n_pv3";
+				nvidia,function = "sdmmc1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			clk2_out_pw5 { /* D5 GPIO */
+				nvidia,pins = "clk2_out_pw5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc1_dat3_py4 {
+				nvidia,pins = "sdmmc1_dat3_py4";
+				nvidia,function = "sdmmc1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc1_dat2_py5 {
+				nvidia,pins = "sdmmc1_dat2_py5";
+				nvidia,function = "sdmmc1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc1_dat1_py6 {
+				nvidia,pins = "sdmmc1_dat1_py6";
+				nvidia,function = "sdmmc1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc1_dat0_py7 {
+				nvidia,pins = "sdmmc1_dat0_py7";
+				nvidia,function = "sdmmc1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc1_clk_pz0 {
+				nvidia,pins = "sdmmc1_clk_pz0";
+				nvidia,function = "sdmmc1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc1_cmd_pz1 {
+				nvidia,pins = "sdmmc1_cmd_pz1";
+				nvidia,function = "sdmmc1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			clk2_req_pcc5 { /* D4 GPIO */
+				nvidia,pins = "clk2_req_pcc5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc3_clk_lb_in_pee5 { /* D6 GPIO */
+				nvidia,pins = "sdmmc3_clk_lb_in_pee5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			usb_vbus_en2_pff1 { /* D7 GPIO */
+				nvidia,pins = "usb_vbus_en2_pff1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis PWM */
+			ph0 {
+				nvidia,pins = "ph0";
+				nvidia,function = "pwm0";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ph1 {
+				nvidia,pins = "ph1";
+				nvidia,function = "pwm1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ph2 {
+				nvidia,pins = "ph2";
+				nvidia,function = "pwm2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			/* PWM3 active on pu6 being Apalis BKL1_PWM as well */
+			ph3 {
+				nvidia,pins = "ph3";
+				nvidia,function = "pwm3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis SATA1_ACT# */
+			dap1_dout_pn2 {
+				nvidia,pins = "dap1_dout_pn2";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis SD1 */
+			sdmmc3_clk_pa6 {
+				nvidia,pins = "sdmmc3_clk_pa6";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc3_cmd_pa7 {
+				nvidia,pins = "sdmmc3_cmd_pa7";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc3_dat3_pb4 {
+				nvidia,pins = "sdmmc3_dat3_pb4";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc3_dat2_pb5 {
+				nvidia,pins = "sdmmc3_dat2_pb5";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc3_dat1_pb6 {
+				nvidia,pins = "sdmmc3_dat1_pb6";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc3_dat0_pb7 {
+				nvidia,pins = "sdmmc3_dat0_pb7";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc3_cd_n_pv2 { /* CD# GPIO */
+				nvidia,pins = "sdmmc3_cd_n_pv2";
+				nvidia,function = "rsvd3";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis SPDIF */
+			spdif_out_pk5 {
+				nvidia,pins = "spdif_out_pk5";
+				nvidia,function = "spdif";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			spdif_in_pk6 {
+				nvidia,pins = "spdif_in_pk6";
+				nvidia,function = "spdif";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis SPI1 */
+			ulpi_clk_py0 {
+				nvidia,pins = "ulpi_clk_py0";
+				nvidia,function = "spi1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ulpi_dir_py1 {
+				nvidia,pins = "ulpi_dir_py1";
+				nvidia,function = "spi1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			ulpi_nxt_py2 {
+				nvidia,pins = "ulpi_nxt_py2";
+				nvidia,function = "spi1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ulpi_stp_py3 {
+				nvidia,pins = "ulpi_stp_py3";
+				nvidia,function = "spi1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis SPI2 */
+			pg5 {
+				nvidia,pins = "pg5";
+				nvidia,function = "spi4";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pg6 {
+				nvidia,pins = "pg6";
+				nvidia,function = "spi4";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pg7 {
+				nvidia,pins = "pg7";
+				nvidia,function = "spi4";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			pi3 {
+				nvidia,pins = "pi3";
+				nvidia,function = "spi4";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis UART1 */
+			pb1 { /* DCD GPIO */
+				nvidia,pins = "pb1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			pk7 { /* RI GPIO */
+				nvidia,pins = "pk7";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			uart1_txd_pu0 {
+				nvidia,pins = "pu0";
+				nvidia,function = "uarta";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			uart1_rxd_pu1 {
+				nvidia,pins = "pu1";
+				nvidia,function = "uarta";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			uart1_cts_n_pu2 {
+				nvidia,pins = "pu2";
+				nvidia,function = "uarta";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			uart1_rts_n_pu3 {
+				nvidia,pins = "pu3";
+				nvidia,function = "uarta";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			uart3_cts_n_pa1 { /* DSR GPIO */
+				nvidia,pins = "uart3_cts_n_pa1";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			uart3_rts_n_pc0 { /* DTR GPIO */
+				nvidia,pins = "uart3_rts_n_pc0";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis UART2 */
+			uart2_txd_pc2 {
+				nvidia,pins = "uart2_txd_pc2";
+				nvidia,function = "irda";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			uart2_rxd_pc3 {
+				nvidia,pins = "uart2_rxd_pc3";
+				nvidia,function = "irda";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			uart2_cts_n_pj5 {
+				nvidia,pins = "uart2_cts_n_pj5";
+				nvidia,function = "uartb";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			uart2_rts_n_pj6 {
+				nvidia,pins = "uart2_rts_n_pj6";
+				nvidia,function = "uartb";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis UART3 */
+			uart3_txd_pw6 {
+				nvidia,pins = "uart3_txd_pw6";
+				nvidia,function = "uartc";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			uart3_rxd_pw7 {
+				nvidia,pins = "uart3_rxd_pw7";
+				nvidia,function = "uartc";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis UART4 */
+			uart4_rxd_pb0 {
+				nvidia,pins = "pb0";
+				nvidia,function = "uartd";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			uart4_txd_pj7 {
+				nvidia,pins = "pj7";
+				nvidia,function = "uartd";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis USBH_EN */
+			gen2_i2c_sda_pt6 {
+				nvidia,pins = "gen2_i2c_sda_pt6";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+				nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis USBH_OC# */
+			pbb0 {
+				nvidia,pins = "pbb0";
+				nvidia,function = "vgp6";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis USBO1_EN */
+			gen2_i2c_scl_pt5 {
+				nvidia,pins = "gen2_i2c_scl_pt5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+				nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Apalis USBO1_OC# */
+			pbb4 {
+				nvidia,pins = "pbb4";
+				nvidia,function = "vgp4";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* Apalis WAKE1_MICO */
+			pex_wake_n_pdd3 {
+				nvidia,pins = "pex_wake_n_pdd3";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* CORE_PWR_REQ */
+			core_pwr_req {
+				nvidia,pins = "core_pwr_req";
+				nvidia,function = "pwron";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* CPU_PWR_REQ */
+			cpu_pwr_req {
+				nvidia,pins = "cpu_pwr_req";
+				nvidia,function = "cpu";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* DVFS */
+			dvfs_pwm_px0 {
+				nvidia,pins = "dvfs_pwm_px0";
+				nvidia,function = "cldvfs";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dvfs_clk_px2 {
+				nvidia,pins = "dvfs_clk_px2";
+				nvidia,function = "cldvfs";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* eMMC */
+			sdmmc4_dat0_paa0 {
+				nvidia,pins = "sdmmc4_dat0_paa0";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_dat1_paa1 {
+				nvidia,pins = "sdmmc4_dat1_paa1";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_dat2_paa2 {
+				nvidia,pins = "sdmmc4_dat2_paa2";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_dat3_paa3 {
+				nvidia,pins = "sdmmc4_dat3_paa3";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_dat4_paa4 {
+				nvidia,pins = "sdmmc4_dat4_paa4";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_dat5_paa5 {
+				nvidia,pins = "sdmmc4_dat5_paa5";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_dat6_paa6 {
+				nvidia,pins = "sdmmc4_dat6_paa6";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_dat7_paa7 {
+				nvidia,pins = "sdmmc4_dat7_paa7";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_clk_pcc4 {
+				nvidia,pins = "sdmmc4_clk_pcc4";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			sdmmc4_cmd_pt7 {
+				nvidia,pins = "sdmmc4_cmd_pt7";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* JTAG_RTCK */
+			jtag_rtck {
+				nvidia,pins = "jtag_rtck";
+				nvidia,function = "rtck";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* LAN_DEV_OFF# */
+			ulpi_data5_po6 {
+				nvidia,pins = "ulpi_data5_po6";
+				nvidia,function = "ulpi";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* LAN_RESET# */
+			kb_row10_ps2 {
+				nvidia,pins = "kb_row10_ps2";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* LAN_WAKE# */
+			ulpi_data4_po5 {
+				nvidia,pins = "ulpi_data4_po5";
+				nvidia,function = "ulpi";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* MCU_INT1# */
+			pk2 {
+				nvidia,pins = "pk2";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* MCU_INT2# */
+			pj2 {
+				nvidia,pins = "pj2";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* MCU_INT3# */
+			pi5 {
+				nvidia,pins = "pi5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* MCU_INT4# */
+			pj0 {
+				nvidia,pins = "pj0";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* MCU_RESET */
+			pbb6 {
+				nvidia,pins = "pbb6";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* MCU SPI */
+			gpio_x4_aud_px4 {
+				nvidia,pins = "gpio_x4_aud_px4";
+				nvidia,function = "spi2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			gpio_x5_aud_px5 {
+				nvidia,pins = "gpio_x5_aud_px5";
+				nvidia,function = "spi2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			gpio_x6_aud_px6 { /* MCU_CS */
+				nvidia,pins = "gpio_x6_aud_px6";
+				nvidia,function = "spi2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			gpio_x7_aud_px7 {
+				nvidia,pins = "gpio_x7_aud_px7";
+				nvidia,function = "spi2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+			gpio_w2_aud_pw2 { /* MCU_CSEZP */
+				nvidia,pins = "gpio_w2_aud_pw2";
+				nvidia,function = "spi2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* PMIC_CLK_32K */
+			clk_32k_in {
+				nvidia,pins = "clk_32k_in";
+				nvidia,function = "clk";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* PMIC_CPU_OC_INT */
+			clk_32k_out_pa0 {
+				nvidia,pins = "clk_32k_out_pa0";
+				nvidia,function = "soc";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* PWR_I2C */
+			pwr_i2c_scl_pz6 {
+				nvidia,pins = "pwr_i2c_scl_pz6";
+				nvidia,function = "i2cpwr";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+			};
+			pwr_i2c_sda_pz7 {
+				nvidia,pins = "pwr_i2c_sda_pz7";
+				nvidia,function = "i2cpwr";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* PWR_INT_N */
+			pwr_int_n {
+				nvidia,pins = "pwr_int_n";
+				nvidia,function = "pmi";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* RESET_MOCI_CTRL */
+			pu4 {
+				nvidia,pins = "pu4";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* RESET_OUT_N */
+			reset_out_n {
+				nvidia,pins = "reset_out_n";
+				nvidia,function = "reset_out_n";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* SHIFT_CTRL_DIR_IN */
+			kb_row0_pr0 {
+				nvidia,pins = "kb_row0_pr0";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row1_pr1 {
+				nvidia,pins = "kb_row1_pr1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* Configure level-shifter as output for HDA */
+			kb_row11_ps3 {
+				nvidia,pins = "kb_row11_ps3";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* SHIFT_CTRL_DIR_OUT */
+			kb_col5_pq5 {
+				nvidia,pins = "kb_col5_pq5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_col6_pq6 {
+				nvidia,pins = "kb_col6_pq6";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_col7_pq7 {
+				nvidia,pins = "kb_col7_pq7";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* SHIFT_CTRL_OE */
+			kb_col0_pq0 {
+				nvidia,pins = "kb_col0_pq0";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_col1_pq1 {
+				nvidia,pins = "kb_col1_pq1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_col2_pq2 {
+				nvidia,pins = "kb_col2_pq2";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_col4_pq4 {
+				nvidia,pins = "kb_col4_pq4";
+				nvidia,function = "kbc";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row2_pr2 {
+				nvidia,pins = "kb_row2_pr2";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+
+			/* GPIO_PI6 aka TMP451 ALERT#/THERM2# */
+			pi6 {
+				nvidia,pins = "pi6";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			/* TOUCH_INT */
+			gpio_w3_aud_pw3 {
+				nvidia,pins = "gpio_w3_aud_pw3";
+				nvidia,function = "spi6";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+
+			pc7 { /* NC */
+				nvidia,pins = "pc7";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pg0 { /* NC */
+				nvidia,pins = "pg0";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pg1 { /* NC */
+				nvidia,pins = "pg1";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pg2 { /* NC */
+				nvidia,pins = "pg2";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pg3 { /* NC */
+				nvidia,pins = "pg3";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pg4 { /* NC */
+				nvidia,pins = "pg4";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ph4 { /* NC */
+				nvidia,pins = "ph4";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ph5 { /* NC */
+				nvidia,pins = "ph5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ph6 { /* NC */
+				nvidia,pins = "ph6";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ph7 { /* NC */
+				nvidia,pins = "ph7";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pi0 { /* NC */
+				nvidia,pins = "pi0";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pi1 { /* NC */
+				nvidia,pins = "pi1";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pi2 { /* NC */
+				nvidia,pins = "pi2";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pi4 { /* NC */
+				nvidia,pins = "pi4";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pi7 { /* NC */
+				nvidia,pins = "pi7";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pk0 { /* NC */
+				nvidia,pins = "pk0";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pk1 { /* NC */
+				nvidia,pins = "pk1";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pk3 { /* NC */
+				nvidia,pins = "pk3";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pk4 { /* NC */
+				nvidia,pins = "pk4";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap1_fs_pn0 { /* NC */
+				nvidia,pins = "dap1_fs_pn0";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap1_din_pn1 { /* NC */
+				nvidia,pins = "dap1_din_pn1";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap1_sclk_pn3 { /* NC */
+				nvidia,pins = "dap1_sclk_pn3";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ulpi_data7_po0 { /* NC */
+				nvidia,pins = "ulpi_data7_po0";
+				nvidia,function = "ulpi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ulpi_data0_po1 { /* NC */
+				nvidia,pins = "ulpi_data0_po1";
+				nvidia,function = "ulpi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ulpi_data1_po2 { /* NC */
+				nvidia,pins = "ulpi_data1_po2";
+				nvidia,function = "ulpi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ulpi_data2_po3 { /* NC */
+				nvidia,pins = "ulpi_data2_po3";
+				nvidia,function = "ulpi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ulpi_data3_po4 { /* NC */
+				nvidia,pins = "ulpi_data3_po4";
+				nvidia,function = "ulpi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			ulpi_data6_po7 { /* NC */
+				nvidia,pins = "ulpi_data6_po7";
+				nvidia,function = "ulpi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap4_fs_pp4 { /* NC */
+				nvidia,pins = "dap4_fs_pp4";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap4_din_pp5 { /* NC */
+				nvidia,pins = "dap4_din_pp5";
+				nvidia,function = "rsvd3";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap4_dout_pp6 { /* NC */
+				nvidia,pins = "dap4_dout_pp6";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap4_sclk_pp7 { /* NC */
+				nvidia,pins = "dap4_sclk_pp7";
+				nvidia,function = "rsvd3";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_col3_pq3 { /* NC */
+				nvidia,pins = "kb_col3_pq3";
+				nvidia,function = "kbc";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row3_pr3 { /* NC */
+				nvidia,pins = "kb_row3_pr3";
+				nvidia,function = "kbc";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row4_pr4 { /* NC */
+				nvidia,pins = "kb_row4_pr4";
+				nvidia,function = "rsvd3";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row5_pr5 { /* NC */
+				nvidia,pins = "kb_row5_pr5";
+				nvidia,function = "rsvd3";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row6_pr6 { /* NC */
+				nvidia,pins = "kb_row6_pr6";
+				nvidia,function = "kbc";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row7_pr7 { /* NC */
+				nvidia,pins = "kb_row7_pr7";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row8_ps0 { /* NC */
+				nvidia,pins = "kb_row8_ps0";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row9_ps1 { /* NC */
+				nvidia,pins = "kb_row9_ps1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row12_ps4 { /* NC */
+				nvidia,pins = "kb_row12_ps4";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row13_ps5 { /* NC */
+				nvidia,pins = "kb_row13_ps5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row14_ps6 { /* NC */
+				nvidia,pins = "kb_row14_ps6";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row15_ps7 { /* NC */
+				nvidia,pins = "kb_row15_ps7";
+				nvidia,function = "rsvd3";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row16_pt0 { /* NC */
+				nvidia,pins = "kb_row16_pt0";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			kb_row17_pt1 { /* NC */
+				nvidia,pins = "kb_row17_pt1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pu5 { /* NC */
+				nvidia,pins = "pu5";
+				nvidia,function = "gmi";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			/*
+			 * PCB Version Indication: V1.2 and later have GPIO_PV0
+			 * wired to GND, was NC before
+			 */
+			pv0 {
+				nvidia,pins = "pv0";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pv1 { /* NC */
+				nvidia,pins = "pv1";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			gpio_x1_aud_px1 { /* NC */
+				nvidia,pins = "gpio_x1_aud_px1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			gpio_x3_aud_px3 { /* NC */
+				nvidia,pins = "gpio_x3_aud_px3";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pbb7 { /* NC */
+				nvidia,pins = "pbb7";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pcc1 { /* NC */
+				nvidia,pins = "pcc1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			pcc2 { /* NC */
+				nvidia,pins = "pcc2";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			clk3_req_pee1 { /* NC */
+				nvidia,pins = "clk3_req_pee1";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap_mclk1_req_pee2 { /* NC */
+				nvidia,pins = "dap_mclk1_req_pee2";
+				nvidia,function = "rsvd4";
+				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			/*
+			 * Leave SDMMC3_CLK_LB_OUT muxed as SDMMC3 with output
+			 * driver enabled aka not tristated and input driver
+			 * enabled as well as it features some magic properties
+			 * even though the external loopback is disabled and the
+			 * internal loopback used as per
+			 * SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1
+			 * bits being set to 0xfffd according to the TRM!
+			 */
+			sdmmc3_clk_lb_out_pee4 { /* NC */
+				nvidia,pins = "sdmmc3_clk_lb_out_pee4";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+		};
+	};
+
+	serial@70006040 {
+		compatible = "nvidia,tegra124-hsuart";
+	};
+
+	serial@70006200 {
+		compatible = "nvidia,tegra124-hsuart";
+	};
+
+	serial@70006300 {
+		compatible = "nvidia,tegra124-hsuart";
+	};
+
+	hdmi_ddc: i2c@7000c700 {
+		clock-frequency = <10000>;
+	};
+
+	/* PWR_I2C: power I2C to audio codec, PMIC and temperature sensor */
+	i2c@7000d000 {
+		status = "okay";
+		clock-frequency = <400000>;
+
+		/* SGTL5000 audio codec */
+		sgtl5000: codec@a {
+			compatible = "fsl,sgtl5000";
+			reg = <0x0a>;
+			VDDA-supply = <&reg_3v3>;
+			VDDIO-supply = <&vddio_1v8>;
+			clocks = <&tegra_car TEGRA124_CLK_EXTERN1>;
+		};
+
+		pmic: pmic@40 {
+			compatible = "ams,as3722";
+			reg = <0x40>;
+			interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+			ams,system-power-controller;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			gpio-controller;
+			#gpio-cells = <2>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&as3722_default>;
+
+			as3722_default: pinmux {
+				gpio2_7 {
+					pins = "gpio2", /* PWR_EN_+V3.3 */
+					       "gpio7"; /* +V1.6_LPO */
+					function = "gpio";
+					bias-pull-up;
+				};
+
+				gpio0_1_3_4_5_6 {
+					pins = "gpio0", "gpio1", "gpio3",
+					       "gpio4", "gpio5", "gpio6";
+					bias-high-impedance;
+				};
+			};
+
+			regulators {
+				vsup-sd2-supply = <&reg_3v3>;
+				vsup-sd3-supply = <&reg_3v3>;
+				vsup-sd4-supply = <&reg_3v3>;
+				vsup-sd5-supply = <&reg_3v3>;
+				vin-ldo0-supply = <&vddio_ddr_1v35>;
+				vin-ldo1-6-supply = <&reg_3v3>;
+				vin-ldo2-5-7-supply = <&vddio_1v8>;
+				vin-ldo3-4-supply = <&reg_3v3>;
+				vin-ldo9-10-supply = <&reg_3v3>;
+				vin-ldo11-supply = <&reg_3v3>;
+
+				vdd_cpu: sd0 {
+					regulator-name = "+VDD_CPU_AP";
+					regulator-min-microvolt = <700000>;
+					regulator-max-microvolt = <1400000>;
+					regulator-min-microamp = <3500000>;
+					regulator-max-microamp = <3500000>;
+					regulator-always-on;
+					regulator-boot-on;
+					ams,ext-control = <2>;
+				};
+
+				sd1 {
+					regulator-name = "+VDD_CORE";
+					regulator-min-microvolt = <700000>;
+					regulator-max-microvolt = <1350000>;
+					regulator-min-microamp = <2500000>;
+					regulator-max-microamp = <4000000>;
+					regulator-always-on;
+					regulator-boot-on;
+					ams,ext-control = <1>;
+				};
+
+				vddio_ddr_1v35: sd2 {
+					regulator-name =
+						"+V1.35_VDDIO_DDR(sd2)";
+					regulator-min-microvolt = <1350000>;
+					regulator-max-microvolt = <1350000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				sd3 {
+					regulator-name =
+						"+V1.35_VDDIO_DDR(sd3)";
+					regulator-min-microvolt = <1350000>;
+					regulator-max-microvolt = <1350000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				vdd_1v05: sd4 {
+					regulator-name = "+V1.05";
+					regulator-min-microvolt = <1050000>;
+					regulator-max-microvolt = <1050000>;
+				};
+
+				vddio_1v8: sd5 {
+					regulator-name = "+V1.8";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				vdd_gpu: sd6 {
+					regulator-name = "+VDD_GPU_AP";
+					regulator-min-microvolt = <650000>;
+					regulator-max-microvolt = <1200000>;
+					regulator-min-microamp = <3500000>;
+					regulator-max-microamp = <3500000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				avdd_1v05: ldo0 {
+					regulator-name = "+V1.05_AVDD";
+					regulator-min-microvolt = <1050000>;
+					regulator-max-microvolt = <1050000>;
+					regulator-boot-on;
+					regulator-always-on;
+					ams,ext-control = <1>;
+				};
+
+				vddio_sdmmc1: ldo1 {
+					regulator-name = "VDDIO_SDMMC1";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo2 {
+					regulator-name = "+V1.2";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+
+				ldo3 {
+					regulator-name = "+V1.05_RTC";
+					regulator-min-microvolt = <1000000>;
+					regulator-max-microvolt = <1000000>;
+					regulator-boot-on;
+					regulator-always-on;
+					ams,enable-tracking;
+				};
+
+				/* 1.8V for LVDS, 3.3V for eDP */
+				ldo4 {
+					regulator-name = "AVDD_LVDS0_PLL";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+				};
+
+				/* LDO5 not used */
+
+				vddio_sdmmc3: ldo6 {
+					regulator-name = "VDDIO_SDMMC3";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				/* LDO7 not used */
+
+				ldo9 {
+					regulator-name = "+V3.3_ETH(ldo9)";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-always-on;
+				};
+
+				ldo10 {
+					regulator-name = "+V3.3_ETH(ldo10)";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-always-on;
+				};
+
+				ldo11 {
+					regulator-name = "+V1.8_VPP_FUSE";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+				};
+			};
+		};
+
+		/*
+		 * TMP451 temperature sensor
+		 * Note: THERM_N directly connected to AS3722 PMIC THERM
+		 */
+		temperature-sensor@4c {
+			compatible = "ti,tmp451";
+			reg = <0x4c>;
+			interrupt-parent = <&gpio>;
+			interrupts = <TEGRA_GPIO(I, 6) IRQ_TYPE_LEVEL_LOW>;
+			#thermal-sensor-cells = <1>;
+		};
+	};
+
+	/* SPI2: MCU SPI */
+	spi@7000d600 {
+		status = "okay";
+		spi-max-frequency = <25000000>;
+	};
+
+	pmc@7000e400 {
+		nvidia,invert-interrupt;
+		nvidia,suspend-mode = <1>;
+		nvidia,cpu-pwr-good-time = <500>;
+		nvidia,cpu-pwr-off-time = <300>;
+		nvidia,core-pwr-good-time = <641 3845>;
+		nvidia,core-pwr-off-time = <61036>;
+		nvidia,core-power-req-active-high;
+		nvidia,sys-clock-req-active-high;
+
+		/* Set power_off bit in ResetControl register of AS3722 PMIC */
+		i2c-thermtrip {
+			nvidia,i2c-controller-id = <4>;
+			nvidia,bus-addr = <0x40>;
+			nvidia,reg-addr = <0x36>;
+			nvidia,reg-data = <0x2>;
+		};
+	};
+
+	sata@70020000 {
+		phys = <&{/padctl@7009f000/pads/sata/lanes/sata-0}>;
+		phy-names = "sata-0";
+		avdd-supply = <&vdd_1v05>;
+		hvdd-supply = <&reg_3v3>;
+		vddio-supply = <&vdd_1v05>;
+	};
+
+	usb@70090000 {
+		/* USBO1, USBO1 (SS), USBH2, USBH4 and USBH4 (SS) */
+		phys = <&{/padctl@7009f000/pads/usb2/lanes/usb2-0}>,
+		       <&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>,
+		       <&{/padctl@7009f000/pads/usb2/lanes/usb2-1}>,
+		       <&{/padctl@7009f000/pads/usb2/lanes/usb2-2}>,
+		       <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>;
+		phy-names = "usb2-0", "usb3-1", "usb2-1", "usb2-2", "usb3-0";
+		avddio-pex-supply = <&vdd_1v05>;
+		avdd-pll-erefe-supply = <&avdd_1v05>;
+		avdd-pll-utmip-supply = <&vddio_1v8>;
+		avdd-usb-ss-pll-supply = <&vdd_1v05>;
+		avdd-usb-supply = <&reg_3v3>;
+		dvddio-pex-supply = <&vdd_1v05>;
+		hvdd-usb-ss-pll-e-supply = <&reg_3v3>;
+		hvdd-usb-ss-supply = <&reg_3v3>;
+	};
+
+	padctl@7009f000 {
+		pads {
+			usb2 {
+				status = "okay";
+
+				lanes {
+					usb2-0 {
+						nvidia,function = "xusb";
+						status = "okay";
+					};
+
+					usb2-1 {
+						nvidia,function = "xusb";
+						status = "okay";
+					};
+
+					usb2-2 {
+						nvidia,function = "xusb";
+						status = "okay";
+					};
+				};
+			};
+
+			pcie {
+				status = "okay";
+
+				lanes {
+					pcie-0 {
+						nvidia,function = "usb3-ss";
+						status = "okay";
+					};
+
+					pcie-1 {
+						nvidia,function = "usb3-ss";
+						status = "okay";
+					};
+
+					pcie-2 {
+						nvidia,function = "pcie";
+						status = "okay";
+					};
+
+					pcie-3 {
+						nvidia,function = "pcie";
+						status = "okay";
+					};
+
+					pcie-4 {
+						nvidia,function = "pcie";
+						status = "okay";
+					};
+				};
+			};
+
+			sata {
+				status = "okay";
+
+				lanes {
+					sata-0 {
+						nvidia,function = "sata";
+						status = "okay";
+					};
+				};
+			};
+		};
+
+		ports {
+			/* USBO1 */
+			usb2-0 {
+				status = "okay";
+				mode = "otg";
+
+				vbus-supply = <&reg_usbo1_vbus>;
+			};
+
+			/* USBH2 */
+			usb2-1 {
+				status = "okay";
+				mode = "host";
+
+				vbus-supply = <&reg_usbh_vbus>;
+			};
+
+			/* USBH4 */
+			usb2-2 {
+				status = "okay";
+				mode = "host";
+
+				vbus-supply = <&reg_usbh_vbus>;
+			};
+
+			usb3-0 {
+				nvidia,usb2-companion = <2>;
+				status = "okay";
+			};
+
+			usb3-1 {
+				nvidia,usb2-companion = <0>;
+				status = "okay";
+			};
+		};
+	};
+
+	/* eMMC */
+	sdhci@700b0600 {
+		status = "okay";
+		bus-width = <8>;
+		non-removable;
+	};
+
+	/* CPU DFLL clock */
+	clock@70110000 {
+		status = "okay";
+		vdd-cpu-supply = <&vdd_cpu>;
+		nvidia,i2c-fs-rate = <400000>;
+	};
+
+	ahub@70300000 {
+		i2s@70301200 {
+			status = "okay";
+		};
+	};
+
+	clocks {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		clk32k_in: clock@0 {
+			compatible = "fixed-clock";
+			reg = <0>;
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+		};
+	};
+
+	cpus {
+		cpu@0 {
+			vdd-cpu-supply = <&vdd_cpu>;
+		};
+	};
+
+	reg_1v05_avdd_hdmi_pll: regulator-1v05-avdd-hdmi-pll {
+		compatible = "regulator-fixed";
+		regulator-name = "+V1.05_AVDD_HDMI_PLL";
+		regulator-min-microvolt = <1050000>;
+		regulator-max-microvolt = <1050000>;
+		gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_LOW>;
+		vin-supply = <&vdd_1v05>;
+	};
+
+	reg_3v3_mxm: regulator-3v3-mxm {
+		compatible = "regulator-fixed";
+		regulator-name = "+V3.3_MXM";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	reg_3v3: regulator-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "+V3.3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+		/* PWR_EN_+V3.3 */
+		gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		vin-supply = <&reg_3v3_mxm>;
+	};
+
+	reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi {
+		compatible = "regulator-fixed";
+		regulator-name = "+V3.3_AVDD_HDMI";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vdd_1v05>;
+	};
+
+	sound {
+		compatible = "toradex,tegra-audio-sgtl5000-apalis_tk1",
+			     "nvidia,tegra-audio-sgtl5000";
+		nvidia,model = "Toradex Apalis TK1";
+		nvidia,audio-routing =
+			"Headphone Jack", "HP_OUT",
+			"LINE_IN", "Line In Jack",
+			"MIC_IN", "Mic Jack";
+		nvidia,i2s-controller = <&tegra_i2s2>;
+		nvidia,audio-codec = <&sgtl5000>;
+		clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
+			 <&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA124_CLK_EXTERN1>;
+		clock-names = "pll_a", "pll_a_out0", "mclk";
+	};
+
+	thermal-zones {
+		cpu {
+			trips {
+				cpu-shutdown-trip {
+					temperature = <101000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+
+		mem {
+			trips {
+				mem-shutdown-trip {
+					temperature = <101000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+
+		gpu {
+			trips {
+				gpu-shutdown-trip {
+					temperature = <101000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+	};
+};
+
+&gpio {
+	/* I210 Gigabit Ethernet Controller Reset */
+	lan_reset_n {
+		gpio-hog;
+		gpios = <TEGRA_GPIO(S, 2) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "LAN_RESET_N";
+	};
+
+	/* Control MXM3 pin 26 Reset Module Output Carrier Input */
+	reset_moci_ctrl {
+		gpio-hog;
+		gpios = <TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "RESET_MOCI_CTRL";
+	};
+};
diff --git a/arch/arm/boot/dts/tegra124-apalis.dtsi b/arch/arm/boot/dts/tegra124-apalis.dtsi
index 5d9b18e..65a2161 100644
--- a/arch/arm/boot/dts/tegra124-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra124-apalis.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Toradex AG
+ * Copyright 2016-2018 Toradex AG
  *
  * This file is dual-licensed: you can use it either under the terms
  * of the GPL or the X11 license, at your option. Note that this dual
@@ -56,7 +56,6 @@
 
 	pcie@1003000 {
 		status = "okay";
-
 		avddio-pex-supply = <&vdd_1v05>;
 		avdd-pex-pll-supply = <&vdd_1v05>;
 		avdd-pll-erefe-supply = <&avdd_1v05>;
@@ -85,7 +84,6 @@
 		hdmi@54280000 {
 			pll-supply = <&reg_1v05_avdd_hdmi_pll>;
 			vdd-supply = <&reg_3v3_avdd_hdmi>;
-
 			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
 			nvidia,hpd-gpio =
 				<&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
@@ -453,12 +451,12 @@
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
 			};
-			/* PWM3 active on pu6 being Apalis BKL1_PWM */
+			/* PWM3 active on pu6 being Apalis BKL1_PWM as well */
 			ph3 {
 				nvidia,pins = "ph3";
-				nvidia,function = "gmi";
-				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
-				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,function = "pwm3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
 			};
 
@@ -1579,7 +1577,7 @@
 	};
 
 	hdmi_ddc: i2c@7000c400 {
-		clock-frequency = <100000>;
+		clock-frequency = <10000>;
 	};
 
 	/* PWR_I2C: power I2C to audio codec, PMIC and temperature sensor */
@@ -1600,15 +1598,11 @@
 			compatible = "ams,as3722";
 			reg = <0x40>;
 			interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
-
 			ams,system-power-controller;
-
 			#interrupt-cells = <2>;
 			interrupt-controller;
-
 			gpio-controller;
 			#gpio-cells = <2>;
-
 			pinctrl-names = "default";
 			pinctrl-0 = <&as3722_default>;
 
@@ -1620,9 +1614,9 @@
 					bias-pull-up;
 				};
 
-				gpio1_3_4_5_6 {
-					pins = "gpio1", "gpio3", "gpio4",
-					       "gpio5", "gpio6";
+				gpio0_1_3_4_5_6 {
+					pins = "gpio0", "gpio1", "gpio3",
+					       "gpio4", "gpio5", "gpio6";
 					bias-high-impedance;
 				};
 			};
@@ -1783,7 +1777,6 @@
 			reg = <0x4c>;
 			interrupt-parent = <&gpio>;
 			interrupts = <TEGRA_GPIO(I, 6) IRQ_TYPE_LEVEL_LOW>;
-
 			#thermal-sensor-cells = <1>;
 		};
 	};
@@ -1816,7 +1809,6 @@
 	sata@70020000 {
 		phys = <&{/padctl@7009f000/pads/sata/lanes/sata-0}>;
 		phy-names = "sata-0";
-
 		avdd-supply = <&vdd_1v05>;
 		hvdd-supply = <&reg_3v3>;
 		vddio-supply = <&vdd_1v05>;
@@ -1830,7 +1822,6 @@
 		       <&{/padctl@7009f000/pads/usb2/lanes/usb2-2}>,
 		       <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>;
 		phy-names = "usb2-0", "usb3-1", "usb2-1", "usb2-2", "usb3-0";
-
 		avddio-pex-supply = <&vdd_1v05>;
 		avdd-pll-erefe-supply = <&avdd_1v05>;
 		avdd-pll-utmip-supply = <&vddio_1v8>;
@@ -2041,53 +2032,50 @@
 	thermal-zones {
 		cpu {
 			trips {
-				trip@0 {
+				cpu-shutdown-trip {
 					temperature = <101000>;
 					hysteresis = <0>;
 					type = "critical";
 				};
 			};
-
-			cooling-maps {
-				/*
-				 * There are currently no cooling maps because
-				 * there are no cooling devices
-				 */
-			};
 		};
 
 		mem {
 			trips {
-				trip@0 {
+				mem-shutdown-trip {
 					temperature = <101000>;
 					hysteresis = <0>;
 					type = "critical";
 				};
 			};
-
-			cooling-maps {
-				/*
-				 * There are currently no cooling maps because
-				 * there are no cooling devices
-				 */
-			};
 		};
 
 		gpu {
 			trips {
-				trip@0 {
+				gpu-shutdown-trip {
 					temperature = <101000>;
 					hysteresis = <0>;
 					type = "critical";
 				};
 			};
-
-			cooling-maps {
-				/*
-				 * There are currently no cooling maps because
-				 * there are no cooling devices
-				 */
-			};
 		};
 	};
 };
+
+&gpio {
+	/* I210 Gigabit Ethernet Controller Reset */
+	lan_reset_n {
+		gpio-hog;
+		gpios = <TEGRA_GPIO(S, 2) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "LAN_RESET_N";
+	};
+
+	/* Control MXM3 pin 26 Reset Module Output Carrier Input */
+	reset_moci_ctrl {
+		gpio-hog;
+		gpios = <TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "RESET_MOCI_CTRL";
+	};
+};
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
index d112f85..6dbcf84 100644
--- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts
+++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
@@ -1418,7 +1418,7 @@
 			compatible = "realtek,rt5639";
 			reg = <0x1c>;
 			interrupt-parent = <&gpio>;
-			interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
+			interrupts = <TEGRA_GPIO(H, 4) IRQ_TYPE_EDGE_FALLING>;
 			realtek,ldo1-en-gpios =
 				<&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
 		};
diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts
index 32d9079..89bcc17 100644
--- a/arch/arm/boot/dts/tegra124-venice2.dts
+++ b/arch/arm/boot/dts/tegra124-venice2.dts
@@ -613,7 +613,7 @@
 			compatible = "maxim,max98090";
 			reg = <0x10>;
 			interrupt-parent = <&gpio>;
-			interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
+			interrupts = <TEGRA_GPIO(H, 4) IRQ_TYPE_EDGE_FALLING>;
 		};
 	};
 
@@ -859,7 +859,7 @@
 					reg = <0x9>;
 					interrupt-parent = <&gpio>;
 					interrupts = <TEGRA_GPIO(J, 0)
-							GPIO_ACTIVE_HIGH>;
+							IRQ_TYPE_EDGE_BOTH>;
 					ti,ac-detect-gpios = <&gpio
 							TEGRA_GPIO(J, 0)
 							GPIO_ACTIVE_HIGH>;
@@ -956,11 +956,6 @@
 						nvidia,function = "usb3-ss";
 						status = "okay";
 					};
-
-					pcie-1 {
-						nvidia,function = "usb3-ss";
-						status = "okay";
-					};
 				};
 			};
 		};
diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
index 813ae34..5c202b3 100644
--- a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
+++ b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
@@ -213,21 +213,27 @@
 			GPIO_ACTIVE_HIGH>;
 	};
 
+	/*
+	 * GEN1_I2C: I2C_SDA/SCL on SODIMM pin 194/196 (e.g. RTC on carrier
+	 * board)
+	 */
 	i2c@7000c000 {
 		clock-frequency = <400000>;
 	};
 
+	/* DDC_SCL/SDA on X3 pin 15/16 (e.g. display EDID) */
 	i2c_ddc: i2c@7000c400 {
-		clock-frequency = <100000>;
+		clock-frequency = <10000>;
 	};
 
-	i2c@7000c500 {
-		clock-frequency = <400000>;
-	};
+	/* GEN2_I2C: unused */
 
+	/* CAM/GEN3_I2C: used as EXT_IO1/2 GPIOs on SODIMM pin 133/127 */
+
+	/* PWR_I2C: power I2C to PMIC and temperature sensor (On-module) */
 	i2c@7000d000 {
 		status = "okay";
-		clock-frequency = <400000>;
+		clock-frequency = <100000>;
 
 		pmic: tps6586x@34 {
 			compatible = "ti,tps6586x";
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 864a958..0a71364 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -17,7 +17,7 @@
 		#size-cells = <1>;
 		ranges = <0 0x40000000 0x40000>;
 
-		vde_pool: vde {
+		vde_pool: vde@400 {
 			reg = <0x400 0x3fc00>;
 			pool;
 		};
@@ -741,7 +741,7 @@
 		phy_type = "ulpi";
 		clocks = <&tegra_car TEGRA20_CLK_USB2>,
 			 <&tegra_car TEGRA20_CLK_PLL_U>,
-			 <&tegra_car TEGRA20_CLK_CDEV2>;
+			 <&tegra_car TEGRA20_CLK_PLL_P_OUT4>;
 		clock-names = "reg", "pll_u", "ulpi-link";
 		resets = <&tegra_car 58>, <&tegra_car 22>;
 		reset-names = "usb", "utmi-pads";
diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts
index 07b945b..0dc85a2 100644
--- a/arch/arm/boot/dts/tegra30-apalis-eval.dts
+++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts
@@ -79,7 +79,7 @@
 	 */
 	i2c@7000c000 {
 		status = "okay";
-		clock-frequency = <100000>;
+		clock-frequency = <400000>;
 
 		pcie-switch@58 {
 			compatible = "plx,pex8605";
@@ -88,7 +88,7 @@
 
 		/* M41T0M6 real time clock on carrier board */
 		rtc@68 {
-			compatible = "st,m41t00";
+			compatible = "st,m41t0";
 			reg = <0x68>;
 		};
 	};
diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
index faa8cd2..d1d21ec 100644
--- a/arch/arm/boot/dts/tegra30-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -437,7 +437,7 @@
 	};
 
 	hdmiddc: i2c@7000c700 {
-		clock-frequency = <100000>;
+		clock-frequency = <10000>;
 	};
 
 	/*
@@ -597,7 +597,6 @@
 
 			stmpe_touchscreen@0 {
 				compatible = "st,stmpe-ts";
-				reg = <0>;
 				/* 3.25 MHz ADC clock speed */
 				st,adc-freq = <1>;
 				/* 8 sample average control */
@@ -657,7 +656,7 @@
 			reg = <1>;
 			clocks = <&clk16m>;
 			interrupt-parent = <&gpio>;
-			interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_LOW>;
+			interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_EDGE_RISING>;
 			spi-max-frequency = <10000000>;
 		};
 	};
@@ -672,7 +671,7 @@
 			reg = <0>;
 			clocks = <&clk16m>;
 			interrupt-parent = <&gpio>;
-			interrupts = <TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
+			interrupts = <TEGRA_GPIO(W, 2) IRQ_TYPE_EDGE_RISING>;
 			spi-max-frequency = <10000000>;
 		};
 	};
diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts
index 5331a8f..ae52a50 100644
--- a/arch/arm/boot/dts/tegra30-beaver.dts
+++ b/arch/arm/boot/dts/tegra30-beaver.dts
@@ -260,14 +260,14 @@
 			};
 			sdmmc3_dat6_pd3 {
 				nvidia,pins = "sdmmc3_dat6_pd3";
-				nvidia,function = "rsvd1";
+				nvidia,function = "spdif";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
 			};
 			sdmmc3_dat7_pd4 {
 				nvidia,pins = "sdmmc3_dat7_pd4";
-				nvidia,function = "rsvd1";
+				nvidia,function = "spdif";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -281,14 +281,14 @@
 			};
 			vi_vsync_pd6 {
 				nvidia,pins = "vi_vsync_pd6";
-				nvidia,function = "rsvd1";
+				nvidia,function = "ddr";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
 			};
 			vi_hsync_pd7 {
 				nvidia,pins = "vi_hsync_pd7";
-				nvidia,function = "rsvd1";
+				nvidia,function = "ddr";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -806,7 +806,7 @@
 			};
 			hdmi_int_pn7 {
 				nvidia,pins = "hdmi_int_pn7";
-				nvidia,function = "rsvd1";
+				nvidia,function = "hdmi";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_ENABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -841,7 +841,7 @@
 			};
 			ulpi_data3_po4 {
 				nvidia,pins = "ulpi_data3_po4";
-				nvidia,function = "rsvd1";
+				nvidia,function = "uarta";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -1107,21 +1107,21 @@
 			};
 			vi_d10_pt2 {
 				nvidia,pins = "vi_d10_pt2";
-				nvidia,function = "rsvd1";
+				nvidia,function = "ddr";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
 			};
 			vi_d11_pt3 {
 				nvidia,pins = "vi_d11_pt3";
-				nvidia,function = "rsvd1";
+				nvidia,function = "ddr";
 				nvidia,pull = <TEGRA_PIN_PULL_UP>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
 			};
 			vi_d0_pt4 {
 				nvidia,pins = "vi_d0_pt4";
-				nvidia,function = "rsvd1";
+				nvidia,function = "ddr";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -1151,7 +1151,7 @@
 			};
 			pu0 {
 				nvidia,pins = "pu0";
-				nvidia,function = "rsvd1";
+				nvidia,function = "owr";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -1172,7 +1172,7 @@
 			};
 			pu3 {
 				nvidia,pins = "pu3";
-				nvidia,function = "rsvd1";
+				nvidia,function = "pwm0";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -1193,7 +1193,7 @@
 			};
 			pu6 {
 				nvidia,pins = "pu6";
-				nvidia,function = "rsvd1";
+				nvidia,function = "pwm3";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -1221,7 +1221,7 @@
 			};
 			pv3 {
 				nvidia,pins = "pv3";
-				nvidia,function = "rsvd1";
+				nvidia,function = "clk_12m_out";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
@@ -1510,7 +1510,7 @@
 			};
 			pbb0 {
 				nvidia,pins = "pbb0";
-				nvidia,function = "rsvd1";
+				nvidia,function = "i2s4";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -1575,7 +1575,7 @@
 			};
 			pcc1 {
 				nvidia,pins = "pcc1";
-				nvidia,function = "rsvd1";
+				nvidia,function = "i2s4";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -1762,7 +1762,7 @@
 			compatible = "realtek,rt5640";
 			reg = <0x1c>;
 			interrupt-parent = <&gpio>;
-			interrupts = <TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
+			interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_EDGE_FALLING>;
 			realtek,ldo1-en-gpios =
 				<&gpio TEGRA_GPIO(X, 2) GPIO_ACTIVE_HIGH>;
 		};
diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
index 3c5fb24..16e1f38 100644
--- a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
@@ -56,11 +56,11 @@
 	 */
 	i2c@7000c000 {
 		status = "okay";
-		clock-frequency = <100000>;
+		clock-frequency = <400000>;
 
 		/* M41T0M6 real time clock on carrier board */
 		rtc@68 {
-			compatible = "st,m41t00";
+			compatible = "st,m41t0";
 			reg = <0x68>;
 		};
 	};
@@ -79,7 +79,7 @@
 			reg = <0>;
 			clocks = <&clk16m>;
 			interrupt-parent = <&gpio>;
-			interrupts = <TEGRA_GPIO(S, 0) GPIO_ACTIVE_LOW>;
+			interrupts = <TEGRA_GPIO(S, 0) IRQ_TYPE_EDGE_RISING>;
 			spi-max-frequency = <10000000>;
 		};
 		spidev0: spi@1 {
diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index 139bfa0..c44d8c4 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -215,7 +215,7 @@
 	};
 
 	hdmiddc: i2c@7000c700 {
-		clock-frequency = <100000>;
+		clock-frequency = <10000>;
 	};
 
 	/*
@@ -363,7 +363,6 @@
 
 			stmpe_touchscreen {
 				compatible = "st,stmpe-ts";
-				reg = <0>;
 				/* 3.25 MHz ADC clock speed */
 				st,adc-freq = <1>;
 				/* 8 sample average control */
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index c3e9f1e..a110cf8 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -91,6 +91,19 @@
 		};
 	};
 
+	iram@40000000 {
+		compatible = "mmio-sram";
+		reg = <0x40000000 0x40000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x40000000 0x40000>;
+
+		vde_pool: vde@400 {
+			reg = <0x400 0x3fc00>;
+			pool;
+		};
+	};
+
 	host1x@50000000 {
 		compatible = "nvidia,tegra30-host1x", "simple-bus";
 		reg = <0x50000000 0x00024000>;
@@ -358,6 +371,28 @@
 		*/
 	};
 
+	vde@6001a000 {
+		compatible = "nvidia,tegra30-vde", "nvidia,tegra20-vde";
+		reg = <0x6001a000 0x1000   /* Syntax Engine */
+		       0x6001b000 0x1000   /* Video Bitstream Engine */
+		       0x6001c000  0x100   /* Macroblock Engine */
+		       0x6001c200  0x100   /* Post-processing Engine */
+		       0x6001c400  0x100   /* Motion Compensation Engine */
+		       0x6001c600  0x100   /* Transform Engine */
+		       0x6001c800  0x100   /* Pixel prediction block */
+		       0x6001ca00  0x100   /* Video DMA */
+		       0x6001d800  0x400>; /* Video frame controls */
+		reg-names = "sxe", "bsev", "mbe", "ppe", "mce",
+			    "tfe", "ppb", "vdma", "frameid";
+		iram = <&vde_pool>; /* IRAM region */
+		interrupts = <GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>, /* Sync token interrupt */
+			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, /* BSE-V interrupt */
+			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; /* SXE interrupt */
+		interrupt-names = "sync-token", "bsev", "sxe";
+		clocks = <&tegra_car TEGRA30_CLK_VDE>;
+		resets = <&tegra_car 61>;
+	};
+
 	apbmisc@70000800 {
 		compatible = "nvidia,tegra30-apbmisc", "nvidia,tegra20-apbmisc";
 		reg = <0x70000800 0x64   /* Chip revision */
diff --git a/arch/arm/boot/dts/uniphier-ld4-ref.dts b/arch/arm/boot/dts/uniphier-ld4-ref.dts
index a3afd0c..21407e1 100644
--- a/arch/arm/boot/dts/uniphier-ld4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ld4-ref.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier LD4 Reference Board
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD4 Reference Board
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-ld4.dtsi"
diff --git a/arch/arm/boot/dts/uniphier-ld4.dtsi b/arch/arm/boot/dts/uniphier-ld4.dtsi
index 0459e84..37950ad 100644
--- a/arch/arm/boot/dts/uniphier-ld4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ld4.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier LD4 SoC
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD4 SoC
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 #include <dt-bindings/gpio/uniphier-gpio.h>
 
diff --git a/arch/arm/boot/dts/uniphier-ld6b-ref.dts b/arch/arm/boot/dts/uniphier-ld6b-ref.dts
index 811b999..a0a44a4 100644
--- a/arch/arm/boot/dts/uniphier-ld6b-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ld6b-ref.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier LD6b Reference Board
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD6b Reference Board
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-ld6b.dtsi"
@@ -67,6 +65,17 @@
 	status = "okay";
 };
 
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@0 {
+		reg = <0>;
+	};
+};
+
 &nand {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ld6b.dtsi b/arch/arm/boot/dts/uniphier-ld6b.dtsi
index 9a7b25c..4d07a94 100644
--- a/arch/arm/boot/dts/uniphier-ld6b.dtsi
+++ b/arch/arm/boot/dts/uniphier-ld6b.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier LD6b SoC
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD6b SoC
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /*
  * LD6b consists of two silicon dies: D-chip and A-chip.
diff --git a/arch/arm/boot/dts/uniphier-pinctrl.dtsi b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
index de481c3..51f0e69 100644
--- a/arch/arm/boot/dts/uniphier-pinctrl.dtsi
+++ b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier SoCs default pinctrl settings
- *
- * Copyright (C) 2015-2017 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier SoCs default pinctrl settings
+//
+// Copyright (C) 2015-2017 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 &pinctrl {
 	pinctrl_aout: aout {
@@ -13,6 +11,46 @@
 		function = "aout";
 	};
 
+	pinctrl_ain1: ain1 {
+		groups = "ain1";
+		function = "ain1";
+	};
+
+	pinctrl_ain2: ain2 {
+		groups = "ain2";
+		function = "ain2";
+	};
+
+	pinctrl_ainiec1: ainiec1 {
+		groups = "ainiec1";
+		function = "ainiec1";
+	};
+
+	pinctrl_aout1: aout1 {
+		groups = "aout1";
+		function = "aout1";
+	};
+
+	pinctrl_aout2: aout2 {
+		groups = "aout2";
+		function = "aout2";
+	};
+
+	pinctrl_aout3: aout3 {
+		groups = "aout3";
+		function = "aout3";
+	};
+
+	pinctrl_aoutiec1: aoutiec1 {
+		groups = "aoutiec1";
+		function = "aoutiec1";
+	};
+
+	pinctrl_aoutiec2: aoutiec2 {
+		groups = "aoutiec2";
+		function = "aoutiec2";
+	};
+
 	pinctrl_emmc: emmc {
 		groups = "emmc", "emmc_dat8";
 		function = "emmc";
@@ -33,6 +71,16 @@
 		function = "ether_rmii";
 	};
 
+	pinctrl_ether1_rgmii: ether1-rgmii {
+		groups = "ether1_rgmii";
+		function = "ether1_rgmii";
+	};
+
+	pinctrl_ether1_rmii: ether1-rmii {
+		groups = "ether1_rmii";
+		function = "ether1_rmii";
+	};
+
 	pinctrl_i2c0: i2c0 {
 		groups = "i2c0";
 		function = "i2c0";
diff --git a/arch/arm/boot/dts/uniphier-pro4-ace.dts b/arch/arm/boot/dts/uniphier-pro4-ace.dts
index 089419c..db1b089 100644
--- a/arch/arm/boot/dts/uniphier-pro4-ace.dts
+++ b/arch/arm/boot/dts/uniphier-pro4-ace.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier Pro4 Ace Board
- *
- * Copyright (C) 2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier Pro4 Ace Board
+//
+// Copyright (C) 2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-pro4.dtsi"
@@ -77,3 +75,14 @@
 &usb3 {
 	status = "okay";
 };
+
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@1 {
+		reg = <1>;
+	};
+};
diff --git a/arch/arm/boot/dts/uniphier-pro4-ref.dts b/arch/arm/boot/dts/uniphier-pro4-ref.dts
index 6a004e5..efb0849 100644
--- a/arch/arm/boot/dts/uniphier-pro4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-pro4-ref.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier Pro4 Reference Board
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier Pro4 Reference Board
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-pro4.dtsi"
@@ -75,6 +73,17 @@
 	status = "okay";
 };
 
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@0 {
+		reg = <0>;
+	};
+};
+
 &nand {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-pro4-sanji.dts b/arch/arm/boot/dts/uniphier-pro4-sanji.dts
index adef212..dac4d66 100644
--- a/arch/arm/boot/dts/uniphier-pro4-sanji.dts
+++ b/arch/arm/boot/dts/uniphier-pro4-sanji.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier Pro4 Sanji Board
- *
- * Copyright (C) 2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier Pro4 Sanji Board
+//
+// Copyright (C) 2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-pro4.dtsi"
@@ -72,3 +70,14 @@
 &usb3 {
 	status = "okay";
 };
+
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@1 {
+		reg = <1>;
+	};
+};
diff --git a/arch/arm/boot/dts/uniphier-pro4.dtsi b/arch/arm/boot/dts/uniphier-pro4.dtsi
index 1a29a86..844124b 100644
--- a/arch/arm/boot/dts/uniphier-pro4.dtsi
+++ b/arch/arm/boot/dts/uniphier-pro4.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier Pro4 SoC
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier Pro4 SoC
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 #include <dt-bindings/gpio/uniphier-gpio.h>
 
@@ -366,6 +364,24 @@
 			};
 		};
 
+		eth: ethernet@65000000 {
+			compatible = "socionext,uniphier-pro4-ave4";
+			status = "disabled";
+			reg = <0x65000000 0x8500>;
+			interrupts = <0 66 4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ether_rgmii>;
+			clocks = <&sys_clk 6>;
+			resets = <&sys_rst 6>;
+			phy-mode = "rgmii";
+			local-mac-address = [00 00 00 00 00 00];
+
+			mdio: mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
 		nand: nand@68000000 {
 			compatible = "socionext,uniphier-denali-nand-v5a";
 			status = "disabled";
diff --git a/arch/arm/boot/dts/uniphier-pro5.dtsi b/arch/arm/boot/dts/uniphier-pro5.dtsi
index f291dd6..06c2cef 100644
--- a/arch/arm/boot/dts/uniphier-pro5.dtsi
+++ b/arch/arm/boot/dts/uniphier-pro5.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier Pro5 SoC
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier Pro5 SoC
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 / {
 	compatible = "socionext,uniphier-pro5";
diff --git a/arch/arm/boot/dts/uniphier-pxs2-gentil.dts b/arch/arm/boot/dts/uniphier-pxs2-gentil.dts
index 7dfae26..bed26b8 100644
--- a/arch/arm/boot/dts/uniphier-pxs2-gentil.dts
+++ b/arch/arm/boot/dts/uniphier-pxs2-gentil.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier PXs2 Gentil Board
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier PXs2 Gentil Board
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-pxs2.dtsi"
@@ -34,6 +32,12 @@
 		device_type = "memory";
 		reg = <0x80000000 0x80000000>;
 	};
+
+	sound {
+		compatible = "audio-graph-card";
+		label = "UniPhier PXs2";
+		dais = <&i2s_port2>;
+	};
 };
 
 &serial2 {
@@ -50,6 +54,35 @@
 	};
 };
 
+&i2s_aux {
+	dai-format = "i2s";
+	remote-endpoint = <&wm_speaker>;
+};
+
 &i2c2 {
 	status = "okay";
+
+	wm8960@1a {
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+		#sound-dai-cells = <0>;
+
+		port@0 {
+			wm_speaker: endpoint {
+				dai-format = "i2s";
+				remote-endpoint = <&i2s_aux>;
+			};
+		};
+	};
+};
+
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@1 {
+		reg = <1>;
+	};
 };
diff --git a/arch/arm/boot/dts/uniphier-pxs2-vodka.dts b/arch/arm/boot/dts/uniphier-pxs2-vodka.dts
index 0cf6154..b13d2d1 100644
--- a/arch/arm/boot/dts/uniphier-pxs2-vodka.dts
+++ b/arch/arm/boot/dts/uniphier-pxs2-vodka.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier PXs2 Vodka Board
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier PXs2 Vodka Board
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-pxs2.dtsi"
@@ -32,12 +30,60 @@
 		device_type = "memory";
 		reg = <0x80000000 0x80000000>;
 	};
+
+	sound {
+		compatible = "audio-graph-card";
+		label = "UniPhier PXs2";
+		dais = <&spdif_port0
+			&comp_spdif_port0>;
+	};
+
+	spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+
+		port@0 {
+			spdif_tx: endpoint {
+				remote-endpoint = <&spdif_hiecout1>;
+			};
+		};
+	};
+
+	comp-spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+
+		port@0 {
+			comp_spdif_tx: endpoint {
+				remote-endpoint = <&comp_spdif_hiecout1>;
+			};
+		};
+	};
 };
 
 &serial2 {
 	status = "okay";
 };
 
+&spdif_hiecout1 {
+	remote-endpoint = <&spdif_tx>;
+};
+
+&comp_spdif_hiecout1 {
+	remote-endpoint = <&comp_spdif_tx>;
+};
+
 &i2c0 {
 	status = "okay";
 };
+
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@1 {
+		reg = <1>;
+	};
+};
diff --git a/arch/arm/boot/dts/uniphier-pxs2.dtsi b/arch/arm/boot/dts/uniphier-pxs2.dtsi
index c083468..debcbd1 100644
--- a/arch/arm/boot/dts/uniphier-pxs2.dtsi
+++ b/arch/arm/boot/dts/uniphier-pxs2.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier PXs2 SoC
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier PXs2 SoC
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 #include <dt-bindings/gpio/uniphier-gpio.h>
 #include <dt-bindings/thermal/thermal.h>
@@ -227,6 +225,61 @@
 						     <21 217 3>;
 		};
 
+		audio@56000000 {
+			compatible = "socionext,uniphier-pxs2-aio";
+			reg = <0x56000000 0x80000>;
+			interrupts = <0 144 4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ain1>,
+				    <&pinctrl_ain2>,
+				    <&pinctrl_ainiec1>,
+				    <&pinctrl_aout2>,
+				    <&pinctrl_aout3>,
+				    <&pinctrl_aoutiec1>,
+				    <&pinctrl_aoutiec2>;
+			clock-names = "aio";
+			clocks = <&sys_clk 40>;
+			reset-names = "aio";
+			resets = <&sys_rst 40>;
+			#sound-dai-cells = <1>;
+			socionext,syscon = <&soc_glue>;
+
+			i2s_port0: port@0 {
+				i2s_hdmi: endpoint {
+				};
+			};
+
+			i2s_port1: port@1 {
+				i2s_line: endpoint {
+				};
+			};
+
+			i2s_port2: port@2 {
+				i2s_aux: endpoint {
+				};
+			};
+
+			spdif_port0: port@3 {
+				spdif_hiecout1: endpoint {
+				};
+			};
+
+			spdif_port1: port@4 {
+				spdif_iecout1: endpoint {
+				};
+			};
+
+			comp_spdif_port0: port@5 {
+				comp_spdif_hiecout1: endpoint {
+				};
+			};
+
+			comp_spdif_port1: port@6 {
+				comp_spdif_iecout1: endpoint {
+				};
+			};
+		};
+
 		i2c0: i2c@58780000 {
 			compatible = "socionext,uniphier-fi2c";
 			status = "disabled";
@@ -366,7 +419,7 @@
 			};
 		};
 
-		soc-glue@5f800000 {
+		soc_glue: soc-glue@5f800000 {
 			compatible = "socionext,uniphier-pxs2-soc-glue",
 				     "simple-mfd", "syscon";
 			reg = <0x5f800000 0x2000>;
@@ -446,6 +499,24 @@
 			};
 		};
 
+		eth: ethernet@65000000 {
+			compatible = "socionext,uniphier-pxs2-ave4";
+			status = "disabled";
+			reg = <0x65000000 0x8500>;
+			interrupts = <0 66 4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ether_rgmii>;
+			clocks = <&sys_clk 6>;
+			resets = <&sys_rst 6>;
+			phy-mode = "rgmii";
+			local-mac-address = [00 00 00 00 00 00];
+
+			mdio: mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
 		nand: nand@68000000 {
 			compatible = "socionext,uniphier-denali-nand-v5b";
 			status = "disabled";
diff --git a/arch/arm/boot/dts/uniphier-ref-daughter.dtsi b/arch/arm/boot/dts/uniphier-ref-daughter.dtsi
index 7a1c29b..04e60c2 100644
--- a/arch/arm/boot/dts/uniphier-ref-daughter.dtsi
+++ b/arch/arm/boot/dts/uniphier-ref-daughter.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier Reference Daughter Board
- *
- * Copyright (C) 2015-2017 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier Reference Daughter Board
+//
+// Copyright (C) 2015-2017 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 &i2c0 {
 	eeprom@50 {
diff --git a/arch/arm/boot/dts/uniphier-sld8-ref.dts b/arch/arm/boot/dts/uniphier-sld8-ref.dts
index e052ea3..fe386fa 100644
--- a/arch/arm/boot/dts/uniphier-sld8-ref.dts
+++ b/arch/arm/boot/dts/uniphier-sld8-ref.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier sLD8 Reference Board
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier sLD8 Reference Board
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-sld8.dtsi"
diff --git a/arch/arm/boot/dts/uniphier-sld8.dtsi b/arch/arm/boot/dts/uniphier-sld8.dtsi
index bc8c240..e9b9b4f 100644
--- a/arch/arm/boot/dts/uniphier-sld8.dtsi
+++ b/arch/arm/boot/dts/uniphier-sld8.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier sLD8 SoC
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier sLD8 SoC
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 #include <dt-bindings/gpio/uniphier-gpio.h>
 
diff --git a/arch/arm/boot/dts/uniphier-support-card.dtsi b/arch/arm/boot/dts/uniphier-support-card.dtsi
index e4e7e1b..bf441c2 100644
--- a/arch/arm/boot/dts/uniphier-support-card.dtsi
+++ b/arch/arm/boot/dts/uniphier-support-card.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier Support Card (Expansion Board)
- *
- * Copyright (C) 2015-2017 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier Support Card (Expansion Board)
+//
+// Copyright (C) 2015-2017 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 &system_bus {
 	status = "okay";
diff --git a/arch/arm/boot/dts/versatile-ab-ib2.dts b/arch/arm/boot/dts/versatile-ab-ib2.dts
new file mode 100644
index 0000000..5890cb9
--- /dev/null
+++ b/arch/arm/boot/dts/versatile-ab-ib2.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Versatile AB with the IB2 expansion board mounted.
+ * This works as a superset of the Versatile AB.
+ */
+
+#include "versatile-ab.dts"
+
+/ {
+	model = "ARM Versatile AB + IB2 board";
+
+	/* Special IB2 control register */
+	ib2_syscon@27000000 {
+		compatible = "arm,versatile-ib2-syscon", "syscon", "simple-mfd";
+		reg = <0x27000000 0x4>;
+
+		led@00.4 {
+			compatible = "register-bit-led";
+			offset = <0x00>;
+			mask = <0x10>;
+			label = "versatile-ib2:0";
+			linux,default-trigger = "heartbeat";
+			default-state = "on";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
index 4a51612..5f61d36 100644
--- a/arch/arm/boot/dts/versatile-ab.dts
+++ b/arch/arm/boot/dts/versatile-ab.dts
@@ -30,6 +30,43 @@
 		clock-frequency = <24000000>;
 	};
 
+	bridge {
+		compatible = "ti,ths8134b", "ti,ths8134";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				vga_bridge_in: endpoint {
+					remote-endpoint = <&clcd_pads_vga_dac>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				vga_bridge_out: endpoint {
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	vga {
+		compatible = "vga-connector";
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_bridge_out>;
+			};
+		};
+	};
+
 	core-module@10000000 {
 		compatible = "arm,core-module-versatile", "syscon", "simple-mfd";
 		reg = <0x10000000 0x200>;
@@ -230,7 +267,39 @@
 			reg = <0x10120000 0x1000>;
 			interrupts = <16>;
 			clocks = <&osc1>, <&pclk>;
-			clock-names = "clcd", "apb_pclk";
+			clock-names = "clcdclk", "apb_pclk";
+			/* 800x600 16bpp @ 36MHz works fine */
+			max-memory-bandwidth = <54000000>;
+
+			/*
+			 * This port is routed through a PLD (Programmable
+			 * Logic Device) that routes the output from the CLCD
+			 * (after transformations) to the VGA DAC and also an
+			 * external panel connector. The PLD is essential for
+			 * supporting RGB565/BGR565.
+			 *
+			 * The signals from the port thus reaches two endpoints.
+			 * The PLD is managed through a few special bits in the
+			 * FPGA "sysreg".
+			 *
+			 * This arrangement can be clearly seen in
+			 * ARM DUI 0225D, page 3-41, figure 3-19.
+			 */
+			port@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				clcd_pads_panel: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&panel_in>;
+					arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+				};
+				clcd_pads_vga_dac: endpoint@1 {
+					reg = <1>;
+					remote-endpoint = <&vga_bridge_in>;
+					arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+				};
+			};
 		};
 
 		sctl@101e0000 {
@@ -319,8 +388,18 @@
 			ranges = <0 0x10000000 0x10000>;
 
 			sysreg@0 {
-				compatible = "arm,versatile-sysreg", "syscon";
+				compatible = "arm,versatile-sysreg", "syscon", "simple-mfd";
 				reg = <0x00000 0x1000>;
+
+				panel: display@0 {
+					compatible = "arm,versatile-tft-panel";
+
+					port {
+						panel_in: endpoint {
+							remote-endpoint = <&clcd_pads_panel>;
+						};
+					};
+				};
 			};
 
 			aaci@4000 {
diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi
index 515c4d2f..2e7e3ce 100644
--- a/arch/arm/boot/dts/vf500-colibri.dtsi
+++ b/arch/arm/boot/dts/vf500-colibri.dtsi
@@ -46,7 +46,7 @@
 	model = "Toradex Colibri VF50 COM";
 	compatible = "toradex,vf610-colibri_vf50", "fsl,vf500";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x8000000>;
 	};
 
diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi
index 348bcd3..bbff011 100644
--- a/arch/arm/boot/dts/vf500.dtsi
+++ b/arch/arm/boot/dts/vf500.dtsi
@@ -39,11 +39,16 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "skeleton.dtsi"
 #include "vfxxx.dtsi"
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	chosen { };
+	aliases { };
+	memory { device_type = "memory"; };
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/arch/arm/boot/dts/vf610-colibri.dtsi b/arch/arm/boot/dts/vf610-colibri.dtsi
index 395812c..aeaf99f 100644
--- a/arch/arm/boot/dts/vf610-colibri.dtsi
+++ b/arch/arm/boot/dts/vf610-colibri.dtsi
@@ -46,7 +46,7 @@
 	model = "Toradex Colibri VF61 COM";
 	compatible = "toradex,vf610-colibri_vf61", "fsl,vf610";
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x10000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/vf610-cosmic.dts b/arch/arm/boot/dts/vf610-cosmic.dts
index 5447f25..a3014e8 100644
--- a/arch/arm/boot/dts/vf610-cosmic.dts
+++ b/arch/arm/boot/dts/vf610-cosmic.dts
@@ -19,7 +19,7 @@
 		bootargs = "console=ttyLP1,115200";
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x10000000>;
 	};
 
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index 6f787e67..6be7a82 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -50,7 +50,7 @@
 		bootargs = "console=ttyLP1,115200";
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x8000000>;
 	};
 
diff --git a/arch/arm/boot/dts/vf610-zii-dev.dtsi b/arch/arm/boot/dts/vf610-zii-dev.dtsi
index aadd36d..4890b8a 100644
--- a/arch/arm/boot/dts/vf610-zii-dev.dtsi
+++ b/arch/arm/boot/dts/vf610-zii-dev.dtsi
@@ -49,7 +49,7 @@
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory {
+	memory@80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 
diff --git a/arch/arm/boot/dts/vf610m4-colibri.dts b/arch/arm/boot/dts/vf610m4-colibri.dts
index 7198e8c..41ec66a 100644
--- a/arch/arm/boot/dts/vf610m4-colibri.dts
+++ b/arch/arm/boot/dts/vf610m4-colibri.dts
@@ -51,10 +51,10 @@
 
 	chosen {
 		bootargs = "console=ttyLP2,115200 clk_ignore_unused init=/linuxrc rw";
-		linux,stdout-path = "&uart2";
+		stdout-path = "&uart2";
 	};
 
-	memory {
+	memory@8c000000 {
 		reg = <0x8c000000 0x3000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/vf610m4.dtsi b/arch/arm/boot/dts/vf610m4.dtsi
index 1474bd3..8293276 100644
--- a/arch/arm/boot/dts/vf610m4.dtsi
+++ b/arch/arm/boot/dts/vf610m4.dtsi
@@ -42,10 +42,17 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "skeleton.dtsi"
 #include "armv7-m.dtsi"
 #include "vfxxx.dtsi"
 
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	chosen { };
+	aliases { };
+	memory { device_type = "memory"; };
+};
+
 &mscm_ir {
 	interrupt-parent = <&nvic>;
 };
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index 0f79fe1..e22507e 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- *  Copyright (C) 2011 - 2014 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.
+ * Copyright (C) 2011 - 2014 Xilinx
  */
 
 / {
diff --git a/arch/arm/boot/dts/zynq-cc108.dts b/arch/arm/boot/dts/zynq-cc108.dts
new file mode 100644
index 0000000..1a0f631
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-cc108.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Xilinx CC108 board DTS
+ *
+ * (C) Copyright 2007-2018 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+	compatible = "xlnx,zynq-cc108", "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+
+	aliases {
+		ethernet0 = &gem0;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		bootargs = "";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x20000000>;
+	};
+
+	usb_phy0: phy0 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+	};
+
+	usb_phy1: phy1 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+	};
+};
+
+&gem0 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy>;
+
+	ethernet_phy: ethernet-phy@1 {
+		reg = <1>;
+		device_type = "ethernet-phy";
+	};
+};
+
+&sdhci1 {
+	status = "okay";
+	broken-cd ;
+	wp-inverted ;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "host";
+	usb-phy = <&usb_phy0>;
+};
+
+&usb1 {
+	status = "okay";
+	dr_mode = "host";
+	usb-phy = <&usb_phy1>;
+};
diff --git a/arch/arm/boot/dts/zynq-microzed.dts b/arch/arm/boot/dts/zynq-microzed.dts
index b9376a4..aa4a0b6 100644
--- a/arch/arm/boot/dts/zynq-microzed.dts
+++ b/arch/arm/boot/dts/zynq-microzed.dts
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2011 - 2014 Xilinx
  * Copyright (C) 2016 Jagan Teki <jteki@openedev.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.
  */
 /dts-v1/;
 /include/ "zynq-7000.dtsi"
@@ -23,7 +15,7 @@
 		serial0 = &uart1;
 	};
 
-	memory {
+	memory@0 {
 		device_type = "memory";
 		reg = <0x0 0x40000000>;
 	};
diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts
index 0144acf..c05f4b6 100644
--- a/arch/arm/boot/dts/zynq-parallella.dts
+++ b/arch/arm/boot/dts/zynq-parallella.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2014 SUSE LINUX Products GmbH
  *
@@ -6,15 +7,6 @@
  *  Copyright (C) 2011 Xilinx
  *  Copyright (C) 2012 National Instruments Corp.
  *  Copyright (C) 2013 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/;
 /include/ "zynq-7000.dtsi"
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
index 70a5de7..f2330b0 100644
--- a/arch/arm/boot/dts/zynq-zc702.dts
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  Copyright (C) 2011 - 2014 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"
@@ -112,7 +104,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c0_default>;
 
-	i2cswitch@74 {
+	i2c-mux@74 {
 		compatible = "nxp,pca9548";
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts
index cdc326e..3ad1260 100644
--- a/arch/arm/boot/dts/zynq-zc706.dts
+++ b/arch/arm/boot/dts/zynq-zc706.dts
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  Copyright (C) 2011 - 2014 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"
@@ -68,7 +60,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c0_default>;
 
-	i2cswitch@74 {
+	i2c-mux@74 {
 		compatible = "nxp,pca9548";
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/arch/arm/boot/dts/zynq-zc770-xm010.dts b/arch/arm/boot/dts/zynq-zc770-xm010.dts
new file mode 100644
index 0000000..6884f1a
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zc770-xm010.dts
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Xilinx ZC770 XM010 board DTS
+ *
+ * Copyright (C) 2013-2018 Xilinx, Inc.
+ */
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+	compatible = "xlnx,zynq-zc770-xm010", "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+
+	aliases {
+		ethernet0 = &gem0;
+		i2c0 = &i2c0;
+		serial0 = &uart1;
+		spi1 = &spi1;
+	};
+
+	chosen {
+		bootargs = "";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+
+	usb_phy0: phy0 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+	};
+};
+
+&can0 {
+	status = "okay";
+};
+
+&gem0 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy>;
+
+	ethernet_phy: ethernet-phy@7 {
+		reg = <7>;
+		device_type = "ethernet-phy";
+	};
+};
+
+&i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	eeprom: eeprom@52 {
+		compatible = "atmel,24c02";
+		reg = <0x52>;
+	};
+
+};
+
+&sdhci0 {
+	status = "okay";
+};
+
+&spi1 {
+	status = "okay";
+	num-cs = <4>;
+	is-decoded-cs = <0>;
+	flash@0 {
+		compatible = "sst25wf080", "jedec,spi-nor";
+		reg = <1>;
+		spi-max-frequency = <1000000>;
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition@0 {
+				label = "data";
+				reg = <0x0 0x100000>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "host";
+	usb-phy = <&usb_phy0>;
+};
diff --git a/arch/arm/boot/dts/zynq-zc770-xm011.dts b/arch/arm/boot/dts/zynq-zc770-xm011.dts
new file mode 100644
index 0000000..b78883c
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zc770-xm011.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Xilinx ZC770 XM013 board DTS
+ *
+ * Copyright (C) 2013-2018 Xilinx, Inc.
+ */
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+	compatible = "xlnx,zynq-zc770-xm011", "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+
+	aliases {
+		i2c0 = &i2c1;
+		serial0 = &uart1;
+		spi0 = &spi0;
+	};
+
+	chosen {
+		bootargs = "";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+
+	usb_phy1: phy1 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+	};
+};
+
+&can0 {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	eeprom: eeprom@52 {
+		compatible = "atmel,24c02";
+		reg = <0x52>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+	num-cs = <4>;
+	is-decoded-cs = <0>;
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+	dr_mode = "host";
+	usb-phy = <&usb_phy1>;
+};
diff --git a/arch/arm/boot/dts/zynq-zc770-xm012.dts b/arch/arm/boot/dts/zynq-zc770-xm012.dts
new file mode 100644
index 0000000..c3169d6
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zc770-xm012.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Xilinx ZC770 XM012 board DTS
+ *
+ * Copyright (C) 2013-2018 Xilinx, Inc.
+ */
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+	compatible = "xlnx,zynq-zc770-xm012", "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		serial0 = &uart1;
+		spi0 = &spi1;
+	};
+
+	chosen {
+		bootargs = "";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	eeprom0: eeprom@52 {
+		compatible = "atmel,24c02";
+		reg = <0x52>;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	eeprom1: eeprom@52 {
+		compatible = "atmel,24c02";
+		reg = <0x52>;
+	};
+};
+
+&spi1 {
+	status = "okay";
+	num-cs = <4>;
+	is-decoded-cs = <0>;
+};
+
+&uart1 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/zynq-zc770-xm013.dts b/arch/arm/boot/dts/zynq-zc770-xm013.dts
new file mode 100644
index 0000000..8bb6685
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zc770-xm013.dts
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Xilinx ZC770 XM013 board DTS
+ *
+ * Copyright (C) 2013 Xilinx, Inc.
+ */
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+	compatible = "xlnx,zynq-zc770-xm013", "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+
+	aliases {
+		ethernet0 = &gem1;
+		i2c0 = &i2c1;
+		serial0 = &uart0;
+		spi1 = &spi0;
+	};
+
+	chosen {
+		bootargs = "";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&gem1 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy>;
+
+	ethernet_phy: ethernet-phy@7 {
+		reg = <7>;
+		device_type = "ethernet-phy";
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	si570: clock-generator@55 {
+		#clock-cells = <0>;
+		compatible = "silabs,si570";
+		temperature-stability = <50>;
+		reg = <0x55>;
+		factory-fout = <156250000>;
+		clock-frequency = <148500000>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+	num-cs = <4>;
+	is-decoded-cs = <0>;
+	eeprom: eeprom@0 {
+		at25,byte-len = <8192>;
+		at25,addr-mode = <2>;
+		at25,page-size = <32>;
+
+		compatible = "atmel,at25";
+		reg = <2>;
+		spi-max-frequency = <1000000>;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts
index 5e44dc1..53c6883 100644
--- a/arch/arm/boot/dts/zynq-zed.dts
+++ b/arch/arm/boot/dts/zynq-zed.dts
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  Copyright (C) 2011 - 2014 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"
diff --git a/arch/arm/boot/dts/zynq-zybo-z7.dts b/arch/arm/boot/dts/zynq-zybo-z7.dts
new file mode 100644
index 0000000..1e713dc
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zybo-z7.dts
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+	model = "Zynq ZYBO Z7 Development Board";
+	compatible = "digilent,zynq-zybo-z7", "xlnx,zynq-7000";
+
+	aliases {
+		ethernet0 = &gem0;
+		serial0 = &uart1;
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x20000000>;
+	};
+
+	chosen {
+		bootargs = "";
+		stdout-path = "serial0:115200n8";
+	};
+
+	usb_phy0: phy0 {
+		#phy-cells = <0>;
+		compatible = "usb-nop-xceiv";
+		reset-gpios = <&gpio0 46 1>;
+	};
+};
+
+&clkc {
+	ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy>;
+
+	ethernet_phy: ethernet-phy@0 {
+		reg = <0>;
+		device_type = "ethernet-phy";
+	};
+};
+
+&sdhci0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "host";
+	usb-phy = <&usb_phy0>;
+};
diff --git a/arch/arm/boot/dts/zynq-zybo.dts b/arch/arm/boot/dts/zynq-zybo.dts
index e40cafc..a6c00e7 100644
--- a/arch/arm/boot/dts/zynq-zybo.dts
+++ b/arch/arm/boot/dts/zynq-zybo.dts
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  Copyright (C) 2011 - 2014 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"
diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index 43dab48..8682b15 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -49,6 +49,9 @@
 CONFIG_IP_PNP_DHCP=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
+CONFIG_BT=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCM=y
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
 CONFIG_DEVTMPFS=y
@@ -74,6 +77,7 @@
 CONFIG_SERIAL_8250_BCM2835AUX=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
 CONFIG_TTY_PRINTK=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_BCM2835=y
diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig
index c0418e03..5e349c6 100644
--- a/arch/arm/configs/cm_x300_defconfig
+++ b/arch/arm/configs/cm_x300_defconfig
@@ -49,7 +49,7 @@
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 026154c..c302a04 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -126,9 +126,10 @@
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
+CONFIG_SYSCON_REBOOT_MODE=m
 CONFIG_BATTERY_LEGO_EV3=m
 CONFIG_WATCHDOG=y
-CONFIG_DAVINCI_WATCHDOG=m
+CONFIG_DAVINCI_WATCHDOG=y
 CONFIG_MFD_DM355EVM_MSP=y
 CONFIG_TPS6507X=y
 CONFIG_REGULATOR=y
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index ca0f13ca..054591d 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -1,7 +1,6 @@
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -78,7 +77,6 @@
 CONFIG_SMC911X=y
 CONFIG_SMSC911X=y
 CONFIG_SMSC_PHY=y
-# CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_IMX=y
@@ -105,8 +103,8 @@
 CONFIG_SENSORS_MC13783_ADC=m
 CONFIG_WATCHDOG=y
 CONFIG_IMX2_WDT=y
-CONFIG_MFD_MX25_TSADC=y
 CONFIG_MFD_MC13XXX_SPI=y
+CONFIG_MFD_MX25_TSADC=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
@@ -116,10 +114,8 @@
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_SOC_CAMERA=y
-CONFIG_VIDEO_MX2=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_CODA=y
-CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_FB=y
 CONFIG_FB_IMX=y
 CONFIG_LCD_L4F00242T03=y
@@ -134,8 +130,9 @@
 CONFIG_SND_SOC_MX27VIS_AIC32X4=y
 CONFIG_SND_SOC_PHYCORE_AC97=y
 CONFIG_SND_SOC_EUKREA_TLV320=y
-CONFIG_SND_SOC_IMX_SGTL5000=y
 CONFIG_SND_SOC_IMX_MC13783=y
+CONFIG_SND_SOC_FSL_ASOC_CARD=y
+CONFIG_SND_SOC_SGTL5000=y
 CONFIG_USB_HID=m
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 4cb9829..3a30843 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -48,9 +48,7 @@
 CONFIG_SMP=y
 CONFIG_ARM_PSCI=y
 CONFIG_PREEMPT_VOLUNTARY=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
-CONFIG_CMA=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
 CONFIG_KEXEC=y
@@ -60,6 +58,7 @@
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPUFREQ_DT=y
 CONFIG_ARM_IMX6Q_CPUFREQ=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
@@ -81,7 +80,6 @@
 CONFIG_CAN_FLEXCAN=y
 CONFIG_BT=y
 CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_SERDEV=y
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_LL=y
 CONFIG_CFG80211=y
@@ -92,7 +90,6 @@
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
-CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_IMX_WEIM=y
 CONFIG_CONNECTOR=y
@@ -170,9 +167,9 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=y
 CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_MAX11801=y
 CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
 CONFIG_TOUCHSCREEN_EDT_FT5X06=y
-CONFIG_TOUCHSCREEN_MAX11801=y
 CONFIG_TOUCHSCREEN_MC13783=y
 CONFIG_TOUCHSCREEN_TSC2004=y
 CONFIG_TOUCHSCREEN_TSC2007=y
@@ -181,7 +178,6 @@
 CONFIG_TOUCHSCREEN_COLIBRI_VF50=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MMA8450=y
-CONFIG_HID_MULTITOUCH=y
 CONFIG_SERIO_SERPORT=m
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_IMX=y
@@ -189,7 +185,6 @@
 CONFIG_SERIAL_FSL_LPUART=y
 CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
 CONFIG_SERIAL_DEV_BUS=y
-CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
@@ -209,19 +204,19 @@
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_74X164=y
 CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_IMX=y
 CONFIG_POWER_RESET_SYSCON=y
 CONFIG_POWER_RESET_SYSCON_POWEROFF=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_SENSORS_GPIO_FAN=y
 CONFIG_SENSORS_IIO_HWMON=y
-CONFIG_THERMAL=y
 CONFIG_THERMAL_WRITABLE_TRIPS=y
 CONFIG_CPU_THERMAL=y
 CONFIG_IMX_THERMAL=y
 CONFIG_WATCHDOG=y
+CONFIG_DA9062_WATCHDOG=y
 CONFIG_IMX2_WDT=y
 CONFIG_MFD_DA9052_I2C=y
+CONFIG_MFD_DA9062=y
 CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_MFD_MC13XXX_I2C=y
 CONFIG_MFD_STMPE=y
@@ -229,17 +224,18 @@
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ANATOP=y
 CONFIG_REGULATOR_DA9052=y
+CONFIG_REGULATOR_DA9062=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_REGULATOR_PFUZE100=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_RC_CORE=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_RC_DEVICES=y
 CONFIG_IR_GPIO_CIR=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
@@ -250,7 +246,6 @@
 # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_OV5640=m
-CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_IMX_IPUV3_CORE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_LVDS=y
@@ -285,10 +280,13 @@
 CONFIG_SND_SOC_IMX_SPDIF=y
 CONFIG_SND_SOC_IMX_MC13783=y
 CONFIG_SND_SOC_FSL_ASOC_CARD=y
+CONFIG_SND_SOC_AC97_CODEC=y
 CONFIG_SND_SOC_CS42XX8_I2C=y
 CONFIG_SND_SOC_TLV320AIC3X=y
 CONFIG_SND_SOC_WM8960=y
+CONFIG_SND_SOC_WM8962=y
 CONFIG_SND_SIMPLE_CARD=y
+CONFIG_HID_MULTITOUCH=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MXC=y
@@ -354,6 +352,7 @@
 CONFIG_RTC_DRV_PCF8523=y
 CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_M41T80=y
+CONFIG_RTC_DRV_DA9063=y
 CONFIG_RTC_DRV_MC13XXX=y
 CONFIG_RTC_DRV_MXC=y
 CONFIG_RTC_DRV_MXC_V2=y
@@ -369,11 +368,14 @@
 CONFIG_IIO=y
 CONFIG_IMX7D_ADC=y
 CONFIG_VF610_ADC=y
+CONFIG_MAG3110=y
 CONFIG_MPL3115=y
 CONFIG_PWM=y
 CONFIG_PWM_FSL_FTM=y
 CONFIG_PWM_IMX=y
 CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
 CONFIG_MUX_MMIO=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index da73876..e6b3c96 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -80,6 +80,7 @@
 CONFIG_MACH_SPEAR1310=y
 CONFIG_MACH_SPEAR1340=y
 CONFIG_ARCH_STI=y
+CONFIG_ARCH_STM32=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_EXYNOS5420_MCPM=y
 CONFIG_ARCH_RENESAS=y
@@ -174,6 +175,7 @@
 CONFIG_CAN_BCM=y
 CONFIG_CAN_DEV=y
 CONFIG_CAN_AT91=m
+CONFIG_CAN_FLEXCAN=m
 CONFIG_CAN_RCAR=m
 CONFIG_CAN_XILINXCAN=y
 CONFIG_CAN_MCP251X=y
@@ -208,6 +210,7 @@
 CONFIG_MTD_NAND_OMAP2=y
 CONFIG_MTD_NAND_OMAP_BCH=y
 CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_NAND_BRCMNAND=y
 CONFIG_MTD_NAND_VF610_NFC=y
 CONFIG_MTD_NAND_DAVINCI=y
@@ -307,11 +310,15 @@
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MAX77693_HAPTIC=m
 CONFIG_INPUT_MAX8997_HAPTIC=m
+CONFIG_INPUT_CPCAP_PWRBUTTON=m
 CONFIG_INPUT_AXP20X_PEK=m
 CONFIG_INPUT_ADXL34X=m
 CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_BCM2835AUX=y
 CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_EM=y
 CONFIG_SERIAL_8250_MT6577=y
@@ -351,6 +358,8 @@
 CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y
 CONFIG_SERIAL_ST_ASC=y
 CONFIG_SERIAL_ST_ASC_CONSOLE=y
+CONFIG_SERIAL_STM32=y
+CONFIG_SERIAL_STM32_CONSOLE=y
 CONFIG_HVC_DRIVER=y
 CONFIG_VIRTIO_CONSOLE=y
 CONFIG_I2C_CHARDEV=y
@@ -368,7 +377,7 @@
 CONFIG_I2C_EMEV2=m
 CONFIG_I2C_GPIO=m
 CONFIG_I2C_EXYNOS5=y
-CONFIG_I2C_IMX=m
+CONFIG_I2C_IMX=y
 CONFIG_I2C_MV64XXX=y
 CONFIG_I2C_RIIC=y
 CONFIG_I2C_RK3X=y
@@ -438,9 +447,11 @@
 CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
 CONFIG_BATTERY_ACT8945A=y
+CONFIG_BATTERY_CPCAP=m
 CONFIG_BATTERY_SBS=y
 CONFIG_BATTERY_MAX17040=m
 CONFIG_BATTERY_MAX17042=m
+CONFIG_CHARGER_CPCAP=m
 CONFIG_CHARGER_MAX14577=m
 CONFIG_CHARGER_MAX77693=m
 CONFIG_CHARGER_MAX8997=m
@@ -462,7 +473,9 @@
 CONFIG_SENSORS_PWM_FAN=m
 CONFIG_SENSORS_INA2XX=m
 CONFIG_CPU_THERMAL=y
+CONFIG_BCM2835_THERMAL=m
 CONFIG_BRCMSTB_THERMAL=m
+CONFIG_IMX_THERMAL=y
 CONFIG_ROCKCHIP_THERMAL=y
 CONFIG_RCAR_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
@@ -476,6 +489,7 @@
 CONFIG_AT91SAM9X_WATCHDOG=y
 CONFIG_SAMA5D4_WATCHDOG=y
 CONFIG_ORION_WATCHDOG=y
+CONFIG_RN5T618_WATCHDOG=y
 CONFIG_ST_LPC_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
 CONFIG_IMX2_WDT=y
@@ -508,9 +522,11 @@
 CONFIG_MFD_MAX8997=y
 CONFIG_MFD_MAX8998=y
 CONFIG_MFD_RK808=y
+CONFIG_MFD_CPCAP=y
 CONFIG_MFD_PM8XXX=y
 CONFIG_MFD_QCOM_RPM=y
 CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_RN5T618=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_PALMAS=y
@@ -527,6 +543,7 @@
 CONFIG_REGULATOR_AS3722=y
 CONFIG_REGULATOR_AXP20X=y
 CONFIG_REGULATOR_BCM590XX=y
+CONFIG_REGULATOR_CPCAP=y
 CONFIG_REGULATOR_DA9210=y
 CONFIG_REGULATOR_FAN53555=y
 CONFIG_REGULATOR_RK808=y
@@ -547,6 +564,7 @@
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_QCOM_RPM=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=y
+CONFIG_REGULATOR_RN5T618=y
 CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_S5M8767=y
 CONFIG_REGULATOR_TI_ABB=y
@@ -617,6 +635,7 @@
 CONFIG_DRM_RCAR_DU=m
 CONFIG_DRM_RCAR_LVDS=y
 CONFIG_DRM_SUN4I=m
+CONFIG_DRM_FSL_DCU=m
 CONFIG_DRM_TEGRA=y
 CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
 CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
@@ -624,6 +643,8 @@
 CONFIG_DRM_SII9234=m
 CONFIG_DRM_STI=m
 CONFIG_DRM_VC4=y
+CONFIG_DRM_ETNAVIV=m
+CONFIG_DRM_MXSFB=m
 CONFIG_FB_ARMCLCD=y
 CONFIG_FB_EFI=y
 CONFIG_FB_WM8505=y
@@ -674,6 +695,7 @@
 CONFIG_SND_SOC_TEGRA_WM9712=m
 CONFIG_SND_SOC_TEGRA_TRIMSLICE=m
 CONFIG_SND_SOC_TEGRA_ALC5632=m
+CONFIG_SND_SOC_CPCAP=m
 CONFIG_SND_SOC_TEGRA_MAX98090=m
 CONFIG_SND_SOC_AK4642=m
 CONFIG_SND_SOC_SGTL5000=m
@@ -683,6 +705,7 @@
 CONFIG_SND_SOC_STI_SAS=m
 CONFIG_SND_SIMPLE_CARD=m
 CONFIG_USB=y
+CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_MVEBU=y
 CONFIG_USB_XHCI_RCAR=m
@@ -704,6 +727,15 @@
 CONFIG_USB_UAS=m
 CONFIG_USB_MUSB_HDRC=m
 CONFIG_USB_MUSB_SUNXI=m
+CONFIG_USB_MUSB_TUSB6010=m
+CONFIG_USB_MUSB_OMAP2PLUS=m
+CONFIG_USB_MUSB_AM35X=m
+CONFIG_USB_MUSB_DSPS=m
+CONFIG_USB_MUSB_UX500=m
+CONFIG_USB_UX500_DMA=y
+CONFIG_USB_INVENTRA_DMA=y
+CONFIG_USB_TI_CPPI41_DMA=y
+CONFIG_USB_TUSB_OMAP_DMA=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC2=y
 CONFIG_USB_HSIC_USB3503=y
@@ -712,6 +744,9 @@
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_AB8500_USB=y
 CONFIG_KEYSTONE_USB_PHY=y
+CONFIG_NOP_USB_XCEIV=m
+CONFIG_AM335X_PHY_USB=m
+CONFIG_TWL6030_USB=m
 CONFIG_USB_GPIO_VBUS=y
 CONFIG_USB_ISP1301=y
 CONFIG_USB_MSM_OTG=m
@@ -719,6 +754,25 @@
 CONFIG_USB_GADGET=y
 CONFIG_USB_FSL_USB2=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_CONFIGFS_F_UVC=y
+CONFIG_USB_CONFIGFS_F_PRINTER=y
 CONFIG_USB_ETH=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=16
@@ -751,9 +805,11 @@
 CONFIG_MMC_SH_MMCIF=y
 CONFIG_MMC_SUNXI=y
 CONFIG_MMC_BCM2835=y
+CONFIG_MMC_SDHCI_OMAP=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_CLASS_FLASH=m
+CONFIG_LEDS_CPCAP=m
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_PWM=y
 CONFIG_LEDS_MAX77693=m
@@ -804,6 +860,7 @@
 CONFIG_RTC_DRV_SUNXI=y
 CONFIG_RTC_DRV_MV=y
 CONFIG_RTC_DRV_TEGRA=y
+CONFIG_RTC_DRV_CPCAP=m
 CONFIG_DMADEVICES=y
 CONFIG_DW_DMAC=y
 CONFIG_AT_HDMAC=y
@@ -876,6 +933,7 @@
 CONFIG_AT91_ADC=m
 CONFIG_AT91_SAMA5D2_ADC=m
 CONFIG_BERLIN2_ADC=m
+CONFIG_CPCAP_ADC=m
 CONFIG_EXYNOS_ADC=m
 CONFIG_VF610_ADC=m
 CONFIG_XILINX_XADC=y
@@ -901,9 +959,12 @@
 CONFIG_PWM_STI=y
 CONFIG_PWM_BCM2835=y
 CONFIG_PWM_BRCMSTB=m
+CONFIG_PHY_DM816X_USB=m
 CONFIG_OMAP_USB2=y
 CONFIG_TI_PIPE3=y
+CONFIG_TWL4030_USB=m
 CONFIG_PHY_BERLIN_USB=y
+CONFIG_PHY_CPCAP_USB=m
 CONFIG_PHY_BERLIN_SATA=y
 CONFIG_PHY_ROCKCHIP_DP=m
 CONFIG_PHY_ROCKCHIP_USB=y
@@ -917,7 +978,9 @@
 CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_PHY_BRCM_SATA=y
 CONFIG_NVMEM=y
+CONFIG_NVMEM_IMX_OCOTP=y
 CONFIG_NVMEM_SUNXI_SID=y
+CONFIG_NVMEM_VF610_OCOTP=y
 CONFIG_BCM2835_MBOX=y
 CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_EFI_VARS=m
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index bbfb675..a508eb3 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -1,5 +1,4 @@
 CONFIG_SYSVIPC=y
-CONFIG_FHANDLE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_TASKSTATS=y
@@ -62,14 +61,13 @@
 CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
 CONFIG_ENC28J60=y
-CONFIG_SMSC_PHY=y
 CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
 CONFIG_MICREL_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_SMSC_PHY=y
 CONFIG_USB_USBNET=y
 CONFIG_USB_NET_SMSC95XX=y
 # CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
@@ -77,9 +75,7 @@
 CONFIG_TOUCHSCREEN_MXS_LRADC=y
 CONFIG_TOUCHSCREEN_TSC2007=m
 # CONFIG_SERIO is not set
-CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_MXS_AUART=y
@@ -138,11 +134,10 @@
 CONFIG_DMADEVICES=y
 CONFIG_MXS_DMA=y
 CONFIG_IIO=y
-CONFIG_IIO_SYSFS_TRIGGER=y
 CONFIG_MXS_LRADC_ADC=y
+CONFIG_IIO_SYSFS_TRIGGER=y
 CONFIG_PWM=y
 CONFIG_PWM_MXS=y
-CONFIG_NVMEM=y
 CONFIG_NVMEM_MXS_OCOTP=y
 CONFIG_EXT4_FS=y
 # CONFIG_DNOTIFY is not set
@@ -172,8 +167,7 @@
 CONFIG_UNUSED_SYMBOLS=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_TIMER_STATS=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_STRICT_DEVMEM=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 92674f2..6491419 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -50,7 +50,6 @@
 CONFIG_ARM_ERRATA_411920=y
 CONFIG_PCI=y
 CONFIG_PCI_MSI=y
-CONFIG_PCI_DRA7XX=y
 CONFIG_PCI_DRA7XX_EP=y
 CONFIG_PCI_ENDPOINT=y
 CONFIG_PCI_ENDPOINT_CONFIGFS=y
@@ -71,9 +70,10 @@
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 CONFIG_CPUFREQ_DT=m
-CONFIG_ARM_TI_CPUFREQ=y
 # CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
+CONFIG_ARM_TI_CPUFREQ=y
 CONFIG_CPU_IDLE=y
+CONFIG_KERNEL_MODE_NEON=y
 CONFIG_BINFMT_MISC=y
 CONFIG_PM_DEBUG=y
 CONFIG_NET=y
@@ -103,9 +103,11 @@
 CONFIG_BT_HCIBTUSB=m
 CONFIG_BT_HCIBTSDIO=m
 CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_NOKIA=m
 CONFIG_BT_HCIUART_BCSP=y
 CONFIG_BT_HCIUART_LL=y
 CONFIG_BT_HCIUART_3WIRE=y
+CONFIG_BT_HCIUART_BCM=y
 CONFIG_BT_HCIBCM203X=m
 CONFIG_BT_HCIBPA10X=m
 CONFIG_BT_HCIBFUSB=m
@@ -232,7 +234,9 @@
 CONFIG_INPUT_CPCAP_PWRBUTTON=m
 CONFIG_INPUT_TPS65218_PWRBUTTON=m
 CONFIG_INPUT_TWL4030_PWRBUTTON=m
+CONFIG_INPUT_UINPUT=m
 CONFIG_INPUT_PALMAS_PWRBUTTON=m
+CONFIG_INPUT_PWM_VIBRA=m
 CONFIG_SERIO=m
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
@@ -244,9 +248,11 @@
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_8250_DETECT_IRQ=y
 CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_8250_OMAP=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_OMAP=y
 CONFIG_SERIAL_OMAP_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_SPI=y
 CONFIG_SPI_OMAP24XX=y
@@ -291,6 +297,7 @@
 CONFIG_TWL4030_WATCHDOG=m
 CONFIG_MFD_CPCAP=y
 CONFIG_MFD_TI_AM335X_TSCADC=m
+CONFIG_MFD_TI_LMU=m
 CONFIG_MFD_PALMAS=y
 CONFIG_MFD_TPS65217=y
 CONFIG_MFD_TI_LP873X=y
@@ -314,40 +321,47 @@
 CONFIG_REGULATOR_TPS65218=y
 CONFIG_REGULATOR_TPS65910=y
 CONFIG_REGULATOR_TWL4030=y
-CONFIG_MEDIA_SUPPORT=m
-CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_RC_CORE=m
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_LIRC=y
 CONFIG_RC_DEVICES=y
+CONFIG_IR_SPI=m
 CONFIG_IR_RX51=m
+CONFIG_IR_GPIO_TX=m
+CONFIG_IR_PWM_TX=m
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CEC_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_OMAP3=m
+CONFIG_CEC_PLATFORM_DRIVERS=y
 # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_TVP5150=m
+CONFIG_DRM=m
+CONFIG_DRM_OMAP=m
+CONFIG_OMAP5_DSS_HDMI=y
+CONFIG_OMAP2_DSS_SDI=y
+CONFIG_OMAP2_DSS_DSI=y
+CONFIG_DRM_OMAP_ENCODER_OPA362=m
+CONFIG_DRM_OMAP_ENCODER_TFP410=m
+CONFIG_DRM_OMAP_ENCODER_TPD12S015=m
+CONFIG_DRM_OMAP_CONNECTOR_DVI=m
+CONFIG_DRM_OMAP_CONNECTOR_HDMI=m
+CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV=m
+CONFIG_DRM_OMAP_PANEL_DPI=m
+CONFIG_DRM_OMAP_PANEL_DSI_CM=m
+CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM=m
+CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02=m
+CONFIG_DRM_OMAP_PANEL_SHARP_LS037V7DW01=m
+CONFIG_DRM_OMAP_PANEL_TPO_TD028TTEC1=m
+CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1=m
+CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11=m
+CONFIG_DRM_TILCDC=m
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
-CONFIG_FB_OMAP2=m
-CONFIG_FB_OMAP5_DSS_HDMI=y
-CONFIG_FB_OMAP2_DSS_SDI=y
-CONFIG_FB_OMAP2_DSS_DSI=y
-CONFIG_FB_OMAP2_ENCODER_TFP410=m
-CONFIG_FB_OMAP2_ENCODER_TPD12S015=m
-CONFIG_FB_OMAP2_CONNECTOR_DVI=m
-CONFIG_FB_OMAP2_CONNECTOR_HDMI=m
-CONFIG_FB_OMAP2_CONNECTOR_ANALOG_TV=m
-CONFIG_FB_OMAP2_PANEL_DPI=m
-CONFIG_FB_OMAP2_PANEL_DSI_CM=m
-CONFIG_FB_OMAP2_PANEL_SONY_ACX565AKM=m
-CONFIG_FB_OMAP2_PANEL_LGPHILIPS_LB035Q02=m
-CONFIG_FB_OMAP2_PANEL_SHARP_LS037V7DW01=m
-CONFIG_FB_OMAP2_PANEL_TPO_TD028TTEC1=m
-CONFIG_FB_OMAP2_PANEL_TPO_TD043MTEA1=m
-CONFIG_FB_OMAP2_PANEL_NEC_NL8048HL11=m
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_PLATFORM=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
@@ -356,11 +370,11 @@
 CONFIG_BACKLIGHT_PANDORA=m
 CONFIG_BACKLIGHT_GPIO=m
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
 CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 CONFIG_LOGO=y
 CONFIG_SOUND=m
 CONFIG_SND=m
+CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_VERBOSE_PRINTK=y
@@ -374,7 +388,9 @@
 CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
 CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
 CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
+CONFIG_SND_SOC_CPCAP=m
 CONFIG_SND_SIMPLE_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_HID_GENERIC=m
 CONFIG_USB_HIDDEV=y
 CONFIG_USB_KBD=m
@@ -385,7 +401,6 @@
 CONFIG_USB_XHCI_HCD=m
 CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_WDM=m
 CONFIG_USB_ACM=m
 CONFIG_USB_STORAGE=m
 CONFIG_USB_MUSB_HDRC=m
@@ -431,8 +446,11 @@
 CONFIG_USB_G_NOKIA=m
 CONFIG_MMC=y
 CONFIG_SDIO_UART=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_OMAP=y
 CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_SDHCI_OMAP=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=m
 CONFIG_LEDS_CPCAP=m
@@ -459,10 +477,16 @@
 CONFIG_DMA_OMAP=y
 CONFIG_TI_EDMA=y
 CONFIG_OMAP_IOMMU=y
-CONFIG_EXTCON=m
+CONFIG_REMOTEPROC=m
+CONFIG_OMAP_REMOTEPROC=m
+CONFIG_WKUP_M3_RPROC=m
+CONFIG_SOC_TI=y
+CONFIG_AMX3_PM=m
+CONFIG_WKUP_M3_IPC=m
 CONFIG_EXTCON_PALMAS=m
 CONFIG_EXTCON_USB_GPIO=m
 CONFIG_TI_EMIF=m
+CONFIG_TI_EMIF_SRAM=m
 CONFIG_IIO=m
 CONFIG_IIO_SW_DEVICE=m
 CONFIG_IIO_SW_TRIGGER=m
@@ -477,6 +501,7 @@
 CONFIG_PWM_TWL=m
 CONFIG_PWM_TWL_LED=m
 CONFIG_PHY_CPCAP_USB=m
+CONFIG_PHY_MAPPHONE_MDM6600=m
 CONFIG_PHY_DM816X_USB=m
 CONFIG_OMAP_USB2=m
 CONFIG_TI_PIPE3=y
@@ -491,7 +516,6 @@
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_CONFIGFS_FS=y
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_SUMMARY=y
 CONFIG_JFFS2_FS_XATTR=y
@@ -512,11 +536,18 @@
 CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
 CONFIG_PROVE_LOCKING=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_SECURITY=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM_NEON=m
+CONFIG_CRYPTO_SHA256_ARM=m
+CONFIG_CRYPTO_SHA512_ARM=m
+CONFIG_CRYPTO_AES_ARM=m
+CONFIG_CRYPTO_AES_ARM_BS=m
+CONFIG_CRYPTO_GHASH_ARM_CE=m
+CONFIG_CRYPTO_CHACHA20_NEON=m
 CONFIG_CRC_CCITT=y
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=y
@@ -525,13 +556,3 @@
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
-CONFIG_KERNEL_MODE_NEON=y
-CONFIG_ARM_CRYPTO=y
-CONFIG_CRYPTO_SHA1_ARM=m
-CONFIG_CRYPTO_SHA1_ARM_NEON=m
-CONFIG_CRYPTO_SHA256_ARM=m
-CONFIG_CRYPTO_SHA512_ARM=m
-CONFIG_CRYPTO_AES_ARM=m
-CONFIG_CRYPTO_AES_ARM_BS=m
-CONFIG_CRYPTO_CHACHA20_NEON=m
-CONFIG_CRYPTO_GHASH_ARM_CE=m
diff --git a/arch/arm/configs/oxnas_v6_defconfig b/arch/arm/configs/oxnas_v6_defconfig
new file mode 100644
index 0000000..f6ba32c
--- /dev/null
+++ b/arch/arm/configs/oxnas_v6_defconfig
@@ -0,0 +1,93 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_CGROUPS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+CONFIG_STRICT_KERNEL_RWX=y
+CONFIG_STRICT_MODULE_RWX=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_ARCH_MULTI_V6=y
+CONFIG_ARCH_OXNAS=y
+CONFIG_MACH_OX820=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=16
+CONFIG_CMA=y
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_SECCOMP=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_KEXEC=y
+CONFIG_EFI=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=64
+CONFIG_SIMPLE_PM_BUS=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_OXNAS=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_NETDEVICES=y
+CONFIG_STMMAC_ETH=y
+CONFIG_REALTEK_PHY=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_FLASH=m
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_ARM_TIMER_SP804=y
+CONFIG_EXT4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UBIFS_FS=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_PMSG=y
+CONFIG_PSTORE_RAM=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig
index bfea687..3e0de03 100644
--- a/arch/arm/configs/pxa3xx_defconfig
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -32,8 +32,7 @@
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PXA3xx=y
-CONFIG_MTD_NAND_PXA3xx_BUILTIN=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_ONENAND=y
 CONFIG_MTD_ONENAND_VERIFY_WRITE=y
 CONFIG_MTD_ONENAND_GENERIC=y
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
index 837d0c9..5655a1c 100644
--- a/arch/arm/configs/pxa_defconfig
+++ b/arch/arm/configs/pxa_defconfig
@@ -197,7 +197,7 @@
 CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
 CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
 CONFIG_MTD_NAND_SHARPSL=m
-CONFIG_MTD_NAND_PXA3xx=m
+CONFIG_MTD_NAND_MARVELL=m
 CONFIG_MTD_NAND_CM_X270=m
 CONFIG_MTD_NAND_TMIO=m
 CONFIG_MTD_NAND_BRCMNAND=m
diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig
index 77a56c2..2dd56e9 100644
--- a/arch/arm/configs/raumfeld_defconfig
+++ b/arch/arm/configs/raumfeld_defconfig
@@ -33,7 +33,7 @@
 CONFIG_NFTL_RW=y
 CONFIG_MTD_BLOCK2MTD=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_ISL29003=y
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
index 2a6d69d..cc9fa24 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -11,19 +11,17 @@
 # CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_MULTI_V6=y
 CONFIG_ARCH_REALVIEW=y
-CONFIG_REALVIEW_DT=y
 CONFIG_MACH_REALVIEW_EB=y
 CONFIG_REALVIEW_EB_ARM1136=y
 CONFIG_REALVIEW_EB_ARM1176=y
 CONFIG_REALVIEW_EB_A9MP=y
 CONFIG_REALVIEW_EB_ARM11MP=y
-CONFIG_REALVIEW_EB_ARM11MP_REVB=y
 CONFIG_MACH_REALVIEW_PB11MP=y
 CONFIG_MACH_REALVIEW_PB1176=y
 CONFIG_MACH_REALVIEW_PBA8=y
 CONFIG_MACH_REALVIEW_PBX=y
 CONFIG_SMP=y
-CONFIG_AEABI=y
+CONFIG_CMA=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
@@ -46,7 +44,7 @@
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_ROM=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_ARM_CHARLCD=y
+CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
@@ -59,21 +57,21 @@
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
 CONFIG_I2C_VERSATILE=y
 CONFIG_SPI=y
 CONFIG_GPIOLIB=y
 # CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_ARMCLCD=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_DRM=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PL111=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
 # CONFIG_SND_DRIVERS is not set
 CONFIG_SND_ARMAACI=y
 CONFIG_USB=y
@@ -83,13 +81,14 @@
 CONFIG_MMC_ARMMMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_VERSATILE=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_CPU=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_RTC_DRV_PL031=y
+CONFIG_AUXDISPLAY=y
+CONFIG_ARM_CHARLCD=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_CRAMFS=y
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 578434c..a701601 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -5,8 +5,6 @@
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
 CONFIG_ARCH_RENESAS=y
@@ -34,7 +32,6 @@
 CONFIG_SCHED_MC=y
 CONFIG_HAVE_ARM_ARCH_TIMER=y
 CONFIG_NR_CPUS=8
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_CMA=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -104,9 +101,6 @@
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_EM=y
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=20
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-CONFIG_SERIAL_SH_SCI_DMA=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
 CONFIG_I2C_DEMUX_PINCTRL=y
@@ -120,6 +114,7 @@
 CONFIG_SPI_RSPI=y
 CONFIG_SPI_SH_MSIOF=y
 CONFIG_SPI_SH_HSPI=y
+CONFIG_PINCTRL_RZA1=y
 CONFIG_GPIO_EM=y
 CONFIG_GPIO_RCAR=y
 CONFIG_GPIO_PCF857X=y
@@ -166,7 +161,6 @@
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_AS3711=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
@@ -227,4 +221,5 @@
 CONFIG_PRINTK_TIME=y
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
 # CONFIG_ARM_UNWIND is not set
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index bb358ff..ba805b7 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -57,6 +57,8 @@
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 # CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
@@ -71,6 +73,7 @@
 CONFIG_IIO=y
 CONFIG_STM32_ADC_CORE=y
 CONFIG_STM32_ADC=y
+CONFIG_EXT3_FS=y
 # CONFIG_FILE_LOCKING is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY_USER is not set
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index 295408e..df68dc4 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -12,6 +12,7 @@
 CONFIG_ARCH_VERSATILE=y
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
+CONFIG_CMA=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="root=1f03 mem=32M"
@@ -32,7 +33,9 @@
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_EEPROM_LEGACY=m
 CONFIG_NETDEVICES=y
@@ -47,21 +50,22 @@
 CONFIG_SERIAL_8250_RSA=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_VERSATILE=y
 CONFIG_SPI=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
-CONFIG_MFD_SYSCON=y
-CONFIG_FB=y
-CONFIG_FB_ARMCLCD=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_DRM=y
+CONFIG_DRM_PANEL_ARM_VERSATILE=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PL111=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
 CONFIG_SND_ARMAACI=m
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
diff --git a/arch/arm/include/debug/exynos.S b/arch/arm/include/debug/exynos.S
index 60bf3c2..74b5676 100644
--- a/arch/arm/include/debug/exynos.S
+++ b/arch/arm/include/debug/exynos.S
@@ -1,11 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
+ */
 
 /* pull in the relevant register and map files. */
 
diff --git a/arch/arm/include/debug/samsung.S b/arch/arm/include/debug/samsung.S
index f4eeed2..69201d7 100644
--- a/arch/arm/include/debug/samsung.S
+++ b/arch/arm/include/debug/samsung.S
@@ -1,13 +1,9 @@
-/* arch/arm/plat-samsung/include/plat/debug-macro.S
- *
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
  * Copyright 2005, 2007 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
- *
- * 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/serial_s3c.h>
 
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 6d87042..1254bf9 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -1,5 +1,5 @@
 menuconfig ARCH_AT91
-	bool "Atmel SoCs"
+	bool "AT91/Microchip SoCs"
 	depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
 	select ARM_CPU_SUSPEND if PM && ARCH_MULTI_V7
 	select COMMON_CLK_AT91
@@ -13,7 +13,7 @@
 	select COMMON_CLK_AT91
 	select PINCTRL_AT91
 	help
-	  Select this if you are using an SoC from Atmel's SAME7, SAMS7 or SAMV7
+	  Select this if you are using an SoC from Microchip's SAME7, SAMS7 or SAMV7
 	  families.
 
 config SOC_SAMA5D2
@@ -29,7 +29,7 @@
 	select HAVE_AT91_AUDIO_PLL
 	select PINCTRL_AT91PIO4
 	help
-	  Select this if ou are using one of Atmel's SAMA5D2 family SoC.
+	  Select this if ou are using one of Microchip's SAMA5D2 family SoC.
 
 config SOC_SAMA5D3
 	bool "SAMA5D3 family"
@@ -41,7 +41,7 @@
 	select HAVE_AT91_USB_CLK
 	select PINCTRL_AT91
 	help
-	  Select this if you are using one of Atmel's SAMA5D3 family SoC.
+	  Select this if you are using one of Microchip's SAMA5D3 family SoC.
 	  This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36.
 
 config SOC_SAMA5D4
@@ -56,7 +56,7 @@
 	select HAVE_AT91_H32MX
 	select PINCTRL_AT91
 	help
-	  Select this if you are using one of Atmel's SAMA5D4 family SoC.
+	  Select this if you are using one of Microchip's SAMA5D4 family SoC.
 
 config SOC_AT91RM9200
 	bool "AT91RM9200"
@@ -70,7 +70,7 @@
 	select SOC_SAM_V4_V5
 	select SRAM if PM
 	help
-	  Select this if you are using Atmel's AT91RM9200 SoC.
+	  Select this if you are using Microchip's AT91RM9200 SoC.
 
 config SOC_AT91SAM9
 	bool "AT91SAM9"
@@ -88,7 +88,7 @@
 	select SOC_SAM_V4_V5
 	select SRAM if PM
 	help
-	  Select this if you are using one of those Atmel SoC:
+	  Select this if you are using one of those Microchip SoC:
 	    AT91SAM9260
 	    AT91SAM9261
 	    AT91SAM9263
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index f673cd7..004f9c8 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -239,20 +239,6 @@ static inline void da830_evm_init_mmc(void)
 	}
 }
 
-/*
- * UI board NAND/NOR flashes only use 8-bit data bus.
- */
-static const short da830_evm_emif25_pins[] = {
-	DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
-	DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
-	DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
-	DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
-	DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
-	DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE,
-	DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0,
-	-1
-};
-
 #define HAS_MMC		IS_ENABLED(CONFIG_MMC_DAVINCI)
 
 #ifdef CONFIG_DA830_UI_NAND
@@ -357,6 +343,20 @@ static struct platform_device da830_evm_nand_device = {
 	.resource	= da830_evm_nand_resources,
 };
 
+/*
+ * UI board NAND/NOR flashes only use 8-bit data bus.
+ */
+static const short da830_evm_emif25_pins[] = {
+	DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
+	DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
+	DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
+	DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
+	DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
+	DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE,
+	DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0,
+	-1
+};
+
 static inline void da830_evm_init_nand(int mux_mode)
 {
 	int ret;
@@ -551,10 +551,6 @@ static __init void da830_evm_init(void)
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
 	int ret;
 
-	ret = da8xx_register_cfgchip();
-	if (ret)
-		pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
-
 	ret = da830_register_gpio();
 	if (ret)
 		pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
@@ -638,9 +634,8 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
 	.atag_offset	= 0x100,
 	.map_io		= da830_evm_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da830_init_time,
 	.init_machine	= da830_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= da8xx_restart,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index d898a94..3063478 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1334,10 +1334,6 @@ static __init void da850_evm_init(void)
 {
 	int ret;
 
-	ret = da8xx_register_cfgchip();
-	if (ret)
-		pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
-
 	ret = da850_register_gpio();
 	if (ret)
 		pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
@@ -1481,10 +1477,9 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
 	.atag_offset	= 0x100,
 	.map_io		= da850_evm_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= da850_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= da8xx_restart,
 	.reserve	= da8xx_rproc_reserve_cma,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index d6b1190..cb30637 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -427,9 +427,8 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
 	.atag_offset  = 0x100,
 	.map_io	      = dm355_evm_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm355_init_time,
 	.init_machine = dm355_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= davinci_restart,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index fad9a56..59743bd 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -271,9 +271,8 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
 	.atag_offset  = 0x100,
 	.map_io	      = dm355_leopard_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm355_init_time,
 	.init_machine = dm355_leopard_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= davinci_restart,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index e378098..0ac085b 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -774,10 +774,9 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
 	.atag_offset	= 0x100,
 	.map_io		= dm365_evm_map_io,
 	.init_irq	= davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm365_init_time,
 	.init_machine	= dm365_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= davinci_restart,
 MACHINE_END
 
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 85e6fb3..95b55aa 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -828,9 +828,8 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
 	.atag_offset  = 0x100,
 	.map_io	      = davinci_evm_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= davinci_restart,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index cb0a41e..2d37f5b 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -44,10 +44,8 @@
 #include <mach/common.h>
 #include <mach/irqs.h>
 #include <mach/serial.h>
-#include <mach/clock.h>
 
 #include "davinci.h"
-#include "clock.h"
 
 #define NAND_BLOCK_SIZE		SZ_128K
 
@@ -716,14 +714,23 @@ static void __init evm_init_i2c(void)
 }
 #endif
 
+#define DM646X_REF_FREQ			27000000
+#define DM646X_AUX_FREQ			24000000
 #define DM6467T_EVM_REF_FREQ		33000000
 
 static void __init davinci_map_io(void)
 {
 	dm646x_init();
+}
 
-	if (machine_is_davinci_dm6467tevm())
-		davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+static void __init dm646x_evm_init_time(void)
+{
+	dm646x_init_time(DM646X_REF_FREQ, DM646X_AUX_FREQ);
+}
+
+static void __init dm6467t_evm_init_time(void)
+{
+	dm646x_init_time(DM6467T_EVM_REF_FREQ, DM646X_AUX_FREQ);
 }
 
 #define DM646X_EVM_PHY_ID		"davinci_mdio-0:01"
@@ -797,21 +804,19 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
 	.atag_offset  = 0x100,
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm646x_evm_init_time,
 	.init_machine = evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= davinci_restart,
 MACHINE_END
 
 MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
 	.atag_offset  = 0x100,
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm6467t_evm_init_time,
 	.init_machine = evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= davinci_restart,
 MACHINE_END
 
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index b73ce7b..d1c8548 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -502,10 +502,6 @@ static void __init mityomapl138_init(void)
 {
 	int ret;
 
-	ret = da8xx_register_cfgchip();
-	if (ret)
-		pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
-
 	/* for now, no special EDMA channels are reserved */
 	ret = da850_register_edma(NULL);
 	if (ret)
@@ -570,9 +566,8 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
 	.atag_offset	= 0x100,
 	.map_io		= mityomapl138_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= mityomapl138_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= da8xx_restart,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 4da210a..f287577 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -227,9 +227,8 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
 	.atag_offset	= 0x100,
 	.map_io		 = davinci_ntosd2_map_io,
 	.init_irq	= davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_ntosd2_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= davinci_restart,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 62eb7d6..0d32042 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -281,10 +281,6 @@ static __init void omapl138_hawk_init(void)
 {
 	int ret;
 
-	ret = da8xx_register_cfgchip();
-	if (ret)
-		pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
-
 	ret = da850_register_gpio();
 	if (ret)
 		pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
@@ -334,10 +330,9 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
 	.atag_offset	= 0x100,
 	.map_io		= omapl138_hawk_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= omapl138_hawk_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= da8xx_restart,
 	.reserve	= da8xx_rproc_reserve_cma,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index d85accf..2922da9 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -150,9 +150,8 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
 	.atag_offset  = 0x100,
 	.map_io	      = davinci_sffsdr_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_sffsdr_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
-	.restart	= davinci_restart,
 MACHINE_END
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index fa2b837..d7894d5 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -135,9 +135,6 @@ int davinci_clk_reset(struct clk *clk, bool reset);
 void davinci_clk_enable(struct clk *clk);
 void davinci_clk_disable(struct clk *clk);
 
-extern struct platform_device davinci_wdt_device;
-extern void davinci_watchdog_reset(struct platform_device *);
-
 #endif
 
 #endif
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 57ab18c..350d767 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1200,7 +1200,6 @@ static const struct davinci_soc_info davinci_soc_info_da830 = {
 	.jtag_id_reg		= DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
 	.ids			= da830_ids,
 	.ids_num		= ARRAY_SIZE(da830_ids),
-	.cpu_clks		= da830_clks,
 	.psc_bases		= da830_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da830_psc_bases),
 	.pinmux_base		= DA8XX_SYSCFG0_BASE + 0x120,
@@ -1220,6 +1219,10 @@ void __init da830_init(void)
 
 	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
 	WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
+}
 
-	davinci_clk_init(davinci_soc_info_da830.cpu_clks);
+void __init da830_init_time(void)
+{
+	davinci_clk_init(da830_clks);
+	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index aa37cbd..34117e61 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1353,7 +1353,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
 	.jtag_id_reg		= DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
 	.ids			= da850_ids,
 	.ids_num		= ARRAY_SIZE(da850_ids),
-	.cpu_clks		= da850_clks,
 	.psc_bases		= da850_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da850_psc_bases),
 	.pinmux_base		= DA8XX_SYSCFG0_BASE + 0x120,
@@ -1392,6 +1391,10 @@ void __init da850_init(void)
 	v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
 	v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
 	__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+}
 
-	davinci_clk_init(davinci_soc_info_da850.cpu_clks);
+void __init da850_init_time(void)
+{
+	davinci_clk_init(da850_clks);
+	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index f06db67..ab199f4 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -96,11 +96,10 @@ static const char *const da850_boards_compat[] __initconst = {
 
 DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
 	.map_io		= da850_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= da850_init_machine,
 	.dt_compat	= da850_boards_compat,
 	.init_late	= davinci_init_late,
-	.restart	= da8xx_restart,
 MACHINE_END
 
 #endif
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index c62b90c..270cef8 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -83,6 +83,7 @@ int davinci_init_wdt(void);
 
 /* DM355 function declarations */
 void dm355_init(void);
+void dm355_init_time(void);
 void dm355_init_spi0(unsigned chipselect_mask,
 		const struct spi_board_info *info, unsigned len);
 void dm355_init_asp1(u32 evt_enable);
@@ -91,6 +92,7 @@ int dm355_gpio_register(void);
 
 /* DM365 function declarations */
 void dm365_init(void);
+void dm365_init_time(void);
 void dm365_init_asp(void);
 void dm365_init_vc(void);
 void dm365_init_ks(struct davinci_ks_platform_data *pdata);
@@ -102,12 +104,14 @@ int dm365_gpio_register(void);
 
 /* DM644x function declarations */
 void dm644x_init(void);
+void dm644x_init_time(void);
 void dm644x_init_asp(void);
 int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
 int dm644x_gpio_register(void);
 
 /* DM646x function declarations */
 void dm646x_init(void);
+void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate);
 void dm646x_init_mcasp0(struct snd_platform_data *pdata);
 void dm646x_init_mcasp1(struct snd_platform_data *pdata);
 int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index e1c40e7..78390c6 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -11,7 +11,6 @@
  * (at your option) any later version.
  */
 #include <linux/init.h>
-#include <linux/platform_data/syscon.h>
 #include <linux/platform_device.h>
 #include <linux/dma-contiguous.h>
 #include <linux/serial_8250.h>
@@ -371,19 +370,6 @@ static struct platform_device da8xx_wdt_device = {
 	.resource	= da8xx_watchdog_resources,
 };
 
-void da8xx_restart(enum reboot_mode mode, const char *cmd)
-{
-	struct device *dev;
-
-	dev = bus_find_device_by_name(&platform_bus_type, NULL, "davinci-wdt");
-	if (!dev) {
-		pr_err("%s: failed to find watchdog device\n", __func__);
-		return;
-	}
-
-	davinci_watchdog_reset(to_platform_device(dev));
-}
-
 int __init da8xx_register_watchdog(void)
 {
 	return platform_device_register(&da8xx_wdt_device);
@@ -1118,29 +1104,30 @@ int __init da850_register_sata(unsigned long refclkpn)
 }
 #endif
 
-static struct syscon_platform_data da8xx_cfgchip_platform_data = {
-	.label	= "cfgchip",
+static struct regmap *da8xx_cfgchip;
+
+static const struct regmap_config da8xx_cfgchip_config __initconst = {
+	.name		= "cfgchip",
+	.reg_bits	= 32,
+	.val_bits	= 32,
+	.reg_stride	= 4,
+	.max_register	= DA8XX_CFGCHIP4_REG - DA8XX_CFGCHIP0_REG,
 };
 
-static struct resource da8xx_cfgchip_resources[] = {
-	{
-		.start	= DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP0_REG,
-		.end	= DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP4_REG + 3,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device da8xx_cfgchip_device = {
-	.name	= "syscon",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &da8xx_cfgchip_platform_data,
-	},
-	.num_resources	= ARRAY_SIZE(da8xx_cfgchip_resources),
-	.resource	= da8xx_cfgchip_resources,
-};
-
-int __init da8xx_register_cfgchip(void)
+/**
+ * da8xx_get_cfgchip - Lazy gets CFGCHIP as regmap
+ *
+ * This is for use on non-DT boards only. For DT boards, use
+ * syscon_regmap_lookup_by_compatible("ti,da830-cfgchip")
+ *
+ * Returns: Pointer to the CFGCHIP regmap or negative error code.
+ */
+struct regmap * __init da8xx_get_cfgchip(void)
 {
-	return platform_device_register(&da8xx_cfgchip_device);
+	if (IS_ERR_OR_NULL(da8xx_cfgchip))
+		da8xx_cfgchip = regmap_init_mmio(NULL,
+					DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG),
+					&da8xx_cfgchip_config);
+
+	return da8xx_cfgchip;
 }
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 3ae70f2..0edda40 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -282,18 +282,13 @@ static struct resource wdt_resources[] = {
 	},
 };
 
-struct platform_device davinci_wdt_device = {
+static struct platform_device davinci_wdt_device = {
 	.name		= "davinci-wdt",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(wdt_resources),
 	.resource	= wdt_resources,
 };
 
-void davinci_restart(enum reboot_mode mode, const char *cmd)
-{
-	davinci_watchdog_reset(&davinci_wdt_device);
-}
-
 int davinci_init_wdt(void)
 {
 	return platform_device_register(&davinci_wdt_device);
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 938747f..f294804 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -1012,7 +1012,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm355_ids,
 	.ids_num		= ARRAY_SIZE(dm355_ids),
-	.cpu_clks		= dm355_clks,
 	.psc_bases		= dm355_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm355_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -1043,7 +1042,12 @@ void __init dm355_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm355);
 	davinci_map_sysmod();
-	davinci_clk_init(davinci_soc_info_dm355.cpu_clks);
+}
+
+void __init dm355_init_time(void)
+{
+	davinci_clk_init(dm355_clks);
+	davinci_timer_init();
 }
 
 int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 5d9f96d..1e3df9d 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -1116,7 +1116,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm365_ids,
 	.ids_num		= ARRAY_SIZE(dm365_ids),
-	.cpu_clks		= dm365_clks,
 	.psc_bases		= dm365_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm365_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -1168,7 +1167,12 @@ void __init dm365_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm365);
 	davinci_map_sysmod();
-	davinci_clk_init(davinci_soc_info_dm365.cpu_clks);
+}
+
+void __init dm365_init_time(void)
+{
+	davinci_clk_init(dm365_clks);
+	davinci_timer_init();
 }
 
 static struct resource dm365_vpss_resources[] = {
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 6b41e1c..b409801 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -905,7 +905,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm644x_ids,
 	.ids_num		= ARRAY_SIZE(dm644x_ids),
-	.cpu_clks		= dm644x_clks,
 	.psc_bases		= dm644x_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm644x_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -931,7 +930,12 @@ void __init dm644x_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm644x);
 	davinci_map_sysmod();
-	davinci_clk_init(davinci_soc_info_dm644x.cpu_clks);
+}
+
+void __init dm644x_init_time(void)
+{
+	davinci_clk_init(dm644x_clks);
+	davinci_timer_init();
 }
 
 int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 6fc06a6..109ab1f 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -39,12 +39,6 @@
 #define VSCLKDIS_MASK		(BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\
 					BIT_MASK(8))
 
-/*
- * Device specific clocks
- */
-#define DM646X_REF_FREQ		27000000
-#define DM646X_AUX_FREQ		24000000
-
 #define DM646X_EMAC_BASE		0x01c80000
 #define DM646X_EMAC_MDIO_BASE		(DM646X_EMAC_BASE + 0x4000)
 #define DM646X_EMAC_CNTRL_OFFSET	0x0000
@@ -64,13 +58,12 @@ static struct pll_data pll2_data = {
 
 static struct clk ref_clk = {
 	.name = "ref_clk",
-	.rate = DM646X_REF_FREQ,
-	.set_rate = davinci_simple_set_rate,
+	/* rate is initialized in dm646x_init_time() */
 };
 
 static struct clk aux_clkin = {
 	.name = "aux_clkin",
-	.rate = DM646X_AUX_FREQ,
+	/* rate is initialized in dm646x_init_time() */
 };
 
 static struct clk pll1_clk = {
@@ -888,7 +881,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm646x_ids,
 	.ids_num		= ARRAY_SIZE(dm646x_ids),
-	.cpu_clks		= dm646x_clks,
 	.psc_bases		= dm646x_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm646x_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -956,7 +948,15 @@ void __init dm646x_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm646x);
 	davinci_map_sysmod();
-	davinci_clk_init(davinci_soc_info_dm646x.cpu_clks);
+}
+
+void __init dm646x_init_time(unsigned long ref_clk_rate,
+			     unsigned long aux_clkin_rate)
+{
+	ref_clk.rate = ref_clk_rate;
+	aux_clkin.rate = aux_clkin_rate;
+	davinci_clk_init(dm646x_clks);
+	davinci_timer_init();
 }
 
 static int __init dm646x_init_devices(void)
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 433a008..f0d5e858 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -53,7 +53,6 @@ struct davinci_soc_info {
 	u32				jtag_id_reg;
 	struct davinci_id		*ids;
 	unsigned long			ids_num;
-	struct clk_lookup		*cpu_clks;
 	u32				*psc_bases;
 	unsigned long			psc_bases_num;
 	u32				pinmux_base;
@@ -81,7 +80,6 @@ extern struct davinci_soc_info davinci_soc_info;
 
 extern void davinci_common_init(const struct davinci_soc_info *soc_info);
 extern void davinci_init_ide(void);
-void davinci_restart(enum reboot_mode mode, const char *cmd);
 void davinci_init_late(void);
 
 #ifdef CONFIG_DAVINCI_RESET_CLOCKS
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 93ff156..9fd6d01 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -18,6 +18,7 @@
 #include <linux/spi/spi.h>
 #include <linux/platform_data/davinci_asp.h>
 #include <linux/reboot.h>
+#include <linux/regmap.h>
 #include <linux/videodev2.h>
 
 #include <mach/serial.h>
@@ -87,7 +88,10 @@ extern unsigned int da850_max_speed;
 #define DA8XX_ARM_RAM_BASE	0xffff0000
 
 void da830_init(void);
+void da830_init_time(void);
+
 void da850_init(void);
+void da850_init_time(void);
 
 int da830_register_edma(struct edma_rsv_info *rsv);
 int da850_register_edma(struct edma_rsv_info *rsv[2]);
@@ -118,12 +122,11 @@ int da850_register_vpif_display
 			(struct vpif_display_config *display_config);
 int da850_register_vpif_capture
 			(struct vpif_capture_config *capture_config);
-void da8xx_restart(enum reboot_mode mode, const char *cmd);
 void da8xx_rproc_reserve_cma(void);
 int da8xx_register_rproc(void);
 int da850_register_gpio(void);
 int da830_register_gpio(void);
-int da8xx_register_cfgchip(void);
+struct regmap *da8xx_get_cfgchip(void);
 
 extern struct platform_device da8xx_serial_device[];
 extern struct emac_platform_data da8xx_emac_pdata;
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 034f865..1bb991a 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -80,13 +80,6 @@ enum {
 #define TGCR_UNRESET                 0x1
 #define TGCR_RESET_MASK              0x3
 
-#define WDTCR_WDEN_SHIFT             14
-#define WDTCR_WDEN_DISABLE           0x0
-#define WDTCR_WDEN_ENABLE            0x1
-#define WDTCR_WDKEY_SHIFT            16
-#define WDTCR_WDKEY_SEQ0             0xa5c6
-#define WDTCR_WDKEY_SEQ1             0xda7e
-
 struct timer_s {
 	char *name;
 	unsigned int id;
@@ -409,53 +402,3 @@ void __init davinci_timer_init(void)
 	for (i=0; i< ARRAY_SIZE(timers); i++)
 		timer32_config(&timers[i]);
 }
-
-/* reset board using watchdog timer */
-void davinci_watchdog_reset(struct platform_device *pdev)
-{
-	u32 tgcr, wdtcr;
-	void __iomem *base;
-	struct clk *wd_clk;
-
-	base = ioremap(pdev->resource[0].start, SZ_4K);
-	if (WARN_ON(!base))
-		return;
-
-	wd_clk = clk_get(&pdev->dev, NULL);
-	if (WARN_ON(IS_ERR(wd_clk)))
-		return;
-	clk_prepare_enable(wd_clk);
-
-	/* disable, internal clock source */
-	__raw_writel(0, base + TCR);
-
-	/* reset timer, set mode to 64-bit watchdog, and unreset */
-	tgcr = 0;
-	__raw_writel(tgcr, base + TGCR);
-	tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
-	tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
-		(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
-	__raw_writel(tgcr, base + TGCR);
-
-	/* clear counter and period regs */
-	__raw_writel(0, base + TIM12);
-	__raw_writel(0, base + TIM34);
-	__raw_writel(0, base + PRD12);
-	__raw_writel(0, base + PRD34);
-
-	/* put watchdog in pre-active state */
-	wdtcr = __raw_readl(base + WDTCR);
-	wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
-		(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
-	__raw_writel(wdtcr, base + WDTCR);
-
-	/* put watchdog in active state */
-	wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
-		(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
-	__raw_writel(wdtcr, base + WDTCR);
-
-	/* write an invalid value to the WDKEY field to trigger
-	 * a watchdog reset */
-	wdtcr = 0x00004000;
-	__raw_writel(wdtcr, base + WDTCR);
-}
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index d480a02..50445f0 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -8,6 +8,7 @@
 #include <linux/init.h>
 #include <linux/mfd/da8xx-cfgchip.h>
 #include <linux/phy/phy.h>
+#include <linux/platform_data/phy-da8xx-usb.h>
 #include <linux/platform_data/usb-davinci.h>
 #include <linux/platform_device.h>
 #include <linux/usb/musb.h>
@@ -25,6 +26,8 @@
 
 static struct clk *usb20_clk;
 
+static struct da8xx_usb_phy_platform_data da8xx_usb_phy_pdata;
+
 static struct platform_device da8xx_usb_phy = {
 	.name		= "da8xx-usb-phy",
 	.id		= -1,
@@ -35,11 +38,14 @@ static struct platform_device da8xx_usb_phy = {
 		 * registered yet.
 		 */
 		.init_name	= "da8xx-usb-phy",
+		.platform_data	= &da8xx_usb_phy_pdata,
 	},
 };
 
 int __init da8xx_register_usb_phy(void)
 {
+	da8xx_usb_phy_pdata.cfgchip = da8xx_get_cfgchip();
+
 	return platform_device_register(&da8xx_usb_phy);
 }
 
@@ -256,14 +262,14 @@ static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
 }
 
 static struct clk usb20_phy_clk = {
-	.name		= "usb20_phy",
+	.name		= "usb0_clk48",
 	.clk_enable	= usb20_phy_clk_enable,
 	.clk_disable	= usb20_phy_clk_disable,
 	.set_parent	= usb20_phy_clk_set_parent,
 };
 
 static struct clk_lookup usb20_phy_clk_lookup =
-	CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk);
+	CLK("da8xx-usb-phy", "usb0_clk48", &usb20_phy_clk);
 
 /**
  * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
@@ -320,18 +326,18 @@ static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
 }
 
 static struct clk usb11_phy_clk = {
-	.name		= "usb11_phy",
+	.name		= "usb1_clk48",
 	.set_parent	= usb11_phy_clk_set_parent,
 };
 
 static struct clk_lookup usb11_phy_clk_lookup =
-	CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk);
+	CLK("da8xx-usb-phy", "usb1_clk48", &usb11_phy_clk);
 
 /**
  * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
  *
  * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- *	or "usb20_phy" if false.
+ *	or "usb0_clk48" if false.
  */
 int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
 {
@@ -341,7 +347,7 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
 	if (use_usb_refclkin)
 		parent = clk_get(NULL, "usb_refclkin");
 	else
-		parent = clk_get(&da8xx_usb_phy.dev, "usb20_phy");
+		parent = clk_get(&da8xx_usb_phy.dev, "usb0_clk48");
 	if (IS_ERR(parent))
 		return PTR_ERR(parent);
 
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index fbd108c..8c4f5e3 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -192,7 +192,8 @@ static void __init exynos_dt_machine_init(void)
 #endif
 	if (of_machine_is_compatible("samsung,exynos4210") ||
 	    (of_machine_is_compatible("samsung,exynos4412") &&
-	     of_machine_is_compatible("samsung,trats2")) ||
+	     (of_machine_is_compatible("samsung,trats2") ||
+		  of_machine_is_compatible("samsung,midas"))) ||
 	    of_machine_is_compatible("samsung,exynos3250") ||
 	    of_machine_is_compatible("samsung,exynos5250"))
 		platform_device_register(&exynos_cpuidle);
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index dc4346e..a822c50 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -163,7 +163,7 @@ void exynos_enter_aftr(void)
 
 	exynos_pm_central_suspend();
 
-	if (of_machine_is_compatible("samsung,exynos4412")) {
+	if (soc_is_exynos4412()) {
 		/* Setting SEQ_OPTION register */
 		pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
 			       S5P_CENTRAL_SEQ_OPTION);
@@ -271,11 +271,7 @@ static int exynos_cpu0_enter_aftr(void)
 				goto fail;
 
 			call_firmware_op(cpu_boot, 1);
-
-			if (soc_is_exynos3250())
-				dsb_sev();
-			else
-				arch_send_wakeup_ipi_mask(cpumask_of(1));
+			dsb_sev();
 		}
 	}
 fail:
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 782699e..e47fa13 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -32,18 +32,6 @@
 	  data/address de-multiplexing and decode, signal level shift,
 	  interrupt control and various board functions.
 
-config HAVE_EPIT
-	bool
-
-config MXC_USE_EPIT
-	bool "Use EPIT instead of GPT"
-	depends on HAVE_EPIT
-	help
-	  Use EPIT as the system timer on systems that have it. Normally you
-	  don't have a reason to do so as the EPIT has the same features and
-	  uses the same clocks as the GPT. Anyway, on some systems the GPT
-	  may be in use for other purposes.
-
 config HAVE_IMX_ANATOP
 	bool
 
@@ -85,7 +73,6 @@
 config SOC_IMX35
 	bool
 	select ARCH_MXC_IOMUX_V3
-	select HAVE_EPIT
 	select MXC_AVIC
 	select PINCTRL_IMX35
 
@@ -482,7 +469,7 @@
 
 config SOC_IMX6
 	bool
-	select ARM_CPU_SUSPEND if PM
+	select ARM_CPU_SUSPEND if (PM || CPU_IDLE)
 	select ARM_ERRATA_754322
 	select ARM_ERRATA_775420
 	select ARM_GIC
@@ -512,6 +499,13 @@
 	help
 	  This enables support for Freescale i.MX6 SoloLite processor.
 
+config SOC_IMX6SLL
+	bool "i.MX6 SoloLiteLite support"
+	select SOC_IMX6
+
+	help
+	  This enables support for Freescale i.MX6 SoloLiteLite processor.
+
 config SOC_IMX6SX
 	bool "i.MX6 SoloX support"
 	select PINCTRL_IMX6SX
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 8ff7105..2327e3e 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -20,13 +20,13 @@
 obj-$(CONFIG_MXC_TZIC) += tzic.o
 obj-$(CONFIG_MXC_AVIC) += avic.o
 
-obj-$(CONFIG_MXC_USE_EPIT) += epit.o
 obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
 
 ifeq ($(CONFIG_CPU_IDLE),y)
 obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
 obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
 obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SLL) += cpuidle-imx6sl.o
 obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
 obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o
 endif
@@ -78,6 +78,7 @@
 endif
 obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
 obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o
 obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
 obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
 obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
index 649a84c..61f3d94 100644
--- a/arch/arm/mach-imx/anatop.c
+++ b/arch/arm/mach-imx/anatop.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
@@ -116,6 +117,7 @@ void __init imx_init_revision_from_anatop(void)
 	unsigned int revision;
 	u32 digprog;
 	u16 offset = ANADIG_DIGPROG;
+	u8 major_part, minor_part;
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
 	anatop_base = of_iomap(np, 0);
@@ -127,45 +129,25 @@ void __init imx_init_revision_from_anatop(void)
 	digprog = readl_relaxed(anatop_base + offset);
 	iounmap(anatop_base);
 
-	switch (digprog & 0xff) {
-	case 0:
-		/*
-		 * For i.MX6QP, most of the code for i.MX6Q can be resued,
-		 * so internally, we identify it as i.MX6Q Rev 2.0
-		 */
-		if (digprog >> 8 & 0x01)
-			revision = IMX_CHIP_REVISION_2_0;
-		else
-			revision = IMX_CHIP_REVISION_1_0;
-		break;
-	case 1:
-		revision = IMX_CHIP_REVISION_1_1;
-		break;
-	case 2:
-		revision = IMX_CHIP_REVISION_1_2;
-		break;
-	case 3:
-		revision = IMX_CHIP_REVISION_1_3;
-		break;
-	case 4:
-		revision = IMX_CHIP_REVISION_1_4;
-		break;
-	case 5:
-		/*
-		 * i.MX6DQ TO1.5 is defined as Rev 1.3 in Data Sheet, marked
-		 * as 'D' in Part Number last character.
-		 */
-		revision = IMX_CHIP_REVISION_1_5;
-		break;
-	default:
-		/*
-		 * Fail back to return raw register value instead of 0xff.
-		 * It will be easy to know version information in SOC if it
-		 * can't be recognized by known version. And some chip's (i.MX7D)
-		 * digprog value match linux version format, so it needn't map
-		 * again and we can use register value directly.
-		 */
+	/*
+	 * On i.MX7D digprog value match linux version format, so
+	 * it needn't map again and we can use register value directly.
+	 */
+	if (of_device_is_compatible(np, "fsl,imx7d-anatop")) {
 		revision = digprog & 0xff;
+	} else {
+		/*
+		 * MAJOR: [15:8], the major silicon revison;
+		 * MINOR: [7: 0], the minor silicon revison;
+		 *
+		 * please refer to the i.MX RM for the detailed
+		 * silicon revison bit define.
+		 * format the major part and minor part to match the
+		 * linux kernel soc version format.
+		 */
+		major_part = (digprog >> 8) & 0xf;
+		minor_part = digprog & 0xf;
+		revision = ((major_part + 1) << 4) | minor_part;
 	}
 
 	mxc_set_cpu_type(digprog >> 16 & 0xff);
diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c
index 1afccae..c0434a3 100644
--- a/arch/arm/mach-imx/avic.c
+++ b/arch/arm/mach-imx/avic.c
@@ -22,6 +22,7 @@
 #include <linux/irqdomain.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <asm/mach/irq.h>
 #include <asm/exception.h>
 
@@ -51,7 +52,12 @@
 
 #define AVIC_NUM_IRQS 64
 
+/* low power interrupt mask registers */
+#define MX25_CCM_LPIMR0	0x68
+#define MX25_CCM_LPIMR1	0x6C
+
 static void __iomem *avic_base;
+static void __iomem *mx25_ccm_base;
 static struct irq_domain *domain;
 
 #ifdef CONFIG_FIQ
@@ -93,6 +99,18 @@ static void avic_irq_suspend(struct irq_data *d)
 
 	avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask);
 	imx_writel(gc->wake_active, avic_base + ct->regs.mask);
+
+	if (mx25_ccm_base) {
+		u8 offs = d->hwirq < AVIC_NUM_IRQS / 2 ?
+			MX25_CCM_LPIMR0 : MX25_CCM_LPIMR1;
+		/*
+		 * The interrupts which are still enabled will be used as wakeup
+		 * sources. Allow those interrupts in low-power mode.
+		 * The LPIMR registers use 0 to allow an interrupt, the AVIC
+		 * registers use 1.
+		 */
+		imx_writel(~gc->wake_active, mx25_ccm_base + offs);
+	}
 }
 
 static void avic_irq_resume(struct irq_data *d)
@@ -102,6 +120,13 @@ static void avic_irq_resume(struct irq_data *d)
 	int idx = d->hwirq >> 5;
 
 	imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask);
+
+	if (mx25_ccm_base) {
+		u8 offs = d->hwirq < AVIC_NUM_IRQS / 2 ?
+			MX25_CCM_LPIMR0 : MX25_CCM_LPIMR1;
+
+		imx_writel(0xffffffff, mx25_ccm_base + offs);
+	}
 }
 
 #else
@@ -158,6 +183,18 @@ void __init mxc_init_irq(void __iomem *irqbase)
 
 	avic_base = irqbase;
 
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx25-ccm");
+	mx25_ccm_base = of_iomap(np, 0);
+
+	if (mx25_ccm_base) {
+		/*
+		 * By default, we mask all interrupts. We set the actual mask
+		 * before we go into low-power mode.
+		 */
+		imx_writel(0xffffffff, mx25_ccm_base + MX25_CCM_LPIMR0);
+		imx_writel(0xffffffff, mx25_ccm_base + MX25_CCM_LPIMR1);
+	}
+
 	/* put the AVIC into the reset value with
 	 * all interrupts disabled
 	 */
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index d4e55f2..32969f3 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -135,6 +135,9 @@ struct device * __init imx_soc_device_init(void)
 	case MXC_CPU_IMX6ULL:
 		soc_id = "i.MX6ULL";
 		break;
+	case MXC_CPU_IMX6SLL:
+		soc_id = "i.MX6SLL";
+		break;
 	case MXC_CPU_IMX7D:
 		soc_id = "i.MX7D";
 		break;
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
index 8d866fb..fa8ead1 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sl.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sl.c
@@ -12,6 +12,7 @@
 
 #include "common.h"
 #include "cpuidle.h"
+#include "hardware.h"
 
 static int imx6sl_enter_wait(struct cpuidle_device *dev,
 			    struct cpuidle_driver *drv, int index)
@@ -21,9 +22,11 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev,
 	 * Software workaround for ERR005311, see function
 	 * description for details.
 	 */
-	imx6sl_set_wait_clk(true);
+	if (cpu_is_imx6sl())
+		imx6sl_set_wait_clk(true);
 	cpu_do_idle();
-	imx6sl_set_wait_clk(false);
+	if (cpu_is_imx6sl())
+		imx6sl_set_wait_clk(false);
 	imx6_set_lpm(WAIT_CLOCKED);
 
 	return index;
diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
index c5a5c3a..d0f14b7 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sx.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -89,6 +89,7 @@ static struct cpuidle_driver imx6sx_cpuidle_driver = {
 			 */
 			.exit_latency = 300,
 			.target_residency = 500,
+			.flags = CPUIDLE_FLAG_TIMER_STOP,
 			.enter = imx6sx_enter_wait,
 			.name = "LOW-POWER-IDLE",
 			.desc = "ARM power off",
diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c
deleted file mode 100644
index fb9a73a..0000000
--- a/arch/arm/mach-imx/epit.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- *  linux/arch/arm/plat-mxc/epit.c
- *
- *  Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#define EPITCR		0x00
-#define EPITSR		0x04
-#define EPITLR		0x08
-#define EPITCMPR	0x0c
-#define EPITCNR		0x10
-
-#define EPITCR_EN			(1 << 0)
-#define EPITCR_ENMOD			(1 << 1)
-#define EPITCR_OCIEN			(1 << 2)
-#define EPITCR_RLD			(1 << 3)
-#define EPITCR_PRESC(x)			(((x) & 0xfff) << 4)
-#define EPITCR_SWR			(1 << 16)
-#define EPITCR_IOVW			(1 << 17)
-#define EPITCR_DBGEN			(1 << 18)
-#define EPITCR_WAITEN			(1 << 19)
-#define EPITCR_RES			(1 << 20)
-#define EPITCR_STOPEN			(1 << 21)
-#define EPITCR_OM_DISCON		(0 << 22)
-#define EPITCR_OM_TOGGLE		(1 << 22)
-#define EPITCR_OM_CLEAR			(2 << 22)
-#define EPITCR_OM_SET			(3 << 22)
-#define EPITCR_CLKSRC_OFF		(0 << 24)
-#define EPITCR_CLKSRC_PERIPHERAL	(1 << 24)
-#define EPITCR_CLKSRC_REF_HIGH		(1 << 24)
-#define EPITCR_CLKSRC_REF_LOW		(3 << 24)
-
-#define EPITSR_OCIF			(1 << 0)
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/clockchips.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <asm/mach/time.h>
-
-#include "common.h"
-#include "hardware.h"
-
-static struct clock_event_device clockevent_epit;
-
-static void __iomem *timer_base;
-
-static inline void epit_irq_disable(void)
-{
-	u32 val;
-
-	val = imx_readl(timer_base + EPITCR);
-	val &= ~EPITCR_OCIEN;
-	imx_writel(val, timer_base + EPITCR);
-}
-
-static inline void epit_irq_enable(void)
-{
-	u32 val;
-
-	val = imx_readl(timer_base + EPITCR);
-	val |= EPITCR_OCIEN;
-	imx_writel(val, timer_base + EPITCR);
-}
-
-static void epit_irq_acknowledge(void)
-{
-	imx_writel(EPITSR_OCIF, timer_base + EPITSR);
-}
-
-static int __init epit_clocksource_init(struct clk *timer_clk)
-{
-	unsigned int c = clk_get_rate(timer_clk);
-
-	return clocksource_mmio_init(timer_base + EPITCNR, "epit", c, 200, 32,
-			clocksource_mmio_readl_down);
-}
-
-/* clock event */
-
-static int epit_set_next_event(unsigned long evt,
-			      struct clock_event_device *unused)
-{
-	unsigned long tcmp;
-
-	tcmp = imx_readl(timer_base + EPITCNR);
-
-	imx_writel(tcmp - evt, timer_base + EPITCMPR);
-
-	return 0;
-}
-
-/* Left event sources disabled, no more interrupts appear */
-static int epit_shutdown(struct clock_event_device *evt)
-{
-	unsigned long flags;
-
-	/*
-	 * The timer interrupt generation is disabled at least
-	 * for enough time to call epit_set_next_event()
-	 */
-	local_irq_save(flags);
-
-	/* Disable interrupt in GPT module */
-	epit_irq_disable();
-
-	/* Clear pending interrupt */
-	epit_irq_acknowledge();
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static int epit_set_oneshot(struct clock_event_device *evt)
-{
-	unsigned long flags;
-
-	/*
-	 * The timer interrupt generation is disabled at least
-	 * for enough time to call epit_set_next_event()
-	 */
-	local_irq_save(flags);
-
-	/* Disable interrupt in GPT module */
-	epit_irq_disable();
-
-	/* Clear pending interrupt, only while switching mode */
-	if (!clockevent_state_oneshot(evt))
-		epit_irq_acknowledge();
-
-	/*
-	 * Do not put overhead of interrupt enable/disable into
-	 * epit_set_next_event(), the core has about 4 minutes
-	 * to call epit_set_next_event() or shutdown clock after
-	 * mode switching
-	 */
-	epit_irq_enable();
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = &clockevent_epit;
-
-	epit_irq_acknowledge();
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction epit_timer_irq = {
-	.name		= "i.MX EPIT Timer Tick",
-	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= epit_timer_interrupt,
-};
-
-static struct clock_event_device clockevent_epit = {
-	.name			= "epit",
-	.features		= CLOCK_EVT_FEAT_ONESHOT,
-	.set_state_shutdown	= epit_shutdown,
-	.tick_resume		= epit_shutdown,
-	.set_state_oneshot	= epit_set_oneshot,
-	.set_next_event		= epit_set_next_event,
-	.rating			= 200,
-};
-
-static int __init epit_clockevent_init(struct clk *timer_clk)
-{
-	clockevent_epit.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&clockevent_epit,
-					clk_get_rate(timer_clk),
-					0x800, 0xfffffffe);
-
-	return 0;
-}
-
-void __init epit_timer_init(void __iomem *base, int irq)
-{
-	struct clk *timer_clk;
-
-	timer_clk = clk_get_sys("imx-epit.0", NULL);
-	if (IS_ERR(timer_clk)) {
-		pr_err("i.MX epit: unable to get clk\n");
-		return;
-	}
-
-	clk_prepare_enable(timer_clk);
-
-	timer_base = base;
-
-	/*
-	 * Initialise to a known state (all timers off, and timing reset)
-	 */
-	imx_writel(0x0, timer_base + EPITCR);
-
-	imx_writel(0xffffffff, timer_base + EPITLR);
-	imx_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
-		   timer_base + EPITCR);
-
-	/* init and register the timer to the framework */
-	epit_clocksource_init(timer_clk);
-	epit_clockevent_init(timer_clk);
-
-	/* Make irqs happen */
-	setup_irq(irq, &epit_timer_irq);
-}
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 0408490..c7a1ef1 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -18,6 +18,7 @@
 
 #include "common.h"
 #include "cpuidle.h"
+#include "hardware.h"
 
 static void __init imx6sl_fec_init(void)
 {
@@ -54,7 +55,8 @@ static void __init imx6sl_init_machine(void)
 
 	of_platform_default_populate(NULL, NULL, parent);
 
-	imx6sl_fec_init();
+	if (cpu_is_imx6sl())
+		imx6sl_fec_init();
 	imx_anatop_init();
 	imx6sl_pm_init();
 }
@@ -66,11 +68,15 @@ static void __init imx6sl_init_irq(void)
 	imx_init_l2cache();
 	imx_src_init();
 	irqchip_init();
-	imx6_pm_ccm_init("fsl,imx6sl-ccm");
+	if (cpu_is_imx6sl())
+		imx6_pm_ccm_init("fsl,imx6sl-ccm");
+	else
+		imx6_pm_ccm_init("fsl,imx6sll-ccm");
 }
 
 static const char * const imx6sl_dt_compat[] __initconst = {
 	"fsl,imx6sl",
+	"fsl,imx6sll",
 	NULL,
 };
 
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index e00d626..026e2ca 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -40,6 +40,7 @@
 #define MXC_CPU_IMX6Q		0x63
 #define MXC_CPU_IMX6UL		0x64
 #define MXC_CPU_IMX6ULL		0x65
+#define MXC_CPU_IMX6SLL		0x67
 #define MXC_CPU_IMX7D		0x72
 
 #define IMX_DDR_TYPE_LPDDR2		1
@@ -79,6 +80,11 @@ static inline bool cpu_is_imx6ull(void)
 	return __mxc_cpu_type == MXC_CPU_IMX6ULL;
 }
 
+static inline bool cpu_is_imx6sll(void)
+{
+	return __mxc_cpu_type == MXC_CPU_IMX6SLL;
+}
+
 static inline bool cpu_is_imx6q(void)
 {
 	return __mxc_cpu_type == MXC_CPU_IMX6Q;
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index ecdf071..017539d 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -428,10 +428,8 @@ static int __init imx6_pm_get_base(struct imx6_pm_base *base,
 	int ret = 0;
 
 	node = of_find_compatible_node(NULL, NULL, compat);
-	if (!node) {
-		ret = -ENODEV;
-		goto out;
-	}
+	if (!node)
+		return -ENODEV;
 
 	ret = of_address_to_resource(node, 0, &res);
 	if (ret)
@@ -444,7 +442,6 @@ static int __init imx6_pm_get_base(struct imx6_pm_base *base,
 
 put_node:
 	of_node_put(node);
-out:
 	return ret;
 }
 
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index d228300..6c2ebf0 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -172,10 +172,8 @@ static struct mtd_partition aspenite_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data aspenite_nand_info = {
-	.enable_arbiter	= 1,
-	.num_cs = 1,
-	.parts[0]	= aspenite_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(aspenite_nand_partitions),
+	.parts		= aspenite_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(aspenite_nand_partitions),
 };
 
 static struct i2c_board_info aspenite_i2c_info[] __initdata = {
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index d90c74f..c7897fb 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -178,11 +178,8 @@ static struct mv_usb_platform_data ttc_usb_pdata = {
 #endif
 #endif
 
-#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx)
-static struct pxa3xx_nand_platform_data dkb_nand_info = {
-	.enable_arbiter = 1,
-	.num_cs = 1,
-};
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
+static struct pxa3xx_nand_platform_data dkb_nand_info = {};
 #endif
 
 #if IS_ENABLED(CONFIG_MMP_DISP)
@@ -275,7 +272,7 @@ static void __init ttc_dkb_init(void)
 
 	/* on-chip devices */
 	pxa910_add_uart(1);
-#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 	pxa910_add_nand(&dkb_nand_info);
 #endif
 
diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig
new file mode 100644
index 0000000..684c9c9
--- /dev/null
+++ b/arch/arm/mach-npcm/Kconfig
@@ -0,0 +1,30 @@
+menuconfig ARCH_NPCM
+	bool "Nuvoton NPCM Architecture"
+	depends on ARCH_MULTI_V7
+	select PINCTRL
+
+if ARCH_NPCM
+
+config ARCH_NPCM7XX
+	bool "Support for NPCM7xx BMC (Poleg)"
+	depends on ARCH_MULTI_V7
+	select PINCTRL_NPCM7XX
+	select NPCM7XX_TIMER
+	select ARCH_REQUIRE_GPIOLIB
+	select CACHE_L2X0
+	select ARM_GIC
+	select HAVE_ARM_TWD if SMP
+	select HAVE_ARM_SCU if SMP
+	select ARM_ERRATA_764369 if SMP
+	select ARM_ERRATA_720789
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_794072
+	select PL310_ERRATA_588369
+	select PL310_ERRATA_727915
+	select MFD_SYSCON
+	help
+	  General support for NPCM7xx BMC (Poleg).
+
+	  Nuvoton NPCM7xx BMC based on the Cortex A9.
+
+endif
diff --git a/arch/arm/mach-npcm/Makefile b/arch/arm/mach-npcm/Makefile
new file mode 100644
index 0000000..f5f6720
--- /dev/null
+++ b/arch/arm/mach-npcm/Makefile
@@ -0,0 +1,4 @@
+AFLAGS_headsmp.o		+= -march=armv7-a
+
+obj-$(CONFIG_ARCH_NPCM7XX)	+= npcm7xx.o
+obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
diff --git a/arch/arm/mach-npcm/headsmp.S b/arch/arm/mach-npcm/headsmp.S
new file mode 100644
index 0000000..c083fe0
--- /dev/null
+++ b/arch/arm/mach-npcm/headsmp.S
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Nuvoton Technology corporation.
+// Copyright 2018 Google, Inc.
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+
+/*
+ * The boot ROM does not start secondary CPUs in SVC mode, so we need to do that
+ * here.
+ */
+ENTRY(npcm7xx_secondary_startup)
+	safe_svcmode_maskall r0
+
+	b	secondary_startup
+ENDPROC(npcm7xx_secondary_startup)
diff --git a/arch/arm/mach-npcm/npcm7xx.c b/arch/arm/mach-npcm/npcm7xx.c
new file mode 100644
index 0000000..5f7cd88
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm7xx.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Nuvoton Technology corporation.
+// Copyright 2018 Google, Inc.
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
+static const char *const npcm7xx_dt_match[] = {
+	"nuvoton,npcm750",
+	NULL
+};
+
+DT_MACHINE_START(NPCM7XX_DT, "NPCM7XX Chip family")
+	.atag_offset	= 0x100,
+	.dt_compat	= npcm7xx_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-npcm/platsmp.c b/arch/arm/mach-npcm/platsmp.c
new file mode 100644
index 0000000..21633c7
--- /dev/null
+++ b/arch/arm/mach-npcm/platsmp.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Nuvoton Technology corporation.
+// Copyright 2018 Google, Inc.
+
+#define pr_fmt(fmt) "nuvoton,npcm7xx-smp: " fmt
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <asm/cacheflush.h>
+#include <asm/smp.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#define NPCM7XX_SCRPAD_REG 0x13c
+
+extern void npcm7xx_secondary_startup(void);
+
+static int npcm7xx_smp_boot_secondary(unsigned int cpu,
+				      struct task_struct *idle)
+{
+	struct device_node *gcr_np;
+	void __iomem *gcr_base;
+	int ret = 0;
+
+	gcr_np = of_find_compatible_node(NULL, NULL, "nuvoton,npcm750-gcr");
+	if (!gcr_np) {
+		pr_err("no gcr device node\n");
+		ret = -ENODEV;
+		goto out;
+	}
+	gcr_base = of_iomap(gcr_np, 0);
+	if (!gcr_base) {
+		pr_err("could not iomap gcr");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* give boot ROM kernel start address. */
+	iowrite32(__pa_symbol(npcm7xx_secondary_startup), gcr_base +
+		  NPCM7XX_SCRPAD_REG);
+	/* make sure the previous write is seen by all observers. */
+	dsb_sev();
+
+	iounmap(gcr_base);
+out:
+	return ret;
+}
+
+static void __init npcm7xx_smp_prepare_cpus(unsigned int max_cpus)
+{
+	struct device_node *scu_np;
+	void __iomem *scu_base;
+
+	scu_np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+	if (!scu_np) {
+		pr_err("no scu device node\n");
+		return;
+	}
+	scu_base = of_iomap(scu_np, 0);
+	if (!scu_base) {
+		pr_err("could not iomap scu");
+		return;
+	}
+
+	scu_enable(scu_base);
+
+	iounmap(scu_base);
+}
+
+static struct smp_operations npcm7xx_smp_ops __initdata = {
+	.smp_prepare_cpus = npcm7xx_smp_prepare_cpus,
+	.smp_boot_secondary = npcm7xx_smp_boot_secondary,
+};
+
+CPU_METHOD_OF_DECLARE(npcm7xx_smp, "nuvoton,npcm750-smp", &npcm7xx_smp_ops);
diff --git a/arch/arm/mach-nspire/nspire.c b/arch/arm/mach-nspire/nspire.c
index f0808fc..8584cdd 100644
--- a/arch/arm/mach-nspire/nspire.c
+++ b/arch/arm/mach-nspire/nspire.c
@@ -33,11 +33,6 @@ static const char *const nspire_dt_match[] __initconst = {
 	NULL,
 };
 
-static void __init nspire_map_io(void)
-{
-	debug_ll_io_init();
-}
-
 static struct clcd_board nspire_clcd_data = {
 	.name		= "LCD",
 	.caps		= CLCD_CAP_5551 | CLCD_CAP_565,
@@ -71,7 +66,6 @@ static void nspire_restart(enum reboot_mode mode, const char *cmd)
 
 DT_MACHINE_START(NSPIRE, "TI-NSPIRE")
 	.dt_compat	= nspire_dt_match,
-	.map_io		= nspire_map_io,
 	.init_machine	= nspire_init,
 	.restart	= nspire_restart,
 MACHINE_END
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 45c6b73..c4694f2 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -30,6 +30,7 @@
 	bool "OMAP16xx Based System"
 	select ARCH_OMAP_OTG
 	select CPU_ARM926T
+	select OMAP_DM_TIMER
 
 config OMAP_MUX
 	bool "OMAP multiplexing support"
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
index 65bb6e8..d83ff25 100644
--- a/arch/arm/mach-omap1/common.h
+++ b/arch/arm/mach-omap1/common.h
@@ -32,11 +32,10 @@
 
 #include <asm/exception.h>
 
-#include <plat/i2c.h>
-
 #include <mach/irqs.h>
 
 #include "soc.h"
+#include "i2c.h"
 
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 void omap7xx_map_io(void);
diff --git a/arch/arm/mach-omap1/i2c.c b/arch/arm/mach-omap1/i2c.c
index 32f6c53..5bdf3c4 100644
--- a/arch/arm/mach-omap1/i2c.c
+++ b/arch/arm/mach-omap1/i2c.c
@@ -24,8 +24,6 @@
 #include <mach/mux.h>
 #include "soc.h"
 
-#include <plat/i2c.h>
-
 #define OMAP_I2C_SIZE		0x3f
 #define OMAP1_I2C_BASE		0xfffb3800
 
diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/mach-omap1/i2c.h
similarity index 89%
rename from arch/arm/plat-omap/include/plat/i2c.h
rename to arch/arm/mach-omap1/i2c.h
index 810629d..54a2bce 100644
--- a/arch/arm/plat-omap/include/plat/i2c.h
+++ b/arch/arm/mach-omap1/i2c.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef __PLAT_OMAP_I2C_H
-#define __PLAT_OMAP_I2C_H
+#ifndef __ARCH_ARM_MACH_OMAP1_I2C_H
+#define __ARCH_ARM_MACH_OMAP1_I2C_H
 
 struct i2c_board_info;
 struct omap_i2c_bus_platform_data;
@@ -47,7 +47,4 @@ static inline int omap_register_i2c_bus_cmdline(void)
 }
 #endif
 
-struct omap_hwmod;
-int omap_i2c_reset(struct omap_hwmod *oh);
-
-#endif /* __PLAT_OMAP_I2C_H */
+#endif /* __ARCH_ARM_MACH_OMAP1_I2C_H */
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index f1135bf..3e1de14 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -55,7 +55,7 @@
 #include <mach/tc.h>
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
-#include <plat/dmtimer.h>
+#include <clocksource/timer-ti-dm.h>
 
 #include <mach/irqs.h>
 
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
index 8fb1ec6..4447210 100644
--- a/arch/arm/mach-omap1/timer.c
+++ b/arch/arm/mach-omap1/timer.c
@@ -27,7 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_data/dmtimer-omap.h>
 
-#include <plat/dmtimer.h>
+#include <clocksource/timer-ti-dm.h>
 
 #include "soc.h"
 
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 00b1f17..9f27b48 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -72,6 +72,7 @@
 	select ARM_ERRATA_754322
 	select ARM_ERRATA_775420
 	select OMAP_INTERCONNECT
+	select ARM_CPU_SUSPEND if PM
 
 config SOC_DRA7XX
 	bool "TI DRA7XX"
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index c15bbca..4603c30 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -88,6 +88,8 @@
 obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-pm-common)
 obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-pm-common)
 obj-$(CONFIG_SOC_DRA7XX)		+= $(omap-4-5-pm-common)
+obj-$(CONFIG_SOC_AM33XX)		+= pm33xx-core.o sleep33xx.o
+obj-$(CONFIG_SOC_AM43XX)		+= pm33xx-core.o sleep43xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 
 obj-$(CONFIG_POWER_AVS_OMAP)		+= sr_device.o
@@ -95,6 +97,8 @@
 
 AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
 AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep33xx.o			:=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep43xx.o			:=-Wa,-march=armv7-a$(plus_sec)
 
 endif
 
@@ -232,3 +236,15 @@
 obj-y					+= omap_phy_internal.o
 
 obj-$(CONFIG_MACH_OMAP2_TUSB6010)	+= usb-tusb6010.o
+
+arch/arm/mach-omap2/pm-asm-offsets.s: arch/arm/mach-omap2/pm-asm-offsets.c
+	$(call if_changed_dep,cc_s_c)
+
+include/generated/ti-pm-asm-offsets.h: arch/arm/mach-omap2/pm-asm-offsets.s FORCE
+	$(call filechk,offsets,__TI_PM_ASM_OFFSETS_H__)
+
+# For rule to generate ti-emif-asm-offsets.h dependency
+include drivers/memory/Makefile.asm-offsets
+
+arch/arm/mach-omap2/sleep33xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h
+arch/arm/mach-omap2/sleep43xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 20f2553..75bc186 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -566,11 +566,11 @@ static int n8x0_menelaus_late_init(struct device *dev)
 }
 #endif
 
-struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
+struct menelaus_platform_data n8x0_menelaus_platform_data = {
 	.late_init = n8x0_menelaus_late_init,
 };
 
-struct aic3x_pdata n810_aic33_data __initdata = {
+struct aic3x_pdata n810_aic33_data = {
 	.gpio_reset = 118,
 };
 
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index bc20283..fbe0b78 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -77,6 +77,13 @@ static inline int omap4_pm_init_early(void)
 }
 #endif
 
+#if defined(CONFIG_PM) && (defined(CONFIG_SOC_AM33XX) || \
+	defined(CONFIG_SOC_AM43XX))
+void amx3_common_pm_init(void);
+#else
+static inline void amx3_common_pm_init(void) { }
+#endif
+
 extern void omap2_init_common_infrastructure(void);
 
 extern void omap_init_time(void);
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index bd8089f..180da403 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -623,6 +623,7 @@ void __init omap3_ctrl_init(void)
 
 struct control_init_data {
 	int index;
+	void __iomem *mem;
 	s16 offset;
 };
 
@@ -635,6 +636,10 @@ static const struct control_init_data omap2_ctrl_data = {
 	.offset = -OMAP2_CONTROL_GENERAL,
 };
 
+static const struct control_init_data ctrl_aux_data = {
+	.index = TI_CLKM_CTRL_AUX,
+};
+
 static const struct of_device_id omap_scrm_dt_match_table[] = {
 	{ .compatible = "ti,am3-scm", .data = &ctrl_data },
 	{ .compatible = "ti,am4-scm", .data = &ctrl_data },
@@ -644,6 +649,7 @@ static const struct of_device_id omap_scrm_dt_match_table[] = {
 	{ .compatible = "ti,dm816-scrm", .data = &ctrl_data },
 	{ .compatible = "ti,omap4-scm-core", .data = &ctrl_data },
 	{ .compatible = "ti,omap5-scm-core", .data = &ctrl_data },
+	{ .compatible = "ti,omap5-scm-wkup-pad-conf", .data = &ctrl_aux_data },
 	{ .compatible = "ti,dra7-scm-core", .data = &ctrl_data },
 	{ }
 };
@@ -660,15 +666,21 @@ int __init omap2_control_base_init(void)
 	struct device_node *np;
 	const struct of_device_id *match;
 	struct control_init_data *data;
+	void __iomem *mem;
 
 	for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
 		data = (struct control_init_data *)match->data;
 
-		omap2_ctrl_base = of_iomap(np, 0);
-		if (!omap2_ctrl_base)
+		mem = of_iomap(np, 0);
+		if (!mem)
 			return -ENOMEM;
 
-		omap2_ctrl_offset = data->offset;
+		if (data->index == TI_CLKM_CTRL) {
+			omap2_ctrl_base = mem;
+			omap2_ctrl_offset = data->offset;
+		}
+
+		data->mem = mem;
 	}
 
 	return 0;
@@ -713,7 +725,7 @@ int __init omap_control_init(void)
 		} else {
 			/* No scm_conf found, direct access */
 			ret = omap2_clk_provider_init(np, data->index, NULL,
-						      omap2_ctrl_base);
+						      data->mem);
 			if (ret)
 				return ret;
 		}
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 93057fb..ed6f074 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -8,7 +8,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
-#include <linux/gpio.h>
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 6d28aa2..b064066 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -13,9 +13,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
-#include <linux/gpio.h>
 #include <linux/mmc/host.h>
-#include <linux/platform_data/gpio-omap.h>
 #include <linux/platform_data/hsmmc-omap.h>
 
 #include "soc.h"
diff --git a/arch/arm/mach-omap2/i2c.h b/arch/arm/mach-omap2/i2c.h
index 42b6f2e..4d085c7 100644
--- a/arch/arm/mach-omap2/i2c.h
+++ b/arch/arm/mach-omap2/i2c.h
@@ -19,23 +19,10 @@
  *
  */
 
-#include <plat/i2c.h>
-
 #ifndef __MACH_OMAP2_I2C_H
 #define __MACH_OMAP2_I2C_H
 
-/**
- * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod
- * @fifo_depth: total controller FIFO size (in bytes)
- * @flags: differences in hardware support capability
- *
- * @fifo_depth represents what exists on the hardware, not what is
- * actually configured at runtime by the device driver.
- */
-struct omap_i2c_dev_attr {
-	u8	fifo_depth;
-	u32	flags;
-};
+struct omap_hwmod;
 
 int omap_i2c_reset(struct omap_hwmod *oh);
 
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index cb5d731..cf546df 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -622,6 +622,7 @@ void __init am33xx_init_early(void)
 void __init am33xx_init_late(void)
 {
 	omap_common_late_init();
+	amx3_common_pm_init();
 }
 #endif
 
@@ -646,6 +647,7 @@ void __init am43xx_init_late(void)
 {
 	omap_common_late_init();
 	omap2_clk_enable_autoidle_all();
+	amx3_common_pm_init();
 }
 #endif
 
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c
index 5a3bc3d..978fba7 100644
--- a/arch/arm/mach-omap2/msdi.c
+++ b/arch/arm/mach-omap2/msdi.c
@@ -23,7 +23,6 @@
 
 #include <linux/kernel.h>
 #include <linux/err.h>
-#include <linux/platform_data/gpio-omap.h>
 
 #include "prm.h"
 #include "common.h"
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index 5b2966a..9fc4e26 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -28,7 +28,7 @@
 #define L2X0_AUXCTRL_OFFSET			0xff8
 #define L2X0_PREFETCH_CTRL_OFFSET		0xffc
 
-/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
+/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK1 */
 #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET		0xa04
 #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET		0xa08
 #define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index f038805..3b829a5 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -140,6 +140,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
 	struct omap_device *od;
 	struct omap_hwmod *oh;
 	struct device_node *node = pdev->dev.of_node;
+	struct resource res;
 	const char *oh_name;
 	int oh_cnt, i, ret = 0;
 	bool device_active = false;
@@ -150,6 +151,10 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	/* Use ti-sysc driver instead of omap_device? */
+	if (!omap_hwmod_parse_module_range(NULL, node, &res))
+		return -ENODEV;
+
 	hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
 	if (!hwmods) {
 		ret = -ENOMEM;
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 34156ec..e7d23e20 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -145,6 +145,8 @@
 
 #include <linux/platform_data/ti-sysc.h>
 
+#include <dt-bindings/bus/ti-sysc.h>
+
 #include <asm/system_misc.h>
 
 #include "clock.h"
@@ -2498,7 +2500,7 @@ static void __init _setup_postsetup(struct omap_hwmod *oh)
  * affects the IP block hardware, or system integration hardware
  * associated with the IP block.  Returns 0.
  */
-static int __init _setup(struct omap_hwmod *oh, void *data)
+static int _setup(struct omap_hwmod *oh, void *data)
 {
 	if (oh->_state != _HWMOD_STATE_INITIALIZED)
 		return 0;
@@ -3060,6 +3062,414 @@ int __init omap_hwmod_setup_one(const char *oh_name)
 	return 0;
 }
 
+static void omap_hwmod_check_one(struct device *dev,
+				 const char *name, s8 v1, u8 v2)
+{
+	if (v1 < 0)
+		return;
+
+	if (v1 != v2)
+		dev_warn(dev, "%s %d != %d\n", name, v1, v2);
+}
+
+/**
+ * omap_hwmod_check_sysc - check sysc against platform sysc
+ * @dev: struct device
+ * @data: module data
+ * @sysc_fields: new sysc configuration
+ */
+static int omap_hwmod_check_sysc(struct device *dev,
+				 const struct ti_sysc_module_data *data,
+				 struct sysc_regbits *sysc_fields)
+{
+	const struct sysc_regbits *regbits = data->cap->regbits;
+
+	omap_hwmod_check_one(dev, "dmadisable_shift",
+			     regbits->dmadisable_shift,
+			     sysc_fields->dmadisable_shift);
+	omap_hwmod_check_one(dev, "midle_shift",
+			     regbits->midle_shift,
+			     sysc_fields->midle_shift);
+	omap_hwmod_check_one(dev, "sidle_shift",
+			     regbits->sidle_shift,
+			     sysc_fields->sidle_shift);
+	omap_hwmod_check_one(dev, "clkact_shift",
+			     regbits->clkact_shift,
+			     sysc_fields->clkact_shift);
+	omap_hwmod_check_one(dev, "enwkup_shift",
+			     regbits->enwkup_shift,
+			     sysc_fields->enwkup_shift);
+	omap_hwmod_check_one(dev, "srst_shift",
+			     regbits->srst_shift,
+			     sysc_fields->srst_shift);
+	omap_hwmod_check_one(dev, "autoidle_shift",
+			     regbits->autoidle_shift,
+			     sysc_fields->autoidle_shift);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_init_regbits - init sysconfig specific register bits
+ * @dev: struct device
+ * @data: module data
+ * @sysc_fields: new sysc configuration
+ */
+static int omap_hwmod_init_regbits(struct device *dev,
+				   const struct ti_sysc_module_data *data,
+				   struct sysc_regbits **sysc_fields)
+{
+	*sysc_fields = NULL;
+
+	switch (data->cap->type) {
+	case TI_SYSC_OMAP2:
+	case TI_SYSC_OMAP2_TIMER:
+		*sysc_fields = &omap_hwmod_sysc_type1;
+		break;
+	case TI_SYSC_OMAP3_SHAM:
+		*sysc_fields = &omap3_sham_sysc_fields;
+		break;
+	case TI_SYSC_OMAP3_AES:
+		*sysc_fields = &omap3xxx_aes_sysc_fields;
+		break;
+	case TI_SYSC_OMAP4:
+	case TI_SYSC_OMAP4_TIMER:
+		*sysc_fields = &omap_hwmod_sysc_type2;
+		break;
+	case TI_SYSC_OMAP4_SIMPLE:
+		*sysc_fields = &omap_hwmod_sysc_type3;
+		break;
+	case TI_SYSC_OMAP34XX_SR:
+		*sysc_fields = &omap34xx_sr_sysc_fields;
+		break;
+	case TI_SYSC_OMAP36XX_SR:
+		*sysc_fields = &omap36xx_sr_sysc_fields;
+		break;
+	case TI_SYSC_OMAP4_SR:
+		*sysc_fields = &omap36xx_sr_sysc_fields;
+		break;
+	case TI_SYSC_OMAP4_MCASP:
+		*sysc_fields = &omap_hwmod_sysc_type_mcasp;
+		break;
+	case TI_SYSC_OMAP4_USB_HOST_FS:
+		*sysc_fields = &omap_hwmod_sysc_type_usb_host_fs;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return omap_hwmod_check_sysc(dev, data, *sysc_fields);
+}
+
+/**
+ * omap_hwmod_init_reg_offs - initialize sysconfig register offsets
+ * @dev: struct device
+ * @data: module data
+ * @rev_offs: revision register offset
+ * @sysc_offs: sysc register offset
+ * @syss_offs: syss register offset
+ */
+int omap_hwmod_init_reg_offs(struct device *dev,
+			     const struct ti_sysc_module_data *data,
+			     u32 *rev_offs, u32 *sysc_offs, u32 *syss_offs)
+{
+	*rev_offs = 0;
+	*sysc_offs = 0;
+	*syss_offs = 0;
+
+	if (data->offsets[SYSC_REVISION] > 0)
+		*rev_offs = data->offsets[SYSC_REVISION];
+
+	if (data->offsets[SYSC_SYSCONFIG] > 0)
+		*sysc_offs = data->offsets[SYSC_SYSCONFIG];
+
+	if (data->offsets[SYSC_SYSSTATUS] > 0)
+		*syss_offs = data->offsets[SYSC_SYSSTATUS];
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_init_sysc_flags - initialize sysconfig features
+ * @dev: struct device
+ * @data: module data
+ * @sysc_flags: module configuration
+ */
+int omap_hwmod_init_sysc_flags(struct device *dev,
+			       const struct ti_sysc_module_data *data,
+			       u32 *sysc_flags)
+{
+	*sysc_flags = 0;
+
+	switch (data->cap->type) {
+	case TI_SYSC_OMAP2:
+	case TI_SYSC_OMAP2_TIMER:
+		/* See SYSC_OMAP2_* in include/dt-bindings/bus/ti-sysc.h */
+		if (data->cfg->sysc_val & SYSC_OMAP2_CLOCKACTIVITY)
+			*sysc_flags |= SYSC_HAS_CLOCKACTIVITY;
+		if (data->cfg->sysc_val & SYSC_OMAP2_EMUFREE)
+			*sysc_flags |= SYSC_HAS_EMUFREE;
+		if (data->cfg->sysc_val & SYSC_OMAP2_ENAWAKEUP)
+			*sysc_flags |= SYSC_HAS_ENAWAKEUP;
+		if (data->cfg->sysc_val & SYSC_OMAP2_SOFTRESET)
+			*sysc_flags |= SYSC_HAS_SOFTRESET;
+		if (data->cfg->sysc_val & SYSC_OMAP2_AUTOIDLE)
+			*sysc_flags |= SYSC_HAS_AUTOIDLE;
+		break;
+	case TI_SYSC_OMAP4:
+	case TI_SYSC_OMAP4_TIMER:
+		/* See SYSC_OMAP4_* in include/dt-bindings/bus/ti-sysc.h */
+		if (data->cfg->sysc_val & SYSC_OMAP4_DMADISABLE)
+			*sysc_flags |= SYSC_HAS_DMADISABLE;
+		if (data->cfg->sysc_val & SYSC_OMAP4_FREEEMU)
+			*sysc_flags |= SYSC_HAS_EMUFREE;
+		if (data->cfg->sysc_val & SYSC_OMAP4_SOFTRESET)
+			*sysc_flags |= SYSC_HAS_SOFTRESET;
+		break;
+	case TI_SYSC_OMAP34XX_SR:
+	case TI_SYSC_OMAP36XX_SR:
+		/* See SYSC_OMAP3_SR_* in include/dt-bindings/bus/ti-sysc.h */
+		if (data->cfg->sysc_val & SYSC_OMAP3_SR_ENAWAKEUP)
+			*sysc_flags |= SYSC_HAS_ENAWAKEUP;
+		break;
+	default:
+		if (data->cap->regbits->emufree_shift >= 0)
+			*sysc_flags |= SYSC_HAS_EMUFREE;
+		if (data->cap->regbits->enwkup_shift >= 0)
+			*sysc_flags |= SYSC_HAS_ENAWAKEUP;
+		if (data->cap->regbits->srst_shift >= 0)
+			*sysc_flags |= SYSC_HAS_SOFTRESET;
+		if (data->cap->regbits->autoidle_shift >= 0)
+			*sysc_flags |= SYSC_HAS_AUTOIDLE;
+		break;
+	}
+
+	if (data->cap->regbits->midle_shift >= 0 &&
+	    data->cfg->midlemodes)
+		*sysc_flags |= SYSC_HAS_MIDLEMODE;
+
+	if (data->cap->regbits->sidle_shift >= 0 &&
+	    data->cfg->sidlemodes)
+		*sysc_flags |= SYSC_HAS_SIDLEMODE;
+
+	if (data->cfg->quirks & SYSC_QUIRK_UNCACHED)
+		*sysc_flags |= SYSC_NO_CACHE;
+	if (data->cfg->quirks & SYSC_QUIRK_RESET_STATUS)
+		*sysc_flags |= SYSC_HAS_RESET_STATUS;
+
+	if (data->cfg->syss_mask & 1)
+		*sysc_flags |= SYSS_HAS_RESET_STATUS;
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_init_idlemodes - initialize module idle modes
+ * @dev: struct device
+ * @data: module data
+ * @idlemodes: module supported idle modes
+ */
+int omap_hwmod_init_idlemodes(struct device *dev,
+			      const struct ti_sysc_module_data *data,
+			      u32 *idlemodes)
+{
+	*idlemodes = 0;
+
+	if (data->cfg->midlemodes & BIT(SYSC_IDLE_FORCE))
+		*idlemodes |= MSTANDBY_FORCE;
+	if (data->cfg->midlemodes & BIT(SYSC_IDLE_NO))
+		*idlemodes |= MSTANDBY_NO;
+	if (data->cfg->midlemodes & BIT(SYSC_IDLE_SMART))
+		*idlemodes |= MSTANDBY_SMART;
+	if (data->cfg->midlemodes & BIT(SYSC_IDLE_SMART_WKUP))
+		*idlemodes |= MSTANDBY_SMART_WKUP;
+
+	if (data->cfg->sidlemodes & BIT(SYSC_IDLE_FORCE))
+		*idlemodes |= SIDLE_FORCE;
+	if (data->cfg->sidlemodes & BIT(SYSC_IDLE_NO))
+		*idlemodes |= SIDLE_NO;
+	if (data->cfg->sidlemodes & BIT(SYSC_IDLE_SMART))
+		*idlemodes |= SIDLE_SMART;
+	if (data->cfg->sidlemodes & BIT(SYSC_IDLE_SMART_WKUP))
+		*idlemodes |= SIDLE_SMART_WKUP;
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_check_module - check new module against platform data
+ * @dev: struct device
+ * @oh: module
+ * @data: new module data
+ * @sysc_fields: sysc register bits
+ * @rev_offs: revision register offset
+ * @sysc_offs: sysconfig register offset
+ * @syss_offs: sysstatus register offset
+ * @sysc_flags: sysc specific flags
+ * @idlemodes: sysc supported idlemodes
+ */
+static int omap_hwmod_check_module(struct device *dev,
+				   struct omap_hwmod *oh,
+				   const struct ti_sysc_module_data *data,
+				   struct sysc_regbits *sysc_fields,
+				   u32 rev_offs, u32 sysc_offs,
+				   u32 syss_offs, u32 sysc_flags,
+				   u32 idlemodes)
+{
+	if (!oh->class->sysc)
+		return -ENODEV;
+
+	if (sysc_fields != oh->class->sysc->sysc_fields)
+		dev_warn(dev, "sysc_fields %p != %p\n", sysc_fields,
+			 oh->class->sysc->sysc_fields);
+
+	if (rev_offs != oh->class->sysc->rev_offs)
+		dev_warn(dev, "rev_offs %08x != %08x\n", rev_offs,
+			 oh->class->sysc->rev_offs);
+	if (sysc_offs != oh->class->sysc->sysc_offs)
+		dev_warn(dev, "sysc_offs %08x != %08x\n", sysc_offs,
+			 oh->class->sysc->sysc_offs);
+	if (syss_offs != oh->class->sysc->syss_offs)
+		dev_warn(dev, "syss_offs %08x != %08x\n", syss_offs,
+			 oh->class->sysc->syss_offs);
+
+	if (sysc_flags != oh->class->sysc->sysc_flags)
+		dev_warn(dev, "sysc_flags %08x != %08x\n", sysc_flags,
+			 oh->class->sysc->sysc_flags);
+
+	if (idlemodes != oh->class->sysc->idlemodes)
+		dev_warn(dev, "idlemodes %08x != %08x\n", idlemodes,
+			 oh->class->sysc->idlemodes);
+
+	if (data->cfg->srst_udelay != oh->class->sysc->srst_udelay)
+		dev_warn(dev, "srst_udelay %i != %i\n",
+			 data->cfg->srst_udelay,
+			 oh->class->sysc->srst_udelay);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_allocate_module - allocate new module
+ * @dev: struct device
+ * @oh: module
+ * @sysc_fields: sysc register bits
+ * @rev_offs: revision register offset
+ * @sysc_offs: sysconfig register offset
+ * @syss_offs: sysstatus register offset
+ * @sysc_flags: sysc specific flags
+ * @idlemodes: sysc supported idlemodes
+ *
+ * Note that the allocations here cannot use devm as ti-sysc can rebind.
+ */
+int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
+			       const struct ti_sysc_module_data *data,
+			       struct sysc_regbits *sysc_fields,
+			       u32 rev_offs, u32 sysc_offs, u32 syss_offs,
+			       u32 sysc_flags, u32 idlemodes)
+{
+	struct omap_hwmod_class_sysconfig *sysc;
+	struct omap_hwmod_class *class;
+	void __iomem *regs = NULL;
+	unsigned long flags;
+
+	sysc = kzalloc(sizeof(*sysc), GFP_KERNEL);
+	if (!sysc)
+		return -ENOMEM;
+
+	sysc->sysc_fields = sysc_fields;
+	sysc->rev_offs = rev_offs;
+	sysc->sysc_offs = sysc_offs;
+	sysc->syss_offs = syss_offs;
+	sysc->sysc_flags = sysc_flags;
+	sysc->idlemodes = idlemodes;
+	sysc->srst_udelay = data->cfg->srst_udelay;
+
+	if (!oh->_mpu_rt_va) {
+		regs = ioremap(data->module_pa,
+			       data->module_size);
+		if (!regs)
+			return -ENOMEM;
+	}
+
+	/*
+	 * We need new oh->class as the other devices in the same class
+	 * may not yet have ioremapped their registers.
+	 */
+	class = kmemdup(oh->class, sizeof(*oh->class), GFP_KERNEL);
+	if (!class)
+		return -ENOMEM;
+
+	class->sysc = sysc;
+
+	spin_lock_irqsave(&oh->_lock, flags);
+	if (regs)
+		oh->_mpu_rt_va = regs;
+	oh->class = class;
+	oh->_state = _HWMOD_STATE_INITIALIZED;
+	_setup(oh, NULL);
+	spin_unlock_irqrestore(&oh->_lock, flags);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_init_module - initialize new module
+ * @dev: struct device
+ * @data: module data
+ * @cookie: cookie for the caller to use for later calls
+ */
+int omap_hwmod_init_module(struct device *dev,
+			   const struct ti_sysc_module_data *data,
+			   struct ti_sysc_cookie *cookie)
+{
+	struct omap_hwmod *oh;
+	struct sysc_regbits *sysc_fields;
+	u32 rev_offs, sysc_offs, syss_offs, sysc_flags, idlemodes;
+	int error;
+
+	if (!dev || !data)
+		return -EINVAL;
+
+	oh = _lookup(data->name);
+	if (!oh)
+		return -ENODEV;
+
+	cookie->data = oh;
+
+	error = omap_hwmod_init_regbits(dev, data, &sysc_fields);
+	if (error)
+		return error;
+
+	error = omap_hwmod_init_reg_offs(dev, data, &rev_offs,
+					 &sysc_offs, &syss_offs);
+	if (error)
+		return error;
+
+	error = omap_hwmod_init_sysc_flags(dev, data, &sysc_flags);
+	if (error)
+		return error;
+
+	error = omap_hwmod_init_idlemodes(dev, data, &idlemodes);
+	if (error)
+		return error;
+
+	if (data->cfg->quirks & SYSC_QUIRK_NO_IDLE_ON_INIT)
+		oh->flags |= HWMOD_INIT_NO_IDLE;
+	if (data->cfg->quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
+		oh->flags |= HWMOD_INIT_NO_RESET;
+
+	error = omap_hwmod_check_module(dev, oh, data, sysc_fields,
+					rev_offs, sysc_offs, syss_offs,
+					sysc_flags, idlemodes);
+	if (!error)
+		return error;
+
+	return omap_hwmod_allocate_module(dev, oh, data, sysc_fields,
+					  rev_offs, sysc_offs, syss_offs,
+					  sysc_flags, idlemodes);
+}
+
 /**
  * omap_hwmod_setup_earlycon_flags - set up flags for early console
  *
@@ -3082,6 +3492,12 @@ static void __init omap_hwmod_setup_earlycon_flags(void)
 			if (np) {
 				uart = of_get_property(np, "ti,hwmods", NULL);
 				oh = omap_hwmod_lookup(uart);
+				if (!oh) {
+					uart = of_get_property(np->parent,
+							       "ti,hwmods",
+							       NULL);
+					oh = omap_hwmod_lookup(uart);
+				}
 				if (oh)
 					oh->flags |= DEBUG_OMAPUART_FLAGS;
 			}
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 0b8e19f..c7122ab 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -620,6 +620,13 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
 				  struct device_node *np,
 				  struct resource *res);
 
+struct ti_sysc_module_data;
+struct ti_sysc_cookie;
+
+int omap_hwmod_init_module(struct device *dev,
+			   const struct ti_sysc_module_data *data,
+			   struct ti_sysc_cookie *cookie);
+
 int omap_hwmod_enable(struct omap_hwmod *oh);
 int omap_hwmod_idle(struct omap_hwmod *oh);
 int omap_hwmod_shutdown(struct omap_hwmod *oh);
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 0afb014..fe66cf2 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -14,9 +14,7 @@
  */
 
 #include <linux/i2c-omap.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/omap-dma.h>
-#include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
@@ -97,13 +95,6 @@ static struct omap_hwmod_class i2c_class = {
 	.reset		= &omap_i2c_reset,
 };
 
-static struct omap_i2c_dev_attr i2c_dev_attr = {
-	.flags		= OMAP_I2C_FLAG_NO_FIFO |
-			  OMAP_I2C_FLAG_SIMPLE_CLOCK |
-			  OMAP_I2C_FLAG_16BIT_DATA_REG |
-			  OMAP_I2C_FLAG_BUS_SHIFT_2,
-};
-
 /* I2C1 */
 static struct omap_hwmod omap2420_i2c1_hwmod = {
 	.name		= "i2c1",
@@ -116,7 +107,6 @@ static struct omap_hwmod omap2420_i2c1_hwmod = {
 		},
 	},
 	.class		= &i2c_class,
-	.dev_attr	= &i2c_dev_attr,
 	/*
 	 * From mach-omap2/pm24xx.c: "Putting MPU into the WFI state
 	 * while a transfer is active seems to cause the I2C block to
@@ -137,7 +127,6 @@ static struct omap_hwmod omap2420_i2c2_hwmod = {
 		},
 	},
 	.class		= &i2c_class,
-	.dev_attr	= &i2c_dev_attr,
 	.flags		= HWMOD_16BIT_REG,
 };
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 013b26b..74eefd3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -14,11 +14,8 @@
  */
 
 #include <linux/i2c-omap.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/hsmmc-omap.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/omap-dma.h>
-#include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
@@ -75,12 +72,6 @@ static struct omap_hwmod_class i2c_class = {
 	.reset		= &omap_i2c_reset,
 };
 
-static struct omap_i2c_dev_attr i2c_dev_attr = {
-	.fifo_depth	= 8, /* bytes */
-	.flags		= OMAP_I2C_FLAG_BUS_SHIFT_2 |
-			  OMAP_I2C_FLAG_FORCE_19200_INT_CLK,
-};
-
 /* I2C1 */
 static struct omap_hwmod omap2430_i2c1_hwmod = {
 	.name		= "i2c1",
@@ -102,7 +93,6 @@ static struct omap_hwmod omap2430_i2c1_hwmod = {
 		},
 	},
 	.class		= &i2c_class,
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* I2C2 */
@@ -118,7 +108,6 @@ static struct omap_hwmod omap2430_i2c2_hwmod = {
 		},
 	},
 	.class		= &i2c_class,
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* gpio5 */
@@ -134,7 +123,6 @@ static struct omap_hwmod omap2430_gpio5_hwmod = {
 		},
 	},
 	.class		= &omap2xxx_gpio_hwmod_class,
-	.dev_attr	= &omap2xxx_gpio_dev_attr,
 };
 
 /* dma attributes */
@@ -167,10 +155,6 @@ static struct omap_hwmod omap2430_mailbox_hwmod = {
 };
 
 /* mcspi3 */
-static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = {
-	.num_chipselect = 2,
-};
-
 static struct omap_hwmod omap2430_mcspi3_hwmod = {
 	.name		= "mcspi3",
 	.main_clk	= "mcspi3_fck",
@@ -182,7 +166,6 @@ static struct omap_hwmod omap2430_mcspi3_hwmod = {
 		},
 	},
 	.class		= &omap2xxx_mcspi_class,
-	.dev_attr	= &omap_mcspi3_dev_attr,
 };
 
 /* usbhsotg */
@@ -239,7 +222,6 @@ static struct omap_hwmod_class_sysconfig omap2430_mcbsp_sysc = {
 static struct omap_hwmod_class omap2430_mcbsp_hwmod_class = {
 	.name = "mcbsp",
 	.sysc = &omap2430_mcbsp_sysc,
-	.rev  = MCBSP_CONFIG_TYPE2,
 };
 
 static struct omap_hwmod_opt_clk mcbsp_opt_clks[] = {
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 4b094cb..5345919 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -9,10 +9,8 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/platform_data/gpio-omap.h>
+#include <linux/types.h>
 #include <linux/omap-dma.h>
-#include <plat/dmtimer.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
@@ -159,7 +157,6 @@ static struct omap_hwmod_class_sysconfig omap2xxx_mcspi_sysc = {
 struct omap_hwmod_class omap2xxx_mcspi_class = {
 	.name	= "mcspi",
 	.sysc	= &omap2xxx_mcspi_sysc,
-	.rev	= OMAP2_MCSPI_REV,
 };
 
 /*
@@ -220,23 +217,7 @@ struct omap_hwmod omap2xxx_iva_hwmod = {
 	.class		= &iva_hwmod_class,
 };
 
-/* always-on timers dev attribute */
-static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
-	.timer_capability       = OMAP_TIMER_ALWON,
-};
-
-/* pwm timers dev attribute */
-static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
-	.timer_capability       = OMAP_TIMER_HAS_PWM,
-};
-
-/* timers with DSP interrupt dev attribute */
-static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
-	.timer_capability       = OMAP_TIMER_HAS_DSP_IRQ,
-};
-
 /* timer1 */
-
 struct omap_hwmod omap2xxx_timer1_hwmod = {
 	.name		= "timer1",
 	.main_clk	= "gpt1_fck",
@@ -247,13 +228,11 @@ struct omap_hwmod omap2xxx_timer1_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer2 */
-
 struct omap_hwmod omap2xxx_timer2_hwmod = {
 	.name		= "timer2",
 	.main_clk	= "gpt2_fck",
@@ -269,7 +248,6 @@ struct omap_hwmod omap2xxx_timer2_hwmod = {
 };
 
 /* timer3 */
-
 struct omap_hwmod omap2xxx_timer3_hwmod = {
 	.name		= "timer3",
 	.main_clk	= "gpt3_fck",
@@ -285,7 +263,6 @@ struct omap_hwmod omap2xxx_timer3_hwmod = {
 };
 
 /* timer4 */
-
 struct omap_hwmod omap2xxx_timer4_hwmod = {
 	.name		= "timer4",
 	.main_clk	= "gpt4_fck",
@@ -301,7 +278,6 @@ struct omap_hwmod omap2xxx_timer4_hwmod = {
 };
 
 /* timer5 */
-
 struct omap_hwmod omap2xxx_timer5_hwmod = {
 	.name		= "timer5",
 	.main_clk	= "gpt5_fck",
@@ -312,13 +288,11 @@ struct omap_hwmod omap2xxx_timer5_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer6 */
-
 struct omap_hwmod omap2xxx_timer6_hwmod = {
 	.name		= "timer6",
 	.main_clk	= "gpt6_fck",
@@ -329,13 +303,11 @@ struct omap_hwmod omap2xxx_timer6_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer7 */
-
 struct omap_hwmod omap2xxx_timer7_hwmod = {
 	.name		= "timer7",
 	.main_clk	= "gpt7_fck",
@@ -346,13 +318,11 @@ struct omap_hwmod omap2xxx_timer7_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer8 */
-
 struct omap_hwmod omap2xxx_timer8_hwmod = {
 	.name		= "timer8",
 	.main_clk	= "gpt8_fck",
@@ -363,13 +333,11 @@ struct omap_hwmod omap2xxx_timer8_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer9 */
-
 struct omap_hwmod omap2xxx_timer9_hwmod = {
 	.name		= "timer9",
 	.main_clk	= "gpt9_fck",
@@ -380,13 +348,11 @@ struct omap_hwmod omap2xxx_timer9_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer10 */
-
 struct omap_hwmod omap2xxx_timer10_hwmod = {
 	.name		= "timer10",
 	.main_clk	= "gpt10_fck",
@@ -397,13 +363,11 @@ struct omap_hwmod omap2xxx_timer10_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer11 */
-
 struct omap_hwmod omap2xxx_timer11_hwmod = {
 	.name		= "timer11",
 	.main_clk	= "gpt11_fck",
@@ -414,13 +378,11 @@ struct omap_hwmod omap2xxx_timer11_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer12 */
-
 struct omap_hwmod omap2xxx_timer12_hwmod = {
 	.name		= "timer12",
 	.main_clk	= "gpt12_fck",
@@ -431,7 +393,6 @@ struct omap_hwmod omap2xxx_timer12_hwmod = {
 			.idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 	.class		= &omap2xxx_timer_hwmod_class,
 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -568,12 +529,6 @@ struct omap_hwmod omap2xxx_dss_venc_hwmod = {
 	.flags		= HWMOD_NO_IDLEST,
 };
 
-/* gpio dev_attr */
-struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr = {
-	.bank_width = 32,
-	.dbck_flag = false,
-};
-
 /* gpio1 */
 struct omap_hwmod omap2xxx_gpio1_hwmod = {
 	.name		= "gpio1",
@@ -587,7 +542,6 @@ struct omap_hwmod omap2xxx_gpio1_hwmod = {
 		},
 	},
 	.class		= &omap2xxx_gpio_hwmod_class,
-	.dev_attr	= &omap2xxx_gpio_dev_attr,
 };
 
 /* gpio2 */
@@ -603,7 +557,6 @@ struct omap_hwmod omap2xxx_gpio2_hwmod = {
 		},
 	},
 	.class		= &omap2xxx_gpio_hwmod_class,
-	.dev_attr	= &omap2xxx_gpio_dev_attr,
 };
 
 /* gpio3 */
@@ -619,7 +572,6 @@ struct omap_hwmod omap2xxx_gpio3_hwmod = {
 		},
 	},
 	.class		= &omap2xxx_gpio_hwmod_class,
-	.dev_attr	= &omap2xxx_gpio_dev_attr,
 };
 
 /* gpio4 */
@@ -635,14 +587,9 @@ struct omap_hwmod omap2xxx_gpio4_hwmod = {
 		},
 	},
 	.class		= &omap2xxx_gpio_hwmod_class,
-	.dev_attr	= &omap2xxx_gpio_dev_attr,
 };
 
 /* mcspi1 */
-static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = {
-	.num_chipselect = 4,
-};
-
 struct omap_hwmod omap2xxx_mcspi1_hwmod = {
 	.name		= "mcspi1",
 	.main_clk	= "mcspi1_fck",
@@ -654,14 +601,9 @@ struct omap_hwmod omap2xxx_mcspi1_hwmod = {
 		},
 	},
 	.class		= &omap2xxx_mcspi_class,
-	.dev_attr	= &omap_mcspi1_dev_attr,
 };
 
 /* mcspi2 */
-static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = {
-	.num_chipselect = 2,
-};
-
 struct omap_hwmod omap2xxx_mcspi2_hwmod = {
 	.name		= "mcspi2",
 	.main_clk	= "mcspi2_fck",
@@ -673,7 +615,6 @@ struct omap_hwmod omap2xxx_mcspi2_hwmod = {
 		},
 	},
 	.class		= &omap2xxx_mcspi_class,
-	.dev_attr	= &omap_mcspi2_dev_attr,
 };
 
 static struct omap_hwmod_class omap2xxx_counter_hwmod_class = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
index 434bd1a..6f81d7a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
@@ -139,9 +139,6 @@ extern struct omap_hwmod_class am33xx_epwmss_hwmod_class;
 extern struct omap_hwmod_class am33xx_ehrpwm_hwmod_class;
 extern struct omap_hwmod_class am33xx_spi_hwmod_class;
 
-extern struct omap_gpio_dev_attr gpio_dev_attr;
-extern struct omap2_mcspi_dev_attr mcspi_attrib;
-
 void omap_hwmod_am33xx_reg(void);
 void omap_hwmod_am43xx_reg(void);
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
index 4bcf9f3..5efe91c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
@@ -14,9 +14,9 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/platform_data/gpio-omap.h>
+#include <linux/types.h>
+
 #include <linux/platform_data/hsmmc-omap.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
 #include "omap_hwmod.h"
 #include "i2c.h"
 #include "wd_timer.h"
@@ -537,11 +537,6 @@ struct omap_hwmod_class am33xx_gpio_hwmod_class = {
 	.rev		= 2,
 };
 
-struct omap_gpio_dev_attr gpio_dev_attr = {
-	.bank_width	= 32,
-	.dbck_flag	= true,
-};
-
 /* gpio1 */
 static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio1_dbclk" },
@@ -560,7 +555,6 @@ struct omap_hwmod am33xx_gpio1_hwmod = {
 	},
 	.opt_clks	= gpio1_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio1_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio2 */
@@ -581,7 +575,6 @@ struct omap_hwmod am33xx_gpio2_hwmod = {
 	},
 	.opt_clks	= gpio2_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio2_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio3 */
@@ -602,7 +595,6 @@ struct omap_hwmod am33xx_gpio3_hwmod = {
 	},
 	.opt_clks	= gpio3_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio3_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpmc */
@@ -654,10 +646,6 @@ static struct omap_hwmod_class i2c_class = {
 	.reset		= &omap_i2c_reset,
 };
 
-static struct omap_i2c_dev_attr i2c_dev_attr = {
-	.flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
-};
-
 /* i2c1 */
 struct omap_hwmod am33xx_i2c1_hwmod = {
 	.name		= "i2c1",
@@ -670,7 +658,6 @@ struct omap_hwmod am33xx_i2c1_hwmod = {
 			.modulemode	= MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c1 */
@@ -685,7 +672,6 @@ struct omap_hwmod am33xx_i2c2_hwmod = {
 			.modulemode	= MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c3 */
@@ -700,7 +686,6 @@ struct omap_hwmod am33xx_i2c3_hwmod = {
 			.modulemode	= MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /*
@@ -893,13 +878,9 @@ static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = {
 struct omap_hwmod_class am33xx_spi_hwmod_class = {
 	.name		= "mcspi",
 	.sysc		= &am33xx_mcspi_sysc,
-	.rev		= OMAP4_MCSPI_REV,
 };
 
 /* spi0 */
-struct omap2_mcspi_dev_attr mcspi_attrib = {
-	.num_chipselect	= 2,
-};
 struct omap_hwmod am33xx_spi0_hwmod = {
 	.name		= "spi0",
 	.class		= &am33xx_spi_hwmod_class,
@@ -910,7 +891,6 @@ struct omap_hwmod am33xx_spi0_hwmod = {
 			.modulemode	= MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi_attrib,
 };
 
 /* spi1 */
@@ -924,7 +904,6 @@ struct omap_hwmod am33xx_spi1_hwmod = {
 			.modulemode	= MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi_attrib,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 4d16b15..53e1ac3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -17,9 +17,6 @@
 #include <linux/i2c-omap.h>
 
 #include "omap_hwmod.h"
-#include <linux/platform_data/gpio-omap.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
-
 #include "omap_hwmod_common_data.h"
 
 #include "control.h"
@@ -252,7 +249,6 @@ static struct omap_hwmod am33xx_gpio0_hwmod = {
 	},
 	.opt_clks	= gpio0_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio0_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* lcdc */
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 1a2f224..23336b6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -17,15 +17,11 @@
 
 #include <linux/i2c-omap.h>
 #include <linux/power/smartreflex.h>
-#include <linux/platform_data/gpio-omap.h>
 #include <linux/platform_data/hsmmc-omap.h>
 
 #include <linux/omap-dma.h>
 #include "l3_3xxx.h"
 #include "l4_3xxx.h"
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <plat/dmtimer.h>
 
 #include "soc.h"
 #include "omap_hwmod.h"
@@ -155,31 +151,6 @@ static struct omap_hwmod_class omap3xxx_timer_hwmod_class = {
 	.sysc = &omap3xxx_timer_sysc,
 };
 
-/* secure timers dev attribute */
-static struct omap_timer_capability_dev_attr capability_secure_dev_attr = {
-	.timer_capability	= OMAP_TIMER_ALWON | OMAP_TIMER_SECURE,
-};
-
-/* always-on timers dev attribute */
-static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
-	.timer_capability	= OMAP_TIMER_ALWON,
-};
-
-/* pwm timers dev attribute */
-static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
-	.timer_capability	= OMAP_TIMER_HAS_PWM,
-};
-
-/* timers with DSP interrupt dev attribute */
-static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
-	.timer_capability       = OMAP_TIMER_HAS_DSP_IRQ,
-};
-
-/* pwm timers with DSP interrupt dev attribute */
-static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = {
-	.timer_capability       = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM,
-};
-
 /* timer1 */
 static struct omap_hwmod omap3xxx_timer1_hwmod = {
 	.name		= "timer1",
@@ -191,7 +162,6 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT1_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -252,7 +222,6 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -268,7 +237,6 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -284,7 +252,6 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -300,7 +267,6 @@ static struct omap_hwmod omap3xxx_timer8_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT8_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_dsp_pwm_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -316,7 +282,6 @@ static struct omap_hwmod omap3xxx_timer9_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT9_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -332,7 +297,6 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -348,13 +312,11 @@ static struct omap_hwmod omap3xxx_timer11_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT11_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
 /* timer12 */
-
 static struct omap_hwmod omap3xxx_timer12_hwmod = {
 	.name		= "timer12",
 	.main_clk	= "gpt12_fck",
@@ -365,7 +327,6 @@ static struct omap_hwmod omap3xxx_timer12_hwmod = {
 			.idlest_idle_bit = OMAP3430_ST_GPT12_SHIFT,
 		},
 	},
-	.dev_attr	= &capability_secure_dev_attr,
 	.class		= &omap3xxx_timer_hwmod_class,
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
 };
@@ -683,11 +644,6 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
 };
 
 /* I2C1 */
-static struct omap_i2c_dev_attr i2c1_dev_attr = {
-	.fifo_depth	= 8, /* bytes */
-	.flags		= OMAP_I2C_FLAG_BUS_SHIFT_2,
-};
-
 static struct omap_hwmod omap3xxx_i2c1_hwmod = {
 	.name		= "i2c1",
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
@@ -700,15 +656,9 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = {
 		},
 	},
 	.class		= &i2c_class,
-	.dev_attr	= &i2c1_dev_attr,
 };
 
 /* I2C2 */
-static struct omap_i2c_dev_attr i2c2_dev_attr = {
-	.fifo_depth	= 8, /* bytes */
-	.flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
-};
-
 static struct omap_hwmod omap3xxx_i2c2_hwmod = {
 	.name		= "i2c2",
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
@@ -721,17 +671,9 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = {
 		},
 	},
 	.class		= &i2c_class,
-	.dev_attr	= &i2c2_dev_attr,
 };
 
 /* I2C3 */
-static struct omap_i2c_dev_attr i2c3_dev_attr = {
-	.fifo_depth	= 64, /* bytes */
-	.flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
-};
-
-
-
 static struct omap_hwmod omap3xxx_i2c3_hwmod = {
 	.name		= "i2c3",
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
@@ -744,7 +686,6 @@ static struct omap_hwmod omap3xxx_i2c3_hwmod = {
 		},
 	},
 	.class		= &i2c_class,
-	.dev_attr	= &i2c3_dev_attr,
 };
 
 /*
@@ -769,12 +710,6 @@ static struct omap_hwmod_class omap3xxx_gpio_hwmod_class = {
 	.rev = 1,
 };
 
-/* gpio_dev_attr */
-static struct omap_gpio_dev_attr gpio_dev_attr = {
-	.bank_width = 32,
-	.dbck_flag = true,
-};
-
 /* gpio1 */
 static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio1_dbck", },
@@ -794,7 +729,6 @@ static struct omap_hwmod omap3xxx_gpio1_hwmod = {
 		},
 	},
 	.class		= &omap3xxx_gpio_hwmod_class,
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio2 */
@@ -816,7 +750,6 @@ static struct omap_hwmod omap3xxx_gpio2_hwmod = {
 		},
 	},
 	.class		= &omap3xxx_gpio_hwmod_class,
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio3 */
@@ -838,7 +771,6 @@ static struct omap_hwmod omap3xxx_gpio3_hwmod = {
 		},
 	},
 	.class		= &omap3xxx_gpio_hwmod_class,
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio4 */
@@ -860,7 +792,6 @@ static struct omap_hwmod omap3xxx_gpio4_hwmod = {
 		},
 	},
 	.class		= &omap3xxx_gpio_hwmod_class,
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio5 */
@@ -883,7 +814,6 @@ static struct omap_hwmod omap3xxx_gpio5_hwmod = {
 		},
 	},
 	.class		= &omap3xxx_gpio_hwmod_class,
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio6 */
@@ -906,7 +836,6 @@ static struct omap_hwmod omap3xxx_gpio6_hwmod = {
 		},
 	},
 	.class		= &omap3xxx_gpio_hwmod_class,
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* dma attributes */
@@ -966,7 +895,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = {
 static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = {
 	.name = "mcbsp",
 	.sysc = &omap3xxx_mcbsp_sysc,
-	.rev  = MCBSP_CONFIG_TYPE3,
 };
 
 /* McBSP functional clock mapping */
@@ -981,7 +909,6 @@ static struct omap_hwmod_opt_clk mcbsp234_opt_clks[] = {
 };
 
 /* mcbsp1 */
-
 static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {
 	.name		= "mcbsp1",
 	.class		= &omap3xxx_mcbsp_hwmod_class,
@@ -998,11 +925,6 @@ static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {
 };
 
 /* mcbsp2 */
-
-static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = {
-	.sidetone	= "mcbsp2_sidetone",
-};
-
 static struct omap_hwmod omap3xxx_mcbsp2_hwmod = {
 	.name		= "mcbsp2",
 	.class		= &omap3xxx_mcbsp_hwmod_class,
@@ -1016,15 +938,9 @@ static struct omap_hwmod omap3xxx_mcbsp2_hwmod = {
 	},
 	.opt_clks	= mcbsp234_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(mcbsp234_opt_clks),
-	.dev_attr	= &omap34xx_mcbsp2_dev_attr,
 };
 
 /* mcbsp3 */
-
-static struct omap_mcbsp_dev_attr omap34xx_mcbsp3_dev_attr = {
-	.sidetone	= "mcbsp3_sidetone",
-};
-
 static struct omap_hwmod omap3xxx_mcbsp3_hwmod = {
 	.name		= "mcbsp3",
 	.class		= &omap3xxx_mcbsp_hwmod_class,
@@ -1038,12 +954,9 @@ static struct omap_hwmod omap3xxx_mcbsp3_hwmod = {
 	},
 	.opt_clks	= mcbsp234_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(mcbsp234_opt_clks),
-	.dev_attr	= &omap34xx_mcbsp3_dev_attr,
 };
 
 /* mcbsp4 */
-
-
 static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {
 	.name		= "mcbsp4",
 	.class		= &omap3xxx_mcbsp_hwmod_class,
@@ -1060,8 +973,6 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {
 };
 
 /* mcbsp5 */
-
-
 static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {
 	.name		= "mcbsp5",
 	.class		= &omap3xxx_mcbsp_hwmod_class,
@@ -1090,7 +1001,6 @@ static struct omap_hwmod_class omap3xxx_mcbsp_sidetone_hwmod_class = {
 };
 
 /* mcbsp2_sidetone */
-
 static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = {
 	.name		= "mcbsp2_sidetone",
 	.class		= &omap3xxx_mcbsp_sidetone_hwmod_class,
@@ -1099,7 +1009,6 @@ static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = {
 };
 
 /* mcbsp3_sidetone */
-
 static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {
 	.name		= "mcbsp3_sidetone",
 	.class		= &omap3xxx_mcbsp_sidetone_hwmod_class,
@@ -1258,14 +1167,9 @@ static struct omap_hwmod_class_sysconfig omap34xx_mcspi_sysc = {
 static struct omap_hwmod_class omap34xx_mcspi_class = {
 	.name = "mcspi",
 	.sysc = &omap34xx_mcspi_sysc,
-	.rev = OMAP3_MCSPI_REV,
 };
 
 /* mcspi1 */
-static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = {
-	.num_chipselect = 4,
-};
-
 static struct omap_hwmod omap34xx_mcspi1 = {
 	.name		= "mcspi1",
 	.main_clk	= "mcspi1_fck",
@@ -1277,14 +1181,9 @@ static struct omap_hwmod omap34xx_mcspi1 = {
 		},
 	},
 	.class		= &omap34xx_mcspi_class,
-	.dev_attr       = &omap_mcspi1_dev_attr,
 };
 
 /* mcspi2 */
-static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = {
-	.num_chipselect = 2,
-};
-
 static struct omap_hwmod omap34xx_mcspi2 = {
 	.name		= "mcspi2",
 	.main_clk	= "mcspi2_fck",
@@ -1296,16 +1195,9 @@ static struct omap_hwmod omap34xx_mcspi2 = {
 		},
 	},
 	.class		= &omap34xx_mcspi_class,
-	.dev_attr       = &omap_mcspi2_dev_attr,
 };
 
 /* mcspi3 */
-
-
-static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = {
-	.num_chipselect = 2,
-};
-
 static struct omap_hwmod omap34xx_mcspi3 = {
 	.name		= "mcspi3",
 	.main_clk	= "mcspi3_fck",
@@ -1317,16 +1209,9 @@ static struct omap_hwmod omap34xx_mcspi3 = {
 		},
 	},
 	.class		= &omap34xx_mcspi_class,
-	.dev_attr       = &omap_mcspi3_dev_attr,
 };
 
 /* mcspi4 */
-
-
-static struct omap2_mcspi_dev_attr omap_mcspi4_dev_attr = {
-	.num_chipselect = 1,
-};
-
 static struct omap_hwmod omap34xx_mcspi4 = {
 	.name		= "mcspi4",
 	.main_clk	= "mcspi4_fck",
@@ -1338,7 +1223,6 @@ static struct omap_hwmod omap34xx_mcspi4 = {
 		},
 	},
 	.class		= &omap34xx_mcspi_class,
-	.dev_attr       = &omap_mcspi4_dev_attr,
 };
 
 /* usbhsotg */
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
index afbce1f..5f73b73 100644
--- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
@@ -14,8 +14,6 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/platform_data/gpio-omap.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
 #include "omap_hwmod.h"
 #include "omap_hwmod_33xx_43xx_common_data.h"
 #include "prcm43xx.h"
@@ -107,7 +105,6 @@ static struct omap_hwmod am43xx_gpio0_hwmod = {
 	},
 	.opt_clks	= gpio0_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio0_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 static struct omap_hwmod_class_sysconfig am43xx_synctimer_sysc = {
@@ -239,7 +236,6 @@ static struct omap_hwmod am43xx_spi2_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi_attrib,
 };
 
 static struct omap_hwmod am43xx_spi3_hwmod = {
@@ -253,7 +249,6 @@ static struct omap_hwmod am43xx_spi3_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi_attrib,
 };
 
 static struct omap_hwmod am43xx_spi4_hwmod = {
@@ -267,7 +262,6 @@ static struct omap_hwmod am43xx_spi4_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi_attrib,
 };
 
 static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
@@ -288,7 +282,6 @@ static struct omap_hwmod am43xx_gpio4_hwmod = {
 	},
 	.opt_clks	= gpio4_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio4_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
@@ -309,7 +302,6 @@ static struct omap_hwmod am43xx_gpio5_hwmod = {
 	},
 	.opt_clks	= gpio5_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio5_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 static struct omap_hwmod_class am43xx_ocp2scp_hwmod_class = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index a1901c2..e4f8ae9 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -21,17 +21,12 @@
  */
 
 #include <linux/io.h>
-#include <linux/platform_data/gpio-omap.h>
 #include <linux/platform_data/hsmmc-omap.h>
 #include <linux/power/smartreflex.h>
 #include <linux/i2c-omap.h>
 
 #include <linux/omap-dma.h>
 
-#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <plat/dmtimer.h>
-
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
 #include "cm1_44xx.h"
@@ -1083,12 +1078,6 @@ static struct omap_hwmod_class omap44xx_gpio_hwmod_class = {
 	.rev	= 2,
 };
 
-/* gpio dev_attr */
-static struct omap_gpio_dev_attr gpio_dev_attr = {
-	.bank_width	= 32,
-	.dbck_flag	= true,
-};
-
 /* gpio1 */
 static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio1_dbclk" },
@@ -1108,7 +1097,6 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
 	},
 	.opt_clks	= gpio1_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio1_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio2 */
@@ -1131,7 +1119,6 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
 	},
 	.opt_clks	= gpio2_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio2_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio3 */
@@ -1154,7 +1141,6 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
 	},
 	.opt_clks	= gpio3_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio3_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio4 */
@@ -1177,7 +1163,6 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
 	},
 	.opt_clks	= gpio4_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio4_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio5 */
@@ -1200,7 +1185,6 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
 	},
 	.opt_clks	= gpio5_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio5_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio6 */
@@ -1223,7 +1207,6 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
 	},
 	.opt_clks	= gpio6_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio6_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /*
@@ -1394,10 +1377,6 @@ static struct omap_hwmod_class omap44xx_i2c_hwmod_class = {
 	.reset	= &omap_i2c_reset,
 };
 
-static struct omap_i2c_dev_attr i2c_dev_attr = {
-	.flags	= OMAP_I2C_FLAG_BUS_SHIFT_NONE,
-};
-
 /* i2c1 */
 static struct omap_hwmod omap44xx_i2c1_hwmod = {
 	.name		= "i2c1",
@@ -1412,7 +1391,6 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c2 */
@@ -1429,7 +1407,6 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c3 */
@@ -1446,7 +1423,6 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c4 */
@@ -1463,7 +1439,6 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /*
@@ -1702,7 +1677,6 @@ static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = {
 static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = {
 	.name	= "mcbsp",
 	.sysc	= &omap44xx_mcbsp_sysc,
-	.rev	= MCBSP_CONFIG_TYPE4,
 };
 
 /* mcbsp1 */
@@ -1860,14 +1834,9 @@ static struct omap_hwmod_class_sysconfig omap44xx_mcspi_sysc = {
 static struct omap_hwmod_class omap44xx_mcspi_hwmod_class = {
 	.name	= "mcspi",
 	.sysc	= &omap44xx_mcspi_sysc,
-	.rev	= OMAP4_MCSPI_REV,
 };
 
 /* mcspi1 */
-static struct omap2_mcspi_dev_attr mcspi1_dev_attr = {
-	.num_chipselect	= 4,
-};
-
 static struct omap_hwmod omap44xx_mcspi1_hwmod = {
 	.name		= "mcspi1",
 	.class		= &omap44xx_mcspi_hwmod_class,
@@ -1880,14 +1849,9 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi1_dev_attr,
 };
 
 /* mcspi2 */
-static struct omap2_mcspi_dev_attr mcspi2_dev_attr = {
-	.num_chipselect	= 2,
-};
-
 static struct omap_hwmod omap44xx_mcspi2_hwmod = {
 	.name		= "mcspi2",
 	.class		= &omap44xx_mcspi_hwmod_class,
@@ -1900,14 +1864,9 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi2_dev_attr,
 };
 
 /* mcspi3 */
-static struct omap2_mcspi_dev_attr mcspi3_dev_attr = {
-	.num_chipselect	= 2,
-};
-
 static struct omap_hwmod omap44xx_mcspi3_hwmod = {
 	.name		= "mcspi3",
 	.class		= &omap44xx_mcspi_hwmod_class,
@@ -1920,14 +1879,9 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi3_dev_attr,
 };
 
 /* mcspi4 */
-static struct omap2_mcspi_dev_attr mcspi4_dev_attr = {
-	.num_chipselect	= 1,
-};
-
 static struct omap_hwmod omap44xx_mcspi4_hwmod = {
 	.name		= "mcspi4",
 	.class		= &omap44xx_mcspi_hwmod_class,
@@ -1940,7 +1894,6 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi4_dev_attr,
 };
 
 /*
@@ -2547,26 +2500,6 @@ static struct omap_hwmod_class omap44xx_timer_hwmod_class = {
 	.sysc	= &omap44xx_timer_sysc,
 };
 
-/* always-on timers dev attribute */
-static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
-	.timer_capability	= OMAP_TIMER_ALWON,
-};
-
-/* pwm timers dev attribute */
-static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
-	.timer_capability	= OMAP_TIMER_HAS_PWM,
-};
-
-/* timers with DSP interrupt dev attribute */
-static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
-	.timer_capability       = OMAP_TIMER_HAS_DSP_IRQ,
-};
-
-/* pwm timers with DSP interrupt dev attribute */
-static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = {
-	.timer_capability       = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM,
-};
-
 /* timer1 */
 static struct omap_hwmod omap44xx_timer1_hwmod = {
 	.name		= "timer1",
@@ -2581,7 +2514,6 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 };
 
 /* timer2 */
@@ -2643,7 +2575,6 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 };
 
 /* timer6 */
@@ -2659,7 +2590,6 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 };
 
 /* timer7 */
@@ -2675,7 +2605,6 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_dsp_dev_attr,
 };
 
 /* timer8 */
@@ -2691,7 +2620,6 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_dsp_pwm_dev_attr,
 };
 
 /* timer9 */
@@ -2707,7 +2635,6 @@ static struct omap_hwmod omap44xx_timer9_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 };
 
 /* timer10 */
@@ -2724,7 +2651,6 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 };
 
 /* timer11 */
@@ -2740,7 +2666,6 @@ static struct omap_hwmod omap44xx_timer11_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_pwm_dev_attr,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 988e7ea..c72cd84 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -18,15 +18,11 @@
  */
 
 #include <linux/io.h>
-#include <linux/platform_data/gpio-omap.h>
 #include <linux/platform_data/hsmmc-omap.h>
 #include <linux/power/smartreflex.h>
 #include <linux/i2c-omap.h>
 
 #include <linux/omap-dma.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
@@ -627,12 +623,6 @@ static struct omap_hwmod_class omap54xx_gpio_hwmod_class = {
 	.rev	= 2,
 };
 
-/* gpio dev_attr */
-static struct omap_gpio_dev_attr gpio_dev_attr = {
-	.bank_width	= 32,
-	.dbck_flag	= true,
-};
-
 /* gpio1 */
 static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio1_dbclk" },
@@ -652,7 +642,6 @@ static struct omap_hwmod omap54xx_gpio1_hwmod = {
 	},
 	.opt_clks	= gpio1_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio1_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio2 */
@@ -675,7 +664,6 @@ static struct omap_hwmod omap54xx_gpio2_hwmod = {
 	},
 	.opt_clks	= gpio2_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio2_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio3 */
@@ -698,7 +686,6 @@ static struct omap_hwmod omap54xx_gpio3_hwmod = {
 	},
 	.opt_clks	= gpio3_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio3_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio4 */
@@ -721,7 +708,6 @@ static struct omap_hwmod omap54xx_gpio4_hwmod = {
 	},
 	.opt_clks	= gpio4_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio4_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio5 */
@@ -744,7 +730,6 @@ static struct omap_hwmod omap54xx_gpio5_hwmod = {
 	},
 	.opt_clks	= gpio5_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio5_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio6 */
@@ -767,7 +752,6 @@ static struct omap_hwmod omap54xx_gpio6_hwmod = {
 	},
 	.opt_clks	= gpio6_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio6_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio7 */
@@ -790,7 +774,6 @@ static struct omap_hwmod omap54xx_gpio7_hwmod = {
 	},
 	.opt_clks	= gpio7_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio7_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio8 */
@@ -813,7 +796,6 @@ static struct omap_hwmod omap54xx_gpio8_hwmod = {
 	},
 	.opt_clks	= gpio8_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio8_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /*
@@ -839,11 +821,6 @@ static struct omap_hwmod_class omap54xx_i2c_hwmod_class = {
 	.rev	= OMAP_I2C_IP_VERSION_2,
 };
 
-/* i2c dev_attr */
-static struct omap_i2c_dev_attr i2c_dev_attr = {
-	.flags	= OMAP_I2C_FLAG_BUS_SHIFT_NONE,
-};
-
 /* i2c1 */
 static struct omap_hwmod omap54xx_i2c1_hwmod = {
 	.name		= "i2c1",
@@ -858,7 +835,6 @@ static struct omap_hwmod omap54xx_i2c1_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c2 */
@@ -875,7 +851,6 @@ static struct omap_hwmod omap54xx_i2c2_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c3 */
@@ -892,7 +867,6 @@ static struct omap_hwmod omap54xx_i2c3_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c4 */
@@ -909,7 +883,6 @@ static struct omap_hwmod omap54xx_i2c4_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c5 */
@@ -926,7 +899,6 @@ static struct omap_hwmod omap54xx_i2c5_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /*
@@ -1012,7 +984,6 @@ static struct omap_hwmod_class_sysconfig omap54xx_mcbsp_sysc = {
 static struct omap_hwmod_class omap54xx_mcbsp_hwmod_class = {
 	.name	= "mcbsp",
 	.sysc	= &omap54xx_mcbsp_sysc,
-	.rev	= MCBSP_CONFIG_TYPE4,
 };
 
 /* mcbsp1 */
@@ -1149,15 +1120,9 @@ static struct omap_hwmod_class_sysconfig omap54xx_mcspi_sysc = {
 static struct omap_hwmod_class omap54xx_mcspi_hwmod_class = {
 	.name	= "mcspi",
 	.sysc	= &omap54xx_mcspi_sysc,
-	.rev	= OMAP4_MCSPI_REV,
 };
 
 /* mcspi1 */
-/* mcspi1 dev_attr */
-static struct omap2_mcspi_dev_attr mcspi1_dev_attr = {
-	.num_chipselect	= 4,
-};
-
 static struct omap_hwmod omap54xx_mcspi1_hwmod = {
 	.name		= "mcspi1",
 	.class		= &omap54xx_mcspi_hwmod_class,
@@ -1170,15 +1135,9 @@ static struct omap_hwmod omap54xx_mcspi1_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi1_dev_attr,
 };
 
 /* mcspi2 */
-/* mcspi2 dev_attr */
-static struct omap2_mcspi_dev_attr mcspi2_dev_attr = {
-	.num_chipselect	= 2,
-};
-
 static struct omap_hwmod omap54xx_mcspi2_hwmod = {
 	.name		= "mcspi2",
 	.class		= &omap54xx_mcspi_hwmod_class,
@@ -1191,15 +1150,9 @@ static struct omap_hwmod omap54xx_mcspi2_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi2_dev_attr,
 };
 
 /* mcspi3 */
-/* mcspi3 dev_attr */
-static struct omap2_mcspi_dev_attr mcspi3_dev_attr = {
-	.num_chipselect	= 2,
-};
-
 static struct omap_hwmod omap54xx_mcspi3_hwmod = {
 	.name		= "mcspi3",
 	.class		= &omap54xx_mcspi_hwmod_class,
@@ -1212,15 +1165,9 @@ static struct omap_hwmod omap54xx_mcspi3_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi3_dev_attr,
 };
 
 /* mcspi4 */
-/* mcspi4 dev_attr */
-static struct omap2_mcspi_dev_attr mcspi4_dev_attr = {
-	.num_chipselect	= 1,
-};
-
 static struct omap_hwmod omap54xx_mcspi4_hwmod = {
 	.name		= "mcspi4",
 	.class		= &omap54xx_mcspi_hwmod_class,
@@ -1233,7 +1180,6 @@ static struct omap_hwmod omap54xx_mcspi4_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi4_dev_attr,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 4c2a05b..62352d1 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -18,15 +18,11 @@
  */
 
 #include <linux/io.h>
-#include <linux/platform_data/gpio-omap.h>
 #include <linux/platform_data/hsmmc-omap.h>
 #include <linux/power/smartreflex.h>
 #include <linux/i2c-omap.h>
 
 #include <linux/omap-dma.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
@@ -818,12 +814,6 @@ static struct omap_hwmod_class dra7xx_gpio_hwmod_class = {
 	.rev	= 2,
 };
 
-/* gpio dev_attr */
-static struct omap_gpio_dev_attr gpio_dev_attr = {
-	.bank_width	= 32,
-	.dbck_flag	= true,
-};
-
 /* gpio1 */
 static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio1_dbclk" },
@@ -844,7 +834,6 @@ static struct omap_hwmod dra7xx_gpio1_hwmod = {
 	},
 	.opt_clks	= gpio1_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio1_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio2 */
@@ -867,7 +856,6 @@ static struct omap_hwmod dra7xx_gpio2_hwmod = {
 	},
 	.opt_clks	= gpio2_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio2_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio3 */
@@ -890,7 +878,6 @@ static struct omap_hwmod dra7xx_gpio3_hwmod = {
 	},
 	.opt_clks	= gpio3_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio3_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio4 */
@@ -913,7 +900,6 @@ static struct omap_hwmod dra7xx_gpio4_hwmod = {
 	},
 	.opt_clks	= gpio4_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio4_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio5 */
@@ -936,7 +922,6 @@ static struct omap_hwmod dra7xx_gpio5_hwmod = {
 	},
 	.opt_clks	= gpio5_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio5_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio6 */
@@ -959,7 +944,6 @@ static struct omap_hwmod dra7xx_gpio6_hwmod = {
 	},
 	.opt_clks	= gpio6_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio6_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio7 */
@@ -982,7 +966,6 @@ static struct omap_hwmod dra7xx_gpio7_hwmod = {
 	},
 	.opt_clks	= gpio7_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio7_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /* gpio8 */
@@ -1005,7 +988,6 @@ static struct omap_hwmod dra7xx_gpio8_hwmod = {
 	},
 	.opt_clks	= gpio8_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio8_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 /*
@@ -1105,11 +1087,6 @@ static struct omap_hwmod_class dra7xx_i2c_hwmod_class = {
 	.rev	= OMAP_I2C_IP_VERSION_2,
 };
 
-/* i2c dev_attr */
-static struct omap_i2c_dev_attr i2c_dev_attr = {
-	.flags	= OMAP_I2C_FLAG_BUS_SHIFT_NONE,
-};
-
 /* i2c1 */
 static struct omap_hwmod dra7xx_i2c1_hwmod = {
 	.name		= "i2c1",
@@ -1124,7 +1101,6 @@ static struct omap_hwmod dra7xx_i2c1_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c2 */
@@ -1141,7 +1117,6 @@ static struct omap_hwmod dra7xx_i2c2_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c3 */
@@ -1158,7 +1133,6 @@ static struct omap_hwmod dra7xx_i2c3_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c4 */
@@ -1175,7 +1149,6 @@ static struct omap_hwmod dra7xx_i2c4_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /* i2c5 */
@@ -1192,7 +1165,6 @@ static struct omap_hwmod dra7xx_i2c5_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &i2c_dev_attr,
 };
 
 /*
@@ -1401,15 +1373,9 @@ static struct omap_hwmod_class_sysconfig dra7xx_mcspi_sysc = {
 static struct omap_hwmod_class dra7xx_mcspi_hwmod_class = {
 	.name	= "mcspi",
 	.sysc	= &dra7xx_mcspi_sysc,
-	.rev	= OMAP4_MCSPI_REV,
 };
 
 /* mcspi1 */
-/* mcspi1 dev_attr */
-static struct omap2_mcspi_dev_attr mcspi1_dev_attr = {
-	.num_chipselect	= 4,
-};
-
 static struct omap_hwmod dra7xx_mcspi1_hwmod = {
 	.name		= "mcspi1",
 	.class		= &dra7xx_mcspi_hwmod_class,
@@ -1422,15 +1388,9 @@ static struct omap_hwmod dra7xx_mcspi1_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi1_dev_attr,
 };
 
 /* mcspi2 */
-/* mcspi2 dev_attr */
-static struct omap2_mcspi_dev_attr mcspi2_dev_attr = {
-	.num_chipselect	= 2,
-};
-
 static struct omap_hwmod dra7xx_mcspi2_hwmod = {
 	.name		= "mcspi2",
 	.class		= &dra7xx_mcspi_hwmod_class,
@@ -1443,15 +1403,9 @@ static struct omap_hwmod dra7xx_mcspi2_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi2_dev_attr,
 };
 
 /* mcspi3 */
-/* mcspi3 dev_attr */
-static struct omap2_mcspi_dev_attr mcspi3_dev_attr = {
-	.num_chipselect	= 2,
-};
-
 static struct omap_hwmod dra7xx_mcspi3_hwmod = {
 	.name		= "mcspi3",
 	.class		= &dra7xx_mcspi_hwmod_class,
@@ -1464,15 +1418,9 @@ static struct omap_hwmod dra7xx_mcspi3_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi3_dev_attr,
 };
 
 /* mcspi4 */
-/* mcspi4 dev_attr */
-static struct omap2_mcspi_dev_attr mcspi4_dev_attr = {
-	.num_chipselect	= 1,
-};
-
 static struct omap_hwmod dra7xx_mcspi4_hwmod = {
 	.name		= "mcspi4",
 	.class		= &dra7xx_mcspi_hwmod_class,
@@ -1485,7 +1433,6 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &mcspi4_dev_attr,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
index 84f1182..686655f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -15,10 +15,9 @@
  *
  */
 
-#include <linux/platform_data/gpio-omap.h>
+#include <linux/types.h>
+
 #include <linux/platform_data/hsmmc-omap.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <plat/dmtimer.h>
 
 #include "omap_hwmod_common_data.h"
 #include "cm81xx.h"
@@ -488,11 +487,6 @@ static struct omap_hwmod_class dm81xx_gpio_hwmod_class = {
 	.rev	= 2,
 };
 
-static struct omap_gpio_dev_attr gpio_dev_attr = {
-	.bank_width	= 32,
-	.dbck_flag	= true,
-};
-
 static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
 	{ .role = "dbclk", .clk = "sysclk18_ck" },
 };
@@ -510,7 +504,6 @@ static struct omap_hwmod dm81xx_gpio1_hwmod = {
 	},
 	.opt_clks	= gpio1_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio1_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio1 = {
@@ -537,7 +530,6 @@ static struct omap_hwmod dm81xx_gpio2_hwmod = {
 	},
 	.opt_clks	= gpio2_opt_clks,
 	.opt_clks_cnt	= ARRAY_SIZE(gpio2_opt_clks),
-	.dev_attr	= &gpio_dev_attr,
 };
 
 static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio2 = {
@@ -654,15 +646,10 @@ static struct omap_hwmod_class dm816x_timer_hwmod_class = {
 	.sysc = &dm816x_timer_sysc,
 };
 
-static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
-	.timer_capability	= OMAP_TIMER_ALWON,
-};
-
 static struct omap_hwmod dm814x_timer1_hwmod = {
 	.name		= "timer1",
 	.clkdm_name	= "alwon_l3s_clkdm",
 	.main_clk	= "timer1_fck",
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 	.flags		= HWMOD_NO_IDLEST,
 };
@@ -684,7 +671,6 @@ static struct omap_hwmod dm816x_timer1_hwmod = {
 			.modulemode = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 };
 
@@ -699,7 +685,6 @@ static struct omap_hwmod dm814x_timer2_hwmod = {
 	.name		= "timer2",
 	.clkdm_name	= "alwon_l3s_clkdm",
 	.main_clk	= "timer2_fck",
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 	.flags		= HWMOD_NO_IDLEST,
 };
@@ -721,7 +706,6 @@ static struct omap_hwmod dm816x_timer2_hwmod = {
 			.modulemode = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 };
 
@@ -742,7 +726,6 @@ static struct omap_hwmod dm816x_timer3_hwmod = {
 			.modulemode = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 };
 
@@ -763,7 +746,6 @@ static struct omap_hwmod dm816x_timer4_hwmod = {
 			.modulemode = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 };
 
@@ -784,7 +766,6 @@ static struct omap_hwmod dm816x_timer5_hwmod = {
 			.modulemode = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 };
 
@@ -805,7 +786,6 @@ static struct omap_hwmod dm816x_timer6_hwmod = {
 			.modulemode = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 };
 
@@ -826,7 +806,6 @@ static struct omap_hwmod dm816x_timer7_hwmod = {
 			.modulemode = MODULEMODE_SWCTRL,
 		},
 	},
-	.dev_attr	= &capability_alwon_dev_attr,
 	.class		= &dm816x_timer_hwmod_class,
 };
 
@@ -1138,11 +1117,6 @@ static struct omap_hwmod_class_sysconfig dm816x_mcspi_sysc = {
 static struct omap_hwmod_class dm816x_mcspi_class = {
 	.name = "mcspi",
 	.sysc = &dm816x_mcspi_sysc,
-	.rev = OMAP3_MCSPI_REV,
-};
-
-static struct omap2_mcspi_dev_attr dm816x_mcspi1_dev_attr = {
-	.num_chipselect = 4,
 };
 
 static struct omap_hwmod dm81xx_mcspi1_hwmod = {
@@ -1156,7 +1130,6 @@ static struct omap_hwmod dm81xx_mcspi1_hwmod = {
 		},
 	},
 	.class		= &dm816x_mcspi_class,
-	.dev_attr	= &dm816x_mcspi1_dev_attr,
 };
 
 static struct omap_hwmod_ocp_if dm81xx_l4_ls__mcspi1 = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h
index 29a52df..56dbaca 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.h
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h
@@ -19,7 +19,6 @@
 #include "display.h"
 
 /* Common IP block data across OMAP2xxx */
-extern struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr;
 extern struct omap_hwmod omap2xxx_l3_main_hwmod;
 extern struct omap_hwmod omap2xxx_l4_core_hwmod;
 extern struct omap_hwmod omap2xxx_l4_wkup_hwmod;
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 6b433fc..6459816 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -17,17 +17,17 @@
 #include <linux/wl12xx.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
+#include <linux/power/smartreflex.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 
 #include <linux/platform_data/pinctrl-single.h>
 #include <linux/platform_data/hsmmc-omap.h>
 #include <linux/platform_data/iommu-omap.h>
+#include <linux/platform_data/ti-sysc.h>
 #include <linux/platform_data/wkup_m3.h>
-#include <linux/platform_data/pwm_omap_dmtimer.h>
 #include <linux/platform_data/media/ir-rx51.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <plat/dmtimer.h>
 
 #include "common.h"
 #include "common-board-devices.h"
@@ -454,6 +454,43 @@ static void __init dra7x_evm_mmc_quirk(void)
 }
 #endif
 
+static int ti_sysc_enable_module(struct device *dev,
+				 const struct ti_sysc_cookie *cookie)
+{
+	if (!cookie->data)
+		return -EINVAL;
+
+	return omap_hwmod_enable(cookie->data);
+}
+
+static int ti_sysc_idle_module(struct device *dev,
+			       const struct ti_sysc_cookie *cookie)
+{
+	if (!cookie->data)
+		return -EINVAL;
+
+	return omap_hwmod_idle(cookie->data);
+}
+
+static int ti_sysc_shutdown_module(struct device *dev,
+				   const struct ti_sysc_cookie *cookie)
+{
+	if (!cookie->data)
+		return -EINVAL;
+
+	return omap_hwmod_shutdown(cookie->data);
+}
+
+static struct of_dev_auxdata omap_auxdata_lookup[];
+
+static struct ti_sysc_platform_data ti_sysc_pdata = {
+	.auxdata = omap_auxdata_lookup,
+	.init_module = omap_hwmod_init_module,
+	.enable_module = ti_sysc_enable_module,
+	.idle_module = ti_sysc_idle_module,
+	.shutdown_module = ti_sysc_shutdown_module,
+};
+
 static struct pcs_pdata pcs_pdata;
 
 void omap_pcs_legacy_init(int irq, void (*rearm)(void))
@@ -477,33 +514,6 @@ void omap_auxdata_legacy_init(struct device *dev)
 	dev->platform_data = &twl_gpio_auxdata;
 }
 
-/* Dual mode timer PWM callbacks platdata */
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-static struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = {
-	.request_by_node = omap_dm_timer_request_by_node,
-	.request_specific = omap_dm_timer_request_specific,
-	.request = omap_dm_timer_request,
-	.set_source = omap_dm_timer_set_source,
-	.get_irq = omap_dm_timer_get_irq,
-	.set_int_enable = omap_dm_timer_set_int_enable,
-	.set_int_disable = omap_dm_timer_set_int_disable,
-	.free = omap_dm_timer_free,
-	.enable = omap_dm_timer_enable,
-	.disable = omap_dm_timer_disable,
-	.get_fclk = omap_dm_timer_get_fclk,
-	.start = omap_dm_timer_start,
-	.stop = omap_dm_timer_stop,
-	.set_load = omap_dm_timer_set_load,
-	.set_match = omap_dm_timer_set_match,
-	.set_pwm = omap_dm_timer_set_pwm,
-	.set_prescaler = omap_dm_timer_set_prescaler,
-	.read_counter = omap_dm_timer_read_counter,
-	.write_counter = omap_dm_timer_write_counter,
-	.read_status = omap_dm_timer_read_status,
-	.write_status = omap_dm_timer_write_status,
-};
-#endif
-
 static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = {
 	.set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
 };
@@ -542,7 +552,9 @@ static struct pdata_init auxdata_quirks[] __initdata = {
 	{ /* sentinel */ },
 };
 
-static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
+struct omap_sr_data __maybe_unused omap_sr_pdata[OMAP_SR_NR];
+
+static struct of_dev_auxdata omap_auxdata_lookup[] = {
 #ifdef CONFIG_MACH_NOKIA_N8X0
 	OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL),
 	OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data),
@@ -551,6 +563,10 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 #ifdef CONFIG_ARCH_OMAP3
 	OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu",
 		       &omap3_iommu_pdata),
+	OF_DEV_AUXDATA("ti,omap3-smartreflex-core", 0x480cb000,
+		       "480cb000.smartreflex", &omap_sr_pdata[OMAP_SR_CORE]),
+	OF_DEV_AUXDATA("ti,omap3-smartreflex-mpu-iva", 0x480c9000,
+		       "480c9000.smartreflex", &omap_sr_pdata[OMAP_SR_MPU]),
 	OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x4809c000, "4809c000.mmc", &mmc_pdata[0]),
 	OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x480b4000, "480b4000.mmc", &mmc_pdata[1]),
 	OF_DEV_AUXDATA("nokia,n900-ir", 0, "n900-ir", &rx51_ir_data),
@@ -572,14 +588,17 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d00000, "44d00000.wkup_m3",
 		       &wkup_m3_data),
 #endif
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-	OF_DEV_AUXDATA("ti,omap-dmtimer-pwm", 0, NULL, &pwm_dmtimer_pdata),
-#endif
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
 	OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
 		       &omap4_iommu_pdata),
 	OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu",
 		       &omap4_iommu_pdata),
+	OF_DEV_AUXDATA("ti,omap4-smartreflex-iva", 0x4a0db000,
+		       "4a0db000.smartreflex", &omap_sr_pdata[OMAP_SR_IVA]),
+	OF_DEV_AUXDATA("ti,omap4-smartreflex-core", 0x4a0dd000,
+		       "4a0dd000.smartreflex", &omap_sr_pdata[OMAP_SR_CORE]),
+	OF_DEV_AUXDATA("ti,omap4-smartreflex-mpu", 0x4a0d9000,
+		       "4a0d9000.smartreflex", &omap_sr_pdata[OMAP_SR_MPU]),
 #endif
 #ifdef CONFIG_SOC_DRA7XX
 	OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x4809c000, "4809c000.mmc",
@@ -590,6 +609,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 		       &dra7_hsmmc_data_mmc3),
 #endif
 	/* Common auxdata */
+	OF_DEV_AUXDATA("ti,sysc", 0, NULL, &ti_sysc_pdata),
 	OF_DEV_AUXDATA("pinctrl-single", 0, NULL, &pcs_pdata),
 	{ /* sentinel */ },
 };
diff --git a/arch/arm/mach-omap2/pm-asm-offsets.c b/arch/arm/mach-omap2/pm-asm-offsets.c
new file mode 100644
index 0000000..6d4392d
--- /dev/null
+++ b/arch/arm/mach-omap2/pm-asm-offsets.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI AM33XX and AM43XX PM Assembly Offsets
+ *
+ * Copyright (C) 2017-2018 Texas Instruments Inc.
+ */
+
+#include <linux/kbuild.h>
+#include <linux/platform_data/pm33xx.h>
+
+int main(void)
+{
+	DEFINE(AMX3_PM_WFI_FLAGS_OFFSET,
+	       offsetof(struct am33xx_pm_sram_data, wfi_flags));
+	DEFINE(AMX3_PM_L2_AUX_CTRL_VAL_OFFSET,
+	       offsetof(struct am33xx_pm_sram_data, l2_aux_ctrl_val));
+	DEFINE(AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET,
+	       offsetof(struct am33xx_pm_sram_data, l2_prefetch_ctrl_val));
+	DEFINE(AMX3_PM_SRAM_DATA_SIZE, sizeof(struct am33xx_pm_sram_data));
+
+	BLANK();
+
+	DEFINE(AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET,
+	       offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_virt));
+	DEFINE(AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET,
+	       offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_phys));
+	DEFINE(AMX3_PM_RO_SRAM_DATA_SIZE,
+	       sizeof(struct am33xx_pm_ro_sram_data));
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 8e30772..c73776b 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -81,6 +81,9 @@ extern unsigned int omap3_do_wfi_sz;
 /* ... and its pointer from SRAM after copy */
 extern void (*omap3_do_wfi_sram)(void);
 
+extern struct am33xx_pm_sram_addr am33xx_pm_sram;
+extern struct am33xx_pm_sram_addr am43xx_pm_sram;
+
 extern void omap3_save_scratchpad_contents(void);
 
 #define PM_RTA_ERRATUM_i608		(1 << 0)
diff --git a/arch/arm/mach-omap2/pm33xx-core.c b/arch/arm/mach-omap2/pm33xx-core.c
new file mode 100644
index 0000000..93c0b5b
--- /dev/null
+++ b/arch/arm/mach-omap2/pm33xx-core.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AM33XX Arch Power Management Routines
+ *
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ *	Dave Gerlach
+ */
+
+#include <asm/smp_scu.h>
+#include <asm/suspend.h>
+#include <linux/errno.h>
+#include <linux/platform_data/pm33xx.h>
+
+#include "cm33xx.h"
+#include "common.h"
+#include "control.h"
+#include "clockdomain.h"
+#include "iomap.h"
+#include "omap_hwmod.h"
+#include "pm.h"
+#include "powerdomain.h"
+#include "prm33xx.h"
+#include "soc.h"
+#include "sram.h"
+
+static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
+static struct clockdomain *gfx_l4ls_clkdm;
+static void __iomem *scu_base;
+
+static int __init am43xx_map_scu(void)
+{
+	scu_base = ioremap(scu_a9_get_base(), SZ_256);
+
+	if (!scu_base)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int amx3_common_init(void)
+{
+	gfx_pwrdm = pwrdm_lookup("gfx_pwrdm");
+	per_pwrdm = pwrdm_lookup("per_pwrdm");
+	mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
+
+	if ((!gfx_pwrdm) || (!per_pwrdm) || (!mpu_pwrdm))
+		return -ENODEV;
+
+	(void)clkdm_for_each(omap_pm_clkdms_setup, NULL);
+
+	/* CEFUSE domain can be turned off post bootup */
+	cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm");
+	if (cefuse_pwrdm)
+		omap_set_pwrdm_state(cefuse_pwrdm, PWRDM_POWER_OFF);
+	else
+		pr_err("PM: Failed to get cefuse_pwrdm\n");
+
+	return 0;
+}
+
+static int am33xx_suspend_init(void)
+{
+	int ret;
+
+	gfx_l4ls_clkdm = clkdm_lookup("gfx_l4ls_gfx_clkdm");
+
+	if (!gfx_l4ls_clkdm) {
+		pr_err("PM: Cannot lookup gfx_l4ls_clkdm clockdomains\n");
+		return -ENODEV;
+	}
+
+	ret = amx3_common_init();
+
+	return ret;
+}
+
+static int am43xx_suspend_init(void)
+{
+	int ret = 0;
+
+	ret = am43xx_map_scu();
+	if (ret) {
+		pr_err("PM: Could not ioremap SCU\n");
+		return ret;
+	}
+
+	ret = amx3_common_init();
+
+	return ret;
+}
+
+static void amx3_pre_suspend_common(void)
+{
+	omap_set_pwrdm_state(gfx_pwrdm, PWRDM_POWER_OFF);
+}
+
+static void amx3_post_suspend_common(void)
+{
+	int status;
+	/*
+	 * Because gfx_pwrdm is the only one under MPU control,
+	 * comment on transition status
+	 */
+	status = pwrdm_read_pwrst(gfx_pwrdm);
+	if (status != PWRDM_POWER_OFF)
+		pr_err("PM: GFX domain did not transition: %x\n", status);
+}
+
+static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long))
+{
+	int ret = 0;
+
+	amx3_pre_suspend_common();
+	ret = cpu_suspend(0, fn);
+	amx3_post_suspend_common();
+
+	/*
+	 * BUG: GFX_L4LS clock domain needs to be woken up to
+	 * ensure thet L4LS clock domain does not get stuck in
+	 * transition. If that happens L3 module does not get
+	 * disabled, thereby leading to PER power domain
+	 * transition failing
+	 */
+
+	clkdm_wakeup(gfx_l4ls_clkdm);
+	clkdm_sleep(gfx_l4ls_clkdm);
+
+	return ret;
+}
+
+static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long))
+{
+	int ret = 0;
+
+	amx3_pre_suspend_common();
+	scu_power_mode(scu_base, SCU_PM_POWEROFF);
+	ret = cpu_suspend(0, fn);
+	scu_power_mode(scu_base, SCU_PM_NORMAL);
+	amx3_post_suspend_common();
+
+	return ret;
+}
+
+static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void)
+{
+	if (soc_is_am33xx())
+		return &am33xx_pm_sram;
+	else if (soc_is_am437x())
+		return &am43xx_pm_sram;
+	else
+		return NULL;
+}
+
+static struct am33xx_pm_platform_data am33xx_ops = {
+	.init = am33xx_suspend_init,
+	.soc_suspend = am33xx_suspend,
+	.get_sram_addrs = amx3_get_sram_addrs,
+};
+
+static struct am33xx_pm_platform_data am43xx_ops = {
+	.init = am43xx_suspend_init,
+	.soc_suspend = am43xx_suspend,
+	.get_sram_addrs = amx3_get_sram_addrs,
+};
+
+static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
+{
+	if (soc_is_am33xx())
+		return &am33xx_ops;
+	else if (soc_is_am437x())
+		return &am43xx_ops;
+	else
+		return NULL;
+}
+
+void __init amx3_common_pm_init(void)
+{
+	struct am33xx_pm_platform_data *pdata;
+	struct platform_device_info devinfo;
+
+	pdata = am33xx_pm_get_pdata();
+
+	memset(&devinfo, 0, sizeof(devinfo));
+	devinfo.name = "pm33xx";
+	devinfo.data = pdata;
+	devinfo.size_data = sizeof(*pdata);
+	devinfo.id = -1;
+	platform_device_register_full(&devinfo);
+}
diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S
new file mode 100644
index 0000000..218d799
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep33xx.S
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Low level suspend code for AM33XX SoCs
+ *
+ * Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/
+ *	Dave Gerlach, Vaibhav Bedia
+ */
+
+#include <generated/ti-emif-asm-offsets.h>
+#include <generated/ti-pm-asm-offsets.h>
+#include <linux/linkage.h>
+#include <linux/ti-emif-sram.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+#include "iomap.h"
+#include "cm33xx.h"
+
+#define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED			0x00030000
+#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE			0x0003
+#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE			0x0002
+
+	.arm
+	.align 3
+
+ENTRY(am33xx_do_wfi)
+	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
+
+	/*
+	 * Flush all data from the L1 and L2 data cache before disabling
+	 * SCTLR.C bit.
+	 */
+	ldr	r1, kernel_flush
+	blx	r1
+
+	/*
+	 * Clear the SCTLR.C bit to prevent further data cache
+	 * allocation. Clearing SCTLR.C would make all the data accesses
+	 * strongly ordered and would not hit the cache.
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #(1 << 2)	@ Disable the C bit
+	mcr	p15, 0, r0, c1, c0, 0
+	isb
+
+	/*
+	 * Invalidate L1 and L2 data cache.
+	 */
+	ldr	r1, kernel_flush
+	blx	r1
+
+	adr	r9, am33xx_emif_sram_table
+
+	ldr	r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
+	blx	r3
+
+	ldr	r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
+	blx	r3
+
+	/* Disable EMIF */
+	ldr     r1, virt_emif_clkctrl
+	ldr     r2, [r1]
+	bic     r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
+	str     r2, [r1]
+
+	ldr	r1, virt_emif_clkctrl
+wait_emif_disable:
+	ldr	r2, [r1]
+	mov	r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED
+	cmp	r2, r3
+	bne	wait_emif_disable
+
+	/*
+	 * For the MPU WFI to be registered as an interrupt
+	 * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
+	 * to DISABLED
+	 */
+	ldr	r1, virt_mpu_clkctrl
+	ldr	r2, [r1]
+	bic	r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
+	str	r2, [r1]
+
+	/*
+	 * Execute an ISB instruction to ensure that all of the
+	 * CP15 register changes have been committed.
+	 */
+	isb
+
+	/*
+	 * Execute a barrier instruction to ensure that all cache,
+	 * TLB and branch predictor maintenance operations issued
+	 * have completed.
+	 */
+	dsb
+	dmb
+
+	/*
+	 * Execute a WFI instruction and wait until the
+	 * STANDBYWFI output is asserted to indicate that the
+	 * CPU is in idle and low power state. CPU can specualatively
+	 * prefetch the instructions so add NOPs after WFI. Thirteen
+	 * NOPs as per Cortex-A8 pipeline.
+	 */
+	wfi
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* We come here in case of an abort due to a late interrupt */
+
+	/* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */
+	ldr	r1, virt_mpu_clkctrl
+	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
+	str	r2, [r1]
+
+	/* Re-enable EMIF */
+	ldr	r1, virt_emif_clkctrl
+	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
+	str	r2, [r1]
+wait_emif_enable:
+	ldr	r3, [r1]
+	cmp	r2, r3
+	bne	wait_emif_enable
+
+
+	ldr	r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
+	blx	r1
+
+	/*
+	 * Set SCTLR.C bit to allow data cache allocation
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #(1 << 2)	@ Enable the C bit
+	mcr	p15, 0, r0, c1, c0, 0
+	isb
+
+	/* Let the suspend code know about the abort */
+	mov	r0, #1
+	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
+ENDPROC(am33xx_do_wfi)
+
+	.align
+ENTRY(am33xx_resume_offset)
+	.word . - am33xx_do_wfi
+
+ENTRY(am33xx_resume_from_deep_sleep)
+	/* Re-enable EMIF */
+	ldr	r0, phys_emif_clkctrl
+	mov	r1, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
+	str	r1, [r0]
+wait_emif_enable1:
+	ldr	r2, [r0]
+	cmp	r1, r2
+	bne	wait_emif_enable1
+
+	adr	r9, am33xx_emif_sram_table
+
+	ldr	r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET]
+	blx	r1
+
+	ldr	r1, [r9, #EMIF_PM_EXIT_SR_OFFSET]
+	blx	r1
+
+resume_to_ddr:
+	/* We are back. Branch to the common CPU resume routine */
+	mov	r0, #0
+	ldr	pc, resume_addr
+ENDPROC(am33xx_resume_from_deep_sleep)
+
+/*
+ * Local variables
+ */
+	.align
+resume_addr:
+	.word	cpu_resume - PAGE_OFFSET + 0x80000000
+kernel_flush:
+	.word   v7_flush_dcache_all
+virt_mpu_clkctrl:
+	.word	AM33XX_CM_MPU_MPU_CLKCTRL
+virt_emif_clkctrl:
+	.word	AM33XX_CM_PER_EMIF_CLKCTRL
+phys_emif_clkctrl:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_PER_MOD + \
+		AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET)
+
+.align 3
+/* DDR related defines */
+am33xx_emif_sram_table:
+	.space EMIF_PM_FUNCTIONS_SIZE
+
+ENTRY(am33xx_pm_sram)
+	.word am33xx_do_wfi
+	.word am33xx_do_wfi_sz
+	.word am33xx_resume_offset
+	.word am33xx_emif_sram_table
+	.word am33xx_pm_ro_sram_data
+
+.align 3
+ENTRY(am33xx_pm_ro_sram_data)
+	.space AMX3_PM_RO_SRAM_DATA_SIZE
+
+ENTRY(am33xx_do_wfi_sz)
+	.word	. - am33xx_do_wfi
diff --git a/arch/arm/mach-omap2/sleep43xx.S b/arch/arm/mach-omap2/sleep43xx.S
new file mode 100644
index 0000000..b24be62
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep43xx.S
@@ -0,0 +1,391 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Low level suspend code for AM43XX SoCs
+ *
+ * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
+ *	Dave Gerlach, Vaibhav Bedia
+ */
+
+#include <generated/ti-emif-asm-offsets.h>
+#include <generated/ti-pm-asm-offsets.h>
+#include <linux/linkage.h>
+#include <linux/ti-emif-sram.h>
+
+#include <asm/assembler.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/memory.h>
+
+#include "cm33xx.h"
+#include "common.h"
+#include "iomap.h"
+#include "omap-secure.h"
+#include "omap44xx.h"
+#include "prm33xx.h"
+#include "prcm43xx.h"
+
+#define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED		0x00030000
+#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE		0x0003
+#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE		0x0002
+
+#define AM43XX_EMIF_POWEROFF_ENABLE			0x1
+#define AM43XX_EMIF_POWEROFF_DISABLE			0x0
+
+#define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP		0x1
+#define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO		0x3
+
+#define AM43XX_CM_BASE					0x44DF0000
+
+#define AM43XX_CM_REGADDR(inst, reg)                           \
+       AM33XX_L4_WK_IO_ADDRESS(AM43XX_CM_BASE + (inst) + (reg))
+
+#define AM43XX_CM_MPU_CLKSTCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \
+					AM43XX_CM_MPU_MPU_CDOFFS)
+#define AM43XX_CM_MPU_MPU_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \
+					AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET)
+#define AM43XX_CM_PER_EMIF_CLKCTRL  AM43XX_CM_REGADDR(AM43XX_CM_PER_INST, \
+					AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
+#define AM43XX_PRM_EMIF_CTRL_OFFSET			0x0030
+
+	.arm
+	.align 3
+
+ENTRY(am43xx_do_wfi)
+	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
+
+#ifdef CONFIG_CACHE_L2X0
+	/* Retrieve l2 cache virt address BEFORE we shut off EMIF */
+	ldr	r1, get_l2cache_base
+	blx	r1
+	mov	r8, r0
+#endif
+
+	/*
+	 * Flush all data from the L1 and L2 data cache before disabling
+	 * SCTLR.C bit.
+	 */
+	ldr	r1, kernel_flush
+	blx	r1
+
+	/*
+	 * Clear the SCTLR.C bit to prevent further data cache
+	 * allocation. Clearing SCTLR.C would make all the data accesses
+	 * strongly ordered and would not hit the cache.
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #(1 << 2)	@ Disable the C bit
+	mcr	p15, 0, r0, c1, c0, 0
+	isb
+	dsb
+
+	/*
+	 * Invalidate L1 and L2 data cache.
+	 */
+	ldr	r1, kernel_flush
+	blx	r1
+
+#ifdef CONFIG_CACHE_L2X0
+	/*
+	 * Clean and invalidate the L2 cache.
+	 */
+#ifdef CONFIG_PL310_ERRATA_727915
+	mov	r0, #0x03
+	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
+	dsb
+	smc	#0
+	dsb
+#endif
+	mov	r0, r8
+	adr	r4, am43xx_pm_ro_sram_data
+	ldr	r3, [r4, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+
+	mov	r2, r0
+	ldr	r0, [r2, #L2X0_AUX_CTRL]
+	str	r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
+	ldr	r0, [r2, #L310_PREFETCH_CTRL]
+	str	r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
+
+	ldr	r0, l2_val
+	str	r0, [r2, #L2X0_CLEAN_INV_WAY]
+wait:
+	ldr	r0, [r2, #L2X0_CLEAN_INV_WAY]
+	ldr	r1, l2_val
+	ands	r0, r0, r1
+	bne	wait
+#ifdef CONFIG_PL310_ERRATA_727915
+	mov	r0, #0x00
+	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
+	dsb
+	smc	#0
+	dsb
+#endif
+l2x_sync:
+	mov	r0, r8
+	mov	r2, r0
+	mov	r0, #0x0
+	str	r0, [r2, #L2X0_CACHE_SYNC]
+sync:
+	ldr	r0, [r2, #L2X0_CACHE_SYNC]
+	ands	r0, r0, #0x1
+	bne	sync
+#endif
+
+	adr     r9, am43xx_emif_sram_table
+
+	ldr     r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
+	blx     r3
+
+	ldr     r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
+	blx     r3
+
+	/* Disable EMIF */
+	ldr	r1, am43xx_virt_emif_clkctrl
+	ldr	r2, [r1]
+	bic	r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
+	str	r2, [r1]
+
+wait_emif_disable:
+	ldr	r2, [r1]
+	mov	r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED
+	cmp	r2, r3
+	bne	wait_emif_disable
+
+	/*
+	 * For the MPU WFI to be registered as an interrupt
+	 * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
+	 * to DISABLED
+	 */
+	ldr	r1, am43xx_virt_mpu_clkctrl
+	ldr	r2, [r1]
+	bic	r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
+	str	r2, [r1]
+
+	/*
+	 * Put MPU CLKDM to SW_SLEEP
+	 */
+	ldr	r1, am43xx_virt_mpu_clkstctrl
+	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP
+	str	r2, [r1]
+
+	/*
+	 * Execute a barrier instruction to ensure that all cache,
+	 * TLB and branch predictor maintenance operations issued
+	 * have completed.
+	 */
+	dsb
+	dmb
+
+	/*
+	 * Execute a WFI instruction and wait until the
+	 * STANDBYWFI output is asserted to indicate that the
+	 * CPU is in idle and low power state. CPU can specualatively
+	 * prefetch the instructions so add NOPs after WFI. Sixteen
+	 * NOPs as per Cortex-A9 pipeline.
+	 */
+	wfi
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* We come here in case of an abort due to a late interrupt */
+	ldr	r1, am43xx_virt_mpu_clkstctrl
+	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
+	str	r2, [r1]
+
+	/* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */
+	ldr	r1, am43xx_virt_mpu_clkctrl
+	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
+	str	r2, [r1]
+
+	/* Re-enable EMIF */
+	ldr	r1, am43xx_virt_emif_clkctrl
+	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
+	str	r2, [r1]
+wait_emif_enable:
+	ldr	r3, [r1]
+	cmp	r2, r3
+	bne	wait_emif_enable
+
+	/*
+	 * Set SCTLR.C bit to allow data cache allocation
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #(1 << 2)	@ Enable the C bit
+	mcr	p15, 0, r0, c1, c0, 0
+	isb
+
+	ldr     r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
+	blx     r1
+
+	/* Let the suspend code know about the abort */
+	mov	r0, #1
+	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
+ENDPROC(am43xx_do_wfi)
+
+	.align
+ENTRY(am43xx_resume_offset)
+	.word . - am43xx_do_wfi
+
+ENTRY(am43xx_resume_from_deep_sleep)
+	/* Set MPU CLKSTCTRL to HW AUTO so that CPUidle works properly */
+	ldr	r1, am43xx_virt_mpu_clkstctrl
+	mov	r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
+	str	r2, [r1]
+
+	/* For AM43xx, use EMIF power down until context is restored */
+	ldr	r2, am43xx_phys_emif_poweroff
+	mov	r1, #AM43XX_EMIF_POWEROFF_ENABLE
+	str	r1, [r2, #0x0]
+
+	/* Re-enable EMIF */
+	ldr	r1, am43xx_phys_emif_clkctrl
+	mov	r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
+	str	r2, [r1]
+wait_emif_enable1:
+	ldr	r3, [r1]
+	cmp	r2, r3
+	bne	wait_emif_enable1
+
+	adr     r9, am43xx_emif_sram_table
+
+	ldr     r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET]
+	blx     r1
+
+	ldr     r1, [r9, #EMIF_PM_EXIT_SR_OFFSET]
+	blx     r1
+
+	ldr     r2, am43xx_phys_emif_poweroff
+	mov     r1, #AM43XX_EMIF_POWEROFF_DISABLE
+	str     r1, [r2, #0x0]
+
+#ifdef CONFIG_CACHE_L2X0
+	ldr	r2, l2_cache_base
+	ldr	r0, [r2, #L2X0_CTRL]
+	and	r0, #0x0f
+	cmp	r0, #1
+	beq	skip_l2en			@ Skip if already enabled
+
+	adr	r4, am43xx_pm_ro_sram_data
+	ldr	r3, [r4, #AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET]
+	ldr     r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
+
+	ldr	r12, l2_smc1
+	dsb
+	smc	#0
+	dsb
+set_aux_ctrl:
+	ldr     r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
+	ldr	r12, l2_smc2
+	dsb
+	smc	#0
+	dsb
+
+	/* L2 invalidate on resume */
+	ldr	r0, l2_val
+	ldr	r2, l2_cache_base
+	str	r0, [r2, #L2X0_INV_WAY]
+wait2:
+	ldr	r0, [r2, #L2X0_INV_WAY]
+	ldr	r1, l2_val
+	ands	r0, r0, r1
+	bne	wait2
+#ifdef CONFIG_PL310_ERRATA_727915
+	mov	r0, #0x00
+	mov	r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
+	dsb
+	smc	#0
+	dsb
+#endif
+l2x_sync2:
+	ldr	r2, l2_cache_base
+	mov	r0, #0x0
+	str	r0, [r2, #L2X0_CACHE_SYNC]
+sync2:
+	ldr	r0, [r2, #L2X0_CACHE_SYNC]
+	ands	r0, r0, #0x1
+	bne	sync2
+
+	mov	r0, #0x1
+	ldr	r12, l2_smc3
+	dsb
+	smc	#0
+	dsb
+#endif
+skip_l2en:
+	/* We are back. Branch to the common CPU resume routine */
+	mov	r0, #0
+	ldr	pc, resume_addr
+ENDPROC(am43xx_resume_from_deep_sleep)
+
+/*
+ * Local variables
+ */
+	.align
+resume_addr:
+	.word	cpu_resume - PAGE_OFFSET + 0x80000000
+kernel_flush:
+	.word   v7_flush_dcache_all
+ddr_start:
+	.word	PAGE_OFFSET
+
+am43xx_phys_emif_poweroff:
+	.word   (AM43XX_CM_BASE + AM43XX_PRM_DEVICE_INST + \
+		 AM43XX_PRM_EMIF_CTRL_OFFSET)
+am43xx_virt_mpu_clkstctrl:
+	.word	(AM43XX_CM_MPU_CLKSTCTRL)
+am43xx_virt_mpu_clkctrl:
+	.word	(AM43XX_CM_MPU_MPU_CLKCTRL)
+am43xx_virt_emif_clkctrl:
+	.word	(AM43XX_CM_PER_EMIF_CLKCTRL)
+am43xx_phys_emif_clkctrl:
+	.word	(AM43XX_CM_BASE + AM43XX_CM_PER_INST + \
+		 AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
+
+#ifdef CONFIG_CACHE_L2X0
+/* L2 cache related defines for AM437x */
+get_l2cache_base:
+	.word	omap4_get_l2cache_base
+l2_cache_base:
+	.word	OMAP44XX_L2CACHE_BASE
+l2_smc1:
+	.word	OMAP4_MON_L2X0_PREFETCH_INDEX
+l2_smc2:
+	.word	OMAP4_MON_L2X0_AUXCTRL_INDEX
+l2_smc3:
+	.word	OMAP4_MON_L2X0_CTRL_INDEX
+l2_val:
+	.word	0xffff
+#endif
+
+.align 3
+/* DDR related defines */
+ENTRY(am43xx_emif_sram_table)
+	.space EMIF_PM_FUNCTIONS_SIZE
+
+ENTRY(am43xx_pm_sram)
+	.word am43xx_do_wfi
+	.word am43xx_do_wfi_sz
+	.word am43xx_resume_offset
+	.word am43xx_emif_sram_table
+	.word am43xx_pm_ro_sram_data
+
+.align 3
+
+ENTRY(am43xx_pm_ro_sram_data)
+	.space AMX3_PM_RO_SRAM_DATA_SIZE
+
+ENTRY(am43xx_do_wfi_sz)
+	.word	. - am43xx_do_wfi
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
index 56dfa2d5..0cae3b0 100644
--- a/arch/arm/mach-omap2/sleep44xx.S
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -90,12 +90,7 @@
 	mcr	p15, 0, r0, c1, c0, 0
 	isb
 
-	/*
-	 * Invalidate L1 data cache. Even though only invalidate is
-	 * necessary exported flush API is used here. Doing clean
-	 * on already clean cache would be almost NOP.
-	 */
-	bl	v7_flush_dcache_all
+	bl	v7_invalidate_l1
 
 	/*
 	 * Switch the CPU from Symmetric Multiprocessing (SMP) mode
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index eef6935..0854ed9 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -89,18 +89,27 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
 	sr_data->nvalue_count = j;
 }
 
+extern struct omap_sr_data omap_sr_pdata[];
+
 static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
 {
-	struct omap_sr_data *sr_data;
-	struct platform_device *pdev;
+	struct omap_sr_data *sr_data = NULL;
 	struct omap_volt_data *volt_data;
 	struct omap_smartreflex_dev_attr *sr_dev_attr;
-	char *name = "smartreflex";
 	static int i;
 
-	sr_data = kzalloc(sizeof(*sr_data), GFP_KERNEL);
-	if (!sr_data)
-		return -ENOMEM;
+	if (!strncmp(oh->name, "smartreflex_mpu_iva", 20) ||
+	    !strncmp(oh->name, "smartreflex_mpu", 16))
+		sr_data = &omap_sr_pdata[OMAP_SR_MPU];
+	else if (!strncmp(oh->name, "smartreflex_core", 17))
+		sr_data = &omap_sr_pdata[OMAP_SR_CORE];
+	else if (!strncmp(oh->name, "smartreflex_iva", 16))
+		sr_data = &omap_sr_pdata[OMAP_SR_IVA];
+
+	if (!sr_data) {
+		pr_err("%s: Unknown instance %s\n", __func__, oh->name);
+		return -EINVAL;
+	}
 
 	sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
 	if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
@@ -145,13 +154,9 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
 
 	sr_data->enable_on_init = sr_enable_on_init;
 
-	pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data));
-	if (IS_ERR(pdev))
-		pr_warn("%s: Could not build omap_device for %s: %s\n",
-			__func__, name, oh->name);
 exit:
 	i++;
-	kfree(sr_data);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index d61fbd7..4fb4dc2 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -49,7 +49,7 @@
 #include "omap_hwmod.h"
 #include "omap_device.h"
 #include <plat/counter-32k.h>
-#include <plat/dmtimer.h>
+#include <clocksource/timer-ti-dm.h>
 #include "omap-pm.h"
 
 #include "soc.h"
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 69d7f48..c5c0ab8 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -404,7 +404,7 @@ static void __init cm_x300_init_ac97(void)
 static inline void cm_x300_init_ac97(void) {}
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct mtd_partition cm_x300_nand_partitions[] = {
 	[0] = {
 		.name        = "OBM",
@@ -442,11 +442,9 @@ static struct mtd_partition cm_x300_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
-	.enable_arbiter	= 1,
 	.keep_config	= 1,
-	.num_cs		= 1,
-	.parts[0]	= cm_x300_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(cm_x300_nand_partitions),
+	.parts		= cm_x300_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(cm_x300_nand_partitions),
 };
 
 static void __init cm_x300_init_nand(void)
@@ -522,7 +520,7 @@ static int cm_x300_ulpi_phy_reset(void)
 	return 0;
 }
 
-static inline int cm_x300_u2d_init(struct device *dev)
+static int cm_x300_u2d_init(struct device *dev)
 {
 	int err = 0;
 
@@ -534,7 +532,7 @@ static inline int cm_x300_u2d_init(struct device *dev)
 			pr_err("failed to get CLK_POUT: %d\n", err);
 			return err;
 		}
-		clk_enable(pout_clk);
+		clk_prepare_enable(pout_clk);
 
 		err = cm_x300_ulpi_phy_reset();
 		if (err) {
@@ -549,7 +547,7 @@ static inline int cm_x300_u2d_init(struct device *dev)
 static void cm_x300_u2d_exit(struct device *dev)
 {
 	if (cpu_is_pxa310()) {
-		clk_disable(pout_clk);
+		clk_disable_unprepare(pout_clk);
 		clk_put(pout_clk);
 	}
 }
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index b04431b..e31a591 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -110,7 +110,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin)
 }
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct mtd_partition colibri_nand_partitions[] = {
 	{
 		.name        = "bootloader",
@@ -138,11 +138,9 @@ static struct mtd_partition colibri_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data colibri_nand_info = {
-	.enable_arbiter	= 1,
 	.keep_config	= 1,
-	.num_cs		= 1,
-	.parts[0]	= colibri_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(colibri_nand_partitions),
+	.parts		= colibri_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(colibri_nand_partitions),
 };
 
 void __init colibri_pxa3xx_init_nand(void)
diff --git a/arch/arm/mach-pxa/colibri.h b/arch/arm/mach-pxa/colibri.h
index 673a131..85525d4 100644
--- a/arch/arm/mach-pxa/colibri.h
+++ b/arch/arm/mach-pxa/colibri.h
@@ -46,7 +46,7 @@ static inline void colibri_pxa3xx_init_lcd(int bl_pin) {}
 extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data);
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 extern void colibri_pxa3xx_init_nand(void);
 #else
 static inline void colibri_pxa3xx_init_nand(void) {}
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 4105614..9e132b3 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -291,7 +291,7 @@ static void __init littleton_init_mmc(void)
 static inline void littleton_init_mmc(void) {}
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct mtd_partition littleton_nand_partitions[] = {
 	[0] = {
 		.name        = "Bootloader",
@@ -329,10 +329,8 @@ static struct mtd_partition littleton_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data littleton_nand_info = {
-	.enable_arbiter	= 1,
-	.num_cs		= 1,
-	.parts[0]	= littleton_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(littleton_nand_partitions),
+	.parts		= littleton_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(littleton_nand_partitions),
 };
 
 static void __init littleton_init_nand(void)
@@ -341,7 +339,7 @@ static void __init littleton_init_nand(void)
 }
 #else
 static inline void littleton_init_nand(void) {}
-#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */
 
 #if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
 static struct led_info littleton_da9034_leds[] = {
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
index f9e3d41..616b223 100644
--- a/arch/arm/mach-pxa/mxm8x10.c
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -359,7 +359,7 @@ void __init mxm_8x10_ac97_init(void)
 }
 
 /* NAND flash Support */
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 #define NAND_BLOCK_SIZE SZ_128K
 #define NB(x)           (NAND_BLOCK_SIZE * (x))
 static struct mtd_partition mxm_8x10_nand_partitions[] = {
@@ -389,11 +389,9 @@ static struct mtd_partition mxm_8x10_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
-	.enable_arbiter	= 1,
 	.keep_config	= 1,
-	.num_cs		= 1,
-	.parts[0]	= mxm_8x10_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(mxm_8x10_nand_partitions)
+	.parts		= mxm_8x10_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(mxm_8x10_nand_partitions)
 };
 
 static void __init mxm_8x10_nand_init(void)
@@ -402,7 +400,7 @@ static void __init mxm_8x10_nand_init(void)
 }
 #else
 static inline void mxm_8x10_nand_init(void) {}
-#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */
 
 /* Ethernet support: Davicom DM9000 */
 static struct resource dm9k_resources[] = {
diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c
index 60cb59a..b3e2016 100644
--- a/arch/arm/mach-pxa/pxa3xx-ulpi.c
+++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c
@@ -256,7 +256,7 @@ int pxa3xx_u2d_start_hc(struct usb_bus *host)
 	if (!u2d)
 		return 0;
 
-	clk_enable(u2d->clk);
+	clk_prepare_enable(u2d->clk);
 
 	if (cpu_is_pxa310()) {
 		pxa310_u2d_setup_otg_hc();
@@ -276,7 +276,7 @@ void pxa3xx_u2d_stop_hc(struct usb_bus *host)
 	if (cpu_is_pxa310())
 		pxa310_stop_otg_hc();
 
-	clk_disable(u2d->clk);
+	clk_disable_unprepare(u2d->clk);
 }
 EXPORT_SYMBOL_GPL(pxa3xx_u2d_stop_hc);
 
@@ -331,7 +331,7 @@ static int pxa3xx_u2d_probe(struct platform_device *pdev)
 			goto err_free_plat;
 	}
 
-	platform_set_drvdata(pdev, &u2d);
+	platform_set_drvdata(pdev, u2d);
 
 	return 0;
 
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index e7ac7dc..0343455 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -346,11 +346,9 @@ static struct mtd_partition raumfeld_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
-	.enable_arbiter	= 1,
 	.keep_config	= 1,
-	.num_cs		= 1,
-	.parts[0]	= raumfeld_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(raumfeld_nand_partitions),
+	.parts		= raumfeld_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(raumfeld_nand_partitions),
 };
 
 /**
@@ -378,9 +376,9 @@ static struct gpiod_lookup_table raumfeld_rotary_gpios_table = {
 };
 
 static const struct property_entry raumfeld_rotary_properties[] __initconst = {
-	PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24),
-	PROPERTY_ENTRY_INTEGER("linux,axis",			  u32, REL_X),
-	PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis",	  u32, 1),
+	PROPERTY_ENTRY_U32("rotary-encoder,steps-per-period", 24),
+	PROPERTY_ENTRY_U32("linux,axis",		      REL_X),
+	PROPERTY_ENTRY_U32("rotary-encoder,relative_axis",    1),
 	{ },
 };
 
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 4268552..d69de31 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -338,7 +338,7 @@ static void __init zylonite_init_keypad(void)
 static inline void zylonite_init_keypad(void) {}
 #endif
 
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
 static struct mtd_partition zylonite_nand_partitions[] = {
 	[0] = {
 		.name        = "Bootloader",
@@ -376,10 +376,8 @@ static struct mtd_partition zylonite_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data zylonite_nand_info = {
-	.enable_arbiter	= 1,
-	.num_cs		= 1,
-	.parts[0]	= zylonite_nand_partitions,
-	.nr_parts[0]	= ARRAY_SIZE(zylonite_nand_partitions),
+	.parts		= zylonite_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(zylonite_nand_partitions),
 };
 
 static void __init zylonite_init_nand(void)
@@ -388,7 +386,7 @@ static void __init zylonite_init_nand(void)
 }
 #else
 static inline void zylonite_init_nand(void) {}
-#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 static struct pxaohci_platform_data zylonite_ohci_info = {
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
index ecec340..51984a4 100644
--- a/arch/arm/mach-rockchip/platsmp.c
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -208,6 +208,7 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node)
 }
 
 static const struct regmap_config rockchip_pmu_regmap_config = {
+	.name = "rockchip-pmu",
 	.reg_bits = 32,
 	.val_bits = 32,
 	.reg_stride = 4,
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
index a8fa4f7..43c1ac69 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -7,6 +7,10 @@ extern void shmobile_init_delay(void);
 extern void shmobile_boot_vector(void);
 extern unsigned long shmobile_boot_fn;
 extern unsigned long shmobile_boot_size;
+extern void shmobile_boot_vector_gen2(void);
+extern unsigned long shmobile_boot_fn_gen2;
+extern unsigned long shmobile_boot_cpu_gen2;
+extern unsigned long shmobile_boot_size_gen2;
 extern void shmobile_smp_boot(void);
 extern void shmobile_smp_sleep(void);
 extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
index 32e0bf6..cef8e8c 100644
--- a/arch/arm/mach-shmobile/headsmp.S
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -16,6 +16,11 @@
 #include <asm/assembler.h>
 #include <asm/memory.h>
 
+#define SCTLR_MMU	0x01
+#define BOOTROM_ADDRESS	0xE6340000
+#define RWTCSRA_ADDRESS 0xE6020004
+#define RWTCSRA_WOVF	0x10
+
 /*
  * Reset vector for secondary CPUs.
  * This will be mapped at address 0 by SBAR register.
@@ -37,6 +42,56 @@
 shmobile_boot_size:
 	.long	. - shmobile_boot_vector
 
+#ifdef CONFIG_ARCH_RCAR_GEN2
+/*
+ * Reset vector for R-Car Gen2 and RZ/G1 secondary CPUs.
+ * This will be mapped at address 0 by SBAR register.
+ */
+ENTRY(shmobile_boot_vector_gen2)
+	mrc	p15, 0, r0, c0, c0, 5		@ r0 = MPIDR
+	ldr	r1, shmobile_boot_cpu_gen2
+	cmp	r0, r1
+	bne	shmobile_smp_continue_gen2
+
+	mrc	p15, 0, r1, c1, c0, 0		@ r1 = SCTLR
+	and	r0, r1, #SCTLR_MMU
+	cmp	r0, #SCTLR_MMU
+	beq	shmobile_smp_continue_gen2
+
+	ldr	r0, rwtcsra
+	mov	r1, #0
+	ldrb	r1, [r0]
+	and	r0, r1, #RWTCSRA_WOVF
+	cmp	r0, #RWTCSRA_WOVF
+	bne	shmobile_smp_continue_gen2
+
+	ldr	r0, bootrom
+	bx	r0
+
+shmobile_smp_continue_gen2:
+	ldr     r1, shmobile_boot_fn_gen2
+	bx	r1
+
+ENDPROC(shmobile_boot_vector_gen2)
+
+	.align	4
+rwtcsra:
+	.word	RWTCSRA_ADDRESS
+bootrom:
+	.word	BOOTROM_ADDRESS
+	.globl	shmobile_boot_cpu_gen2
+shmobile_boot_cpu_gen2:
+	.word	0x00000000
+
+	.align	2
+	.globl	shmobile_boot_fn_gen2
+shmobile_boot_fn_gen2:
+	.space	4
+	.globl	shmobile_boot_size_gen2
+shmobile_boot_size_gen2:
+	.long	. - shmobile_boot_vector_gen2
+#endif /* CONFIG_ARCH_RCAR_GEN2 */
+
 /*
  * Per-CPU SMP boot function/argument selection code based on MPIDR
  */
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
index 4422b61..ba732ef 100644
--- a/arch/arm/mach-shmobile/platsmp-apmu.c
+++ b/arch/arm/mach-shmobile/platsmp-apmu.c
@@ -191,6 +191,7 @@ static void __init shmobile_smp_apmu_setup_boot(void)
 {
 	/* install boot code shared by all CPUs */
 	shmobile_boot_fn = __pa_symbol(shmobile_smp_boot);
+	shmobile_boot_fn_gen2 = shmobile_boot_fn;
 }
 
 void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c
index e5f215c..5a798b4 100644
--- a/arch/arm/mach-shmobile/pm-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c
@@ -17,6 +17,7 @@
 #include <linux/smp.h>
 #include <linux/soc/renesas/rcar-sysc.h>
 #include <asm/io.h>
+#include <asm/cputype.h>
 #include "common.h"
 #include "rcar-gen2.h"
 
@@ -37,7 +38,6 @@
 #define CA7RESCNT_CODE	0x5a5a0000
 #define CA7RESCNT_CPUS	0xf		/* CPU0-3 */
 
-
 /* On-chip RAM */
 #define ICRAM1		0xe63c0000	/* Inter Connect RAM1 (4 KiB) */
 
@@ -119,8 +119,17 @@ void __init rcar_gen2_pm_init(void)
 	p = ioremap(res.start, resource_size(&res));
 	if (!p)
 		return;
-
-	memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
+	/*
+	 * install the reset vector, use the largest version if we have enough
+	 * memory available
+	 */
+	if (resource_size(&res) >= shmobile_boot_size_gen2) {
+		shmobile_boot_cpu_gen2 = read_cpuid_mpidr();
+		memcpy_toio(p, shmobile_boot_vector_gen2,
+			    shmobile_boot_size_gen2);
+	} else {
+		memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
+	}
 	iounmap(p);
 
 	/* setup reset vectors */
diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
index 44438f3..93f628a 100644
--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -1,9 +1,9 @@
 /*
  * R-Car Generation 2 da9063/da9210 regulator quirk
  *
- * The r8a7790/lager and r8a7791/koelsch development boards have da9063 and
- * da9210 regulators.  Both regulators have their interrupt request lines tied
- * to the same interrupt pin (IRQ2) on the SoC.
+ * Certain Gen2 development boards have an da9063 and one or more da9210
+ * regulators. All of these regulators have their interrupt request lines
+ * tied to the same interrupt pin (IRQ2) on the SoC.
  *
  * After cold boot or da9063-induced restart, both the da9063 and da9210 seem
  * to assert their interrupt request lines.  Hence as soon as one driver
@@ -50,7 +50,7 @@ static void __iomem *irqc;
 static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff };
 static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff };
 
-static struct i2c_msg da9xxx_msgs[2] = {
+static struct i2c_msg da9xxx_msgs[3] = {
 	{
 		.addr = 0x58,
 		.len = ARRAY_SIZE(da9063_irq_clr),
@@ -59,6 +59,10 @@ static struct i2c_msg da9xxx_msgs[2] = {
 		.addr = 0x68,
 		.len = ARRAY_SIZE(da9210_irq_clr),
 		.buf = da9210_irq_clr,
+	}, {
+		.addr = 0x70,
+		.len = ARRAY_SIZE(da9210_irq_clr),
+		.buf = da9210_irq_clr,
 	},
 };
 
@@ -85,12 +89,16 @@ static int regulator_quirk_notify(struct notifier_block *nb,
 	dev_dbg(dev, "Detected %s\n", client->name);
 
 	if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) ||
-	    (client->addr == 0x68 && !strcmp(client->name, "da9210"))) {
-		int ret;
+	    (client->addr == 0x68 && !strcmp(client->name, "da9210")) ||
+	    (client->addr == 0x70 && !strcmp(client->name, "da9210"))) {
+		int ret, len;
+
+		/* There are two DA9210 on Stout, one on the other boards. */
+		len = of_machine_is_compatible("renesas,stout") ? 3 : 2;
 
 		dev_info(&client->dev, "clearing da9063/da9210 interrupts\n");
-		ret = i2c_transfer(client->adapter, da9xxx_msgs, ARRAY_SIZE(da9xxx_msgs));
-		if (ret != ARRAY_SIZE(da9xxx_msgs))
+		ret = i2c_transfer(client->adapter, da9xxx_msgs, len);
+		if (ret != len)
 			dev_err(&client->dev, "i2c error %d\n", ret);
 	}
 
@@ -118,6 +126,7 @@ static int __init rcar_gen2_regulator_quirk(void)
 
 	if (!of_machine_is_compatible("renesas,koelsch") &&
 	    !of_machine_is_compatible("renesas,lager") &&
+	    !of_machine_is_compatible("renesas,stout") &&
 	    !of_machine_is_compatible("renesas,gose"))
 		return -ENODEV;
 
diff --git a/arch/arm/mach-socfpga/pm.c b/arch/arm/mach-socfpga/pm.c
index c378ab0..d486678 100644
--- a/arch/arm/mach-socfpga/pm.c
+++ b/arch/arm/mach-socfpga/pm.c
@@ -116,7 +116,6 @@ static int socfpga_pm_suspend(unsigned long arg)
 static int socfpga_pm_enter(suspend_state_t state)
 {
 	switch (state) {
-	case PM_SUSPEND_STANDBY:
 	case PM_SUSPEND_MEM:
 		outer_disable();
 		cpu_suspend(0, socfpga_pm_suspend);
diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig
index 0d1889b..713c068 100644
--- a/arch/arm/mach-stm32/Kconfig
+++ b/arch/arm/mach-stm32/Kconfig
@@ -1,8 +1,10 @@
-config ARCH_STM32
-	bool "STMicrolectronics STM32"
-	depends on ARM_SINGLE_ARMV7M
+menuconfig ARCH_STM32
+	bool "STMicroelectronics STM32 family" if ARM_SINGLE_ARMV7M || ARCH_MULTI_V7
+	select ARMV7M_SYSTICK if ARM_SINGLE_ARMV7M
+	select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
+	select ARM_GIC if ARCH_MULTI_V7
+	select ARM_PSCI if ARCH_MULTI_V7
 	select ARCH_HAS_RESET_CONTROLLER
-	select ARMV7M_SYSTICK
 	select CLKSRC_STM32
 	select PINCTRL
 	select RESET_CONTROLLER
@@ -10,22 +12,42 @@
 	help
 	  Support for STMicroelectronics STM32 processors.
 
+if ARCH_STM32
+
+if ARM_SINGLE_ARMV7M
+
 config MACH_STM32F429
-	bool "STMicrolectronics STM32F429"
-	depends on ARCH_STM32
+	bool "STMicroelectronics STM32F429"
+	select ARM_AMBA
 	default y
 
 config MACH_STM32F469
-	bool "STMicrolectronics STM32F469"
-	depends on ARCH_STM32
+	bool "STMicroelectronics STM32F469"
+	select ARM_AMBA
 	default y
 
 config MACH_STM32F746
-	bool "STMicrolectronics STM32F746"
-	depends on ARCH_STM32
+	bool "STMicroelectronics STM32F746"
+	select ARM_AMBA
+	default y
+
+config MACH_STM32F769
+	bool "STMicroelectronics STM32F769"
+	select ARM_AMBA
 	default y
 
 config MACH_STM32H743
-	bool "STMicrolectronics STM32H743"
-	depends on ARCH_STM32
+	bool "STMicroelectronics STM32H743"
 	default y
+
+endif # ARMv7-M
+
+if ARCH_MULTI_V7
+
+config MACH_STM32MP157
+	bool "STMicroelectronics STM32MP157"
+	default y
+
+endif # ARMv7-A
+
+endif
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
index e918686..011d57b 100644
--- a/arch/arm/mach-stm32/board-dt.c
+++ b/arch/arm/mach-stm32/board-dt.c
@@ -1,22 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) Maxime Coquelin 2015
+ * Copyright (C) STMicroelectronics 2017
  * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/kernel.h>
-#include <asm/v7m.h>
 #include <asm/mach/arch.h>
+#ifdef CONFIG_ARM_SINGLE_ARMV7M
+#include <asm/v7m.h>
+#endif
 
 static const char *const stm32_compat[] __initconst = {
 	"st,stm32f429",
 	"st,stm32f469",
 	"st,stm32f746",
+	"st,stm32f769",
 	"st,stm32h743",
+	"st,stm32mp157",
 	NULL
 };
 
 DT_MACHINE_START(STM32DT, "STM32 (Device Tree Support)")
 	.dt_compat = stm32_compat,
+#ifdef CONFIG_ARM_SINGLE_ARMV7M
 	.restart = armv7m_restart,
+#endif
 MACHINE_END
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 58153cd..ce53cea 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -48,4 +48,11 @@
 	default ARCH_SUNXI
 	select ARM_GIC
 
+config ARCH_SUNXI_MC_SMP
+	bool
+	depends on SMP
+	default MACH_SUN9I
+	select ARM_CCI400_PORT_CTRL
+	select ARM_CPU_SUSPEND
+
 endif
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 27b168f..7de9cc2 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -1,2 +1,5 @@
+CFLAGS_mc_smp.o	+= -march=armv7-a
+
 obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
+obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o
 obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
new file mode 100644
index 0000000..c0246ec
--- /dev/null
+++ b/arch/arm/mach-sunxi/mc_smp.c
@@ -0,0 +1,856 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * arch/arm/mach-sunxi/mc_smp.c
+ *
+ * Based on Allwinner code, arch/arm/mach-exynos/mcpm-exynos.c, and
+ * arch/arm/mach-hisi/platmcpm.c
+ * Cluster cache enable trampoline code adapted from MCPM framework
+ */
+
+#include <linux/arm-cci.h>
+#include <linux/cpu_pm.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/cputype.h>
+#include <asm/idmap.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+
+#define SUNXI_CPUS_PER_CLUSTER		4
+#define SUNXI_NR_CLUSTERS		2
+
+#define POLL_USEC	100
+#define TIMEOUT_USEC	100000
+
+#define CPUCFG_CX_CTRL_REG0(c)		(0x10 * (c))
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n)	BIT(n)
+#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL	0xf
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7	BIT(4)
+#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15	BIT(0)
+#define CPUCFG_CX_CTRL_REG1(c)		(0x10 * (c) + 0x4)
+#define CPUCFG_CX_CTRL_REG1_ACINACTM	BIT(0)
+#define CPUCFG_CX_STATUS(c)		(0x30 + 0x4 * (c))
+#define CPUCFG_CX_STATUS_STANDBYWFI(n)	BIT(16 + (n))
+#define CPUCFG_CX_STATUS_STANDBYWFIL2	BIT(0)
+#define CPUCFG_CX_RST_CTRL(c)		(0x80 + 0x4 * (c))
+#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST	BIT(24)
+#define CPUCFG_CX_RST_CTRL_ETM_RST(n)	BIT(20 + (n))
+#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL	(0xf << 20)
+#define CPUCFG_CX_RST_CTRL_DBG_RST(n)	BIT(16 + (n))
+#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL	(0xf << 16)
+#define CPUCFG_CX_RST_CTRL_H_RST	BIT(12)
+#define CPUCFG_CX_RST_CTRL_L2_RST	BIT(8)
+#define CPUCFG_CX_RST_CTRL_CX_RST(n)	BIT(4 + (n))
+#define CPUCFG_CX_RST_CTRL_CORE_RST(n)	BIT(n)
+
+#define PRCM_CPU_PO_RST_CTRL(c)		(0x4 + 0x4 * (c))
+#define PRCM_CPU_PO_RST_CTRL_CORE(n)	BIT(n)
+#define PRCM_CPU_PO_RST_CTRL_CORE_ALL	0xf
+#define PRCM_PWROFF_GATING_REG(c)	(0x100 + 0x4 * (c))
+#define PRCM_PWROFF_GATING_REG_CLUSTER	BIT(4)
+#define PRCM_PWROFF_GATING_REG_CORE(n)	BIT(n)
+#define PRCM_PWR_SWITCH_REG(c, cpu)	(0x140 + 0x10 * (c) + 0x4 * (cpu))
+#define PRCM_CPU_SOFT_ENTRY_REG		0x164
+
+#define CPU0_SUPPORT_HOTPLUG_MAGIC0	0xFA50392F
+#define CPU0_SUPPORT_HOTPLUG_MAGIC1	0x790DCA3A
+
+static void __iomem *cpucfg_base;
+static void __iomem *prcm_base;
+static void __iomem *sram_b_smp_base;
+
+static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster)
+{
+	struct device_node *node;
+	int cpu = cluster * SUNXI_CPUS_PER_CLUSTER + core;
+
+	node = of_cpu_device_node_get(cpu);
+
+	/* In case of_cpu_device_node_get fails */
+	if (!node)
+		node = of_get_cpu_node(cpu, NULL);
+
+	if (!node) {
+		/*
+		 * There's no point in returning an error, since we
+		 * would be mid way in a core or cluster power sequence.
+		 */
+		pr_err("%s: Couldn't get CPU cluster %u core %u device node\n",
+		       __func__, cluster, core);
+
+		return false;
+	}
+
+	return of_device_is_compatible(node, "arm,cortex-a15");
+}
+
+static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int cluster,
+				      bool enable)
+{
+	u32 reg;
+
+	/* control sequence from Allwinner A80 user manual v1.2 PRCM section */
+	reg = readl(prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+	if (enable) {
+		if (reg == 0x00) {
+			pr_debug("power clamp for cluster %u cpu %u already open\n",
+				 cluster, cpu);
+			return 0;
+		}
+
+		writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+		udelay(10);
+		writel(0xfe, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+		udelay(10);
+		writel(0xf8, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+		udelay(10);
+		writel(0xf0, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+		udelay(10);
+		writel(0x00, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+		udelay(10);
+	} else {
+		writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu));
+		udelay(10);
+	}
+
+	return 0;
+}
+
+static void sunxi_cpu0_hotplug_support_set(bool enable)
+{
+	if (enable) {
+		writel(CPU0_SUPPORT_HOTPLUG_MAGIC0, sram_b_smp_base);
+		writel(CPU0_SUPPORT_HOTPLUG_MAGIC1, sram_b_smp_base + 0x4);
+	} else {
+		writel(0x0, sram_b_smp_base);
+		writel(0x0, sram_b_smp_base + 0x4);
+	}
+}
+
+static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster)
+{
+	u32 reg;
+
+	pr_debug("%s: cluster %u cpu %u\n", __func__, cluster, cpu);
+	if (cpu >= SUNXI_CPUS_PER_CLUSTER || cluster >= SUNXI_NR_CLUSTERS)
+		return -EINVAL;
+
+	/* Set hotplug support magic flags for cpu0 */
+	if (cluster == 0 && cpu == 0)
+		sunxi_cpu0_hotplug_support_set(true);
+
+	/* assert processor power-on reset */
+	reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+	reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu);
+	writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+
+	/* Cortex-A7: hold L1 reset disable signal low */
+	if (!sunxi_core_is_cortex_a15(cpu, cluster)) {
+		reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster));
+		reg &= ~CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(cpu);
+		writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster));
+	}
+
+	/* assert processor related resets */
+	reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+	reg &= ~CPUCFG_CX_RST_CTRL_DBG_RST(cpu);
+
+	/*
+	 * Allwinner code also asserts resets for NEON on A15. According
+	 * to ARM manuals, asserting power-on reset is sufficient.
+	 */
+	if (!sunxi_core_is_cortex_a15(cpu, cluster))
+		reg &= ~CPUCFG_CX_RST_CTRL_ETM_RST(cpu);
+
+	writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+
+	/* open power switch */
+	sunxi_cpu_power_switch_set(cpu, cluster, true);
+
+	/* clear processor power gate */
+	reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
+	reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu);
+	writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
+	udelay(20);
+
+	/* de-assert processor power-on reset */
+	reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+	reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu);
+	writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+
+	/* de-assert all processor resets */
+	reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+	reg |= CPUCFG_CX_RST_CTRL_DBG_RST(cpu);
+	reg |= CPUCFG_CX_RST_CTRL_CORE_RST(cpu);
+	if (!sunxi_core_is_cortex_a15(cpu, cluster))
+		reg |= CPUCFG_CX_RST_CTRL_ETM_RST(cpu);
+	else
+		reg |= CPUCFG_CX_RST_CTRL_CX_RST(cpu); /* NEON */
+	writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+
+	return 0;
+}
+
+static int sunxi_cluster_powerup(unsigned int cluster)
+{
+	u32 reg;
+
+	pr_debug("%s: cluster %u\n", __func__, cluster);
+	if (cluster >= SUNXI_NR_CLUSTERS)
+		return -EINVAL;
+
+	/* assert ACINACTM */
+	reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster));
+	reg |= CPUCFG_CX_CTRL_REG1_ACINACTM;
+	writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster));
+
+	/* assert cluster processor power-on resets */
+	reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+	reg &= ~PRCM_CPU_PO_RST_CTRL_CORE_ALL;
+	writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+
+	/* assert cluster resets */
+	reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+	reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST;
+	reg &= ~CPUCFG_CX_RST_CTRL_DBG_RST_ALL;
+	reg &= ~CPUCFG_CX_RST_CTRL_H_RST;
+	reg &= ~CPUCFG_CX_RST_CTRL_L2_RST;
+
+	/*
+	 * Allwinner code also asserts resets for NEON on A15. According
+	 * to ARM manuals, asserting power-on reset is sufficient.
+	 */
+	if (!sunxi_core_is_cortex_a15(0, cluster))
+		reg &= ~CPUCFG_CX_RST_CTRL_ETM_RST_ALL;
+
+	writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+
+	/* hold L1/L2 reset disable signals low */
+	reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster));
+	if (sunxi_core_is_cortex_a15(0, cluster)) {
+		/* Cortex-A15: hold L2RSTDISABLE low */
+		reg &= ~CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15;
+	} else {
+		/* Cortex-A7: hold L1RSTDISABLE and L2RSTDISABLE low */
+		reg &= ~CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL;
+		reg &= ~CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7;
+	}
+	writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster));
+
+	/* clear cluster power gate */
+	reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
+	reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER;
+	writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
+	udelay(20);
+
+	/* de-assert cluster resets */
+	reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+	reg |= CPUCFG_CX_RST_CTRL_DBG_SOC_RST;
+	reg |= CPUCFG_CX_RST_CTRL_H_RST;
+	reg |= CPUCFG_CX_RST_CTRL_L2_RST;
+	writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+
+	/* de-assert ACINACTM */
+	reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster));
+	reg &= ~CPUCFG_CX_CTRL_REG1_ACINACTM;
+	writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster));
+
+	return 0;
+}
+
+/*
+ * This bit is shared between the initial nocache_trampoline call to
+ * enable CCI-400 and proper cluster cache disable before power down.
+ */
+static void sunxi_cluster_cache_disable_without_axi(void)
+{
+	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
+		/*
+		 * On the Cortex-A15 we need to disable
+		 * L2 prefetching before flushing the cache.
+		 */
+		asm volatile(
+		"mcr	p15, 1, %0, c15, c0, 3\n"
+		"isb\n"
+		"dsb"
+		: : "r" (0x400));
+	}
+
+	/* Flush all cache levels for this cluster. */
+	v7_exit_coherency_flush(all);
+
+	/*
+	 * Disable cluster-level coherency by masking
+	 * incoming snoops and DVM messages:
+	 */
+	cci_disable_port_by_cpu(read_cpuid_mpidr());
+}
+
+static int sunxi_mc_smp_cpu_table[SUNXI_NR_CLUSTERS][SUNXI_CPUS_PER_CLUSTER];
+static int sunxi_mc_smp_first_comer;
+
+/*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ *
+ * Also enable regional clock gating and L2 data latency settings for
+ * Cortex-A15. These settings are from the vendor kernel.
+ */
+static void __naked sunxi_mc_smp_cluster_cache_enable(void)
+{
+	asm volatile (
+		"mrc	p15, 0, r1, c0, c0, 0\n"
+		"movw	r2, #" __stringify(ARM_CPU_PART_MASK & 0xffff) "\n"
+		"movt	r2, #" __stringify(ARM_CPU_PART_MASK >> 16) "\n"
+		"and	r1, r1, r2\n"
+		"movw	r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 & 0xffff) "\n"
+		"movt	r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 >> 16) "\n"
+		"cmp	r1, r2\n"
+		"bne	not_a15\n"
+
+		/* The following is Cortex-A15 specific */
+
+		/* ACTLR2: Enable CPU regional clock gates */
+		"mrc p15, 1, r1, c15, c0, 4\n"
+		"orr r1, r1, #(0x1<<31)\n"
+		"mcr p15, 1, r1, c15, c0, 4\n"
+
+		/* L2ACTLR */
+		"mrc p15, 1, r1, c15, c0, 0\n"
+		/* Enable L2, GIC, and Timer regional clock gates */
+		"orr r1, r1, #(0x1<<26)\n"
+		/* Disable clean/evict from being pushed to external */
+		"orr r1, r1, #(0x1<<3)\n"
+		"mcr p15, 1, r1, c15, c0, 0\n"
+
+		/* L2CTRL: L2 data RAM latency */
+		"mrc p15, 1, r1, c9, c0, 2\n"
+		"bic r1, r1, #(0x7<<0)\n"
+		"orr r1, r1, #(0x3<<0)\n"
+		"mcr p15, 1, r1, c9, c0, 2\n"
+
+		/* End of Cortex-A15 specific setup */
+		"not_a15:\n"
+
+		/* Get value of sunxi_mc_smp_first_comer */
+		"adr	r1, first\n"
+		"ldr	r0, [r1]\n"
+		"ldr	r0, [r1, r0]\n"
+
+		/* Skip cci_enable_port_for_self if not first comer */
+		"cmp	r0, #0\n"
+		"bxeq	lr\n"
+		"b	cci_enable_port_for_self\n"
+
+		".align 2\n"
+		"first: .word sunxi_mc_smp_first_comer - .\n"
+	);
+}
+
+static void __naked sunxi_mc_smp_secondary_startup(void)
+{
+	asm volatile(
+		"bl	sunxi_mc_smp_cluster_cache_enable\n"
+		"b	secondary_startup"
+		/* Let compiler know about sunxi_mc_smp_cluster_cache_enable */
+		:: "i" (sunxi_mc_smp_cluster_cache_enable)
+	);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static bool sunxi_mc_smp_cluster_is_down(unsigned int cluster)
+{
+	int i;
+
+	for (i = 0; i < SUNXI_CPUS_PER_CLUSTER; i++)
+		if (sunxi_mc_smp_cpu_table[cluster][i])
+			return false;
+	return true;
+}
+
+static void sunxi_mc_smp_secondary_init(unsigned int cpu)
+{
+	/* Clear hotplug support magic flags for cpu0 */
+	if (cpu == 0)
+		sunxi_cpu0_hotplug_support_set(false);
+}
+
+static int sunxi_mc_smp_boot_secondary(unsigned int l_cpu, struct task_struct *idle)
+{
+	unsigned int mpidr, cpu, cluster;
+
+	mpidr = cpu_logical_map(l_cpu);
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	if (!cpucfg_base)
+		return -ENODEV;
+	if (cluster >= SUNXI_NR_CLUSTERS || cpu >= SUNXI_CPUS_PER_CLUSTER)
+		return -EINVAL;
+
+	spin_lock_irq(&boot_lock);
+
+	if (sunxi_mc_smp_cpu_table[cluster][cpu])
+		goto out;
+
+	if (sunxi_mc_smp_cluster_is_down(cluster)) {
+		sunxi_mc_smp_first_comer = true;
+		sunxi_cluster_powerup(cluster);
+	} else {
+		sunxi_mc_smp_first_comer = false;
+	}
+
+	/* This is read by incoming CPUs with their cache and MMU disabled */
+	sync_cache_w(&sunxi_mc_smp_first_comer);
+	sunxi_cpu_powerup(cpu, cluster);
+
+out:
+	sunxi_mc_smp_cpu_table[cluster][cpu]++;
+	spin_unlock_irq(&boot_lock);
+
+	return 0;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void sunxi_cluster_cache_disable(void)
+{
+	unsigned int cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
+	u32 reg;
+
+	pr_debug("%s: cluster %u\n", __func__, cluster);
+
+	sunxi_cluster_cache_disable_without_axi();
+
+	/* last man standing, assert ACINACTM */
+	reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster));
+	reg |= CPUCFG_CX_CTRL_REG1_ACINACTM;
+	writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster));
+}
+
+static void sunxi_mc_smp_cpu_die(unsigned int l_cpu)
+{
+	unsigned int mpidr, cpu, cluster;
+	bool last_man;
+
+	mpidr = cpu_logical_map(l_cpu);
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+	pr_debug("%s: cluster %u cpu %u\n", __func__, cluster, cpu);
+
+	spin_lock(&boot_lock);
+	sunxi_mc_smp_cpu_table[cluster][cpu]--;
+	if (sunxi_mc_smp_cpu_table[cluster][cpu] == 1) {
+		/* A power_up request went ahead of us. */
+		pr_debug("%s: aborting due to a power up request\n",
+			 __func__);
+		spin_unlock(&boot_lock);
+		return;
+	} else if (sunxi_mc_smp_cpu_table[cluster][cpu] > 1) {
+		pr_err("Cluster %d CPU%d boots multiple times\n",
+		       cluster, cpu);
+		BUG();
+	}
+
+	last_man = sunxi_mc_smp_cluster_is_down(cluster);
+	spin_unlock(&boot_lock);
+
+	gic_cpu_if_down(0);
+	if (last_man)
+		sunxi_cluster_cache_disable();
+	else
+		v7_exit_coherency_flush(louis);
+
+	for (;;)
+		wfi();
+}
+
+static int sunxi_cpu_powerdown(unsigned int cpu, unsigned int cluster)
+{
+	u32 reg;
+
+	pr_debug("%s: cluster %u cpu %u\n", __func__, cluster, cpu);
+	if (cpu >= SUNXI_CPUS_PER_CLUSTER || cluster >= SUNXI_NR_CLUSTERS)
+		return -EINVAL;
+
+	/* gate processor power */
+	reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
+	reg |= PRCM_PWROFF_GATING_REG_CORE(cpu);
+	writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
+	udelay(20);
+
+	/* close power switch */
+	sunxi_cpu_power_switch_set(cpu, cluster, false);
+
+	return 0;
+}
+
+static int sunxi_cluster_powerdown(unsigned int cluster)
+{
+	u32 reg;
+
+	pr_debug("%s: cluster %u\n", __func__, cluster);
+	if (cluster >= SUNXI_NR_CLUSTERS)
+		return -EINVAL;
+
+	/* assert cluster resets or system will hang */
+	pr_debug("%s: assert cluster reset\n", __func__);
+	reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+	reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST;
+	reg &= ~CPUCFG_CX_RST_CTRL_H_RST;
+	reg &= ~CPUCFG_CX_RST_CTRL_L2_RST;
+	writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+
+	/* gate cluster power */
+	pr_debug("%s: gate cluster power\n", __func__);
+	reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
+	reg |= PRCM_PWROFF_GATING_REG_CLUSTER;
+	writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
+	udelay(20);
+
+	return 0;
+}
+
+static int sunxi_mc_smp_cpu_kill(unsigned int l_cpu)
+{
+	unsigned int mpidr, cpu, cluster;
+	unsigned int tries, count;
+	int ret = 0;
+	u32 reg;
+
+	mpidr = cpu_logical_map(l_cpu);
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	/* This should never happen */
+	if (WARN_ON(cluster >= SUNXI_NR_CLUSTERS ||
+		    cpu >= SUNXI_CPUS_PER_CLUSTER))
+		return 0;
+
+	/* wait for CPU core to die and enter WFI */
+	count = TIMEOUT_USEC / POLL_USEC;
+	spin_lock_irq(&boot_lock);
+	for (tries = 0; tries < count; tries++) {
+		spin_unlock_irq(&boot_lock);
+		usleep_range(POLL_USEC / 2, POLL_USEC);
+		spin_lock_irq(&boot_lock);
+
+		/*
+		 * If the user turns off a bunch of cores at the same
+		 * time, the kernel might call cpu_kill before some of
+		 * them are ready. This is because boot_lock serializes
+		 * both cpu_die and cpu_kill callbacks. Either one could
+		 * run first. We should wait for cpu_die to complete.
+		 */
+		if (sunxi_mc_smp_cpu_table[cluster][cpu])
+			continue;
+
+		reg = readl(cpucfg_base + CPUCFG_CX_STATUS(cluster));
+		if (reg & CPUCFG_CX_STATUS_STANDBYWFI(cpu))
+			break;
+	}
+
+	if (tries >= count) {
+		ret = ETIMEDOUT;
+		goto out;
+	}
+
+	/* power down CPU core */
+	sunxi_cpu_powerdown(cpu, cluster);
+
+	if (!sunxi_mc_smp_cluster_is_down(cluster))
+		goto out;
+
+	/* wait for cluster L2 WFI */
+	ret = readl_poll_timeout(cpucfg_base + CPUCFG_CX_STATUS(cluster), reg,
+				 reg & CPUCFG_CX_STATUS_STANDBYWFIL2,
+				 POLL_USEC, TIMEOUT_USEC);
+	if (ret) {
+		/*
+		 * Ignore timeout on the cluster. Leaving the cluster on
+		 * will not affect system execution, just use a bit more
+		 * power. But returning an error here will only confuse
+		 * the user as the CPU has already been shutdown.
+		 */
+		ret = 0;
+		goto out;
+	}
+
+	/* Power down cluster */
+	sunxi_cluster_powerdown(cluster);
+
+out:
+	spin_unlock_irq(&boot_lock);
+	pr_debug("%s: cluster %u cpu %u powerdown: %d\n",
+		 __func__, cluster, cpu, ret);
+	return !ret;
+}
+
+static bool sunxi_mc_smp_cpu_can_disable(unsigned int __unused)
+{
+	return true;
+}
+#endif
+
+static const struct smp_operations sunxi_mc_smp_smp_ops __initconst = {
+	.smp_secondary_init	= sunxi_mc_smp_secondary_init,
+	.smp_boot_secondary	= sunxi_mc_smp_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_die		= sunxi_mc_smp_cpu_die,
+	.cpu_kill		= sunxi_mc_smp_cpu_kill,
+	.cpu_can_disable	= sunxi_mc_smp_cpu_can_disable,
+#endif
+};
+
+static bool __init sunxi_mc_smp_cpu_table_init(void)
+{
+	unsigned int mpidr, cpu, cluster;
+
+	mpidr = read_cpuid_mpidr();
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	if (cluster >= SUNXI_NR_CLUSTERS || cpu >= SUNXI_CPUS_PER_CLUSTER) {
+		pr_err("%s: boot CPU is out of bounds!\n", __func__);
+		return false;
+	}
+	sunxi_mc_smp_cpu_table[cluster][cpu] = 1;
+	return true;
+}
+
+/*
+ * Adapted from arch/arm/common/mc_smp_entry.c
+ *
+ * We need the trampoline code to enable CCI-400 on the first cluster
+ */
+typedef typeof(cpu_reset) phys_reset_t;
+
+static void __init __naked sunxi_mc_smp_resume(void)
+{
+	asm volatile(
+		"bl	sunxi_mc_smp_cluster_cache_enable\n"
+		"b	cpu_resume"
+		/* Let compiler know about sunxi_mc_smp_cluster_cache_enable */
+		:: "i" (sunxi_mc_smp_cluster_cache_enable)
+	);
+}
+
+static int __init nocache_trampoline(unsigned long __unused)
+{
+	phys_reset_t phys_reset;
+
+	setup_mm_for_reboot();
+	sunxi_cluster_cache_disable_without_axi();
+
+	phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset);
+	phys_reset(__pa_symbol(sunxi_mc_smp_resume), false);
+	BUG();
+}
+
+static int __init sunxi_mc_smp_loopback(void)
+{
+	int ret;
+
+	/*
+	 * We're going to soft-restart the current CPU through the
+	 * low-level MCPM code by leveraging the suspend/resume
+	 * infrastructure. Let's play it safe by using cpu_pm_enter()
+	 * in case the CPU init code path resets the VFP or similar.
+	 */
+	sunxi_mc_smp_first_comer = true;
+	local_irq_disable();
+	local_fiq_disable();
+	ret = cpu_pm_enter();
+	if (!ret) {
+		ret = cpu_suspend(0, nocache_trampoline);
+		cpu_pm_exit();
+	}
+	local_fiq_enable();
+	local_irq_enable();
+	sunxi_mc_smp_first_comer = false;
+
+	return ret;
+}
+
+/*
+ * This holds any device nodes that we requested resources for,
+ * so that we may easily release resources in the error path.
+ */
+struct sunxi_mc_smp_nodes {
+	struct device_node *prcm_node;
+	struct device_node *cpucfg_node;
+	struct device_node *sram_node;
+};
+
+/* This structure holds SoC-specific bits tied to an enable-method string. */
+struct sunxi_mc_smp_data {
+	const char *enable_method;
+	int (*get_smp_nodes)(struct sunxi_mc_smp_nodes *nodes);
+};
+
+static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes)
+{
+	of_node_put(nodes->prcm_node);
+	of_node_put(nodes->cpucfg_node);
+	of_node_put(nodes->sram_node);
+	memset(nodes, 0, sizeof(*nodes));
+}
+
+static int __init sun9i_a80_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes)
+{
+	nodes->prcm_node = of_find_compatible_node(NULL, NULL,
+						   "allwinner,sun9i-a80-prcm");
+	if (!nodes->prcm_node) {
+		pr_err("%s: PRCM not available\n", __func__);
+		return -ENODEV;
+	}
+
+	nodes->cpucfg_node = of_find_compatible_node(NULL, NULL,
+						     "allwinner,sun9i-a80-cpucfg");
+	if (!nodes->cpucfg_node) {
+		pr_err("%s: CPUCFG not available\n", __func__);
+		return -ENODEV;
+	}
+
+	nodes->sram_node = of_find_compatible_node(NULL, NULL,
+						   "allwinner,sun9i-a80-smp-sram");
+	if (!nodes->sram_node) {
+		pr_err("%s: Secure SRAM not available\n", __func__);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static const struct sunxi_mc_smp_data sunxi_mc_smp_data[] __initconst = {
+	{
+		.enable_method	= "allwinner,sun9i-a80-smp",
+		.get_smp_nodes	= sun9i_a80_get_smp_nodes,
+	},
+};
+
+static int __init sunxi_mc_smp_init(void)
+{
+	struct sunxi_mc_smp_nodes nodes = { 0 };
+	struct device_node *node;
+	struct resource res;
+	int i, ret;
+
+	/*
+	 * Don't bother checking the "cpus" node, as an enable-method
+	 * property in that node is undocumented.
+	 */
+	node = of_cpu_device_node_get(0);
+	if (!node)
+		return -ENODEV;
+
+	/*
+	 * We can't actually use the enable-method magic in the kernel.
+	 * Our loopback / trampoline code uses the CPU suspend framework,
+	 * which requires the identity mapping be available. It would not
+	 * yet be available if we used the .init_cpus or .prepare_cpus
+	 * callbacks in smp_operations, which we would use if we were to
+	 * use CPU_METHOD_OF_DECLARE
+	 */
+	for (i = 0; i < ARRAY_SIZE(sunxi_mc_smp_data); i++) {
+		ret = of_property_match_string(node, "enable-method",
+					       sunxi_mc_smp_data[i].enable_method);
+		if (!ret)
+			break;
+	}
+
+	of_node_put(node);
+	if (ret)
+		return -ENODEV;
+
+	if (!sunxi_mc_smp_cpu_table_init())
+		return -EINVAL;
+
+	if (!cci_probed()) {
+		pr_err("%s: CCI-400 not available\n", __func__);
+		return -ENODEV;
+	}
+
+	/* Get needed device tree nodes */
+	ret = sunxi_mc_smp_data[i].get_smp_nodes(&nodes);
+	if (ret)
+		goto err_put_nodes;
+
+	/*
+	 * Unfortunately we can not request the I/O region for the PRCM.
+	 * It is shared with the PRCM clock.
+	 */
+	prcm_base = of_iomap(nodes.prcm_node, 0);
+	if (!prcm_base) {
+		pr_err("%s: failed to map PRCM registers\n", __func__);
+		ret = -ENOMEM;
+		goto err_put_nodes;
+	}
+
+	cpucfg_base = of_io_request_and_map(nodes.cpucfg_node, 0,
+					    "sunxi-mc-smp");
+	if (IS_ERR(cpucfg_base)) {
+		ret = PTR_ERR(cpucfg_base);
+		pr_err("%s: failed to map CPUCFG registers: %d\n",
+		       __func__, ret);
+		goto err_unmap_prcm;
+	}
+
+	sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0,
+						"sunxi-mc-smp");
+	if (IS_ERR(sram_b_smp_base)) {
+		ret = PTR_ERR(sram_b_smp_base);
+		pr_err("%s: failed to map secure SRAM\n", __func__);
+		goto err_unmap_release_cpucfg;
+	}
+
+	/* Configure CCI-400 for boot cluster */
+	ret = sunxi_mc_smp_loopback();
+	if (ret) {
+		pr_err("%s: failed to configure boot cluster: %d\n",
+		       __func__, ret);
+		goto err_unmap_release_secure_sram;
+	}
+
+	/* We don't need the device nodes anymore */
+	sunxi_mc_smp_put_nodes(&nodes);
+
+	/* Set the hardware entry point address */
+	writel(__pa_symbol(sunxi_mc_smp_secondary_startup),
+	       prcm_base + PRCM_CPU_SOFT_ENTRY_REG);
+
+	/* Actually enable multi cluster SMP */
+	smp_set_ops(&sunxi_mc_smp_smp_ops);
+
+	pr_info("sunxi multi cluster SMP support installed\n");
+
+	return 0;
+
+err_unmap_release_secure_sram:
+	iounmap(sram_b_smp_base);
+	of_address_to_resource(nodes.sram_node, 0, &res);
+	release_mem_region(res.start, resource_size(&res));
+err_unmap_release_cpucfg:
+	iounmap(cpucfg_base);
+	of_address_to_resource(nodes.cpucfg_node, 0, &res);
+	release_mem_region(res.start, resource_size(&res));
+err_unmap_prcm:
+	iounmap(prcm_base);
+err_put_nodes:
+	sunxi_mc_smp_put_nodes(&nodes);
+	return ret;
+}
+
+early_initcall(sunxi_mc_smp_init);
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 7276afe..afc1a1d 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -106,12 +106,6 @@
 	help
 	  PPA routine service ID for setting L2 auxiliary control register.
 
-config OMAP_DM_TIMER
-	bool "Use dual-mode timer"
-	depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
-	help
-	 Select this option if you want to use OMAP Dual-Mode timers.
-
 config OMAP_SERIAL_WAKE
 	bool "Enable wake-up events for serial ports"
 	depends on ARCH_OMAP1 && OMAP_MUX
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 47e1867..7215ada 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -9,5 +9,4 @@
 
 # omap_device support (OMAP2+ only at the moment)
 
-obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index fbedbd8..2b1535c 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -190,12 +190,24 @@
 	help
 	  This enables support for the Renesas R-Car M3-W SoC.
 
+config ARCH_R8A77965
+	bool "Renesas R-Car M3-N SoC Platform"
+	depends on ARCH_RENESAS
+	help
+	  This enables support for the Renesas R-Car M3-N SoC.
+
 config ARCH_R8A77970
 	bool "Renesas R-Car V3M SoC Platform"
 	depends on ARCH_RENESAS
 	help
 	  This enables support for the Renesas R-Car V3M SoC.
 
+config ARCH_R8A77980
+	bool "Renesas R-Car V3H SoC Platform"
+	depends on ARCH_RENESAS
+	help
+	  This enables support for the Renesas R-Car V3H SoC.
+
 config ARCH_R8A77995
 	bool "Renesas R-Car D3 SoC Platform"
 	depends on ARCH_RENESAS
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index f505227..8bebe7d 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -5,8 +5,11 @@
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-pc2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-prime.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-zero-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-zero-plus2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo-plus2.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
index a697567..2250dec 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
@@ -120,8 +120,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	bus-width = <4>;
 	status = "okay";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
index 2beef9e..e2dce48 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
@@ -82,8 +82,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	bus-width = <4>;
 	status = "okay";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
index 8807664..3b3081b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
@@ -68,8 +68,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	bus-width = <4>;
 	status = "okay";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
index 240d357..bf42690 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
@@ -67,8 +67,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 604cdae..a758257 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -103,8 +103,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
 	vmmc-supply = <&reg_dcdc1>;
-	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
-	cd-inverted;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	bus-width = <4>;
 	status = "okay";
@@ -230,6 +229,11 @@
 	regulator-name = "vcc-rtc";
 };
 
+/* On Euler connector */
+&spdif {
+	status = "disabled";
+};
+
 /* On Exp and Euler connectors */
 &uart0 {
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
new file mode 100644
index 0000000..d9baab3
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) Harald Geyer <harald@ccbib.org>
+ * based on sun50i-a64-olinuxino.dts by Jagan Teki <jteki@openedev.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+/dts-v1/;
+
+#include "sun50i-a64.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+	model = "Olimex A64 Teres-I";
+	compatible = "olimex,a64-teres-i", "allwinner,sun50i-a64";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+
+		framebuffer-lcd {
+			eDP25-supply = <&reg_dldo2>;
+			eDP12-supply = <&reg_dldo3>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		lid-switch {
+			label = "Lid Switch";
+			gpios = <&r_pio 0 8 GPIO_ACTIVE_LOW>; /* PL8 */
+			linux,input-type = <EV_SW>;
+			linux,code = <SW_LID>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		capslock {
+			label = "teres-i:green:capslock";
+			gpios = <&pio 2 7 GPIO_ACTIVE_HIGH>; /* PC7 */
+		};
+
+		numlock {
+			label = "teres-i:green:numlock";
+			gpios = <&pio 2 4 GPIO_ACTIVE_HIGH>; /* PC4 */
+		};
+	};
+
+	reg_usb1_vbus: usb1-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb1-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */
+		status = "okay";
+	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+	};
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+
+/* The ANX6345 eDP-bridge is on i2c0. There is no linux (mainline)
+ * driver for this chip at the moment, the bootloader initializes it.
+ * However it can be accessed with the i2c-dev driver from user space.
+ */
+&i2c0 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins>;
+	vmmc-supply = <&reg_dcdc1>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&reg_aldo2>;
+	vqmmc-supply = <&reg_dldo4>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	rtl8723bs: wifi@1 {
+		reg = <1>;
+		interrupt-parent = <&r_pio>;
+		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
+		interrupt-names = "host-wake";
+	};
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>;
+	vmmc-supply = <&reg_dcdc1>;
+	vqmmc-supply = <&reg_dcdc1>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&r_rsb {
+	status = "okay";
+
+	axp803: pmic@3a3 {
+		compatible = "x-powers,axp803";
+		reg = <0x3a3>;
+		interrupt-parent = <&r_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		wakeup-source;
+	};
+};
+
+#include "axp803.dtsi"
+
+&reg_aldo1 {
+	regulator-always-on;
+	regulator-min-microvolt = <2800000>;
+	regulator-max-microvolt = <2800000>;
+	regulator-name = "vcc-pe";
+};
+
+&reg_aldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-pl";
+};
+
+&reg_aldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-pll-avcc";
+};
+
+&reg_dcdc1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-3v3";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1040000>;
+	regulator-max-microvolt = <1300000>;
+	regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+&reg_dcdc5 {
+	regulator-always-on;
+	regulator-min-microvolt = <1500000>;
+	regulator-max-microvolt = <1500000>;
+	regulator-name = "vcc-ddr3";
+};
+
+&reg_dcdc6 {
+	regulator-always-on;
+	regulator-min-microvolt = <1100000>;
+	regulator-max-microvolt = <1100000>;
+	regulator-name = "vdd-sys";
+};
+
+&reg_dldo1 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-hdmi";
+};
+
+&reg_dldo2 {
+	regulator-min-microvolt = <2500000>;
+	regulator-max-microvolt = <2500000>;
+	regulator-name = "vcc-pd";
+};
+
+&reg_dldo3 {
+	regulator-min-microvolt = <1200000>;
+	regulator-max-microvolt = <1200000>;
+	regulator-name = "eDP12";
+};
+
+&reg_dldo4 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi-io";
+};
+
+&reg_eldo1 {
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-name = "cpvdd";
+};
+
+&reg_eldo2 {
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-name = "vcc-dvdd-csi";
+};
+
+&reg_fldo1 {
+	regulator-min-microvolt = <1200000>;
+	regulator-max-microvolt = <1200000>;
+	regulator-name = "vcc-1v2-hsic";
+};
+
+/*
+ * The A64 chip cannot work without this regulator off, although
+ * it seems to be only driving the AR100 core.
+ * Maybe we don't still know well about CPUs domain.
+ */
+&reg_fldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1100000>;
+	regulator-max-microvolt = <1100000>;
+	regulator-name = "vdd-cpus";
+};
+
+&reg_rtc_ldo {
+	regulator-name = "vcc-rtc";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&usbphy {
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index d783d16..1b2ef28 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -52,6 +52,26 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
+	chosen {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+/*
+ * The pipeline mixer0-lcd0 depends on clock CLK_MIXER0 from DE2 CCU.
+ * However there is no support for this clock on A64 yet, so we depend
+ * on the upstream clocks here to keep them (and thus CLK_MIXER0) up.
+ */
+		simplefb_lcd: framebuffer-lcd {
+			compatible = "allwinner,simple-framebuffer",
+				     "simple-framebuffer";
+			allwinner,pipeline = "mixer0-lcd0";
+			clocks = <&ccu CLK_TCON0>,
+				 <&ccu CLK_DE>, <&ccu CLK_BUS_DE>;
+			status = "disabled";
+		};
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -112,6 +132,24 @@
 		method = "smc";
 	};
 
+	sound_spdif {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "On-board SPDIF";
+
+		simple-audio-card,cpu {
+			sound-dai = <&spdif>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&spdif_out>;
+		};
+	};
+
+	spdif_out: spdif-out {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <GIC_PPI 13
@@ -291,6 +329,11 @@
 			interrupt-controller;
 			#interrupt-cells = <3>;
 
+			i2c0_pins: i2c0_pins {
+				pins = "PH0", "PH1";
+				function = "i2c0";
+			};
+
 			i2c1_pins: i2c1_pins {
 				pins = "PH2", "PH3";
 				function = "i2c1";
@@ -336,6 +379,11 @@
 				drive-strength = <40>;
 			};
 
+			spdif_tx_pin: spdif {
+				pins = "PH8";
+				function = "spdif";
+			};
+
 			spi0_pins: spi0 {
 				pins = "PC0", "PC1", "PC2", "PC3";
 				function = "spi0";
@@ -382,6 +430,50 @@
 			};
 		};
 
+		spdif: spdif@1c21000 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun50i-a64-spdif",
+				     "allwinner,sun8i-h3-spdif";
+			reg = <0x01c21000 0x400>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>;
+			resets = <&ccu RST_BUS_SPDIF>;
+			clock-names = "apb", "spdif";
+			dmas = <&dma 2>;
+			dma-names = "tx";
+			pinctrl-names = "default";
+			pinctrl-0 = <&spdif_tx_pin>;
+			status = "disabled";
+		};
+
+		i2s0: i2s@1c22000 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun50i-a64-i2s",
+				     "allwinner,sun8i-h3-i2s";
+			reg = <0x01c22000 0x400>;
+			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2S0>, <&ccu CLK_I2S0>;
+			clock-names = "apb", "mod";
+			resets = <&ccu RST_BUS_I2S0>;
+			dma-names = "rx", "tx";
+			dmas = <&dma 3>, <&dma 3>;
+			status = "disabled";
+		};
+
+		i2s1: i2s@1c22400 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun50i-a64-i2s",
+				     "allwinner,sun8i-h3-i2s";
+			reg = <0x01c22400 0x400>;
+			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2S1>, <&ccu CLK_I2S1>;
+			clock-names = "apb", "mod";
+			resets = <&ccu RST_BUS_I2S1>;
+			dma-names = "rx", "tx";
+			dmas = <&dma 4>, <&dma 4>;
+			status = "disabled";
+		};
+
 		uart0: serial@1c28000 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x01c28000 0x400>;
@@ -593,5 +685,12 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 		};
+
+		wdt0: watchdog@1c20ca0 {
+			compatible = "allwinner,sun50i-a64-wdt",
+				     "allwinner,sun6i-a31-wdt";
+			reg = <0x01c20ca0 0x20>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts
index 1ed9f21..506e25b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts
@@ -151,8 +151,6 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
 	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
@@ -160,8 +158,6 @@
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	vqmmc-supply = <&reg_vcc3v3>;
 	mmc-pwrseq = <&wifi_pwrseq>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
index f144700..cc268a6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
@@ -126,8 +126,6 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
 	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
index 9e51d3a..98862c7 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
@@ -67,6 +67,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -121,6 +132,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -153,6 +168,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -160,8 +185,6 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
 	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts
index 0f25c4a..b75ca4d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts
@@ -62,6 +62,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -128,6 +139,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -160,6 +175,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
@@ -167,8 +192,6 @@
 };
 
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
 	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
@@ -176,8 +199,6 @@
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	mmc-pwrseq = <&wifi_pwrseq>;
 	bus-width = <4>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts
new file mode 100644
index 0000000..1238de2
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2016 ARM Ltd.
+ * Copyright (C) 2018 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR X11)
+ */
+
+/dts-v1/;
+#include "sun50i-h5.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "Xunlong Orange Pi Zero Plus";
+	compatible = "xunlong,orangepi-zero-plus", "allwinner,sun50i-h5";
+
+	reg_vcc3v3: vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	aliases {
+		ethernet0 = &emac;
+		ethernet1 = &rtl8189ftv;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		pwr {
+			label = "orangepi:green:pwr";
+			gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PA10 */
+			default-state = "on";
+		};
+
+		status {
+			label = "orangepi:red:status";
+			gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>; /* PA17 */
+		};
+	};
+
+	reg_gmac_3v3: gmac-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "gmac-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <100000>;
+		enable-active-high;
+		gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
+	};
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&emac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&emac_rgmii_pins>;
+	phy-supply = <&reg_gmac_3v3>;
+	phy-handle = <&ext_rgmii_phy>;
+	phy-mode = "rgmii";
+	status = "okay";
+};
+
+&external_mdio {
+	ext_rgmii_phy: ethernet-phy@1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+	};
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+	status = "okay";
+};
+
+&mmc1 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	/*
+	 * Explicitly define the sdio device, so that we can add an ethernet
+	 * alias for it (which e.g. makes u-boot set a mac-address).
+	 */
+	rtl8189ftv: sdio_wifi@1 {
+		reg = <1>;
+	};
+};
+
+&spi0  {
+	status = "okay";
+
+	flash@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "mxicy,mx25l1606e", "winbond,w25q128";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+	};
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "peripheral";
+	status = "okay";
+};
+
+&usbphy {
+	/* USB Type-A ports' VBUS is always on */
+	usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
index af43533..53c8c11 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
@@ -58,6 +58,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	reg_vcc3v3: vcc3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3";
@@ -73,9 +84,21 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	bus-width = <4>;
 	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
@@ -83,8 +106,6 @@
 };
 
 &mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins_a>;
 	vmmc-supply = <&reg_vcc3v3>;
 	vqmmc-supply = <&reg_vcc3v3>;
 	mmc-pwrseq = <&wifi_pwrseq>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
new file mode 100644
index 0000000..d36de5e
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h6.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "Pine H64";
+	compatible = "pine64,pine-h64", "allwinner,sun50i-h6";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
new file mode 100644
index 0000000..5656315
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			reg = <0>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu@1 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			reg = <1>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu@2 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			reg = <2>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu@3 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			reg = <3>;
+			enable-method = "psci";
+		};
+	};
+
+	iosc: internal-osc-clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <16000000>;
+		clock-accuracy = <300000000>;
+		clock-output-names = "iosc";
+	};
+
+	osc24M: osc24M_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "osc24M";
+	};
+
+	osc32k: osc32k_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <32768>;
+		clock-output-names = "osc32k";
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		ccu: clock@3001000 {
+			compatible = "allwinner,sun50i-h6-ccu";
+			reg = <0x03001000 0x1000>;
+			clocks = <&osc24M>, <&osc32k>, <&iosc>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		gic: interrupt-controller@3021000 {
+			compatible = "arm,gic-400";
+			reg = <0x03021000 0x1000>,
+			      <0x03022000 0x2000>,
+			      <0x03024000 0x2000>,
+			      <0x03026000 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		pio: pinctrl@300b000 {
+			compatible = "allwinner,sun50i-h6-pinctrl";
+			reg = <0x0300b000 0x400>;
+			interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu 26>, <&osc24M>, <&osc32k>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+
+			uart0_ph_pins: uart0-ph {
+				pins = "PH0", "PH1";
+				function = "uart0";
+			};
+		};
+
+		uart0: serial@5000000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05000000 0x400>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu 70>;
+			resets = <&ccu 21>;
+			status = "disabled";
+		};
+
+		uart1: serial@5000400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05000400 0x400>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu 71>;
+			resets = <&ccu 22>;
+			status = "disabled";
+		};
+
+		uart2: serial@5000800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05000800 0x400>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu 72>;
+			resets = <&ccu 23>;
+			status = "disabled";
+		};
+
+		uart3: serial@5000c00 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05000c00 0x400>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu 73>;
+			resets = <&ccu 24>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
index 51ce583..eaf13fe 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -99,4 +99,9 @@
 
 &usb0 {
 	status = "okay";
+	disable-over-current;
+};
+
+&watchdog0 {
+	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
index 447b98d..57eedce 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
@@ -14,6 +13,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		serial1 = &uart_A;
 	};
 };
 
@@ -24,8 +24,16 @@
 	pinctrl-names = "default";
 };
 
+&uart_A {
+	status = "okay";
+	pinctrl-0 = <&uart_a_pins>;
+	pinctrl-names = "default";
+};
+
 &uart_AO {
 	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
 };
 
 &ir {
@@ -33,3 +41,9 @@
 	pinctrl-0 = <&remote_input_ao_pins>;
 	pinctrl-names = "default";
 };
+
+&i2c1 {
+	status = "okay";
+	pinctrl-0 = <&i2c1_z_pins>;
+	pinctrl-names = "default";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 70c776e..b58808e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 #include <dt-bindings/gpio/gpio.h>
@@ -163,18 +162,70 @@
 				status = "disabled";
 			};
 
+			i2c0: i2c@1f000 {
+				compatible = "amlogic,meson-axg-i2c";
+				status = "disabled";
+				reg = <0x0 0x1f000 0x0 0x20>;
+				interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 47 IRQ_TYPE_EDGE_RISING>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clocks = <&clkc CLKID_I2C>;
+				clock-names = "clk_i2c";
+			};
+
+			i2c1: i2c@1e000 {
+				compatible = "amlogic,meson-axg-i2c";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x0 0x1e000 0x0 0x20>;
+				status = "disabled";
+				interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 48 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clkc CLKID_I2C>;
+				clock-names = "clk_i2c";
+			};
+
+			i2c2: i2c@1d000 {
+				compatible = "amlogic,meson-axg-i2c";
+				status = "disabled";
+				reg = <0x0 0x1d000 0x0 0x20>;
+				interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 49 IRQ_TYPE_EDGE_RISING>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clocks = <&clkc CLKID_I2C>;
+				clock-names = "clk_i2c";
+			};
+
+			i2c3: i2c@1c000 {
+				compatible = "amlogic,meson-axg-i2c";
+				status = "disabled";
+				reg = <0x0 0x1c000 0x0 0x20>;
+				interrupts = <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 50 IRQ_TYPE_EDGE_RISING>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clocks = <&clkc CLKID_I2C>;
+				clock-names = "clk_i2c";
+			};
+
 			uart_A: serial@24000 {
-				compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart";
+				compatible = "amlogic,meson-gx-uart";
 				reg = <0x0 0x24000 0x0 0x18>;
 				interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
 				status = "disabled";
+				clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
 			};
 
 			uart_B: serial@23000 {
-				compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart";
+				compatible = "amlogic,meson-gx-uart";
 				reg = <0x0 0x23000 0x0 0x18>;
 				interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
 				status = "disabled";
+				clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
 			};
 		};
 
@@ -234,6 +285,13 @@
 			#size-cells = <2>;
 			ranges = <0x0 0x0 0x0 0xff634000 0x0 0x2000>;
 
+			hwrng: rng {
+				compatible = "amlogic,meson-rng";
+				reg = <0x0 0x18 0x0 0x4>;
+				clocks = <&clkc CLKID_RNG0>;
+				clock-names = "core";
+			};
+
 			pinctrl_periphs: pinctrl@480 {
 				compatible = "amlogic,meson-axg-periphs-pinctrl";
 				#address-cells = <2>;
@@ -251,6 +309,36 @@
 					gpio-ranges = <&pinctrl_periphs 0 0 86>;
 				};
 
+				eth_rmii_x_pins: eth-x-rmii {
+					mux {
+						groups = "eth_mdio_x",
+						       "eth_mdc_x",
+						       "eth_rgmii_rx_clk_x",
+						       "eth_rx_dv_x",
+						       "eth_rxd0_x",
+						       "eth_rxd1_x",
+						       "eth_txen_x",
+						       "eth_txd0_x",
+						       "eth_txd1_x";
+						function = "eth";
+					};
+				};
+
+				eth_rmii_y_pins: eth-y-rmii {
+					mux {
+						groups = "eth_mdio_y",
+						       "eth_mdc_y",
+						       "eth_rgmii_rx_clk_y",
+						       "eth_rx_dv_y",
+						       "eth_rxd0_y",
+						       "eth_rxd1_y",
+						       "eth_txen_y",
+						       "eth_txd0_y",
+						       "eth_txd1_y";
+						function = "eth";
+					};
+				};
+
 				eth_rgmii_x_pins: eth-x-rgmii {
 					mux {
 						groups = "eth_mdio_x",
@@ -444,6 +532,134 @@
 						function = "spi1";
 					};
 				};
+
+				i2c0_pins: i2c0 {
+					mux {
+						groups = "i2c0_sck",
+							"i2c0_sda";
+						function = "i2c0";
+					};
+				};
+
+				i2c1_z_pins: i2c1_z {
+					mux {
+						groups = "i2c1_sck_z",
+							"i2c1_sda_z";
+						function = "i2c1";
+					};
+				};
+
+				i2c1_x_pins: i2c1_x {
+					mux {
+						groups = "i2c1_sck_x",
+							"i2c1_sda_x";
+						function = "i2c1";
+					};
+				};
+
+				i2c2_x_pins: i2c2_x {
+					mux {
+						groups = "i2c2_sck_x",
+							"i2c2_sda_x";
+						function = "i2c2";
+					};
+				};
+
+				i2c2_a_pins: i2c2_a {
+					mux {
+						groups = "i2c2_sck_a",
+							"i2c2_sda_a";
+						function = "i2c2";
+					};
+				};
+
+				i2c3_a6_pins: i2c3_a6 {
+					mux {
+						groups = "i2c3_sda_a6",
+							"i2c3_sck_a7";
+						function = "i2c3";
+					};
+				};
+
+				i2c3_a12_pins: i2c3_a12 {
+					mux {
+						groups = "i2c3_sda_a12",
+							"i2c3_sck_a13";
+						function = "i2c3";
+					};
+				};
+
+				i2c3_a19_pins: i2c3_a19 {
+					mux {
+						groups = "i2c3_sda_a19",
+							"i2c3_sck_a20";
+						function = "i2c3";
+					};
+				};
+
+				uart_a_pins: uart_a {
+					mux {
+						groups = "uart_tx_a",
+							"uart_rx_a";
+						function = "uart_a";
+					};
+				};
+
+				uart_a_cts_rts_pins: uart_a_cts_rts {
+					mux {
+						groups = "uart_cts_a",
+							"uart_rts_a";
+						function = "uart_a";
+					};
+				};
+
+				uart_b_x_pins: uart_b_x {
+					mux {
+						groups = "uart_tx_b_x",
+							"uart_rx_b_x";
+						function = "uart_b";
+					};
+				};
+
+				uart_b_x_cts_rts_pins: uart_b_x_cts_rts {
+					mux {
+						groups = "uart_cts_b_x",
+							"uart_rts_b_x";
+						function = "uart_b";
+					};
+				};
+
+				uart_b_z_pins: uart_b_z {
+					mux {
+						groups = "uart_tx_b_z",
+							"uart_rx_b_z";
+						function = "uart_b";
+					};
+				};
+
+				uart_b_z_cts_rts_pins: uart_b_z_cts_rts {
+					mux {
+						groups = "uart_cts_b_z",
+							"uart_rts_b_z";
+						function = "uart_b";
+					};
+				};
+
+				uart_ao_b_z_pins: uart_ao_b_z {
+					mux {
+						groups = "uart_ao_tx_b_z",
+							"uart_ao_rx_b_z";
+						function = "uart_ao_b_z";
+					};
+				};
+
+				uart_ao_b_z_cts_rts_pins: uart_ao_b_z_cts_rts {
+					mux {
+						groups = "uart_ao_cts_b_z",
+							"uart_ao_rts_b_z";
+						function = "uart_ao_b_z";
+					};
+				};
 			};
 		};
 
@@ -494,6 +710,44 @@
 						function = "remote_input_ao";
 					};
 				};
+
+				uart_ao_a_pins: uart_ao_a {
+					mux {
+						groups = "uart_ao_tx_a",
+							"uart_ao_rx_a";
+						function = "uart_ao_a";
+					};
+				};
+
+				uart_ao_a_cts_rts_pins: uart_ao_a_cts_rts {
+					mux {
+						groups = "uart_ao_cts_a",
+							"uart_ao_rts_a";
+						function = "uart_ao_a";
+					};
+				};
+
+				uart_ao_b_pins: uart_ao_b {
+					mux {
+						groups = "uart_ao_tx_b",
+							"uart_ao_rx_b";
+						function = "uart_ao_b";
+					};
+				};
+
+				uart_ao_b_cts_rts_pins: uart_ao_b_cts_rts {
+					mux {
+						groups = "uart_ao_cts_b",
+							"uart_ao_rts_b";
+						function = "uart_ao_b";
+					};
+				};
+			};
+
+			sec_AO: ao-secure@140 {
+				compatible = "amlogic,meson-gx-ao-secure", "syscon";
+				reg = <0x0 0x140 0x0 0x140>;
+				amlogic,has-chip-id;
 			};
 
 			pwm_AO_ab: pwm@7000 {
@@ -504,12 +758,23 @@
 			};
 
 			pwm_AO_cd: pwm@2000 {
-				compatible = "amlogic,axg-ao-pwm";
+				compatible = "amlogic,meson-axg-ao-pwm";
 				reg = <0x0 0x02000  0x0 0x20>;
 				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
+			i2c_AO: i2c@5000 {
+				compatible = "amlogic,meson-axg-i2c";
+				status = "disabled";
+				reg = <0x0 0x05000 0x0 0x20>;
+				interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clocks = <&clkc CLKID_I2C>;
+				clock-names = "clk_i2c";
+			};
+
 			uart_AO: serial@3000 {
 				compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
 				reg = <0x0 0x3000 0x0 0x18>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
index aeb6d21..4eef36b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /* Common DTSI for same Amlogic Q200/Q201 and P230/P231 boards using either
@@ -48,6 +11,7 @@
 / {
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 4ee2e79..3c31e21 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
  *
@@ -6,44 +7,6 @@
  *
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/gpio/gpio.h>
@@ -169,6 +132,7 @@
 		compatible = "amlogic,meson-gx-efuse", "amlogic,meson-gxbb-efuse";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		read-only;
 
 		sn: sn@14 {
 			reg = <0x14 0x10>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
index 011e8e0..7d5709c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
@@ -1,45 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Andreas Färber
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
@@ -52,6 +13,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
index 818954b..4cf7f6e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Neil Armstrong <narmstrong@kernel.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
@@ -54,6 +17,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index ee4ada6..54954b3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Kevin Hilman <khilman@kernel.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
@@ -53,6 +16,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
@@ -310,7 +274,7 @@
 	pinctrl-names = "default", "clk-gate";
 
 	bus-width = <8>;
-	max-frequency = <200000000>;
+	max-frequency = <100000000>;
 	non-removable;
 	disable-wp;
 	cap-mmc-highspeed;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
index 09f34f7e..9d2406a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Kevin Hilman <khilman@kernel.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
index ae31946..56e0dd1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Kevin Hilman <khilman@kernel.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index 932158a..ce86226 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Kevin Hilman <khilman@kernel.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "meson-gxbb.dtsi"
@@ -47,6 +10,7 @@
 / {
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts
index 62fb496..c928adf 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts
index 9a9663a..e81e1d6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts
index 2fe167b..a8fca0c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index 1fe8e24..93a4acf 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "meson-gxbb.dtsi"
@@ -47,6 +10,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts
index 1878ac2..2bfe699 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts
@@ -1,92 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
 
-#include "meson-gxbb-p20x.dtsi"
+#include "meson-gxbb-wetek.dtsi"
 
 / {
 	compatible = "wetek,hub", "amlogic,meson-gxbb";
 	model = "WeTek Hub";
-
-	leds {
-		compatible = "gpio-leds";
-
-		system {
-			label = "wetek-play:system-status";
-			gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
-			default-state = "on";
-			panic-indicator;
-		};
-	};
-};
-
-&cvbs_connector {
-	status = "disabled";
-};
-
-&ethmac {
-	status = "okay";
-	pinctrl-0 = <&eth_rgmii_pins>;
-	pinctrl-names = "default";
-
-	phy-handle = <&eth_phy0>;
-	phy-mode = "rgmii";
-
-	amlogic,tx-delay-ns = <2>;
-
-	snps,reset-gpio = <&gpio GPIOZ_14 0>;
-	snps,reset-delays-us = <0 10000 1000000>;
-	snps,reset-active-low;
-
-	mdio {
-		compatible = "snps,dwmac-mdio";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		eth_phy0: ethernet-phy@0 {
-			/* Realtek RTL8211F (0x001cc916) */
-			reg = <0>;
-		};
-	};
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts
index f7144fd..0038522 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts
@@ -1,49 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
 
-#include "meson-gxbb-p20x.dtsi"
+#include "meson-gxbb-wetek.dtsi"
 #include <dt-bindings/input/input.h>
 
 / {
@@ -51,15 +14,6 @@
 	model = "WeTek Play 2";
 
 	leds {
-		compatible = "gpio-leds";
-
-		system {
-			label = "wetek-play:system-status";
-			gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
-			default-state = "on";
-			panic-indicator;
-		};
-
 		wifi {
 			label = "wetek-play:wifi-status";
 			gpios = <&gpio GPIODV_26 GPIO_ACTIVE_HIGH>;
@@ -85,78 +39,6 @@
 			gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_LOW>;
 		};
 	};
-
-	cvbs-connector {
-		compatible = "composite-video-connector";
-
-		port {
-			cvbs_connector_in: endpoint {
-				remote-endpoint = <&cvbs_vdac_out>;
-			};
-		};
-	};
-
-	hdmi-connector {
-		compatible = "hdmi-connector";
-		type = "a";
-
-		port {
-			hdmi_connector_in: endpoint {
-				remote-endpoint = <&hdmi_tx_tmds_out>;
-			};
-		};
-	};
-};
-
-&cec_AO {
-	status = "okay";
-	pinctrl-0 = <&ao_cec_pins>;
-	pinctrl-names = "default";
-	hdmi-phandle = <&hdmi_tx>;
-};
-
-&cvbs_vdac_port {
-	cvbs_vdac_out: endpoint {
-		remote-endpoint = <&cvbs_connector_in>;
-	};
-};
-
-&ethmac {
-	status = "okay";
-	pinctrl-0 = <&eth_rgmii_pins>;
-	pinctrl-names = "default";
-
-	phy-handle = <&eth_phy0>;
-	phy-mode = "rgmii";
-
-	amlogic,tx-delay-ns = <2>;
-
-	snps,reset-gpio = <&gpio GPIOZ_14 0>;
-	snps,reset-delays-us = <0 10000 1000000>;
-	snps,reset-active-low;
-
-	mdio {
-		compatible = "snps,dwmac-mdio";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		eth_phy0: ethernet-phy@0 {
-			/* Realtek RTL8211F (0x001cc916) */
-			reg = <0>;
-		};
-	};
-};
-
-&hdmi_tx {
-	status = "okay";
-	pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
-	pinctrl-names = "default";
-};
-
-&hdmi_tx_tmds_port {
-	hdmi_tx_tmds_out: endpoint {
-		remote-endpoint = <&hdmi_connector_in>;
-	};
 };
 
 &i2c_A {
@@ -164,3 +46,11 @@
 	pinctrl-0 = <&i2c_a_pins>;
 	pinctrl-names = "default";
 };
+
+&usb1_phy {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
new file mode 100644
index 0000000..70325b2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2016 Andreas Färber
+ * Copyright (c) 2016 BayLibre, Inc.
+ * Author: Kevin Hilman <khilman@kernel.org>
+ */
+
+#include "meson-gxbb.dtsi"
+
+/ {
+	aliases {
+		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		system {
+			label = "wetek-play:system-status";
+			gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+			panic-indicator;
+		};
+	};
+
+	usb_pwr: regulator-usb-pwrs {
+		compatible = "regulator-fixed";
+
+		regulator-name = "USB_PWR";
+
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+
+		gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	vddio_boot: regulator-vddio_boot {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_BOOT";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcc_3v3: regulator-vcc_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	cvbs-connector {
+		compatible = "composite-video-connector";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+};
+
+&cec_AO {
+	status = "okay";
+	pinctrl-0 = <&ao_cec_pins>;
+	pinctrl-names = "default";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
+};
+
+&ethmac {
+	status = "okay";
+	pinctrl-0 = <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+
+	phy-handle = <&eth_phy0>;
+	phy-mode = "rgmii";
+
+	amlogic,tx-delay-ns = <2>;
+
+	snps,reset-gpio = <&gpio GPIOZ_14 0>;
+	snps,reset-delays-us = <0 10000 1000000>;
+	snps,reset-active-low;
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		eth_phy0: ethernet-phy@0 {
+			/* Realtek RTL8211F (0x001cc916) */
+			reg = <0>;
+			eee-broken-1000t;
+		};
+	};
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+	pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&clkc CLKID_FCLK_DIV4>;
+	clock-names = "clkin0";
+};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+
+	brcmf: wifi@1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+	};
+};
+
+/* SD card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_pins>;
+	pinctrl-1 = <&sdcard_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vcc_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+	pinctrl-1 = <&emmc_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	max-frequency = <200000000>;
+	non-removable;
+	disable-wp;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vddio_boot>;
+};
+
+/* This UART is brought out to the DB9 connector */
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&usb0_phy {
+	status = "okay";
+	phy-supply = <&usb_pwr>;
+};
+
+&usb0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 3290a4d..562c26a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "meson-gx.dtsi"
@@ -284,14 +247,17 @@
 		 * MALI_0 and MALI_1 muxed to a single clock by a glitch
 		 * free mux to safely change frequency while running.
 		 */
-		assigned-clocks = <&clkc CLKID_MALI_0_SEL>,
+		assigned-clocks = <&clkc CLKID_GP0_PLL>,
+				  <&clkc CLKID_MALI_0_SEL>,
 				  <&clkc CLKID_MALI_0>,
 				  <&clkc CLKID_MALI>; /* Glitch free mux */
-		assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
+		assigned-clock-parents = <0>, /* Do Nothing */
+					 <&clkc CLKID_GP0_PLL>,
 					 <0>, /* Do Nothing */
 					 <&clkc CLKID_MALI_0>;
-		assigned-clock-rates = <0>, /* Do Nothing */
-				       <666666666>,
+		assigned-clock-rates = <744000000>,
+				       <0>, /* Do Nothing */
+				       <744000000>,
 				       <0>; /* Do Nothing */
 	};
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi
index f06cc234..eb32766 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi
@@ -1,8 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 BayLibre SAS
  * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 &apb {
@@ -30,14 +29,17 @@
 		 * MALI_0 and MALI_1 muxed to a single clock by a glitch
 		 * free mux to safely change frequency while running.
 		 */
-		assigned-clocks = <&clkc CLKID_MALI_0_SEL>,
+		assigned-clocks = <&clkc CLKID_GP0_PLL>,
+				  <&clkc CLKID_MALI_0_SEL>,
 				  <&clkc CLKID_MALI_0>,
 				  <&clkc CLKID_MALI>; /* Glitch free mux */
-		assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
+		assigned-clock-parents = <0>, /* Do Nothing */
+					 <&clkc CLKID_GP0_PLL>,
 					 <0>, /* Do Nothing */
 					 <&clkc CLKID_MALI_0>;
-		assigned-clock-rates = <0>, /* Do Nothing */
-				       <666666666>,
+		assigned-clock-rates = <744000000>,
+				       <0>, /* Do Nothing */
+				       <744000000>,
 				       <0>; /* Do Nothing */
 	};
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
index 4f3f03f..a9f9bb9 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
index 95992cf..80a2314 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d.dtsi
index 5a90e30..4332191 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d.dtsi
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "meson-gxl.dtsi"
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
index e825825..f1c410e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Carlo Caione
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Neil Armstrong <narmstrong@kernel.org>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
@@ -16,6 +15,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
index 71a6e1c..d32cf38 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
@@ -29,6 +28,7 @@
 
 	aliases {
 		serial2 = &uart_AO_B;
+		ethernet0 = &ethmac;
 	};
 
 	gpio-keys-polled {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
index 9671f1e..22bf374 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 BayLibre, SAS.
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  * Author: Jerome Brunet <jbrunet@baylibre.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
@@ -18,6 +17,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
index 271f142..69c721a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
  * Copyright (c) 2016 BayLibre, Inc.
  * Author: Neil Armstrong <narmstrong@kernel.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
@@ -52,6 +15,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
index 6e2bf85..5896e8a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
index 7005068..0a0953f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
  * Based on meson-gx-p23x-q20x.dtsi:
@@ -5,8 +6,6 @@
  *   Author: Carlo Caione <carlo@endlessm.com>
  * - Copyright (c) 2016 BayLibre, SAS.
  *   Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /* Common DTSI for devices which are based on the P212 reference board. */
@@ -17,6 +16,7 @@
 	aliases {
 		serial0 = &uart_AO;
 		serial1 = &uart_A;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
index 3314a0b..40c19f6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "meson-gxl.dtsi"
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index c851411..e1a39cb 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "meson-gx.dtsi"
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
index 1448c3db..4fd46c1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
  * Copyright (c) 2017 BayLibre, SAS
  * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
@@ -59,8 +58,6 @@
 				      1 1
 				      2 2
 				      3 3>;
-		cooling-min-level = <0>;
-		cooling-max-level = <3>;
 		#cooling-cells = <2>;
 	};
 
@@ -209,14 +206,10 @@
 };
 
 &cpu0 {
-	cooling-min-level = <0>;
-	cooling-max-level = <6>;
 	#cooling-cells = <2>;
 };
 
 &cpu4 {
-	cooling-min-level = <0>;
-	cooling-max-level = <4>;
 	#cooling-cells = <2>;
 };
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
index e7a228f6..f7a1cff 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 BayLibre, SAS.
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  *
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
@@ -54,6 +17,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts
index 388fac4..1014172 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-q201.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-q201.dts
index 95e11d7..8d132b1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-q201.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-q201.dts
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
index a5e9b95..7212dc4 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016-2017 Andreas Färber
  *
@@ -8,44 +9,6 @@
  *
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
@@ -58,6 +21,7 @@
 
 	aliases {
 		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-vega-s96.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-vega-s96.dts
index dc37eec..e2ea675 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-vega-s96.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-vega-s96.dts
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 BayLibre, SAS.
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  * Copyright (c) 2017 Oleg <balbes-150@yandex.ru>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
index 19a798d..d076a7c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Endless Computers, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "meson-gxl.dtsi"
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index f165f04..eb749c5 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -68,10 +68,29 @@
 		interrupt-controller;
 		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
 		ranges = <0 0 0 0x2c1c0000 0 0x40000>;
+
 		v2m_0: v2m@0 {
 			compatible = "arm,gic-v2m-frame";
 			msi-controller;
-			reg = <0 0 0 0x1000>;
+			reg = <0 0 0 0x10000>;
+		};
+
+		v2m@10000 {
+			compatible = "arm,gic-v2m-frame";
+			msi-controller;
+			reg = <0 0x10000 0 0x10000>;
+		};
+
+		v2m@20000 {
+			compatible = "arm,gic-v2m-frame";
+			msi-controller;
+			reg = <0 0x20000 0 0x10000>;
+		};
+
+		v2m@30000 {
+			compatible = "arm,gic-v2m-frame";
+			msi-controller;
+			reg = <0 0x30000 0 0x10000>;
 		};
 	};
 
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
index a77462d..a1e3194 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
@@ -14,6 +14,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/sound/samsung-i2s.h>
 
 / {
 	aliases {
@@ -112,8 +113,8 @@
 
 	sound {
 		compatible = "samsung,tm2-audio";
-		audio-codec = <&wm5110>;
-		i2s-controller = <&i2s0>;
+		audio-codec = <&wm5110>, <&hdmi>;
+		i2s-controller = <&i2s0 0>, <&i2s1 0>;
 		audio-amplifier = <&max98504>;
 		mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
 		model = "wm5110";
@@ -217,8 +218,40 @@
 };
 
 &cmu_aud {
-	assigned-clocks = <&cmu_aud CLK_MOUT_AUD_PLL_USER>;
-	assigned-clock-parents = <&cmu_top CLK_FOUT_AUD_PLL>;
+	assigned-clocks = <&cmu_aud CLK_MOUT_AUD_PLL_USER>,
+		<&cmu_aud CLK_MOUT_SCLK_AUD_I2S>,
+		<&cmu_aud CLK_MOUT_SCLK_AUD_PCM>,
+		<&cmu_top CLK_MOUT_AUD_PLL>,
+		<&cmu_top CLK_MOUT_AUD_PLL_USER_T>,
+		<&cmu_top CLK_MOUT_SCLK_AUDIO0>,
+		<&cmu_top CLK_MOUT_SCLK_AUDIO1>,
+		<&cmu_top CLK_MOUT_SCLK_SPDIF>,
+
+		<&cmu_aud CLK_DIV_AUD_CA5>,
+		<&cmu_aud CLK_DIV_ACLK_AUD>,
+		<&cmu_aud CLK_DIV_PCLK_DBG_AUD>,
+		<&cmu_aud CLK_DIV_SCLK_AUD_I2S>,
+		<&cmu_aud CLK_DIV_SCLK_AUD_PCM>,
+		<&cmu_aud CLK_DIV_SCLK_AUD_SLIMBUS>,
+		<&cmu_aud CLK_DIV_SCLK_AUD_UART>,
+		<&cmu_top CLK_DIV_SCLK_AUDIO0>,
+		<&cmu_top CLK_DIV_SCLK_AUDIO1>,
+		<&cmu_top CLK_DIV_SCLK_PCM1>,
+		<&cmu_top CLK_DIV_SCLK_I2S1>;
+
+	assigned-clock-parents = <&cmu_top CLK_FOUT_AUD_PLL>,
+		<&cmu_aud CLK_MOUT_AUD_PLL_USER>,
+		<&cmu_aud CLK_MOUT_AUD_PLL_USER>,
+		<&cmu_top CLK_FOUT_AUD_PLL>,
+		<&cmu_top CLK_MOUT_AUD_PLL>,
+		<&cmu_top CLK_MOUT_AUD_PLL_USER_T>,
+		<&cmu_top CLK_MOUT_AUD_PLL_USER_T>,
+		<&cmu_top CLK_SCLK_AUDIO0>;
+
+	assigned-clock-rates = <0>, <0>, <0>, <0>, <0>, <0>, <0>, <0>,
+		<196608001>, <65536001>, <32768001>, <49152001>,
+		<2048001>, <24576001>, <196608001>,
+		<24576001>, <98304001>, <2048001>, <49152001>;
 };
 
 &cmu_fsys {
@@ -267,6 +300,11 @@
 				 <&cmu_top CLK_MOUT_BUS_PLL_USER>;
 };
 
+&cmu_top {
+	assigned-clocks = <&cmu_top CLK_FOUT_AUD_PLL>;
+	assigned-clock-rates = <196608001>;
+};
+
 &cpu0 {
 	cpu-supply = <&buck3_reg>;
 };
@@ -779,9 +817,22 @@
 		clocks = <&pmu_system_controller 0>;
 		clock-names = "xtal";
 
-		port {
-			mhl_to_hdmi: endpoint {
-				remote-endpoint = <&hdmi_to_mhl>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				mhl_to_hdmi: endpoint {
+					remote-endpoint = <&hdmi_to_mhl>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				mhl_to_musb_con: endpoint {
+					remote-endpoint = <&musb_con_to_mhl>;
+				};
 			};
 		};
 	};
@@ -798,6 +849,25 @@
 
 		muic: max77843-muic {
 			compatible = "maxim,max77843-muic";
+
+			musb_con: musb_connector {
+				compatible = "samsung,usb-connector-11pin",
+					     "usb-b-connector";
+				label = "micro-USB";
+				type = "micro";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@3 {
+						reg = <3>;
+						musb_con_to_mhl: endpoint {
+							remote-endpoint = <&mhl_to_musb_con>;
+						};
+					};
+				};
+			};
 		};
 
 		regulators {
@@ -838,6 +908,12 @@
 	status = "okay";
 };
 
+&i2s1 {
+	assigned-clocks = <&i2s1 CLK_I2S_RCLK_SRC>;
+	assigned-clock-parents = <&cmu_peric CLK_SCLK_I2S1>;
+	status = "okay";
+};
+
 &mshc_0 {
 	status = "okay";
 	mmc-hs200-1_8v;
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index 62f2769..c0231d0 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -969,6 +969,7 @@
 			ddc = <&hsi2c_11>;
 			samsung,syscon-phandle = <&pmu_system_controller>;
 			samsung,sysreg-phandle = <&syscon_disp>;
+			#sound-dai-cells = <0>;
 			status = "disabled";
 		};
 
@@ -1311,6 +1312,25 @@
 			status = "disabled";
 		};
 
+		i2s1: i2s@14d60000 {
+			compatible = "samsung,exynos7-i2s";
+			reg = <0x14d60000 0x100>;
+			dmas = <&pdma0 31 &pdma0 30>;
+			dma-names = "tx", "rx";
+			interrupts = <GIC_SPI 435 IRQ_TYPE_NONE>;
+			clocks = <&cmu_peric CLK_PCLK_I2S1>,
+				 <&cmu_peric CLK_PCLK_I2S1>,
+				 <&cmu_peric CLK_SCLK_I2S1>;
+			clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+			#clock-cells = <1>;
+			samsung,supports-6ch;
+			samsung,supports-rstclr;
+			samsung,supports-tdm;
+			samsung,supports-low-rfs;
+			#sound-dai-cells = <1>;
+			status = "disabled";
+		};
+
 		pwm: pwm@14dd0000 {
 			compatible = "samsung,exynos4210-pwm";
 			reg = <0x14dd0000 0x100>;
@@ -1639,7 +1659,7 @@
 				power-domains = <&pd_aud>;
 			};
 
-			i2s0: i2s0@11440000 {
+			i2s0: i2s@11440000 {
 				compatible = "samsung,exynos7-i2s";
 				reg = <0x11440000 0x100>;
 				dmas = <&adma 0 &adma 2>;
@@ -1651,9 +1671,11 @@
 					<&cmu_aud CLK_SCLK_AUD_I2S>,
 					<&cmu_aud CLK_SCLK_I2S_BCLK>;
 				clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+				#clock-cells = <1>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&i2s0_bus>;
 				power-domains = <&pd_aud>;
+				#sound-dai-cells = <1>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
index 2272352..00dd89b 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
+++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
@@ -23,7 +23,7 @@
 	};
 
 	chosen {
-		linux,stdout-path = &serial_2;
+		stdout-path = &serial_2;
 	};
 
 	memory@40000000 {
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
index 82b272f..bb788ed 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
@@ -70,6 +70,24 @@
 			reg = <0x0>;
 			clocks = <&clockgen 1 0>;
 			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_PH20>;
+		};
+	};
+
+	idle-states {
+		/*
+		 * PSCI node is not added default, U-boot will add missing
+		 * parts if it determines to use PSCI.
+		 */
+		entry-method = "arm,psci";
+
+		CPU_PH20: cpu-ph20 {
+			compatible = "arm,idle-state";
+			idle-state-name = "PH20";
+			arm,psci-suspend-param = <0x0>;
+			entry-latency-us = <1000>;
+			exit-latency-us = <1000>;
+			min-residency-us = <3000>;
 		};
 	};
 
@@ -118,6 +136,37 @@
 		mask = <0x02>;
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&tmu 0>;
+
+			trips {
+				cpu_alert: cpu-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				cpu_crit: cpu-crit {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu0 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -304,37 +353,6 @@
 			#thermal-sensor-cells = <1>;
 		};
 
-		thermal-zones {
-			cpu_thermal: cpu-thermal {
-				polling-delay-passive = <1000>;
-				polling-delay = <5000>;
-				thermal-sensors = <&tmu 0>;
-
-				trips {
-					cpu_alert: cpu-alert {
-						temperature = <85000>;
-						hysteresis = <2000>;
-						type = "passive";
-					};
-
-					cpu_crit: cpu-crit {
-						temperature = <95000>;
-						hysteresis = <2000>;
-						type = "critical";
-					};
-				};
-
-				cooling-maps {
-					map0 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu0 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-				};
-			};
-		};
-
 		i2c0: i2c@2180000 {
 			compatible = "fsl,vf610-i2c";
 			#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index 380e7c7..1109f22 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -81,6 +81,7 @@
 			clocks = <&clockgen 1 0>;
 			next-level-cache = <&l2>;
 			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_PH20>;
 		};
 
 		cpu1: cpu@1 {
@@ -89,6 +90,7 @@
 			reg = <0x1>;
 			clocks = <&clockgen 1 0>;
 			next-level-cache = <&l2>;
+			cpu-idle-states = <&CPU_PH20>;
 		};
 
 		cpu2: cpu@2 {
@@ -97,6 +99,7 @@
 			reg = <0x2>;
 			clocks = <&clockgen 1 0>;
 			next-level-cache = <&l2>;
+			cpu-idle-states = <&CPU_PH20>;
 		};
 
 		cpu3: cpu@3 {
@@ -105,6 +108,7 @@
 			reg = <0x3>;
 			clocks = <&clockgen 1 0>;
 			next-level-cache = <&l2>;
+			cpu-idle-states = <&CPU_PH20>;
 		};
 
 		l2: l2-cache {
@@ -112,6 +116,23 @@
 		};
 	};
 
+	idle-states {
+		/*
+		 * PSCI node is not added default, U-boot will add missing
+		 * parts if it determines to use PSCI.
+		 */
+		entry-method = "arm,psci";
+
+		CPU_PH20: cpu-ph20 {
+			compatible = "arm,idle-state";
+			idle-state-name = "PH20";
+			arm,psci-suspend-param = <0x0>;
+			entry-latency-us = <1000>;
+			exit-latency-us = <1000>;
+			min-residency-us = <3000>;
+		};
+	};
+
 	memory@80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0 0x80000000>;
@@ -159,6 +180,37 @@
 		mask = <0x02>;
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+
+			thermal-sensors = <&tmu 3>;
+
+			trips {
+				cpu_alert: cpu-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit: cpu-crit {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu0 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <1 13 0xf08>, /* Physical Secure PPI */
@@ -342,37 +394,6 @@
 			#thermal-sensor-cells = <1>;
 		};
 
-		thermal-zones {
-			cpu_thermal: cpu-thermal {
-				polling-delay-passive = <1000>;
-				polling-delay = <5000>;
-
-				thermal-sensors = <&tmu 3>;
-
-				trips {
-					cpu_alert: cpu-alert {
-						temperature = <85000>;
-						hysteresis = <2000>;
-						type = "passive";
-					};
-					cpu_crit: cpu-crit {
-						temperature = <95000>;
-						hysteresis = <2000>;
-						type = "critical";
-					};
-				};
-
-				cooling-maps {
-					map0 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu0 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-				};
-			};
-		};
-
 		qman: qman@1880000 {
 			compatible = "fsl,qman";
 			reg = <0x0 0x1880000 0x0 0x10000>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 06b5e12..136ebfa 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -122,7 +122,7 @@
 		CPU_PH20: cpu-ph20 {
 			compatible = "arm,idle-state";
 			idle-state-name = "PH20";
-			arm,psci-suspend-param = <0x00010000>;
+			arm,psci-suspend-param = <0x0>;
 			entry-latency-us = <1000>;
 			exit-latency-us = <1000>;
 			min-residency-us = <3000>;
@@ -131,6 +131,8 @@
 
 	memory@80000000 {
 		device_type = "memory";
+		/* Real size will be filled by bootloader */
+		reg = <0x0 0x80000000 0x0 0x0>;
 	};
 
 	sysclk: sysclk {
@@ -147,6 +149,37 @@
 		mask = <0x02>;
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&tmu 3>;
+
+			trips {
+				cpu_alert: cpu-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				cpu_crit: cpu-crit {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu0 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(0xf) |
@@ -362,37 +395,6 @@
 			#thermal-sensor-cells = <1>;
 		};
 
-		thermal-zones {
-			cpu_thermal: cpu-thermal {
-				polling-delay-passive = <1000>;
-				polling-delay = <5000>;
-				thermal-sensors = <&tmu 3>;
-
-				trips {
-					cpu_alert: cpu-alert {
-						temperature = <85000>;
-						hysteresis = <2000>;
-						type = "passive";
-					};
-
-					cpu_crit: cpu-crit {
-						temperature = <95000>;
-						hysteresis = <2000>;
-						type = "critical";
-					};
-				};
-
-				cooling-maps {
-					map0 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu0 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-				};
-			};
-		};
-
 		dspi: dspi@2100000 {
 			compatible = "fsl,ls1021a-v1.0-dspi";
 			#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 4fc150c..1c6556b 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -130,7 +130,7 @@
 		CPU_PH20: cpu-ph20 {
 			compatible = "arm,idle-state";
 			idle-state-name = "PH20";
-			arm,psci-suspend-param = <0x00010000>;
+			arm,psci-suspend-param = <0x0>;
 			entry-latency-us = <1000>;
 			exit-latency-us = <1000>;
 			min-residency-us = <3000>;
@@ -158,6 +158,44 @@
 		};
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&tmu 0>;
+
+			trips {
+				cpu_alert: cpu-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				cpu_crit: cpu-crit {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu0 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+
+				map1 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu4 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <1 13 IRQ_TYPE_LEVEL_LOW>,/* Physical Secure PPI */
@@ -315,44 +353,6 @@
 			#thermal-sensor-cells = <1>;
 		};
 
-		thermal-zones {
-			cpu_thermal: cpu-thermal {
-				polling-delay-passive = <1000>;
-				polling-delay = <5000>;
-				thermal-sensors = <&tmu 0>;
-
-				trips {
-					cpu_alert: cpu-alert {
-						temperature = <85000>;
-						hysteresis = <2000>;
-						type = "passive";
-					};
-
-					cpu_crit: cpu-crit {
-						temperature = <95000>;
-						hysteresis = <2000>;
-						type = "critical";
-					};
-				};
-
-				cooling-maps {
-					map0 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu0 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-
-					map1 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu4 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-				};
-			};
-		};
-
 		duart0: serial@21c0500 {
 			compatible = "fsl,ns16550", "ns16550a";
 			reg = <0x0 0x21c0500 0x0 0x100>;
@@ -612,6 +612,62 @@
 					<0000 0 0 3 &gic 0 0 0 121 IRQ_TYPE_LEVEL_HIGH>,
 					<0000 0 0 4 &gic 0 0 0 122 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
+		cluster1_core0_watchdog: wdt@c000000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xc000000 0x0 0x1000>;
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "apb_pclk", "wdog_clk";
+		};
+
+		cluster1_core1_watchdog: wdt@c010000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xc010000 0x0 0x1000>;
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "apb_pclk", "wdog_clk";
+		};
+
+		cluster1_core2_watchdog: wdt@c020000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xc020000 0x0 0x1000>;
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "apb_pclk", "wdog_clk";
+		};
+
+		cluster1_core3_watchdog: wdt@c030000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xc030000 0x0 0x1000>;
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "apb_pclk", "wdog_clk";
+		};
+
+		cluster2_core0_watchdog: wdt@c100000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xc100000 0x0 0x1000>;
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "apb_pclk", "wdog_clk";
+		};
+
+		cluster2_core1_watchdog: wdt@c110000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xc110000 0x0 0x1000>;
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "apb_pclk", "wdog_clk";
+		};
+
+		cluster2_core2_watchdog: wdt@c120000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xc120000 0x0 0x1000>;
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "apb_pclk", "wdog_clk";
+		};
+
+		cluster2_core3_watchdog: wdt@c130000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xc130000 0x0 0x1000>;
+			clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+			clock-names = "apb_pclk", "wdog_clk";
+		};
 	};
 
 	firmware {
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi
index aeaef01..0884e1a 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi
@@ -143,7 +143,7 @@
 	CPU_PW20: cpu-pw20 {
 		compatible = "arm,idle-state";
 		idle-state-name = "PW20";
-		arm,psci-suspend-param = <0x00010000>;
+		arm,psci-suspend-param = <0x0>;
 		entry-latency-us = <2000>;
 		exit-latency-us = <2000>;
 		min-residency-us = <6000>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi
index b237446..1de6188 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi
@@ -140,21 +140,21 @@
 
 &dspi {
 	status = "okay";
-	dflash0: n25q128a {
+	dflash0: n25q128a@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "st,m25p80";
 		spi-max-frequency = <3000000>;
 		reg = <0>;
 	};
-	dflash1: sst25wf040b {
+	dflash1: sst25wf040b@1 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "st,m25p80";
 		spi-max-frequency = <3000000>;
 		reg = <1>;
 	};
-	dflash2: en25s64 {
+	dflash2: en25s64@2 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "st,m25p80";
@@ -177,7 +177,7 @@
 		#size-cells = <1>;
 		compatible = "st,m25p80";
 		spi-max-frequency = <20000000>;
-		reg = <0>;
+		reg = <2>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
index f3a40af..137ef4d 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
@@ -111,6 +111,55 @@
 		mask = <0x2>;
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+
+			thermal-sensors = <&tmu 4>;
+
+			trips {
+				cpu_alert: cpu-alert {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit: cpu-crit {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu0 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+				map1 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu2 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+				map2 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu4 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+				map3 {
+					trip = <&cpu_alert>;
+					cooling-device =
+						<&cpu6 THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <1 13 4>, /* Physical Secure PPI, active-low */
@@ -194,55 +243,6 @@
 			#thermal-sensor-cells = <1>;
 		};
 
-		thermal-zones {
-			cpu_thermal: cpu-thermal {
-				polling-delay-passive = <1000>;
-				polling-delay = <5000>;
-
-				thermal-sensors = <&tmu 4>;
-
-				trips {
-					cpu_alert: cpu-alert {
-						temperature = <75000>;
-						hysteresis = <2000>;
-						type = "passive";
-					};
-					cpu_crit: cpu-crit {
-						temperature = <85000>;
-						hysteresis = <2000>;
-						type = "critical";
-					};
-				};
-
-				cooling-maps {
-					map0 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu0 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-					map1 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu2 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-					map2 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu4 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-					map3 {
-						trip = <&cpu_alert>;
-						cooling-device =
-							<&cpu6 THERMAL_NO_LIMIT
-							THERMAL_NO_LIMIT>;
-					};
-				};
-			};
-		};
-
 		serial0: serial@21c0500 {
 			compatible = "fsl,ns16550", "ns16550a";
 			reg = <0x0 0x21c0500 0x0 0x100>;
diff --git a/arch/arm64/boot/dts/freescale/qoriq-bman-portals.dtsi b/arch/arm64/boot/dts/freescale/qoriq-bman-portals.dtsi
index c3c2be4..ae15307 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-bman-portals.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-bman-portals.dtsi
@@ -68,4 +68,10 @@
 		reg = <0x80000 0x4000>, <0x4080000 0x4000>;
 		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
 	};
+
+	bman-portal@90000 {
+		compatible = "fsl,bman-portal";
+		reg = <0x90000 0x4000>, <0x4090000 0x4000>;
+		interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+	};
 };
diff --git a/arch/arm64/boot/dts/freescale/qoriq-qman-portals.dtsi b/arch/arm64/boot/dts/freescale/qoriq-qman-portals.dtsi
index 2a9aa06..6a93a4a 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-qman-portals.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-qman-portals.dtsi
@@ -77,4 +77,11 @@
 		interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
 		cell-index = <8>;
 	};
+
+	qportal9: qman-portal@90000 {
+		compatible = "fsl,qman-portal";
+		reg = <0x90000 0x4000>, <0x4090000 0x4000>;
+		interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+		cell-index = <9>;
+	};
 };
diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index a7ecd90..ec3eb8e 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -100,11 +100,7 @@
 			reg = <0x0 0x100>;
 			enable-method = "psci";
 			next-level-cache = <&A73_L2>;
-			cpu-idle-states = <
-					&CPU_NAP
-					&CPU_SLEEP
-					&CLUSTER_SLEEP_1
-			>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_1>;
 			capacity-dmips-mhz = <1024>;
 		};
 
@@ -114,11 +110,7 @@
 			reg = <0x0 0x101>;
 			enable-method = "psci";
 			next-level-cache = <&A73_L2>;
-			cpu-idle-states = <
-					&CPU_NAP
-					&CPU_SLEEP
-					&CLUSTER_SLEEP_1
-			>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_1>;
 			capacity-dmips-mhz = <1024>;
 		};
 
@@ -128,11 +120,7 @@
 			reg = <0x0 0x102>;
 			enable-method = "psci";
 			next-level-cache = <&A73_L2>;
-			cpu-idle-states = <
-					&CPU_NAP
-					&CPU_SLEEP
-					&CLUSTER_SLEEP_1
-			>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_1>;
 			capacity-dmips-mhz = <1024>;
 		};
 
@@ -142,25 +130,13 @@
 			reg = <0x0 0x103>;
 			enable-method = "psci";
 			next-level-cache = <&A73_L2>;
-			cpu-idle-states = <
-					&CPU_NAP
-					&CPU_SLEEP
-					&CLUSTER_SLEEP_1
-			>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_1>;
 			capacity-dmips-mhz = <1024>;
 		};
 
 		idle-states {
 			entry-method = "psci";
 
-			CPU_NAP: cpu-nap {
-				compatible = "arm,idle-state";
-				arm,psci-suspend-param = <0x0000001>;
-				entry-latency-us = <7>;
-				exit-latency-us = <2>;
-				min-residency-us = <15>;
-			};
-
 			CPU_SLEEP: cpu-sleep {
 				compatible = "arm,idle-state";
 				local-timer-stop;
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index 047641f..724a0d3 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -299,7 +299,9 @@
 		/* GPIO blocks 16 thru 19 do not appear to be routed to pins */
 
 		dwmmc_0: dwmmc0@f723d000 {
+			max-frequency = <150000000>;
 			cap-mmc-highspeed;
+			mmc-hs200-1_8v;
 			non-removable;
 			bus-width = <0x8>;
 			vmmc-supply = <&ldo19>;
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 6a180d1..586b281c 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -88,8 +88,6 @@
 			next-level-cache = <&CLUSTER0_L2>;
 			clocks = <&stub_clock 0>;
 			operating-points-v2 = <&cpu_opp_table>;
-			cooling-min-level = <4>;
-			cooling-max-level = <0>;
 			#cooling-cells = <2>; /* min followed by max */
 			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
 			dynamic-power-coefficient = <311>;
@@ -817,6 +815,14 @@
 			pinctrl-1 = <&sdio_pmx_idle &sdio_clk_cfg_idle &sdio_cfg_idle>;
 		};
 
+		watchdog0: watchdog@f8005000 {
+			compatible = "arm,sp805-wdt", "arm,primecell";
+			reg = <0x0 0xf8005000 0x0 0x1000>;
+			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ao_ctrl HI6220_WDT0_PCLK>;
+			clock-names = "apb_pclk";
+		};
+
 		tsensor: tsensor@0,f7030700 {
 			compatible = "hisilicon,tsensor";
 			reg = <0x0 0xf7030700 0x0 0x1000>;
diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
index a049b64..35202eb 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
@@ -291,6 +291,13 @@
 			#interrupt-cells = <2>;
 			num-pins = <128>;
 		};
+
+		mbigen_pcie0: intc_pcie0 {
+			msi-parent = <&its_dsa 0x40085>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			num-pins = <10>;
+		};
 	};
 
 	mbigen_dsa@c0080000 {
@@ -312,6 +319,31 @@
 		};
 	};
 
+	/**
+	 *  HiSilicon erratum 161010801: This describes the limitation
+	 *  of HiSilicon platforms hip06/hip07 to support the SMMUv3
+	 *  mappings for PCIe MSI transactions.
+	 *  PCIe controller on these platforms has to differentiate the
+	 *  MSI payload against other DMA payload and has to modify the
+	 *  MSI payload. This makes it difficult for these platforms to
+	 *  have a SMMU translation for MSI. In order to workaround this,
+	 *  ARM SMMUv3 driver requires a quirk to treat the MSI regions
+	 *  separately. Such a quirk is currently missing for DT based
+	 *  systems. Hence please make sure that the smmu pcie node on
+	 *  hip06 is disabled as this will break the PCIe functionality
+	 *  when iommu-map entry is used along with the PCIe node.
+	 *  Refer:https://www.spinics.net/lists/arm-kernel/msg602812.html
+	 */
+	smmu0: smmu_pcie {
+		compatible = "arm,smmu-v3";
+		reg = <0x0 0xa0040000 0x0 0x20000>;
+		#iommu-cells = <1>;
+		dma-coherent;
+		smmu-cb-memtype = <0x0 0x1>;
+		hisilicon,broken-prefetch-cmd;
+		status = "disabled";
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -676,6 +708,30 @@
 				     <637 1>,<638 1>,<639 1>;
 			status = "disabled";
 		};
+
+		pcie0: pcie@a0090000 {
+			compatible = "hisilicon,hip06-pcie-ecam";
+			reg = <0 0xb0000000 0 0x2000000>,
+			      <0 0xa0090000 0 0x10000>;
+			bus-range = <0  31>;
+			msi-map = <0x0000 &its_dsa 0x0000 0x2000>;
+			msi-map-mask = <0xffff>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			dma-coherent;
+			ranges = <0x02000000 0 0xb2000000 0x0 0xb2000000 0
+				 0x5ff0000 0x01000000 0 0 0 0xb7ff0000
+				 0 0x10000>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0xf800 0 0 7>;
+			interrupt-map = <0x0 0 0 1 &mbigen_pcie0 650 4
+					0x0 0 0 2 &mbigen_pcie0 650 4
+					0x0 0 0 3 &mbigen_pcie0 650 4
+					0x0 0 0 4 &mbigen_pcie0 650 4>;
+			status = "disabled";
+		};
+
 	};
 
 };
diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
index 2c01a21..0600a6a 100644
--- a/arch/arm64/boot/dts/hisilicon/hip07.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
@@ -1083,6 +1083,31 @@
 		};
 	};
 
+	/**
+	 *  HiSilicon erratum 161010801: This describes the limitation
+	 *  of HiSilicon platforms hip06/hip07 to support the SMMUv3
+	 *  mappings for PCIe MSI transactions.
+	 *  PCIe controller on these platforms has to differentiate the
+	 *  MSI payload against other DMA payload and has to modify the
+	 *  MSI payload. This makes it difficult for these platforms to
+	 *  have a SMMU translation for MSI. In order to workaround this,
+	 *  ARM SMMUv3 driver requires a quirk to treat the MSI regions
+	 *  separately. Such a quirk is currently missing for DT based
+	 *  systems. Hence please make sure that the smmu pcie node on
+	 *  hip07 is disabled as this will break the PCIe functionality
+	 *  when iommu-map entry is used along with the PCIe node.
+	 *  Refer:https://www.spinics.net/lists/arm-kernel/msg602812.html
+	 */
+	smmu0: smmu_pcie {
+		compatible = "arm,smmu-v3";
+		reg = <0x0 0xa0040000 0x0 0x20000>;
+		#iommu-cells = <1>;
+		dma-coherent;
+		smmu-cb-memtype = <0x0 0x1>;
+		hisilicon,broken-prefetch-cmd;
+		status = "disabled";
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -1127,6 +1152,12 @@
 			reg = <0x0 0xc0000000 0x0 0x10000>;
 		};
 
+		dsa_cpld: dsa_cpld@78000010 {
+			compatible = "syscon";
+			reg = <0x0 0x78000010 0x0 0x100>;
+			reg-io-width = <2>;
+		};
+
 		pcie_subctl: pcie_subctl@a0000000 {
 			compatible = "hisilicon,pcie-sas-subctrl", "syscon";
 			reg = <0x0 0xa0000000 0x0 0x10000>;
@@ -1258,6 +1289,7 @@
 			port@0 {
 				reg = <0>;
 				serdes-syscon = <&serdes_ctrl>;
+				cpld-syscon = <&dsa_cpld 0x0>;
 				port-rst-offset = <0>;
 				port-mode-offset = <0>;
 				mc-mac-mask = [ff f0 00 00 00 00];
@@ -1267,6 +1299,7 @@
 			port@1 {
 				reg = <1>;
 				serdes-syscon= <&serdes_ctrl>;
+				cpld-syscon = <&dsa_cpld 0x4>;
 				port-rst-offset = <1>;
 				port-mode-offset = <1>;
 				mc-mac-mask = [ff f0 00 00 00 00];
diff --git a/arch/arm64/boot/dts/marvell/armada-371x.dtsi b/arch/arm64/boot/dts/marvell/armada-371x.dtsi
index 11226f7..dc1182e 100644
--- a/arch/arm64/boot/dts/marvell/armada-371x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-371x.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 371x family of SoCs
  * (also named 88F3710)
@@ -6,43 +7,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "armada-37xx.dtsi"
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index 0f3468e..f2cc005 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Marvell Armada 3720 development board
  * (DB-88F3720-DDR3)
@@ -5,44 +6,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- *
  * This file is compatible with the version 1.4 and the version 2.0 of
  * the board, however the CON numbers are different between the 2
  * version
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
index bdfb555..ef7fd2c 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
@@ -1,46 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Globalscale Marvell ESPRESSOBin Board
  * Copyright (C) 2016 Marvell
  *
  * Romain Perier <romain.perier@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Schematic available at http://espressobin.net/wp-content/uploads/2017/08/ESPRESSObin_V5_Schematics.pdf
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/marvell/armada-372x.dtsi b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
index 2554e0b..97558a6 100644
--- a/arch/arm64/boot/dts/marvell/armada-372x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 372x family of SoCs
  * (also named 88F3720)
@@ -6,43 +7,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "armada-37xx.dtsi"
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 3750268..97207a6 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Marvell Armada 37xx family of SoCs.
  *
@@ -5,43 +6,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
diff --git a/arch/arm64/boot/dts/marvell/armada-7020.dtsi b/arch/arm64/boot/dts/marvell/armada-7020.dtsi
index 4ab0129..4e46326 100644
--- a/arch/arm64/boot/dts/marvell/armada-7020.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-7020.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for the Armada 7020 SoC, made of an AP806 Dual and
  * one CP110.
  */
diff --git a/arch/arm64/boot/dts/marvell/armada-7040-db.dts b/arch/arm64/boot/dts/marvell/armada-7040-db.dts
index 3ae05ee..d6bec05 100644
--- a/arch/arm64/boot/dts/marvell/armada-7040-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-7040-db.dts
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada 7040 Development board platform
  */
 
@@ -162,36 +123,48 @@
 	};
 };
 
-&cp0_nand {
+&cp0_nand_controller {
 	/*
 	 * SPI on CPM and NAND have common pins on this board. We can
-	 * use only one at a time. To enable the NAND (whihch will
+	 * use only one at a time. To enable the NAND (which will
 	 * disable the SPI), the "status = "okay";" line have to be
 	 * added here.
 	 */
-	num-cs = <1>;
 	pinctrl-0 = <&nand_pins>, <&nand_rb>;
 	pinctrl-names = "default";
-	nand-ecc-strength = <4>;
-	nand-ecc-step-size = <512>;
-	marvell,nand-enable-arbiter;
-	nand-on-flash-bbt;
 
-	partition@0 {
-		label = "U-Boot";
-		reg = <0 0x200000>;
-	};
-	partition@200000 {
-		label = "Linux";
-		reg = <0x200000 0xe00000>;
-	};
-	partition@1000000 {
-		label = "Filesystem";
-		reg = <0x1000000 0x3f000000>;
+	nand@0 {
+		reg = <0>;
+		label = "pxa3xx_nand-0";
+		nand-rb = <0>;
+		nand-on-flash-bbt;
+		nand-ecc-strength = <4>;
+		nand-ecc-step-size = <512>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "U-Boot";
+				reg = <0 0x200000>;
+			};
+
+			partition@200000 {
+				label = "Linux";
+				reg = <0x200000 0xe00000>;
+			};
+
+			partition@1000000 {
+				label = "Filesystem";
+				reg = <0x1000000 0x3f000000>;
+			};
+
+		};
 	};
 };
 
-
 &cp0_spi1 {
 	status = "okay";
 
diff --git a/arch/arm64/boot/dts/marvell/armada-7040.dtsi b/arch/arm64/boot/dts/marvell/armada-7040.dtsi
index cbe460b..4724721 100644
--- a/arch/arm64/boot/dts/marvell/armada-7040.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-7040.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for the Armada 7040 SoC, made of an AP806 Quad and
  * one CP110.
  */
diff --git a/arch/arm64/boot/dts/marvell/armada-70x0.dtsi b/arch/arm64/boot/dts/marvell/armada-70x0.dtsi
index f63b4fb..e5c6d7c 100644
--- a/arch/arm64/boot/dts/marvell/armada-70x0.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-70x0.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2017 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for the Armada 70x0 SoC
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-8020.dtsi b/arch/arm64/boot/dts/marvell/armada-8020.dtsi
index 3318d6b..ba1307c 100644
--- a/arch/arm64/boot/dts/marvell/armada-8020.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-8020.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for the Armada 8020 SoC, made of an AP806 Dual and
  * two CP110.
  */
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-db.dts b/arch/arm64/boot/dts/marvell/armada-8040-db.dts
index dba55ba..5689fb2 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-db.dts
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada 8040 Development board platform
  */
 
@@ -279,27 +240,35 @@
  * Proper NAND usage will require DPR-76 to be in position 1-2, which disables
  * MDIO signal of CP1.
  */
-&cp1_nand {
-	num-cs = <1>;
+&cp1_nand_controller {
 	pinctrl-0 = <&nand_pins>, <&nand_rb>;
 	pinctrl-names = "default";
-	nand-ecc-strength = <4>;
-	nand-ecc-step-size = <512>;
-	marvell,nand-enable-arbiter;
-	marvell,system-controller = <&cp1_syscon0>;
-	nand-on-flash-bbt;
 
-	partition@0 {
-		label = "U-Boot";
-		reg = <0 0x200000>;
-	};
-	partition@200000 {
-		label = "Linux";
-		reg = <0x200000 0xe00000>;
-	};
-	partition@1000000 {
-		label = "Filesystem";
-		reg = <0x1000000 0x3f000000>;
+	nand@0 {
+		reg = <0>;
+		nand-rb = <0>;
+		nand-on-flash-bbt;
+		nand-ecc-strength = <4>;
+		nand-ecc-step-size = <512>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "U-Boot";
+				reg = <0 0x200000>;
+			};
+			partition@200000 {
+				label = "Linux";
+				reg = <0x200000 0xe00000>;
+			};
+			partition@1000000 {
+				label = "Filesystem";
+				reg = <0x1000000 0x3f000000>;
+			};
+		};
 	};
 };
 
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
index 626e9d0..81de03e 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for MACCHIATOBin Armada 8040 community board platform
  */
 
@@ -49,7 +10,7 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
-	model = "Marvell 8040 MACHIATOBin";
+	model = "Marvell 8040 MACCHIATOBin";
 	compatible = "marvell,armada8040-mcbin", "marvell,armada8040",
 			"marvell,armada-ap806-quad", "marvell,armada-ap806";
 
@@ -163,6 +124,13 @@
 	};
 };
 
+/* J25 UART header */
+&cp0_uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&cp0_uart1_pins>;
+	status = "okay";
+};
+
 &cp0_mdio {
 	pinctrl-names = "default";
 	pinctrl-0 = <&cp0_ge_mdio_pins>;
@@ -195,6 +163,10 @@
 		marvell,pins = "mpp37", "mpp38";
 		marvell,function = "i2c0";
 	};
+	cp0_uart1_pins: uart1-pins {
+		marvell,pins = "mpp40", "mpp41";
+		marvell,function = "uart1";
+	};
 	cp0_xhci_vbus_pins: xhci0-vbus-pins {
 		marvell,pins = "mpp47";
 		marvell,function = "gpio";
@@ -290,6 +262,17 @@
 		marvell,pins = "mpp12", "mpp13", "mpp14", "mpp15", "mpp16";
 		marvell,function = "spi1";
 	};
+	cp1_uart0_pins: uart0-pins {
+		marvell,pins = "mpp6", "mpp7";
+		marvell,function = "uart0";
+	};
+};
+
+/* J27 UART header */
+&cp1_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&cp1_uart0_pins>;
+	status = "okay";
 };
 
 &cp1_sata0 {
diff --git a/arch/arm64/boot/dts/marvell/armada-8040.dtsi b/arch/arm64/boot/dts/marvell/armada-8040.dtsi
index 83d2b40..7699b19 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-8040.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for the Armada 8040 SoC, made of an AP806 Quad and
  * two CP110.
  */
diff --git a/arch/arm64/boot/dts/marvell/armada-8080-db.dts b/arch/arm64/boot/dts/marvell/armada-8080-db.dts
index 85b58a1..4ba158f 100644
--- a/arch/arm64/boot/dts/marvell/armada-8080-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8080-db.dts
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2017 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada-8080 Development board platform
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-8080.dtsi b/arch/arm64/boot/dts/marvell/armada-8080.dtsi
index d5535b7..299e814 100644
--- a/arch/arm64/boot/dts/marvell/armada-8080.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-8080.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2017 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada-8080 SoC, made of an AP810 OCTA.
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-80x0.dtsi b/arch/arm64/boot/dts/marvell/armada-80x0.dtsi
index e9c84a1..8129b40 100644
--- a/arch/arm64/boot/dts/marvell/armada-80x0.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-80x0.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2017 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for the Armada 80x0 SoC family
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi
index b98ea13..64b5e61 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada AP806.
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
index 116164f..746e792 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada AP806.
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index f9b66b8..176e38d 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada AP806.
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi b/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi
index 7f0661e..7d00ae7 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2017 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada AP810 OCTA cores.
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi b/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi
index 7e6f039..8107d12 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi
@@ -1,46 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2017 Marvell Technology Group Ltd.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
  * Device Tree file for Marvell Armada AP810.
  */
 
diff --git a/arch/arm64/boot/dts/marvell/armada-common.dtsi b/arch/arm64/boot/dts/marvell/armada-common.dtsi
index c6dd1d8..d5e8aed 100644
--- a/arch/arm64/boot/dts/marvell/armada-common.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-common.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR X11)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
  */
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
index a8af413..48cad79 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
@@ -1,9 +1,7 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR X11)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Marvell Technology Group Ltd.
- */
-
-/*
+ *
  * Device Tree file for Marvell Armada CP110.
  */
 
@@ -213,7 +211,9 @@
 			reg = <0x500000 0x4000>;
 			dma-coherent;
 			interrupts = <ICU_GRP_NSR 106 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&CP110_LABEL(clk) 1 22>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 22>,
+				 <&CP110_LABEL(clk) 1 16>;
 			status = "disabled";
 		};
 
@@ -223,7 +223,9 @@
 			reg = <0x510000 0x4000>;
 			dma-coherent;
 			interrupts = <ICU_GRP_NSR 105 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&CP110_LABEL(clk) 1 23>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 23>,
+				 <&CP110_LABEL(clk) 1 16>;
 			status = "disabled";
 		};
 
@@ -232,7 +234,8 @@
 			"generic-ahci";
 			reg = <0x540000 0x30000>;
 			interrupts = <ICU_GRP_NSR 107 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&CP110_LABEL(clk) 1 15>;
+			clocks = <&CP110_LABEL(clk) 1 15>,
+				 <&CP110_LABEL(clk) 1 16>;
 			status = "disabled";
 		};
 
@@ -241,7 +244,9 @@
 			reg = <0x6a0000 0x1000>, <0x6b0000 0x1000>;
 			dma-coherent;
 			msi-parent = <&gic_v2m0>;
-			clocks = <&CP110_LABEL(clk) 1 8>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 8>,
+				 <&CP110_LABEL(clk) 1 14>;
 		};
 
 		CP110_LABEL(xor1): xor@6c0000 {
@@ -249,7 +254,9 @@
 			reg = <0x6c0000 0x1000>, <0x6d0000 0x1000>;
 			dma-coherent;
 			msi-parent = <&gic_v2m0>;
-			clocks = <&CP110_LABEL(clk) 1 7>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 7>,
+				 <&CP110_LABEL(clk) 1 14>;
 		};
 
 		CP110_LABEL(spi0): spi@700600 {
@@ -257,7 +264,9 @@
 			reg = <0x700600 0x50>;
 			#address-cells = <0x1>;
 			#size-cells = <0x0>;
-			clocks = <&CP110_LABEL(clk) 1 21>;
+			clock-names = "core", "axi";
+			clocks = <&CP110_LABEL(clk) 1 21>,
+				 <&CP110_LABEL(clk) 1 17>;
 			status = "disabled";
 		};
 
@@ -266,7 +275,9 @@
 			reg = <0x700680 0x50>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			clocks = <&CP110_LABEL(clk) 1 21>;
+			clock-names = "core", "axi";
+			clocks = <&CP110_LABEL(clk) 1 21>,
+				 <&CP110_LABEL(clk) 1 17>;
 			status = "disabled";
 		};
 
@@ -276,7 +287,9 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			interrupts = <ICU_GRP_NSR 120 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&CP110_LABEL(clk) 1 21>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 21>,
+				 <&CP110_LABEL(clk) 1 17>;
 			status = "disabled";
 		};
 
@@ -286,23 +299,75 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			interrupts = <ICU_GRP_NSR 121 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&CP110_LABEL(clk) 1 21>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 21>,
+				 <&CP110_LABEL(clk) 1 17>;
 			status = "disabled";
 		};
 
-		CP110_LABEL(nand): nand@720000 {
+		CP110_LABEL(uart0): serial@702000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x702000 0x100>;
+			reg-shift = <2>;
+			interrupts = <ICU_GRP_NSR 122 IRQ_TYPE_LEVEL_HIGH>;
+			reg-io-width = <1>;
+			clock-names = "baudclk", "apb_pclk";
+			clocks = <&CP110_LABEL(clk) 1 21>,
+				 <&CP110_LABEL(clk) 1 17>;
+			status = "disabled";
+		};
+
+		CP110_LABEL(uart1): serial@702100 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x702100 0x100>;
+			reg-shift = <2>;
+			interrupts = <ICU_GRP_NSR 123 IRQ_TYPE_LEVEL_HIGH>;
+			reg-io-width = <1>;
+			clock-names = "baudclk", "apb_pclk";
+			clocks = <&CP110_LABEL(clk) 1 21>,
+				 <&CP110_LABEL(clk) 1 17>;
+			status = "disabled";
+		};
+
+		CP110_LABEL(uart2): serial@702200 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x702200 0x100>;
+			reg-shift = <2>;
+			interrupts = <ICU_GRP_NSR 124 IRQ_TYPE_LEVEL_HIGH>;
+			reg-io-width = <1>;
+			clock-names = "baudclk", "apb_pclk";
+			clocks = <&CP110_LABEL(clk) 1 21>,
+				 <&CP110_LABEL(clk) 1 17>;
+			status = "disabled";
+		};
+
+		CP110_LABEL(uart3): serial@702300 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x702300 0x100>;
+			reg-shift = <2>;
+			interrupts = <ICU_GRP_NSR 125 IRQ_TYPE_LEVEL_HIGH>;
+			reg-io-width = <1>;
+			clock-names = "baudclk", "apb_pclk";
+			clocks = <&CP110_LABEL(clk) 1 21>,
+				 <&CP110_LABEL(clk) 1 17>;
+			status = "disabled";
+		};
+
+		CP110_LABEL(nand_controller): nand@720000 {
 			/*
 			* Due to the limitation of the pins available
 			* this controller is only usable on the CPM
 			* for A7K and on the CPS for A8K.
 			*/
-			compatible = "marvell,armada-8k-nand",
-			"marvell,armada370-nand";
+			compatible = "marvell,armada-8k-nand-controller",
+				"marvell,armada370-nand-controller";
 			reg = <0x720000 0x54>;
 			#address-cells = <1>;
-			#size-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <ICU_GRP_NSR 115 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&CP110_LABEL(clk) 1 2>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 2>,
+				 <&CP110_LABEL(clk) 1 17>;
 			marvell,system-controller = <&CP110_LABEL(syscon0)>;
 			status = "disabled";
 		};
@@ -312,7 +377,9 @@
 			"inside-secure,safexcel-eip76";
 			reg = <0x760000 0x7d>;
 			interrupts = <ICU_GRP_NSR 95 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&CP110_LABEL(clk) 1 25>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 25>,
+				 <&CP110_LABEL(clk) 1 17>;
 			status = "okay";
 		};
 
@@ -337,7 +404,9 @@
 				<ICU_GRP_NSR 92 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "mem", "ring0", "ring1",
 				"ring2", "ring3", "eip";
-			clocks = <&CP110_LABEL(clk) 1 26>;
+			clock-names = "core", "reg";
+			clocks = <&CP110_LABEL(clk) 1 26>,
+				 <&CP110_LABEL(clk) 1 17>;
 			dma-coherent;
 		};
 	};
@@ -364,7 +433,8 @@
 		interrupt-map = <0 0 0 0 &CP110_LABEL(icu) ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
 		interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
 		num-lanes = <1>;
-		clocks = <&CP110_LABEL(clk) 1 13>;
+		clock-names = "core", "reg";
+		clocks = <&CP110_LABEL(clk) 1 13>, <&CP110_LABEL(clk) 1 14>;
 		status = "disabled";
 	};
 
@@ -391,7 +461,8 @@
 		interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
 
 		num-lanes = <1>;
-		clocks = <&CP110_LABEL(clk) 1 11>;
+		clock-names = "core", "reg";
+		clocks = <&CP110_LABEL(clk) 1 11>, <&CP110_LABEL(clk) 1 14>;
 		status = "disabled";
 	};
 
@@ -418,7 +489,8 @@
 		interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
 
 		num-lanes = <1>;
-		clocks = <&CP110_LABEL(clk) 1 12>;
+		clock-names = "core", "reg";
+		clocks = <&CP110_LABEL(clk) 1 12>, <&CP110_LABEL(clk) 1 14>;
 		status = "disabled";
 	};
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
index 10f9c76..4ce9d6c 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -41,6 +41,10 @@
 
 };
 
+&auxadc {
+	status = "okay";
+};
+
 &cpu0 {
 	proc-supply = <&cpus_fixed_vproc0>;
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index fdf66f4..9d88f41 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -289,6 +289,15 @@
 			 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
+	auxadc: adc@11001000 {
+		compatible = "mediatek,mt2712-auxadc";
+		reg = <0 0x11001000 0 0x1000>;
+		clocks = <&pericfg CLK_PERI_AUXADC>;
+		clock-names = "main";
+		#io-channel-cells = <1>;
+		status = "disabled";
+	};
+
 	uart0: serial@11002000 {
 		compatible = "mediatek,mt2712-uart",
 			     "mediatek,mt6577-uart";
diff --git a/arch/arm64/boot/dts/mediatek/mt6380.dtsi b/arch/arm64/boot/dts/mediatek/mt6380.dtsi
new file mode 100644
index 0000000..53b335d
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6380.dtsi
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for MediaTek MT6380 regulator
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Chenglin Xu <chenglin.xu@mediatek.com>
+ *	   Sean Wang <sean.wang@mediatek.com>
+ */
+
+&pwrap {
+	regulators {
+		compatible = "mediatek,mt6380-regulator";
+
+		mt6380_vcpu_reg: buck-vcore1 {
+			regulator-name = "vcore1";
+			regulator-min-microvolt = < 600000>;
+			regulator-max-microvolt = <1393750>;
+			regulator-ramp-delay = <6250>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vcore_reg: buck-vcore {
+			regulator-name = "vcore";
+			regulator-min-microvolt = <600000>;
+			regulator-max-microvolt = <1393750>;
+			regulator-ramp-delay = <6250>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vrf_reg: buck-vrf {
+			regulator-name = "vrf";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1575000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vm_reg: ldo-vm {
+			regulator-name = "vm";
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1400000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_va_reg: ldo-va {
+			regulator-name = "va";
+			regulator-min-microvolt = <2200000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vphy_reg: ldo-vphy {
+			regulator-name = "vphy";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vddr_reg: ldo-vddr {
+			regulator-name = "vddr";
+			regulator-min-microvolt = <1240000>;
+			regulator-max-microvolt = <1840000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		mt6380_vt_reg: ldo-vt {
+			regulator-name = "vt";
+			regulator-min-microvolt = <2200000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-ramp-delay = <0>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index c08309d..45d8655 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -7,7 +7,11 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
 #include "mt7622.dtsi"
+#include "mt6380.dtsi"
 
 / {
 	model = "MediaTek MT7622 RFB1 board";
@@ -17,11 +21,476 @@
 		bootargs = "console=ttyS0,115200n1";
 	};
 
+	cpus {
+		cpu@0 {
+			proc-supply = <&mt6380_vcpu_reg>;
+			sram-supply = <&mt6380_vm_reg>;
+		};
+
+		cpu@1 {
+			proc-supply = <&mt6380_vcpu_reg>;
+			sram-supply = <&mt6380_vm_reg>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		factory {
+			label = "factory";
+			linux,code = <BTN_0>;
+			gpios = <&pio 0 0>;
+		};
+
+		wps {
+			label = "wps";
+			linux,code = <KEY_WPS_BUTTON>;
+			gpios = <&pio 102 0>;
+		};
+	};
+
 	memory {
 		reg = <0 0x40000000 0 0x3F000000>;
 	};
+
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_5v: regulator-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins>;
+	status = "okay";
+
+	pcie@0,0 {
+		status = "okay";
+	};
+};
+
+&pio {
+	/* eMMC is shared pin with parallel NAND */
+	emmc_pins_default: emmc-pins-default {
+		mux {
+			function = "emmc", "emmc_rst";
+			groups = "emmc";
+		};
+
+		/* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7",
+		 * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4,
+		 * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively
+		 */
+		conf-cmd-dat {
+			pins = "NDL0", "NDL1", "NDL2",
+			       "NDL3", "NDL4", "NDL5",
+			       "NDL6", "NDL7", "NRB";
+			input-enable;
+			bias-pull-up;
+		};
+
+		conf-clk {
+			pins = "NCLE";
+			bias-pull-down;
+		};
+	};
+
+	emmc_pins_uhs: emmc-pins-uhs {
+		mux {
+			function = "emmc";
+			groups = "emmc";
+		};
+
+		conf-cmd-dat {
+			pins = "NDL0", "NDL1", "NDL2",
+			       "NDL3", "NDL4", "NDL5",
+			       "NDL6", "NDL7", "NRB";
+			input-enable;
+			drive-strength = <4>;
+			bias-pull-up;
+		};
+
+		conf-clk {
+			pins = "NCLE";
+			drive-strength = <4>;
+			bias-pull-down;
+		};
+	};
+
+	eth_pins: eth-pins {
+		mux {
+			function = "eth";
+			groups = "mdc_mdio", "rgmii_via_gmac2";
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		mux {
+			function = "i2c";
+			groups =  "i2c1_0";
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		mux {
+			function = "i2c";
+			groups =  "i2c2_0";
+		};
+	};
+
+	i2s1_pins: i2s1-pins {
+		mux {
+			function = "i2s";
+			groups =  "i2s_out_bclk_ws_mclk",
+				  "i2s1_in_data",
+				  "i2s1_out_data";
+		};
+	};
+
+	irrx_pins: irrx-pins {
+		mux {
+			function = "ir";
+			groups =  "ir_1_rx";
+		};
+	};
+
+	irtx_pins: irtx-pins {
+		mux {
+			function = "ir";
+			groups =  "ir_1_tx";
+		};
+	};
+
+	/* Parallel nand is shared pin with eMMC */
+	parallel_nand_pins: parallel-nand-pins {
+		mux {
+			function = "flash";
+			groups = "par_nand";
+		};
+	};
+
+	pcie0_pins: pcie0-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie0_pad_perst",
+				 "pcie0_1_waken",
+				 "pcie0_1_clkreq";
+		};
+	};
+
+	pcie1_pins: pcie1-pins {
+		mux {
+			function = "pcie";
+			groups = "pcie1_pad_perst",
+				 "pcie1_0_waken",
+				 "pcie1_0_clkreq";
+		};
+	};
+
+	pmic_bus_pins: pmic-bus-pins {
+		mux {
+			function = "pmic";
+			groups = "pmic_bus";
+		};
+	};
+
+	pwm7_pins: pwm1-2-pins {
+		mux {
+			function = "pwm";
+			groups = "pwm_ch7_2";
+		};
+	};
+
+	wled_pins: wled-pins {
+		mux {
+			function = "led";
+			groups = "wled";
+		};
+	};
+
+	sd0_pins_default: sd0-pins-default {
+		mux {
+			function = "sd";
+			groups = "sd_0";
+		};
+
+		/* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN",
+		 *  "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1,
+		 *  DAT2, DAT3, CMD, CLK for SD respectively.
+		 */
+		conf-cmd-data {
+			pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN",
+			       "I2S2_IN","I2S4_OUT";
+			input-enable;
+			drive-strength = <8>;
+			bias-pull-up;
+		};
+		conf-clk {
+			pins = "I2S3_OUT";
+			drive-strength = <12>;
+			bias-pull-down;
+		};
+		conf-cd {
+			pins = "TXD3";
+			bias-pull-up;
+		};
+	};
+
+	sd0_pins_uhs: sd0-pins-uhs {
+		mux {
+			function = "sd";
+			groups = "sd_0";
+		};
+
+		conf-cmd-data {
+			pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN",
+			       "I2S2_IN","I2S4_OUT";
+			input-enable;
+			bias-pull-up;
+		};
+
+		conf-clk {
+			pins = "I2S3_OUT";
+			bias-pull-down;
+		};
+	};
+
+	/* Serial NAND is shared pin with SPI-NOR */
+	serial_nand_pins: serial-nand-pins {
+		mux {
+			function = "flash";
+			groups = "snfi";
+		};
+	};
+
+	spic0_pins: spic0-pins {
+		mux {
+			function = "spi";
+			groups = "spic0_0";
+		};
+	};
+
+	spic1_pins: spic1-pins {
+		mux {
+			function = "spi";
+			groups = "spic1_0";
+		};
+	};
+
+	/* SPI-NOR is shared pin with serial NAND */
+	spi_nor_pins: spi-nor-pins {
+		mux {
+			function = "flash";
+			groups = "spi_nor";
+		};
+	};
+
+	/* serial NAND is shared pin with SPI-NOR */
+	serial_nand_pins: serial-nand-pins {
+		mux {
+			function = "flash";
+			groups = "snfi";
+		};
+	};
+
+	uart0_pins: uart0-pins {
+		mux {
+			function = "uart";
+			groups = "uart0_0_tx_rx" ;
+		};
+	};
+
+	uart2_pins: uart2-pins {
+		mux {
+			function = "uart";
+			groups = "uart2_1_tx_rx" ;
+		};
+	};
+
+	watchdog_pins: watchdog-pins {
+		mux {
+			function = "watchdog";
+			groups = "watchdog";
+		};
+	};
+};
+
+&bch {
+	status = "disabled";
+};
+
+&btif {
+	status = "okay";
+};
+
+&cir {
+	pinctrl-names = "default";
+	pinctrl-0 = <&irrx_pins>;
+	status = "okay";
+};
+
+&eth {
+	pinctrl-names = "default";
+	pinctrl-0 = <&eth_pins>;
+	status = "okay";
+
+	gmac1: mac@1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		phy-handle = <&phy5>;
+	};
+
+	mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "sgmii";
+		};
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+	status = "okay";
+};
+
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&emmc_pins_default>;
+	pinctrl-1 = <&emmc_pins_uhs>;
+	status = "okay";
+	bus-width = <8>;
+	max-frequency = <50000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_1p8v>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
+	non-removable;
+};
+
+&mmc1 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&sd0_pins_default>;
+	pinctrl-1 = <&sd0_pins_uhs>;
+	status = "okay";
+	bus-width = <4>;
+	max-frequency = <50000000>;
+	cap-sd-highspeed;
+	r_smpl = <1>;
+	cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
+};
+
+&nandc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&parallel_nand_pins>;
+	status = "disabled";
+};
+
+&nor_flash {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_nor_pins>;
+	status = "disabled";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm7_pins>;
+	status = "okay";
+};
+
+&pwrap {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmic_bus_pins>;
+
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+};
+
+&sata_phy {
+	status = "okay";
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spic0_pins>;
+	status = "okay";
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spic1_pins>;
+	status = "okay";
+};
+
+&ssusb {
+	vusb33-supply = <&reg_3p3v>;
+	vbus-supply = <&reg_5v>;
+	status = "okay";
+};
+
+&u3phy {
+	status = "okay";
 };
 
 &uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+	status = "okay";
+};
+
+&watchdog {
+	pinctrl-names = "default";
+	pinctrl-0 = <&watchdog_pins>;
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index b111fec..e9d5130 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -8,6 +8,11 @@
 
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt7622-clk.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/power/mt7622-power.h>
+#include <dt-bindings/reset/mt7622-reset.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	compatible = "mediatek,mt7622";
@@ -15,6 +20,50 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	cpu_opp_table: opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+		opp-300000000 {
+			opp-hz = /bits/ 64 <30000000>;
+			opp-microvolt = <950000>;
+		};
+
+		opp-437500000 {
+			opp-hz = /bits/ 64 <437500000>;
+			opp-microvolt = <1000000>;
+		};
+
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <1050000>;
+		};
+
+		opp-812500000 {
+			opp-hz = /bits/ 64 <812500000>;
+			opp-microvolt = <1100000>;
+		};
+
+		opp-1025000000 {
+			opp-hz = /bits/ 64 <1025000000>;
+			opp-microvolt = <1150000>;
+		};
+
+		opp-1137500000 {
+			opp-hz = /bits/ 64 <1137500000>;
+			opp-microvolt = <1200000>;
+		};
+
+		opp-1262500000 {
+			opp-hz = /bits/ 64 <1262500000>;
+			opp-microvolt = <1250000>;
+		};
+
+		opp-1350000000 {
+			opp-hz = /bits/ 64 <1350000000>;
+			opp-microvolt = <1310000>;
+		};
+	};
+
 	cpus {
 		#address-cells = <2>;
 		#size-cells = <0>;
@@ -23,6 +72,11 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0x0 0x0>;
+			clocks = <&infracfg CLK_INFRA_MUX1_SEL>,
+				 <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cpu_opp_table>;
+			#cooling-cells = <2>;
 			enable-method = "psci";
 			clock-frequency = <1300000000>;
 		};
@@ -31,21 +85,26 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0x0 0x1>;
+			clocks = <&infracfg CLK_INFRA_MUX1_SEL>,
+				 <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cpu_opp_table>;
 			enable-method = "psci";
 			clock-frequency = <1300000000>;
 		};
 	};
 
-	uart_clk: dummy25m {
+	pwrap_clk: dummy40m {
+		compatible = "fixed-clock";
+		clock-frequency = <40000000>;
+		#clock-cells = <0>;
+	};
+
+	clk25m: oscillator {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <25000000>;
-	};
-
-	bus_clk: dummy280m {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <280000000>;
+		clock-output-names = "clkxtal";
 	};
 
 	psci {
@@ -65,6 +124,58 @@
 		};
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&thermal 0>;
+
+			trips {
+				cpu_passive: cpu-passive {
+					temperature = <47000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				cpu_active: cpu-active {
+					temperature = <67000>;
+					hysteresis = <2000>;
+					type = "active";
+				};
+
+				cpu_hot: cpu-hot {
+					temperature = <87000>;
+					hysteresis = <2000>;
+					type = "hot";
+				};
+
+				cpu-crit {
+					temperature = <107000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_passive>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+
+				map1 {
+					trip = <&cpu_active>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+
+				map2 {
+					trip = <&cpu_hot>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
@@ -78,6 +189,58 @@
 			      IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
+	infracfg: infracfg@10000000 {
+		compatible = "mediatek,mt7622-infracfg",
+			     "syscon";
+		reg = <0 0x10000000 0 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	pwrap: pwrap@10001000 {
+		compatible = "mediatek,mt7622-pwrap";
+		reg = <0 0x10001000 0 0x250>;
+		reg-names = "pwrap";
+		clocks = <&infracfg CLK_INFRA_PMIC_PD>, <&pwrap_clk>;
+		clock-names = "spi", "wrap";
+		resets = <&infracfg MT7622_INFRA_PMIC_WRAP_RST>;
+		reset-names = "pwrap";
+		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	pericfg: pericfg@10002000 {
+		compatible = "mediatek,mt7622-pericfg",
+			     "syscon";
+		reg = <0 0x10002000 0 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	scpsys: scpsys@10006000 {
+		compatible = "mediatek,mt7622-scpsys",
+			     "syscon";
+		#power-domain-cells = <1>;
+		reg = <0 0x10006000 0 0x1000>;
+		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 166 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 167 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 168 IRQ_TYPE_LEVEL_LOW>;
+		infracfg = <&infracfg>;
+		clocks = <&topckgen CLK_TOP_HIF_SEL>;
+		clock-names = "hif_sel";
+	};
+
+	cir: cir@10009000 {
+		compatible = "mediatek,mt7622-cir";
+		reg = <0 0x10009000 0 0x1000>;
+		interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&infracfg CLK_INFRA_IRRX_PD>,
+			 <&topckgen CLK_TOP_AXI_SEL>;
+		clock-names = "clk", "bus";
+		status = "disabled";
+	};
+
 	sysirq: interrupt-controller@10200620 {
 		compatible = "mediatek,mt7622-sysirq",
 			     "mediatek,mt6577-sysirq";
@@ -87,6 +250,62 @@
 		reg = <0 0x10200620 0 0x20>;
 	};
 
+	efuse: efuse@10206000 {
+		compatible = "mediatek,mt7622-efuse",
+			     "mediatek,efuse";
+		reg = <0 0x10206000 0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		thermal_calibration: calib@198 {
+			reg = <0x198 0xc>;
+		};
+	};
+
+	apmixedsys: apmixedsys@10209000 {
+		compatible = "mediatek,mt7622-apmixedsys",
+			     "syscon";
+		reg = <0 0x10209000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	topckgen: topckgen@10210000 {
+		compatible = "mediatek,mt7622-topckgen",
+			     "syscon";
+		reg = <0 0x10210000 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	rng: rng@1020f000 {
+		compatible = "mediatek,mt7622-rng",
+			     "mediatek,mt7623-rng";
+		reg = <0 0x1020f000 0 0x1000>;
+		clocks = <&infracfg CLK_INFRA_TRNG>;
+		clock-names = "rng";
+	};
+
+	pio: pinctrl@10211000 {
+		compatible = "mediatek,mt7622-pinctrl";
+		reg = <0 0x10211000 0 0x1000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	watchdog: watchdog@10212000 {
+		compatible = "mediatek,mt7622-wdt",
+			     "mediatek,mt6589-wdt";
+		reg = <0 0x10212000 0 0x800>;
+	};
+
+	rtc: rtc@10212800 {
+		compatible = "mediatek,mt7622-rtc",
+			     "mediatek,soc-rtc";
+		reg = <0 0x10212800 0 0x200>;
+		interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_RTC>;
+		clock-names = "rtc";
+	};
+
 	gic: interrupt-controller@10300000 {
 		compatible = "arm,gic-400";
 		interrupt-controller;
@@ -98,13 +317,459 @@
 		      <0 0x10360000 0 0x2000>;
 	};
 
+	auxadc: adc@11001000 {
+		compatible = "mediatek,mt7622-auxadc";
+		reg = <0 0x11001000 0 0x1000>;
+		clocks = <&pericfg CLK_PERI_AUXADC_PD>;
+		clock-names = "main";
+		#io-channel-cells = <1>;
+	};
+
 	uart0: serial@11002000 {
 		compatible = "mediatek,mt7622-uart",
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11002000 0 0x400>;
 		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&uart_clk>, <&bus_clk>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART1_PD>;
 		clock-names = "baud", "bus";
 		status = "disabled";
 	};
+
+	uart1: serial@11003000 {
+		compatible = "mediatek,mt7622-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11003000 0 0x400>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART1_PD>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	uart2: serial@11004000 {
+		compatible = "mediatek,mt7622-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11004000 0 0x400>;
+		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART2_PD>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	uart3: serial@11005000 {
+		compatible = "mediatek,mt7622-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11005000 0 0x400>;
+		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART3_PD>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	pwm: pwm@11006000 {
+		compatible = "mediatek,mt7622-pwm";
+		reg = <0 0x11006000 0 0x1000>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_PWM_SEL>,
+			 <&pericfg CLK_PERI_PWM_PD>,
+			 <&pericfg CLK_PERI_PWM1_PD>,
+			 <&pericfg CLK_PERI_PWM2_PD>,
+			 <&pericfg CLK_PERI_PWM3_PD>,
+			 <&pericfg CLK_PERI_PWM4_PD>,
+			 <&pericfg CLK_PERI_PWM5_PD>,
+			 <&pericfg CLK_PERI_PWM6_PD>;
+		clock-names = "top", "main", "pwm1", "pwm2", "pwm3", "pwm4",
+			      "pwm5", "pwm6";
+		status = "disabled";
+	};
+
+	i2c0: i2c@11007000 {
+		compatible = "mediatek,mt7622-i2c";
+		reg = <0 0x11007000 0 0x90>,
+		      <0 0x11000100 0 0x80>;
+		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>;
+		clock-div = <16>;
+		clocks = <&pericfg CLK_PERI_I2C0_PD>,
+			 <&pericfg CLK_PERI_AP_DMA_PD>;
+		clock-names = "main", "dma";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c1: i2c@11008000 {
+		compatible = "mediatek,mt7622-i2c";
+		reg = <0 0x11008000 0 0x90>,
+		      <0 0x11000180 0 0x80>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_LOW>;
+		clock-div = <16>;
+		clocks = <&pericfg CLK_PERI_I2C1_PD>,
+			 <&pericfg CLK_PERI_AP_DMA_PD>;
+		clock-names = "main", "dma";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c2: i2c@11009000 {
+		compatible = "mediatek,mt7622-i2c";
+		reg = <0 0x11009000 0 0x90>,
+		      <0 0x11000200 0 0x80>;
+		interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>;
+		clock-div = <16>;
+		clocks = <&pericfg CLK_PERI_I2C2_PD>,
+			 <&pericfg CLK_PERI_AP_DMA_PD>;
+		clock-names = "main", "dma";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi0: spi@1100a000 {
+		compatible = "mediatek,mt7622-spi";
+		reg = <0 0x1100a000 0 0x100>;
+		interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+			 <&topckgen CLK_TOP_SPI0_SEL>,
+			 <&pericfg CLK_PERI_SPI0_PD>;
+		clock-names = "parent-clk", "sel-clk", "spi-clk";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	thermal: thermal@1100b000 {
+		#thermal-sensor-cells = <1>;
+		compatible = "mediatek,mt7622-thermal";
+		reg = <0 0x1100b000 0 0x1000>;
+		interrupts = <0 78 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_THERM_PD>,
+			 <&pericfg CLK_PERI_AUXADC_PD>;
+		clock-names = "therm", "auxadc";
+		resets = <&pericfg MT7622_PERI_THERM_SW_RST>;
+		reset-names = "therm";
+		mediatek,auxadc = <&auxadc>;
+		mediatek,apmixedsys = <&apmixedsys>;
+		nvmem-cells = <&thermal_calibration>;
+		nvmem-cell-names = "calibration-data";
+	};
+
+	btif: serial@1100c000 {
+		compatible = "mediatek,mt7622-btif",
+			     "mediatek,mtk-btif";
+		reg = <0 0x1100c000 0 0x1000>;
+		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_BTIF_PD>;
+		clock-names = "main";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		status = "disabled";
+	};
+
+	nandc: nfi@1100d000 {
+		compatible = "mediatek,mt7622-nfc";
+		reg = <0 0x1100D000 0 0x1000>;
+		interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_NFI_PD>,
+			 <&pericfg CLK_PERI_SNFI_PD>;
+		clock-names = "nfi_clk", "pad_clk";
+		ecc-engine = <&bch>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	bch: ecc@1100e000 {
+		compatible = "mediatek,mt7622-ecc";
+		reg = <0 0x1100e000 0 0x1000>;
+		interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_NFIECC_PD>;
+		clock-names = "nfiecc_clk";
+		status = "disabled";
+	};
+
+	nor_flash: spi@11014000 {
+		compatible = "mediatek,mt7622-nor",
+			     "mediatek,mt8173-nor";
+		reg = <0 0x11014000 0 0xe0>;
+		clocks = <&pericfg CLK_PERI_FLASH_PD>,
+			 <&topckgen CLK_TOP_FLASH_SEL>;
+		clock-names = "spi", "sf";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi1: spi@11016000 {
+		compatible = "mediatek,mt7622-spi";
+		reg = <0 0x11016000 0 0x100>;
+		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+			 <&topckgen CLK_TOP_SPI1_SEL>,
+			 <&pericfg CLK_PERI_SPI1_PD>;
+		clock-names = "parent-clk", "sel-clk", "spi-clk";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	uart4: serial@11019000 {
+		compatible = "mediatek,mt7622-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11019000 0 0x400>;
+		interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_UART_SEL>,
+			 <&pericfg CLK_PERI_UART4_PD>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	mmc0: mmc@11230000 {
+		compatible = "mediatek,mt7622-mmc";
+		reg = <0 0x11230000 0 0x1000>;
+		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_MSDC30_0_PD>,
+			 <&topckgen CLK_TOP_MSDC50_0_SEL>;
+		clock-names = "source", "hclk";
+		status = "disabled";
+	};
+
+	mmc1: mmc@11240000 {
+		compatible = "mediatek,mt7622-mmc";
+		reg = <0 0x11240000 0 0x1000>;
+		interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_MSDC30_1_PD>,
+			 <&topckgen CLK_TOP_AXI_SEL>;
+		clock-names = "source", "hclk";
+		status = "disabled";
+	};
+
+	ssusbsys: ssusbsys@1a000000 {
+		compatible = "mediatek,mt7622-ssusbsys",
+			     "syscon";
+		reg = <0 0x1a000000 0 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	ssusb: usb@1a0c0000 {
+		compatible = "mediatek,mt7622-xhci",
+			     "mediatek,mtk-xhci";
+		reg = <0 0x1a0c0000 0 0x01000>,
+		      <0 0x1a0c4700 0 0x0100>;
+		reg-names = "mac", "ippc";
+		interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF1>;
+		clocks = <&ssusbsys CLK_SSUSB_SYS_EN>,
+			 <&ssusbsys CLK_SSUSB_REF_EN>,
+			 <&ssusbsys CLK_SSUSB_MCU_EN>,
+			 <&ssusbsys CLK_SSUSB_DMA_EN>;
+		clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
+		phys = <&u2port0 PHY_TYPE_USB2>,
+		       <&u3port0 PHY_TYPE_USB3>,
+		       <&u2port1 PHY_TYPE_USB2>;
+
+		status = "disabled";
+	};
+
+	u3phy: usb-phy@1a0c4000 {
+		compatible = "mediatek,mt7622-u3phy",
+			     "mediatek,generic-tphy-v1";
+		reg = <0 0x1a0c4000 0 0x700>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		u2port0: usb-phy@1a0c4800 {
+			reg = <0 0x1a0c4800 0 0x0100>;
+			#phy-cells = <1>;
+			clocks = <&ssusbsys CLK_SSUSB_U2_PHY_EN>;
+			clock-names = "ref";
+		};
+
+		u3port0: usb-phy@1a0c4900 {
+			reg = <0 0x1a0c4900 0 0x0700>;
+			#phy-cells = <1>;
+			clocks = <&clk25m>;
+			clock-names = "ref";
+		};
+
+		u2port1: usb-phy@1a0c5000 {
+			reg = <0 0x1a0c5000 0 0x0100>;
+			#phy-cells = <1>;
+			clocks = <&ssusbsys CLK_SSUSB_U2_PHY_1P_EN>;
+			clock-names = "ref";
+		};
+	};
+
+	pciesys: pciesys@1a100800 {
+		compatible = "mediatek,mt7622-pciesys",
+			     "syscon";
+		reg = <0 0x1a100800 0 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	pcie: pcie@1a140000 {
+		compatible = "mediatek,mt7622-pcie";
+		device_type = "pci";
+		reg = <0 0x1a140000 0 0x1000>,
+		      <0 0x1a143000 0 0x1000>,
+		      <0 0x1a145000 0 0x1000>;
+		reg-names = "subsys", "port0", "port1";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pciesys CLK_PCIE_P0_MAC_EN>,
+			 <&pciesys CLK_PCIE_P1_MAC_EN>,
+			 <&pciesys CLK_PCIE_P0_AHB_EN>,
+			 <&pciesys CLK_PCIE_P0_AHB_EN>,
+			 <&pciesys CLK_PCIE_P0_AUX_EN>,
+			 <&pciesys CLK_PCIE_P1_AUX_EN>,
+			 <&pciesys CLK_PCIE_P0_AXI_EN>,
+			 <&pciesys CLK_PCIE_P1_AXI_EN>,
+			 <&pciesys CLK_PCIE_P0_OBFF_EN>,
+			 <&pciesys CLK_PCIE_P1_OBFF_EN>,
+			 <&pciesys CLK_PCIE_P0_PIPE_EN>,
+			 <&pciesys CLK_PCIE_P1_PIPE_EN>;
+		clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1",
+			      "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1",
+			      "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1";
+		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
+		bus-range = <0x00 0xff>;
+		ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
+		status = "disabled";
+
+		pcie0: pcie@0,0 {
+			reg = <0x0000 0 0 0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges;
+			status = "disabled";
+
+			num-lanes = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+					<0 0 0 2 &pcie_intc0 1>,
+					<0 0 0 3 &pcie_intc0 2>,
+					<0 0 0 4 &pcie_intc0 3>;
+			pcie_intc0: interrupt-controller {
+				interrupt-controller;
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+			};
+		};
+
+		pcie1: pcie@1,0 {
+			reg = <0x0800 0 0 0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+			ranges;
+			status = "disabled";
+
+			num-lanes = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie_intc1 0>,
+					<0 0 0 2 &pcie_intc1 1>,
+					<0 0 0 3 &pcie_intc1 2>,
+					<0 0 0 4 &pcie_intc1 3>;
+			pcie_intc1: interrupt-controller {
+				interrupt-controller;
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+			};
+		};
+	};
+
+	sata: sata@1a200000 {
+		compatible = "mediatek,mt7622-ahci",
+			     "mediatek,mtk-ahci";
+		reg = <0 0x1a200000 0 0x1100>;
+		interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "hostc";
+		clocks = <&pciesys CLK_SATA_AHB_EN>,
+			 <&pciesys CLK_SATA_AXI_EN>,
+			 <&pciesys CLK_SATA_ASIC_EN>,
+			 <&pciesys CLK_SATA_RBC_EN>,
+			 <&pciesys CLK_SATA_PM_EN>;
+		clock-names = "ahb", "axi", "asic", "rbc", "pm";
+		phys = <&sata_port PHY_TYPE_SATA>;
+		phy-names = "sata-phy";
+		ports-implemented = <0x1>;
+		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
+		resets = <&pciesys MT7622_SATA_AXI_BUS_RST>,
+			 <&pciesys MT7622_SATA_PHY_SW_RST>,
+			 <&pciesys MT7622_SATA_PHY_REG_RST>;
+		reset-names = "axi", "sw", "reg";
+		mediatek,phy-mode = <&pciesys>;
+		status = "disabled";
+	};
+
+	sata_phy: sata-phy@1a243000 {
+		compatible = "mediatek,generic-tphy-v1";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		sata_port: sata-phy@1a243000 {
+			reg = <0 0x1a243000 0 0x0100>;
+			clocks = <&topckgen CLK_TOP_ETH_500M>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+		};
+	};
+
+	ethsys: syscon@1b000000 {
+		compatible = "mediatek,mt7622-ethsys",
+			     "syscon";
+		reg = <0 0x1b000000 0 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	eth: ethernet@1b100000 {
+		compatible = "mediatek,mt7622-eth",
+			     "mediatek,mt2701-eth",
+			     "syscon";
+		reg = <0 0x1b100000 0 0x20000>;
+		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 224 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 225 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&topckgen CLK_TOP_ETH_SEL>,
+			 <&ethsys CLK_ETH_ESW_EN>,
+			 <&ethsys CLK_ETH_GP0_EN>,
+			 <&ethsys CLK_ETH_GP1_EN>,
+			 <&ethsys CLK_ETH_GP2_EN>,
+			 <&sgmiisys CLK_SGMII_TX250M_EN>,
+			 <&sgmiisys CLK_SGMII_RX250M_EN>,
+			 <&sgmiisys CLK_SGMII_CDR_REF>,
+			 <&sgmiisys CLK_SGMII_CDR_FB>,
+			 <&topckgen CLK_TOP_SGMIIPLL>,
+			 <&apmixedsys CLK_APMIXED_ETH2PLL>;
+		clock-names = "ethif", "esw", "gp0", "gp1", "gp2",
+			      "sgmii_tx250m", "sgmii_rx250m",
+			      "sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii_ck",
+			      "eth2pll";
+		power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
+		mediatek,ethsys = <&ethsys>;
+		mediatek,sgmiisys = <&sgmiisys>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	sgmiisys: sgmiisys@1b128000 {
+		compatible = "mediatek,mt7622-sgmiisys",
+			     "syscon";
+		reg = <0 0x1b128000 0 0x1000>;
+		#clock-cells = <1>;
+	};
 };
diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
index 676aa2f..7c13d7d 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -5,3 +5,4 @@
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-smaug.dtb
 dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-0000.dtb
+dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p2972-0000.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
new file mode 100644
index 0000000..ecb0341
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
@@ -0,0 +1,248 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "tegra194.dtsi"
+
+#include <dt-bindings/mfd/max77620.h>
+
+/ {
+	model = "NVIDIA Tegra194 P2888 Processor Module";
+	compatible = "nvidia,p2888", "nvidia,tegra194";
+
+	aliases {
+		sdhci0 = "/cbb/sdhci@3460000";
+		sdhci1 = "/cbb/sdhci@3400000";
+		serial0 = &uartb;
+		i2c0 = "/bpmp/i2c";
+		i2c1 = "/cbb/i2c@3160000";
+		i2c2 = "/cbb/i2c@c240000";
+		i2c3 = "/cbb/i2c@3180000";
+		i2c4 = "/cbb/i2c@3190000";
+		i2c5 = "/cbb/i2c@31c0000";
+		i2c6 = "/cbb/i2c@c250000";
+		i2c7 = "/cbb/i2c@31e0000";
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+		stdout-path = "serial0:115200n8";
+	};
+
+	cbb {
+		serial@3110000 {
+			status = "okay";
+		};
+
+		/* SDMMC1 (SD/MMC) */
+		sdhci@3400000 {
+/*
+			cd-gpios = <&gpio TEGRA194_MAIN_GPIO(A, 0) GPIO_ACTIVE_LOW>;
+*/
+		};
+
+		/* SDMMC4 (eMMC) */
+		sdhci@3460000 {
+			status = "okay";
+			bus-width = <8>;
+			non-removable;
+
+			vqmmc-supply = <&vdd_1v8ls>;
+			vmmc-supply = <&vdd_emmc_3v3>;
+		};
+
+		pmc@c360000 {
+			nvidia,invert-interrupt;
+		};
+	};
+
+	bpmp {
+		i2c {
+			status = "okay";
+
+			pmic: pmic@3c {
+				compatible = "maxim,max20024";
+				reg = <0x3c>;
+
+				interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+
+				#gpio-cells = <2>;
+				gpio-controller;
+
+				pinctrl-names = "default";
+				pinctrl-0 = <&max20024_default>;
+
+				max20024_default: pinmux {
+					gpio0 {
+						pins = "gpio0";
+						function = "gpio";
+					};
+
+					gpio1 {
+						pins = "gpio1";
+						function = "fps-out";
+						maxim,active-fps-source = <MAX77620_FPS_SRC_DEF>;
+					};
+
+					gpio2 {
+						pins = "gpio2";
+						function = "fps-out";
+						maxim,active-fps-source = <MAX77620_FPS_SRC_DEF>;
+					};
+
+					gpio3 {
+						pins = "gpio3";
+						function = "fps-out";
+						maxim,active-fps-source = <MAX77620_FPS_SRC_DEF>;
+					};
+
+					gpio4 {
+						pins = "gpio4";
+						function = "32k-out1";
+						drive-push-pull = <1>;
+					};
+
+					gpio6 {
+						pins = "gpio6";
+						function = "gpio";
+						drive-push-pull = <1>;
+					};
+
+					gpio7 {
+						pins = "gpio7";
+						function = "gpio";
+						drive-push-pull = <0>;
+					};
+				};
+
+				fps {
+					fps0 {
+						maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
+						maxim,shutdown-fps-time-period-us = <640>;
+					};
+
+					fps1 {
+						maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
+						maxim,shutdown-fps-time-period-us = <640>;
+						maxim,device-state-on-disabled-event = <MAX77620_FPS_INACTIVE_STATE_SLEEP>;
+					};
+
+					fps2 {
+						maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
+						maxim,shutdown-fps-time-period-us = <640>;
+					};
+				};
+
+				regulators {
+					in-sd0-supply = <&vdd_5v0_sys>;
+					in-sd1-supply = <&vdd_5v0_sys>;
+					in-sd2-supply = <&vdd_5v0_sys>;
+					in-sd3-supply = <&vdd_5v0_sys>;
+					in-sd4-supply = <&vdd_5v0_sys>;
+
+					in-ldo0-1-supply = <&vdd_5v0_sys>;
+					in-ldo2-supply = <&vdd_5v0_sys>;
+					in-ldo3-5-supply = <&vdd_5v0_sys>;
+					in-ldo4-6-supply = <&vdd_5v0_sys>;
+					in-ldo7-8-supply = <&vdd_1v8ls>;
+
+					sd0 {
+						regulator-name = "VDD_1V0";
+						regulator-min-microvolt = <1000000>;
+						regulator-max-microvolt = <1000000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					sd1 {
+						regulator-name = "VDD_1V8HS";
+						regulator-min-microvolt = <1800000>;
+						regulator-max-microvolt = <1800000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					vdd_1v8ls: sd2 {
+						regulator-name = "VDD_1V8LS";
+						regulator-min-microvolt = <1800000>;
+						regulator-max-microvolt = <1800000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					sd3 {
+						regulator-name = "VDD_1V8AO";
+						regulator-min-microvolt = <1800000>;
+						regulator-max-microvolt = <1800000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					sd4 {
+						regulator-name = "VDD_DDR_1V1";
+						regulator-min-microvolt = <1100000>;
+						regulator-max-microvolt = <1100000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					ldo0 {
+						regulator-name = "VDD_RTC";
+						regulator-min-microvolt = <800000>;
+						regulator-max-microvolt = <800000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					ldo2 {
+						regulator-name = "VDD_AO_3V3";
+						regulator-min-microvolt = <3300000>;
+						regulator-max-microvolt = <3300000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					vdd_emmc_3v3: ldo3 {
+						regulator-name = "VDD_EMMC_3V3";
+						regulator-min-microvolt = <3300000>;
+						regulator-max-microvolt = <3300000>;
+					};
+
+					ldo5 {
+						regulator-name = "VDD_USB_3V3";
+						regulator-min-microvolt = <3300000>;
+						regulator-max-microvolt = <3300000>;
+					};
+
+					ldo6 {
+						regulator-name = "VDD_SDIO_3V3";
+						regulator-min-microvolt = <3300000>;
+						regulator-max-microvolt = <3300000>;
+					};
+
+					ldo7 {
+						regulator-name = "VDD_CSI_1V2";
+						regulator-min-microvolt = <1200000>;
+						regulator-max-microvolt = <1200000>;
+					};
+				};
+			};
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		vdd_5v0_sys: regulator@0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+
+			regulator-name = "VIN_SYS_5V0";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
new file mode 100644
index 0000000..9ff3c18
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "tegra194-p2888.dtsi"
+
+/ {
+	model = "NVIDIA Tegra194 P2972-0000 Development Board";
+	compatible = "nvidia,p2972-0000", "nvidia,tegra194";
+
+	cbb {
+		/* SDMMC1 (SD/MMC) */
+		sdhci@3400000 {
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
new file mode 100644
index 0000000..6322ef2
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/clock/tegra194-clock.h>
+#include <dt-bindings/gpio/tegra194-gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/tegra186-hsp.h>
+#include <dt-bindings/reset/tegra194-reset.h>
+
+/ {
+	compatible = "nvidia,tegra194";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	/* control backbone */
+	cbb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x0 0x40000000>;
+
+		uarta: serial@3100000 {
+			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
+			reg = <0x03100000 0x40>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_UARTA>;
+			clock-names = "serial";
+			resets = <&bpmp TEGRA194_RESET_UARTA>;
+			reset-names = "serial";
+			status = "disabled";
+		};
+
+		uartb: serial@3110000 {
+			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
+			reg = <0x03110000 0x40>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_UARTB>;
+			clock-names = "serial";
+			resets = <&bpmp TEGRA194_RESET_UARTB>;
+			reset-names = "serial";
+			status = "disabled";
+		};
+
+		uartd: serial@3130000 {
+			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
+			reg = <0x03130000 0x40>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_UARTD>;
+			clock-names = "serial";
+			resets = <&bpmp TEGRA194_RESET_UARTD>;
+			reset-names = "serial";
+			status = "disabled";
+		};
+
+		uarte: serial@3140000 {
+			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
+			reg = <0x03140000 0x40>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_UARTE>;
+			clock-names = "serial";
+			resets = <&bpmp TEGRA194_RESET_UARTE>;
+			reset-names = "serial";
+			status = "disabled";
+		};
+
+		uartf: serial@3150000 {
+			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
+			reg = <0x03150000 0x40>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_UARTF>;
+			clock-names = "serial";
+			resets = <&bpmp TEGRA194_RESET_UARTF>;
+			reset-names = "serial";
+			status = "disabled";
+		};
+
+		gen1_i2c: i2c@3160000 {
+			compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+			reg = <0x03160000 0x10000>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&bpmp TEGRA194_CLK_I2C1>;
+			clock-names = "div-clk";
+			resets = <&bpmp TEGRA194_RESET_I2C1>;
+			reset-names = "i2c";
+			status = "disabled";
+		};
+
+		uarth: serial@3170000 {
+			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
+			reg = <0x03170000 0x40>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_UARTH>;
+			clock-names = "serial";
+			resets = <&bpmp TEGRA194_RESET_UARTH>;
+			reset-names = "serial";
+			status = "disabled";
+		};
+
+		cam_i2c: i2c@3180000 {
+			compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+			reg = <0x03180000 0x10000>;
+			interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&bpmp TEGRA194_CLK_I2C3>;
+			clock-names = "div-clk";
+			resets = <&bpmp TEGRA194_RESET_I2C3>;
+			reset-names = "i2c";
+			status = "disabled";
+		};
+
+		/* shares pads with dpaux1 */
+		dp_aux_ch1_i2c: i2c@3190000 {
+			compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+			reg = <0x03190000 0x10000>;
+			interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&bpmp TEGRA194_CLK_I2C4>;
+			clock-names = "div-clk";
+			resets = <&bpmp TEGRA194_RESET_I2C4>;
+			reset-names = "i2c";
+			status = "disabled";
+		};
+
+		/* shares pads with dpaux0 */
+		dp_aux_ch0_i2c: i2c@31b0000 {
+			compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+			reg = <0x031b0000 0x10000>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&bpmp TEGRA194_CLK_I2C6>;
+			clock-names = "div-clk";
+			resets = <&bpmp TEGRA194_RESET_I2C6>;
+			reset-names = "i2c";
+			status = "disabled";
+		};
+
+		gen7_i2c: i2c@31c0000 {
+			compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+			reg = <0x031c0000 0x10000>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&bpmp TEGRA194_CLK_I2C7>;
+			clock-names = "div-clk";
+			resets = <&bpmp TEGRA194_RESET_I2C7>;
+			reset-names = "i2c";
+			status = "disabled";
+		};
+
+		gen9_i2c: i2c@31e0000 {
+			compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+			reg = <0x031e0000 0x10000>;
+			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&bpmp TEGRA194_CLK_I2C9>;
+			clock-names = "div-clk";
+			resets = <&bpmp TEGRA194_RESET_I2C9>;
+			reset-names = "i2c";
+			status = "disabled";
+		};
+
+		sdmmc1: sdhci@3400000 {
+			compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci";
+			reg = <0x03400000 0x10000>;
+			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_SDMMC1>;
+			clock-names = "sdhci";
+			resets = <&bpmp TEGRA194_RESET_SDMMC1>;
+			reset-names = "sdhci";
+			status = "disabled";
+		};
+
+		sdmmc3: sdhci@3440000 {
+			compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci";
+			reg = <0x03440000 0x10000>;
+			interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_SDMMC3>;
+			clock-names = "sdhci";
+			resets = <&bpmp TEGRA194_RESET_SDMMC3>;
+			reset-names = "sdhci";
+			status = "disabled";
+		};
+
+		sdmmc4: sdhci@3460000 {
+			compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci";
+			reg = <0x03460000 0x10000>;
+			interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_SDMMC4>;
+			clock-names = "sdhci";
+			resets = <&bpmp TEGRA194_RESET_SDMMC4>;
+			reset-names = "sdhci";
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@3881000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x03881000 0x1000>,
+			      <0x03882000 0x2000>,
+			      <0x03884000 0x2000>,
+			      <0x03886000 0x2000>;
+			interrupts = <GIC_PPI 9
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			interrupt-parent = <&gic>;
+		};
+
+		hsp_top0: hsp@3c00000 {
+			compatible = "nvidia,tegra186-hsp";
+			reg = <0x03c00000 0xa0000>;
+			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "doorbell";
+			#mbox-cells = <2>;
+		};
+
+		gen2_i2c: i2c@c240000 {
+			compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+			reg = <0x0c240000 0x10000>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&bpmp TEGRA194_CLK_I2C2>;
+			clock-names = "div-clk";
+			resets = <&bpmp TEGRA194_RESET_I2C2>;
+			reset-names = "i2c";
+			status = "disabled";
+		};
+
+		gen8_i2c: i2c@c250000 {
+			compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+			reg = <0x0c250000 0x10000>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&bpmp TEGRA194_CLK_I2C8>;
+			clock-names = "div-clk";
+			resets = <&bpmp TEGRA194_RESET_I2C8>;
+			reset-names = "i2c";
+			status = "disabled";
+		};
+
+		uartc: serial@c280000 {
+			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
+			reg = <0x0c280000 0x40>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_UARTC>;
+			clock-names = "serial";
+			resets = <&bpmp TEGRA194_RESET_UARTC>;
+			reset-names = "serial";
+			status = "disabled";
+		};
+
+		uartg: serial@c290000 {
+			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
+			reg = <0x0c290000 0x40>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA194_CLK_UARTG>;
+			clock-names = "serial";
+			resets = <&bpmp TEGRA194_RESET_UARTG>;
+			reset-names = "serial";
+			status = "disabled";
+		};
+
+		pmc@c360000 {
+			compatible = "nvidia,tegra194-pmc";
+			reg = <0x0c360000 0x10000>,
+			      <0x0c370000 0x10000>,
+			      <0x0c380000 0x10000>,
+			      <0x0c390000 0x10000>,
+			      <0x0c3a0000 0x10000>;
+			reg-names = "pmc", "wake", "aotag", "scratch", "misc";
+		};
+	};
+
+	sysram@40000000 {
+		compatible = "nvidia,tegra194-sysram", "mmio-sram";
+		reg = <0x0 0x40000000 0x0 0x50000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x40000000 0x50000>;
+
+		cpu_bpmp_tx: shmem@4e000 {
+			compatible = "nvidia,tegra194-bpmp-shmem";
+			reg = <0x4e000 0x1000>;
+			label = "cpu-bpmp-tx";
+			pool;
+		};
+
+		cpu_bpmp_rx: shmem@4f000 {
+			compatible = "nvidia,tegra194-bpmp-shmem";
+			reg = <0x4f000 0x1000>;
+			label = "cpu-bpmp-rx";
+			pool;
+		};
+	};
+
+	bpmp: bpmp {
+		compatible = "nvidia,tegra186-bpmp";
+		mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB
+				    TEGRA_HSP_DB_MASTER_BPMP>;
+		shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+		#power-domain-cells = <1>;
+
+		bpmp_i2c: i2c {
+			compatible = "nvidia,tegra186-bpmp-i2c";
+			nvidia,bpmp-bus-id = <5>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		bpmp_thermal: thermal {
+			compatible = "nvidia,tegra186-bpmp-thermal";
+			#thermal-sensor-cells = <1>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+		interrupt-parent = <&gic>;
+	};
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
index d67ef43..9d5a0e6 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
@@ -1325,6 +1325,11 @@
 		status = "okay";
 	};
 
+	sata@70020000 {
+		status = "okay";
+		phys = <&{/padctl@7009f000/pads/sata/lanes/sata-0}>;
+	};
+
 	padctl@7009f000 {
 		status = "okay";
 
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 9c24021..3be920e 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -798,6 +798,22 @@
 		#iommu-cells = <1>;
 	};
 
+	sata@70020000 {
+		compatible = "nvidia,tegra210-ahci";
+		reg = <0x0 0x70027000 0x0 0x2000>, /* AHCI */
+		      <0x0 0x70020000 0x0 0x7000>, /* SATA */
+		      <0x0 0x70001100 0x0 0x1000>; /* SATA AUX */
+		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA210_CLK_SATA>,
+			 <&tegra_car TEGRA210_CLK_SATA_OOB>;
+		clock-names = "sata", "sata-oob";
+		resets = <&tegra_car 124>,
+			 <&tegra_car 123>,
+			 <&tegra_car 129>;
+		reset-names = "sata", "sata-oob", "sata-cold";
+		status = "disabled";
+	};
+
 	hda@70030000 {
 		compatible = "nvidia,tegra210-hda", "nvidia,tegra30-hda";
 		reg = <0x0 0x70030000 0x0 0x10000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index e51b049..66b318e 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -15,6 +15,7 @@
 #include <dt-bindings/clock/qcom,gcc-msm8916.h>
 #include <dt-bindings/reset/qcom,gcc-msm8916.h>
 #include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	model = "Qualcomm Technologies, Inc. MSM8916";
@@ -113,6 +114,9 @@
 			next-level-cache = <&L2_0>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SPC>;
+			clocks = <&apcs 0>;
+			operating-points-v2 = <&cpu_opp_table>;
+			#cooling-cells = <2>;
 		};
 
 		CPU1: cpu@1 {
@@ -122,6 +126,9 @@
 			next-level-cache = <&L2_0>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SPC>;
+			clocks = <&apcs 0>;
+			operating-points-v2 = <&cpu_opp_table>;
+			#cooling-cells = <2>;
 		};
 
 		CPU2: cpu@2 {
@@ -131,6 +138,9 @@
 			next-level-cache = <&L2_0>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SPC>;
+			clocks = <&apcs 0>;
+			operating-points-v2 = <&cpu_opp_table>;
+			#cooling-cells = <2>;
 		};
 
 		CPU3: cpu@3 {
@@ -140,6 +150,9 @@
 			next-level-cache = <&L2_0>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SPC>;
+			clocks = <&apcs 0>;
+			operating-points-v2 = <&cpu_opp_table>;
+			#cooling-cells = <2>;
 		};
 
 		L2_0: l2-cache {
@@ -188,6 +201,13 @@
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert0>;
+					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu-thermal1 {
@@ -208,10 +228,35 @@
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert1>;
+					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 	};
 
+	cpu_opp_table: cpu_opp_table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+		};
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+		};
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+		};
+		opp-998400000 {
+			opp-hz = /bits/ 64 <998400000>;
+		};
+	};
+
 	gpu_opp_table: opp_table {
 		compatible = "operating-points-v2";
 
@@ -326,9 +371,18 @@
 			status = "disabled";
 		};
 
-		apcs: syscon@b011000 {
-			compatible = "syscon";
-			reg = <0x0b011000 0x1000>;
+		a53pll: clock@b016000 {
+			compatible = "qcom,msm8916-a53pll";
+			reg = <0xb016000 0x40>;
+			#clock-cells = <0>;
+		};
+
+		apcs: mailbox@b011000 {
+			compatible = "qcom,msm8916-apcs-kpss-global", "syscon";
+			reg = <0xb011000 0x1000>;
+			#mbox-cells = <1>;
+			clocks = <&a53pll>;
+			#clock-cells = <0>;
 		};
 
 		blsp1_uart2: serial@78b0000 {
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 0a6f795..410ae78 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -75,6 +75,17 @@
 			reg = <0x0 0x86200000 0x0 0x2600000>;
 			no-map;
 		};
+
+		rmtfs@86700000 {
+			compatible = "qcom,rmtfs-mem";
+
+			size = <0x0 0x200000>;
+			alloc-ranges = <0x0 0xa0000000 0x0 0x2000000>;
+			no-map;
+
+			qcom,client-id = <1>;
+			qcom,vmid = <15>;
+		};
 	};
 
 	cpus {
@@ -232,10 +243,10 @@
 
 	timer {
 		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
 	};
 
 	clocks {
@@ -497,8 +508,8 @@
 		blsp2_spi5: spi@75ba000{
 			compatible = "qcom,spi-qup-v2.2.1";
 			reg = <0x075ba000 0x600>;
-			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&gcc GCC_BLSP2_QUP5_SPI_APPS_CLK>,
+			interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP2_QUP6_SPI_APPS_CLK>,
 				 <&gcc GCC_BLSP2_AHB_CLK>;
 			clock-names = "core", "iface";
 			pinctrl-names = "default", "sleep";
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 2186d01..5ede060 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -7,5 +7,7 @@
 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-kf.dtb
 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb r8a77965-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle.dtb r8a77970-v3msk.dtb
+dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-condor.dtb
 dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
index 26769a1..f9acd12 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
@@ -23,6 +23,7 @@
 
 	/delete-node/ mmu@febe0000;
 	/delete-node/ mmu@fe980000;
+	/delete-node/ mmu@fd950000;
 	/delete-node/ mmu@fd960000;
 	/delete-node/ mmu@fd970000;
 
@@ -80,7 +81,7 @@
 
 	vspd3: vsp@fea38000 {
 		compatible = "renesas,vsp2";
-		reg = <0 0xfea38000 0 0x4000>;
+		reg = <0 0xfea38000 0 0x8000>;
 		interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cpg CPG_MOD 620>;
 		power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index d12df6f..1d5e3ac 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -41,6 +41,9 @@
 			power-domains = <&sysc R8A7795_PD_CA57_CPU0>;
 			next-level-cache = <&L2_CA57>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7795_CLK_Z>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		a57_1: cpu@1 {
@@ -50,6 +53,9 @@
 			power-domains = <&sysc R8A7795_PD_CA57_CPU1>;
 			next-level-cache = <&L2_CA57>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7795_CLK_Z>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		a57_2: cpu@2 {
@@ -59,6 +65,9 @@
 			power-domains = <&sysc R8A7795_PD_CA57_CPU2>;
 			next-level-cache = <&L2_CA57>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7795_CLK_Z>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		a57_3: cpu@3 {
@@ -68,6 +77,9 @@
 			power-domains = <&sysc R8A7795_PD_CA57_CPU3>;
 			next-level-cache = <&L2_CA57>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7795_CLK_Z>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		a53_0: cpu@100 {
@@ -77,6 +89,8 @@
 			power-domains = <&sysc R8A7795_PD_CA53_CPU0>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7795_CLK_Z2>;
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		a53_1: cpu@101 {
@@ -86,6 +100,8 @@
 			power-domains = <&sysc R8A7795_PD_CA53_CPU1>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7795_CLK_Z2>;
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		a53_2: cpu@102 {
@@ -95,6 +111,8 @@
 			power-domains = <&sysc R8A7795_PD_CA53_CPU2>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7795_CLK_Z2>;
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		a53_3: cpu@103 {
@@ -104,6 +122,8 @@
 			power-domains = <&sysc R8A7795_PD_CA53_CPU3>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7795_CLK_Z2>;
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		L2_CA57: cache-controller-0 {
@@ -165,11 +185,59 @@
 		clock-frequency = <0>;
 	};
 
-	/* External SCIF clock - to be overridden by boards that provide it */
-	scif_clk: scif {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <0>;
+	cluster0_opp: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <830000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <830000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1500000000 {
+			opp-hz = /bits/ 64 <1500000000>;
+			opp-microvolt = <830000>;
+			clock-latency-ns = <300000>;
+			opp-suspend;
+		};
+		opp-1600000000 {
+			opp-hz = /bits/ 64 <1600000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+		opp-1700000000 {
+			opp-hz = /bits/ 64 <1700000000>;
+			opp-microvolt = <960000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+	};
+
+	cluster1_opp: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
 	};
 
 	/* External PCIe clock - can be overridden by the board */
@@ -208,6 +276,13 @@
 		method = "smc";
 	};
 
+	/* External SCIF clock - to be overridden by boards that provide it */
+	scif_clk: scif {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
 	soc: soc {
 		compatible = "simple-bus";
 		interrupt-parent = <&gic>;
@@ -470,6 +545,15 @@
 			status = "disabled";
 		};
 
+		ipmmu_pv1: mmu@fd950000 {
+			compatible = "renesas,ipmmu-r8a7795";
+			reg = <0 0xfd950000 0 0x1000>;
+			renesas,ipmmu-main = <&ipmmu_mm 7>;
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			#iommu-cells = <1>;
+			status = "disabled";
+		};
+
 		ipmmu_pv2: mmu@fd960000 {
 			compatible = "renesas,ipmmu-r8a7795";
 			reg = <0 0xfd960000 0 0x1000>;
@@ -798,7 +882,7 @@
 			clocks = <&cpg CPG_MOD 812>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 812>;
-			phy-mode = "rgmii-txid";
+			phy-mode = "rgmii";
 			iommus = <&ipmmu_ds0 16>;
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -992,8 +1076,9 @@
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x31>, <&dmac1 0x30>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 520>;
 			status = "disabled";
@@ -1009,8 +1094,9 @@
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x33>, <&dmac1 0x32>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+			       <&dmac2 0x33>, <&dmac2 0x32>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 519>;
 			status = "disabled";
@@ -1026,8 +1112,9 @@
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x35>, <&dmac1 0x34>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+			       <&dmac2 0x35>, <&dmac2 0x34>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 518>;
 			status = "disabled";
@@ -1138,8 +1225,9 @@
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x51>, <&dmac1 0x50>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+			       <&dmac2 0x51>, <&dmac2 0x50>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 207>;
 			status = "disabled";
@@ -1154,8 +1242,9 @@
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x53>, <&dmac1 0x52>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+			       <&dmac2 0x53>, <&dmac2 0x52>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 206>;
 			status = "disabled";
@@ -1170,8 +1259,9 @@
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x13>, <&dmac1 0x12>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x13>, <&dmac1 0x12>,
+			       <&dmac2 0x13>, <&dmac2 0x12>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 310>;
 			status = "disabled";
@@ -1218,8 +1308,9 @@
 				 <&cpg CPG_CORE R8A7795_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
-			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+			       <&dmac2 0x5b>, <&dmac2 0x5a>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 202>;
 			status = "disabled";
@@ -1251,8 +1342,9 @@
 			clocks = <&cpg CPG_MOD 931>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 931>;
-			dmas = <&dmac1 0x91>, <&dmac1 0x90>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+			       <&dmac2 0x91>, <&dmac2 0x90>;
+			dma-names = "tx", "rx", "tx", "rx";
 			i2c-scl-internal-delay-ns = <110>;
 			status = "disabled";
 		};
@@ -1267,8 +1359,9 @@
 			clocks = <&cpg CPG_MOD 930>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 930>;
-			dmas = <&dmac1 0x93>, <&dmac1 0x92>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+			       <&dmac2 0x93>, <&dmac2 0x92>;
+			dma-names = "tx", "rx", "tx", "rx";
 			i2c-scl-internal-delay-ns = <6>;
 			status = "disabled";
 		};
@@ -1283,8 +1376,9 @@
 			clocks = <&cpg CPG_MOD 929>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 			resets = <&cpg 929>;
-			dmas = <&dmac1 0x95>, <&dmac1 0x94>;
-			dma-names = "tx", "rx";
+			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+			       <&dmac2 0x95>, <&dmac2 0x94>;
+			dma-names = "tx", "rx", "tx", "rx";
 			i2c-scl-internal-delay-ns = <6>;
 			status = "disabled";
 		};
@@ -2143,7 +2237,7 @@
 
 		vspd0: vsp@fea20000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea20000 0 0x4000>;
+			reg = <0 0xfea20000 0 0x8000>;
 			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 623>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -2163,7 +2257,7 @@
 
 		vspd1: vsp@fea28000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea28000 0 0x4000>;
+			reg = <0 0xfea28000 0 0x8000>;
 			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 622>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -2183,7 +2277,7 @@
 
 		vspd2: vsp@fea30000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea30000 0 0x4000>;
+			reg = <0 0xfea30000 0 0x8000>;
 			interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 621>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -2320,9 +2414,9 @@
 
 		tsc: thermal@e6198000 {
 			compatible = "renesas,r8a7795-thermal";
-			reg = <0 0xe6198000 0 0x68>,
-			      <0 0xe61a0000 0 0x5c>,
-			      <0 0xe61a8000 0 0x5c>;
+			reg = <0 0xe6198000 0 0x100>,
+			      <0 0xe61a0000 0 0x100>,
+			      <0 0xe61a8000 0 0x100>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
@@ -2357,12 +2451,24 @@
 			thermal-sensors = <&tsc 0>;
 
 			trips {
+				sensor1_passive: sensor1-passive {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
 				sensor1_crit: sensor1-crit {
 					temperature = <120000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&sensor1_passive>;
+					cooling-device = <&a57_0 4 4>;
+				};
+			};
 		};
 
 		sensor_thermal2: sensor-thermal2 {
@@ -2371,12 +2477,24 @@
 			thermal-sensors = <&tsc 1>;
 
 			trips {
+				sensor2_passive: sensor2-passive {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
 				sensor2_crit: sensor2-crit {
 					temperature = <120000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&sensor2_passive>;
+					cooling-device = <&a57_0 4 4>;
+				};
+			};
 		};
 
 		sensor_thermal3: sensor-thermal3 {
@@ -2385,12 +2503,24 @@
 			thermal-sensors = <&tsc 2>;
 
 			trips {
+				sensor3_passive: sensor3-passive {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
 				sensor3_crit: sensor3-crit {
 					temperature = <120000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&sensor3_passive>;
+					cooling-device = <&a57_0 4 4>;
+				};
+			};
 		};
 	};
 
diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index c5192d5..556eb8e 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -71,6 +71,9 @@
 			power-domains = <&sysc R8A7796_PD_CA57_CPU0>;
 			next-level-cache = <&L2_CA57>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7796_CLK_Z>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		a57_1: cpu@1 {
@@ -80,6 +83,9 @@
 			power-domains = <&sysc R8A7796_PD_CA57_CPU1>;
 			next-level-cache = <&L2_CA57>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7796_CLK_Z>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		a53_0: cpu@100 {
@@ -89,6 +95,8 @@
 			power-domains = <&sysc R8A7796_PD_CA53_CPU0>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7796_CLK_Z2>;
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		a53_1: cpu@101 {
@@ -98,6 +106,8 @@
 			power-domains = <&sysc R8A7796_PD_CA53_CPU1>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7796_CLK_Z2>;
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		a53_2: cpu@102 {
@@ -107,6 +117,8 @@
 			power-domains = <&sysc R8A7796_PD_CA53_CPU2>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7796_CLK_Z2>;
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		a53_3: cpu@103 {
@@ -116,6 +128,8 @@
 			power-domains = <&sysc R8A7796_PD_CA53_CPU3>;
 			next-level-cache = <&L2_CA53>;
 			enable-method = "psci";
+			clocks =<&cpg CPG_CORE R8A7796_CLK_Z2>;
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		L2_CA57: cache-controller-0 {
@@ -147,6 +161,72 @@
 		clock-frequency = <0>;
 	};
 
+	cluster0_opp: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1500000000 {
+			opp-hz = /bits/ 64 <1500000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1600000000 {
+			opp-hz = /bits/ 64 <1600000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+		opp-1700000000 {
+			opp-hz = /bits/ 64 <1700000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+		opp-1800000000 {
+			opp-hz = /bits/ 64 <1800000000>;
+			opp-microvolt = <960000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+	};
+
+	cluster1_opp: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-1300000000 {
+			opp-hz = /bits/ 64 <1300000000>;
+			opp-microvolt = <820000>;
+			clock-latency-ns = <300000>;
+			turbo-mode;
+		};
+	};
+
 	/* External PCIe clock - can be overridden by the board */
 	pcie_bus_clk: pcie_bus {
 		compatible = "fixed-clock";
@@ -894,7 +974,7 @@
 			clocks = <&cpg CPG_MOD 812>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
 			resets = <&cpg 812>;
-			phy-mode = "rgmii-txid";
+			phy-mode = "rgmii";
 			iommus = <&ipmmu_ds0 16>;
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1561,9 +1641,9 @@
 
 		tsc: thermal@e6198000 {
 			compatible = "renesas,r8a7796-thermal";
-			reg = <0 0xe6198000 0 0x68>,
-			      <0 0xe61a0000 0 0x5c>,
-			      <0 0xe61a8000 0 0x5c>;
+			reg = <0 0xe6198000 0 0x100>,
+			      <0 0xe61a0000 0 0x100>,
+			      <0 0xe61a8000 0 0x100>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
@@ -1839,7 +1919,7 @@
 
 		vspd0: vsp@fea20000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea20000 0 0x4000>;
+			reg = <0 0xfea20000 0 0x8000>;
 			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 623>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -1859,7 +1939,7 @@
 
 		vspd1: vsp@fea28000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea28000 0 0x4000>;
+			reg = <0 0xfea28000 0 0x8000>;
 			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 622>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -1879,7 +1959,7 @@
 
 		vspd2: vsp@fea30000 {
 			compatible = "renesas,vsp2";
-			reg = <0 0xfea30000 0 0x4000>;
+			reg = <0 0xfea30000 0 0x8000>;
 			interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 621>;
 			power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -1998,12 +2078,24 @@
 			thermal-sensors = <&tsc 0>;
 
 			trips {
+				sensor1_passive: sensor1-passive {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
 				sensor1_crit: sensor1-crit {
 					temperature = <120000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&sensor1_passive>;
+					cooling-device = <&a57_0 5 5>;
+				};
+			};
 		};
 
 		sensor_thermal2: sensor-thermal2 {
@@ -2012,12 +2104,24 @@
 			thermal-sensors = <&tsc 1>;
 
 			trips {
+				sensor2_passive: sensor2-passive {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
 				sensor2_crit: sensor2-crit {
 					temperature = <120000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&sensor2_passive>;
+					cooling-device = <&a57_0 5 5>;
+				};
+			};
 		};
 
 		sensor_thermal3: sensor-thermal3 {
@@ -2026,12 +2130,24 @@
 			thermal-sensors = <&tsc 2>;
 
 			trips {
+				sensor3_passive: sensor3-passive {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
 				sensor3_crit: sensor3-crit {
 					temperature = <120000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&sensor3_passive>;
+					cooling-device = <&a57_0 5 5>;
+				};
+			};
 		};
 	};
 
diff --git a/arch/arm64/boot/dts/renesas/r8a77965-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a77965-salvator-x.dts
new file mode 100644
index 0000000..75d890d
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a77965-salvator-x.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Salvator-X board with R-Car M3-N
+ *
+ * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
+ */
+
+/dts-v1/;
+#include "r8a77965.dtsi"
+#include "salvator-x.dtsi"
+
+/ {
+	model = "Renesas Salvator-X board based on r8a77965";
+	compatible = "renesas,salvator-x", "renesas,r8a77965";
+
+	memory@48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x78000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts
new file mode 100644
index 0000000..a83a00d
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Salvator-X 2nd version board with R-Car M3-N
+ *
+ * Copyright (C) 2017 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a77965.dtsi"
+#include "salvator-xs.dtsi"
+
+/ {
+	model = "Renesas Salvator-X 2nd version board based on r8a77965";
+	compatible = "renesas,salvator-xs", "renesas,r8a77965";
+
+	memory@48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x78000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
new file mode 100644
index 0000000..f0871fc
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
@@ -0,0 +1,878 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the r8a77965 SoC
+ *
+ * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
+ *
+ * Based on r8a7796.dtsi
+ * Copyright (C) 2016 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#define CPG_AUDIO_CLK_I		10
+
+/ {
+	compatible = "renesas,r8a77965";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		i2c7 = &i2c_dvfs;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		a57_0: cpu@0 {
+			compatible = "arm,cortex-a57", "arm,armv8";
+			reg = <0x0>;
+			device_type = "cpu";
+			power-domains = <&sysc 0>;
+			next-level-cache = <&L2_CA57>;
+			enable-method = "psci";
+		};
+
+		a57_1: cpu@1 {
+			compatible = "arm,cortex-a57","arm,armv8";
+			reg = <0x1>;
+			device_type = "cpu";
+			power-domains = <&sysc 1>;
+			next-level-cache = <&L2_CA57>;
+			enable-method = "psci";
+		};
+
+		L2_CA57: cache-controller-0 {
+			compatible = "cache";
+			power-domains = <&sysc 12>;
+			cache-unified;
+			cache-level = <2>;
+		};
+	};
+
+	extal_clk: extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board */
+		clock-frequency = <0>;
+	};
+
+	extalr_clk: extalr {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board */
+		clock-frequency = <0>;
+	};
+
+	/*
+	 * The external audio clocks are configured as 0 Hz fixed frequency
+	 * clocks by default.
+	 * Boards that provide audio clocks should override them.
+	 */
+	audio_clk_a: audio_clk_a {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	audio_clk_b: audio_clk_b {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	audio_clk_c: audio_clk_c {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External CAN clock - to be overridden by boards that provide it */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External SCIF clock - to be overridden by boards that provide it */
+	scif_clk: scif {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External PCIe clock - can be overridden by the board */
+	pcie_bus_clk: pcie_bus {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	/* External USB clocks - can be overridden by the board */
+	usb3s0_clk: usb3s0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	usb_extal_clk: usb_extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	pmu_a57 {
+		compatible = "arm,cortex-a57-pmu";
+		interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				      <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&a57_0>,
+				     <&a57_1>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller@f1010000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xf1010000 0 0x1000>,
+			      <0x0 0xf1020000 0 0x20000>,
+			      <0x0 0xf1040000 0 0x20000>,
+			      <0x0 0xf1060000 0 0x20000>;
+			interrupts = <GIC_PPI 9
+					(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 408>;
+		};
+
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a77965";
+			reg = <0 0xe6060000 0 0x50c>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a77965-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&extalr_clk>;
+			clock-names = "extal", "extalr";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a77965-rst";
+			reg = <0 0xe6160000 0 0x0200>;
+		};
+
+		prr: chipid@fff00044 {
+			compatible = "renesas,prr";
+			reg = <0 0xfff00044 0 4>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a77965-sysc";
+			reg = <0 0xe6180000 0 0x0400>;
+			#power-domain-cells = <1>;
+		};
+
+		gpio0: gpio@e6050000 {
+			compatible = "renesas,gpio-r8a77965",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6050000 0 0x50>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 0 16>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 912>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 912>;
+		};
+
+		gpio1: gpio@e6051000 {
+			compatible = "renesas,gpio-r8a77965",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6051000 0 0x50>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 32 29>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 911>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 911>;
+		};
+
+		gpio2: gpio@e6052000 {
+			compatible = "renesas,gpio-r8a77965",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6052000 0 0x50>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 64 15>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 910>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 910>;
+		};
+
+		gpio3: gpio@e6053000 {
+			compatible = "renesas,gpio-r8a77965",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6053000 0 0x50>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 96 16>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 909>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 909>;
+		};
+
+		gpio4: gpio@e6054000 {
+			compatible = "renesas,gpio-r8a77965",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6054000 0 0x50>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 128 18>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 908>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 908>;
+		};
+
+		gpio5: gpio@e6055000 {
+			compatible = "renesas,gpio-r8a77965",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6055000 0 0x50>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 160 26>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 907>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 907>;
+		};
+
+		gpio6: gpio@e6055400 {
+			compatible = "renesas,gpio-r8a77965",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6055400 0 0x50>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 192 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 906>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 906>;
+		};
+
+		gpio7: gpio@e6055800 {
+			compatible = "renesas,gpio-r8a77965",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6055800 0 0x50>;
+			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 224 4>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 905>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 905>;
+		};
+
+		intc_ex: interrupt-controller@e61c0000 {
+			compatible = "renesas,intc-ex-r8a77965", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 407>;
+		};
+
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a77965",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x10000>;
+			interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 219>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+		};
+
+		dmac1: dma-controller@e7300000 {
+			compatible = "renesas,dmac-r8a77965",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7300000 0 0x10000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+		};
+
+		dmac2: dma-controller@e7310000 {
+			compatible = "renesas,dmac-r8a77965",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7310000 0 0x10000>;
+			interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 217>;
+			clock-names = "fck";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 217>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a77965",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>,
+				 <&cpg CPG_CORE 20>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+			       <&dmac2 0x51>, <&dmac2 0x50>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 207>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a77965",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e68000 0 64>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>,
+				 <&cpg CPG_CORE 20>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+			       <&dmac2 0x53>, <&dmac2 0x52>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 206>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e88000 {
+			compatible = "renesas,scif-r8a77965",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e88000 0 64>;
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 310>,
+				 <&cpg CPG_CORE 20>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 310>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6c50000 {
+			compatible = "renesas,scif-r8a77965",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>,
+				 <&cpg CPG_CORE 20>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6c40000 {
+			compatible = "renesas,scif-r8a77965",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>,
+				 <&cpg CPG_CORE 20>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6f30000 {
+			compatible = "renesas,scif-r8a77965",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6f30000 0 64>;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>,
+				 <&cpg CPG_CORE 20>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+			       <&dmac2 0x5b>, <&dmac2 0x5a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 202>;
+			status = "disabled";
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a77965",
+				     "renesas,etheravb-rcar-gen3";
+			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 812>;
+			phy-mode = "rgmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		csi20: csi2@fea80000 {
+			reg = <0 0xfea80000 0 0x10000>;
+			/* placeholder */
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		csi40: csi2@feaa0000 {
+			reg = <0 0xfeaa0000 0 0x10000>;
+			/* placeholder */
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		vin0: video@e6ef0000 {
+			reg = <0 0xe6ef0000 0 0x1000>;
+			/* placeholder */
+		};
+
+		vin1: video@e6ef1000 {
+			reg = <0 0xe6ef1000 0 0x1000>;
+			/* placeholder */
+		};
+
+		vin2: video@e6ef2000 {
+			reg = <0 0xe6ef2000 0 0x1000>;
+			/* placeholder */
+		};
+
+		vin3: video@e6ef3000 {
+			reg = <0 0xe6ef3000 0 0x1000>;
+			/* placeholder */
+		};
+
+		vin4: video@e6ef4000 {
+			reg = <0 0xe6ef4000 0 0x1000>;
+			/* placeholder */
+		};
+
+		vin5: video@e6ef5000 {
+			reg = <0 0xe6ef5000 0 0x1000>;
+			/* placeholder */
+		};
+
+		vin6: video@e6ef6000 {
+			reg = <0 0xe6ef6000 0 0x1000>;
+			/* placeholder */
+		};
+
+		vin7: video@e6ef7000 {
+			reg = <0 0xe6ef7000 0 0x1000>;
+			/* placeholder */
+		};
+
+		ohci0: usb@ee080000 {
+			reg = <0 0xee080000 0 0x100>;
+			/* placeholder */
+		};
+
+		ehci0: usb@ee080100 {
+			reg = <0 0xee080100 0 0x100>;
+			/* placeholder */
+		};
+
+		usb2_phy0: usb-phy@ee080200 {
+			reg = <0 0xee080200 0 0x700>;
+			/* placeholder */
+		};
+
+		usb2_phy1: usb-phy@ee0a0200 {
+			reg = <0 0xee0a0200 0 0x700>;
+			/* placeholder */
+		};
+
+		ohci1: usb@ee0a0000 {
+			reg = <0 0xee0a0000 0 0x100>;
+			/* placeholder */
+		};
+
+		ehci1: usb@ee0a0100 {
+			reg = <0 0xee0a0100 0 0x100>;
+			/* placeholder */
+		};
+
+		i2c0: i2c@e6500000 {
+			reg = <0 0xe6500000 0 0x40>;
+			/* placeholder */
+		};
+
+		i2c1: i2c@e6508000 {
+			reg = <0 0xe6508000 0 0x40>;
+			/* placeholder */
+		};
+
+		i2c2: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			reg = <0 0xe6510000 0 0x40>;
+			/* placeholder */
+		};
+
+		i2c3: i2c@e66d0000 {
+			reg = <0 0xe66d0000 0 0x40>;
+			/* placeholder */
+		};
+
+		i2c4: i2c@e66d8000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			reg = <0 0xe66d8000 0 0x40>;
+			/* placeholder */
+		};
+
+		i2c5: i2c@e66e0000 {
+			reg = <0 0xe66e0000 0 0x40>;
+			/* placeholder */
+		};
+
+		i2c6: i2c@e66e8000 {
+			reg = <0 0xe66e8000 0 0x40>;
+			/* placeholder */
+		};
+
+		i2c_dvfs: i2c@e60b0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,iic-r8a77965",
+				     "renesas,rcar-gen3-iic",
+				     "renesas,rmobile-iic";
+			reg = <0 0xe60b0000 0 0x425>;
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 926>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 926>;
+			dmas = <&dmac0 0x11>, <&dmac0 0x10>;
+			dma-names = "tx", "rx";
+			status = "disabled";
+		};
+
+		pwm0: pwm@e6e30000 {
+			reg = <0 0xe6e30000 0 8>;
+			/* placeholder */
+		};
+
+		pwm1: pwm@e6e31000 {
+			reg = <0 0xe6e31000 0 8>;
+			#pwm-cells = <2>;
+			/* placeholder */
+		};
+
+		pwm2: pwm@e6e32000 {
+			reg = <0 0xe6e32000 0 8>;
+			/* placeholder */
+		};
+
+		pwm3: pwm@e6e33000 {
+			reg = <0 0xe6e33000 0 8>;
+			/* placeholder */
+		};
+
+		pwm4: pwm@e6e34000 {
+			reg = <0 0xe6e34000 0 8>;
+			/* placeholder */
+		};
+
+		pwm5: pwm@e6e35000 {
+			reg = <0 0xe6e35000 0 8>;
+			/* placeholder */
+		};
+
+		pwm6: pwm@e6e36000 {
+			reg = <0 0xe6e36000 0 8>;
+			/* placeholder */
+		};
+
+		du: display@feb00000 {
+			reg = <0 0xfeb00000 0 0x80000>,
+			      <0 0xfeb90000 0 0x14>;
+			/* placeholder */
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+				port@1 {
+					reg = <1>;
+					du_out_hdmi0: endpoint {
+					};
+				};
+				port@2 {
+					reg = <2>;
+					du_out_lvds0: endpoint {
+					};
+				};
+			};
+		};
+
+		hsusb: usb@e6590000 {
+			reg = <0 0xe6590000 0 0x100>;
+			/* placeholder */
+		};
+
+		pciec0: pcie@fe000000 {
+			reg = <0 0xfe000000 0 0x80000>;
+			/* placeholder */
+		};
+
+		pciec1: pcie@ee800000 {
+			reg = <0 0xee800000 0 0x80000>;
+			/* placeholder */
+		};
+
+		rcar_sound: sound@ec500000 {
+			reg =	<0 0xec500000 0 0x1000>, /* SCU */
+				<0 0xec5a0000 0 0x100>,  /* ADG */
+				<0 0xec540000 0 0x1000>, /* SSIU */
+				<0 0xec541000 0 0x280>,  /* SSI */
+				<0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
+			/* placeholder */
+
+			rcar_sound,dvc {
+				dvc0: dvc-0 {
+				};
+				dvc1: dvc-1 {
+				};
+			};
+
+			rcar_sound,src {
+				src0: src-0 {
+				};
+				src1: src-1 {
+				};
+			};
+
+			rcar_sound,ssi {
+				ssi0: ssi-0 {
+				};
+				ssi1: ssi-1 {
+				};
+			};
+		};
+
+		sdhi0: sd@ee100000 {
+			reg = <0 0xee100000 0 0x2000>;
+			/* placeholder */
+		};
+
+		sdhi1: sd@ee120000 {
+			reg = <0 0xee120000 0 0x2000>;
+			/* placeholder */
+		};
+
+		sdhi2: sd@ee140000 {
+			reg = <0 0xee140000 0 0x2000>;
+			/* placeholder */
+		};
+
+		sdhi3: sd@ee160000 {
+			reg = <0 0xee160000 0 0x2000>;
+			/* placeholder */
+		};
+
+		usb3_phy0: usb-phy@e65ee000 {
+			reg = <0 0xe65ee000 0 0x90>;
+			#phy-cells = <0>;
+			/* placeholder */
+		};
+
+		usb3_peri0: usb@ee020000 {
+			reg = <0 0xee020000 0 0x400>;
+			/* placeholder */
+		};
+
+		xhci0: usb@ee000000 {
+			reg = <0 0xee000000 0 0xc00>;
+			/* placeholder */
+		};
+
+		wdt0: watchdog@e6020000 {
+			reg = <0 0xe6020000 0 0x0c>;
+			/* placeholder */
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
index 8fe5c19..3c5f598 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
@@ -36,11 +36,14 @@
 &avb {
 	renesas,no-ether-link;
 	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
 	status = "okay";
 
 	phy0: ethernet-phy@0 {
 		rxc-skew-ps = <1500>;
 		reg = <0>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
 	};
 };
 
@@ -52,11 +55,41 @@
 	clock-frequency = <32768>;
 };
 
+&i2c0 {
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+	clock-frequency = <400000>;
+
+	io_expander: gpio@20 {
+		compatible = "onnn,pca9654";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&pfc {
+	i2c0_pins: i2c0 {
+		groups = "i2c0";
+		function = "i2c0";
+	};
+
+	scif0_pins: scif0 {
+		groups = "scif0_data";
+		function = "scif0";
+	};
+};
+
 &rwdt {
 	timeout-sec = <60>;
 	status = "okay";
 };
 
 &scif0 {
+	pinctrl-0 = <&scif0_pins>;
+	pinctrl-names = "default";
+
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
index 8624ca8..a8ceeac 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
@@ -34,6 +34,7 @@
 &avb {
 	renesas,no-ether-link;
 	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
 	status = "okay";
 
 	phy0: ethernet-phy@0 {
@@ -50,6 +51,16 @@
 	clock-frequency = <32768>;
 };
 
+&pfc {
+	scif0_pins: scif0 {
+		groups = "scif0_data";
+		function = "scif0";
+	};
+};
+
 &scif0 {
+	pinctrl-0 = <&scif0_pins>;
+	pinctrl-names = "default";
+
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
index c35a117..c6db8ea 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
@@ -19,9 +19,12 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2";
-		method = "smc";
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
 	};
 
 	cpus {
@@ -60,6 +63,11 @@
 		clock-frequency = <0>;
 	};
 
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
 	/* External SCIF clock - to be overridden by boards that provide it */
 	scif_clk: scif {
 		compatible = "fixed-clock";
@@ -92,18 +100,6 @@
 			resets = <&cpg 408>;
 		};
 
-		timer {
-			compatible = "arm,armv8-timer";
-			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) |
-						  IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) |
-						  IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) |
-						  IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) |
-						  IRQ_TYPE_LEVEL_LOW)>;
-		};
-
 		rwdt: watchdog@e6020000 {
 			compatible = "renesas,r8a77970-wdt",
 				     "renesas,rcar-gen3-wdt";
@@ -178,6 +174,101 @@
 			#iommu-cells = <1>;
 		};
 
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a77970";
+			reg = <0 0xe6060000 0 0x504>;
+		};
+
+		gpio0: gpio@e6050000 {
+			compatible = "renesas,gpio-r8a77970",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6050000 0 0x50>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 0 22>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 912>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 912>;
+		};
+
+		gpio1: gpio@e6051000 {
+			compatible = "renesas,gpio-r8a77970",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6051000 0 0x50>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 32 28>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 911>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 911>;
+		};
+
+		gpio2: gpio@e6052000 {
+			compatible = "renesas,gpio-r8a77970",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6052000 0 0x50>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 64 17>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 910>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 910>;
+		};
+
+		gpio3: gpio@e6053000 {
+			compatible = "renesas,gpio-r8a77970",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6053000 0 0x50>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 96 17>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 909>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 909>;
+		};
+
+		gpio4: gpio@e6054000 {
+			compatible = "renesas,gpio-r8a77970",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6054000 0 0x50>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 128 6>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 908>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 908>;
+		};
+
+		gpio5: gpio@e6055000 {
+			compatible = "renesas,gpio-r8a77970",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6055000 0 0x50>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 160 15>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 907>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 907>;
+		};
+
 		intc_ex: interrupt-controller@e61c0000 {
 			compatible = "renesas,intc-ex-r8a77970", "renesas,irqc";
 			#interrupt-cells = <2>;
@@ -255,6 +346,91 @@
 			       <&ipmmu_ds1 22>, <&ipmmu_ds1 23>;
 		};
 
+		i2c0: i2c@e6500000 {
+			compatible = "renesas,i2c-r8a77970",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+			       <&dmac2 0x91>, <&dmac2 0x90>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6508000 {
+			compatible = "renesas,i2c-r8a77970",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+			       <&dmac2 0x93>, <&dmac2 0x92>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6510000 {
+			compatible = "renesas,i2c-r8a77970",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6510000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+			       <&dmac2 0x95>, <&dmac2 0x94>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e66d0000 {
+			compatible = "renesas,i2c-r8a77970",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d0000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			dmas = <&dmac1 0x97>, <&dmac1 0x96>,
+			       <&dmac2 0x97>, <&dmac2 0x96>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@e66d8000 {
+			compatible = "renesas,i2c-r8a77970",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d8000 0 0x40>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 927>;
+			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+			resets = <&cpg 927>;
+			dmas = <&dmac1 0x99>, <&dmac1 0x98>,
+			       <&dmac2 0x99>, <&dmac2 0x98>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		hscif0: serial@e6540000 {
 			compatible = "renesas,hscif-r8a77970",
 				     "renesas,rcar-gen3-hscif",
@@ -400,7 +576,7 @@
 		avb: ethernet@e6800000 {
 			compatible = "renesas,etheravb-r8a77970",
 				     "renesas,etheravb-rcar-gen3";
-			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+			reg = <0 0xe6800000 0 0x800>;
 			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
@@ -436,10 +612,18 @@
 			clocks = <&cpg CPG_MOD 812>;
 			power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
 			resets = <&cpg 812>;
-			phy-mode = "rgmii-id";
+			phy-mode = "rgmii";
 			iommus = <&ipmmu_rt 3>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 		};
 	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+	};
 };
diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
new file mode 100644
index 0000000..06cf684
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Condor board
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+/dts-v1/;
+#include "r8a77980.dtsi"
+
+/ {
+	model = "Renesas Condor board based on r8a77980";
+	compatible = "renesas,condor", "renesas,r8a77980";
+
+	aliases {
+		serial0 = &scif0;
+		ethernet0 = &avb;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0 0x48000000 0 0x78000000>;
+	};
+};
+
+&avb {
+	phy-mode = "rgmii-id";
+	phy-handle = <&phy0>;
+	renesas,no-ether-link;
+	status = "okay";
+
+	phy0: ethernet-phy@0 {
+		rxc-skew-ps = <1500>;
+		reg = <0>;
+	};
+};
+
+&extal_clk {
+	clock-frequency = <16666666>;
+};
+
+&extalr_clk {
+	clock-frequency = <32768>;
+};
+
+&scif0 {
+	status = "okay";
+};
+
+&scif_clk {
+	clock-frequency = <14745600>;
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
new file mode 100644
index 0000000..03845fd
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the r8a77980 SoC
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/ {
+	compatible = "renesas,r8a77980";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		a53_0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0>;
+			clocks = <&cpg CPG_CORE 0>;
+			power-domains = <&sysc 5>;
+			next-level-cache = <&L2_CA53>;
+			enable-method = "psci";
+		};
+
+		L2_CA53: cache-controller {
+			compatible = "cache";
+			power-domains = <&sysc 21>;
+			cache-unified;
+			cache-level = <2>;
+		};
+	};
+
+	extal_clk: extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board */
+		clock-frequency = <0>;
+	};
+
+	extalr_clk: extalr {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board */
+		clock-frequency = <0>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
+	/* External SCIF clock - to be overridden by boards that provide it */
+	scif_clk: scif {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a77980-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&extalr_clk>;
+			clock-names = "extal", "extalr";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a77980-rst";
+			reg = <0 0xe6160000 0 0x200>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a77980-sysc";
+			reg = <0 0xe6180000 0 0x440>;
+			#power-domain-cells = <1>;
+		};
+
+		hscif0: serial@e6540000 {
+			compatible = "renesas,hscif-r8a77980",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6540000 0 0x60>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 520>,
+				 <&cpg CPG_CORE 19>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 520>;
+			status = "disabled";
+		};
+
+		hscif1: serial@e6550000 {
+			compatible = "renesas,hscif-r8a77980",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6550000 0 0x60>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 519>,
+				 <&cpg CPG_CORE 19>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+			       <&dmac2 0x33>, <&dmac2 0x32>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 519>;
+			status = "disabled";
+		};
+
+		hscif2: serial@e6560000 {
+			compatible = "renesas,hscif-r8a77980",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6560000 0 0x60>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 518>,
+				 <&cpg CPG_CORE 19>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+			       <&dmac2 0x35>, <&dmac2 0x34>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 518>;
+			status = "disabled";
+		};
+
+		hscif3: serial@e66a0000 {
+			compatible = "renesas,hscif-r8a77980",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe66a0000 0 0x60>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 517>,
+				 <&cpg CPG_CORE 19>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x37>, <&dmac1 0x36>,
+			       <&dmac2 0x37>, <&dmac2 0x36>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 517>;
+			status = "disabled";
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a77980",
+				     "renesas,etheravb-rcar-gen3";
+			reg = <0 0xe6800000 0 0x800>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 812>;
+			phy-mode = "rgmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a77980",
+				     "renesas,rcar-gen3-scif",
+				     "renesas,scif";
+			reg = <0 0xe6e60000 0 0x40>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>,
+				 <&cpg CPG_CORE 19>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+			       <&dmac2 0x51>, <&dmac2 0x50>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 207>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a77980",
+				     "renesas,rcar-gen3-scif",
+				     "renesas,scif";
+			reg = <0 0xe6e68000 0 0x40>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>,
+				 <&cpg CPG_CORE 19>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+			       <&dmac2 0x53>, <&dmac2 0x52>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 206>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6c50000 {
+			compatible = "renesas,scif-r8a77980",
+				     "renesas,rcar-gen3-scif",
+				     "renesas,scif";
+			reg = <0 0xe6c50000 0 0x40>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>,
+				 <&cpg CPG_CORE 19>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x57>, <&dmac1 0x56>,
+			       <&dmac2 0x57>, <&dmac2 0x56>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6c40000 {
+			compatible = "renesas,scif-r8a77980",
+				     "renesas,rcar-gen3-scif",
+				     "renesas,scif";
+			reg = <0 0xe6c40000 0 0x40>;
+			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>,
+				 <&cpg CPG_CORE 19>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x59>, <&dmac1 0x58>,
+			       <&dmac2 0x59>, <&dmac2 0x58>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		dmac1: dma-controller@e7300000 {
+			compatible = "renesas,dmac-r8a77980",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7300000 0 0x10000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 218>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+		};
+
+		dmac2: dma-controller@e7310000 {
+			compatible = "renesas,dmac-r8a77980",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe7310000 0 0x10000>;
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 366 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 217>;
+			clock-names = "fck";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 217>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+		};
+
+		gic: interrupt-controller@f1010000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xf1010000 0 0x1000>,
+			      <0x0 0xf1020000 0 0x20000>,
+			      <0x0 0xf1040000 0 0x20000>,
+			      <0x0 0xf1060000 0 0x20000>;
+			interrupts = <GIC_PPI 9	(GIC_CPU_MASK_SIMPLE(1) |
+				      IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 408>;
+		};
+
+		prr: chipid@fff00044 {
+			compatible = "renesas,prr";
+			reg = <0 0xfff00044 0 4>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) |
+				       IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) |
+				       IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) |
+				       IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) |
+				       IRQ_TYPE_LEVEL_LOW)>;
+	};
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index 09de73b..d03f194 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
@@ -27,11 +27,61 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	vga {
+		compatible = "vga-connector";
+
+		port {
+			vga_in: endpoint {
+				remote-endpoint = <&adv7123_out>;
+			};
+		};
+	};
+
+	vga-encoder {
+		compatible = "adi,adv7123";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7123_in: endpoint {
+					remote-endpoint = <&du_out_rgb>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				adv7123_out: endpoint {
+					remote-endpoint = <&vga_in>;
+				};
+			};
+		};
+	};
+
 	memory@48000000 {
 		device_type = "memory";
 		/* first 128MB is reserved for secure area. */
 		reg = <0x0 0x48000000 0x0 0x18000000>;
 	};
+
+	reg_1p8v: regulator0 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator1 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
 };
 
 &extal_clk {
@@ -46,6 +96,21 @@
 		};
 	};
 
+	du_pins: du {
+		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
+		function = "du";
+	};
+
+	i2c0_pins: i2c0 {
+		groups = "i2c0";
+		function = "i2c0";
+	};
+
+	i2c1_pins: i2c1 {
+		groups = "i2c1";
+		function = "i2c1";
+	};
+
 	pwm0_pins: pwm0 {
 		groups = "pwm0_c";
 		function = "pwm0";
@@ -61,12 +126,56 @@
 		function = "scif2";
 	};
 
+	sdhi2_pins: sd2 {
+		groups = "mmc_data8", "mmc_ctrl";
+		function = "mmc";
+		power-source = <1800>;
+	};
+
+	sdhi2_pins_uhs: sd2_uhs {
+		groups = "mmc_data8", "mmc_ctrl";
+		function = "mmc";
+		power-source = <1800>;
+	};
+
 	usb0_pins: usb0 {
 		groups = "usb0";
 		function = "usb0";
 	};
 };
 
+&i2c0 {
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	eeprom@50 {
+		compatible = "rohm,br24t01", "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+	};
+};
+
+&i2c1 {
+	pinctrl-0 = <&i2c1_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&du {
+	pinctrl-0 = <&du_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	ports {
+		port@0 {
+			endpoint {
+				remote-endpoint = <&adv7123_in>;
+			};
+		};
+	};
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -80,6 +189,7 @@
 	pinctrl-names = "default";
 	renesas,no-ether-link;
 	phy-handle = <&phy0>;
+	phy-mode = "rgmii-txid";
 	status = "okay";
 
 	phy0: ethernet-phy@0 {
@@ -97,6 +207,20 @@
 	status = "okay";
 };
 
+&sdhi2 {
+	/* used for on-board eMMC */
+	pinctrl-0 = <&sdhi2_pins>;
+	pinctrl-1 = <&sdhi2_pins_uhs>;
+	pinctrl-names = "default", "state_uhs";
+
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_1p8v>;
+	bus-width = <8>;
+	mmc-hs200-1_8v;
+	non-removable;
+	status = "okay";
+};
+
 &usb2_phy0 {
 	pinctrl-0 = <&usb0_pins>;
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index cff42cd..82aed7e 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -58,6 +58,11 @@
 		clock-frequency = <0>;
 	};
 
+	pmu_a53 {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	scif_clk: scif {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
@@ -88,18 +93,6 @@
 			resets = <&cpg 408>;
 		};
 
-		timer {
-			compatible = "arm,armv8-timer";
-			interrupts = <GIC_PPI 13
-					(GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 14
-					(GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 11
-					(GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 10
-					(GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
-		};
-
 		rwdt: watchdog@e6020000 {
 			compatible = "renesas,r8a77995-wdt",
 				     "renesas,rcar-gen3-wdt";
@@ -110,11 +103,6 @@
 			status = "disabled";
 		};
 
-		pmu_a53 {
-			compatible = "arm,cortex-a53-pmu";
-			interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
 		ipmmu_vi0: mmu@febd0000 {
 			compatible = "renesas,ipmmu-r8a77995";
 			reg = <0 0xfebd0000 0 0x1000>;
@@ -488,7 +476,7 @@
 		avb: ethernet@e6800000 {
 			compatible = "renesas,etheravb-r8a77995",
 				     "renesas,etheravb-rcar-gen3";
-			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+			reg = <0 0xe6800000 0 0x800>;
 			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
@@ -524,7 +512,7 @@
 			clocks = <&cpg CPG_MOD 812>;
 			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
 			resets = <&cpg 812>;
-			phy-mode = "rgmii-txid";
+			phy-mode = "rgmii";
 			iommus = <&ipmmu_ds0 16>;
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -548,6 +536,73 @@
 			status = "disabled";
 		};
 
+		i2c0: i2c@e6500000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77995",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 931>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 931>;
+			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+			       <&dmac2 0x91>, <&dmac2 0x90>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@e6508000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77995",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 930>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 930>;
+			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+			       <&dmac2 0x93>, <&dmac2 0x92>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@e6510000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77995",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe6510000 0 0x40>;
+			interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 929>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 929>;
+			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+			       <&dmac2 0x95>, <&dmac2 0x94>;
+			dma-names = "tx", "rx", "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
+		i2c3: i2c@e66d0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "renesas,i2c-r8a77995",
+				     "renesas,rcar-gen3-i2c";
+			reg = <0 0xe66d0000 0 0x40>;
+			interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 928>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 928>;
+			dmas = <&dmac0 0x97>, <&dmac0 0x96>;
+			dma-names = "tx", "rx";
+			i2c-scl-internal-delay-ns = <6>;
+			status = "disabled";
+		};
+
 		pwm0: pwm@e6e30000 {
 			compatible = "renesas,pwm-r8a77995", "renesas,pwm-rcar";
 			reg = <0 0xe6e30000 0 0x8>;
@@ -636,5 +691,105 @@
 			#phy-cells = <0>;
 			status = "disabled";
 		};
+
+		vspbs: vsp@fe960000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfe960000 0 0x8000>;
+			interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 627>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 627>;
+			renesas,fcp = <&fcpvb0>;
+		};
+
+		fcpvb0: fcp@fe96f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfe96f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 607>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 607>;
+			iommus = <&ipmmu_vp0 5>;
+		};
+
+		vspd0: vsp@fea20000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea20000 0 0x8000>;
+			interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 623>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 623>;
+			renesas,fcp = <&fcpvd0>;
+		};
+
+		fcpvd0: fcp@fea27000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea27000 0 0x200>;
+			clocks = <&cpg CPG_MOD 603>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 603>;
+			iommus = <&ipmmu_vi0 8>;
+		};
+
+		vspd1: vsp@fea28000 {
+			compatible = "renesas,vsp2";
+			reg = <0 0xfea28000 0 0x8000>;
+			interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 622>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 622>;
+			renesas,fcp = <&fcpvd1>;
+		};
+
+		fcpvd1: fcp@fea2f000 {
+			compatible = "renesas,fcpv";
+			reg = <0 0xfea2f000 0 0x200>;
+			clocks = <&cpg CPG_MOD 602>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 602>;
+			iommus = <&ipmmu_vi0 9>;
+		};
+
+		du: display@feb00000 {
+			compatible = "renesas,du-r8a77995";
+			reg = <0 0xfeb00000 0 0x80000>;
+			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 724>,
+				 <&cpg CPG_MOD 723>;
+			clock-names = "du.0", "du.1";
+			vsps = <&vspd0 0 &vspd1 0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					du_out_rgb: endpoint {
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					du_out_lvds0: endpoint {
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					du_out_lvds1: endpoint {
+					};
+				};
+			};
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 };
diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
index c3fafb6..2a7f36a 100644
--- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
@@ -256,6 +256,7 @@
 	pinctrl-0 = <&avb_pins>;
 	pinctrl-names = "default";
 	phy-handle = <&phy0>;
+	phy-mode = "rgmii-txid";
 	status = "okay";
 
 	phy0: ethernet-phy@0 {
@@ -338,6 +339,13 @@
 &i2c4 {
 	status = "okay";
 
+	pca9654: gpio@20 {
+		compatible = "onnn,pca9654";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
 	csa_vdd: adc@7c {
 		compatible = "maxim,max9611";
 		reg = <0x7c>;
diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi
index 3e7a6b9..6f81484 100644
--- a/arch/arm64/boot/dts/renesas/ulcb.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi
@@ -146,6 +146,7 @@
 	pinctrl-0 = <&avb_pins>;
 	pinctrl-names = "default";
 	phy-handle = <&phy0>;
+	phy-mode = "rgmii-txid";
 	status = "okay";
 
 	phy0: ethernet-phy@0 {
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index ce2701e..48a83f8 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -1,8 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-lion-haikou.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-px5-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb
@@ -10,4 +12,5 @@
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
new file mode 100644
index 0000000..246c317
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 T-Chip Intelligent Technology Co., Ltd
+ */
+
+/dts-v1/;
+#include "rk3328.dtsi"
+
+/ {
+	model = "Firefly roc-rk3328-cc";
+	compatible = "firefly,roc-rk3328-cc", "rockchip,rk3328";
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	gmac_clkin: external-gmac-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "gmac_clkin";
+		#clock-cells = <0>;
+	};
+
+	dc_12v: dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc_sd: sdmmc-regulator {
+		compatible = "regulator-fixed";
+		gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc0m1_gpio>;
+		regulator-name = "vcc_sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb20_host_drv>;
+		regulator-name = "vcc_host1_5v";
+		regulator-always-on;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc_sys: vcc-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc_phy: vcc-phy-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_phy";
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&emmc {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+	status = "okay";
+};
+
+&gmac2io {
+	assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
+	assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>;
+	clock_in_out = "input";
+	phy-supply = <&vcc_phy>;
+	phy-mode = "rgmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmiim1_pins>;
+	snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 50000>;
+	tx_delay = <0x25>;
+	rx_delay = <0x11>;
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+
+	rk805: pmic@18 {
+		compatible = "rockchip,rk805";
+		reg = <0x18>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <1>;
+		clock-output-names = "xin32k", "rk805-clkout2";
+		gpio-controller;
+		#gpio-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>;
+		rockchip,system-power-controller;
+		wakeup-source;
+
+		vcc1-supply = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc5-supply = <&vcc_io>;
+		vcc6-supply = <&vcc_io>;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-min-microvolt = <712500>;
+				regulator-max-microvolt = <1450000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+
+			vdd_arm: DCDC_REG2 {
+				regulator-name = "vdd_arm";
+				regulator-min-microvolt = <712500>;
+				regulator-max-microvolt = <1450000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <950000>;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_io: DCDC_REG4 {
+				regulator-name = "vcc_io";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_18: LDO_REG1 {
+				regulator-name = "vcc_18";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc18_emmc: LDO_REG2 {
+				regulator-name = "vcc18_emmc";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_10: LDO_REG3 {
+				regulator-name = "vdd_10";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+		};
+	};
+};
+
+&pinctrl {
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb2 {
+		usb20_host_drv: usb20-host-drv {
+			rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	disable-wp;
+	max-frequency = <150000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>;
+	vmmc-supply = <&vcc_sd>;
+	status = "okay";
+};
+
+&tsadc {
+	status = "okay";
+};
+
+&u2phy {
+	status = "okay";
+};
+
+&u2phy_host {
+	status = "okay";
+};
+
+&u2phy_otg {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb20_otg {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index cae3415..be2bfbc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -318,7 +318,7 @@
 		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
 		clock-names = "baudclk", "apb_pclk";
 		dmas = <&dmac 2>, <&dmac 3>;
-		#dma-cells = <2>;
+		dma-names = "tx", "rx";
 		pinctrl-names = "default";
 		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
 		reg-io-width = <4>;
@@ -333,7 +333,7 @@
 		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
 		clock-names = "sclk_uart", "pclk_uart";
 		dmas = <&dmac 4>, <&dmac 5>;
-		#dma-cells = <2>;
+		dma-names = "tx", "rx";
 		pinctrl-names = "default";
 		pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>;
 		reg-io-width = <4>;
@@ -348,7 +348,7 @@
 		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
 		clock-names = "baudclk", "apb_pclk";
 		dmas = <&dmac 6>, <&dmac 7>;
-		#dma-cells = <2>;
+		dma-names = "tx", "rx";
 		pinctrl-names = "default";
 		pinctrl-0 = <&uart2m1_xfer>;
 		reg-io-width = <4>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-lion-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3368-lion-haikou.dts
new file mode 100644
index 0000000..fca8e87
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3368-lion-haikou.dts
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+#include "rk3368-lion.dtsi"
+
+/ {
+	model = "Theobroma Systems RK3368-uQ7 Baseboard";
+	compatible = "tsd,rk3368-lion-haikou", "rockchip,rk3368";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	i2cmux2 {
+		i2c@0 {
+			eeprom: eeprom@50 {
+				compatible = "atmel,24c01";
+				pagesize = <8>;
+				reg = <0x50>;
+			};
+		};
+	};
+
+	leds {
+		pinctrl-0 = <&led_pins_module>, <&led_sd_haikou>;
+
+		sd-card-led {
+			label = "sd_card_led";
+			gpios = <&gpio0 RK_PD2 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+		};
+	};
+
+	dc_12v: dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc3v3_baseboard: vcc3v3-baseboard {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_baseboard";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_otg: vcc5v0-otg-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&otg_vbus_drv>;
+		regulator-name = "vcc5v0_otg";
+		regulator-always-on;
+	};
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	max-frequency = <25000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
+	rockchip,default-sample-phase = <90>;
+	vmmc-supply = <&vcc3v3_baseboard>;
+	status = "okay";
+};
+
+&spi2 {
+	cs-gpios = <0>, <&gpio2 RK_PC3 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+	status = "okay";
+};
+
+&uart1 {
+	/* alternate function of GPIO5/6 */
+	status = "disabled";
+};
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&haikou_pin_hog>;
+
+	hog {
+		haikou_pin_hog: haikou-pin-hog {
+			rockchip,pins =
+				/* LID_BTN */
+				<RK_GPIO3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>,
+				/* BATLOW# */
+				<RK_GPIO0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>,
+				/* SLP_BTN# */
+				<RK_GPIO3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>,
+				/* BIOS_DISABLE# */
+				<RK_GPIO3 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	leds {
+		led_sd_haikou: led-sd-gpio {
+			rockchip,pins =
+				<RK_GPIO0 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdmmc {
+		sdmmc_cd_gpio: sdmmc-cd-gpio {
+			rockchip,pins =
+				<RK_GPIO2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb_otg {
+		otg_vbus_drv: otg-vbus-drv {
+			rockchip,pins =
+				<RK_GPIO0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi
new file mode 100644
index 0000000..1315972
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+#include "rk3368.dtsi"
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	ext_gmac: gmac-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "ext_gmac";
+		#clock-cells = <0>;
+	};
+
+	i2cmux1 {
+		compatible = "i2c-mux-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-parent = <&i2c1>;
+		mux-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
+
+		/* Q7_GPO_I2C */
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		/* Q7_SMB */
+		i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	i2cmux2 {
+		compatible = "i2c-mux-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-parent = <&i2c2>;
+		mux-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>;
+
+		/* Q7_LVDS_BLC_I2C */
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fan: fan@18 {
+				compatible = "ti,amc6821";
+				reg = <0x18>;
+				cooling-min-state = <0>;
+				cooling-max-state = <9>;
+				#cooling-cells = <2>;
+			};
+
+			rtc_twi: rtc@6f {
+				compatible = "isil,isl1208";
+				reg = <0x6f>;
+			};
+		};
+
+		/* Q7_GP2_I2C */
+		i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_module>;
+
+		module_led1 {
+			label = "module_led1";
+			gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			panic-indicator;
+		};
+
+		module_led2 {
+			label = "module_led2";
+			gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	vcc_sys: vcc-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&emmc {
+	bus-width = <8>;
+	clock-frequency = <150000000>;
+	disable-wp;
+	mmc-hs200-1_8v;
+	non-removable;
+	vmmc-supply = <&vcc33_io>;
+	vqmmc-supply = <&vcc18_io>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>;
+	status = "okay";
+};
+
+&gmac {
+	assigned-clocks = <&cru SCLK_MAC>;
+	assigned-clock-parents = <&ext_gmac>;
+	clock_in_out = "input";
+	phy-supply = <&vcc33_io>;
+	phy-mode = "rgmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 50000>;
+	snps,reset-gpio = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+	tx_delay = <0x10>;
+	rx_delay = <0x10>;
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk808: pmic@1b {
+		compatible = "rockchip,rk808";
+		reg = <0x1b>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA5 IRQ_TYPE_LEVEL_LOW>;
+		clock-output-names = "xin32k", "rk808-clkout2";
+		#clock-cells = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>, <&pmic_sleep>;
+		rockchip,system-power-controller;
+		vcc1-supply = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
+		vcc8-supply = <&vcc_sys>;
+		vcc9-supply = <&vcc_sys>;
+		vcc10-supply = <&vcc_sys>;
+		vcc11-supply = <&vcc_sys>;
+		vcc12-supply = <&vcc_sys>;
+
+		regulators {
+			vdd_cpu: DCDC_REG1 {
+				regulator-name = "vdd_cpu";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vdd_log: DCDC_REG2 {
+				regulator-name = "vdd_log";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc33_io: DCDC_REG4 {
+				regulator-name = "vcc33_io";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc33_video: LDO_REG2 {
+				regulator-name = "vcc33_video";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vdd10_pll: LDO_REG3 {
+				regulator-name = "vdd10_pll";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc18_io: LDO_REG4 {
+				regulator-name = "vcc18_io";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+			};
+
+			vdd10_video: LDO_REG6 {
+				regulator-name = "vdd10_video";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc18_video: LDO_REG8 {
+				regulator-name = "vcc18_video";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&pinctrl {
+	leds {
+		led_pins_module: led-module-gpio {
+			rockchip,pins =
+				<RK_GPIO2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>,
+				<RK_GPIO3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <RK_GPIO0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		pmic_sleep: pmic-sleep {
+			rockchip,pins = <RK_GPIO0 RK_PA0 RK_FUNC_2 &pcfg_pull_none>;
+		};
+	};
+};
+
+&spi1 {
+	status = "okay";
+
+	norflash: flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&wdt {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index 204bdb9..18f546f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -516,10 +516,15 @@
 		compatible = "rockchip,rk3399-gru-sound";
 		rockchip,cpu = <&i2s0 &i2s2>;
 		rockchip,codec = <&max98357a &headsetcodec
-				  &codec &wacky_spi_audio>;
+				  &codec &wacky_spi_audio &cdn_dp>;
 	};
 };
 
+&cdn_dp {
+	status = "okay";
+	extcon = <&usbc_extcon0>, <&usbc_extcon1>;
+};
+
 /*
  * Set some suspend operating points to avoid OVP in suspend
  *
@@ -582,7 +587,8 @@
 		<&cru PCLK_PERIHP>,
 		<&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>,
 		<&cru PCLK_PERILP0>, <&cru ACLK_CCI>,
-		<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>;
+		<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>,
+		<&cru ACLK_VIO>;
 	assigned-clock-rates =
 		<600000000>, <800000000>,
 		<1000000000>,
@@ -590,7 +596,8 @@
 		<37500000>,
 		<100000000>, <100000000>,
 		<50000000>, <800000000>,
-		<100000000>, <50000000>;
+		<100000000>, <50000000>,
+		<400000000>;
 };
 
 &emmc_phy {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
index 9a74860..7d3e8bf 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
@@ -61,6 +61,30 @@
 		};
 	};
 
+	i2s0-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,name = "Haikou,I2S-codec";
+		simple-audio-card,mclk-fs = <512>;
+
+		simple-audio-card,codec {
+			clocks = <&sgtl5000_clk>;
+			sound-dai = <&sgtl5000>;
+		};
+
+		simple-audio-card,cpu {
+			bitclock-master;
+			frame-master;
+			sound-dai = <&i2s0>;
+		};
+	};
+
+	sgtl5000_clk: sgtl5000-oscillator  {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency  = <24576000>;
+	};
+
 	dc_12v: dc-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "dc_12v";
@@ -80,6 +104,16 @@
 		vin-supply = <&dc_12v>;
 	};
 
+	vcc5v0_baseboard: vcc5v0-baseboard {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_baseboard";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
 	vcc5v0_otg: vcc5v0-otg-regulator {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -89,6 +123,24 @@
 		regulator-name = "vcc5v0_otg";
 		regulator-always-on;
 	};
+
+	vdda_codec: vdda-codec {
+		compatible = "regulator-fixed";
+		regulator-name = "vdda_codec";
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc5v0_baseboard>;
+	};
+
+	vddd_codec: vddd-codec {
+		compatible = "regulator-fixed";
+		regulator-name = "vddd_codec";
+		regulator-boot-on;
+		regulator-min-microvolt = <1600000>;
+		regulator-max-microvolt = <1600000>;
+		vin-supply = <&vcc5v0_baseboard>;
+	};
 };
 
 &i2c1 {
@@ -110,6 +162,17 @@
 &i2c4 {
 	status = "okay";
 	clock-frequency = <400000>;
+
+	sgtl5000: codec@0a {
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		clocks = <&sgtl5000_clk>;
+		#sound-dai-cells = <0>;
+		VDDA-supply = <&vdda_codec>;
+		VDDIO-supply = <&vdda_codec>;
+		VDDD-supply = <&vddd_codec>;
+		status = "okay";
+	};
 };
 
 &i2c6 {
@@ -117,14 +180,6 @@
 	clock-frequency = <400000>;
 };
 
-&i2s0 {
-	status = "okay";
-	rockchip,playback-channels = <8>;
-	rockchip,capture-channels = <8>;
-	#sound-dai-cells = <0>;
-	status = "okay";
-};
-
 &pcie_phy {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
index 1fc5060..4a2d06a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -435,6 +435,28 @@
 	};
 };
 
+&i2s0 {
+	pinctrl-0 = <&i2s0_2ch_bus>;
+	rockchip,playback-channels = <2>;
+	rockchip,capture-channels = <2>;
+	#sound-dai-cells = <0>;
+	status = "okay";
+};
+
+/*
+ * As Q7 does not specify neither a global nor a RX clock for I2S these
+ * signals are not used. Furthermore I2S0_LRCK_RX is used as GPIO.
+ * Therefore we have to redefine the i2s0_2ch_bus definition to prevent
+ * conflicts.
+ */
+&i2s0_2ch_bus {
+	rockchip,pins =
+		<RK_GPIO3 RK_PD0 RK_FUNC_1 &pcfg_pull_none>,
+		<RK_GPIO3 RK_PD2 RK_FUNC_1 &pcfg_pull_none>,
+		<RK_GPIO3 RK_PD3 RK_FUNC_1 &pcfg_pull_none>,
+		<RK_GPIO3 RK_PD7 RK_FUNC_1 &pcfg_pull_none>;
+};
+
 &io_domains {
 	status = "okay";
 	bt656-supply = <&vcc_1v8>;
@@ -505,6 +527,12 @@
 	};
 };
 
+&tsadc {
+	rockchip,hw-tshut-mode = <1>;
+	rockchip,hw-tshut-polarity = <1>;
+	status = "okay";
+};
+
 &u2phy1 {
 	status = "okay";
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
index b7bd88f..56952d1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
@@ -41,7 +41,6 @@
  */
 
 /dts-v1/;
-#include <dt-bindings/input/input.h>
 #include "rk3399-sapphire.dtsi"
 
 / {
@@ -95,22 +94,6 @@
 		};
 	};
 
-	keys: gpio-keys {
-		compatible = "gpio-keys";
-		autorepeat;
-
-		power {
-			debounce-interval = <100>;
-			gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
-			label = "GPIO Power";
-			linux,code = <KEY_POWER>;
-			linux,input-type = <1>;
-			pinctrl-names = "default";
-			pinctrl-0 = <&pwr_btn>;
-			wakeup-source;
-		};
-	};
-
 	rt5651-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,name = "realtek,rt5651-codec";
@@ -207,18 +190,7 @@
 	status = "okay";
 };
 
-&i2s2 {
-	#sound-dai-cells = <0>;
-	status = "okay";
-};
-
 &pinctrl {
-	buttons {
-		pwr_btn: pwr-btn {
-			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-	};
-
 	sdio-pwrseq {
 		wifi_enable_h: wifi-enable-h {
 			rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -232,6 +204,22 @@
 	};
 };
 
+&sdio0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	clock-frequency = <50000000>;
+	disable-wp;
+	keep-power-in-suspend;
+	max-frequency = <50000000>;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+	sd-uhs-sdr104;
+	status = "okay";
+};
+
 &spdif {
 	i2c-scl-rising-time-ns = <450>;
 	i2c-scl-falling-time-ns = <15>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dts
new file mode 100644
index 0000000..5a58060
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+#include "rk3399-sapphire.dtsi"
+
+/ {
+	model = "Sapphire-RK3399 Board";
+	compatible = "rockchip,rk3399-sapphire", "rockchip,rk3399";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
index ce592a4..e5daed7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
@@ -41,6 +41,7 @@
  */
 
 #include "dt-bindings/pwm/pwm.h"
+#include "dt-bindings/input/input.h"
 #include "rk3399.dtsi"
 #include "rk3399-opp.dtsi"
 
@@ -102,6 +103,22 @@
 		regulator-max-microvolt = <12000000>;
 	};
 
+	keys: gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+
+		power {
+			debounce-interval = <100>;
+			gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+			label = "GPIO Power";
+			linux,code = <KEY_POWER>;
+			linux,input-type = <1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pwr_btn>;
+			wakeup-source;
+		};
+	};
+
 	/* switched by pmic_sleep */
 	vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 {
 		compatible = "regulator-fixed";
@@ -143,6 +160,17 @@
 		regulator-always-on;
 		vin-supply = <&vcc_sys>;
 	};
+
+	vdd_log: vdd-log {
+		compatible = "pwm-regulator";
+		pwms = <&pwm2 0 25000 1>;
+		regulator-name = "vdd_log";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1400000>;
+		vin-supply = <&vcc_sys>;
+	};
 };
 
 &cpu_l0 {
@@ -421,17 +449,6 @@
 			regulator-off-in-suspend;
 		};
 	};
-
-	vdd_log: vdd-log {
-		compatible = "pwm-regulator";
-		pwms = <&pwm2 0 25000 1>;
-		regulator-name = "vdd_log";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <800000>;
-		regulator-max-microvolt = <1400000>;
-		vin-supply = <&vcc_sys>;
-	};
 };
 
 &i2c3 {
@@ -440,6 +457,11 @@
 	status = "okay";
 };
 
+&i2s2 {
+	#sound-dai-cells = <0>;
+	status = "okay";
+};
+
 &io_domains {
 	status = "okay";
 
@@ -470,6 +492,12 @@
 };
 
 &pinctrl {
+	buttons {
+		pwr_btn: pwr-btn {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
 	pmic {
 		pmic_int_l: pmic-int-l {
 			rockchip,pins =
@@ -513,29 +541,12 @@
 
 &sdhci {
 	bus-width = <8>;
-	keep-power-in-suspend;
 	mmc-hs400-1_8v;
 	mmc-hs400-enhanced-strobe;
 	non-removable;
 	status = "okay";
 };
 
-&sdio0 {
-	bus-width = <4>;
-	cap-sd-highspeed;
-	cap-sdio-irq;
-	clock-frequency = <50000000>;
-	disable-wp;
-	keep-power-in-suspend;
-	max-frequency = <50000000>;
-	mmc-pwrseq = <&sdio_pwrseq>;
-	non-removable;
-	pinctrl-names = "default";
-	pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
-	sd-uhs-sdr104;
-	status = "okay";
-};
-
 &sdmmc {
 	bus-width = <4>;
 	cap-mmc-highspeed;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 0b81ca1..4550c0f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -457,6 +457,42 @@
 		};
 	};
 
+	cdn_dp: dp@fec00000 {
+		compatible = "rockchip,rk3399-cdn-dp";
+		reg = <0x0 0xfec00000 0x0 0x100000>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+		assigned-clocks = <&cru SCLK_DP_CORE>;
+		assigned-clock-rates = <100000000>;
+		clocks = <&cru SCLK_DP_CORE>, <&cru PCLK_DP_CTRL>,
+			 <&cru SCLK_SPDIF_REC_DPTX>, <&cru PCLK_VIO_GRF>;
+		clock-names = "core-clk", "pclk", "spdif", "grf";
+		phys = <&tcphy0_dp>, <&tcphy1_dp>;
+		power-domains = <&power RK3399_PD_HDCP>;
+		resets = <&cru SRST_DPTX_SPDIF_REC>, <&cru SRST_P_UPHY0_DPTX>,
+			 <&cru SRST_P_UPHY0_APB>, <&cru SRST_DP_CORE>;
+		reset-names = "spdif", "dptx", "apb", "core";
+		rockchip,grf = <&grf>;
+		#sound-dai-cells = <1>;
+		status = "disabled";
+
+		ports {
+			dp_in: port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				dp_in_vopb: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&vopb_out_dp>;
+				};
+
+				dp_in_vopl: endpoint@1 {
+					reg = <1>;
+					remote-endpoint = <&vopl_out_dp>;
+				};
+			};
+		};
+	};
+
 	gic: interrupt-controller@fee00000 {
 		compatible = "arm,gic-v3";
 		#interrupt-cells = <4>;
@@ -1286,7 +1322,8 @@
 			<&cru PCLK_PERIHP>,
 			<&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>,
 			<&cru PCLK_PERILP0>, <&cru ACLK_CCI>,
-			<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>;
+			<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>,
+			<&cru ACLK_VIO>;
 		assigned-clock-rates =
 			 <594000000>,  <800000000>,
 			<1000000000>,
@@ -1294,7 +1331,8 @@
 			  <37500000>,
 			 <100000000>,  <100000000>,
 			  <50000000>, <600000000>,
-			 <100000000>,   <50000000>;
+			 <100000000>,   <50000000>,
+			 <400000000>;
 	};
 
 	grf: syscon@ff770000 {
@@ -1547,6 +1585,11 @@
 				reg = <3>;
 				remote-endpoint = <&mipi1_in_vopl>;
 			};
+
+			vopl_out_dp: endpoint@4 {
+				reg = <4>;
+				remote-endpoint = <&dp_in_vopl>;
+			};
 		};
 	};
 
@@ -1599,6 +1642,11 @@
 				reg = <3>;
 				remote-endpoint = <&mipi1_in_vopb>;
 			};
+
+			vopb_out_dp: endpoint@4 {
+				reg = <4>;
+				remote-endpoint = <&dp_in_vopb>;
+			};
 		};
 	};
 
@@ -2043,6 +2091,16 @@
 		};
 
 		i2s0 {
+			i2s0_2ch_bus: i2s0-2ch-bus {
+				rockchip,pins =
+					<3 24 RK_FUNC_1 &pcfg_pull_none>,
+					<3 25 RK_FUNC_1 &pcfg_pull_none>,
+					<3 26 RK_FUNC_1 &pcfg_pull_none>,
+					<3 27 RK_FUNC_1 &pcfg_pull_none>,
+					<3 31 RK_FUNC_1 &pcfg_pull_none>,
+					<4 0 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
 			i2s0_8ch_bus: i2s0-8ch-bus {
 				rockchip,pins =
 					<3 24 RK_FUNC_1 &pcfg_pull_none>,
@@ -2293,6 +2351,23 @@
 			};
 		};
 
+		testclk {
+			test_clkout0: test-clkout0 {
+				rockchip,pins =
+					<0 0 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			test_clkout1: test-clkout1 {
+				rockchip,pins =
+					<2 25 RK_FUNC_2 &pcfg_pull_none>;
+			};
+
+			test_clkout2: test-clkout2 {
+				rockchip,pins =
+					<0 8 RK_FUNC_3 &pcfg_pull_none>;
+			};
+		};
+
 		tsadc {
 			otp_gpio: otp-gpio {
 				rockchip,pins = <1 6 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts b/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts
index 2452b22..9b4dc41 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts
@@ -1,14 +1,13 @@
-/*
- * Device Tree Source for UniPhier LD11 Global Board
- *
- * Copyright (C) 2016-2017 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *           Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD11 Global Board
+//
+// Copyright (C) 2016-2017 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+//           Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
 
 /dts-v1/;
+#include <dt-bindings/gpio/uniphier-gpio.h>
 #include "uniphier-ld11.dtsi"
 
 / {
@@ -37,6 +36,53 @@
 		device_type = "memory";
 		reg = <0 0x80000000 0 0x40000000>;
 	};
+
+	dvdd_reg: reg-fixed {
+		compatible = "regulator-fixed";
+		regulator-name = "DVDD";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	amp_vcc_reg: reg-fixed {
+		compatible = "regulator-fixed";
+		regulator-name = "AMP_VCC";
+		regulator-min-microvolt = <24000000>;
+		regulator-max-microvolt = <24000000>;
+	};
+
+	sound {
+		compatible = "audio-graph-card";
+		label = "UniPhier LD11";
+		widgets = "Headphone", "Headphone Jack";
+		dais = <&i2s_port2
+			&i2s_port3
+			&i2s_port4
+			&spdif_port0
+			&comp_spdif_port0>;
+	};
+
+	spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+
+		port@0 {
+			spdif_tx: endpoint {
+				remote-endpoint = <&spdif_hiecout1>;
+			};
+		};
+	};
+
+	comp-spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+
+		port@0 {
+			comp_spdif_tx: endpoint {
+				remote-endpoint = <&comp_spdif_hiecout1>;
+			};
+		};
+	};
 };
 
 &serial0 {
@@ -47,9 +93,43 @@
 	status = "okay";
 };
 
+&i2s_hpcmout1 {
+	dai-format = "i2s";
+	remote-endpoint = <&tas_speaker>;
+};
+
+&spdif_hiecout1 {
+	remote-endpoint = <&spdif_tx>;
+};
+
+&comp_spdif_hiecout1 {
+	remote-endpoint = <&comp_spdif_tx>;
+};
+
 &i2c0 {
 	status = "okay";
 
+	tas5707a@1d {
+		compatible = "ti,tas5711";
+		reg = <0x1d>;
+		reset-gpios = <&gpio UNIPHIER_GPIO_PORT(23, 4) GPIO_ACTIVE_LOW>;
+		pdn-gpios = <&gpio UNIPHIER_GPIO_PORT(23, 5) GPIO_ACTIVE_LOW>;
+		#sound-dai-cells = <0>;
+		AVDD-supply = <&dvdd_reg>;
+		DVDD-supply = <&dvdd_reg>;
+		PVDD_A-supply = <&amp_vcc_reg>;
+		PVDD_B-supply = <&amp_vcc_reg>;
+		PVDD_C-supply = <&amp_vcc_reg>;
+		PVDD_D-supply = <&amp_vcc_reg>;
+
+		port@0 {
+			tas_speaker: endpoint {
+				dai-format = "i2s";
+				remote-endpoint = <&i2s_hpcmout1>;
+			};
+		};
+	};
+
 	eeprom@50 {
 		compatible = "st,24c64", "atmel,24c64";
 		reg = <0x50>;
@@ -69,6 +149,17 @@
 	status = "okay";
 };
 
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@1 {
+		reg = <1>;
+	};
+};
+
 &nand {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts
index 54c5317..b8f6273 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier LD11 Reference Board
- *
- * Copyright (C) 2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD11 Reference Board
+//
+// Copyright (C) 2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-ld11.dtsi"
@@ -70,3 +68,14 @@
 &usb2 {
 	status = "okay";
 };
+
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@1 {
+		reg = <1>;
+	};
+};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
index cd7c2d0..e62bda1 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier LD11 SoC
- *
- * Copyright (C) 2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD11 SoC
+//
+// Copyright (C) 2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/gpio/uniphier-gpio.h>
@@ -187,6 +185,92 @@
 						     <21 217 3>;
 		};
 
+		audio@56000000 {
+			compatible = "socionext,uniphier-ld11-aio";
+			reg = <0x56000000 0x80000>;
+			interrupts = <0 144 4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_aout1>,
+				    <&pinctrl_aoutiec1>;
+			clock-names = "aio";
+			clocks = <&sys_clk 40>;
+			reset-names = "aio";
+			resets = <&sys_rst 40>;
+			#sound-dai-cells = <1>;
+			socionext,syscon = <&soc_glue>;
+
+			i2s_port0: port@0 {
+				i2s_hdmi: endpoint {
+				};
+			};
+
+			i2s_port1: port@1 {
+				i2s_pcmin2: endpoint {
+				};
+			};
+
+			i2s_port2: port@2 {
+				i2s_line: endpoint {
+					dai-format = "i2s";
+					remote-endpoint = <&evea_line>;
+				};
+			};
+
+			i2s_port3: port@3 {
+				i2s_hpcmout1: endpoint {
+				};
+			};
+
+			i2s_port4: port@4 {
+				i2s_hp: endpoint {
+					dai-format = "i2s";
+					remote-endpoint = <&evea_hp>;
+				};
+			};
+
+			spdif_port0: port@5 {
+				spdif_hiecout1: endpoint {
+				};
+			};
+
+			src_port0: port@6 {
+				i2s_epcmout2: endpoint {
+				};
+			};
+
+			src_port1: port@7 {
+				i2s_epcmout3: endpoint {
+				};
+			};
+
+			comp_spdif_port0: port@8 {
+				comp_spdif_hiecout1: endpoint {
+				};
+			};
+		};
+
+		codec@57900000 {
+			compatible = "socionext,uniphier-evea";
+			reg = <0x57900000 0x1000>;
+			clock-names = "evea", "exiv";
+			clocks = <&sys_clk 41>, <&sys_clk 42>;
+			reset-names = "evea", "exiv", "adamv";
+			resets = <&sys_rst 41>, <&sys_rst 42>, <&adamv_rst 0>;
+			#sound-dai-cells = <1>;
+
+			port@0 {
+				evea_line: endpoint {
+					remote-endpoint = <&i2s_line>;
+				};
+			};
+
+			port@1 {
+				evea_hp: endpoint {
+					remote-endpoint = <&i2s_hp>;
+				};
+			};
+		};
+
 		adamv@57920000 {
 			compatible = "socionext,uniphier-ld11-adamv",
 				     "simple-mfd", "syscon";
@@ -396,7 +480,7 @@
 			};
 		};
 
-		soc-glue@5f800000 {
+		soc_glue: soc-glue@5f800000 {
 			compatible = "socionext,uniphier-ld11-soc-glue",
 				     "simple-mfd", "syscon";
 			reg = <0x5f800000 0x2000>;
@@ -460,6 +544,22 @@
 			};
 		};
 
+		eth: ethernet@65000000 {
+			compatible = "socionext,uniphier-ld11-ave4";
+			status = "disabled";
+			reg = <0x65000000 0x8500>;
+			interrupts = <0 66 4>;
+			clocks = <&sys_clk 6>;
+			resets = <&sys_rst 6>;
+			phy-mode = "rmii";
+			local-mac-address = [00 00 00 00 00 00];
+
+			mdio: mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
 		nand: nand@68000000 {
 			compatible = "socionext,uniphier-denali-nand-v5b";
 			status = "disabled";
@@ -475,3 +575,12 @@
 };
 
 #include "uniphier-pinctrl.dtsi"
+
+&pinctrl_aoutiec1 {
+	drive-strength = <4>;	/* default: 4mA */
+
+	ao1arc {
+		pins = "AO1ARC";
+		drive-strength = <8>;	/* 8mA */
+	};
+};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
index fc2bc9d..fe6608e 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
@@ -1,14 +1,13 @@
-/*
- * Device Tree Source for UniPhier LD20 Global Board
- *
- * Copyright (C) 2015-2017 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *           Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD20 Global Board
+//
+// Copyright (C) 2015-2017 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+//           Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
 
 /dts-v1/;
+#include <dt-bindings/gpio/uniphier-gpio.h>
 #include "uniphier-ld20.dtsi"
 
 / {
@@ -37,6 +36,53 @@
 		device_type = "memory";
 		reg = <0 0x80000000 0 0xc0000000>;
 	};
+
+	dvdd_reg: reg-fixed {
+		compatible = "regulator-fixed";
+		regulator-name = "DVDD";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	amp_vcc_reg: reg-fixed {
+		compatible = "regulator-fixed";
+		regulator-name = "AMP_VCC";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	sound {
+		compatible = "audio-graph-card";
+		label = "UniPhier LD20";
+		widgets = "Headphone", "Headphone Jack";
+		dais = <&i2s_port2
+			&i2s_port3
+			&i2s_port4
+			&spdif_port0
+			&comp_spdif_port0>;
+	};
+
+	spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+
+		port@0 {
+			spdif_tx: endpoint {
+				remote-endpoint = <&spdif_hiecout1>;
+			};
+		};
+	};
+
+	comp-spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+
+		port@0 {
+			comp_spdif_tx: endpoint {
+				remote-endpoint = <&comp_spdif_hiecout1>;
+			};
+		};
+	};
 };
 
 &serial0 {
@@ -47,8 +93,55 @@
 	status = "okay";
 };
 
+&i2s_hpcmout1 {
+	dai-format = "i2s";
+	remote-endpoint = <&tas_speaker>;
+};
+
+&spdif_hiecout1 {
+	remote-endpoint = <&spdif_tx>;
+};
+
+&comp_spdif_hiecout1 {
+	remote-endpoint = <&comp_spdif_tx>;
+};
+
 &i2c0 {
 	status = "okay";
+
+	tas5707@1b {
+		compatible = "ti,tas5711";
+		reg = <0x1b>;
+		reset-gpios = <&gpio UNIPHIER_GPIO_PORT(0, 0) GPIO_ACTIVE_LOW>;
+		pdn-gpios = <&gpio UNIPHIER_GPIO_PORT(0, 1) GPIO_ACTIVE_LOW>;
+		#sound-dai-cells = <0>;
+		AVDD-supply = <&dvdd_reg>;
+		DVDD-supply = <&dvdd_reg>;
+		PVDD_A-supply = <&amp_vcc_reg>;
+		PVDD_B-supply = <&amp_vcc_reg>;
+		PVDD_C-supply = <&amp_vcc_reg>;
+		PVDD_D-supply = <&amp_vcc_reg>;
+
+		port@0 {
+			tas_speaker: endpoint {
+				dai-format = "i2s";
+				remote-endpoint = <&i2s_hpcmout1>;
+			};
+		};
+	};
+};
+
+&eth {
+	status = "okay";
+	phy-mode = "rmii";
+	pinctrl-0 = <&pinctrl_ether_rmii>;
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@1 {
+		reg = <1>;
+	};
 };
 
 &nand {
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts
index 6933710..2c1a92f 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier LD20 Reference Board
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD20 Reference Board
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-ld20.dtsi"
@@ -58,3 +56,14 @@
 &i2c0 {
 	status = "okay";
 };
+
+&eth {
+	status = "okay";
+	phy-handle = <&ethphy>;
+};
+
+&mdio {
+	ethphy: ethphy@0 {
+		reg = <0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
index 8a3276b..9efe20d 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier LD20 SoC
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier LD20 SoC
+//
+// Copyright (C) 2015-2016 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/gpio/uniphier-gpio.h>
@@ -287,6 +285,92 @@
 						     <21 217 3>;
 		};
 
+		audio@56000000 {
+			compatible = "socionext,uniphier-ld20-aio";
+			reg = <0x56000000 0x80000>;
+			interrupts = <0 144 4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_aout1>,
+				    <&pinctrl_aoutiec1>;
+			clock-names = "aio";
+			clocks = <&sys_clk 40>;
+			reset-names = "aio";
+			resets = <&sys_rst 40>;
+			#sound-dai-cells = <1>;
+			socionext,syscon = <&soc_glue>;
+
+			i2s_port0: port@0 {
+				i2s_hdmi: endpoint {
+				};
+			};
+
+			i2s_port1: port@1 {
+				i2s_pcmin2: endpoint {
+				};
+			};
+
+			i2s_port2: port@2 {
+				i2s_line: endpoint {
+					dai-format = "i2s";
+					remote-endpoint = <&evea_line>;
+				};
+			};
+
+			i2s_port3: port@3 {
+				i2s_hpcmout1: endpoint {
+				};
+			};
+
+			i2s_port4: port@4 {
+				i2s_hp: endpoint {
+					dai-format = "i2s";
+					remote-endpoint = <&evea_hp>;
+				};
+			};
+
+			spdif_port0: port@5 {
+				spdif_hiecout1: endpoint {
+				};
+			};
+
+			src_port0: port@6 {
+				i2s_epcmout2: endpoint {
+				};
+			};
+
+			src_port1: port@7 {
+				i2s_epcmout3: endpoint {
+				};
+			};
+
+			comp_spdif_port0: port@8 {
+				comp_spdif_hiecout1: endpoint {
+				};
+			};
+		};
+
+		codec@57900000 {
+			compatible = "socionext,uniphier-evea";
+			reg = <0x57900000 0x1000>;
+			clock-names = "evea", "exiv";
+			clocks = <&sys_clk 41>, <&sys_clk 42>;
+			reset-names = "evea", "exiv", "adamv";
+			resets = <&sys_rst 41>, <&sys_rst 42>, <&adamv_rst 0>;
+			#sound-dai-cells = <1>;
+
+			port@0 {
+				evea_line: endpoint {
+					remote-endpoint = <&i2s_line>;
+				};
+			};
+
+			port@1 {
+				evea_hp: endpoint {
+					remote-endpoint = <&i2s_hp>;
+				};
+			};
+		};
+
 		adamv@57920000 {
 			compatible = "socionext,uniphier-ld20-adamv",
 				     "simple-mfd", "syscon";
@@ -442,7 +526,7 @@
 			cdns,phy-dll-delay-sdclk-hsmmc = <21>;
 		};
 
-		soc-glue@5f800000 {
+		soc_glue: soc-glue@5f800000 {
 			compatible = "socionext,uniphier-ld20-soc-glue",
 				     "simple-mfd", "syscon";
 			reg = <0x5f800000 0x2000>;
@@ -513,6 +597,24 @@
 			};
 		};
 
+		eth: ethernet@65000000 {
+			compatible = "socionext,uniphier-ld20-ave4";
+			status = "disabled";
+			reg = <0x65000000 0x8500>;
+			interrupts = <0 66 4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ether_rgmii>;
+			clocks = <&sys_clk 6>;
+			resets = <&sys_rst 6>;
+			phy-mode = "rgmii";
+			local-mac-address = [00 00 00 00 00 00];
+
+			mdio: mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
 		nand: nand@68000000 {
 			compatible = "socionext,uniphier-denali-nand-v5b";
 			status = "disabled";
@@ -528,3 +630,21 @@
 };
 
 #include "uniphier-pinctrl.dtsi"
+
+&pinctrl_aout1 {
+	drive-strength = <4>;	/* default: 3.5mA */
+
+	ao1dacck {
+		pins = "AO1DACCK";
+		drive-strength = <5>;	/* 5mA */
+	};
+};
+
+&pinctrl_aoutiec1 {
+	drive-strength = <4>;	/* default: 3.5mA */
+
+	ao1arc {
+		pins = "AO1ARC";
+		drive-strength = <11>;	/* 11mA */
+	};
+};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts
index 3c71087..c1bb607 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts
+++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier PXs3 Reference Board
- *
- * Copyright (C) 2017 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier PXs3 Reference Board
+//
+// Copyright (C) 2017 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 /dts-v1/;
 #include "uniphier-pxs3.dtsi"
@@ -77,6 +75,28 @@
 	status = "okay";
 };
 
+&eth0 {
+	status = "okay";
+	phy-handle = <&ethphy0>;
+};
+
+&mdio0 {
+	ethphy0: ethphy@0 {
+		reg = <0>;
+	};
+};
+
+&eth1 {
+	status = "okay";
+	phy-handle = <&ethphy1>;
+};
+
+&mdio1 {
+	ethphy1: ethphy@0 {
+		reg = <0>;
+	};
+};
+
 &nand {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi
index 234fc58..7c8f710 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi
@@ -1,11 +1,9 @@
-/*
- * Device Tree Source for UniPhier PXs3 SoC
- *
- * Copyright (C) 2017 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- */
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for UniPhier PXs3 SoC
+//
+// Copyright (C) 2017 Socionext Inc.
+//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/gpio/uniphier-gpio.h>
@@ -407,6 +405,42 @@
 			};
 		};
 
+		eth0: ethernet@65000000 {
+			compatible = "socionext,uniphier-pxs3-ave4";
+			status = "disabled";
+			reg = <0x65000000 0x8500>;
+			interrupts = <0 66 4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ether_rgmii>;
+			clocks = <&sys_clk 6>;
+			resets = <&sys_rst 6>;
+			phy-mode = "rgmii";
+			local-mac-address = [00 00 00 00 00 00];
+
+			mdio0: mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		eth1: ethernet@65200000 {
+			compatible = "socionext,uniphier-pxs3-ave4";
+			status = "disabled";
+			reg = <0x65200000 0x8500>;
+			interrupts = <0 67 4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ether1_rgmii>;
+			clocks = <&sys_clk 7>;
+			resets = <&sys_rst 7>;
+			phy-mode = "rgmii";
+			local-mac-address = [00 00 00 00 00 00];
+
+			mdio1: mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
 		nand: nand@68000000 {
 			compatible = "socionext,uniphier-denali-nand-v5b";
 			status = "disabled";
diff --git a/arch/arm64/boot/dts/sprd/sc2731.dtsi b/arch/arm64/boot/dts/sprd/sc2731.dtsi
new file mode 100644
index 0000000..4331006
--- /dev/null
+++ b/arch/arm64/boot/dts/sprd/sc2731.dtsi
@@ -0,0 +1,169 @@
+/*
+ * Spreadtrum SC2731 PMIC dts file
+ *
+ * Copyright (C) 2018, Spreadtrum Communications Inc.
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+&adi_bus {
+	sc2731_pmic: pmic@0 {
+		compatible = "sprd,sc2731";
+		reg = <0>;
+		spi-max-frequency = <26000000>;
+		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		rtc@280 {
+			compatible = "sprd,sc27xx-rtc", "sprd,sc2731-rtc";
+			reg = <0x280>;
+			interrupt-parent = <&sc2731_pmic>;
+			interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		regulators {
+			compatible = "sprd,sc27xx-regulator";
+
+			vddarm0: BUCK_CPU0 {
+				regulator-name = "vddarm0";
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1996875>;
+				regulator-ramp-delay = <25000>;
+				regulator-always-on;
+			};
+
+			vddarm1: BUCK_CPU1 {
+				regulator-name = "vddarm1";
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1996875>;
+				regulator-ramp-delay = <25000>;
+				regulator-always-on;
+			};
+
+			dcdcrf: BUCK_RF {
+				regulator-name = "dcdcrf";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <2196875>;
+				regulator-ramp-delay = <25000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-always-on;
+			};
+
+			vddcama0: LDO_CAMA0 {
+				regulator-name = "vddcama0";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+			};
+
+			vddcama1: LDO_CAMA1 {
+				regulator-name = "vddcama1";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddcammot: LDO_CAMMOT {
+				regulator-name = "vddcammot";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddvldo: LDO_VLDO {
+				regulator-name = "vddvldo";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddemmccore: LDO_EMMCCORE {
+				regulator-name = "vddemmccore";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+				regulator-boot-on;
+			};
+
+			vddsdcore: LDO_SDCORE {
+				regulator-name = "vddsdcore";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddsdio: LDO_SDIO {
+				regulator-name = "vddsdio";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddwifipa: LDO_WIFIPA {
+				regulator-name = "vddwifipa";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddusb33: LDO_USB33 {
+				regulator-name = "vddusb33";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3750000>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddcamd0: LDO_CAMD0 {
+				regulator-name = "vddcamd0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1793750>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddcamd1: LDO_CAMD1 {
+				regulator-name = "vddcamd1";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1793750>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddcon: LDO_CON {
+				regulator-name = "vddcon";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1793750>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddcamio: LDO_CAMIO {
+				regulator-name = "vddcamio";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1793750>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+			};
+
+			vddsram: LDO_SRAM {
+				regulator-name = "vddsram";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1793750>;
+				regulator-enable-ramp-delay = <100>;
+				regulator-ramp-delay = <25000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/sprd/sp9860g-1h10.dts b/arch/arm64/boot/dts/sprd/sp9860g-1h10.dts
index ae0b28c..985ebb5 100644
--- a/arch/arm64/boot/dts/sprd/sp9860g-1h10.dts
+++ b/arch/arm64/boot/dts/sprd/sp9860g-1h10.dts
@@ -9,6 +9,7 @@
 /dts-v1/;
 
 #include "sc9860.dtsi"
+#include "sc2731.dtsi"
 
 / {
 	model = "Spreadtrum SP9860G 3GFHD Board";
@@ -20,6 +21,7 @@
 		serial1 = &uart1; /* UART console */
 		serial2 = &uart2; /* Reserved */
 		serial3 = &uart3; /* for GPS */
+		spi0 = &adi_bus;
 	};
 
 	memory{
diff --git a/arch/arm64/boot/dts/sprd/whale2.dtsi b/arch/arm64/boot/dts/sprd/whale2.dtsi
index 328009c..66a881e 100644
--- a/arch/arm64/boot/dts/sprd/whale2.dtsi
+++ b/arch/arm64/boot/dts/sprd/whale2.dtsi
@@ -6,6 +6,8 @@
  * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
+#include <dt-bindings/clock/sprd,sc9860-clk.h>
+
 / {
 	interrupt-parent = <&gic>;
 	#address-cells = <2>;
@@ -104,6 +106,85 @@
 				status = "disabled";
 			};
 		};
+
+		ap-ahb {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			ap_dma: dma-controller@20100000 {
+				compatible = "sprd,sc9860-dma";
+				reg = <0 0x20100000 0 0x4000>;
+				interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+				#dma-cells = <1>;
+				#dma-channels = <32>;
+				clock-names = "enable";
+				clocks = <&apahb_gate CLK_DMA_EB>;
+			};
+		};
+
+		aon {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			adi_bus: spi@40030000 {
+				compatible = "sprd,sc9860-adi";
+				reg = <0 0x40030000 0 0x10000>;
+				hwlocks = <&hwlock 0>;
+				hwlock-names = "adi";
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			timer@40050000 {
+				compatible = "sprd,sc9860-timer";
+				reg = <0 0x40050000 0 0x20>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&ext_32k>;
+			};
+
+			hwlock: hwspinlock@40500000 {
+				compatible = "sprd,hwspinlock-r3p0";
+				reg = <0 0x40500000 0 0x1000>;
+				#hwlock-cells = <1>;
+				clock-names = "enable";
+				clocks = <&aon_gate CLK_SPLK_EB>;
+			};
+
+			pin_controller: pinctrl@402a0000 {
+				compatible = "sprd,sc9860-pinctrl";
+				reg = <0 0x402a0000 0 0x10000>;
+			};
+
+			watchdog@40310000 {
+				compatible = "sprd,sp9860-wdt";
+				reg = <0 0x40310000 0 0x1000>;
+				interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+				timeout-sec = <12>;
+				clock-names = "enable";
+				clocks = <&aon_gate CLK_APCPU_WDG_EB>;
+			};
+		};
+
+		agcp {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			agcp_dma: dma-controller@41580000 {
+				compatible = "sprd,sc9860-dma";
+				reg = <0 0x41580000 0 0x4000>;
+				#dma-cells = <1>;
+				#dma-channels = <32>;
+				clock-names = "enable", "ashb_eb";
+				clocks = <&agcp_gate CLK_AGCP_DMAAP_EB>,
+				       <&agcp_gate CLK_AGCP_AP_ASHB_EB>;
+			};
+		};
 	};
 
 	ext_32k: ext_32k {
diff --git a/arch/arm64/boot/dts/xilinx/Makefile b/arch/arm64/boot/dts/xilinx/Makefile
index a2d6708..c2a0c00 100644
--- a/arch/arm64/boot/dts/xilinx/Makefile
+++ b/arch/arm64/boot/dts/xilinx/Makefile
@@ -1 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-ep108.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1232-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1254-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1275-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1751-xm015-dc1.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1751-xm016-dc2.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1751-xm017-dc3.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1751-xm018-dc4.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1751-xm019-dc5.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu100-revC.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu102-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu102-revB.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu102-rev1.0.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu104-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu106-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu111-revA.dtb
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi
new file mode 100644
index 0000000..9c09bac
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Clock specification for Xilinx ZynqMP
+ *
+ * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/ {
+	clk100: clk100 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <100000000>;
+	};
+
+	clk125: clk125 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+	};
+
+	clk200: clk200 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <200000000>;
+	};
+
+	clk250: clk250 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <250000000>;
+	};
+
+	clk300: clk300 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <300000000>;
+	};
+
+	clk600: clk600 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <600000000>;
+	};
+
+	dp_aclk: clock0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <100000000>;
+		clock-accuracy = <100>;
+	};
+
+	dp_aud_clk: clock1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24576000>;
+		clock-accuracy = <100>;
+	};
+
+	dpdma_clk: dpdma_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0x0>;
+		clock-frequency = <533000000>;
+	};
+
+	drm_clock: drm_clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0x0>;
+		clock-frequency = <262750000>;
+		clock-accuracy = <0x64>;
+	};
+};
+
+&can0 {
+	clocks = <&clk100 &clk100>;
+};
+
+&can1 {
+	clocks = <&clk100 &clk100>;
+};
+
+&fpd_dma_chan1 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan2 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan3 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan4 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan5 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan6 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan7 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan8 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan1 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan2 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan3 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan4 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan5 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan6 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan7 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan8 {
+	clocks = <&clk600>, <&clk100>;
+};
+
+&gem0 {
+	clocks = <&clk125>, <&clk125>, <&clk125>;
+};
+
+&gem1 {
+	clocks = <&clk125>, <&clk125>, <&clk125>;
+};
+
+&gem2 {
+	clocks = <&clk125>, <&clk125>, <&clk125>;
+};
+
+&gem3 {
+	clocks = <&clk125>, <&clk125>, <&clk125>;
+};
+
+&gpio {
+	clocks = <&clk100>;
+};
+
+&i2c0 {
+	clocks = <&clk100>;
+};
+
+&i2c1 {
+	clocks = <&clk100>;
+};
+
+&sata {
+	clocks = <&clk250>;
+};
+
+&sdhci0 {
+	clocks = <&clk200 &clk200>;
+};
+
+&sdhci1 {
+	clocks = <&clk200 &clk200>;
+};
+
+&spi0 {
+	clocks = <&clk200 &clk200>;
+};
+
+&spi1 {
+	clocks = <&clk200 &clk200>;
+};
+
+&uart0 {
+	clocks = <&clk100 &clk100>;
+};
+
+&uart1 {
+	clocks = <&clk100 &clk100>;
+};
+
+&usb0 {
+	clocks = <&clk250>, <&clk250>;
+};
+
+&usb1 {
+	clocks = <&clk250>, <&clk250>;
+};
+
+&watchdog0 {
+	clocks = <&clk250>;
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi
index b87b831..9f5eedb 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * clock specification for Xilinx ZynqMP ep108 development board
  *
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
index bf55267..4b06849 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * dts file for Xilinx ZynqMP ep108 development board
  *
@@ -47,7 +48,7 @@
 	status = "okay";
 	phy-handle = <&phy0>;
 	phy-mode = "rgmii-id";
-	phy0: phy@0{
+	phy0: phy@0 {
 		reg = <0>;
 		max-speed = <100>;
 	};
@@ -78,10 +79,20 @@
 &sata {
 	status = "okay";
 	ceva,broken-gen2;
+	/* SATA Phy OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
+	ceva,p0-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
+	ceva,p0-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x0216 0x7F06>;
+	ceva,p1-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
+	ceva,p1-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
+	ceva,p1-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x0216 0x7F06>;
 };
 
 &sdhci0 {
 	status = "okay";
+	bus-width = <8>;
 };
 
 &sdhci1 {
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1232-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1232-revA.dts
new file mode 100644
index 0000000..0f7b4cf
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1232-revA.dts
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZC1232
+ *
+ * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+
+/ {
+	model = "ZynqMP ZC1232 RevA";
+	compatible = "xlnx,zynqmp-zc1232-revA", "xlnx,zynqmp-zc1232", "xlnx,zynqmp";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &dcc;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+};
+
+&dcc {
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+	/* SATA OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1254-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1254-revA.dts
new file mode 100644
index 0000000..9092828
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1254-revA.dts
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZC1254
+ *
+ * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ * Siva Durga Prasad Paladugu <sivadur@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+
+/ {
+	model = "ZynqMP ZC1254 RevA";
+	compatible = "xlnx,zynqmp-zc1254-revA", "xlnx,zynqmp-zc1254", "xlnx,zynqmp";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &dcc;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+};
+
+&dcc {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
new file mode 100644
index 0000000..4f404c5
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZC1275
+ *
+ * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ * Siva Durga Prasad Paladugu <sivadur@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+
+/ {
+	model = "ZynqMP ZC1275 RevA";
+	compatible = "xlnx,zynqmp-zc1275-revA", "xlnx,zynqmp-zc1275", "xlnx,zynqmp";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &dcc;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+};
+
+&dcc {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
new file mode 100644
index 0000000..9a3e39d
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP zc1751-xm015-dc1
+ *
+ * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "ZynqMP zc1751-xm015-dc1 RevA";
+	compatible = "xlnx,zynqmp-zc1751", "xlnx,zynqmp";
+
+	aliases {
+		ethernet0 = &gem3;
+		i2c0 = &i2c1;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+	};
+};
+
+&fpd_dma_chan1 {
+	status = "okay";
+};
+
+&fpd_dma_chan2 {
+	status = "okay";
+};
+
+&fpd_dma_chan3 {
+	status = "okay";
+};
+
+&fpd_dma_chan4 {
+	status = "okay";
+};
+
+&fpd_dma_chan5 {
+	status = "okay";
+};
+
+&fpd_dma_chan6 {
+	status = "okay";
+};
+
+&fpd_dma_chan7 {
+	status = "okay";
+};
+
+&fpd_dma_chan8 {
+	status = "okay";
+};
+
+&gem3 {
+	status = "okay";
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+	phy0: phy@0 {
+		reg = <0>;
+	};
+};
+
+&gpio {
+	status = "okay";
+};
+
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	eeprom: eeprom@55 {
+		compatible = "atmel,24c64"; /* 24AA64 */
+		reg = <0x55>;
+	};
+};
+
+&rtc {
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+	/* SATA phy OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x1B 0x4D 0x18 0x28>;
+	ceva,p0-comwake-params = /bits/ 8 <0x06 0x19 0x08 0x0E>;
+	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	ceva,p1-cominit-params = /bits/ 8 <0x1B 0x4D 0x18 0x28>;
+	ceva,p1-comwake-params = /bits/ 8 <0x06 0x19 0x08 0x0E>;
+	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+};
+
+/* eMMC */
+&sdhci0 {
+	status = "okay";
+	bus-width = <8>;
+};
+
+/* SD1 with level shifter */
+&sdhci1 {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+/* ULPI SMSC USB3320 */
+&usb0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
new file mode 100644
index 0000000..11cc671
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP zc1751-xm016-dc2
+ *
+ * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "ZynqMP zc1751-xm016-dc2 RevA";
+	compatible = "xlnx,zynqmp-zc1751", "xlnx,zynqmp";
+
+	aliases {
+		can0 = &can0;
+		can1 = &can1;
+		ethernet0 = &gem2;
+		i2c0 = &i2c0;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		spi0 = &spi0;
+		spi1 = &spi1;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+	};
+};
+
+&can0 {
+	status = "okay";
+};
+
+&can1 {
+	status = "okay";
+};
+
+&fpd_dma_chan1 {
+	status = "okay";
+};
+
+&fpd_dma_chan2 {
+	status = "okay";
+};
+
+&fpd_dma_chan3 {
+	status = "okay";
+};
+
+&fpd_dma_chan4 {
+	status = "okay";
+};
+
+&fpd_dma_chan5 {
+	status = "okay";
+};
+
+&fpd_dma_chan6 {
+	status = "okay";
+};
+
+&fpd_dma_chan7 {
+	status = "okay";
+};
+
+&fpd_dma_chan8 {
+	status = "okay";
+};
+
+&gem2 {
+	status = "okay";
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+	phy0: phy@5 {
+		reg = <5>;
+		ti,rx-internal-delay = <0x8>;
+		ti,tx-internal-delay = <0xa>;
+		ti,fifo-depth = <0x1>;
+	};
+};
+
+&gpio {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tca6416_u26: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		/* IRQ not connected */
+	};
+
+	rtc@68 {
+		compatible = "dallas,ds1339";
+		reg = <0x68>;
+	};
+};
+
+&rtc {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+	num-cs = <1>;
+
+	spi0_flash0: flash0@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "sst,sst25wf080", "jedec,spi-nor";
+		spi-max-frequency = <50000000>;
+		reg = <0>;
+
+		partition@0 {
+			label = "data";
+			reg = <0x0 0x100000>;
+		};
+	};
+};
+
+&spi1 {
+	status = "okay";
+	num-cs = <1>;
+
+	spi1_flash0: flash0@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "atmel,at45db041e", "atmel,at45", "atmel,dataflash";
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+
+		partition@0 {
+			label = "data";
+			reg = <0x0 0x84000>;
+		};
+	};
+};
+
+/* ULPI SMSC USB3320 */
+&usb1 {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
new file mode 100644
index 0000000..7a49dee
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP zc1751-xm017-dc3
+ *
+ * (C) Copyright 2016 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+
+/ {
+	model = "ZynqMP zc1751-xm017-dc3 RevA";
+	compatible = "xlnx,zynqmp-zc1751", "xlnx,zynqmp";
+
+	aliases {
+		ethernet0 = &gem0;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		mmc0 = &sdhci1;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+	};
+};
+
+&fpd_dma_chan1 {
+	status = "okay";
+};
+
+&fpd_dma_chan2 {
+	status = "okay";
+};
+
+&fpd_dma_chan3 {
+	status = "okay";
+};
+
+&fpd_dma_chan4 {
+	status = "okay";
+};
+
+&fpd_dma_chan5 {
+	status = "okay";
+};
+
+&fpd_dma_chan6 {
+	status = "okay";
+};
+
+&fpd_dma_chan7 {
+	status = "okay";
+};
+
+&fpd_dma_chan8 {
+	status = "okay";
+};
+
+&gem0 {
+	status = "okay";
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+	phy0: phy@0 { /* VSC8211 */
+		reg = <0>;
+	};
+};
+
+&gpio {
+	status = "okay";
+};
+
+/* just eeprom here */
+&i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tca6416_u26: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		/* IRQ not connected */
+	};
+
+	rtc@68 {
+		compatible = "dallas,ds1339";
+		reg = <0x68>;
+	};
+};
+
+/* eeprom24c02 and SE98A temp chip pca9306 */
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+};
+
+&rtc {
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+	/* SATA phy OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x1B 0x4D 0x18 0x28>;
+	ceva,p0-comwake-params = /bits/ 8 <0x06 0x19 0x08 0x0E>;
+	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	ceva,p1-cominit-params = /bits/ 8 <0x1B 0x4D 0x18 0x28>;
+	ceva,p1-comwake-params = /bits/ 8 <0x06 0x19 0x08 0x0E>;
+	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+};
+
+&sdhci1 { /* emmc with some settings */
+	status = "okay";
+};
+
+/* main */
+&uart0 {
+	status = "okay";
+};
+
+/* DB9 */
+&uart1 {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "host";
+};
+
+/* ULPI SMSC USB3320 */
+&usb1 {
+	status = "okay";
+	dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm018-dc4.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm018-dc4.dts
new file mode 100644
index 0000000..54c7b4f
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm018-dc4.dts
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP zc1751-xm018-dc4
+ *
+ * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+
+/ {
+	model = "ZynqMP zc1751-xm018-dc4";
+	compatible = "xlnx,zynqmp-zc1751", "xlnx,zynqmp";
+
+	aliases {
+		ethernet0 = &gem0;
+		ethernet1 = &gem1;
+		ethernet2 = &gem2;
+		ethernet3 = &gem3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+	};
+};
+
+&can0 {
+	status = "okay";
+};
+
+&can1 {
+	status = "okay";
+};
+
+&fpd_dma_chan1 {
+	status = "okay";
+};
+
+&fpd_dma_chan2 {
+	status = "okay";
+};
+
+&fpd_dma_chan3 {
+	status = "okay";
+};
+
+&fpd_dma_chan4 {
+	status = "okay";
+};
+
+&fpd_dma_chan5 {
+	status = "okay";
+};
+
+&fpd_dma_chan6 {
+	status = "okay";
+};
+
+&fpd_dma_chan7 {
+	status = "okay";
+};
+
+&fpd_dma_chan8 {
+	status = "okay";
+};
+
+&lpd_dma_chan1 {
+	status = "okay";
+};
+
+&lpd_dma_chan2 {
+	status = "okay";
+};
+
+&lpd_dma_chan3 {
+	status = "okay";
+};
+
+&lpd_dma_chan4 {
+	status = "okay";
+};
+
+&lpd_dma_chan5 {
+	status = "okay";
+};
+
+&lpd_dma_chan6 {
+	status = "okay";
+};
+
+&lpd_dma_chan7 {
+	status = "okay";
+};
+
+&lpd_dma_chan8 {
+	status = "okay";
+};
+
+&gem0 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+	ethernet_phy0: ethernet-phy@0 { /* Marvell 88e1512 */
+		reg = <0>;
+	};
+	ethernet_phy7: ethernet-phy@7 { /* Vitesse VSC8211 */
+		reg = <7>;
+	};
+	ethernet_phy3: ethernet-phy@3 { /* Realtek RTL8211DN */
+		reg = <3>;
+	};
+	ethernet_phy8: ethernet-phy@8 { /* Vitesse VSC8211 */
+		reg = <8>;
+	};
+};
+
+&gem1 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy7>;
+};
+
+&gem2 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy3>;
+};
+
+&gem3 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy8>;
+};
+
+&gpio {
+	status = "okay";
+};
+
+&i2c0 {
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&rtc {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&watchdog0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts
new file mode 100644
index 0000000..b8b5ff1
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP zc1751-xm019-dc5
+ *
+ * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ *
+ * Siva Durga Prasad <siva.durga.paladugu@xilinx.com>
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "ZynqMP zc1751-xm019-dc5 RevA";
+	compatible = "xlnx,zynqmp-zc1751", "xlnx,zynqmp";
+
+	aliases {
+		ethernet0 = &gem1;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		mmc0 = &sdhci0;
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+	};
+};
+
+&fpd_dma_chan1 {
+	status = "okay";
+};
+
+&fpd_dma_chan2 {
+	status = "okay";
+};
+
+&fpd_dma_chan3 {
+	status = "okay";
+};
+
+&fpd_dma_chan4 {
+	status = "okay";
+};
+
+&fpd_dma_chan5 {
+	status = "okay";
+};
+
+&fpd_dma_chan6 {
+	status = "okay";
+};
+
+&fpd_dma_chan7 {
+	status = "okay";
+};
+
+&fpd_dma_chan8 {
+	status = "okay";
+};
+
+&gem1 {
+	status = "okay";
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+	phy0: phy@0 {
+		reg = <0>;
+	};
+};
+
+&gpio {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&sdhci0 {
+	status = "okay";
+	no-1-8-v;
+};
+
+&ttc0 {
+	status = "okay";
+};
+
+&ttc1 {
+	status = "okay";
+};
+
+&ttc2 {
+	status = "okay";
+};
+
+&ttc3 {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&watchdog0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
new file mode 100644
index 0000000..3e862a9
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZCU100 revC
+ *
+ * (C) Copyright 2016 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ * Nathalie Chan King Choy
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "ZynqMP ZCU100 RevC";
+	compatible = "xlnx,zynqmp-zcu100-revC", "xlnx,zynqmp-zcu100", "xlnx,zynqmp";
+
+	aliases {
+		i2c0 = &i2c1;
+		rtc0 = &rtc;
+		serial0 = &uart1;
+		serial1 = &uart0;
+		serial2 = &dcc;
+		spi0 = &spi0;
+		spi1 = &spi1;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		autorepeat;
+		sw4 {
+			label = "sw4";
+			gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+			gpio-key,wakeup;
+			autorepeat;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		ds2 {
+			label = "ds2";
+			gpios = <&gpio 20 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		ds3 {
+			label = "ds3";
+			gpios = <&gpio 19 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0tx"; /* WLAN tx */
+			default-state = "off";
+		};
+
+		ds4 {
+			label = "ds4";
+			gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0rx"; /* WLAN rx */
+			default-state = "off";
+		};
+
+		ds5 {
+			label = "ds5";
+			gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "bluetooth-power";
+		};
+
+		vbus_det { /* U5 USB5744 VBUS detection via MIO25 */
+			label = "vbus_det";
+			gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		bt_power {
+			label = "bt_power";
+			gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	wmmcsdio_fixed: fixedregulator-mmcsdio {
+		compatible = "regulator-fixed";
+		regulator-name = "wmmcsdio_fixed";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	sdio_pwrseq: sdio_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>; /* WIFI_EN */
+	};
+};
+
+&dcc {
+	status = "okay";
+};
+
+&gpio {
+	status = "okay";
+	gpio-line-names = "UART1_TX", "UART1_RX", "UART0_RX", "UART0_TX", "I2C1_SCL",
+			  "I2C1_SDA", "SPI1_SCLK", "WLAN_EN", "BT_EN", "SPI1_CS",
+			  "SPI1_MISO", "SPI1_MOSI", "I2C_MUX_RESET", "SD0_DAT0", "SD0_DAT1",
+			  "SD0_DAT2", "SD0_DAT3", "PS_LED3", "PS_LED2", "PS_LED1",
+			  "PS_LED0", "SD0_CMD", "SD0_CLK", "GPIO_PB", "SD0_DETECT",
+			  "VBUS_DET", "POWER_INT", "DP_AUX", "DP_HPD", "DP_OE",
+			  "DP_AUX_IN", "INA226_ALERT", "PS_FP_PWR_EN", "PL_PWR_EN", "POWER_KILL",
+			  "", "GPIO-A", "GPIO-B", "SPI0_SCLK", "GPIO-C",
+			  "GPIO-D", "SPI0_CS", "SPI0_MISO", "SPI_MOSI", "GPIO-E",
+			  "GPIO-F", "SD1_D0", "SD1_D1", "SD1_D2", "SD1_D3",
+			  "SD1_CMD", "SD1_CLK", "USB0_CLK", "USB0_DIR", "USB0_DATA2",
+			  "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3",
+			  "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "USB1_CLK",
+			  "USB1_DIR", "USB1_DATA2", "USB1_NXT", "USB1_DATA0", "USB1_DATA1",
+			  "USB1_STP", "USB1_DATA3", "USB1_DATA4", "USB1_DATA5", "USB1_DATA6",
+			  "USB_DATA7", "WLAN_IRQ", "PMIC_IRQ", /* MIO end and EMIO start */
+			  "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "", "", "",
+			  "", "", "", "";
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <100000>;
+	i2c-mux@75 { /* u11 */
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+		i2csw_0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			label = "LS-I2C0";
+		};
+		i2csw_1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			label = "LS-I2C1";
+		};
+		i2csw_2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			label = "HS-I2C2";
+		};
+		i2csw_3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			label = "HS-I2C3";
+		};
+		i2csw_4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x4>;
+
+			pmic: pmic@5e { /* Custom TI PMIC u33 */
+				compatible = "ti,tps65086";
+				reg = <0x5e>;
+				interrupt-parent = <&gpio>;
+				interrupts = <77 GPIO_ACTIVE_LOW>;
+				#gpio-cells = <2>;
+				gpio-controller;
+			};
+		};
+		i2csw_5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			/* PS_PMBUS */
+			ina226@40 { /* u35 */
+				compatible = "ti,ina226";
+				reg = <0x40>;
+				shunt-resistor = <10000>;
+				/* MIO31 is alert which should be routed to PMUFW */
+			};
+		};
+		i2csw_6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			/*
+			 * Not Connected
+			 */
+		};
+		i2csw_7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			/*
+			 * usb5744 (DNP) - U5
+			 * 100kHz - this is default freq for us
+			 */
+		};
+	};
+};
+
+&rtc {
+	status = "okay";
+};
+
+/* SD0 only supports 3.3V, no level shifter */
+&sdhci0 {
+	status = "okay";
+	no-1-8-v;
+	broken-cd; /* CD has to be enabled by default */
+	disable-wp;
+};
+
+&sdhci1 {
+	status = "okay";
+	bus-width = <0x4>;
+	non-removable;
+	disable-wp;
+	cap-power-off-card;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	vqmmc-supply = <&wmmcsdio_fixed>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wlcore: wifi@2 {
+		compatible = "ti,wl1831";
+		reg = <2>;
+		interrupt-parent = <&gpio>;
+		interrupts = <76 IRQ_TYPE_EDGE_RISING>; /* MIO76 WLAN_IRQ 1V8 */
+	};
+};
+
+&spi0 { /* Low Speed connector */
+	status = "okay";
+	label = "LS-SPI0";
+};
+
+&spi1 { /* High Speed connector */
+	status = "okay";
+	label = "HS-SPI1";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+
+};
+
+/* ULPI SMSC USB3320 */
+&usb0 {
+	status = "okay";
+};
+
+/* ULPI SMSC USB3320 */
+&usb1 {
+	status = "okay";
+};
+
+&watchdog0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
new file mode 100644
index 0000000..6647e97
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZCU102 Rev1.0
+ *
+ * (C) Copyright 2016 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+#include "zynqmp-zcu102-revB.dts"
+
+/ {
+	model = "ZynqMP ZCU102 Rev1.0";
+	compatible = "xlnx,zynqmp-zcu102-rev1.0", "xlnx,zynqmp-zcu102", "xlnx,zynqmp";
+};
+
+&eeprom {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	board_sn: board-sn@0 {
+		reg = <0x0 0x14>;
+	};
+
+	eth_mac: eth-mac@20 {
+		reg = <0x20 0x6>;
+	};
+
+	board_name: board-name@d0 {
+		reg = <0xd0 0x6>;
+	};
+
+	board_revision: board-revision@e0 {
+		reg = <0xe0 0x3>;
+	};
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
new file mode 100644
index 0000000..5b4ffe6
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
@@ -0,0 +1,548 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZCU102 RevA
+ *
+ * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "ZynqMP ZCU102 RevA";
+	compatible = "xlnx,zynqmp-zcu102-revA", "xlnx,zynqmp-zcu102", "xlnx,zynqmp";
+
+	aliases {
+		ethernet0 = &gem3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		mmc0 = &sdhci1;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &dcc;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		autorepeat;
+		sw19 {
+			label = "sw19";
+			gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_DOWN>;
+			gpio-key,wakeup;
+			autorepeat;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		heartbeat_led {
+			label = "heartbeat";
+			gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&dcc {
+	status = "okay";
+};
+
+&fpd_dma_chan1 {
+	status = "okay";
+};
+
+&fpd_dma_chan2 {
+	status = "okay";
+};
+
+&fpd_dma_chan3 {
+	status = "okay";
+};
+
+&fpd_dma_chan4 {
+	status = "okay";
+};
+
+&fpd_dma_chan5 {
+	status = "okay";
+};
+
+&fpd_dma_chan6 {
+	status = "okay";
+};
+
+&fpd_dma_chan7 {
+	status = "okay";
+};
+
+&fpd_dma_chan8 {
+	status = "okay";
+};
+
+&gem3 {
+	status = "okay";
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+	phy0: phy@21 {
+		reg = <21>;
+		ti,rx-internal-delay = <0x8>;
+		ti,tx-internal-delay = <0xa>;
+		ti,fifo-depth = <0x1>;
+	};
+};
+
+&gpio {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tca6416_u97: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		/*
+		 * IRQ not connected
+		 * Lines:
+		 * 0 - PS_GTR_LAN_SEL0
+		 * 1 - PS_GTR_LAN_SEL1
+		 * 2 - PS_GTR_LAN_SEL2
+		 * 3 - PS_GTR_LAN_SEL3
+		 * 4 - PCI_CLK_DIR_SEL
+		 * 5 - IIC_MUX_RESET_B
+		 * 6 - GEM3_EXP_RESET_B
+		 * 7, 10 - 17 - not connected
+		 */
+
+		gtr_sel0 {
+			gpio-hog;
+			gpios = <0 0>;
+			output-low; /* PCIE = 0, DP = 1 */
+			line-name = "sel0";
+		};
+		gtr_sel1 {
+			gpio-hog;
+			gpios = <1 0>;
+			output-high; /* PCIE = 0, DP = 1 */
+			line-name = "sel1";
+		};
+		gtr_sel2 {
+			gpio-hog;
+			gpios = <2 0>;
+			output-high; /* PCIE = 0, USB0 = 1 */
+			line-name = "sel2";
+		};
+		gtr_sel3 {
+			gpio-hog;
+			gpios = <3 0>;
+			output-high; /* PCIE = 0, SATA = 1 */
+			line-name = "sel3";
+		};
+	};
+
+	tca6416_u61: gpio@21 {
+		compatible = "ti,tca6416";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		/*
+		 * IRQ not connected
+		 * Lines:
+		 * 0 - VCCPSPLL_EN
+		 * 1 - MGTRAVCC_EN
+		 * 2 - MGTRAVTT_EN
+		 * 3 - VCCPSDDRPLL_EN
+		 * 4 - MIO26_PMU_INPUT_LS
+		 * 5 - PL_PMBUS_ALERT
+		 * 6 - PS_PMBUS_ALERT
+		 * 7 - MAXIM_PMBUS_ALERT
+		 * 10 - PL_DDR4_VTERM_EN
+		 * 11 - PL_DDR4_VPP_2V5_EN
+		 * 12 - PS_DIMM_VDDQ_TO_PSVCCO_ON
+		 * 13 - PS_DIMM_SUSPEND_EN
+		 * 14 - PS_DDR4_VTERM_EN
+		 * 15 - PS_DDR4_VPP_2V5_EN
+		 * 16 - 17 - not connected
+		 */
+	};
+
+	i2c-mux@75 { /* u60 */
+		compatible = "nxp,pca9544";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/* PS_PMBUS */
+			ina226@40 { /* u76 */
+				compatible = "ti,ina226";
+				reg = <0x40>;
+				shunt-resistor = <5000>;
+			};
+			ina226@41 { /* u77 */
+				compatible = "ti,ina226";
+				reg = <0x41>;
+				shunt-resistor = <5000>;
+			};
+			ina226@42 { /* u78 */
+				compatible = "ti,ina226";
+				reg = <0x42>;
+				shunt-resistor = <5000>;
+			};
+			ina226@43 { /* u87 */
+				compatible = "ti,ina226";
+				reg = <0x43>;
+				shunt-resistor = <5000>;
+			};
+			ina226@44 { /* u85 */
+				compatible = "ti,ina226";
+				reg = <0x44>;
+				shunt-resistor = <5000>;
+			};
+			ina226@45 { /* u86 */
+				compatible = "ti,ina226";
+				reg = <0x45>;
+				shunt-resistor = <5000>;
+			};
+			ina226@46 { /* u93 */
+				compatible = "ti,ina226";
+				reg = <0x46>;
+				shunt-resistor = <5000>;
+			};
+			ina226@47 { /* u88 */
+				compatible = "ti,ina226";
+				reg = <0x47>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4a { /* u15 */
+				compatible = "ti,ina226";
+				reg = <0x4a>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4b { /* u92 */
+				compatible = "ti,ina226";
+				reg = <0x4b>;
+				shunt-resistor = <5000>;
+			};
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			/* PL_PMBUS */
+			ina226@40 { /* u79 */
+				compatible = "ti,ina226";
+				reg = <0x40>;
+				shunt-resistor = <2000>;
+			};
+			ina226@41 { /* u81 */
+				compatible = "ti,ina226";
+				reg = <0x41>;
+				shunt-resistor = <5000>;
+			};
+			ina226@42 { /* u80 */
+				compatible = "ti,ina226";
+				reg = <0x42>;
+				shunt-resistor = <5000>;
+			};
+			ina226@43 { /* u84 */
+				compatible = "ti,ina226";
+				reg = <0x43>;
+				shunt-resistor = <5000>;
+			};
+			ina226@44 { /* u16 */
+				compatible = "ti,ina226";
+				reg = <0x44>;
+				shunt-resistor = <5000>;
+			};
+			ina226@45 { /* u65 */
+				compatible = "ti,ina226";
+				reg = <0x45>;
+				shunt-resistor = <5000>;
+			};
+			ina226@46 { /* u74 */
+				compatible = "ti,ina226";
+				reg = <0x46>;
+				shunt-resistor = <5000>;
+			};
+			ina226@47 { /* u75 */
+				compatible = "ti,ina226";
+				reg = <0x47>;
+				shunt-resistor = <5000>;
+			};
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			/* MAXIM_PMBUS - 00 */
+			max15301@a { /* u46 */
+				compatible = "maxim,max15301";
+				reg = <0xa>;
+			};
+			max15303@b { /* u4 */
+				compatible = "maxim,max15303";
+				reg = <0xb>;
+			};
+			max15303@10 { /* u13 */
+				compatible = "maxim,max15303";
+				reg = <0x10>;
+			};
+			max15301@13 { /* u47 */
+				compatible = "maxim,max15301";
+				reg = <0x13>;
+			};
+			max15303@14 { /* u7 */
+				compatible = "maxim,max15303";
+				reg = <0x14>;
+			};
+			max15303@15 { /* u6 */
+				compatible = "maxim,max15303";
+				reg = <0x15>;
+			};
+			max15303@16 { /* u10 */
+				compatible = "maxim,max15303";
+				reg = <0x16>;
+			};
+			max15303@17 { /* u9 */
+				compatible = "maxim,max15303";
+				reg = <0x17>;
+			};
+			max15301@18 { /* u63 */
+				compatible = "maxim,max15301";
+				reg = <0x18>;
+			};
+			max15303@1a { /* u49 */
+				compatible = "maxim,max15303";
+				reg = <0x1a>;
+			};
+			max15303@1d { /* u18 */
+				compatible = "maxim,max15303";
+				reg = <0x1d>;
+			};
+			max15303@20 { /* u8 */
+				compatible = "maxim,max15303";
+				status = "disabled"; /* unreachable */
+				reg = <0x20>;
+			};
+
+			max20751@72 { /* u95 */
+				compatible = "maxim,max20751";
+				reg = <0x72>;
+			};
+			max20751@73 { /* u96 */
+				compatible = "maxim,max20751";
+				reg = <0x73>;
+			};
+		};
+		/* Bus 3 is not connected */
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	/* PL i2c via PCA9306 - u45 */
+	i2c-mux@74 { /* u34 */
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x74>;
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/*
+			 * IIC_EEPROM 1kB memory which uses 256B blocks
+			 * where every block has different address.
+			 *    0 - 256B address 0x54
+			 * 256B - 512B address 0x55
+			 * 512B - 768B address 0x56
+			 * 768B - 1024B address 0x57
+			 */
+			eeprom: eeprom@54 { /* u23 */
+				compatible = "atmel,24c08";
+				reg = <0x54>;
+			};
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			si5341: clock-generator@36 { /* SI5341 - u69 */
+				reg = <0x36>;
+			};
+
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			si570_1: clock-generator@5d { /* USER SI570 - u42 */
+				#clock-cells = <0>;
+				compatible = "silabs,si570";
+				reg = <0x5d>;
+				temperature-stability = <50>;
+				factory-fout = <300000000>;
+				clock-frequency = <300000000>;
+			};
+		};
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			si570_2: clock-generator@5d { /* USER MGT SI570 - u56 */
+				#clock-cells = <0>;
+				compatible = "silabs,si570";
+				reg = <0x5d>;
+				temperature-stability = <50>; /* copy from zc702 */
+				factory-fout = <156250000>;
+				clock-frequency = <148500000>;
+			};
+		};
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			si5328: clock-generator@69 {/* SI5328 - u20 */
+				reg = <0x69>;
+				/*
+				 * Chip has interrupt present connected to PL
+				 * interrupt-parent = <&>;
+				 * interrupts = <>;
+				 */
+			};
+		};
+		/* 5 - 7 unconnected */
+	};
+
+	i2c-mux@75 {
+		compatible = "nxp,pca9548"; /* u135 */
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/* HPC0_IIC */
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			/* HPC1_IIC */
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			/* SYSMON */
+		};
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			/* DDR4 SODIMM */
+		};
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			/* SEP 3 */
+		};
+		i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			/* SEP 2 */
+		};
+		i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			/* SEP 1 */
+		};
+		i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			/* SEP 0 */
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&rtc {
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+	/* SATA OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+};
+
+/* SD1 with level shifter */
+&sdhci1 {
+	status = "okay";
+	no-1-8-v;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+/* ULPI SMSC USB3320 */
+&usb0 {
+	status = "okay";
+};
+
+&watchdog0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revB.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revB.dts
new file mode 100644
index 0000000..af4d868
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revB.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZCU102 RevB
+ *
+ * (C) Copyright 2016 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+#include "zynqmp-zcu102-revA.dts"
+
+/ {
+	model = "ZynqMP ZCU102 RevB";
+	compatible = "xlnx,zynqmp-zcu102-revB", "xlnx,zynqmp-zcu102", "xlnx,zynqmp";
+};
+
+&gem3 {
+	phy-handle = <&phyc>;
+	phyc: phy@c {
+		reg = <0xc>;
+		ti,rx-internal-delay = <0x8>;
+		ti,tx-internal-delay = <0xa>;
+		ti,fifo-depth = <0x1>;
+	};
+	/* Cleanup from RevA */
+	/delete-node/ phy@21;
+};
+
+/* Fix collision with u61 */
+&i2c0 {
+	i2c-mux@75 {
+		i2c@2 {
+			max15303@1b { /* u8 */
+				compatible = "maxim,max15303";
+				reg = <0x1b>;
+			};
+			/delete-node/ max15303@20;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
new file mode 100644
index 0000000..d4ad19a
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZCU104
+ *
+ * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "ZynqMP ZCU104 RevA";
+	compatible = "xlnx,zynqmp-zcu104-revA", "xlnx,zynqmp-zcu104", "xlnx,zynqmp";
+
+	aliases {
+		ethernet0 = &gem3;
+		i2c0 = &i2c1;
+		mmc0 = &sdhci1;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &dcc;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&dcc {
+	status = "okay";
+};
+
+&gem3 {
+	status = "okay";
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+	phy0: phy@c {
+		reg = <0xc>;
+		ti,rx-internal-delay = <0x8>;
+		ti,tx-internal-delay = <0xa>;
+		ti,fifo-depth = <0x1>;
+	};
+};
+
+&gpio {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	/* Another connection to this bus via PL i2c via PCA9306 - u45 */
+	i2c-mux@74 { /* u34 */
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x74>;
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/*
+			 * IIC_EEPROM 1kB memory which uses 256B blocks
+			 * where every block has different address.
+			 *    0 - 256B address 0x54
+			 * 256B - 512B address 0x55
+			 * 512B - 768B address 0x56
+			 * 768B - 1024B address 0x57
+			 */
+			eeprom@54 { /* u23 */
+				compatible = "atmel,24c08";
+				reg = <0x54>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+			};
+		};
+
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			clock_8t49n287: clock-generator@6c { /* 8T49N287 - u182 */
+				reg = <0x6c>;
+			};
+		};
+
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			irps5401_43: irps54012@43 { /* IRPS5401 - u175 */
+				reg = <0x43>;
+			};
+			irps5401_4d: irps54012@4d { /* IRPS5401 - u180 */
+				reg = <0x4d>;
+			};
+		};
+
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			tca6416_u97: gpio@21 {
+				compatible = "ti,tca6416";
+				reg = <0x21>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				/*
+				 * IRQ not connected
+				 * Lines:
+				 * 0 - IRPS5401_ALERT_B
+				 * 1 - HDMI_8T49N241_INT_ALM
+				 * 2 - MAX6643_OT_B
+				 * 3 - MAX6643_FANFAIL_B
+				 * 5 - IIC_MUX_RESET_B
+				 * 6 - GEM3_EXP_RESET_B
+				 * 7 - FMC_LPC_PRSNT_M2C_B
+				 * 4, 10 - 17 - not connected
+				 */
+			};
+		};
+
+		i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+
+		/* 3, 6 not connected */
+	};
+};
+
+&rtc {
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+	/* SATA OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+};
+
+/* SD1 with level shifter */
+&sdhci1 {
+	status = "okay";
+	no-1-8-v;
+	disable-wp;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+/* ULPI SMSC USB3320 */
+&usb0 {
+	status = "okay";
+};
+
+&watchdog0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
new file mode 100644
index 0000000..668f7f2
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
@@ -0,0 +1,522 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZCU106
+ *
+ * (C) Copyright 2016, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "ZynqMP ZCU106 RevA";
+	compatible = "xlnx,zynqmp-zcu106-revA", "xlnx,zynqmp-zcu106", "xlnx,zynqmp";
+
+	aliases {
+		ethernet0 = &gem3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		mmc0 = &sdhci1;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &dcc;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		autorepeat;
+		sw19 {
+			label = "sw19";
+			gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_DOWN>;
+			gpio-key,wakeup;
+			autorepeat;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		heartbeat_led {
+			label = "heartbeat";
+			gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&dcc {
+	status = "okay";
+};
+
+/* fpd_dma clk 667MHz, lpd_dma 500MHz */
+&fpd_dma_chan1 {
+	status = "okay";
+};
+
+&fpd_dma_chan2 {
+	status = "okay";
+};
+
+&fpd_dma_chan3 {
+	status = "okay";
+};
+
+&fpd_dma_chan4 {
+	status = "okay";
+};
+
+&fpd_dma_chan5 {
+	status = "okay";
+};
+
+&fpd_dma_chan6 {
+	status = "okay";
+};
+
+&fpd_dma_chan7 {
+	status = "okay";
+};
+
+&fpd_dma_chan8 {
+	status = "okay";
+};
+
+&gem3 {
+	status = "okay";
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+	phy0: phy@c {
+		reg = <0xc>;
+		ti,rx-internal-delay = <0x8>;
+		ti,tx-internal-delay = <0xa>;
+		ti,fifo-depth = <0x1>;
+	};
+};
+
+&gpio {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tca6416_u97: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller; /* interrupt not connected */
+		#gpio-cells = <2>;
+		/*
+		 * IRQ not connected
+		 * Lines:
+		 * 0 - SFP_SI5328_INT_ALM
+		 * 1 - HDMI_SI5328_INT_ALM
+		 * 5 - IIC_MUX_RESET_B
+		 * 6 - GEM3_EXP_RESET_B
+		 * 10 - FMC_HPC0_PRSNT_M2C_B
+		 * 11 - FMC_HPC1_PRSNT_M2C_B
+		 * 2-4, 7, 12-17 - not connected
+		 */
+	};
+
+	tca6416_u61: gpio@21 {
+		compatible = "ti,tca6416";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		/*
+		 * IRQ not connected
+		 * Lines:
+		 * 0 - VCCPSPLL_EN
+		 * 1 - MGTRAVCC_EN
+		 * 2 - MGTRAVTT_EN
+		 * 3 - VCCPSDDRPLL_EN
+		 * 4 - MIO26_PMU_INPUT_LS
+		 * 5 - PL_PMBUS_ALERT
+		 * 6 - PS_PMBUS_ALERT
+		 * 7 - MAXIM_PMBUS_ALERT
+		 * 10 - PL_DDR4_VTERM_EN
+		 * 11 - PL_DDR4_VPP_2V5_EN
+		 * 12 - PS_DIMM_VDDQ_TO_PSVCCO_ON
+		 * 13 - PS_DIMM_SUSPEND_EN
+		 * 14 - PS_DDR4_VTERM_EN
+		 * 15 - PS_DDR4_VPP_2V5_EN
+		 * 16 - 17 - not connected
+		 */
+	};
+
+	i2c-mux@75 { /* u60 */
+		compatible = "nxp,pca9544";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/* PS_PMBUS */
+			ina226@40 { /* u76 */
+				compatible = "ti,ina226";
+				reg = <0x40>;
+				shunt-resistor = <5000>;
+			};
+			ina226@41 { /* u77 */
+				compatible = "ti,ina226";
+				reg = <0x41>;
+				shunt-resistor = <5000>;
+			};
+			ina226@42 { /* u78 */
+				compatible = "ti,ina226";
+				reg = <0x42>;
+				shunt-resistor = <5000>;
+			};
+			ina226@43 { /* u87 */
+				compatible = "ti,ina226";
+				reg = <0x43>;
+				shunt-resistor = <5000>;
+			};
+			ina226@44 { /* u85 */
+				compatible = "ti,ina226";
+				reg = <0x44>;
+				shunt-resistor = <5000>;
+			};
+			ina226@45 { /* u86 */
+				compatible = "ti,ina226";
+				reg = <0x45>;
+				shunt-resistor = <5000>;
+			};
+			ina226@46 { /* u93 */
+				compatible = "ti,ina226";
+				reg = <0x46>;
+				shunt-resistor = <5000>;
+			};
+			ina226@47 { /* u88 */
+				compatible = "ti,ina226";
+				reg = <0x47>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4a { /* u15 */
+				compatible = "ti,ina226";
+				reg = <0x4a>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4b { /* u92 */
+				compatible = "ti,ina226";
+				reg = <0x4b>;
+				shunt-resistor = <5000>;
+			};
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			/* PL_PMBUS */
+			ina226@40 { /* u79 */
+				compatible = "ti,ina226";
+				reg = <0x40>;
+				shunt-resistor = <2000>;
+			};
+			ina226@41 { /* u81 */
+				compatible = "ti,ina226";
+				reg = <0x41>;
+				shunt-resistor = <5000>;
+			};
+			ina226@42 { /* u80 */
+				compatible = "ti,ina226";
+				reg = <0x42>;
+				shunt-resistor = <5000>;
+			};
+			ina226@43 { /* u84 */
+				compatible = "ti,ina226";
+				reg = <0x43>;
+				shunt-resistor = <5000>;
+			};
+			ina226@44 { /* u16 */
+				compatible = "ti,ina226";
+				reg = <0x44>;
+				shunt-resistor = <5000>;
+			};
+			ina226@45 { /* u65 */
+				compatible = "ti,ina226";
+				reg = <0x45>;
+				shunt-resistor = <5000>;
+			};
+			ina226@46 { /* u74 */
+				compatible = "ti,ina226";
+				reg = <0x46>;
+				shunt-resistor = <5000>;
+			};
+			ina226@47 { /* u75 */
+				compatible = "ti,ina226";
+				reg = <0x47>;
+				shunt-resistor = <5000>;
+			};
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			/* MAXIM_PMBUS - 00 */
+			max15301@a { /* u46 */
+				compatible = "maxim,max15301";
+				reg = <0xa>;
+			};
+			max15303@b { /* u4 */
+				compatible = "maxim,max15303";
+				reg = <0xb>;
+			};
+			max15303@10 { /* u13 */
+				compatible = "maxim,max15303";
+				reg = <0x10>;
+			};
+			max15301@13 { /* u47 */
+				compatible = "maxim,max15301";
+				reg = <0x13>;
+			};
+			max15303@14 { /* u7 */
+				compatible = "maxim,max15303";
+				reg = <0x14>;
+			};
+			max15303@15 { /* u6 */
+				compatible = "maxim,max15303";
+				reg = <0x15>;
+			};
+			max15303@16 { /* u10 */
+				compatible = "maxim,max15303";
+				reg = <0x16>;
+			};
+			max15303@17 { /* u9 */
+				compatible = "maxim,max15303";
+				reg = <0x17>;
+			};
+			max15301@18 { /* u63 */
+				compatible = "maxim,max15301";
+				reg = <0x18>;
+			};
+			max15303@1a { /* u49 */
+				compatible = "maxim,max15303";
+				reg = <0x1a>;
+			};
+			max15303@1b { /* u8 */
+				compatible = "maxim,max15303";
+				reg = <0x1b>;
+			};
+			max15303@1d { /* u18 */
+				compatible = "maxim,max15303";
+				reg = <0x1d>;
+			};
+
+			max20751@72 { /* u95 */
+				compatible = "maxim,max20751";
+				reg = <0x72>;
+			};
+			max20751@73 { /* u96 */
+				compatible = "maxim,max20751";
+				reg = <0x73>;
+			};
+		};
+		/* Bus 3 is not connected */
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	/* PL i2c via PCA9306 - u45 */
+	i2c-mux@74 { /* u34 */
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x74>;
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/*
+			 * IIC_EEPROM 1kB memory which uses 256B blocks
+			 * where every block has different address.
+			 *    0 - 256B address 0x54
+			 * 256B - 512B address 0x55
+			 * 512B - 768B address 0x56
+			 * 768B - 1024B address 0x57
+			 */
+			eeprom: eeprom@54 { /* u23 */
+				compatible = "atmel,24c08";
+				reg = <0x54>;
+			};
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			si5341: clock-generator@36 { /* SI5341 - u69 */
+				reg = <0x36>;
+			};
+
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			si570_1: clock-generator@5d { /* USER SI570 - u42 */
+				#clock-cells = <0>;
+				compatible = "silabs,si570";
+				reg = <0x5d>;
+				temperature-stability = <50>;
+				factory-fout = <300000000>;
+				clock-frequency = <300000000>;
+			};
+		};
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			si570_2: clock-generator@5d { /* USER MGT SI570 - u56 */
+				#clock-cells = <0>;
+				compatible = "silabs,si570";
+				reg = <0x5d>;
+				temperature-stability = <50>; /* copy from zc702 */
+				factory-fout = <156250000>;
+				clock-frequency = <148500000>;
+			};
+		};
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			si5328: clock-generator@69 {/* SI5328 - u20 */
+				reg = <0x69>;
+			};
+		};
+		i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>; /* FAN controller */
+			temp@4c {/* lm96163 - u128 */
+				compatible = "national,lm96163";
+				reg = <0x4c>;
+			};
+		};
+		/* 6 - 7 unconnected */
+	};
+
+	i2c-mux@75 {
+		compatible = "nxp,pca9548"; /* u135 */
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/* HPC0_IIC */
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			/* HPC1_IIC */
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			/* SYSMON */
+		};
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			/* DDR4 SODIMM */
+		};
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			/* SEP 3 */
+		};
+		i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			/* SEP 2 */
+		};
+		i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			/* SEP 1 */
+		};
+		i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			/* SEP 0 */
+		};
+	};
+};
+
+&rtc {
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+	/* SATA OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+};
+
+/* SD1 with level shifter */
+&sdhci1 {
+	status = "okay";
+	no-1-8-v;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+/* ULPI SMSC USB3320 */
+&usb0 {
+	status = "okay";
+};
+
+&watchdog0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
new file mode 100644
index 0000000..9a9dd6a
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZCU111
+ *
+ * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "ZynqMP ZCU111 RevA";
+	compatible = "xlnx,zynqmp-zcu111-revA", "xlnx,zynqmp-zcu111", "xlnx,zynqmp";
+
+	aliases {
+		ethernet0 = &gem3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		mmc0 = &sdhci1;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+		serial1 = &dcc;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+		/* Another 4GB connected to PL */
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		autorepeat;
+		sw19 {
+			label = "sw19";
+			gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_DOWN>;
+			gpio-key,wakeup;
+			autorepeat;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		heartbeat_led {
+			label = "heartbeat";
+			gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+};
+
+&dcc {
+	status = "okay";
+};
+
+&fpd_dma_chan1 {
+	status = "okay";
+};
+
+&fpd_dma_chan2 {
+	status = "okay";
+};
+
+&fpd_dma_chan3 {
+	status = "okay";
+};
+
+&fpd_dma_chan4 {
+	status = "okay";
+};
+
+&fpd_dma_chan5 {
+	status = "okay";
+};
+
+&fpd_dma_chan6 {
+	status = "okay";
+};
+
+&fpd_dma_chan7 {
+	status = "okay";
+};
+
+&fpd_dma_chan8 {
+	status = "okay";
+};
+
+&gem3 {
+	status = "okay";
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+	phy0: phy@c {
+		reg = <0xc>;
+		ti,rx-internal-delay = <0x8>;
+		ti,tx-internal-delay = <0xa>;
+		ti,fifo-depth = <0x1>;
+	};
+};
+
+&gpio {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tca6416_u22: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller; /* interrupt not connected */
+		#gpio-cells = <2>;
+		/*
+		 * IRQ not connected
+		 * Lines:
+		 * 0 - MAX6643_OT_B
+		 * 1 - MAX6643_FANFAIL_B
+		 * 2 - MIO26_PMU_INPUT_LS
+		 * 4 - SFP_SI5382_INT_ALM
+		 * 5 - IIC_MUX_RESET_B
+		 * 6 - GEM3_EXP_RESET_B
+		 * 10 - FMCP_HSPC_PRSNT_M2C_B
+		 * 11 - CLK_SPI_MUX_SEL0
+		 * 12 - CLK_SPI_MUX_SEL1
+		 * 16 - IRPS5401_ALERT_B
+		 * 17 - INA226_PMBUS_ALERT
+		 * 3, 7, 13-15 - not connected
+		 */
+	};
+
+	i2c-mux@75 { /* u23 */
+		compatible = "nxp,pca9544";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/* PS_PMBUS */
+			/* PMBUS_ALERT done via pca9544 */
+			ina226@40 { /* u67 */
+				compatible = "ti,ina226";
+				reg = <0x40>;
+				shunt-resistor = <2000>;
+			};
+			ina226@41 { /* u59 */
+				compatible = "ti,ina226";
+				reg = <0x41>;
+				shunt-resistor = <5000>;
+			};
+			ina226@42 { /* u61 */
+				compatible = "ti,ina226";
+				reg = <0x42>;
+				shunt-resistor = <5000>;
+			};
+			ina226@43 { /* u60 */
+				compatible = "ti,ina226";
+				reg = <0x43>;
+				shunt-resistor = <5000>;
+			};
+			ina226@45 { /* u64 */
+				compatible = "ti,ina226";
+				reg = <0x45>;
+				shunt-resistor = <5000>;
+			};
+			ina226@46 { /* u69 */
+				compatible = "ti,ina226";
+				reg = <0x46>;
+				shunt-resistor = <2000>;
+			};
+			ina226@47 { /* u66 */
+				compatible = "ti,ina226";
+				reg = <0x47>;
+				shunt-resistor = <5000>;
+			};
+			ina226@48 { /* u65 */
+				compatible = "ti,ina226";
+				reg = <0x48>;
+				shunt-resistor = <5000>;
+			};
+			ina226@49 { /* u63 */
+				compatible = "ti,ina226";
+				reg = <0x49>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4a { /* u3 */
+				compatible = "ti,ina226";
+				reg = <0x4a>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4b { /* u71 */
+				compatible = "ti,ina226";
+				reg = <0x4b>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4c { /* u77 */
+				compatible = "ti,ina226";
+				reg = <0x4c>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4d { /* u73 */
+				compatible = "ti,ina226";
+				reg = <0x4d>;
+				shunt-resistor = <5000>;
+			};
+			ina226@4e { /* u79 */
+				compatible = "ti,ina226";
+				reg = <0x4e>;
+				shunt-resistor = <5000>;
+			};
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			/* NC */
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			irps5401_43: irps54012@43 { /* IRPS5401 - u53 check these */
+				reg = <0x43>;
+			};
+			irps5401_44: irps54012@44 { /* IRPS5401 - u55 */
+				reg = <0x44>;
+			};
+			irps5401_45: irps54012@45 { /* IRPS5401 - u57 */
+				reg = <0x45>;
+			};
+			/* u68 IR38064 +0 */
+			/* u70 IR38060 +1 */
+			/* u74 IR38060 +2 */
+			/* u75 IR38060 +6 */
+			/* J19 header too */
+
+		};
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			/* SYSMON */
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	i2c-mux@74 { /* u26 */
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x74>;
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/*
+			 * IIC_EEPROM 1kB memory which uses 256B blocks
+			 * where every block has different address.
+			 *    0 - 256B address 0x54
+			 * 256B - 512B address 0x55
+			 * 512B - 768B address 0x56
+			 * 768B - 1024B address 0x57
+			 */
+			eeprom: eeprom@54 { /* u88 */
+				compatible = "atmel,24c08";
+				reg = <0x54>;
+			};
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			si5341: clock-generator@36 { /* SI5341 - u46 */
+				reg = <0x36>;
+			};
+
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			si570_1: clock-generator@5d { /* USER SI570 - u47 */
+				#clock-cells = <0>;
+				compatible = "silabs,si570";
+				reg = <0x5d>;
+				temperature-stability = <50>;
+				factory-fout = <300000000>;
+				clock-frequency = <300000000>;
+			};
+		};
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			si570_2: clock-generator@5d { /* USER MGT SI570 - u49 */
+				#clock-cells = <0>;
+				compatible = "silabs,si570";
+				reg = <0x5d>;
+				temperature-stability = <50>;
+				factory-fout = <156250000>;
+				clock-frequency = <148500000>;
+			};
+		};
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			si5328: clock-generator@69 { /* SI5328 - u48 */
+				reg = <0x69>;
+			};
+		};
+		i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+				sc18is603@2f { /* sc18is602 - u93 */
+					compatible = "nxp,sc18is603";
+					reg = <0x2f>;
+					/* 4 gpios for CS not handled by driver */
+					/*
+					 * USB2ANY cable or
+					 * LMK04208 - u90 or
+					 * LMX2594 - u102 or
+					 * LMX2594 - u103 or
+					 * LMX2594 - u104
+					 */
+				};
+		};
+		i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			/* FMC connector */
+		};
+		/* 7 NC */
+	};
+
+	i2c-mux@75 {
+		compatible = "nxp,pca9548"; /* u27 */
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			/* FMCP_HSPC_IIC */
+		};
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			/* NC */
+		};
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			/* SYSMON */
+		};
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			/* DDR4 SODIMM */
+		};
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			/* SFP3 */
+		};
+		i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			/* SFP2 */
+		};
+		i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			/* SFP1 */
+		};
+		i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			/* SFP0 */
+		};
+	};
+};
+
+&rtc {
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+	/* SATA OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+};
+
+/* SD1 with level shifter */
+&sdhci1 {
+	status = "okay";
+	no-1-8-v;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+/* ULPI SMSC USB3320 */
+&usb0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 7665fbd..a091e6f 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * dts file for Xilinx ZynqMP
  *
@@ -355,7 +356,7 @@
 		};
 
 		gem0: ethernet@ff0b0000 {
-			compatible = "cdns,gem";
+			compatible = "cdns,zynqmp-gem", "cdns,gem";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupts = <0 57 4>, <0 57 4>;
@@ -366,7 +367,7 @@
 		};
 
 		gem1: ethernet@ff0c0000 {
-			compatible = "cdns,gem";
+			compatible = "cdns,zynqmp-gem", "cdns,gem";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupts = <0 59 4>, <0 59 4>;
@@ -377,7 +378,7 @@
 		};
 
 		gem2: ethernet@ff0d0000 {
-			compatible = "cdns,gem";
+			compatible = "cdns,zynqmp-gem", "cdns,gem";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupts = <0 61 4>, <0 61 4>;
@@ -388,7 +389,7 @@
 		};
 
 		gem3: ethernet@ff0e0000 {
-			compatible = "cdns,gem";
+			compatible = "cdns,zynqmp-gem", "cdns,gem";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupts = <0 63 4>, <0 63 4>;
@@ -439,10 +440,10 @@
 			device_type = "pci";
 			interrupt-parent = <&gic>;
 			interrupts = <0 118 4>,
-				    <0 117 4>,
-				    <0 116 4>,
-				    <0 115 4>,	/* MSI_1 [63...32] */
-				    <0 114 4>;	/* MSI_0 [31...0] */
+				     <0 117 4>,
+				     <0 116 4>,
+				     <0 115 4>,	/* MSI_1 [63...32] */
+				     <0 114 4>;	/* MSI_0 [31...0] */
 			interrupt-names = "misc", "dummy", "intx",
 					  "msi1", "msi0";
 			msi-parent = <&pcie>;
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 634b373..ecf6137 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -31,7 +31,6 @@
 CONFIG_JUMP_LABEL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
 CONFIG_ARCH_BCM2835=y
@@ -51,11 +50,14 @@
 CONFIG_ARCH_RENESAS=y
 CONFIG_ARCH_R8A7795=y
 CONFIG_ARCH_R8A7796=y
+CONFIG_ARCH_R8A77965=y
 CONFIG_ARCH_R8A77970=y
+CONFIG_ARCH_R8A77980=y
 CONFIG_ARCH_R8A77995=y
 CONFIG_ARCH_STRATIX10=y
 CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_SPRD=y
+CONFIG_ARCH_SYNQUACER=y
 CONFIG_ARCH_THUNDER=y
 CONFIG_ARCH_THUNDER2=y
 CONFIG_ARCH_UNIPHIER=y
@@ -99,10 +101,19 @@
 CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
 CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
 CONFIG_ARM_SCPI_CPUFREQ=y
+CONFIG_ARM_TEGRA186_CPUFREQ=y
 CONFIG_ACPI_CPPC_CPUFREQ=m
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -209,7 +220,14 @@
 CONFIG_RAVB=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
+CONFIG_SNI_AVE=y
+CONFIG_SNI_NETSEC=y
 CONFIG_STMMAC_ETH=m
+CONFIG_DWMAC_IPQ806X=m
+CONFIG_DWMAC_MESON=m
+CONFIG_DWMAC_ROCKCHIP=m
+CONFIG_DWMAC_SUNXI=m
+CONFIG_DWMAC_SUN8I=m
 CONFIG_MDIO_BUS_MUX_MMIOREG=y
 CONFIG_AT803X_PHY=m
 CONFIG_MARVELL_PHY=m
@@ -305,6 +323,7 @@
 CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_GPIO_DWAPB=y
+CONFIG_GPIO_MB86S7X=y
 CONFIG_GPIO_PL061=y
 CONFIG_GPIO_RCAR=y
 CONFIG_GPIO_UNIPHIER=y
@@ -327,7 +346,10 @@
 CONFIG_BRCMSTB_THERMAL=m
 CONFIG_EXYNOS_THERMAL=y
 CONFIG_RCAR_GEN3_THERMAL=y
+CONFIG_QCOM_TSENS=y
 CONFIG_ROCKCHIP_THERMAL=m
+CONFIG_TEGRA_BPMP_THERMAL=m
+CONFIG_UNIPHIER_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_S3C2410_WATCHDOG=y
 CONFIG_MESON_GXBB_WATCHDOG=m
@@ -444,12 +466,14 @@
 CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_USB_RENESAS_USB3=m
 CONFIG_USB_ULPI_BUS=y
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ACPI=y
+CONFIG_MMC_SDHCI_F_SDH30=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_OF_ARASAN=y
 CONFIG_MMC_SDHCI_OF_ESDHC=y
@@ -500,6 +524,7 @@
 CONFIG_QCOM_HIDMA_MGMT=y
 CONFIG_QCOM_HIDMA=y
 CONFIG_RCAR_DMAC=y
+CONFIG_RENESAS_USB_DMAC=m
 CONFIG_VFIO=y
 CONFIG_VFIO_PCI=y
 CONFIG_VIRTIO_PCI=y
@@ -525,7 +550,9 @@
 CONFIG_PLATFORM_MHU=y
 CONFIG_BCM2835_MBOX=y
 CONFIG_HI6220_MBOX=y
+CONFIG_QCOM_APCS_IPC=y
 CONFIG_ROCKCHIP_IOMMU=y
+CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_ARM_SMMU=y
 CONFIG_ARM_SMMU_V3=y
 CONFIG_QCOM_IOMMU=y
@@ -539,7 +566,10 @@
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_ARCH_TEGRA_186_SOC=y
+CONFIG_ARCH_TEGRA_194_SOC=y
 CONFIG_EXTCON_USB_GPIO=y
+CONFIG_MEMORY=y
+CONFIG_TEGRA_MC=y
 CONFIG_IIO=y
 CONFIG_EXYNOS_ADC=y
 CONFIG_ROCKCHIP_SARADC=m
@@ -547,10 +577,12 @@
 CONFIG_PWM_BCM2835=m
 CONFIG_PWM_CROS_EC=m
 CONFIG_PWM_MESON=m
+CONFIG_PWM_RCAR=m
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_PWM_SAMSUNG=y
 CONFIG_PWM_TEGRA=m
 CONFIG_PHY_RCAR_GEN3_USB2=y
+CONFIG_PHY_RCAR_GEN3_USB3=m
 CONFIG_PHY_HI6220_USB=y
 CONFIG_PHY_QCOM_USB_HS=y
 CONFIG_PHY_SUN4I_USB=y
@@ -562,6 +594,8 @@
 CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
+CONFIG_MESON_EFUSE=m
+CONFIG_QCOM_QFPROM=y
 CONFIG_UNIPHIER_EFUSE=y
 CONFIG_TEE=y
 CONFIG_OPTEE=y
@@ -629,3 +663,6 @@
 CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
 CONFIG_CRYPTO_AES_ARM64_BS=m
+CONFIG_CRYPTO_SHA512_ARM64_CE=m
+CONFIG_CRYPTO_SHA3_ARM64=m
+CONFIG_CRYPTO_SM3_ARM64_CE=m
diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
index c7fcb23..a820ed0 100644
--- a/arch/arm64/kernel/image.h
+++ b/arch/arm64/kernel/image.h
@@ -103,6 +103,7 @@ __efistub_strlen		= KALLSYMS_HIDE(__pi_strlen);
 __efistub_strnlen		= KALLSYMS_HIDE(__pi_strnlen);
 __efistub_strcmp		= KALLSYMS_HIDE(__pi_strcmp);
 __efistub_strncmp		= KALLSYMS_HIDE(__pi_strncmp);
+__efistub_strrchr		= KALLSYMS_HIDE(__pi_strrchr);
 __efistub___flush_dcache_area	= KALLSYMS_HIDE(__pi___flush_dcache_area);
 
 #ifdef CONFIG_KASAN
diff --git a/arch/arm64/lib/strrchr.S b/arch/arm64/lib/strrchr.S
index 61eabd9..f8e2784 100644
--- a/arch/arm64/lib/strrchr.S
+++ b/arch/arm64/lib/strrchr.S
@@ -40,4 +40,4 @@
 	b	1b
 2:	mov	x0, x3
 	ret
-ENDPROC(strrchr)
+ENDPIPROC(strrchr)
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index e79421f..f7cd5ec 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -574,6 +574,66 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *
 
 #endif /* CONFIG_FPU */
 
+static inline void siginfo_build_tests(void)
+{
+	/* This needs to be tested on m68k as it has a lesser
+	 * alignment requirment than x86 and that can cause surprises.
+	 */
+
+	/* This is part of the ABI and can never change in size: */
+	BUILD_BUG_ON(sizeof(siginfo_t) != 128);
+
+	/* Ensure the know fields never change in location */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_signo) != 0);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_errno) != 4);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_code)  != 8);
+
+	/* _kill */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x0C);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x10);
+
+	/* _timer */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_tid)     != 0x0C);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_overrun) != 0x10);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_value)   != 0x14);
+
+	/* _rt */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_pid)   != 0x0C);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_uid)   != 0x10);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x14);
+
+	/* _sigchld */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_pid)    != 0x0C);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_uid)    != 0x10);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_status) != 0x14);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_utime)  != 0x18);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_stime)  != 0x1C);
+
+	/* _sigfault */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x0C);
+
+	/* _sigfault._mcerr */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x10);
+
+	/* _sigfault._addr_bnd */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_lower) != 0x12);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_upper) != 0x16);
+
+	/* _sigfault._addr_pkey */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12);
+
+	/* _sigpoll */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_band)   != 0x0C);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_fd)     != 0x10);
+
+	/* _sigsys */
+	BUILD_BUG_ON(offsetof(siginfo_t, si_call_addr) != 0x0C);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_syscall)   != 0x10);
+	BUILD_BUG_ON(offsetof(siginfo_t, si_arch)      != 0x14);
+
+	/* any new si_fields should be added here */
+}
+
 static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
 			       void __user *fp)
 {
@@ -635,6 +695,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u
 	struct sigcontext context;
 	int err = 0;
 
+	siginfo_build_tests();
+
 	/* Always make any pending restarted system calls return -EINTR */
 	current->restart_block.fn = do_no_restart_syscall;
 
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c
index a701261..98042ef 100644
--- a/arch/powerpc/boot/stdio.c
+++ b/arch/powerpc/boot/stdio.c
@@ -21,6 +21,16 @@ size_t strnlen(const char * s, size_t count)
 	return sc - s;
 }
 
+char *strrchr(const char *s, int c)
+{
+	const char *last = NULL;
+	do {
+		if (*s == (char)c)
+			last = s;
+	} while (*s++);
+	return (char *)last;
+}
+
 #ifdef __powerpc64__
 
 # define do_div(n, base) ({						\
diff --git a/arch/powerpc/boot/string.h b/arch/powerpc/boot/string.h
index 3fb7117..8c2ec0c 100644
--- a/arch/powerpc/boot/string.h
+++ b/arch/powerpc/boot/string.h
@@ -7,6 +7,7 @@ extern char *strcpy(char *dest, const char *src);
 extern char *strncpy(char *dest, const char *src, size_t n);
 extern char *strcat(char *dest, const char *src);
 extern char *strchr(const char *s, int c);
+extern char *strrchr(const char *s, int c);
 extern int strcmp(const char *s1, const char *s2);
 extern int strncmp(const char *s1, const char *s2, size_t n);
 extern size_t strlen(const char *s);
diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig
index 4bb832a..6c1196b 100644
--- a/arch/powerpc/configs/c2k_defconfig
+++ b/arch/powerpc/configs/c2k_defconfig
@@ -184,7 +184,6 @@
 CONFIG_MEGARAID_MM=m
 CONFIG_MEGARAID_MAILBOX=m
 CONFIG_MEGARAID_SAS=m
-CONFIG_SCSI_FUTURE_DOMAIN=m
 CONFIG_SCSI_GDTH=m
 CONFIG_SCSI_IPS=m
 CONFIG_SCSI_INITIO=m
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 27fede4..d234cca 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1296,7 +1296,7 @@
 	  the Linux kernel.
 
 	  The preferred method to load microcode from a detached initrd is described
-	  in Documentation/x86/early-microcode.txt. For that you need to enable
+	  in Documentation/x86/microcode.txt. For that you need to enable
 	  CONFIG_BLK_DEV_INITRD in order for the loader to be able to scan the
 	  initrd for microcode blobs.
 
@@ -2665,11 +2665,13 @@
 source "drivers/pci/Kconfig"
 
 config ISA_BUS
-	bool "ISA-style bus support on modern systems" if EXPERT
-	select ISA_BUS_API
+	bool "ISA bus support on modern systems" if EXPERT
 	help
-	  Enables ISA-style drivers on modern systems. This is necessary to
-	  support PC/104 devices on X86_64 platforms.
+	  Expose ISA bus device drivers and options available for selection and
+	  configuration. Enable this option if your target machine has an ISA
+	  bus. ISA is an older system, displaced by PCI and newer bus
+	  architectures -- if your target machine is modern, it probably does
+	  not have an ISA bus.
 
 	  If unsure, say N.
 
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
index 46e1ef1..92212bf 100644
--- a/arch/x86/include/asm/atomic64_32.h
+++ b/arch/x86/include/asm/atomic64_32.h
@@ -123,7 +123,7 @@ static inline long long arch_atomic64_read(const atomic64_t *v)
 	long long r;
 	alternative_atomic64(read, "=&A" (r), "c" (v) : "memory");
 	return r;
- }
+}
 
 /**
  * arch_atomic64_add_return - add and return
diff --git a/arch/x86/include/asm/platform_sst_audio.h b/arch/x86/include/asm/platform_sst_audio.h
index 5973a2f..059823b 100644
--- a/arch/x86/include/asm/platform_sst_audio.h
+++ b/arch/x86/include/asm/platform_sst_audio.h
@@ -135,6 +135,7 @@ struct sst_platform_info {
 	const struct sst_res_info *res_info;
 	const struct sst_lib_dnld_info *lib_info;
 	const char *platform;
+	bool streams_lost_on_suspend;
 };
 int add_sst_platform_device(void);
 #endif
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 4817992..0624957 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -58,7 +58,7 @@ static u8 amd_ucode_patch[PATCH_MAX_SIZE];
 
 /*
  * Microcode patch container file is prepended to the initrd in cpio
- * format. See Documentation/x86/early-microcode.txt
+ * format. See Documentation/x86/microcode.txt
  */
 static const char
 ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin";
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index 1b64184..026211e 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -21,7 +21,6 @@
 #include <platform/simcall.h>
 
 #define SIMDISK_MAJOR 240
-#define SECTOR_SHIFT 9
 #define SIMDISK_MINORS 1
 #define MAX_SIMDISK_COUNT 10
 
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index aeca22d..f0ecd98 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -201,7 +201,20 @@ static struct kmem_cache *bfq_pool;
 /* Target observation time interval for a peak-rate update (ns) */
 #define BFQ_RATE_REF_INTERVAL	NSEC_PER_SEC
 
-/* Shift used for peak rate fixed precision calculations. */
+/*
+ * Shift used for peak-rate fixed precision calculations.
+ * With
+ * - the current shift: 16 positions
+ * - the current type used to store rate: u32
+ * - the current unit of measure for rate: [sectors/usec], or, more precisely,
+ *   [(sectors/usec) / 2^BFQ_RATE_SHIFT] to take into account the shift,
+ * the range of rates that can be stored is
+ * [1 / 2^BFQ_RATE_SHIFT, 2^(32 - BFQ_RATE_SHIFT)] sectors/usec =
+ * [1 / 2^16, 2^16] sectors/usec = [15e-6, 65536] sectors/usec =
+ * [15, 65G] sectors/sec
+ * Which, assuming a sector size of 512B, corresponds to a range of
+ * [7.5K, 33T] B/sec
+ */
 #define BFQ_RATE_SHIFT		16
 
 /*
@@ -2637,6 +2650,16 @@ static void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
 	rate /= divisor; /* smoothing constant alpha = 1/divisor */
 
 	bfqd->peak_rate += rate;
+
+	/*
+	 * For a very slow device, bfqd->peak_rate can reach 0 (see
+	 * the minimum representable values reported in the comments
+	 * on BFQ_RATE_SHIFT). Push to 1 if this happens, to avoid
+	 * divisions by zero where bfqd->peak_rate is used as a
+	 * divisor.
+	 */
+	bfqd->peak_rate = max_t(u32, 1, bfqd->peak_rate);
+
 	update_thr_responsiveness_params(bfqd);
 
 reset_computation:
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
index 350c39a..ae2f3da 100644
--- a/block/bfq-iosched.h
+++ b/block/bfq-iosched.h
@@ -499,7 +499,7 @@ struct bfq_data {
 	u64 delta_from_first;
 	/*
 	 * Current estimate of the device peak rate, measured in
-	 * [BFQ_RATE_SHIFT * sectors/usec]. The left-shift by
+	 * [(sectors/usec) / 2^BFQ_RATE_SHIFT]. The left-shift by
 	 * BFQ_RATE_SHIFT is performed to increase precision in
 	 * fixed-point calculations.
 	 */
diff --git a/block/bio.c b/block/bio.c
index e1708db..53e0f0a 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -43,9 +43,9 @@
  * break badly! cannot be bigger than what you can fit into an
  * unsigned short
  */
-#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
+#define BV(x, n) { .nr_vecs = x, .name = "biovec-"#n }
 static struct biovec_slab bvec_slabs[BVEC_POOL_NR] __read_mostly = {
-	BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
+	BV(1, 1), BV(4, 4), BV(16, 16), BV(64, 64), BV(128, 128), BV(BIO_MAX_PAGES, max),
 };
 #undef BV
 
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index c2033a2..1c16694 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -307,11 +307,28 @@ struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
 	}
 }
 
+static void blkg_pd_offline(struct blkcg_gq *blkg)
+{
+	int i;
+
+	lockdep_assert_held(blkg->q->queue_lock);
+	lockdep_assert_held(&blkg->blkcg->lock);
+
+	for (i = 0; i < BLKCG_MAX_POLS; i++) {
+		struct blkcg_policy *pol = blkcg_policy[i];
+
+		if (blkg->pd[i] && !blkg->pd[i]->offline &&
+		    pol->pd_offline_fn) {
+			pol->pd_offline_fn(blkg->pd[i]);
+			blkg->pd[i]->offline = true;
+		}
+	}
+}
+
 static void blkg_destroy(struct blkcg_gq *blkg)
 {
 	struct blkcg *blkcg = blkg->blkcg;
 	struct blkcg_gq *parent = blkg->parent;
-	int i;
 
 	lockdep_assert_held(blkg->q->queue_lock);
 	lockdep_assert_held(&blkcg->lock);
@@ -320,13 +337,6 @@ static void blkg_destroy(struct blkcg_gq *blkg)
 	WARN_ON_ONCE(list_empty(&blkg->q_node));
 	WARN_ON_ONCE(hlist_unhashed(&blkg->blkcg_node));
 
-	for (i = 0; i < BLKCG_MAX_POLS; i++) {
-		struct blkcg_policy *pol = blkcg_policy[i];
-
-		if (blkg->pd[i] && pol->pd_offline_fn)
-			pol->pd_offline_fn(blkg->pd[i]);
-	}
-
 	if (parent) {
 		blkg_rwstat_add_aux(&parent->stat_bytes, &blkg->stat_bytes);
 		blkg_rwstat_add_aux(&parent->stat_ios, &blkg->stat_ios);
@@ -369,6 +379,7 @@ static void blkg_destroy_all(struct request_queue *q)
 		struct blkcg *blkcg = blkg->blkcg;
 
 		spin_lock(&blkcg->lock);
+		blkg_pd_offline(blkg);
 		blkg_destroy(blkg);
 		spin_unlock(&blkcg->lock);
 	}
@@ -995,25 +1006,25 @@ static struct cftype blkcg_legacy_files[] = {
  * @css: css of interest
  *
  * This function is called when @css is about to go away and responsible
- * for shooting down all blkgs associated with @css.  blkgs should be
- * removed while holding both q and blkcg locks.  As blkcg lock is nested
- * inside q lock, this function performs reverse double lock dancing.
+ * for offlining all blkgs pd and killing all wbs associated with @css.
+ * blkgs pd offline should be done while holding both q and blkcg locks.
+ * As blkcg lock is nested inside q lock, this function performs reverse
+ * double lock dancing.
  *
  * This is the blkcg counterpart of ioc_release_fn().
  */
 static void blkcg_css_offline(struct cgroup_subsys_state *css)
 {
 	struct blkcg *blkcg = css_to_blkcg(css);
+	struct blkcg_gq *blkg;
 
 	spin_lock_irq(&blkcg->lock);
 
-	while (!hlist_empty(&blkcg->blkg_list)) {
-		struct blkcg_gq *blkg = hlist_entry(blkcg->blkg_list.first,
-						struct blkcg_gq, blkcg_node);
+	hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
 		struct request_queue *q = blkg->q;
 
 		if (spin_trylock(q->queue_lock)) {
-			blkg_destroy(blkg);
+			blkg_pd_offline(blkg);
 			spin_unlock(q->queue_lock);
 		} else {
 			spin_unlock_irq(&blkcg->lock);
@@ -1027,11 +1038,43 @@ static void blkcg_css_offline(struct cgroup_subsys_state *css)
 	wb_blkcg_offline(blkcg);
 }
 
+/**
+ * blkcg_destroy_all_blkgs - destroy all blkgs associated with a blkcg
+ * @blkcg: blkcg of interest
+ *
+ * This function is called when blkcg css is about to free and responsible for
+ * destroying all blkgs associated with @blkcg.
+ * blkgs should be removed while holding both q and blkcg locks. As blkcg lock
+ * is nested inside q lock, this function performs reverse double lock dancing.
+ */
+static void blkcg_destroy_all_blkgs(struct blkcg *blkcg)
+{
+	spin_lock_irq(&blkcg->lock);
+	while (!hlist_empty(&blkcg->blkg_list)) {
+		struct blkcg_gq *blkg = hlist_entry(blkcg->blkg_list.first,
+						    struct blkcg_gq,
+						    blkcg_node);
+		struct request_queue *q = blkg->q;
+
+		if (spin_trylock(q->queue_lock)) {
+			blkg_destroy(blkg);
+			spin_unlock(q->queue_lock);
+		} else {
+			spin_unlock_irq(&blkcg->lock);
+			cpu_relax();
+			spin_lock_irq(&blkcg->lock);
+		}
+	}
+	spin_unlock_irq(&blkcg->lock);
+}
+
 static void blkcg_css_free(struct cgroup_subsys_state *css)
 {
 	struct blkcg *blkcg = css_to_blkcg(css);
 	int i;
 
+	blkcg_destroy_all_blkgs(blkcg);
+
 	mutex_lock(&blkcg_pol_mutex);
 
 	list_del(&blkcg->all_blkcgs_node);
@@ -1371,8 +1414,11 @@ void blkcg_deactivate_policy(struct request_queue *q,
 		spin_lock(&blkg->blkcg->lock);
 
 		if (blkg->pd[pol->plid]) {
-			if (pol->pd_offline_fn)
+			if (!blkg->pd[pol->plid]->offline &&
+			    pol->pd_offline_fn) {
 				pol->pd_offline_fn(blkg->pd[pol->plid]);
+				blkg->pd[pol->plid]->offline = true;
+			}
 			pol->pd_free_fn(blkg->pd[pol->plid]);
 			blkg->pd[pol->plid] = NULL;
 		}
diff --git a/block/blk-core.c b/block/blk-core.c
index 6d82c4f..abcb868 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -71,6 +71,78 @@ struct kmem_cache *blk_requestq_cachep;
  */
 static struct workqueue_struct *kblockd_workqueue;
 
+/**
+ * blk_queue_flag_set - atomically set a queue flag
+ * @flag: flag to be set
+ * @q: request queue
+ */
+void blk_queue_flag_set(unsigned int flag, struct request_queue *q)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	queue_flag_set(flag, q);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+}
+EXPORT_SYMBOL(blk_queue_flag_set);
+
+/**
+ * blk_queue_flag_clear - atomically clear a queue flag
+ * @flag: flag to be cleared
+ * @q: request queue
+ */
+void blk_queue_flag_clear(unsigned int flag, struct request_queue *q)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	queue_flag_clear(flag, q);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+}
+EXPORT_SYMBOL(blk_queue_flag_clear);
+
+/**
+ * blk_queue_flag_test_and_set - atomically test and set a queue flag
+ * @flag: flag to be set
+ * @q: request queue
+ *
+ * Returns the previous value of @flag - 0 if the flag was not set and 1 if
+ * the flag was already set.
+ */
+bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q)
+{
+	unsigned long flags;
+	bool res;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	res = queue_flag_test_and_set(flag, q);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+
+	return res;
+}
+EXPORT_SYMBOL_GPL(blk_queue_flag_test_and_set);
+
+/**
+ * blk_queue_flag_test_and_clear - atomically test and clear a queue flag
+ * @flag: flag to be cleared
+ * @q: request queue
+ *
+ * Returns the previous value of @flag - 0 if the flag was not set and 1 if
+ * the flag was set.
+ */
+bool blk_queue_flag_test_and_clear(unsigned int flag, struct request_queue *q)
+{
+	unsigned long flags;
+	bool res;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	res = queue_flag_test_and_clear(flag, q);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+
+	return res;
+}
+EXPORT_SYMBOL_GPL(blk_queue_flag_test_and_clear);
+
 static void blk_clear_congested(struct request_list *rl, int sync)
 {
 #ifdef CONFIG_CGROUP_WRITEBACK
@@ -361,25 +433,14 @@ EXPORT_SYMBOL(blk_sync_queue);
  */
 int blk_set_preempt_only(struct request_queue *q)
 {
-	unsigned long flags;
-	int res;
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	res = queue_flag_test_and_set(QUEUE_FLAG_PREEMPT_ONLY, q);
-	spin_unlock_irqrestore(q->queue_lock, flags);
-
-	return res;
+	return blk_queue_flag_test_and_set(QUEUE_FLAG_PREEMPT_ONLY, q);
 }
 EXPORT_SYMBOL_GPL(blk_set_preempt_only);
 
 void blk_clear_preempt_only(struct request_queue *q)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	queue_flag_clear(QUEUE_FLAG_PREEMPT_ONLY, q);
+	blk_queue_flag_clear(QUEUE_FLAG_PREEMPT_ONLY, q);
 	wake_up_all(&q->mq_freeze_wq);
-	spin_unlock_irqrestore(q->queue_lock, flags);
 }
 EXPORT_SYMBOL_GPL(blk_clear_preempt_only);
 
@@ -629,9 +690,7 @@ EXPORT_SYMBOL_GPL(blk_queue_bypass_end);
 
 void blk_set_queue_dying(struct request_queue *q)
 {
-	spin_lock_irq(q->queue_lock);
-	queue_flag_set(QUEUE_FLAG_DYING, q);
-	spin_unlock_irq(q->queue_lock);
+	blk_queue_flag_set(QUEUE_FLAG_DYING, q);
 
 	/*
 	 * When queue DYING flag is set, we need to block new req
@@ -719,6 +778,37 @@ void blk_cleanup_queue(struct request_queue *q)
 	del_timer_sync(&q->backing_dev_info->laptop_mode_wb_timer);
 	blk_sync_queue(q);
 
+	/*
+	 * I/O scheduler exit is only safe after the sysfs scheduler attribute
+	 * has been removed.
+	 */
+	WARN_ON_ONCE(q->kobj.state_in_sysfs);
+
+	/*
+	 * Since the I/O scheduler exit code may access cgroup information,
+	 * perform I/O scheduler exit before disassociating from the block
+	 * cgroup controller.
+	 */
+	if (q->elevator) {
+		ioc_clear_queue(q);
+		elevator_exit(q, q->elevator);
+		q->elevator = NULL;
+	}
+
+	/*
+	 * Remove all references to @q from the block cgroup controller before
+	 * restoring @q->queue_lock to avoid that restoring this pointer causes
+	 * e.g. blkcg_print_blkgs() to crash.
+	 */
+	blkcg_exit_queue(q);
+
+	/*
+	 * Since the cgroup code may dereference the @q->backing_dev_info
+	 * pointer, only decrease its reference count after having removed the
+	 * association with the block cgroup controller.
+	 */
+	bdi_put(q->backing_dev_info);
+
 	if (q->mq_ops)
 		blk_mq_free_queue(q);
 	percpu_ref_exit(&q->q_usage_counter);
@@ -810,7 +900,7 @@ void blk_exit_rl(struct request_queue *q, struct request_list *rl)
 
 struct request_queue *blk_alloc_queue(gfp_t gfp_mask)
 {
-	return blk_alloc_queue_node(gfp_mask, NUMA_NO_NODE);
+	return blk_alloc_queue_node(gfp_mask, NUMA_NO_NODE, NULL);
 }
 EXPORT_SYMBOL(blk_alloc_queue);
 
@@ -827,7 +917,7 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags)
 		bool success = false;
 		int ret;
 
-		rcu_read_lock_sched();
+		rcu_read_lock();
 		if (percpu_ref_tryget_live(&q->q_usage_counter)) {
 			/*
 			 * The code that sets the PREEMPT_ONLY flag is
@@ -840,7 +930,7 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags)
 				percpu_ref_put(&q->q_usage_counter);
 			}
 		}
-		rcu_read_unlock_sched();
+		rcu_read_unlock();
 
 		if (success)
 			return 0;
@@ -888,7 +978,21 @@ static void blk_rq_timed_out_timer(struct timer_list *t)
 	kblockd_schedule_work(&q->timeout_work);
 }
 
-struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
+/**
+ * blk_alloc_queue_node - allocate a request queue
+ * @gfp_mask: memory allocation flags
+ * @node_id: NUMA node to allocate memory from
+ * @lock: For legacy queues, pointer to a spinlock that will be used to e.g.
+ *        serialize calls to the legacy .request_fn() callback. Ignored for
+ *	  blk-mq request queues.
+ *
+ * Note: pass the queue lock as the third argument to this function instead of
+ * setting the queue lock pointer explicitly to avoid triggering a sporadic
+ * crash in the blkcg code. This function namely calls blkcg_init_queue() and
+ * the queue lock pointer must be set before blkcg_init_queue() is called.
+ */
+struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id,
+					   spinlock_t *lock)
 {
 	struct request_queue *q;
 
@@ -939,11 +1043,8 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 	mutex_init(&q->sysfs_lock);
 	spin_lock_init(&q->__queue_lock);
 
-	/*
-	 * By default initialize queue_lock to internal lock and driver can
-	 * override it later if need be.
-	 */
-	q->queue_lock = &q->__queue_lock;
+	if (!q->mq_ops)
+		q->queue_lock = lock ? : &q->__queue_lock;
 
 	/*
 	 * A queue starts its life with bypass turned on to avoid
@@ -952,7 +1053,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 	 * registered by blk_register_queue().
 	 */
 	q->bypass_depth = 1;
-	__set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags);
+	queue_flag_set_unlocked(QUEUE_FLAG_BYPASS, q);
 
 	init_waitqueue_head(&q->mq_freeze_wq);
 
@@ -1030,13 +1131,11 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
 {
 	struct request_queue *q;
 
-	q = blk_alloc_queue_node(GFP_KERNEL, node_id);
+	q = blk_alloc_queue_node(GFP_KERNEL, node_id, lock);
 	if (!q)
 		return NULL;
 
 	q->request_fn = rfn;
-	if (lock)
-		q->queue_lock = lock;
 	if (blk_init_allocated_queue(q) < 0) {
 		blk_cleanup_queue(q);
 		return NULL;
@@ -2023,7 +2122,7 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
 	return BLK_QC_T_NONE;
 }
 
-static void handle_bad_sector(struct bio *bio)
+static void handle_bad_sector(struct bio *bio, sector_t maxsector)
 {
 	char b[BDEVNAME_SIZE];
 
@@ -2031,7 +2130,7 @@ static void handle_bad_sector(struct bio *bio)
 	printk(KERN_INFO "%s: rw=%d, want=%Lu, limit=%Lu\n",
 			bio_devname(bio, b), bio->bi_opf,
 			(unsigned long long)bio_end_sector(bio),
-			(long long)get_capacity(bio->bi_disk));
+			(long long)maxsector);
 }
 
 #ifdef CONFIG_FAIL_MAKE_REQUEST
@@ -2093,67 +2192,58 @@ static noinline int should_fail_bio(struct bio *bio)
 ALLOW_ERROR_INJECTION(should_fail_bio, ERRNO);
 
 /*
+ * Check whether this bio extends beyond the end of the device or partition.
+ * This may well happen - the kernel calls bread() without checking the size of
+ * the device, e.g., when mounting a file system.
+ */
+static inline int bio_check_eod(struct bio *bio, sector_t maxsector)
+{
+	unsigned int nr_sectors = bio_sectors(bio);
+
+	if (nr_sectors && maxsector &&
+	    (nr_sectors > maxsector ||
+	     bio->bi_iter.bi_sector > maxsector - nr_sectors)) {
+		handle_bad_sector(bio, maxsector);
+		return -EIO;
+	}
+	return 0;
+}
+
+/*
  * Remap block n of partition p to block n+start(p) of the disk.
  */
 static inline int blk_partition_remap(struct bio *bio)
 {
 	struct hd_struct *p;
-	int ret = 0;
+	int ret = -EIO;
 
 	rcu_read_lock();
 	p = __disk_get_part(bio->bi_disk, bio->bi_partno);
-	if (unlikely(!p || should_fail_request(p, bio->bi_iter.bi_size) ||
-		     bio_check_ro(bio, p))) {
-		ret = -EIO;
+	if (unlikely(!p))
 		goto out;
-	}
+	if (unlikely(should_fail_request(p, bio->bi_iter.bi_size)))
+		goto out;
+	if (unlikely(bio_check_ro(bio, p)))
+		goto out;
 
 	/*
 	 * Zone reset does not include bi_size so bio_sectors() is always 0.
 	 * Include a test for the reset op code and perform the remap if needed.
 	 */
-	if (!bio_sectors(bio) && bio_op(bio) != REQ_OP_ZONE_RESET)
-		goto out;
-
-	bio->bi_iter.bi_sector += p->start_sect;
-	bio->bi_partno = 0;
-	trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p),
-			      bio->bi_iter.bi_sector - p->start_sect);
-
+	if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET) {
+		if (bio_check_eod(bio, part_nr_sects_read(p)))
+			goto out;
+		bio->bi_iter.bi_sector += p->start_sect;
+		bio->bi_partno = 0;
+		trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p),
+				      bio->bi_iter.bi_sector - p->start_sect);
+	}
+	ret = 0;
 out:
 	rcu_read_unlock();
 	return ret;
 }
 
-/*
- * Check whether this bio extends beyond the end of the device.
- */
-static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
-{
-	sector_t maxsector;
-
-	if (!nr_sectors)
-		return 0;
-
-	/* Test device or partition size, when known. */
-	maxsector = get_capacity(bio->bi_disk);
-	if (maxsector) {
-		sector_t sector = bio->bi_iter.bi_sector;
-
-		if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
-			/*
-			 * This may well happen - the kernel calls bread()
-			 * without checking the size of the device, e.g., when
-			 * mounting a device.
-			 */
-			handle_bad_sector(bio);
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
 static noinline_for_stack bool
 generic_make_request_checks(struct bio *bio)
 {
@@ -2164,9 +2254,6 @@ generic_make_request_checks(struct bio *bio)
 
 	might_sleep();
 
-	if (bio_check_eod(bio, nr_sectors))
-		goto end_io;
-
 	q = bio->bi_disk->queue;
 	if (unlikely(!q)) {
 		printk(KERN_ERR
@@ -2186,17 +2273,16 @@ generic_make_request_checks(struct bio *bio)
 	if (should_fail_bio(bio))
 		goto end_io;
 
-	if (!bio->bi_partno) {
-		if (unlikely(bio_check_ro(bio, &bio->bi_disk->part0)))
+	if (bio->bi_partno) {
+		if (unlikely(blk_partition_remap(bio)))
 			goto end_io;
 	} else {
-		if (blk_partition_remap(bio))
+		if (unlikely(bio_check_ro(bio, &bio->bi_disk->part0)))
+			goto end_io;
+		if (unlikely(bio_check_eod(bio, get_capacity(bio->bi_disk))))
 			goto end_io;
 	}
 
-	if (bio_check_eod(bio, nr_sectors))
-		goto end_io;
-
 	/*
 	 * Filter flush bio's early so that make_request based
 	 * drivers without flush support don't have to worry
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index 21cbc1f..58b3b79 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -24,6 +24,64 @@
 #include "blk-mq-debugfs.h"
 #include "blk-mq-tag.h"
 
+static void print_stat(struct seq_file *m, struct blk_rq_stat *stat)
+{
+	if (stat->nr_samples) {
+		seq_printf(m, "samples=%d, mean=%lld, min=%llu, max=%llu",
+			   stat->nr_samples, stat->mean, stat->min, stat->max);
+	} else {
+		seq_puts(m, "samples=0");
+	}
+}
+
+static int queue_poll_stat_show(void *data, struct seq_file *m)
+{
+	struct request_queue *q = data;
+	int bucket;
+
+	for (bucket = 0; bucket < BLK_MQ_POLL_STATS_BKTS/2; bucket++) {
+		seq_printf(m, "read  (%d Bytes): ", 1 << (9+bucket));
+		print_stat(m, &q->poll_stat[2*bucket]);
+		seq_puts(m, "\n");
+
+		seq_printf(m, "write (%d Bytes): ",  1 << (9+bucket));
+		print_stat(m, &q->poll_stat[2*bucket+1]);
+		seq_puts(m, "\n");
+	}
+	return 0;
+}
+
+static void *queue_requeue_list_start(struct seq_file *m, loff_t *pos)
+	__acquires(&q->requeue_lock)
+{
+	struct request_queue *q = m->private;
+
+	spin_lock_irq(&q->requeue_lock);
+	return seq_list_start(&q->requeue_list, *pos);
+}
+
+static void *queue_requeue_list_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct request_queue *q = m->private;
+
+	return seq_list_next(v, &q->requeue_list, pos);
+}
+
+static void queue_requeue_list_stop(struct seq_file *m, void *v)
+	__releases(&q->requeue_lock)
+{
+	struct request_queue *q = m->private;
+
+	spin_unlock_irq(&q->requeue_lock);
+}
+
+static const struct seq_operations queue_requeue_list_seq_ops = {
+	.start	= queue_requeue_list_start,
+	.next	= queue_requeue_list_next,
+	.stop	= queue_requeue_list_stop,
+	.show	= blk_mq_debugfs_rq_show,
+};
+
 static int blk_flags_show(struct seq_file *m, const unsigned long flags,
 			  const char *const *flag_name, int flag_name_count)
 {
@@ -125,16 +183,6 @@ static ssize_t queue_state_write(void *data, const char __user *buf,
 	return count;
 }
 
-static void print_stat(struct seq_file *m, struct blk_rq_stat *stat)
-{
-	if (stat->nr_samples) {
-		seq_printf(m, "samples=%d, mean=%lld, min=%llu, max=%llu",
-			   stat->nr_samples, stat->mean, stat->min, stat->max);
-	} else {
-		seq_puts(m, "samples=0");
-	}
-}
-
 static int queue_write_hint_show(void *data, struct seq_file *m)
 {
 	struct request_queue *q = data;
@@ -158,23 +206,30 @@ static ssize_t queue_write_hint_store(void *data, const char __user *buf,
 	return count;
 }
 
-static int queue_poll_stat_show(void *data, struct seq_file *m)
+static int queue_zone_wlock_show(void *data, struct seq_file *m)
 {
 	struct request_queue *q = data;
-	int bucket;
+	unsigned int i;
 
-	for (bucket = 0; bucket < BLK_MQ_POLL_STATS_BKTS/2; bucket++) {
-		seq_printf(m, "read  (%d Bytes): ", 1 << (9+bucket));
-		print_stat(m, &q->poll_stat[2*bucket]);
-		seq_puts(m, "\n");
+	if (!q->seq_zones_wlock)
+		return 0;
 
-		seq_printf(m, "write (%d Bytes): ",  1 << (9+bucket));
-		print_stat(m, &q->poll_stat[2*bucket+1]);
-		seq_puts(m, "\n");
-	}
+	for (i = 0; i < blk_queue_nr_zones(q); i++)
+		if (test_bit(i, q->seq_zones_wlock))
+			seq_printf(m, "%u\n", i);
+
 	return 0;
 }
 
+static const struct blk_mq_debugfs_attr blk_mq_debugfs_queue_attrs[] = {
+	{ "poll_stat", 0400, queue_poll_stat_show },
+	{ "requeue_list", 0400, .seq_ops = &queue_requeue_list_seq_ops },
+	{ "state", 0600, queue_state_show, queue_state_write },
+	{ "write_hints", 0600, queue_write_hint_show, queue_write_hint_store },
+	{ "zone_wlock", 0400, queue_zone_wlock_show, NULL },
+	{ },
+};
+
 #define HCTX_STATE_NAME(name) [BLK_MQ_S_##name] = #name
 static const char *const hctx_state_name[] = {
 	HCTX_STATE_NAME(STOPPED),
@@ -295,6 +350,20 @@ static const char *const rqf_name[] = {
 };
 #undef RQF_NAME
 
+static const char *const blk_mq_rq_state_name_array[] = {
+	[MQ_RQ_IDLE]		= "idle",
+	[MQ_RQ_IN_FLIGHT]	= "in_flight",
+	[MQ_RQ_COMPLETE]	= "complete",
+};
+
+static const char *blk_mq_rq_state_name(enum mq_rq_state rq_state)
+{
+	if (WARN_ON_ONCE((unsigned int)rq_state >
+			 ARRAY_SIZE(blk_mq_rq_state_name_array)))
+		return "(?)";
+	return blk_mq_rq_state_name_array[rq_state];
+}
+
 int __blk_mq_debugfs_rq_show(struct seq_file *m, struct request *rq)
 {
 	const struct blk_mq_ops *const mq_ops = rq->q->mq_ops;
@@ -311,7 +380,7 @@ int __blk_mq_debugfs_rq_show(struct seq_file *m, struct request *rq)
 	seq_puts(m, ", .rq_flags=");
 	blk_flags_show(m, (__force unsigned int)rq->rq_flags, rqf_name,
 		       ARRAY_SIZE(rqf_name));
-	seq_printf(m, ", complete=%d", blk_rq_is_complete(rq));
+	seq_printf(m, ", .state=%s", blk_mq_rq_state_name(blk_mq_rq_state(rq)));
 	seq_printf(m, ", .tag=%d, .internal_tag=%d", rq->tag,
 		   rq->internal_tag);
 	if (mq_ops->show_rq)
@@ -327,37 +396,6 @@ int blk_mq_debugfs_rq_show(struct seq_file *m, void *v)
 }
 EXPORT_SYMBOL_GPL(blk_mq_debugfs_rq_show);
 
-static void *queue_requeue_list_start(struct seq_file *m, loff_t *pos)
-	__acquires(&q->requeue_lock)
-{
-	struct request_queue *q = m->private;
-
-	spin_lock_irq(&q->requeue_lock);
-	return seq_list_start(&q->requeue_list, *pos);
-}
-
-static void *queue_requeue_list_next(struct seq_file *m, void *v, loff_t *pos)
-{
-	struct request_queue *q = m->private;
-
-	return seq_list_next(v, &q->requeue_list, pos);
-}
-
-static void queue_requeue_list_stop(struct seq_file *m, void *v)
-	__releases(&q->requeue_lock)
-{
-	struct request_queue *q = m->private;
-
-	spin_unlock_irq(&q->requeue_lock);
-}
-
-static const struct seq_operations queue_requeue_list_seq_ops = {
-	.start	= queue_requeue_list_start,
-	.next	= queue_requeue_list_next,
-	.stop	= queue_requeue_list_stop,
-	.show	= blk_mq_debugfs_rq_show,
-};
-
 static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos)
 	__acquires(&hctx->lock)
 {
@@ -747,14 +785,6 @@ static const struct file_operations blk_mq_debugfs_fops = {
 	.release	= blk_mq_debugfs_release,
 };
 
-static const struct blk_mq_debugfs_attr blk_mq_debugfs_queue_attrs[] = {
-	{"poll_stat", 0400, queue_poll_stat_show},
-	{"requeue_list", 0400, .seq_ops = &queue_requeue_list_seq_ops},
-	{"state", 0600, queue_state_show, queue_state_write},
-	{"write_hints", 0600, queue_write_hint_show, queue_write_hint_store},
-	{},
-};
-
 static const struct blk_mq_debugfs_attr blk_mq_debugfs_hctx_attrs[] = {
 	{"state", 0400, hctx_state_show},
 	{"flags", 0400, hctx_flags_show},
diff --git a/block/blk-mq-pci.c b/block/blk-mq-pci.c
index 76944e3..e233996 100644
--- a/block/blk-mq-pci.c
+++ b/block/blk-mq-pci.c
@@ -21,6 +21,7 @@
  * blk_mq_pci_map_queues - provide a default queue mapping for PCI device
  * @set:	tagset to provide the mapping for
  * @pdev:	PCI device associated with @set.
+ * @offset:	Offset to use for the pci irq vector
  *
  * This function assumes the PCI device @pdev has at least as many available
  * interrupt vectors as @set has queues.  It will then query the vector
@@ -28,13 +29,14 @@
  * that maps a queue to the CPUs that have irq affinity for the corresponding
  * vector.
  */
-int blk_mq_pci_map_queues(struct blk_mq_tag_set *set, struct pci_dev *pdev)
+int blk_mq_pci_map_queues(struct blk_mq_tag_set *set, struct pci_dev *pdev,
+			    int offset)
 {
 	const struct cpumask *mask;
 	unsigned int queue, cpu;
 
 	for (queue = 0; queue < set->nr_hw_queues; queue++) {
-		mask = pci_irq_get_affinity(pdev, queue);
+		mask = pci_irq_get_affinity(pdev, queue + offset);
 		if (!mask)
 			goto fallback;
 
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 16e83e6..f5c7dbc 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -194,11 +194,7 @@ EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
  */
 void blk_mq_quiesce_queue_nowait(struct request_queue *q)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	queue_flag_set(QUEUE_FLAG_QUIESCED, q);
-	spin_unlock_irqrestore(q->queue_lock, flags);
+	blk_queue_flag_set(QUEUE_FLAG_QUIESCED, q);
 }
 EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_nowait);
 
@@ -239,11 +235,7 @@ EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
  */
 void blk_mq_unquiesce_queue(struct request_queue *q)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	queue_flag_clear(QUEUE_FLAG_QUIESCED, q);
-	spin_unlock_irqrestore(q->queue_lock, flags);
+	blk_queue_flag_clear(QUEUE_FLAG_QUIESCED, q);
 
 	/* dispatch requests which are inserted during quiescing */
 	blk_mq_run_hw_queues(q, true);
@@ -986,9 +978,9 @@ static bool flush_busy_ctx(struct sbitmap *sb, unsigned int bitnr, void *data)
 	struct blk_mq_hw_ctx *hctx = flush_data->hctx;
 	struct blk_mq_ctx *ctx = hctx->ctxs[bitnr];
 
-	sbitmap_clear_bit(sb, bitnr);
 	spin_lock(&ctx->lock);
 	list_splice_tail_init(&ctx->rq_list, flush_data->list);
+	sbitmap_clear_bit(sb, bitnr);
 	spin_unlock(&ctx->lock);
 	return true;
 }
@@ -2556,7 +2548,7 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
 {
 	struct request_queue *uninit_q, *q;
 
-	uninit_q = blk_alloc_queue_node(GFP_KERNEL, set->numa_node);
+	uninit_q = blk_alloc_queue_node(GFP_KERNEL, set->numa_node, NULL);
 	if (!uninit_q)
 		return ERR_PTR(-ENOMEM);
 
@@ -2678,7 +2670,7 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
 	q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;
 
 	if (!(set->flags & BLK_MQ_F_SG_MERGE))
-		q->queue_flags |= 1 << QUEUE_FLAG_NO_SG_MERGE;
+		queue_flag_set_unlocked(QUEUE_FLAG_NO_SG_MERGE, q);
 
 	q->sg_reserved_size = INT_MAX;
 
@@ -3005,7 +2997,7 @@ EXPORT_SYMBOL_GPL(blk_mq_update_nr_hw_queues);
 static bool blk_poll_stats_enable(struct request_queue *q)
 {
 	if (test_bit(QUEUE_FLAG_POLL_STATS, &q->queue_flags) ||
-	    test_and_set_bit(QUEUE_FLAG_POLL_STATS, &q->queue_flags))
+	    blk_queue_flag_test_and_set(QUEUE_FLAG_POLL_STATS, q))
 		return true;
 	blk_stat_add_callback(q, q->poll_cb);
 	return false;
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 48ebe6b..d1de711 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -859,12 +859,10 @@ EXPORT_SYMBOL(blk_queue_update_dma_alignment);
 
 void blk_queue_flush_queueable(struct request_queue *q, bool queueable)
 {
-	spin_lock_irq(q->queue_lock);
 	if (queueable)
-		clear_bit(QUEUE_FLAG_FLUSH_NQ, &q->queue_flags);
+		blk_queue_flag_clear(QUEUE_FLAG_FLUSH_NQ, q);
 	else
-		set_bit(QUEUE_FLAG_FLUSH_NQ, &q->queue_flags);
-	spin_unlock_irq(q->queue_lock);
+		blk_queue_flag_set(QUEUE_FLAG_FLUSH_NQ, q);
 }
 EXPORT_SYMBOL_GPL(blk_queue_flush_queueable);
 
diff --git a/block/blk-stat.c b/block/blk-stat.c
index 28003bf..bd365a9 100644
--- a/block/blk-stat.c
+++ b/block/blk-stat.c
@@ -152,7 +152,7 @@ void blk_stat_add_callback(struct request_queue *q,
 
 	spin_lock(&q->stats->lock);
 	list_add_tail_rcu(&cb->list, &q->stats->callbacks);
-	set_bit(QUEUE_FLAG_STATS, &q->queue_flags);
+	blk_queue_flag_set(QUEUE_FLAG_STATS, q);
 	spin_unlock(&q->stats->lock);
 }
 EXPORT_SYMBOL_GPL(blk_stat_add_callback);
@@ -163,7 +163,7 @@ void blk_stat_remove_callback(struct request_queue *q,
 	spin_lock(&q->stats->lock);
 	list_del_rcu(&cb->list);
 	if (list_empty(&q->stats->callbacks) && !q->stats->enable_accounting)
-		clear_bit(QUEUE_FLAG_STATS, &q->queue_flags);
+		blk_queue_flag_clear(QUEUE_FLAG_STATS, q);
 	spin_unlock(&q->stats->lock);
 
 	del_timer_sync(&cb->timer);
@@ -191,7 +191,7 @@ void blk_stat_enable_accounting(struct request_queue *q)
 {
 	spin_lock(&q->stats->lock);
 	q->stats->enable_accounting = true;
-	set_bit(QUEUE_FLAG_STATS, &q->queue_flags);
+	blk_queue_flag_set(QUEUE_FLAG_STATS, q);
 	spin_unlock(&q->stats->lock);
 }
 
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index cbea895..d00d1b0 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -276,12 +276,10 @@ queue_store_##name(struct request_queue *q, const char *page, size_t count) \
 	if (neg)							\
 		val = !val;						\
 									\
-	spin_lock_irq(q->queue_lock);					\
 	if (val)							\
-		queue_flag_set(QUEUE_FLAG_##flag, q);			\
+		blk_queue_flag_set(QUEUE_FLAG_##flag, q);		\
 	else								\
-		queue_flag_clear(QUEUE_FLAG_##flag, q);			\
-	spin_unlock_irq(q->queue_lock);					\
+		blk_queue_flag_clear(QUEUE_FLAG_##flag, q);		\
 	return ret;							\
 }
 
@@ -414,12 +412,10 @@ static ssize_t queue_poll_store(struct request_queue *q, const char *page,
 	if (ret < 0)
 		return ret;
 
-	spin_lock_irq(q->queue_lock);
 	if (poll_on)
-		queue_flag_set(QUEUE_FLAG_POLL, q);
+		blk_queue_flag_set(QUEUE_FLAG_POLL, q);
 	else
-		queue_flag_clear(QUEUE_FLAG_POLL, q);
-	spin_unlock_irq(q->queue_lock);
+		blk_queue_flag_clear(QUEUE_FLAG_POLL, q);
 
 	return ret;
 }
@@ -487,12 +483,10 @@ static ssize_t queue_wc_store(struct request_queue *q, const char *page,
 	if (set == -1)
 		return -EINVAL;
 
-	spin_lock_irq(q->queue_lock);
 	if (set)
-		queue_flag_set(QUEUE_FLAG_WC, q);
+		blk_queue_flag_set(QUEUE_FLAG_WC, q);
 	else
-		queue_flag_clear(QUEUE_FLAG_WC, q);
-	spin_unlock_irq(q->queue_lock);
+		blk_queue_flag_clear(QUEUE_FLAG_WC, q);
 
 	return count;
 }
@@ -798,13 +792,6 @@ static void __blk_release_queue(struct work_struct *work)
 	if (test_bit(QUEUE_FLAG_POLL_STATS, &q->queue_flags))
 		blk_stat_remove_callback(q, q->poll_cb);
 	blk_stat_free_callback(q->poll_cb);
-	bdi_put(q->backing_dev_info);
-	blkcg_exit_queue(q);
-
-	if (q->elevator) {
-		ioc_clear_queue(q);
-		elevator_exit(q, q->elevator);
-	}
 
 	blk_free_queue_stats(q->stats);
 
@@ -953,9 +940,7 @@ void blk_unregister_queue(struct gendisk *disk)
 	 */
 	mutex_lock(&q->sysfs_lock);
 
-	spin_lock_irq(q->queue_lock);
-	queue_flag_clear(QUEUE_FLAG_REGISTERED, q);
-	spin_unlock_irq(q->queue_lock);
+	blk_queue_flag_clear(QUEUE_FLAG_REGISTERED, q);
 
 	/*
 	 * Remove the sysfs attributes before unregistering the queue data
diff --git a/block/blk-timeout.c b/block/blk-timeout.c
index a05e367..652d4d4 100644
--- a/block/blk-timeout.c
+++ b/block/blk-timeout.c
@@ -57,12 +57,10 @@ ssize_t part_timeout_store(struct device *dev, struct device_attribute *attr,
 		char *p = (char *) buf;
 
 		val = simple_strtoul(p, &p, 10);
-		spin_lock_irq(q->queue_lock);
 		if (val)
-			queue_flag_set(QUEUE_FLAG_FAIL_IO, q);
+			blk_queue_flag_set(QUEUE_FLAG_FAIL_IO, q);
 		else
-			queue_flag_clear(QUEUE_FLAG_FAIL_IO, q);
-		spin_unlock_irq(q->queue_lock);
+			blk_queue_flag_clear(QUEUE_FLAG_FAIL_IO, q);
 	}
 
 	return count;
@@ -165,7 +163,7 @@ void blk_abort_request(struct request *req)
 		 * No need for fancy synchronizations.
 		 */
 		blk_rq_set_deadline(req, jiffies);
-		mod_timer(&req->q->timeout, 0);
+		kblockd_schedule_work(&req->q->timeout_work);
 	} else {
 		if (blk_mark_rq_complete(req))
 			return;
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index acb7252..08e84ef 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -296,7 +296,7 @@ int blkdev_reset_zones(struct block_device *bdev,
 }
 EXPORT_SYMBOL_GPL(blkdev_reset_zones);
 
-/**
+/*
  * BLKREPORTZONE ioctl processing.
  * Called from blkdev_ioctl.
  */
@@ -355,7 +355,7 @@ int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode,
 	return ret;
 }
 
-/**
+/*
  * BLKRESETZONE ioctl processing.
  * Called from blkdev_ioctl.
  */
diff --git a/block/blk.h b/block/blk.h
index 46db5dc..b034fd2 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -41,6 +41,75 @@ extern struct kmem_cache *request_cachep;
 extern struct kobj_type blk_queue_ktype;
 extern struct ida blk_queue_ida;
 
+/*
+ * @q->queue_lock is set while a queue is being initialized. Since we know
+ * that no other threads access the queue object before @q->queue_lock has
+ * been set, it is safe to manipulate queue flags without holding the
+ * queue_lock if @q->queue_lock == NULL. See also blk_alloc_queue_node() and
+ * blk_init_allocated_queue().
+ */
+static inline void queue_lockdep_assert_held(struct request_queue *q)
+{
+	if (q->queue_lock)
+		lockdep_assert_held(q->queue_lock);
+}
+
+static inline void queue_flag_set_unlocked(unsigned int flag,
+					   struct request_queue *q)
+{
+	if (test_bit(QUEUE_FLAG_INIT_DONE, &q->queue_flags) &&
+	    kref_read(&q->kobj.kref))
+		lockdep_assert_held(q->queue_lock);
+	__set_bit(flag, &q->queue_flags);
+}
+
+static inline void queue_flag_clear_unlocked(unsigned int flag,
+					     struct request_queue *q)
+{
+	if (test_bit(QUEUE_FLAG_INIT_DONE, &q->queue_flags) &&
+	    kref_read(&q->kobj.kref))
+		lockdep_assert_held(q->queue_lock);
+	__clear_bit(flag, &q->queue_flags);
+}
+
+static inline int queue_flag_test_and_clear(unsigned int flag,
+					    struct request_queue *q)
+{
+	queue_lockdep_assert_held(q);
+
+	if (test_bit(flag, &q->queue_flags)) {
+		__clear_bit(flag, &q->queue_flags);
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline int queue_flag_test_and_set(unsigned int flag,
+					  struct request_queue *q)
+{
+	queue_lockdep_assert_held(q);
+
+	if (!test_bit(flag, &q->queue_flags)) {
+		__set_bit(flag, &q->queue_flags);
+		return 0;
+	}
+
+	return 1;
+}
+
+static inline void queue_flag_set(unsigned int flag, struct request_queue *q)
+{
+	queue_lockdep_assert_held(q);
+	__set_bit(flag, &q->queue_flags);
+}
+
+static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
+{
+	queue_lockdep_assert_held(q);
+	__clear_bit(flag, &q->queue_flags);
+}
+
 static inline struct blk_flush_queue *blk_get_flush_queue(
 		struct request_queue *q, struct blk_mq_ctx *ctx)
 {
diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 1474153..fc2e5ff 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -27,6 +27,94 @@
 #include <linux/bsg-lib.h>
 #include <linux/export.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/sg.h>
+
+#define uptr64(val) ((void __user *)(uintptr_t)(val))
+
+static int bsg_transport_check_proto(struct sg_io_v4 *hdr)
+{
+	if (hdr->protocol != BSG_PROTOCOL_SCSI  ||
+	    hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_TRANSPORT)
+		return -EINVAL;
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+	return 0;
+}
+
+static int bsg_transport_fill_hdr(struct request *rq, struct sg_io_v4 *hdr,
+		fmode_t mode)
+{
+	struct bsg_job *job = blk_mq_rq_to_pdu(rq);
+
+	job->request_len = hdr->request_len;
+	job->request = memdup_user(uptr64(hdr->request), hdr->request_len);
+	if (IS_ERR(job->request))
+		return PTR_ERR(job->request);
+	return 0;
+}
+
+static int bsg_transport_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
+{
+	struct bsg_job *job = blk_mq_rq_to_pdu(rq);
+	int ret = 0;
+
+	/*
+	 * The assignments below don't make much sense, but are kept for
+	 * bug by bug backwards compatibility:
+	 */
+	hdr->device_status = job->result & 0xff;
+	hdr->transport_status = host_byte(job->result);
+	hdr->driver_status = driver_byte(job->result);
+	hdr->info = 0;
+	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
+		hdr->info |= SG_INFO_CHECK;
+	hdr->response_len = 0;
+
+	if (job->result < 0) {
+		/* we're only returning the result field in the reply */
+		job->reply_len = sizeof(u32);
+		ret = job->result;
+	}
+
+	if (job->reply_len && hdr->response) {
+		int len = min(hdr->max_response_len, job->reply_len);
+
+		if (copy_to_user(uptr64(hdr->response), job->reply, len))
+			ret = -EFAULT;
+		else
+			hdr->response_len = len;
+	}
+
+	/* we assume all request payload was transferred, residual == 0 */
+	hdr->dout_resid = 0;
+
+	if (rq->next_rq) {
+		unsigned int rsp_len = job->reply_payload.payload_len;
+
+		if (WARN_ON(job->reply_payload_rcv_len > rsp_len))
+			hdr->din_resid = 0;
+		else
+			hdr->din_resid = rsp_len - job->reply_payload_rcv_len;
+	} else {
+		hdr->din_resid = 0;
+	}
+
+	return ret;
+}
+
+static void bsg_transport_free_rq(struct request *rq)
+{
+	struct bsg_job *job = blk_mq_rq_to_pdu(rq);
+
+	kfree(job->request);
+}
+
+static const struct bsg_ops bsg_transport_ops = {
+	.check_proto		= bsg_transport_check_proto,
+	.fill_hdr		= bsg_transport_fill_hdr,
+	.complete_rq		= bsg_transport_complete_rq,
+	.free_rq		= bsg_transport_free_rq,
+};
 
 /**
  * bsg_teardown_job - routine to teardown a bsg job
@@ -35,7 +123,7 @@
 static void bsg_teardown_job(struct kref *kref)
 {
 	struct bsg_job *job = container_of(kref, struct bsg_job, kref);
-	struct request *rq = job->req;
+	struct request *rq = blk_mq_rq_from_pdu(job);
 
 	put_device(job->dev);	/* release reference for the request */
 
@@ -68,28 +156,9 @@ EXPORT_SYMBOL_GPL(bsg_job_get);
 void bsg_job_done(struct bsg_job *job, int result,
 		  unsigned int reply_payload_rcv_len)
 {
-	struct request *req = job->req;
-	struct request *rsp = req->next_rq;
-	struct scsi_request *rq = scsi_req(req);
-	int err;
-
-	err = scsi_req(job->req)->result = result;
-	if (err < 0)
-		/* we're only returning the result field in the reply */
-		rq->sense_len = sizeof(u32);
-	else
-		rq->sense_len = job->reply_len;
-	/* we assume all request payload was transferred, residual == 0 */
-	rq->resid_len = 0;
-
-	if (rsp) {
-		WARN_ON(reply_payload_rcv_len > scsi_req(rsp)->resid_len);
-
-		/* set reply (bidi) residual */
-		scsi_req(rsp)->resid_len -=
-			min(reply_payload_rcv_len, scsi_req(rsp)->resid_len);
-	}
-	blk_complete_request(req);
+	job->result = result;
+	job->reply_payload_rcv_len = reply_payload_rcv_len;
+	blk_complete_request(blk_mq_rq_from_pdu(job));
 }
 EXPORT_SYMBOL_GPL(bsg_job_done);
 
@@ -114,7 +183,6 @@ static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
 	if (!buf->sg_list)
 		return -ENOMEM;
 	sg_init_table(buf->sg_list, req->nr_phys_segments);
-	scsi_req(req)->resid_len = blk_rq_bytes(req);
 	buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
 	buf->payload_len = blk_rq_bytes(req);
 	return 0;
@@ -125,15 +193,13 @@ static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
  * @dev: device that is being sent the bsg request
  * @req: BSG request that needs a job structure
  */
-static int bsg_prepare_job(struct device *dev, struct request *req)
+static bool bsg_prepare_job(struct device *dev, struct request *req)
 {
 	struct request *rsp = req->next_rq;
-	struct scsi_request *rq = scsi_req(req);
 	struct bsg_job *job = blk_mq_rq_to_pdu(req);
 	int ret;
 
-	job->request = rq->cmd;
-	job->request_len = rq->cmd_len;
+	job->timeout = req->timeout;
 
 	if (req->bio) {
 		ret = bsg_map_buffer(&job->request_payload, req);
@@ -149,12 +215,13 @@ static int bsg_prepare_job(struct device *dev, struct request *req)
 	/* take a reference for the request */
 	get_device(job->dev);
 	kref_init(&job->kref);
-	return 0;
+	return true;
 
 failjob_rls_rqst_payload:
 	kfree(job->request_payload.sg_list);
 failjob_rls_job:
-	return -ENOMEM;
+	job->result = -ENOMEM;
+	return false;
 }
 
 /**
@@ -183,9 +250,7 @@ static void bsg_request_fn(struct request_queue *q)
 			break;
 		spin_unlock_irq(q->queue_lock);
 
-		ret = bsg_prepare_job(dev, req);
-		if (ret) {
-			scsi_req(req)->result = ret;
+		if (!bsg_prepare_job(dev, req)) {
 			blk_end_request_all(req, BLK_STS_OK);
 			spin_lock_irq(q->queue_lock);
 			continue;
@@ -202,47 +267,34 @@ static void bsg_request_fn(struct request_queue *q)
 	spin_lock_irq(q->queue_lock);
 }
 
+/* called right after the request is allocated for the request_queue */
 static int bsg_init_rq(struct request_queue *q, struct request *req, gfp_t gfp)
 {
 	struct bsg_job *job = blk_mq_rq_to_pdu(req);
-	struct scsi_request *sreq = &job->sreq;
 
-	/* called right after the request is allocated for the request_queue */
-
-	sreq->sense = kzalloc(SCSI_SENSE_BUFFERSIZE, gfp);
-	if (!sreq->sense)
+	job->reply = kzalloc(SCSI_SENSE_BUFFERSIZE, gfp);
+	if (!job->reply)
 		return -ENOMEM;
-
 	return 0;
 }
 
+/* called right before the request is given to the request_queue user */
 static void bsg_initialize_rq(struct request *req)
 {
 	struct bsg_job *job = blk_mq_rq_to_pdu(req);
-	struct scsi_request *sreq = &job->sreq;
-	void *sense = sreq->sense;
-
-	/* called right before the request is given to the request_queue user */
+	void *reply = job->reply;
 
 	memset(job, 0, sizeof(*job));
-
-	scsi_req_init(sreq);
-
-	sreq->sense = sense;
-	sreq->sense_len = SCSI_SENSE_BUFFERSIZE;
-
-	job->req = req;
-	job->reply = sense;
-	job->reply_len = sreq->sense_len;
+	job->reply = reply;
+	job->reply_len = SCSI_SENSE_BUFFERSIZE;
 	job->dd_data = job + 1;
 }
 
 static void bsg_exit_rq(struct request_queue *q, struct request *req)
 {
 	struct bsg_job *job = blk_mq_rq_to_pdu(req);
-	struct scsi_request *sreq = &job->sreq;
 
-	kfree(sreq->sense);
+	kfree(job->reply);
 }
 
 /**
@@ -275,12 +327,11 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name,
 
 	q->queuedata = dev;
 	q->bsg_job_fn = job_fn;
-	queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
-	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
+	blk_queue_flag_set(QUEUE_FLAG_BIDI, q);
 	blk_queue_softirq_done(q, bsg_softirq_done);
 	blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
 
-	ret = bsg_register_queue(q, dev, name, release);
+	ret = bsg_register_queue(q, dev, name, &bsg_transport_ops, release);
 	if (ret) {
 		printk(KERN_ERR "%s: bsg interface failed to "
 		       "initialize - register queue\n", dev->kobj.name);
diff --git a/block/bsg.c b/block/bsg.c
index 06dc96e..defa06c 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -130,32 +130,110 @@ static inline struct hlist_head *bsg_dev_idx_hash(int index)
 	return &bsg_device_list[index & (BSG_LIST_ARRAY_SIZE - 1)];
 }
 
-static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
-				struct sg_io_v4 *hdr, struct bsg_device *bd,
-				fmode_t mode)
-{
-	struct scsi_request *req = scsi_req(rq);
+#define uptr64(val) ((void __user *)(uintptr_t)(val))
 
-	if (hdr->request_len > BLK_MAX_CDB) {
-		req->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
-		if (!req->cmd)
+static int bsg_scsi_check_proto(struct sg_io_v4 *hdr)
+{
+	if (hdr->protocol != BSG_PROTOCOL_SCSI  ||
+	    hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_CMD)
+		return -EINVAL;
+	return 0;
+}
+
+static int bsg_scsi_fill_hdr(struct request *rq, struct sg_io_v4 *hdr,
+		fmode_t mode)
+{
+	struct scsi_request *sreq = scsi_req(rq);
+
+	sreq->cmd_len = hdr->request_len;
+	if (sreq->cmd_len > BLK_MAX_CDB) {
+		sreq->cmd = kzalloc(sreq->cmd_len, GFP_KERNEL);
+		if (!sreq->cmd)
 			return -ENOMEM;
 	}
 
-	if (copy_from_user(req->cmd, (void __user *)(unsigned long)hdr->request,
-			   hdr->request_len))
+	if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len))
 		return -EFAULT;
-
-	if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
-		if (blk_verify_command(req->cmd, mode))
-			return -EPERM;
-	} else if (!capable(CAP_SYS_RAWIO))
+	if (blk_verify_command(sreq->cmd, mode))
 		return -EPERM;
+	return 0;
+}
+
+static int bsg_scsi_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
+{
+	struct scsi_request *sreq = scsi_req(rq);
+	int ret = 0;
 
 	/*
-	 * fill in request structure
+	 * fill in all the output members
 	 */
-	req->cmd_len = hdr->request_len;
+	hdr->device_status = sreq->result & 0xff;
+	hdr->transport_status = host_byte(sreq->result);
+	hdr->driver_status = driver_byte(sreq->result);
+	hdr->info = 0;
+	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
+		hdr->info |= SG_INFO_CHECK;
+	hdr->response_len = 0;
+
+	if (sreq->sense_len && hdr->response) {
+		int len = min_t(unsigned int, hdr->max_response_len,
+					sreq->sense_len);
+
+		if (copy_to_user(uptr64(hdr->response), sreq->sense, len))
+			ret = -EFAULT;
+		else
+			hdr->response_len = len;
+	}
+
+	if (rq->next_rq) {
+		hdr->dout_resid = sreq->resid_len;
+		hdr->din_resid = scsi_req(rq->next_rq)->resid_len;
+	} else if (rq_data_dir(rq) == READ) {
+		hdr->din_resid = sreq->resid_len;
+	} else {
+		hdr->dout_resid = sreq->resid_len;
+	}
+
+	return ret;
+}
+
+static void bsg_scsi_free_rq(struct request *rq)
+{
+	scsi_req_free_cmd(scsi_req(rq));
+}
+
+static const struct bsg_ops bsg_scsi_ops = {
+	.check_proto		= bsg_scsi_check_proto,
+	.fill_hdr		= bsg_scsi_fill_hdr,
+	.complete_rq		= bsg_scsi_complete_rq,
+	.free_rq		= bsg_scsi_free_rq,
+};
+
+static struct request *
+bsg_map_hdr(struct request_queue *q, struct sg_io_v4 *hdr, fmode_t mode)
+{
+	struct request *rq, *next_rq = NULL;
+	int ret;
+
+	if (!q->bsg_dev.class_dev)
+		return ERR_PTR(-ENXIO);
+
+	if (hdr->guard != 'Q')
+		return ERR_PTR(-EINVAL);
+
+	ret = q->bsg_dev.ops->check_proto(hdr);
+	if (ret)
+		return ERR_PTR(ret);
+
+	rq = blk_get_request(q, hdr->dout_xfer_len ?
+			REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
+			GFP_KERNEL);
+	if (IS_ERR(rq))
+		return rq;
+
+	ret = q->bsg_dev.ops->fill_hdr(rq, hdr, mode);
+	if (ret)
+		goto out;
 
 	rq->timeout = msecs_to_jiffies(hdr->timeout);
 	if (!rq->timeout)
@@ -165,79 +243,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
 	if (rq->timeout < BLK_MIN_SG_TIMEOUT)
 		rq->timeout = BLK_MIN_SG_TIMEOUT;
 
-	return 0;
-}
-
-/*
- * Check if sg_io_v4 from user is allowed and valid
- */
-static int
-bsg_validate_sgv4_hdr(struct sg_io_v4 *hdr, int *op)
-{
-	int ret = 0;
-
-	if (hdr->guard != 'Q')
-		return -EINVAL;
-
-	switch (hdr->protocol) {
-	case BSG_PROTOCOL_SCSI:
-		switch (hdr->subprotocol) {
-		case BSG_SUB_PROTOCOL_SCSI_CMD:
-		case BSG_SUB_PROTOCOL_SCSI_TRANSPORT:
-			break;
-		default:
-			ret = -EINVAL;
-		}
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	*op = hdr->dout_xfer_len ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN;
-	return ret;
-}
-
-/*
- * map sg_io_v4 to a request.
- */
-static struct request *
-bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t mode)
-{
-	struct request_queue *q = bd->queue;
-	struct request *rq, *next_rq = NULL;
-	int ret;
-	unsigned int op, dxfer_len;
-	void __user *dxferp = NULL;
-	struct bsg_class_device *bcd = &q->bsg_dev;
-
-	/* if the LLD has been removed then the bsg_unregister_queue will
-	 * eventually be called and the class_dev was freed, so we can no
-	 * longer use this request_queue. Return no such address.
-	 */
-	if (!bcd->class_dev)
-		return ERR_PTR(-ENXIO);
-
-	bsg_dbg(bd, "map hdr %llx/%u %llx/%u\n",
-		(unsigned long long) hdr->dout_xferp,
-		hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp,
-		hdr->din_xfer_len);
-
-	ret = bsg_validate_sgv4_hdr(hdr, &op);
-	if (ret)
-		return ERR_PTR(ret);
-
-	/*
-	 * map scatter-gather elements separately and string them to request
-	 */
-	rq = blk_get_request(q, op, GFP_KERNEL);
-	if (IS_ERR(rq))
-		return rq;
-
-	ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, mode);
-	if (ret)
-		goto out;
-
-	if (op == REQ_OP_SCSI_OUT && hdr->din_xfer_len) {
+	if (hdr->dout_xfer_len && hdr->din_xfer_len) {
 		if (!test_bit(QUEUE_FLAG_BIDI, &q->queue_flags)) {
 			ret = -EOPNOTSUPP;
 			goto out;
@@ -246,42 +252,39 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t mode)
 		next_rq = blk_get_request(q, REQ_OP_SCSI_IN, GFP_KERNEL);
 		if (IS_ERR(next_rq)) {
 			ret = PTR_ERR(next_rq);
-			next_rq = NULL;
 			goto out;
 		}
-		rq->next_rq = next_rq;
 
-		dxferp = (void __user *)(unsigned long)hdr->din_xferp;
-		ret =  blk_rq_map_user(q, next_rq, NULL, dxferp,
+		rq->next_rq = next_rq;
+		ret = blk_rq_map_user(q, next_rq, NULL, uptr64(hdr->din_xferp),
 				       hdr->din_xfer_len, GFP_KERNEL);
 		if (ret)
-			goto out;
+			goto out_free_nextrq;
 	}
 
 	if (hdr->dout_xfer_len) {
-		dxfer_len = hdr->dout_xfer_len;
-		dxferp = (void __user *)(unsigned long)hdr->dout_xferp;
+		ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr->dout_xferp),
+				hdr->dout_xfer_len, GFP_KERNEL);
 	} else if (hdr->din_xfer_len) {
-		dxfer_len = hdr->din_xfer_len;
-		dxferp = (void __user *)(unsigned long)hdr->din_xferp;
-	} else
-		dxfer_len = 0;
-
-	if (dxfer_len) {
-		ret = blk_rq_map_user(q, rq, NULL, dxferp, dxfer_len,
-				      GFP_KERNEL);
-		if (ret)
-			goto out;
+		ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr->din_xferp),
+				hdr->din_xfer_len, GFP_KERNEL);
+	} else {
+		ret = blk_rq_map_user(q, rq, NULL, NULL, 0, GFP_KERNEL);
 	}
 
+	if (ret)
+		goto out_unmap_nextrq;
 	return rq;
+
+out_unmap_nextrq:
+	if (rq->next_rq)
+		blk_rq_unmap_user(rq->next_rq->bio);
+out_free_nextrq:
+	if (rq->next_rq)
+		blk_put_request(rq->next_rq);
 out:
-	scsi_req_free_cmd(scsi_req(rq));
+	q->bsg_dev.ops->free_rq(rq);
 	blk_put_request(rq);
-	if (next_rq) {
-		blk_rq_unmap_user(next_rq->bio);
-		blk_put_request(next_rq);
-	}
 	return ERR_PTR(ret);
 }
 
@@ -383,56 +386,18 @@ static struct bsg_command *bsg_get_done_cmd(struct bsg_device *bd)
 static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
 				    struct bio *bio, struct bio *bidi_bio)
 {
-	struct scsi_request *req = scsi_req(rq);
-	int ret = 0;
+	int ret;
 
-	pr_debug("rq %p bio %p 0x%x\n", rq, bio, req->result);
-	/*
-	 * fill in all the output members
-	 */
-	hdr->device_status = req->result & 0xff;
-	hdr->transport_status = host_byte(req->result);
-	hdr->driver_status = driver_byte(req->result);
-	hdr->info = 0;
-	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
-		hdr->info |= SG_INFO_CHECK;
-	hdr->response_len = 0;
-
-	if (req->sense_len && hdr->response) {
-		int len = min_t(unsigned int, hdr->max_response_len,
-					req->sense_len);
-
-		ret = copy_to_user((void __user *)(unsigned long)hdr->response,
-				   req->sense, len);
-		if (!ret)
-			hdr->response_len = len;
-		else
-			ret = -EFAULT;
-	}
+	ret = rq->q->bsg_dev.ops->complete_rq(rq, hdr);
 
 	if (rq->next_rq) {
-		hdr->dout_resid = req->resid_len;
-		hdr->din_resid = scsi_req(rq->next_rq)->resid_len;
 		blk_rq_unmap_user(bidi_bio);
 		blk_put_request(rq->next_rq);
-	} else if (rq_data_dir(rq) == READ)
-		hdr->din_resid = req->resid_len;
-	else
-		hdr->dout_resid = req->resid_len;
-
-	/*
-	 * If the request generated a negative error number, return it
-	 * (providing we aren't already returning an error); if it's
-	 * just a protocol response (i.e. non negative), that gets
-	 * processed above.
-	 */
-	if (!ret && req->result < 0)
-		ret = req->result;
+	}
 
 	blk_rq_unmap_user(bio);
-	scsi_req_free_cmd(req);
+	rq->q->bsg_dev.ops->free_rq(rq);
 	blk_put_request(rq);
-
 	return ret;
 }
 
@@ -614,7 +579,7 @@ static int __bsg_write(struct bsg_device *bd, const char __user *buf,
 		/*
 		 * get a request, fill in the blanks, and add to request queue
 		 */
-		rq = bsg_map_hdr(bd, &bc->hdr, mode);
+		rq = bsg_map_hdr(bd->queue, &bc->hdr, mode);
 		if (IS_ERR(rq)) {
 			ret = PTR_ERR(rq);
 			rq = NULL;
@@ -742,11 +707,6 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
 	struct bsg_device *bd;
 	unsigned char buf[32];
 
-	if (!blk_queue_scsi_passthrough(rq)) {
-		WARN_ONCE(true, "Attempt to register a non-SCSI queue\n");
-		return ERR_PTR(-EINVAL);
-	}
-
 	if (!blk_get_queue(rq))
 		return ERR_PTR(-ENXIO);
 
@@ -907,7 +867,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (copy_from_user(&hdr, uarg, sizeof(hdr)))
 			return -EFAULT;
 
-		rq = bsg_map_hdr(bd, &hdr, file->f_mode);
+		rq = bsg_map_hdr(bd->queue, &hdr, file->f_mode);
 		if (IS_ERR(rq))
 			return PTR_ERR(rq);
 
@@ -959,7 +919,8 @@ void bsg_unregister_queue(struct request_queue *q)
 EXPORT_SYMBOL_GPL(bsg_unregister_queue);
 
 int bsg_register_queue(struct request_queue *q, struct device *parent,
-		       const char *name, void (*release)(struct device *))
+		const char *name, const struct bsg_ops *ops,
+		void (*release)(struct device *))
 {
 	struct bsg_class_device *bcd;
 	dev_t dev;
@@ -996,6 +957,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
 	bcd->queue = q;
 	bcd->parent = get_device(parent);
 	bcd->release = release;
+	bcd->ops = ops;
 	kref_init(&bcd->ref);
 	dev = MKDEV(bsg_major, bcd->minor);
 	class_dev = device_create(bsg_class, parent, dev, NULL, "%s", devname);
@@ -1023,7 +985,17 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
 	mutex_unlock(&bsg_mutex);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(bsg_register_queue);
+
+int bsg_scsi_register_queue(struct request_queue *q, struct device *parent)
+{
+	if (!blk_queue_scsi_passthrough(q)) {
+		WARN_ONCE(true, "Attempt to register a non-SCSI queue\n");
+		return -EINVAL;
+	}
+
+	return bsg_register_queue(q, parent, NULL, &bsg_scsi_ops, NULL);
+}
+EXPORT_SYMBOL_GPL(bsg_scsi_register_queue);
 
 static struct cdev bsg_cdev;
 
diff --git a/block/sed-opal.c b/block/sed-opal.c
index e4929ee..945f4b8 100644
--- a/block/sed-opal.c
+++ b/block/sed-opal.c
@@ -554,15 +554,14 @@ static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
 
 	size_t len;
 	int msb;
-	u8 n;
 
 	if (!(number & ~TINY_ATOM_DATA_MASK)) {
 		add_token_u8(err, cmd, number);
 		return;
 	}
 
-	msb = fls(number);
-	len = DIV_ROUND_UP(msb, 4);
+	msb = fls64(number);
+	len = DIV_ROUND_UP(msb, 8);
 
 	if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) {
 		pr_debug("Error adding u64: end of buffer.\n");
@@ -570,10 +569,8 @@ static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
 		return;
 	}
 	add_short_atom_header(cmd, false, false, len);
-	while (len--) {
-		n = number >> (len * 8);
-		add_token_u8(err, cmd, n);
-	}
+	while (len--)
+		add_token_u8(err, cmd, number >> (len * 8));
 }
 
 static void add_token_bytestring(int *err, struct opal_dev *cmd,
@@ -871,6 +868,9 @@ static int response_parse(const u8 *buf, size_t length,
 static size_t response_get_string(const struct parsed_resp *resp, int n,
 				  const char **store)
 {
+	u8 skip;
+	const struct opal_resp_tok *token;
+
 	*store = NULL;
 	if (!resp) {
 		pr_debug("Response is NULL\n");
@@ -883,13 +883,30 @@ static size_t response_get_string(const struct parsed_resp *resp, int n,
 		return 0;
 	}
 
-	if (resp->toks[n].type != OPAL_DTA_TOKENID_BYTESTRING) {
+	token = &resp->toks[n];
+	if (token->type != OPAL_DTA_TOKENID_BYTESTRING) {
 		pr_debug("Token is not a byte string!\n");
 		return 0;
 	}
 
-	*store = resp->toks[n].pos + 1;
-	return resp->toks[n].len - 1;
+	switch (token->width) {
+	case OPAL_WIDTH_TINY:
+	case OPAL_WIDTH_SHORT:
+		skip = 1;
+		break;
+	case OPAL_WIDTH_MEDIUM:
+		skip = 2;
+		break;
+	case OPAL_WIDTH_LONG:
+		skip = 4;
+		break;
+	default:
+		pr_debug("Token has invalid width!\n");
+		return 0;
+	}
+
+	*store = token->pos + skip;
+	return token->len - skip;
 }
 
 static u64 response_get_u64(const struct parsed_resp *resp, int n)
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
index c68e724..e967c11 100644
--- a/drivers/acpi/custom_method.c
+++ b/drivers/acpi/custom_method.c
@@ -94,7 +94,7 @@ static void __exit acpi_custom_method_exit(void)
 {
 	if (cm_dentry)
 		debugfs_remove(cm_dentry);
- }
+}
 
 module_init(acpi_custom_method_init);
 module_exit(acpi_custom_method_exit);
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 6cf4988..3563103 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -219,7 +219,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
 		return fan_set_state_acpi4(device, state);
 	else
 		return fan_set_state(device, state);
- }
+}
 
 static const struct thermal_cooling_device_ops fan_cooling_ops = {
 	.get_max_state = fan_get_max_state,
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index eb09ef5..22a112b 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/nd.h>
 #include <asm/cacheflush.h>
+#include <acpi/nfit.h>
 #include "nfit.h"
 
 /*
@@ -690,6 +691,32 @@ static bool add_memdev(struct acpi_nfit_desc *acpi_desc,
 	return true;
 }
 
+int nfit_get_smbios_id(u32 device_handle, u16 *flags)
+{
+	struct acpi_nfit_memory_map *memdev;
+	struct acpi_nfit_desc *acpi_desc;
+	struct nfit_mem *nfit_mem;
+
+	mutex_lock(&acpi_desc_lock);
+	list_for_each_entry(acpi_desc, &acpi_descs, list) {
+		mutex_lock(&acpi_desc->init_mutex);
+		list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
+			memdev = __to_nfit_memdev(nfit_mem);
+			if (memdev->device_handle == device_handle) {
+				mutex_unlock(&acpi_desc->init_mutex);
+				mutex_unlock(&acpi_desc_lock);
+				*flags = memdev->flags;
+				return memdev->physical_id;
+			}
+		}
+		mutex_unlock(&acpi_desc->init_mutex);
+	}
+	mutex_unlock(&acpi_desc_lock);
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(nfit_get_smbios_id);
+
 /*
  * An implementation may provide a truncated control region if no block windows
  * are defined.
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index deea78e..66cb0f8 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -24,7 +24,6 @@
 
 #include <linux/uaccess.h>
 
-#define SECTOR_SHIFT		9
 #define PAGE_SECTORS_SHIFT	(PAGE_SHIFT - SECTOR_SHIFT)
 #define PAGE_SECTORS		(1 << PAGE_SECTORS_SHIFT)
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0a0394a..185f1ef 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2816,7 +2816,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
 
 	drbd_init_set_defaults(device);
 
-	q = blk_alloc_queue(GFP_KERNEL);
+	q = blk_alloc_queue_node(GFP_KERNEL, NUMA_NO_NODE, &resource->req_lock);
 	if (!q)
 		goto out_no_q;
 	device->rq_queue = q;
@@ -2848,7 +2848,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
 	/* Setting the max_hw_sectors to an odd value of 8kibyte here
 	   This triggers a max_bio_size message upon first attach or connect */
 	blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8);
-	q->queue_lock = &resource->req_lock;
 
 	device->md_io.page = alloc_page(GFP_KERNEL);
 	if (!device->md_io.page)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index a12f77e..b4f0276 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1212,10 +1212,10 @@ static void decide_on_discard_support(struct drbd_device *device,
 		 * topology on all peers. */
 		blk_queue_discard_granularity(q, 512);
 		q->limits.max_discard_sectors = drbd_max_discard_sectors(connection);
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
 		q->limits.max_write_zeroes_sectors = drbd_max_discard_sectors(connection);
 	} else {
-		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
+		blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
 		blk_queue_discard_granularity(q, 0);
 		q->limits.max_discard_sectors = 0;
 		q->limits.max_write_zeroes_sectors = 0;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index ee62d2d..264abaa 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -214,10 +214,10 @@ static void __loop_update_dio(struct loop_device *lo, bool dio)
 	blk_mq_freeze_queue(lo->lo_queue);
 	lo->use_dio = use_dio;
 	if (use_dio) {
-		queue_flag_clear_unlocked(QUEUE_FLAG_NOMERGES, lo->lo_queue);
+		blk_queue_flag_clear(QUEUE_FLAG_NOMERGES, lo->lo_queue);
 		lo->lo_flags |= LO_FLAGS_DIRECT_IO;
 	} else {
-		queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, lo->lo_queue);
+		blk_queue_flag_set(QUEUE_FLAG_NOMERGES, lo->lo_queue);
 		lo->lo_flags &= ~LO_FLAGS_DIRECT_IO;
 	}
 	blk_mq_unfreeze_queue(lo->lo_queue);
@@ -817,7 +817,7 @@ static void loop_config_discard(struct loop_device *lo)
 		q->limits.discard_alignment = 0;
 		blk_queue_max_discard_sectors(q, 0);
 		blk_queue_max_write_zeroes_sectors(q, 0);
-		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
+		blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
 		return;
 	}
 
@@ -826,7 +826,7 @@ static void loop_config_discard(struct loop_device *lo)
 
 	blk_queue_max_discard_sectors(q, UINT_MAX >> 9);
 	blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9);
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
 }
 
 static void loop_unprepare_queue(struct loop_device *lo)
@@ -1167,21 +1167,17 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
 static int
 loop_get_status(struct loop_device *lo, struct loop_info64 *info)
 {
-	struct file *file = lo->lo_backing_file;
+	struct file *file;
 	struct kstat stat;
-	int error;
+	int ret;
 
-	if (lo->lo_state != Lo_bound)
+	if (lo->lo_state != Lo_bound) {
+		mutex_unlock(&lo->lo_ctl_mutex);
 		return -ENXIO;
-	error = vfs_getattr(&file->f_path, &stat,
-			    STATX_INO, AT_STATX_SYNC_AS_STAT);
-	if (error)
-		return error;
+	}
+
 	memset(info, 0, sizeof(*info));
 	info->lo_number = lo->lo_number;
-	info->lo_device = huge_encode_dev(stat.dev);
-	info->lo_inode = stat.ino;
-	info->lo_rdevice = huge_encode_dev(lo->lo_device ? stat.rdev : stat.dev);
 	info->lo_offset = lo->lo_offset;
 	info->lo_sizelimit = lo->lo_sizelimit;
 	info->lo_flags = lo->lo_flags;
@@ -1194,7 +1190,19 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
 		memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
 		       lo->lo_encrypt_key_size);
 	}
-	return 0;
+
+	/* Drop lo_ctl_mutex while we call into the filesystem. */
+	file = get_file(lo->lo_backing_file);
+	mutex_unlock(&lo->lo_ctl_mutex);
+	ret = vfs_getattr(&file->f_path, &stat, STATX_INO,
+			  AT_STATX_SYNC_AS_STAT);
+	if (!ret) {
+		info->lo_device = huge_encode_dev(stat.dev);
+		info->lo_inode = stat.ino;
+		info->lo_rdevice = huge_encode_dev(stat.rdev);
+	}
+	fput(file);
+	return ret;
 }
 
 static void
@@ -1352,7 +1360,10 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
 	struct loop_device *lo = bdev->bd_disk->private_data;
 	int err;
 
-	mutex_lock_nested(&lo->lo_ctl_mutex, 1);
+	err = mutex_lock_killable_nested(&lo->lo_ctl_mutex, 1);
+	if (err)
+		goto out_unlocked;
+
 	switch (cmd) {
 	case LOOP_SET_FD:
 		err = loop_set_fd(lo, mode, bdev, arg);
@@ -1374,7 +1385,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
 		break;
 	case LOOP_GET_STATUS:
 		err = loop_get_status_old(lo, (struct loop_info __user *) arg);
-		break;
+		/* loop_get_status() unlocks lo_ctl_mutex */
+		goto out_unlocked;
 	case LOOP_SET_STATUS64:
 		err = -EPERM;
 		if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
@@ -1383,7 +1395,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
 		break;
 	case LOOP_GET_STATUS64:
 		err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
-		break;
+		/* loop_get_status() unlocks lo_ctl_mutex */
+		goto out_unlocked;
 	case LOOP_SET_CAPACITY:
 		err = -EPERM;
 		if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
@@ -1535,16 +1548,20 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode,
 
 	switch(cmd) {
 	case LOOP_SET_STATUS:
-		mutex_lock(&lo->lo_ctl_mutex);
-		err = loop_set_status_compat(
-			lo, (const struct compat_loop_info __user *) arg);
-		mutex_unlock(&lo->lo_ctl_mutex);
+		err = mutex_lock_killable(&lo->lo_ctl_mutex);
+		if (!err) {
+			err = loop_set_status_compat(lo,
+						     (const struct compat_loop_info __user *)arg);
+			mutex_unlock(&lo->lo_ctl_mutex);
+		}
 		break;
 	case LOOP_GET_STATUS:
-		mutex_lock(&lo->lo_ctl_mutex);
-		err = loop_get_status_compat(
-			lo, (struct compat_loop_info __user *) arg);
-		mutex_unlock(&lo->lo_ctl_mutex);
+		err = mutex_lock_killable(&lo->lo_ctl_mutex);
+		if (!err) {
+			err = loop_get_status_compat(lo,
+						     (struct compat_loop_info __user *)arg);
+			/* loop_get_status() unlocks lo_ctl_mutex */
+		}
 		break;
 	case LOOP_SET_CAPACITY:
 	case LOOP_CLR_FD:
@@ -1808,7 +1825,7 @@ static int loop_add(struct loop_device **l, int i)
 	 * page. For directio mode, merge does help to dispatch bigger request
 	 * to underlayer disk. We will enable merge once directio is enabled.
 	 */
-	queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, lo->lo_queue);
+	blk_queue_flag_set(QUEUE_FLAG_NOMERGES, lo->lo_queue);
 
 	err = -ENOMEM;
 	disk = lo->lo_disk = alloc_disk(1 << part_shift);
@@ -1864,8 +1881,8 @@ static int loop_add(struct loop_device **l, int i)
 
 static void loop_remove(struct loop_device *lo)
 {
-	blk_cleanup_queue(lo->lo_queue);
 	del_gendisk(lo->lo_disk);
+	blk_cleanup_queue(lo->lo_queue);
 	blk_mq_free_tag_set(&lo->tag_set);
 	put_disk(lo->lo_disk);
 	kfree(lo);
@@ -1949,7 +1966,9 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd,
 		ret = loop_lookup(&lo, parm);
 		if (ret < 0)
 			break;
-		mutex_lock(&lo->lo_ctl_mutex);
+		ret = mutex_lock_killable(&lo->lo_ctl_mutex);
+		if (ret)
+			break;
 		if (lo->lo_state != Lo_unbound) {
 			ret = -EBUSY;
 			mutex_unlock(&lo->lo_ctl_mutex);
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index b8af735..769c551 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -159,7 +159,7 @@ static bool mtip_check_surprise_removal(struct pci_dev *pdev)
 	if (vendor_id == 0xFFFF) {
 		dd->sr = true;
 		if (dd->queue)
-			set_bit(QUEUE_FLAG_DEAD, &dd->queue->queue_flags);
+			blk_queue_flag_set(QUEUE_FLAG_DEAD, dd->queue);
 		else
 			dev_warn(&dd->pdev->dev,
 				"%s: dd->queue is NULL\n", __func__);
@@ -3855,8 +3855,8 @@ static int mtip_block_initialize(struct driver_data *dd)
 		goto start_service_thread;
 
 	/* Set device limits. */
-	set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags);
-	clear_bit(QUEUE_FLAG_ADD_RANDOM, &dd->queue->queue_flags);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, dd->queue);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, dd->queue);
 	blk_queue_max_segments(dd->queue, MTIP_MAX_SG);
 	blk_queue_physical_block_size(dd->queue, 4096);
 	blk_queue_max_hw_sectors(dd->queue, 0xffff);
@@ -3866,7 +3866,7 @@ static int mtip_block_initialize(struct driver_data *dd)
 
 	/* Signal trim support */
 	if (dd->trim_supp == true) {
-		set_bit(QUEUE_FLAG_DISCARD, &dd->queue->queue_flags);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, dd->queue);
 		dd->queue->limits.discard_granularity = 4096;
 		blk_queue_max_discard_sectors(dd->queue,
 			MTIP_MAX_TRIM_ENTRY_LEN * MTIP_MAX_TRIM_ENTRIES);
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 86258b0..afbc202 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -964,7 +964,7 @@ static void nbd_parse_flags(struct nbd_device *nbd)
 	else
 		set_disk_ro(nbd->disk, false);
 	if (config->flags & NBD_FLAG_SEND_TRIM)
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, nbd->disk->queue);
 	if (config->flags & NBD_FLAG_SEND_FLUSH) {
 		if (config->flags & NBD_FLAG_SEND_FUA)
 			blk_queue_write_cache(nbd->disk->queue, true, true);
@@ -1040,7 +1040,7 @@ static void nbd_config_put(struct nbd_device *nbd)
 		nbd->config = NULL;
 
 		nbd->tag_set.timeout = 0;
-		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
+		blk_queue_flag_clear(QUEUE_FLAG_DISCARD, nbd->disk->queue);
 
 		mutex_unlock(&nbd->config_lock);
 		nbd_put(nbd);
@@ -1488,8 +1488,8 @@ static int nbd_dev_add(int index)
 	/*
 	 * Tell the block layer that we are not a rotational device
 	 */
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue);
-	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, disk->queue);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, disk->queue);
 	disk->queue->limits.discard_granularity = 512;
 	blk_queue_max_discard_sectors(disk->queue, UINT_MAX);
 	blk_queue_max_segment_size(disk->queue, UINT_MAX);
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index 287a096..a765532 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -16,10 +16,8 @@
 #include <linux/badblocks.h>
 #include <linux/fault-inject.h>
 
-#define SECTOR_SHIFT		9
 #define PAGE_SECTORS_SHIFT	(PAGE_SHIFT - SECTOR_SHIFT)
 #define PAGE_SECTORS		(1 << PAGE_SECTORS_SHIFT)
-#define SECTOR_SIZE		(1 << SECTOR_SHIFT)
 #define SECTOR_MASK		(PAGE_SECTORS - 1)
 
 #define FREE_BATCH		16
@@ -29,6 +27,7 @@
 
 #ifdef CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION
 static DECLARE_FAULT_ATTR(null_timeout_attr);
+static DECLARE_FAULT_ATTR(null_requeue_attr);
 #endif
 
 static inline u64 mb_per_tick(int mbps)
@@ -53,6 +52,7 @@ struct nullb_queue {
 	wait_queue_head_t wait;
 	unsigned int queue_depth;
 	struct nullb_device *dev;
+	unsigned int requeue_selection;
 
 	struct nullb_cmd *cmds;
 };
@@ -72,6 +72,7 @@ enum nullb_device_flags {
 	NULLB_DEV_FL_CACHE	= 3,
 };
 
+#define MAP_SZ		((PAGE_SIZE >> SECTOR_SHIFT) + 2)
 /*
  * nullb_page is a page in memory for nullb devices.
  *
@@ -86,10 +87,10 @@ enum nullb_device_flags {
  */
 struct nullb_page {
 	struct page *page;
-	unsigned long bitmap;
+	DECLARE_BITMAP(bitmap, MAP_SZ);
 };
-#define NULLB_PAGE_LOCK (sizeof(unsigned long) * 8 - 1)
-#define NULLB_PAGE_FREE (sizeof(unsigned long) * 8 - 2)
+#define NULLB_PAGE_LOCK (MAP_SZ - 1)
+#define NULLB_PAGE_FREE (MAP_SZ - 2)
 
 struct nullb_device {
 	struct nullb *nullb;
@@ -170,6 +171,9 @@ MODULE_PARM_DESC(home_node, "Home node for the device");
 #ifdef CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION
 static char g_timeout_str[80];
 module_param_string(timeout, g_timeout_str, sizeof(g_timeout_str), S_IRUGO);
+
+static char g_requeue_str[80];
+module_param_string(requeue, g_requeue_str, sizeof(g_requeue_str), S_IRUGO);
 #endif
 
 static int g_queue_mode = NULL_Q_MQ;
@@ -728,7 +732,7 @@ static struct nullb_page *null_alloc_page(gfp_t gfp_flags)
 	if (!t_page->page)
 		goto out_freepage;
 
-	t_page->bitmap = 0;
+	memset(t_page->bitmap, 0, sizeof(t_page->bitmap));
 	return t_page;
 out_freepage:
 	kfree(t_page);
@@ -738,13 +742,20 @@ static struct nullb_page *null_alloc_page(gfp_t gfp_flags)
 
 static void null_free_page(struct nullb_page *t_page)
 {
-	__set_bit(NULLB_PAGE_FREE, &t_page->bitmap);
-	if (test_bit(NULLB_PAGE_LOCK, &t_page->bitmap))
+	__set_bit(NULLB_PAGE_FREE, t_page->bitmap);
+	if (test_bit(NULLB_PAGE_LOCK, t_page->bitmap))
 		return;
 	__free_page(t_page->page);
 	kfree(t_page);
 }
 
+static bool null_page_empty(struct nullb_page *page)
+{
+	int size = MAP_SZ - 2;
+
+	return find_first_bit(page->bitmap, size) == size;
+}
+
 static void null_free_sector(struct nullb *nullb, sector_t sector,
 	bool is_cache)
 {
@@ -759,9 +770,9 @@ static void null_free_sector(struct nullb *nullb, sector_t sector,
 
 	t_page = radix_tree_lookup(root, idx);
 	if (t_page) {
-		__clear_bit(sector_bit, &t_page->bitmap);
+		__clear_bit(sector_bit, t_page->bitmap);
 
-		if (!t_page->bitmap) {
+		if (null_page_empty(t_page)) {
 			ret = radix_tree_delete_item(root, idx, t_page);
 			WARN_ON(ret != t_page);
 			null_free_page(ret);
@@ -832,7 +843,7 @@ static struct nullb_page *__null_lookup_page(struct nullb *nullb,
 	t_page = radix_tree_lookup(root, idx);
 	WARN_ON(t_page && t_page->page->index != idx);
 
-	if (t_page && (for_write || test_bit(sector_bit, &t_page->bitmap)))
+	if (t_page && (for_write || test_bit(sector_bit, t_page->bitmap)))
 		return t_page;
 
 	return NULL;
@@ -895,10 +906,10 @@ static int null_flush_cache_page(struct nullb *nullb, struct nullb_page *c_page)
 
 	t_page = null_insert_page(nullb, idx << PAGE_SECTORS_SHIFT, true);
 
-	__clear_bit(NULLB_PAGE_LOCK, &c_page->bitmap);
-	if (test_bit(NULLB_PAGE_FREE, &c_page->bitmap)) {
+	__clear_bit(NULLB_PAGE_LOCK, c_page->bitmap);
+	if (test_bit(NULLB_PAGE_FREE, c_page->bitmap)) {
 		null_free_page(c_page);
-		if (t_page && t_page->bitmap == 0) {
+		if (t_page && null_page_empty(t_page)) {
 			ret = radix_tree_delete_item(&nullb->dev->data,
 				idx, t_page);
 			null_free_page(t_page);
@@ -914,11 +925,11 @@ static int null_flush_cache_page(struct nullb *nullb, struct nullb_page *c_page)
 
 	for (i = 0; i < PAGE_SECTORS;
 			i += (nullb->dev->blocksize >> SECTOR_SHIFT)) {
-		if (test_bit(i, &c_page->bitmap)) {
+		if (test_bit(i, c_page->bitmap)) {
 			offset = (i << SECTOR_SHIFT);
 			memcpy(dst + offset, src + offset,
 				nullb->dev->blocksize);
-			__set_bit(i, &t_page->bitmap);
+			__set_bit(i, t_page->bitmap);
 		}
 	}
 
@@ -955,10 +966,10 @@ static int null_make_cache_space(struct nullb *nullb, unsigned long n)
 		 * We found the page which is being flushed to disk by other
 		 * threads
 		 */
-		if (test_bit(NULLB_PAGE_LOCK, &c_pages[i]->bitmap))
+		if (test_bit(NULLB_PAGE_LOCK, c_pages[i]->bitmap))
 			c_pages[i] = NULL;
 		else
-			__set_bit(NULLB_PAGE_LOCK, &c_pages[i]->bitmap);
+			__set_bit(NULLB_PAGE_LOCK, c_pages[i]->bitmap);
 	}
 
 	one_round = 0;
@@ -1011,7 +1022,7 @@ static int copy_to_nullb(struct nullb *nullb, struct page *source,
 		kunmap_atomic(dst);
 		kunmap_atomic(src);
 
-		__set_bit(sector & SECTOR_MASK, &t_page->bitmap);
+		__set_bit(sector & SECTOR_MASK, t_page->bitmap);
 
 		if (is_fua)
 			null_free_sector(nullb, sector, true);
@@ -1380,7 +1391,15 @@ static bool should_timeout_request(struct request *rq)
 	if (g_timeout_str[0])
 		return should_fail(&null_timeout_attr, 1);
 #endif
+	return false;
+}
 
+static bool should_requeue_request(struct request *rq)
+{
+#ifdef CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION
+	if (g_requeue_str[0])
+		return should_fail(&null_requeue_attr, 1);
+#endif
 	return false;
 }
 
@@ -1391,11 +1410,17 @@ static void null_request_fn(struct request_queue *q)
 	while ((rq = blk_fetch_request(q)) != NULL) {
 		struct nullb_cmd *cmd = rq->special;
 
-		if (!should_timeout_request(rq)) {
-			spin_unlock_irq(q->queue_lock);
-			null_handle_cmd(cmd);
-			spin_lock_irq(q->queue_lock);
+		/* just ignore the request */
+		if (should_timeout_request(rq))
+			continue;
+		if (should_requeue_request(rq)) {
+			blk_requeue_request(q, rq);
+			continue;
 		}
+
+		spin_unlock_irq(q->queue_lock);
+		null_handle_cmd(cmd);
+		spin_lock_irq(q->queue_lock);
 	}
 }
 
@@ -1422,10 +1447,23 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
 
 	blk_mq_start_request(bd->rq);
 
-	if (!should_timeout_request(bd->rq))
-		return null_handle_cmd(cmd);
+	if (should_requeue_request(bd->rq)) {
+		/*
+		 * Alternate between hitting the core BUSY path, and the
+		 * driver driven requeue path
+		 */
+		nq->requeue_selection++;
+		if (nq->requeue_selection & 1)
+			return BLK_STS_RESOURCE;
+		else {
+			blk_mq_requeue_request(bd->rq, true);
+			return BLK_STS_OK;
+		}
+	}
+	if (should_timeout_request(bd->rq))
+		return BLK_STS_OK;
 
-	return BLK_STS_OK;
+	return null_handle_cmd(cmd);
 }
 
 static const struct blk_mq_ops null_mq_ops = {
@@ -1485,7 +1523,7 @@ static void null_config_discard(struct nullb *nullb)
 	nullb->q->limits.discard_granularity = nullb->dev->blocksize;
 	nullb->q->limits.discard_alignment = nullb->dev->blocksize;
 	blk_queue_max_discard_sectors(nullb->q, UINT_MAX >> 9);
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, nullb->q);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, nullb->q);
 }
 
 static int null_open(struct block_device *bdev, fmode_t mode)
@@ -1659,16 +1697,27 @@ static void null_validate_conf(struct nullb_device *dev)
 		dev->mbps = 0;
 }
 
+#ifdef CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION
+static bool __null_setup_fault(struct fault_attr *attr, char *str)
+{
+	if (!str[0])
+		return true;
+
+	if (!setup_fault_attr(attr, str))
+		return false;
+
+	attr->verbose = 0;
+	return true;
+}
+#endif
+
 static bool null_setup_fault(void)
 {
 #ifdef CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION
-	if (!g_timeout_str[0])
-		return true;
-
-	if (!setup_fault_attr(&null_timeout_attr, g_timeout_str))
+	if (!__null_setup_fault(&null_timeout_attr, g_timeout_str))
 		return false;
-
-	null_timeout_attr.verbose = 0;
+	if (!__null_setup_fault(&null_requeue_attr, g_requeue_str))
+		return false;
 #endif
 	return true;
 }
@@ -1717,7 +1766,8 @@ static int null_add_dev(struct nullb_device *dev)
 		}
 		null_init_queues(nullb);
 	} else if (dev->queue_mode == NULL_Q_BIO) {
-		nullb->q = blk_alloc_queue_node(GFP_KERNEL, dev->home_node);
+		nullb->q = blk_alloc_queue_node(GFP_KERNEL, dev->home_node,
+						NULL);
 		if (!nullb->q) {
 			rv = -ENOMEM;
 			goto out_cleanup_queues;
@@ -1758,8 +1808,8 @@ static int null_add_dev(struct nullb_device *dev)
 	}
 
 	nullb->q->queuedata = nullb;
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, nullb->q);
-	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, nullb->q);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, nullb->q);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, nullb->q);
 
 	mutex_lock(&lock);
 	nullb->index = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL);
@@ -1802,10 +1852,6 @@ static int __init null_init(void)
 	struct nullb *nullb;
 	struct nullb_device *dev;
 
-	/* check for nullb_page.bitmap */
-	if (sizeof(unsigned long) * 8 - 2 < (PAGE_SIZE >> SECTOR_SHIFT))
-		return -EINVAL;
-
 	if (g_bs > PAGE_SIZE) {
 		pr_warn("null_blk: invalid block size\n");
 		pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE);
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 7b8c636..a026211 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -230,6 +230,8 @@ static int pcd_block_open(struct block_device *bdev, fmode_t mode)
 	struct pcd_unit *cd = bdev->bd_disk->private_data;
 	int ret;
 
+	check_disk_change(bdev);
+
 	mutex_lock(&pcd_mutex);
 	ret = cdrom_open(&cd->info, bdev, mode);
 	mutex_unlock(&pcd_mutex);
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 8e40da0..1e03b04 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -51,15 +51,6 @@
 #define RBD_DEBUG	/* Activate rbd_assert() calls */
 
 /*
- * The basic unit of block I/O is a sector.  It is interpreted in a
- * number of contexts in Linux (blk, bio, genhd), but the default is
- * universally 512 bytes.  These symbols are just slightly more
- * meaningful than the bare numbers they represent.
- */
-#define	SECTOR_SHIFT	9
-#define	SECTOR_SIZE	(1ULL << SECTOR_SHIFT)
-
-/*
  * Increment the given counter and return its updated value.
  * If the counter is already 0 it will not be incremented.
  * If the counter is already at its maximum value returns
@@ -4370,7 +4361,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
 		goto out_tag_set;
 	}
 
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
 	/* QUEUE_FLAG_ADD_RANDOM is off by default for blk-mq */
 
 	/* set io sizes to object size */
@@ -4383,7 +4374,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
 	blk_queue_io_opt(q, segment_size);
 
 	/* enable the discard support */
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
 	q->limits.discard_granularity = segment_size;
 	blk_queue_max_discard_sectors(q, segment_size / SECTOR_SIZE);
 	blk_queue_max_write_zeroes_sectors(q, segment_size / SECTOR_SIZE);
diff --git a/drivers/block/rsxx/dev.c b/drivers/block/rsxx/dev.c
index e397d3e..dddb3f2 100644
--- a/drivers/block/rsxx/dev.c
+++ b/drivers/block/rsxx/dev.c
@@ -287,10 +287,10 @@ int rsxx_setup_dev(struct rsxx_cardinfo *card)
 	blk_queue_max_hw_sectors(card->queue, blkdev_max_hw_sectors);
 	blk_queue_physical_block_size(card->queue, RSXX_HW_BLK_SIZE);
 
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, card->queue);
-	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, card->queue);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, card->queue);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, card->queue);
 	if (rsxx_discard_supported(card)) {
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, card->queue);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, card->queue);
 		blk_queue_max_discard_sectors(card->queue,
 						RSXX_HW_BLK_SIZE >> 9);
 		card->queue->limits.discard_granularity = RSXX_HW_BLK_SIZE;
diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c
index e41935a..bc7aea6 100644
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -2858,8 +2858,8 @@ static int skd_cons_disk(struct skd_device *skdev)
 	/* set optimal I/O size to 8KB */
 	blk_queue_io_opt(q, 8192);
 
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
-	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q);
 
 	blk_queue_rq_timeout(q, 8 * HZ);
 
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 8077123..5c7fb8c 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -888,13 +888,14 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	card->Active = -1;	/* no page is active */
 	card->bio = NULL;
 	card->biotail = &card->bio;
+	spin_lock_init(&card->lock);
 
-	card->queue = blk_alloc_queue(GFP_KERNEL);
+	card->queue = blk_alloc_queue_node(GFP_KERNEL, NUMA_NO_NODE,
+					   &card->lock);
 	if (!card->queue)
 		goto failed_alloc;
 
 	blk_queue_make_request(card->queue, mm_make_request);
-	card->queue->queue_lock = &card->lock;
 	card->queue->queuedata = card;
 
 	tasklet_init(&card->tasklet, process_page, (unsigned long)card);
@@ -968,8 +969,6 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	dev_printk(KERN_INFO, &card->dev->dev,
 		"Window size %d bytes, IRQ %d\n", data, dev->irq);
 
-	spin_lock_init(&card->lock);
-
 	pci_set_drvdata(dev, card);
 
 	if (pci_write_cmd != 0x0F) 	/* If not Memory Write & Invalidate */
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 92ec1bb..2a8e781 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -932,15 +932,15 @@ static void blkif_set_queue_limits(struct blkfront_info *info)
 	unsigned int segments = info->max_indirect_segments ? :
 				BLKIF_MAX_SEGMENTS_PER_REQUEST;
 
-	queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq);
+	blk_queue_flag_set(QUEUE_FLAG_VIRT, rq);
 
 	if (info->feature_discard) {
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, rq);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, rq);
 		blk_queue_max_discard_sectors(rq, get_capacity(gd));
 		rq->limits.discard_granularity = info->discard_granularity;
 		rq->limits.discard_alignment = info->discard_alignment;
 		if (info->feature_secdiscard)
-			queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, rq);
+			blk_queue_flag_set(QUEUE_FLAG_SECERASE, rq);
 	}
 
 	/* Hard sector size and max sectors impersonate the equiv. hardware. */
@@ -1611,8 +1611,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
 				blkif_req(req)->error = BLK_STS_NOTSUPP;
 				info->feature_discard = 0;
 				info->feature_secdiscard = 0;
-				queue_flag_clear(QUEUE_FLAG_DISCARD, rq);
-				queue_flag_clear(QUEUE_FLAG_SECERASE, rq);
+				blk_queue_flag_clear(QUEUE_FLAG_DISCARD, rq);
+				blk_queue_flag_clear(QUEUE_FLAG_SECERASE, rq);
 			}
 			break;
 		case BLKIF_OP_FLUSH_DISKCACHE:
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index bd38f46..0f3fadd 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1537,8 +1537,8 @@ static int zram_add(void)
 	/* Actual capacity set using syfs (/sys/block/zram<id>/disksize */
 	set_capacity(zram->disk, 0);
 	/* zram devices sort of resembles non-rotational disks */
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
-	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, zram->disk->queue);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, zram->disk->queue);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, zram->disk->queue);
 
 	/*
 	 * To ensure that we always get PAGE_SIZE aligned
@@ -1551,7 +1551,7 @@ static int zram_add(void)
 	blk_queue_io_opt(zram->disk->queue, PAGE_SIZE);
 	zram->disk->queue->limits.discard_granularity = PAGE_SIZE;
 	blk_queue_max_discard_sectors(zram->disk->queue, UINT_MAX);
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, zram->disk->queue);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, zram->disk->queue);
 
 	/*
 	 * zram_bio_discard() will clear all logical blocks if logical block
@@ -1627,8 +1627,8 @@ static int zram_remove(struct zram *zram)
 
 	pr_info("Removed device: %s\n", zram->disk->disk_name);
 
-	blk_cleanup_queue(zram->disk->queue);
 	del_gendisk(zram->disk);
+	blk_cleanup_queue(zram->disk->queue);
 	put_disk(zram->disk);
 	kfree(zram);
 	return 0;
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index d71c800..0088612 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -21,7 +21,6 @@
 
 #include "zcomp.h"
 
-#define SECTOR_SHIFT		9
 #define SECTORS_PER_PAGE_SHIFT	(PAGE_SHIFT - SECTOR_SHIFT)
 #define SECTORS_PER_PAGE	(1 << SECTORS_PER_PAGE_SHIFT)
 #define ZRAM_LOGICAL_BLOCK_SHIFT 12
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 769599b..ff70850 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -8,25 +8,10 @@
 config ARM_CCI
 	bool
 
-config ARM_CCI_PMU
-	bool
-	select ARM_CCI
-
 config ARM_CCI400_COMMON
 	bool
 	select ARM_CCI
 
-config ARM_CCI400_PMU
-	bool "ARM CCI400 PMU support"
-	depends on (ARM && CPU_V7) || ARM64
-	depends on PERF_EVENTS
-	select ARM_CCI400_COMMON
-	select ARM_CCI_PMU
-	help
-	  Support for PMU events monitoring on the ARM CCI-400 (cache coherent
-	  interconnect). CCI-400 supports counting events related to the
-	  connected slave/master interfaces.
-
 config ARM_CCI400_PORT_CTRL
 	bool
 	depends on ARM && OF && CPU_V7
@@ -35,27 +20,6 @@
 	  Low level power management driver for CCI400 cache coherent
 	  interconnect for ARM platforms.
 
-config ARM_CCI5xx_PMU
-	bool "ARM CCI-500/CCI-550 PMU support"
-	depends on (ARM && CPU_V7) || ARM64
-	depends on PERF_EVENTS
-	select ARM_CCI_PMU
-	help
-	  Support for PMU events monitoring on the ARM CCI-500/CCI-550 cache
-	  coherent interconnects. Both of them provide 8 independent event counters,
-	  which can count events pertaining to the slave/master interfaces as well
-	  as the internal events to the CCI.
-
-	  If unsure, say Y
-
-config ARM_CCN
-	tristate "ARM CCN driver support"
-	depends on ARM || ARM64
-	depends on PERF_EVENTS
-	help
-	  PMU (perf) driver supporting the ARM CCN (Cache Coherent Network)
-	  interconnect.
-
 config BRCMSTB_GISB_ARB
 	bool "Broadcom STB GISB bus arbiter"
 	depends on ARM || ARM64 || MIPS
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index b666c49..3d473b8 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -5,8 +5,6 @@
 
 # Interconnect bus drivers for ARM platforms
 obj-$(CONFIG_ARM_CCI)		+= arm-cci.o
-obj-$(CONFIG_ARM_CCN)		+= arm-ccn.o
-
 obj-$(CONFIG_BRCMSTB_GISB_ARB)	+= brcmstb_gisb.o
 
 # DPAA2 fsl-mc bus
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index c4c0c85..443e4c3 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -16,21 +16,17 @@
 
 #include <linux/arm-cci.h>
 #include <linux/io.h>
-#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
-#include <linux/of_irq.h>
 #include <linux/of_platform.h>
-#include <linux/perf_event.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/spinlock.h>
 
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 
-static void __iomem *cci_ctrl_base;
-static unsigned long cci_ctrl_phys;
+static void __iomem *cci_ctrl_base __ro_after_init;
+static unsigned long cci_ctrl_phys __ro_after_init;
 
 #ifdef CONFIG_ARM_CCI400_PORT_CTRL
 struct cci_nb_ports {
@@ -59,1733 +55,26 @@ static const struct of_device_id arm_cci_matches[] = {
 	{},
 };
 
-#ifdef CONFIG_ARM_CCI_PMU
+static const struct of_dev_auxdata arm_cci_auxdata[] = {
+	OF_DEV_AUXDATA("arm,cci-400-pmu", 0, NULL, &cci_ctrl_base),
+	OF_DEV_AUXDATA("arm,cci-400-pmu,r0", 0, NULL, &cci_ctrl_base),
+	OF_DEV_AUXDATA("arm,cci-400-pmu,r1", 0, NULL, &cci_ctrl_base),
+	OF_DEV_AUXDATA("arm,cci-500-pmu,r0", 0, NULL, &cci_ctrl_base),
+	OF_DEV_AUXDATA("arm,cci-550-pmu,r0", 0, NULL, &cci_ctrl_base),
+	{}
+};
 
 #define DRIVER_NAME		"ARM-CCI"
-#define DRIVER_NAME_PMU		DRIVER_NAME " PMU"
-
-#define CCI_PMCR		0x0100
-#define CCI_PID2		0x0fe8
-
-#define CCI_PMCR_CEN		0x00000001
-#define CCI_PMCR_NCNT_MASK	0x0000f800
-#define CCI_PMCR_NCNT_SHIFT	11
-
-#define CCI_PID2_REV_MASK	0xf0
-#define CCI_PID2_REV_SHIFT	4
-
-#define CCI_PMU_EVT_SEL		0x000
-#define CCI_PMU_CNTR		0x004
-#define CCI_PMU_CNTR_CTRL	0x008
-#define CCI_PMU_OVRFLW		0x00c
-
-#define CCI_PMU_OVRFLW_FLAG	1
-
-#define CCI_PMU_CNTR_SIZE(model)	((model)->cntr_size)
-#define CCI_PMU_CNTR_BASE(model, idx)	((idx) * CCI_PMU_CNTR_SIZE(model))
-#define CCI_PMU_CNTR_MASK		((1ULL << 32) -1)
-#define CCI_PMU_CNTR_LAST(cci_pmu)	(cci_pmu->num_cntrs - 1)
-
-#define CCI_PMU_MAX_HW_CNTRS(model) \
-	((model)->num_hw_cntrs + (model)->fixed_hw_cntrs)
-
-/* Types of interfaces that can generate events */
-enum {
-	CCI_IF_SLAVE,
-	CCI_IF_MASTER,
-#ifdef CONFIG_ARM_CCI5xx_PMU
-	CCI_IF_GLOBAL,
-#endif
-	CCI_IF_MAX,
-};
-
-struct event_range {
-	u32 min;
-	u32 max;
-};
-
-struct cci_pmu_hw_events {
-	struct perf_event **events;
-	unsigned long *used_mask;
-	raw_spinlock_t pmu_lock;
-};
-
-struct cci_pmu;
-/*
- * struct cci_pmu_model:
- * @fixed_hw_cntrs - Number of fixed event counters
- * @num_hw_cntrs - Maximum number of programmable event counters
- * @cntr_size - Size of an event counter mapping
- */
-struct cci_pmu_model {
-	char *name;
-	u32 fixed_hw_cntrs;
-	u32 num_hw_cntrs;
-	u32 cntr_size;
-	struct attribute **format_attrs;
-	struct attribute **event_attrs;
-	struct event_range event_ranges[CCI_IF_MAX];
-	int (*validate_hw_event)(struct cci_pmu *, unsigned long);
-	int (*get_event_idx)(struct cci_pmu *, struct cci_pmu_hw_events *, unsigned long);
-	void (*write_counters)(struct cci_pmu *, unsigned long *);
-};
-
-static struct cci_pmu_model cci_pmu_models[];
-
-struct cci_pmu {
-	void __iomem *base;
-	struct pmu pmu;
-	int nr_irqs;
-	int *irqs;
-	unsigned long active_irqs;
-	const struct cci_pmu_model *model;
-	struct cci_pmu_hw_events hw_events;
-	struct platform_device *plat_device;
-	int num_cntrs;
-	atomic_t active_events;
-	struct mutex reserve_mutex;
-	struct hlist_node node;
-	cpumask_t cpus;
-};
-
-#define to_cci_pmu(c)	(container_of(c, struct cci_pmu, pmu))
-
-enum cci_models {
-#ifdef CONFIG_ARM_CCI400_PMU
-	CCI400_R0,
-	CCI400_R1,
-#endif
-#ifdef CONFIG_ARM_CCI5xx_PMU
-	CCI500_R0,
-	CCI550_R0,
-#endif
-	CCI_MODEL_MAX
-};
-
-static void pmu_write_counters(struct cci_pmu *cci_pmu,
-				 unsigned long *mask);
-static ssize_t cci_pmu_format_show(struct device *dev,
-			struct device_attribute *attr, char *buf);
-static ssize_t cci_pmu_event_show(struct device *dev,
-			struct device_attribute *attr, char *buf);
-
-#define CCI_EXT_ATTR_ENTRY(_name, _func, _config) 				\
-	&((struct dev_ext_attribute[]) {					\
-		{ __ATTR(_name, S_IRUGO, _func, NULL), (void *)_config }	\
-	})[0].attr.attr
-
-#define CCI_FORMAT_EXT_ATTR_ENTRY(_name, _config) \
-	CCI_EXT_ATTR_ENTRY(_name, cci_pmu_format_show, (char *)_config)
-#define CCI_EVENT_EXT_ATTR_ENTRY(_name, _config) \
-	CCI_EXT_ATTR_ENTRY(_name, cci_pmu_event_show, (unsigned long)_config)
-
-/* CCI400 PMU Specific definitions */
-
-#ifdef CONFIG_ARM_CCI400_PMU
-
-/* Port ids */
-#define CCI400_PORT_S0		0
-#define CCI400_PORT_S1		1
-#define CCI400_PORT_S2		2
-#define CCI400_PORT_S3		3
-#define CCI400_PORT_S4		4
-#define CCI400_PORT_M0		5
-#define CCI400_PORT_M1		6
-#define CCI400_PORT_M2		7
-
-#define CCI400_R1_PX		5
-
-/*
- * Instead of an event id to monitor CCI cycles, a dedicated counter is
- * provided. Use 0xff to represent CCI cycles and hope that no future revisions
- * make use of this event in hardware.
- */
-enum cci400_perf_events {
-	CCI400_PMU_CYCLES = 0xff
-};
-
-#define CCI400_PMU_CYCLE_CNTR_IDX	0
-#define CCI400_PMU_CNTR0_IDX		1
-
-/*
- * CCI PMU event id is an 8-bit value made of two parts - bits 7:5 for one of 8
- * ports and bits 4:0 are event codes. There are different event codes
- * associated with each port type.
- *
- * Additionally, the range of events associated with the port types changed
- * between Rev0 and Rev1.
- *
- * The constants below define the range of valid codes for each port type for
- * the different revisions and are used to validate the event to be monitored.
- */
-
-#define CCI400_PMU_EVENT_MASK		0xffUL
-#define CCI400_PMU_EVENT_SOURCE_SHIFT	5
-#define CCI400_PMU_EVENT_SOURCE_MASK	0x7
-#define CCI400_PMU_EVENT_CODE_SHIFT	0
-#define CCI400_PMU_EVENT_CODE_MASK	0x1f
-#define CCI400_PMU_EVENT_SOURCE(event) \
-	((event >> CCI400_PMU_EVENT_SOURCE_SHIFT) & \
-			CCI400_PMU_EVENT_SOURCE_MASK)
-#define CCI400_PMU_EVENT_CODE(event) \
-	((event >> CCI400_PMU_EVENT_CODE_SHIFT) & CCI400_PMU_EVENT_CODE_MASK)
-
-#define CCI400_R0_SLAVE_PORT_MIN_EV	0x00
-#define CCI400_R0_SLAVE_PORT_MAX_EV	0x13
-#define CCI400_R0_MASTER_PORT_MIN_EV	0x14
-#define CCI400_R0_MASTER_PORT_MAX_EV	0x1a
-
-#define CCI400_R1_SLAVE_PORT_MIN_EV	0x00
-#define CCI400_R1_SLAVE_PORT_MAX_EV	0x14
-#define CCI400_R1_MASTER_PORT_MIN_EV	0x00
-#define CCI400_R1_MASTER_PORT_MAX_EV	0x11
-
-#define CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(_name, _config) \
-	CCI_EXT_ATTR_ENTRY(_name, cci400_pmu_cycle_event_show, \
-					(unsigned long)_config)
-
-static ssize_t cci400_pmu_cycle_event_show(struct device *dev,
-			struct device_attribute *attr, char *buf);
-
-static struct attribute *cci400_pmu_format_attrs[] = {
-	CCI_FORMAT_EXT_ATTR_ENTRY(event, "config:0-4"),
-	CCI_FORMAT_EXT_ATTR_ENTRY(source, "config:5-7"),
-	NULL
-};
-
-static struct attribute *cci400_r0_pmu_event_attrs[] = {
-	/* Slave events */
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_any, 0x0),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_device, 0x01),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_normal_or_nonshareable, 0x2),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_inner_or_outershareable, 0x3),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maintenance, 0x4),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_mem_barrier, 0x5),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_sync_barrier, 0x6),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg_sync, 0x8),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_tt_full, 0x9),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_last_hs_snoop, 0xA),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall_rvalids_h_rready_l, 0xB),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_any, 0xC),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_device, 0xD),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_normal_or_nonshareable, 0xE),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_inner_or_outershare_wback_wclean, 0xF),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_unique, 0x10),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_line_unique, 0x11),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_evict, 0x12),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall_tt_full, 0x13),
-	/* Master events */
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_retry_speculative_fetch, 0x14),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_addr_hazard, 0x15),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_id_hazard, 0x16),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_tt_full, 0x17),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_barrier_hazard, 0x18),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_barrier_hazard, 0x19),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_tt_full, 0x1A),
-	/* Special event for cycles counter */
-	CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(cycles, 0xff),
-	NULL
-};
-
-static struct attribute *cci400_r1_pmu_event_attrs[] = {
-	/* Slave events */
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_any, 0x0),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_device, 0x01),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_normal_or_nonshareable, 0x2),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_inner_or_outershareable, 0x3),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maintenance, 0x4),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_mem_barrier, 0x5),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_sync_barrier, 0x6),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg_sync, 0x8),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_tt_full, 0x9),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_last_hs_snoop, 0xA),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall_rvalids_h_rready_l, 0xB),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_any, 0xC),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_device, 0xD),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_normal_or_nonshareable, 0xE),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_inner_or_outershare_wback_wclean, 0xF),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_unique, 0x10),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_line_unique, 0x11),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_evict, 0x12),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall_tt_full, 0x13),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_slave_id_hazard, 0x14),
-	/* Master events */
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_retry_speculative_fetch, 0x0),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_stall_cycle_addr_hazard, 0x1),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_master_id_hazard, 0x2),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_hi_prio_rtq_full, 0x3),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_barrier_hazard, 0x4),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_barrier_hazard, 0x5),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_wtq_full, 0x6),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_low_prio_rtq_full, 0x7),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_mid_prio_rtq_full, 0x8),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn0, 0x9),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn1, 0xA),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn2, 0xB),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn3, 0xC),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn0, 0xD),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn1, 0xE),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn2, 0xF),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn3, 0x10),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_unique_or_line_unique_addr_hazard, 0x11),
-	/* Special event for cycles counter */
-	CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(cycles, 0xff),
-	NULL
-};
-
-static ssize_t cci400_pmu_cycle_event_show(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	struct dev_ext_attribute *eattr = container_of(attr,
-				struct dev_ext_attribute, attr);
-	return snprintf(buf, PAGE_SIZE, "config=0x%lx\n", (unsigned long)eattr->var);
-}
-
-static int cci400_get_event_idx(struct cci_pmu *cci_pmu,
-				struct cci_pmu_hw_events *hw,
-				unsigned long cci_event)
-{
-	int idx;
-
-	/* cycles event idx is fixed */
-	if (cci_event == CCI400_PMU_CYCLES) {
-		if (test_and_set_bit(CCI400_PMU_CYCLE_CNTR_IDX, hw->used_mask))
-			return -EAGAIN;
-
-		return CCI400_PMU_CYCLE_CNTR_IDX;
-	}
-
-	for (idx = CCI400_PMU_CNTR0_IDX; idx <= CCI_PMU_CNTR_LAST(cci_pmu); ++idx)
-		if (!test_and_set_bit(idx, hw->used_mask))
-			return idx;
-
-	/* No counters available */
-	return -EAGAIN;
-}
-
-static int cci400_validate_hw_event(struct cci_pmu *cci_pmu, unsigned long hw_event)
-{
-	u8 ev_source = CCI400_PMU_EVENT_SOURCE(hw_event);
-	u8 ev_code = CCI400_PMU_EVENT_CODE(hw_event);
-	int if_type;
-
-	if (hw_event & ~CCI400_PMU_EVENT_MASK)
-		return -ENOENT;
-
-	if (hw_event == CCI400_PMU_CYCLES)
-		return hw_event;
-
-	switch (ev_source) {
-	case CCI400_PORT_S0:
-	case CCI400_PORT_S1:
-	case CCI400_PORT_S2:
-	case CCI400_PORT_S3:
-	case CCI400_PORT_S4:
-		/* Slave Interface */
-		if_type = CCI_IF_SLAVE;
-		break;
-	case CCI400_PORT_M0:
-	case CCI400_PORT_M1:
-	case CCI400_PORT_M2:
-		/* Master Interface */
-		if_type = CCI_IF_MASTER;
-		break;
-	default:
-		return -ENOENT;
-	}
-
-	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
-		ev_code <= cci_pmu->model->event_ranges[if_type].max)
-		return hw_event;
-
-	return -ENOENT;
-}
-
-static int probe_cci400_revision(void)
-{
-	int rev;
-	rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK;
-	rev >>= CCI_PID2_REV_SHIFT;
-
-	if (rev < CCI400_R1_PX)
-		return CCI400_R0;
-	else
-		return CCI400_R1;
-}
-
-static const struct cci_pmu_model *probe_cci_model(struct platform_device *pdev)
-{
-	if (platform_has_secure_cci_access())
-		return &cci_pmu_models[probe_cci400_revision()];
-	return NULL;
-}
-#else	/* !CONFIG_ARM_CCI400_PMU */
-static inline struct cci_pmu_model *probe_cci_model(struct platform_device *pdev)
-{
-	return NULL;
-}
-#endif	/* CONFIG_ARM_CCI400_PMU */
-
-#ifdef CONFIG_ARM_CCI5xx_PMU
-
-/*
- * CCI5xx PMU event id is an 9-bit value made of two parts.
- *	 bits [8:5] - Source for the event
- *	 bits [4:0] - Event code (specific to type of interface)
- *
- *
- */
-
-/* Port ids */
-#define CCI5xx_PORT_S0			0x0
-#define CCI5xx_PORT_S1			0x1
-#define CCI5xx_PORT_S2			0x2
-#define CCI5xx_PORT_S3			0x3
-#define CCI5xx_PORT_S4			0x4
-#define CCI5xx_PORT_S5			0x5
-#define CCI5xx_PORT_S6			0x6
-
-#define CCI5xx_PORT_M0			0x8
-#define CCI5xx_PORT_M1			0x9
-#define CCI5xx_PORT_M2			0xa
-#define CCI5xx_PORT_M3			0xb
-#define CCI5xx_PORT_M4			0xc
-#define CCI5xx_PORT_M5			0xd
-#define CCI5xx_PORT_M6			0xe
-
-#define CCI5xx_PORT_GLOBAL		0xf
-
-#define CCI5xx_PMU_EVENT_MASK		0x1ffUL
-#define CCI5xx_PMU_EVENT_SOURCE_SHIFT	0x5
-#define CCI5xx_PMU_EVENT_SOURCE_MASK	0xf
-#define CCI5xx_PMU_EVENT_CODE_SHIFT	0x0
-#define CCI5xx_PMU_EVENT_CODE_MASK	0x1f
-
-#define CCI5xx_PMU_EVENT_SOURCE(event)	\
-	((event >> CCI5xx_PMU_EVENT_SOURCE_SHIFT) & CCI5xx_PMU_EVENT_SOURCE_MASK)
-#define CCI5xx_PMU_EVENT_CODE(event)	\
-	((event >> CCI5xx_PMU_EVENT_CODE_SHIFT) & CCI5xx_PMU_EVENT_CODE_MASK)
-
-#define CCI5xx_SLAVE_PORT_MIN_EV	0x00
-#define CCI5xx_SLAVE_PORT_MAX_EV	0x1f
-#define CCI5xx_MASTER_PORT_MIN_EV	0x00
-#define CCI5xx_MASTER_PORT_MAX_EV	0x06
-#define CCI5xx_GLOBAL_PORT_MIN_EV	0x00
-#define CCI5xx_GLOBAL_PORT_MAX_EV	0x0f
-
-
-#define CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(_name, _config) \
-	CCI_EXT_ATTR_ENTRY(_name, cci5xx_pmu_global_event_show, \
-					(unsigned long) _config)
-
-static ssize_t cci5xx_pmu_global_event_show(struct device *dev,
-				struct device_attribute *attr, char *buf);
-
-static struct attribute *cci5xx_pmu_format_attrs[] = {
-	CCI_FORMAT_EXT_ATTR_ENTRY(event, "config:0-4"),
-	CCI_FORMAT_EXT_ATTR_ENTRY(source, "config:5-8"),
-	NULL,
-};
-
-static struct attribute *cci5xx_pmu_event_attrs[] = {
-	/* Slave events */
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_arvalid, 0x0),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_dev, 0x1),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_nonshareable, 0x2),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_shareable_non_alloc, 0x3),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_shareable_alloc, 0x4),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_invalidate, 0x5),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maint, 0x6),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_rval, 0x8),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_rlast_snoop, 0x9),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_awalid, 0xA),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_dev, 0xB),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_non_shareable, 0xC),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wb, 0xD),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wlu, 0xE),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wunique, 0xF),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_evict, 0x10),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_wrevict, 0x11),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_w_data_beat, 0x12),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_acvalid, 0x13),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_read, 0x14),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_clean, 0x15),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_data_transfer_low, 0x16),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_arvalid, 0x17),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall, 0x18),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall, 0x19),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_w_data_stall, 0x1A),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_w_resp_stall, 0x1B),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_stall, 0x1C),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_s_data_stall, 0x1D),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_rq_stall_ot_limit, 0x1E),
-	CCI_EVENT_EXT_ATTR_ENTRY(si_r_stall_arbit, 0x1F),
-
-	/* Master events */
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_r_data_beat_any, 0x0),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_data_beat_any, 0x1),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall, 0x2),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_r_data_stall, 0x3),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall, 0x4),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_data_stall, 0x5),
-	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_resp_stall, 0x6),
-
-	/* Global events */
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_0_1, 0x0),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_2_3, 0x1),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_4_5, 0x2),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_6_7, 0x3),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_0_1, 0x4),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_2_3, 0x5),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_4_5, 0x6),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_6_7, 0x7),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_back_invalidation, 0x8),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_alloc_busy, 0x9),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_tt_full, 0xA),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_wrq, 0xB),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_cd_hs, 0xC),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_rq_stall_addr_hazard, 0xD),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_stall_tt_full, 0xE),
-	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_tzmp1_prot, 0xF),
-	NULL
-};
-
-static ssize_t cci5xx_pmu_global_event_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct dev_ext_attribute *eattr = container_of(attr,
-					struct dev_ext_attribute, attr);
-	/* Global events have single fixed source code */
-	return snprintf(buf, PAGE_SIZE, "event=0x%lx,source=0x%x\n",
-				(unsigned long)eattr->var, CCI5xx_PORT_GLOBAL);
-}
-
-/*
- * CCI500 provides 8 independent event counters that can count
- * any of the events available.
- * CCI500 PMU event source ids
- *	0x0-0x6 - Slave interfaces
- *	0x8-0xD - Master interfaces
- *	0xf     - Global Events
- *	0x7,0xe - Reserved
- */
-static int cci500_validate_hw_event(struct cci_pmu *cci_pmu,
-					unsigned long hw_event)
-{
-	u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event);
-	u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event);
-	int if_type;
-
-	if (hw_event & ~CCI5xx_PMU_EVENT_MASK)
-		return -ENOENT;
-
-	switch (ev_source) {
-	case CCI5xx_PORT_S0:
-	case CCI5xx_PORT_S1:
-	case CCI5xx_PORT_S2:
-	case CCI5xx_PORT_S3:
-	case CCI5xx_PORT_S4:
-	case CCI5xx_PORT_S5:
-	case CCI5xx_PORT_S6:
-		if_type = CCI_IF_SLAVE;
-		break;
-	case CCI5xx_PORT_M0:
-	case CCI5xx_PORT_M1:
-	case CCI5xx_PORT_M2:
-	case CCI5xx_PORT_M3:
-	case CCI5xx_PORT_M4:
-	case CCI5xx_PORT_M5:
-		if_type = CCI_IF_MASTER;
-		break;
-	case CCI5xx_PORT_GLOBAL:
-		if_type = CCI_IF_GLOBAL;
-		break;
-	default:
-		return -ENOENT;
-	}
-
-	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
-		ev_code <= cci_pmu->model->event_ranges[if_type].max)
-		return hw_event;
-
-	return -ENOENT;
-}
-
-/*
- * CCI550 provides 8 independent event counters that can count
- * any of the events available.
- * CCI550 PMU event source ids
- *	0x0-0x6 - Slave interfaces
- *	0x8-0xe - Master interfaces
- *	0xf     - Global Events
- *	0x7	- Reserved
- */
-static int cci550_validate_hw_event(struct cci_pmu *cci_pmu,
-					unsigned long hw_event)
-{
-	u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event);
-	u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event);
-	int if_type;
-
-	if (hw_event & ~CCI5xx_PMU_EVENT_MASK)
-		return -ENOENT;
-
-	switch (ev_source) {
-	case CCI5xx_PORT_S0:
-	case CCI5xx_PORT_S1:
-	case CCI5xx_PORT_S2:
-	case CCI5xx_PORT_S3:
-	case CCI5xx_PORT_S4:
-	case CCI5xx_PORT_S5:
-	case CCI5xx_PORT_S6:
-		if_type = CCI_IF_SLAVE;
-		break;
-	case CCI5xx_PORT_M0:
-	case CCI5xx_PORT_M1:
-	case CCI5xx_PORT_M2:
-	case CCI5xx_PORT_M3:
-	case CCI5xx_PORT_M4:
-	case CCI5xx_PORT_M5:
-	case CCI5xx_PORT_M6:
-		if_type = CCI_IF_MASTER;
-		break;
-	case CCI5xx_PORT_GLOBAL:
-		if_type = CCI_IF_GLOBAL;
-		break;
-	default:
-		return -ENOENT;
-	}
-
-	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
-		ev_code <= cci_pmu->model->event_ranges[if_type].max)
-		return hw_event;
-
-	return -ENOENT;
-}
-
-#endif	/* CONFIG_ARM_CCI5xx_PMU */
-
-/*
- * Program the CCI PMU counters which have PERF_HES_ARCH set
- * with the event period and mark them ready before we enable
- * PMU.
- */
-static void cci_pmu_sync_counters(struct cci_pmu *cci_pmu)
-{
-	int i;
-	struct cci_pmu_hw_events *cci_hw = &cci_pmu->hw_events;
-
-	DECLARE_BITMAP(mask, cci_pmu->num_cntrs);
-
-	bitmap_zero(mask, cci_pmu->num_cntrs);
-	for_each_set_bit(i, cci_pmu->hw_events.used_mask, cci_pmu->num_cntrs) {
-		struct perf_event *event = cci_hw->events[i];
-
-		if (WARN_ON(!event))
-			continue;
-
-		/* Leave the events which are not counting */
-		if (event->hw.state & PERF_HES_STOPPED)
-			continue;
-		if (event->hw.state & PERF_HES_ARCH) {
-			set_bit(i, mask);
-			event->hw.state &= ~PERF_HES_ARCH;
-		}
-	}
-
-	pmu_write_counters(cci_pmu, mask);
-}
-
-/* Should be called with cci_pmu->hw_events->pmu_lock held */
-static void __cci_pmu_enable_nosync(struct cci_pmu *cci_pmu)
-{
-	u32 val;
-
-	/* Enable all the PMU counters. */
-	val = readl_relaxed(cci_ctrl_base + CCI_PMCR) | CCI_PMCR_CEN;
-	writel(val, cci_ctrl_base + CCI_PMCR);
-}
-
-/* Should be called with cci_pmu->hw_events->pmu_lock held */
-static void __cci_pmu_enable_sync(struct cci_pmu *cci_pmu)
-{
-	cci_pmu_sync_counters(cci_pmu);
-	__cci_pmu_enable_nosync(cci_pmu);
-}
-
-/* Should be called with cci_pmu->hw_events->pmu_lock held */
-static void __cci_pmu_disable(void)
-{
-	u32 val;
-
-	/* Disable all the PMU counters. */
-	val = readl_relaxed(cci_ctrl_base + CCI_PMCR) & ~CCI_PMCR_CEN;
-	writel(val, cci_ctrl_base + CCI_PMCR);
-}
-
-static ssize_t cci_pmu_format_show(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	struct dev_ext_attribute *eattr = container_of(attr,
-				struct dev_ext_attribute, attr);
-	return snprintf(buf, PAGE_SIZE, "%s\n", (char *)eattr->var);
-}
-
-static ssize_t cci_pmu_event_show(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	struct dev_ext_attribute *eattr = container_of(attr,
-				struct dev_ext_attribute, attr);
-	/* source parameter is mandatory for normal PMU events */
-	return snprintf(buf, PAGE_SIZE, "source=?,event=0x%lx\n",
-					 (unsigned long)eattr->var);
-}
-
-static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
-{
-	return 0 <= idx && idx <= CCI_PMU_CNTR_LAST(cci_pmu);
-}
-
-static u32 pmu_read_register(struct cci_pmu *cci_pmu, int idx, unsigned int offset)
-{
-	return readl_relaxed(cci_pmu->base +
-			     CCI_PMU_CNTR_BASE(cci_pmu->model, idx) + offset);
-}
-
-static void pmu_write_register(struct cci_pmu *cci_pmu, u32 value,
-			       int idx, unsigned int offset)
-{
-	writel_relaxed(value, cci_pmu->base +
-		       CCI_PMU_CNTR_BASE(cci_pmu->model, idx) + offset);
-}
-
-static void pmu_disable_counter(struct cci_pmu *cci_pmu, int idx)
-{
-	pmu_write_register(cci_pmu, 0, idx, CCI_PMU_CNTR_CTRL);
-}
-
-static void pmu_enable_counter(struct cci_pmu *cci_pmu, int idx)
-{
-	pmu_write_register(cci_pmu, 1, idx, CCI_PMU_CNTR_CTRL);
-}
-
-static bool __maybe_unused
-pmu_counter_is_enabled(struct cci_pmu *cci_pmu, int idx)
-{
-	return (pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR_CTRL) & 0x1) != 0;
-}
-
-static void pmu_set_event(struct cci_pmu *cci_pmu, int idx, unsigned long event)
-{
-	pmu_write_register(cci_pmu, event, idx, CCI_PMU_EVT_SEL);
-}
-
-/*
- * For all counters on the CCI-PMU, disable any 'enabled' counters,
- * saving the changed counters in the mask, so that we can restore
- * it later using pmu_restore_counters. The mask is private to the
- * caller. We cannot rely on the used_mask maintained by the CCI_PMU
- * as it only tells us if the counter is assigned to perf_event or not.
- * The state of the perf_event cannot be locked by the PMU layer, hence
- * we check the individual counter status (which can be locked by
- * cci_pm->hw_events->pmu_lock).
- *
- * @mask should be initialised to empty by the caller.
- */
-static void __maybe_unused
-pmu_save_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
-{
-	int i;
-
-	for (i = 0; i < cci_pmu->num_cntrs; i++) {
-		if (pmu_counter_is_enabled(cci_pmu, i)) {
-			set_bit(i, mask);
-			pmu_disable_counter(cci_pmu, i);
-		}
-	}
-}
-
-/*
- * Restore the status of the counters. Reversal of the pmu_save_counters().
- * For each counter set in the mask, enable the counter back.
- */
-static void __maybe_unused
-pmu_restore_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
-{
-	int i;
-
-	for_each_set_bit(i, mask, cci_pmu->num_cntrs)
-		pmu_enable_counter(cci_pmu, i);
-}
-
-/*
- * Returns the number of programmable counters actually implemented
- * by the cci
- */
-static u32 pmu_get_max_counters(void)
-{
-	return (readl_relaxed(cci_ctrl_base + CCI_PMCR) &
-		CCI_PMCR_NCNT_MASK) >> CCI_PMCR_NCNT_SHIFT;
-}
-
-static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, struct perf_event *event)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	unsigned long cci_event = event->hw.config_base;
-	int idx;
-
-	if (cci_pmu->model->get_event_idx)
-		return cci_pmu->model->get_event_idx(cci_pmu, hw, cci_event);
-
-	/* Generic code to find an unused idx from the mask */
-	for(idx = 0; idx <= CCI_PMU_CNTR_LAST(cci_pmu); idx++)
-		if (!test_and_set_bit(idx, hw->used_mask))
-			return idx;
-
-	/* No counters available */
-	return -EAGAIN;
-}
-
-static int pmu_map_event(struct perf_event *event)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-
-	if (event->attr.type < PERF_TYPE_MAX ||
-			!cci_pmu->model->validate_hw_event)
-		return -ENOENT;
-
-	return	cci_pmu->model->validate_hw_event(cci_pmu, event->attr.config);
-}
-
-static int pmu_request_irq(struct cci_pmu *cci_pmu, irq_handler_t handler)
-{
-	int i;
-	struct platform_device *pmu_device = cci_pmu->plat_device;
-
-	if (unlikely(!pmu_device))
-		return -ENODEV;
-
-	if (cci_pmu->nr_irqs < 1) {
-		dev_err(&pmu_device->dev, "no irqs for CCI PMUs defined\n");
-		return -ENODEV;
-	}
-
-	/*
-	 * Register all available CCI PMU interrupts. In the interrupt handler
-	 * we iterate over the counters checking for interrupt source (the
-	 * overflowing counter) and clear it.
-	 *
-	 * This should allow handling of non-unique interrupt for the counters.
-	 */
-	for (i = 0; i < cci_pmu->nr_irqs; i++) {
-		int err = request_irq(cci_pmu->irqs[i], handler, IRQF_SHARED,
-				"arm-cci-pmu", cci_pmu);
-		if (err) {
-			dev_err(&pmu_device->dev, "unable to request IRQ%d for ARM CCI PMU counters\n",
-				cci_pmu->irqs[i]);
-			return err;
-		}
-
-		set_bit(i, &cci_pmu->active_irqs);
-	}
-
-	return 0;
-}
-
-static void pmu_free_irq(struct cci_pmu *cci_pmu)
-{
-	int i;
-
-	for (i = 0; i < cci_pmu->nr_irqs; i++) {
-		if (!test_and_clear_bit(i, &cci_pmu->active_irqs))
-			continue;
-
-		free_irq(cci_pmu->irqs[i], cci_pmu);
-	}
-}
-
-static u32 pmu_read_counter(struct perf_event *event)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	struct hw_perf_event *hw_counter = &event->hw;
-	int idx = hw_counter->idx;
-	u32 value;
-
-	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
-		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
-		return 0;
-	}
-	value = pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR);
-
-	return value;
-}
-
-static void pmu_write_counter(struct cci_pmu *cci_pmu, u32 value, int idx)
-{
-	pmu_write_register(cci_pmu, value, idx, CCI_PMU_CNTR);
-}
-
-static void __pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
-{
-	int i;
-	struct cci_pmu_hw_events *cci_hw = &cci_pmu->hw_events;
-
-	for_each_set_bit(i, mask, cci_pmu->num_cntrs) {
-		struct perf_event *event = cci_hw->events[i];
-
-		if (WARN_ON(!event))
-			continue;
-		pmu_write_counter(cci_pmu, local64_read(&event->hw.prev_count), i);
-	}
-}
-
-static void pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
-{
-	if (cci_pmu->model->write_counters)
-		cci_pmu->model->write_counters(cci_pmu, mask);
-	else
-		__pmu_write_counters(cci_pmu, mask);
-}
-
-#ifdef CONFIG_ARM_CCI5xx_PMU
-
-/*
- * CCI-500/CCI-550 has advanced power saving policies, which could gate the
- * clocks to the PMU counters, which makes the writes to them ineffective.
- * The only way to write to those counters is when the global counters
- * are enabled and the particular counter is enabled.
- *
- * So we do the following :
- *
- * 1) Disable all the PMU counters, saving their current state
- * 2) Enable the global PMU profiling, now that all counters are
- *    disabled.
- *
- * For each counter to be programmed, repeat steps 3-7:
- *
- * 3) Write an invalid event code to the event control register for the
-      counter, so that the counters are not modified.
- * 4) Enable the counter control for the counter.
- * 5) Set the counter value
- * 6) Disable the counter
- * 7) Restore the event in the target counter
- *
- * 8) Disable the global PMU.
- * 9) Restore the status of the rest of the counters.
- *
- * We choose an event which for CCI-5xx is guaranteed not to count.
- * We use the highest possible event code (0x1f) for the master interface 0.
- */
-#define CCI5xx_INVALID_EVENT	((CCI5xx_PORT_M0 << CCI5xx_PMU_EVENT_SOURCE_SHIFT) | \
-				 (CCI5xx_PMU_EVENT_CODE_MASK << CCI5xx_PMU_EVENT_CODE_SHIFT))
-static void cci5xx_pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
-{
-	int i;
-	DECLARE_BITMAP(saved_mask, cci_pmu->num_cntrs);
-
-	bitmap_zero(saved_mask, cci_pmu->num_cntrs);
-	pmu_save_counters(cci_pmu, saved_mask);
-
-	/*
-	 * Now that all the counters are disabled, we can safely turn the PMU on,
-	 * without syncing the status of the counters
-	 */
-	__cci_pmu_enable_nosync(cci_pmu);
-
-	for_each_set_bit(i, mask, cci_pmu->num_cntrs) {
-		struct perf_event *event = cci_pmu->hw_events.events[i];
-
-		if (WARN_ON(!event))
-			continue;
-
-		pmu_set_event(cci_pmu, i, CCI5xx_INVALID_EVENT);
-		pmu_enable_counter(cci_pmu, i);
-		pmu_write_counter(cci_pmu, local64_read(&event->hw.prev_count), i);
-		pmu_disable_counter(cci_pmu, i);
-		pmu_set_event(cci_pmu, i, event->hw.config_base);
-	}
-
-	__cci_pmu_disable();
-
-	pmu_restore_counters(cci_pmu, saved_mask);
-}
-
-#endif	/* CONFIG_ARM_CCI5xx_PMU */
-
-static u64 pmu_event_update(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 delta, prev_raw_count, new_raw_count;
-
-	do {
-		prev_raw_count = local64_read(&hwc->prev_count);
-		new_raw_count = pmu_read_counter(event);
-	} while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
-		 new_raw_count) != prev_raw_count);
-
-	delta = (new_raw_count - prev_raw_count) & CCI_PMU_CNTR_MASK;
-
-	local64_add(delta, &event->count);
-
-	return new_raw_count;
-}
-
-static void pmu_read(struct perf_event *event)
-{
-	pmu_event_update(event);
-}
-
-static void pmu_event_set_period(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	/*
-	 * The CCI PMU counters have a period of 2^32. To account for the
-	 * possiblity of extreme interrupt latency we program for a period of
-	 * half that. Hopefully we can handle the interrupt before another 2^31
-	 * events occur and the counter overtakes its previous value.
-	 */
-	u64 val = 1ULL << 31;
-	local64_set(&hwc->prev_count, val);
-
-	/*
-	 * CCI PMU uses PERF_HES_ARCH to keep track of the counters, whose
-	 * values needs to be sync-ed with the s/w state before the PMU is
-	 * enabled.
-	 * Mark this counter for sync.
-	 */
-	hwc->state |= PERF_HES_ARCH;
-}
-
-static irqreturn_t pmu_handle_irq(int irq_num, void *dev)
-{
-	unsigned long flags;
-	struct cci_pmu *cci_pmu = dev;
-	struct cci_pmu_hw_events *events = &cci_pmu->hw_events;
-	int idx, handled = IRQ_NONE;
-
-	raw_spin_lock_irqsave(&events->pmu_lock, flags);
-
-	/* Disable the PMU while we walk through the counters */
-	__cci_pmu_disable();
-	/*
-	 * Iterate over counters and update the corresponding perf events.
-	 * This should work regardless of whether we have per-counter overflow
-	 * interrupt or a combined overflow interrupt.
-	 */
-	for (idx = 0; idx <= CCI_PMU_CNTR_LAST(cci_pmu); idx++) {
-		struct perf_event *event = events->events[idx];
-
-		if (!event)
-			continue;
-
-		/* Did this counter overflow? */
-		if (!(pmu_read_register(cci_pmu, idx, CCI_PMU_OVRFLW) &
-		      CCI_PMU_OVRFLW_FLAG))
-			continue;
-
-		pmu_write_register(cci_pmu, CCI_PMU_OVRFLW_FLAG, idx,
-							CCI_PMU_OVRFLW);
-
-		pmu_event_update(event);
-		pmu_event_set_period(event);
-		handled = IRQ_HANDLED;
-	}
-
-	/* Enable the PMU and sync possibly overflowed counters */
-	__cci_pmu_enable_sync(cci_pmu);
-	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
-
-	return IRQ_RETVAL(handled);
-}
-
-static int cci_pmu_get_hw(struct cci_pmu *cci_pmu)
-{
-	int ret = pmu_request_irq(cci_pmu, pmu_handle_irq);
-	if (ret) {
-		pmu_free_irq(cci_pmu);
-		return ret;
-	}
-	return 0;
-}
-
-static void cci_pmu_put_hw(struct cci_pmu *cci_pmu)
-{
-	pmu_free_irq(cci_pmu);
-}
-
-static void hw_perf_event_destroy(struct perf_event *event)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	atomic_t *active_events = &cci_pmu->active_events;
-	struct mutex *reserve_mutex = &cci_pmu->reserve_mutex;
-
-	if (atomic_dec_and_mutex_lock(active_events, reserve_mutex)) {
-		cci_pmu_put_hw(cci_pmu);
-		mutex_unlock(reserve_mutex);
-	}
-}
-
-static void cci_pmu_enable(struct pmu *pmu)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
-	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
-	int enabled = bitmap_weight(hw_events->used_mask, cci_pmu->num_cntrs);
-	unsigned long flags;
-
-	if (!enabled)
-		return;
-
-	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
-	__cci_pmu_enable_sync(cci_pmu);
-	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
-
-}
-
-static void cci_pmu_disable(struct pmu *pmu)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
-	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
-	__cci_pmu_disable();
-	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
-}
-
-/*
- * Check if the idx represents a non-programmable counter.
- * All the fixed event counters are mapped before the programmable
- * counters.
- */
-static bool pmu_fixed_hw_idx(struct cci_pmu *cci_pmu, int idx)
-{
-	return (idx >= 0) && (idx < cci_pmu->model->fixed_hw_cntrs);
-}
-
-static void cci_pmu_start(struct perf_event *event, int pmu_flags)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
-	struct hw_perf_event *hwc = &event->hw;
-	int idx = hwc->idx;
-	unsigned long flags;
-
-	/*
-	 * To handle interrupt latency, we always reprogram the period
-	 * regardlesss of PERF_EF_RELOAD.
-	 */
-	if (pmu_flags & PERF_EF_RELOAD)
-		WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
-
-	hwc->state = 0;
-
-	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
-		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
-		return;
-	}
-
-	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
-
-	/* Configure the counter unless you are counting a fixed event */
-	if (!pmu_fixed_hw_idx(cci_pmu, idx))
-		pmu_set_event(cci_pmu, idx, hwc->config_base);
-
-	pmu_event_set_period(event);
-	pmu_enable_counter(cci_pmu, idx);
-
-	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
-}
-
-static void cci_pmu_stop(struct perf_event *event, int pmu_flags)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	struct hw_perf_event *hwc = &event->hw;
-	int idx = hwc->idx;
-
-	if (hwc->state & PERF_HES_STOPPED)
-		return;
-
-	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
-		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
-		return;
-	}
-
-	/*
-	 * We always reprogram the counter, so ignore PERF_EF_UPDATE. See
-	 * cci_pmu_start()
-	 */
-	pmu_disable_counter(cci_pmu, idx);
-	pmu_event_update(event);
-	hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
-}
-
-static int cci_pmu_add(struct perf_event *event, int flags)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
-	struct hw_perf_event *hwc = &event->hw;
-	int idx;
-	int err = 0;
-
-	perf_pmu_disable(event->pmu);
-
-	/* If we don't have a space for the counter then finish early. */
-	idx = pmu_get_event_idx(hw_events, event);
-	if (idx < 0) {
-		err = idx;
-		goto out;
-	}
-
-	event->hw.idx = idx;
-	hw_events->events[idx] = event;
-
-	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
-	if (flags & PERF_EF_START)
-		cci_pmu_start(event, PERF_EF_RELOAD);
-
-	/* Propagate our changes to the userspace mapping. */
-	perf_event_update_userpage(event);
-
-out:
-	perf_pmu_enable(event->pmu);
-	return err;
-}
-
-static void cci_pmu_del(struct perf_event *event, int flags)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
-	struct hw_perf_event *hwc = &event->hw;
-	int idx = hwc->idx;
-
-	cci_pmu_stop(event, PERF_EF_UPDATE);
-	hw_events->events[idx] = NULL;
-	clear_bit(idx, hw_events->used_mask);
-
-	perf_event_update_userpage(event);
-}
-
-static int
-validate_event(struct pmu *cci_pmu,
-               struct cci_pmu_hw_events *hw_events,
-               struct perf_event *event)
-{
-	if (is_software_event(event))
-		return 1;
-
-	/*
-	 * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
-	 * core perf code won't check that the pmu->ctx == leader->ctx
-	 * until after pmu->event_init(event).
-	 */
-	if (event->pmu != cci_pmu)
-		return 0;
-
-	if (event->state < PERF_EVENT_STATE_OFF)
-		return 1;
-
-	if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
-		return 1;
-
-	return pmu_get_event_idx(hw_events, event) >= 0;
-}
-
-static int
-validate_group(struct perf_event *event)
-{
-	struct perf_event *sibling, *leader = event->group_leader;
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	unsigned long mask[BITS_TO_LONGS(cci_pmu->num_cntrs)];
-	struct cci_pmu_hw_events fake_pmu = {
-		/*
-		 * Initialise the fake PMU. We only need to populate the
-		 * used_mask for the purposes of validation.
-		 */
-		.used_mask = mask,
-	};
-	memset(mask, 0, BITS_TO_LONGS(cci_pmu->num_cntrs) * sizeof(unsigned long));
-
-	if (!validate_event(event->pmu, &fake_pmu, leader))
-		return -EINVAL;
-
-	for_each_sibling_event(sibling, leader) {
-		if (!validate_event(event->pmu, &fake_pmu, sibling))
-			return -EINVAL;
-	}
-
-	if (!validate_event(event->pmu, &fake_pmu, event))
-		return -EINVAL;
-
-	return 0;
-}
-
-static int
-__hw_perf_event_init(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	int mapping;
-
-	mapping = pmu_map_event(event);
-
-	if (mapping < 0) {
-		pr_debug("event %x:%llx not supported\n", event->attr.type,
-			 event->attr.config);
-		return mapping;
-	}
-
-	/*
-	 * We don't assign an index until we actually place the event onto
-	 * hardware. Use -1 to signify that we haven't decided where to put it
-	 * yet.
-	 */
-	hwc->idx		= -1;
-	hwc->config_base	= 0;
-	hwc->config		= 0;
-	hwc->event_base		= 0;
-
-	/*
-	 * Store the event encoding into the config_base field.
-	 */
-	hwc->config_base	    |= (unsigned long)mapping;
-
-	/*
-	 * Limit the sample_period to half of the counter width. That way, the
-	 * new counter value is far less likely to overtake the previous one
-	 * unless you have some serious IRQ latency issues.
-	 */
-	hwc->sample_period  = CCI_PMU_CNTR_MASK >> 1;
-	hwc->last_period    = hwc->sample_period;
-	local64_set(&hwc->period_left, hwc->sample_period);
-
-	if (event->group_leader != event) {
-		if (validate_group(event) != 0)
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int cci_pmu_event_init(struct perf_event *event)
-{
-	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
-	atomic_t *active_events = &cci_pmu->active_events;
-	int err = 0;
-	int cpu;
-
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	/* Shared by all CPUs, no meaningful state to sample */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
-	/* We have no filtering of any kind */
-	if (event->attr.exclude_user	||
-	    event->attr.exclude_kernel	||
-	    event->attr.exclude_hv	||
-	    event->attr.exclude_idle	||
-	    event->attr.exclude_host	||
-	    event->attr.exclude_guest)
-		return -EINVAL;
-
-	/*
-	 * Following the example set by other "uncore" PMUs, we accept any CPU
-	 * and rewrite its affinity dynamically rather than having perf core
-	 * handle cpu == -1 and pid == -1 for this case.
-	 *
-	 * The perf core will pin online CPUs for the duration of this call and
-	 * the event being installed into its context, so the PMU's CPU can't
-	 * change under our feet.
-	 */
-	cpu = cpumask_first(&cci_pmu->cpus);
-	if (event->cpu < 0 || cpu < 0)
-		return -EINVAL;
-	event->cpu = cpu;
-
-	event->destroy = hw_perf_event_destroy;
-	if (!atomic_inc_not_zero(active_events)) {
-		mutex_lock(&cci_pmu->reserve_mutex);
-		if (atomic_read(active_events) == 0)
-			err = cci_pmu_get_hw(cci_pmu);
-		if (!err)
-			atomic_inc(active_events);
-		mutex_unlock(&cci_pmu->reserve_mutex);
-	}
-	if (err)
-		return err;
-
-	err = __hw_perf_event_init(event);
-	if (err)
-		hw_perf_event_destroy(event);
-
-	return err;
-}
-
-static ssize_t pmu_cpumask_attr_show(struct device *dev,
-				     struct device_attribute *attr, char *buf)
-{
-	struct pmu *pmu = dev_get_drvdata(dev);
-	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
-
-	int n = scnprintf(buf, PAGE_SIZE - 1, "%*pbl",
-			  cpumask_pr_args(&cci_pmu->cpus));
-	buf[n++] = '\n';
-	buf[n] = '\0';
-	return n;
-}
-
-static struct device_attribute pmu_cpumask_attr =
-	__ATTR(cpumask, S_IRUGO, pmu_cpumask_attr_show, NULL);
-
-static struct attribute *pmu_attrs[] = {
-	&pmu_cpumask_attr.attr,
-	NULL,
-};
-
-static struct attribute_group pmu_attr_group = {
-	.attrs = pmu_attrs,
-};
-
-static struct attribute_group pmu_format_attr_group = {
-	.name = "format",
-	.attrs = NULL,		/* Filled in cci_pmu_init_attrs */
-};
-
-static struct attribute_group pmu_event_attr_group = {
-	.name = "events",
-	.attrs = NULL,		/* Filled in cci_pmu_init_attrs */
-};
-
-static const struct attribute_group *pmu_attr_groups[] = {
-	&pmu_attr_group,
-	&pmu_format_attr_group,
-	&pmu_event_attr_group,
-	NULL
-};
-
-static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
-{
-	const struct cci_pmu_model *model = cci_pmu->model;
-	char *name = model->name;
-	u32 num_cntrs;
-
-	pmu_event_attr_group.attrs = model->event_attrs;
-	pmu_format_attr_group.attrs = model->format_attrs;
-
-	cci_pmu->pmu = (struct pmu) {
-		.name		= cci_pmu->model->name,
-		.task_ctx_nr	= perf_invalid_context,
-		.pmu_enable	= cci_pmu_enable,
-		.pmu_disable	= cci_pmu_disable,
-		.event_init	= cci_pmu_event_init,
-		.add		= cci_pmu_add,
-		.del		= cci_pmu_del,
-		.start		= cci_pmu_start,
-		.stop		= cci_pmu_stop,
-		.read		= pmu_read,
-		.attr_groups	= pmu_attr_groups,
-	};
-
-	cci_pmu->plat_device = pdev;
-	num_cntrs = pmu_get_max_counters();
-	if (num_cntrs > cci_pmu->model->num_hw_cntrs) {
-		dev_warn(&pdev->dev,
-			"PMU implements more counters(%d) than supported by"
-			" the model(%d), truncated.",
-			num_cntrs, cci_pmu->model->num_hw_cntrs);
-		num_cntrs = cci_pmu->model->num_hw_cntrs;
-	}
-	cci_pmu->num_cntrs = num_cntrs + cci_pmu->model->fixed_hw_cntrs;
-
-	return perf_pmu_register(&cci_pmu->pmu, name, -1);
-}
-
-static int cci_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
-{
-	struct cci_pmu *cci_pmu = hlist_entry_safe(node, struct cci_pmu, node);
-	unsigned int target;
-
-	if (!cpumask_test_and_clear_cpu(cpu, &cci_pmu->cpus))
-		return 0;
-	target = cpumask_any_but(cpu_online_mask, cpu);
-	if (target >= nr_cpu_ids)
-		return 0;
-	/*
-	 * TODO: migrate context once core races on event->ctx have
-	 * been fixed.
-	 */
-	cpumask_set_cpu(target, &cci_pmu->cpus);
-	return 0;
-}
-
-static struct cci_pmu_model cci_pmu_models[] = {
-#ifdef CONFIG_ARM_CCI400_PMU
-	[CCI400_R0] = {
-		.name = "CCI_400",
-		.fixed_hw_cntrs = 1,	/* Cycle counter */
-		.num_hw_cntrs = 4,
-		.cntr_size = SZ_4K,
-		.format_attrs = cci400_pmu_format_attrs,
-		.event_attrs = cci400_r0_pmu_event_attrs,
-		.event_ranges = {
-			[CCI_IF_SLAVE] = {
-				CCI400_R0_SLAVE_PORT_MIN_EV,
-				CCI400_R0_SLAVE_PORT_MAX_EV,
-			},
-			[CCI_IF_MASTER] = {
-				CCI400_R0_MASTER_PORT_MIN_EV,
-				CCI400_R0_MASTER_PORT_MAX_EV,
-			},
-		},
-		.validate_hw_event = cci400_validate_hw_event,
-		.get_event_idx = cci400_get_event_idx,
-	},
-	[CCI400_R1] = {
-		.name = "CCI_400_r1",
-		.fixed_hw_cntrs = 1,	/* Cycle counter */
-		.num_hw_cntrs = 4,
-		.cntr_size = SZ_4K,
-		.format_attrs = cci400_pmu_format_attrs,
-		.event_attrs = cci400_r1_pmu_event_attrs,
-		.event_ranges = {
-			[CCI_IF_SLAVE] = {
-				CCI400_R1_SLAVE_PORT_MIN_EV,
-				CCI400_R1_SLAVE_PORT_MAX_EV,
-			},
-			[CCI_IF_MASTER] = {
-				CCI400_R1_MASTER_PORT_MIN_EV,
-				CCI400_R1_MASTER_PORT_MAX_EV,
-			},
-		},
-		.validate_hw_event = cci400_validate_hw_event,
-		.get_event_idx = cci400_get_event_idx,
-	},
-#endif
-#ifdef CONFIG_ARM_CCI5xx_PMU
-	[CCI500_R0] = {
-		.name = "CCI_500",
-		.fixed_hw_cntrs = 0,
-		.num_hw_cntrs = 8,
-		.cntr_size = SZ_64K,
-		.format_attrs = cci5xx_pmu_format_attrs,
-		.event_attrs = cci5xx_pmu_event_attrs,
-		.event_ranges = {
-			[CCI_IF_SLAVE] = {
-				CCI5xx_SLAVE_PORT_MIN_EV,
-				CCI5xx_SLAVE_PORT_MAX_EV,
-			},
-			[CCI_IF_MASTER] = {
-				CCI5xx_MASTER_PORT_MIN_EV,
-				CCI5xx_MASTER_PORT_MAX_EV,
-			},
-			[CCI_IF_GLOBAL] = {
-				CCI5xx_GLOBAL_PORT_MIN_EV,
-				CCI5xx_GLOBAL_PORT_MAX_EV,
-			},
-		},
-		.validate_hw_event = cci500_validate_hw_event,
-		.write_counters	= cci5xx_pmu_write_counters,
-	},
-	[CCI550_R0] = {
-		.name = "CCI_550",
-		.fixed_hw_cntrs = 0,
-		.num_hw_cntrs = 8,
-		.cntr_size = SZ_64K,
-		.format_attrs = cci5xx_pmu_format_attrs,
-		.event_attrs = cci5xx_pmu_event_attrs,
-		.event_ranges = {
-			[CCI_IF_SLAVE] = {
-				CCI5xx_SLAVE_PORT_MIN_EV,
-				CCI5xx_SLAVE_PORT_MAX_EV,
-			},
-			[CCI_IF_MASTER] = {
-				CCI5xx_MASTER_PORT_MIN_EV,
-				CCI5xx_MASTER_PORT_MAX_EV,
-			},
-			[CCI_IF_GLOBAL] = {
-				CCI5xx_GLOBAL_PORT_MIN_EV,
-				CCI5xx_GLOBAL_PORT_MAX_EV,
-			},
-		},
-		.validate_hw_event = cci550_validate_hw_event,
-		.write_counters	= cci5xx_pmu_write_counters,
-	},
-#endif
-};
-
-static const struct of_device_id arm_cci_pmu_matches[] = {
-#ifdef CONFIG_ARM_CCI400_PMU
-	{
-		.compatible = "arm,cci-400-pmu",
-		.data	= NULL,
-	},
-	{
-		.compatible = "arm,cci-400-pmu,r0",
-		.data	= &cci_pmu_models[CCI400_R0],
-	},
-	{
-		.compatible = "arm,cci-400-pmu,r1",
-		.data	= &cci_pmu_models[CCI400_R1],
-	},
-#endif
-#ifdef CONFIG_ARM_CCI5xx_PMU
-	{
-		.compatible = "arm,cci-500-pmu,r0",
-		.data = &cci_pmu_models[CCI500_R0],
-	},
-	{
-		.compatible = "arm,cci-550-pmu,r0",
-		.data = &cci_pmu_models[CCI550_R0],
-	},
-#endif
-	{},
-};
-
-static inline const struct cci_pmu_model *get_cci_model(struct platform_device *pdev)
-{
-	const struct of_device_id *match = of_match_node(arm_cci_pmu_matches,
-							pdev->dev.of_node);
-	if (!match)
-		return NULL;
-	if (match->data)
-		return match->data;
-
-	dev_warn(&pdev->dev, "DEPRECATED compatible property,"
-			 "requires secure access to CCI registers");
-	return probe_cci_model(pdev);
-}
-
-static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs)
-{
-	int i;
-
-	for (i = 0; i < nr_irqs; i++)
-		if (irq == irqs[i])
-			return true;
-
-	return false;
-}
-
-static struct cci_pmu *cci_pmu_alloc(struct platform_device *pdev)
-{
-	struct cci_pmu *cci_pmu;
-	const struct cci_pmu_model *model;
-
-	/*
-	 * All allocations are devm_* hence we don't have to free
-	 * them explicitly on an error, as it would end up in driver
-	 * detach.
-	 */
-	model = get_cci_model(pdev);
-	if (!model) {
-		dev_warn(&pdev->dev, "CCI PMU version not supported\n");
-		return ERR_PTR(-ENODEV);
-	}
-
-	cci_pmu = devm_kzalloc(&pdev->dev, sizeof(*cci_pmu), GFP_KERNEL);
-	if (!cci_pmu)
-		return ERR_PTR(-ENOMEM);
-
-	cci_pmu->model = model;
-	cci_pmu->irqs = devm_kcalloc(&pdev->dev, CCI_PMU_MAX_HW_CNTRS(model),
-					sizeof(*cci_pmu->irqs), GFP_KERNEL);
-	if (!cci_pmu->irqs)
-		return ERR_PTR(-ENOMEM);
-	cci_pmu->hw_events.events = devm_kcalloc(&pdev->dev,
-					     CCI_PMU_MAX_HW_CNTRS(model),
-					     sizeof(*cci_pmu->hw_events.events),
-					     GFP_KERNEL);
-	if (!cci_pmu->hw_events.events)
-		return ERR_PTR(-ENOMEM);
-	cci_pmu->hw_events.used_mask = devm_kcalloc(&pdev->dev,
-						BITS_TO_LONGS(CCI_PMU_MAX_HW_CNTRS(model)),
-						sizeof(*cci_pmu->hw_events.used_mask),
-						GFP_KERNEL);
-	if (!cci_pmu->hw_events.used_mask)
-		return ERR_PTR(-ENOMEM);
-
-	return cci_pmu;
-}
-
-
-static int cci_pmu_probe(struct platform_device *pdev)
-{
-	struct resource *res;
-	struct cci_pmu *cci_pmu;
-	int i, ret, irq;
-
-	cci_pmu = cci_pmu_alloc(pdev);
-	if (IS_ERR(cci_pmu))
-		return PTR_ERR(cci_pmu);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	cci_pmu->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(cci_pmu->base))
-		return -ENOMEM;
-
-	/*
-	 * CCI PMU has one overflow interrupt per counter; but some may be tied
-	 * together to a common interrupt.
-	 */
-	cci_pmu->nr_irqs = 0;
-	for (i = 0; i < CCI_PMU_MAX_HW_CNTRS(cci_pmu->model); i++) {
-		irq = platform_get_irq(pdev, i);
-		if (irq < 0)
-			break;
-
-		if (is_duplicate_irq(irq, cci_pmu->irqs, cci_pmu->nr_irqs))
-			continue;
-
-		cci_pmu->irqs[cci_pmu->nr_irqs++] = irq;
-	}
-
-	/*
-	 * Ensure that the device tree has as many interrupts as the number
-	 * of counters.
-	 */
-	if (i < CCI_PMU_MAX_HW_CNTRS(cci_pmu->model)) {
-		dev_warn(&pdev->dev, "In-correct number of interrupts: %d, should be %d\n",
-			i, CCI_PMU_MAX_HW_CNTRS(cci_pmu->model));
-		return -EINVAL;
-	}
-
-	raw_spin_lock_init(&cci_pmu->hw_events.pmu_lock);
-	mutex_init(&cci_pmu->reserve_mutex);
-	atomic_set(&cci_pmu->active_events, 0);
-	cpumask_set_cpu(get_cpu(), &cci_pmu->cpus);
-
-	ret = cci_pmu_init(cci_pmu, pdev);
-	if (ret) {
-		put_cpu();
-		return ret;
-	}
-
-	cpuhp_state_add_instance_nocalls(CPUHP_AP_PERF_ARM_CCI_ONLINE,
-					 &cci_pmu->node);
-	put_cpu();
-	pr_info("ARM %s PMU driver probed", cci_pmu->model->name);
-	return 0;
-}
 
 static int cci_platform_probe(struct platform_device *pdev)
 {
 	if (!cci_probed())
 		return -ENODEV;
 
-	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	return of_platform_populate(pdev->dev.of_node, NULL,
+				    arm_cci_auxdata, &pdev->dev);
 }
 
-static struct platform_driver cci_pmu_driver = {
-	.driver = {
-		   .name = DRIVER_NAME_PMU,
-		   .of_match_table = arm_cci_pmu_matches,
-		  },
-	.probe = cci_pmu_probe,
-};
-
 static struct platform_driver cci_platform_driver = {
 	.driver = {
 		   .name = DRIVER_NAME,
@@ -1796,30 +85,9 @@ static struct platform_driver cci_platform_driver = {
 
 static int __init cci_platform_init(void)
 {
-	int ret;
-
-	ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_CCI_ONLINE,
-				      "perf/arm/cci:online", NULL,
-				      cci_pmu_offline_cpu);
-	if (ret)
-		return ret;
-
-	ret = platform_driver_register(&cci_pmu_driver);
-	if (ret)
-		return ret;
-
 	return platform_driver_register(&cci_platform_driver);
 }
 
-#else /* !CONFIG_ARM_CCI_PMU */
-
-static int __init cci_platform_init(void)
-{
-	return 0;
-}
-
-#endif /* CONFIG_ARM_CCI_PMU */
-
 #ifdef CONFIG_ARM_CCI400_PORT_CTRL
 
 #define CCI_PORT_CTRL		0x0
@@ -2189,13 +457,10 @@ static int cci_probe_ports(struct device_node *np)
 	if (!ports)
 		return -ENOMEM;
 
-	for_each_child_of_node(np, cp) {
+	for_each_available_child_of_node(np, cp) {
 		if (!of_match_node(arm_cci_ctrl_if_matches, cp))
 			continue;
 
-		if (!of_device_is_available(cp))
-			continue;
-
 		i = nb_ace + nb_ace_lite;
 
 		if (i >= nb_cci_ports)
@@ -2275,7 +540,7 @@ static int cci_probe(void)
 	struct resource res;
 
 	np = of_find_matching_node(NULL, arm_cci_matches);
-	if(!np || !of_device_is_available(np))
+	if (!of_device_is_available(np))
 		return -ENODEV;
 
 	ret = of_address_to_resource(np, 0, &res);
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
index cdaeeea..7cd2fd0 100644
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -13,22 +13,20 @@
 
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
+
 #include <linux/platform_data/ti-sysc.h>
 
 #include <dt-bindings/bus/ti-sysc.h>
 
-enum sysc_registers {
-	SYSC_REVISION,
-	SYSC_SYSCONFIG,
-	SYSC_SYSSTATUS,
-	SYSC_MAX_REGS,
-};
-
 static const char * const reg_names[] = { "rev", "sysc", "syss", };
 
 enum sysc_clocks {
@@ -55,6 +53,7 @@ static const char * const clock_names[] = { "fck", "ick", };
  * @cfg: interconnect target module configuration
  * @name: name if available
  * @revision: interconnect target module revision
+ * @needs_resume: runtime resume needed on resume from suspend
  */
 struct sysc {
 	struct device *dev;
@@ -66,8 +65,13 @@ struct sysc {
 	const char *legacy_mode;
 	const struct sysc_capabilities *cap;
 	struct sysc_config cfg;
+	struct ti_sysc_cookie cookie;
 	const char *name;
 	u32 revision;
+	bool enabled;
+	bool needs_resume;
+	bool child_needs_resume;
+	struct delayed_work idle_work;
 };
 
 static u32 sysc_read(struct sysc *ddata, int offset)
@@ -136,9 +140,6 @@ static int sysc_get_clocks(struct sysc *ddata)
 {
 	int i, error;
 
-	if (ddata->legacy_mode)
-		return 0;
-
 	for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
 		error = sysc_get_one_clock(ddata, i);
 		if (error && error != -ENOENT)
@@ -197,12 +198,53 @@ static int sysc_parse_and_check_child_range(struct sysc *ddata)
 	ddata->module_pa = of_translate_address(np, ranges++);
 	ddata->module_size = be32_to_cpup(ranges);
 
-	dev_dbg(ddata->dev, "interconnect target 0x%llx size 0x%x for %pOF\n",
-		ddata->module_pa, ddata->module_size, np);
-
 	return 0;
 }
 
+static struct device_node *stdout_path;
+
+static void sysc_init_stdout_path(struct sysc *ddata)
+{
+	struct device_node *np = NULL;
+	const char *uart;
+
+	if (IS_ERR(stdout_path))
+		return;
+
+	if (stdout_path)
+		return;
+
+	np = of_find_node_by_path("/chosen");
+	if (!np)
+		goto err;
+
+	uart = of_get_property(np, "stdout-path", NULL);
+	if (!uart)
+		goto err;
+
+	np = of_find_node_by_path(uart);
+	if (!np)
+		goto err;
+
+	stdout_path = np;
+
+	return;
+
+err:
+	stdout_path = ERR_PTR(-ENODEV);
+}
+
+static void sysc_check_quirk_stdout(struct sysc *ddata,
+				    struct device_node *np)
+{
+	sysc_init_stdout_path(ddata);
+	if (np != stdout_path)
+		return;
+
+	ddata->cfg.quirks |= SYSC_QUIRK_NO_IDLE_ON_INIT |
+				SYSC_QUIRK_NO_RESET_ON_INIT;
+}
+
 /**
  * sysc_check_one_child - check child configuration
  * @ddata: device driver data
@@ -221,6 +263,8 @@ static int sysc_check_one_child(struct sysc *ddata,
 	if (name)
 		dev_warn(ddata->dev, "really a child ti,hwmods property?");
 
+	sysc_check_quirk_stdout(ddata, np);
+
 	return 0;
 }
 
@@ -246,11 +290,8 @@ static int sysc_check_children(struct sysc *ddata)
  */
 static void sysc_check_quirk_16bit(struct sysc *ddata, struct resource *res)
 {
-	if (resource_size(res) == 8) {
-		dev_dbg(ddata->dev,
-			"enabling 16-bit and clockactivity quirks\n");
+	if (resource_size(res) == 8)
 		ddata->cfg.quirks |= SYSC_QUIRK_16BIT | SYSC_QUIRK_USE_CLOCKACT;
-	}
 }
 
 /**
@@ -276,7 +317,6 @@ static int sysc_parse_one(struct sysc *ddata, enum sysc_registers reg)
 	res = platform_get_resource_byname(to_platform_device(ddata->dev),
 					   IORESOURCE_MEM, name);
 	if (!res) {
-		dev_dbg(ddata->dev, "has no %s register\n", name);
 		ddata->offsets[reg] = -ENODEV;
 
 		return 0;
@@ -437,6 +477,14 @@ static int sysc_show_reg(struct sysc *ddata,
 	return sprintf(bufp, ":%x", ddata->offsets[reg]);
 }
 
+static int sysc_show_name(char *bufp, struct sysc *ddata)
+{
+	if (!ddata->name)
+		return 0;
+
+	return sprintf(bufp, ":%s", ddata->name);
+}
+
 /**
  * sysc_show_registers - show information about interconnect target module
  * @ddata: device driver data
@@ -451,6 +499,7 @@ static void sysc_show_registers(struct sysc *ddata)
 		bufp += sysc_show_reg(ddata, bufp, i);
 
 	bufp += sysc_show_rev(bufp, ddata);
+	bufp += sysc_show_name(bufp, ddata);
 
 	dev_dbg(ddata->dev, "%llx:%x%s\n",
 		ddata->module_pa, ddata->module_size,
@@ -459,33 +508,70 @@ static void sysc_show_registers(struct sysc *ddata)
 
 static int __maybe_unused sysc_runtime_suspend(struct device *dev)
 {
+	struct ti_sysc_platform_data *pdata;
 	struct sysc *ddata;
-	int i;
+	int error = 0, i;
 
 	ddata = dev_get_drvdata(dev);
 
-	if (ddata->legacy_mode)
+	if (!ddata->enabled)
 		return 0;
 
+	if (ddata->legacy_mode) {
+		pdata = dev_get_platdata(ddata->dev);
+		if (!pdata)
+			return 0;
+
+		if (!pdata->idle_module)
+			return -ENODEV;
+
+		error = pdata->idle_module(dev, &ddata->cookie);
+		if (error)
+			dev_err(dev, "%s: could not idle: %i\n",
+				__func__, error);
+
+		goto idled;
+	}
+
 	for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
 		if (IS_ERR_OR_NULL(ddata->clocks[i]))
 			continue;
 		clk_disable(ddata->clocks[i]);
 	}
 
-	return 0;
+idled:
+	ddata->enabled = false;
+
+	return error;
 }
 
 static int __maybe_unused sysc_runtime_resume(struct device *dev)
 {
+	struct ti_sysc_platform_data *pdata;
 	struct sysc *ddata;
-	int i, error;
+	int error = 0, i;
 
 	ddata = dev_get_drvdata(dev);
 
-	if (ddata->legacy_mode)
+	if (ddata->enabled)
 		return 0;
 
+	if (ddata->legacy_mode) {
+		pdata = dev_get_platdata(ddata->dev);
+		if (!pdata)
+			return 0;
+
+		if (!pdata->enable_module)
+			return -ENODEV;
+
+		error = pdata->enable_module(dev, &ddata->cookie);
+		if (error)
+			dev_err(dev, "%s: could not enable: %i\n",
+				__func__, error);
+
+		goto awake;
+	}
+
 	for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
 		if (IS_ERR_OR_NULL(ddata->clocks[i]))
 			continue;
@@ -494,20 +580,136 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
 			return error;
 	}
 
-	return 0;
+awake:
+	ddata->enabled = true;
+
+	return error;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int sysc_suspend(struct device *dev)
+{
+	struct sysc *ddata;
+
+	ddata = dev_get_drvdata(dev);
+
+	if (!ddata->enabled)
+		return 0;
+
+	ddata->needs_resume = true;
+
+	return sysc_runtime_suspend(dev);
+}
+
+static int sysc_resume(struct device *dev)
+{
+	struct sysc *ddata;
+
+	ddata = dev_get_drvdata(dev);
+	if (ddata->needs_resume) {
+		ddata->needs_resume = false;
+
+		return sysc_runtime_resume(dev);
+	}
+
+	return 0;
+}
+#endif
+
 static const struct dev_pm_ops sysc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(sysc_suspend, sysc_resume)
 	SET_RUNTIME_PM_OPS(sysc_runtime_suspend,
 			   sysc_runtime_resume,
 			   NULL)
 };
 
+/* Module revision register based quirks */
+struct sysc_revision_quirk {
+	const char *name;
+	u32 base;
+	int rev_offset;
+	int sysc_offset;
+	int syss_offset;
+	u32 revision;
+	u32 revision_mask;
+	u32 quirks;
+};
+
+#define SYSC_QUIRK(optname, optbase, optrev, optsysc, optsyss,		\
+		   optrev_val, optrevmask, optquirkmask)		\
+	{								\
+		.name = (optname),					\
+		.base = (optbase),					\
+		.rev_offset = (optrev),					\
+		.sysc_offset = (optsysc),				\
+		.syss_offset = (optsyss),				\
+		.revision = (optrev_val),				\
+		.revision_mask = (optrevmask),				\
+		.quirks = (optquirkmask),				\
+	}
+
+static const struct sysc_revision_quirk sysc_revision_quirks[] = {
+	/* These drivers need to be fixed to not use pm_runtime_irq_safe() */
+	SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffffffff,
+		   SYSC_QUIRK_LEGACY_IDLE),
+	SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000020, 0xffffffff,
+		   SYSC_QUIRK_LEGACY_IDLE),
+	SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000030, 0xffffffff,
+		   SYSC_QUIRK_LEGACY_IDLE),
+	SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff,
+		   SYSC_QUIRK_LEGACY_IDLE),
+	SYSC_QUIRK("smartreflex", 0, -1, 0x24, -1, 0x00000000, 0xffffffff,
+		   SYSC_QUIRK_LEGACY_IDLE),
+	SYSC_QUIRK("smartreflex", 0, -1, 0x38, -1, 0x00000000, 0xffffffff,
+		   SYSC_QUIRK_LEGACY_IDLE),
+	SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff,
+		   SYSC_QUIRK_LEGACY_IDLE),
+	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
+		   SYSC_QUIRK_LEGACY_IDLE),
+};
+
+static void sysc_init_revision_quirks(struct sysc *ddata)
+{
+	const struct sysc_revision_quirk *q;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sysc_revision_quirks); i++) {
+		q = &sysc_revision_quirks[i];
+
+		if (q->base && q->base != ddata->module_pa)
+			continue;
+
+		if (q->rev_offset >= 0 &&
+		    q->rev_offset != ddata->offsets[SYSC_REVISION])
+			continue;
+
+		if (q->sysc_offset >= 0 &&
+		    q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG])
+			continue;
+
+		if (q->syss_offset >= 0 &&
+		    q->syss_offset != ddata->offsets[SYSC_SYSSTATUS])
+			continue;
+
+		if (q->revision == ddata->revision ||
+		    (q->revision & q->revision_mask) ==
+		    (ddata->revision & q->revision_mask)) {
+			ddata->name = q->name;
+			ddata->cfg.quirks |= q->quirks;
+		}
+	}
+}
+
 /* At this point the module is configured enough to read the revision */
 static int sysc_init_module(struct sysc *ddata)
 {
 	int error;
 
+	if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE_ON_INIT) {
+		ddata->revision = sysc_read_revision(ddata);
+		goto rev_quirks;
+	}
+
 	error = pm_runtime_get_sync(ddata->dev);
 	if (error < 0) {
 		pm_runtime_put_noidle(ddata->dev);
@@ -517,6 +719,9 @@ static int sysc_init_module(struct sysc *ddata)
 	ddata->revision = sysc_read_revision(ddata);
 	pm_runtime_put_sync(ddata->dev);
 
+rev_quirks:
+	sysc_init_revision_quirks(ddata);
+
 	return 0;
 }
 
@@ -605,6 +810,196 @@ static int sysc_init_syss_mask(struct sysc *ddata)
 	return 0;
 }
 
+/*
+ * Many child device drivers need to have fck available to get the clock
+ * rate for device internal configuration.
+ */
+static int sysc_child_add_fck(struct sysc *ddata,
+			      struct device *child)
+{
+	struct clk *fck;
+	struct clk_lookup *l;
+	const char *name = clock_names[SYSC_FCK];
+
+	if (IS_ERR_OR_NULL(ddata->clocks[SYSC_FCK]))
+		return 0;
+
+	fck = clk_get(child, name);
+	if (!IS_ERR(fck)) {
+		clk_put(fck);
+
+		return -EEXIST;
+	}
+
+	l = clkdev_create(ddata->clocks[SYSC_FCK], name, dev_name(child));
+
+	return l ? 0 : -ENODEV;
+}
+
+static struct device_type sysc_device_type = {
+};
+
+static struct sysc *sysc_child_to_parent(struct device *dev)
+{
+	struct device *parent = dev->parent;
+
+	if (!parent || parent->type != &sysc_device_type)
+		return NULL;
+
+	return dev_get_drvdata(parent);
+}
+
+static int __maybe_unused sysc_child_runtime_suspend(struct device *dev)
+{
+	struct sysc *ddata;
+	int error;
+
+	ddata = sysc_child_to_parent(dev);
+
+	error = pm_generic_runtime_suspend(dev);
+	if (error)
+		return error;
+
+	if (!ddata->enabled)
+		return 0;
+
+	return sysc_runtime_suspend(ddata->dev);
+}
+
+static int __maybe_unused sysc_child_runtime_resume(struct device *dev)
+{
+	struct sysc *ddata;
+	int error;
+
+	ddata = sysc_child_to_parent(dev);
+
+	if (!ddata->enabled) {
+		error = sysc_runtime_resume(ddata->dev);
+		if (error < 0)
+			dev_err(ddata->dev,
+				"%s error: %i\n", __func__, error);
+	}
+
+	return pm_generic_runtime_resume(dev);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sysc_child_suspend_noirq(struct device *dev)
+{
+	struct sysc *ddata;
+	int error;
+
+	ddata = sysc_child_to_parent(dev);
+
+	error = pm_generic_suspend_noirq(dev);
+	if (error)
+		return error;
+
+	if (!pm_runtime_status_suspended(dev)) {
+		error = pm_generic_runtime_suspend(dev);
+		if (error)
+			return error;
+
+		error = sysc_runtime_suspend(ddata->dev);
+		if (error)
+			return error;
+
+		ddata->child_needs_resume = true;
+	}
+
+	return 0;
+}
+
+static int sysc_child_resume_noirq(struct device *dev)
+{
+	struct sysc *ddata;
+	int error;
+
+	ddata = sysc_child_to_parent(dev);
+
+	if (ddata->child_needs_resume) {
+		ddata->child_needs_resume = false;
+
+		error = sysc_runtime_resume(ddata->dev);
+		if (error)
+			dev_err(ddata->dev,
+				"%s runtime resume error: %i\n",
+				__func__, error);
+
+		error = pm_generic_runtime_resume(dev);
+		if (error)
+			dev_err(ddata->dev,
+				"%s generic runtime resume: %i\n",
+				__func__, error);
+	}
+
+	return pm_generic_resume_noirq(dev);
+}
+#endif
+
+struct dev_pm_domain sysc_child_pm_domain = {
+	.ops = {
+		SET_RUNTIME_PM_OPS(sysc_child_runtime_suspend,
+				   sysc_child_runtime_resume,
+				   NULL)
+		USE_PLATFORM_PM_SLEEP_OPS
+		SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_child_suspend_noirq,
+					      sysc_child_resume_noirq)
+	}
+};
+
+/**
+ * sysc_legacy_idle_quirk - handle children in omap_device compatible way
+ * @ddata: device driver data
+ * @child: child device driver
+ *
+ * Allow idle for child devices as done with _od_runtime_suspend().
+ * Otherwise many child devices will not idle because of the permanent
+ * parent usecount set in pm_runtime_irq_safe().
+ *
+ * Note that the long term solution is to just modify the child device
+ * drivers to not set pm_runtime_irq_safe() and then this can be just
+ * dropped.
+ */
+static void sysc_legacy_idle_quirk(struct sysc *ddata, struct device *child)
+{
+	if (!ddata->legacy_mode)
+		return;
+
+	if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
+		dev_pm_domain_set(child, &sysc_child_pm_domain);
+}
+
+static int sysc_notifier_call(struct notifier_block *nb,
+			      unsigned long event, void *device)
+{
+	struct device *dev = device;
+	struct sysc *ddata;
+	int error;
+
+	ddata = sysc_child_to_parent(dev);
+	if (!ddata)
+		return NOTIFY_DONE;
+
+	switch (event) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		error = sysc_child_add_fck(ddata, dev);
+		if (error && error != -EEXIST)
+			dev_warn(ddata->dev, "could not add %s fck: %i\n",
+				 dev_name(dev), error);
+		sysc_legacy_idle_quirk(ddata, dev);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sysc_nb = {
+	.notifier_call = sysc_notifier_call,
+};
+
 /* Device tree configured quirks */
 struct sysc_dts_quirk {
 	const char *name;
@@ -797,7 +1192,8 @@ static const struct sysc_capabilities sysc_34xx_sr = {
 	.type = TI_SYSC_OMAP34XX_SR,
 	.sysc_mask = SYSC_OMAP2_CLOCKACTIVITY,
 	.regbits = &sysc_regbits_omap34xx_sr,
-	.mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED,
+	.mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED |
+		      SYSC_QUIRK_LEGACY_IDLE,
 };
 
 /*
@@ -818,12 +1214,13 @@ static const struct sysc_capabilities sysc_36xx_sr = {
 	.type = TI_SYSC_OMAP36XX_SR,
 	.sysc_mask = SYSC_OMAP3_SR_ENAWAKEUP,
 	.regbits = &sysc_regbits_omap36xx_sr,
-	.mod_quirks = SYSC_QUIRK_UNCACHED,
+	.mod_quirks = SYSC_QUIRK_UNCACHED | SYSC_QUIRK_LEGACY_IDLE,
 };
 
 static const struct sysc_capabilities sysc_omap4_sr = {
 	.type = TI_SYSC_OMAP4_SR,
 	.regbits = &sysc_regbits_omap36xx_sr,
+	.mod_quirks = SYSC_QUIRK_LEGACY_IDLE,
 };
 
 /*
@@ -865,6 +1262,33 @@ static const struct sysc_capabilities sysc_omap4_usb_host_fs = {
 	.regbits = &sysc_regbits_omap4_usb_host_fs,
 };
 
+static int sysc_init_pdata(struct sysc *ddata)
+{
+	struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
+	struct ti_sysc_module_data mdata;
+	int error = 0;
+
+	if (!pdata || !ddata->legacy_mode)
+		return 0;
+
+	mdata.name = ddata->legacy_mode;
+	mdata.module_pa = ddata->module_pa;
+	mdata.module_size = ddata->module_size;
+	mdata.offsets = ddata->offsets;
+	mdata.nr_offsets = SYSC_MAX_REGS;
+	mdata.cap = ddata->cap;
+	mdata.cfg = &ddata->cfg;
+
+	if (!pdata->init_module)
+		return -ENODEV;
+
+	error = pdata->init_module(ddata->dev, &mdata, &ddata->cookie);
+	if (error == -EEXIST)
+		error = 0;
+
+	return error;
+}
+
 static int sysc_init_match(struct sysc *ddata)
 {
 	const struct sysc_capabilities *cap;
@@ -880,8 +1304,19 @@ static int sysc_init_match(struct sysc *ddata)
 	return 0;
 }
 
+static void ti_sysc_idle(struct work_struct *work)
+{
+	struct sysc *ddata;
+
+	ddata = container_of(work, struct sysc, idle_work.work);
+
+	if (pm_runtime_active(ddata->dev))
+		pm_runtime_put_sync(ddata->dev);
+}
+
 static int sysc_probe(struct platform_device *pdev)
 {
+	struct ti_sysc_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct sysc *ddata;
 	int error;
 
@@ -920,6 +1355,10 @@ static int sysc_probe(struct platform_device *pdev)
 	if (error)
 		goto unprepare;
 
+	error = sysc_init_pdata(ddata);
+	if (error)
+		goto unprepare;
+
 	pm_runtime_enable(ddata->dev);
 
 	error = sysc_init_module(ddata);
@@ -933,22 +1372,28 @@ static int sysc_probe(struct platform_device *pdev)
 		goto unprepare;
 	}
 
-	pm_runtime_use_autosuspend(ddata->dev);
-
 	sysc_show_registers(ddata);
 
+	ddata->dev->type = &sysc_device_type;
 	error = of_platform_populate(ddata->dev->of_node,
-				     NULL, NULL, ddata->dev);
+				     NULL, pdata ? pdata->auxdata : NULL,
+				     ddata->dev);
 	if (error)
 		goto err;
 
-	pm_runtime_mark_last_busy(ddata->dev);
-	pm_runtime_put_autosuspend(ddata->dev);
+	INIT_DELAYED_WORK(&ddata->idle_work, ti_sysc_idle);
+
+	/* At least earlycon won't survive without deferred idle */
+	if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE_ON_INIT |
+				 SYSC_QUIRK_NO_RESET_ON_INIT)) {
+		schedule_delayed_work(&ddata->idle_work, 3000);
+	} else {
+		pm_runtime_put(&pdev->dev);
+	}
 
 	return 0;
 
 err:
-	pm_runtime_dont_use_autosuspend(&pdev->dev);
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 unprepare:
@@ -962,6 +1407,8 @@ static int sysc_remove(struct platform_device *pdev)
 	struct sysc *ddata = platform_get_drvdata(pdev);
 	int error;
 
+	cancel_delayed_work_sync(&ddata->idle_work);
+
 	error = pm_runtime_get_sync(ddata->dev);
 	if (error < 0) {
 		pm_runtime_put_noidle(ddata->dev);
@@ -971,7 +1418,6 @@ static int sysc_remove(struct platform_device *pdev)
 
 	of_platform_depopulate(&pdev->dev);
 
-	pm_runtime_dont_use_autosuspend(&pdev->dev);
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
@@ -1008,7 +1454,21 @@ static struct platform_driver sysc_driver = {
 		.pm = &sysc_pm_ops,
 	},
 };
-module_platform_driver(sysc_driver);
+
+static int __init sysc_init(void)
+{
+	bus_register_notifier(&platform_bus_type, &sysc_nb);
+
+	return platform_driver_register(&sysc_driver);
+}
+module_init(sysc_init);
+
+static void __exit sysc_exit(void)
+{
+	bus_unregister_notifier(&platform_bus_type, &sysc_nb);
+	platform_driver_unregister(&sysc_driver);
+}
+module_exit(sysc_exit);
 
 MODULE_DESCRIPTION("TI sysc interconnect target driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index e36d160..8327478 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1152,9 +1152,6 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
 
 	cd_dbg(CD_OPEN, "entering cdrom_open\n");
 
-	/* open is event synchronization point, check events first */
-	check_disk_change(bdev);
-
 	/* if this was a O_NONBLOCK open and we should honor the flags,
 	 * do a quick open without drive/disc integrity checks. */
 	cdi->use_count++;
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 6495b03f..ae3a753 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -497,6 +497,9 @@ static const struct cdrom_device_ops gdrom_ops = {
 static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode)
 {
 	int ret;
+
+	check_disk_change(bdev);
+
 	mutex_lock(&gdrom_mutex);
 	ret = cdrom_open(gd.cd_info, bdev, mode);
 	mutex_unlock(&gdrom_mutex);
diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
index d5c6a2e9..f6e1dbe 100644
--- a/drivers/char/tpm/tpm_tis_core.h
+++ b/drivers/char/tpm/tpm_tis_core.h
@@ -62,10 +62,10 @@ enum tis_defaults {
 /* Some timeout values are needed before it is known whether the chip is
  * TPM 1.0 or TPM 2.0.
  */
-#define TIS_TIMEOUT_A_MAX	max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_A)
-#define TIS_TIMEOUT_B_MAX	max(TIS_LONG_TIMEOUT, TPM2_TIMEOUT_B)
-#define TIS_TIMEOUT_C_MAX	max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_C)
-#define TIS_TIMEOUT_D_MAX	max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_D)
+#define TIS_TIMEOUT_A_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_A)
+#define TIS_TIMEOUT_B_MAX	max_t(int, TIS_LONG_TIMEOUT, TPM2_TIMEOUT_B)
+#define TIS_TIMEOUT_C_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_C)
+#define TIS_TIMEOUT_D_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_D)
 
 #define	TPM_ACCESS(l)			(0x0000 | ((l) << 12))
 #define	TPM_INT_ENABLE(l)		(0x0008 | ((l) << 12))
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 98ce9fc..7ae23b2 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -62,6 +62,16 @@
 	  multi-function device has one fixed-rate oscillator, clocked
 	  at 32KHz.
 
+config COMMON_CLK_SCMI
+	tristate "Clock driver controlled via SCMI interface"
+	depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
+	  ---help---
+	  This driver provides support for clocks that are controlled
+	  by firmware that implements the SCMI interface.
+
+	  This driver uses SCMI Message Protocol to interact with the
+	  firmware providing all the clock controls.
+
 config COMMON_CLK_SCPI
 	tristate "Clock driver controlled via SCPI interface"
 	depends on ARM_SCPI_PROTOCOL || COMPILE_TEST
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 71ec41e..6605513 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -41,6 +41,7 @@
 obj-$(CONFIG_COMMON_CLK_RK808)		+= clk-rk808.o
 obj-$(CONFIG_COMMON_CLK_HI655X)		+= clk-hi655x.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)	+= clk-s2mps11.o
+obj-$(CONFIG_COMMON_CLK_SCMI)           += clk-scmi.o
 obj-$(CONFIG_COMMON_CLK_SCPI)           += clk-scpi.o
 obj-$(CONFIG_COMMON_CLK_SI5351)		+= clk-si5351.o
 obj-$(CONFIG_COMMON_CLK_SI514)		+= clk-si514.o
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
new file mode 100644
index 0000000..488c213
--- /dev/null
+++ b/drivers/clk/clk-scmi.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Power Interface (SCMI) Protocol based clock driver
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/scmi_protocol.h>
+#include <asm/div64.h>
+
+struct scmi_clk {
+	u32 id;
+	struct clk_hw hw;
+	const struct scmi_clock_info *info;
+	const struct scmi_handle *handle;
+};
+
+#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
+
+static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	int ret;
+	u64 rate;
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	ret = clk->handle->clk_ops->rate_get(clk->handle, clk->id, &rate);
+	if (ret)
+		return 0;
+	return rate;
+}
+
+static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *parent_rate)
+{
+	int step;
+	u64 fmin, fmax, ftmp;
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	/*
+	 * We can't figure out what rate it will be, so just return the
+	 * rate back to the caller. scmi_clk_recalc_rate() will be called
+	 * after the rate is set and we'll know what rate the clock is
+	 * running at then.
+	 */
+	if (clk->info->rate_discrete)
+		return rate;
+
+	fmin = clk->info->range.min_rate;
+	fmax = clk->info->range.max_rate;
+	if (rate <= fmin)
+		return fmin;
+	else if (rate >= fmax)
+		return fmax;
+
+	ftmp = rate - fmin;
+	ftmp += clk->info->range.step_size - 1; /* to round up */
+	step = do_div(ftmp, clk->info->range.step_size);
+
+	return step * clk->info->range.step_size + fmin;
+}
+
+static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
+{
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	return clk->handle->clk_ops->rate_set(clk->handle, clk->id, 0, rate);
+}
+
+static int scmi_clk_enable(struct clk_hw *hw)
+{
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	return clk->handle->clk_ops->enable(clk->handle, clk->id);
+}
+
+static void scmi_clk_disable(struct clk_hw *hw)
+{
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	clk->handle->clk_ops->disable(clk->handle, clk->id);
+}
+
+static const struct clk_ops scmi_clk_ops = {
+	.recalc_rate = scmi_clk_recalc_rate,
+	.round_rate = scmi_clk_round_rate,
+	.set_rate = scmi_clk_set_rate,
+	/*
+	 * We can't provide enable/disable callback as we can't perform the same
+	 * in atomic context. Since the clock framework provides standard API
+	 * clk_prepare_enable that helps cases using clk_enable in non-atomic
+	 * context, it should be fine providing prepare/unprepare.
+	 */
+	.prepare = scmi_clk_enable,
+	.unprepare = scmi_clk_disable,
+};
+
+static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
+{
+	int ret;
+	struct clk_init_data init = {
+		.flags = CLK_GET_RATE_NOCACHE,
+		.num_parents = 0,
+		.ops = &scmi_clk_ops,
+		.name = sclk->info->name,
+	};
+
+	sclk->hw.init = &init;
+	ret = devm_clk_hw_register(dev, &sclk->hw);
+	if (!ret)
+		clk_hw_set_rate_range(&sclk->hw, sclk->info->range.min_rate,
+				      sclk->info->range.max_rate);
+	return ret;
+}
+
+static int scmi_clocks_probe(struct scmi_device *sdev)
+{
+	int idx, count, err;
+	struct clk_hw **hws;
+	struct clk_hw_onecell_data *clk_data;
+	struct device *dev = &sdev->dev;
+	struct device_node *np = dev->of_node;
+	const struct scmi_handle *handle = sdev->handle;
+
+	if (!handle || !handle->clk_ops)
+		return -ENODEV;
+
+	count = handle->clk_ops->count_get(handle);
+	if (count < 0) {
+		dev_err(dev, "%s: invalid clock output count\n", np->name);
+		return -EINVAL;
+	}
+
+	clk_data = devm_kzalloc(dev, sizeof(*clk_data) +
+				sizeof(*clk_data->hws) * count, GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	clk_data->num = count;
+	hws = clk_data->hws;
+
+	for (idx = 0; idx < count; idx++) {
+		struct scmi_clk *sclk;
+
+		sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
+		if (!sclk)
+			return -ENOMEM;
+
+		sclk->info = handle->clk_ops->info_get(handle, idx);
+		if (!sclk->info) {
+			dev_dbg(dev, "invalid clock info for idx %d\n", idx);
+			continue;
+		}
+
+		sclk->id = idx;
+		sclk->handle = handle;
+
+		err = scmi_clk_ops_init(dev, sclk);
+		if (err) {
+			dev_err(dev, "failed to register clock %d\n", idx);
+			devm_kfree(dev, sclk);
+			hws[idx] = NULL;
+		} else {
+			dev_dbg(dev, "Registered clock:%s\n", sclk->info->name);
+			hws[idx] = &sclk->hw;
+		}
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   clk_data);
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+	{ SCMI_PROTOCOL_CLOCK },
+	{ },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_clocks_driver = {
+	.name = "scmi-clocks",
+	.probe = scmi_clocks_probe,
+	.id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_clocks_driver);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCMI clock driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 80dc211..617beb2 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -795,6 +795,8 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 	clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
 	clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
 	clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
+	clks[IMX7D_SNVS_CLK] = imx_clk_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0);
+	clks[IMX7D_CAAM_CLK] = imx_clk_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0);
 	clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
 	clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
 	clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
@@ -857,6 +859,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 	clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate4("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0);
 	clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate4("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0);
 	clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate4("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0);
+	clks[IMX7D_KPP_ROOT_CLK] = imx_clk_gate4("kpp_root_clk", "ipg_root_clk", base + 0x4aa0, 0);
 	clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
 	clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
 	clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 6021a5a..9ee2888 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -21,6 +21,9 @@
 config I8253_LOCK
 	bool
 
+config OMAP_DM_TIMER
+	bool
+
 config CLKBLD_I8253
 	def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index f0cb076..e8e76df 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -16,6 +16,7 @@
 obj-$(CONFIG_CLKBLD_I8253)	+= i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
 obj-$(CONFIG_DIGICOLOR_TIMER)	+= timer-digicolor.o
+obj-$(CONFIG_OMAP_DM_TIMER)	+= timer-ti-dm.o
 obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_FTTMR010_TIMER)	+= timer-fttmr010.o
diff --git a/arch/arm/plat-omap/dmtimer.c b/drivers/clocksource/timer-ti-dm.c
similarity index 86%
rename from arch/arm/plat-omap/dmtimer.c
rename to drivers/clocksource/timer-ti-dm.c
index 8805a59..4cce6b2 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -47,7 +47,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_data/dmtimer-omap.h>
 
-#include <plat/dmtimer.h>
+#include <clocksource/timer-ti-dm.h>
 
 static u32 omap_reserved_systimers;
 static LIST_HEAD(omap_timer_list);
@@ -163,6 +163,86 @@ static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
 	return ret;
 }
 
+static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+{
+	int ret;
+	const char *parent_name;
+	struct clk *parent;
+	struct dmtimer_platform_data *pdata;
+
+	if (unlikely(!timer) || IS_ERR(timer->fclk))
+		return -EINVAL;
+
+	switch (source) {
+	case OMAP_TIMER_SRC_SYS_CLK:
+		parent_name = "timer_sys_ck";
+		break;
+	case OMAP_TIMER_SRC_32_KHZ:
+		parent_name = "timer_32k_ck";
+		break;
+	case OMAP_TIMER_SRC_EXT_CLK:
+		parent_name = "timer_ext_ck";
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	pdata = timer->pdev->dev.platform_data;
+
+	/*
+	 * FIXME: Used for OMAP1 devices only because they do not currently
+	 * use the clock framework to set the parent clock. To be removed
+	 * once OMAP1 migrated to using clock framework for dmtimers
+	 */
+	if (pdata && pdata->set_timer_src)
+		return pdata->set_timer_src(timer->pdev, source);
+
+#if defined(CONFIG_COMMON_CLK)
+	/* Check if the clock has configurable parents */
+	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
+		return 0;
+#endif
+
+	parent = clk_get(&timer->pdev->dev, parent_name);
+	if (IS_ERR(parent)) {
+		pr_err("%s: %s not found\n", __func__, parent_name);
+		return -EINVAL;
+	}
+
+	ret = clk_set_parent(timer->fclk, parent);
+	if (ret < 0)
+		pr_err("%s: failed to set %s as parent\n", __func__,
+			parent_name);
+
+	clk_put(parent);
+
+	return ret;
+}
+
+static void omap_dm_timer_enable(struct omap_dm_timer *timer)
+{
+	int c;
+
+	pm_runtime_get_sync(&timer->pdev->dev);
+
+	if (!(timer->capability & OMAP_TIMER_ALWON)) {
+		if (timer->get_context_loss_count) {
+			c = timer->get_context_loss_count(&timer->pdev->dev);
+			if (c != timer->ctx_loss_count) {
+				omap_timer_restore_context(timer);
+				timer->ctx_loss_count = c;
+			}
+		} else {
+			omap_timer_restore_context(timer);
+		}
+	}
+}
+
+static void omap_dm_timer_disable(struct omap_dm_timer *timer)
+{
+	pm_runtime_put_sync(&timer->pdev->dev);
+}
+
 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
 {
 	int rc;
@@ -298,24 +378,22 @@ static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
 	return timer;
 }
 
-struct omap_dm_timer *omap_dm_timer_request(void)
+static struct omap_dm_timer *omap_dm_timer_request(void)
 {
 	return _omap_dm_timer_request(REQUEST_ANY, NULL);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request);
 
-struct omap_dm_timer *omap_dm_timer_request_specific(int id)
+static struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
 	/* Requesting timer by ID is not supported when device tree is used */
 	if (of_have_populated_dt()) {
-		pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
+		pr_warn("%s: Please use omap_dm_timer_request_by_node()\n",
 			__func__);
 		return NULL;
 	}
 
 	return _omap_dm_timer_request(REQUEST_BY_ID, &id);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
 /**
  * omap_dm_timer_request_by_cap - Request a timer by capability
@@ -330,7 +408,6 @@ struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
 {
 	return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
 
 /**
  * omap_dm_timer_request_by_node - Request a timer by device-tree node
@@ -339,16 +416,15 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
  * Request a timer based upon a device node pointer. Returns pointer to
  * timer handle on success and a NULL pointer on failure.
  */
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
+static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
 {
 	if (!np)
 		return NULL;
 
 	return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
 
-int omap_dm_timer_free(struct omap_dm_timer *timer)
+static int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer))
 		return -EINVAL;
@@ -359,33 +435,6 @@ int omap_dm_timer_free(struct omap_dm_timer *timer)
 	timer->reserved = 0;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_free);
-
-void omap_dm_timer_enable(struct omap_dm_timer *timer)
-{
-	int c;
-
-	pm_runtime_get_sync(&timer->pdev->dev);
-
-	if (!(timer->capability & OMAP_TIMER_ALWON)) {
-		if (timer->get_context_loss_count) {
-			c = timer->get_context_loss_count(&timer->pdev->dev);
-			if (c != timer->ctx_loss_count) {
-				omap_timer_restore_context(timer);
-				timer->ctx_loss_count = c;
-			}
-		} else {
-			omap_timer_restore_context(timer);
-		}
-	}
-}
-EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
-
-void omap_dm_timer_disable(struct omap_dm_timer *timer)
-{
-	pm_runtime_put_sync(&timer->pdev->dev);
-}
-EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 {
@@ -393,10 +442,15 @@ int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 		return timer->irq;
 	return -EINVAL;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
 
 #if defined(CONFIG_ARCH_OMAP1)
 #include <mach/hardware.h>
+
+static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
+{
+	return NULL;
+}
+
 /**
  * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
  * @inputmask: current value of idlect mask
@@ -429,17 +483,15 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 	return inputmask;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #else
 
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
+static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
 {
 	if (timer && !IS_ERR(timer->fclk))
 		return timer->fclk;
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
 
 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 {
@@ -447,7 +499,6 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #endif
 
@@ -461,9 +512,8 @@ int omap_dm_timer_trigger(struct omap_dm_timer *timer)
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
 
-int omap_dm_timer_start(struct omap_dm_timer *timer)
+static int omap_dm_timer_start(struct omap_dm_timer *timer)
 {
 	u32 l;
 
@@ -482,9 +532,8 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
 	timer->context.tclr = l;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_start);
 
-int omap_dm_timer_stop(struct omap_dm_timer *timer)
+static int omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
 	unsigned long rate = 0;
 
@@ -506,73 +555,9 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
-{
-	int ret;
-	char *parent_name = NULL;
-	struct clk *parent;
-	struct dmtimer_platform_data *pdata;
-
-	if (unlikely(!timer))
-		return -EINVAL;
-
-	pdata = timer->pdev->dev.platform_data;
-
-	if (source < 0 || source >= 3)
-		return -EINVAL;
-
-	/*
-	 * FIXME: Used for OMAP1 devices only because they do not currently
-	 * use the clock framework to set the parent clock. To be removed
-	 * once OMAP1 migrated to using clock framework for dmtimers
-	 */
-	if (pdata && pdata->set_timer_src)
-		return pdata->set_timer_src(timer->pdev, source);
-
-	if (IS_ERR(timer->fclk))
-		return -EINVAL;
-
-#if defined(CONFIG_COMMON_CLK)
-	/* Check if the clock has configurable parents */
-	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
-		return 0;
-#endif
-
-	switch (source) {
-	case OMAP_TIMER_SRC_SYS_CLK:
-		parent_name = "timer_sys_ck";
-		break;
-
-	case OMAP_TIMER_SRC_32_KHZ:
-		parent_name = "timer_32k_ck";
-		break;
-
-	case OMAP_TIMER_SRC_EXT_CLK:
-		parent_name = "timer_ext_ck";
-		break;
-	}
-
-	parent = clk_get(&timer->pdev->dev, parent_name);
-	if (IS_ERR(parent)) {
-		pr_err("%s: %s not found\n", __func__, parent_name);
-		return -EINVAL;
-	}
-
-	ret = clk_set_parent(timer->fclk, parent);
-	if (ret < 0)
-		pr_err("%s: failed to set %s as parent\n", __func__,
-			parent_name);
-
-	clk_put(parent);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
-
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
-			    unsigned int load)
+static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+				  unsigned int load)
 {
 	u32 l;
 
@@ -595,7 +580,6 @@ int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
 
 /* Optimized set_load which removes costly spin wait in timer_start */
 int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
@@ -625,10 +609,8 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
 	timer->context.tcrr = load;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
-
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
-			     unsigned int match)
+static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
+				   unsigned int match)
 {
 	u32 l;
 
@@ -650,10 +632,9 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
 
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
-			   int toggle, int trigger)
+static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
+				 int toggle, int trigger)
 {
 	u32 l;
 
@@ -676,19 +657,19 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
 
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
+static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
+					int prescaler)
 {
 	u32 l;
 
-	if (unlikely(!timer))
+	if (unlikely(!timer) || prescaler < -1 || prescaler > 7)
 		return -EINVAL;
 
 	omap_dm_timer_enable(timer);
 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
 	l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
-	if (prescaler >= 0x00 && prescaler <= 0x07) {
+	if (prescaler >= 0) {
 		l |= OMAP_TIMER_CTRL_PRE;
 		l |= prescaler << 2;
 	}
@@ -699,10 +680,9 @@ int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
 
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
-				  unsigned int value)
+static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+					unsigned int value)
 {
 	if (unlikely(!timer))
 		return -EINVAL;
@@ -716,7 +696,6 @@ int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
 
 /**
  * omap_dm_timer_set_int_disable - disable timer interrupts
@@ -725,7 +704,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
  *
  * Disables the specified timer interrupts for a timer.
  */
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
+static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 {
 	u32 l = mask;
 
@@ -747,9 +726,8 @@ int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_disable);
 
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
+static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 {
 	unsigned int l;
 
@@ -762,9 +740,8 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 
 	return l;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
 
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
+static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
 		return -EINVAL;
@@ -773,9 +750,8 @@ int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
 
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
+static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
 		pr_err("%s: timer not iavailable or enabled.\n", __func__);
@@ -784,9 +760,8 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 
 	return __omap_dm_timer_read_counter(timer, timer->posted);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
 
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
+static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
 		pr_err("%s: timer not available or enabled.\n", __func__);
@@ -799,7 +774,6 @@ int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 	timer->context.tcrr = value;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
 
 int omap_dm_timers_active(void)
 {
@@ -816,7 +790,6 @@ int omap_dm_timers_active(void)
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timers_active);
 
 static const struct of_device_id omap_timer_match[];
 
@@ -833,14 +806,16 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
 	struct omap_dm_timer *timer;
 	struct resource *mem, *irq;
 	struct device *dev = &pdev->dev;
-	const struct of_device_id *match;
 	const struct dmtimer_platform_data *pdata;
 	int ret;
 
-	match = of_match_device(of_match_ptr(omap_timer_match), dev);
-	pdata = match ? match->data : dev->platform_data;
+	pdata = of_device_get_match_data(dev);
+	if (!pdata)
+		pdata = dev_get_platdata(dev);
+	else
+		dev->platform_data = (void *)pdata;
 
-	if (!pdata && !dev->of_node) {
+	if (!pdata) {
 		dev_err(dev, "%s: no platform data.\n", __func__);
 		return -ENODEV;
 	}
@@ -946,8 +921,33 @@ static int omap_dm_timer_remove(struct platform_device *pdev)
 	return ret;
 }
 
+const static struct omap_dm_timer_ops dmtimer_ops = {
+	.request_by_node = omap_dm_timer_request_by_node,
+	.request_specific = omap_dm_timer_request_specific,
+	.request = omap_dm_timer_request,
+	.set_source = omap_dm_timer_set_source,
+	.get_irq = omap_dm_timer_get_irq,
+	.set_int_enable = omap_dm_timer_set_int_enable,
+	.set_int_disable = omap_dm_timer_set_int_disable,
+	.free = omap_dm_timer_free,
+	.enable = omap_dm_timer_enable,
+	.disable = omap_dm_timer_disable,
+	.get_fclk = omap_dm_timer_get_fclk,
+	.start = omap_dm_timer_start,
+	.stop = omap_dm_timer_stop,
+	.set_load = omap_dm_timer_set_load,
+	.set_match = omap_dm_timer_set_match,
+	.set_pwm = omap_dm_timer_set_pwm,
+	.set_prescaler = omap_dm_timer_set_prescaler,
+	.read_counter = omap_dm_timer_read_counter,
+	.write_counter = omap_dm_timer_write_counter,
+	.read_status = omap_dm_timer_read_status,
+	.write_status = omap_dm_timer_write_status,
+};
+
 static const struct dmtimer_platform_data omap3plus_pdata = {
 	.timer_errata = OMAP_TIMER_ERRATA_I103_I767,
+	.timer_ops = &dmtimer_ops,
 };
 
 static const struct of_device_id omap_timer_match[] = {
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 833b5f4..7f56fe5 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -239,6 +239,18 @@
 config ARM_SA1110_CPUFREQ
 	bool
 
+config ARM_SCMI_CPUFREQ
+	tristate "SCMI based CPUfreq driver"
+	depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
+	depends on !CPU_THERMAL || THERMAL
+	select PM_OPP
+	help
+	  This adds the CPUfreq driver support for ARM platforms using SCMI
+	  protocol for CPU power management.
+
+	  This driver uses SCMI Message Protocol driver to interact with the
+	  firmware providing the CPU DVFS functionality.
+
 config ARM_SPEAR_CPUFREQ
 	bool "SPEAr CPUFreq support"
 	depends on PLAT_SPEAR
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index b2cbdc0..8d24ade 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -75,6 +75,7 @@
 obj-$(CONFIG_ARM_S5PV210_CPUFREQ)	+= s5pv210-cpufreq.o
 obj-$(CONFIG_ARM_SA1100_CPUFREQ)	+= sa1100-cpufreq.o
 obj-$(CONFIG_ARM_SA1110_CPUFREQ)	+= sa1110-cpufreq.o
+obj-$(CONFIG_ARM_SCMI_CPUFREQ)		+= scmi-cpufreq.o
 obj-$(CONFIG_ARM_SCPI_CPUFREQ)		+= scpi-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)		+= spear-cpufreq.o
 obj-$(CONFIG_ARM_STI_CPUFREQ)		+= sti-cpufreq.o
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
new file mode 100644
index 0000000..959a1db
--- /dev/null
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Power Interface (SCMI) based CPUFreq Interface driver
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ * Sudeep Holla <sudeep.holla@arm.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_cooling.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/scmi_protocol.h>
+#include <linux/types.h>
+
+struct scmi_data {
+	int domain_id;
+	struct device *cpu_dev;
+	struct thermal_cooling_device *cdev;
+};
+
+static const struct scmi_handle *handle;
+
+static unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
+{
+	struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
+	struct scmi_perf_ops *perf_ops = handle->perf_ops;
+	struct scmi_data *priv = policy->driver_data;
+	unsigned long rate;
+	int ret;
+
+	ret = perf_ops->freq_get(handle, priv->domain_id, &rate, false);
+	if (ret)
+		return 0;
+	return rate / 1000;
+}
+
+/*
+ * perf_ops->freq_set is not a synchronous, the actual OPP change will
+ * happen asynchronously and can get notified if the events are
+ * subscribed for by the SCMI firmware
+ */
+static int
+scmi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
+{
+	int ret;
+	struct scmi_data *priv = policy->driver_data;
+	struct scmi_perf_ops *perf_ops = handle->perf_ops;
+	u64 freq = policy->freq_table[index].frequency * 1000;
+
+	ret = perf_ops->freq_set(handle, priv->domain_id, freq, false);
+	if (!ret)
+		arch_set_freq_scale(policy->related_cpus, freq,
+				    policy->cpuinfo.max_freq);
+	return ret;
+}
+
+static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
+					     unsigned int target_freq)
+{
+	struct scmi_data *priv = policy->driver_data;
+	struct scmi_perf_ops *perf_ops = handle->perf_ops;
+
+	if (!perf_ops->freq_set(handle, priv->domain_id,
+				target_freq * 1000, true)) {
+		arch_set_freq_scale(policy->related_cpus, target_freq,
+				    policy->cpuinfo.max_freq);
+		return target_freq;
+	}
+
+	return 0;
+}
+
+static int
+scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
+{
+	int cpu, domain, tdomain;
+	struct device *tcpu_dev;
+
+	domain = handle->perf_ops->device_domain_id(cpu_dev);
+	if (domain < 0)
+		return domain;
+
+	for_each_possible_cpu(cpu) {
+		if (cpu == cpu_dev->id)
+			continue;
+
+		tcpu_dev = get_cpu_device(cpu);
+		if (!tcpu_dev)
+			continue;
+
+		tdomain = handle->perf_ops->device_domain_id(tcpu_dev);
+		if (tdomain == domain)
+			cpumask_set_cpu(cpu, cpumask);
+	}
+
+	return 0;
+}
+
+static int scmi_cpufreq_init(struct cpufreq_policy *policy)
+{
+	int ret;
+	unsigned int latency;
+	struct device *cpu_dev;
+	struct scmi_data *priv;
+	struct cpufreq_frequency_table *freq_table;
+
+	cpu_dev = get_cpu_device(policy->cpu);
+	if (!cpu_dev) {
+		pr_err("failed to get cpu%d device\n", policy->cpu);
+		return -ENODEV;
+	}
+
+	ret = handle->perf_ops->add_opps_to_device(handle, cpu_dev);
+	if (ret) {
+		dev_warn(cpu_dev, "failed to add opps to the device\n");
+		return ret;
+	}
+
+	ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
+	if (ret) {
+		dev_warn(cpu_dev, "failed to get sharing cpumask\n");
+		return ret;
+	}
+
+	ret = dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus);
+	if (ret) {
+		dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	ret = dev_pm_opp_get_opp_count(cpu_dev);
+	if (ret <= 0) {
+		dev_dbg(cpu_dev, "OPP table is not ready, deferring probe\n");
+		ret = -EPROBE_DEFER;
+		goto out_free_opp;
+	}
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		ret = -ENOMEM;
+		goto out_free_opp;
+	}
+
+	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+	if (ret) {
+		dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+		goto out_free_priv;
+	}
+
+	priv->cpu_dev = cpu_dev;
+	priv->domain_id = handle->perf_ops->device_domain_id(cpu_dev);
+
+	policy->driver_data = priv;
+
+	ret = cpufreq_table_validate_and_show(policy, freq_table);
+	if (ret) {
+		dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__,
+			ret);
+		goto out_free_cpufreq_table;
+	}
+
+	/* SCMI allows DVFS request for any domain from any CPU */
+	policy->dvfs_possible_from_any_cpu = true;
+
+	latency = handle->perf_ops->get_transition_latency(handle, cpu_dev);
+	if (!latency)
+		latency = CPUFREQ_ETERNAL;
+
+	policy->cpuinfo.transition_latency = latency;
+
+	policy->fast_switch_possible = true;
+	return 0;
+
+out_free_cpufreq_table:
+	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+out_free_priv:
+	kfree(priv);
+out_free_opp:
+	dev_pm_opp_cpumask_remove_table(policy->cpus);
+
+	return ret;
+}
+
+static int scmi_cpufreq_exit(struct cpufreq_policy *policy)
+{
+	struct scmi_data *priv = policy->driver_data;
+
+	cpufreq_cooling_unregister(priv->cdev);
+	dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
+	kfree(priv);
+	dev_pm_opp_cpumask_remove_table(policy->related_cpus);
+
+	return 0;
+}
+
+static void scmi_cpufreq_ready(struct cpufreq_policy *policy)
+{
+	struct scmi_data *priv = policy->driver_data;
+
+	priv->cdev = of_cpufreq_cooling_register(policy);
+}
+
+static struct cpufreq_driver scmi_cpufreq_driver = {
+	.name	= "scmi",
+	.flags	= CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
+		  CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+	.verify	= cpufreq_generic_frequency_table_verify,
+	.attr	= cpufreq_generic_attr,
+	.target_index	= scmi_cpufreq_set_target,
+	.fast_switch	= scmi_cpufreq_fast_switch,
+	.get	= scmi_cpufreq_get_rate,
+	.init	= scmi_cpufreq_init,
+	.exit	= scmi_cpufreq_exit,
+	.ready	= scmi_cpufreq_ready,
+};
+
+static int scmi_cpufreq_probe(struct scmi_device *sdev)
+{
+	int ret;
+
+	handle = sdev->handle;
+
+	if (!handle || !handle->perf_ops)
+		return -ENODEV;
+
+	ret = cpufreq_register_driver(&scmi_cpufreq_driver);
+	if (ret) {
+		dev_err(&sdev->dev, "%s: registering cpufreq failed, err: %d\n",
+			__func__, ret);
+	}
+
+	return ret;
+}
+
+static void scmi_cpufreq_remove(struct scmi_device *sdev)
+{
+	cpufreq_unregister_driver(&scmi_cpufreq_driver);
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+	{ SCMI_PROTOCOL_PERF },
+	{ },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_cpufreq_drv = {
+	.name		= "scmi-cpufreq",
+	.probe		= scmi_cpufreq_probe,
+	.remove		= scmi_cpufreq_remove,
+	.id_table	= scmi_id_table,
+};
+module_scmi_driver(scmi_cpufreq_drv);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCMI CPUFreq interface driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index cfcb910..da2da53 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -232,9 +232,12 @@
 config EDAC_SKX
 	tristate "Intel Skylake server Integrated MC"
 	depends on PCI && X86_64 && X86_MCE_INTEL && PCI_MMCONFIG
+	select DMI
 	help
 	  Support for error detection and correction the Intel
-	  Skylake server Integrated Memory Controllers.
+	  Skylake server Integrated Memory Controllers. If your
+	  system has non-volatile DIMMs you should also manually
+	  select CONFIG_ACPI_NFIT.
 
 config EDAC_PND2
 	tristate "Intel Pondicherry2"
@@ -254,7 +257,7 @@
 
 config EDAC_LAYERSCAPE
 	tristate "Freescale Layerscape DDR"
-	depends on ARCH_LAYERSCAPE
+	depends on ARCH_LAYERSCAPE || SOC_LS1021A
 	help
 	  Support for error detection and correction on Freescale memory
 	  controllers on Layerscape SoCs.
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 48193f5..3bb82e5 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -195,26 +195,27 @@ static void edac_mc_dump_mci(struct mem_ctl_info *mci)
 #endif				/* CONFIG_EDAC_DEBUG */
 
 const char * const edac_mem_types[] = {
-	[MEM_EMPTY]	= "Empty csrow",
-	[MEM_RESERVED]	= "Reserved csrow type",
-	[MEM_UNKNOWN]	= "Unknown csrow type",
-	[MEM_FPM]	= "Fast page mode RAM",
-	[MEM_EDO]	= "Extended data out RAM",
-	[MEM_BEDO]	= "Burst Extended data out RAM",
-	[MEM_SDR]	= "Single data rate SDRAM",
-	[MEM_RDR]	= "Registered single data rate SDRAM",
-	[MEM_DDR]	= "Double data rate SDRAM",
-	[MEM_RDDR]	= "Registered Double data rate SDRAM",
-	[MEM_RMBS]	= "Rambus DRAM",
-	[MEM_DDR2]	= "Unbuffered DDR2 RAM",
-	[MEM_FB_DDR2]	= "Fully buffered DDR2",
-	[MEM_RDDR2]	= "Registered DDR2 RAM",
-	[MEM_XDR]	= "Rambus XDR",
-	[MEM_DDR3]	= "Unbuffered DDR3 RAM",
-	[MEM_RDDR3]	= "Registered DDR3 RAM",
-	[MEM_LRDDR3]	= "Load-Reduced DDR3 RAM",
-	[MEM_DDR4]	= "Unbuffered DDR4 RAM",
-	[MEM_RDDR4]	= "Registered DDR4 RAM",
+	[MEM_EMPTY]	= "Empty",
+	[MEM_RESERVED]	= "Reserved",
+	[MEM_UNKNOWN]	= "Unknown",
+	[MEM_FPM]	= "FPM",
+	[MEM_EDO]	= "EDO",
+	[MEM_BEDO]	= "BEDO",
+	[MEM_SDR]	= "Unbuffered-SDR",
+	[MEM_RDR]	= "Registered-SDR",
+	[MEM_DDR]	= "Unbuffered-DDR",
+	[MEM_RDDR]	= "Registered-DDR",
+	[MEM_RMBS]	= "RMBS",
+	[MEM_DDR2]	= "Unbuffered-DDR2",
+	[MEM_FB_DDR2]	= "FullyBuffered-DDR2",
+	[MEM_RDDR2]	= "Registered-DDR2",
+	[MEM_XDR]	= "XDR",
+	[MEM_DDR3]	= "Unbuffered-DDR3",
+	[MEM_RDDR3]	= "Registered-DDR3",
+	[MEM_LRDDR3]	= "Load-Reduced-DDR3-RAM",
+	[MEM_DDR4]	= "Unbuffered-DDR4",
+	[MEM_RDDR4]	= "Registered-DDR4",
+	[MEM_NVDIMM]	= "Non-volatile-RAM",
 };
 EXPORT_SYMBOL_GPL(edac_mem_types);
 
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index c70ea82..7481955 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -91,28 +91,6 @@ static struct device *mci_pdev;
 /*
  * various constants for Memory Controllers
  */
-static const char * const mem_types[] = {
-	[MEM_EMPTY] = "Empty",
-	[MEM_RESERVED] = "Reserved",
-	[MEM_UNKNOWN] = "Unknown",
-	[MEM_FPM] = "FPM",
-	[MEM_EDO] = "EDO",
-	[MEM_BEDO] = "BEDO",
-	[MEM_SDR] = "Unbuffered-SDR",
-	[MEM_RDR] = "Registered-SDR",
-	[MEM_DDR] = "Unbuffered-DDR",
-	[MEM_RDDR] = "Registered-DDR",
-	[MEM_RMBS] = "RMBS",
-	[MEM_DDR2] = "Unbuffered-DDR2",
-	[MEM_FB_DDR2] = "FullyBuffered-DDR2",
-	[MEM_RDDR2] = "Registered-DDR2",
-	[MEM_XDR] = "XDR",
-	[MEM_DDR3] = "Unbuffered-DDR3",
-	[MEM_RDDR3] = "Registered-DDR3",
-	[MEM_DDR4] = "Unbuffered-DDR4",
-	[MEM_RDDR4] = "Registered-DDR4"
-};
-
 static const char * const dev_types[] = {
 	[DEV_UNKNOWN] = "Unknown",
 	[DEV_X1] = "x1",
@@ -196,7 +174,7 @@ static ssize_t csrow_mem_type_show(struct device *dev,
 {
 	struct csrow_info *csrow = to_csrow(dev);
 
-	return sprintf(data, "%s\n", mem_types[csrow->channels[0]->dimm->mtype]);
+	return sprintf(data, "%s\n", edac_mem_types[csrow->channels[0]->dimm->mtype]);
 }
 
 static ssize_t csrow_dev_type_show(struct device *dev,
@@ -549,7 +527,7 @@ static ssize_t dimmdev_mem_type_show(struct device *dev,
 {
 	struct dimm_info *dimm = to_dimm(dev);
 
-	return sprintf(data, "%s\n", mem_types[dimm->mtype]);
+	return sprintf(data, "%s\n", edac_mem_types[dimm->mtype]);
 }
 
 static ssize_t dimmdev_dev_type_show(struct device *dev,
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 8721002..4a89c80 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -110,6 +110,10 @@ static const u32 knl_interleave_list[] = {
 	0xdc, 0xe4, 0xec, 0xf4, 0xfc, /* 15-19 */
 	0x104, 0x10c, 0x114, 0x11c,   /* 20-23 */
 };
+#define MAX_INTERLEAVE							\
+	(max_t(unsigned int, ARRAY_SIZE(sbridge_interleave_list),	\
+	       max_t(unsigned int, ARRAY_SIZE(ibridge_interleave_list),	\
+		     ARRAY_SIZE(knl_interleave_list))))
 
 struct interleave_pkg {
 	unsigned char start;
@@ -321,7 +325,6 @@ struct sbridge_info {
 	const u32	*interleave_list;
 	const struct interleave_pkg *interleave_pkg;
 	u8		max_sad;
-	u8		max_interleave;
 	u8		(*get_node_id)(struct sbridge_pvt *pvt);
 	enum mem_type	(*get_memory_type)(struct sbridge_pvt *pvt);
 	enum dev_type	(*get_width)(struct sbridge_pvt *pvt, u32 mtr);
@@ -1899,7 +1902,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
 	int			n_rir, n_sads, n_tads, sad_way, sck_xch;
 	int			sad_interl, idx, base_ch;
 	int			interleave_mode, shiftup = 0;
-	unsigned		sad_interleave[pvt->info.max_interleave];
+	unsigned int		sad_interleave[MAX_INTERLEAVE];
 	u32			reg, dram_rule;
 	u8			ch_way, sck_way, pkg, sad_ha = 0;
 	u32			tad_offset;
@@ -3169,7 +3172,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
 		pvt->info.dram_attr = dram_attr;
 		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
 		pvt->info.interleave_list = ibridge_interleave_list;
-		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
 		pvt->info.interleave_pkg = ibridge_interleave_pkg;
 		pvt->info.get_width = ibridge_get_width;
 
@@ -3194,7 +3196,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
 		pvt->info.dram_attr = dram_attr;
 		pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule);
 		pvt->info.interleave_list = sbridge_interleave_list;
-		pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
 		pvt->info.interleave_pkg = sbridge_interleave_pkg;
 		pvt->info.get_width = sbridge_get_width;
 
@@ -3219,7 +3220,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
 		pvt->info.dram_attr = dram_attr;
 		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
 		pvt->info.interleave_list = ibridge_interleave_list;
-		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
 		pvt->info.interleave_pkg = ibridge_interleave_pkg;
 		pvt->info.get_width = ibridge_get_width;
 
@@ -3244,7 +3244,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
 		pvt->info.dram_attr = dram_attr;
 		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
 		pvt->info.interleave_list = ibridge_interleave_list;
-		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
 		pvt->info.interleave_pkg = ibridge_interleave_pkg;
 		pvt->info.get_width = broadwell_get_width;
 
@@ -3269,7 +3268,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
 		pvt->info.dram_attr = dram_attr_knl;
 		pvt->info.max_sad = ARRAY_SIZE(knl_dram_rule);
 		pvt->info.interleave_list = knl_interleave_list;
-		pvt->info.max_interleave = ARRAY_SIZE(knl_interleave_list);
 		pvt->info.interleave_pkg = ibridge_interleave_pkg;
 		pvt->info.get_width = knl_get_width;
 
diff --git a/drivers/edac/skx_edac.c b/drivers/edac/skx_edac.c
index 912c493..fae0951 100644
--- a/drivers/edac/skx_edac.c
+++ b/drivers/edac/skx_edac.c
@@ -14,6 +14,8 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/slab.h>
@@ -24,6 +26,7 @@
 #include <linux/bitmap.h>
 #include <linux/math64.h>
 #include <linux/mod_devicetable.h>
+#include <acpi/nfit.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 #include <asm/processor.h>
@@ -302,6 +305,7 @@ static int get_dimm_attr(u32 reg, int lobit, int hibit, int add, int minval,
 }
 
 #define IS_DIMM_PRESENT(mtr)		GET_BITFIELD((mtr), 15, 15)
+#define IS_NVDIMM_PRESENT(mcddrtcfg, i)	GET_BITFIELD((mcddrtcfg), (i), (i))
 
 #define numrank(reg) get_dimm_attr((reg), 12, 13, 0, 0, 2, "ranks")
 #define numrow(reg) get_dimm_attr((reg), 2, 4, 12, 1, 6, "rows")
@@ -350,8 +354,6 @@ static int get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm,
 	int  banks = 16, ranks, rows, cols, npages;
 	u64 size;
 
-	if (!IS_DIMM_PRESENT(mtr))
-		return 0;
 	ranks = numrank(mtr);
 	rows = numrow(mtr);
 	cols = numcol(mtr);
@@ -383,6 +385,54 @@ static int get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm,
 	return 1;
 }
 
+static int get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc,
+			   int chan, int dimmno)
+{
+	int smbios_handle;
+	u32 dev_handle;
+	u16 flags;
+	u64 size = 0;
+
+	dev_handle = ACPI_NFIT_BUILD_DEVICE_HANDLE(dimmno, chan, imc->lmc,
+						   imc->src_id, 0);
+
+	smbios_handle = nfit_get_smbios_id(dev_handle, &flags);
+	if (smbios_handle == -EOPNOTSUPP) {
+		pr_warn_once(EDAC_MOD_STR ": Can't find size of NVDIMM. Try enabling CONFIG_ACPI_NFIT\n");
+		goto unknown_size;
+	}
+
+	if (smbios_handle < 0) {
+		skx_printk(KERN_ERR, "Can't find handle for NVDIMM ADR=%x\n", dev_handle);
+		goto unknown_size;
+	}
+
+	if (flags & ACPI_NFIT_MEM_MAP_FAILED) {
+		skx_printk(KERN_ERR, "NVDIMM ADR=%x is not mapped\n", dev_handle);
+		goto unknown_size;
+	}
+
+	size = dmi_memdev_size(smbios_handle);
+	if (size == ~0ull)
+		skx_printk(KERN_ERR, "Can't find size for NVDIMM ADR=%x/SMBIOS=%x\n",
+			   dev_handle, smbios_handle);
+
+unknown_size:
+	dimm->nr_pages = size >> PAGE_SHIFT;
+	dimm->grain = 32;
+	dimm->dtype = DEV_UNKNOWN;
+	dimm->mtype = MEM_NVDIMM;
+	dimm->edac_mode = EDAC_SECDED; /* likely better than this */
+
+	edac_dbg(0, "mc#%d: channel %d, dimm %d, %llu Mb (%u pages)\n",
+		 imc->mc, chan, dimmno, size >> 20, dimm->nr_pages);
+
+	snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
+		 imc->src_id, imc->lmc, chan, dimmno);
+
+	return (size == 0 || size == ~0ull) ? 0 : 1;
+}
+
 #define SKX_GET_MTMTR(dev, reg) \
 	pci_read_config_dword((dev), 0x87c, &reg)
 
@@ -399,20 +449,24 @@ static int skx_get_dimm_config(struct mem_ctl_info *mci)
 {
 	struct skx_pvt *pvt = mci->pvt_info;
 	struct skx_imc *imc = pvt->imc;
+	u32 mtr, amap, mcddrtcfg;
 	struct dimm_info *dimm;
 	int i, j;
-	u32 mtr, amap;
 	int ndimms;
 
 	for (i = 0; i < NUM_CHANNELS; i++) {
 		ndimms = 0;
 		pci_read_config_dword(imc->chan[i].cdev, 0x8C, &amap);
+		pci_read_config_dword(imc->chan[i].cdev, 0x400, &mcddrtcfg);
 		for (j = 0; j < NUM_DIMMS; j++) {
 			dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
 					     mci->n_layers, i, j, 0);
 			pci_read_config_dword(imc->chan[i].cdev,
 					0x80 + 4*j, &mtr);
-			ndimms += get_dimm_info(mtr, amap, dimm, imc, i, j);
+			if (IS_DIMM_PRESENT(mtr))
+				ndimms += get_dimm_info(mtr, amap, dimm, imc, i, j);
+			else if (IS_NVDIMM_PRESENT(mcddrtcfg, j))
+				ndimms += get_nvdimm_info(dimm, imc, i, j);
 		}
 		if (ndimms && !skx_check_ecc(imc->chan[0].cdev)) {
 			skx_printk(KERN_ERR, "ECC is disabled on imc %d\n", imc->mc);
@@ -468,13 +522,14 @@ static int skx_register_mci(struct skx_imc *imc)
 	pvt = mci->pvt_info;
 	pvt->imc = imc;
 
-	mci->ctl_name = kasprintf(GFP_KERNEL, "Skylake Socket#%d IMC#%d", imc->node_id, imc->lmc);
+	mci->ctl_name = kasprintf(GFP_KERNEL, "Skylake Socket#%d IMC#%d",
+				  imc->node_id, imc->lmc);
 	if (!mci->ctl_name) {
 		rc = -ENOMEM;
 		goto fail0;
 	}
 
-	mci->mtype_cap = MEM_FLAG_DDR4;
+	mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_NVDIMM;
 	mci->edac_ctl_cap = EDAC_FLAG_NONE;
 	mci->edac_cap = EDAC_FLAG_NONE;
 	mci->mod_name = EDAC_MOD_STR;
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index b7c7482..6e83880 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -19,6 +19,40 @@
 	  on and off through hotplug, so for now torture tests and PSCI checker
 	  are mutually exclusive.
 
+config ARM_SCMI_PROTOCOL
+	bool "ARM System Control and Management Interface (SCMI) Message Protocol"
+	depends on ARM || ARM64 || COMPILE_TEST
+	depends on MAILBOX
+	help
+	  ARM System Control and Management Interface (SCMI) protocol is a
+	  set of operating system-independent software interfaces that are
+	  used in system management. SCMI is extensible and currently provides
+	  interfaces for: Discovery and self-description of the interfaces
+	  it supports, Power domain management which is the ability to place
+	  a given device or domain into the various power-saving states that
+	  it supports, Performance management which is the ability to control
+	  the performance of a domain that is composed of compute engines
+	  such as application processors and other accelerators, Clock
+	  management which is the ability to set and inquire rates on platform
+	  managed clocks and Sensor management which is the ability to read
+	  sensor data, and be notified of sensor value.
+
+	  This protocol library provides interface for all the client drivers
+	  making use of the features offered by the SCMI.
+
+config ARM_SCMI_POWER_DOMAIN
+	tristate "SCMI power domain driver"
+	depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
+	default y
+	select PM_GENERIC_DOMAINS if PM
+	help
+	  This enables support for the SCMI power domains which can be
+	  enabled or disabled via the SCP firmware
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called scmi_pm_domain. Note this may needed early in boot
+	  before rootfs may be available.
+
 config ARM_SCPI_PROTOCOL
 	tristate "ARM System Control and Power Interface (SCPI) Message Protocol"
 	depends on ARM || ARM64 || COMPILE_TEST
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index b248238..e18a041 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -25,6 +25,7 @@
 CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a
 obj-$(CONFIG_TI_SCI_PROTOCOL)	+= ti_sci.o
 
+obj-$(CONFIG_ARM_SCMI_PROTOCOL)	+= arm_scmi/
 obj-y				+= broadcom/
 obj-y				+= meson/
 obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
new file mode 100644
index 0000000..99e36c5
--- /dev/null
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -0,0 +1,5 @@
+obj-y	= scmi-bus.o scmi-driver.o scmi-protocols.o
+scmi-bus-y = bus.o
+scmi-driver-y = driver.o
+scmi-protocols-y = base.o clock.o perf.o power.o sensors.o
+obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
new file mode 100644
index 0000000..0d3806c
--- /dev/null
+++ b/drivers/firmware/arm_scmi/base.c
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Base Protocol
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include "common.h"
+
+enum scmi_base_protocol_cmd {
+	BASE_DISCOVER_VENDOR = 0x3,
+	BASE_DISCOVER_SUB_VENDOR = 0x4,
+	BASE_DISCOVER_IMPLEMENT_VERSION = 0x5,
+	BASE_DISCOVER_LIST_PROTOCOLS = 0x6,
+	BASE_DISCOVER_AGENT = 0x7,
+	BASE_NOTIFY_ERRORS = 0x8,
+};
+
+struct scmi_msg_resp_base_attributes {
+	u8 num_protocols;
+	u8 num_agents;
+	__le16 reserved;
+};
+
+/**
+ * scmi_base_attributes_get() - gets the implementation details
+ *	that are associated with the base protocol.
+ *
+ * @handle - SCMI entity handle
+ *
+ * Return: 0 on success, else appropriate SCMI error.
+ */
+static int scmi_base_attributes_get(const struct scmi_handle *handle)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_base_attributes *attr_info;
+	struct scmi_revision_info *rev = handle->version;
+
+	ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES,
+				 SCMI_PROTOCOL_BASE, 0, sizeof(*attr_info), &t);
+	if (ret)
+		return ret;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		attr_info = t->rx.buf;
+		rev->num_protocols = attr_info->num_protocols;
+		rev->num_agents = attr_info->num_agents;
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+/**
+ * scmi_base_vendor_id_get() - gets vendor/subvendor identifier ASCII string.
+ *
+ * @handle - SCMI entity handle
+ * @sub_vendor - specify true if sub-vendor ID is needed
+ *
+ * Return: 0 on success, else appropriate SCMI error.
+ */
+static int
+scmi_base_vendor_id_get(const struct scmi_handle *handle, bool sub_vendor)
+{
+	u8 cmd;
+	int ret, size;
+	char *vendor_id;
+	struct scmi_xfer *t;
+	struct scmi_revision_info *rev = handle->version;
+
+	if (sub_vendor) {
+		cmd = BASE_DISCOVER_SUB_VENDOR;
+		vendor_id = rev->sub_vendor_id;
+		size = ARRAY_SIZE(rev->sub_vendor_id);
+	} else {
+		cmd = BASE_DISCOVER_VENDOR;
+		vendor_id = rev->vendor_id;
+		size = ARRAY_SIZE(rev->vendor_id);
+	}
+
+	ret = scmi_one_xfer_init(handle, cmd, SCMI_PROTOCOL_BASE, 0, size, &t);
+	if (ret)
+		return ret;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret)
+		memcpy(vendor_id, t->rx.buf, size);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+/**
+ * scmi_base_implementation_version_get() - gets a vendor-specific
+ *	implementation 32-bit version. The format of the version number is
+ *	vendor-specific
+ *
+ * @handle - SCMI entity handle
+ *
+ * Return: 0 on success, else appropriate SCMI error.
+ */
+static int
+scmi_base_implementation_version_get(const struct scmi_handle *handle)
+{
+	int ret;
+	__le32 *impl_ver;
+	struct scmi_xfer *t;
+	struct scmi_revision_info *rev = handle->version;
+
+	ret = scmi_one_xfer_init(handle, BASE_DISCOVER_IMPLEMENT_VERSION,
+				 SCMI_PROTOCOL_BASE, 0, sizeof(*impl_ver), &t);
+	if (ret)
+		return ret;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		impl_ver = t->rx.buf;
+		rev->impl_ver = le32_to_cpu(*impl_ver);
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+/**
+ * scmi_base_implementation_list_get() - gets the list of protocols it is
+ *	OSPM is allowed to access
+ *
+ * @handle - SCMI entity handle
+ * @protocols_imp - pointer to hold the list of protocol identifiers
+ *
+ * Return: 0 on success, else appropriate SCMI error.
+ */
+static int scmi_base_implementation_list_get(const struct scmi_handle *handle,
+					     u8 *protocols_imp)
+{
+	u8 *list;
+	int ret, loop;
+	struct scmi_xfer *t;
+	__le32 *num_skip, *num_ret;
+	u32 tot_num_ret = 0, loop_num_ret;
+	struct device *dev = handle->dev;
+
+	ret = scmi_one_xfer_init(handle, BASE_DISCOVER_LIST_PROTOCOLS,
+				 SCMI_PROTOCOL_BASE, sizeof(*num_skip), 0, &t);
+	if (ret)
+		return ret;
+
+	num_skip = t->tx.buf;
+	num_ret = t->rx.buf;
+	list = t->rx.buf + sizeof(*num_ret);
+
+	do {
+		/* Set the number of protocols to be skipped/already read */
+		*num_skip = cpu_to_le32(tot_num_ret);
+
+		ret = scmi_do_xfer(handle, t);
+		if (ret)
+			break;
+
+		loop_num_ret = le32_to_cpu(*num_ret);
+		if (tot_num_ret + loop_num_ret > MAX_PROTOCOLS_IMP) {
+			dev_err(dev, "No. of Protocol > MAX_PROTOCOLS_IMP");
+			break;
+		}
+
+		for (loop = 0; loop < loop_num_ret; loop++)
+			protocols_imp[tot_num_ret + loop] = *(list + loop);
+
+		tot_num_ret += loop_num_ret;
+	} while (loop_num_ret);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+/**
+ * scmi_base_discover_agent_get() - discover the name of an agent
+ *
+ * @handle - SCMI entity handle
+ * @id - Agent identifier
+ * @name - Agent identifier ASCII string
+ *
+ * An agent id of 0 is reserved to identify the platform itself.
+ * Generally operating system is represented as "OSPM"
+ *
+ * Return: 0 on success, else appropriate SCMI error.
+ */
+static int scmi_base_discover_agent_get(const struct scmi_handle *handle,
+					int id, char *name)
+{
+	int ret;
+	struct scmi_xfer *t;
+
+	ret = scmi_one_xfer_init(handle, BASE_DISCOVER_AGENT,
+				 SCMI_PROTOCOL_BASE, sizeof(__le32),
+				 SCMI_MAX_STR_SIZE, &t);
+	if (ret)
+		return ret;
+
+	*(__le32 *)t->tx.buf = cpu_to_le32(id);
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret)
+		memcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+int scmi_base_protocol_init(struct scmi_handle *h)
+{
+	int id, ret;
+	u8 *prot_imp;
+	u32 version;
+	char name[SCMI_MAX_STR_SIZE];
+	const struct scmi_handle *handle = h;
+	struct device *dev = handle->dev;
+	struct scmi_revision_info *rev = handle->version;
+
+	ret = scmi_version_get(handle, SCMI_PROTOCOL_BASE, &version);
+	if (ret)
+		return ret;
+
+	prot_imp = devm_kcalloc(dev, MAX_PROTOCOLS_IMP, sizeof(u8), GFP_KERNEL);
+	if (!prot_imp)
+		return -ENOMEM;
+
+	rev->major_ver = PROTOCOL_REV_MAJOR(version),
+	rev->minor_ver = PROTOCOL_REV_MINOR(version);
+
+	scmi_base_attributes_get(handle);
+	scmi_base_vendor_id_get(handle, false);
+	scmi_base_vendor_id_get(handle, true);
+	scmi_base_implementation_version_get(handle);
+	scmi_base_implementation_list_get(handle, prot_imp);
+	scmi_setup_protocol_implemented(handle, prot_imp);
+
+	dev_info(dev, "SCMI Protocol v%d.%d '%s:%s' Firmware version 0x%x\n",
+		 rev->major_ver, rev->minor_ver, rev->vendor_id,
+		 rev->sub_vendor_id, rev->impl_ver);
+	dev_dbg(dev, "Found %d protocol(s) %d agent(s)\n", rev->num_protocols,
+		rev->num_agents);
+
+	for (id = 0; id < rev->num_agents; id++) {
+		scmi_base_discover_agent_get(handle, id, name);
+		dev_dbg(dev, "Agent %d: %s\n", id, name);
+	}
+
+	return 0;
+}
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
new file mode 100644
index 0000000..f2760a5
--- /dev/null
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Message Protocol bus layer
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+
+#include "common.h"
+
+static DEFINE_IDA(scmi_bus_id);
+static DEFINE_IDR(scmi_protocols);
+static DEFINE_SPINLOCK(protocol_lock);
+
+static const struct scmi_device_id *
+scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
+{
+	const struct scmi_device_id *id = scmi_drv->id_table;
+
+	if (!id)
+		return NULL;
+
+	for (; id->protocol_id; id++)
+		if (id->protocol_id == scmi_dev->protocol_id)
+			return id;
+
+	return NULL;
+}
+
+static int scmi_dev_match(struct device *dev, struct device_driver *drv)
+{
+	struct scmi_driver *scmi_drv = to_scmi_driver(drv);
+	struct scmi_device *scmi_dev = to_scmi_dev(dev);
+	const struct scmi_device_id *id;
+
+	id = scmi_dev_match_id(scmi_dev, scmi_drv);
+	if (id)
+		return 1;
+
+	return 0;
+}
+
+static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
+{
+	scmi_prot_init_fn_t fn = idr_find(&scmi_protocols, protocol_id);
+
+	if (unlikely(!fn))
+		return -EINVAL;
+	return fn(handle);
+}
+
+static int scmi_dev_probe(struct device *dev)
+{
+	struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
+	struct scmi_device *scmi_dev = to_scmi_dev(dev);
+	const struct scmi_device_id *id;
+	int ret;
+
+	id = scmi_dev_match_id(scmi_dev, scmi_drv);
+	if (!id)
+		return -ENODEV;
+
+	if (!scmi_dev->handle)
+		return -EPROBE_DEFER;
+
+	ret = scmi_protocol_init(scmi_dev->protocol_id, scmi_dev->handle);
+	if (ret)
+		return ret;
+
+	return scmi_drv->probe(scmi_dev);
+}
+
+static int scmi_dev_remove(struct device *dev)
+{
+	struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
+	struct scmi_device *scmi_dev = to_scmi_dev(dev);
+
+	if (scmi_drv->remove)
+		scmi_drv->remove(scmi_dev);
+
+	return 0;
+}
+
+static struct bus_type scmi_bus_type = {
+	.name =	"scmi_protocol",
+	.match = scmi_dev_match,
+	.probe = scmi_dev_probe,
+	.remove = scmi_dev_remove,
+};
+
+int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
+			 const char *mod_name)
+{
+	int retval;
+
+	driver->driver.bus = &scmi_bus_type;
+	driver->driver.name = driver->name;
+	driver->driver.owner = owner;
+	driver->driver.mod_name = mod_name;
+
+	retval = driver_register(&driver->driver);
+	if (!retval)
+		pr_debug("registered new scmi driver %s\n", driver->name);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(scmi_driver_register);
+
+void scmi_driver_unregister(struct scmi_driver *driver)
+{
+	driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(scmi_driver_unregister);
+
+struct scmi_device *
+scmi_device_create(struct device_node *np, struct device *parent, int protocol)
+{
+	int id, retval;
+	struct scmi_device *scmi_dev;
+
+	id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
+	if (id < 0)
+		return NULL;
+
+	scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL);
+	if (!scmi_dev)
+		goto no_mem;
+
+	scmi_dev->id = id;
+	scmi_dev->protocol_id = protocol;
+	scmi_dev->dev.parent = parent;
+	scmi_dev->dev.of_node = np;
+	scmi_dev->dev.bus = &scmi_bus_type;
+	dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
+
+	retval = device_register(&scmi_dev->dev);
+	if (!retval)
+		return scmi_dev;
+
+	put_device(&scmi_dev->dev);
+	kfree(scmi_dev);
+no_mem:
+	ida_simple_remove(&scmi_bus_id, id);
+	return NULL;
+}
+
+void scmi_device_destroy(struct scmi_device *scmi_dev)
+{
+	scmi_handle_put(scmi_dev->handle);
+	device_unregister(&scmi_dev->dev);
+	ida_simple_remove(&scmi_bus_id, scmi_dev->id);
+	kfree(scmi_dev);
+}
+
+void scmi_set_handle(struct scmi_device *scmi_dev)
+{
+	scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
+}
+
+int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn)
+{
+	int ret;
+
+	spin_lock(&protocol_lock);
+	ret = idr_alloc(&scmi_protocols, fn, protocol_id, protocol_id + 1,
+			GFP_ATOMIC);
+	if (ret != protocol_id)
+		pr_err("unable to allocate SCMI idr slot, err %d\n", ret);
+	spin_unlock(&protocol_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(scmi_protocol_register);
+
+void scmi_protocol_unregister(int protocol_id)
+{
+	spin_lock(&protocol_lock);
+	idr_remove(&scmi_protocols, protocol_id);
+	spin_unlock(&protocol_lock);
+}
+EXPORT_SYMBOL_GPL(scmi_protocol_unregister);
+
+static int __scmi_devices_unregister(struct device *dev, void *data)
+{
+	struct scmi_device *scmi_dev = to_scmi_dev(dev);
+
+	scmi_device_destroy(scmi_dev);
+	return 0;
+}
+
+static void scmi_devices_unregister(void)
+{
+	bus_for_each_dev(&scmi_bus_type, NULL, NULL, __scmi_devices_unregister);
+}
+
+static int __init scmi_bus_init(void)
+{
+	int retval;
+
+	retval = bus_register(&scmi_bus_type);
+	if (retval)
+		pr_err("scmi protocol bus register failed (%d)\n", retval);
+
+	return retval;
+}
+subsys_initcall(scmi_bus_init);
+
+static void __exit scmi_bus_exit(void)
+{
+	scmi_devices_unregister();
+	bus_unregister(&scmi_bus_type);
+	ida_destroy(&scmi_bus_id);
+}
+module_exit(scmi_bus_exit);
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
new file mode 100644
index 0000000..e6f1782
--- /dev/null
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Clock Protocol
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include "common.h"
+
+enum scmi_clock_protocol_cmd {
+	CLOCK_ATTRIBUTES = 0x3,
+	CLOCK_DESCRIBE_RATES = 0x4,
+	CLOCK_RATE_SET = 0x5,
+	CLOCK_RATE_GET = 0x6,
+	CLOCK_CONFIG_SET = 0x7,
+};
+
+struct scmi_msg_resp_clock_protocol_attributes {
+	__le16 num_clocks;
+	u8 max_async_req;
+	u8 reserved;
+};
+
+struct scmi_msg_resp_clock_attributes {
+	__le32 attributes;
+#define	CLOCK_ENABLE	BIT(0)
+	    u8 name[SCMI_MAX_STR_SIZE];
+};
+
+struct scmi_clock_set_config {
+	__le32 id;
+	__le32 attributes;
+};
+
+struct scmi_msg_clock_describe_rates {
+	__le32 id;
+	__le32 rate_index;
+};
+
+struct scmi_msg_resp_clock_describe_rates {
+	__le32 num_rates_flags;
+#define NUM_RETURNED(x)		((x) & 0xfff)
+#define RATE_DISCRETE(x)	!((x) & BIT(12))
+#define NUM_REMAINING(x)	((x) >> 16)
+	struct {
+		__le32 value_low;
+		__le32 value_high;
+	} rate[0];
+#define RATE_TO_U64(X)		\
+({				\
+	typeof(X) x = (X);	\
+	le32_to_cpu((x).value_low) | (u64)le32_to_cpu((x).value_high) << 32; \
+})
+};
+
+struct scmi_clock_set_rate {
+	__le32 flags;
+#define CLOCK_SET_ASYNC		BIT(0)
+#define CLOCK_SET_DELAYED	BIT(1)
+#define CLOCK_SET_ROUND_UP	BIT(2)
+#define CLOCK_SET_ROUND_AUTO	BIT(3)
+	__le32 id;
+	__le32 value_low;
+	__le32 value_high;
+};
+
+struct clock_info {
+	int num_clocks;
+	int max_async_req;
+	struct scmi_clock_info *clk;
+};
+
+static int scmi_clock_protocol_attributes_get(const struct scmi_handle *handle,
+					      struct clock_info *ci)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_clock_protocol_attributes *attr;
+
+	ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES,
+				 SCMI_PROTOCOL_CLOCK, 0, sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	attr = t->rx.buf;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		ci->num_clocks = le16_to_cpu(attr->num_clocks);
+		ci->max_async_req = attr->max_async_req;
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_clock_attributes_get(const struct scmi_handle *handle,
+				     u32 clk_id, struct scmi_clock_info *clk)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_clock_attributes *attr;
+
+	ret = scmi_one_xfer_init(handle, CLOCK_ATTRIBUTES, SCMI_PROTOCOL_CLOCK,
+				 sizeof(clk_id), sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	*(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
+	attr = t->rx.buf;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret)
+		memcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);
+	else
+		clk->name[0] = '\0';
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int
+scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
+			      struct scmi_clock_info *clk)
+{
+	u64 *rate;
+	int ret, cnt;
+	bool rate_discrete = false;
+	u32 tot_rate_cnt = 0, rates_flag;
+	u16 num_returned, num_remaining;
+	struct scmi_xfer *t;
+	struct scmi_msg_clock_describe_rates *clk_desc;
+	struct scmi_msg_resp_clock_describe_rates *rlist;
+
+	ret = scmi_one_xfer_init(handle, CLOCK_DESCRIBE_RATES,
+				 SCMI_PROTOCOL_CLOCK, sizeof(*clk_desc), 0, &t);
+	if (ret)
+		return ret;
+
+	clk_desc = t->tx.buf;
+	rlist = t->rx.buf;
+
+	do {
+		clk_desc->id = cpu_to_le32(clk_id);
+		/* Set the number of rates to be skipped/already read */
+		clk_desc->rate_index = cpu_to_le32(tot_rate_cnt);
+
+		ret = scmi_do_xfer(handle, t);
+		if (ret)
+			goto err;
+
+		rates_flag = le32_to_cpu(rlist->num_rates_flags);
+		num_remaining = NUM_REMAINING(rates_flag);
+		rate_discrete = RATE_DISCRETE(rates_flag);
+		num_returned = NUM_RETURNED(rates_flag);
+
+		if (tot_rate_cnt + num_returned > SCMI_MAX_NUM_RATES) {
+			dev_err(handle->dev, "No. of rates > MAX_NUM_RATES");
+			break;
+		}
+
+		if (!rate_discrete) {
+			clk->range.min_rate = RATE_TO_U64(rlist->rate[0]);
+			clk->range.max_rate = RATE_TO_U64(rlist->rate[1]);
+			clk->range.step_size = RATE_TO_U64(rlist->rate[2]);
+			dev_dbg(handle->dev, "Min %llu Max %llu Step %llu Hz\n",
+				clk->range.min_rate, clk->range.max_rate,
+				clk->range.step_size);
+			break;
+		}
+
+		rate = &clk->list.rates[tot_rate_cnt];
+		for (cnt = 0; cnt < num_returned; cnt++, rate++) {
+			*rate = RATE_TO_U64(rlist->rate[cnt]);
+			dev_dbg(handle->dev, "Rate %llu Hz\n", *rate);
+		}
+
+		tot_rate_cnt += num_returned;
+		/*
+		 * check for both returned and remaining to avoid infinite
+		 * loop due to buggy firmware
+		 */
+	} while (num_returned && num_remaining);
+
+	if (rate_discrete)
+		clk->list.num_rates = tot_rate_cnt;
+
+err:
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int
+scmi_clock_rate_get(const struct scmi_handle *handle, u32 clk_id, u64 *value)
+{
+	int ret;
+	struct scmi_xfer *t;
+
+	ret = scmi_one_xfer_init(handle, CLOCK_RATE_GET, SCMI_PROTOCOL_CLOCK,
+				 sizeof(__le32), sizeof(u64), &t);
+	if (ret)
+		return ret;
+
+	*(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		__le32 *pval = t->rx.buf;
+
+		*value = le32_to_cpu(*pval);
+		*value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_clock_rate_set(const struct scmi_handle *handle, u32 clk_id,
+			       u32 config, u64 rate)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_clock_set_rate *cfg;
+
+	ret = scmi_one_xfer_init(handle, CLOCK_RATE_SET, SCMI_PROTOCOL_CLOCK,
+				 sizeof(*cfg), 0, &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->flags = cpu_to_le32(config);
+	cfg->id = cpu_to_le32(clk_id);
+	cfg->value_low = cpu_to_le32(rate & 0xffffffff);
+	cfg->value_high = cpu_to_le32(rate >> 32);
+
+	ret = scmi_do_xfer(handle, t);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int
+scmi_clock_config_set(const struct scmi_handle *handle, u32 clk_id, u32 config)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_clock_set_config *cfg;
+
+	ret = scmi_one_xfer_init(handle, CLOCK_CONFIG_SET, SCMI_PROTOCOL_CLOCK,
+				 sizeof(*cfg), 0, &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->id = cpu_to_le32(clk_id);
+	cfg->attributes = cpu_to_le32(config);
+
+	ret = scmi_do_xfer(handle, t);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_clock_enable(const struct scmi_handle *handle, u32 clk_id)
+{
+	return scmi_clock_config_set(handle, clk_id, CLOCK_ENABLE);
+}
+
+static int scmi_clock_disable(const struct scmi_handle *handle, u32 clk_id)
+{
+	return scmi_clock_config_set(handle, clk_id, 0);
+}
+
+static int scmi_clock_count_get(const struct scmi_handle *handle)
+{
+	struct clock_info *ci = handle->clk_priv;
+
+	return ci->num_clocks;
+}
+
+static const struct scmi_clock_info *
+scmi_clock_info_get(const struct scmi_handle *handle, u32 clk_id)
+{
+	struct clock_info *ci = handle->clk_priv;
+	struct scmi_clock_info *clk = ci->clk + clk_id;
+
+	if (!clk->name || !clk->name[0])
+		return NULL;
+
+	return clk;
+}
+
+static struct scmi_clk_ops clk_ops = {
+	.count_get = scmi_clock_count_get,
+	.info_get = scmi_clock_info_get,
+	.rate_get = scmi_clock_rate_get,
+	.rate_set = scmi_clock_rate_set,
+	.enable = scmi_clock_enable,
+	.disable = scmi_clock_disable,
+};
+
+static int scmi_clock_protocol_init(struct scmi_handle *handle)
+{
+	u32 version;
+	int clkid, ret;
+	struct clock_info *cinfo;
+
+	scmi_version_get(handle, SCMI_PROTOCOL_CLOCK, &version);
+
+	dev_dbg(handle->dev, "Clock Version %d.%d\n",
+		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+	cinfo = devm_kzalloc(handle->dev, sizeof(*cinfo), GFP_KERNEL);
+	if (!cinfo)
+		return -ENOMEM;
+
+	scmi_clock_protocol_attributes_get(handle, cinfo);
+
+	cinfo->clk = devm_kcalloc(handle->dev, cinfo->num_clocks,
+				  sizeof(*cinfo->clk), GFP_KERNEL);
+	if (!cinfo->clk)
+		return -ENOMEM;
+
+	for (clkid = 0; clkid < cinfo->num_clocks; clkid++) {
+		struct scmi_clock_info *clk = cinfo->clk + clkid;
+
+		ret = scmi_clock_attributes_get(handle, clkid, clk);
+		if (!ret)
+			scmi_clock_describe_rates_get(handle, clkid, clk);
+	}
+
+	handle->clk_ops = &clk_ops;
+	handle->clk_priv = cinfo;
+
+	return 0;
+}
+
+static int __init scmi_clock_init(void)
+{
+	return scmi_protocol_register(SCMI_PROTOCOL_CLOCK,
+				      &scmi_clock_protocol_init);
+}
+subsys_initcall(scmi_clock_init);
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
new file mode 100644
index 0000000..0c30234
--- /dev/null
+++ b/drivers/firmware/arm_scmi/common.h
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Message Protocol
+ * driver common header file containing some definitions, structures
+ * and function prototypes used in all the different SCMI protocols.
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/scmi_protocol.h>
+#include <linux/types.h>
+
+#define PROTOCOL_REV_MINOR_BITS	16
+#define PROTOCOL_REV_MINOR_MASK	((1U << PROTOCOL_REV_MINOR_BITS) - 1)
+#define PROTOCOL_REV_MAJOR(x)	((x) >> PROTOCOL_REV_MINOR_BITS)
+#define PROTOCOL_REV_MINOR(x)	((x) & PROTOCOL_REV_MINOR_MASK)
+#define MAX_PROTOCOLS_IMP	16
+#define MAX_OPPS		16
+
+enum scmi_common_cmd {
+	PROTOCOL_VERSION = 0x0,
+	PROTOCOL_ATTRIBUTES = 0x1,
+	PROTOCOL_MESSAGE_ATTRIBUTES = 0x2,
+};
+
+/**
+ * struct scmi_msg_resp_prot_version - Response for a message
+ *
+ * @major_version: Major version of the ABI that firmware supports
+ * @minor_version: Minor version of the ABI that firmware supports
+ *
+ * In general, ABI version changes follow the rule that minor version increments
+ * are backward compatible. Major revision changes in ABI may not be
+ * backward compatible.
+ *
+ * Response to a generic message with message type SCMI_MSG_VERSION
+ */
+struct scmi_msg_resp_prot_version {
+	__le16 minor_version;
+	__le16 major_version;
+};
+
+/**
+ * struct scmi_msg_hdr - Message(Tx/Rx) header
+ *
+ * @id: The identifier of the command being sent
+ * @protocol_id: The identifier of the protocol used to send @id command
+ * @seq: The token to identify the message. when a message/command returns,
+ *       the platform returns the whole message header unmodified including
+ *	 the token.
+ */
+struct scmi_msg_hdr {
+	u8 id;
+	u8 protocol_id;
+	u16 seq;
+	u32 status;
+	bool poll_completion;
+};
+
+/**
+ * struct scmi_msg - Message(Tx/Rx) structure
+ *
+ * @buf: Buffer pointer
+ * @len: Length of data in the Buffer
+ */
+struct scmi_msg {
+	void *buf;
+	size_t len;
+};
+
+/**
+ * struct scmi_xfer - Structure representing a message flow
+ *
+ * @hdr: Transmit message header
+ * @tx: Transmit message
+ * @rx: Receive message, the buffer should be pre-allocated to store
+ *	message. If request-ACK protocol is used, we can reuse the same
+ *	buffer for the rx path as we use for the tx path.
+ * @done: completion event
+ */
+
+struct scmi_xfer {
+	void *con_priv;
+	struct scmi_msg_hdr hdr;
+	struct scmi_msg tx;
+	struct scmi_msg rx;
+	struct completion done;
+};
+
+void scmi_one_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer);
+int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer);
+int scmi_one_xfer_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id,
+		       size_t tx_size, size_t rx_size, struct scmi_xfer **p);
+int scmi_handle_put(const struct scmi_handle *handle);
+struct scmi_handle *scmi_handle_get(struct device *dev);
+void scmi_set_handle(struct scmi_device *scmi_dev);
+int scmi_version_get(const struct scmi_handle *h, u8 protocol, u32 *version);
+void scmi_setup_protocol_implemented(const struct scmi_handle *handle,
+				     u8 *prot_imp);
+
+int scmi_base_protocol_init(struct scmi_handle *h);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
new file mode 100644
index 0000000..14b1471
--- /dev/null
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -0,0 +1,871 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Message Protocol driver
+ *
+ * SCMI Message Protocol is used between the System Control Processor(SCP)
+ * and the Application Processors(AP). The Message Handling Unit(MHU)
+ * provides a mechanism for inter-processor communication between SCP's
+ * Cortex M3 and AP.
+ *
+ * SCP offers control and management of the core/cluster power states,
+ * various power domain DVFS including the core/cluster, certain system
+ * clocks configuration, thermal sensors and many others.
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include <linux/bitmap.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/ktime.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/processor.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+
+#include "common.h"
+
+#define MSG_ID_SHIFT		0
+#define MSG_ID_MASK		0xff
+#define MSG_TYPE_SHIFT		8
+#define MSG_TYPE_MASK		0x3
+#define MSG_PROTOCOL_ID_SHIFT	10
+#define MSG_PROTOCOL_ID_MASK	0xff
+#define MSG_TOKEN_ID_SHIFT	18
+#define MSG_TOKEN_ID_MASK	0x3ff
+#define MSG_XTRACT_TOKEN(header)	\
+	(((header) >> MSG_TOKEN_ID_SHIFT) & MSG_TOKEN_ID_MASK)
+
+enum scmi_error_codes {
+	SCMI_SUCCESS = 0,	/* Success */
+	SCMI_ERR_SUPPORT = -1,	/* Not supported */
+	SCMI_ERR_PARAMS = -2,	/* Invalid Parameters */
+	SCMI_ERR_ACCESS = -3,	/* Invalid access/permission denied */
+	SCMI_ERR_ENTRY = -4,	/* Not found */
+	SCMI_ERR_RANGE = -5,	/* Value out of range */
+	SCMI_ERR_BUSY = -6,	/* Device busy */
+	SCMI_ERR_COMMS = -7,	/* Communication Error */
+	SCMI_ERR_GENERIC = -8,	/* Generic Error */
+	SCMI_ERR_HARDWARE = -9,	/* Hardware Error */
+	SCMI_ERR_PROTOCOL = -10,/* Protocol Error */
+	SCMI_ERR_MAX
+};
+
+/* List of all  SCMI devices active in system */
+static LIST_HEAD(scmi_list);
+/* Protection for the entire list */
+static DEFINE_MUTEX(scmi_list_mutex);
+
+/**
+ * struct scmi_xfers_info - Structure to manage transfer information
+ *
+ * @xfer_block: Preallocated Message array
+ * @xfer_alloc_table: Bitmap table for allocated messages.
+ *	Index of this bitmap table is also used for message
+ *	sequence identifier.
+ * @xfer_lock: Protection for message allocation
+ */
+struct scmi_xfers_info {
+	struct scmi_xfer *xfer_block;
+	unsigned long *xfer_alloc_table;
+	/* protect transfer allocation */
+	spinlock_t xfer_lock;
+};
+
+/**
+ * struct scmi_desc - Description of SoC integration
+ *
+ * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
+ * @max_msg: Maximum number of messages that can be pending
+ *	simultaneously in the system
+ * @max_msg_size: Maximum size of data per message that can be handled.
+ */
+struct scmi_desc {
+	int max_rx_timeout_ms;
+	int max_msg;
+	int max_msg_size;
+};
+
+/**
+ * struct scmi_chan_info - Structure representing a SCMI channel informfation
+ *
+ * @cl: Mailbox Client
+ * @chan: Transmit/Receive mailbox channel
+ * @payload: Transmit/Receive mailbox channel payload area
+ * @dev: Reference to device in the SCMI hierarchy corresponding to this
+ *	 channel
+ */
+struct scmi_chan_info {
+	struct mbox_client cl;
+	struct mbox_chan *chan;
+	void __iomem *payload;
+	struct device *dev;
+	struct scmi_handle *handle;
+};
+
+/**
+ * struct scmi_info - Structure representing a  SCMI instance
+ *
+ * @dev: Device pointer
+ * @desc: SoC description for this instance
+ * @handle: Instance of SCMI handle to send to clients
+ * @version: SCMI revision information containing protocol version,
+ *	implementation version and (sub-)vendor identification.
+ * @minfo: Message info
+ * @tx_idr: IDR object to map protocol id to channel info pointer
+ * @protocols_imp: list of protocols implemented, currently maximum of
+ *	MAX_PROTOCOLS_IMP elements allocated by the base protocol
+ * @node: list head
+ * @users: Number of users of this instance
+ */
+struct scmi_info {
+	struct device *dev;
+	const struct scmi_desc *desc;
+	struct scmi_revision_info version;
+	struct scmi_handle handle;
+	struct scmi_xfers_info minfo;
+	struct idr tx_idr;
+	u8 *protocols_imp;
+	struct list_head node;
+	int users;
+};
+
+#define client_to_scmi_chan_info(c) container_of(c, struct scmi_chan_info, cl)
+#define handle_to_scmi_info(h)	container_of(h, struct scmi_info, handle)
+
+/*
+ * SCMI specification requires all parameters, message headers, return
+ * arguments or any protocol data to be expressed in little endian
+ * format only.
+ */
+struct scmi_shared_mem {
+	__le32 reserved;
+	__le32 channel_status;
+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR	BIT(1)
+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE	BIT(0)
+	__le32 reserved1[2];
+	__le32 flags;
+#define SCMI_SHMEM_FLAG_INTR_ENABLED	BIT(0)
+	__le32 length;
+	__le32 msg_header;
+	u8 msg_payload[0];
+};
+
+static const int scmi_linux_errmap[] = {
+	/* better than switch case as long as return value is continuous */
+	0,			/* SCMI_SUCCESS */
+	-EOPNOTSUPP,		/* SCMI_ERR_SUPPORT */
+	-EINVAL,		/* SCMI_ERR_PARAM */
+	-EACCES,		/* SCMI_ERR_ACCESS */
+	-ENOENT,		/* SCMI_ERR_ENTRY */
+	-ERANGE,		/* SCMI_ERR_RANGE */
+	-EBUSY,			/* SCMI_ERR_BUSY */
+	-ECOMM,			/* SCMI_ERR_COMMS */
+	-EIO,			/* SCMI_ERR_GENERIC */
+	-EREMOTEIO,		/* SCMI_ERR_HARDWARE */
+	-EPROTO,		/* SCMI_ERR_PROTOCOL */
+};
+
+static inline int scmi_to_linux_errno(int errno)
+{
+	if (errno < SCMI_SUCCESS && errno > SCMI_ERR_MAX)
+		return scmi_linux_errmap[-errno];
+	return -EIO;
+}
+
+/**
+ * scmi_dump_header_dbg() - Helper to dump a message header.
+ *
+ * @dev: Device pointer corresponding to the SCMI entity
+ * @hdr: pointer to header.
+ */
+static inline void scmi_dump_header_dbg(struct device *dev,
+					struct scmi_msg_hdr *hdr)
+{
+	dev_dbg(dev, "Command ID: %x Sequence ID: %x Protocol: %x\n",
+		hdr->id, hdr->seq, hdr->protocol_id);
+}
+
+static void scmi_fetch_response(struct scmi_xfer *xfer,
+				struct scmi_shared_mem __iomem *mem)
+{
+	xfer->hdr.status = ioread32(mem->msg_payload);
+	/* Skip the length of header and statues in payload area i.e 8 bytes*/
+	xfer->rx.len = min_t(size_t, xfer->rx.len, ioread32(&mem->length) - 8);
+
+	/* Take a copy to the rx buffer.. */
+	memcpy_fromio(xfer->rx.buf, mem->msg_payload + 4, xfer->rx.len);
+}
+
+/**
+ * scmi_rx_callback() - mailbox client callback for receive messages
+ *
+ * @cl: client pointer
+ * @m: mailbox message
+ *
+ * Processes one received message to appropriate transfer information and
+ * signals completion of the transfer.
+ *
+ * NOTE: This function will be invoked in IRQ context, hence should be
+ * as optimal as possible.
+ */
+static void scmi_rx_callback(struct mbox_client *cl, void *m)
+{
+	u16 xfer_id;
+	struct scmi_xfer *xfer;
+	struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
+	struct device *dev = cinfo->dev;
+	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
+	struct scmi_xfers_info *minfo = &info->minfo;
+	struct scmi_shared_mem __iomem *mem = cinfo->payload;
+
+	xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header));
+
+	/*
+	 * Are we even expecting this?
+	 */
+	if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
+		dev_err(dev, "message for %d is not expected!\n", xfer_id);
+		return;
+	}
+
+	xfer = &minfo->xfer_block[xfer_id];
+
+	scmi_dump_header_dbg(dev, &xfer->hdr);
+	/* Is the message of valid length? */
+	if (xfer->rx.len > info->desc->max_msg_size) {
+		dev_err(dev, "unable to handle %zu xfer(max %d)\n",
+			xfer->rx.len, info->desc->max_msg_size);
+		return;
+	}
+
+	scmi_fetch_response(xfer, mem);
+	complete(&xfer->done);
+}
+
+/**
+ * pack_scmi_header() - packs and returns 32-bit header
+ *
+ * @hdr: pointer to header containing all the information on message id,
+ *	protocol id and sequence id.
+ */
+static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
+{
+	return ((hdr->id & MSG_ID_MASK) << MSG_ID_SHIFT) |
+	   ((hdr->seq & MSG_TOKEN_ID_MASK) << MSG_TOKEN_ID_SHIFT) |
+	   ((hdr->protocol_id & MSG_PROTOCOL_ID_MASK) << MSG_PROTOCOL_ID_SHIFT);
+}
+
+/**
+ * scmi_tx_prepare() - mailbox client callback to prepare for the transfer
+ *
+ * @cl: client pointer
+ * @m: mailbox message
+ *
+ * This function prepares the shared memory which contains the header and the
+ * payload.
+ */
+static void scmi_tx_prepare(struct mbox_client *cl, void *m)
+{
+	struct scmi_xfer *t = m;
+	struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
+	struct scmi_shared_mem __iomem *mem = cinfo->payload;
+
+	/* Mark channel busy + clear error */
+	iowrite32(0x0, &mem->channel_status);
+	iowrite32(t->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED,
+		  &mem->flags);
+	iowrite32(sizeof(mem->msg_header) + t->tx.len, &mem->length);
+	iowrite32(pack_scmi_header(&t->hdr), &mem->msg_header);
+	if (t->tx.buf)
+		memcpy_toio(mem->msg_payload, t->tx.buf, t->tx.len);
+}
+
+/**
+ * scmi_one_xfer_get() - Allocate one message
+ *
+ * @handle: SCMI entity handle
+ *
+ * Helper function which is used by various command functions that are
+ * exposed to clients of this driver for allocating a message traffic event.
+ *
+ * This function can sleep depending on pending requests already in the system
+ * for the SCMI entity. Further, this also holds a spinlock to maintain
+ * integrity of internal data structures.
+ *
+ * Return: 0 if all went fine, else corresponding error.
+ */
+static struct scmi_xfer *scmi_one_xfer_get(const struct scmi_handle *handle)
+{
+	u16 xfer_id;
+	struct scmi_xfer *xfer;
+	unsigned long flags, bit_pos;
+	struct scmi_info *info = handle_to_scmi_info(handle);
+	struct scmi_xfers_info *minfo = &info->minfo;
+
+	/* Keep the locked section as small as possible */
+	spin_lock_irqsave(&minfo->xfer_lock, flags);
+	bit_pos = find_first_zero_bit(minfo->xfer_alloc_table,
+				      info->desc->max_msg);
+	if (bit_pos == info->desc->max_msg) {
+		spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+		return ERR_PTR(-ENOMEM);
+	}
+	set_bit(bit_pos, minfo->xfer_alloc_table);
+	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
+	xfer_id = bit_pos;
+
+	xfer = &minfo->xfer_block[xfer_id];
+	xfer->hdr.seq = xfer_id;
+	reinit_completion(&xfer->done);
+
+	return xfer;
+}
+
+/**
+ * scmi_one_xfer_put() - Release a message
+ *
+ * @minfo: transfer info pointer
+ * @xfer: message that was reserved by scmi_one_xfer_get
+ *
+ * This holds a spinlock to maintain integrity of internal data structures.
+ */
+void scmi_one_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
+{
+	unsigned long flags;
+	struct scmi_info *info = handle_to_scmi_info(handle);
+	struct scmi_xfers_info *minfo = &info->minfo;
+
+	/*
+	 * Keep the locked section as small as possible
+	 * NOTE: we might escape with smp_mb and no lock here..
+	 * but just be conservative and symmetric.
+	 */
+	spin_lock_irqsave(&minfo->xfer_lock, flags);
+	clear_bit(xfer->hdr.seq, minfo->xfer_alloc_table);
+	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+}
+
+static bool
+scmi_xfer_poll_done(const struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
+{
+	struct scmi_shared_mem __iomem *mem = cinfo->payload;
+	u16 xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header));
+
+	if (xfer->hdr.seq != xfer_id)
+		return false;
+
+	return ioread32(&mem->channel_status) &
+		(SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR |
+		SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
+}
+
+#define SCMI_MAX_POLL_TO_NS	(100 * NSEC_PER_USEC)
+
+static bool scmi_xfer_done_no_timeout(const struct scmi_chan_info *cinfo,
+				      struct scmi_xfer *xfer, ktime_t stop)
+{
+	ktime_t __cur = ktime_get();
+
+	return scmi_xfer_poll_done(cinfo, xfer) || ktime_after(__cur, stop);
+}
+
+/**
+ * scmi_do_xfer() - Do one transfer
+ *
+ * @info: Pointer to SCMI entity information
+ * @xfer: Transfer to initiate and wait for response
+ *
+ * Return: -ETIMEDOUT in case of no response, if transmit error,
+ *   return corresponding error, else if all goes well,
+ *   return 0.
+ */
+int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
+{
+	int ret;
+	int timeout;
+	struct scmi_info *info = handle_to_scmi_info(handle);
+	struct device *dev = info->dev;
+	struct scmi_chan_info *cinfo;
+
+	cinfo = idr_find(&info->tx_idr, xfer->hdr.protocol_id);
+	if (unlikely(!cinfo))
+		return -EINVAL;
+
+	ret = mbox_send_message(cinfo->chan, xfer);
+	if (ret < 0) {
+		dev_dbg(dev, "mbox send fail %d\n", ret);
+		return ret;
+	}
+
+	/* mbox_send_message returns non-negative value on success, so reset */
+	ret = 0;
+
+	if (xfer->hdr.poll_completion) {
+		ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
+
+		spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
+
+		if (ktime_before(ktime_get(), stop))
+			scmi_fetch_response(xfer, cinfo->payload);
+		else
+			ret = -ETIMEDOUT;
+	} else {
+		/* And we wait for the response. */
+		timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
+		if (!wait_for_completion_timeout(&xfer->done, timeout)) {
+			dev_err(dev, "mbox timed out in resp(caller: %pS)\n",
+				(void *)_RET_IP_);
+			ret = -ETIMEDOUT;
+		}
+	}
+
+	if (!ret && xfer->hdr.status)
+		ret = scmi_to_linux_errno(xfer->hdr.status);
+
+	/*
+	 * NOTE: we might prefer not to need the mailbox ticker to manage the
+	 * transfer queueing since the protocol layer queues things by itself.
+	 * Unfortunately, we have to kick the mailbox framework after we have
+	 * received our message.
+	 */
+	mbox_client_txdone(cinfo->chan, ret);
+
+	return ret;
+}
+
+/**
+ * scmi_one_xfer_init() - Allocate and initialise one message
+ *
+ * @handle: SCMI entity handle
+ * @msg_id: Message identifier
+ * @msg_prot_id: Protocol identifier for the message
+ * @tx_size: transmit message size
+ * @rx_size: receive message size
+ * @p: pointer to the allocated and initialised message
+ *
+ * This function allocates the message using @scmi_one_xfer_get and
+ * initialise the header.
+ *
+ * Return: 0 if all went fine with @p pointing to message, else
+ *	corresponding error.
+ */
+int scmi_one_xfer_init(const struct scmi_handle *handle, u8 msg_id, u8 prot_id,
+		       size_t tx_size, size_t rx_size, struct scmi_xfer **p)
+{
+	int ret;
+	struct scmi_xfer *xfer;
+	struct scmi_info *info = handle_to_scmi_info(handle);
+	struct device *dev = info->dev;
+
+	/* Ensure we have sane transfer sizes */
+	if (rx_size > info->desc->max_msg_size ||
+	    tx_size > info->desc->max_msg_size)
+		return -ERANGE;
+
+	xfer = scmi_one_xfer_get(handle);
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "failed to get free message slot(%d)\n", ret);
+		return ret;
+	}
+
+	xfer->tx.len = tx_size;
+	xfer->rx.len = rx_size ? : info->desc->max_msg_size;
+	xfer->hdr.id = msg_id;
+	xfer->hdr.protocol_id = prot_id;
+	xfer->hdr.poll_completion = false;
+
+	*p = xfer;
+	return 0;
+}
+
+/**
+ * scmi_version_get() - command to get the revision of the SCMI entity
+ *
+ * @handle: Handle to SCMI entity information
+ *
+ * Updates the SCMI information in the internal data structure.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+int scmi_version_get(const struct scmi_handle *handle, u8 protocol,
+		     u32 *version)
+{
+	int ret;
+	__le32 *rev_info;
+	struct scmi_xfer *t;
+
+	ret = scmi_one_xfer_init(handle, PROTOCOL_VERSION, protocol, 0,
+				 sizeof(*version), &t);
+	if (ret)
+		return ret;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		rev_info = t->rx.buf;
+		*version = le32_to_cpu(*rev_info);
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+void scmi_setup_protocol_implemented(const struct scmi_handle *handle,
+				     u8 *prot_imp)
+{
+	struct scmi_info *info = handle_to_scmi_info(handle);
+
+	info->protocols_imp = prot_imp;
+}
+
+static bool
+scmi_is_protocol_implemented(const struct scmi_handle *handle, u8 prot_id)
+{
+	int i;
+	struct scmi_info *info = handle_to_scmi_info(handle);
+
+	if (!info->protocols_imp)
+		return false;
+
+	for (i = 0; i < MAX_PROTOCOLS_IMP; i++)
+		if (info->protocols_imp[i] == prot_id)
+			return true;
+	return false;
+}
+
+/**
+ * scmi_handle_get() - Get the  SCMI handle for a device
+ *
+ * @dev: pointer to device for which we want SCMI handle
+ *
+ * NOTE: The function does not track individual clients of the framework
+ * and is expected to be maintained by caller of  SCMI protocol library.
+ * scmi_handle_put must be balanced with successful scmi_handle_get
+ *
+ * Return: pointer to handle if successful, NULL on error
+ */
+struct scmi_handle *scmi_handle_get(struct device *dev)
+{
+	struct list_head *p;
+	struct scmi_info *info;
+	struct scmi_handle *handle = NULL;
+
+	mutex_lock(&scmi_list_mutex);
+	list_for_each(p, &scmi_list) {
+		info = list_entry(p, struct scmi_info, node);
+		if (dev->parent == info->dev) {
+			handle = &info->handle;
+			info->users++;
+			break;
+		}
+	}
+	mutex_unlock(&scmi_list_mutex);
+
+	return handle;
+}
+
+/**
+ * scmi_handle_put() - Release the handle acquired by scmi_handle_get
+ *
+ * @handle: handle acquired by scmi_handle_get
+ *
+ * NOTE: The function does not track individual clients of the framework
+ * and is expected to be maintained by caller of  SCMI protocol library.
+ * scmi_handle_put must be balanced with successful scmi_handle_get
+ *
+ * Return: 0 is successfully released
+ *	if null was passed, it returns -EINVAL;
+ */
+int scmi_handle_put(const struct scmi_handle *handle)
+{
+	struct scmi_info *info;
+
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_scmi_info(handle);
+	mutex_lock(&scmi_list_mutex);
+	if (!WARN_ON(!info->users))
+		info->users--;
+	mutex_unlock(&scmi_list_mutex);
+
+	return 0;
+}
+
+static const struct scmi_desc scmi_generic_desc = {
+	.max_rx_timeout_ms = 30,	/* we may increase this if required */
+	.max_msg = 20,		/* Limited by MBOX_TX_QUEUE_LEN */
+	.max_msg_size = 128,
+};
+
+/* Each compatible listed below must have descriptor associated with it */
+static const struct of_device_id scmi_of_match[] = {
+	{ .compatible = "arm,scmi", .data = &scmi_generic_desc },
+	{ /* Sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, scmi_of_match);
+
+static int scmi_xfer_info_init(struct scmi_info *sinfo)
+{
+	int i;
+	struct scmi_xfer *xfer;
+	struct device *dev = sinfo->dev;
+	const struct scmi_desc *desc = sinfo->desc;
+	struct scmi_xfers_info *info = &sinfo->minfo;
+
+	/* Pre-allocated messages, no more than what hdr.seq can support */
+	if (WARN_ON(desc->max_msg >= (MSG_TOKEN_ID_MASK + 1))) {
+		dev_err(dev, "Maximum message of %d exceeds supported %d\n",
+			desc->max_msg, MSG_TOKEN_ID_MASK + 1);
+		return -EINVAL;
+	}
+
+	info->xfer_block = devm_kcalloc(dev, desc->max_msg,
+					sizeof(*info->xfer_block), GFP_KERNEL);
+	if (!info->xfer_block)
+		return -ENOMEM;
+
+	info->xfer_alloc_table = devm_kcalloc(dev, BITS_TO_LONGS(desc->max_msg),
+					      sizeof(long), GFP_KERNEL);
+	if (!info->xfer_alloc_table)
+		return -ENOMEM;
+
+	bitmap_zero(info->xfer_alloc_table, desc->max_msg);
+
+	/* Pre-initialize the buffer pointer to pre-allocated buffers */
+	for (i = 0, xfer = info->xfer_block; i < desc->max_msg; i++, xfer++) {
+		xfer->rx.buf = devm_kcalloc(dev, sizeof(u8), desc->max_msg_size,
+					    GFP_KERNEL);
+		if (!xfer->rx.buf)
+			return -ENOMEM;
+
+		xfer->tx.buf = xfer->rx.buf;
+		init_completion(&xfer->done);
+	}
+
+	spin_lock_init(&info->xfer_lock);
+
+	return 0;
+}
+
+static int scmi_mailbox_check(struct device_node *np)
+{
+	struct of_phandle_args arg;
+
+	return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells", 0, &arg);
+}
+
+static int scmi_mbox_free_channel(int id, void *p, void *data)
+{
+	struct scmi_chan_info *cinfo = p;
+	struct idr *idr = data;
+
+	if (!IS_ERR_OR_NULL(cinfo->chan)) {
+		mbox_free_channel(cinfo->chan);
+		cinfo->chan = NULL;
+	}
+
+	idr_remove(idr, id);
+
+	return 0;
+}
+
+static int scmi_remove(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct scmi_info *info = platform_get_drvdata(pdev);
+	struct idr *idr = &info->tx_idr;
+
+	mutex_lock(&scmi_list_mutex);
+	if (info->users)
+		ret = -EBUSY;
+	else
+		list_del(&info->node);
+	mutex_unlock(&scmi_list_mutex);
+
+	if (!ret) {
+		/* Safe to free channels since no more users */
+		ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
+		idr_destroy(&info->tx_idr);
+	}
+
+	return ret;
+}
+
+static inline int
+scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, int prot_id)
+{
+	int ret;
+	struct resource res;
+	resource_size_t size;
+	struct device_node *shmem, *np = dev->of_node;
+	struct scmi_chan_info *cinfo;
+	struct mbox_client *cl;
+
+	if (scmi_mailbox_check(np)) {
+		cinfo = idr_find(&info->tx_idr, SCMI_PROTOCOL_BASE);
+		goto idr_alloc;
+	}
+
+	cinfo = devm_kzalloc(info->dev, sizeof(*cinfo), GFP_KERNEL);
+	if (!cinfo)
+		return -ENOMEM;
+
+	cinfo->dev = dev;
+
+	cl = &cinfo->cl;
+	cl->dev = dev;
+	cl->rx_callback = scmi_rx_callback;
+	cl->tx_prepare = scmi_tx_prepare;
+	cl->tx_block = false;
+	cl->knows_txdone = true;
+
+	shmem = of_parse_phandle(np, "shmem", 0);
+	ret = of_address_to_resource(shmem, 0, &res);
+	of_node_put(shmem);
+	if (ret) {
+		dev_err(dev, "failed to get SCMI Tx payload mem resource\n");
+		return ret;
+	}
+
+	size = resource_size(&res);
+	cinfo->payload = devm_ioremap(info->dev, res.start, size);
+	if (!cinfo->payload) {
+		dev_err(dev, "failed to ioremap SCMI Tx payload\n");
+		return -EADDRNOTAVAIL;
+	}
+
+	/* Transmit channel is first entry i.e. index 0 */
+	cinfo->chan = mbox_request_channel(cl, 0);
+	if (IS_ERR(cinfo->chan)) {
+		ret = PTR_ERR(cinfo->chan);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to request SCMI Tx mailbox\n");
+		return ret;
+	}
+
+idr_alloc:
+	ret = idr_alloc(&info->tx_idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
+	if (ret != prot_id) {
+		dev_err(dev, "unable to allocate SCMI idr slot err %d\n", ret);
+		return ret;
+	}
+
+	cinfo->handle = &info->handle;
+	return 0;
+}
+
+static inline void
+scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
+			    int prot_id)
+{
+	struct scmi_device *sdev;
+
+	sdev = scmi_device_create(np, info->dev, prot_id);
+	if (!sdev) {
+		dev_err(info->dev, "failed to create %d protocol device\n",
+			prot_id);
+		return;
+	}
+
+	if (scmi_mbox_chan_setup(info, &sdev->dev, prot_id)) {
+		dev_err(&sdev->dev, "failed to setup transport\n");
+		scmi_device_destroy(sdev);
+	}
+
+	/* setup handle now as the transport is ready */
+	scmi_set_handle(sdev);
+}
+
+static int scmi_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct scmi_handle *handle;
+	const struct scmi_desc *desc;
+	struct scmi_info *info;
+	struct device *dev = &pdev->dev;
+	struct device_node *child, *np = dev->of_node;
+
+	/* Only mailbox method supported, check for the presence of one */
+	if (scmi_mailbox_check(np)) {
+		dev_err(dev, "no mailbox found in %pOF\n", np);
+		return -EINVAL;
+	}
+
+	desc = of_match_device(scmi_of_match, dev)->data;
+
+	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->dev = dev;
+	info->desc = desc;
+	INIT_LIST_HEAD(&info->node);
+
+	ret = scmi_xfer_info_init(info);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, info);
+	idr_init(&info->tx_idr);
+
+	handle = &info->handle;
+	handle->dev = info->dev;
+	handle->version = &info->version;
+
+	ret = scmi_mbox_chan_setup(info, dev, SCMI_PROTOCOL_BASE);
+	if (ret)
+		return ret;
+
+	ret = scmi_base_protocol_init(handle);
+	if (ret) {
+		dev_err(dev, "unable to communicate with SCMI(%d)\n", ret);
+		return ret;
+	}
+
+	mutex_lock(&scmi_list_mutex);
+	list_add_tail(&info->node, &scmi_list);
+	mutex_unlock(&scmi_list_mutex);
+
+	for_each_available_child_of_node(np, child) {
+		u32 prot_id;
+
+		if (of_property_read_u32(child, "reg", &prot_id))
+			continue;
+
+		prot_id &= MSG_PROTOCOL_ID_MASK;
+
+		if (!scmi_is_protocol_implemented(handle, prot_id)) {
+			dev_err(dev, "SCMI protocol %d not implemented\n",
+				prot_id);
+			continue;
+		}
+
+		scmi_create_protocol_device(child, info, prot_id);
+	}
+
+	return 0;
+}
+
+static struct platform_driver scmi_driver = {
+	.driver = {
+		   .name = "arm-scmi",
+		   .of_match_table = scmi_of_match,
+		   },
+	.probe = scmi_probe,
+	.remove = scmi_remove,
+};
+
+module_platform_driver(scmi_driver);
+
+MODULE_ALIAS("platform: arm-scmi");
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCMI protocol driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
new file mode 100644
index 0000000..987c64d
--- /dev/null
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -0,0 +1,481 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Performance Protocol
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/sort.h>
+
+#include "common.h"
+
+enum scmi_performance_protocol_cmd {
+	PERF_DOMAIN_ATTRIBUTES = 0x3,
+	PERF_DESCRIBE_LEVELS = 0x4,
+	PERF_LIMITS_SET = 0x5,
+	PERF_LIMITS_GET = 0x6,
+	PERF_LEVEL_SET = 0x7,
+	PERF_LEVEL_GET = 0x8,
+	PERF_NOTIFY_LIMITS = 0x9,
+	PERF_NOTIFY_LEVEL = 0xa,
+};
+
+struct scmi_opp {
+	u32 perf;
+	u32 power;
+	u32 trans_latency_us;
+};
+
+struct scmi_msg_resp_perf_attributes {
+	__le16 num_domains;
+	__le16 flags;
+#define POWER_SCALE_IN_MILLIWATT(x)	((x) & BIT(0))
+	__le32 stats_addr_low;
+	__le32 stats_addr_high;
+	__le32 stats_size;
+};
+
+struct scmi_msg_resp_perf_domain_attributes {
+	__le32 flags;
+#define SUPPORTS_SET_LIMITS(x)		((x) & BIT(31))
+#define SUPPORTS_SET_PERF_LVL(x)	((x) & BIT(30))
+#define SUPPORTS_PERF_LIMIT_NOTIFY(x)	((x) & BIT(29))
+#define SUPPORTS_PERF_LEVEL_NOTIFY(x)	((x) & BIT(28))
+	__le32 rate_limit_us;
+	__le32 sustained_freq_khz;
+	__le32 sustained_perf_level;
+	    u8 name[SCMI_MAX_STR_SIZE];
+};
+
+struct scmi_msg_perf_describe_levels {
+	__le32 domain;
+	__le32 level_index;
+};
+
+struct scmi_perf_set_limits {
+	__le32 domain;
+	__le32 max_level;
+	__le32 min_level;
+};
+
+struct scmi_perf_get_limits {
+	__le32 max_level;
+	__le32 min_level;
+};
+
+struct scmi_perf_set_level {
+	__le32 domain;
+	__le32 level;
+};
+
+struct scmi_perf_notify_level_or_limits {
+	__le32 domain;
+	__le32 notify_enable;
+};
+
+struct scmi_msg_resp_perf_describe_levels {
+	__le16 num_returned;
+	__le16 num_remaining;
+	struct {
+		__le32 perf_val;
+		__le32 power;
+		__le16 transition_latency_us;
+		__le16 reserved;
+	} opp[0];
+};
+
+struct perf_dom_info {
+	bool set_limits;
+	bool set_perf;
+	bool perf_limit_notify;
+	bool perf_level_notify;
+	u32 opp_count;
+	u32 sustained_freq_khz;
+	u32 sustained_perf_level;
+	u32 mult_factor;
+	char name[SCMI_MAX_STR_SIZE];
+	struct scmi_opp opp[MAX_OPPS];
+};
+
+struct scmi_perf_info {
+	int num_domains;
+	bool power_scale_mw;
+	u64 stats_addr;
+	u32 stats_size;
+	struct perf_dom_info *dom_info;
+};
+
+static int scmi_perf_attributes_get(const struct scmi_handle *handle,
+				    struct scmi_perf_info *pi)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_perf_attributes *attr;
+
+	ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES,
+				 SCMI_PROTOCOL_PERF, 0, sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	attr = t->rx.buf;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		u16 flags = le16_to_cpu(attr->flags);
+
+		pi->num_domains = le16_to_cpu(attr->num_domains);
+		pi->power_scale_mw = POWER_SCALE_IN_MILLIWATT(flags);
+		pi->stats_addr = le32_to_cpu(attr->stats_addr_low) |
+				(u64)le32_to_cpu(attr->stats_addr_high) << 32;
+		pi->stats_size = le32_to_cpu(attr->stats_size);
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int
+scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
+				struct perf_dom_info *dom_info)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_perf_domain_attributes *attr;
+
+	ret = scmi_one_xfer_init(handle, PERF_DOMAIN_ATTRIBUTES,
+				 SCMI_PROTOCOL_PERF, sizeof(domain),
+				 sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	*(__le32 *)t->tx.buf = cpu_to_le32(domain);
+	attr = t->rx.buf;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		u32 flags = le32_to_cpu(attr->flags);
+
+		dom_info->set_limits = SUPPORTS_SET_LIMITS(flags);
+		dom_info->set_perf = SUPPORTS_SET_PERF_LVL(flags);
+		dom_info->perf_limit_notify = SUPPORTS_PERF_LIMIT_NOTIFY(flags);
+		dom_info->perf_level_notify = SUPPORTS_PERF_LEVEL_NOTIFY(flags);
+		dom_info->sustained_freq_khz =
+					le32_to_cpu(attr->sustained_freq_khz);
+		dom_info->sustained_perf_level =
+					le32_to_cpu(attr->sustained_perf_level);
+		dom_info->mult_factor =	(dom_info->sustained_freq_khz * 1000) /
+					dom_info->sustained_perf_level;
+		memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int opp_cmp_func(const void *opp1, const void *opp2)
+{
+	const struct scmi_opp *t1 = opp1, *t2 = opp2;
+
+	return t1->perf - t2->perf;
+}
+
+static int
+scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain,
+			      struct perf_dom_info *perf_dom)
+{
+	int ret, cnt;
+	u32 tot_opp_cnt = 0;
+	u16 num_returned, num_remaining;
+	struct scmi_xfer *t;
+	struct scmi_opp *opp;
+	struct scmi_msg_perf_describe_levels *dom_info;
+	struct scmi_msg_resp_perf_describe_levels *level_info;
+
+	ret = scmi_one_xfer_init(handle, PERF_DESCRIBE_LEVELS,
+				 SCMI_PROTOCOL_PERF, sizeof(*dom_info), 0, &t);
+	if (ret)
+		return ret;
+
+	dom_info = t->tx.buf;
+	level_info = t->rx.buf;
+
+	do {
+		dom_info->domain = cpu_to_le32(domain);
+		/* Set the number of OPPs to be skipped/already read */
+		dom_info->level_index = cpu_to_le32(tot_opp_cnt);
+
+		ret = scmi_do_xfer(handle, t);
+		if (ret)
+			break;
+
+		num_returned = le16_to_cpu(level_info->num_returned);
+		num_remaining = le16_to_cpu(level_info->num_remaining);
+		if (tot_opp_cnt + num_returned > MAX_OPPS) {
+			dev_err(handle->dev, "No. of OPPs exceeded MAX_OPPS");
+			break;
+		}
+
+		opp = &perf_dom->opp[tot_opp_cnt];
+		for (cnt = 0; cnt < num_returned; cnt++, opp++) {
+			opp->perf = le32_to_cpu(level_info->opp[cnt].perf_val);
+			opp->power = le32_to_cpu(level_info->opp[cnt].power);
+			opp->trans_latency_us = le16_to_cpu
+				(level_info->opp[cnt].transition_latency_us);
+
+			dev_dbg(handle->dev, "Level %d Power %d Latency %dus\n",
+				opp->perf, opp->power, opp->trans_latency_us);
+		}
+
+		tot_opp_cnt += num_returned;
+		/*
+		 * check for both returned and remaining to avoid infinite
+		 * loop due to buggy firmware
+		 */
+	} while (num_returned && num_remaining);
+
+	perf_dom->opp_count = tot_opp_cnt;
+	scmi_one_xfer_put(handle, t);
+
+	sort(perf_dom->opp, tot_opp_cnt, sizeof(*opp), opp_cmp_func, NULL);
+	return ret;
+}
+
+static int scmi_perf_limits_set(const struct scmi_handle *handle, u32 domain,
+				u32 max_perf, u32 min_perf)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_perf_set_limits *limits;
+
+	ret = scmi_one_xfer_init(handle, PERF_LIMITS_SET, SCMI_PROTOCOL_PERF,
+				 sizeof(*limits), 0, &t);
+	if (ret)
+		return ret;
+
+	limits = t->tx.buf;
+	limits->domain = cpu_to_le32(domain);
+	limits->max_level = cpu_to_le32(max_perf);
+	limits->min_level = cpu_to_le32(min_perf);
+
+	ret = scmi_do_xfer(handle, t);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_perf_limits_get(const struct scmi_handle *handle, u32 domain,
+				u32 *max_perf, u32 *min_perf)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_perf_get_limits *limits;
+
+	ret = scmi_one_xfer_init(handle, PERF_LIMITS_GET, SCMI_PROTOCOL_PERF,
+				 sizeof(__le32), 0, &t);
+	if (ret)
+		return ret;
+
+	*(__le32 *)t->tx.buf = cpu_to_le32(domain);
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		limits = t->rx.buf;
+
+		*max_perf = le32_to_cpu(limits->max_level);
+		*min_perf = le32_to_cpu(limits->min_level);
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_perf_level_set(const struct scmi_handle *handle, u32 domain,
+			       u32 level, bool poll)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_perf_set_level *lvl;
+
+	ret = scmi_one_xfer_init(handle, PERF_LEVEL_SET, SCMI_PROTOCOL_PERF,
+				 sizeof(*lvl), 0, &t);
+	if (ret)
+		return ret;
+
+	t->hdr.poll_completion = poll;
+	lvl = t->tx.buf;
+	lvl->domain = cpu_to_le32(domain);
+	lvl->level = cpu_to_le32(level);
+
+	ret = scmi_do_xfer(handle, t);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_perf_level_get(const struct scmi_handle *handle, u32 domain,
+			       u32 *level, bool poll)
+{
+	int ret;
+	struct scmi_xfer *t;
+
+	ret = scmi_one_xfer_init(handle, PERF_LEVEL_GET, SCMI_PROTOCOL_PERF,
+				 sizeof(u32), sizeof(u32), &t);
+	if (ret)
+		return ret;
+
+	t->hdr.poll_completion = poll;
+	*(__le32 *)t->tx.buf = cpu_to_le32(domain);
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret)
+		*level = le32_to_cpu(*(__le32 *)t->rx.buf);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+/* Device specific ops */
+static int scmi_dev_domain_id(struct device *dev)
+{
+	struct of_phandle_args clkspec;
+
+	if (of_parse_phandle_with_args(dev->of_node, "clocks", "#clock-cells",
+				       0, &clkspec))
+		return -EINVAL;
+
+	return clkspec.args[0];
+}
+
+static int scmi_dvfs_add_opps_to_device(const struct scmi_handle *handle,
+					struct device *dev)
+{
+	int idx, ret, domain;
+	unsigned long freq;
+	struct scmi_opp *opp;
+	struct perf_dom_info *dom;
+	struct scmi_perf_info *pi = handle->perf_priv;
+
+	domain = scmi_dev_domain_id(dev);
+	if (domain < 0)
+		return domain;
+
+	dom = pi->dom_info + domain;
+	if (!dom)
+		return -EIO;
+
+	for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) {
+		freq = opp->perf * dom->mult_factor;
+
+		ret = dev_pm_opp_add(dev, freq, 0);
+		if (ret) {
+			dev_warn(dev, "failed to add opp %luHz\n", freq);
+
+			while (idx-- > 0) {
+				freq = (--opp)->perf * dom->mult_factor;
+				dev_pm_opp_remove(dev, freq);
+			}
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int scmi_dvfs_get_transition_latency(const struct scmi_handle *handle,
+					    struct device *dev)
+{
+	struct perf_dom_info *dom;
+	struct scmi_perf_info *pi = handle->perf_priv;
+	int domain = scmi_dev_domain_id(dev);
+
+	if (domain < 0)
+		return domain;
+
+	dom = pi->dom_info + domain;
+	if (!dom)
+		return -EIO;
+
+	/* uS to nS */
+	return dom->opp[dom->opp_count - 1].trans_latency_us * 1000;
+}
+
+static int scmi_dvfs_freq_set(const struct scmi_handle *handle, u32 domain,
+			      unsigned long freq, bool poll)
+{
+	struct scmi_perf_info *pi = handle->perf_priv;
+	struct perf_dom_info *dom = pi->dom_info + domain;
+
+	return scmi_perf_level_set(handle, domain, freq / dom->mult_factor,
+				   poll);
+}
+
+static int scmi_dvfs_freq_get(const struct scmi_handle *handle, u32 domain,
+			      unsigned long *freq, bool poll)
+{
+	int ret;
+	u32 level;
+	struct scmi_perf_info *pi = handle->perf_priv;
+	struct perf_dom_info *dom = pi->dom_info + domain;
+
+	ret = scmi_perf_level_get(handle, domain, &level, poll);
+	if (!ret)
+		*freq = level * dom->mult_factor;
+
+	return ret;
+}
+
+static struct scmi_perf_ops perf_ops = {
+	.limits_set = scmi_perf_limits_set,
+	.limits_get = scmi_perf_limits_get,
+	.level_set = scmi_perf_level_set,
+	.level_get = scmi_perf_level_get,
+	.device_domain_id = scmi_dev_domain_id,
+	.get_transition_latency = scmi_dvfs_get_transition_latency,
+	.add_opps_to_device = scmi_dvfs_add_opps_to_device,
+	.freq_set = scmi_dvfs_freq_set,
+	.freq_get = scmi_dvfs_freq_get,
+};
+
+static int scmi_perf_protocol_init(struct scmi_handle *handle)
+{
+	int domain;
+	u32 version;
+	struct scmi_perf_info *pinfo;
+
+	scmi_version_get(handle, SCMI_PROTOCOL_PERF, &version);
+
+	dev_dbg(handle->dev, "Performance Version %d.%d\n",
+		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+	pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL);
+	if (!pinfo)
+		return -ENOMEM;
+
+	scmi_perf_attributes_get(handle, pinfo);
+
+	pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains,
+				       sizeof(*pinfo->dom_info), GFP_KERNEL);
+	if (!pinfo->dom_info)
+		return -ENOMEM;
+
+	for (domain = 0; domain < pinfo->num_domains; domain++) {
+		struct perf_dom_info *dom = pinfo->dom_info + domain;
+
+		scmi_perf_domain_attributes_get(handle, domain, dom);
+		scmi_perf_describe_levels_get(handle, domain, dom);
+	}
+
+	handle->perf_ops = &perf_ops;
+	handle->perf_priv = pinfo;
+
+	return 0;
+}
+
+static int __init scmi_perf_init(void)
+{
+	return scmi_protocol_register(SCMI_PROTOCOL_PERF,
+				      &scmi_perf_protocol_init);
+}
+subsys_initcall(scmi_perf_init);
diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c
new file mode 100644
index 0000000..087c287
--- /dev/null
+++ b/drivers/firmware/arm_scmi/power.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Power Protocol
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include "common.h"
+
+enum scmi_power_protocol_cmd {
+	POWER_DOMAIN_ATTRIBUTES = 0x3,
+	POWER_STATE_SET = 0x4,
+	POWER_STATE_GET = 0x5,
+	POWER_STATE_NOTIFY = 0x6,
+};
+
+struct scmi_msg_resp_power_attributes {
+	__le16 num_domains;
+	__le16 reserved;
+	__le32 stats_addr_low;
+	__le32 stats_addr_high;
+	__le32 stats_size;
+};
+
+struct scmi_msg_resp_power_domain_attributes {
+	__le32 flags;
+#define SUPPORTS_STATE_SET_NOTIFY(x)	((x) & BIT(31))
+#define SUPPORTS_STATE_SET_ASYNC(x)	((x) & BIT(30))
+#define SUPPORTS_STATE_SET_SYNC(x)	((x) & BIT(29))
+	    u8 name[SCMI_MAX_STR_SIZE];
+};
+
+struct scmi_power_set_state {
+	__le32 flags;
+#define STATE_SET_ASYNC		BIT(0)
+	__le32 domain;
+	__le32 state;
+};
+
+struct scmi_power_state_notify {
+	__le32 domain;
+	__le32 notify_enable;
+};
+
+struct power_dom_info {
+	bool state_set_sync;
+	bool state_set_async;
+	bool state_set_notify;
+	char name[SCMI_MAX_STR_SIZE];
+};
+
+struct scmi_power_info {
+	int num_domains;
+	u64 stats_addr;
+	u32 stats_size;
+	struct power_dom_info *dom_info;
+};
+
+static int scmi_power_attributes_get(const struct scmi_handle *handle,
+				     struct scmi_power_info *pi)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_power_attributes *attr;
+
+	ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES,
+				 SCMI_PROTOCOL_POWER, 0, sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	attr = t->rx.buf;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		pi->num_domains = le16_to_cpu(attr->num_domains);
+		pi->stats_addr = le32_to_cpu(attr->stats_addr_low) |
+				(u64)le32_to_cpu(attr->stats_addr_high) << 32;
+		pi->stats_size = le32_to_cpu(attr->stats_size);
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int
+scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
+				 struct power_dom_info *dom_info)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_power_domain_attributes *attr;
+
+	ret = scmi_one_xfer_init(handle, POWER_DOMAIN_ATTRIBUTES,
+				 SCMI_PROTOCOL_POWER, sizeof(domain),
+				 sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	*(__le32 *)t->tx.buf = cpu_to_le32(domain);
+	attr = t->rx.buf;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		u32 flags = le32_to_cpu(attr->flags);
+
+		dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags);
+		dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags);
+		dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags);
+		memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int
+scmi_power_state_set(const struct scmi_handle *handle, u32 domain, u32 state)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_power_set_state *st;
+
+	ret = scmi_one_xfer_init(handle, POWER_STATE_SET, SCMI_PROTOCOL_POWER,
+				 sizeof(*st), 0, &t);
+	if (ret)
+		return ret;
+
+	st = t->tx.buf;
+	st->flags = cpu_to_le32(0);
+	st->domain = cpu_to_le32(domain);
+	st->state = cpu_to_le32(state);
+
+	ret = scmi_do_xfer(handle, t);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int
+scmi_power_state_get(const struct scmi_handle *handle, u32 domain, u32 *state)
+{
+	int ret;
+	struct scmi_xfer *t;
+
+	ret = scmi_one_xfer_init(handle, POWER_STATE_GET, SCMI_PROTOCOL_POWER,
+				 sizeof(u32), sizeof(u32), &t);
+	if (ret)
+		return ret;
+
+	*(__le32 *)t->tx.buf = cpu_to_le32(domain);
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret)
+		*state = le32_to_cpu(*(__le32 *)t->rx.buf);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_power_num_domains_get(const struct scmi_handle *handle)
+{
+	struct scmi_power_info *pi = handle->power_priv;
+
+	return pi->num_domains;
+}
+
+static char *scmi_power_name_get(const struct scmi_handle *handle, u32 domain)
+{
+	struct scmi_power_info *pi = handle->power_priv;
+	struct power_dom_info *dom = pi->dom_info + domain;
+
+	return dom->name;
+}
+
+static struct scmi_power_ops power_ops = {
+	.num_domains_get = scmi_power_num_domains_get,
+	.name_get = scmi_power_name_get,
+	.state_set = scmi_power_state_set,
+	.state_get = scmi_power_state_get,
+};
+
+static int scmi_power_protocol_init(struct scmi_handle *handle)
+{
+	int domain;
+	u32 version;
+	struct scmi_power_info *pinfo;
+
+	scmi_version_get(handle, SCMI_PROTOCOL_POWER, &version);
+
+	dev_dbg(handle->dev, "Power Version %d.%d\n",
+		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+	pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL);
+	if (!pinfo)
+		return -ENOMEM;
+
+	scmi_power_attributes_get(handle, pinfo);
+
+	pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains,
+				       sizeof(*pinfo->dom_info), GFP_KERNEL);
+	if (!pinfo->dom_info)
+		return -ENOMEM;
+
+	for (domain = 0; domain < pinfo->num_domains; domain++) {
+		struct power_dom_info *dom = pinfo->dom_info + domain;
+
+		scmi_power_domain_attributes_get(handle, domain, dom);
+	}
+
+	handle->power_ops = &power_ops;
+	handle->power_priv = pinfo;
+
+	return 0;
+}
+
+static int __init scmi_power_init(void)
+{
+	return scmi_protocol_register(SCMI_PROTOCOL_POWER,
+				      &scmi_power_protocol_init);
+}
+subsys_initcall(scmi_power_init);
diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c b/drivers/firmware/arm_scmi/scmi_pm_domain.c
new file mode 100644
index 0000000..87f737e
--- /dev/null
+++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SCMI Generic power domain support.
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pm_domain.h>
+#include <linux/scmi_protocol.h>
+
+struct scmi_pm_domain {
+	struct generic_pm_domain genpd;
+	const struct scmi_handle *handle;
+	const char *name;
+	u32 domain;
+};
+
+#define to_scmi_pd(gpd) container_of(gpd, struct scmi_pm_domain, genpd)
+
+static int scmi_pd_power(struct generic_pm_domain *domain, bool power_on)
+{
+	int ret;
+	u32 state, ret_state;
+	struct scmi_pm_domain *pd = to_scmi_pd(domain);
+	const struct scmi_power_ops *ops = pd->handle->power_ops;
+
+	if (power_on)
+		state = SCMI_POWER_STATE_GENERIC_ON;
+	else
+		state = SCMI_POWER_STATE_GENERIC_OFF;
+
+	ret = ops->state_set(pd->handle, pd->domain, state);
+	if (!ret)
+		ret = ops->state_get(pd->handle, pd->domain, &ret_state);
+	if (!ret && state != ret_state)
+		return -EIO;
+
+	return ret;
+}
+
+static int scmi_pd_power_on(struct generic_pm_domain *domain)
+{
+	return scmi_pd_power(domain, true);
+}
+
+static int scmi_pd_power_off(struct generic_pm_domain *domain)
+{
+	return scmi_pd_power(domain, false);
+}
+
+static int scmi_pm_domain_probe(struct scmi_device *sdev)
+{
+	int num_domains, i;
+	struct device *dev = &sdev->dev;
+	struct device_node *np = dev->of_node;
+	struct scmi_pm_domain *scmi_pd;
+	struct genpd_onecell_data *scmi_pd_data;
+	struct generic_pm_domain **domains;
+	const struct scmi_handle *handle = sdev->handle;
+
+	if (!handle || !handle->power_ops)
+		return -ENODEV;
+
+	num_domains = handle->power_ops->num_domains_get(handle);
+	if (num_domains < 0) {
+		dev_err(dev, "number of domains not found\n");
+		return num_domains;
+	}
+
+	scmi_pd = devm_kcalloc(dev, num_domains, sizeof(*scmi_pd), GFP_KERNEL);
+	if (!scmi_pd)
+		return -ENOMEM;
+
+	scmi_pd_data = devm_kzalloc(dev, sizeof(*scmi_pd_data), GFP_KERNEL);
+	if (!scmi_pd_data)
+		return -ENOMEM;
+
+	domains = devm_kcalloc(dev, num_domains, sizeof(*domains), GFP_KERNEL);
+	if (!domains)
+		return -ENOMEM;
+
+	for (i = 0; i < num_domains; i++, scmi_pd++) {
+		u32 state;
+
+		domains[i] = &scmi_pd->genpd;
+
+		scmi_pd->domain = i;
+		scmi_pd->handle = handle;
+		scmi_pd->name = handle->power_ops->name_get(handle, i);
+		scmi_pd->genpd.name = scmi_pd->name;
+		scmi_pd->genpd.power_off = scmi_pd_power_off;
+		scmi_pd->genpd.power_on = scmi_pd_power_on;
+
+		if (handle->power_ops->state_get(handle, i, &state)) {
+			dev_warn(dev, "failed to get state for domain %d\n", i);
+			continue;
+		}
+
+		pm_genpd_init(&scmi_pd->genpd, NULL,
+			      state == SCMI_POWER_STATE_GENERIC_OFF);
+	}
+
+	scmi_pd_data->domains = domains;
+	scmi_pd_data->num_domains = num_domains;
+
+	of_genpd_add_provider_onecell(np, scmi_pd_data);
+
+	return 0;
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+	{ SCMI_PROTOCOL_POWER },
+	{ },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_power_domain_driver = {
+	.name = "scmi-power-domain",
+	.probe = scmi_pm_domain_probe,
+	.id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_power_domain_driver);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCMI power domain driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c
new file mode 100644
index 0000000..bbb469f
--- /dev/null
+++ b/drivers/firmware/arm_scmi/sensors.c
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Sensor Protocol
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+
+#include "common.h"
+
+enum scmi_sensor_protocol_cmd {
+	SENSOR_DESCRIPTION_GET = 0x3,
+	SENSOR_CONFIG_SET = 0x4,
+	SENSOR_TRIP_POINT_SET = 0x5,
+	SENSOR_READING_GET = 0x6,
+};
+
+struct scmi_msg_resp_sensor_attributes {
+	__le16 num_sensors;
+	u8 max_requests;
+	u8 reserved;
+	__le32 reg_addr_low;
+	__le32 reg_addr_high;
+	__le32 reg_size;
+};
+
+struct scmi_msg_resp_sensor_description {
+	__le16 num_returned;
+	__le16 num_remaining;
+	struct {
+		__le32 id;
+		__le32 attributes_low;
+#define SUPPORTS_ASYNC_READ(x)	((x) & BIT(31))
+#define NUM_TRIP_POINTS(x)	(((x) >> 4) & 0xff)
+		__le32 attributes_high;
+#define SENSOR_TYPE(x)		((x) & 0xff)
+#define SENSOR_SCALE(x)		(((x) >> 11) & 0x3f)
+#define SENSOR_UPDATE_SCALE(x)	(((x) >> 22) & 0x1f)
+#define SENSOR_UPDATE_BASE(x)	(((x) >> 27) & 0x1f)
+		    u8 name[SCMI_MAX_STR_SIZE];
+	} desc[0];
+};
+
+struct scmi_msg_set_sensor_config {
+	__le32 id;
+	__le32 event_control;
+};
+
+struct scmi_msg_set_sensor_trip_point {
+	__le32 id;
+	__le32 event_control;
+#define SENSOR_TP_EVENT_MASK	(0x3)
+#define SENSOR_TP_DISABLED	0x0
+#define SENSOR_TP_POSITIVE	0x1
+#define SENSOR_TP_NEGATIVE	0x2
+#define SENSOR_TP_BOTH		0x3
+#define SENSOR_TP_ID(x)		(((x) & 0xff) << 4)
+	__le32 value_low;
+	__le32 value_high;
+};
+
+struct scmi_msg_sensor_reading_get {
+	__le32 id;
+	__le32 flags;
+#define SENSOR_READ_ASYNC	BIT(0)
+};
+
+struct sensors_info {
+	int num_sensors;
+	int max_requests;
+	u64 reg_addr;
+	u32 reg_size;
+	struct scmi_sensor_info *sensors;
+};
+
+static int scmi_sensor_attributes_get(const struct scmi_handle *handle,
+				      struct sensors_info *si)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_sensor_attributes *attr;
+
+	ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES,
+				 SCMI_PROTOCOL_SENSOR, 0, sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	attr = t->rx.buf;
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		si->num_sensors = le16_to_cpu(attr->num_sensors);
+		si->max_requests = attr->max_requests;
+		si->reg_addr = le32_to_cpu(attr->reg_addr_low) |
+				(u64)le32_to_cpu(attr->reg_addr_high) << 32;
+		si->reg_size = le32_to_cpu(attr->reg_size);
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_sensor_description_get(const struct scmi_handle *handle,
+				       struct sensors_info *si)
+{
+	int ret, cnt;
+	u32 desc_index = 0;
+	u16 num_returned, num_remaining;
+	struct scmi_xfer *t;
+	struct scmi_msg_resp_sensor_description *buf;
+
+	ret = scmi_one_xfer_init(handle, SENSOR_DESCRIPTION_GET,
+				 SCMI_PROTOCOL_SENSOR, sizeof(__le32), 0, &t);
+	if (ret)
+		return ret;
+
+	buf = t->rx.buf;
+
+	do {
+		/* Set the number of sensors to be skipped/already read */
+		*(__le32 *)t->tx.buf = cpu_to_le32(desc_index);
+
+		ret = scmi_do_xfer(handle, t);
+		if (ret)
+			break;
+
+		num_returned = le16_to_cpu(buf->num_returned);
+		num_remaining = le16_to_cpu(buf->num_remaining);
+
+		if (desc_index + num_returned > si->num_sensors) {
+			dev_err(handle->dev, "No. of sensors can't exceed %d",
+				si->num_sensors);
+			break;
+		}
+
+		for (cnt = 0; cnt < num_returned; cnt++) {
+			u32 attrh;
+			struct scmi_sensor_info *s;
+
+			attrh = le32_to_cpu(buf->desc[cnt].attributes_high);
+			s = &si->sensors[desc_index + cnt];
+			s->id = le32_to_cpu(buf->desc[cnt].id);
+			s->type = SENSOR_TYPE(attrh);
+			memcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE);
+		}
+
+		desc_index += num_returned;
+		/*
+		 * check for both returned and remaining to avoid infinite
+		 * loop due to buggy firmware
+		 */
+	} while (num_returned && num_remaining);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int
+scmi_sensor_configuration_set(const struct scmi_handle *handle, u32 sensor_id)
+{
+	int ret;
+	u32 evt_cntl = BIT(0);
+	struct scmi_xfer *t;
+	struct scmi_msg_set_sensor_config *cfg;
+
+	ret = scmi_one_xfer_init(handle, SENSOR_CONFIG_SET,
+				 SCMI_PROTOCOL_SENSOR, sizeof(*cfg), 0, &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->id = cpu_to_le32(sensor_id);
+	cfg->event_control = cpu_to_le32(evt_cntl);
+
+	ret = scmi_do_xfer(handle, t);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_sensor_trip_point_set(const struct scmi_handle *handle,
+				      u32 sensor_id, u8 trip_id, u64 trip_value)
+{
+	int ret;
+	u32 evt_cntl = SENSOR_TP_BOTH;
+	struct scmi_xfer *t;
+	struct scmi_msg_set_sensor_trip_point *trip;
+
+	ret = scmi_one_xfer_init(handle, SENSOR_TRIP_POINT_SET,
+				 SCMI_PROTOCOL_SENSOR, sizeof(*trip), 0, &t);
+	if (ret)
+		return ret;
+
+	trip = t->tx.buf;
+	trip->id = cpu_to_le32(sensor_id);
+	trip->event_control = cpu_to_le32(evt_cntl | SENSOR_TP_ID(trip_id));
+	trip->value_low = cpu_to_le32(trip_value & 0xffffffff);
+	trip->value_high = cpu_to_le32(trip_value >> 32);
+
+	ret = scmi_do_xfer(handle, t);
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static int scmi_sensor_reading_get(const struct scmi_handle *handle,
+				   u32 sensor_id, bool async, u64 *value)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_sensor_reading_get *sensor;
+
+	ret = scmi_one_xfer_init(handle, SENSOR_READING_GET,
+				 SCMI_PROTOCOL_SENSOR, sizeof(*sensor),
+				 sizeof(u64), &t);
+	if (ret)
+		return ret;
+
+	sensor = t->tx.buf;
+	sensor->id = cpu_to_le32(sensor_id);
+	sensor->flags = cpu_to_le32(async ? SENSOR_READ_ASYNC : 0);
+
+	ret = scmi_do_xfer(handle, t);
+	if (!ret) {
+		__le32 *pval = t->rx.buf;
+
+		*value = le32_to_cpu(*pval);
+		*value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
+	}
+
+	scmi_one_xfer_put(handle, t);
+	return ret;
+}
+
+static const struct scmi_sensor_info *
+scmi_sensor_info_get(const struct scmi_handle *handle, u32 sensor_id)
+{
+	struct sensors_info *si = handle->sensor_priv;
+
+	return si->sensors + sensor_id;
+}
+
+static int scmi_sensor_count_get(const struct scmi_handle *handle)
+{
+	struct sensors_info *si = handle->sensor_priv;
+
+	return si->num_sensors;
+}
+
+static struct scmi_sensor_ops sensor_ops = {
+	.count_get = scmi_sensor_count_get,
+	.info_get = scmi_sensor_info_get,
+	.configuration_set = scmi_sensor_configuration_set,
+	.trip_point_set = scmi_sensor_trip_point_set,
+	.reading_get = scmi_sensor_reading_get,
+};
+
+static int scmi_sensors_protocol_init(struct scmi_handle *handle)
+{
+	u32 version;
+	struct sensors_info *sinfo;
+
+	scmi_version_get(handle, SCMI_PROTOCOL_SENSOR, &version);
+
+	dev_dbg(handle->dev, "Sensor Version %d.%d\n",
+		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+	sinfo = devm_kzalloc(handle->dev, sizeof(*sinfo), GFP_KERNEL);
+	if (!sinfo)
+		return -ENOMEM;
+
+	scmi_sensor_attributes_get(handle, sinfo);
+
+	sinfo->sensors = devm_kcalloc(handle->dev, sinfo->num_sensors,
+				      sizeof(*sinfo->sensors), GFP_KERNEL);
+	if (!sinfo->sensors)
+		return -ENOMEM;
+
+	scmi_sensor_description_get(handle, sinfo);
+
+	handle->sensor_ops = &sensor_ops;
+	handle->sensor_priv = sinfo;
+
+	return 0;
+}
+
+static int __init scmi_sensors_init(void)
+{
+	return scmi_protocol_register(SCMI_PROTOCOL_SENSOR,
+				      &scmi_sensors_protocol_init);
+}
+subsys_initcall(scmi_sensors_init);
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index 7da9f1b..6d7a6c0 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -28,6 +28,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/bitmap.h>
+#include <linux/bitfield.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/export.h>
@@ -45,48 +46,32 @@
 #include <linux/sort.h>
 #include <linux/spinlock.h>
 
-#define CMD_ID_SHIFT		0
-#define CMD_ID_MASK		0x7f
-#define CMD_TOKEN_ID_SHIFT	8
-#define CMD_TOKEN_ID_MASK	0xff
-#define CMD_DATA_SIZE_SHIFT	16
-#define CMD_DATA_SIZE_MASK	0x1ff
-#define CMD_LEGACY_DATA_SIZE_SHIFT	20
-#define CMD_LEGACY_DATA_SIZE_MASK	0x1ff
-#define PACK_SCPI_CMD(cmd_id, tx_sz)			\
-	((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) |	\
-	(((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
-#define ADD_SCPI_TOKEN(cmd, token)			\
-	((cmd) |= (((token) & CMD_TOKEN_ID_MASK) << CMD_TOKEN_ID_SHIFT))
-#define PACK_LEGACY_SCPI_CMD(cmd_id, tx_sz)				\
-	((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) |			       \
-	(((tx_sz) & CMD_LEGACY_DATA_SIZE_MASK) << CMD_LEGACY_DATA_SIZE_SHIFT))
+#define CMD_ID_MASK		GENMASK(6, 0)
+#define CMD_TOKEN_ID_MASK	GENMASK(15, 8)
+#define CMD_DATA_SIZE_MASK	GENMASK(24, 16)
+#define CMD_LEGACY_DATA_SIZE_MASK	GENMASK(28, 20)
+#define PACK_SCPI_CMD(cmd_id, tx_sz)		\
+	(FIELD_PREP(CMD_ID_MASK, cmd_id) |	\
+	FIELD_PREP(CMD_DATA_SIZE_MASK, tx_sz))
+#define PACK_LEGACY_SCPI_CMD(cmd_id, tx_sz)	\
+	(FIELD_PREP(CMD_ID_MASK, cmd_id) |	\
+	FIELD_PREP(CMD_LEGACY_DATA_SIZE_MASK, tx_sz))
 
-#define CMD_SIZE(cmd)	(((cmd) >> CMD_DATA_SIZE_SHIFT) & CMD_DATA_SIZE_MASK)
-#define CMD_LEGACY_SIZE(cmd)	(((cmd) >> CMD_LEGACY_DATA_SIZE_SHIFT) & \
-					CMD_LEGACY_DATA_SIZE_MASK)
-#define CMD_UNIQ_MASK	(CMD_TOKEN_ID_MASK << CMD_TOKEN_ID_SHIFT | CMD_ID_MASK)
+#define CMD_SIZE(cmd)	FIELD_GET(CMD_DATA_SIZE_MASK, cmd)
+#define CMD_UNIQ_MASK	(CMD_TOKEN_ID_MASK | CMD_ID_MASK)
 #define CMD_XTRACT_UNIQ(cmd)	((cmd) & CMD_UNIQ_MASK)
 
 #define SCPI_SLOT		0
 
 #define MAX_DVFS_DOMAINS	8
 #define MAX_DVFS_OPPS		16
-#define DVFS_LATENCY(hdr)	(le32_to_cpu(hdr) >> 16)
-#define DVFS_OPP_COUNT(hdr)	((le32_to_cpu(hdr) >> 8) & 0xff)
 
-#define PROTOCOL_REV_MINOR_BITS	16
-#define PROTOCOL_REV_MINOR_MASK	((1U << PROTOCOL_REV_MINOR_BITS) - 1)
-#define PROTOCOL_REV_MAJOR(x)	((x) >> PROTOCOL_REV_MINOR_BITS)
-#define PROTOCOL_REV_MINOR(x)	((x) & PROTOCOL_REV_MINOR_MASK)
+#define PROTO_REV_MAJOR_MASK	GENMASK(31, 16)
+#define PROTO_REV_MINOR_MASK	GENMASK(15, 0)
 
-#define FW_REV_MAJOR_BITS	24
-#define FW_REV_MINOR_BITS	16
-#define FW_REV_PATCH_MASK	((1U << FW_REV_MINOR_BITS) - 1)
-#define FW_REV_MINOR_MASK	((1U << FW_REV_MAJOR_BITS) - 1)
-#define FW_REV_MAJOR(x)		((x) >> FW_REV_MAJOR_BITS)
-#define FW_REV_MINOR(x)		(((x) & FW_REV_MINOR_MASK) >> FW_REV_MINOR_BITS)
-#define FW_REV_PATCH(x)		((x) & FW_REV_PATCH_MASK)
+#define FW_REV_MAJOR_MASK	GENMASK(31, 24)
+#define FW_REV_MINOR_MASK	GENMASK(23, 16)
+#define FW_REV_PATCH_MASK	GENMASK(15, 0)
 
 #define MAX_RX_TIMEOUT		(msecs_to_jiffies(30))
 
@@ -311,10 +296,6 @@ struct clk_get_info {
 	u8 name[20];
 } __packed;
 
-struct clk_get_value {
-	__le32 rate;
-} __packed;
-
 struct clk_set_value {
 	__le16 id;
 	__le16 reserved;
@@ -328,7 +309,9 @@ struct legacy_clk_set_value {
 } __packed;
 
 struct dvfs_info {
-	__le32 header;
+	u8 domain;
+	u8 opp_count;
+	__le16 latency;
 	struct {
 		__le32 freq;
 		__le32 m_volt;
@@ -340,10 +323,6 @@ struct dvfs_set {
 	u8 index;
 } __packed;
 
-struct sensor_capabilities {
-	__le16 sensors;
-} __packed;
-
 struct _scpi_sensor_info {
 	__le16 sensor_id;
 	u8 class;
@@ -351,11 +330,6 @@ struct _scpi_sensor_info {
 	char name[20];
 };
 
-struct sensor_value {
-	__le32 lo_val;
-	__le32 hi_val;
-} __packed;
-
 struct dev_pstate_set {
 	__le16 dev_id;
 	u8 pstate;
@@ -419,19 +393,20 @@ static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd)
 		unsigned int len;
 
 		if (scpi_info->is_legacy) {
-			struct legacy_scpi_shared_mem *mem = ch->rx_payload;
+			struct legacy_scpi_shared_mem __iomem *mem =
+							ch->rx_payload;
 
 			/* RX Length is not replied by the legacy Firmware */
 			len = match->rx_len;
 
-			match->status = le32_to_cpu(mem->status);
+			match->status = ioread32(&mem->status);
 			memcpy_fromio(match->rx_buf, mem->payload, len);
 		} else {
-			struct scpi_shared_mem *mem = ch->rx_payload;
+			struct scpi_shared_mem __iomem *mem = ch->rx_payload;
 
-			len = min(match->rx_len, CMD_SIZE(cmd));
+			len = min_t(unsigned int, match->rx_len, CMD_SIZE(cmd));
 
-			match->status = le32_to_cpu(mem->status);
+			match->status = ioread32(&mem->status);
 			memcpy_fromio(match->rx_buf, mem->payload, len);
 		}
 
@@ -445,11 +420,11 @@ static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd)
 static void scpi_handle_remote_msg(struct mbox_client *c, void *msg)
 {
 	struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
-	struct scpi_shared_mem *mem = ch->rx_payload;
+	struct scpi_shared_mem __iomem *mem = ch->rx_payload;
 	u32 cmd = 0;
 
 	if (!scpi_info->is_legacy)
-		cmd = le32_to_cpu(mem->command);
+		cmd = ioread32(&mem->command);
 
 	scpi_process_cmd(ch, cmd);
 }
@@ -459,7 +434,7 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg)
 	unsigned long flags;
 	struct scpi_xfer *t = msg;
 	struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
-	struct scpi_shared_mem *mem = (struct scpi_shared_mem *)ch->tx_payload;
+	struct scpi_shared_mem __iomem *mem = ch->tx_payload;
 
 	if (t->tx_buf) {
 		if (scpi_info->is_legacy)
@@ -471,14 +446,14 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg)
 	if (t->rx_buf) {
 		if (!(++ch->token))
 			++ch->token;
-		ADD_SCPI_TOKEN(t->cmd, ch->token);
+		t->cmd |= FIELD_PREP(CMD_TOKEN_ID_MASK, ch->token);
 		spin_lock_irqsave(&ch->rx_lock, flags);
 		list_add_tail(&t->node, &ch->rx_pending);
 		spin_unlock_irqrestore(&ch->rx_lock, flags);
 	}
 
 	if (!scpi_info->is_legacy)
-		mem->command = cpu_to_le32(t->cmd);
+		iowrite32(t->cmd, &mem->command);
 }
 
 static struct scpi_xfer *get_scpi_xfer(struct scpi_chan *ch)
@@ -583,13 +558,13 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
 static unsigned long scpi_clk_get_val(u16 clk_id)
 {
 	int ret;
-	struct clk_get_value clk;
+	__le32 rate;
 	__le16 le_clk_id = cpu_to_le16(clk_id);
 
 	ret = scpi_send_message(CMD_GET_CLOCK_VALUE, &le_clk_id,
-				sizeof(le_clk_id), &clk, sizeof(clk));
+				sizeof(le_clk_id), &rate, sizeof(rate));
 
-	return ret ? ret : le32_to_cpu(clk.rate);
+	return ret ? ret : le32_to_cpu(rate);
 }
 
 static int scpi_clk_set_val(u16 clk_id, unsigned long rate)
@@ -665,8 +640,8 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
 	if (!info)
 		return ERR_PTR(-ENOMEM);
 
-	info->count = DVFS_OPP_COUNT(buf.header);
-	info->latency = DVFS_LATENCY(buf.header) * 1000; /* uS to nS */
+	info->count = buf.opp_count;
+	info->latency = le16_to_cpu(buf.latency) * 1000; /* uS to nS */
 
 	info->opps = kcalloc(info->count, sizeof(*opp), GFP_KERNEL);
 	if (!info->opps) {
@@ -713,9 +688,6 @@ static int scpi_dvfs_get_transition_latency(struct device *dev)
 	if (IS_ERR(info))
 		return PTR_ERR(info);
 
-	if (!info->latency)
-		return 0;
-
 	return info->latency;
 }
 
@@ -746,13 +718,13 @@ static int scpi_dvfs_add_opps_to_device(struct device *dev)
 
 static int scpi_sensor_get_capability(u16 *sensors)
 {
-	struct sensor_capabilities cap_buf;
+	__le16 cap;
 	int ret;
 
-	ret = scpi_send_message(CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf,
-				sizeof(cap_buf));
+	ret = scpi_send_message(CMD_SENSOR_CAPABILITIES, NULL, 0, &cap,
+				sizeof(cap));
 	if (!ret)
-		*sensors = le16_to_cpu(cap_buf.sensors);
+		*sensors = le16_to_cpu(cap);
 
 	return ret;
 }
@@ -776,20 +748,19 @@ static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info)
 static int scpi_sensor_get_value(u16 sensor, u64 *val)
 {
 	__le16 id = cpu_to_le16(sensor);
-	struct sensor_value buf;
+	__le64 value;
 	int ret;
 
 	ret = scpi_send_message(CMD_SENSOR_VALUE, &id, sizeof(id),
-				&buf, sizeof(buf));
+				&value, sizeof(value));
 	if (ret)
 		return ret;
 
 	if (scpi_info->is_legacy)
-		/* only 32-bits supported, hi_val can be junk */
-		*val = le32_to_cpu(buf.lo_val);
+		/* only 32-bits supported, upper 32 bits can be junk */
+		*val = le32_to_cpup((__le32 *)&value);
 	else
-		*val = (u64)le32_to_cpu(buf.hi_val) << 32 |
-			le32_to_cpu(buf.lo_val);
+		*val = le64_to_cpu(value);
 
 	return 0;
 }
@@ -864,9 +835,9 @@ static ssize_t protocol_version_show(struct device *dev,
 {
 	struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev);
 
-	return sprintf(buf, "%d.%d\n",
-		       PROTOCOL_REV_MAJOR(scpi_info->protocol_version),
-		       PROTOCOL_REV_MINOR(scpi_info->protocol_version));
+	return sprintf(buf, "%lu.%lu\n",
+		FIELD_GET(PROTO_REV_MAJOR_MASK, scpi_info->protocol_version),
+		FIELD_GET(PROTO_REV_MINOR_MASK, scpi_info->protocol_version));
 }
 static DEVICE_ATTR_RO(protocol_version);
 
@@ -875,10 +846,10 @@ static ssize_t firmware_version_show(struct device *dev,
 {
 	struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev);
 
-	return sprintf(buf, "%d.%d.%d\n",
-		       FW_REV_MAJOR(scpi_info->firmware_version),
-		       FW_REV_MINOR(scpi_info->firmware_version),
-		       FW_REV_PATCH(scpi_info->firmware_version));
+	return sprintf(buf, "%lu.%lu.%lu\n",
+		FIELD_GET(FW_REV_MAJOR_MASK, scpi_info->firmware_version),
+		FIELD_GET(FW_REV_MINOR_MASK, scpi_info->firmware_version),
+		FIELD_GET(FW_REV_PATCH_MASK, scpi_info->firmware_version));
 }
 static DEVICE_ATTR_RO(firmware_version);
 
@@ -889,37 +860,26 @@ static struct attribute *versions_attrs[] = {
 };
 ATTRIBUTE_GROUPS(versions);
 
-static void
-scpi_free_channels(struct device *dev, struct scpi_chan *pchan, int count)
+static void scpi_free_channels(void *data)
 {
+	struct scpi_drvinfo *info = data;
 	int i;
 
-	for (i = 0; i < count && pchan->chan; i++, pchan++) {
-		mbox_free_channel(pchan->chan);
-		devm_kfree(dev, pchan->xfers);
-		devm_iounmap(dev, pchan->rx_payload);
-	}
+	for (i = 0; i < info->num_chans; i++)
+		mbox_free_channel(info->channels[i].chan);
 }
 
 static int scpi_remove(struct platform_device *pdev)
 {
 	int i;
-	struct device *dev = &pdev->dev;
 	struct scpi_drvinfo *info = platform_get_drvdata(pdev);
 
 	scpi_info = NULL; /* stop exporting SCPI ops through get_scpi_ops */
 
-	of_platform_depopulate(dev);
-	sysfs_remove_groups(&dev->kobj, versions_groups);
-	scpi_free_channels(dev, info->channels, info->num_chans);
-	platform_set_drvdata(pdev, NULL);
-
 	for (i = 0; i < MAX_DVFS_DOMAINS && info->dvfs[i]; i++) {
 		kfree(info->dvfs[i]->opps);
 		kfree(info->dvfs[i]);
 	}
-	devm_kfree(dev, info->channels);
-	devm_kfree(dev, info);
 
 	return 0;
 }
@@ -952,7 +912,6 @@ static int scpi_probe(struct platform_device *pdev)
 {
 	int count, idx, ret;
 	struct resource res;
-	struct scpi_chan *scpi_chan;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 
@@ -969,13 +928,19 @@ static int scpi_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	scpi_chan = devm_kcalloc(dev, count, sizeof(*scpi_chan), GFP_KERNEL);
-	if (!scpi_chan)
+	scpi_info->channels = devm_kcalloc(dev, count, sizeof(struct scpi_chan),
+					   GFP_KERNEL);
+	if (!scpi_info->channels)
 		return -ENOMEM;
 
-	for (idx = 0; idx < count; idx++) {
+	ret = devm_add_action(dev, scpi_free_channels, scpi_info);
+	if (ret)
+		return ret;
+
+	for (; scpi_info->num_chans < count; scpi_info->num_chans++) {
 		resource_size_t size;
-		struct scpi_chan *pchan = scpi_chan + idx;
+		int idx = scpi_info->num_chans;
+		struct scpi_chan *pchan = scpi_info->channels + idx;
 		struct mbox_client *cl = &pchan->cl;
 		struct device_node *shmem = of_parse_phandle(np, "shmem", idx);
 
@@ -983,15 +948,14 @@ static int scpi_probe(struct platform_device *pdev)
 		of_node_put(shmem);
 		if (ret) {
 			dev_err(dev, "failed to get SCPI payload mem resource\n");
-			goto err;
+			return ret;
 		}
 
 		size = resource_size(&res);
 		pchan->rx_payload = devm_ioremap(dev, res.start, size);
 		if (!pchan->rx_payload) {
 			dev_err(dev, "failed to ioremap SCPI payload\n");
-			ret = -EADDRNOTAVAIL;
-			goto err;
+			return -EADDRNOTAVAIL;
 		}
 		pchan->tx_payload = pchan->rx_payload + (size >> 1);
 
@@ -1017,14 +981,9 @@ static int scpi_probe(struct platform_device *pdev)
 				dev_err(dev, "failed to get channel%d err %d\n",
 					idx, ret);
 		}
-err:
-		scpi_free_channels(dev, scpi_chan, idx);
-		scpi_info = NULL;
 		return ret;
 	}
 
-	scpi_info->channels = scpi_chan;
-	scpi_info->num_chans = count;
 	scpi_info->commands = scpi_std_commands;
 
 	platform_set_drvdata(pdev, scpi_info);
@@ -1043,23 +1002,31 @@ static int scpi_probe(struct platform_device *pdev)
 	ret = scpi_init_versions(scpi_info);
 	if (ret) {
 		dev_err(dev, "incorrect or no SCP firmware found\n");
-		scpi_remove(pdev);
 		return ret;
 	}
 
-	_dev_info(dev, "SCP Protocol %d.%d Firmware %d.%d.%d version\n",
-		  PROTOCOL_REV_MAJOR(scpi_info->protocol_version),
-		  PROTOCOL_REV_MINOR(scpi_info->protocol_version),
-		  FW_REV_MAJOR(scpi_info->firmware_version),
-		  FW_REV_MINOR(scpi_info->firmware_version),
-		  FW_REV_PATCH(scpi_info->firmware_version));
+	if (scpi_info->is_legacy && !scpi_info->protocol_version &&
+	    !scpi_info->firmware_version)
+		dev_info(dev, "SCP Protocol legacy pre-1.0 firmware\n");
+	else
+		dev_info(dev, "SCP Protocol %lu.%lu Firmware %lu.%lu.%lu version\n",
+			 FIELD_GET(PROTO_REV_MAJOR_MASK,
+				   scpi_info->protocol_version),
+			 FIELD_GET(PROTO_REV_MINOR_MASK,
+				   scpi_info->protocol_version),
+			 FIELD_GET(FW_REV_MAJOR_MASK,
+				   scpi_info->firmware_version),
+			 FIELD_GET(FW_REV_MINOR_MASK,
+				   scpi_info->firmware_version),
+			 FIELD_GET(FW_REV_PATCH_MASK,
+				   scpi_info->firmware_version));
 	scpi_info->scpi_ops = &scpi_ops;
 
-	ret = sysfs_create_groups(&dev->kobj, versions_groups);
+	ret = devm_device_add_groups(dev, versions_groups);
 	if (ret)
 		dev_err(dev, "unable to create sysfs version group\n");
 
-	return of_platform_populate(dev->of_node, NULL, NULL, dev);
+	return devm_of_platform_populate(dev);
 }
 
 static const struct of_device_id scpi_of_match[] = {
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index e35c5e0..6feeacb 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -32,6 +32,7 @@ static char dmi_ids_string[128] __initdata;
 static struct dmi_memdev_info {
 	const char *device;
 	const char *bank;
+	u64 size;		/* bytes */
 	u16 handle;
 } *dmi_memdev;
 static int dmi_memdev_nr;
@@ -386,6 +387,8 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v)
 {
 	const char *d = (const char *)dm;
 	static int nr;
+	u64 bytes;
+	u16 size;
 
 	if (dm->type != DMI_ENTRY_MEM_DEVICE || dm->length < 0x12)
 		return;
@@ -396,6 +399,20 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v)
 	dmi_memdev[nr].handle = get_unaligned(&dm->handle);
 	dmi_memdev[nr].device = dmi_string(dm, d[0x10]);
 	dmi_memdev[nr].bank = dmi_string(dm, d[0x11]);
+
+	size = get_unaligned((u16 *)&d[0xC]);
+	if (size == 0)
+		bytes = 0;
+	else if (size == 0xffff)
+		bytes = ~0ull;
+	else if (size & 0x8000)
+		bytes = (u64)(size & 0x7fff) << 10;
+	else if (size != 0x7fff)
+		bytes = (u64)size << 20;
+	else
+		bytes = (u64)get_unaligned((u32 *)&d[0x1C]) << 20;
+
+	dmi_memdev[nr].size = bytes;
 	nr++;
 }
 
@@ -1085,3 +1102,17 @@ void dmi_memdev_name(u16 handle, const char **bank, const char **device)
 	}
 }
 EXPORT_SYMBOL_GPL(dmi_memdev_name);
+
+u64 dmi_memdev_size(u16 handle)
+{
+	int n;
+
+	if (dmi_memdev) {
+		for (n = 0; n < dmi_memdev_nr; n++) {
+			if (handle == dmi_memdev[n].handle)
+				return dmi_memdev[n].size;
+		}
+	}
+	return ~0ull;
+}
+EXPORT_SYMBOL_GPL(dmi_memdev_size);
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 60a8f13..1b82c89 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -748,14 +748,12 @@ edd_init(void)
 	int rc=0;
 	struct edd_device *edev;
 
+	if (!edd_num_devices())
+		return -ENODEV;
+
 	printk(KERN_INFO "BIOS EDD facility v%s %s, %d devices found\n",
 	       EDD_VERSION, EDD_DATE, edd_num_devices());
 
-	if (!edd_num_devices()) {
-		printk(KERN_INFO "EDD information not available.\n");
-		return -ENODEV;
-	}
-
 	edd_kset = kset_create_and_add("edd", NULL, firmware_kobj);
 	if (!edd_kset)
 		return -ENOMEM;
diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index ff20442..0ec2ca8 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -17,8 +17,10 @@
 #include <linux/arm-smccc.h>
 #include <linux/bug.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/platform_device.h>
 #include <linux/printk.h>
 #include <linux/types.h>
 #include <linux/sizes.h>
@@ -217,21 +219,11 @@ static const struct of_device_id meson_sm_ids[] = {
 	{ /* sentinel */ },
 };
 
-int __init meson_sm_init(void)
+static int __init meson_sm_probe(struct platform_device *pdev)
 {
 	const struct meson_sm_chip *chip;
-	const struct of_device_id *matched_np;
-	struct device_node *np;
 
-	np = of_find_matching_node_and_match(NULL, meson_sm_ids, &matched_np);
-	if (!np)
-		return -ENODEV;
-
-	chip = matched_np->data;
-	if (!chip) {
-		pr_err("unable to setup secure-monitor data\n");
-		goto out;
-	}
+	chip = of_match_device(meson_sm_ids, &pdev->dev)->data;
 
 	if (chip->cmd_shmem_in_base) {
 		fw.sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
@@ -257,4 +249,11 @@ int __init meson_sm_init(void)
 out:
 	return -EINVAL;
 }
-device_initcall(meson_sm_init);
+
+static struct platform_driver meson_sm_driver = {
+	.driver = {
+		.name = "meson-sm",
+		.of_match_table = of_match_ptr(meson_sm_ids),
+	},
+};
+module_platform_driver_probe(meson_sm_driver, meson_sm_probe);
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index a7f461f..14a456a 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -70,57 +70,20 @@ void tegra_bpmp_put(struct tegra_bpmp *bpmp)
 }
 EXPORT_SYMBOL_GPL(tegra_bpmp_put);
 
-static int tegra_bpmp_channel_get_index(struct tegra_bpmp_channel *channel)
-{
-	return channel - channel->bpmp->channels;
-}
-
 static int
 tegra_bpmp_channel_get_thread_index(struct tegra_bpmp_channel *channel)
 {
 	struct tegra_bpmp *bpmp = channel->bpmp;
-	unsigned int offset, count;
+	unsigned int count;
 	int index;
 
-	offset = bpmp->soc->channels.thread.offset;
 	count = bpmp->soc->channels.thread.count;
 
-	index = tegra_bpmp_channel_get_index(channel);
-	if (index < 0)
-		return index;
-
-	if (index < offset || index >= offset + count)
+	index = channel - channel->bpmp->threaded_channels;
+	if (index < 0 || index >= count)
 		return -EINVAL;
 
-	return index - offset;
-}
-
-static struct tegra_bpmp_channel *
-tegra_bpmp_channel_get_thread(struct tegra_bpmp *bpmp, unsigned int index)
-{
-	unsigned int offset = bpmp->soc->channels.thread.offset;
-	unsigned int count = bpmp->soc->channels.thread.count;
-
-	if (index >= count)
-		return NULL;
-
-	return &bpmp->channels[offset + index];
-}
-
-static struct tegra_bpmp_channel *
-tegra_bpmp_channel_get_tx(struct tegra_bpmp *bpmp)
-{
-	unsigned int offset = bpmp->soc->channels.cpu_tx.offset;
-
-	return &bpmp->channels[offset + smp_processor_id()];
-}
-
-static struct tegra_bpmp_channel *
-tegra_bpmp_channel_get_rx(struct tegra_bpmp *bpmp)
-{
-	unsigned int offset = bpmp->soc->channels.cpu_rx.offset;
-
-	return &bpmp->channels[offset];
+	return index;
 }
 
 static bool tegra_bpmp_message_valid(const struct tegra_bpmp_message *msg)
@@ -271,11 +234,7 @@ tegra_bpmp_write_threaded(struct tegra_bpmp *bpmp, unsigned int mrq,
 		goto unlock;
 	}
 
-	channel = tegra_bpmp_channel_get_thread(bpmp, index);
-	if (!channel) {
-		err = -EINVAL;
-		goto unlock;
-	}
+	channel = &bpmp->threaded_channels[index];
 
 	if (!tegra_bpmp_master_free(channel)) {
 		err = -EBUSY;
@@ -328,12 +287,18 @@ int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
 	if (!tegra_bpmp_message_valid(msg))
 		return -EINVAL;
 
-	channel = tegra_bpmp_channel_get_tx(bpmp);
+	channel = bpmp->tx_channel;
+
+	spin_lock(&bpmp->atomic_tx_lock);
 
 	err = tegra_bpmp_channel_write(channel, msg->mrq, MSG_ACK,
 				       msg->tx.data, msg->tx.size);
-	if (err < 0)
+	if (err < 0) {
+		spin_unlock(&bpmp->atomic_tx_lock);
 		return err;
+	}
+
+	spin_unlock(&bpmp->atomic_tx_lock);
 
 	err = mbox_send_message(bpmp->mbox.channel, NULL);
 	if (err < 0)
@@ -607,7 +572,7 @@ static void tegra_bpmp_handle_rx(struct mbox_client *client, void *data)
 	unsigned int i, count;
 	unsigned long *busy;
 
-	channel = tegra_bpmp_channel_get_rx(bpmp);
+	channel = bpmp->rx_channel;
 	count = bpmp->soc->channels.thread.count;
 	busy = bpmp->threaded.busy;
 
@@ -619,9 +584,7 @@ static void tegra_bpmp_handle_rx(struct mbox_client *client, void *data)
 	for_each_set_bit(i, busy, count) {
 		struct tegra_bpmp_channel *channel;
 
-		channel = tegra_bpmp_channel_get_thread(bpmp, i);
-		if (!channel)
-			continue;
+		channel = &bpmp->threaded_channels[i];
 
 		if (tegra_bpmp_master_acked(channel)) {
 			tegra_bpmp_channel_signal(channel);
@@ -698,7 +661,6 @@ static void tegra_bpmp_channel_cleanup(struct tegra_bpmp_channel *channel)
 
 static int tegra_bpmp_probe(struct platform_device *pdev)
 {
-	struct tegra_bpmp_channel *channel;
 	struct tegra_bpmp *bpmp;
 	unsigned int i;
 	char tag[32];
@@ -732,7 +694,7 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
 	}
 
 	bpmp->rx.virt = gen_pool_dma_alloc(bpmp->rx.pool, 4096, &bpmp->rx.phys);
-	if (!bpmp->rx.pool) {
+	if (!bpmp->rx.virt) {
 		dev_err(&pdev->dev, "failed to allocate from RX pool\n");
 		err = -ENOMEM;
 		goto free_tx;
@@ -758,24 +720,45 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
 		goto free_rx;
 	}
 
-	bpmp->num_channels = bpmp->soc->channels.cpu_tx.count +
-			     bpmp->soc->channels.thread.count +
-			     bpmp->soc->channels.cpu_rx.count;
-
-	bpmp->channels = devm_kcalloc(&pdev->dev, bpmp->num_channels,
-				      sizeof(*channel), GFP_KERNEL);
-	if (!bpmp->channels) {
+	spin_lock_init(&bpmp->atomic_tx_lock);
+	bpmp->tx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->tx_channel),
+					GFP_KERNEL);
+	if (!bpmp->tx_channel) {
 		err = -ENOMEM;
 		goto free_rx;
 	}
 
-	/* message channel initialization */
-	for (i = 0; i < bpmp->num_channels; i++) {
-		struct tegra_bpmp_channel *channel = &bpmp->channels[i];
+	bpmp->rx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->rx_channel),
+	                                GFP_KERNEL);
+	if (!bpmp->rx_channel) {
+		err = -ENOMEM;
+		goto free_rx;
+	}
 
-		err = tegra_bpmp_channel_init(channel, bpmp, i);
+	bpmp->threaded_channels = devm_kcalloc(&pdev->dev, bpmp->threaded.count,
+					       sizeof(*bpmp->threaded_channels),
+					       GFP_KERNEL);
+	if (!bpmp->threaded_channels) {
+		err = -ENOMEM;
+		goto free_rx;
+	}
+
+	err = tegra_bpmp_channel_init(bpmp->tx_channel, bpmp,
+				      bpmp->soc->channels.cpu_tx.offset);
+	if (err < 0)
+		goto free_rx;
+
+	err = tegra_bpmp_channel_init(bpmp->rx_channel, bpmp,
+				      bpmp->soc->channels.cpu_rx.offset);
+	if (err < 0)
+		goto cleanup_tx_channel;
+
+	for (i = 0; i < bpmp->threaded.count; i++) {
+		err = tegra_bpmp_channel_init(
+			&bpmp->threaded_channels[i], bpmp,
+			bpmp->soc->channels.thread.offset + i);
 		if (err < 0)
-			goto cleanup_channels;
+			goto cleanup_threaded_channels;
 	}
 
 	/* mbox registration */
@@ -788,15 +771,14 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
 	if (IS_ERR(bpmp->mbox.channel)) {
 		err = PTR_ERR(bpmp->mbox.channel);
 		dev_err(&pdev->dev, "failed to get HSP mailbox: %d\n", err);
-		goto cleanup_channels;
+		goto cleanup_threaded_channels;
 	}
 
 	/* reset message channels */
-	for (i = 0; i < bpmp->num_channels; i++) {
-		struct tegra_bpmp_channel *channel = &bpmp->channels[i];
-
-		tegra_bpmp_channel_reset(channel);
-	}
+	tegra_bpmp_channel_reset(bpmp->tx_channel);
+	tegra_bpmp_channel_reset(bpmp->rx_channel);
+	for (i = 0; i < bpmp->threaded.count; i++)
+		tegra_bpmp_channel_reset(&bpmp->threaded_channels[i]);
 
 	err = tegra_bpmp_request_mrq(bpmp, MRQ_PING,
 				     tegra_bpmp_mrq_handle_ping, bpmp);
@@ -845,9 +827,15 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
 	tegra_bpmp_free_mrq(bpmp, MRQ_PING, bpmp);
 free_mbox:
 	mbox_free_channel(bpmp->mbox.channel);
-cleanup_channels:
-	while (i--)
-		tegra_bpmp_channel_cleanup(&bpmp->channels[i]);
+cleanup_threaded_channels:
+	for (i = 0; i < bpmp->threaded.count; i++) {
+		if (bpmp->threaded_channels[i].bpmp)
+			tegra_bpmp_channel_cleanup(&bpmp->threaded_channels[i]);
+	}
+
+	tegra_bpmp_channel_cleanup(bpmp->rx_channel);
+cleanup_tx_channel:
+	tegra_bpmp_channel_cleanup(bpmp->tx_channel);
 free_rx:
 	gen_pool_free(bpmp->rx.pool, (unsigned long)bpmp->rx.virt, 4096);
 free_tx:
@@ -858,18 +846,16 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
 static const struct tegra_bpmp_soc tegra186_soc = {
 	.channels = {
 		.cpu_tx = {
-			.offset = 0,
-			.count = 6,
+			.offset = 3,
 			.timeout = 60 * USEC_PER_SEC,
 		},
 		.thread = {
-			.offset = 6,
-			.count = 7,
+			.offset = 0,
+			.count = 3,
 			.timeout = 600 * USEC_PER_SEC,
 		},
 		.cpu_rx = {
 			.offset = 13,
-			.count = 1,
 			.timeout = 0,
 		},
 	},
diff --git a/drivers/fmc/fmc-core.c b/drivers/fmc/fmc-core.c
index cec3b8d..bbcb505 100644
--- a/drivers/fmc/fmc-core.c
+++ b/drivers/fmc/fmc-core.c
@@ -244,7 +244,7 @@ int fmc_device_register_n_gw(struct fmc_device **devs, int n,
 		if (!fmc->carrier_name || !fmc->carrier_data ||
 		    !fmc->device_id) {
 			dev_err(fmc->hwdev,
-				"deivce nr %i: carrier name, "
+				"device nr %i: carrier name, "
 				"data or dev_id not set\n", i);
 			ret = -EINVAL;
 		}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 68d812b..b960f6f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -122,6 +122,17 @@
 	  Select this option to enable GPIO driver for
 	  Atheros AR71XX/AR724X/AR913X SoC devices.
 
+config GPIO_RASPBERRYPI_EXP
+	tristate "Raspberry Pi 3 GPIO Expander"
+	default RASPBERRYPI_FIRMWARE
+	depends on OF_GPIO
+	# Make sure not 'y' when RASPBERRYPI_FIRMWARE is 'm'. This can only
+	# happen when COMPILE_TEST=y, hence the added !RASPBERRYPI_FIRMWARE.
+	depends on (ARCH_BCM2835 && RASPBERRYPI_FIRMWARE) || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
+	help
+	  Turn on GPIO support for the expander on Raspberry Pi 3 boards, using
+	  the firmware mailbox to communicate with VideoCore on BCM283x chips.
+
 config GPIO_BCM_KONA
 	bool "Broadcom Kona GPIO"
 	depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
@@ -159,6 +170,14 @@
 	  Say Y or M here to build support for the Synopsys DesignWare APB
 	  GPIO block.
 
+config GPIO_EIC_SPRD
+	tristate "Spreadtrum EIC support"
+	depends on ARCH_SPRD || COMPILE_TEST
+	depends on OF_GPIO
+	select GPIOLIB_IRQCHIP
+	help
+	  Say yes here to support Spreadtrum EIC device.
+
 config GPIO_EM
 	tristate "Emma Mobile GPIO"
 	depends on (ARCH_EMEV2 || COMPILE_TEST) && OF_GPIO
@@ -214,6 +233,15 @@
 	  Select this to support Aeroflex Gaisler GRGPIO cores from the GRLIB
 	  VHDL IP core library.
 
+config GPIO_HLWD
+	tristate "Nintendo Wii (Hollywood) GPIO"
+	depends on OF_GPIO
+	select GPIO_GENERIC
+	help
+	  Select this to support the GPIO controller of the Nintendo Wii.
+
+	  If unsure, say N.
+
 config GPIO_ICH
 	tristate "Intel ICH GPIO"
 	depends on PCI && X86
@@ -363,6 +391,14 @@
 	help
 	  Say yes here to support the PrimeCell PL061 GPIO device
 
+config GPIO_PMIC_EIC_SPRD
+	tristate "Spreadtrum PMIC EIC support"
+	depends on MFD_SC27XX_PMIC || COMPILE_TEST
+	depends on OF_GPIO
+	select GPIOLIB_IRQCHIP
+	help
+	  Say yes here to support Spreadtrum PMIC EIC device.
+
 config GPIO_PXA
 	bool "PXA GPIO support"
 	depends on ARCH_PXA || ARCH_MMP
@@ -389,6 +425,14 @@
 	help
 	  Say yes here to support ST SPEAr SPI Chip Select as GPIO device
 
+config GPIO_SPRD
+	tristate "Spreadtrum GPIO support"
+	depends on ARCH_SPRD || COMPILE_TEST
+	depends on OF_GPIO
+	select GPIOLIB_IRQCHIP
+	help
+	  Say yes here to support Spreadtrum GPIO device.
+
 config GPIO_STA2X11
 	bool "STA2x11/ConneXt GPIO support"
 	depends on MFD_STA2X11
@@ -453,21 +497,6 @@
 	  Say yes here to support the on-chip GPIO lines on the ThunderX
 	  and OCTEON-TX families of SoCs.
 
-config GPIO_TZ1090
-	bool "Toumaz Xenif TZ1090 GPIO support"
-	depends on SOC_TZ1090
-	select GENERIC_IRQ_CHIP
-	default y
-	help
-	  Say yes here to support Toumaz Xenif TZ1090 GPIOs.
-
-config GPIO_TZ1090_PDC
-	bool "Toumaz Xenif TZ1090 PDC GPIO support"
-	depends on SOC_TZ1090
-	default y
-	help
-	  Say yes here to support Toumaz Xenif TZ1090 PDC GPIOs.
-
 config GPIO_UNIPHIER
 	tristate "UniPhier GPIO support"
 	depends on ARCH_UNIPHIER || COMPILE_TEST
@@ -581,7 +610,8 @@
 
 config GPIO_104_DIO_48E
 	tristate "ACCES 104-DIO-48E GPIO support"
-	depends on PC104 && ISA_BUS_API
+	depends on PC104
+	select ISA_BUS_API
 	select GPIOLIB_IRQCHIP
 	help
 	  Enables GPIO support for the ACCES 104-DIO-48E series (104-DIO-48E,
@@ -591,7 +621,8 @@
 
 config GPIO_104_IDIO_16
 	tristate "ACCES 104-IDIO-16 GPIO support"
-	depends on PC104 && ISA_BUS_API
+	depends on PC104
+	select ISA_BUS_API
 	select GPIOLIB_IRQCHIP
 	help
 	  Enables GPIO support for the ACCES 104-IDIO-16 family (104-IDIO-16,
@@ -602,7 +633,8 @@
 
 config GPIO_104_IDI_48
 	tristate "ACCES 104-IDI-48 GPIO support"
-	depends on PC104 && ISA_BUS_API
+	depends on PC104
+	select ISA_BUS_API
 	select GPIOLIB_IRQCHIP
 	help
 	  Enables GPIO support for the ACCES 104-IDI-48 family (104-IDI-48A,
@@ -622,7 +654,8 @@
 
 config GPIO_GPIO_MM
 	tristate "Diamond Systems GPIO-MM GPIO support"
-	depends on PC104 && ISA_BUS_API
+	depends on PC104
+	select ISA_BUS_API
 	help
 	  Enables GPIO support for the Diamond Systems GPIO-MM and GPIO-MM-12.
 
@@ -691,7 +724,7 @@
 
 config GPIO_WINBOND
 	tristate "Winbond Super I/O GPIO support"
-	depends on ISA_BUS_API
+	select ISA_BUS_API
 	help
 	  This option enables support for GPIOs found on Winbond Super I/O
 	  chips.
@@ -707,7 +740,7 @@
 
 config GPIO_WS16C48
 	tristate "WinSystems WS16C48 GPIO support"
-	depends on ISA_BUS_API
+	select ISA_BUS_API
 	select GPIOLIB_IRQCHIP
 	help
 	  Enables GPIO support for the WinSystems WS16C48. The base port
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index db8c9d4..1324c8f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -32,6 +32,7 @@
 obj-$(CONFIG_GPIO_ARIZONA)	+= gpio-arizona.o
 obj-$(CONFIG_GPIO_ATH79)	+= gpio-ath79.o
 obj-$(CONFIG_GPIO_ASPEED)	+= gpio-aspeed.o
+obj-$(CONFIG_GPIO_RASPBERRYPI_EXP)	+= gpio-raspberrypi-exp.o
 obj-$(CONFIG_GPIO_BCM_KONA)	+= gpio-bcm-kona.o
 obj-$(CONFIG_GPIO_BD9571MWV)	+= gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BRCMSTB)	+= gpio-brcmstb.o
@@ -44,6 +45,7 @@
 obj-$(CONFIG_GPIO_DAVINCI)	+= gpio-davinci.o
 obj-$(CONFIG_GPIO_DLN2)		+= gpio-dln2.o
 obj-$(CONFIG_GPIO_DWAPB)	+= gpio-dwapb.o
+obj-$(CONFIG_GPIO_EIC_SPRD)	+= gpio-eic-sprd.o
 obj-$(CONFIG_GPIO_EM)		+= gpio-em.o
 obj-$(CONFIG_GPIO_EP93XX)	+= gpio-ep93xx.o
 obj-$(CONFIG_GPIO_EXAR)		+= gpio-exar.o
@@ -52,6 +54,7 @@
 obj-$(CONFIG_GPIO_GE_FPGA)	+= gpio-ge.o
 obj-$(CONFIG_GPIO_GPIO_MM)	+= gpio-gpio-mm.o
 obj-$(CONFIG_GPIO_GRGPIO)	+= gpio-grgpio.o
+obj-$(CONFIG_GPIO_HLWD)		+= gpio-hlwd.o
 obj-$(CONFIG_HTC_EGPIO)		+= gpio-htc-egpio.o
 obj-$(CONFIG_GPIO_ICH)		+= gpio-ich.o
 obj-$(CONFIG_GPIO_INGENIC)	+= gpio-ingenic.o
@@ -97,6 +100,7 @@
 obj-$(CONFIG_GPIO_PCIE_IDIO_24)	+= gpio-pcie-idio-24.o
 obj-$(CONFIG_GPIO_PISOSR)	+= gpio-pisosr.o
 obj-$(CONFIG_GPIO_PL061)	+= gpio-pl061.o
+obj-$(CONFIG_GPIO_PMIC_EIC_SPRD)	+= gpio-pmic-eic-sprd.o
 obj-$(CONFIG_GPIO_PXA)		+= gpio-pxa.o
 obj-$(CONFIG_GPIO_RC5T583)	+= gpio-rc5t583.o
 obj-$(CONFIG_GPIO_RDC321X)	+= gpio-rdc321x.o
@@ -107,6 +111,7 @@
 obj-$(CONFIG_GPIO_SCH311X)	+= gpio-sch311x.o
 obj-$(CONFIG_GPIO_SODAVILLE)	+= gpio-sodaville.o
 obj-$(CONFIG_GPIO_SPEAR_SPICS)	+= gpio-spear-spics.o
+obj-$(CONFIG_GPIO_SPRD)		+= gpio-sprd.o
 obj-$(CONFIG_GPIO_STA2X11)	+= gpio-sta2x11.o
 obj-$(CONFIG_GPIO_STMPE)	+= gpio-stmpe.o
 obj-$(CONFIG_GPIO_STP_XWAY)	+= gpio-stp-xway.o
@@ -130,8 +135,6 @@
 obj-$(CONFIG_GPIO_TS5500)	+= gpio-ts5500.o
 obj-$(CONFIG_GPIO_TWL4030)	+= gpio-twl4030.o
 obj-$(CONFIG_GPIO_TWL6040)	+= gpio-twl6040.o
-obj-$(CONFIG_GPIO_TZ1090)	+= gpio-tz1090.o
-obj-$(CONFIG_GPIO_TZ1090_PDC)	+= gpio-tz1090-pdc.o
 obj-$(CONFIG_GPIO_UCB1400)	+= gpio-ucb1400.o
 obj-$(CONFIG_GPIO_UNIPHIER)	+= gpio-uniphier.o
 obj-$(CONFIG_GPIO_VF610)	+= gpio-vf610.o
diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c
index bab3b94..31e22c9 100644
--- a/drivers/gpio/gpio-104-dio-48e.c
+++ b/drivers/gpio/gpio-104-dio-48e.c
@@ -14,6 +14,7 @@
  * This driver supports the following ACCES devices: 104-DIO-48E and
  * 104-DIO-24E.
  */
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/errno.h>
@@ -182,6 +183,51 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset)
 	return !!(port_state & mask);
 }
 
+static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
+	unsigned long *bits)
+{
+	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
+	size_t i;
+	const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
+	const unsigned int gpio_reg_size = 8;
+	unsigned int bits_offset;
+	size_t word_index;
+	unsigned int word_offset;
+	unsigned long word_mask;
+	const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+	unsigned long port_state;
+
+	/* clear bits array to a clean slate */
+	bitmap_zero(bits, chip->ngpio);
+
+	/* get bits are evaluated a gpio port register at a time */
+	for (i = 0; i < ARRAY_SIZE(ports); i++) {
+		/* gpio offset in bits array */
+		bits_offset = i * gpio_reg_size;
+
+		/* word index for bits array */
+		word_index = BIT_WORD(bits_offset);
+
+		/* gpio offset within current word of bits array */
+		word_offset = bits_offset % BITS_PER_LONG;
+
+		/* mask of get bits for current gpio within current word */
+		word_mask = mask[word_index] & (port_mask << word_offset);
+		if (!word_mask) {
+			/* no get bits in this port so skip to next one */
+			continue;
+		}
+
+		/* read bits from current gpio port */
+		port_state = inb(dio48egpio->base + ports[i]);
+
+		/* store acquired bits at respective bits array offset */
+		bits[word_index] |= port_state << word_offset;
+	}
+
+	return 0;
+}
+
 static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
@@ -384,6 +430,7 @@ static int dio48e_probe(struct device *dev, unsigned int id)
 	dio48egpio->chip.direction_input = dio48e_gpio_direction_input;
 	dio48egpio->chip.direction_output = dio48e_gpio_direction_output;
 	dio48egpio->chip.get = dio48e_gpio_get;
+	dio48egpio->chip.get_multiple = dio48e_gpio_get_multiple;
 	dio48egpio->chip.set = dio48e_gpio_set;
 	dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
 	dio48egpio->base = base[id];
diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c
index add859d..f356326 100644
--- a/drivers/gpio/gpio-104-idi-48.c
+++ b/drivers/gpio/gpio-104-idi-48.c
@@ -14,6 +14,7 @@
  * This driver supports the following ACCES devices: 104-IDI-48A,
  * 104-IDI-48AC, 104-IDI-48B, and 104-IDI-48BC.
  */
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/errno.h>
@@ -88,6 +89,51 @@ static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset)
 	return 0;
 }
 
+static int idi_48_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
+	unsigned long *bits)
+{
+	struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
+	size_t i;
+	const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
+	const unsigned int gpio_reg_size = 8;
+	unsigned int bits_offset;
+	size_t word_index;
+	unsigned int word_offset;
+	unsigned long word_mask;
+	const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+	unsigned long port_state;
+
+	/* clear bits array to a clean slate */
+	bitmap_zero(bits, chip->ngpio);
+
+	/* get bits are evaluated a gpio port register at a time */
+	for (i = 0; i < ARRAY_SIZE(ports); i++) {
+		/* gpio offset in bits array */
+		bits_offset = i * gpio_reg_size;
+
+		/* word index for bits array */
+		word_index = BIT_WORD(bits_offset);
+
+		/* gpio offset within current word of bits array */
+		word_offset = bits_offset % BITS_PER_LONG;
+
+		/* mask of get bits for current gpio within current word */
+		word_mask = mask[word_index] & (port_mask << word_offset);
+		if (!word_mask) {
+			/* no get bits in this port so skip to next one */
+			continue;
+		}
+
+		/* read bits from current gpio port */
+		port_state = inb(idi48gpio->base + ports[i]);
+
+		/* store acquired bits at respective bits array offset */
+		bits[word_index] |= port_state << word_offset;
+	}
+
+	return 0;
+}
+
 static void idi_48_irq_ack(struct irq_data *data)
 {
 }
@@ -256,6 +302,7 @@ static int idi_48_probe(struct device *dev, unsigned int id)
 	idi48gpio->chip.get_direction = idi_48_gpio_get_direction;
 	idi48gpio->chip.direction_input = idi_48_gpio_direction_input;
 	idi48gpio->chip.get = idi_48_gpio_get;
+	idi48gpio->chip.get_multiple = idi_48_gpio_get_multiple;
 	idi48gpio->base = base[id];
 
 	raw_spin_lock_init(&idi48gpio->lock);
diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c
index 2f16638..9670030 100644
--- a/drivers/gpio/gpio-104-idio-16.c
+++ b/drivers/gpio/gpio-104-idio-16.c
@@ -90,6 +90,20 @@ static int idio_16_gpio_get(struct gpio_chip *chip, unsigned offset)
 	return !!(inb(idio16gpio->base + 5) & (mask>>8));
 }
 
+static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
+	unsigned long *mask, unsigned long *bits)
+{
+	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
+
+	*bits = 0;
+	if (*mask & GENMASK(23, 16))
+		*bits |= (unsigned long)inb(idio16gpio->base + 1) << 16;
+	if (*mask & GENMASK(31, 24))
+		*bits |= (unsigned long)inb(idio16gpio->base + 5) << 24;
+
+	return 0;
+}
+
 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
@@ -244,6 +258,7 @@ static int idio_16_probe(struct device *dev, unsigned int id)
 	idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
 	idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
 	idio16gpio->chip.get = idio_16_gpio_get;
+	idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
 	idio16gpio->chip.set = idio_16_gpio_set;
 	idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
 	idio16gpio->base = base[id];
diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c
index 3ae7c18..684e9d6 100644
--- a/drivers/gpio/gpio-ath79.c
+++ b/drivers/gpio/gpio-ath79.c
@@ -258,6 +258,8 @@ static int ath79_gpio_probe(struct platform_device *pdev)
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -EINVAL;
 	ctrl->base = devm_ioremap_nocache(
 		&pdev->dev, res->start, resource_size(res));
 	if (!ctrl->base)
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
index 0b951ca..987126c 100644
--- a/drivers/gpio/gpio-davinci.c
+++ b/drivers/gpio/gpio-davinci.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/irqchip/chained_irq.h>
@@ -225,6 +226,11 @@ static int davinci_gpio_probe(struct platform_device *pdev)
 	chips->chip.of_gpio_n_cells = 2;
 	chips->chip.parent = dev;
 	chips->chip.of_node = dev->of_node;
+
+	if (of_property_read_bool(dev->of_node, "gpio-ranges")) {
+		chips->chip.request = gpiochip_generic_request;
+		chips->chip.free = gpiochip_generic_free;
+	}
 #endif
 	spin_lock_init(&chips->lock);
 	bank_base += ngpio;
diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c
index 1dada68..c4e7953 100644
--- a/drivers/gpio/gpio-dln2.c
+++ b/drivers/gpio/gpio-dln2.c
@@ -15,7 +15,6 @@
 #include <linux/irqdomain.h>
 #include <linux/irq.h>
 #include <linux/irqchip/chained_irq.h>
-#include <linux/gpio.h>
 #include <linux/gpio/driver.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/dln2.h>
@@ -204,9 +203,9 @@ static int dln2_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
 	struct dln2_gpio *dln2 = gpiochip_get_data(chip);
 
 	if (test_bit(offset, dln2->output_enabled))
-		return GPIOF_DIR_OUT;
+		return 0;
 
-	return GPIOF_DIR_IN;
+	return 1;
 }
 
 static int dln2_gpio_get(struct gpio_chip *chip, unsigned int offset)
@@ -218,7 +217,7 @@ static int dln2_gpio_get(struct gpio_chip *chip, unsigned int offset)
 	if (dir < 0)
 		return dir;
 
-	if (dir == GPIOF_DIR_IN)
+	if (dir == 1)
 		return dln2_gpio_pin_get_in_val(dln2, offset);
 
 	return dln2_gpio_pin_get_out_val(dln2, offset);
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 6730c66..226977f 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -8,10 +8,9 @@
  * All enquiries to support@picochip.com
  */
 #include <linux/acpi.h>
-#include <linux/gpio/driver.h>
-/* FIXME: for gpio_get_value(), replace this with direct register read */
-#include <linux/gpio.h>
+#include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/gpio/driver.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -53,9 +52,9 @@
 #define GPIO_EXT_PORTD		0x5c
 
 #define DWAPB_MAX_PORTS		4
-#define GPIO_EXT_PORT_SIZE	(GPIO_EXT_PORTB - GPIO_EXT_PORTA)
-#define GPIO_SWPORT_DR_SIZE	(GPIO_SWPORTB_DR - GPIO_SWPORTA_DR)
-#define GPIO_SWPORT_DDR_SIZE	(GPIO_SWPORTB_DDR - GPIO_SWPORTA_DDR)
+#define GPIO_EXT_PORT_STRIDE	0x04 /* register stride 32 bits */
+#define GPIO_SWPORT_DR_STRIDE	0x0c /* register stride 3*32 bits */
+#define GPIO_SWPORT_DDR_STRIDE	0x0c /* register stride 3*32 bits */
 
 #define GPIO_REG_OFFSET_V2	1
 
@@ -100,6 +99,7 @@ struct dwapb_gpio {
 	struct irq_domain	*domain;
 	unsigned int		flags;
 	struct reset_control	*rst;
+	struct clk		*clk;
 };
 
 static inline u32 gpio_reg_v2_convert(unsigned int offset)
@@ -153,16 +153,40 @@ static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 	return irq_find_mapping(gpio->domain, offset);
 }
 
+static struct dwapb_gpio_port *dwapb_offs_to_port(struct dwapb_gpio *gpio, unsigned int offs)
+{
+	struct dwapb_gpio_port *port;
+	int i;
+
+	for (i = 0; i < gpio->nr_ports; i++) {
+		port = &gpio->ports[i];
+		if (port->idx == offs / 32)
+			return port;
+	}
+
+	return NULL;
+}
+
 static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)
 {
-	u32 v = dwapb_read(gpio, GPIO_INT_POLARITY);
+	struct dwapb_gpio_port *port = dwapb_offs_to_port(gpio, offs);
+	struct gpio_chip *gc;
+	u32 pol;
+	int val;
 
-	if (gpio_get_value(gpio->ports[0].gc.base + offs))
-		v &= ~BIT(offs);
+	if (!port)
+		return;
+	gc = &port->gc;
+
+	pol = dwapb_read(gpio, GPIO_INT_POLARITY);
+	/* Just read the current value right out of the data register */
+	val = gc->get(gc, offs % 32);
+	if (val)
+		pol &= ~BIT(offs);
 	else
-		v |= BIT(offs);
+		pol |= BIT(offs);
 
-	dwapb_write(gpio, GPIO_INT_POLARITY, v);
+	dwapb_write(gpio, GPIO_INT_POLARITY, pol);
 }
 
 static u32 dwapb_do_irq(struct dwapb_gpio *gpio)
@@ -476,11 +500,12 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
 		return -ENOMEM;
 #endif
 
-	dat = gpio->regs + GPIO_EXT_PORTA + (pp->idx * GPIO_EXT_PORT_SIZE);
-	set = gpio->regs + GPIO_SWPORTA_DR + (pp->idx * GPIO_SWPORT_DR_SIZE);
+	dat = gpio->regs + GPIO_EXT_PORTA + (pp->idx * GPIO_EXT_PORT_STRIDE);
+	set = gpio->regs + GPIO_SWPORTA_DR + (pp->idx * GPIO_SWPORT_DR_STRIDE);
 	dirout = gpio->regs + GPIO_SWPORTA_DDR +
-		(pp->idx * GPIO_SWPORT_DDR_SIZE);
+		(pp->idx * GPIO_SWPORT_DDR_STRIDE);
 
+	/* This registers 32 GPIO lines per port */
 	err = bgpio_init(&port->gc, gpio->dev, 4, dat, set, NULL, dirout,
 			 NULL, 0);
 	if (err) {
@@ -647,6 +672,16 @@ static int dwapb_gpio_probe(struct platform_device *pdev)
 	if (IS_ERR(gpio->regs))
 		return PTR_ERR(gpio->regs);
 
+	/* Optional bus clock */
+	gpio->clk = devm_clk_get(&pdev->dev, "bus");
+	if (!IS_ERR(gpio->clk)) {
+		err = clk_prepare_enable(gpio->clk);
+		if (err) {
+			dev_info(&pdev->dev, "Cannot enable clock\n");
+			return err;
+		}
+	}
+
 	gpio->flags = 0;
 	if (dev->of_node) {
 		const struct of_device_id *of_devid;
@@ -689,6 +724,7 @@ static int dwapb_gpio_remove(struct platform_device *pdev)
 	dwapb_gpio_unregister(gpio);
 	dwapb_irq_teardown(gpio);
 	reset_control_assert(gpio->rst);
+	clk_disable_unprepare(gpio->clk);
 
 	return 0;
 }
@@ -710,13 +746,13 @@ static int dwapb_gpio_suspend(struct device *dev)
 
 		BUG_ON(!ctx);
 
-		offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_SIZE;
+		offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_STRIDE;
 		ctx->dir = dwapb_read(gpio, offset);
 
-		offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_SIZE;
+		offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_STRIDE;
 		ctx->data = dwapb_read(gpio, offset);
 
-		offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_SIZE;
+		offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_STRIDE;
 		ctx->ext = dwapb_read(gpio, offset);
 
 		/* Only port A can provide interrupts */
@@ -734,6 +770,8 @@ static int dwapb_gpio_suspend(struct device *dev)
 	}
 	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
 
+	clk_disable_unprepare(gpio->clk);
+
 	return 0;
 }
 
@@ -745,6 +783,9 @@ static int dwapb_gpio_resume(struct device *dev)
 	unsigned long flags;
 	int i;
 
+	if (!IS_ERR(gpio->clk))
+		clk_prepare_enable(gpio->clk);
+
 	spin_lock_irqsave(&gc->bgpio_lock, flags);
 	for (i = 0; i < gpio->nr_ports; i++) {
 		unsigned int offset;
@@ -753,13 +794,13 @@ static int dwapb_gpio_resume(struct device *dev)
 
 		BUG_ON(!ctx);
 
-		offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_SIZE;
+		offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_STRIDE;
 		dwapb_write(gpio, offset, ctx->data);
 
-		offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_SIZE;
+		offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_STRIDE;
 		dwapb_write(gpio, offset, ctx->dir);
 
-		offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_SIZE;
+		offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_STRIDE;
 		dwapb_write(gpio, offset, ctx->ext);
 
 		/* Only port A can provide interrupts */
diff --git a/drivers/gpio/gpio-eic-sprd.c b/drivers/gpio/gpio-eic-sprd.c
new file mode 100644
index 0000000..de7dd93
--- /dev/null
+++ b/drivers/gpio/gpio-eic-sprd.c
@@ -0,0 +1,606 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Spreadtrum Communications Inc.
+ * Copyright (C) 2018 Linaro Ltd.
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+/* EIC registers definition */
+#define SPRD_EIC_DBNC_DATA		0x0
+#define SPRD_EIC_DBNC_DMSK		0x4
+#define SPRD_EIC_DBNC_IEV		0x14
+#define SPRD_EIC_DBNC_IE		0x18
+#define SPRD_EIC_DBNC_RIS		0x1c
+#define SPRD_EIC_DBNC_MIS		0x20
+#define SPRD_EIC_DBNC_IC		0x24
+#define SPRD_EIC_DBNC_TRIG		0x28
+#define SPRD_EIC_DBNC_CTRL0		0x40
+
+#define SPRD_EIC_LATCH_INTEN		0x0
+#define SPRD_EIC_LATCH_INTRAW		0x4
+#define SPRD_EIC_LATCH_INTMSK		0x8
+#define SPRD_EIC_LATCH_INTCLR		0xc
+#define SPRD_EIC_LATCH_INTPOL		0x10
+#define SPRD_EIC_LATCH_INTMODE		0x14
+
+#define SPRD_EIC_ASYNC_INTIE		0x0
+#define SPRD_EIC_ASYNC_INTRAW		0x4
+#define SPRD_EIC_ASYNC_INTMSK		0x8
+#define SPRD_EIC_ASYNC_INTCLR		0xc
+#define SPRD_EIC_ASYNC_INTMODE		0x10
+#define SPRD_EIC_ASYNC_INTBOTH		0x14
+#define SPRD_EIC_ASYNC_INTPOL		0x18
+#define SPRD_EIC_ASYNC_DATA		0x1c
+
+#define SPRD_EIC_SYNC_INTIE		0x0
+#define SPRD_EIC_SYNC_INTRAW		0x4
+#define SPRD_EIC_SYNC_INTMSK		0x8
+#define SPRD_EIC_SYNC_INTCLR		0xc
+#define SPRD_EIC_SYNC_INTMODE		0x10
+#define SPRD_EIC_SYNC_INTBOTH		0x14
+#define SPRD_EIC_SYNC_INTPOL		0x18
+#define SPRD_EIC_SYNC_DATA		0x1c
+
+/*
+ * The digital-chip EIC controller can support maximum 3 banks, and each bank
+ * contains 8 EICs.
+ */
+#define SPRD_EIC_MAX_BANK		3
+#define SPRD_EIC_PER_BANK_NR		8
+#define SPRD_EIC_DATA_MASK		GENMASK(7, 0)
+#define SPRD_EIC_BIT(x)			((x) & (SPRD_EIC_PER_BANK_NR - 1))
+#define SPRD_EIC_DBNC_MASK		GENMASK(11, 0)
+
+/*
+ * The Spreadtrum EIC (external interrupt controller) can be used only in
+ * input mode to generate interrupts if detecting input signals.
+ *
+ * The Spreadtrum digital-chip EIC controller contains 4 sub-modules:
+ * debounce EIC, latch EIC, async EIC and sync EIC,
+ *
+ * The debounce EIC is used to capture the input signals' stable status
+ * (millisecond resolution) and a single-trigger mechanism is introduced
+ * into this sub-module to enhance the input event detection reliability.
+ * The debounce range is from 1ms to 4s with a step size of 1ms.
+ *
+ * The latch EIC is used to latch some special power down signals and
+ * generate interrupts, since the latch EIC does not depend on the APB clock
+ * to capture signals.
+ *
+ * The async EIC uses a 32k clock to capture the short signals (microsecond
+ * resolution) to generate interrupts by level or edge trigger.
+ *
+ * The EIC-sync is similar with GPIO's input function, which is a synchronized
+ * signal input register.
+ */
+enum sprd_eic_type {
+	SPRD_EIC_DEBOUNCE,
+	SPRD_EIC_LATCH,
+	SPRD_EIC_ASYNC,
+	SPRD_EIC_SYNC,
+	SPRD_EIC_MAX,
+};
+
+struct sprd_eic {
+	struct gpio_chip chip;
+	struct irq_chip intc;
+	void __iomem *base[SPRD_EIC_MAX_BANK];
+	enum sprd_eic_type type;
+	spinlock_t lock;
+	int irq;
+};
+
+struct sprd_eic_variant_data {
+	enum sprd_eic_type type;
+	u32 num_eics;
+};
+
+static const char *sprd_eic_label_name[SPRD_EIC_MAX] = {
+	"eic-debounce", "eic-latch", "eic-async",
+	"eic-sync",
+};
+
+static const struct sprd_eic_variant_data sc9860_eic_dbnc_data = {
+	.type = SPRD_EIC_DEBOUNCE,
+	.num_eics = 8,
+};
+
+static const struct sprd_eic_variant_data sc9860_eic_latch_data = {
+	.type = SPRD_EIC_LATCH,
+	.num_eics = 8,
+};
+
+static const struct sprd_eic_variant_data sc9860_eic_async_data = {
+	.type = SPRD_EIC_ASYNC,
+	.num_eics = 8,
+};
+
+static const struct sprd_eic_variant_data sc9860_eic_sync_data = {
+	.type = SPRD_EIC_SYNC,
+	.num_eics = 8,
+};
+
+static inline void __iomem *sprd_eic_offset_base(struct sprd_eic *sprd_eic,
+						 unsigned int bank)
+{
+	if (bank >= SPRD_EIC_MAX_BANK)
+		return NULL;
+
+	return sprd_eic->base[bank];
+}
+
+static void sprd_eic_update(struct gpio_chip *chip, unsigned int offset,
+			    u16 reg, unsigned int val)
+{
+	struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+	void __iomem *base =
+		sprd_eic_offset_base(sprd_eic, offset / SPRD_EIC_PER_BANK_NR);
+	unsigned long flags;
+	u32 tmp;
+
+	spin_lock_irqsave(&sprd_eic->lock, flags);
+	tmp = readl_relaxed(base + reg);
+
+	if (val)
+		tmp |= BIT(SPRD_EIC_BIT(offset));
+	else
+		tmp &= ~BIT(SPRD_EIC_BIT(offset));
+
+	writel_relaxed(tmp, base + reg);
+	spin_unlock_irqrestore(&sprd_eic->lock, flags);
+}
+
+static int sprd_eic_read(struct gpio_chip *chip, unsigned int offset, u16 reg)
+{
+	struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+	void __iomem *base =
+		sprd_eic_offset_base(sprd_eic, offset / SPRD_EIC_PER_BANK_NR);
+
+	return !!(readl_relaxed(base + reg) & BIT(SPRD_EIC_BIT(offset)));
+}
+
+static int sprd_eic_request(struct gpio_chip *chip, unsigned int offset)
+{
+	sprd_eic_update(chip, offset, SPRD_EIC_DBNC_DMSK, 1);
+	return 0;
+}
+
+static void sprd_eic_free(struct gpio_chip *chip, unsigned int offset)
+{
+	sprd_eic_update(chip, offset, SPRD_EIC_DBNC_DMSK, 0);
+}
+
+static int sprd_eic_get(struct gpio_chip *chip, unsigned int offset)
+{
+	return sprd_eic_read(chip, offset, SPRD_EIC_DBNC_DATA);
+}
+
+static int sprd_eic_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	/* EICs are always input, nothing need to do here. */
+	return 0;
+}
+
+static void sprd_eic_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	/* EICs are always input, nothing need to do here. */
+}
+
+static int sprd_eic_set_debounce(struct gpio_chip *chip, unsigned int offset,
+				 unsigned int debounce)
+{
+	struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+	void __iomem *base =
+		sprd_eic_offset_base(sprd_eic, offset / SPRD_EIC_PER_BANK_NR);
+	u32 reg = SPRD_EIC_DBNC_CTRL0 + SPRD_EIC_BIT(offset) * 0x4;
+	u32 value = readl_relaxed(base + reg) & ~SPRD_EIC_DBNC_MASK;
+
+	value |= (debounce / 1000) & SPRD_EIC_DBNC_MASK;
+	writel_relaxed(value, base + reg);
+
+	return 0;
+}
+
+static int sprd_eic_set_config(struct gpio_chip *chip, unsigned int offset,
+			       unsigned long config)
+{
+	unsigned long param = pinconf_to_config_param(config);
+	u32 arg = pinconf_to_config_argument(config);
+
+	if (param == PIN_CONFIG_INPUT_DEBOUNCE)
+		return sprd_eic_set_debounce(chip, offset, arg);
+
+	return -ENOTSUPP;
+}
+
+static void sprd_eic_irq_mask(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+	u32 offset = irqd_to_hwirq(data);
+
+	switch (sprd_eic->type) {
+	case SPRD_EIC_DEBOUNCE:
+		sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IE, 0);
+		sprd_eic_update(chip, offset, SPRD_EIC_DBNC_TRIG, 0);
+		break;
+	case SPRD_EIC_LATCH:
+		sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTEN, 0);
+		break;
+	case SPRD_EIC_ASYNC:
+		sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTIE, 0);
+		break;
+	case SPRD_EIC_SYNC:
+		sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTIE, 0);
+		break;
+	default:
+		dev_err(chip->parent, "Unsupported EIC type.\n");
+	}
+}
+
+static void sprd_eic_irq_unmask(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+	u32 offset = irqd_to_hwirq(data);
+
+	switch (sprd_eic->type) {
+	case SPRD_EIC_DEBOUNCE:
+		sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IE, 1);
+		sprd_eic_update(chip, offset, SPRD_EIC_DBNC_TRIG, 1);
+		break;
+	case SPRD_EIC_LATCH:
+		sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTEN, 1);
+		break;
+	case SPRD_EIC_ASYNC:
+		sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTIE, 1);
+		break;
+	case SPRD_EIC_SYNC:
+		sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTIE, 1);
+		break;
+	default:
+		dev_err(chip->parent, "Unsupported EIC type.\n");
+	}
+}
+
+static void sprd_eic_irq_ack(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+	u32 offset = irqd_to_hwirq(data);
+
+	switch (sprd_eic->type) {
+	case SPRD_EIC_DEBOUNCE:
+		sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1);
+		break;
+	case SPRD_EIC_LATCH:
+		sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1);
+		break;
+	case SPRD_EIC_ASYNC:
+		sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
+		break;
+	case SPRD_EIC_SYNC:
+		sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
+		break;
+	default:
+		dev_err(chip->parent, "Unsupported EIC type.\n");
+	}
+}
+
+static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+	u32 offset = irqd_to_hwirq(data);
+
+	switch (sprd_eic->type) {
+	case SPRD_EIC_DEBOUNCE:
+		switch (flow_type) {
+		case IRQ_TYPE_LEVEL_HIGH:
+			sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1);
+			break;
+		case IRQ_TYPE_LEVEL_LOW:
+			sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0);
+			break;
+		default:
+			return -ENOTSUPP;
+		}
+
+		irq_set_handler_locked(data, handle_level_irq);
+		break;
+	case SPRD_EIC_LATCH:
+		switch (flow_type) {
+		case IRQ_TYPE_LEVEL_HIGH:
+			sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0);
+			break;
+		case IRQ_TYPE_LEVEL_LOW:
+			sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1);
+			break;
+		default:
+			return -ENOTSUPP;
+		}
+
+		irq_set_handler_locked(data, handle_level_irq);
+		break;
+	case SPRD_EIC_ASYNC:
+		switch (flow_type) {
+		case IRQ_TYPE_EDGE_RISING:
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1);
+			irq_set_handler_locked(data, handle_edge_irq);
+			break;
+		case IRQ_TYPE_EDGE_FALLING:
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0);
+			irq_set_handler_locked(data, handle_edge_irq);
+			break;
+		case IRQ_TYPE_EDGE_BOTH:
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1);
+			irq_set_handler_locked(data, handle_edge_irq);
+			break;
+		case IRQ_TYPE_LEVEL_HIGH:
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1);
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1);
+			irq_set_handler_locked(data, handle_level_irq);
+			break;
+		case IRQ_TYPE_LEVEL_LOW:
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1);
+			sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0);
+			irq_set_handler_locked(data, handle_level_irq);
+			break;
+		default:
+			return -ENOTSUPP;
+		}
+		break;
+	case SPRD_EIC_SYNC:
+		switch (flow_type) {
+		case IRQ_TYPE_EDGE_RISING:
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1);
+			irq_set_handler_locked(data, handle_edge_irq);
+			break;
+		case IRQ_TYPE_EDGE_FALLING:
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0);
+			irq_set_handler_locked(data, handle_edge_irq);
+			break;
+		case IRQ_TYPE_EDGE_BOTH:
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 1);
+			irq_set_handler_locked(data, handle_edge_irq);
+			break;
+		case IRQ_TYPE_LEVEL_HIGH:
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1);
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1);
+			irq_set_handler_locked(data, handle_level_irq);
+			break;
+		case IRQ_TYPE_LEVEL_LOW:
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1);
+			sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0);
+			irq_set_handler_locked(data, handle_level_irq);
+			break;
+		default:
+			return -ENOTSUPP;
+		}
+	default:
+		dev_err(chip->parent, "Unsupported EIC type.\n");
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int sprd_eic_match_chip_by_type(struct gpio_chip *chip, void *data)
+{
+	enum sprd_eic_type type = *(enum sprd_eic_type *)data;
+
+	return !strcmp(chip->label, sprd_eic_label_name[type]);
+}
+
+static void sprd_eic_handle_one_type(struct gpio_chip *chip)
+{
+	struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+	u32 bank, n, girq;
+
+	for (bank = 0; bank * SPRD_EIC_PER_BANK_NR < chip->ngpio; bank++) {
+		void __iomem *base = sprd_eic_offset_base(sprd_eic, bank);
+		unsigned long reg;
+
+		switch (sprd_eic->type) {
+		case SPRD_EIC_DEBOUNCE:
+			reg = readl_relaxed(base + SPRD_EIC_DBNC_MIS) &
+				SPRD_EIC_DATA_MASK;
+			break;
+		case SPRD_EIC_LATCH:
+			reg = readl_relaxed(base + SPRD_EIC_LATCH_INTMSK) &
+				SPRD_EIC_DATA_MASK;
+			break;
+		case SPRD_EIC_ASYNC:
+			reg = readl_relaxed(base + SPRD_EIC_ASYNC_INTMSK) &
+				SPRD_EIC_DATA_MASK;
+			break;
+		case SPRD_EIC_SYNC:
+			reg = readl_relaxed(base + SPRD_EIC_SYNC_INTMSK) &
+				SPRD_EIC_DATA_MASK;
+			break;
+		default:
+			dev_err(chip->parent, "Unsupported EIC type.\n");
+			return;
+		}
+
+		for_each_set_bit(n, &reg, SPRD_EIC_PER_BANK_NR) {
+			girq = irq_find_mapping(chip->irq.domain,
+					bank * SPRD_EIC_PER_BANK_NR + n);
+
+			generic_handle_irq(girq);
+		}
+	}
+}
+
+static void sprd_eic_irq_handler(struct irq_desc *desc)
+{
+	struct irq_chip *ic = irq_desc_get_chip(desc);
+	struct gpio_chip *chip;
+	enum sprd_eic_type type;
+
+	chained_irq_enter(ic, desc);
+
+	/*
+	 * Since the digital-chip EIC 4 sub-modules (debounce, latch, async
+	 * and sync) share one same interrupt line, we should iterate each
+	 * EIC module to check if there are EIC interrupts were triggered.
+	 */
+	for (type = SPRD_EIC_DEBOUNCE; type < SPRD_EIC_MAX; type++) {
+		chip = gpiochip_find(&type, sprd_eic_match_chip_by_type);
+		if (!chip)
+			continue;
+
+		sprd_eic_handle_one_type(chip);
+	}
+
+	chained_irq_exit(ic, desc);
+}
+
+static int sprd_eic_probe(struct platform_device *pdev)
+{
+	const struct sprd_eic_variant_data *pdata;
+	struct gpio_irq_chip *irq;
+	struct sprd_eic *sprd_eic;
+	struct resource *res;
+	int ret, i;
+
+	pdata = of_device_get_match_data(&pdev->dev);
+	if (!pdata) {
+		dev_err(&pdev->dev, "No matching driver data found.\n");
+		return -EINVAL;
+	}
+
+	sprd_eic = devm_kzalloc(&pdev->dev, sizeof(*sprd_eic), GFP_KERNEL);
+	if (!sprd_eic)
+		return -ENOMEM;
+
+	spin_lock_init(&sprd_eic->lock);
+	sprd_eic->type = pdata->type;
+
+	sprd_eic->irq = platform_get_irq(pdev, 0);
+	if (sprd_eic->irq < 0) {
+		dev_err(&pdev->dev, "Failed to get EIC interrupt.\n");
+		return sprd_eic->irq;
+	}
+
+	for (i = 0; i < SPRD_EIC_MAX_BANK; i++) {
+		/*
+		 * We can have maximum 3 banks EICs, and each EIC has
+		 * its own base address. But some platform maybe only
+		 * have one bank EIC, thus base[1] and base[2] can be
+		 * optional.
+		 */
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!res)
+			continue;
+
+		sprd_eic->base[i] = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(sprd_eic->base[i]))
+			return PTR_ERR(sprd_eic->base[i]);
+	}
+
+	sprd_eic->chip.label = sprd_eic_label_name[sprd_eic->type];
+	sprd_eic->chip.ngpio = pdata->num_eics;
+	sprd_eic->chip.base = -1;
+	sprd_eic->chip.parent = &pdev->dev;
+	sprd_eic->chip.of_node = pdev->dev.of_node;
+	sprd_eic->chip.direction_input = sprd_eic_direction_input;
+	switch (sprd_eic->type) {
+	case SPRD_EIC_DEBOUNCE:
+		sprd_eic->chip.request = sprd_eic_request;
+		sprd_eic->chip.free = sprd_eic_free;
+		sprd_eic->chip.set_config = sprd_eic_set_config;
+		sprd_eic->chip.set = sprd_eic_set;
+		/* fall-through */
+	case SPRD_EIC_ASYNC:
+		/* fall-through */
+	case SPRD_EIC_SYNC:
+		sprd_eic->chip.get = sprd_eic_get;
+		break;
+	case SPRD_EIC_LATCH:
+		/* fall-through */
+	default:
+		break;
+	}
+
+	sprd_eic->intc.name = dev_name(&pdev->dev);
+	sprd_eic->intc.irq_ack = sprd_eic_irq_ack;
+	sprd_eic->intc.irq_mask = sprd_eic_irq_mask;
+	sprd_eic->intc.irq_unmask = sprd_eic_irq_unmask;
+	sprd_eic->intc.irq_set_type = sprd_eic_irq_set_type;
+	sprd_eic->intc.flags = IRQCHIP_SKIP_SET_WAKE;
+
+	irq = &sprd_eic->chip.irq;
+	irq->chip = &sprd_eic->intc;
+	irq->handler = handle_bad_irq;
+	irq->default_type = IRQ_TYPE_NONE;
+	irq->parent_handler = sprd_eic_irq_handler;
+	irq->parent_handler_data = sprd_eic;
+	irq->num_parents = 1;
+	irq->parents = &sprd_eic->irq;
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &sprd_eic->chip, sprd_eic);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip %d.\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, sprd_eic);
+	return 0;
+}
+
+static const struct of_device_id sprd_eic_of_match[] = {
+	{
+		.compatible = "sprd,sc9860-eic-debounce",
+		.data = &sc9860_eic_dbnc_data,
+	},
+	{
+		.compatible = "sprd,sc9860-eic-latch",
+		.data = &sc9860_eic_latch_data,
+	},
+	{
+		.compatible = "sprd,sc9860-eic-async",
+		.data = &sc9860_eic_async_data,
+	},
+	{
+		.compatible = "sprd,sc9860-eic-sync",
+		.data = &sc9860_eic_sync_data,
+	},
+	{
+		/* end of list */
+	}
+};
+MODULE_DEVICE_TABLE(of, sprd_eic_of_match);
+
+static struct platform_driver sprd_eic_driver = {
+	.probe = sprd_eic_probe,
+	.driver = {
+		.name = "sprd-eic",
+		.of_match_table	= sprd_eic_of_match,
+	},
+};
+
+module_platform_driver(sprd_eic_driver);
+
+MODULE_DESCRIPTION("Spreadtrum EIC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c
index b86e09e..2b466b8 100644
--- a/drivers/gpio/gpio-em.c
+++ b/drivers/gpio/gpio-em.c
@@ -27,7 +27,7 @@
 #include <linux/irqdomain.h>
 #include <linux/bitops.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/pinctrl/consumer.h>
diff --git a/drivers/gpio/gpio-ftgpio010.c b/drivers/gpio/gpio-ftgpio010.c
index b7a3a2d..868bf85 100644
--- a/drivers/gpio/gpio-ftgpio010.c
+++ b/drivers/gpio/gpio-ftgpio010.c
@@ -14,19 +14,20 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/of_gpio.h>
 #include <linux/bitops.h>
 
 /* GPIO registers definition */
 #define GPIO_DATA_OUT		0x00
 #define GPIO_DATA_IN		0x04
 #define GPIO_DIR		0x08
+#define GPIO_BYPASS_IN		0x0C
 #define GPIO_DATA_SET		0x10
 #define GPIO_DATA_CLR		0x14
 #define GPIO_PULL_EN		0x18
 #define GPIO_PULL_TYPE		0x1C
 #define GPIO_INT_EN		0x20
-#define GPIO_INT_STAT		0x24
+#define GPIO_INT_STAT_RAW	0x24
+#define GPIO_INT_STAT_MASKED	0x28
 #define GPIO_INT_MASK		0x2C
 #define GPIO_INT_CLR		0x30
 #define GPIO_INT_TYPE		0x34
@@ -147,7 +148,7 @@ static void ftgpio_gpio_irq_handler(struct irq_desc *desc)
 
 	chained_irq_enter(irqchip, desc);
 
-	stat = readl(g->base + GPIO_INT_STAT);
+	stat = readl(g->base + GPIO_INT_STAT_RAW);
 	if (stat)
 		for_each_set_bit(offset, &stat, gc->ngpio)
 			generic_handle_irq(irq_find_mapping(gc->irq.domain,
diff --git a/drivers/gpio/gpio-ge.c b/drivers/gpio/gpio-ge.c
index 6f5a7fe..1fe2d34 100644
--- a/drivers/gpio/gpio-ge.c
+++ b/drivers/gpio/gpio-ge.c
@@ -21,7 +21,6 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
 #include <linux/of_address.h>
 #include <linux/module.h>
 #include <linux/gpio/driver.h>
diff --git a/drivers/gpio/gpio-gpio-mm.c b/drivers/gpio/gpio-gpio-mm.c
index 11ade5b..d496cc56 100644
--- a/drivers/gpio/gpio-gpio-mm.c
+++ b/drivers/gpio/gpio-gpio-mm.c
@@ -14,6 +14,7 @@
  * This driver supports the following Diamond Systems devices: GPIO-MM and
  * GPIO-MM-12.
  */
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/errno.h>
@@ -171,6 +172,51 @@ static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset)
 	return !!(port_state & mask);
 }
 
+static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
+	unsigned long *bits)
+{
+	struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
+	size_t i;
+	const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
+	const unsigned int gpio_reg_size = 8;
+	unsigned int bits_offset;
+	size_t word_index;
+	unsigned int word_offset;
+	unsigned long word_mask;
+	const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+	unsigned long port_state;
+
+	/* clear bits array to a clean slate */
+	bitmap_zero(bits, chip->ngpio);
+
+	/* get bits are evaluated a gpio port register at a time */
+	for (i = 0; i < ARRAY_SIZE(ports); i++) {
+		/* gpio offset in bits array */
+		bits_offset = i * gpio_reg_size;
+
+		/* word index for bits array */
+		word_index = BIT_WORD(bits_offset);
+
+		/* gpio offset within current word of bits array */
+		word_offset = bits_offset % BITS_PER_LONG;
+
+		/* mask of get bits for current gpio within current word */
+		word_mask = mask[word_index] & (port_mask << word_offset);
+		if (!word_mask) {
+			/* no get bits in this port so skip to next one */
+			continue;
+		}
+
+		/* read bits from current gpio port */
+		port_state = inb(gpiommgpio->base + ports[i]);
+
+		/* store acquired bits at respective bits array offset */
+		bits[word_index] |= port_state << word_offset;
+	}
+
+	return 0;
+}
+
 static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset,
 	int value)
 {
@@ -268,6 +314,7 @@ static int gpiomm_probe(struct device *dev, unsigned int id)
 	gpiommgpio->chip.direction_input = gpiomm_gpio_direction_input;
 	gpiommgpio->chip.direction_output = gpiomm_gpio_direction_output;
 	gpiommgpio->chip.get = gpiomm_gpio_get;
+	gpiommgpio->chip.get_multiple = gpiomm_gpio_get_multiple;
 	gpiommgpio->chip.set = gpiomm_gpio_set;
 	gpiommgpio->chip.set_multiple = gpiomm_gpio_set_multiple;
 	gpiommgpio->base = base[id];
diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
index e2fc561..60a1556 100644
--- a/drivers/gpio/gpio-grgpio.c
+++ b/drivers/gpio/gpio-grgpio.c
@@ -26,9 +26,8 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <linux/of_gpio.h>
 #include <linux/of_platform.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
diff --git a/drivers/gpio/gpio-hlwd.c b/drivers/gpio/gpio-hlwd.c
new file mode 100644
index 0000000..a63136a
--- /dev/null
+++ b/drivers/gpio/gpio-hlwd.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (C) 2008-2009 The GameCube Linux Team
+// Copyright (C) 2008,2009 Albert Herranz
+// Copyright (C) 2017-2018 Jonathan Neuschäfer
+//
+// Nintendo Wii (Hollywood) GPIO driver
+
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+/*
+ * Register names and offsets courtesy of WiiBrew:
+ * https://wiibrew.org/wiki/Hardware/Hollywood_GPIOs
+ *
+ * Note that for most registers, there are two versions:
+ * - HW_GPIOB_* Is always accessible by the Broadway PowerPC core, but does
+ *   always give access to all GPIO lines
+ * - HW_GPIO_* Is only accessible by the Broadway PowerPC code if the memory
+ *   firewall (AHBPROT) in the Hollywood chipset has been configured to allow
+ *   such access.
+ *
+ * The ownership of each GPIO line can be configured in the HW_GPIO_OWNER
+ * register: A one bit configures the line for access via the HW_GPIOB_*
+ * registers, a zero bit indicates access via HW_GPIO_*. This driver uses
+ * HW_GPIOB_*.
+ */
+#define HW_GPIOB_OUT		0x00
+#define HW_GPIOB_DIR		0x04
+#define HW_GPIOB_IN		0x08
+#define HW_GPIOB_INTLVL		0x0c
+#define HW_GPIOB_INTFLAG	0x10
+#define HW_GPIOB_INTMASK	0x14
+#define HW_GPIOB_INMIR		0x18
+#define HW_GPIO_ENABLE		0x1c
+#define HW_GPIO_OUT		0x20
+#define HW_GPIO_DIR		0x24
+#define HW_GPIO_IN		0x28
+#define HW_GPIO_INTLVL		0x2c
+#define HW_GPIO_INTFLAG		0x30
+#define HW_GPIO_INTMASK		0x34
+#define HW_GPIO_INMIR		0x38
+#define HW_GPIO_OWNER		0x3c
+
+struct hlwd_gpio {
+	struct gpio_chip gpioc;
+	void __iomem *regs;
+};
+
+static int hlwd_gpio_probe(struct platform_device *pdev)
+{
+	struct hlwd_gpio *hlwd;
+	struct resource *regs_resource;
+	u32 ngpios;
+	int res;
+
+	hlwd = devm_kzalloc(&pdev->dev, sizeof(*hlwd), GFP_KERNEL);
+	if (!hlwd)
+		return -ENOMEM;
+
+	regs_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hlwd->regs = devm_ioremap_resource(&pdev->dev, regs_resource);
+	if (IS_ERR(hlwd->regs))
+		return PTR_ERR(hlwd->regs);
+
+	/*
+	 * Claim all GPIOs using the OWNER register. This will not work on
+	 * systems where the AHBPROT memory firewall hasn't been configured to
+	 * permit PPC access to HW_GPIO_*.
+	 *
+	 * Note that this has to happen before bgpio_init reads the
+	 * HW_GPIOB_OUT and HW_GPIOB_DIR, because otherwise it reads the wrong
+	 * values.
+	 */
+	iowrite32be(0xffffffff, hlwd->regs + HW_GPIO_OWNER);
+
+	res = bgpio_init(&hlwd->gpioc, &pdev->dev, 4,
+			hlwd->regs + HW_GPIOB_IN, hlwd->regs + HW_GPIOB_OUT,
+			NULL, hlwd->regs + HW_GPIOB_DIR, NULL,
+			BGPIOF_BIG_ENDIAN_BYTE_ORDER);
+	if (res < 0) {
+		dev_warn(&pdev->dev, "bgpio_init failed: %d\n", res);
+		return res;
+	}
+
+	res = of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios);
+	if (res)
+		ngpios = 32;
+	hlwd->gpioc.ngpio = ngpios;
+
+	return devm_gpiochip_add_data(&pdev->dev, &hlwd->gpioc, hlwd);
+}
+
+static const struct of_device_id hlwd_gpio_match[] = {
+	{ .compatible = "nintendo,hollywood-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, hlwd_gpio_match);
+
+static struct platform_driver hlwd_gpio_driver = {
+	.driver	= {
+		.name		= "gpio-hlwd",
+		.of_match_table	= hlwd_gpio_match,
+	},
+	.probe	= hlwd_gpio_probe,
+};
+module_platform_driver(hlwd_gpio_driver);
+
+MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>");
+MODULE_DESCRIPTION("Nintendo Wii GPIO driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-htc-egpio.c b/drivers/gpio/gpio-htc-egpio.c
index 271356e..5163839 100644
--- a/drivers/gpio/gpio-htc-egpio.c
+++ b/drivers/gpio/gpio-htc-egpio.c
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/gpio/driver.h>
 
 struct egpio_chip {
 	int              reg_start;
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c
index 4f6d643..dba3922 100644
--- a/drivers/gpio/gpio-ich.c
+++ b/drivers/gpio/gpio-ich.c
@@ -23,9 +23,10 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/lpc_ich.h>
+#include <linux/bitops.h>
 
 #define DRV_NAME "gpio_ich"
 
@@ -131,9 +132,9 @@ static int ichx_write_bit(int reg, unsigned nr, int val, int verify)
 				 ichx_priv.gpio_base);
 
 	if (val)
-		data |= 1 << bit;
+		data |= BIT(bit);
 	else
-		data &= ~(1 << bit);
+		data &= ~BIT(bit);
 	ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr],
 			 ichx_priv.gpio_base);
 	if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
@@ -166,17 +167,17 @@ static int ichx_read_bit(int reg, unsigned nr)
 
 	spin_unlock_irqrestore(&ichx_priv.lock, flags);
 
-	return data & (1 << bit) ? 1 : 0;
+	return !!(data & BIT(bit));
 }
 
 static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
 {
-	return !!(ichx_priv.use_gpio & (1 << (nr / 32)));
+	return !!(ichx_priv.use_gpio & BIT(nr / 32));
 }
 
 static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned nr)
 {
-	return ichx_read_bit(GPIO_IO_SEL, nr) ? GPIOF_DIR_IN : GPIOF_DIR_OUT;
+	return ichx_read_bit(GPIO_IO_SEL, nr);
 }
 
 static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
@@ -232,12 +233,12 @@ static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
 		spin_lock_irqsave(&ichx_priv.lock, flags);
 
 		/* GPI 0 - 15 are latched, write 1 to clear*/
-		ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base);
+		ICHX_WRITE(BIT(16 + nr), 0, ichx_priv.pm_base);
 		data = ICHX_READ(0, ichx_priv.pm_base);
 
 		spin_unlock_irqrestore(&ichx_priv.lock, flags);
 
-		return (data >> 16) & (1 << nr) ? 1 : 0;
+		return !!((data >> 16) & BIT(nr));
 	} else {
 		return ichx_gpio_get(chip, nr);
 	}
@@ -254,7 +255,7 @@ static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr)
 	 * the chipset's USE value can be trusted for this specific bit.
 	 * If it can't be trusted, assume that the pin can be used as a GPIO.
 	 */
-	if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f)))
+	if (ichx_priv.desc->use_sel_ignore[nr / 32] & BIT(nr & 0x1f))
 		return 0;
 
 	return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV;
@@ -394,7 +395,7 @@ static int ichx_gpio_request_regions(struct device *dev,
 		return -ENODEV;
 
 	for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
-		if (!(use_gpio & (1 << i)))
+		if (!(use_gpio & BIT(i)))
 			continue;
 		if (!devm_request_region(dev,
 				res_base->start + ichx_priv.desc->regs[0][i],
diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c
index 629575e..028d64c 100644
--- a/drivers/gpio/gpio-intel-mid.c
+++ b/drivers/gpio/gpio-intel-mid.c
@@ -361,10 +361,8 @@ static int intel_gpio_probe(struct pci_dev *pdev,
 	pcim_iounmap_regions(pdev, 1 << 1);
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		dev_err(&pdev->dev, "can't allocate chip data\n");
+	if (!priv)
 		return -ENOMEM;
-	}
 
 	priv->reg_base = pcim_iomap_table(pdev)[0];
 	priv->chip.label = dev_name(&pdev->dev);
diff --git a/drivers/gpio/gpio-it87.c b/drivers/gpio/gpio-it87.c
index efb46ed..7cad14d 100644
--- a/drivers/gpio/gpio-it87.c
+++ b/drivers/gpio/gpio-it87.c
@@ -31,7 +31,7 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 
 /* Chip Id numbers */
 #define NO_DEV_ID	0xffff
diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c
index a8d0a6b..6b9bf8b 100644
--- a/drivers/gpio/gpio-janz-ttl.c
+++ b/drivers/gpio/gpio-janz-ttl.c
@@ -16,8 +16,9 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/slab.h>
+#include <linux/bitops.h>
 
 #include <linux/mfd/janz.h>
 
@@ -33,9 +34,9 @@
 #define MASTER_INT_CTL		0x00
 #define MASTER_CONF_CTL		0x01
 
-#define CONF_PAE		(1 << 2)
-#define CONF_PBE		(1 << 7)
-#define CONF_PCE		(1 << 4)
+#define CONF_PAE		BIT(2)
+#define CONF_PBE		BIT(7)
+#define CONF_PCE		BIT(4)
 
 struct ttl_control_regs {
 	__be16 portc;
@@ -74,7 +75,7 @@ static int ttl_get_value(struct gpio_chip *gpio, unsigned offset)
 	}
 
 	spin_lock(&mod->lock);
-	ret = *shadow & (1 << offset);
+	ret = *shadow & BIT(offset);
 	spin_unlock(&mod->lock);
 	return !!ret;
 }
@@ -100,9 +101,9 @@ static void ttl_set_value(struct gpio_chip *gpio, unsigned offset, int value)
 
 	spin_lock(&mod->lock);
 	if (value)
-		*shadow |= (1 << offset);
+		*shadow |= BIT(offset);
 	else
-		*shadow &= ~(1 << offset);
+		*shadow &= ~BIT(offset);
 
 	iowrite16be(*shadow, port);
 	spin_unlock(&mod->lock);
diff --git a/drivers/gpio/gpio-kempld.c b/drivers/gpio/gpio-kempld.c
index 701f151..7bb96f4 100644
--- a/drivers/gpio/gpio-kempld.c
+++ b/drivers/gpio/gpio-kempld.c
@@ -20,7 +20,7 @@
 #include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/mfd/kempld.h>
 
 #define KEMPLD_GPIO_MAX_NUM		16
diff --git a/drivers/gpio/gpio-ks8695.c b/drivers/gpio/gpio-ks8695.c
index 179723d..55d562e 100644
--- a/drivers/gpio/gpio-ks8695.c
+++ b/drivers/gpio/gpio-ks8695.c
@@ -18,7 +18,7 @@
  * 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/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
diff --git a/drivers/gpio/gpio-max3191x.c b/drivers/gpio/gpio-max3191x.c
index f74b107..b5b9cb1 100644
--- a/drivers/gpio/gpio-max3191x.c
+++ b/drivers/gpio/gpio-max3191x.c
@@ -315,12 +315,17 @@ static void gpiod_set_array_single_value_cansleep(unsigned int ndescs,
 						  struct gpio_desc **desc,
 						  int value)
 {
-	int i, values[ndescs];
+	int i, *values;
+
+	values = kmalloc_array(ndescs, sizeof(*values), GFP_KERNEL);
+	if (!values)
+		return;
 
 	for (i = 0; i < ndescs; i++)
 		values[i] = value;
 
 	gpiod_set_array_value_cansleep(ndescs, desc, values);
+	kfree(values);
 }
 
 static struct gpio_descs *devm_gpiod_get_array_optional_count(
diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c
index c38624e..97421bd 100644
--- a/drivers/gpio/gpio-merrifield.c
+++ b/drivers/gpio/gpio-merrifield.c
@@ -416,10 +416,8 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
 	pcim_iounmap_regions(pdev, BIT(1));
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		dev_err(&pdev->dev, "can't allocate chip data\n");
+	if (!priv)
 		return -ENOMEM;
-	}
 
 	priv->dev = &pdev->dev;
 	priv->reg_base = pcim_iomap_table(pdev)[0];
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c
index 4b80e99..b3678bd 100644
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -445,7 +445,6 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
 
 	chip_save = kzalloc(sizeof(*chip) * 8, GFP_KERNEL);
 	if (chip_save == NULL) {
-		dev_err(&pdev->dev, "%s : kzalloc failed", __func__);
 		ret = -ENOMEM;
 		goto err_kzalloc;
 	}
diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c
index 3a545ad..76c2fe9 100644
--- a/drivers/gpio/gpio-mockup.c
+++ b/drivers/gpio/gpio-mockup.c
@@ -2,7 +2,7 @@
  * GPIO Testing Device Driver
  *
  * Copyright (C) 2014  Kamlakant Patel <kamlakant.patel@broadcom.com>
- * Copyright (C) 2015-2016  Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
+ * Copyright (C) 2015-2016  Bamvor Jian Zhang <bamv2005@gmail.com>
  * Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl>
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -314,7 +314,7 @@ static int gpio_mockup_probe(struct platform_device *pdev)
 	if (rv)
 		return rv;
 
-	if (gpio_mockup_dbg_dir)
+	if (!IS_ERR_OR_NULL(gpio_mockup_dbg_dir))
 		gpio_mockup_debugfs_setup(dev, chip);
 
 	return 0;
@@ -411,7 +411,7 @@ module_init(gpio_mockup_init);
 module_exit(gpio_mockup_exit);
 
 MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>");
-MODULE_AUTHOR("Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>");
+MODULE_AUTHOR("Bamvor Jian Zhang <bamv2005@gmail.com>");
 MODULE_AUTHOR("Bartosz Golaszewski <brgl@bgdev.pl>");
 MODULE_DESCRIPTION("GPIO Testing driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index ab5035b..35971a3 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1157,11 +1157,9 @@ static int omap_gpio_probe(struct platform_device *pdev)
 	if (!pdata)
 		return -EINVAL;
 
-	bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL);
-	if (!bank) {
-		dev_err(dev, "Memory alloc failed\n");
+	bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL);
+	if (!bank)
 		return -ENOMEM;
-	}
 
 	irqc = devm_kzalloc(dev, sizeof(*irqc), GFP_KERNEL);
 	if (!irqc)
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index a0a5f97..d2ead4b 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -70,6 +70,7 @@ static const struct i2c_device_id pca953x_id[] = {
 	{ "pca9575", 16 | PCA957X_TYPE | PCA_INT, },
 	{ "pca9698", 40 | PCA953X_TYPE, },
 
+	{ "pcal6524", 24 | PCA953X_TYPE | PCA_INT | PCA_PCAL, },
 	{ "pcal9555a", 16 | PCA953X_TYPE | PCA_INT | PCA_PCAL, },
 
 	{ "max7310", 8  | PCA953X_TYPE, },
@@ -935,6 +936,9 @@ static const struct of_device_id pca953x_dt_ids[] = {
 	{ .compatible = "nxp,pca9575", .data = OF_957X(16, PCA_INT), },
 	{ .compatible = "nxp,pca9698", .data = OF_953X(40, 0), },
 
+	{ .compatible = "nxp,pcal6524", .data = OF_953X(24, PCA_INT), },
+	{ .compatible = "nxp,pcal9555a", .data = OF_953X(16, PCA_INT), },
+
 	{ .compatible = "maxim,max7310", .data = OF_953X( 8, 0), },
 	{ .compatible = "maxim,max7312", .data = OF_953X(16, PCA_INT), },
 	{ .compatible = "maxim,max7313", .data = OF_953X(16, PCA_INT), },
diff --git a/drivers/gpio/gpio-pci-idio-16.c b/drivers/gpio/gpio-pci-idio-16.c
index 57d1b7f..1948724 100644
--- a/drivers/gpio/gpio-pci-idio-16.c
+++ b/drivers/gpio/gpio-pci-idio-16.c
@@ -11,6 +11,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  */
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/errno.h>
@@ -103,6 +104,54 @@ static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
 	return !!(ioread8(&idio16gpio->reg->in8_15) & (mask >> 24));
 }
 
+static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
+	unsigned long *mask, unsigned long *bits)
+{
+	struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
+	size_t i;
+	const unsigned int gpio_reg_size = 8;
+	unsigned int bits_offset;
+	size_t word_index;
+	unsigned int word_offset;
+	unsigned long word_mask;
+	const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+	unsigned long port_state;
+	u8 __iomem ports[] = {
+		idio16gpio->reg->out0_7, idio16gpio->reg->out8_15,
+		idio16gpio->reg->in0_7, idio16gpio->reg->in8_15,
+	};
+
+	/* clear bits array to a clean slate */
+	bitmap_zero(bits, chip->ngpio);
+
+	/* get bits are evaluated a gpio port register at a time */
+	for (i = 0; i < ARRAY_SIZE(ports); i++) {
+		/* gpio offset in bits array */
+		bits_offset = i * gpio_reg_size;
+
+		/* word index for bits array */
+		word_index = BIT_WORD(bits_offset);
+
+		/* gpio offset within current word of bits array */
+		word_offset = bits_offset % BITS_PER_LONG;
+
+		/* mask of get bits for current gpio within current word */
+		word_mask = mask[word_index] & (port_mask << word_offset);
+		if (!word_mask) {
+			/* no get bits in this port so skip to next one */
+			continue;
+		}
+
+		/* read bits from current gpio port */
+		port_state = ioread8(ports + i);
+
+		/* store acquired bits at respective bits array offset */
+		bits[word_index] |= port_state << word_offset;
+	}
+
+	return 0;
+}
+
 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
 	int value)
 {
@@ -299,6 +348,7 @@ static int idio_16_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
 	idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
 	idio16gpio->chip.get = idio_16_gpio_get;
+	idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
 	idio16gpio->chip.set = idio_16_gpio_set;
 	idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
 
diff --git a/drivers/gpio/gpio-pcie-idio-24.c b/drivers/gpio/gpio-pcie-idio-24.c
index f666e2e..835607e 100644
--- a/drivers/gpio/gpio-pcie-idio-24.c
+++ b/drivers/gpio/gpio-pcie-idio-24.c
@@ -15,6 +15,7 @@
  * This driver supports the following ACCES devices: PCIe-IDIO-24,
  * PCIe-IDI-24, PCIe-IDO-24, and PCIe-IDIO-12.
  */
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/errno.h>
@@ -193,6 +194,61 @@ static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset)
 	return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask);
 }
 
+static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
+	unsigned long *mask, unsigned long *bits)
+{
+	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
+	size_t i;
+	const unsigned int gpio_reg_size = 8;
+	unsigned int bits_offset;
+	size_t word_index;
+	unsigned int word_offset;
+	unsigned long word_mask;
+	const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+	unsigned long port_state;
+	u8 __iomem ports[] = {
+		idio24gpio->reg->out0_7, idio24gpio->reg->out8_15,
+		idio24gpio->reg->out16_23, idio24gpio->reg->in0_7,
+		idio24gpio->reg->in8_15, idio24gpio->reg->in16_23,
+	};
+	const unsigned long out_mode_mask = BIT(1);
+
+	/* clear bits array to a clean slate */
+	bitmap_zero(bits, chip->ngpio);
+
+	/* get bits are evaluated a gpio port register at a time */
+	for (i = 0; i < ARRAY_SIZE(ports); i++) {
+		/* gpio offset in bits array */
+		bits_offset = i * gpio_reg_size;
+
+		/* word index for bits array */
+		word_index = BIT_WORD(bits_offset);
+
+		/* gpio offset within current word of bits array */
+		word_offset = bits_offset % BITS_PER_LONG;
+
+		/* mask of get bits for current gpio within current word */
+		word_mask = mask[word_index] & (port_mask << word_offset);
+		if (!word_mask) {
+			/* no get bits in this port so skip to next one */
+			continue;
+		}
+
+		/* read bits from current gpio port (port 6 is TTL GPIO) */
+		if (i < 6)
+			port_state = ioread8(ports + i);
+		else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
+			port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
+		else
+			port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
+
+		/* store acquired bits at respective bits array offset */
+		bits[word_index] |= port_state << word_offset;
+	}
+
+	return 0;
+}
+
 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
 	int value)
 {
@@ -234,6 +290,65 @@ static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
 	raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
 }
 
+static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
+	unsigned long *mask, unsigned long *bits)
+{
+	struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
+	size_t i;
+	unsigned long bits_offset;
+	unsigned long gpio_mask;
+	const unsigned int gpio_reg_size = 8;
+	const unsigned long port_mask = GENMASK(gpio_reg_size, 0);
+	unsigned long flags;
+	unsigned int out_state;
+	u8 __iomem ports[] = {
+		idio24gpio->reg->out0_7, idio24gpio->reg->out8_15,
+		idio24gpio->reg->out16_23
+	};
+	const unsigned long out_mode_mask = BIT(1);
+	const unsigned int ttl_offset = 48;
+	const size_t ttl_i = BIT_WORD(ttl_offset);
+	const unsigned int word_offset = ttl_offset % BITS_PER_LONG;
+	const unsigned long ttl_mask = (mask[ttl_i] >> word_offset) & port_mask;
+	const unsigned long ttl_bits = (bits[ttl_i] >> word_offset) & ttl_mask;
+
+	/* set bits are processed a gpio port register at a time */
+	for (i = 0; i < ARRAY_SIZE(ports); i++) {
+		/* gpio offset in bits array */
+		bits_offset = i * gpio_reg_size;
+
+		/* check if any set bits for current port */
+		gpio_mask = (*mask >> bits_offset) & port_mask;
+		if (!gpio_mask) {
+			/* no set bits for this port so move on to next port */
+			continue;
+		}
+
+		raw_spin_lock_irqsave(&idio24gpio->lock, flags);
+
+		/* process output lines */
+		out_state = ioread8(ports + i) & ~gpio_mask;
+		out_state |= (*bits >> bits_offset) & gpio_mask;
+		iowrite8(out_state, ports + i);
+
+		raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
+	}
+
+	/* check if setting TTL lines and if they are in output mode */
+	if (!ttl_mask || !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
+		return;
+
+	/* handle TTL output */
+	raw_spin_lock_irqsave(&idio24gpio->lock, flags);
+
+	/* process output lines */
+	out_state = ioread8(&idio24gpio->reg->ttl_out0_7) & ~ttl_mask;
+	out_state |= ttl_bits;
+	iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
+
+	raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
+}
+
 static void idio_24_irq_ack(struct irq_data *data)
 {
 }
@@ -397,7 +512,9 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
 	idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
 	idio24gpio->chip.get = idio_24_gpio_get;
+	idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
 	idio24gpio->chip.set = idio_24_gpio_set;
+	idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
 
 	raw_spin_lock_init(&idio24gpio->lock);
 
diff --git a/drivers/gpio/gpio-pmic-eic-sprd.c b/drivers/gpio/gpio-pmic-eic-sprd.c
new file mode 100644
index 0000000..66d68d9
--- /dev/null
+++ b/drivers/gpio/gpio-pmic-eic-sprd.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Spreadtrum Communications Inc.
+ * Copyright (C) 2018 Linaro Ltd.
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+/* EIC registers definition */
+#define SPRD_PMIC_EIC_DATA		0x0
+#define SPRD_PMIC_EIC_DMSK		0x4
+#define SPRD_PMIC_EIC_IEV		0x14
+#define SPRD_PMIC_EIC_IE		0x18
+#define SPRD_PMIC_EIC_RIS		0x1c
+#define SPRD_PMIC_EIC_MIS		0x20
+#define SPRD_PMIC_EIC_IC		0x24
+#define SPRD_PMIC_EIC_TRIG		0x28
+#define SPRD_PMIC_EIC_CTRL0		0x40
+
+/*
+ * The PMIC EIC controller only has one bank, and each bank now can contain
+ * 16 EICs.
+ */
+#define SPRD_PMIC_EIC_PER_BANK_NR	16
+#define SPRD_PMIC_EIC_NR		SPRD_PMIC_EIC_PER_BANK_NR
+#define SPRD_PMIC_EIC_DATA_MASK		GENMASK(15, 0)
+#define SPRD_PMIC_EIC_BIT(x)		((x) & (SPRD_PMIC_EIC_PER_BANK_NR - 1))
+#define SPRD_PMIC_EIC_DBNC_MASK		GENMASK(11, 0)
+
+/*
+ * These registers are modified under the irq bus lock and cached to avoid
+ * unnecessary writes in bus_sync_unlock.
+ */
+enum {
+	REG_IEV,
+	REG_IE,
+	REG_TRIG,
+	CACHE_NR_REGS
+};
+
+/**
+ * struct sprd_pmic_eic - PMIC EIC controller
+ * @chip: the gpio_chip structure.
+ * @intc: the irq_chip structure.
+ * @regmap: the regmap from the parent device.
+ * @offset: the EIC controller's offset address of the PMIC.
+ * @reg: the array to cache the EIC registers.
+ * @buslock: for bus lock/sync and unlock.
+ * @irq: the interrupt number of the PMIC EIC conteroller.
+ */
+struct sprd_pmic_eic {
+	struct gpio_chip chip;
+	struct irq_chip intc;
+	struct regmap *map;
+	u32 offset;
+	u8 reg[CACHE_NR_REGS];
+	struct mutex buslock;
+	int irq;
+};
+
+static void sprd_pmic_eic_update(struct gpio_chip *chip, unsigned int offset,
+				 u16 reg, unsigned int val)
+{
+	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
+	u32 shift = SPRD_PMIC_EIC_BIT(offset);
+
+	regmap_update_bits(pmic_eic->map, pmic_eic->offset + reg,
+			   BIT(shift), val << shift);
+}
+
+static int sprd_pmic_eic_read(struct gpio_chip *chip, unsigned int offset,
+			      u16 reg)
+{
+	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
+	u32 value;
+	int ret;
+
+	ret = regmap_read(pmic_eic->map, pmic_eic->offset + reg, &value);
+	if (ret)
+		return ret;
+
+	return !!(value & BIT(SPRD_PMIC_EIC_BIT(offset)));
+}
+
+static int sprd_pmic_eic_request(struct gpio_chip *chip, unsigned int offset)
+{
+	sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_DMSK, 1);
+	return 0;
+}
+
+static void sprd_pmic_eic_free(struct gpio_chip *chip, unsigned int offset)
+{
+	sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_DMSK, 0);
+}
+
+static int sprd_pmic_eic_get(struct gpio_chip *chip, unsigned int offset)
+{
+	return sprd_pmic_eic_read(chip, offset, SPRD_PMIC_EIC_DATA);
+}
+
+static int sprd_pmic_eic_direction_input(struct gpio_chip *chip,
+					 unsigned int offset)
+{
+	/* EICs are always input, nothing need to do here. */
+	return 0;
+}
+
+static void sprd_pmic_eic_set(struct gpio_chip *chip, unsigned int offset,
+			      int value)
+{
+	/* EICs are always input, nothing need to do here. */
+}
+
+static int sprd_pmic_eic_set_debounce(struct gpio_chip *chip,
+				      unsigned int offset,
+				      unsigned int debounce)
+{
+	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
+	u32 reg, value;
+	int ret;
+
+	reg = SPRD_PMIC_EIC_CTRL0 + SPRD_PMIC_EIC_BIT(offset) * 0x4;
+	ret = regmap_read(pmic_eic->map, pmic_eic->offset + reg, &value);
+	if (ret)
+		return ret;
+
+	value &= ~SPRD_PMIC_EIC_DBNC_MASK;
+	value |= (debounce / 1000) & SPRD_PMIC_EIC_DBNC_MASK;
+	return regmap_write(pmic_eic->map, pmic_eic->offset + reg, value);
+}
+
+static int sprd_pmic_eic_set_config(struct gpio_chip *chip, unsigned int offset,
+				    unsigned long config)
+{
+	unsigned long param = pinconf_to_config_param(config);
+	u32 arg = pinconf_to_config_argument(config);
+
+	if (param == PIN_CONFIG_INPUT_DEBOUNCE)
+		return sprd_pmic_eic_set_debounce(chip, offset, arg);
+
+	return -ENOTSUPP;
+}
+
+static void sprd_pmic_eic_irq_mask(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
+
+	pmic_eic->reg[REG_IE] = 0;
+	pmic_eic->reg[REG_TRIG] = 0;
+}
+
+static void sprd_pmic_eic_irq_unmask(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
+
+	pmic_eic->reg[REG_IE] = 1;
+	pmic_eic->reg[REG_TRIG] = 1;
+}
+
+static int sprd_pmic_eic_irq_set_type(struct irq_data *data,
+				      unsigned int flow_type)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
+
+	switch (flow_type) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		pmic_eic->reg[REG_IEV] = 1;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		pmic_eic->reg[REG_IEV] = 0;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static void sprd_pmic_eic_bus_lock(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
+
+	mutex_lock(&pmic_eic->buslock);
+}
+
+static void sprd_pmic_eic_bus_sync_unlock(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
+	u32 offset = irqd_to_hwirq(data);
+
+	/* Set irq type */
+	sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_IEV,
+			     pmic_eic->reg[REG_IEV]);
+	/* Set irq unmask */
+	sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_IE,
+			     pmic_eic->reg[REG_IE]);
+	/* Generate trigger start pulse for debounce EIC */
+	sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_TRIG,
+			     pmic_eic->reg[REG_TRIG]);
+
+	mutex_unlock(&pmic_eic->buslock);
+}
+
+static irqreturn_t sprd_pmic_eic_irq_handler(int irq, void *data)
+{
+	struct sprd_pmic_eic *pmic_eic = data;
+	struct gpio_chip *chip = &pmic_eic->chip;
+	unsigned long status;
+	u32 n, girq, val;
+	int ret;
+
+	ret = regmap_read(pmic_eic->map, pmic_eic->offset + SPRD_PMIC_EIC_MIS,
+			  &val);
+	if (ret)
+		return IRQ_RETVAL(ret);
+
+	status = val & SPRD_PMIC_EIC_DATA_MASK;
+
+	for_each_set_bit(n, &status, chip->ngpio) {
+		/* Clear the interrupt */
+		sprd_pmic_eic_update(chip, n, SPRD_PMIC_EIC_IC, 1);
+
+		girq = irq_find_mapping(chip->irq.domain, n);
+		handle_nested_irq(girq);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int sprd_pmic_eic_probe(struct platform_device *pdev)
+{
+	struct gpio_irq_chip *irq;
+	struct sprd_pmic_eic *pmic_eic;
+	int ret;
+
+	pmic_eic = devm_kzalloc(&pdev->dev, sizeof(*pmic_eic), GFP_KERNEL);
+	if (!pmic_eic)
+		return -ENOMEM;
+
+	mutex_init(&pmic_eic->buslock);
+
+	pmic_eic->irq = platform_get_irq(pdev, 0);
+	if (pmic_eic->irq < 0) {
+		dev_err(&pdev->dev, "Failed to get PMIC EIC interrupt.\n");
+		return pmic_eic->irq;
+	}
+
+	pmic_eic->map = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!pmic_eic->map)
+		return -ENODEV;
+
+	ret = of_property_read_u32(pdev->dev.of_node, "reg", &pmic_eic->offset);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get PMIC EIC base address.\n");
+		return ret;
+	}
+
+	ret = devm_request_threaded_irq(&pdev->dev, pmic_eic->irq, NULL,
+					sprd_pmic_eic_irq_handler,
+					IRQF_TRIGGER_LOW |
+					IRQF_ONESHOT | IRQF_NO_SUSPEND,
+					dev_name(&pdev->dev), pmic_eic);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request PMIC EIC IRQ.\n");
+		return ret;
+	}
+
+	pmic_eic->chip.label = dev_name(&pdev->dev);
+	pmic_eic->chip.ngpio = SPRD_PMIC_EIC_NR;
+	pmic_eic->chip.base = -1;
+	pmic_eic->chip.parent = &pdev->dev;
+	pmic_eic->chip.of_node = pdev->dev.of_node;
+	pmic_eic->chip.direction_input = sprd_pmic_eic_direction_input;
+	pmic_eic->chip.request = sprd_pmic_eic_request;
+	pmic_eic->chip.free = sprd_pmic_eic_free;
+	pmic_eic->chip.set_config = sprd_pmic_eic_set_config;
+	pmic_eic->chip.set = sprd_pmic_eic_set;
+	pmic_eic->chip.get = sprd_pmic_eic_get;
+
+	pmic_eic->intc.name = dev_name(&pdev->dev);
+	pmic_eic->intc.irq_mask = sprd_pmic_eic_irq_mask;
+	pmic_eic->intc.irq_unmask = sprd_pmic_eic_irq_unmask;
+	pmic_eic->intc.irq_set_type = sprd_pmic_eic_irq_set_type;
+	pmic_eic->intc.irq_bus_lock = sprd_pmic_eic_bus_lock;
+	pmic_eic->intc.irq_bus_sync_unlock = sprd_pmic_eic_bus_sync_unlock;
+	pmic_eic->intc.flags = IRQCHIP_SKIP_SET_WAKE;
+
+	irq = &pmic_eic->chip.irq;
+	irq->chip = &pmic_eic->intc;
+	irq->threaded = true;
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &pmic_eic->chip, pmic_eic);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip %d.\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, pmic_eic);
+	return 0;
+}
+
+static const struct of_device_id sprd_pmic_eic_of_match[] = {
+	{ .compatible = "sprd,sc27xx-eic", },
+	{ /* end of list */ }
+};
+MODULE_DEVICE_TABLE(of, sprd_pmic_eic_of_match);
+
+static struct platform_driver sprd_pmic_eic_driver = {
+	.probe = sprd_pmic_eic_probe,
+	.driver = {
+		.name = "sprd-pmic-eic",
+		.of_match_table	= sprd_pmic_eic_of_match,
+	},
+};
+
+module_platform_driver(sprd_pmic_eic_driver);
+
+MODULE_DESCRIPTION("Spreadtrum PMIC EIC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
new file mode 100644
index 0000000..d6d36d5
--- /dev/null
+++ b/drivers/gpio/gpio-raspberrypi-exp.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Raspberry Pi 3 expander GPIO driver
+ *
+ *  Uses the firmware mailbox service to communicate with the
+ *  GPIO expander on the VPU.
+ *
+ *  Copyright (C) 2017 Raspberry Pi Trading Ltd.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+#define MODULE_NAME "raspberrypi-exp-gpio"
+#define NUM_GPIO 8
+
+#define RPI_EXP_GPIO_BASE	128
+
+#define RPI_EXP_GPIO_DIR_IN	0
+#define RPI_EXP_GPIO_DIR_OUT	1
+
+struct rpi_exp_gpio {
+	struct gpio_chip gc;
+	struct rpi_firmware *fw;
+};
+
+/* VC4 firmware mailbox interface data structures */
+
+struct gpio_set_config {
+	u32 gpio;
+	u32 direction;
+	u32 polarity;
+	u32 term_en;
+	u32 term_pull_up;
+	u32 state;
+};
+
+struct gpio_get_config {
+	u32 gpio;
+	u32 direction;
+	u32 polarity;
+	u32 term_en;
+	u32 term_pull_up;
+};
+
+struct gpio_get_set_state {
+	u32 gpio;
+	u32 state;
+};
+
+static int rpi_exp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off)
+{
+	struct rpi_exp_gpio *gpio;
+	struct gpio_get_config get;
+	int ret;
+
+	gpio = gpiochip_get_data(gc);
+
+	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
+
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
+				    &get, sizeof(get));
+	if (ret || get.gpio != 0) {
+		dev_err(gc->parent, "Failed to get GPIO %u config (%d %x)\n",
+			off, ret, get.gpio);
+		return ret ? ret : -EIO;
+	}
+	return get.polarity;
+}
+
+static int rpi_exp_gpio_dir_in(struct gpio_chip *gc, unsigned int off)
+{
+	struct rpi_exp_gpio *gpio;
+	struct gpio_set_config set_in;
+	int ret;
+
+	gpio = gpiochip_get_data(gc);
+
+	set_in.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
+	set_in.direction = RPI_EXP_GPIO_DIR_IN;
+	set_in.term_en = 0;		/* termination disabled */
+	set_in.term_pull_up = 0;	/* n/a as termination disabled */
+	set_in.state = 0;		/* n/a as configured as an input */
+
+	ret = rpi_exp_gpio_get_polarity(gc, off);
+	if (ret < 0)
+		return ret;
+	set_in.polarity = ret;		/* Retain existing setting */
+
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
+				    &set_in, sizeof(set_in));
+	if (ret || set_in.gpio != 0) {
+		dev_err(gc->parent, "Failed to set GPIO %u to input (%d %x)\n",
+			off, ret, set_in.gpio);
+		return ret ? ret : -EIO;
+	}
+	return 0;
+}
+
+static int rpi_exp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val)
+{
+	struct rpi_exp_gpio *gpio;
+	struct gpio_set_config set_out;
+	int ret;
+
+	gpio = gpiochip_get_data(gc);
+
+	set_out.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
+	set_out.direction = RPI_EXP_GPIO_DIR_OUT;
+	set_out.term_en = 0;		/* n/a as an output */
+	set_out.term_pull_up = 0;	/* n/a as termination disabled */
+	set_out.state = val;		/* Output state */
+
+	ret = rpi_exp_gpio_get_polarity(gc, off);
+	if (ret < 0)
+		return ret;
+	set_out.polarity = ret;		/* Retain existing setting */
+
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
+				    &set_out, sizeof(set_out));
+	if (ret || set_out.gpio != 0) {
+		dev_err(gc->parent, "Failed to set GPIO %u to output (%d %x)\n",
+			off, ret, set_out.gpio);
+		return ret ? ret : -EIO;
+	}
+	return 0;
+}
+
+static int rpi_exp_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
+{
+	struct rpi_exp_gpio *gpio;
+	struct gpio_get_config get;
+	int ret;
+
+	gpio = gpiochip_get_data(gc);
+
+	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
+
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
+				    &get, sizeof(get));
+	if (ret || get.gpio != 0) {
+		dev_err(gc->parent,
+			"Failed to get GPIO %u config (%d %x)\n", off, ret,
+			get.gpio);
+		return ret ? ret : -EIO;
+	}
+	return !get.direction;
+}
+
+static int rpi_exp_gpio_get(struct gpio_chip *gc, unsigned int off)
+{
+	struct rpi_exp_gpio *gpio;
+	struct gpio_get_set_state get;
+	int ret;
+
+	gpio = gpiochip_get_data(gc);
+
+	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
+	get.state = 0;		/* storage for returned value */
+
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE,
+					 &get, sizeof(get));
+	if (ret || get.gpio != 0) {
+		dev_err(gc->parent,
+			"Failed to get GPIO %u state (%d %x)\n", off, ret,
+			get.gpio);
+		return ret ? ret : -EIO;
+	}
+	return !!get.state;
+}
+
+static void rpi_exp_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
+{
+	struct rpi_exp_gpio *gpio;
+	struct gpio_get_set_state set;
+	int ret;
+
+	gpio = gpiochip_get_data(gc);
+
+	set.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
+	set.state = val;	/* Output state */
+
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE,
+					 &set, sizeof(set));
+	if (ret || set.gpio != 0)
+		dev_err(gc->parent,
+			"Failed to set GPIO %u state (%d %x)\n", off, ret,
+			set.gpio);
+}
+
+static int rpi_exp_gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *fw_node;
+	struct rpi_firmware *fw;
+	struct rpi_exp_gpio *rpi_gpio;
+
+	fw_node = of_get_parent(np);
+	if (!fw_node) {
+		dev_err(dev, "Missing firmware node\n");
+		return -ENOENT;
+	}
+
+	fw = rpi_firmware_get(fw_node);
+	if (!fw)
+		return -EPROBE_DEFER;
+
+	rpi_gpio = devm_kzalloc(dev, sizeof(*rpi_gpio), GFP_KERNEL);
+	if (!rpi_gpio)
+		return -ENOMEM;
+
+	rpi_gpio->fw = fw;
+	rpi_gpio->gc.parent = dev;
+	rpi_gpio->gc.label = MODULE_NAME;
+	rpi_gpio->gc.owner = THIS_MODULE;
+	rpi_gpio->gc.of_node = np;
+	rpi_gpio->gc.base = -1;
+	rpi_gpio->gc.ngpio = NUM_GPIO;
+
+	rpi_gpio->gc.direction_input = rpi_exp_gpio_dir_in;
+	rpi_gpio->gc.direction_output = rpi_exp_gpio_dir_out;
+	rpi_gpio->gc.get_direction = rpi_exp_gpio_get_direction;
+	rpi_gpio->gc.get = rpi_exp_gpio_get;
+	rpi_gpio->gc.set = rpi_exp_gpio_set;
+	rpi_gpio->gc.can_sleep = true;
+
+	return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
+}
+
+static const struct of_device_id rpi_exp_gpio_ids[] = {
+	{ .compatible = "raspberrypi,firmware-gpio" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, rpi_exp_gpio_ids);
+
+static struct platform_driver rpi_exp_gpio_driver = {
+	.driver	= {
+		.name		= MODULE_NAME,
+		.of_match_table	= of_match_ptr(rpi_exp_gpio_ids),
+	},
+	.probe	= rpi_exp_gpio_probe,
+};
+module_platform_driver(rpi_exp_gpio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.org>");
+MODULE_DESCRIPTION("Raspberry Pi 3 expander GPIO driver");
+MODULE_ALIAS("platform:rpi-exp-gpio");
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index ebaea8b..350390c 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -30,6 +30,16 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 
+struct gpio_rcar_bank_info {
+	u32 iointsel;
+	u32 inoutsel;
+	u32 outdt;
+	u32 posneg;
+	u32 edglevel;
+	u32 bothedge;
+	u32 intmsk;
+};
+
 struct gpio_rcar_priv {
 	void __iomem *base;
 	spinlock_t lock;
@@ -39,6 +49,7 @@ struct gpio_rcar_priv {
 	unsigned int irq_parent;
 	atomic_t wakeup_path;
 	bool has_both_edge_trigger;
+	struct gpio_rcar_bank_info bank_info;
 };
 
 #define IOINTSEL 0x00	/* General IO/Interrupt Switching Register */
@@ -512,17 +523,62 @@ static int gpio_rcar_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static int __maybe_unused gpio_rcar_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int gpio_rcar_suspend(struct device *dev)
 {
 	struct gpio_rcar_priv *p = dev_get_drvdata(dev);
 
+	p->bank_info.iointsel = gpio_rcar_read(p, IOINTSEL);
+	p->bank_info.inoutsel = gpio_rcar_read(p, INOUTSEL);
+	p->bank_info.outdt = gpio_rcar_read(p, OUTDT);
+	p->bank_info.intmsk = gpio_rcar_read(p, INTMSK);
+	p->bank_info.posneg = gpio_rcar_read(p, POSNEG);
+	p->bank_info.edglevel = gpio_rcar_read(p, EDGLEVEL);
+	if (p->has_both_edge_trigger)
+		p->bank_info.bothedge = gpio_rcar_read(p, BOTHEDGE);
+
 	if (atomic_read(&p->wakeup_path))
 		device_set_wakeup_path(dev);
 
 	return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, NULL);
+static int gpio_rcar_resume(struct device *dev)
+{
+	struct gpio_rcar_priv *p = dev_get_drvdata(dev);
+	unsigned int offset;
+	u32 mask;
+
+	for (offset = 0; offset < p->gpio_chip.ngpio; offset++) {
+		mask = BIT(offset);
+		/* I/O pin */
+		if (!(p->bank_info.iointsel & mask)) {
+			if (p->bank_info.inoutsel & mask)
+				gpio_rcar_direction_output(
+					&p->gpio_chip, offset,
+					!!(p->bank_info.outdt & mask));
+			else
+				gpio_rcar_direction_input(&p->gpio_chip,
+							  offset);
+		} else {
+			/* Interrupt pin */
+			gpio_rcar_config_interrupt_input_mode(
+				p,
+				offset,
+				!(p->bank_info.posneg & mask),
+				!(p->bank_info.edglevel & mask),
+				!!(p->bank_info.bothedge & mask));
+
+			if (p->bank_info.intmsk & mask)
+				gpio_rcar_write(p, MSKCLR, mask);
+		}
+	}
+
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP*/
+
+static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, gpio_rcar_resume);
 
 static struct platform_driver gpio_rcar_device_driver = {
 	.probe		= gpio_rcar_probe,
diff --git a/drivers/gpio/gpio-sprd.c b/drivers/gpio/gpio-sprd.c
new file mode 100644
index 0000000..55072d2
--- /dev/null
+++ b/drivers/gpio/gpio-sprd.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Spreadtrum Communications Inc.
+ * Copyright (C) 2018 Linaro Ltd.
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+/* GPIO registers definition */
+#define SPRD_GPIO_DATA		0x0
+#define SPRD_GPIO_DMSK		0x4
+#define SPRD_GPIO_DIR		0x8
+#define SPRD_GPIO_IS		0xc
+#define SPRD_GPIO_IBE		0x10
+#define SPRD_GPIO_IEV		0x14
+#define SPRD_GPIO_IE		0x18
+#define SPRD_GPIO_RIS		0x1c
+#define SPRD_GPIO_MIS		0x20
+#define SPRD_GPIO_IC		0x24
+#define SPRD_GPIO_INEN		0x28
+
+/* We have 16 banks GPIOs and each bank contain 16 GPIOs */
+#define SPRD_GPIO_BANK_NR	16
+#define SPRD_GPIO_NR		256
+#define SPRD_GPIO_BANK_SIZE	0x80
+#define SPRD_GPIO_BANK_MASK	GENMASK(15, 0)
+#define SPRD_GPIO_BIT(x)	((x) & (SPRD_GPIO_BANK_NR - 1))
+
+struct sprd_gpio {
+	struct gpio_chip chip;
+	void __iomem *base;
+	spinlock_t lock;
+	int irq;
+};
+
+static inline void __iomem *sprd_gpio_bank_base(struct sprd_gpio *sprd_gpio,
+						unsigned int bank)
+{
+	return sprd_gpio->base + SPRD_GPIO_BANK_SIZE * bank;
+}
+
+static void sprd_gpio_update(struct gpio_chip *chip, unsigned int offset,
+			     u16 reg, int val)
+{
+	struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip);
+	void __iomem *base = sprd_gpio_bank_base(sprd_gpio,
+						 offset / SPRD_GPIO_BANK_NR);
+	unsigned long flags;
+	u32 tmp;
+
+	spin_lock_irqsave(&sprd_gpio->lock, flags);
+	tmp = readl_relaxed(base + reg);
+
+	if (val)
+		tmp |= BIT(SPRD_GPIO_BIT(offset));
+	else
+		tmp &= ~BIT(SPRD_GPIO_BIT(offset));
+
+	writel_relaxed(tmp, base + reg);
+	spin_unlock_irqrestore(&sprd_gpio->lock, flags);
+}
+
+static int sprd_gpio_read(struct gpio_chip *chip, unsigned int offset, u16 reg)
+{
+	struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip);
+	void __iomem *base = sprd_gpio_bank_base(sprd_gpio,
+						 offset / SPRD_GPIO_BANK_NR);
+
+	return !!(readl_relaxed(base + reg) & BIT(SPRD_GPIO_BIT(offset)));
+}
+
+static int sprd_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+	sprd_gpio_update(chip, offset, SPRD_GPIO_DMSK, 1);
+	return 0;
+}
+
+static void sprd_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+	sprd_gpio_update(chip, offset, SPRD_GPIO_DMSK, 0);
+}
+
+static int sprd_gpio_direction_input(struct gpio_chip *chip,
+				     unsigned int offset)
+{
+	sprd_gpio_update(chip, offset, SPRD_GPIO_DIR, 0);
+	sprd_gpio_update(chip, offset, SPRD_GPIO_INEN, 1);
+	return 0;
+}
+
+static int sprd_gpio_direction_output(struct gpio_chip *chip,
+				      unsigned int offset, int value)
+{
+	sprd_gpio_update(chip, offset, SPRD_GPIO_DIR, 1);
+	sprd_gpio_update(chip, offset, SPRD_GPIO_INEN, 0);
+	sprd_gpio_update(chip, offset, SPRD_GPIO_DATA, value);
+	return 0;
+}
+
+static int sprd_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	return sprd_gpio_read(chip, offset, SPRD_GPIO_DATA);
+}
+
+static void sprd_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			  int value)
+{
+	sprd_gpio_update(chip, offset, SPRD_GPIO_DATA, value);
+}
+
+static void sprd_gpio_irq_mask(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	u32 offset = irqd_to_hwirq(data);
+
+	sprd_gpio_update(chip, offset, SPRD_GPIO_IE, 0);
+}
+
+static void sprd_gpio_irq_ack(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	u32 offset = irqd_to_hwirq(data);
+
+	sprd_gpio_update(chip, offset, SPRD_GPIO_IC, 1);
+}
+
+static void sprd_gpio_irq_unmask(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	u32 offset = irqd_to_hwirq(data);
+
+	sprd_gpio_update(chip, offset, SPRD_GPIO_IE, 1);
+}
+
+static int sprd_gpio_irq_set_type(struct irq_data *data,
+				  unsigned int flow_type)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	u32 offset = irqd_to_hwirq(data);
+
+	switch (flow_type) {
+	case IRQ_TYPE_EDGE_RISING:
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 1);
+		irq_set_handler_locked(data, handle_edge_irq);
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 0);
+		irq_set_handler_locked(data, handle_edge_irq);
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 1);
+		irq_set_handler_locked(data, handle_edge_irq);
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 1);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 1);
+		irq_set_handler_locked(data, handle_level_irq);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 1);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0);
+		sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 0);
+		irq_set_handler_locked(data, handle_level_irq);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void sprd_gpio_irq_handler(struct irq_desc *desc)
+{
+	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+	struct irq_chip *ic = irq_desc_get_chip(desc);
+	struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip);
+	u32 bank, n, girq;
+
+	chained_irq_enter(ic, desc);
+
+	for (bank = 0; bank * SPRD_GPIO_BANK_NR < chip->ngpio; bank++) {
+		void __iomem *base = sprd_gpio_bank_base(sprd_gpio, bank);
+		unsigned long reg = readl_relaxed(base + SPRD_GPIO_MIS) &
+			SPRD_GPIO_BANK_MASK;
+
+		for_each_set_bit(n, &reg, SPRD_GPIO_BANK_NR) {
+			girq = irq_find_mapping(chip->irq.domain,
+						bank * SPRD_GPIO_BANK_NR + n);
+
+			generic_handle_irq(girq);
+		}
+
+	}
+	chained_irq_exit(ic, desc);
+}
+
+static struct irq_chip sprd_gpio_irqchip = {
+	.name = "sprd-gpio",
+	.irq_ack = sprd_gpio_irq_ack,
+	.irq_mask = sprd_gpio_irq_mask,
+	.irq_unmask = sprd_gpio_irq_unmask,
+	.irq_set_type = sprd_gpio_irq_set_type,
+	.flags = IRQCHIP_SKIP_SET_WAKE,
+};
+
+static int sprd_gpio_probe(struct platform_device *pdev)
+{
+	struct gpio_irq_chip *irq;
+	struct sprd_gpio *sprd_gpio;
+	struct resource *res;
+	int ret;
+
+	sprd_gpio = devm_kzalloc(&pdev->dev, sizeof(*sprd_gpio), GFP_KERNEL);
+	if (!sprd_gpio)
+		return -ENOMEM;
+
+	sprd_gpio->irq = platform_get_irq(pdev, 0);
+	if (sprd_gpio->irq < 0) {
+		dev_err(&pdev->dev, "Failed to get GPIO interrupt.\n");
+		return sprd_gpio->irq;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	sprd_gpio->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(sprd_gpio->base))
+		return PTR_ERR(sprd_gpio->base);
+
+	spin_lock_init(&sprd_gpio->lock);
+
+	sprd_gpio->chip.label = dev_name(&pdev->dev);
+	sprd_gpio->chip.ngpio = SPRD_GPIO_NR;
+	sprd_gpio->chip.base = -1;
+	sprd_gpio->chip.parent = &pdev->dev;
+	sprd_gpio->chip.of_node = pdev->dev.of_node;
+	sprd_gpio->chip.request = sprd_gpio_request;
+	sprd_gpio->chip.free = sprd_gpio_free;
+	sprd_gpio->chip.get = sprd_gpio_get;
+	sprd_gpio->chip.set = sprd_gpio_set;
+	sprd_gpio->chip.direction_input = sprd_gpio_direction_input;
+	sprd_gpio->chip.direction_output = sprd_gpio_direction_output;
+
+	irq = &sprd_gpio->chip.irq;
+	irq->chip = &sprd_gpio_irqchip;
+	irq->handler = handle_bad_irq;
+	irq->default_type = IRQ_TYPE_NONE;
+	irq->parent_handler = sprd_gpio_irq_handler;
+	irq->parent_handler_data = sprd_gpio;
+	irq->num_parents = 1;
+	irq->parents = &sprd_gpio->irq;
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &sprd_gpio->chip, sprd_gpio);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, sprd_gpio);
+	return 0;
+}
+
+static const struct of_device_id sprd_gpio_of_match[] = {
+	{ .compatible = "sprd,sc9860-gpio", },
+	{ /* end of list */ }
+};
+MODULE_DEVICE_TABLE(of, sprd_gpio_of_match);
+
+static struct platform_driver sprd_gpio_driver = {
+	.probe = sprd_gpio_probe,
+	.driver = {
+		.name = "sprd-gpio",
+		.of_match_table	= sprd_gpio_of_match,
+	},
+};
+
+module_platform_driver_probe(sprd_gpio_driver, sprd_gpio_probe);
+
+MODULE_DESCRIPTION("Spreadtrum GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 02fa8fe..94396ca 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -506,7 +506,7 @@ static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 
-static int dbg_gpio_show(struct seq_file *s, void *unused)
+static int tegra_dbg_gpio_show(struct seq_file *s, void *unused)
 {
 	struct tegra_gpio_info *tgi = s->private;
 	unsigned int i, j;
@@ -530,22 +530,12 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
 	return 0;
 }
 
-static int dbg_gpio_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, dbg_gpio_show, inode->i_private);
-}
-
-static const struct file_operations debug_fops = {
-	.open		= dbg_gpio_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(tegra_dbg_gpio);
 
 static void tegra_gpio_debuginit(struct tegra_gpio_info *tgi)
 {
 	(void) debugfs_create_file("tegra_gpio", 0444,
-					NULL, tgi, &debug_fops);
+				   NULL, tgi, &tegra_dbg_gpio_fops);
 }
 
 #else
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c
index 181f86c..6520a84 100644
--- a/drivers/gpio/gpio-timberdale.c
+++ b/drivers/gpio/gpio-timberdale.c
@@ -238,11 +238,10 @@ static int timbgpio_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	tgpio = devm_kzalloc(dev, sizeof(struct timbgpio), GFP_KERNEL);
-	if (!tgpio) {
-		dev_err(dev, "Memory alloc failed\n");
+	tgpio = devm_kzalloc(dev, sizeof(*tgpio), GFP_KERNEL);
+	if (!tgpio)
 		return -EINVAL;
-	}
+
 	tgpio->irq_base = pdata->irq_base;
 
 	spin_lock_init(&tgpio->lock);
diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c
index fa2662f..aff6e50 100644
--- a/drivers/gpio/gpio-tps68470.c
+++ b/drivers/gpio/gpio-tps68470.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * GPIO driver for TPS68470 PMIC
  *
@@ -8,15 +9,6 @@
  *	Tianshu Qiu <tian.shu.qiu@intel.com>
  *	Jian Xu Zheng <jian.xu.zheng@intel.com>
  *	Yuning Pu <yuning.pu@intel.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/gpio/driver.h>
diff --git a/drivers/gpio/gpio-tz1090-pdc.c b/drivers/gpio/gpio-tz1090-pdc.c
deleted file mode 100644
index 5b77817..0000000
--- a/drivers/gpio/gpio-tz1090-pdc.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Toumaz Xenif TZ1090 PDC GPIO handling.
- *
- * Copyright (C) 2012-2013 Imagination Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/bitops.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of_irq.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/syscore_ops.h>
-#include <asm/global_lock.h>
-
-/* Register offsets from SOC_GPIO_CONTROL0 */
-#define REG_SOC_GPIO_CONTROL0	0x00
-#define REG_SOC_GPIO_CONTROL1	0x04
-#define REG_SOC_GPIO_CONTROL2	0x08
-#define REG_SOC_GPIO_CONTROL3	0x0c
-#define REG_SOC_GPIO_STATUS	0x80
-
-/* PDC GPIOs go after normal GPIOs */
-#define GPIO_PDC_BASE		90
-#define GPIO_PDC_NGPIO		7
-
-/* Out of PDC gpios, only syswakes have irqs */
-#define GPIO_PDC_IRQ_FIRST	2
-#define GPIO_PDC_NIRQ		3
-
-/**
- * struct tz1090_pdc_gpio - GPIO bank private data
- * @chip:	Generic GPIO chip for GPIO bank
- * @reg:	Base of registers, offset for this GPIO bank
- * @irq:	IRQ numbers for Syswake GPIOs
- *
- * This is the main private data for the PDC GPIO driver. It encapsulates a
- * gpio_chip, and the callbacks for the gpio_chip can access the private data
- * with the to_pdc() macro below.
- */
-struct tz1090_pdc_gpio {
-	struct gpio_chip chip;
-	void __iomem *reg;
-	int irq[GPIO_PDC_NIRQ];
-};
-
-/* Register accesses into the PDC MMIO area */
-
-static inline void pdc_write(struct tz1090_pdc_gpio *priv, unsigned int reg_offs,
-		      unsigned int data)
-{
-	writel(data, priv->reg + reg_offs);
-}
-
-static inline unsigned int pdc_read(struct tz1090_pdc_gpio *priv,
-			     unsigned int reg_offs)
-{
-	return readl(priv->reg + reg_offs);
-}
-
-/* Generic GPIO interface */
-
-static int tz1090_pdc_gpio_direction_input(struct gpio_chip *chip,
-					   unsigned int offset)
-{
-	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
-	u32 value;
-	int lstat;
-
-	__global_lock2(lstat);
-	value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
-	value |= BIT(offset);
-	pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
-	__global_unlock2(lstat);
-
-	return 0;
-}
-
-static int tz1090_pdc_gpio_direction_output(struct gpio_chip *chip,
-					    unsigned int offset,
-					    int output_value)
-{
-	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
-	u32 value;
-	int lstat;
-
-	__global_lock2(lstat);
-	/* EXT_POWER doesn't seem to have an output value bit */
-	if (offset < 6) {
-		value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
-		if (output_value)
-			value |= BIT(offset);
-		else
-			value &= ~BIT(offset);
-		pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
-	}
-
-	value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
-	value &= ~BIT(offset);
-	pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
-	__global_unlock2(lstat);
-
-	return 0;
-}
-
-static int tz1090_pdc_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
-	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
-	return !!(pdc_read(priv, REG_SOC_GPIO_STATUS) & BIT(offset));
-}
-
-static void tz1090_pdc_gpio_set(struct gpio_chip *chip, unsigned int offset,
-				int output_value)
-{
-	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
-	u32 value;
-	int lstat;
-
-	/* EXT_POWER doesn't seem to have an output value bit */
-	if (offset >= 6)
-		return;
-
-	__global_lock2(lstat);
-	value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
-	if (output_value)
-		value |= BIT(offset);
-	else
-		value &= ~BIT(offset);
-	pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
-	__global_unlock2(lstat);
-}
-
-static int tz1090_pdc_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
-	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
-	unsigned int syswake = offset - GPIO_PDC_IRQ_FIRST;
-	int irq;
-
-	/* only syswakes have irqs */
-	if (syswake >= GPIO_PDC_NIRQ)
-		return -EINVAL;
-
-	irq = priv->irq[syswake];
-	if (!irq)
-		return -EINVAL;
-
-	return irq;
-}
-
-static int tz1090_pdc_gpio_probe(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	struct resource *res_regs;
-	struct tz1090_pdc_gpio *priv;
-	unsigned int i;
-
-	if (!np) {
-		dev_err(&pdev->dev, "must be instantiated via devicetree\n");
-		return -ENOENT;
-	}
-
-	res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res_regs) {
-		dev_err(&pdev->dev, "cannot find registers resource\n");
-		return -ENOENT;
-	}
-
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		dev_err(&pdev->dev, "unable to allocate driver data\n");
-		return -ENOMEM;
-	}
-
-	/* Ioremap the registers */
-	priv->reg = devm_ioremap(&pdev->dev, res_regs->start,
-				 resource_size(res_regs));
-	if (!priv->reg) {
-		dev_err(&pdev->dev, "unable to ioremap registers\n");
-		return -ENOMEM;
-	}
-
-	/* Set up GPIO chip */
-	priv->chip.label		= "tz1090-pdc-gpio";
-	priv->chip.parent		= &pdev->dev;
-	priv->chip.direction_input	= tz1090_pdc_gpio_direction_input;
-	priv->chip.direction_output	= tz1090_pdc_gpio_direction_output;
-	priv->chip.get			= tz1090_pdc_gpio_get;
-	priv->chip.set			= tz1090_pdc_gpio_set;
-	priv->chip.free			= gpiochip_generic_free;
-	priv->chip.request		= gpiochip_generic_request;
-	priv->chip.to_irq		= tz1090_pdc_gpio_to_irq;
-	priv->chip.of_node		= np;
-
-	/* GPIO numbering */
-	priv->chip.base			= GPIO_PDC_BASE;
-	priv->chip.ngpio		= GPIO_PDC_NGPIO;
-
-	/* Map the syswake irqs */
-	for (i = 0; i < GPIO_PDC_NIRQ; ++i)
-		priv->irq[i] = irq_of_parse_and_map(np, i);
-
-	/* Add the GPIO bank */
-	gpiochip_add_data(&priv->chip, priv);
-
-	return 0;
-}
-
-static struct of_device_id tz1090_pdc_gpio_of_match[] = {
-	{ .compatible = "img,tz1090-pdc-gpio" },
-	{ },
-};
-
-static struct platform_driver tz1090_pdc_gpio_driver = {
-	.driver = {
-		.name		= "tz1090-pdc-gpio",
-		.of_match_table	= tz1090_pdc_gpio_of_match,
-	},
-	.probe		= tz1090_pdc_gpio_probe,
-};
-
-static int __init tz1090_pdc_gpio_init(void)
-{
-	return platform_driver_register(&tz1090_pdc_gpio_driver);
-}
-subsys_initcall(tz1090_pdc_gpio_init);
diff --git a/drivers/gpio/gpio-tz1090.c b/drivers/gpio/gpio-tz1090.c
deleted file mode 100644
index 0bb9bb5..0000000
--- a/drivers/gpio/gpio-tz1090.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Toumaz Xenif TZ1090 GPIO handling.
- *
- * Copyright (C) 2008-2013 Imagination Technologies Ltd.
- *
- *  Based on ARM PXA code and others.
- *
- * 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/bitops.h>
-#include <linux/export.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/kernel.h>
-#include <linux/of_irq.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/syscore_ops.h>
-#include <asm/global_lock.h>
-
-/* Register offsets from bank base address */
-#define REG_GPIO_DIR		0x00
-#define REG_GPIO_IRQ_PLRT	0x20
-#define REG_GPIO_IRQ_TYPE	0x30
-#define REG_GPIO_IRQ_EN		0x40
-#define REG_GPIO_IRQ_STS	0x50
-#define REG_GPIO_BIT_EN		0x60
-#define REG_GPIO_DIN		0x70
-#define REG_GPIO_DOUT		0x80
-
-/* REG_GPIO_IRQ_PLRT */
-#define REG_GPIO_IRQ_PLRT_LOW	0
-#define REG_GPIO_IRQ_PLRT_HIGH	1
-
-/* REG_GPIO_IRQ_TYPE */
-#define REG_GPIO_IRQ_TYPE_LEVEL	0
-#define REG_GPIO_IRQ_TYPE_EDGE	1
-
-/**
- * struct tz1090_gpio_bank - GPIO bank private data
- * @chip:	Generic GPIO chip for GPIO bank
- * @domain:	IRQ domain for GPIO bank (may be NULL)
- * @reg:	Base of registers, offset for this GPIO bank
- * @irq:	IRQ number for GPIO bank
- * @label:	Debug GPIO bank label, used for storage of chip->label
- *
- * This is the main private data for a GPIO bank. It encapsulates a gpio_chip,
- * and the callbacks for the gpio_chip can access the private data with the
- * to_bank() macro below.
- */
-struct tz1090_gpio_bank {
-	struct gpio_chip chip;
-	struct irq_domain *domain;
-	void __iomem *reg;
-	int irq;
-	char label[16];
-};
-
-/**
- * struct tz1090_gpio - Overall GPIO device private data
- * @dev:	Device (from platform device)
- * @reg:	Base of GPIO registers
- *
- * Represents the overall GPIO device. This structure is actually only
- * temporary, and used during init.
- */
-struct tz1090_gpio {
-	struct device *dev;
-	void __iomem *reg;
-};
-
-/**
- * struct tz1090_gpio_bank_info - Temporary registration info for GPIO bank
- * @priv:	Overall GPIO device private data
- * @node:	Device tree node specific to this GPIO bank
- * @index:	Index of bank in range 0-2
- */
-struct tz1090_gpio_bank_info {
-	struct tz1090_gpio *priv;
-	struct device_node *node;
-	unsigned int index;
-};
-
-/* Convenience register accessors */
-static inline void tz1090_gpio_write(struct tz1090_gpio_bank *bank,
-			      unsigned int reg_offs, u32 data)
-{
-	iowrite32(data, bank->reg + reg_offs);
-}
-
-static inline u32 tz1090_gpio_read(struct tz1090_gpio_bank *bank,
-			    unsigned int reg_offs)
-{
-	return ioread32(bank->reg + reg_offs);
-}
-
-/* caller must hold LOCK2 */
-static inline void _tz1090_gpio_clear_bit(struct tz1090_gpio_bank *bank,
-					  unsigned int reg_offs,
-					  unsigned int offset)
-{
-	u32 value;
-
-	value = tz1090_gpio_read(bank, reg_offs);
-	value &= ~BIT(offset);
-	tz1090_gpio_write(bank, reg_offs, value);
-}
-
-static void tz1090_gpio_clear_bit(struct tz1090_gpio_bank *bank,
-				  unsigned int reg_offs,
-				  unsigned int offset)
-{
-	int lstat;
-
-	__global_lock2(lstat);
-	_tz1090_gpio_clear_bit(bank, reg_offs, offset);
-	__global_unlock2(lstat);
-}
-
-/* caller must hold LOCK2 */
-static inline void _tz1090_gpio_set_bit(struct tz1090_gpio_bank *bank,
-					unsigned int reg_offs,
-					unsigned int offset)
-{
-	u32 value;
-
-	value = tz1090_gpio_read(bank, reg_offs);
-	value |= BIT(offset);
-	tz1090_gpio_write(bank, reg_offs, value);
-}
-
-static void tz1090_gpio_set_bit(struct tz1090_gpio_bank *bank,
-				unsigned int reg_offs,
-				unsigned int offset)
-{
-	int lstat;
-
-	__global_lock2(lstat);
-	_tz1090_gpio_set_bit(bank, reg_offs, offset);
-	__global_unlock2(lstat);
-}
-
-/* caller must hold LOCK2 */
-static inline void _tz1090_gpio_mod_bit(struct tz1090_gpio_bank *bank,
-					unsigned int reg_offs,
-					unsigned int offset,
-					bool val)
-{
-	u32 value;
-
-	value = tz1090_gpio_read(bank, reg_offs);
-	value &= ~BIT(offset);
-	if (val)
-		value |= BIT(offset);
-	tz1090_gpio_write(bank, reg_offs, value);
-}
-
-static void tz1090_gpio_mod_bit(struct tz1090_gpio_bank *bank,
-				unsigned int reg_offs,
-				unsigned int offset,
-				bool val)
-{
-	int lstat;
-
-	__global_lock2(lstat);
-	_tz1090_gpio_mod_bit(bank, reg_offs, offset, val);
-	__global_unlock2(lstat);
-}
-
-static inline int tz1090_gpio_read_bit(struct tz1090_gpio_bank *bank,
-				       unsigned int reg_offs,
-				       unsigned int offset)
-{
-	return tz1090_gpio_read(bank, reg_offs) & BIT(offset);
-}
-
-/* GPIO chip callbacks */
-
-static int tz1090_gpio_direction_input(struct gpio_chip *chip,
-				       unsigned int offset)
-{
-	struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-	tz1090_gpio_set_bit(bank, REG_GPIO_DIR, offset);
-
-	return 0;
-}
-
-static int tz1090_gpio_direction_output(struct gpio_chip *chip,
-					unsigned int offset, int output_value)
-{
-	struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-	int lstat;
-
-	__global_lock2(lstat);
-	_tz1090_gpio_mod_bit(bank, REG_GPIO_DOUT, offset, output_value);
-	_tz1090_gpio_clear_bit(bank, REG_GPIO_DIR, offset);
-	__global_unlock2(lstat);
-
-	return 0;
-}
-
-/*
- * Return GPIO level
- */
-static int tz1090_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
-	struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-
-	return !!tz1090_gpio_read_bit(bank, REG_GPIO_DIN, offset);
-}
-
-/*
- * Set output GPIO level
- */
-static void tz1090_gpio_set(struct gpio_chip *chip, unsigned int offset,
-			    int output_value)
-{
-	struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-
-	tz1090_gpio_mod_bit(bank, REG_GPIO_DOUT, offset, output_value);
-}
-
-static int tz1090_gpio_request(struct gpio_chip *chip, unsigned int offset)
-{
-	struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-	int ret;
-
-	ret = pinctrl_gpio_request(chip->base + offset);
-	if (ret)
-		return ret;
-
-	tz1090_gpio_set_bit(bank, REG_GPIO_DIR, offset);
-	tz1090_gpio_set_bit(bank, REG_GPIO_BIT_EN, offset);
-
-	return 0;
-}
-
-static void tz1090_gpio_free(struct gpio_chip *chip, unsigned int offset)
-{
-	struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-
-	pinctrl_gpio_free(chip->base + offset);
-
-	tz1090_gpio_clear_bit(bank, REG_GPIO_BIT_EN, offset);
-}
-
-static int tz1090_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
-	struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-
-	if (!bank->domain)
-		return -EINVAL;
-
-	return irq_create_mapping(bank->domain, offset);
-}
-
-/* IRQ chip handlers */
-
-/* Get TZ1090 GPIO chip from irq data provided to generic IRQ callbacks */
-static inline struct tz1090_gpio_bank *irqd_to_gpio_bank(struct irq_data *data)
-{
-	return (struct tz1090_gpio_bank *)data->domain->host_data;
-}
-
-static void tz1090_gpio_irq_polarity(struct tz1090_gpio_bank *bank,
-				     unsigned int offset, unsigned int polarity)
-{
-	tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_PLRT, offset, polarity);
-}
-
-static void tz1090_gpio_irq_type(struct tz1090_gpio_bank *bank,
-				 unsigned int offset, unsigned int type)
-{
-	tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_TYPE, offset, type);
-}
-
-/* set polarity to trigger on next edge, whether rising or falling */
-static void tz1090_gpio_irq_next_edge(struct tz1090_gpio_bank *bank,
-				      unsigned int offset)
-{
-	unsigned int value_p, value_i;
-	int lstat;
-
-	/*
-	 * Set the GPIO's interrupt polarity to the opposite of the current
-	 * input value so that the next edge triggers an interrupt.
-	 */
-	__global_lock2(lstat);
-	value_i = ~tz1090_gpio_read(bank, REG_GPIO_DIN);
-	value_p = tz1090_gpio_read(bank, REG_GPIO_IRQ_PLRT);
-	value_p &= ~BIT(offset);
-	value_p |= value_i & BIT(offset);
-	tz1090_gpio_write(bank, REG_GPIO_IRQ_PLRT, value_p);
-	__global_unlock2(lstat);
-}
-
-static unsigned int gpio_startup_irq(struct irq_data *data)
-{
-	/*
-	 * This warning indicates that the type of the irq hasn't been set
-	 * before enabling the irq. This would normally be done by passing some
-	 * trigger flags to request_irq().
-	 */
-	WARN(irqd_get_trigger_type(data) == IRQ_TYPE_NONE,
-		"irq type not set before enabling gpio irq %d", data->irq);
-
-	irq_gc_ack_clr_bit(data);
-	irq_gc_mask_set_bit(data);
-	return 0;
-}
-
-static int gpio_set_irq_type(struct irq_data *data, unsigned int flow_type)
-{
-	struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
-	unsigned int type;
-	unsigned int polarity;
-
-	switch (flow_type) {
-	case IRQ_TYPE_EDGE_BOTH:
-		type = REG_GPIO_IRQ_TYPE_EDGE;
-		polarity = REG_GPIO_IRQ_PLRT_LOW;
-		break;
-	case IRQ_TYPE_EDGE_RISING:
-		type = REG_GPIO_IRQ_TYPE_EDGE;
-		polarity = REG_GPIO_IRQ_PLRT_HIGH;
-		break;
-	case IRQ_TYPE_EDGE_FALLING:
-		type = REG_GPIO_IRQ_TYPE_EDGE;
-		polarity = REG_GPIO_IRQ_PLRT_LOW;
-		break;
-	case IRQ_TYPE_LEVEL_HIGH:
-		type = REG_GPIO_IRQ_TYPE_LEVEL;
-		polarity = REG_GPIO_IRQ_PLRT_HIGH;
-		break;
-	case IRQ_TYPE_LEVEL_LOW:
-		type = REG_GPIO_IRQ_TYPE_LEVEL;
-		polarity = REG_GPIO_IRQ_PLRT_LOW;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	tz1090_gpio_irq_type(bank, data->hwirq, type);
-	irq_setup_alt_chip(data, flow_type);
-
-	if (flow_type == IRQ_TYPE_EDGE_BOTH)
-		tz1090_gpio_irq_next_edge(bank, data->hwirq);
-	else
-		tz1090_gpio_irq_polarity(bank, data->hwirq, polarity);
-
-	return 0;
-}
-
-#ifdef CONFIG_SUSPEND
-static int gpio_set_irq_wake(struct irq_data *data, unsigned int on)
-{
-	struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
-
-#ifdef CONFIG_PM_DEBUG
-	pr_info("irq_wake irq%d state:%d\n", data->irq, on);
-#endif
-
-	/* wake on gpio block interrupt */
-	return irq_set_irq_wake(bank->irq, on);
-}
-#else
-#define gpio_set_irq_wake NULL
-#endif
-
-static void tz1090_gpio_irq_handler(struct irq_desc *desc)
-{
-	irq_hw_number_t hw;
-	unsigned int irq_stat, irq_no;
-	struct tz1090_gpio_bank *bank;
-	struct irq_desc *child_desc;
-
-	bank = (struct tz1090_gpio_bank *)irq_desc_get_handler_data(desc);
-	irq_stat = tz1090_gpio_read(bank, REG_GPIO_DIR) &
-		   tz1090_gpio_read(bank, REG_GPIO_IRQ_STS) &
-		   tz1090_gpio_read(bank, REG_GPIO_IRQ_EN) &
-		   0x3FFFFFFF; /* 30 bits only */
-
-	for (hw = 0; irq_stat; irq_stat >>= 1, ++hw) {
-		if (!(irq_stat & 1))
-			continue;
-
-		irq_no = irq_linear_revmap(bank->domain, hw);
-		child_desc = irq_to_desc(irq_no);
-
-		/* Toggle edge for pin with both edges triggering enabled */
-		if (irqd_get_trigger_type(&child_desc->irq_data)
-				== IRQ_TYPE_EDGE_BOTH)
-			tz1090_gpio_irq_next_edge(bank, hw);
-
-		generic_handle_irq_desc(child_desc);
-	}
-}
-
-static int tz1090_gpio_bank_probe(struct tz1090_gpio_bank_info *info)
-{
-	struct device_node *np = info->node;
-	struct device *dev = info->priv->dev;
-	struct tz1090_gpio_bank *bank;
-	struct irq_chip_generic *gc;
-	int err;
-
-	bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL);
-	if (!bank) {
-		dev_err(dev, "unable to allocate driver data\n");
-		return -ENOMEM;
-	}
-
-	/* Offset the main registers to the first register in this bank */
-	bank->reg = info->priv->reg + info->index * 4;
-
-	/* Set up GPIO chip */
-	snprintf(bank->label, sizeof(bank->label), "tz1090-gpio-%u",
-		 info->index);
-	bank->chip.label		= bank->label;
-	bank->chip.parent		= dev;
-	bank->chip.direction_input	= tz1090_gpio_direction_input;
-	bank->chip.direction_output	= tz1090_gpio_direction_output;
-	bank->chip.get			= tz1090_gpio_get;
-	bank->chip.set			= tz1090_gpio_set;
-	bank->chip.free			= tz1090_gpio_free;
-	bank->chip.request		= tz1090_gpio_request;
-	bank->chip.to_irq		= tz1090_gpio_to_irq;
-	bank->chip.of_node		= np;
-
-	/* GPIO numbering from 0 */
-	bank->chip.base			= info->index * 30;
-	bank->chip.ngpio		= 30;
-
-	/* Add the GPIO bank */
-	gpiochip_add_data(&bank->chip, bank);
-
-	/* Get the GPIO bank IRQ if provided */
-	bank->irq = irq_of_parse_and_map(np, 0);
-
-	/* The interrupt is optional (it may be used by another core on chip) */
-	if (!bank->irq) {
-		dev_info(dev, "IRQ not provided for bank %u, IRQs disabled\n",
-			 info->index);
-		return 0;
-	}
-
-	dev_info(dev, "Setting up IRQs for GPIO bank %u\n",
-		 info->index);
-
-	/*
-	 * Initialise all interrupts to disabled so we don't get
-	 * spurious ones on a dirty boot and hit the BUG_ON in the
-	 * handler.
-	 */
-	tz1090_gpio_write(bank, REG_GPIO_IRQ_EN, 0);
-
-	/* Add a virtual IRQ for each GPIO */
-	bank->domain = irq_domain_add_linear(np,
-					     bank->chip.ngpio,
-					     &irq_generic_chip_ops,
-					     bank);
-
-	/* Set up a generic irq chip with 2 chip types (level and edge) */
-	err = irq_alloc_domain_generic_chips(bank->domain, bank->chip.ngpio, 2,
-					     bank->label, handle_bad_irq, 0, 0,
-					     IRQ_GC_INIT_NESTED_LOCK);
-	if (err) {
-		dev_info(dev,
-			 "irq_alloc_domain_generic_chips failed for bank %u, IRQs disabled\n",
-			 info->index);
-		irq_domain_remove(bank->domain);
-		return 0;
-	}
-
-	gc = irq_get_domain_generic_chip(bank->domain, 0);
-	gc->reg_base	= bank->reg;
-
-	/* level chip type */
-	gc->chip_types[0].type			= IRQ_TYPE_LEVEL_MASK;
-	gc->chip_types[0].handler		= handle_level_irq;
-	gc->chip_types[0].regs.ack		= REG_GPIO_IRQ_STS;
-	gc->chip_types[0].regs.mask		= REG_GPIO_IRQ_EN;
-	gc->chip_types[0].chip.irq_startup	= gpio_startup_irq;
-	gc->chip_types[0].chip.irq_ack		= irq_gc_ack_clr_bit;
-	gc->chip_types[0].chip.irq_mask		= irq_gc_mask_clr_bit;
-	gc->chip_types[0].chip.irq_unmask	= irq_gc_mask_set_bit;
-	gc->chip_types[0].chip.irq_set_type	= gpio_set_irq_type;
-	gc->chip_types[0].chip.irq_set_wake	= gpio_set_irq_wake;
-	gc->chip_types[0].chip.flags		= IRQCHIP_MASK_ON_SUSPEND;
-
-	/* edge chip type */
-	gc->chip_types[1].type			= IRQ_TYPE_EDGE_BOTH;
-	gc->chip_types[1].handler		= handle_edge_irq;
-	gc->chip_types[1].regs.ack		= REG_GPIO_IRQ_STS;
-	gc->chip_types[1].regs.mask		= REG_GPIO_IRQ_EN;
-	gc->chip_types[1].chip.irq_startup	= gpio_startup_irq;
-	gc->chip_types[1].chip.irq_ack		= irq_gc_ack_clr_bit;
-	gc->chip_types[1].chip.irq_mask		= irq_gc_mask_clr_bit;
-	gc->chip_types[1].chip.irq_unmask	= irq_gc_mask_set_bit;
-	gc->chip_types[1].chip.irq_set_type	= gpio_set_irq_type;
-	gc->chip_types[1].chip.irq_set_wake	= gpio_set_irq_wake;
-	gc->chip_types[1].chip.flags		= IRQCHIP_MASK_ON_SUSPEND;
-
-	/* Setup chained handler for this GPIO bank */
-	irq_set_chained_handler_and_data(bank->irq, tz1090_gpio_irq_handler,
-					 bank);
-
-	return 0;
-}
-
-static void tz1090_gpio_register_banks(struct tz1090_gpio *priv)
-{
-	struct device_node *np = priv->dev->of_node;
-	struct device_node *node;
-
-	for_each_available_child_of_node(np, node) {
-		struct tz1090_gpio_bank_info info;
-		u32 addr;
-		int ret;
-
-		ret = of_property_read_u32(node, "reg", &addr);
-		if (ret) {
-			dev_err(priv->dev, "invalid reg on %pOF\n", node);
-			continue;
-		}
-		if (addr >= 3) {
-			dev_err(priv->dev, "index %u in %pOF out of range\n",
-				addr, node);
-			continue;
-		}
-
-		info.index = addr;
-		info.node = of_node_get(node);
-		info.priv = priv;
-
-		ret = tz1090_gpio_bank_probe(&info);
-		if (ret) {
-			dev_err(priv->dev, "failure registering %pOF\n", node);
-			of_node_put(node);
-			continue;
-		}
-	}
-}
-
-static int tz1090_gpio_probe(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	struct resource *res_regs;
-	struct tz1090_gpio priv;
-
-	if (!np) {
-		dev_err(&pdev->dev, "must be instantiated via devicetree\n");
-		return -ENOENT;
-	}
-
-	res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res_regs) {
-		dev_err(&pdev->dev, "cannot find registers resource\n");
-		return -ENOENT;
-	}
-
-	priv.dev = &pdev->dev;
-
-	/* Ioremap the registers */
-	priv.reg = devm_ioremap(&pdev->dev, res_regs->start,
-				resource_size(res_regs));
-	if (!priv.reg) {
-		dev_err(&pdev->dev, "unable to ioremap registers\n");
-		return -ENOMEM;
-	}
-
-	/* Look for banks */
-	tz1090_gpio_register_banks(&priv);
-
-	return 0;
-}
-
-static struct of_device_id tz1090_gpio_of_match[] = {
-	{ .compatible = "img,tz1090-gpio" },
-	{ },
-};
-
-static struct platform_driver tz1090_gpio_driver = {
-	.driver = {
-		.name		= "tz1090-gpio",
-		.of_match_table	= tz1090_gpio_of_match,
-	},
-	.probe		= tz1090_gpio_probe,
-};
-
-static int __init tz1090_gpio_init(void)
-{
-	return platform_driver_register(&tz1090_gpio_driver);
-}
-subsys_initcall(tz1090_gpio_init);
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c
index 938bbe3..324813e 100644
--- a/drivers/gpio/gpio-wm831x.c
+++ b/drivers/gpio/gpio-wm831x.c
@@ -182,7 +182,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 			dev_err(wm831x->dev,
 				"GPIO control %d read failed: %d\n",
 				gpio, reg);
-			seq_printf(s, "\n");
+			seq_putc(s, '\n');
 			continue;
 		}
 
diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c
index 7466482..c7028eb 100644
--- a/drivers/gpio/gpio-ws16c48.c
+++ b/drivers/gpio/gpio-ws16c48.c
@@ -11,6 +11,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  */
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/errno.h>
@@ -129,6 +130,51 @@ static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
 	return !!(port_state & mask);
 }
 
+static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,
+	unsigned long *mask, unsigned long *bits)
+{
+	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
+	const unsigned int gpio_reg_size = 8;
+	size_t i;
+	const size_t num_ports = chip->ngpio / gpio_reg_size;
+	unsigned int bits_offset;
+	size_t word_index;
+	unsigned int word_offset;
+	unsigned long word_mask;
+	const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
+	unsigned long port_state;
+
+	/* clear bits array to a clean slate */
+	bitmap_zero(bits, chip->ngpio);
+
+	/* get bits are evaluated a gpio port register at a time */
+	for (i = 0; i < num_ports; i++) {
+		/* gpio offset in bits array */
+		bits_offset = i * gpio_reg_size;
+
+		/* word index for bits array */
+		word_index = BIT_WORD(bits_offset);
+
+		/* gpio offset within current word of bits array */
+		word_offset = bits_offset % BITS_PER_LONG;
+
+		/* mask of get bits for current gpio within current word */
+		word_mask = mask[word_index] & (port_mask << word_offset);
+		if (!word_mask) {
+			/* no get bits in this port so skip to next one */
+			continue;
+		}
+
+		/* read bits from current gpio port */
+		port_state = inb(ws16c48gpio->base + i);
+
+		/* store acquired bits at respective bits array offset */
+		bits[word_index] |= port_state << word_offset;
+	}
+
+	return 0;
+}
+
 static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
@@ -383,6 +429,7 @@ static int ws16c48_probe(struct device *dev, unsigned int id)
 	ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input;
 	ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output;
 	ws16c48gpio->chip.get = ws16c48_gpio_get;
+	ws16c48gpio->chip.get_multiple = ws16c48_gpio_get_multiple;
 	ws16c48gpio->chip.set = ws16c48_gpio_set;
 	ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple;
 	ws16c48gpio->base = base[id];
diff --git a/drivers/gpio/gpio-xra1403.c b/drivers/gpio/gpio-xra1403.c
index 0230e4b..8d4c8e9 100644
--- a/drivers/gpio/gpio-xra1403.c
+++ b/drivers/gpio/gpio-xra1403.c
@@ -126,11 +126,16 @@ static void xra1403_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 {
 	int reg;
 	struct xra1403 *xra = gpiochip_get_data(chip);
-	int value[xra1403_regmap_cfg.max_register];
+	int *value;
 	int i;
 	unsigned int gcr;
 	unsigned int gsr;
 
+	value = kmalloc_array(xra1403_regmap_cfg.max_register, sizeof(*value),
+				GFP_KERNEL);
+	if (!value)
+		return;
+
 	seq_puts(s, "xra reg:");
 	for (reg = 0; reg <= xra1403_regmap_cfg.max_register; reg++)
 		seq_printf(s, " %2.2x", reg);
@@ -154,6 +159,7 @@ static void xra1403_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 			   (gcr & BIT(i)) ? "in" : "out",
 			   (gsr & BIT(i)) ? "hi" : "lo");
 	}
+	kfree(value);
 }
 #else
 #define xra1403_dbg_show NULL
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 84e5a9d..586d151 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -111,8 +111,8 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
 	struct gpio_desc *desc;
 	int ret;
 
-	ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
-					 &gpiospec);
+	ret = of_parse_phandle_with_args_map(np, propname, "gpio", index,
+					     &gpiospec);
 	if (ret) {
 		pr_debug("%s: can't parse '%s' property of node '%pOF[%d]'\n",
 			__func__, propname, np, index);
@@ -511,6 +511,28 @@ void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc)
 }
 EXPORT_SYMBOL(of_mm_gpiochip_remove);
 
+static void of_gpiochip_init_valid_mask(struct gpio_chip *chip)
+{
+	int len, i;
+	u32 start, count;
+	struct device_node *np = chip->of_node;
+
+	len = of_property_count_u32_elems(np,  "gpio-reserved-ranges");
+	if (len < 0 || len % 2 != 0)
+		return;
+
+	for (i = 0; i < len; i += 2) {
+		of_property_read_u32_index(np, "gpio-reserved-ranges",
+					   i, &start);
+		of_property_read_u32_index(np, "gpio-reserved-ranges",
+					   i + 1, &count);
+		if (start >= chip->ngpio || start + count >= chip->ngpio)
+			continue;
+
+		bitmap_clear(chip->valid_mask, start, count);
+	}
+};
+
 #ifdef CONFIG_PINCTRL
 static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
 {
@@ -615,6 +637,8 @@ int of_gpiochip_add(struct gpio_chip *chip)
 	if (chip->of_gpio_n_cells > MAX_PHANDLE_ARGS)
 		return -EINVAL;
 
+	of_gpiochip_init_valid_mask(chip);
+
 	status = of_gpiochip_add_pin_range(chip);
 	if (status)
 		return status;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index d66de67..43aeb07 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -337,6 +337,57 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc)
 	return 0;
 }
 
+static unsigned long *gpiochip_allocate_mask(struct gpio_chip *chip)
+{
+	unsigned long *p;
+
+	p = kmalloc_array(BITS_TO_LONGS(chip->ngpio), sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return NULL;
+
+	/* Assume by default all GPIOs are valid */
+	bitmap_fill(p, chip->ngpio);
+
+	return p;
+}
+
+static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip)
+{
+#ifdef CONFIG_OF_GPIO
+	int size;
+	struct device_node *np = gpiochip->of_node;
+
+	size = of_property_count_u32_elems(np,  "gpio-reserved-ranges");
+	if (size > 0 && size % 2 == 0)
+		gpiochip->need_valid_mask = true;
+#endif
+
+	if (!gpiochip->need_valid_mask)
+		return 0;
+
+	gpiochip->valid_mask = gpiochip_allocate_mask(gpiochip);
+	if (!gpiochip->valid_mask)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void gpiochip_free_valid_mask(struct gpio_chip *gpiochip)
+{
+	kfree(gpiochip->valid_mask);
+	gpiochip->valid_mask = NULL;
+}
+
+bool gpiochip_line_is_valid(const struct gpio_chip *gpiochip,
+				unsigned int offset)
+{
+	/* No mask means all valid */
+	if (likely(!gpiochip->valid_mask))
+		return true;
+	return test_bit(offset, gpiochip->valid_mask);
+}
+EXPORT_SYMBOL_GPL(gpiochip_line_is_valid);
+
 /*
  * GPIO line handle management
  */
@@ -1261,6 +1312,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
 	if (status)
 		goto err_remove_from_list;
 
+	status = gpiochip_init_valid_mask(chip);
+	if (status)
+		goto err_remove_irqchip_mask;
+
 	status = gpiochip_add_irqchip(chip, lock_key, request_key);
 	if (status)
 		goto err_remove_chip;
@@ -1290,6 +1345,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
 	acpi_gpiochip_remove(chip);
 	gpiochip_free_hogs(chip);
 	of_gpiochip_remove(chip);
+	gpiochip_free_valid_mask(chip);
+err_remove_irqchip_mask:
 	gpiochip_irqchip_free_valid_mask(chip);
 err_remove_from_list:
 	spin_lock_irqsave(&gpio_lock, flags);
@@ -1346,6 +1403,7 @@ void gpiochip_remove(struct gpio_chip *chip)
 	acpi_gpiochip_remove(chip);
 	gpiochip_remove_pin_ranges(chip);
 	of_gpiochip_remove(chip);
+	gpiochip_free_valid_mask(chip);
 	/*
 	 * We accept no more calls into the driver from this point, so
 	 * NULL the driver data pointer
@@ -1506,14 +1564,10 @@ static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip)
 	if (!gpiochip->irq.need_valid_mask)
 		return 0;
 
-	gpiochip->irq.valid_mask = kcalloc(BITS_TO_LONGS(gpiochip->ngpio),
-					   sizeof(long), GFP_KERNEL);
+	gpiochip->irq.valid_mask = gpiochip_allocate_mask(gpiochip);
 	if (!gpiochip->irq.valid_mask)
 		return -ENOMEM;
 
-	/* Assume by default all GPIOs are valid */
-	bitmap_fill(gpiochip->irq.valid_mask, gpiochip->ngpio);
-
 	return 0;
 }
 
@@ -1526,6 +1580,8 @@ static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip)
 bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip,
 				unsigned int offset)
 {
+	if (!gpiochip_line_is_valid(gpiochip, offset))
+		return false;
 	/* No mask means all valid */
 	if (likely(!gpiochip->irq.valid_mask))
 		return true;
@@ -3689,7 +3745,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
 	}
 
 	if (IS_ERR(desc)) {
-		dev_dbg(dev, "lookup for GPIO %s failed\n", con_id);
+		dev_dbg(dev, "No GPIO consumer %s found\n", con_id);
 		return desc;
 	}
 
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index b17ec67..ad456b6 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -13,13 +13,13 @@
 #define GPIOLIB_H
 
 #include <linux/gpio/driver.h>
+#include <linux/gpio/consumer.h> /* for enum gpiod_flags */
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/cdev.h>
 
 enum of_gpio_flags;
-enum gpiod_flags;
 enum gpio_lookup_flags;
 struct acpi_device;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
index dd6f989..5916cc2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
@@ -277,7 +277,7 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
 		else
 			return AMDGPU_FW_LOAD_PSP;
 	default:
-		DRM_ERROR("Unknow firmware load type\n");
+		DRM_ERROR("Unknown firmware load type\n");
 	}
 
 	return AMDGPU_FW_LOAD_DIRECT;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 63a3d46..9cd3566 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -589,7 +589,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
  ******************************************************************************/
 
 struct dc *dc_create(const struct dc_init_data *init_params)
- {
+{
 	struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
 	unsigned int full_pipe_count;
 
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 4ff0646..b97e2de 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -417,8 +417,8 @@ int drm_plane_create_color_properties(struct drm_plane *plane,
 {
 	struct drm_device *dev = plane->dev;
 	struct drm_property *prop;
-	struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
-						DRM_COLOR_RANGE_MAX)];
+	struct drm_prop_enum_list enum_list[max_t(int, DRM_COLOR_ENCODING_MAX,
+						       DRM_COLOR_RANGE_MAX)];
 	int i, len;
 
 	if (WARN_ON(supported_encodings == 0 ||
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index dc7db8a..fc8b2c6 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1626,7 +1626,7 @@ static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
 
 	/* Timeout 200us */
 	if (wait_for((I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) == 0, 1))
-		DRM_ERROR("timout waiting for CDCLK PLL unlock\n");
+		DRM_ERROR("timeout waiting for CDCLK PLL unlock\n");
 
 	dev_priv->cdclk.hw.vco = 0;
 }
@@ -1644,7 +1644,7 @@ static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
 
 	/* Timeout 200us */
 	if (wait_for((I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) != 0, 1))
-		DRM_ERROR("timout waiting for CDCLK PLL lock\n");
+		DRM_ERROR("timeout waiting for CDCLK PLL lock\n");
 
 	dev_priv->cdclk.hw.vco = vco;
 }
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 1a6db29..b8d5053 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -995,15 +995,17 @@ static const struct snd_soc_dapm_route vc4_hdmi_audio_routes[] = {
 	{ "TX", NULL, "Playback" },
 };
 
-static const struct snd_soc_codec_driver vc4_hdmi_audio_codec_drv = {
-	.component_driver = {
-		.controls = vc4_hdmi_audio_controls,
-		.num_controls = ARRAY_SIZE(vc4_hdmi_audio_controls),
-		.dapm_widgets = vc4_hdmi_audio_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(vc4_hdmi_audio_widgets),
-		.dapm_routes = vc4_hdmi_audio_routes,
-		.num_dapm_routes = ARRAY_SIZE(vc4_hdmi_audio_routes),
-	},
+static const struct snd_soc_component_driver vc4_hdmi_audio_component_drv = {
+	.controls		= vc4_hdmi_audio_controls,
+	.num_controls		= ARRAY_SIZE(vc4_hdmi_audio_controls),
+	.dapm_widgets		= vc4_hdmi_audio_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(vc4_hdmi_audio_widgets),
+	.dapm_routes		= vc4_hdmi_audio_routes,
+	.num_dapm_routes	= ARRAY_SIZE(vc4_hdmi_audio_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct snd_soc_dai_ops vc4_hdmi_audio_dai_ops = {
@@ -1101,11 +1103,11 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
 		return ret;
 	}
 
-	/* register codec and codec dai */
-	ret = snd_soc_register_codec(dev, &vc4_hdmi_audio_codec_drv,
+	/* register component and codec dai */
+	ret = devm_snd_soc_register_component(dev, &vc4_hdmi_audio_component_drv,
 				     &vc4_hdmi_audio_codec_dai_drv, 1);
 	if (ret) {
-		dev_err(dev, "Could not register codec: %d\n", ret);
+		dev_err(dev, "Could not register component: %d\n", ret);
 		return ret;
 	}
 
@@ -1130,29 +1132,11 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
 	 */
 	snd_soc_card_set_drvdata(card, hdmi);
 	ret = devm_snd_soc_register_card(dev, card);
-	if (ret) {
+	if (ret)
 		dev_err(dev, "Could not register sound card: %d\n", ret);
-		goto unregister_codec;
-	}
-
-	return 0;
-
-unregister_codec:
-	snd_soc_unregister_codec(dev);
 
 	return ret;
-}
 
-static void vc4_hdmi_audio_cleanup(struct vc4_hdmi *hdmi)
-{
-	struct device *dev = &hdmi->pdev->dev;
-
-	/*
-	 * If drvdata is not set this means the audio card was not
-	 * registered, just skip codec unregistration in this case.
-	 */
-	if (dev_get_drvdata(dev))
-		snd_soc_unregister_codec(dev);
 }
 
 #ifdef CONFIG_DRM_VC4_HDMI_CEC
@@ -1480,7 +1464,6 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
 	struct vc4_dev *vc4 = drm->dev_private;
 	struct vc4_hdmi *hdmi = vc4->hdmi;
 
-	vc4_hdmi_audio_cleanup(hdmi);
 	cec_unregister_adapter(hdmi->cec_adap);
 	vc4_hdmi_connector_destroy(hdmi->connector);
 	vc4_hdmi_encoder_destroy(hdmi->encoder);
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 19c499f..60252fd 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -274,15 +274,23 @@
 	Currently the following devices are known to be supported:
 	 - Trio Linker Plus II
 
+config HID_ELAN
+	tristate "ELAN USB Touchpad Support"
+	depends on LEDS_CLASS && USB_HID
+	---help---
+	Say Y to enable support for the USB ELAN touchpad
+	Currently the following devices are known to be supported:
+	 - HP Pavilion X2 10-p0XX.
+
 config HID_ELECOM
 	tristate "ELECOM HID devices"
 	depends on HID
 	---help---
 	Support for ELECOM devices:
 	  - BM084 Bluetooth Mouse
-	  - EX-G Trackball (Wired and wireless)
-	  - DEFT Trackball (Wired and wireless)
-	  - HUGE Trackball (Wired and wireless)
+	  - EX-G Trackballs (M-XT3DRBK, M-XT3URBK)
+	  - DEFT Trackballs (M-DT1DRBK, M-DT1URBK, M-DT2DRBK, M-DT2URBK)
+	  - HUGE Trackballs (M-HT1DRBK, M-HT1URBK)
 
 config HID_ELO
 	tristate "ELO USB 4000/4500 touchscreen"
@@ -331,6 +339,12 @@
 	  Say Y here if you have a Holtek On Line Grip based game controller
 	  and want to have force feedback support for it.
 
+config HID_GOOGLE_HAMMER
+	tristate "Google Hammer Keyboard"
+	depends on USB_HID && LEDS_CLASS
+	---help---
+	Say Y here if you have a Google Hammer device.
+
 config HID_GT683R
 	tristate "MSI GT68xR LED support"
 	depends on LEDS_CLASS && USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index eb13b9e..17a8bd9 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -39,11 +39,13 @@
 obj-$(CONFIG_HID_CYPRESS)	+= hid-cypress.o
 obj-$(CONFIG_HID_DRAGONRISE)	+= hid-dr.o
 obj-$(CONFIG_HID_EMS_FF)	+= hid-emsff.o
+obj-$(CONFIG_HID_ELAN)		+= hid-elan.o
 obj-$(CONFIG_HID_ELECOM)	+= hid-elecom.o
 obj-$(CONFIG_HID_ELO)		+= hid-elo.o
 obj-$(CONFIG_HID_EZKEY)		+= hid-ezkey.o
 obj-$(CONFIG_HID_GEMBIRD)	+= hid-gembird.o
 obj-$(CONFIG_HID_GFRM)		+= hid-gfrm.o
+obj-$(CONFIG_HID_GOOGLE_HAMMER)	+= hid-google-hammer.o
 obj-$(CONFIG_HID_GT683R)	+= hid-gt683r.o
 obj-$(CONFIG_HID_GYRATION)	+= hid-gyration.o
 obj-$(CONFIG_HID_HOLTEK)	+= hid-holtek-kbd.o
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 88b9703..88a5672f 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -570,7 +570,9 @@ static int asus_input_mapping(struct hid_device *hdev,
 static int asus_start_multitouch(struct hid_device *hdev)
 {
 	int ret;
-	const unsigned char buf[] = { FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00 };
+	static const unsigned char buf[] = {
+		FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00
+	};
 	unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
 
 	if (!dmabuf) {
@@ -644,8 +646,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		 * All functionality is on a single HID interface and for
 		 * userspace the touchpad must be a separate input_dev.
 		 */
-		hdev->quirks |= HID_QUIRK_MULTI_INPUT |
-				HID_QUIRK_NO_EMPTY_INPUT;
+		hdev->quirks |= HID_QUIRK_MULTI_INPUT;
 		drvdata->tp = &asus_t100chi_tp;
 	}
 
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index c2560aa..5d7cc6b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1365,7 +1365,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
 	 * of implement() working on 8 byte chunks
 	 */
 
-	int len = hid_report_len(report) + 7;
+	u32 len = hid_report_len(report) + 7;
 
 	return kmalloc(len, flags);
 }
@@ -1430,7 +1430,7 @@ void __hid_request(struct hid_device *hid, struct hid_report *report,
 {
 	char *buf;
 	int ret;
-	int len;
+	u32 len;
 
 	buf = hid_alloc_report_buf(report, GFP_KERNEL);
 	if (!buf)
@@ -1456,14 +1456,14 @@ void __hid_request(struct hid_device *hid, struct hid_report *report,
 }
 EXPORT_SYMBOL_GPL(__hid_request);
 
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 		int interrupt)
 {
 	struct hid_report_enum *report_enum = hid->report_enum + type;
 	struct hid_report *report;
 	struct hid_driver *hdrv;
 	unsigned int a;
-	int rsize, csize = size;
+	u32 rsize, csize = size;
 	u8 *cdata = data;
 	int ret = 0;
 
@@ -1521,7 +1521,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event);
  *
  * This is data entry for lower layers.
  */
-int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt)
+int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt)
 {
 	struct hid_report_enum *report_enum;
 	struct hid_driver *hdrv;
@@ -1966,6 +1966,8 @@ static int hid_device_probe(struct device *dev)
 			}
 		}
 
+		/* reset the quirks that has been previously set */
+		hdev->quirks = hid_lookup_quirk(hdev);
 		hdev->driver = hdrv;
 		if (hdrv->probe) {
 			ret = hdrv->probe(hdev, id);
@@ -2197,31 +2199,40 @@ void hid_destroy_device(struct hid_device *hdev)
 EXPORT_SYMBOL_GPL(hid_destroy_device);
 
 
-static int __bus_add_driver(struct device_driver *drv, void *data)
+static int __hid_bus_reprobe_drivers(struct device *dev, void *data)
 {
-	struct hid_driver *added_hdrv = data;
+	struct hid_driver *hdrv = data;
+	struct hid_device *hdev = to_hid_device(dev);
+
+	if (hdev->driver == hdrv &&
+	    !hdrv->match(hdev, hid_ignore_special_drivers))
+		return device_reprobe(dev);
+
+	return 0;
+}
+
+static int __hid_bus_driver_added(struct device_driver *drv, void *data)
+{
 	struct hid_driver *hdrv = to_hid_driver(drv);
 
-	if (hdrv->bus_add_driver)
-		hdrv->bus_add_driver(added_hdrv);
+	if (hdrv->match) {
+		bus_for_each_dev(&hid_bus_type, NULL, hdrv,
+				 __hid_bus_reprobe_drivers);
+	}
 
 	return 0;
 }
 
 static int __bus_removed_driver(struct device_driver *drv, void *data)
 {
-	struct hid_driver *removed_hdrv = data;
-	struct hid_driver *hdrv = to_hid_driver(drv);
-
-	if (hdrv->bus_removed_driver)
-		hdrv->bus_removed_driver(removed_hdrv);
-
-	return 0;
+	return bus_rescan_devices(&hid_bus_type);
 }
 
 int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
 		const char *mod_name)
 {
+	int ret;
+
 	hdrv->driver.name = hdrv->name;
 	hdrv->driver.bus = &hid_bus_type;
 	hdrv->driver.owner = owner;
@@ -2230,9 +2241,13 @@ int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
 	INIT_LIST_HEAD(&hdrv->dyn_list);
 	spin_lock_init(&hdrv->dyn_lock);
 
-	bus_for_each_drv(&hid_bus_type, NULL, hdrv, __bus_add_driver);
+	ret = driver_register(&hdrv->driver);
 
-	return driver_register(&hdrv->driver);
+	if (ret == 0)
+		bus_for_each_drv(&hid_bus_type, NULL, NULL,
+				 __hid_bus_driver_added);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(__hid_register_driver);
 
diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c
index 9ba5d98..ec9e060 100644
--- a/drivers/hid/hid-corsair.c
+++ b/drivers/hid/hid-corsair.c
@@ -2,11 +2,14 @@
  * HID driver for Corsair devices
  *
  * Supported devices:
+ *  - Vengeance K70 Keyboard
+ *  - K70 RAPIDFIRE Keyboard
  *  - Vengeance K90 Keyboard
  *  - Scimitar PRO RGB Gaming Mouse
  *
  * Copyright (c) 2015 Clement Vuchener
  * Copyright (c) 2017 Oscar Campos
+ * Copyright (c) 2017 Aaron Bottegal
  */
 
 /*
@@ -673,7 +676,7 @@ static int corsair_input_mapping(struct hid_device *dev,
 }
 
 /*
- * The report descriptor of Corsair Scimitar RGB Pro gaming mouse is
+ * The report descriptor of some of the Corsair gaming mice is
  * non parseable as they define two consecutive Logical Minimum for
  * the Usage Page (Consumer) in rdescs bytes 75 and 77 being 77 0x16
  * that should be obviousy 0x26 for Logical Magimum of 16 bits. This
@@ -681,7 +684,8 @@ static int corsair_input_mapping(struct hid_device *dev,
  * Minimum being larger than Logical Maximum.
  *
  * This driver fixes the report descriptor for:
- * - USB ID b1c:1b3e, sold as Scimitar RGB Pro Gaming mouse
+ * - USB ID 1b1c:1b34, sold as GLAIVE RGB Gaming mouse
+ * - USB ID 1b1c:1b3e, sold as Scimitar RGB Pro Gaming mouse
  */
 
 static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -691,13 +695,14 @@ static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 
 	if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
 		/*
-		 * Corsair Scimitar RGB Pro report descriptor is broken and
-		 * defines two different Logical Minimum for the Consumer
-		 * Application. The byte 77 should be a 0x26 defining a 16
-		 * bits integer for the Logical Maximum but it is a 0x16
+		 * Corsair GLAIVE RGB and Scimitar RGB Pro report descriptor is
+		 * broken and defines two different Logical Minimum for the
+		 * Consumer Application. The byte 77 should be a 0x26 defining
+		 * a 16 bits integer for the Logical Maximum but it is a 0x16
 		 * instead (Logical Minimum)
 		 */
 		switch (hdev->product) {
+		case USB_DEVICE_ID_CORSAIR_GLAIVE_RGB:
 		case USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB:
 			if (*rsize >= 172 && rdesc[75] == 0x15 && rdesc[77] == 0x16
 			&& rdesc[78] == 0xff && rdesc[79] == 0x0f) {
@@ -716,7 +721,14 @@ static const struct hid_device_id corsair_devices[] = {
 		.driver_data = CORSAIR_USE_K90_MACRO |
 			       CORSAIR_USE_K90_BACKLIGHT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
+            USB_DEVICE_ID_CORSAIR_GLAIVE_RGB) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
             USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
+	/*
+	 * Vengeance K70 and K70 RAPIDFIRE share product IDs.
+	 */
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
+            USB_DEVICE_ID_CORSAIR_K70R) },
 	{}
 };
 
diff --git a/drivers/hid/hid-elan.c b/drivers/hid/hid-elan.c
new file mode 100644
index 0000000..803a725
--- /dev/null
+++ b/drivers/hid/hid-elan.c
@@ -0,0 +1,421 @@
+/*
+ * HID Driver for ELAN Touchpad
+ *
+ * Currently only supports touchpad found on HP Pavilion X2 10
+ *
+ * Copyright (c) 2016 Alexandrov Stanislav <neko@nya.ai>
+ *
+ * This program is free software; you can redistribute 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/hid.h>
+#include <linux/input/mt.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "hid-ids.h"
+
+#define ELAN_SINGLE_FINGER	0x81
+#define ELAN_MT_FIRST_FINGER	0x82
+#define ELAN_MT_SECOND_FINGER	0x83
+#define ELAN_INPUT_REPORT_SIZE	8
+
+#define ELAN_MUTE_LED_REPORT	0xBC
+#define ELAN_LED_REPORT_SIZE	8
+
+struct elan_touchpad_settings {
+	u8 max_fingers;
+	u16 max_x;
+	u16 max_y;
+	u8 max_area_x;
+	u8 max_area_y;
+	u8 max_w;
+	int usb_bInterfaceNumber;
+};
+
+struct elan_drvdata {
+	struct input_dev *input;
+	u8 prev_report[ELAN_INPUT_REPORT_SIZE];
+	struct led_classdev mute_led;
+	u8 mute_led_state;
+	struct elan_touchpad_settings *settings;
+};
+
+static int is_not_elan_touchpad(struct hid_device *hdev)
+{
+	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+	struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
+
+	return (intf->altsetting->desc.bInterfaceNumber != drvdata->settings->usb_bInterfaceNumber);
+}
+
+static int elan_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+			      struct hid_field *field, struct hid_usage *usage,
+			      unsigned long **bit, int *max)
+{
+	if (is_not_elan_touchpad(hdev))
+		return 0;
+
+	if (field->report->id == ELAN_SINGLE_FINGER ||
+	    field->report->id == ELAN_MT_FIRST_FINGER ||
+	    field->report->id == ELAN_MT_SECOND_FINGER)
+		return -1;
+
+	return 0;
+}
+
+static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi)
+{
+	int ret;
+	struct input_dev *input;
+	struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
+
+	if (is_not_elan_touchpad(hdev))
+		return 0;
+
+	input = devm_input_allocate_device(&hdev->dev);
+	if (!input)
+		return -ENOMEM;
+
+	input->name = "Elan Touchpad";
+	input->phys = hdev->phys;
+	input->uniq = hdev->uniq;
+	input->id.bustype = hdev->bus;
+	input->id.vendor  = hdev->vendor;
+	input->id.product = hdev->product;
+	input->id.version = hdev->version;
+	input->dev.parent = &hdev->dev;
+
+	input_set_abs_params(input, ABS_MT_POSITION_X, 0,
+			     drvdata->settings->max_x, 0, 0);
+	input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
+			     drvdata->settings->max_y, 0, 0);
+	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0,
+			     drvdata->settings->max_fingers, 0, 0);
+	input_set_abs_params(input, ABS_TOOL_WIDTH, 0,
+			     drvdata->settings->max_w, 0, 0);
+
+	__set_bit(BTN_LEFT, input->keybit);
+	__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+
+	ret = input_mt_init_slots(input, drvdata->settings->max_fingers,
+				  INPUT_MT_POINTER);
+	if (ret) {
+		hid_err(hdev, "Failed to init elan MT slots: %d\n", ret);
+		return ret;
+	}
+
+	ret = input_register_device(input);
+	if (ret) {
+		hid_err(hdev, "Failed to register elan input device: %d\n",
+			ret);
+		input_free_device(input);
+		return ret;
+	}
+
+	drvdata->input = input;
+
+	return 0;
+}
+
+static void elan_report_mt_slot(struct elan_drvdata *drvdata, u8 *data,
+				unsigned int slot_num)
+{
+	struct input_dev *input = drvdata->input;
+	int x, y, w;
+
+	bool active = !!data;
+
+	input_mt_slot(input, slot_num);
+	input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
+	if (active) {
+		x = ((data[0] & 0xF0) << 4) | data[1];
+		y = drvdata->settings->max_y -
+		    (((data[0] & 0x07) << 8) | data[2]);
+		w = data[4];
+
+		input_report_abs(input, ABS_MT_POSITION_X, x);
+		input_report_abs(input, ABS_MT_POSITION_Y, y);
+		input_report_abs(input, ABS_TOOL_WIDTH, w);
+	}
+}
+
+static void elan_report_input(struct elan_drvdata *drvdata, u8 *data)
+{
+	int i;
+	struct input_dev *input = drvdata->input;
+
+	/*
+	 * There is 3 types of reports: for single touch,
+	 * for multitouch - first finger and for multitouch - second finger
+	 *
+	 * packet structure for ELAN_SINGLE_FINGER and ELAN_MT_FIRST_FINGER:
+	 *
+	 * byte 1: 1   0   0   0   0   0   0   1  // 0x81 or 0x82
+	 * byte 2: 0   0   0   0   0   0   0   0  // looks like unused
+	 * byte 3: f5  f4  f3  f2  f1  0   0   L
+	 * byte 4: x12 x11 x10 x9  0?  y11 y10 y9
+	 * byte 5: x8  x7  x6  x5  x4  x3  x2  x1
+	 * byte 6: y8  y7  y6  y5  y4  y3  y2  y1
+	 * byte 7: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1
+	 * byte 8: w8  w7  w6  w5  w4  w3  w2  w1
+	 *
+	 * packet structure for ELAN_MT_SECOND_FINGER:
+	 *
+	 * byte 1: 1   0   0   0   0   0   1   1  // 0x83
+	 * byte 2: x12 x11 x10 x9  0   y11 y10 y9
+	 * byte 3: x8  x7  x6  x5  x4  x3  x2  x1
+	 * byte 4: y8  y7  y6  y5  y4  y3  y2  y1
+	 * byte 5: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1
+	 * byte 6: w8  w7  w6  w5  w4  w3  w2  w1
+	 * byte 7: 0   0   0   0   0   0   0   0
+	 * byte 8: 0   0   0   0   0   0   0   0
+	 *
+	 * f5-f1: finger touch bits
+	 * L: clickpad button
+	 * sy / sx: not sure yet, but this looks like rectangular
+	 * area for finger
+	 * w: looks like finger width
+	 */
+
+	if (data[0] == ELAN_SINGLE_FINGER) {
+		for (i = 0; i < drvdata->settings->max_fingers; i++) {
+			if (data[2] & BIT(i + 3))
+				elan_report_mt_slot(drvdata, data + 3, i);
+			else
+				elan_report_mt_slot(drvdata, NULL, i);
+		}
+		input_report_key(input, BTN_LEFT, data[2] & 0x01);
+	}
+	/*
+	 * When touched with two fingers Elan touchpad will emit two HID reports
+	 * first is ELAN_MT_FIRST_FINGER and second is ELAN_MT_SECOND_FINGER
+	 * we will save ELAN_MT_FIRST_FINGER report and wait for
+	 * ELAN_MT_SECOND_FINGER to finish multitouch
+	 */
+	if (data[0] == ELAN_MT_FIRST_FINGER) {
+		memcpy(drvdata->prev_report, data,
+		       sizeof(drvdata->prev_report));
+		return;
+	}
+
+	if (data[0] == ELAN_MT_SECOND_FINGER) {
+		int first = 0;
+		u8 *prev_report = drvdata->prev_report;
+
+		if (prev_report[0] != ELAN_MT_FIRST_FINGER)
+			return;
+
+		for (i = 0; i < drvdata->settings->max_fingers; i++) {
+			if (prev_report[2] & BIT(i + 3)) {
+				if (!first) {
+					first = 1;
+					elan_report_mt_slot(drvdata, prev_report + 3, i);
+				} else {
+					elan_report_mt_slot(drvdata, data + 1, i);
+				}
+			} else {
+				elan_report_mt_slot(drvdata, NULL, i);
+			}
+		}
+		input_report_key(input, BTN_LEFT, prev_report[2] & 0x01);
+	}
+
+	input_mt_sync_frame(input);
+	input_sync(input);
+}
+
+static int elan_raw_event(struct hid_device *hdev,
+			  struct hid_report *report, u8 *data, int size)
+{
+	struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
+
+	if (is_not_elan_touchpad(hdev))
+		return 0;
+
+	if (data[0] == ELAN_SINGLE_FINGER ||
+	    data[0] == ELAN_MT_FIRST_FINGER ||
+	    data[0] == ELAN_MT_SECOND_FINGER) {
+		if (size == ELAN_INPUT_REPORT_SIZE) {
+			elan_report_input(drvdata, data);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int elan_start_multitouch(struct hid_device *hdev)
+{
+	int ret;
+
+	/*
+	 * This byte sequence will enable multitouch mode and disable
+	 * mouse emulation
+	 */
+	const unsigned char buf[] = { 0x0D, 0x00, 0x03, 0x21, 0x00 };
+	unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
+
+	if (!dmabuf)
+		return -ENOMEM;
+
+	ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, sizeof(buf),
+				 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+
+	kfree(dmabuf);
+
+	if (ret != sizeof(buf)) {
+		hid_err(hdev, "Failed to start multitouch: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static enum led_brightness elan_mute_led_get_brigtness(struct led_classdev *led_cdev)
+{
+	struct device *dev = led_cdev->dev->parent;
+	struct hid_device *hdev = to_hid_device(dev);
+	struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
+
+	return drvdata->mute_led_state;
+}
+
+static int elan_mute_led_set_brigtness(struct led_classdev *led_cdev,
+				       enum led_brightness value)
+{
+	int ret;
+	u8 led_state;
+	struct device *dev = led_cdev->dev->parent;
+	struct hid_device *hdev = to_hid_device(dev);
+	struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
+
+	unsigned char *dmabuf = kzalloc(ELAN_LED_REPORT_SIZE, GFP_KERNEL);
+
+	if (!dmabuf)
+		return -ENOMEM;
+
+	led_state = !!value;
+
+	dmabuf[0] = ELAN_MUTE_LED_REPORT;
+	dmabuf[1] = 0x02;
+	dmabuf[2] = led_state;
+
+	ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, ELAN_LED_REPORT_SIZE,
+				 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+
+	kfree(dmabuf);
+
+	if (ret != ELAN_LED_REPORT_SIZE) {
+		hid_err(hdev, "Failed to set mute led brightness: %d\n", ret);
+		return ret;
+	}
+
+	drvdata->mute_led_state = led_state;
+	return 0;
+}
+
+static int elan_init_mute_led(struct hid_device *hdev)
+{
+	struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
+	struct led_classdev *mute_led = &drvdata->mute_led;
+
+	mute_led->name = "elan:red:mute";
+	mute_led->brightness_get = elan_mute_led_get_brigtness;
+	mute_led->brightness_set_blocking = elan_mute_led_set_brigtness;
+	mute_led->max_brightness = LED_ON;
+	mute_led->dev = &hdev->dev;
+
+	return devm_led_classdev_register(&hdev->dev, mute_led);
+}
+
+static int elan_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+	struct elan_drvdata *drvdata;
+
+	drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
+
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->settings = (struct elan_touchpad_settings *)id->driver_data;
+	hid_set_drvdata(hdev, drvdata);
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		hid_err(hdev, "Hid Parse failed\n");
+		return ret;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+	if (ret) {
+		hid_err(hdev, "Hid hw start failed\n");
+		return ret;
+	}
+
+	if (is_not_elan_touchpad(hdev))
+		return 0;
+
+	if (!drvdata->input) {
+		hid_err(hdev, "Input device is not registred\n");
+		ret = -ENAVAIL;
+		goto err;
+	}
+
+	ret = elan_start_multitouch(hdev);
+	if (ret)
+		goto err;
+
+	ret = elan_init_mute_led(hdev);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	hid_hw_stop(hdev);
+	return ret;
+}
+
+static void elan_remove(struct hid_device *hdev)
+{
+	hid_hw_stop(hdev);
+}
+
+static const struct elan_touchpad_settings hp_x2_10_touchpad_data = {
+	.max_fingers = 5,
+	.max_x = 2930,
+	.max_y = 1250,
+	.max_area_x = 15,
+	.max_area_y = 15,
+	.max_w = 255,
+	.usb_bInterfaceNumber = 1,
+};
+
+static const struct hid_device_id elan_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2_10_COVER),
+		(kernel_ulong_t)&hp_x2_10_touchpad_data},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(hid, elan_devices);
+
+static struct hid_driver elan_driver = {
+	.name = "elan",
+	.id_table = elan_devices,
+	.input_mapping = elan_input_mapping,
+	.input_configured = elan_input_configured,
+	.raw_event = elan_raw_event,
+	.probe = elan_probe,
+	.remove = elan_remove,
+};
+
+module_hid_driver(elan_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexandrov Stanislav");
+MODULE_DESCRIPTION("Driver for HID ELAN Touchpads");
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
index 1a1ecc4..ae8e941 100644
--- a/drivers/hid/hid-elecom.c
+++ b/drivers/hid/hid-elecom.c
@@ -1,9 +1,9 @@
 /*
  *  HID driver for ELECOM devices:
  *  - BM084 Bluetooth Mouse
- *  - EX-G Trackball (Wired and wireless)
- *  - DEFT Trackball (Wired and wireless)
- *  - HUGE Trackball (Wired and wireless)
+ *  - EX-G Trackballs (M-XT3DRBK, M-XT3URBK, M-XT4DRBK)
+ *  - DEFT Trackballs (M-DT1DRBK, M-DT1URBK, M-DT2DRBK, M-DT2URBK)
+ *  - HUGE Trackballs (M-HT1DRBK, M-HT1URBK)
  *
  *  Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
  *  Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
@@ -65,14 +65,15 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 			rdesc[47] = 0x00;
 		}
 		break;
-	case USB_DEVICE_ID_ELECOM_EX_G_WIRED:
-	case USB_DEVICE_ID_ELECOM_EX_G_WIRELESS:
+	case USB_DEVICE_ID_ELECOM_M_XT3URBK:
+	case USB_DEVICE_ID_ELECOM_M_XT3DRBK:
+	case USB_DEVICE_ID_ELECOM_M_XT4DRBK:
 		mouse_button_fixup(hdev, rdesc, *rsize, 6);
 		break;
-	case USB_DEVICE_ID_ELECOM_DEFT_WIRED:
-	case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS:
-	case USB_DEVICE_ID_ELECOM_HUGE_WIRED:
-	case USB_DEVICE_ID_ELECOM_HUGE_WIRELESS:
+	case USB_DEVICE_ID_ELECOM_M_DT1URBK:
+	case USB_DEVICE_ID_ELECOM_M_DT1DRBK:
+	case USB_DEVICE_ID_ELECOM_M_HT1URBK:
+	case USB_DEVICE_ID_ELECOM_M_HT1DRBK:
 		mouse_button_fixup(hdev, rdesc, *rsize, 8);
 		break;
 	}
@@ -81,12 +82,13 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 
 static const struct hid_device_id elecom_devices[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_EX_G_WIRED) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_EX_G_WIRELESS) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, elecom_devices);
diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c
index 3c0a1bf..c25b471 100644
--- a/drivers/hid/hid-generic.c
+++ b/drivers/hid/hid-generic.c
@@ -26,37 +26,6 @@
 
 static struct hid_driver hid_generic;
 
-static int __unmap_hid_generic(struct device *dev, void *data)
-{
-	struct hid_driver *hdrv = data;
-	struct hid_device *hdev = to_hid_device(dev);
-
-	/* only unbind matching devices already bound to hid-generic */
-	if (hdev->driver != &hid_generic ||
-	    hid_match_device(hdev, hdrv) == NULL)
-		return 0;
-
-	if (dev->parent)	/* Needed for USB */
-		device_lock(dev->parent);
-	device_release_driver(dev);
-	if (dev->parent)
-		device_unlock(dev->parent);
-
-	return 0;
-}
-
-static void hid_generic_add_driver(struct hid_driver *hdrv)
-{
-	bus_for_each_dev(&hid_bus_type, NULL, hdrv, __unmap_hid_generic);
-}
-
-static void hid_generic_removed_driver(struct hid_driver *hdrv)
-{
-	int ret;
-
-	ret = driver_attach(&hid_generic.driver);
-}
-
 static int __check_hid_generic(struct device_driver *drv, void *data)
 {
 	struct hid_driver *hdrv = to_hid_driver(drv);
@@ -97,8 +66,6 @@ static struct hid_driver hid_generic = {
 	.name = "hid-generic",
 	.id_table = hid_table,
 	.match = hid_generic_match,
-	.bus_add_driver = hid_generic_add_driver,
-	.bus_removed_driver = hid_generic_removed_driver,
 };
 module_hid_driver(hid_generic);
 
diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c
new file mode 100644
index 0000000..7b8e17b
--- /dev/null
+++ b/drivers/hid/hid-google-hammer.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  HID driver for Google Hammer device.
+ *
+ *  Copyright (c) 2017 Google Inc.
+ *  Author: Wei-Ning Huang <wnhuang@google.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/hid.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define MAX_BRIGHTNESS 100
+
+/* HID usage for keyboard backlight (Alphanumeric display brightness) */
+#define HID_AD_BRIGHTNESS 0x00140046
+
+struct hammer_kbd_leds {
+	struct led_classdev cdev;
+	struct hid_device *hdev;
+	u8 buf[2] ____cacheline_aligned;
+};
+
+static int hammer_kbd_brightness_set_blocking(struct led_classdev *cdev,
+		enum led_brightness br)
+{
+	struct hammer_kbd_leds *led = container_of(cdev,
+						   struct hammer_kbd_leds,
+						   cdev);
+	int ret;
+
+	led->buf[0] = 0;
+	led->buf[1] = br;
+
+	/*
+	 * Request USB HID device to be in Full On mode, so that sending
+	 * hardware output report and hardware raw request won't fail.
+	 */
+	ret = hid_hw_power(led->hdev, PM_HINT_FULLON);
+	if (ret < 0) {
+		hid_err(led->hdev, "failed: device not resumed %d\n", ret);
+		return ret;
+	}
+
+	ret = hid_hw_output_report(led->hdev, led->buf, sizeof(led->buf));
+	if (ret == -ENOSYS)
+		ret = hid_hw_raw_request(led->hdev, 0, led->buf,
+					 sizeof(led->buf),
+					 HID_OUTPUT_REPORT,
+					 HID_REQ_SET_REPORT);
+	if (ret < 0)
+		hid_err(led->hdev, "failed to set keyboard backlight: %d\n",
+			ret);
+
+	/* Request USB HID device back to Normal Mode. */
+	hid_hw_power(led->hdev, PM_HINT_NORMAL);
+
+	return ret;
+}
+
+static int hammer_register_leds(struct hid_device *hdev)
+{
+	struct hammer_kbd_leds *kbd_backlight;
+
+	kbd_backlight = devm_kzalloc(&hdev->dev,
+				     sizeof(*kbd_backlight),
+				     GFP_KERNEL);
+	if (!kbd_backlight)
+		return -ENOMEM;
+
+	kbd_backlight->hdev = hdev;
+	kbd_backlight->cdev.name = "hammer::kbd_backlight";
+	kbd_backlight->cdev.max_brightness = MAX_BRIGHTNESS;
+	kbd_backlight->cdev.brightness_set_blocking =
+		hammer_kbd_brightness_set_blocking;
+	kbd_backlight->cdev.flags = LED_HW_PLUGGABLE;
+
+	/* Set backlight to 0% initially. */
+	hammer_kbd_brightness_set_blocking(&kbd_backlight->cdev, 0);
+
+	return devm_led_classdev_register(&hdev->dev, &kbd_backlight->cdev);
+}
+
+static int hammer_input_configured(struct hid_device *hdev,
+				   struct hid_input *hi)
+{
+	struct list_head *report_list =
+		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct hid_report *report;
+
+	if (list_empty(report_list))
+		return 0;
+
+	report = list_first_entry(report_list, struct hid_report, list);
+
+	if (report->maxfield == 1 &&
+	    report->field[0]->application == HID_GD_KEYBOARD &&
+	    report->field[0]->maxusage == 1 &&
+	    report->field[0]->usage[0].hid == HID_AD_BRIGHTNESS) {
+		int err = hammer_register_leds(hdev);
+
+		if (err)
+			hid_warn(hdev,
+				"Failed to register keyboard backlight: %d\n",
+				err);
+	}
+
+	return 0;
+}
+
+static const struct hid_device_id hammer_devices[] = {
+	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
+		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) },
+	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
+		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) },
+	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
+		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, hammer_devices);
+
+static struct hid_driver hammer_driver = {
+	.name = "hammer",
+	.id_table = hammer_devices,
+	.input_configured = hammer_input_configured,
+};
+module_hid_driver(hammer_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 9454ac1..5a3a7ea 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -291,6 +291,7 @@
 #define USB_DEVICE_ID_CORSAIR_K70RGB    0x1b13
 #define USB_DEVICE_ID_CORSAIR_STRAFE    0x1b15
 #define USB_DEVICE_ID_CORSAIR_K65RGB    0x1b17
+#define USB_DEVICE_ID_CORSAIR_GLAIVE_RGB        0x1b34
 #define USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE  0x1b38
 #define USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE  0x1b39
 #define USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB  0x1b3e
@@ -368,15 +369,17 @@
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001	0xa001
 
 #define USB_VENDOR_ID_ELAN		0x04f3
+#define USB_DEVICE_ID_HP_X2_10_COVER	0x0755
 
 #define USB_VENDOR_ID_ELECOM		0x056e
 #define USB_DEVICE_ID_ELECOM_BM084	0x0061
-#define USB_DEVICE_ID_ELECOM_EX_G_WIRED	0x00fb
-#define USB_DEVICE_ID_ELECOM_EX_G_WIRELESS	0x00fc
-#define USB_DEVICE_ID_ELECOM_DEFT_WIRED	0x00fe
-#define USB_DEVICE_ID_ELECOM_DEFT_WIRELESS	0x00ff
-#define USB_DEVICE_ID_ELECOM_HUGE_WIRED	0x010c
-#define USB_DEVICE_ID_ELECOM_HUGE_WIRELESS	0x010d
+#define USB_DEVICE_ID_ELECOM_M_XT3URBK	0x00fb
+#define USB_DEVICE_ID_ELECOM_M_XT3DRBK	0x00fc
+#define USB_DEVICE_ID_ELECOM_M_XT4DRBK	0x00fd
+#define USB_DEVICE_ID_ELECOM_M_DT1URBK	0x00fe
+#define USB_DEVICE_ID_ELECOM_M_DT1DRBK	0x00ff
+#define USB_DEVICE_ID_ELECOM_M_HT1URBK	0x010c
+#define USB_DEVICE_ID_ELECOM_M_HT1DRBK	0x010d
 
 #define USB_VENDOR_ID_DREAM_CHEEKY	0x1d34
 #define USB_DEVICE_ID_DREAM_CHEEKY_WN	0x0004
@@ -445,7 +448,10 @@
 #define USB_DEVICE_ID_GOODTOUCH_000f	0x000f
 
 #define USB_VENDOR_ID_GOOGLE		0x18d1
+#define USB_DEVICE_ID_GOOGLE_HAMMER	0x5022
 #define USB_DEVICE_ID_GOOGLE_TOUCH_ROSE	0x5028
+#define USB_DEVICE_ID_GOOGLE_STAFF	0x502b
+#define USB_DEVICE_ID_GOOGLE_WAND	0x502d
 
 #define USB_VENDOR_ID_GOTOP		0x08f2
 #define USB_DEVICE_ID_SUPER_Q2		0x007f
@@ -961,6 +967,9 @@
 
 #define USB_VENDOR_ID_SMK		0x0609
 #define USB_DEVICE_ID_SMK_PS3_BDREMOTE	0x0306
+#define USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE       0x0368
+#define USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE       0x0369
+
 
 #define USB_VENDOR_ID_SONY			0x054c
 #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE	0x024b
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 04d01b5..6836a85 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1368,7 +1368,8 @@ static void hidinput_led_worker(struct work_struct *work)
 					      led_work);
 	struct hid_field *field;
 	struct hid_report *report;
-	int len, ret;
+	int ret;
+	u32 len;
 	__u8 *buf;
 
 	field = hidinput_get_led_field(hid);
@@ -1656,16 +1657,16 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
 	}
 
 	list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
-		if ((hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
-		    !hidinput_has_been_populated(hidinput)) {
+		if (drv->input_configured &&
+		    drv->input_configured(hid, hidinput))
+			goto out_unwind;
+
+		if (!hidinput_has_been_populated(hidinput)) {
 			/* no need to register an input device not populated */
 			hidinput_cleanup_hidinput(hid, hidinput);
 			continue;
 		}
 
-		if (drv->input_configured &&
-		    drv->input_configured(hid, hidinput))
-			goto out_unwind;
 		if (input_register_device(hidinput->input))
 			goto out_unwind;
 		hidinput->registered = true;
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 3b4739bd..dad2fbb 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -74,6 +74,7 @@ MODULE_LICENSE("GPL");
 #define MT_QUIRK_TOUCH_SIZE_SCALING	BIT(15)
 #define MT_QUIRK_STICKY_FINGERS		BIT(16)
 #define MT_QUIRK_ASUS_CUSTOM_UP		BIT(17)
+#define MT_QUIRK_WIN8_PTP_BUTTONS	BIT(18)
 
 #define MT_INPUTMODE_TOUCHSCREEN	0x02
 #define MT_INPUTMODE_TOUCHPAD		0x03
@@ -126,7 +127,6 @@ struct mt_device {
 	int left_button_state;	/* left button state */
 	unsigned last_slot_field;	/* the last field of a slot */
 	unsigned mt_report_id;	/* the report ID of the multitouch device */
-	unsigned long initial_quirks;	/* initial quirks state */
 	__s16 inputmode;	/* InputMode HID feature, -1 if non-existent */
 	__s16 inputmode_index;	/* InputMode HID feature index in the report */
 	__s16 maxcontact_report_id;	/* Maximum Contact Number HID feature,
@@ -183,6 +183,7 @@ static void mt_post_parse(struct mt_device *td);
 #define MT_CLS_ASUS				0x010b
 #define MT_CLS_VTL				0x0110
 #define MT_CLS_GOOGLE				0x0111
+#define MT_CLS_RAZER_BLADE_STEALTH		0x0112
 
 #define MT_DEFAULT_MAXCONTACT	10
 #define MT_MAX_MAXCONTACT	250
@@ -241,7 +242,8 @@ static struct mt_class mt_classes[] = {
 			MT_QUIRK_IGNORE_DUPLICATES |
 			MT_QUIRK_HOVERING |
 			MT_QUIRK_CONTACT_CNT_ACCURATE |
-			MT_QUIRK_STICKY_FINGERS },
+			MT_QUIRK_STICKY_FINGERS |
+			MT_QUIRK_WIN8_PTP_BUTTONS },
 	{ .name = MT_CLS_EXPORT_ALL_INPUTS,
 		.quirks = MT_QUIRK_ALWAYS_VALID |
 			MT_QUIRK_CONTACT_CNT_ACCURATE,
@@ -250,7 +252,8 @@ static struct mt_class mt_classes[] = {
 		.quirks = MT_QUIRK_ALWAYS_VALID |
 			MT_QUIRK_IGNORE_DUPLICATES |
 			MT_QUIRK_HOVERING |
-			MT_QUIRK_CONTACT_CNT_ACCURATE,
+			MT_QUIRK_CONTACT_CNT_ACCURATE |
+			MT_QUIRK_WIN8_PTP_BUTTONS,
 		.export_all_inputs = true },
 
 	/*
@@ -323,6 +326,13 @@ static struct mt_class mt_classes[] = {
 			MT_QUIRK_SLOT_IS_CONTACTID |
 			MT_QUIRK_HOVERING
 	},
+	{ .name = MT_CLS_RAZER_BLADE_STEALTH,
+		.quirks = MT_QUIRK_ALWAYS_VALID |
+			MT_QUIRK_IGNORE_DUPLICATES |
+			MT_QUIRK_HOVERING |
+			MT_QUIRK_CONTACT_CNT_ACCURATE |
+			MT_QUIRK_WIN8_PTP_BUTTONS,
+	},
 	{ }
 };
 
@@ -369,15 +379,15 @@ static const struct attribute_group mt_attribute_group = {
 
 static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
 {
-	struct mt_device *td = hid_get_drvdata(hdev);
-	int ret, size = hid_report_len(report);
+	int ret;
+	u32 size = hid_report_len(report);
 	u8 *buf;
 
 	/*
 	 * Do not fetch the feature report if the device has been explicitly
 	 * marked as non-capable.
 	 */
-	if (td->initial_quirks & HID_QUIRK_NO_INIT_REPORTS)
+	if (hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)
 		return;
 
 	buf = hid_alloc_report_buf(report, GFP_KERNEL);
@@ -659,8 +669,7 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		 * MS PTP spec says that external buttons left and right have
 		 * usages 2 and 3.
 		 */
-		if ((cls->name == MT_CLS_WIN_8 ||
-			cls->name == MT_CLS_WIN_8_DUAL) &&
+		if ((cls->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
 		    field->application == HID_DG_TOUCHPAD &&
 		    (usage->hid & HID_USAGE) > 1)
 			code--;
@@ -722,7 +731,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
 		}
 
 		if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE))
-			s->confidence_state = 1;
+			s->confidence_state = true;
 		active = (s->touch_state || s->inrange_state) &&
 							s->confidence_state;
 
@@ -772,9 +781,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
  */
 static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
 {
-	__s32 cls = td->mtclass.name;
-
-	if (cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL)
+	if (td->mtclass.quirks & MT_QUIRK_WIN8_PTP_BUTTONS)
 		input_event(input, EV_KEY, BTN_LEFT, td->left_button_state);
 
 	input_mt_sync_frame(input);
@@ -826,7 +833,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
 				bool first_packet)
 {
 	struct mt_device *td = hid_get_drvdata(hid);
-	__s32 cls = td->mtclass.name;
 	__s32 quirks = td->mtclass.quirks;
 	struct input_dev *input = field->hidinput->input;
 
@@ -904,7 +910,7 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
 			 * non finger/touch events in the first_packet of
 			 * a (possible) multi-packet frame.
 			 */
-			if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
+			if ((quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
 			    !first_packet)
 				return;
 
@@ -915,7 +921,7 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
 			 * BTN_LEFT if either is pressed, so we or all values
 			 * together and report the result in mt_sync_frame().
 			 */
-			if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
+			if ((quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
 			    usage->type == EV_KEY && usage->code == BTN_LEFT) {
 				td->left_button_state |= value;
 				return;
@@ -939,7 +945,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
 static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
 {
 	struct mt_device *td = hid_get_drvdata(hid);
-	__s32 cls = td->mtclass.name;
 	struct hid_field *field;
 	bool first_packet;
 	unsigned count;
@@ -968,7 +973,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
 		 * of a possible multi-packet frame be checking that the
 		 * timestamp has changed.
 		 */
-		if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
+		if ((td->mtclass.quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
 		    td->num_received == 0 && td->prev_scantime != scantime)
 			td->num_expected = value;
 		/* A non 0 contact count always indicates a first packet */
@@ -1183,7 +1188,7 @@ static void mt_set_input_mode(struct hid_device *hdev)
 	struct hid_report_enum *re;
 	struct mt_class *cls = &td->mtclass;
 	char *buf;
-	int report_len;
+	u32 report_len;
 
 	if (td->inputmode < 0)
 		return;
@@ -1447,11 +1452,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
 		td->serial_maybe = true;
 
-	/*
-	 * Store the initial quirk state
-	 */
-	td->initial_quirks = hdev->quirks;
-
 	/* This allows the driver to correctly support devices
 	 * that emit events over several HID messages.
 	 */
@@ -1463,22 +1463,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	 * device.
 	 */
 	hdev->quirks |= HID_QUIRK_MULTI_INPUT;
-	hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
-
-	/*
-	 * Some multitouch screens do not like to be polled for input
-	 * reports. Fortunately, the Win8 spec says that all touches
-	 * should be sent during each report, making the initialization
-	 * of input reports unnecessary. For Win7 devices, well, let's hope
-	 * they will still be happy (this is only be a problem if a touch
-	 * was already there while probing the device).
-	 *
-	 * In addition some touchpads do not behave well if we read
-	 * all feature reports from them. Instead we prevent
-	 * initial report fetching and then selectively fetch each
-	 * report we are interested in.
-	 */
-	hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
 
 	timer_setup(&td->release_timer, mt_expired_timeout, 0);
 
@@ -1537,7 +1521,6 @@ static void mt_remove(struct hid_device *hdev)
 
 	sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
 	hid_hw_stop(hdev);
-	hdev->quirks = td->initial_quirks;
 }
 
 /*
@@ -1793,6 +1776,11 @@ static const struct hid_device_id mt_devices[] = {
 		MT_USB_DEVICE(USB_VENDOR_ID_QUANTA,
 			USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) },
 
+	/* Razer touchpads */
+	{ .driver_data = MT_CLS_RAZER_BLADE_STEALTH,
+		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+			USB_VENDOR_ID_SYNAPTICS, 0x8323) },
+
 	/* Stantum panels */
 	{ .driver_data = MT_CLS_CONFIDENCE,
 		MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index 3d121d8..43b1c72 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -591,8 +591,8 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 	switch (usage->hid) {
 	case 0xff000001:
 		/* Tag indicating the start of a multitouch group */
-		nd->reading_mt = 1;
-		nd->first_contact_touch = 0;
+		nd->reading_mt = true;
+		nd->first_contact_touch = false;
 		break;
 	case HID_DG_TIPSWITCH:
 		nd->tipswitch = value;
@@ -663,7 +663,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 			 * even if deactivation slack is turned off.
 			 */
 			nd->act_state = deactivate_slack - 1;
-			nd->confidence = 0;
+			nd->confidence = false;
 			break;
 		}
 
@@ -679,7 +679,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 			 */
 			if (nd->w < nd->min_width ||
 			    nd->h < nd->min_height)
-				nd->confidence = 0;
+				nd->confidence = false;
 		} else
 			break;
 
@@ -758,7 +758,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 		if (!nd->reading_mt) /* Just to be sure */
 			break;
 
-		nd->reading_mt = 0;
+		nd->reading_mt = false;
 
 
 		/*
@@ -910,7 +910,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		return -ENOMEM;
 	}
 
-	nd->reading_mt = 0;
+	nd->reading_mt = false;
 	nd->min_width = 0;
 	nd->min_height = 0;
 	nd->activate_slack = activate_slack;
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index e92b77f..587e268 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -62,6 +62,7 @@ static const struct hid_device_id hid_quirks[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R), HID_QUIRK_NO_INIT_REPORTS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB), HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET },
@@ -317,6 +318,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 #endif
 #if IS_ENABLED(CONFIG_HID_CORSAIR)
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
 #endif
 #if IS_ENABLED(CONFIG_HID_CP2112)
@@ -333,14 +335,18 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
 #endif
+#if IS_ENABLED(CONFIG_HID_ELAN)
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2_10_COVER) },
+#endif
 #if IS_ENABLED(CONFIG_HID_ELECOM)
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_EX_G_WIRED) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_EX_G_WIRELESS) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK) },
 #endif
 #if IS_ENABLED(CONFIG_HID_ELO)
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
@@ -608,6 +614,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
 #if IS_ENABLED(CONFIG_HID_SONY)
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) },
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index c6c05df..9c93621 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -89,8 +89,8 @@ struct rmi_data {
 	u8 *writeReport;
 	u8 *readReport;
 
-	int input_report_size;
-	int output_report_size;
+	u32 input_report_size;
+	u32 output_report_size;
 
 	unsigned long flags;
 
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index ccdc5f2..e475c50 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -9,6 +9,7 @@
  *  Copyright (c) 2006-2013 Jiri Kosina
  *  Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
  *  Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com>
+ *  Copyright (c) 2018 Todd Kelner
  */
 
 /*
@@ -55,6 +56,8 @@
 #define NAVIGATION_CONTROLLER_BT  BIT(11)
 #define SINO_LITE_CONTROLLER      BIT(12)
 #define FUTUREMAX_DANCE_MAT       BIT(13)
+#define NSG_MR5U_REMOTE_BT        BIT(14)
+#define NSG_MR7U_REMOTE_BT        BIT(15)
 
 #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
 #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
@@ -72,8 +75,11 @@
 				MOTION_CONTROLLER)
 #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\
 			MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT)
+#define NSG_MRXU_REMOTE (NSG_MR5U_REMOTE_BT | NSG_MR7U_REMOTE_BT)
 
 #define MAX_LEDS 4
+#define NSG_MRXU_MAX_X 1667
+#define NSG_MRXU_MAX_Y 1868
 
 
 /* PS/3 Motion controller */
@@ -1098,6 +1104,80 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
 	}
 }
 
+static void nsg_mrxu_parse_report(struct sony_sc *sc, u8 *rd, int size)
+{
+	int n, offset, relx, rely;
+	u8 active;
+
+	/*
+	 * The NSG-MRxU multi-touch trackpad data starts at offset 1 and
+	 *   the touch-related data starts at offset 2.
+	 * For the first byte, bit 0 is set when touchpad button is pressed.
+	 * Bit 2 is set when a touch is active and the drag (Fn) key is pressed.
+	 * This drag key is mapped to BTN_LEFT.  It is operational only when a 
+	 *   touch point is active.
+	 * Bit 4 is set when only the first touch point is active.
+	 * Bit 6 is set when only the second touch point is active.
+	 * Bits 5 and 7 are set when both touch points are active.
+	 * The next 3 bytes are two 12 bit X/Y coordinates for the first touch.
+	 * The following byte, offset 5, has the touch width and length.
+	 *   Bits 0-4=X (width), bits 5-7=Y (length).
+	 * A signed relative X coordinate is at offset 6.
+	 * The bytes at offset 7-9 are the second touch X/Y coordinates.
+	 * Offset 10 has the second touch width and length.
+	 * Offset 11 has the relative Y coordinate.
+	 */
+	offset = 1;
+
+	input_report_key(sc->touchpad, BTN_LEFT, rd[offset] & 0x0F);
+	active = (rd[offset] >> 4);
+	relx = (s8) rd[offset+5];
+	rely = ((s8) rd[offset+10]) * -1;
+
+	offset++;
+
+	for (n = 0; n < 2; n++) {
+		u16 x, y;
+		u8 contactx, contacty;
+
+		x = rd[offset] | ((rd[offset+1] & 0x0F) << 8);
+		y = ((rd[offset+1] & 0xF0) >> 4) | (rd[offset+2] << 4);
+
+		input_mt_slot(sc->touchpad, n);
+		input_mt_report_slot_state(sc->touchpad, MT_TOOL_FINGER, active & 0x03);
+
+		if (active & 0x03) {
+			contactx = rd[offset+3] & 0x0F;
+			contacty = rd[offset+3] >> 4;
+			input_report_abs(sc->touchpad, ABS_MT_TOUCH_MAJOR,
+				max(contactx, contacty));
+			input_report_abs(sc->touchpad, ABS_MT_TOUCH_MINOR,
+				min(contactx, contacty));
+			input_report_abs(sc->touchpad, ABS_MT_ORIENTATION,
+				(bool) (contactx > contacty));
+			input_report_abs(sc->touchpad, ABS_MT_POSITION_X, x);
+			input_report_abs(sc->touchpad, ABS_MT_POSITION_Y,
+				NSG_MRXU_MAX_Y - y);
+			/*
+			 * The relative coordinates belong to the first touch
+			 * point, when present, or to the second touch point
+			 * when the first is not active.
+			 */
+			if ((n == 0) || ((n == 1) && (active & 0x01))) {
+				input_report_rel(sc->touchpad, REL_X, relx);
+				input_report_rel(sc->touchpad, REL_Y, rely);
+			}
+		}
+
+		offset += 5;
+		active >>= 2;
+	}
+
+	input_mt_sync_frame(sc->touchpad);
+
+	input_sync(sc->touchpad);
+}
+
 static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
 		u8 *rd, int size)
 {
@@ -1206,6 +1286,10 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
 		}
 
 		dualshock4_parse_report(sc, rd, size);
+
+	} else if ((sc->quirks & NSG_MRXU_REMOTE) && rd[0] == 0x02) {
+		nsg_mrxu_parse_report(sc, rd, size);
+		return 1;
 	}
 
 	if (sc->defer_initialization) {
@@ -1263,7 +1347,7 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
 }
 
 static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
-					int w, int h)
+		int w, int h, int touch_major, int touch_minor, int orientation)
 {
 	size_t name_sz;
 	char *name;
@@ -1294,10 +1378,6 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
 	snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name);
 	sc->touchpad->name = name;
 
-	ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER);
-	if (ret < 0)
-		goto err;
-
 	/* We map the button underneath the touchpad to BTN_LEFT. */
 	__set_bit(EV_KEY, sc->touchpad->evbit);
 	__set_bit(BTN_LEFT, sc->touchpad->keybit);
@@ -1306,6 +1386,25 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
 	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0);
 	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0);
 
+	if (touch_major > 0) {
+		input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR, 
+			0, touch_major, 0, 0);
+		if (touch_minor > 0)
+			input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR, 
+				0, touch_minor, 0, 0);
+		if (orientation > 0)
+			input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION, 
+				0, orientation, 0, 0);
+	}
+
+	if (sc->quirks & NSG_MRXU_REMOTE) {
+		__set_bit(EV_REL, sc->touchpad->evbit);
+	}
+
+	ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER);
+	if (ret < 0)
+		goto err;
+
 	ret = input_register_device(sc->touchpad);
 	if (ret < 0)
 		goto err;
@@ -2690,7 +2789,7 @@ static int sony_input_configured(struct hid_device *hdev,
 		 * The Dualshock 4 touchpad supports 2 touches and has a
 		 * resolution of 1920x942 (44.86 dots/mm).
 		 */
-		ret = sony_register_touchpad(sc, 2, 1920, 942);
+		ret = sony_register_touchpad(sc, 2, 1920, 942, 0, 0, 0);
 		if (ret) {
 			hid_err(sc->hdev,
 			"Unable to initialize multi-touch slots: %d\n",
@@ -2721,6 +2820,20 @@ static int sony_input_configured(struct hid_device *hdev,
 		}
 
 		sony_init_output_report(sc, dualshock4_send_output_report);
+	} else if (sc->quirks & NSG_MRXU_REMOTE) {
+		/*
+		 * The NSG-MRxU touchpad supports 2 touches and has a
+		 * resolution of 1667x1868
+		 */
+		ret = sony_register_touchpad(sc, 2,
+			NSG_MRXU_MAX_X, NSG_MRXU_MAX_Y, 15, 15, 1);
+		if (ret) {
+			hid_err(sc->hdev,
+			"Unable to initialize multi-touch slots: %d\n",
+			ret);
+			goto err_stop;
+		}
+
 	} else if (sc->quirks & MOTION_CONTROLLER) {
 		sony_init_output_report(sc, motion_send_output_report);
 	} else {
@@ -2969,6 +3082,12 @@ static const struct hid_device_id sony_devices[] = {
 	/* Nyko Core Controller for PS3 */
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER),
 		.driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER },
+	/* SMK-Link NSG-MR5U Remote Control */
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE),
+		.driver_data = NSG_MR5U_REMOTE_BT },
+	/* SMK-Link NSG-MR7U Remote Control */
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE),
+		.driver_data = NSG_MR7U_REMOTE_BT },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, sony_devices);
diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c
index e3e6e5c..56b196d 100644
--- a/drivers/hid/hid-uclogic.c
+++ b/drivers/hid/hid-uclogic.c
@@ -946,7 +946,6 @@ static int uclogic_probe(struct hid_device *hdev,
 	 * than the pen, so use QUIRK_MULTI_INPUT for all tablets.
 	 */
 	hdev->quirks |= HID_QUIRK_MULTI_INPUT;
-	hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
 
 	/* Allocate and assign driver data */
 	drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 7230243..97689e9 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -144,10 +144,10 @@ struct i2c_hid {
 						   * register of the HID
 						   * descriptor. */
 	unsigned int		bufsize;	/* i2c buffer size */
-	char			*inbuf;		/* Input buffer */
-	char			*rawbuf;	/* Raw Input buffer */
-	char			*cmdbuf;	/* Command buffer */
-	char			*argsbuf;	/* Command arguments buffer */
+	u8			*inbuf;		/* Input buffer */
+	u8			*rawbuf;	/* Raw Input buffer */
+	u8			*cmdbuf;	/* Command buffer */
+	u8			*argsbuf;	/* Command arguments buffer */
 
 	unsigned long		flags;		/* device flags */
 	unsigned long		quirks;		/* Various quirks */
@@ -455,7 +455,8 @@ static int i2c_hid_hwreset(struct i2c_client *client)
 
 static void i2c_hid_get_input(struct i2c_hid *ihid)
 {
-	int ret, ret_size;
+	int ret;
+	u32 ret_size;
 	int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
 
 	if (size > ihid->bufsize)
@@ -480,7 +481,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
 		return;
 	}
 
-	if (ret_size > size) {
+	if ((ret_size > size) || (ret_size <= 2)) {
 		dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
 			__func__, size, ret_size);
 		return;
@@ -891,10 +892,10 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
 
 static void i2c_hid_acpi_fix_up_power(struct device *dev)
 {
-	acpi_handle handle = ACPI_HANDLE(dev);
 	struct acpi_device *adev;
 
-	if (handle && acpi_bus_get_device(handle, &adev) == 0)
+	adev = ACPI_COMPANION(dev);
+	if (adev)
 		acpi_device_fix_up_power(adev);
 }
 
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 4e0e7ba..3c55073 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -496,12 +496,12 @@ static int uhid_dev_create2(struct uhid_device *uhid,
 		goto err_free;
 	}
 
-	len = min(sizeof(hid->name), sizeof(ev->u.create2.name)) - 1;
-	strncpy(hid->name, ev->u.create2.name, len);
-	len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)) - 1;
-	strncpy(hid->phys, ev->u.create2.phys, len);
-	len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)) - 1;
-	strncpy(hid->uniq, ev->u.create2.uniq, len);
+	len = min(sizeof(hid->name), sizeof(ev->u.create2.name));
+	strlcpy(hid->name, ev->u.create2.name, len);
+	len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys));
+	strlcpy(hid->phys, ev->u.create2.phys, len);
+	len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq));
+	strlcpy(hid->uniq, ev->u.create2.uniq, len);
 
 	hid->ll_driver = &uhid_hid_driver;
 	hid->bus = ev->u.create2.bus;
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 77c50cd..af0e0d0 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -56,6 +56,10 @@ static unsigned int hid_jspoll_interval;
 module_param_named(jspoll, hid_jspoll_interval, uint, 0644);
 MODULE_PARM_DESC(jspoll, "Polling interval of joysticks");
 
+static unsigned int hid_kbpoll_interval;
+module_param_named(kbpoll, hid_kbpoll_interval, uint, 0644);
+MODULE_PARM_DESC(kbpoll, "Polling interval of keyboards");
+
 static unsigned int ignoreled;
 module_param_named(ignoreled, ignoreled, uint, 0644);
 MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
@@ -1094,7 +1098,9 @@ static int usbhid_start(struct hid_device *hid)
 				hid->name, endpoint->bInterval, interval);
 		}
 
-		/* Change the polling interval of mice and joysticks. */
+		/* Change the polling interval of mice, joysticks
+		 * and keyboards.
+		 */
 		switch (hid->collection->usage) {
 		case HID_GD_MOUSE:
 			if (hid_mousepoll_interval > 0)
@@ -1104,6 +1110,10 @@ static int usbhid_start(struct hid_device *hid)
 			if (hid_jspoll_interval > 0)
 				interval = hid_jspoll_interval;
 			break;
+		case HID_GD_KEYBOARD:
+			if (hid_kbpoll_interval > 0)
+				interval = hid_kbpoll_interval;
+			break;
 		}
 
 		ret = -ENOMEM;
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 4095431..b54ef1f 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -219,7 +219,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 	unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
 	u8 *data;
 	int ret;
-	int n;
+	u32 n;
 
 	switch (equivalent_usage) {
 	case HID_DG_CONTACTMAX:
@@ -519,7 +519,7 @@ static int wacom_set_device_mode(struct hid_device *hdev,
 	u8 *rep_data;
 	struct hid_report *r;
 	struct hid_report_enum *re;
-	int length;
+	u32 length;
 	int error = -ENOMEM, limit = 0;
 
 	if (wacom_wac->mode_report < 0)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 90c38a0..6da16a8 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1202,15 +1202,24 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
 
 static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
 {
-	const int pen_frame_len = 14;
-	const int pen_frames = 7;
+	int pen_frame_len, pen_frames;
 
 	struct input_dev *pen_input = wacom->pen_input;
 	unsigned char *data = wacom->data;
 	int i;
 
-	wacom->serial[0] = get_unaligned_le64(&data[99]);
-	wacom->id[0]     = get_unaligned_le16(&data[107]);
+	if (wacom->features.type == INTUOSP2_BT) {
+		wacom->serial[0] = get_unaligned_le64(&data[99]);
+		wacom->id[0]     = get_unaligned_le16(&data[107]);
+		pen_frame_len = 14;
+		pen_frames = 7;
+	} else {
+		wacom->serial[0] = get_unaligned_le64(&data[33]);
+		wacom->id[0]     = get_unaligned_le16(&data[41]);
+		pen_frame_len = 8;
+		pen_frames = 4;
+	}
+
 	if (wacom->serial[0] >> 52 == 1) {
 		/* Add back in missing bits of ID for non-USI pens */
 		wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF;
@@ -1227,21 +1236,35 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
 			continue;
 
 		if (range) {
-			/* Fix rotation alignment: userspace expects zero at left */
-			int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]);
-			rotation += 1800/4;
-			if (rotation > 899)
-				rotation -= 1800;
-
 			input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1]));
 			input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3]));
-			input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]);
-			input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]);
-			input_report_abs(pen_input, ABS_Z, rotation);
-			input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11]));
+
+			if (wacom->features.type == INTUOSP2_BT) {
+				/* Fix rotation alignment: userspace expects zero at left */
+				int16_t rotation =
+					(int16_t)get_unaligned_le16(&frame[9]);
+				rotation += 1800/4;
+
+				if (rotation > 899)
+					rotation -= 1800;
+
+				input_report_abs(pen_input, ABS_TILT_X,
+						 (char)frame[7]);
+				input_report_abs(pen_input, ABS_TILT_Y,
+						 (char)frame[8]);
+				input_report_abs(pen_input, ABS_Z, rotation);
+				input_report_abs(pen_input, ABS_WHEEL,
+						 get_unaligned_le16(&frame[11]));
+			}
 		}
 		input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));
-		input_report_abs(pen_input, ABS_DISTANCE, range ? frame[13] : wacom->features.distance_max);
+		if (wacom->features.type == INTUOSP2_BT) {
+			input_report_abs(pen_input, ABS_DISTANCE,
+					 range ? frame[13] : wacom->features.distance_max);
+		} else {
+			input_report_abs(pen_input, ABS_DISTANCE,
+					 range ? frame[7] : wacom->features.distance_max);
+		}
 
 		input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x01);
 		input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02);
@@ -1357,20 +1380,52 @@ static void wacom_intuos_pro2_bt_battery(struct wacom_wac *wacom)
 			     battery_status, chg, 1, chg);
 }
 
+static void wacom_intuos_gen3_bt_pad(struct wacom_wac *wacom)
+{
+	struct input_dev *pad_input = wacom->pad_input;
+	unsigned char *data = wacom->data;
+
+	int buttons = data[44];
+
+	wacom_report_numbered_buttons(pad_input, 4, buttons);
+
+	input_report_key(pad_input, wacom->tool[1], buttons ? 1 : 0);
+	input_report_abs(pad_input, ABS_MISC, buttons ? PAD_DEVICE_ID : 0);
+	input_event(pad_input, EV_MSC, MSC_SERIAL, 0xffffffff);
+
+	input_sync(pad_input);
+}
+
+static void wacom_intuos_gen3_bt_battery(struct wacom_wac *wacom)
+{
+	unsigned char *data = wacom->data;
+
+	bool chg = data[45] & 0x80;
+	int battery_status = data[45] & 0x7F;
+
+	wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,
+			     battery_status, chg, 1, chg);
+}
+
 static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len)
 {
 	unsigned char *data = wacom->data;
 
-	if (data[0] != 0x80) {
+	if (data[0] != 0x80 && data[0] != 0x81) {
 		dev_dbg(wacom->pen_input->dev.parent,
 			"%s: received unknown report #%d\n", __func__, data[0]);
 		return 0;
 	}
 
 	wacom_intuos_pro2_bt_pen(wacom);
-	wacom_intuos_pro2_bt_touch(wacom);
-	wacom_intuos_pro2_bt_pad(wacom);
-	wacom_intuos_pro2_bt_battery(wacom);
+	if (wacom->features.type == INTUOSP2_BT) {
+		wacom_intuos_pro2_bt_touch(wacom);
+		wacom_intuos_pro2_bt_pad(wacom);
+		wacom_intuos_pro2_bt_battery(wacom);
+	} else {
+		wacom_intuos_gen3_bt_pad(wacom);
+		wacom_intuos_gen3_bt_battery(wacom);
+	}
 	return 0;
 }
 
@@ -1660,7 +1715,8 @@ int wacom_equivalent_usage(int usage)
 		    usage == WACOM_HID_WD_TOUCHSTRIP ||
 		    usage == WACOM_HID_WD_TOUCHSTRIP2 ||
 		    usage == WACOM_HID_WD_TOUCHRING ||
-		    usage == WACOM_HID_WD_TOUCHRINGSTATUS) {
+		    usage == WACOM_HID_WD_TOUCHRINGSTATUS ||
+		    usage == WACOM_HID_WD_REPORT_VALID) {
 			return usage;
 		}
 
@@ -2017,7 +2073,7 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev,
 }
 
 static void wacom_wac_pad_report(struct hid_device *hdev,
-		struct hid_report *report)
+		struct hid_report *report, struct hid_field *field)
 {
 	struct wacom *wacom = hid_get_drvdata(hdev);
 	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
@@ -2025,7 +2081,7 @@ static void wacom_wac_pad_report(struct hid_device *hdev,
 	bool active = wacom_wac->hid_data.inrange_state != 0;
 
 	/* report prox for expresskey events */
-	if ((wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY) &&
+	if ((wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) &&
 	    wacom_wac->hid_data.pad_input_event_flag) {
 		input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0);
 		input_sync(input);
@@ -2144,6 +2200,9 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
 	struct input_dev *input = wacom_wac->pen_input;
 	unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
 
+	if (wacom_wac->is_invalid_bt_frame)
+		return;
+
 	switch (equivalent_usage) {
 	case HID_GD_Z:
 		/*
@@ -2240,6 +2299,9 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
 				 features->offset_bottom);
 		features->offset_bottom = value;
 		return;
+	case WACOM_HID_WD_REPORT_VALID:
+		wacom_wac->is_invalid_bt_frame = !value;
+		return;
 	}
 
 	/* send pen events only when touch is up or forced out
@@ -2258,6 +2320,10 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
 static void wacom_wac_pen_pre_report(struct hid_device *hdev,
 		struct hid_report *report)
 {
+	struct wacom *wacom = hid_get_drvdata(hdev);
+	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+
+	wacom_wac->is_invalid_bt_frame = false;
 	return;
 }
 
@@ -2270,6 +2336,9 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
 	bool range = wacom_wac->hid_data.inrange_state;
 	bool sense = wacom_wac->hid_data.sense_state;
 
+	if (wacom_wac->is_invalid_bt_frame)
+		return;
+
 	if (!wacom_wac->tool[0] && range) { /* first in range */
 		/* Going into range select tool */
 		if (wacom_wac->hid_data.invert_state)
@@ -2572,11 +2641,13 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
 		wacom_wac_finger_event(hdev, field, usage, value);
 }
 
-static void wacom_report_events(struct hid_device *hdev, struct hid_report *report)
+static void wacom_report_events(struct hid_device *hdev,
+				struct hid_report *report, int collection_index,
+				int field_index)
 {
 	int r;
 
-	for (r = 0; r < report->maxfield; r++) {
+	for (r = field_index; r < report->maxfield; r++) {
 		struct hid_field *field;
 		unsigned count, n;
 
@@ -2586,30 +2657,23 @@ static void wacom_report_events(struct hid_device *hdev, struct hid_report *repo
 		if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
 			continue;
 
-		for (n = 0; n < count; n++)
-			wacom_wac_event(hdev, field, &field->usage[n], field->value[n]);
+		for (n = 0 ; n < count; n++) {
+			if (field->usage[n].collection_index == collection_index)
+				wacom_wac_event(hdev, field, &field->usage[n],
+						field->value[n]);
+			else
+				return;
+		}
 	}
 }
 
-void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
+static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report,
+			 int collection_index, struct hid_field *field,
+			 int field_index)
 {
 	struct wacom *wacom = hid_get_drvdata(hdev);
-	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
-	struct hid_field *field = report->field[0];
 
-	if (wacom_wac->features.type != HID_GENERIC)
-		return;
-
-	wacom_wac_battery_pre_report(hdev, report);
-
-	if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input)
-		wacom_wac_pad_pre_report(hdev, report);
-	else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
-		wacom_wac_pen_pre_report(hdev, report);
-	else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
-		wacom_wac_finger_pre_report(hdev, report);
-
-	wacom_report_events(hdev, report);
+	wacom_report_events(hdev, report, collection_index, field_index);
 
 	/*
 	 * Non-input reports may be sent prior to the device being
@@ -2619,16 +2683,63 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
 	 * processing functions.
 	 */
 	if (report->type != HID_INPUT_REPORT)
-		return;
-
-	wacom_wac_battery_report(hdev, report);
+		return -1;
 
 	if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input)
-		wacom_wac_pad_report(hdev, report);
+		wacom_wac_pad_report(hdev, report, field);
 	else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
 		wacom_wac_pen_report(hdev, report);
 	else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
 		wacom_wac_finger_report(hdev, report);
+
+	return 0;
+}
+
+void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
+{
+	struct wacom *wacom = hid_get_drvdata(hdev);
+	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+	struct hid_field *field;
+	bool pad_in_hid_field = false, pen_in_hid_field = false,
+		finger_in_hid_field = false;
+	int r;
+	int prev_collection = -1;
+
+	if (wacom_wac->features.type != HID_GENERIC)
+		return;
+
+	for (r = 0; r < report->maxfield; r++) {
+		field = report->field[r];
+
+		if (WACOM_PAD_FIELD(field))
+			pad_in_hid_field = true;
+		if (WACOM_PEN_FIELD(field))
+			pen_in_hid_field = true;
+		if (WACOM_FINGER_FIELD(field))
+			finger_in_hid_field = true;
+	}
+
+	wacom_wac_battery_pre_report(hdev, report);
+
+	if (pad_in_hid_field && wacom->wacom_wac.pad_input)
+		wacom_wac_pad_pre_report(hdev, report);
+	if (pen_in_hid_field && wacom->wacom_wac.pen_input)
+		wacom_wac_pen_pre_report(hdev, report);
+	if (finger_in_hid_field && wacom->wacom_wac.touch_input)
+		wacom_wac_finger_pre_report(hdev, report);
+
+	for (r = 0; r < report->maxfield; r++) {
+		field = report->field[r];
+
+		if (field->usage[0].collection_index != prev_collection) {
+			if (wacom_wac_collection(hdev, report,
+				field->usage[0].collection_index, field, r) < 0)
+				return;
+			prev_collection = field->usage[0].collection_index;
+		}
+	}
+
+	wacom_wac_battery_report(hdev, report);
 }
 
 static int wacom_bpt_touch(struct wacom_wac *wacom)
@@ -3093,6 +3204,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
 		break;
 
 	case INTUOSP2_BT:
+	case INTUOSHT3_BT:
 		sync = wacom_intuos_pro2_bt_irq(wacom_wac, len);
 		break;
 
@@ -3272,6 +3384,12 @@ void wacom_setup_device_quirks(struct wacom *wacom)
 		features->quirks |= WACOM_QUIRK_BATTERY;
 	}
 
+	if (features->type == INTUOSHT3_BT) {
+		features->device_type |= WACOM_DEVICETYPE_PEN |
+					 WACOM_DEVICETYPE_PAD;
+		features->quirks |= WACOM_QUIRK_BATTERY;
+	}
+
 	switch (features->type) {
 	case PL:
 	case DTU:
@@ -3466,7 +3584,9 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
 	case BAMBOO_PT:
 	case BAMBOO_PEN:
 	case INTUOSHT2:
-		if (features->type == INTUOSHT2) {
+	case INTUOSHT3_BT:
+		if (features->type == INTUOSHT2 ||
+		    features->type == INTUOSHT3_BT) {
 			wacom_setup_basic_pro_pen(wacom_wac);
 		} else {
 			__clear_bit(ABS_MISC, input_dev->absbit);
@@ -3887,6 +4007,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
 		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
 		break;
 
+	case INTUOSHT3_BT:
 	case HID_GENERIC:
 		break;
 
@@ -4415,6 +4536,12 @@ static const struct wacom_features wacom_features_0x360 =
 static const struct wacom_features wacom_features_0x361 =
 	{ "Wacom Intuos Pro L", 62200, 43200, 8191, 63,
 	  INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 };
+static const struct wacom_features wacom_features_0x377 =
+	{ "Wacom Intuos BT S", 15200, 9500, 4095, 63,
+	  INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };
+static const struct wacom_features wacom_features_0x379 =
+	{ "Wacom Intuos BT M", 21600, 13500, 4095, 63,
+	  INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };
 static const struct wacom_features wacom_features_0x37A =
 	{ "Wacom One by Wacom S", 15200, 9500, 2047, 63,
 	  BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -4589,6 +4716,8 @@ const struct hid_device_id wacom_ids[] = {
 	{ USB_DEVICE_WACOM(0x343) },
 	{ BT_DEVICE_WACOM(0x360) },
 	{ BT_DEVICE_WACOM(0x361) },
+	{ BT_DEVICE_WACOM(0x377) },
+	{ BT_DEVICE_WACOM(0x379) },
 	{ USB_DEVICE_WACOM(0x37A) },
 	{ USB_DEVICE_WACOM(0x37B) },
 	{ USB_DEVICE_WACOM(0x4001) },
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 15d9c14..295fd37 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -118,6 +118,7 @@
 #define WACOM_HID_WD_TOUCHSTRIP2        (WACOM_HID_UP_WACOMDIGITIZER | 0x0137)
 #define WACOM_HID_WD_TOUCHRING          (WACOM_HID_UP_WACOMDIGITIZER | 0x0138)
 #define WACOM_HID_WD_TOUCHRINGSTATUS    (WACOM_HID_UP_WACOMDIGITIZER | 0x0139)
+#define WACOM_HID_WD_REPORT_VALID       (WACOM_HID_UP_WACOMDIGITIZER | 0x01d0)
 #define WACOM_HID_WD_ACCELEROMETER_X    (WACOM_HID_UP_WACOMDIGITIZER | 0x0401)
 #define WACOM_HID_WD_ACCELEROMETER_Y    (WACOM_HID_UP_WACOMDIGITIZER | 0x0402)
 #define WACOM_HID_WD_ACCELEROMETER_Z    (WACOM_HID_UP_WACOMDIGITIZER | 0x0403)
@@ -213,6 +214,7 @@ enum {
 	INTUOSPM,
 	INTUOSPL,
 	INTUOSP2_BT,
+	INTUOSHT3_BT,
 	WACOM_21UX2,
 	WACOM_22HD,
 	DTK,
@@ -352,7 +354,7 @@ struct wacom_wac {
 	bool has_mute_touch_switch;
 	bool has_mode_change;
 	bool is_direct_mode;
-
+	bool is_invalid_bt_frame;
 };
 
 #endif
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index ef23553..033e573 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -317,6 +317,18 @@
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
+config SENSORS_ARM_SCMI
+	tristate "ARM SCMI Sensors"
+	depends on ARM_SCMI_PROTOCOL
+	depends on THERMAL || !THERMAL_OF
+	help
+	  This driver provides support for temperature, voltage, current
+	  and power sensors available on SCMI based platforms. The actual
+	  number and type of sensors exported depend on the platform.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called scmi-hwmon.
+
 config SENSORS_ARM_SCPI
 	tristate "ARM SCPI Sensors"
 	depends on ARM_SCPI_PROTOCOL
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index f814b4a..e7d52a3 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -46,6 +46,7 @@
 obj-$(CONFIG_SENSORS_ADT7470)	+= adt7470.o
 obj-$(CONFIG_SENSORS_ADT7475)	+= adt7475.o
 obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
+obj-$(CONFIG_SENSORS_ARM_SCMI)	+= scmi-hwmon.o
 obj-$(CONFIG_SENSORS_ARM_SCPI)	+= scpi-hwmon.o
 obj-$(CONFIG_SENSORS_ASC7621)	+= asc7621.o
 obj-$(CONFIG_SENSORS_ASPEED)	+= aspeed-pwm-tacho.o
diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
new file mode 100644
index 0000000..363bf56
--- /dev/null
+++ b/drivers/hwmon/scmi-hwmon.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface(SCMI) based hwmon sensor driver
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ * Sudeep Holla <sudeep.holla@arm.com>
+ */
+
+#include <linux/hwmon.h>
+#include <linux/module.h>
+#include <linux/scmi_protocol.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/thermal.h>
+
+struct scmi_sensors {
+	const struct scmi_handle *handle;
+	const struct scmi_sensor_info **info[hwmon_max];
+};
+
+static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+			   u32 attr, int channel, long *val)
+{
+	int ret;
+	u64 value;
+	const struct scmi_sensor_info *sensor;
+	struct scmi_sensors *scmi_sensors = dev_get_drvdata(dev);
+	const struct scmi_handle *h = scmi_sensors->handle;
+
+	sensor = *(scmi_sensors->info[type] + channel);
+	ret = h->sensor_ops->reading_get(h, sensor->id, false, &value);
+	if (!ret)
+		*val = value;
+
+	return ret;
+}
+
+static int
+scmi_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
+		       u32 attr, int channel, const char **str)
+{
+	const struct scmi_sensor_info *sensor;
+	struct scmi_sensors *scmi_sensors = dev_get_drvdata(dev);
+
+	sensor = *(scmi_sensors->info[type] + channel);
+	*str = sensor->name;
+
+	return 0;
+}
+
+static umode_t
+scmi_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
+		      u32 attr, int channel)
+{
+	const struct scmi_sensor_info *sensor;
+	const struct scmi_sensors *scmi_sensors = drvdata;
+
+	sensor = *(scmi_sensors->info[type] + channel);
+	if (sensor && sensor->name)
+		return S_IRUGO;
+
+	return 0;
+}
+
+static const struct hwmon_ops scmi_hwmon_ops = {
+	.is_visible = scmi_hwmon_is_visible,
+	.read = scmi_hwmon_read,
+	.read_string = scmi_hwmon_read_string,
+};
+
+static struct hwmon_chip_info scmi_chip_info = {
+	.ops = &scmi_hwmon_ops,
+	.info = NULL,
+};
+
+static int scmi_hwmon_add_chan_info(struct hwmon_channel_info *scmi_hwmon_chan,
+				    struct device *dev, int num,
+				    enum hwmon_sensor_types type, u32 config)
+{
+	int i;
+	u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL);
+
+	if (!cfg)
+		return -ENOMEM;
+
+	scmi_hwmon_chan->type = type;
+	scmi_hwmon_chan->config = cfg;
+	for (i = 0; i < num; i++, cfg++)
+		*cfg = config;
+
+	return 0;
+}
+
+static enum hwmon_sensor_types scmi_types[] = {
+	[TEMPERATURE_C] = hwmon_temp,
+	[VOLTAGE] = hwmon_in,
+	[CURRENT] = hwmon_curr,
+	[POWER] = hwmon_power,
+	[ENERGY] = hwmon_energy,
+};
+
+static u32 hwmon_attributes[] = {
+	[hwmon_chip] = HWMON_C_REGISTER_TZ,
+	[hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL,
+	[hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL,
+	[hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL,
+	[hwmon_power] = HWMON_P_INPUT | HWMON_P_LABEL,
+	[hwmon_energy] = HWMON_E_INPUT | HWMON_E_LABEL,
+};
+
+static int scmi_hwmon_probe(struct scmi_device *sdev)
+{
+	int i, idx;
+	u16 nr_sensors;
+	enum hwmon_sensor_types type;
+	struct scmi_sensors *scmi_sensors;
+	const struct scmi_sensor_info *sensor;
+	int nr_count[hwmon_max] = {0}, nr_types = 0;
+	const struct hwmon_chip_info *chip_info;
+	struct device *hwdev, *dev = &sdev->dev;
+	struct hwmon_channel_info *scmi_hwmon_chan;
+	const struct hwmon_channel_info **ptr_scmi_ci;
+	const struct scmi_handle *handle = sdev->handle;
+
+	if (!handle || !handle->sensor_ops)
+		return -ENODEV;
+
+	nr_sensors = handle->sensor_ops->count_get(handle);
+	if (!nr_sensors)
+		return -EIO;
+
+	scmi_sensors = devm_kzalloc(dev, sizeof(*scmi_sensors), GFP_KERNEL);
+	if (!scmi_sensors)
+		return -ENOMEM;
+
+	scmi_sensors->handle = handle;
+
+	for (i = 0; i < nr_sensors; i++) {
+		sensor = handle->sensor_ops->info_get(handle, i);
+		if (!sensor)
+			return -EINVAL;
+
+		switch (sensor->type) {
+		case TEMPERATURE_C:
+		case VOLTAGE:
+		case CURRENT:
+		case POWER:
+		case ENERGY:
+			type = scmi_types[sensor->type];
+			if (!nr_count[type])
+				nr_types++;
+			nr_count[type]++;
+			break;
+		}
+	}
+
+	if (nr_count[hwmon_temp])
+		nr_count[hwmon_chip]++, nr_types++;
+
+	scmi_hwmon_chan = devm_kcalloc(dev, nr_types, sizeof(*scmi_hwmon_chan),
+				       GFP_KERNEL);
+	if (!scmi_hwmon_chan)
+		return -ENOMEM;
+
+	ptr_scmi_ci = devm_kcalloc(dev, nr_types + 1, sizeof(*ptr_scmi_ci),
+				   GFP_KERNEL);
+	if (!ptr_scmi_ci)
+		return -ENOMEM;
+
+	scmi_chip_info.info = ptr_scmi_ci;
+	chip_info = &scmi_chip_info;
+
+	for (type = 0; type < hwmon_max && nr_count[type]; type++) {
+		scmi_hwmon_add_chan_info(scmi_hwmon_chan, dev, nr_count[type],
+					 type, hwmon_attributes[type]);
+		*ptr_scmi_ci++ = scmi_hwmon_chan++;
+
+		scmi_sensors->info[type] =
+			devm_kcalloc(dev, nr_count[type],
+				     sizeof(*scmi_sensors->info), GFP_KERNEL);
+		if (!scmi_sensors->info[type])
+			return -ENOMEM;
+	}
+
+	for (i = nr_sensors - 1; i >= 0 ; i--) {
+		sensor = handle->sensor_ops->info_get(handle, i);
+		if (!sensor)
+			continue;
+
+		switch (sensor->type) {
+		case TEMPERATURE_C:
+		case VOLTAGE:
+		case CURRENT:
+		case POWER:
+		case ENERGY:
+			type = scmi_types[sensor->type];
+			idx = --nr_count[type];
+			*(scmi_sensors->info[type] + idx) = sensor;
+			break;
+		}
+	}
+
+	hwdev = devm_hwmon_device_register_with_info(dev, "scmi_sensors",
+						     scmi_sensors, chip_info,
+						     NULL);
+
+	return PTR_ERR_OR_ZERO(hwdev);
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+	{ SCMI_PROTOCOL_SENSOR },
+	{ },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_hwmon_drv = {
+	.name		= "scmi-hwmon",
+	.probe		= scmi_hwmon_probe,
+	.id_table	= scmi_id_table,
+};
+module_scmi_driver(scmi_hwmon_drv);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCMI HWMON interface driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 7c3ed7c..5a8e8e3 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -712,7 +712,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
 	struct request_queue *q = drive->queue;
 	int write = rq_data_dir(rq) == WRITE;
 	unsigned short sectors_per_frame =
-		queue_logical_block_size(q) >> SECTOR_BITS;
+		queue_logical_block_size(q) >> SECTOR_SHIFT;
 
 	ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
 				  "secs_per_frame: %u",
@@ -919,7 +919,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
 	 * end up being bogus.
 	 */
 	blocklen = be32_to_cpu(capbuf.blocklen);
-	blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS;
+	blocklen = (blocklen >> SECTOR_SHIFT) << SECTOR_SHIFT;
 	switch (blocklen) {
 	case 512:
 	case 1024:
@@ -935,7 +935,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
 	}
 
 	*capacity = 1 + be32_to_cpu(capbuf.lba);
-	*sectors_per_frame = blocklen >> SECTOR_BITS;
+	*sectors_per_frame = blocklen >> SECTOR_SHIFT;
 
 	ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu",
 				     *capacity, *sectors_per_frame);
@@ -1012,7 +1012,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
 	drive->probed_capacity = toc->capacity * sectors_per_frame;
 
 	blk_queue_logical_block_size(drive->queue,
-				     sectors_per_frame << SECTOR_BITS);
+				     sectors_per_frame << SECTOR_SHIFT);
 
 	/* first read just the header, so we know how long the TOC is */
 	stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
@@ -1613,6 +1613,8 @@ static int idecd_open(struct block_device *bdev, fmode_t mode)
 	struct cdrom_info *info;
 	int rc = -ENXIO;
 
+	check_disk_change(bdev);
+
 	mutex_lock(&ide_cd_mutex);
 	info = ide_cd_get(bdev->bd_disk);
 	if (!info)
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 264e822..04f0f31 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -21,11 +21,7 @@
 
 /************************************************************************/
 
-#define SECTOR_BITS 		9
-#ifndef SECTOR_SIZE
-#define SECTOR_SIZE		(1 << SECTOR_BITS)
-#endif
-#define SECTORS_PER_FRAME	(CD_FRAMESIZE >> SECTOR_BITS)
+#define SECTORS_PER_FRAME	(CD_FRAMESIZE >> SECTOR_SHIFT)
 #define SECTOR_BUFFER_SIZE	(CD_FRAMESIZE * 32)
 
 /* Capabilities Page size including 8 bytes of Mode Page Header */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 67bc72d..f1a7c58 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -687,8 +687,8 @@ static void ide_disk_setup(ide_drive_t *drive)
 	       queue_max_sectors(q) / 2);
 
 	if (ata_id_is_ssd(id)) {
-		queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
-		queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q);
+		blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
+		blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q);
 	}
 
 	/* calculate drive capacity, and select LBA if possible */
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index caa20eb..2019e66 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -766,14 +766,14 @@ static int ide_init_queue(ide_drive_t *drive)
 	 *	limits and LBA48 we could raise it but as yet
 	 *	do not.
 	 */
-	q = blk_alloc_queue_node(GFP_KERNEL, hwif_to_node(hwif));
+	q = blk_alloc_queue_node(GFP_KERNEL, hwif_to_node(hwif), NULL);
 	if (!q)
 		return 1;
 
 	q->request_fn = do_ide_request;
 	q->initialize_rq_fn = ide_initialize_rq;
 	q->cmd_size = sizeof(struct ide_request);
-	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
+	blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
 	if (blk_init_allocated_queue(q) < 0) {
 		blk_cleanup_queue(q);
 		return 1;
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 914b6f8..15606f2 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -697,7 +697,8 @@
 
 config STX104
 	tristate "Apex Embedded Systems STX104 driver"
-	depends on PC104 && X86 && ISA_BUS_API
+	depends on PC104 && X86
+	select ISA_BUS_API
 	select GPIOLIB
 	help
 	  Say yes here to build support for the Apex Embedded Systems STX104
diff --git a/drivers/iio/counter/Kconfig b/drivers/iio/counter/Kconfig
index 474e1ac..bf1e559 100644
--- a/drivers/iio/counter/Kconfig
+++ b/drivers/iio/counter/Kconfig
@@ -7,7 +7,8 @@
 
 config 104_QUAD_8
 	tristate "ACCES 104-QUAD-8 driver"
-	depends on PC104 && X86 && ISA_BUS_API
+	depends on PC104 && X86
+	select ISA_BUS_API
 	help
 	  Say yes here to build support for the ACCES 104-QUAD-8 quadrature
 	  encoder counter/interface device family (104-QUAD-8, 104-QUAD-4).
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index 965d5c0..76db076 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -195,7 +195,8 @@
 
 config CIO_DAC
 	tristate "Measurement Computing CIO-DAC IIO driver"
-	depends on X86 && ISA_BUS_API
+	depends on X86 && (ISA_BUS || PC104)
+	select ISA_BUS_API
 	help
 	  Say yes here to build support for the Measurement Computing CIO-DAC
 	  analog output device family (CIO-DAC16, CIO-DAC08, PC104-DAC06). The
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index f3c2f6e..9591fc0 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -351,4 +351,14 @@
 
 	  To drive rumble motor a dedicated power supply is required.
 
+config JOYSTICK_PXRC
+	tristate "PhoenixRC Flight Controller Adapter"
+	depends on USB_ARCH_HAS_HCD
+	select USB
+	help
+	  Say Y here if you want to use the PhoenixRC Flight Controller Adapter.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pxrc.
+
 endif
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile
index 67651ef..dd0492e 100644
--- a/drivers/input/joystick/Makefile
+++ b/drivers/input/joystick/Makefile
@@ -23,6 +23,7 @@
 obj-$(CONFIG_JOYSTICK_MAGELLAN)		+= magellan.o
 obj-$(CONFIG_JOYSTICK_MAPLE)		+= maplecontrol.o
 obj-$(CONFIG_JOYSTICK_PSXPAD_SPI)	+= psxpad-spi.o
+obj-$(CONFIG_JOYSTICK_PXRC)			+= pxrc.o
 obj-$(CONFIG_JOYSTICK_SIDEWINDER)	+= sidewinder.o
 obj-$(CONFIG_JOYSTICK_SPACEBALL)	+= spaceball.o
 obj-$(CONFIG_JOYSTICK_SPACEORB)		+= spaceorb.o
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index eefac79..c79dbcb 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -163,7 +163,7 @@ static unsigned int get_time_pit(void)
 #define GET_TIME(x)	do { x = (unsigned int)rdtsc(); } while (0)
 #define DELTA(x,y)	((y)-(x))
 #define TIME_NAME	"TSC"
-#elif defined(__alpha__) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
+#elif defined(__alpha__) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_PPC) || defined(CONFIG_RISCV)
 #define GET_TIME(x)	do { x = get_cycles(); } while (0)
 #define DELTA(x,y)	((y)-(x))
 #define TIME_NAME	"get_cycles"
diff --git a/drivers/input/joystick/pxrc.c b/drivers/input/joystick/pxrc.c
new file mode 100644
index 0000000..07a0dbd
--- /dev/null
+++ b/drivers/input/joystick/pxrc.c
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Phoenix RC Flight Controller Adapter
+ *
+ * Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <linux/mutex.h>
+#include <linux/input.h>
+
+#define PXRC_VENDOR_ID	(0x1781)
+#define PXRC_PRODUCT_ID	(0x0898)
+
+static const struct usb_device_id pxrc_table[] = {
+	{ USB_DEVICE(PXRC_VENDOR_ID, PXRC_PRODUCT_ID) },
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, pxrc_table);
+
+struct pxrc {
+	struct input_dev	*input;
+	struct usb_device	*udev;
+	struct usb_interface	*intf;
+	struct urb		*urb;
+	struct mutex		pm_mutex;
+	bool			is_open;
+	__u8			epaddr;
+	char			phys[64];
+	unsigned char           *data;
+	size_t			bsize;
+};
+
+static void pxrc_usb_irq(struct urb *urb)
+{
+	struct pxrc *pxrc = urb->context;
+	int error;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ETIME:
+		/* this urb is timing out */
+		dev_dbg(&pxrc->intf->dev,
+			"%s - urb timed out - was the device unplugged?\n",
+			__func__);
+		return;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+	case -EPIPE:
+		/* this urb is terminated, clean up */
+		dev_dbg(&pxrc->intf->dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
+		return;
+	default:
+		dev_dbg(&pxrc->intf->dev, "%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
+		goto exit;
+	}
+
+	if (urb->actual_length == 8) {
+		input_report_abs(pxrc->input, ABS_X, pxrc->data[0]);
+		input_report_abs(pxrc->input, ABS_Y, pxrc->data[2]);
+		input_report_abs(pxrc->input, ABS_RX, pxrc->data[3]);
+		input_report_abs(pxrc->input, ABS_RY, pxrc->data[4]);
+		input_report_abs(pxrc->input, ABS_RUDDER, pxrc->data[5]);
+		input_report_abs(pxrc->input, ABS_THROTTLE, pxrc->data[6]);
+		input_report_abs(pxrc->input, ABS_MISC, pxrc->data[7]);
+
+		input_report_key(pxrc->input, BTN_A, pxrc->data[1]);
+	}
+
+exit:
+	/* Resubmit to fetch new fresh URBs */
+	error = usb_submit_urb(urb, GFP_ATOMIC);
+	if (error && error != -EPERM)
+		dev_err(&pxrc->intf->dev,
+			"%s - usb_submit_urb failed with result: %d",
+			__func__, error);
+}
+
+static int pxrc_open(struct input_dev *input)
+{
+	struct pxrc *pxrc = input_get_drvdata(input);
+	int retval;
+
+	mutex_lock(&pxrc->pm_mutex);
+	retval = usb_submit_urb(pxrc->urb, GFP_KERNEL);
+	if (retval) {
+		dev_err(&pxrc->intf->dev,
+			"%s - usb_submit_urb failed, error: %d\n",
+			__func__, retval);
+		retval = -EIO;
+		goto out;
+	}
+
+	pxrc->is_open = true;
+
+out:
+	mutex_unlock(&pxrc->pm_mutex);
+	return retval;
+}
+
+static void pxrc_close(struct input_dev *input)
+{
+	struct pxrc *pxrc = input_get_drvdata(input);
+
+	mutex_lock(&pxrc->pm_mutex);
+	usb_kill_urb(pxrc->urb);
+	pxrc->is_open = false;
+	mutex_unlock(&pxrc->pm_mutex);
+}
+
+static int pxrc_usb_init(struct pxrc *pxrc)
+{
+	struct usb_endpoint_descriptor *epirq;
+	unsigned int pipe;
+	int retval;
+
+	/* Set up the endpoint information */
+	/* This device only has an interrupt endpoint */
+	retval = usb_find_common_endpoints(pxrc->intf->cur_altsetting,
+			NULL, NULL, &epirq, NULL);
+	if (retval) {
+		dev_err(&pxrc->intf->dev,
+			"Could not find endpoint\n");
+		goto error;
+	}
+
+	pxrc->bsize = usb_endpoint_maxp(epirq);
+	pxrc->epaddr = epirq->bEndpointAddress;
+	pxrc->data = devm_kmalloc(&pxrc->intf->dev, pxrc->bsize, GFP_KERNEL);
+	if (!pxrc->data) {
+		retval = -ENOMEM;
+		goto error;
+	}
+
+	usb_set_intfdata(pxrc->intf, pxrc);
+	usb_make_path(pxrc->udev, pxrc->phys, sizeof(pxrc->phys));
+	strlcat(pxrc->phys, "/input0", sizeof(pxrc->phys));
+
+	pxrc->urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!pxrc->urb) {
+		retval = -ENOMEM;
+		goto error;
+	}
+
+	pipe = usb_rcvintpipe(pxrc->udev, pxrc->epaddr),
+	usb_fill_int_urb(pxrc->urb, pxrc->udev, pipe, pxrc->data, pxrc->bsize,
+						pxrc_usb_irq, pxrc, 1);
+
+error:
+	return retval;
+
+
+}
+
+static int pxrc_input_init(struct pxrc *pxrc)
+{
+	pxrc->input = devm_input_allocate_device(&pxrc->intf->dev);
+	if (pxrc->input == NULL) {
+		dev_err(&pxrc->intf->dev, "couldn't allocate input device\n");
+		return -ENOMEM;
+	}
+
+	pxrc->input->name = "PXRC Flight Controller Adapter";
+	pxrc->input->phys = pxrc->phys;
+	usb_to_input_id(pxrc->udev, &pxrc->input->id);
+
+	pxrc->input->open = pxrc_open;
+	pxrc->input->close = pxrc_close;
+
+	input_set_capability(pxrc->input, EV_KEY, BTN_A);
+	input_set_abs_params(pxrc->input, ABS_X, 0, 255, 0, 0);
+	input_set_abs_params(pxrc->input, ABS_Y, 0, 255, 0, 0);
+	input_set_abs_params(pxrc->input, ABS_RX, 0, 255, 0, 0);
+	input_set_abs_params(pxrc->input, ABS_RY, 0, 255, 0, 0);
+	input_set_abs_params(pxrc->input, ABS_RUDDER, 0, 255, 0, 0);
+	input_set_abs_params(pxrc->input, ABS_THROTTLE, 0, 255, 0, 0);
+	input_set_abs_params(pxrc->input, ABS_MISC, 0, 255, 0, 0);
+
+	input_set_drvdata(pxrc->input, pxrc);
+
+	return input_register_device(pxrc->input);
+}
+
+static int pxrc_probe(struct usb_interface *intf,
+		      const struct usb_device_id *id)
+{
+	struct pxrc *pxrc;
+	int retval;
+
+	pxrc = devm_kzalloc(&intf->dev, sizeof(*pxrc), GFP_KERNEL);
+	if (!pxrc)
+		return -ENOMEM;
+
+	mutex_init(&pxrc->pm_mutex);
+	pxrc->udev = usb_get_dev(interface_to_usbdev(intf));
+	pxrc->intf = intf;
+
+	retval = pxrc_usb_init(pxrc);
+	if (retval)
+		goto error;
+
+	retval = pxrc_input_init(pxrc);
+	if (retval)
+		goto err_free_urb;
+
+	return 0;
+
+err_free_urb:
+	usb_free_urb(pxrc->urb);
+
+error:
+	return retval;
+}
+
+static void pxrc_disconnect(struct usb_interface *intf)
+{
+	struct pxrc *pxrc = usb_get_intfdata(intf);
+
+	usb_free_urb(pxrc->urb);
+	usb_set_intfdata(intf, NULL);
+}
+
+static int pxrc_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct pxrc *pxrc = usb_get_intfdata(intf);
+
+	mutex_lock(&pxrc->pm_mutex);
+	if (pxrc->is_open)
+		usb_kill_urb(pxrc->urb);
+	mutex_unlock(&pxrc->pm_mutex);
+
+	return 0;
+}
+
+static int pxrc_resume(struct usb_interface *intf)
+{
+	struct pxrc *pxrc = usb_get_intfdata(intf);
+	int retval = 0;
+
+	mutex_lock(&pxrc->pm_mutex);
+	if (pxrc->is_open && usb_submit_urb(pxrc->urb, GFP_KERNEL) < 0)
+		retval = -EIO;
+
+	mutex_unlock(&pxrc->pm_mutex);
+	return retval;
+}
+
+static int pxrc_pre_reset(struct usb_interface *intf)
+{
+	struct pxrc *pxrc = usb_get_intfdata(intf);
+
+	mutex_lock(&pxrc->pm_mutex);
+	usb_kill_urb(pxrc->urb);
+	return 0;
+}
+
+static int pxrc_post_reset(struct usb_interface *intf)
+{
+	struct pxrc *pxrc = usb_get_intfdata(intf);
+	int retval = 0;
+
+	if (pxrc->is_open && usb_submit_urb(pxrc->urb, GFP_KERNEL) < 0)
+		retval = -EIO;
+
+	mutex_unlock(&pxrc->pm_mutex);
+
+	return retval;
+}
+
+static int pxrc_reset_resume(struct usb_interface *intf)
+{
+	return pxrc_resume(intf);
+}
+
+static struct usb_driver pxrc_driver = {
+	.name =		"pxrc",
+	.probe =	pxrc_probe,
+	.disconnect =	pxrc_disconnect,
+	.id_table =	pxrc_table,
+	.suspend	= pxrc_suspend,
+	.resume		= pxrc_resume,
+	.pre_reset	= pxrc_pre_reset,
+	.post_reset	= pxrc_post_reset,
+	.reset_resume	= pxrc_reset_resume,
+};
+
+module_usb_driver(pxrc_driver);
+
+MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
+MODULE_DESCRIPTION("PhoenixRC Flight Controller Adapter");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 9d2688f..06e9650 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -227,6 +227,7 @@ static const struct xpad_device {
 	{ 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
 	{ 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE },
+	{ 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 },
 	{ 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 },
@@ -475,7 +476,8 @@ static const u8 xboxone_hori_init[] = {
 
 /*
  * This packet is required for some of the PDP pads to start
- * sending input reports. One of those pads is (0x0e6f:0x02ab).
+ * sending input reports. These pads include: (0x0e6f:0x02ab),
+ * (0x0e6f:0x02a4).
  */
 static const u8 xboxone_pdp_init1[] = {
 	0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
@@ -483,7 +485,8 @@ static const u8 xboxone_pdp_init1[] = {
 
 /*
  * This packet is required for some of the PDP pads to start
- * sending input reports. One of those pads is (0x0e6f:0x02ab).
+ * sending input reports. These pads include: (0x0e6f:0x02ab),
+ * (0x0e6f:0x02a4).
  */
 static const u8 xboxone_pdp_init2[] = {
 	0x06, 0x20, 0x00, 0x02, 0x01, 0x00
@@ -521,6 +524,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = {
 	XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
 	XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init1),
 	XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init2),
+	XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init1),
+	XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init2),
 	XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
 	XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init),
 	XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init),
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 87e613d..052e376 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -30,6 +30,7 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/spinlock.h>
+#include <dt-bindings/input/gpio-keys.h>
 
 struct gpio_button_data {
 	const struct gpio_keys_button *button;
@@ -45,6 +46,7 @@ struct gpio_button_data {
 	unsigned int software_debounce;	/* in msecs, for GPIO-driven buttons */
 
 	unsigned int irq;
+	unsigned int wakeup_trigger_type;
 	spinlock_t lock;
 	bool disabled;
 	bool key_pressed;
@@ -540,6 +542,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
 	}
 
 	if (bdata->gpiod) {
+		bool active_low = gpiod_is_active_low(bdata->gpiod);
+
 		if (button->debounce_interval) {
 			error = gpiod_set_debounce(bdata->gpiod,
 					button->debounce_interval * 1000);
@@ -568,6 +572,24 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
 		isr = gpio_keys_gpio_isr;
 		irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
 
+		switch (button->wakeup_event_action) {
+		case EV_ACT_ASSERTED:
+			bdata->wakeup_trigger_type = active_low ?
+				IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
+			break;
+		case EV_ACT_DEASSERTED:
+			bdata->wakeup_trigger_type = active_low ?
+				IRQ_TYPE_EDGE_RISING : IRQ_TYPE_EDGE_FALLING;
+			break;
+		case EV_ACT_ANY:
+			/* fall through */
+		default:
+			/*
+			 * For other cases, we are OK letting suspend/resume
+			 * not reconfigure the trigger type.
+			 */
+			break;
+		}
 	} else {
 		if (!button->irq) {
 			dev_err(dev, "Found button without gpio or irq\n");
@@ -586,6 +608,11 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
 
 		isr = gpio_keys_irq_isr;
 		irqflags = 0;
+
+		/*
+		 * For IRQ buttons, there is no interrupt for release.
+		 * So we don't need to reconfigure the trigger type for wakeup.
+		 */
 	}
 
 	bdata->code = &ddata->keymap[idx];
@@ -718,6 +745,9 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 			/* legacy name */
 			fwnode_property_read_bool(child, "gpio-key,wakeup");
 
+		fwnode_property_read_u32(child, "wakeup-event-action",
+					 &button->wakeup_event_action);
+
 		button->can_disable =
 			fwnode_property_read_bool(child, "linux,can-disable");
 
@@ -845,19 +875,112 @@ static int gpio_keys_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int __maybe_unused
+gpio_keys_button_enable_wakeup(struct gpio_button_data *bdata)
+{
+	int error;
+
+	error = enable_irq_wake(bdata->irq);
+	if (error) {
+		dev_err(bdata->input->dev.parent,
+			"failed to configure IRQ %d as wakeup source: %d\n",
+			bdata->irq, error);
+		return error;
+	}
+
+	if (bdata->wakeup_trigger_type) {
+		error = irq_set_irq_type(bdata->irq,
+					 bdata->wakeup_trigger_type);
+		if (error) {
+			dev_err(bdata->input->dev.parent,
+				"failed to set wakeup trigger %08x for IRQ %d: %d\n",
+				bdata->wakeup_trigger_type, bdata->irq, error);
+			disable_irq_wake(bdata->irq);
+			return error;
+		}
+	}
+
+	return 0;
+}
+
+static void __maybe_unused
+gpio_keys_button_disable_wakeup(struct gpio_button_data *bdata)
+{
+	int error;
+
+	/*
+	 * The trigger type is always both edges for gpio-based keys and we do
+	 * not support changing wakeup trigger for interrupt-based keys.
+	 */
+	if (bdata->wakeup_trigger_type) {
+		error = irq_set_irq_type(bdata->irq, IRQ_TYPE_EDGE_BOTH);
+		if (error)
+			dev_warn(bdata->input->dev.parent,
+				 "failed to restore interrupt trigger for IRQ %d: %d\n",
+				 bdata->irq, error);
+	}
+
+	error = disable_irq_wake(bdata->irq);
+	if (error)
+		dev_warn(bdata->input->dev.parent,
+			 "failed to disable IRQ %d as wake source: %d\n",
+			 bdata->irq, error);
+}
+
+static int __maybe_unused
+gpio_keys_enable_wakeup(struct gpio_keys_drvdata *ddata)
+{
+	struct gpio_button_data *bdata;
+	int error;
+	int i;
+
+	for (i = 0; i < ddata->pdata->nbuttons; i++) {
+		bdata = &ddata->data[i];
+		if (bdata->button->wakeup) {
+			error = gpio_keys_button_enable_wakeup(bdata);
+			if (error)
+				goto err_out;
+		}
+		bdata->suspended = true;
+	}
+
+	return 0;
+
+err_out:
+	while (i--) {
+		bdata = &ddata->data[i];
+		if (bdata->button->wakeup)
+			gpio_keys_button_disable_wakeup(bdata);
+		bdata->suspended = false;
+	}
+
+	return error;
+}
+
+static void __maybe_unused
+gpio_keys_disable_wakeup(struct gpio_keys_drvdata *ddata)
+{
+	struct gpio_button_data *bdata;
+	int i;
+
+	for (i = 0; i < ddata->pdata->nbuttons; i++) {
+		bdata = &ddata->data[i];
+		bdata->suspended = false;
+		if (irqd_is_wakeup_set(irq_get_irq_data(bdata->irq)))
+			gpio_keys_button_disable_wakeup(bdata);
+	}
+}
+
 static int __maybe_unused gpio_keys_suspend(struct device *dev)
 {
 	struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
 	struct input_dev *input = ddata->input;
-	int i;
+	int error;
 
 	if (device_may_wakeup(dev)) {
-		for (i = 0; i < ddata->pdata->nbuttons; i++) {
-			struct gpio_button_data *bdata = &ddata->data[i];
-			if (bdata->button->wakeup)
-				enable_irq_wake(bdata->irq);
-			bdata->suspended = true;
-		}
+		error = gpio_keys_enable_wakeup(ddata);
+		if (error)
+			return error;
 	} else {
 		mutex_lock(&input->mutex);
 		if (input->users)
@@ -873,15 +996,9 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
 	struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
 	struct input_dev *input = ddata->input;
 	int error = 0;
-	int i;
 
 	if (device_may_wakeup(dev)) {
-		for (i = 0; i < ddata->pdata->nbuttons; i++) {
-			struct gpio_button_data *bdata = &ddata->data[i];
-			if (bdata->button->wakeup)
-				disable_irq_wake(bdata->irq);
-			bdata->suspended = false;
-		}
+		gpio_keys_disable_wakeup(ddata);
 	} else {
 		mutex_lock(&input->mutex);
 		if (input->users)
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c
index 8c6c0b9..d69e631 100644
--- a/drivers/input/keyboard/stmpe-keypad.c
+++ b/drivers/input/keyboard/stmpe-keypad.c
@@ -48,6 +48,14 @@
 #define STMPE_KEYPAD_KEYMAP_MAX_SIZE \
 	(STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)
 
+
+#define STMPE1601_NUM_DATA	5
+#define STMPE2401_NUM_DATA	3
+#define STMPE2403_NUM_DATA	5
+
+/* Make sure it covers all cases above */
+#define MAX_NUM_DATA		5
+
 /**
  * struct stmpe_keypad_variant - model-specific attributes
  * @auto_increment: whether the KPC_DATA_BYTE register address
@@ -74,7 +82,7 @@ struct stmpe_keypad_variant {
 static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 	[STMPE1601] = {
 		.auto_increment		= true,
-		.num_data		= 5,
+		.num_data		= STMPE1601_NUM_DATA,
 		.num_normal_data	= 3,
 		.max_cols		= 8,
 		.max_rows		= 8,
@@ -84,7 +92,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 	[STMPE2401] = {
 		.auto_increment		= false,
 		.set_pullup		= true,
-		.num_data		= 3,
+		.num_data		= STMPE2401_NUM_DATA,
 		.num_normal_data	= 2,
 		.max_cols		= 8,
 		.max_rows		= 12,
@@ -94,7 +102,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 	[STMPE2403] = {
 		.auto_increment		= true,
 		.set_pullup		= true,
-		.num_data		= 5,
+		.num_data		= STMPE2403_NUM_DATA,
 		.num_normal_data	= 3,
 		.max_cols		= 8,
 		.max_rows		= 12,
@@ -156,7 +164,7 @@ static irqreturn_t stmpe_keypad_irq(int irq, void *dev)
 	struct stmpe_keypad *keypad = dev;
 	struct input_dev *input = keypad->input;
 	const struct stmpe_keypad_variant *variant = keypad->variant;
-	u8 fifo[variant->num_data];
+	u8 fifo[MAX_NUM_DATA];
 	int ret;
 	int i;
 
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index e9770f5..572b15f 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -832,4 +832,13 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called hisi_powerkey.
 
+config INPUT_RAVE_SP_PWRBUTTON
+	tristate "RAVE SP Power button Driver"
+	depends on RAVE_SP_CORE
+	help
+	  Say Y here if you want to enable power key reporting from RAVE SP
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rave-sp-pwrbutton.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index eb9c6c3..72cde28 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -59,6 +59,7 @@
 obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
 obj-$(CONFIG_INPUT_PWM_BEEPER)		+= pwm-beeper.o
 obj-$(CONFIG_INPUT_PWM_VIBRA)		+= pwm-vibra.o
+obj-$(CONFIG_INPUT_RAVE_SP_PWRBUTTON)	+= rave-sp-pwrbutton.o
 obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
 obj-$(CONFIG_INPUT_REGULATOR_HAPTIC)	+= regulator-haptic.o
 obj-$(CONFIG_INPUT_RETU_PWRBUTTON)	+= retu-pwrbutton.o
diff --git a/drivers/input/misc/rave-sp-pwrbutton.c b/drivers/input/misc/rave-sp-pwrbutton.c
new file mode 100644
index 0000000..bcab3cd
--- /dev/null
+++ b/drivers/input/misc/rave-sp-pwrbutton.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Power Button driver for RAVE SP
+//
+// Copyright (C) 2017 Zodiac Inflight Innovations
+//
+//
+
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/rave-sp.h>
+#include <linux/platform_device.h>
+
+#define RAVE_SP_EVNT_BUTTON_PRESS	(RAVE_SP_EVNT_BASE + 0x00)
+
+struct rave_sp_power_button {
+	struct input_dev *idev;
+	struct notifier_block nb;
+};
+
+static int rave_sp_power_button_event(struct notifier_block *nb,
+				      unsigned long action, void *data)
+{
+	struct rave_sp_power_button *pb =
+		container_of(nb, struct rave_sp_power_button, nb);
+	const u8 event = rave_sp_action_unpack_event(action);
+	const u8 value = rave_sp_action_unpack_value(action);
+	struct input_dev *idev = pb->idev;
+
+	if (event == RAVE_SP_EVNT_BUTTON_PRESS) {
+		input_report_key(idev, KEY_POWER, value);
+		input_sync(idev);
+
+		return NOTIFY_STOP;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int rave_sp_pwrbutton_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rave_sp_power_button *pb;
+	struct input_dev *idev;
+	int error;
+
+	pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL);
+	if (!pb)
+		return -ENOMEM;
+
+	idev = devm_input_allocate_device(dev);
+	if (!idev)
+		return -ENOMEM;
+
+	idev->name = pdev->name;
+
+	input_set_capability(idev, EV_KEY, KEY_POWER);
+
+	error = input_register_device(idev);
+	if (error)
+		return error;
+
+	pb->idev = idev;
+	pb->nb.notifier_call = rave_sp_power_button_event;
+	pb->nb.priority = 128;
+
+	error = devm_rave_sp_register_event_notifier(dev, &pb->nb);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static const struct of_device_id rave_sp_pwrbutton_of_match[] = {
+	{ .compatible = "zii,rave-sp-pwrbutton" },
+	{}
+};
+
+static struct platform_driver rave_sp_pwrbutton_driver = {
+	.probe = rave_sp_pwrbutton_probe,
+	.driver	= {
+		.name = KBUILD_MODNAME,
+		.of_match_table = rave_sp_pwrbutton_of_match,
+	},
+};
+module_platform_driver(rave_sp_pwrbutton_driver);
+
+MODULE_DEVICE_TABLE(of, rave_sp_pwrbutton_of_match);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>");
+MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>");
+MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
+MODULE_DESCRIPTION("RAVE SP Power Button driver");
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index dbe57da..0a67f23 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -139,11 +139,11 @@ static const struct alps_model_info alps_model_data[] = {
 };
 
 static const struct alps_protocol_info alps_v3_protocol_data = {
-	ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT
+	ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
 };
 
 static const struct alps_protocol_info alps_v3_rushmore_data = {
-	ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT
+	ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
 };
 
 static const struct alps_protocol_info alps_v4_protocol_data = {
@@ -155,7 +155,7 @@ static const struct alps_protocol_info alps_v5_protocol_data = {
 };
 
 static const struct alps_protocol_info alps_v7_protocol_data = {
-	ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT
+	ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
 };
 
 static const struct alps_protocol_info alps_v8_protocol_data = {
@@ -583,7 +583,7 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
 
 	x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f));
 	y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
-	z = (packet[4] & 0x7c) >> 2;
+	z = packet[4] & 0x7c;
 
 	/*
 	 * The x and y values tend to be quite large, and when used
@@ -595,6 +595,7 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
 
 	input_report_rel(dev, REL_X, x);
 	input_report_rel(dev, REL_Y, -y);
+	input_report_abs(dev, ABS_PRESSURE, z);
 
 	/*
 	 * Most ALPS models report the trackstick buttons in the touchpad
@@ -827,7 +828,7 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
 	unsigned char *packet = psmouse->packet;
 	struct input_dev *dev = psmouse->dev;
 	struct input_dev *dev2 = priv->dev2;
-	int x, y, z, left, right, middle;
+	int x, y, z;
 
 	/*
 	 * We can use Byte5 to distinguish if the packet is from Touchpad
@@ -847,9 +848,6 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
 		x = packet[1] | ((packet[3] & 0x20) << 2);
 		y = packet[2] | ((packet[3] & 0x40) << 1);
 		z = packet[4];
-		left = packet[3] & 0x01;
-		right = packet[3] & 0x02;
-		middle = packet[3] & 0x04;
 
 		/* To prevent the cursor jump when finger lifted */
 		if (x == 0x7F && y == 0x7F && z == 0x7F)
@@ -859,9 +857,7 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
 		input_report_rel(dev2, REL_X, (char)x / 4);
 		input_report_rel(dev2, REL_Y, -((char)y / 4));
 
-		input_report_key(dev2, BTN_LEFT, left);
-		input_report_key(dev2, BTN_RIGHT, right);
-		input_report_key(dev2, BTN_MIDDLE, middle);
+		psmouse_report_standard_buttons(dev2, packet[3]);
 
 		input_sync(dev2);
 		return;
@@ -871,8 +867,6 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
 	x = packet[1] | ((packet[3] & 0x78) << 4);
 	y = packet[2] | ((packet[4] & 0x78) << 4);
 	z = packet[5];
-	left = packet[3] & 0x01;
-	right = packet[3] & 0x02;
 
 	if (z > 30)
 		input_report_key(dev, BTN_TOUCH, 1);
@@ -888,8 +882,8 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
 	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
 
 	/* v6 touchpad does not have middle button */
-	input_report_key(dev, BTN_LEFT, left);
-	input_report_key(dev, BTN_RIGHT, right);
+	packet[3] &= ~BIT(2);
+	psmouse_report_standard_buttons(dev2, packet[3]);
 
 	input_sync(dev);
 }
@@ -1098,7 +1092,7 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
 	struct alps_data *priv = psmouse->private;
 	unsigned char *packet = psmouse->packet;
 	struct input_dev *dev2 = priv->dev2;
-	int x, y, z, left, right, middle;
+	int x, y, z;
 
 	/* It should be a DualPoint when received trackstick packet */
 	if (!(priv->flags & ALPS_DUALPOINT)) {
@@ -1112,16 +1106,11 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
 	    ((packet[3] & 0x20) << 1);
 	z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1);
 
-	left = (packet[1] & 0x01);
-	right = (packet[1] & 0x02) >> 1;
-	middle = (packet[1] & 0x04) >> 2;
-
 	input_report_rel(dev2, REL_X, (char)x);
 	input_report_rel(dev2, REL_Y, -((char)y));
+	input_report_abs(dev2, ABS_PRESSURE, z);
 
-	input_report_key(dev2, BTN_LEFT, left);
-	input_report_key(dev2, BTN_RIGHT, right);
-	input_report_key(dev2, BTN_MIDDLE, middle);
+	psmouse_report_standard_buttons(dev2, packet[1]);
 
 	input_sync(dev2);
 }
@@ -1503,10 +1492,7 @@ static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
 		alps_report_buttons(dev, dev2,
 				packet[0] & 1, packet[0] & 2, packet[0] & 4);
 
-	input_report_rel(dev, REL_X,
-		packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
-	input_report_rel(dev, REL_Y,
-		packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
+	psmouse_report_standard_motion(dev, packet);
 
 	input_sync(dev);
 }
@@ -2544,13 +2530,31 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
 }
 
 static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
-				       struct alps_data *priv)
+					struct alps_data *priv,
+					struct psmouse *psmouse)
 {
 	bool is_dual = false;
+	int reg_val = 0;
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
 
-	if (IS_SS4PLUS_DEV(priv->dev_id))
+	if (IS_SS4PLUS_DEV(priv->dev_id)) {
 		is_dual = (otp[0][0] >> 4) & 0x01;
 
+		if (!is_dual) {
+			/* For support TrackStick of Thinkpad L/E series */
+			if (alps_exit_command_mode(psmouse) == 0 &&
+				alps_enter_command_mode(psmouse) == 0) {
+				reg_val = alps_command_mode_read_reg(psmouse,
+									0xD7);
+			}
+			alps_exit_command_mode(psmouse);
+			ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+
+			if (reg_val == 0x0C || reg_val == 0x1D)
+				is_dual = true;
+		}
+	}
+
 	if (is_dual)
 		priv->flags |= ALPS_DUALPOINT |
 					ALPS_DUALPOINT_WITH_PRESSURE;
@@ -2573,7 +2577,7 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
 
 	alps_update_btn_info_ss4_v2(otp, priv);
 
-	alps_update_dual_info_ss4_v2(otp, priv);
+	alps_update_dual_info_ss4_v2(otp, priv, psmouse);
 
 	return 0;
 }
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 81a695d..032d279 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -587,7 +587,7 @@ static void atp_complete_geyser_1_2(struct urb *urb)
 		/* Perform size detection, if not done already */
 		if (unlikely(!dev->size_detect_done)) {
 			atp_detect_size(dev);
-			dev->size_detect_done = 1;
+			dev->size_detect_done = true;
 			goto exit;
 		}
 	}
@@ -813,7 +813,7 @@ static int atp_open(struct input_dev *input)
 	if (usb_submit_urb(dev->urb, GFP_ATOMIC))
 		return -EIO;
 
-	dev->open = 1;
+	dev->open = true;
 	return 0;
 }
 
@@ -823,7 +823,7 @@ static void atp_close(struct input_dev *input)
 
 	usb_kill_urb(dev->urb);
 	cancel_work_sync(&dev->work);
-	dev->open = 0;
+	dev->open = false;
 }
 
 static int atp_handle_geyser(struct atp *dev)
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index a4aaa74..db47a5e 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -35,7 +35,7 @@
 static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c,
 				unsigned char *param)
 {
-	if (psmouse_sliced_command(psmouse, c) ||
+	if (ps2_sliced_command(&psmouse->ps2dev, c) ||
 	    ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) {
 		psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c);
 		return -1;
@@ -107,8 +107,8 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
 
 	switch (etd->hw_version) {
 	case 1:
-		if (psmouse_sliced_command(psmouse, ETP_REGISTER_READ) ||
-		    psmouse_sliced_command(psmouse, reg) ||
+		if (ps2_sliced_command(&psmouse->ps2dev, ETP_REGISTER_READ) ||
+		    ps2_sliced_command(&psmouse->ps2dev, reg) ||
 		    ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) {
 			rc = -1;
 		}
@@ -162,9 +162,9 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
 
 	switch (etd->hw_version) {
 	case 1:
-		if (psmouse_sliced_command(psmouse, ETP_REGISTER_WRITE) ||
-		    psmouse_sliced_command(psmouse, reg) ||
-		    psmouse_sliced_command(psmouse, val) ||
+		if (ps2_sliced_command(&psmouse->ps2dev, ETP_REGISTER_WRITE) ||
+		    ps2_sliced_command(&psmouse->ps2dev, reg) ||
+		    ps2_sliced_command(&psmouse->ps2dev, val) ||
 		    ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) {
 			rc = -1;
 		}
@@ -279,8 +279,8 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
 	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
 	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
 	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
-	input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
-	input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+
+	psmouse_report_standard_buttons(dev, packet[0]);
 
 	if (etd->fw_version < 0x020000 &&
 	    (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) {
@@ -390,8 +390,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
 	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
 	input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
-	input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
-	input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+	psmouse_report_standard_buttons(dev, packet[0]);
 	if (etd->reports_pressure) {
 		input_report_abs(dev, ABS_PRESSURE, pres);
 		input_report_abs(dev, ABS_TOOL_WIDTH, width);
@@ -434,9 +433,7 @@ static void elantech_report_trackpoint(struct psmouse *psmouse,
 		x = packet[4] - (int)((packet[1]^0x80) << 1);
 		y = (int)((packet[2]^0x80) << 1) - packet[5];
 
-		input_report_key(tp_dev, BTN_LEFT, packet[0] & 0x01);
-		input_report_key(tp_dev, BTN_RIGHT, packet[0] & 0x02);
-		input_report_key(tp_dev, BTN_MIDDLE, packet[0] & 0x04);
+		psmouse_report_standard_buttons(tp_dev, packet[0]);
 
 		input_report_rel(tp_dev, REL_X, x);
 		input_report_rel(tp_dev, REL_Y, y);
@@ -526,12 +523,10 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse,
 	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
 
 	/* For clickpads map both buttons to BTN_LEFT */
-	if (etd->fw_version & 0x001000) {
+	if (etd->fw_version & 0x001000)
 		input_report_key(dev, BTN_LEFT, packet[0] & 0x03);
-	} else {
-		input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
-		input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
-	}
+	else
+		psmouse_report_standard_buttons(dev, packet[0]);
 
 	input_report_abs(dev, ABS_PRESSURE, pres);
 	input_report_abs(dev, ABS_TOOL_WIDTH, width);
@@ -546,13 +541,10 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
 	unsigned char *packet = psmouse->packet;
 
 	/* For clickpads map both buttons to BTN_LEFT */
-	if (etd->fw_version & 0x001000) {
+	if (etd->fw_version & 0x001000)
 		input_report_key(dev, BTN_LEFT, packet[0] & 0x03);
-	} else {
-		input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
-		input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
-		input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
-	}
+	else
+		psmouse_report_standard_buttons(dev, packet[0]);
 
 	input_mt_report_pointer_emulation(dev, true);
 	input_sync(dev);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 13d324c..a5765f7 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -17,6 +17,7 @@
 #include <linux/libps2.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <linux/types.h>
 
 #include "psmouse.h"
 #include "lifebook.h"
@@ -136,7 +137,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
 	struct lifebook_data *priv = psmouse->private;
 	struct input_dev *dev1 = psmouse->dev;
 	struct input_dev *dev2 = priv ? priv->dev2 : NULL;
-	unsigned char *packet = psmouse->packet;
+	u8 *packet = psmouse->packet;
 	bool relative_packet = packet[0] & 0x08;
 
 	if (relative_packet || !lifebook_use_6byte_proto) {
@@ -188,14 +189,10 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
 	}
 
 	if (dev2) {
-		if (relative_packet) {
-			input_report_rel(dev2, REL_X,
-				((packet[0] & 0x10) ? packet[1] - 256 : packet[1]));
-			input_report_rel(dev2, REL_Y,
-				 -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2]));
-		}
-		input_report_key(dev2, BTN_LEFT, packet[0] & 0x01);
-		input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02);
+		if (relative_packet)
+			psmouse_report_standard_motion(dev2, packet);
+
+		psmouse_report_standard_buttons(dev2, packet[0]);
 		input_sync(dev2);
 	}
 
@@ -205,10 +202,12 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
 static int lifebook_absolute_mode(struct psmouse *psmouse)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param;
+	u8 param;
+	int error;
 
-	if (psmouse_reset(psmouse))
-		return -1;
+	error = psmouse_reset(psmouse);
+	if (error)
+		return error;
 
 	/*
 	 * Enable absolute output -- ps2_command fails always but if
@@ -224,15 +223,15 @@ static int lifebook_absolute_mode(struct psmouse *psmouse)
 static void lifebook_relative_mode(struct psmouse *psmouse)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param = 0x06;
+	u8 param = 0x06;
 
 	ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES);
 }
 
 static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 {
-	static const unsigned char params[] = { 0, 1, 2, 2, 3 };
-	unsigned char p;
+	static const u8 params[] = { 0, 1, 2, 2, 3 };
+	u8 p;
 
 	if (resolution == 0 || resolution > 400)
 		resolution = 400;
@@ -257,11 +256,11 @@ static void lifebook_disconnect(struct psmouse *psmouse)
 int lifebook_detect(struct psmouse *psmouse, bool set_properties)
 {
 	if (!lifebook_present)
-		return -1;
+		return -ENXIO;
 
 	if (desired_serio_phys &&
 	    strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys))
-		return -1;
+		return -ENXIO;
 
 	if (set_properties) {
 		psmouse->vendor = "Fujitsu";
@@ -294,10 +293,10 @@ static int lifebook_create_relative_device(struct psmouse *psmouse)
 	dev2->id.version = 0x0000;
 	dev2->dev.parent = &psmouse->ps2dev.serio->dev;
 
-	dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-	dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-	dev2->keybit[BIT_WORD(BTN_LEFT)] =
-				BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
+	input_set_capability(dev2, EV_REL, REL_X);
+	input_set_capability(dev2, EV_REL, REL_Y);
+	input_set_capability(dev2, EV_KEY, BTN_LEFT);
+	input_set_capability(dev2, EV_KEY, BTN_RIGHT);
 
 	error = input_register_device(priv->dev2);
 	if (error)
@@ -316,21 +315,26 @@ int lifebook_init(struct psmouse *psmouse)
 {
 	struct input_dev *dev1 = psmouse->dev;
 	int max_coord = lifebook_use_6byte_proto ? 4096 : 1024;
+	int error;
 
-	if (lifebook_absolute_mode(psmouse))
-		return -1;
+	error = lifebook_absolute_mode(psmouse);
+	if (error)
+		return error;
 
-	dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
-	dev1->relbit[0] = 0;
-	dev1->keybit[BIT_WORD(BTN_MOUSE)] = 0;
-	dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	/* Clear default capabilities */
+	bitmap_zero(dev1->evbit, EV_CNT);
+	bitmap_zero(dev1->relbit, REL_CNT);
+	bitmap_zero(dev1->keybit, KEY_CNT);
+
+	input_set_capability(dev1, EV_KEY, BTN_TOUCH);
 	input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0);
 	input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0);
 
 	if (!desired_serio_phys) {
-		if (lifebook_create_relative_device(psmouse)) {
+		error = lifebook_create_relative_device(psmouse);
+		if (error) {
 			lifebook_relative_mode(psmouse);
-			return -1;
+			return error;
 		}
 	}
 
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index ef9c97f..3d5637e 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -9,9 +9,11 @@
  * the Free Software Foundation.
  */
 
+#include <linux/bitops.h>
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
+#include <linux/types.h>
 #include "psmouse.h"
 #include "logips2pp.h"
 
@@ -22,12 +24,12 @@
 #define PS2PP_KIND_TRACKMAN	4
 
 /* Logitech mouse features */
-#define PS2PP_WHEEL		0x01
-#define PS2PP_HWHEEL		0x02
-#define PS2PP_SIDE_BTN		0x04
-#define PS2PP_EXTRA_BTN		0x08
-#define PS2PP_TASK_BTN		0x10
-#define PS2PP_NAV_BTN		0x20
+#define PS2PP_WHEEL		BIT(0)
+#define PS2PP_HWHEEL		BIT(1)
+#define PS2PP_SIDE_BTN		BIT(2)
+#define PS2PP_EXTRA_BTN		BIT(3)
+#define PS2PP_TASK_BTN		BIT(4)
+#define PS2PP_NAV_BTN		BIT(5)
 
 struct ps2pp_info {
 	u8 model;
@@ -42,7 +44,7 @@ struct ps2pp_info {
 static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
 {
 	struct input_dev *dev = psmouse->dev;
-	unsigned char *packet = psmouse->packet;
+	u8 *packet = psmouse->packet;
 
 	if (psmouse->pktcnt < 3)
 		return PSMOUSE_GOOD_DATA;
@@ -58,28 +60,30 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
 
 		case 0x0d: /* Mouse extra info */
 
-			input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
-				(int) (packet[2] & 8) - (int) (packet[2] & 7));
-			input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
-			input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
+			input_report_rel(dev,
+				packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
+				-sign_extend32(packet[2], 3));
+			input_report_key(dev, BTN_SIDE,  packet[2] & BIT(4));
+			input_report_key(dev, BTN_EXTRA, packet[2] & BIT(5));
 
 			break;
 
 		case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */
 
-			input_report_key(dev, BTN_SIDE, (packet[2]) & 1);
-			input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1);
-			input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1);
-			input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1);
-			input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1);
+			input_report_key(dev, BTN_SIDE,    packet[2] & BIT(0));
+			input_report_key(dev, BTN_EXTRA,   packet[2] & BIT(1));
+			input_report_key(dev, BTN_TASK,    packet[2] & BIT(2));
+			input_report_key(dev, BTN_BACK,    packet[2] & BIT(3));
+			input_report_key(dev, BTN_FORWARD, packet[2] & BIT(4));
 
 			break;
 
 		case 0x0f: /* TouchPad extra info */
 
-			input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
-				(int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7));
-			packet[0] = packet[2] | 0x08;
+			input_report_rel(dev,
+				packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
+				-sign_extend32(packet[2] >> 4, 3));
+			packet[0] = packet[2] | BIT(3);
 			break;
 
 		default:
@@ -88,16 +92,14 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
 				    (packet[1] >> 4) | (packet[0] & 0x30));
 			break;
 		}
+
+		psmouse_report_standard_buttons(dev, packet[0]);
+
 	} else {
 		/* Standard PS/2 motion data */
-		input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
-		input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
+		psmouse_report_standard_packet(dev, packet);
 	}
 
-	input_report_key(dev, BTN_LEFT,    packet[0]       & 1);
-	input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
-	input_report_key(dev, BTN_RIGHT,  (packet[0] >> 1) & 1);
-
 	input_sync(dev);
 
 	return PSMOUSE_FULL_PACKET;
@@ -111,13 +113,17 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
  * Ugly.
  */
 
-static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
+static int ps2pp_cmd(struct psmouse *psmouse, u8 *param, u8 command)
 {
-	if (psmouse_sliced_command(psmouse, command))
-		return -1;
+	int error;
 
-	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300))
-		return -1;
+	error = ps2_sliced_command(&psmouse->ps2dev, command);
+	if (error)
+		return error;
+
+	error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300);
+	if (error)
+		return error;
 
 	return 0;
 }
@@ -133,7 +139,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
 static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[4];
+	u8 param[4];
 
 	ps2pp_cmd(psmouse, param, 0x32);
 
@@ -171,7 +177,7 @@ static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data,
 }
 
 PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL,
-			ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll);
+		    ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll);
 
 /*
  * Support 800 dpi resolution _only_ if the user wants it (there are good
@@ -179,11 +185,12 @@ PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL,
  * also good reasons to use it, let the user decide).
  */
 
-static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolution)
+static void ps2pp_set_resolution(struct psmouse *psmouse,
+				 unsigned int resolution)
 {
 	if (resolution > 400) {
 		struct ps2dev *ps2dev = &psmouse->ps2dev;
-		unsigned char param = 3;
+		u8 param = 3;
 
 		ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
 		ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
@@ -196,7 +203,8 @@ static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolutio
 
 static void ps2pp_disconnect(struct psmouse *psmouse)
 {
-	device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr);
+	device_remove_file(&psmouse->ps2dev.serio->dev,
+			   &psmouse_attr_smartscroll.dattr);
 }
 
 static const struct ps2pp_info *get_model_info(unsigned char model)
@@ -269,24 +277,24 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
 	struct input_dev *input_dev = psmouse->dev;
 
 	if (model_info->features & PS2PP_SIDE_BTN)
-		__set_bit(BTN_SIDE, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY, BTN_SIDE);
 
 	if (model_info->features & PS2PP_EXTRA_BTN)
-		__set_bit(BTN_EXTRA, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY, BTN_EXTRA);
 
 	if (model_info->features & PS2PP_TASK_BTN)
-		__set_bit(BTN_TASK, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY, BTN_TASK);
 
 	if (model_info->features & PS2PP_NAV_BTN) {
-		__set_bit(BTN_FORWARD, input_dev->keybit);
-		__set_bit(BTN_BACK, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY, BTN_FORWARD);
+		input_set_capability(input_dev, EV_KEY, BTN_BACK);
 	}
 
 	if (model_info->features & PS2PP_WHEEL)
-		__set_bit(REL_WHEEL, input_dev->relbit);
+		input_set_capability(input_dev, EV_REL, REL_WHEEL);
 
 	if (model_info->features & PS2PP_HWHEEL)
-		__set_bit(REL_HWHEEL, input_dev->relbit);
+		input_set_capability(input_dev, EV_REL, REL_HWHEEL);
 
 	switch (model_info->kind) {
 
@@ -318,6 +326,30 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
 	}
 }
 
+static int ps2pp_setup_protocol(struct psmouse *psmouse,
+				const struct ps2pp_info *model_info)
+{
+	int error;
+
+	psmouse->protocol_handler = ps2pp_process_byte;
+	psmouse->pktsize = 3;
+
+	if (model_info->kind != PS2PP_KIND_TP3) {
+		psmouse->set_resolution = ps2pp_set_resolution;
+		psmouse->disconnect = ps2pp_disconnect;
+
+		error = device_create_file(&psmouse->ps2dev.serio->dev,
+					   &psmouse_attr_smartscroll.dattr);
+		if (error) {
+			psmouse_err(psmouse,
+				    "failed to create smartscroll sysfs attribute, error: %d\n",
+				    error);
+			return error;
+		}
+	}
+
+	return 0;
+}
 
 /*
  * Logitech magic init. Detect whether the mouse is a Logitech one
@@ -328,9 +360,9 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
 int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[4];
-	unsigned char model, buttons;
 	const struct ps2pp_info *model_info;
+	u8 param[4];
+	u8 model, buttons;
 	bool use_ps2pp = false;
 	int error;
 
@@ -346,7 +378,7 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
 	buttons = param[1];
 
 	if (!model || !buttons)
-		return -1;
+		return -ENXIO;
 
 	model_info = get_model_info(model);
 	if (model_info) {
@@ -368,7 +400,8 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
 
 			param[0] = 0;
 			if (!ps2_command(ps2dev, param, 0x13d1) &&
-			    param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
+			    param[0] == 0x06 && param[1] == 0x00 &&
+			    param[2] == 0x14) {
 				use_ps2pp = true;
 			}
 
@@ -387,7 +420,9 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
 		}
 
 	} else {
-		psmouse_warn(psmouse, "Detected unknown Logitech mouse model %d\n", model);
+		psmouse_warn(psmouse,
+			     "Detected unknown Logitech mouse model %d\n",
+			     model);
 	}
 
 	if (set_properties) {
@@ -395,31 +430,18 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
 		psmouse->model = model;
 
 		if (use_ps2pp) {
-			psmouse->protocol_handler = ps2pp_process_byte;
-			psmouse->pktsize = 3;
-
-			if (model_info->kind != PS2PP_KIND_TP3) {
-				psmouse->set_resolution = ps2pp_set_resolution;
-				psmouse->disconnect = ps2pp_disconnect;
-
-				error = device_create_file(&ps2dev->serio->dev,
-							   &psmouse_attr_smartscroll.dattr);
-				if (error) {
-					psmouse_err(psmouse,
-						    "failed to create smartscroll sysfs attribute, error: %d\n",
-						    error);
-					return -1;
-				}
-			}
+			error = ps2pp_setup_protocol(psmouse, model_info);
+			if (error)
+				return error;
 		}
 
 		if (buttons >= 3)
-			__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+			input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE);
 
 		if (model_info)
 			ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
 	}
 
-	return use_ps2pp ? 0 : -1;
+	return use_ps2pp ? 0 : -ENXIO;
 }
 
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 8ac9e03..8900c31 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
 #define psmouse_fmt(fmt)	fmt
 
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -23,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/libps2.h>
 #include <linux/mutex.h>
+#include <linux/types.h>
 
 #include "psmouse.h"
 #include "synaptics.h"
@@ -68,6 +70,10 @@ static bool psmouse_smartscroll = true;
 module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);
 MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
 
+static bool psmouse_a4tech_2wheels;
+module_param_named(a4tech_workaround, psmouse_a4tech_2wheels, bool, 0644);
+MODULE_PARM_DESC(a4tech_workaround, "A4Tech second scroll wheel workaround, 1 = enabled, 0 = disabled (default).");
+
 static unsigned int psmouse_resetafter = 5;
 module_param_named(resetafter, psmouse_resetafter, uint, 0644);
 MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
@@ -116,13 +122,30 @@ static DEFINE_MUTEX(psmouse_mutex);
 
 static struct workqueue_struct *kpsmoused_wq;
 
-static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
+void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
 {
 	input_report_key(dev, BTN_LEFT,   buttons & BIT(0));
 	input_report_key(dev, BTN_MIDDLE, buttons & BIT(2));
 	input_report_key(dev, BTN_RIGHT,  buttons & BIT(1));
 }
 
+void psmouse_report_standard_motion(struct input_dev *dev, u8 *packet)
+{
+	int x, y;
+
+	x = packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0;
+	y = packet[2] ? packet[2] - ((packet[0] << 3) & 0x100) : 0;
+
+	input_report_rel(dev, REL_X, x);
+	input_report_rel(dev, REL_Y, -y);
+}
+
+void psmouse_report_standard_packet(struct input_dev *dev, u8 *packet)
+{
+	psmouse_report_standard_buttons(dev, packet[0]);
+	psmouse_report_standard_motion(dev, packet);
+}
+
 /*
  * psmouse_process_byte() analyzes the PS/2 data stream and reports
  * relevant events to the input module once full packet has arrived.
@@ -130,7 +153,8 @@ static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
 psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
 {
 	struct input_dev *dev = psmouse->dev;
-	unsigned char *packet = psmouse->packet;
+	u8 *packet = psmouse->packet;
+	int wheel;
 
 	if (psmouse->pktcnt < psmouse->pktsize)
 		return PSMOUSE_GOOD_DATA;
@@ -140,39 +164,52 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
 	switch (psmouse->protocol->type) {
 	case PSMOUSE_IMPS:
 		/* IntelliMouse has scroll wheel */
-		input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);
+		input_report_rel(dev, REL_WHEEL, -(s8) packet[3]);
 		break;
 
 	case PSMOUSE_IMEX:
 		/* Scroll wheel and buttons on IntelliMouse Explorer */
 		switch (packet[3] & 0xC0) {
 		case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */
-			input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31));
+			input_report_rel(dev, REL_WHEEL,
+					 -sign_extend32(packet[3], 5));
 			break;
 		case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */
-			input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31));
+			input_report_rel(dev, REL_HWHEEL,
+					 -sign_extend32(packet[3], 5));
 			break;
 		case 0x00:
 		case 0xC0:
-			input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7));
-			input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1);
-			input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1);
+			wheel = sign_extend32(packet[3], 3);
+
+			/*
+			 * Some A4Tech mice have two scroll wheels, with first
+			 * one reporting +/-1 in the lower nibble, and second
+			 * one reporting +/-2.
+			 */
+			if (psmouse_a4tech_2wheels && abs(wheel) > 1)
+				input_report_rel(dev, REL_HWHEEL, wheel / 2);
+			else
+				input_report_rel(dev, REL_WHEEL, -wheel);
+
+			input_report_key(dev, BTN_SIDE,  BIT(4));
+			input_report_key(dev, BTN_EXTRA, BIT(5));
 			break;
 		}
 		break;
 
 	case PSMOUSE_GENPS:
 		/* Report scroll buttons on NetMice */
-		input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);
+		input_report_rel(dev, REL_WHEEL, -(s8) packet[3]);
 
 		/* Extra buttons on Genius NewNet 3D */
-		input_report_key(dev, BTN_SIDE, (packet[0] >> 6) & 1);
-		input_report_key(dev, BTN_EXTRA, (packet[0] >> 7) & 1);
+		input_report_key(dev, BTN_SIDE,  BIT(6));
+		input_report_key(dev, BTN_EXTRA, BIT(7));
 		break;
 
 	case PSMOUSE_THINKPS:
 		/* Extra button on ThinkingMouse */
-		input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1);
+		input_report_key(dev, BTN_EXTRA, BIT(3));
 
 		/*
 		 * Without this bit of weirdness moving up gives wildly
@@ -186,8 +223,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
 		 * Cortron PS2 Trackball reports SIDE button in the
 		 * 4th bit of the first byte.
 		 */
-		input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1);
-		packet[0] |= 0x08;
+		input_report_key(dev, BTN_SIDE, BIT(3));
+		packet[0] |= BIT(3);
 		break;
 
 	default:
@@ -195,11 +232,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
 	}
 
 	/* Generic PS/2 Mouse */
-	psmouse_report_standard_buttons(dev,
-					packet[0] | psmouse->extra_buttons);
-
-	input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
-	input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
+	packet[0] |= psmouse->extra_buttons;
+	psmouse_report_standard_packet(dev, packet);
 
 	input_sync(dev);
 
@@ -255,7 +289,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
 				psmouse_notice(psmouse,
 						"issuing reconnect request\n");
 				serio_reconnect(psmouse->ps2dev.serio);
-				return -1;
+				return -EIO;
 			}
 		}
 		psmouse->pktcnt = 0;
@@ -306,7 +340,7 @@ static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
  * for normal processing or gathering them as command response.
  */
 static irqreturn_t psmouse_interrupt(struct serio *serio,
-		unsigned char data, unsigned int flags)
+				     u8 data, unsigned int flags)
 {
 	struct psmouse *psmouse = serio_get_drvdata(serio);
 
@@ -398,40 +432,19 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
 }
 
 /*
- * psmouse_sliced_command() sends an extended PS/2 command to the mouse
- * using sliced syntax, understood by advanced devices, such as Logitech
- * or Synaptics touchpads. The command is encoded as:
- * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
- * is the command.
- */
-int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
-{
-	int i;
-
-	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11))
-		return -1;
-
-	for (i = 6; i >= 0; i -= 2) {
-		unsigned char d = (command >> i) & 3;
-		if (ps2_command(&psmouse->ps2dev, &d, PSMOUSE_CMD_SETRES))
-			return -1;
-	}
-
-	return 0;
-}
-
-/*
  * psmouse_reset() resets the mouse into power-on state.
  */
 int psmouse_reset(struct psmouse *psmouse)
 {
-	unsigned char param[2];
+	u8 param[2];
+	int error;
 
-	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT))
-		return -1;
+	error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT);
+	if (error)
+		return error;
 
 	if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID)
-		return -1;
+		return -EIO;
 
 	return 0;
 }
@@ -441,8 +454,8 @@ int psmouse_reset(struct psmouse *psmouse)
  */
 void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 {
-	static const unsigned char params[] = { 0, 1, 2, 2, 3 };
-	unsigned char p;
+	static const u8 params[] = { 0, 1, 2, 2, 3 };
+	u8 p;
 
 	if (resolution == 0 || resolution > 200)
 		resolution = 200;
@@ -457,11 +470,12 @@ void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
  */
 static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
 {
-	static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
-	unsigned char r;
+	static const u8 rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+	u8 r;
 	int i = 0;
 
-	while (rates[i] > rate) i++;
+	while (rates[i] > rate)
+		i++;
 	r = rates[i];
 	ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
 	psmouse->rate = r;
@@ -533,7 +547,7 @@ bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[])
 static int genius_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[4];
+	u8 param[4];
 
 	param[0] = 3;
 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
@@ -543,7 +557,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties)
 	ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
 
 	if (param[0] != 0x00 || param[1] != 0x33 || param[2] != 0x55)
-		return -1;
+		return -ENODEV;
 
 	if (set_properties) {
 		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
@@ -565,7 +579,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties)
 static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[2];
+	u8 param[2];
 
 	param[0] = 200;
 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
@@ -576,7 +590,7 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
 	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 
 	if (param[0] != 3)
-		return -1;
+		return -ENODEV;
 
 	if (set_properties) {
 		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
@@ -598,7 +612,7 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
 static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[2];
+	u8 param[2];
 
 	intellimouse_detect(psmouse, 0);
 
@@ -611,7 +625,7 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
 	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 
 	if (param[0] != 4)
-		return -1;
+		return -ENODEV;
 
 	/* Magic to enable horizontal scrolling on IntelliMouse 4.0 */
 	param[0] = 200;
@@ -644,8 +658,8 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
 static int thinking_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[2];
-	static const unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
+	u8 param[2];
+	static const u8 seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
 	int i;
 
 	param[0] = 10;
@@ -659,7 +673,7 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties)
 	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 
 	if (param[0] != 2)
-		return -1;
+		return -ENODEV;
 
 	if (set_properties) {
 		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
@@ -687,7 +701,7 @@ static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
 		 * We have no way of figuring true number of buttons so let's
 		 * assume that the device has 3.
 		 */
-		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+		input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE);
 	}
 
 	return 0;
@@ -942,20 +956,17 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
 {
 	struct input_dev *input_dev = psmouse->dev;
 
-	memset(input_dev->evbit, 0, sizeof(input_dev->evbit));
-	memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
-	memset(input_dev->relbit, 0, sizeof(input_dev->relbit));
-	memset(input_dev->absbit, 0, sizeof(input_dev->absbit));
-	memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit));
+	bitmap_zero(input_dev->evbit, EV_CNT);
+	bitmap_zero(input_dev->keybit, KEY_CNT);
+	bitmap_zero(input_dev->relbit, REL_CNT);
+	bitmap_zero(input_dev->absbit, ABS_CNT);
+	bitmap_zero(input_dev->mscbit, MSC_CNT);
 
-	__set_bit(EV_KEY, input_dev->evbit);
-	__set_bit(EV_REL, input_dev->evbit);
+	input_set_capability(input_dev, EV_KEY, BTN_LEFT);
+	input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
 
-	__set_bit(BTN_LEFT, input_dev->keybit);
-	__set_bit(BTN_RIGHT, input_dev->keybit);
-
-	__set_bit(REL_X, input_dev->relbit);
-	__set_bit(REL_Y, input_dev->relbit);
+	input_set_capability(input_dev, EV_REL, REL_X);
+	input_set_capability(input_dev, EV_REL, REL_Y);
 
 	__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
 
@@ -1225,7 +1236,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
 static int psmouse_probe(struct psmouse *psmouse)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[2];
+	u8 param[2];
+	int error;
 
 	/*
 	 * First, we check if it's a mouse. It should send 0x00 or 0x03 in
@@ -1234,20 +1246,22 @@ static int psmouse_probe(struct psmouse *psmouse)
 	 * subsequent ID queries, probably due to a firmware bug.
 	 */
 	param[0] = 0xa5;
-	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
-		return -1;
+	error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
+	if (error)
+		return error;
 
 	if (param[0] != 0x00 && param[0] != 0x03 &&
 	    param[0] != 0x04 && param[0] != 0xff)
-		return -1;
+		return -ENODEV;
 
 	/*
 	 * Then we reset and disable the mouse so that it doesn't generate
 	 * events.
 	 */
-	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS))
-		psmouse_warn(psmouse, "Failed to reset mouse on %s\n",
-			     ps2dev->serio->phys);
+	error = ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
+	if (error)
+		psmouse_warn(psmouse, "Failed to reset mouse on %s: %d\n",
+			     ps2dev->serio->phys, error);
 
 	return 0;
 }
@@ -1288,10 +1302,13 @@ int psmouse_activate(struct psmouse *psmouse)
  */
 int psmouse_deactivate(struct psmouse *psmouse)
 {
-	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) {
-		psmouse_warn(psmouse, "Failed to deactivate mouse on %s\n",
-			     psmouse->ps2dev.serio->phys);
-		return -1;
+	int error;
+
+	error = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE);
+	if (error) {
+		psmouse_warn(psmouse, "Failed to deactivate mouse on %s: %d\n",
+			     psmouse->ps2dev.serio->phys, error);
+		return error;
 	}
 
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 8cd4538..71ac500 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -131,7 +131,6 @@ struct psmouse {
 
 void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
 		unsigned long delay);
-int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
 int psmouse_reset(struct psmouse *psmouse);
 void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state);
 void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
@@ -140,6 +139,10 @@ int psmouse_activate(struct psmouse *psmouse);
 int psmouse_deactivate(struct psmouse *psmouse);
 bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[]);
 
+void psmouse_report_standard_buttons(struct input_dev *, u8 buttons);
+void psmouse_report_standard_motion(struct input_dev *, u8 *packet);
+void psmouse_report_standard_packet(struct input_dev *, u8 *packet);
+
 struct psmouse_attribute {
 	struct device_attribute dattr;
 	void *data;
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index 11c32ac..1d6010d 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
@@ -710,7 +710,6 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 	unsigned char *packet = psmouse->packet;
 	unsigned char button_status = 0, lscroll = 0, rscroll = 0;
 	unsigned short abs_x, abs_y, fgrs = 0;
-	int rel_x, rel_y;
 
 	if (psmouse->pktcnt < 4)
 		return PSMOUSE_GOOD_DATA;
@@ -840,15 +839,7 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 		/*
 		 * Standard PS/2 Mouse
 		 */
-		input_report_key(dev, BTN_LEFT, packet[0] & 1);
-		input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
-		input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
-
-		rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0;
-		rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0;
-
-		input_report_rel(dev, REL_X, rel_x);
-		input_report_rel(dev, REL_Y, rel_y);
+		psmouse_report_standard_packet(dev, packet);
 		break;
 	}
 
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index a246fc6..60f2c46 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -84,7 +84,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, u8 mode)
 	u8 param[1];
 	int error;
 
-	error = psmouse_sliced_command(psmouse, mode);
+	error = ps2_sliced_command(&psmouse->ps2dev, mode);
 	if (error)
 		return error;
 
@@ -189,7 +189,7 @@ static int synaptics_send_cmd(struct psmouse *psmouse, u8 cmd, u8 *param)
 {
 	int error;
 
-	error = psmouse_sliced_command(psmouse, cmd);
+	error = ps2_sliced_command(&psmouse->ps2dev, cmd);
 	if (error)
 		return error;
 
@@ -546,7 +546,7 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
 	static u8 param = 0xc8;
 	int error;
 
-	error = psmouse_sliced_command(psmouse, SYN_QUE_MODEL);
+	error = ps2_sliced_command(&psmouse->ps2dev, SYN_QUE_MODEL);
 	if (error)
 		return error;
 
@@ -613,7 +613,7 @@ static int synaptics_pt_write(struct serio *serio, u8 c)
 	u8 rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
 	int error;
 
-	error = psmouse_sliced_command(parent, c);
+	error = ps2_sliced_command(&parent->ps2dev, c);
 	if (error)
 		return error;
 
@@ -1227,32 +1227,39 @@ static void set_abs_position_params(struct input_dev *dev,
 	input_abs_set_res(dev, y_code, info->y_res);
 }
 
-static void set_input_params(struct psmouse *psmouse,
-			     struct synaptics_data *priv)
+static int set_input_params(struct psmouse *psmouse,
+			    struct synaptics_data *priv)
 {
 	struct input_dev *dev = psmouse->dev;
 	struct synaptics_device_info *info = &priv->info;
 	int i;
+	int error;
+
+	/* Reset default psmouse capabilities */
+	__clear_bit(EV_REL, dev->evbit);
+	bitmap_zero(dev->relbit, REL_CNT);
+	bitmap_zero(dev->keybit, KEY_CNT);
 
 	/* Things that apply to both modes */
 	__set_bit(INPUT_PROP_POINTER, dev->propbit);
-	__set_bit(EV_KEY, dev->evbit);
-	__set_bit(BTN_LEFT, dev->keybit);
-	__set_bit(BTN_RIGHT, dev->keybit);
 
-	if (SYN_CAP_MIDDLE_BUTTON(info->capabilities))
-		__set_bit(BTN_MIDDLE, dev->keybit);
+	input_set_capability(dev, EV_KEY, BTN_LEFT);
+
+	/* Clickpads report only left button */
+	if (!SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
+		input_set_capability(dev, EV_KEY, BTN_RIGHT);
+		if (SYN_CAP_MIDDLE_BUTTON(info->capabilities))
+			input_set_capability(dev, EV_KEY, BTN_MIDDLE);
+	}
 
 	if (!priv->absolute_mode) {
 		/* Relative mode */
-		__set_bit(EV_REL, dev->evbit);
-		__set_bit(REL_X, dev->relbit);
-		__set_bit(REL_Y, dev->relbit);
-		return;
+		input_set_capability(dev, EV_REL, REL_X);
+		input_set_capability(dev, EV_REL, REL_Y);
+		return 0;
 	}
 
 	/* Absolute mode */
-	__set_bit(EV_ABS, dev->evbit);
 	set_abs_position_params(dev, &priv->info, ABS_X, ABS_Y);
 	input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
 
@@ -1264,11 +1271,15 @@ static void set_input_params(struct psmouse *psmouse,
 					ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
 		/* Image sensors can report per-contact pressure */
 		input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
-		input_mt_init_slots(dev, 2, INPUT_MT_POINTER | INPUT_MT_TRACK);
+
+		error = input_mt_init_slots(dev, 2,
+					    INPUT_MT_POINTER | INPUT_MT_TRACK);
+		if (error)
+			return error;
 
 		/* Image sensors can signal 4 and 5 finger clicks */
-		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
-		__set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
+		input_set_capability(dev, EV_KEY, BTN_TOOL_QUADTAP);
+		input_set_capability(dev, EV_KEY, BTN_TOOL_QUINTTAP);
 	} else if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c)) {
 		set_abs_position_params(dev, info,
 					ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
@@ -1276,10 +1287,13 @@ static void set_input_params(struct psmouse *psmouse,
 		 * Profile sensor in CR-48 tracks contacts reasonably well,
 		 * other non-image sensors with AGM use semi-mt.
 		 */
-		input_mt_init_slots(dev, 2,
-				    INPUT_MT_POINTER |
-				    (cr48_profile_sensor ?
-					INPUT_MT_TRACK : INPUT_MT_SEMI_MT));
+		error = input_mt_init_slots(dev, 2,
+					    INPUT_MT_POINTER |
+					     (cr48_profile_sensor ?
+					      INPUT_MT_TRACK :
+					      INPUT_MT_SEMI_MT));
+		if (error)
+			return error;
 
 		/*
 		 * For semi-mt devices we send ABS_X/Y ourselves instead of
@@ -1295,37 +1309,32 @@ static void set_input_params(struct psmouse *psmouse,
 	if (SYN_CAP_PALMDETECT(info->capabilities))
 		input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
 
-	__set_bit(BTN_TOUCH, dev->keybit);
-	__set_bit(BTN_TOOL_FINGER, dev->keybit);
+	input_set_capability(dev, EV_KEY, BTN_TOUCH);
+	input_set_capability(dev, EV_KEY, BTN_TOOL_FINGER);
 
 	if (synaptics_has_multifinger(priv)) {
-		__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
-		__set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
+		input_set_capability(dev, EV_KEY, BTN_TOOL_DOUBLETAP);
+		input_set_capability(dev, EV_KEY, BTN_TOOL_TRIPLETAP);
 	}
 
 	if (SYN_CAP_FOUR_BUTTON(info->capabilities) ||
 	    SYN_CAP_MIDDLE_BUTTON(info->capabilities)) {
-		__set_bit(BTN_FORWARD, dev->keybit);
-		__set_bit(BTN_BACK, dev->keybit);
+		input_set_capability(dev, EV_KEY, BTN_FORWARD);
+		input_set_capability(dev, EV_KEY, BTN_BACK);
 	}
 
 	if (!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
 		for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(info->ext_cap); i++)
-			__set_bit(BTN_0 + i, dev->keybit);
-
-	__clear_bit(EV_REL, dev->evbit);
-	__clear_bit(REL_X, dev->relbit);
-	__clear_bit(REL_Y, dev->relbit);
+			input_set_capability(dev, EV_KEY, BTN_0 + i);
 
 	if (SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
 		__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
 		if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
 		    !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
 			__set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
-		/* Clickpads report only left button */
-		__clear_bit(BTN_RIGHT, dev->keybit);
-		__clear_bit(BTN_MIDDLE, dev->keybit);
 	}
+
+	return 0;
 }
 
 static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse,
@@ -1563,7 +1572,12 @@ static int synaptics_init_ps2(struct psmouse *psmouse,
 		     info->capabilities, info->ext_cap, info->ext_cap_0c,
 		     info->ext_cap_10, info->board_id, info->firmware_id);
 
-	set_input_params(psmouse, priv);
+	err = set_input_params(psmouse, priv);
+	if (err) {
+		psmouse_err(psmouse,
+			    "failed to set up capabilities: %d\n", err);
+		goto init_fail;
+	}
 
 	/*
 	 * Encode touchpad model so that it can be used to set
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c
index cb7d15d..83d2412 100644
--- a/drivers/input/mouse/synaptics_usb.c
+++ b/drivers/input/mouse/synaptics_usb.c
@@ -82,6 +82,10 @@ struct synusb {
 	struct urb *urb;
 	unsigned char *data;
 
+	/* serialize access to open/suspend */
+	struct mutex pm_mutex;
+	bool is_open;
+
 	/* input device related data structures */
 	struct input_dev *input;
 	char name[128];
@@ -252,6 +256,7 @@ static int synusb_open(struct input_dev *dev)
 		return retval;
 	}
 
+	mutex_lock(&synusb->pm_mutex);
 	retval = usb_submit_urb(synusb->urb, GFP_KERNEL);
 	if (retval) {
 		dev_err(&synusb->intf->dev,
@@ -262,8 +267,10 @@ static int synusb_open(struct input_dev *dev)
 	}
 
 	synusb->intf->needs_remote_wakeup = 1;
+	synusb->is_open = true;
 
 out:
+	mutex_unlock(&synusb->pm_mutex);
 	usb_autopm_put_interface(synusb->intf);
 	return retval;
 }
@@ -275,8 +282,11 @@ static void synusb_close(struct input_dev *dev)
 
 	autopm_error = usb_autopm_get_interface(synusb->intf);
 
+	mutex_lock(&synusb->pm_mutex);
 	usb_kill_urb(synusb->urb);
 	synusb->intf->needs_remote_wakeup = 0;
+	synusb->is_open = false;
+	mutex_unlock(&synusb->pm_mutex);
 
 	if (!autopm_error)
 		usb_autopm_put_interface(synusb->intf);
@@ -315,6 +325,7 @@ static int synusb_probe(struct usb_interface *intf,
 	synusb->udev = udev;
 	synusb->intf = intf;
 	synusb->input = input_dev;
+	mutex_init(&synusb->pm_mutex);
 
 	synusb->flags = id->driver_info;
 	if (synusb->flags & SYNUSB_COMBO) {
@@ -466,11 +477,10 @@ static void synusb_disconnect(struct usb_interface *intf)
 static int synusb_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct synusb *synusb = usb_get_intfdata(intf);
-	struct input_dev *input_dev = synusb->input;
 
-	mutex_lock(&input_dev->mutex);
+	mutex_lock(&synusb->pm_mutex);
 	usb_kill_urb(synusb->urb);
-	mutex_unlock(&input_dev->mutex);
+	mutex_unlock(&synusb->pm_mutex);
 
 	return 0;
 }
@@ -478,17 +488,16 @@ static int synusb_suspend(struct usb_interface *intf, pm_message_t message)
 static int synusb_resume(struct usb_interface *intf)
 {
 	struct synusb *synusb = usb_get_intfdata(intf);
-	struct input_dev *input_dev = synusb->input;
 	int retval = 0;
 
-	mutex_lock(&input_dev->mutex);
+	mutex_lock(&synusb->pm_mutex);
 
-	if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
+	if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
 	    usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
 		retval = -EIO;
 	}
 
-	mutex_unlock(&input_dev->mutex);
+	mutex_unlock(&synusb->pm_mutex);
 
 	return retval;
 }
@@ -496,9 +505,8 @@ static int synusb_resume(struct usb_interface *intf)
 static int synusb_pre_reset(struct usb_interface *intf)
 {
 	struct synusb *synusb = usb_get_intfdata(intf);
-	struct input_dev *input_dev = synusb->input;
 
-	mutex_lock(&input_dev->mutex);
+	mutex_lock(&synusb->pm_mutex);
 	usb_kill_urb(synusb->urb);
 
 	return 0;
@@ -507,15 +515,14 @@ static int synusb_pre_reset(struct usb_interface *intf)
 static int synusb_post_reset(struct usb_interface *intf)
 {
 	struct synusb *synusb = usb_get_intfdata(intf);
-	struct input_dev *input_dev = synusb->input;
 	int retval = 0;
 
-	if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
+	if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
 	    usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
 		retval = -EIO;
 	}
 
-	mutex_unlock(&input_dev->mutex);
+	mutex_unlock(&synusb->pm_mutex);
 
 	return retval;
 }
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index bbd2922..6590d10 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -33,18 +33,15 @@ static const char * const trackpoint_variants[] = {
  */
 static int trackpoint_power_on_reset(struct ps2dev *ps2dev)
 {
-	u8 results[2];
-	int tries = 0;
+	u8 param[2] = { TP_POR };
+	int err;
 
-	/* Issue POR command, and repeat up to once if 0xFC00 received */
-	do {
-		if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
-		    ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 2, TP_POR)))
-			return -1;
-	} while (results[0] == 0xFC && results[1] == 0x00 && ++tries < 2);
+	err = ps2_command(ps2dev, param, MAKE_PS2_CMD(1, 2, TP_COMMAND));
+	if (err)
+		return err;
 
 	/* Check for success response -- 0xAA00 */
-	if (results[0] != 0xAA || results[1] != 0x00)
+	if (param[0] != 0xAA || param[1] != 0x00)
 		return -ENODEV;
 
 	return 0;
@@ -55,49 +52,39 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev)
  */
 static int trackpoint_read(struct ps2dev *ps2dev, u8 loc, u8 *results)
 {
-	if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
-	    ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) {
-		return -1;
-	}
+	results[0] = loc;
 
-	return 0;
+	return ps2_command(ps2dev, results, MAKE_PS2_CMD(1, 1, TP_COMMAND));
 }
 
 static int trackpoint_write(struct ps2dev *ps2dev, u8 loc, u8 val)
 {
-	if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
-	    ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) ||
-	    ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc)) ||
-	    ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, val))) {
-		return -1;
-	}
+	u8 param[3] = { TP_WRITE_MEM, loc, val };
 
-	return 0;
+	return ps2_command(ps2dev, param, MAKE_PS2_CMD(3, 0, TP_COMMAND));
 }
 
 static int trackpoint_toggle_bit(struct ps2dev *ps2dev, u8 loc, u8 mask)
 {
+	u8 param[3] = { TP_TOGGLE, loc, mask };
+
 	/* Bad things will happen if the loc param isn't in this range */
 	if (loc < 0x20 || loc >= 0x2F)
-		return -1;
+		return -EINVAL;
 
-	if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
-	    ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_TOGGLE)) ||
-	    ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc)) ||
-	    ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, mask))) {
-		return -1;
-	}
-
-	return 0;
+	return ps2_command(ps2dev, param, MAKE_PS2_CMD(3, 0, TP_COMMAND));
 }
 
 static int trackpoint_update_bit(struct ps2dev *ps2dev,
 				 u8 loc, u8 mask, u8 value)
 {
-	int retval = 0;
+	int retval;
 	u8 data;
 
-	trackpoint_read(ps2dev, loc, &data);
+	retval = trackpoint_read(ps2dev, loc, &data);
+	if (retval)
+		return retval;
+
 	if (((data & mask) == mask) != !!value)
 		retval = trackpoint_toggle_bit(ps2dev, loc, mask);
 
@@ -142,9 +129,9 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
 		return err;
 
 	*field = value;
-	trackpoint_write(&psmouse->ps2dev, attr->command, value);
+	err = trackpoint_write(&psmouse->ps2dev, attr->command, value);
 
-	return count;
+	return err ?: count;
 }
 
 #define TRACKPOINT_INT_ATTR(_name, _command, _default)				\
@@ -175,10 +162,11 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
 
 	if (*field != value) {
 		*field = value;
-		trackpoint_toggle_bit(&psmouse->ps2dev, attr->command, attr->mask);
+		err = trackpoint_toggle_bit(&psmouse->ps2dev,
+					    attr->command, attr->mask);
 	}
 
-	return count;
+	return err ?: count;
 }
 
 
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 6cbbdc6..b353d49 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -530,6 +530,20 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
 	{ }
 };
 
+static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = {
+	{
+		/*
+		 * Sony Vaio VGN-CS series require MUX or the touch sensor
+		 * buttons will disturb touchpad operation
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"),
+		},
+	},
+	{ }
+};
+
 /*
  * On some Asus laptops, just running self tests cause problems.
  */
@@ -621,6 +635,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
 		},
 	},
 	{
+		/* Lenovo ThinkPad L460 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"),
+		},
+	},
+	{
 		/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
@@ -1163,6 +1184,9 @@ static int __init i8042_platform_init(void)
 	if (dmi_check_system(i8042_dmi_nomux_table))
 		i8042_nomux = true;
 
+	if (dmi_check_system(i8042_dmi_forcemux_table))
+		i8042_nomux = false;
+
 	if (dmi_check_system(i8042_dmi_notimeout_table))
 		i8042_notimeout = true;
 
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 83e9c66..e6a07e6 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -26,31 +26,79 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
 MODULE_DESCRIPTION("PS/2 driver library");
 MODULE_LICENSE("GPL");
 
+static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte,
+			   unsigned int timeout, unsigned int max_attempts)
+	__releases(&ps2dev->serio->lock) __acquires(&ps2dev->serio->lock)
+{
+	int attempt = 0;
+	int error;
+
+	lockdep_assert_held(&ps2dev->serio->lock);
+
+	do {
+		ps2dev->nak = 1;
+		ps2dev->flags |= PS2_FLAG_ACK;
+
+		serio_continue_rx(ps2dev->serio);
+
+		error = serio_write(ps2dev->serio, byte);
+		if (error)
+			dev_dbg(&ps2dev->serio->dev,
+				"failed to write %#02x: %d\n", byte, error);
+		else
+			wait_event_timeout(ps2dev->wait,
+					   !(ps2dev->flags & PS2_FLAG_ACK),
+					   msecs_to_jiffies(timeout));
+
+		serio_pause_rx(ps2dev->serio);
+	} while (ps2dev->nak == PS2_RET_NAK && ++attempt < max_attempts);
+
+	ps2dev->flags &= ~PS2_FLAG_ACK;
+
+	if (!error) {
+		switch (ps2dev->nak) {
+		case 0:
+			break;
+		case PS2_RET_NAK:
+			error = -EAGAIN;
+			break;
+		case PS2_RET_ERR:
+			error = -EPROTO;
+			break;
+		default:
+			error = -EIO;
+			break;
+		}
+	}
+
+	if (error || attempt > 1)
+		dev_dbg(&ps2dev->serio->dev,
+			"%02x - %d (%x), attempt %d\n",
+			byte, error, ps2dev->nak, attempt);
+
+	return error;
+}
+
 /*
  * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
- * It doesn't handle retransmission, though it could - because if there
- * is a need for retransmissions device has to be replaced anyway.
+ * It doesn't handle retransmission, the caller is expected to handle
+ * it when needed.
  *
  * ps2_sendbyte() can only be called from a process context.
  */
 
-int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
+int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout)
 {
-	serio_pause_rx(ps2dev->serio);
-	ps2dev->nak = 1;
-	ps2dev->flags |= PS2_FLAG_ACK;
-	serio_continue_rx(ps2dev->serio);
-
-	if (serio_write(ps2dev->serio, byte) == 0)
-		wait_event_timeout(ps2dev->wait,
-				   !(ps2dev->flags & PS2_FLAG_ACK),
-				   msecs_to_jiffies(timeout));
+	int retval;
 
 	serio_pause_rx(ps2dev->serio);
-	ps2dev->flags &= ~PS2_FLAG_ACK;
+
+	retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1);
+	dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak);
+
 	serio_continue_rx(ps2dev->serio);
 
-	return -ps2dev->nak;
+	return retval;
 }
 EXPORT_SYMBOL(ps2_sendbyte);
 
@@ -75,7 +123,7 @@ EXPORT_SYMBOL(ps2_end_command);
  * and discards them.
  */
 
-void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
+void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)
 {
 	if (maxbytes > sizeof(ps2dev->cmdbuf)) {
 		WARN_ON(1);
@@ -102,9 +150,9 @@ EXPORT_SYMBOL(ps2_drain);
  * known keyboard IDs.
  */
 
-int ps2_is_keyboard_id(char id_byte)
+bool ps2_is_keyboard_id(u8 id_byte)
 {
-	static const char keyboard_ids[] = {
+	static const u8 keyboard_ids[] = {
 		0xab,	/* Regular keyboards		*/
 		0xac,	/* NCD Sun keyboard		*/
 		0x2b,	/* Trust keyboard, translated	*/
@@ -123,49 +171,50 @@ EXPORT_SYMBOL(ps2_is_keyboard_id);
  * completion.
  */
 
-static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
+static int ps2_adjust_timeout(struct ps2dev *ps2dev,
+			      unsigned int command, unsigned int timeout)
 {
 	switch (command) {
-		case PS2_CMD_RESET_BAT:
-			/*
-			 * Device has sent the first response byte after
-			 * reset command, reset is thus done, so we can
-			 * shorten the timeout.
-			 * The next byte will come soon (keyboard) or not
-			 * at all (mouse).
-			 */
-			if (timeout > msecs_to_jiffies(100))
-				timeout = msecs_to_jiffies(100);
-			break;
+	case PS2_CMD_RESET_BAT:
+		/*
+		 * Device has sent the first response byte after
+		 * reset command, reset is thus done, so we can
+		 * shorten the timeout.
+		 * The next byte will come soon (keyboard) or not
+		 * at all (mouse).
+		 */
+		if (timeout > msecs_to_jiffies(100))
+			timeout = msecs_to_jiffies(100);
+		break;
 
-		case PS2_CMD_GETID:
-			/*
-			 * Microsoft Natural Elite keyboard responds to
-			 * the GET ID command as it were a mouse, with
-			 * a single byte. Fail the command so atkbd will
-			 * use alternative probe to detect it.
-			 */
-			if (ps2dev->cmdbuf[1] == 0xaa) {
-				serio_pause_rx(ps2dev->serio);
-				ps2dev->flags = 0;
-				serio_continue_rx(ps2dev->serio);
-				timeout = 0;
-			}
+	case PS2_CMD_GETID:
+		/*
+		 * Microsoft Natural Elite keyboard responds to
+		 * the GET ID command as it were a mouse, with
+		 * a single byte. Fail the command so atkbd will
+		 * use alternative probe to detect it.
+		 */
+		if (ps2dev->cmdbuf[1] == 0xaa) {
+			serio_pause_rx(ps2dev->serio);
+			ps2dev->flags = 0;
+			serio_continue_rx(ps2dev->serio);
+			timeout = 0;
+		}
 
-			/*
-			 * If device behind the port is not a keyboard there
-			 * won't be 2nd byte of ID response.
-			 */
-			if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
-				serio_pause_rx(ps2dev->serio);
-				ps2dev->flags = ps2dev->cmdcnt = 0;
-				serio_continue_rx(ps2dev->serio);
-				timeout = 0;
-			}
-			break;
+		/*
+		 * If device behind the port is not a keyboard there
+		 * won't be 2nd byte of ID response.
+		 */
+		if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
+			serio_pause_rx(ps2dev->serio);
+			ps2dev->flags = ps2dev->cmdcnt = 0;
+			serio_continue_rx(ps2dev->serio);
+			timeout = 0;
+		}
+		break;
 
-		default:
-			break;
+	default:
+		break;
 	}
 
 	return timeout;
@@ -178,50 +227,60 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
  * ps2_command() can only be called from a process context
  */
 
-int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
+int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
 {
-	int timeout;
-	int send = (command >> 12) & 0xf;
-	int receive = (command >> 8) & 0xf;
-	int rc = -1;
+	unsigned int timeout;
+	unsigned int send = (command >> 12) & 0xf;
+	unsigned int receive = (command >> 8) & 0xf;
+	int rc;
 	int i;
+	u8 send_param[16];
 
 	if (receive > sizeof(ps2dev->cmdbuf)) {
 		WARN_ON(1);
-		return -1;
+		return -EINVAL;
 	}
 
 	if (send && !param) {
 		WARN_ON(1);
-		return -1;
+		return -EINVAL;
 	}
 
+	memcpy(send_param, param, send);
+
 	serio_pause_rx(ps2dev->serio);
+
 	ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
 	ps2dev->cmdcnt = receive;
 	if (receive && param)
 		for (i = 0; i < receive; i++)
 			ps2dev->cmdbuf[(receive - 1) - i] = param[i];
-	serio_continue_rx(ps2dev->serio);
+
+	/* Signal that we are sending the command byte */
+	ps2dev->flags |= PS2_FLAG_ACK_CMD;
 
 	/*
 	 * Some devices (Synaptics) peform the reset before
 	 * ACKing the reset command, and so it can take a long
 	 * time before the ACK arrives.
 	 */
-	if (ps2_sendbyte(ps2dev, command & 0xff,
-			 command == PS2_CMD_RESET_BAT ? 1000 : 200)) {
-		serio_pause_rx(ps2dev->serio);
+	timeout = command == PS2_CMD_RESET_BAT ? 1000 : 200;
+
+	rc = ps2_do_sendbyte(ps2dev, command & 0xff, timeout, 2);
+	if (rc)
 		goto out_reset_flags;
-	}
+
+	/* Now we are sending command parameters, if any */
+	ps2dev->flags &= ~PS2_FLAG_ACK_CMD;
 
 	for (i = 0; i < send; i++) {
-		if (ps2_sendbyte(ps2dev, param[i], 200)) {
-			serio_pause_rx(ps2dev->serio);
+		rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2);
+		if (rc)
 			goto out_reset_flags;
-		}
 	}
 
+	serio_continue_rx(ps2dev->serio);
+
 	/*
 	 * The reset command takes a long time to execute.
 	 */
@@ -243,8 +302,11 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 		for (i = 0; i < receive; i++)
 			param[i] = ps2dev->cmdbuf[(receive - 1) - i];
 
-	if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1))
+	if (ps2dev->cmdcnt &&
+	    (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) {
+		rc = -EPROTO;
 		goto out_reset_flags;
+	}
 
 	rc = 0;
 
@@ -252,11 +314,21 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 	ps2dev->flags = 0;
 	serio_continue_rx(ps2dev->serio);
 
-	return rc;
+	dev_dbg(&ps2dev->serio->dev,
+		"%02x [%*ph] - %x/%08lx [%*ph]\n",
+		command & 0xff, send, send_param,
+		ps2dev->nak, ps2dev->flags,
+		receive, param ?: send_param);
+
+	/*
+	 * ps_command() handles resends itself, so do not leak -EAGAIN
+	 * to the callers.
+	 */
+	return rc != -EAGAIN ? rc : -EPROTO;
 }
 EXPORT_SYMBOL(__ps2_command);
 
-int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
+int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
 {
 	int rc;
 
@@ -269,6 +341,39 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 EXPORT_SYMBOL(ps2_command);
 
 /*
+ * ps2_sliced_command() sends an extended PS/2 command to the mouse
+ * using sliced syntax, understood by advanced devices, such as Logitech
+ * or Synaptics touchpads. The command is encoded as:
+ * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
+ * is the command.
+ */
+
+int ps2_sliced_command(struct ps2dev *ps2dev, u8 command)
+{
+	int i;
+	int retval;
+
+	ps2_begin_command(ps2dev);
+
+	retval = __ps2_command(ps2dev, NULL, PS2_CMD_SETSCALE11);
+	if (retval)
+		goto out;
+
+	for (i = 6; i >= 0; i -= 2) {
+		u8 d = (command >> i) & 3;
+		retval = __ps2_command(ps2dev, &d, PS2_CMD_SETRES);
+		if (retval)
+			break;
+	}
+
+out:
+	dev_dbg(&ps2dev->serio->dev, "%02x - %d\n", command, retval);
+	ps2_end_command(ps2dev);
+	return retval;
+}
+EXPORT_SYMBOL(ps2_sliced_command);
+
+/*
  * ps2_init() initializes ps2dev structure
  */
 
@@ -286,42 +391,53 @@ EXPORT_SYMBOL(ps2_init);
  * to properly process ACK/NAK of a command from a PS/2 device.
  */
 
-int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
+bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data)
 {
 	switch (data) {
-		case PS2_RET_ACK:
+	case PS2_RET_ACK:
+		ps2dev->nak = 0;
+		break;
+
+	case PS2_RET_NAK:
+		ps2dev->flags |= PS2_FLAG_NAK;
+		ps2dev->nak = PS2_RET_NAK;
+		break;
+
+	case PS2_RET_ERR:
+		if (ps2dev->flags & PS2_FLAG_NAK) {
+			ps2dev->flags &= ~PS2_FLAG_NAK;
+			ps2dev->nak = PS2_RET_ERR;
+			break;
+		}
+
+	/*
+	 * Workaround for mice which don't ACK the Get ID command.
+	 * These are valid mouse IDs that we recognize.
+	 */
+	case 0x00:
+	case 0x03:
+	case 0x04:
+		if (ps2dev->flags & PS2_FLAG_WAITID) {
 			ps2dev->nak = 0;
 			break;
-
-		case PS2_RET_NAK:
-			ps2dev->flags |= PS2_FLAG_NAK;
-			ps2dev->nak = PS2_RET_NAK;
-			break;
-
-		case PS2_RET_ERR:
-			if (ps2dev->flags & PS2_FLAG_NAK) {
-				ps2dev->flags &= ~PS2_FLAG_NAK;
-				ps2dev->nak = PS2_RET_ERR;
-				break;
-			}
-
+		}
+		/* Fall through */
+	default:
 		/*
-		 * Workaround for mice which don't ACK the Get ID command.
-		 * These are valid mouse IDs that we recognize.
+		 * Do not signal errors if we get unexpected reply while
+		 * waiting for an ACK to the initial (first) command byte:
+		 * the device might not be quiesced yet and continue
+		 * delivering data.
+		 * Note that we reset PS2_FLAG_WAITID flag, so the workaround
+		 * for mice not acknowledging the Get ID command only triggers
+		 * on the 1st byte; if device spews data we really want to see
+		 * a real ACK from it.
 		 */
-		case 0x00:
-		case 0x03:
-		case 0x04:
-			if (ps2dev->flags & PS2_FLAG_WAITID) {
-				ps2dev->nak = 0;
-				break;
-			}
-			/* Fall through */
-		default:
-			return 0;
+		dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data);
+		ps2dev->flags &= ~PS2_FLAG_WAITID;
+		return ps2dev->flags & PS2_FLAG_ACK_CMD;
 	}
 
-
 	if (!ps2dev->nak) {
 		ps2dev->flags &= ~PS2_FLAG_NAK;
 		if (ps2dev->cmdcnt)
@@ -334,7 +450,7 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
 	if (data != PS2_RET_ACK)
 		ps2_handle_response(ps2dev, data);
 
-	return 1;
+	return true;
 }
 EXPORT_SYMBOL(ps2_handle_ack);
 
@@ -344,7 +460,7 @@ EXPORT_SYMBOL(ps2_handle_ack);
  * waiting for completion of the command.
  */
 
-int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data)
+bool ps2_handle_response(struct ps2dev *ps2dev, u8 data)
 {
 	if (ps2dev->cmdcnt)
 		ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
@@ -360,7 +476,7 @@ int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data)
 		wake_up(&ps2dev->wait);
 	}
 
-	return 1;
+	return true;
 }
 EXPORT_SYMBOL(ps2_handle_response);
 
diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c
index 47de5a8..ffd03cf 100644
--- a/drivers/input/tablet/pegasus_notetaker.c
+++ b/drivers/input/tablet/pegasus_notetaker.c
@@ -41,6 +41,7 @@
 #include <linux/usb/input.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/mutex.h>
 
 /* USB HID defines */
 #define USB_REQ_GET_REPORT		0x01
@@ -76,6 +77,11 @@ struct pegasus {
 	struct usb_device *usbdev;
 	struct usb_interface *intf;
 	struct urb *irq;
+
+	/* serialize access to open/suspend */
+	struct mutex pm_mutex;
+	bool is_open;
+
 	char name[128];
 	char phys[64];
 	struct work_struct init;
@@ -216,6 +222,7 @@ static int pegasus_open(struct input_dev *dev)
 	if (error)
 		return error;
 
+	mutex_lock(&pegasus->pm_mutex);
 	pegasus->irq->dev = pegasus->usbdev;
 	if (usb_submit_urb(pegasus->irq, GFP_KERNEL)) {
 		error = -EIO;
@@ -226,12 +233,15 @@ static int pegasus_open(struct input_dev *dev)
 	if (error)
 		goto err_kill_urb;
 
+	pegasus->is_open = true;
+	mutex_unlock(&pegasus->pm_mutex);
 	return 0;
 
 err_kill_urb:
 	usb_kill_urb(pegasus->irq);
 	cancel_work_sync(&pegasus->init);
 err_autopm_put:
+	mutex_unlock(&pegasus->pm_mutex);
 	usb_autopm_put_interface(pegasus->intf);
 	return error;
 }
@@ -240,8 +250,12 @@ static void pegasus_close(struct input_dev *dev)
 {
 	struct pegasus *pegasus = input_get_drvdata(dev);
 
+	mutex_lock(&pegasus->pm_mutex);
 	usb_kill_urb(pegasus->irq);
 	cancel_work_sync(&pegasus->init);
+	pegasus->is_open = false;
+	mutex_unlock(&pegasus->pm_mutex);
+
 	usb_autopm_put_interface(pegasus->intf);
 }
 
@@ -274,6 +288,8 @@ static int pegasus_probe(struct usb_interface *intf,
 		goto err_free_mem;
 	}
 
+	mutex_init(&pegasus->pm_mutex);
+
 	pegasus->usbdev = dev;
 	pegasus->dev = input_dev;
 	pegasus->intf = intf;
@@ -388,10 +404,10 @@ static int pegasus_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct pegasus *pegasus = usb_get_intfdata(intf);
 
-	mutex_lock(&pegasus->dev->mutex);
+	mutex_lock(&pegasus->pm_mutex);
 	usb_kill_urb(pegasus->irq);
 	cancel_work_sync(&pegasus->init);
-	mutex_unlock(&pegasus->dev->mutex);
+	mutex_unlock(&pegasus->pm_mutex);
 
 	return 0;
 }
@@ -401,10 +417,10 @@ static int pegasus_resume(struct usb_interface *intf)
 	struct pegasus *pegasus = usb_get_intfdata(intf);
 	int retval = 0;
 
-	mutex_lock(&pegasus->dev->mutex);
-	if (pegasus->dev->users && usb_submit_urb(pegasus->irq, GFP_NOIO) < 0)
+	mutex_lock(&pegasus->pm_mutex);
+	if (pegasus->is_open && usb_submit_urb(pegasus->irq, GFP_NOIO) < 0)
 		retval = -EIO;
-	mutex_unlock(&pegasus->dev->mutex);
+	mutex_unlock(&pegasus->pm_mutex);
 
 	return retval;
 }
@@ -414,14 +430,14 @@ static int pegasus_reset_resume(struct usb_interface *intf)
 	struct pegasus *pegasus = usb_get_intfdata(intf);
 	int retval = 0;
 
-	mutex_lock(&pegasus->dev->mutex);
-	if (pegasus->dev->users) {
+	mutex_lock(&pegasus->pm_mutex);
+	if (pegasus->is_open) {
 		retval = pegasus_set_mode(pegasus, PEN_MODE_XY,
 					  NOTETAKER_LED_MOUSE);
 		if (!retval && usb_submit_urb(pegasus->irq, GFP_NOIO) < 0)
 			retval = -EIO;
 	}
-	mutex_unlock(&pegasus->dev->mutex);
+	mutex_unlock(&pegasus->pm_mutex);
 
 	return retval;
 }
diff --git a/drivers/input/touchscreen/s6sy761.c b/drivers/input/touchscreen/s6sy761.c
index 675efa9..b63d7fd 100644
--- a/drivers/input/touchscreen/s6sy761.c
+++ b/drivers/input/touchscreen/s6sy761.c
@@ -2,7 +2,7 @@
 // Samsung S6SY761 Touchscreen device driver
 //
 // Copyright (c) 2017 Samsung Electronics Co., Ltd.
-// Copyright (c) 2017 Andi Shyti <andi.shyti@samsung.com>
+// Copyright (c) 2017 Andi Shyti <andi@etezian.org>
 
 #include <asm/unaligned.h>
 #include <linux/delay.h>
diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c
index 646b1e7..ff7043f 100644
--- a/drivers/input/touchscreen/silead.c
+++ b/drivers/input/touchscreen/silead.c
@@ -602,6 +602,7 @@ static const struct acpi_device_id silead_ts_acpi_match[] = {
 	{ "GSL3675", 0 },
 	{ "GSL3692", 0 },
 	{ "MSSL1680", 0 },
+	{ "MSSL0001", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(acpi, silead_ts_acpi_match);
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index efdb1a7..704e990 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -2,7 +2,7 @@
 // STMicroelectronics FTS Touchscreen device driver
 //
 // Copyright (c) 2017 Samsung Electronics Co., Ltd.
-// Copyright (c) 2017 Andi Shyti <andi.shyti@samsung.com>
+// Copyright (c) 2017 Andi Shyti <andi@etezian.org>
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
@@ -730,6 +730,7 @@ static int stmfts_probe(struct i2c_client *client,
 		return err;
 
 	pm_runtime_enable(&client->dev);
+	device_enable_async_suspend(&client->dev);
 
 	return 0;
 }
@@ -805,6 +806,7 @@ static struct i2c_driver stmfts_driver = {
 		.name = STMFTS_DEV_NAME,
 		.of_match_table = of_match_ptr(stmfts_of_match),
 		.pm = &stmfts_pm_ops,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
 	},
 	.probe = stmfts_probe,
 	.remove = stmfts_remove,
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index aa77d24..c6cf908 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -54,6 +54,7 @@
 #include <linux/usb.h>
 #include <linux/usb/input.h>
 #include <linux/hid.h>
+#include <linux/mutex.h>
 
 static bool swap_xy;
 module_param(swap_xy, bool, 0644);
@@ -107,6 +108,8 @@ struct usbtouch_usb {
 	struct usb_interface *interface;
 	struct input_dev *input;
 	struct usbtouch_device_info *type;
+	struct mutex pm_mutex;  /* serialize access to open/suspend */
+	bool is_open;
 	char name[128];
 	char phys[64];
 	void *priv;
@@ -1450,6 +1453,7 @@ static int usbtouch_open(struct input_dev *input)
 	if (r < 0)
 		goto out;
 
+	mutex_lock(&usbtouch->pm_mutex);
 	if (!usbtouch->type->irq_always) {
 		if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) {
 			r = -EIO;
@@ -1458,7 +1462,9 @@ static int usbtouch_open(struct input_dev *input)
 	}
 
 	usbtouch->interface->needs_remote_wakeup = 1;
+	usbtouch->is_open = true;
 out_put:
+	mutex_unlock(&usbtouch->pm_mutex);
 	usb_autopm_put_interface(usbtouch->interface);
 out:
 	return r;
@@ -1469,8 +1475,12 @@ static void usbtouch_close(struct input_dev *input)
 	struct usbtouch_usb *usbtouch = input_get_drvdata(input);
 	int r;
 
+	mutex_lock(&usbtouch->pm_mutex);
 	if (!usbtouch->type->irq_always)
 		usb_kill_urb(usbtouch->irq);
+	usbtouch->is_open = false;
+	mutex_unlock(&usbtouch->pm_mutex);
+
 	r = usb_autopm_get_interface(usbtouch->interface);
 	usbtouch->interface->needs_remote_wakeup = 0;
 	if (!r)
@@ -1490,13 +1500,12 @@ static int usbtouch_suspend
 static int usbtouch_resume(struct usb_interface *intf)
 {
 	struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
-	struct input_dev *input = usbtouch->input;
 	int result = 0;
 
-	mutex_lock(&input->mutex);
-	if (input->users || usbtouch->type->irq_always)
+	mutex_lock(&usbtouch->pm_mutex);
+	if (usbtouch->is_open || usbtouch->type->irq_always)
 		result = usb_submit_urb(usbtouch->irq, GFP_NOIO);
-	mutex_unlock(&input->mutex);
+	mutex_unlock(&usbtouch->pm_mutex);
 
 	return result;
 }
@@ -1504,7 +1513,6 @@ static int usbtouch_resume(struct usb_interface *intf)
 static int usbtouch_reset_resume(struct usb_interface *intf)
 {
 	struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
-	struct input_dev *input = usbtouch->input;
 	int err = 0;
 
 	/* reinit the device */
@@ -1519,10 +1527,10 @@ static int usbtouch_reset_resume(struct usb_interface *intf)
 	}
 
 	/* restart IO if needed */
-	mutex_lock(&input->mutex);
-	if (input->users)
+	mutex_lock(&usbtouch->pm_mutex);
+	if (usbtouch->is_open)
 		err = usb_submit_urb(usbtouch->irq, GFP_NOIO);
-	mutex_unlock(&input->mutex);
+	mutex_unlock(&usbtouch->pm_mutex);
 
 	return err;
 }
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index dcc9e62..63171cd 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -36,13 +36,13 @@ static DECLARE_RWSEM(nvm_lock);
 /* Map between virtual and physical channel and lun */
 struct nvm_ch_map {
 	int ch_off;
-	int nr_luns;
+	int num_lun;
 	int *lun_offs;
 };
 
 struct nvm_dev_map {
 	struct nvm_ch_map *chnls;
-	int nr_chnls;
+	int num_ch;
 };
 
 static struct nvm_target *nvm_find_target(struct nvm_dev *dev, const char *name)
@@ -114,15 +114,15 @@ static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear)
 	struct nvm_dev_map *dev_map = tgt_dev->map;
 	int i, j;
 
-	for (i = 0; i < dev_map->nr_chnls; i++) {
+	for (i = 0; i < dev_map->num_ch; i++) {
 		struct nvm_ch_map *ch_map = &dev_map->chnls[i];
 		int *lun_offs = ch_map->lun_offs;
 		int ch = i + ch_map->ch_off;
 
 		if (clear) {
-			for (j = 0; j < ch_map->nr_luns; j++) {
+			for (j = 0; j < ch_map->num_lun; j++) {
 				int lun = j + lun_offs[j];
-				int lunid = (ch * dev->geo.nr_luns) + lun;
+				int lunid = (ch * dev->geo.num_lun) + lun;
 
 				WARN_ON(!test_and_clear_bit(lunid,
 							dev->lun_map));
@@ -147,47 +147,46 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct nvm_dev *dev,
 	struct nvm_dev_map *dev_rmap = dev->rmap;
 	struct nvm_dev_map *dev_map;
 	struct ppa_addr *luns;
-	int nr_luns = lun_end - lun_begin + 1;
-	int luns_left = nr_luns;
-	int nr_chnls = nr_luns / dev->geo.nr_luns;
-	int nr_chnls_mod = nr_luns % dev->geo.nr_luns;
-	int bch = lun_begin / dev->geo.nr_luns;
-	int blun = lun_begin % dev->geo.nr_luns;
+	int num_lun = lun_end - lun_begin + 1;
+	int luns_left = num_lun;
+	int num_ch = num_lun / dev->geo.num_lun;
+	int num_ch_mod = num_lun % dev->geo.num_lun;
+	int bch = lun_begin / dev->geo.num_lun;
+	int blun = lun_begin % dev->geo.num_lun;
 	int lunid = 0;
 	int lun_balanced = 1;
-	int prev_nr_luns;
+	int sec_per_lun, prev_num_lun;
 	int i, j;
 
-	nr_chnls = (nr_chnls_mod == 0) ? nr_chnls : nr_chnls + 1;
+	num_ch = (num_ch_mod == 0) ? num_ch : num_ch + 1;
 
 	dev_map = kmalloc(sizeof(struct nvm_dev_map), GFP_KERNEL);
 	if (!dev_map)
 		goto err_dev;
 
-	dev_map->chnls = kcalloc(nr_chnls, sizeof(struct nvm_ch_map),
-								GFP_KERNEL);
+	dev_map->chnls = kcalloc(num_ch, sizeof(struct nvm_ch_map), GFP_KERNEL);
 	if (!dev_map->chnls)
 		goto err_chnls;
 
-	luns = kcalloc(nr_luns, sizeof(struct ppa_addr), GFP_KERNEL);
+	luns = kcalloc(num_lun, sizeof(struct ppa_addr), GFP_KERNEL);
 	if (!luns)
 		goto err_luns;
 
-	prev_nr_luns = (luns_left > dev->geo.nr_luns) ?
-					dev->geo.nr_luns : luns_left;
-	for (i = 0; i < nr_chnls; i++) {
+	prev_num_lun = (luns_left > dev->geo.num_lun) ?
+					dev->geo.num_lun : luns_left;
+	for (i = 0; i < num_ch; i++) {
 		struct nvm_ch_map *ch_rmap = &dev_rmap->chnls[i + bch];
 		int *lun_roffs = ch_rmap->lun_offs;
 		struct nvm_ch_map *ch_map = &dev_map->chnls[i];
 		int *lun_offs;
-		int luns_in_chnl = (luns_left > dev->geo.nr_luns) ?
-					dev->geo.nr_luns : luns_left;
+		int luns_in_chnl = (luns_left > dev->geo.num_lun) ?
+					dev->geo.num_lun : luns_left;
 
-		if (lun_balanced && prev_nr_luns != luns_in_chnl)
+		if (lun_balanced && prev_num_lun != luns_in_chnl)
 			lun_balanced = 0;
 
 		ch_map->ch_off = ch_rmap->ch_off = bch;
-		ch_map->nr_luns = luns_in_chnl;
+		ch_map->num_lun = luns_in_chnl;
 
 		lun_offs = kcalloc(luns_in_chnl, sizeof(int), GFP_KERNEL);
 		if (!lun_offs)
@@ -195,8 +194,8 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct nvm_dev *dev,
 
 		for (j = 0; j < luns_in_chnl; j++) {
 			luns[lunid].ppa = 0;
-			luns[lunid].g.ch = i;
-			luns[lunid++].g.lun = j;
+			luns[lunid].a.ch = i;
+			luns[lunid++].a.lun = j;
 
 			lun_offs[j] = blun;
 			lun_roffs[j + blun] = blun;
@@ -209,24 +208,29 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct nvm_dev *dev,
 		luns_left -= luns_in_chnl;
 	}
 
-	dev_map->nr_chnls = nr_chnls;
+	dev_map->num_ch = num_ch;
 
 	tgt_dev = kmalloc(sizeof(struct nvm_tgt_dev), GFP_KERNEL);
 	if (!tgt_dev)
 		goto err_ch;
 
+	/* Inherit device geometry from parent */
 	memcpy(&tgt_dev->geo, &dev->geo, sizeof(struct nvm_geo));
+
 	/* Target device only owns a portion of the physical device */
-	tgt_dev->geo.nr_chnls = nr_chnls;
-	tgt_dev->geo.all_luns = nr_luns;
-	tgt_dev->geo.nr_luns = (lun_balanced) ? prev_nr_luns : -1;
+	tgt_dev->geo.num_ch = num_ch;
+	tgt_dev->geo.num_lun = (lun_balanced) ? prev_num_lun : -1;
+	tgt_dev->geo.all_luns = num_lun;
+	tgt_dev->geo.all_chunks = num_lun * dev->geo.num_chk;
+
 	tgt_dev->geo.op = op;
-	tgt_dev->total_secs = nr_luns * tgt_dev->geo.sec_per_lun;
+
+	sec_per_lun = dev->geo.clba * dev->geo.num_chk;
+	tgt_dev->geo.total_secs = num_lun * sec_per_lun;
+
 	tgt_dev->q = dev->q;
 	tgt_dev->map = dev_map;
 	tgt_dev->luns = luns;
-	memcpy(&tgt_dev->identity, &dev->identity, sizeof(struct nvm_id));
-
 	tgt_dev->parent = dev;
 
 	return tgt_dev;
@@ -296,24 +300,20 @@ static int __nvm_config_simple(struct nvm_dev *dev,
 static int __nvm_config_extended(struct nvm_dev *dev,
 				 struct nvm_ioctl_create_extended *e)
 {
-	struct nvm_geo *geo = &dev->geo;
-
 	if (e->lun_begin == 0xFFFF && e->lun_end == 0xFFFF) {
 		e->lun_begin = 0;
 		e->lun_end = dev->geo.all_luns - 1;
 	}
 
 	/* op not set falls into target's default */
-	if (e->op == 0xFFFF)
+	if (e->op == 0xFFFF) {
 		e->op = NVM_TARGET_DEFAULT_OP;
-
-	if (e->op < NVM_TARGET_MIN_OP ||
-	    e->op > NVM_TARGET_MAX_OP) {
+	} else if (e->op < NVM_TARGET_MIN_OP || e->op > NVM_TARGET_MAX_OP) {
 		pr_err("nvm: invalid over provisioning value\n");
 		return -EINVAL;
 	}
 
-	return nvm_config_check_luns(geo, e->lun_begin, e->lun_end);
+	return nvm_config_check_luns(&dev->geo, e->lun_begin, e->lun_end);
 }
 
 static int nvm_create_tgt(struct nvm_dev *dev, struct nvm_ioctl_create *create)
@@ -384,7 +384,7 @@ static int nvm_create_tgt(struct nvm_dev *dev, struct nvm_ioctl_create *create)
 		goto err_dev;
 	}
 
-	tqueue = blk_alloc_queue_node(GFP_KERNEL, dev->q->node);
+	tqueue = blk_alloc_queue_node(GFP_KERNEL, dev->q->node, NULL);
 	if (!tqueue) {
 		ret = -ENOMEM;
 		goto err_disk;
@@ -407,7 +407,8 @@ static int nvm_create_tgt(struct nvm_dev *dev, struct nvm_ioctl_create *create)
 	tdisk->private_data = targetdata;
 	tqueue->queuedata = targetdata;
 
-	blk_queue_max_hw_sectors(tqueue, 8 * dev->ops->max_phys_sect);
+	blk_queue_max_hw_sectors(tqueue,
+			(dev->geo.csecs >> 9) * NVM_MAX_VLBA);
 
 	set_capacity(tdisk, tt->capacity(targetdata));
 	add_disk(tdisk);
@@ -503,20 +504,20 @@ static int nvm_register_map(struct nvm_dev *dev)
 	if (!rmap)
 		goto err_rmap;
 
-	rmap->chnls = kcalloc(dev->geo.nr_chnls, sizeof(struct nvm_ch_map),
+	rmap->chnls = kcalloc(dev->geo.num_ch, sizeof(struct nvm_ch_map),
 								GFP_KERNEL);
 	if (!rmap->chnls)
 		goto err_chnls;
 
-	for (i = 0; i < dev->geo.nr_chnls; i++) {
+	for (i = 0; i < dev->geo.num_ch; i++) {
 		struct nvm_ch_map *ch_rmap;
 		int *lun_roffs;
-		int luns_in_chnl = dev->geo.nr_luns;
+		int luns_in_chnl = dev->geo.num_lun;
 
 		ch_rmap = &rmap->chnls[i];
 
 		ch_rmap->ch_off = -1;
-		ch_rmap->nr_luns = luns_in_chnl;
+		ch_rmap->num_lun = luns_in_chnl;
 
 		lun_roffs = kcalloc(luns_in_chnl, sizeof(int), GFP_KERNEL);
 		if (!lun_roffs)
@@ -545,7 +546,7 @@ static void nvm_unregister_map(struct nvm_dev *dev)
 	struct nvm_dev_map *rmap = dev->rmap;
 	int i;
 
-	for (i = 0; i < dev->geo.nr_chnls; i++)
+	for (i = 0; i < dev->geo.num_ch; i++)
 		kfree(rmap->chnls[i].lun_offs);
 
 	kfree(rmap->chnls);
@@ -555,22 +556,22 @@ static void nvm_unregister_map(struct nvm_dev *dev)
 static void nvm_map_to_dev(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *p)
 {
 	struct nvm_dev_map *dev_map = tgt_dev->map;
-	struct nvm_ch_map *ch_map = &dev_map->chnls[p->g.ch];
-	int lun_off = ch_map->lun_offs[p->g.lun];
+	struct nvm_ch_map *ch_map = &dev_map->chnls[p->a.ch];
+	int lun_off = ch_map->lun_offs[p->a.lun];
 
-	p->g.ch += ch_map->ch_off;
-	p->g.lun += lun_off;
+	p->a.ch += ch_map->ch_off;
+	p->a.lun += lun_off;
 }
 
 static void nvm_map_to_tgt(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *p)
 {
 	struct nvm_dev *dev = tgt_dev->parent;
 	struct nvm_dev_map *dev_rmap = dev->rmap;
-	struct nvm_ch_map *ch_rmap = &dev_rmap->chnls[p->g.ch];
-	int lun_roff = ch_rmap->lun_offs[p->g.lun];
+	struct nvm_ch_map *ch_rmap = &dev_rmap->chnls[p->a.ch];
+	int lun_roff = ch_rmap->lun_offs[p->a.lun];
 
-	p->g.ch -= ch_rmap->ch_off;
-	p->g.lun -= lun_roff;
+	p->a.ch -= ch_rmap->ch_off;
+	p->a.lun -= lun_roff;
 }
 
 static void nvm_ppa_tgt_to_dev(struct nvm_tgt_dev *tgt_dev,
@@ -580,7 +581,7 @@ static void nvm_ppa_tgt_to_dev(struct nvm_tgt_dev *tgt_dev,
 
 	for (i = 0; i < nr_ppas; i++) {
 		nvm_map_to_dev(tgt_dev, &ppa_list[i]);
-		ppa_list[i] = generic_to_dev_addr(tgt_dev, ppa_list[i]);
+		ppa_list[i] = generic_to_dev_addr(tgt_dev->parent, ppa_list[i]);
 	}
 }
 
@@ -590,7 +591,7 @@ static void nvm_ppa_dev_to_tgt(struct nvm_tgt_dev *tgt_dev,
 	int i;
 
 	for (i = 0; i < nr_ppas; i++) {
-		ppa_list[i] = dev_to_generic_addr(tgt_dev, ppa_list[i]);
+		ppa_list[i] = dev_to_generic_addr(tgt_dev->parent, ppa_list[i]);
 		nvm_map_to_tgt(tgt_dev, &ppa_list[i]);
 	}
 }
@@ -674,7 +675,7 @@ static int nvm_set_rqd_ppalist(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd,
 	int i, plane_cnt, pl_idx;
 	struct ppa_addr ppa;
 
-	if (geo->plane_mode == NVM_PLANE_SINGLE && nr_ppas == 1) {
+	if (geo->pln_mode == NVM_PLANE_SINGLE && nr_ppas == 1) {
 		rqd->nr_ppas = nr_ppas;
 		rqd->ppa_addr = ppas[0];
 
@@ -688,7 +689,7 @@ static int nvm_set_rqd_ppalist(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd,
 		return -ENOMEM;
 	}
 
-	plane_cnt = geo->plane_mode;
+	plane_cnt = geo->pln_mode;
 	rqd->nr_ppas *= plane_cnt;
 
 	for (i = 0; i < nr_ppas; i++) {
@@ -711,6 +712,17 @@ static void nvm_free_rqd_ppalist(struct nvm_tgt_dev *tgt_dev,
 	nvm_dev_dma_free(tgt_dev->parent, rqd->ppa_list, rqd->dma_ppa_list);
 }
 
+int nvm_get_chunk_meta(struct nvm_tgt_dev *tgt_dev, struct nvm_chk_meta *meta,
+		struct ppa_addr ppa, int nchks)
+{
+	struct nvm_dev *dev = tgt_dev->parent;
+
+	nvm_ppa_tgt_to_dev(tgt_dev, &ppa, 1);
+
+	return dev->ops->get_chk_meta(tgt_dev->parent, meta,
+						(sector_t)ppa.ppa, nchks);
+}
+EXPORT_SYMBOL(nvm_get_chunk_meta);
 
 int nvm_set_tgt_bb_tbl(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *ppas,
 		       int nr_ppas, int type)
@@ -719,7 +731,7 @@ int nvm_set_tgt_bb_tbl(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *ppas,
 	struct nvm_rq rqd;
 	int ret;
 
-	if (nr_ppas > dev->ops->max_phys_sect) {
+	if (nr_ppas > NVM_MAX_VLBA) {
 		pr_err("nvm: unable to update all blocks atomically\n");
 		return -EINVAL;
 	}
@@ -740,14 +752,6 @@ int nvm_set_tgt_bb_tbl(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *ppas,
 }
 EXPORT_SYMBOL(nvm_set_tgt_bb_tbl);
 
-int nvm_max_phys_sects(struct nvm_tgt_dev *tgt_dev)
-{
-	struct nvm_dev *dev = tgt_dev->parent;
-
-	return dev->ops->max_phys_sect;
-}
-EXPORT_SYMBOL(nvm_max_phys_sects);
-
 int nvm_submit_io(struct nvm_tgt_dev *tgt_dev, struct nvm_rq *rqd)
 {
 	struct nvm_dev *dev = tgt_dev->parent;
@@ -814,15 +818,15 @@ int nvm_bb_tbl_fold(struct nvm_dev *dev, u8 *blks, int nr_blks)
 	struct nvm_geo *geo = &dev->geo;
 	int blk, offset, pl, blktype;
 
-	if (nr_blks != geo->nr_chks * geo->plane_mode)
+	if (nr_blks != geo->num_chk * geo->pln_mode)
 		return -EINVAL;
 
-	for (blk = 0; blk < geo->nr_chks; blk++) {
-		offset = blk * geo->plane_mode;
+	for (blk = 0; blk < geo->num_chk; blk++) {
+		offset = blk * geo->pln_mode;
 		blktype = blks[offset];
 
 		/* Bad blocks on any planes take precedence over other types */
-		for (pl = 0; pl < geo->plane_mode; pl++) {
+		for (pl = 0; pl < geo->pln_mode; pl++) {
 			if (blks[offset + pl] &
 					(NVM_BLK_T_BAD|NVM_BLK_T_GRWN_BAD)) {
 				blktype = blks[offset + pl];
@@ -833,7 +837,7 @@ int nvm_bb_tbl_fold(struct nvm_dev *dev, u8 *blks, int nr_blks)
 		blks[blk] = blktype;
 	}
 
-	return geo->nr_chks;
+	return geo->num_chk;
 }
 EXPORT_SYMBOL(nvm_bb_tbl_fold);
 
@@ -850,44 +854,9 @@ EXPORT_SYMBOL(nvm_get_tgt_bb_tbl);
 
 static int nvm_core_init(struct nvm_dev *dev)
 {
-	struct nvm_id *id = &dev->identity;
-	struct nvm_id_group *grp = &id->grp;
 	struct nvm_geo *geo = &dev->geo;
 	int ret;
 
-	memcpy(&geo->ppaf, &id->ppaf, sizeof(struct nvm_addr_format));
-
-	if (grp->mtype != 0) {
-		pr_err("nvm: memory type not supported\n");
-		return -EINVAL;
-	}
-
-	/* Whole device values */
-	geo->nr_chnls = grp->num_ch;
-	geo->nr_luns = grp->num_lun;
-
-	/* Generic device geometry values */
-	geo->ws_min = grp->ws_min;
-	geo->ws_opt = grp->ws_opt;
-	geo->ws_seq = grp->ws_seq;
-	geo->ws_per_chk = grp->ws_per_chk;
-	geo->nr_chks = grp->num_chk;
-	geo->sec_size = grp->csecs;
-	geo->oob_size = grp->sos;
-	geo->mccap = grp->mccap;
-	geo->max_rq_size = dev->ops->max_phys_sect * geo->sec_size;
-
-	geo->sec_per_chk = grp->clba;
-	geo->sec_per_lun = geo->sec_per_chk * geo->nr_chks;
-	geo->all_luns = geo->nr_luns * geo->nr_chnls;
-
-	/* 1.2 spec device geometry values */
-	geo->plane_mode = 1 << geo->ws_seq;
-	geo->nr_planes = geo->ws_opt / geo->ws_min;
-	geo->sec_per_pg = geo->ws_min;
-	geo->sec_per_pl = geo->sec_per_pg * geo->nr_planes;
-
-	dev->total_secs = geo->all_luns * geo->sec_per_lun;
 	dev->lun_map = kcalloc(BITS_TO_LONGS(geo->all_luns),
 					sizeof(unsigned long), GFP_KERNEL);
 	if (!dev->lun_map)
@@ -902,7 +871,6 @@ static int nvm_core_init(struct nvm_dev *dev)
 	if (ret)
 		goto err_fmtype;
 
-	blk_queue_logical_block_size(dev->q, geo->sec_size);
 	return 0;
 err_fmtype:
 	kfree(dev->lun_map);
@@ -927,18 +895,14 @@ static int nvm_init(struct nvm_dev *dev)
 	struct nvm_geo *geo = &dev->geo;
 	int ret = -EINVAL;
 
-	if (dev->ops->identity(dev, &dev->identity)) {
+	if (dev->ops->identity(dev)) {
 		pr_err("nvm: device could not be identified\n");
 		goto err;
 	}
 
-	pr_debug("nvm: ver:%x nvm_vendor:%x\n",
-			dev->identity.ver_id, dev->identity.vmnt);
-
-	if (dev->identity.ver_id != 1) {
-		pr_err("nvm: device not supported by kernel.");
-		goto err;
-	}
+	pr_debug("nvm: ver:%u.%u nvm_vendor:%x\n",
+				geo->major_ver_id, geo->minor_ver_id,
+				geo->vmnt);
 
 	ret = nvm_core_init(dev);
 	if (ret) {
@@ -946,10 +910,10 @@ static int nvm_init(struct nvm_dev *dev)
 		goto err;
 	}
 
-	pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n",
-			dev->name, geo->sec_per_pg, geo->nr_planes,
-			geo->ws_per_chk, geo->nr_chks,
-			geo->all_luns, geo->nr_chnls);
+	pr_info("nvm: registered %s [%u/%u/%u/%u/%u]\n",
+			dev->name, dev->geo.ws_min, dev->geo.ws_opt,
+			dev->geo.num_chk, dev->geo.all_luns,
+			dev->geo.num_ch);
 	return 0;
 err:
 	pr_err("nvm: failed to initialize nvm\n");
@@ -969,17 +933,10 @@ int nvm_register(struct nvm_dev *dev)
 	if (!dev->q || !dev->ops)
 		return -EINVAL;
 
-	if (dev->ops->max_phys_sect > 256) {
-		pr_info("nvm: max sectors supported is 256.\n");
-		return -EINVAL;
-	}
-
-	if (dev->ops->max_phys_sect > 1) {
-		dev->dma_pool = dev->ops->create_dma_pool(dev, "ppalist");
-		if (!dev->dma_pool) {
-			pr_err("nvm: could not create dma pool\n");
-			return -ENOMEM;
-		}
+	dev->dma_pool = dev->ops->create_dma_pool(dev, "ppalist");
+	if (!dev->dma_pool) {
+		pr_err("nvm: could not create dma pool\n");
+		return -ENOMEM;
 	}
 
 	ret = nvm_init(dev);
@@ -1040,9 +997,6 @@ static long nvm_ioctl_info(struct file *file, void __user *arg)
 	struct nvm_tgt_type *tt;
 	int tgt_iter = 0;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	info = memdup_user(arg, sizeof(struct nvm_ioctl_info));
 	if (IS_ERR(info))
 		return -EFAULT;
@@ -1081,9 +1035,6 @@ static long nvm_ioctl_get_devices(struct file *file, void __user *arg)
 	struct nvm_dev *dev;
 	int i = 0;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	devices = kzalloc(sizeof(struct nvm_ioctl_get_devices), GFP_KERNEL);
 	if (!devices)
 		return -ENOMEM;
@@ -1124,9 +1075,6 @@ static long nvm_ioctl_dev_create(struct file *file, void __user *arg)
 {
 	struct nvm_ioctl_create create;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	if (copy_from_user(&create, arg, sizeof(struct nvm_ioctl_create)))
 		return -EFAULT;
 
@@ -1162,9 +1110,6 @@ static long nvm_ioctl_dev_remove(struct file *file, void __user *arg)
 	struct nvm_dev *dev;
 	int ret = 0;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	if (copy_from_user(&remove, arg, sizeof(struct nvm_ioctl_remove)))
 		return -EFAULT;
 
@@ -1189,9 +1134,6 @@ static long nvm_ioctl_dev_init(struct file *file, void __user *arg)
 {
 	struct nvm_ioctl_dev_init init;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	if (copy_from_user(&init, arg, sizeof(struct nvm_ioctl_dev_init)))
 		return -EFAULT;
 
@@ -1208,9 +1150,6 @@ static long nvm_ioctl_dev_factory(struct file *file, void __user *arg)
 {
 	struct nvm_ioctl_dev_factory fact;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	if (copy_from_user(&fact, arg, sizeof(struct nvm_ioctl_dev_factory)))
 		return -EFAULT;
 
@@ -1226,6 +1165,9 @@ static long nvm_ctl_ioctl(struct file *file, uint cmd, unsigned long arg)
 {
 	void __user *argp = (void __user *)arg;
 
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
 	switch (cmd) {
 	case NVM_INFO:
 		return nvm_ioctl_info(file, argp);
diff --git a/drivers/lightnvm/pblk-cache.c b/drivers/lightnvm/pblk-cache.c
index 000fcad..29a2311 100644
--- a/drivers/lightnvm/pblk-cache.c
+++ b/drivers/lightnvm/pblk-cache.c
@@ -63,6 +63,8 @@ int pblk_write_to_cache(struct pblk *pblk, struct bio *bio, unsigned long flags)
 		bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE);
 	}
 
+	atomic64_add(nr_entries, &pblk->user_wa);
+
 #ifdef CONFIG_NVM_DEBUG
 	atomic_long_add(nr_entries, &pblk->inflight_writes);
 	atomic_long_add(nr_entries, &pblk->req_writes);
@@ -117,6 +119,8 @@ int pblk_write_gc_to_cache(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
 	WARN_ONCE(gc_rq->secs_to_gc != valid_entries,
 					"pblk: inconsistent GC write\n");
 
+	atomic64_add(valid_entries, &pblk->gc_wa);
+
 #ifdef CONFIG_NVM_DEBUG
 	atomic_long_add(valid_entries, &pblk->inflight_writes);
 	atomic_long_add(valid_entries, &pblk->recov_gc_writes);
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 0487b93..94d5d97 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -44,11 +44,12 @@ static void pblk_line_mark_bb(struct work_struct *work)
 }
 
 static void pblk_mark_bb(struct pblk *pblk, struct pblk_line *line,
-			 struct ppa_addr *ppa)
+			 struct ppa_addr ppa_addr)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
-	int pos = pblk_ppa_to_pos(geo, *ppa);
+	struct ppa_addr *ppa;
+	int pos = pblk_ppa_to_pos(geo, ppa_addr);
 
 	pr_debug("pblk: erase failed: line:%d, pos:%d\n", line->id, pos);
 	atomic_long_inc(&pblk->erase_failed);
@@ -58,26 +59,38 @@ static void pblk_mark_bb(struct pblk *pblk, struct pblk_line *line,
 		pr_err("pblk: attempted to erase bb: line:%d, pos:%d\n",
 							line->id, pos);
 
+	/* Not necessary to mark bad blocks on 2.0 spec. */
+	if (geo->version == NVM_OCSSD_SPEC_20)
+		return;
+
+	ppa = kmalloc(sizeof(struct ppa_addr), GFP_ATOMIC);
+	if (!ppa)
+		return;
+
+	*ppa = ppa_addr;
 	pblk_gen_run_ws(pblk, NULL, ppa, pblk_line_mark_bb,
 						GFP_ATOMIC, pblk->bb_wq);
 }
 
 static void __pblk_end_io_erase(struct pblk *pblk, struct nvm_rq *rqd)
 {
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	struct nvm_chk_meta *chunk;
 	struct pblk_line *line;
+	int pos;
 
 	line = &pblk->lines[pblk_ppa_to_line(rqd->ppa_addr)];
+	pos = pblk_ppa_to_pos(geo, rqd->ppa_addr);
+	chunk = &line->chks[pos];
+
 	atomic_dec(&line->left_seblks);
 
 	if (rqd->error) {
-		struct ppa_addr *ppa;
-
-		ppa = kmalloc(sizeof(struct ppa_addr), GFP_ATOMIC);
-		if (!ppa)
-			return;
-
-		*ppa = rqd->ppa_addr;
-		pblk_mark_bb(pblk, line, ppa);
+		chunk->state = NVM_CHK_ST_OFFLINE;
+		pblk_mark_bb(pblk, line, rqd->ppa_addr);
+	} else {
+		chunk->state = NVM_CHK_ST_FREE;
 	}
 
 	atomic_dec(&pblk->inflight_io);
@@ -92,6 +105,49 @@ static void pblk_end_io_erase(struct nvm_rq *rqd)
 	mempool_free(rqd, pblk->e_rq_pool);
 }
 
+/*
+ * Get information for all chunks from the device.
+ *
+ * The caller is responsible for freeing the returned structure
+ */
+struct nvm_chk_meta *pblk_chunk_get_info(struct pblk *pblk)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	struct nvm_chk_meta *meta;
+	struct ppa_addr ppa;
+	unsigned long len;
+	int ret;
+
+	ppa.ppa = 0;
+
+	len = geo->all_chunks * sizeof(*meta);
+	meta = kzalloc(len, GFP_KERNEL);
+	if (!meta)
+		return ERR_PTR(-ENOMEM);
+
+	ret = nvm_get_chunk_meta(dev, meta, ppa, geo->all_chunks);
+	if (ret) {
+		kfree(meta);
+		return ERR_PTR(-EIO);
+	}
+
+	return meta;
+}
+
+struct nvm_chk_meta *pblk_chunk_get_off(struct pblk *pblk,
+					      struct nvm_chk_meta *meta,
+					      struct ppa_addr ppa)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	int ch_off = ppa.m.grp * geo->num_chk * geo->num_lun;
+	int lun_off = ppa.m.pu * geo->num_chk;
+	int chk_off = ppa.m.chk;
+
+	return meta + ch_off + lun_off + chk_off;
+}
+
 void __pblk_map_invalidate(struct pblk *pblk, struct pblk_line *line,
 			   u64 paddr)
 {
@@ -613,7 +669,7 @@ static int pblk_line_submit_emeta_io(struct pblk *pblk, struct pblk_line *line,
 	memset(&rqd, 0, sizeof(struct nvm_rq));
 
 	rq_ppas = pblk_calc_secs(pblk, left_ppas, 0);
-	rq_len = rq_ppas * geo->sec_size;
+	rq_len = rq_ppas * geo->csecs;
 
 	bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len,
 					l_mg->emeta_alloc_type, GFP_KERNEL);
@@ -722,7 +778,7 @@ u64 pblk_line_smeta_start(struct pblk *pblk, struct pblk_line *line)
 	if (bit >= lm->blk_per_line)
 		return -1;
 
-	return bit * geo->sec_per_pl;
+	return bit * geo->ws_opt;
 }
 
 static int pblk_line_submit_smeta_io(struct pblk *pblk, struct pblk_line *line,
@@ -885,7 +941,7 @@ int pblk_line_erase(struct pblk *pblk, struct pblk_line *line)
 		}
 
 		ppa = pblk->luns[bit].bppa; /* set ch and lun */
-		ppa.g.blk = line->id;
+		ppa.a.blk = line->id;
 
 		atomic_dec(&line->left_eblks);
 		WARN_ON(test_and_set_bit(bit, line->erase_bitmap));
@@ -975,7 +1031,8 @@ static int pblk_line_init_metadata(struct pblk *pblk, struct pblk_line *line,
 	memcpy(smeta_buf->header.uuid, pblk->instance_uuid, 16);
 	smeta_buf->header.id = cpu_to_le32(line->id);
 	smeta_buf->header.type = cpu_to_le16(line->type);
-	smeta_buf->header.version = SMETA_VERSION;
+	smeta_buf->header.version_major = SMETA_VERSION_MAJOR;
+	smeta_buf->header.version_minor = SMETA_VERSION_MINOR;
 
 	/* Start metadata */
 	smeta_buf->seq_nr = cpu_to_le64(line->seq_nr);
@@ -998,6 +1055,12 @@ static int pblk_line_init_metadata(struct pblk *pblk, struct pblk_line *line,
 	/* End metadata */
 	memcpy(&emeta_buf->header, &smeta_buf->header,
 						sizeof(struct line_header));
+
+	emeta_buf->header.version_major = EMETA_VERSION_MAJOR;
+	emeta_buf->header.version_minor = EMETA_VERSION_MINOR;
+	emeta_buf->header.crc = cpu_to_le32(
+			pblk_calc_meta_header_crc(pblk, &emeta_buf->header));
+
 	emeta_buf->seq_nr = cpu_to_le64(line->seq_nr);
 	emeta_buf->nr_lbas = cpu_to_le64(line->sec_in_line);
 	emeta_buf->nr_valid_lbas = cpu_to_le64(0);
@@ -1018,28 +1081,26 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line,
 	struct nvm_geo *geo = &dev->geo;
 	struct pblk_line_meta *lm = &pblk->lm;
 	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
-	int nr_bb = 0;
 	u64 off;
 	int bit = -1;
+	int emeta_secs;
 
 	line->sec_in_line = lm->sec_per_line;
 
 	/* Capture bad block information on line mapping bitmaps */
 	while ((bit = find_next_bit(line->blk_bitmap, lm->blk_per_line,
 					bit + 1)) < lm->blk_per_line) {
-		off = bit * geo->sec_per_pl;
+		off = bit * geo->ws_opt;
 		bitmap_shift_left(l_mg->bb_aux, l_mg->bb_template, off,
 							lm->sec_per_line);
 		bitmap_or(line->map_bitmap, line->map_bitmap, l_mg->bb_aux,
 							lm->sec_per_line);
-		line->sec_in_line -= geo->sec_per_chk;
-		if (bit >= lm->emeta_bb)
-			nr_bb++;
+		line->sec_in_line -= geo->clba;
 	}
 
 	/* Mark smeta metadata sectors as bad sectors */
 	bit = find_first_zero_bit(line->blk_bitmap, lm->blk_per_line);
-	off = bit * geo->sec_per_pl;
+	off = bit * geo->ws_opt;
 	bitmap_set(line->map_bitmap, off, lm->smeta_sec);
 	line->sec_in_line -= lm->smeta_sec;
 	line->smeta_ssec = off;
@@ -1055,18 +1116,18 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line,
 	/* Mark emeta metadata sectors as bad sectors. We need to consider bad
 	 * blocks to make sure that there are enough sectors to store emeta
 	 */
-	off = lm->sec_per_line - lm->emeta_sec[0];
-	bitmap_set(line->invalid_bitmap, off, lm->emeta_sec[0]);
-	while (nr_bb) {
-		off -= geo->sec_per_pl;
+	emeta_secs = lm->emeta_sec[0];
+	off = lm->sec_per_line;
+	while (emeta_secs) {
+		off -= geo->ws_opt;
 		if (!test_bit(off, line->invalid_bitmap)) {
-			bitmap_set(line->invalid_bitmap, off, geo->sec_per_pl);
-			nr_bb--;
+			bitmap_set(line->invalid_bitmap, off, geo->ws_opt);
+			emeta_secs -= geo->ws_opt;
 		}
 	}
 
-	line->sec_in_line -= lm->emeta_sec[0];
 	line->emeta_ssec = off;
+	line->sec_in_line -= lm->emeta_sec[0];
 	line->nr_valid_lbas = 0;
 	line->left_msecs = line->sec_in_line;
 	*line->vsc = cpu_to_le32(line->sec_in_line);
@@ -1086,10 +1147,34 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line,
 	return 1;
 }
 
+static int pblk_prepare_new_line(struct pblk *pblk, struct pblk_line *line)
+{
+	struct pblk_line_meta *lm = &pblk->lm;
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	int blk_to_erase = atomic_read(&line->blk_in_line);
+	int i;
+
+	for (i = 0; i < lm->blk_per_line; i++) {
+		struct pblk_lun *rlun = &pblk->luns[i];
+		int pos = pblk_ppa_to_pos(geo, rlun->bppa);
+		int state = line->chks[pos].state;
+
+		/* Free chunks should not be erased */
+		if (state & NVM_CHK_ST_FREE) {
+			set_bit(pblk_ppa_to_pos(geo, rlun->bppa),
+							line->erase_bitmap);
+			blk_to_erase--;
+		}
+	}
+
+	return blk_to_erase;
+}
+
 static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
 {
 	struct pblk_line_meta *lm = &pblk->lm;
-	int blk_in_line = atomic_read(&line->blk_in_line);
+	int blk_to_erase;
 
 	line->map_bitmap = kzalloc(lm->sec_bitmap_len, GFP_ATOMIC);
 	if (!line->map_bitmap)
@@ -1102,7 +1187,21 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
 		return -ENOMEM;
 	}
 
+	/* Bad blocks do not need to be erased */
+	bitmap_copy(line->erase_bitmap, line->blk_bitmap, lm->blk_per_line);
+
 	spin_lock(&line->lock);
+
+	/* If we have not written to this line, we need to mark up free chunks
+	 * as already erased
+	 */
+	if (line->state == PBLK_LINESTATE_NEW) {
+		blk_to_erase = pblk_prepare_new_line(pblk, line);
+		line->state = PBLK_LINESTATE_FREE;
+	} else {
+		blk_to_erase = atomic_read(&line->blk_in_line);
+	}
+
 	if (line->state != PBLK_LINESTATE_FREE) {
 		kfree(line->map_bitmap);
 		kfree(line->invalid_bitmap);
@@ -1114,15 +1213,12 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
 
 	line->state = PBLK_LINESTATE_OPEN;
 
-	atomic_set(&line->left_eblks, blk_in_line);
-	atomic_set(&line->left_seblks, blk_in_line);
+	atomic_set(&line->left_eblks, blk_to_erase);
+	atomic_set(&line->left_seblks, blk_to_erase);
 
 	line->meta_distance = lm->meta_distance;
 	spin_unlock(&line->lock);
 
-	/* Bad blocks do not need to be erased */
-	bitmap_copy(line->erase_bitmap, line->blk_bitmap, lm->blk_per_line);
-
 	kref_init(&line->ref);
 
 	return 0;
@@ -1399,13 +1495,6 @@ struct pblk_line *pblk_line_replace_data(struct pblk *pblk)
 	l_mg->data_line = new;
 
 	spin_lock(&l_mg->free_lock);
-	if (pblk->state != PBLK_STATE_RUNNING) {
-		l_mg->data_line = NULL;
-		l_mg->data_next = NULL;
-		spin_unlock(&l_mg->free_lock);
-		goto out;
-	}
-
 	pblk_line_setup_metadata(new, l_mg, &pblk->lm);
 	spin_unlock(&l_mg->free_lock);
 
@@ -1585,12 +1674,14 @@ static void pblk_line_should_sync_meta(struct pblk *pblk)
 
 void pblk_line_close(struct pblk *pblk, struct pblk_line *line)
 {
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	struct pblk_line_meta *lm = &pblk->lm;
 	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	struct list_head *move_list;
+	int i;
 
 #ifdef CONFIG_NVM_DEBUG
-	struct pblk_line_meta *lm = &pblk->lm;
-
 	WARN(!bitmap_full(line->map_bitmap, lm->sec_per_line),
 				"pblk: corrupt closed line %d\n", line->id);
 #endif
@@ -1612,6 +1703,15 @@ void pblk_line_close(struct pblk *pblk, struct pblk_line *line)
 	line->smeta = NULL;
 	line->emeta = NULL;
 
+	for (i = 0; i < lm->blk_per_line; i++) {
+		struct pblk_lun *rlun = &pblk->luns[i];
+		int pos = pblk_ppa_to_pos(geo, rlun->bppa);
+		int state = line->chks[pos].state;
+
+		if (!(state & NVM_CHK_ST_OFFLINE))
+			state = NVM_CHK_ST_CLOSED;
+	}
+
 	spin_unlock(&line->lock);
 	spin_unlock(&l_mg->gc_lock);
 }
@@ -1622,11 +1722,16 @@ void pblk_line_close_meta(struct pblk *pblk, struct pblk_line *line)
 	struct pblk_line_meta *lm = &pblk->lm;
 	struct pblk_emeta *emeta = line->emeta;
 	struct line_emeta *emeta_buf = emeta->buf;
+	struct wa_counters *wa = emeta_to_wa(lm, emeta_buf);
 
 	/* No need for exact vsc value; avoid a big line lock and take aprox. */
 	memcpy(emeta_to_vsc(pblk, emeta_buf), l_mg->vsc_list, lm->vsc_list_len);
 	memcpy(emeta_to_bb(emeta_buf), line->blk_bitmap, lm->blk_bitmap_len);
 
+	wa->user = cpu_to_le64(atomic64_read(&pblk->user_wa));
+	wa->pad = cpu_to_le64(atomic64_read(&pblk->pad_wa));
+	wa->gc = cpu_to_le64(atomic64_read(&pblk->gc_wa));
+
 	emeta_buf->nr_valid_lbas = cpu_to_le64(line->nr_valid_lbas);
 	emeta_buf->crc = cpu_to_le32(pblk_calc_emeta_crc(pblk, emeta_buf));
 
@@ -1680,8 +1785,8 @@ static void __pblk_down_page(struct pblk *pblk, struct ppa_addr *ppa_list,
 	int i;
 
 	for (i = 1; i < nr_ppas; i++)
-		WARN_ON(ppa_list[0].g.lun != ppa_list[i].g.lun ||
-				ppa_list[0].g.ch != ppa_list[i].g.ch);
+		WARN_ON(ppa_list[0].a.lun != ppa_list[i].a.lun ||
+				ppa_list[0].a.ch != ppa_list[i].a.ch);
 #endif
 
 	ret = down_timeout(&rlun->wr_sem, msecs_to_jiffies(30000));
@@ -1725,8 +1830,8 @@ void pblk_up_page(struct pblk *pblk, struct ppa_addr *ppa_list, int nr_ppas)
 	int i;
 
 	for (i = 1; i < nr_ppas; i++)
-		WARN_ON(ppa_list[0].g.lun != ppa_list[i].g.lun ||
-				ppa_list[0].g.ch != ppa_list[i].g.ch);
+		WARN_ON(ppa_list[0].a.lun != ppa_list[i].a.lun ||
+				ppa_list[0].a.ch != ppa_list[i].a.ch);
 #endif
 
 	rlun = &pblk->luns[pos];
@@ -1739,10 +1844,10 @@ void pblk_up_rq(struct pblk *pblk, struct ppa_addr *ppa_list, int nr_ppas,
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
 	struct pblk_lun *rlun;
-	int nr_luns = geo->all_luns;
+	int num_lun = geo->all_luns;
 	int bit = -1;
 
-	while ((bit = find_next_bit(lun_bitmap, nr_luns, bit + 1)) < nr_luns) {
+	while ((bit = find_next_bit(lun_bitmap, num_lun, bit + 1)) < num_lun) {
 		rlun = &pblk->luns[bit];
 		up(&rlun->wr_sem);
 	}
@@ -1829,6 +1934,7 @@ void pblk_update_map_dev(struct pblk *pblk, sector_t lba,
 #endif
 	/* Invalidate and discard padded entries */
 	if (lba == ADDR_EMPTY) {
+		atomic64_inc(&pblk->pad_wa);
 #ifdef CONFIG_NVM_DEBUG
 		atomic_long_inc(&pblk->padded_wb);
 #endif
diff --git a/drivers/lightnvm/pblk-gc.c b/drivers/lightnvm/pblk-gc.c
index 3d89938..6851a5c 100644
--- a/drivers/lightnvm/pblk-gc.c
+++ b/drivers/lightnvm/pblk-gc.c
@@ -88,7 +88,7 @@ static void pblk_gc_line_ws(struct work_struct *work)
 
 	up(&gc->gc_sem);
 
-	gc_rq->data = vmalloc(gc_rq->nr_secs * geo->sec_size);
+	gc_rq->data = vmalloc(gc_rq->nr_secs * geo->csecs);
 	if (!gc_rq->data) {
 		pr_err("pblk: could not GC line:%d (%d/%d)\n",
 					line->id, *line->vsc, gc_rq->nr_secs);
@@ -147,10 +147,8 @@ static void pblk_gc_line_prepare_ws(struct work_struct *work)
 	int ret;
 
 	invalid_bitmap = kmalloc(lm->sec_bitmap_len, GFP_KERNEL);
-	if (!invalid_bitmap) {
-		pr_err("pblk: could not allocate GC invalid bitmap\n");
+	if (!invalid_bitmap)
 		goto fail_free_ws;
-	}
 
 	emeta_buf = pblk_malloc(lm->emeta_len[0], l_mg->emeta_alloc_type,
 								GFP_KERNEL);
@@ -666,12 +664,10 @@ void pblk_gc_exit(struct pblk *pblk)
 		kthread_stop(gc->gc_reader_ts);
 
 	flush_workqueue(gc->gc_reader_wq);
-	if (gc->gc_reader_wq)
-		destroy_workqueue(gc->gc_reader_wq);
+	destroy_workqueue(gc->gc_reader_wq);
 
 	flush_workqueue(gc->gc_line_reader_wq);
-	if (gc->gc_line_reader_wq)
-		destroy_workqueue(gc->gc_line_reader_wq);
+	destroy_workqueue(gc->gc_line_reader_wq);
 
 	if (gc->gc_writer_ts)
 		kthread_stop(gc->gc_writer_ts);
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 93d671c..91a5bc2 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -80,7 +80,7 @@ static size_t pblk_trans_map_size(struct pblk *pblk)
 {
 	int entry_size = 8;
 
-	if (pblk->ppaf_bitsize < 32)
+	if (pblk->addrf_len < 32)
 		entry_size = 4;
 
 	return entry_size * pblk->rl.nr_secs;
@@ -103,7 +103,40 @@ static void pblk_l2p_free(struct pblk *pblk)
 	vfree(pblk->trans_map);
 }
 
-static int pblk_l2p_init(struct pblk *pblk)
+static int pblk_l2p_recover(struct pblk *pblk, bool factory_init)
+{
+	struct pblk_line *line = NULL;
+
+	if (factory_init) {
+		pblk_setup_uuid(pblk);
+	} else {
+		line = pblk_recov_l2p(pblk);
+		if (IS_ERR(line)) {
+			pr_err("pblk: could not recover l2p table\n");
+			return -EFAULT;
+		}
+	}
+
+#ifdef CONFIG_NVM_DEBUG
+	pr_info("pblk init: L2P CRC: %x\n", pblk_l2p_crc(pblk));
+#endif
+
+	/* Free full lines directly as GC has not been started yet */
+	pblk_gc_free_full_lines(pblk);
+
+	if (!line) {
+		/* Configure next line for user data */
+		line = pblk_line_get_first_data(pblk);
+		if (!line) {
+			pr_err("pblk: line list corrupted\n");
+			return -EFAULT;
+		}
+	}
+
+	return 0;
+}
+
+static int pblk_l2p_init(struct pblk *pblk, bool factory_init)
 {
 	sector_t i;
 	struct ppa_addr ppa;
@@ -119,7 +152,7 @@ static int pblk_l2p_init(struct pblk *pblk)
 	for (i = 0; i < pblk->rl.nr_secs; i++)
 		pblk_trans_map_set(pblk, i, ppa);
 
-	return 0;
+	return pblk_l2p_recover(pblk, factory_init);
 }
 
 static void pblk_rwb_free(struct pblk *pblk)
@@ -146,7 +179,7 @@ static int pblk_rwb_init(struct pblk *pblk)
 		return -ENOMEM;
 
 	power_size = get_count_order(nr_entries);
-	power_seg_sz = get_count_order(geo->sec_size);
+	power_seg_sz = get_count_order(geo->csecs);
 
 	return pblk_rb_init(&pblk->rwb, entries, power_size, power_seg_sz);
 }
@@ -154,47 +187,103 @@ static int pblk_rwb_init(struct pblk *pblk)
 /* Minimum pages needed within a lun */
 #define ADDR_POOL_SIZE 64
 
-static int pblk_set_ppaf(struct pblk *pblk)
+static int pblk_set_addrf_12(struct nvm_geo *geo, struct nvm_addrf_12 *dst)
 {
-	struct nvm_tgt_dev *dev = pblk->dev;
-	struct nvm_geo *geo = &dev->geo;
-	struct nvm_addr_format ppaf = geo->ppaf;
+	struct nvm_addrf_12 *src = (struct nvm_addrf_12 *)&geo->addrf;
 	int power_len;
 
 	/* Re-calculate channel and lun format to adapt to configuration */
-	power_len = get_count_order(geo->nr_chnls);
-	if (1 << power_len != geo->nr_chnls) {
+	power_len = get_count_order(geo->num_ch);
+	if (1 << power_len != geo->num_ch) {
 		pr_err("pblk: supports only power-of-two channel config.\n");
 		return -EINVAL;
 	}
-	ppaf.ch_len = power_len;
+	dst->ch_len = power_len;
 
-	power_len = get_count_order(geo->nr_luns);
-	if (1 << power_len != geo->nr_luns) {
+	power_len = get_count_order(geo->num_lun);
+	if (1 << power_len != geo->num_lun) {
 		pr_err("pblk: supports only power-of-two LUN config.\n");
 		return -EINVAL;
 	}
-	ppaf.lun_len = power_len;
+	dst->lun_len = power_len;
 
-	pblk->ppaf.sec_offset = 0;
-	pblk->ppaf.pln_offset = ppaf.sect_len;
-	pblk->ppaf.ch_offset = pblk->ppaf.pln_offset + ppaf.pln_len;
-	pblk->ppaf.lun_offset = pblk->ppaf.ch_offset + ppaf.ch_len;
-	pblk->ppaf.pg_offset = pblk->ppaf.lun_offset + ppaf.lun_len;
-	pblk->ppaf.blk_offset = pblk->ppaf.pg_offset + ppaf.pg_len;
-	pblk->ppaf.sec_mask = (1ULL << ppaf.sect_len) - 1;
-	pblk->ppaf.pln_mask = ((1ULL << ppaf.pln_len) - 1) <<
-							pblk->ppaf.pln_offset;
-	pblk->ppaf.ch_mask = ((1ULL << ppaf.ch_len) - 1) <<
-							pblk->ppaf.ch_offset;
-	pblk->ppaf.lun_mask = ((1ULL << ppaf.lun_len) - 1) <<
-							pblk->ppaf.lun_offset;
-	pblk->ppaf.pg_mask = ((1ULL << ppaf.pg_len) - 1) <<
-							pblk->ppaf.pg_offset;
-	pblk->ppaf.blk_mask = ((1ULL << ppaf.blk_len) - 1) <<
-							pblk->ppaf.blk_offset;
+	dst->blk_len = src->blk_len;
+	dst->pg_len = src->pg_len;
+	dst->pln_len = src->pln_len;
+	dst->sec_len = src->sec_len;
 
-	pblk->ppaf_bitsize = pblk->ppaf.blk_offset + ppaf.blk_len;
+	dst->sec_offset = 0;
+	dst->pln_offset = dst->sec_len;
+	dst->ch_offset = dst->pln_offset + dst->pln_len;
+	dst->lun_offset = dst->ch_offset + dst->ch_len;
+	dst->pg_offset = dst->lun_offset + dst->lun_len;
+	dst->blk_offset = dst->pg_offset + dst->pg_len;
+
+	dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
+	dst->pln_mask = ((1ULL << dst->pln_len) - 1) << dst->pln_offset;
+	dst->ch_mask = ((1ULL << dst->ch_len) - 1) << dst->ch_offset;
+	dst->lun_mask = ((1ULL << dst->lun_len) - 1) << dst->lun_offset;
+	dst->pg_mask = ((1ULL << dst->pg_len) - 1) << dst->pg_offset;
+	dst->blk_mask = ((1ULL << dst->blk_len) - 1) << dst->blk_offset;
+
+	return dst->blk_offset + src->blk_len;
+}
+
+static int pblk_set_addrf_20(struct nvm_geo *geo, struct nvm_addrf *adst,
+			     struct pblk_addrf *udst)
+{
+	struct nvm_addrf *src = &geo->addrf;
+
+	adst->ch_len = get_count_order(geo->num_ch);
+	adst->lun_len = get_count_order(geo->num_lun);
+	adst->chk_len = src->chk_len;
+	adst->sec_len = src->sec_len;
+
+	adst->sec_offset = 0;
+	adst->ch_offset = adst->sec_len;
+	adst->lun_offset = adst->ch_offset + adst->ch_len;
+	adst->chk_offset = adst->lun_offset + adst->lun_len;
+
+	adst->sec_mask = ((1ULL << adst->sec_len) - 1) << adst->sec_offset;
+	adst->chk_mask = ((1ULL << adst->chk_len) - 1) << adst->chk_offset;
+	adst->lun_mask = ((1ULL << adst->lun_len) - 1) << adst->lun_offset;
+	adst->ch_mask = ((1ULL << adst->ch_len) - 1) << adst->ch_offset;
+
+	udst->sec_stripe = geo->ws_opt;
+	udst->ch_stripe = geo->num_ch;
+	udst->lun_stripe = geo->num_lun;
+
+	udst->sec_lun_stripe = udst->sec_stripe * udst->ch_stripe;
+	udst->sec_ws_stripe = udst->sec_lun_stripe * udst->lun_stripe;
+
+	return adst->chk_offset + adst->chk_len;
+}
+
+static int pblk_set_addrf(struct pblk *pblk)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	int mod;
+
+	switch (geo->version) {
+	case NVM_OCSSD_SPEC_12:
+		div_u64_rem(geo->clba, pblk->min_write_pgs, &mod);
+		if (mod) {
+			pr_err("pblk: bad configuration of sectors/pages\n");
+			return -EINVAL;
+		}
+
+		pblk->addrf_len = pblk_set_addrf_12(geo, (void *)&pblk->addrf);
+		break;
+	case NVM_OCSSD_SPEC_20:
+		pblk->addrf_len = pblk_set_addrf_20(geo, (void *)&pblk->addrf,
+								&pblk->uaddrf);
+		break;
+	default:
+		pr_err("pblk: OCSSD revision not supported (%d)\n",
+								geo->version);
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -252,16 +341,41 @@ static int pblk_core_init(struct pblk *pblk)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
+	int max_write_ppas;
 
-	pblk->pgs_in_buffer = NVM_MEM_PAGE_WRITE * geo->sec_per_pg *
-						geo->nr_planes * geo->all_luns;
+	atomic64_set(&pblk->user_wa, 0);
+	atomic64_set(&pblk->pad_wa, 0);
+	atomic64_set(&pblk->gc_wa, 0);
+	pblk->user_rst_wa = 0;
+	pblk->pad_rst_wa = 0;
+	pblk->gc_rst_wa = 0;
 
-	if (pblk_init_global_caches(pblk))
+	atomic64_set(&pblk->nr_flush, 0);
+	pblk->nr_flush_rst = 0;
+
+	pblk->pgs_in_buffer = geo->mw_cunits * geo->all_luns;
+
+	pblk->min_write_pgs = geo->ws_opt * (geo->csecs / PAGE_SIZE);
+	max_write_ppas = pblk->min_write_pgs * geo->all_luns;
+	pblk->max_write_pgs = min_t(int, max_write_ppas, NVM_MAX_VLBA);
+	pblk_set_sec_per_write(pblk, pblk->min_write_pgs);
+
+	if (pblk->max_write_pgs > PBLK_MAX_REQ_ADDRS) {
+		pr_err("pblk: vector list too big(%u > %u)\n",
+				pblk->max_write_pgs, PBLK_MAX_REQ_ADDRS);
+		return -EINVAL;
+	}
+
+	pblk->pad_dist = kzalloc((pblk->min_write_pgs - 1) * sizeof(atomic64_t),
+								GFP_KERNEL);
+	if (!pblk->pad_dist)
 		return -ENOMEM;
 
+	if (pblk_init_global_caches(pblk))
+		goto fail_free_pad_dist;
+
 	/* Internal bios can be at most the sectors signaled by the device. */
-	pblk->page_bio_pool = mempool_create_page_pool(nvm_max_phys_sects(dev),
-									0);
+	pblk->page_bio_pool = mempool_create_page_pool(NVM_MAX_VLBA, 0);
 	if (!pblk->page_bio_pool)
 		goto free_global_caches;
 
@@ -305,13 +419,11 @@ static int pblk_core_init(struct pblk *pblk)
 	if (!pblk->r_end_wq)
 		goto free_bb_wq;
 
-	if (pblk_set_ppaf(pblk))
-		goto free_r_end_wq;
-
-	if (pblk_rwb_init(pblk))
+	if (pblk_set_addrf(pblk))
 		goto free_r_end_wq;
 
 	INIT_LIST_HEAD(&pblk->compl_list);
+
 	return 0;
 
 free_r_end_wq:
@@ -334,6 +446,8 @@ static int pblk_core_init(struct pblk *pblk)
 	mempool_destroy(pblk->page_bio_pool);
 free_global_caches:
 	pblk_free_global_caches(pblk);
+fail_free_pad_dist:
+	kfree(pblk->pad_dist);
 	return -ENOMEM;
 }
 
@@ -355,39 +469,11 @@ static void pblk_core_free(struct pblk *pblk)
 	mempool_destroy(pblk->e_rq_pool);
 	mempool_destroy(pblk->w_rq_pool);
 
-	pblk_rwb_free(pblk);
-
 	pblk_free_global_caches(pblk);
+	kfree(pblk->pad_dist);
 }
 
-static void pblk_luns_free(struct pblk *pblk)
-{
-	kfree(pblk->luns);
-}
-
-static void pblk_free_line_bitmaps(struct pblk_line *line)
-{
-	kfree(line->blk_bitmap);
-	kfree(line->erase_bitmap);
-}
-
-static void pblk_lines_free(struct pblk *pblk)
-{
-	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
-	struct pblk_line *line;
-	int i;
-
-	spin_lock(&l_mg->free_lock);
-	for (i = 0; i < l_mg->nr_lines; i++) {
-		line = &pblk->lines[i];
-
-		pblk_line_free(pblk, line);
-		pblk_free_line_bitmaps(line);
-	}
-	spin_unlock(&l_mg->free_lock);
-}
-
-static void pblk_line_meta_free(struct pblk *pblk)
+static void pblk_line_mg_free(struct pblk *pblk)
 {
 	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	int i;
@@ -401,21 +487,41 @@ static void pblk_line_meta_free(struct pblk *pblk)
 		pblk_mfree(l_mg->eline_meta[i]->buf, l_mg->emeta_alloc_type);
 		kfree(l_mg->eline_meta[i]);
 	}
+}
 
+static void pblk_line_meta_free(struct pblk_line *line)
+{
+	kfree(line->blk_bitmap);
+	kfree(line->erase_bitmap);
+	kfree(line->chks);
+}
+
+static void pblk_lines_free(struct pblk *pblk)
+{
+	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
+	struct pblk_line *line;
+	int i;
+
+	spin_lock(&l_mg->free_lock);
+	for (i = 0; i < l_mg->nr_lines; i++) {
+		line = &pblk->lines[i];
+
+		pblk_line_free(pblk, line);
+		pblk_line_meta_free(line);
+	}
+	spin_unlock(&l_mg->free_lock);
+
+	pblk_line_mg_free(pblk);
+
+	kfree(pblk->luns);
 	kfree(pblk->lines);
 }
 
-static int pblk_bb_discovery(struct nvm_tgt_dev *dev, struct pblk_lun *rlun)
+static int pblk_bb_get_tbl(struct nvm_tgt_dev *dev, struct pblk_lun *rlun,
+			   u8 *blks, int nr_blks)
 {
-	struct nvm_geo *geo = &dev->geo;
 	struct ppa_addr ppa;
-	u8 *blks;
-	int nr_blks, ret;
-
-	nr_blks = geo->nr_chks * geo->plane_mode;
-	blks = kmalloc(nr_blks, GFP_KERNEL);
-	if (!blks)
-		return -ENOMEM;
+	int ret;
 
 	ppa.ppa = 0;
 	ppa.g.ch = rlun->bppa.g.ch;
@@ -423,69 +529,64 @@ static int pblk_bb_discovery(struct nvm_tgt_dev *dev, struct pblk_lun *rlun)
 
 	ret = nvm_get_tgt_bb_tbl(dev, ppa, blks);
 	if (ret)
-		goto out;
+		return ret;
 
 	nr_blks = nvm_bb_tbl_fold(dev->parent, blks, nr_blks);
-	if (nr_blks < 0) {
-		ret = nr_blks;
-		goto out;
-	}
-
-	rlun->bb_list = blks;
+	if (nr_blks < 0)
+		return -EIO;
 
 	return 0;
-out:
-	kfree(blks);
-	return ret;
 }
 
-static int pblk_bb_line(struct pblk *pblk, struct pblk_line *line,
-			int blk_per_line)
+static void *pblk_bb_get_meta(struct pblk *pblk)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	u8 *meta;
+	int i, nr_blks, blk_per_lun;
+	int ret;
+
+	blk_per_lun = geo->num_chk * geo->pln_mode;
+	nr_blks = blk_per_lun * geo->all_luns;
+
+	meta = kmalloc(nr_blks, GFP_KERNEL);
+	if (!meta)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < geo->all_luns; i++) {
+		struct pblk_lun *rlun = &pblk->luns[i];
+		u8 *meta_pos = meta + i * blk_per_lun;
+
+		ret = pblk_bb_get_tbl(dev, rlun, meta_pos, blk_per_lun);
+		if (ret) {
+			kfree(meta);
+			return ERR_PTR(-EIO);
+		}
+	}
+
+	return meta;
+}
+
+static void *pblk_chunk_get_meta(struct pblk *pblk)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+
+	if (geo->version == NVM_OCSSD_SPEC_12)
+		return pblk_bb_get_meta(pblk);
+	else
+		return pblk_chunk_get_info(pblk);
+}
+
+static int pblk_luns_init(struct pblk *pblk)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
 	struct pblk_lun *rlun;
-	int bb_cnt = 0;
 	int i;
 
-	for (i = 0; i < blk_per_line; i++) {
-		rlun = &pblk->luns[i];
-		if (rlun->bb_list[line->id] == NVM_BLK_T_FREE)
-			continue;
-
-		set_bit(pblk_ppa_to_pos(geo, rlun->bppa), line->blk_bitmap);
-		bb_cnt++;
-	}
-
-	return bb_cnt;
-}
-
-static int pblk_alloc_line_bitmaps(struct pblk *pblk, struct pblk_line *line)
-{
-	struct pblk_line_meta *lm = &pblk->lm;
-
-	line->blk_bitmap = kzalloc(lm->blk_bitmap_len, GFP_KERNEL);
-	if (!line->blk_bitmap)
-		return -ENOMEM;
-
-	line->erase_bitmap = kzalloc(lm->blk_bitmap_len, GFP_KERNEL);
-	if (!line->erase_bitmap) {
-		kfree(line->blk_bitmap);
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static int pblk_luns_init(struct pblk *pblk, struct ppa_addr *luns)
-{
-	struct nvm_tgt_dev *dev = pblk->dev;
-	struct nvm_geo *geo = &dev->geo;
-	struct pblk_lun *rlun;
-	int i, ret;
-
 	/* TODO: Implement unbalanced LUN support */
-	if (geo->nr_luns < 0) {
+	if (geo->num_lun < 0) {
 		pr_err("pblk: unbalanced LUN config.\n");
 		return -EINVAL;
 	}
@@ -497,58 +598,19 @@ static int pblk_luns_init(struct pblk *pblk, struct ppa_addr *luns)
 
 	for (i = 0; i < geo->all_luns; i++) {
 		/* Stripe across channels */
-		int ch = i % geo->nr_chnls;
-		int lun_raw = i / geo->nr_chnls;
-		int lunid = lun_raw + ch * geo->nr_luns;
+		int ch = i % geo->num_ch;
+		int lun_raw = i / geo->num_ch;
+		int lunid = lun_raw + ch * geo->num_lun;
 
 		rlun = &pblk->luns[i];
-		rlun->bppa = luns[lunid];
+		rlun->bppa = dev->luns[lunid];
 
 		sema_init(&rlun->wr_sem, 1);
-
-		ret = pblk_bb_discovery(dev, rlun);
-		if (ret) {
-			while (--i >= 0)
-				kfree(pblk->luns[i].bb_list);
-			return ret;
-		}
 	}
 
 	return 0;
 }
 
-static int pblk_lines_configure(struct pblk *pblk, int flags)
-{
-	struct pblk_line *line = NULL;
-	int ret = 0;
-
-	if (!(flags & NVM_TARGET_FACTORY)) {
-		line = pblk_recov_l2p(pblk);
-		if (IS_ERR(line)) {
-			pr_err("pblk: could not recover l2p table\n");
-			ret = -EFAULT;
-		}
-	}
-
-#ifdef CONFIG_NVM_DEBUG
-	pr_info("pblk init: L2P CRC: %x\n", pblk_l2p_crc(pblk));
-#endif
-
-	/* Free full lines directly as GC has not been started yet */
-	pblk_gc_free_full_lines(pblk);
-
-	if (!line) {
-		/* Configure next line for user data */
-		line = pblk_line_get_first_data(pblk);
-		if (!line) {
-			pr_err("pblk: line list corrupted\n");
-			ret = -EFAULT;
-		}
-	}
-
-	return ret;
-}
-
 /* See comment over struct line_emeta definition */
 static unsigned int calc_emeta_len(struct pblk *pblk)
 {
@@ -559,19 +621,19 @@ static unsigned int calc_emeta_len(struct pblk *pblk)
 
 	/* Round to sector size so that lba_list starts on its own sector */
 	lm->emeta_sec[1] = DIV_ROUND_UP(
-			sizeof(struct line_emeta) + lm->blk_bitmap_len,
-			geo->sec_size);
-	lm->emeta_len[1] = lm->emeta_sec[1] * geo->sec_size;
+			sizeof(struct line_emeta) + lm->blk_bitmap_len +
+			sizeof(struct wa_counters), geo->csecs);
+	lm->emeta_len[1] = lm->emeta_sec[1] * geo->csecs;
 
 	/* Round to sector size so that vsc_list starts on its own sector */
 	lm->dsec_per_line = lm->sec_per_line - lm->emeta_sec[0];
 	lm->emeta_sec[2] = DIV_ROUND_UP(lm->dsec_per_line * sizeof(u64),
-			geo->sec_size);
-	lm->emeta_len[2] = lm->emeta_sec[2] * geo->sec_size;
+			geo->csecs);
+	lm->emeta_len[2] = lm->emeta_sec[2] * geo->csecs;
 
 	lm->emeta_sec[3] = DIV_ROUND_UP(l_mg->nr_lines * sizeof(u32),
-			geo->sec_size);
-	lm->emeta_len[3] = lm->emeta_sec[3] * geo->sec_size;
+			geo->csecs);
+	lm->emeta_len[3] = lm->emeta_sec[3] * geo->csecs;
 
 	lm->vsc_list_len = l_mg->nr_lines * sizeof(u32);
 
@@ -602,23 +664,211 @@ static void pblk_set_provision(struct pblk *pblk, long nr_free_blks)
 	 * on user capacity consider only provisioned blocks
 	 */
 	pblk->rl.total_blocks = nr_free_blks;
-	pblk->rl.nr_secs = nr_free_blks * geo->sec_per_chk;
+	pblk->rl.nr_secs = nr_free_blks * geo->clba;
 
 	/* Consider sectors used for metadata */
 	sec_meta = (lm->smeta_sec + lm->emeta_sec[0]) * l_mg->nr_free_lines;
-	blk_meta = DIV_ROUND_UP(sec_meta, geo->sec_per_chk);
+	blk_meta = DIV_ROUND_UP(sec_meta, geo->clba);
 
-	pblk->capacity = (provisioned - blk_meta) * geo->sec_per_chk;
+	pblk->capacity = (provisioned - blk_meta) * geo->clba;
 
 	atomic_set(&pblk->rl.free_blocks, nr_free_blks);
 	atomic_set(&pblk->rl.free_user_blocks, nr_free_blks);
 }
 
-static int pblk_lines_alloc_metadata(struct pblk *pblk)
+static int pblk_setup_line_meta_12(struct pblk *pblk, struct pblk_line *line,
+				   void *chunk_meta)
 {
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	struct pblk_line_meta *lm = &pblk->lm;
+	int i, chk_per_lun, nr_bad_chks = 0;
+
+	chk_per_lun = geo->num_chk * geo->pln_mode;
+
+	for (i = 0; i < lm->blk_per_line; i++) {
+		struct pblk_lun *rlun = &pblk->luns[i];
+		struct nvm_chk_meta *chunk;
+		int pos = pblk_ppa_to_pos(geo, rlun->bppa);
+		u8 *lun_bb_meta = chunk_meta + pos * chk_per_lun;
+
+		chunk = &line->chks[pos];
+
+		/*
+		 * In 1.2 spec. chunk state is not persisted by the device. Thus
+		 * some of the values are reset each time pblk is instantiated.
+		 */
+		if (lun_bb_meta[line->id] == NVM_BLK_T_FREE)
+			chunk->state =  NVM_CHK_ST_FREE;
+		else
+			chunk->state = NVM_CHK_ST_OFFLINE;
+
+		chunk->type = NVM_CHK_TP_W_SEQ;
+		chunk->wi = 0;
+		chunk->slba = -1;
+		chunk->cnlb = geo->clba;
+		chunk->wp = 0;
+
+		if (!(chunk->state & NVM_CHK_ST_OFFLINE))
+			continue;
+
+		set_bit(pos, line->blk_bitmap);
+		nr_bad_chks++;
+	}
+
+	return nr_bad_chks;
+}
+
+static int pblk_setup_line_meta_20(struct pblk *pblk, struct pblk_line *line,
+				   struct nvm_chk_meta *meta)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	struct pblk_line_meta *lm = &pblk->lm;
+	int i, nr_bad_chks = 0;
+
+	for (i = 0; i < lm->blk_per_line; i++) {
+		struct pblk_lun *rlun = &pblk->luns[i];
+		struct nvm_chk_meta *chunk;
+		struct nvm_chk_meta *chunk_meta;
+		struct ppa_addr ppa;
+		int pos;
+
+		ppa = rlun->bppa;
+		pos = pblk_ppa_to_pos(geo, ppa);
+		chunk = &line->chks[pos];
+
+		ppa.m.chk = line->id;
+		chunk_meta = pblk_chunk_get_off(pblk, meta, ppa);
+
+		chunk->state = chunk_meta->state;
+		chunk->type = chunk_meta->type;
+		chunk->wi = chunk_meta->wi;
+		chunk->slba = chunk_meta->slba;
+		chunk->cnlb = chunk_meta->cnlb;
+		chunk->wp = chunk_meta->wp;
+
+		if (!(chunk->state & NVM_CHK_ST_OFFLINE))
+			continue;
+
+		if (chunk->type & NVM_CHK_TP_SZ_SPEC) {
+			WARN_ONCE(1, "pblk: custom-sized chunks unsupported\n");
+			continue;
+		}
+
+		set_bit(pos, line->blk_bitmap);
+		nr_bad_chks++;
+	}
+
+	return nr_bad_chks;
+}
+
+static long pblk_setup_line_meta(struct pblk *pblk, struct pblk_line *line,
+				 void *chunk_meta, int line_id)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
 	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	struct pblk_line_meta *lm = &pblk->lm;
-	int i;
+	long nr_bad_chks, chk_in_line;
+
+	line->pblk = pblk;
+	line->id = line_id;
+	line->type = PBLK_LINETYPE_FREE;
+	line->state = PBLK_LINESTATE_NEW;
+	line->gc_group = PBLK_LINEGC_NONE;
+	line->vsc = &l_mg->vsc_list[line_id];
+	spin_lock_init(&line->lock);
+
+	if (geo->version == NVM_OCSSD_SPEC_12)
+		nr_bad_chks = pblk_setup_line_meta_12(pblk, line, chunk_meta);
+	else
+		nr_bad_chks = pblk_setup_line_meta_20(pblk, line, chunk_meta);
+
+	chk_in_line = lm->blk_per_line - nr_bad_chks;
+	if (nr_bad_chks < 0 || nr_bad_chks > lm->blk_per_line ||
+					chk_in_line < lm->min_blk_line) {
+		line->state = PBLK_LINESTATE_BAD;
+		list_add_tail(&line->list, &l_mg->bad_list);
+		return 0;
+	}
+
+	atomic_set(&line->blk_in_line, chk_in_line);
+	list_add_tail(&line->list, &l_mg->free_list);
+	l_mg->nr_free_lines++;
+
+	return chk_in_line;
+}
+
+static int pblk_alloc_line_meta(struct pblk *pblk, struct pblk_line *line)
+{
+	struct pblk_line_meta *lm = &pblk->lm;
+
+	line->blk_bitmap = kzalloc(lm->blk_bitmap_len, GFP_KERNEL);
+	if (!line->blk_bitmap)
+		return -ENOMEM;
+
+	line->erase_bitmap = kzalloc(lm->blk_bitmap_len, GFP_KERNEL);
+	if (!line->erase_bitmap) {
+		kfree(line->blk_bitmap);
+		return -ENOMEM;
+	}
+
+	line->chks = kmalloc(lm->blk_per_line * sizeof(struct nvm_chk_meta),
+								GFP_KERNEL);
+	if (!line->chks) {
+		kfree(line->erase_bitmap);
+		kfree(line->blk_bitmap);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int pblk_line_mg_init(struct pblk *pblk)
+{
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
+	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
+	struct pblk_line_meta *lm = &pblk->lm;
+	int i, bb_distance;
+
+	l_mg->nr_lines = geo->num_chk;
+	l_mg->log_line = l_mg->data_line = NULL;
+	l_mg->l_seq_nr = l_mg->d_seq_nr = 0;
+	l_mg->nr_free_lines = 0;
+	bitmap_zero(&l_mg->meta_bitmap, PBLK_DATA_LINES);
+
+	INIT_LIST_HEAD(&l_mg->free_list);
+	INIT_LIST_HEAD(&l_mg->corrupt_list);
+	INIT_LIST_HEAD(&l_mg->bad_list);
+	INIT_LIST_HEAD(&l_mg->gc_full_list);
+	INIT_LIST_HEAD(&l_mg->gc_high_list);
+	INIT_LIST_HEAD(&l_mg->gc_mid_list);
+	INIT_LIST_HEAD(&l_mg->gc_low_list);
+	INIT_LIST_HEAD(&l_mg->gc_empty_list);
+
+	INIT_LIST_HEAD(&l_mg->emeta_list);
+
+	l_mg->gc_lists[0] = &l_mg->gc_high_list;
+	l_mg->gc_lists[1] = &l_mg->gc_mid_list;
+	l_mg->gc_lists[2] = &l_mg->gc_low_list;
+
+	spin_lock_init(&l_mg->free_lock);
+	spin_lock_init(&l_mg->close_lock);
+	spin_lock_init(&l_mg->gc_lock);
+
+	l_mg->vsc_list = kcalloc(l_mg->nr_lines, sizeof(__le32), GFP_KERNEL);
+	if (!l_mg->vsc_list)
+		goto fail;
+
+	l_mg->bb_template = kzalloc(lm->sec_bitmap_len, GFP_KERNEL);
+	if (!l_mg->bb_template)
+		goto fail_free_vsc_list;
+
+	l_mg->bb_aux = kzalloc(lm->sec_bitmap_len, GFP_KERNEL);
+	if (!l_mg->bb_aux)
+		goto fail_free_bb_template;
 
 	/* smeta is always small enough to fit on a kmalloc memory allocation,
 	 * emeta depends on the number of LUNs allocated to the pblk instance
@@ -664,13 +914,13 @@ static int pblk_lines_alloc_metadata(struct pblk *pblk)
 		}
 	}
 
-	l_mg->vsc_list = kcalloc(l_mg->nr_lines, sizeof(__le32), GFP_KERNEL);
-	if (!l_mg->vsc_list)
-		goto fail_free_emeta;
-
 	for (i = 0; i < l_mg->nr_lines; i++)
 		l_mg->vsc_list[i] = cpu_to_le32(EMPTY_ENTRY);
 
+	bb_distance = (geo->all_luns) * geo->ws_opt;
+	for (i = 0; i < lm->sec_per_line; i += bb_distance)
+		bitmap_set(l_mg->bb_template, i, geo->ws_opt);
+
 	return 0;
 
 fail_free_emeta:
@@ -681,50 +931,27 @@ static int pblk_lines_alloc_metadata(struct pblk *pblk)
 			kfree(l_mg->eline_meta[i]->buf);
 		kfree(l_mg->eline_meta[i]);
 	}
-
 fail_free_smeta:
 	for (i = 0; i < PBLK_DATA_LINES; i++)
 		kfree(l_mg->sline_meta[i]);
-
+	kfree(l_mg->bb_aux);
+fail_free_bb_template:
+	kfree(l_mg->bb_template);
+fail_free_vsc_list:
+	kfree(l_mg->vsc_list);
+fail:
 	return -ENOMEM;
 }
 
-static int pblk_lines_init(struct pblk *pblk)
+static int pblk_line_meta_init(struct pblk *pblk)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
-	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
 	struct pblk_line_meta *lm = &pblk->lm;
-	struct pblk_line *line;
 	unsigned int smeta_len, emeta_len;
-	long nr_bad_blks, nr_free_blks;
-	int bb_distance, max_write_ppas, mod;
-	int i, ret;
+	int i;
 
-	pblk->min_write_pgs = geo->sec_per_pl * (geo->sec_size / PAGE_SIZE);
-	max_write_ppas = pblk->min_write_pgs * geo->all_luns;
-	pblk->max_write_pgs = (max_write_ppas < nvm_max_phys_sects(dev)) ?
-				max_write_ppas : nvm_max_phys_sects(dev);
-	pblk_set_sec_per_write(pblk, pblk->min_write_pgs);
-
-	if (pblk->max_write_pgs > PBLK_MAX_REQ_ADDRS) {
-		pr_err("pblk: cannot support device max_phys_sect\n");
-		return -EINVAL;
-	}
-
-	div_u64_rem(geo->sec_per_chk, pblk->min_write_pgs, &mod);
-	if (mod) {
-		pr_err("pblk: bad configuration of sectors/pages\n");
-		return -EINVAL;
-	}
-
-	l_mg->nr_lines = geo->nr_chks;
-	l_mg->log_line = l_mg->data_line = NULL;
-	l_mg->l_seq_nr = l_mg->d_seq_nr = 0;
-	l_mg->nr_free_lines = 0;
-	bitmap_zero(&l_mg->meta_bitmap, PBLK_DATA_LINES);
-
-	lm->sec_per_line = geo->sec_per_chk * geo->all_luns;
+	lm->sec_per_line = geo->clba * geo->all_luns;
 	lm->blk_per_line = geo->all_luns;
 	lm->blk_bitmap_len = BITS_TO_LONGS(geo->all_luns) * sizeof(long);
 	lm->sec_bitmap_len = BITS_TO_LONGS(lm->sec_per_line) * sizeof(long);
@@ -738,8 +965,8 @@ static int pblk_lines_init(struct pblk *pblk)
 	 */
 	i = 1;
 add_smeta_page:
-	lm->smeta_sec = i * geo->sec_per_pl;
-	lm->smeta_len = lm->smeta_sec * geo->sec_size;
+	lm->smeta_sec = i * geo->ws_opt;
+	lm->smeta_len = lm->smeta_sec * geo->csecs;
 
 	smeta_len = sizeof(struct line_smeta) + lm->lun_bitmap_len;
 	if (smeta_len > lm->smeta_len) {
@@ -752,8 +979,8 @@ static int pblk_lines_init(struct pblk *pblk)
 	 */
 	i = 1;
 add_emeta_page:
-	lm->emeta_sec[0] = i * geo->sec_per_pl;
-	lm->emeta_len[0] = lm->emeta_sec[0] * geo->sec_size;
+	lm->emeta_sec[0] = i * geo->ws_opt;
+	lm->emeta_len[0] = lm->emeta_sec[0] * geo->csecs;
 
 	emeta_len = calc_emeta_len(pblk);
 	if (emeta_len > lm->emeta_len[0]) {
@@ -766,119 +993,75 @@ static int pblk_lines_init(struct pblk *pblk)
 	lm->min_blk_line = 1;
 	if (geo->all_luns > 1)
 		lm->min_blk_line += DIV_ROUND_UP(lm->smeta_sec +
-					lm->emeta_sec[0], geo->sec_per_chk);
+					lm->emeta_sec[0], geo->clba);
 
 	if (lm->min_blk_line > lm->blk_per_line) {
 		pr_err("pblk: config. not supported. Min. LUN in line:%d\n",
 							lm->blk_per_line);
-		ret = -EINVAL;
-		goto fail;
+		return -EINVAL;
 	}
 
-	ret = pblk_lines_alloc_metadata(pblk);
+	return 0;
+}
+
+static int pblk_lines_init(struct pblk *pblk)
+{
+	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
+	struct pblk_line *line;
+	void *chunk_meta;
+	long nr_free_chks = 0;
+	int i, ret;
+
+	ret = pblk_line_meta_init(pblk);
 	if (ret)
-		goto fail;
+		return ret;
 
-	l_mg->bb_template = kzalloc(lm->sec_bitmap_len, GFP_KERNEL);
-	if (!l_mg->bb_template) {
-		ret = -ENOMEM;
+	ret = pblk_line_mg_init(pblk);
+	if (ret)
+		return ret;
+
+	ret = pblk_luns_init(pblk);
+	if (ret)
 		goto fail_free_meta;
+
+	chunk_meta = pblk_chunk_get_meta(pblk);
+	if (IS_ERR(chunk_meta)) {
+		ret = PTR_ERR(chunk_meta);
+		goto fail_free_luns;
 	}
 
-	l_mg->bb_aux = kzalloc(lm->sec_bitmap_len, GFP_KERNEL);
-	if (!l_mg->bb_aux) {
-		ret = -ENOMEM;
-		goto fail_free_bb_template;
-	}
-
-	bb_distance = (geo->all_luns) * geo->sec_per_pl;
-	for (i = 0; i < lm->sec_per_line; i += bb_distance)
-		bitmap_set(l_mg->bb_template, i, geo->sec_per_pl);
-
-	INIT_LIST_HEAD(&l_mg->free_list);
-	INIT_LIST_HEAD(&l_mg->corrupt_list);
-	INIT_LIST_HEAD(&l_mg->bad_list);
-	INIT_LIST_HEAD(&l_mg->gc_full_list);
-	INIT_LIST_HEAD(&l_mg->gc_high_list);
-	INIT_LIST_HEAD(&l_mg->gc_mid_list);
-	INIT_LIST_HEAD(&l_mg->gc_low_list);
-	INIT_LIST_HEAD(&l_mg->gc_empty_list);
-
-	INIT_LIST_HEAD(&l_mg->emeta_list);
-
-	l_mg->gc_lists[0] = &l_mg->gc_high_list;
-	l_mg->gc_lists[1] = &l_mg->gc_mid_list;
-	l_mg->gc_lists[2] = &l_mg->gc_low_list;
-
-	spin_lock_init(&l_mg->free_lock);
-	spin_lock_init(&l_mg->close_lock);
-	spin_lock_init(&l_mg->gc_lock);
-
 	pblk->lines = kcalloc(l_mg->nr_lines, sizeof(struct pblk_line),
 								GFP_KERNEL);
 	if (!pblk->lines) {
 		ret = -ENOMEM;
-		goto fail_free_bb_aux;
+		goto fail_free_chunk_meta;
 	}
 
-	nr_free_blks = 0;
 	for (i = 0; i < l_mg->nr_lines; i++) {
-		int blk_in_line;
-
 		line = &pblk->lines[i];
 
-		line->pblk = pblk;
-		line->id = i;
-		line->type = PBLK_LINETYPE_FREE;
-		line->state = PBLK_LINESTATE_FREE;
-		line->gc_group = PBLK_LINEGC_NONE;
-		line->vsc = &l_mg->vsc_list[i];
-		spin_lock_init(&line->lock);
-
-		ret = pblk_alloc_line_bitmaps(pblk, line);
+		ret = pblk_alloc_line_meta(pblk, line);
 		if (ret)
 			goto fail_free_lines;
 
-		nr_bad_blks = pblk_bb_line(pblk, line, lm->blk_per_line);
-		if (nr_bad_blks < 0 || nr_bad_blks > lm->blk_per_line) {
-			pblk_free_line_bitmaps(line);
-			ret = -EINVAL;
-			goto fail_free_lines;
-		}
-
-		blk_in_line = lm->blk_per_line - nr_bad_blks;
-		if (blk_in_line < lm->min_blk_line) {
-			line->state = PBLK_LINESTATE_BAD;
-			list_add_tail(&line->list, &l_mg->bad_list);
-			continue;
-		}
-
-		nr_free_blks += blk_in_line;
-		atomic_set(&line->blk_in_line, blk_in_line);
-
-		l_mg->nr_free_lines++;
-		list_add_tail(&line->list, &l_mg->free_list);
+		nr_free_chks += pblk_setup_line_meta(pblk, line, chunk_meta, i);
 	}
 
-	pblk_set_provision(pblk, nr_free_blks);
+	pblk_set_provision(pblk, nr_free_chks);
 
-	/* Cleanup per-LUN bad block lists - managed within lines on run-time */
-	for (i = 0; i < geo->all_luns; i++)
-		kfree(pblk->luns[i].bb_list);
-
+	kfree(chunk_meta);
 	return 0;
+
 fail_free_lines:
 	while (--i >= 0)
-		pblk_free_line_bitmaps(&pblk->lines[i]);
-fail_free_bb_aux:
-	kfree(l_mg->bb_aux);
-fail_free_bb_template:
-	kfree(l_mg->bb_template);
+		pblk_line_meta_free(&pblk->lines[i]);
+	kfree(pblk->lines);
+fail_free_chunk_meta:
+	kfree(chunk_meta);
+fail_free_luns:
+	kfree(pblk->luns);
 fail_free_meta:
-	pblk_line_meta_free(pblk);
-fail:
-	for (i = 0; i < geo->all_luns; i++)
-		kfree(pblk->luns[i].bb_list);
+	pblk_line_mg_free(pblk);
 
 	return ret;
 }
@@ -912,18 +1095,17 @@ static void pblk_writer_stop(struct pblk *pblk)
 	WARN(pblk_rb_sync_count(&pblk->rwb),
 			"Stopping not fully synced write buffer\n");
 
+	del_timer_sync(&pblk->wtimer);
 	if (pblk->writer_ts)
 		kthread_stop(pblk->writer_ts);
-	del_timer(&pblk->wtimer);
 }
 
 static void pblk_free(struct pblk *pblk)
 {
-	pblk_luns_free(pblk);
 	pblk_lines_free(pblk);
-	pblk_line_meta_free(pblk);
-	pblk_core_free(pblk);
 	pblk_l2p_free(pblk);
+	pblk_rwb_free(pblk);
+	pblk_core_free(pblk);
 
 	kfree(pblk);
 }
@@ -970,9 +1152,17 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk,
 	struct pblk *pblk;
 	int ret;
 
-	if (dev->identity.dom & NVM_RSP_L2P) {
+	/* pblk supports 1.2 and 2.0 versions */
+	if (!(geo->version == NVM_OCSSD_SPEC_12 ||
+					geo->version == NVM_OCSSD_SPEC_20)) {
+		pr_err("pblk: OCSSD version not supported (%u)\n",
+							geo->version);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (geo->version == NVM_OCSSD_SPEC_12 && geo->dom & NVM_RSP_L2P) {
 		pr_err("pblk: host-side L2P table not supported. (%x)\n",
-							dev->identity.dom);
+							geo->dom);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -988,14 +1178,10 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk,
 	spin_lock_init(&pblk->trans_lock);
 	spin_lock_init(&pblk->lock);
 
-	if (flags & NVM_TARGET_FACTORY)
-		pblk_setup_uuid(pblk);
-
 #ifdef CONFIG_NVM_DEBUG
 	atomic_long_set(&pblk->inflight_writes, 0);
 	atomic_long_set(&pblk->padded_writes, 0);
 	atomic_long_set(&pblk->padded_wb, 0);
-	atomic_long_set(&pblk->nr_flush, 0);
 	atomic_long_set(&pblk->req_writes, 0);
 	atomic_long_set(&pblk->sub_writes, 0);
 	atomic_long_set(&pblk->sync_writes, 0);
@@ -1015,41 +1201,35 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk,
 	atomic_long_set(&pblk->write_failed, 0);
 	atomic_long_set(&pblk->erase_failed, 0);
 
-	ret = pblk_luns_init(pblk, dev->luns);
+	ret = pblk_core_init(pblk);
 	if (ret) {
-		pr_err("pblk: could not initialize luns\n");
+		pr_err("pblk: could not initialize core\n");
 		goto fail;
 	}
 
 	ret = pblk_lines_init(pblk);
 	if (ret) {
 		pr_err("pblk: could not initialize lines\n");
-		goto fail_free_luns;
-	}
-
-	ret = pblk_core_init(pblk);
-	if (ret) {
-		pr_err("pblk: could not initialize core\n");
-		goto fail_free_line_meta;
-	}
-
-	ret = pblk_l2p_init(pblk);
-	if (ret) {
-		pr_err("pblk: could not initialize maps\n");
 		goto fail_free_core;
 	}
 
-	ret = pblk_lines_configure(pblk, flags);
+	ret = pblk_rwb_init(pblk);
 	if (ret) {
-		pr_err("pblk: could not configure lines\n");
-		goto fail_free_l2p;
+		pr_err("pblk: could not initialize write buffer\n");
+		goto fail_free_lines;
+	}
+
+	ret = pblk_l2p_init(pblk, flags & NVM_TARGET_FACTORY);
+	if (ret) {
+		pr_err("pblk: could not initialize maps\n");
+		goto fail_free_rwb;
 	}
 
 	ret = pblk_writer_init(pblk);
 	if (ret) {
 		if (ret != -EINTR)
 			pr_err("pblk: could not initialize write thread\n");
-		goto fail_free_lines;
+		goto fail_free_l2p;
 	}
 
 	ret = pblk_gc_init(pblk);
@@ -1064,10 +1244,10 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk,
 
 	blk_queue_write_cache(tqueue, true, false);
 
-	tqueue->limits.discard_granularity = geo->sec_per_chk * geo->sec_size;
+	tqueue->limits.discard_granularity = geo->clba * geo->csecs;
 	tqueue->limits.discard_alignment = 0;
 	blk_queue_max_discard_sectors(tqueue, UINT_MAX >> 9);
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, tqueue);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, tqueue);
 
 	pr_info("pblk(%s): luns:%u, lines:%d, secs:%llu, buf entries:%u\n",
 			tdisk->disk_name,
@@ -1084,16 +1264,14 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk,
 
 fail_stop_writer:
 	pblk_writer_stop(pblk);
-fail_free_lines:
-	pblk_lines_free(pblk);
 fail_free_l2p:
 	pblk_l2p_free(pblk);
+fail_free_rwb:
+	pblk_rwb_free(pblk);
+fail_free_lines:
+	pblk_lines_free(pblk);
 fail_free_core:
 	pblk_core_free(pblk);
-fail_free_line_meta:
-	pblk_line_meta_free(pblk);
-fail_free_luns:
-	pblk_luns_free(pblk);
 fail:
 	kfree(pblk);
 	return ERR_PTR(ret);
diff --git a/drivers/lightnvm/pblk-map.c b/drivers/lightnvm/pblk-map.c
index 7445e64..20dbaa8 100644
--- a/drivers/lightnvm/pblk-map.c
+++ b/drivers/lightnvm/pblk-map.c
@@ -65,6 +65,8 @@ static void pblk_map_page_data(struct pblk *pblk, unsigned int sentry,
 			lba_list[paddr] = cpu_to_le64(w_ctx->lba);
 			if (lba_list[paddr] != addr_empty)
 				line->nr_valid_lbas++;
+			else
+				atomic64_inc(&pblk->pad_wa);
 		} else {
 			lba_list[paddr] = meta_list[i].lba = addr_empty;
 			__pblk_map_invalidate(pblk, line, paddr);
@@ -125,7 +127,7 @@ void pblk_map_erase_rq(struct pblk *pblk, struct nvm_rq *rqd,
 			atomic_dec(&e_line->left_eblks);
 
 			*erase_ppa = rqd->ppa_list[i];
-			erase_ppa->g.blk = e_line->id;
+			erase_ppa->a.blk = e_line->id;
 
 			spin_unlock(&e_line->lock);
 
@@ -166,6 +168,6 @@ void pblk_map_erase_rq(struct pblk *pblk, struct nvm_rq *rqd,
 		set_bit(bit, e_line->erase_bitmap);
 		atomic_dec(&e_line->left_eblks);
 		*erase_ppa = pblk->luns[bit].bppa; /* set ch and lun */
-		erase_ppa->g.blk = e_line->id;
+		erase_ppa->a.blk = e_line->id;
 	}
 }
diff --git a/drivers/lightnvm/pblk-rb.c b/drivers/lightnvm/pblk-rb.c
index ec8fc31..52fdd85 100644
--- a/drivers/lightnvm/pblk-rb.c
+++ b/drivers/lightnvm/pblk-rb.c
@@ -355,10 +355,13 @@ static int pblk_rb_flush_point_set(struct pblk_rb *rb, struct bio *bio,
 	struct pblk_rb_entry *entry;
 	unsigned int sync, flush_point;
 
+	pblk_rb_sync_init(rb, NULL);
 	sync = READ_ONCE(rb->sync);
 
-	if (pos == sync)
+	if (pos == sync) {
+		pblk_rb_sync_end(rb, NULL);
 		return 0;
+	}
 
 #ifdef CONFIG_NVM_DEBUG
 	atomic_inc(&rb->inflight_flush_point);
@@ -367,8 +370,6 @@ static int pblk_rb_flush_point_set(struct pblk_rb *rb, struct bio *bio,
 	flush_point = (pos == 0) ? (rb->nr_entries - 1) : (pos - 1);
 	entry = &rb->entries[flush_point];
 
-	pblk_rb_sync_init(rb, NULL);
-
 	/* Protect flush points */
 	smp_store_release(&rb->flush_point, flush_point);
 
@@ -437,9 +438,7 @@ static int pblk_rb_may_write_flush(struct pblk_rb *rb, unsigned int nr_entries,
 	if (bio->bi_opf & REQ_PREFLUSH) {
 		struct pblk *pblk = container_of(rb, struct pblk, rwb);
 
-#ifdef CONFIG_NVM_DEBUG
-		atomic_long_inc(&pblk->nr_flush);
-#endif
+		atomic64_inc(&pblk->nr_flush);
 		if (pblk_rb_flush_point_set(&pblk->rwb, bio, mem))
 			*io_ret = NVM_IO_OK;
 	}
@@ -620,11 +619,17 @@ unsigned int pblk_rb_read_to_bio(struct pblk_rb *rb, struct nvm_rq *rqd,
 			pr_err("pblk: could not pad page in write bio\n");
 			return NVM_IO_ERR;
 		}
+
+		if (pad < pblk->min_write_pgs)
+			atomic64_inc(&pblk->pad_dist[pad - 1]);
+		else
+			pr_warn("pblk: padding more than min. sectors\n");
+
+		atomic64_add(pad, &pblk->pad_wa);
 	}
 
 #ifdef CONFIG_NVM_DEBUG
-	atomic_long_add(pad, &((struct pblk *)
-			(container_of(rb, struct pblk, rwb)))->padded_writes);
+	atomic_long_add(pad, &pblk->padded_writes);
 #endif
 
 	return NVM_IO_OK;
diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c
index 2f76128..9eee10f 100644
--- a/drivers/lightnvm/pblk-read.c
+++ b/drivers/lightnvm/pblk-read.c
@@ -563,7 +563,7 @@ int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
 	if (!(gc_rq->secs_to_gc))
 		goto out;
 
-	data_len = (gc_rq->secs_to_gc) * geo->sec_size;
+	data_len = (gc_rq->secs_to_gc) * geo->csecs;
 	bio = pblk_bio_map_addr(pblk, gc_rq->data, gc_rq->secs_to_gc, data_len,
 						PBLK_VMALLOC_META, GFP_KERNEL);
 	if (IS_ERR(bio)) {
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
index 1d5e961..3e079c2 100644
--- a/drivers/lightnvm/pblk-recovery.c
+++ b/drivers/lightnvm/pblk-recovery.c
@@ -21,17 +21,15 @@ void pblk_submit_rec(struct work_struct *work)
 	struct pblk_rec_ctx *recovery =
 			container_of(work, struct pblk_rec_ctx, ws_rec);
 	struct pblk *pblk = recovery->pblk;
-	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_rq *rqd = recovery->rqd;
 	struct pblk_c_ctx *c_ctx = nvm_rq_to_pdu(rqd);
-	int max_secs = nvm_max_phys_sects(dev);
 	struct bio *bio;
 	unsigned int nr_rec_secs;
 	unsigned int pgs_read;
 	int ret;
 
 	nr_rec_secs = bitmap_weight((unsigned long int *)&rqd->ppa_status,
-								max_secs);
+								NVM_MAX_VLBA);
 
 	bio = bio_alloc(GFP_KERNEL, nr_rec_secs);
 
@@ -74,8 +72,6 @@ int pblk_recov_setup_rq(struct pblk *pblk, struct pblk_c_ctx *c_ctx,
 			struct pblk_rec_ctx *recovery, u64 *comp_bits,
 			unsigned int comp)
 {
-	struct nvm_tgt_dev *dev = pblk->dev;
-	int max_secs = nvm_max_phys_sects(dev);
 	struct nvm_rq *rec_rqd;
 	struct pblk_c_ctx *rec_ctx;
 	int nr_entries = c_ctx->nr_valid + c_ctx->nr_padded;
@@ -86,7 +82,7 @@ int pblk_recov_setup_rq(struct pblk *pblk, struct pblk_c_ctx *c_ctx,
 	/* Copy completion bitmap, but exclude the first X completed entries */
 	bitmap_shift_right((unsigned long int *)&rec_rqd->ppa_status,
 				(unsigned long int *)comp_bits,
-				comp, max_secs);
+				comp, NVM_MAX_VLBA);
 
 	/* Save the context for the entries that need to be re-written and
 	 * update current context with the completed entries.
@@ -188,7 +184,7 @@ static int pblk_calc_sec_in_line(struct pblk *pblk, struct pblk_line *line)
 	int nr_bb = bitmap_weight(line->blk_bitmap, lm->blk_per_line);
 
 	return lm->sec_per_line - lm->smeta_sec - lm->emeta_sec[0] -
-				nr_bb * geo->sec_per_chk;
+				nr_bb * geo->clba;
 }
 
 struct pblk_recov_alloc {
@@ -236,7 +232,7 @@ static int pblk_recov_read_oob(struct pblk *pblk, struct pblk_line *line,
 	rq_ppas = pblk_calc_secs(pblk, left_ppas, 0);
 	if (!rq_ppas)
 		rq_ppas = pblk->min_write_pgs;
-	rq_len = rq_ppas * geo->sec_size;
+	rq_len = rq_ppas * geo->csecs;
 
 	bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL);
 	if (IS_ERR(bio))
@@ -355,7 +351,7 @@ static int pblk_recov_pad_oob(struct pblk *pblk, struct pblk_line *line,
 	if (!pad_rq)
 		return -ENOMEM;
 
-	data = vzalloc(pblk->max_write_pgs * geo->sec_size);
+	data = vzalloc(pblk->max_write_pgs * geo->csecs);
 	if (!data) {
 		ret = -ENOMEM;
 		goto free_rq;
@@ -372,7 +368,7 @@ static int pblk_recov_pad_oob(struct pblk *pblk, struct pblk_line *line,
 		goto fail_free_pad;
 	}
 
-	rq_len = rq_ppas * geo->sec_size;
+	rq_len = rq_ppas * geo->csecs;
 
 	meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, &dma_meta_list);
 	if (!meta_list) {
@@ -513,7 +509,7 @@ static int pblk_recov_scan_all_oob(struct pblk *pblk, struct pblk_line *line,
 	rq_ppas = pblk_calc_secs(pblk, left_ppas, 0);
 	if (!rq_ppas)
 		rq_ppas = pblk->min_write_pgs;
-	rq_len = rq_ppas * geo->sec_size;
+	rq_len = rq_ppas * geo->csecs;
 
 	bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL);
 	if (IS_ERR(bio))
@@ -644,7 +640,7 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
 	rq_ppas = pblk_calc_secs(pblk, left_ppas, 0);
 	if (!rq_ppas)
 		rq_ppas = pblk->min_write_pgs;
-	rq_len = rq_ppas * geo->sec_size;
+	rq_len = rq_ppas * geo->csecs;
 
 	bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL);
 	if (IS_ERR(bio))
@@ -749,7 +745,7 @@ static int pblk_recov_l2p_from_oob(struct pblk *pblk, struct pblk_line *line)
 	ppa_list = (void *)(meta_list) + pblk_dma_meta_size;
 	dma_ppa_list = dma_meta_list + pblk_dma_meta_size;
 
-	data = kcalloc(pblk->max_write_pgs, geo->sec_size, GFP_KERNEL);
+	data = kcalloc(pblk->max_write_pgs, geo->csecs, GFP_KERNEL);
 	if (!data) {
 		ret = -ENOMEM;
 		goto free_meta_list;
@@ -826,6 +822,63 @@ static u64 pblk_line_emeta_start(struct pblk *pblk, struct pblk_line *line)
 	return emeta_start;
 }
 
+static int pblk_recov_check_line_version(struct pblk *pblk,
+					 struct line_emeta *emeta)
+{
+	struct line_header *header = &emeta->header;
+
+	if (header->version_major != EMETA_VERSION_MAJOR) {
+		pr_err("pblk: line major version mismatch: %d, expected: %d\n",
+		       header->version_major, EMETA_VERSION_MAJOR);
+		return 1;
+	}
+
+#ifdef NVM_DEBUG
+	if (header->version_minor > EMETA_VERSION_MINOR)
+		pr_info("pblk: newer line minor version found: %d\n", line_v);
+#endif
+
+	return 0;
+}
+
+static void pblk_recov_wa_counters(struct pblk *pblk,
+				   struct line_emeta *emeta)
+{
+	struct pblk_line_meta *lm = &pblk->lm;
+	struct line_header *header = &emeta->header;
+	struct wa_counters *wa = emeta_to_wa(lm, emeta);
+
+	/* WA counters were introduced in emeta version 0.2 */
+	if (header->version_major > 0 || header->version_minor >= 2) {
+		u64 user = le64_to_cpu(wa->user);
+		u64 pad = le64_to_cpu(wa->pad);
+		u64 gc = le64_to_cpu(wa->gc);
+
+		atomic64_set(&pblk->user_wa, user);
+		atomic64_set(&pblk->pad_wa, pad);
+		atomic64_set(&pblk->gc_wa, gc);
+
+		pblk->user_rst_wa = user;
+		pblk->pad_rst_wa = pad;
+		pblk->gc_rst_wa = gc;
+	}
+}
+
+static int pblk_line_was_written(struct pblk_line *line,
+			    struct pblk_line_meta *lm)
+{
+
+	int i;
+	int state_mask = NVM_CHK_ST_OFFLINE | NVM_CHK_ST_FREE;
+
+	for (i = 0; i < lm->blk_per_line; i++) {
+		if (!(line->chks[i].state & state_mask))
+			return 1;
+	}
+
+	return 0;
+}
+
 struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
 {
 	struct pblk_line_meta *lm = &pblk->lm;
@@ -862,6 +915,9 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
 		line->lun_bitmap = ((void *)(smeta_buf)) +
 						sizeof(struct line_smeta);
 
+		if (!pblk_line_was_written(line, lm))
+			continue;
+
 		/* Lines that cannot be read are assumed as not written here */
 		if (pblk_line_read_smeta(pblk, line))
 			continue;
@@ -873,9 +929,9 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
 		if (le32_to_cpu(smeta_buf->header.identifier) != PBLK_MAGIC)
 			continue;
 
-		if (smeta_buf->header.version != SMETA_VERSION) {
+		if (smeta_buf->header.version_major != SMETA_VERSION_MAJOR) {
 			pr_err("pblk: found incompatible line version %u\n",
-					le16_to_cpu(smeta_buf->header.version));
+					smeta_buf->header.version_major);
 			return ERR_PTR(-EINVAL);
 		}
 
@@ -943,6 +999,11 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
 			goto next;
 		}
 
+		if (pblk_recov_check_line_version(pblk, line->emeta->buf))
+			return ERR_PTR(-EINVAL);
+
+		pblk_recov_wa_counters(pblk, line->emeta->buf);
+
 		if (pblk_recov_l2p_from_emeta(pblk, line))
 			pblk_recov_l2p_from_oob(pblk, line);
 
diff --git a/drivers/lightnvm/pblk-rl.c b/drivers/lightnvm/pblk-rl.c
index 0d457b1..883a711 100644
--- a/drivers/lightnvm/pblk-rl.c
+++ b/drivers/lightnvm/pblk-rl.c
@@ -200,7 +200,7 @@ void pblk_rl_init(struct pblk_rl *rl, int budget)
 
 	/* Consider sectors used for metadata */
 	sec_meta = (lm->smeta_sec + lm->emeta_sec[0]) * l_mg->nr_free_lines;
-	blk_meta = DIV_ROUND_UP(sec_meta, geo->sec_per_chk);
+	blk_meta = DIV_ROUND_UP(sec_meta, geo->clba);
 
 	rl->high = pblk->op_blks - blk_meta - lm->blk_per_line;
 	rl->high_pw = get_count_order(rl->high);
diff --git a/drivers/lightnvm/pblk-sysfs.c b/drivers/lightnvm/pblk-sysfs.c
index 620bab8..e61909a 100644
--- a/drivers/lightnvm/pblk-sysfs.c
+++ b/drivers/lightnvm/pblk-sysfs.c
@@ -39,8 +39,8 @@ static ssize_t pblk_sysfs_luns_show(struct pblk *pblk, char *page)
 		sz += snprintf(page + sz, PAGE_SIZE - sz,
 				"pblk: pos:%d, ch:%d, lun:%d - %d\n",
 					i,
-					rlun->bppa.g.ch,
-					rlun->bppa.g.lun,
+					rlun->bppa.a.ch,
+					rlun->bppa.a.lun,
 					active);
 	}
 
@@ -115,24 +115,47 @@ static ssize_t pblk_sysfs_ppaf(struct pblk *pblk, char *page)
 	struct nvm_geo *geo = &dev->geo;
 	ssize_t sz = 0;
 
-	sz = snprintf(page, PAGE_SIZE - sz,
-		"g:(b:%d)blk:%d/%d,pg:%d/%d,lun:%d/%d,ch:%d/%d,pl:%d/%d,sec:%d/%d\n",
-		pblk->ppaf_bitsize,
-		pblk->ppaf.blk_offset, geo->ppaf.blk_len,
-		pblk->ppaf.pg_offset, geo->ppaf.pg_len,
-		pblk->ppaf.lun_offset, geo->ppaf.lun_len,
-		pblk->ppaf.ch_offset, geo->ppaf.ch_len,
-		pblk->ppaf.pln_offset, geo->ppaf.pln_len,
-		pblk->ppaf.sec_offset, geo->ppaf.sect_len);
+	if (geo->version == NVM_OCSSD_SPEC_12) {
+		struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->addrf;
+		struct nvm_addrf_12 *gppaf = (struct nvm_addrf_12 *)&geo->addrf;
 
-	sz += snprintf(page + sz, PAGE_SIZE - sz,
-		"d:blk:%d/%d,pg:%d/%d,lun:%d/%d,ch:%d/%d,pl:%d/%d,sec:%d/%d\n",
-		geo->ppaf.blk_offset, geo->ppaf.blk_len,
-		geo->ppaf.pg_offset, geo->ppaf.pg_len,
-		geo->ppaf.lun_offset, geo->ppaf.lun_len,
-		geo->ppaf.ch_offset, geo->ppaf.ch_len,
-		geo->ppaf.pln_offset, geo->ppaf.pln_len,
-		geo->ppaf.sect_offset, geo->ppaf.sect_len);
+		sz = snprintf(page, PAGE_SIZE,
+			"g:(b:%d)blk:%d/%d,pg:%d/%d,lun:%d/%d,ch:%d/%d,pl:%d/%d,sec:%d/%d\n",
+			pblk->addrf_len,
+			ppaf->blk_offset, ppaf->blk_len,
+			ppaf->pg_offset, ppaf->pg_len,
+			ppaf->lun_offset, ppaf->lun_len,
+			ppaf->ch_offset, ppaf->ch_len,
+			ppaf->pln_offset, ppaf->pln_len,
+			ppaf->sec_offset, ppaf->sec_len);
+
+		sz += snprintf(page + sz, PAGE_SIZE - sz,
+			"d:blk:%d/%d,pg:%d/%d,lun:%d/%d,ch:%d/%d,pl:%d/%d,sec:%d/%d\n",
+			gppaf->blk_offset, gppaf->blk_len,
+			gppaf->pg_offset, gppaf->pg_len,
+			gppaf->lun_offset, gppaf->lun_len,
+			gppaf->ch_offset, gppaf->ch_len,
+			gppaf->pln_offset, gppaf->pln_len,
+			gppaf->sec_offset, gppaf->sec_len);
+	} else {
+		struct nvm_addrf *ppaf = &pblk->addrf;
+		struct nvm_addrf *gppaf = &geo->addrf;
+
+		sz = snprintf(page, PAGE_SIZE,
+			"pblk:(s:%d)ch:%d/%d,lun:%d/%d,chk:%d/%d/sec:%d/%d\n",
+			pblk->addrf_len,
+			ppaf->ch_offset, ppaf->ch_len,
+			ppaf->lun_offset, ppaf->lun_len,
+			ppaf->chk_offset, ppaf->chk_len,
+			ppaf->sec_offset, ppaf->sec_len);
+
+		sz += snprintf(page + sz, PAGE_SIZE - sz,
+			"device:ch:%d/%d,lun:%d/%d,chk:%d/%d,sec:%d/%d\n",
+			gppaf->ch_offset, gppaf->ch_len,
+			gppaf->lun_offset, gppaf->lun_len,
+			gppaf->chk_offset, gppaf->chk_len,
+			gppaf->sec_offset, gppaf->sec_len);
+	}
 
 	return sz;
 }
@@ -288,7 +311,7 @@ static ssize_t pblk_sysfs_lines_info(struct pblk *pblk, char *page)
 				"blk_line:%d, sec_line:%d, sec_blk:%d\n",
 					lm->blk_per_line,
 					lm->sec_per_line,
-					geo->sec_per_chk);
+					geo->clba);
 
 	return sz;
 }
@@ -298,15 +321,104 @@ static ssize_t pblk_sysfs_get_sec_per_write(struct pblk *pblk, char *page)
 	return snprintf(page, PAGE_SIZE, "%d\n", pblk->sec_per_write);
 }
 
+static ssize_t pblk_get_write_amp(u64 user, u64 gc, u64 pad,
+				  char *page)
+{
+	int sz;
+
+
+	sz = snprintf(page, PAGE_SIZE,
+			"user:%lld gc:%lld pad:%lld WA:",
+			user, gc, pad);
+
+	if (!user) {
+		sz += snprintf(page + sz, PAGE_SIZE - sz, "NaN\n");
+	} else {
+		u64 wa_int;
+		u32 wa_frac;
+
+		wa_int = (user + gc + pad) * 100000;
+		wa_int = div_u64(wa_int, user);
+		wa_int = div_u64_rem(wa_int, 100000, &wa_frac);
+
+		sz += snprintf(page + sz, PAGE_SIZE - sz, "%llu.%05u\n",
+							wa_int, wa_frac);
+	}
+
+	return sz;
+}
+
+static ssize_t pblk_sysfs_get_write_amp_mileage(struct pblk *pblk, char *page)
+{
+	return pblk_get_write_amp(atomic64_read(&pblk->user_wa),
+		atomic64_read(&pblk->gc_wa), atomic64_read(&pblk->pad_wa),
+		page);
+}
+
+static ssize_t pblk_sysfs_get_write_amp_trip(struct pblk *pblk, char *page)
+{
+	return pblk_get_write_amp(
+		atomic64_read(&pblk->user_wa) - pblk->user_rst_wa,
+		atomic64_read(&pblk->gc_wa) - pblk->gc_rst_wa,
+		atomic64_read(&pblk->pad_wa) - pblk->pad_rst_wa, page);
+}
+
+static long long bucket_percentage(unsigned long long bucket,
+				   unsigned long long total)
+{
+	int p = bucket * 100;
+
+	p = div_u64(p, total);
+
+	return p;
+}
+
+static ssize_t pblk_sysfs_get_padding_dist(struct pblk *pblk, char *page)
+{
+	int sz = 0;
+	unsigned long long total;
+	unsigned long long total_buckets = 0;
+	int buckets = pblk->min_write_pgs - 1;
+	int i;
+
+	total = atomic64_read(&pblk->nr_flush) - pblk->nr_flush_rst;
+	if (!total) {
+		for (i = 0; i < (buckets + 1); i++)
+			sz += snprintf(page + sz, PAGE_SIZE - sz,
+				"%d:0 ", i);
+		sz += snprintf(page + sz, PAGE_SIZE - sz, "\n");
+
+		return sz;
+	}
+
+	for (i = 0; i < buckets; i++)
+		total_buckets += atomic64_read(&pblk->pad_dist[i]);
+
+	sz += snprintf(page + sz, PAGE_SIZE - sz, "0:%lld%% ",
+		bucket_percentage(total - total_buckets, total));
+
+	for (i = 0; i < buckets; i++) {
+		unsigned long long p;
+
+		p = bucket_percentage(atomic64_read(&pblk->pad_dist[i]),
+					  total);
+		sz += snprintf(page + sz, PAGE_SIZE - sz, "%d:%lld%% ",
+				i + 1, p);
+	}
+	sz += snprintf(page + sz, PAGE_SIZE - sz, "\n");
+
+	return sz;
+}
+
 #ifdef CONFIG_NVM_DEBUG
 static ssize_t pblk_sysfs_stats_debug(struct pblk *pblk, char *page)
 {
 	return snprintf(page, PAGE_SIZE,
-		"%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\n",
+		"%lu\t%lu\t%ld\t%llu\t%ld\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\n",
 			atomic_long_read(&pblk->inflight_writes),
 			atomic_long_read(&pblk->inflight_reads),
 			atomic_long_read(&pblk->req_writes),
-			atomic_long_read(&pblk->nr_flush),
+			(u64)atomic64_read(&pblk->nr_flush),
 			atomic_long_read(&pblk->padded_writes),
 			atomic_long_read(&pblk->padded_wb),
 			atomic_long_read(&pblk->sub_writes),
@@ -360,6 +472,56 @@ static ssize_t pblk_sysfs_set_sec_per_write(struct pblk *pblk,
 	return len;
 }
 
+static ssize_t pblk_sysfs_set_write_amp_trip(struct pblk *pblk,
+			const char *page, size_t len)
+{
+	size_t c_len;
+	int reset_value;
+
+	c_len = strcspn(page, "\n");
+	if (c_len >= len)
+		return -EINVAL;
+
+	if (kstrtouint(page, 0, &reset_value))
+		return -EINVAL;
+
+	if (reset_value !=  0)
+		return -EINVAL;
+
+	pblk->user_rst_wa = atomic64_read(&pblk->user_wa);
+	pblk->pad_rst_wa = atomic64_read(&pblk->pad_wa);
+	pblk->gc_rst_wa = atomic64_read(&pblk->gc_wa);
+
+	return len;
+}
+
+
+static ssize_t pblk_sysfs_set_padding_dist(struct pblk *pblk,
+			const char *page, size_t len)
+{
+	size_t c_len;
+	int reset_value;
+	int buckets = pblk->min_write_pgs - 1;
+	int i;
+
+	c_len = strcspn(page, "\n");
+	if (c_len >= len)
+		return -EINVAL;
+
+	if (kstrtouint(page, 0, &reset_value))
+		return -EINVAL;
+
+	if (reset_value !=  0)
+		return -EINVAL;
+
+	for (i = 0; i < buckets; i++)
+		atomic64_set(&pblk->pad_dist[i], 0);
+
+	pblk->nr_flush_rst = atomic64_read(&pblk->nr_flush);
+
+	return len;
+}
+
 static struct attribute sys_write_luns = {
 	.name = "write_luns",
 	.mode = 0444,
@@ -410,6 +572,21 @@ static struct attribute sys_max_sec_per_write = {
 	.mode = 0644,
 };
 
+static struct attribute sys_write_amp_mileage = {
+	.name = "write_amp_mileage",
+	.mode = 0444,
+};
+
+static struct attribute sys_write_amp_trip = {
+	.name = "write_amp_trip",
+	.mode = 0644,
+};
+
+static struct attribute sys_padding_dist = {
+	.name = "padding_dist",
+	.mode = 0644,
+};
+
 #ifdef CONFIG_NVM_DEBUG
 static struct attribute sys_stats_debug_attr = {
 	.name = "stats",
@@ -428,6 +605,9 @@ static struct attribute *pblk_attrs[] = {
 	&sys_stats_ppaf_attr,
 	&sys_lines_attr,
 	&sys_lines_info_attr,
+	&sys_write_amp_mileage,
+	&sys_write_amp_trip,
+	&sys_padding_dist,
 #ifdef CONFIG_NVM_DEBUG
 	&sys_stats_debug_attr,
 #endif
@@ -457,6 +637,12 @@ static ssize_t pblk_sysfs_show(struct kobject *kobj, struct attribute *attr,
 		return pblk_sysfs_lines_info(pblk, buf);
 	else if (strcmp(attr->name, "max_sec_per_write") == 0)
 		return pblk_sysfs_get_sec_per_write(pblk, buf);
+	else if (strcmp(attr->name, "write_amp_mileage") == 0)
+		return pblk_sysfs_get_write_amp_mileage(pblk, buf);
+	else if (strcmp(attr->name, "write_amp_trip") == 0)
+		return pblk_sysfs_get_write_amp_trip(pblk, buf);
+	else if (strcmp(attr->name, "padding_dist") == 0)
+		return pblk_sysfs_get_padding_dist(pblk, buf);
 #ifdef CONFIG_NVM_DEBUG
 	else if (strcmp(attr->name, "stats") == 0)
 		return pblk_sysfs_stats_debug(pblk, buf);
@@ -473,7 +659,10 @@ static ssize_t pblk_sysfs_store(struct kobject *kobj, struct attribute *attr,
 		return pblk_sysfs_gc_force(pblk, buf, len);
 	else if (strcmp(attr->name, "max_sec_per_write") == 0)
 		return pblk_sysfs_set_sec_per_write(pblk, buf, len);
-
+	else if (strcmp(attr->name, "write_amp_trip") == 0)
+		return pblk_sysfs_set_write_amp_trip(pblk, buf, len);
+	else if (strcmp(attr->name, "padding_dist") == 0)
+		return pblk_sysfs_set_padding_dist(pblk, buf, len);
 	return 0;
 }
 
diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c
index aae86ed..3e6f1eb 100644
--- a/drivers/lightnvm/pblk-write.c
+++ b/drivers/lightnvm/pblk-write.c
@@ -333,7 +333,7 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
 	m_ctx = nvm_rq_to_pdu(rqd);
 	m_ctx->private = meta_line;
 
-	rq_len = rq_ppas * geo->sec_size;
+	rq_len = rq_ppas * geo->csecs;
 	data = ((void *)emeta->buf) + emeta->mem;
 
 	bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 8c357fb..9c682ac 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -201,12 +201,6 @@ struct pblk_rb {
 
 struct pblk_lun {
 	struct ppa_addr bppa;
-
-	u8 *bb_list;			/* Bad block list for LUN. Only used on
-					 * bring up. Bad blocks are managed
-					 * within lines on run-time.
-					 */
-
 	struct semaphore wr_sem;
 };
 
@@ -303,6 +297,7 @@ enum {
 	PBLK_LINETYPE_DATA = 2,
 
 	/* Line state */
+	PBLK_LINESTATE_NEW = 9,
 	PBLK_LINESTATE_FREE = 10,
 	PBLK_LINESTATE_OPEN = 11,
 	PBLK_LINESTATE_CLOSED = 12,
@@ -320,14 +315,26 @@ enum {
 };
 
 #define PBLK_MAGIC 0x70626c6b /*pblk*/
-#define SMETA_VERSION cpu_to_le16(1)
+
+/* emeta/smeta persistent storage format versions:
+ * Changes in major version requires offline migration.
+ * Changes in minor version are handled automatically during
+ * recovery.
+ */
+
+#define SMETA_VERSION_MAJOR (0)
+#define SMETA_VERSION_MINOR (1)
+
+#define EMETA_VERSION_MAJOR (0)
+#define EMETA_VERSION_MINOR (2)
 
 struct line_header {
 	__le32 crc;
 	__le32 identifier;	/* pblk identifier */
 	__u8 uuid[16];		/* instance uuid */
 	__le16 type;		/* line type */
-	__le16 version;		/* type version */
+	__u8 version_major;	/* version major */
+	__u8 version_minor;	/* version minor */
 	__le32 id;		/* line id for current line */
 };
 
@@ -349,11 +356,13 @@ struct line_smeta {
 	__le64 lun_bitmap[];
 };
 
+
 /*
  * Metadata layout in media:
  *	First sector:
  *		1. struct line_emeta
  *		2. bad block bitmap (u64 * window_wr_lun)
+ *		3. write amplification counters
  *	Mid sectors (start at lbas_sector):
  *		3. nr_lbas (u64) forming lba list
  *	Last sectors (start at vsc_sector):
@@ -377,7 +386,15 @@ struct line_emeta {
 	__le32 next_id;		/* Line id for next line */
 	__le64 nr_lbas;		/* Number of lbas mapped in line */
 	__le64 nr_valid_lbas;	/* Number of valid lbas mapped in line */
-	__le64 bb_bitmap[];	/* Updated bad block bitmap for line */
+	__le64 bb_bitmap[];     /* Updated bad block bitmap for line */
+};
+
+
+/* Write amplification counters stored on media */
+struct wa_counters {
+	__le64 user;		/* Number of user written sectors */
+	__le64 gc;		/* Number of sectors written by GC*/
+	__le64 pad;		/* Number of padded sectors */
 };
 
 struct pblk_emeta {
@@ -410,6 +427,8 @@ struct pblk_line {
 
 	unsigned long *lun_bitmap;	/* Bitmap for LUNs mapped in line */
 
+	struct nvm_chk_meta *chks;	/* Chunks forming line */
+
 	struct pblk_smeta *smeta;	/* Start metadata */
 	struct pblk_emeta *emeta;	/* End medatada */
 
@@ -507,10 +526,11 @@ struct pblk_line_meta {
 	unsigned int smeta_sec;		/* Sectors needed for smeta */
 
 	unsigned int emeta_len[4];	/* Lengths for emeta:
-					 *  [0]: Total length
-					 *  [1]: struct line_emeta length
-					 *  [2]: L2P portion length
-					 *  [3]: vsc list length
+					 *  [0]: Total
+					 *  [1]: struct line_emeta +
+					 *       bb_bitmap + struct wa_counters
+					 *  [2]: L2P portion
+					 *  [3]: vsc
 					 */
 	unsigned int emeta_sec[4];	/* Sectors needed for emeta. Same layout
 					 * as emeta_len
@@ -534,21 +554,6 @@ struct pblk_line_meta {
 	unsigned int meta_distance;	/* Distance between data and metadata */
 };
 
-struct pblk_addr_format {
-	u64	ch_mask;
-	u64	lun_mask;
-	u64	pln_mask;
-	u64	blk_mask;
-	u64	pg_mask;
-	u64	sec_mask;
-	u8	ch_offset;
-	u8	lun_offset;
-	u8	pln_offset;
-	u8	blk_offset;
-	u8	pg_offset;
-	u8	sec_offset;
-};
-
 enum {
 	PBLK_STATE_RUNNING = 0,
 	PBLK_STATE_STOPPING = 1,
@@ -556,6 +561,18 @@ enum {
 	PBLK_STATE_STOPPED = 3,
 };
 
+/* Internal format to support not power-of-2 device formats */
+struct pblk_addrf {
+	/* gen to dev */
+	int sec_stripe;
+	int ch_stripe;
+	int lun_stripe;
+
+	/* dev to gen */
+	int sec_lun_stripe;
+	int sec_ws_stripe;
+};
+
 struct pblk {
 	struct nvm_tgt_dev *dev;
 	struct gendisk *disk;
@@ -568,8 +585,9 @@ struct pblk {
 	struct pblk_line_mgmt l_mg;		/* Line management */
 	struct pblk_line_meta lm;		/* Line metadata */
 
-	int ppaf_bitsize;
-	struct pblk_addr_format ppaf;
+	struct nvm_addrf addrf;		/* Aligned address format */
+	struct pblk_addrf uaddrf;	/* Unaligned address format */
+	int addrf_len;
 
 	struct pblk_rb rwb;
 
@@ -592,12 +610,27 @@ struct pblk {
 	int sec_per_write;
 
 	unsigned char instance_uuid[16];
+
+	/* Persistent write amplification counters, 4kb sector I/Os */
+	atomic64_t user_wa;		/* Sectors written by user */
+	atomic64_t gc_wa;		/* Sectors written by GC */
+	atomic64_t pad_wa;		/* Padded sectors written */
+
+	/* Reset values for delta write amplification measurements */
+	u64 user_rst_wa;
+	u64 gc_rst_wa;
+	u64 pad_rst_wa;
+
+	/* Counters used for calculating padding distribution */
+	atomic64_t *pad_dist;		/* Padding distribution buckets */
+	u64 nr_flush_rst;		/* Flushes reset value for pad dist.*/
+	atomic64_t nr_flush;		/* Number of flush/fua I/O */
+
 #ifdef CONFIG_NVM_DEBUG
-	/* All debug counters apply to 4kb sector I/Os */
+	/* Non-persistent debug counters, 4kb sector I/Os */
 	atomic_long_t inflight_writes;	/* Inflight writes (user and gc) */
 	atomic_long_t padded_writes;	/* Sectors padded due to flush/fua */
 	atomic_long_t padded_wb;	/* Sectors padded in write buffer */
-	atomic_long_t nr_flush;		/* Number of flush/fua I/O */
 	atomic_long_t req_writes;	/* Sectors stored on write buffer */
 	atomic_long_t sub_writes;	/* Sectors submitted from buffer */
 	atomic_long_t sync_writes;	/* Sectors synced to media */
@@ -712,6 +745,10 @@ void pblk_set_sec_per_write(struct pblk *pblk, int sec_per_write);
 int pblk_setup_w_rec_rq(struct pblk *pblk, struct nvm_rq *rqd,
 			struct pblk_c_ctx *c_ctx);
 void pblk_discard(struct pblk *pblk, struct bio *bio);
+struct nvm_chk_meta *pblk_chunk_get_info(struct pblk *pblk);
+struct nvm_chk_meta *pblk_chunk_get_off(struct pblk *pblk,
+					      struct nvm_chk_meta *lp,
+					      struct ppa_addr ppa);
 void pblk_log_write_err(struct pblk *pblk, struct nvm_rq *rqd);
 void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd);
 int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd);
@@ -888,6 +925,12 @@ static inline void *emeta_to_bb(struct line_emeta *emeta)
 	return emeta->bb_bitmap;
 }
 
+static inline void *emeta_to_wa(struct pblk_line_meta *lm,
+				struct line_emeta *emeta)
+{
+	return emeta->bb_bitmap + lm->blk_bitmap_len;
+}
+
 static inline void *emeta_to_lbas(struct pblk *pblk, struct line_emeta *emeta)
 {
 	return ((void *)emeta + pblk->lm.emeta_len[1]);
@@ -903,38 +946,60 @@ static inline int pblk_line_vsc(struct pblk_line *line)
 	return le32_to_cpu(*line->vsc);
 }
 
-#define NVM_MEM_PAGE_WRITE (8)
-
 static inline int pblk_pad_distance(struct pblk *pblk)
 {
 	struct nvm_tgt_dev *dev = pblk->dev;
 	struct nvm_geo *geo = &dev->geo;
 
-	return NVM_MEM_PAGE_WRITE * geo->all_luns * geo->sec_per_pl;
+	return geo->mw_cunits * geo->all_luns * geo->ws_opt;
 }
 
 static inline int pblk_ppa_to_line(struct ppa_addr p)
 {
-	return p.g.blk;
+	return p.a.blk;
 }
 
 static inline int pblk_ppa_to_pos(struct nvm_geo *geo, struct ppa_addr p)
 {
-	return p.g.lun * geo->nr_chnls + p.g.ch;
+	return p.a.lun * geo->num_ch + p.a.ch;
 }
 
 static inline struct ppa_addr addr_to_gen_ppa(struct pblk *pblk, u64 paddr,
 					      u64 line_id)
 {
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
 	struct ppa_addr ppa;
 
-	ppa.ppa = 0;
-	ppa.g.blk = line_id;
-	ppa.g.pg = (paddr & pblk->ppaf.pg_mask) >> pblk->ppaf.pg_offset;
-	ppa.g.lun = (paddr & pblk->ppaf.lun_mask) >> pblk->ppaf.lun_offset;
-	ppa.g.ch = (paddr & pblk->ppaf.ch_mask) >> pblk->ppaf.ch_offset;
-	ppa.g.pl = (paddr & pblk->ppaf.pln_mask) >> pblk->ppaf.pln_offset;
-	ppa.g.sec = (paddr & pblk->ppaf.sec_mask) >> pblk->ppaf.sec_offset;
+	if (geo->version == NVM_OCSSD_SPEC_12) {
+		struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->addrf;
+
+		ppa.ppa = 0;
+		ppa.g.blk = line_id;
+		ppa.g.pg = (paddr & ppaf->pg_mask) >> ppaf->pg_offset;
+		ppa.g.lun = (paddr & ppaf->lun_mask) >> ppaf->lun_offset;
+		ppa.g.ch = (paddr & ppaf->ch_mask) >> ppaf->ch_offset;
+		ppa.g.pl = (paddr & ppaf->pln_mask) >> ppaf->pln_offset;
+		ppa.g.sec = (paddr & ppaf->sec_mask) >> ppaf->sec_offset;
+	} else {
+		struct pblk_addrf *uaddrf = &pblk->uaddrf;
+		int secs, chnls, luns;
+
+		ppa.ppa = 0;
+
+		ppa.m.chk = line_id;
+
+		paddr = div_u64_rem(paddr, uaddrf->sec_stripe, &secs);
+		ppa.m.sec = secs;
+
+		paddr = div_u64_rem(paddr, uaddrf->ch_stripe, &chnls);
+		ppa.m.grp = chnls;
+
+		paddr = div_u64_rem(paddr, uaddrf->lun_stripe, &luns);
+		ppa.m.pu = luns;
+
+		ppa.m.sec += uaddrf->sec_stripe * paddr;
+	}
 
 	return ppa;
 }
@@ -942,13 +1007,30 @@ static inline struct ppa_addr addr_to_gen_ppa(struct pblk *pblk, u64 paddr,
 static inline u64 pblk_dev_ppa_to_line_addr(struct pblk *pblk,
 							struct ppa_addr p)
 {
+	struct nvm_tgt_dev *dev = pblk->dev;
+	struct nvm_geo *geo = &dev->geo;
 	u64 paddr;
 
-	paddr = (u64)p.g.pg << pblk->ppaf.pg_offset;
-	paddr |= (u64)p.g.lun << pblk->ppaf.lun_offset;
-	paddr |= (u64)p.g.ch << pblk->ppaf.ch_offset;
-	paddr |= (u64)p.g.pl << pblk->ppaf.pln_offset;
-	paddr |= (u64)p.g.sec << pblk->ppaf.sec_offset;
+	if (geo->version == NVM_OCSSD_SPEC_12) {
+		struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->addrf;
+
+		paddr = (u64)p.g.ch << ppaf->ch_offset;
+		paddr |= (u64)p.g.lun << ppaf->lun_offset;
+		paddr |= (u64)p.g.pg << ppaf->pg_offset;
+		paddr |= (u64)p.g.pl << ppaf->pln_offset;
+		paddr |= (u64)p.g.sec << ppaf->sec_offset;
+	} else {
+		struct pblk_addrf *uaddrf = &pblk->uaddrf;
+		u64 secs = p.m.sec;
+		int sec_stripe;
+
+		paddr = (u64)p.m.grp * uaddrf->sec_stripe;
+		paddr += (u64)p.m.pu * uaddrf->sec_lun_stripe;
+
+		secs = div_u64_rem(secs, uaddrf->sec_stripe, &sec_stripe);
+		paddr += secs * uaddrf->sec_ws_stripe;
+		paddr += sec_stripe;
+	}
 
 	return paddr;
 }
@@ -965,18 +1047,37 @@ static inline struct ppa_addr pblk_ppa32_to_ppa64(struct pblk *pblk, u32 ppa32)
 		ppa64.c.line = ppa32 & ((~0U) >> 1);
 		ppa64.c.is_cached = 1;
 	} else {
-		ppa64.g.blk = (ppa32 & pblk->ppaf.blk_mask) >>
-							pblk->ppaf.blk_offset;
-		ppa64.g.pg = (ppa32 & pblk->ppaf.pg_mask) >>
-							pblk->ppaf.pg_offset;
-		ppa64.g.lun = (ppa32 & pblk->ppaf.lun_mask) >>
-							pblk->ppaf.lun_offset;
-		ppa64.g.ch = (ppa32 & pblk->ppaf.ch_mask) >>
-							pblk->ppaf.ch_offset;
-		ppa64.g.pl = (ppa32 & pblk->ppaf.pln_mask) >>
-							pblk->ppaf.pln_offset;
-		ppa64.g.sec = (ppa32 & pblk->ppaf.sec_mask) >>
-							pblk->ppaf.sec_offset;
+		struct nvm_tgt_dev *dev = pblk->dev;
+		struct nvm_geo *geo = &dev->geo;
+
+		if (geo->version == NVM_OCSSD_SPEC_12) {
+			struct nvm_addrf_12 *ppaf =
+					(struct nvm_addrf_12 *)&pblk->addrf;
+
+			ppa64.g.ch = (ppa32 & ppaf->ch_mask) >>
+							ppaf->ch_offset;
+			ppa64.g.lun = (ppa32 & ppaf->lun_mask) >>
+							ppaf->lun_offset;
+			ppa64.g.blk = (ppa32 & ppaf->blk_mask) >>
+							ppaf->blk_offset;
+			ppa64.g.pg = (ppa32 & ppaf->pg_mask) >>
+							ppaf->pg_offset;
+			ppa64.g.pl = (ppa32 & ppaf->pln_mask) >>
+							ppaf->pln_offset;
+			ppa64.g.sec = (ppa32 & ppaf->sec_mask) >>
+							ppaf->sec_offset;
+		} else {
+			struct nvm_addrf *lbaf = &pblk->addrf;
+
+			ppa64.m.grp = (ppa32 & lbaf->ch_mask) >>
+							lbaf->ch_offset;
+			ppa64.m.pu = (ppa32 & lbaf->lun_mask) >>
+							lbaf->lun_offset;
+			ppa64.m.chk = (ppa32 & lbaf->chk_mask) >>
+							lbaf->chk_offset;
+			ppa64.m.sec = (ppa32 & lbaf->sec_mask) >>
+							lbaf->sec_offset;
+		}
 	}
 
 	return ppa64;
@@ -992,12 +1093,27 @@ static inline u32 pblk_ppa64_to_ppa32(struct pblk *pblk, struct ppa_addr ppa64)
 		ppa32 |= ppa64.c.line;
 		ppa32 |= 1U << 31;
 	} else {
-		ppa32 |= ppa64.g.blk << pblk->ppaf.blk_offset;
-		ppa32 |= ppa64.g.pg << pblk->ppaf.pg_offset;
-		ppa32 |= ppa64.g.lun << pblk->ppaf.lun_offset;
-		ppa32 |= ppa64.g.ch << pblk->ppaf.ch_offset;
-		ppa32 |= ppa64.g.pl << pblk->ppaf.pln_offset;
-		ppa32 |= ppa64.g.sec << pblk->ppaf.sec_offset;
+		struct nvm_tgt_dev *dev = pblk->dev;
+		struct nvm_geo *geo = &dev->geo;
+
+		if (geo->version == NVM_OCSSD_SPEC_12) {
+			struct nvm_addrf_12 *ppaf =
+					(struct nvm_addrf_12 *)&pblk->addrf;
+
+			ppa32 |= ppa64.g.ch << ppaf->ch_offset;
+			ppa32 |= ppa64.g.lun << ppaf->lun_offset;
+			ppa32 |= ppa64.g.blk << ppaf->blk_offset;
+			ppa32 |= ppa64.g.pg << ppaf->pg_offset;
+			ppa32 |= ppa64.g.pl << ppaf->pln_offset;
+			ppa32 |= ppa64.g.sec << ppaf->sec_offset;
+		} else {
+			struct nvm_addrf *lbaf = &pblk->addrf;
+
+			ppa32 |= ppa64.m.grp << lbaf->ch_offset;
+			ppa32 |= ppa64.m.pu << lbaf->lun_offset;
+			ppa32 |= ppa64.m.chk << lbaf->chk_offset;
+			ppa32 |= ppa64.m.sec << lbaf->sec_offset;
+		}
 	}
 
 	return ppa32;
@@ -1008,7 +1124,7 @@ static inline struct ppa_addr pblk_trans_map_get(struct pblk *pblk,
 {
 	struct ppa_addr ppa;
 
-	if (pblk->ppaf_bitsize < 32) {
+	if (pblk->addrf_len < 32) {
 		u32 *map = (u32 *)pblk->trans_map;
 
 		ppa = pblk_ppa32_to_ppa64(pblk, map[lba]);
@@ -1024,7 +1140,7 @@ static inline struct ppa_addr pblk_trans_map_get(struct pblk *pblk,
 static inline void pblk_trans_map_set(struct pblk *pblk, sector_t lba,
 						struct ppa_addr ppa)
 {
-	if (pblk->ppaf_bitsize < 32) {
+	if (pblk->addrf_len < 32) {
 		u32 *map = (u32 *)pblk->trans_map;
 
 		map[lba] = pblk_ppa64_to_ppa32(pblk, ppa);
@@ -1115,7 +1231,10 @@ static inline int pblk_set_progr_mode(struct pblk *pblk, int type)
 	struct nvm_geo *geo = &dev->geo;
 	int flags;
 
-	flags = geo->plane_mode >> 1;
+	if (geo->version == NVM_OCSSD_SPEC_20)
+		return 0;
+
+	flags = geo->pln_mode >> 1;
 
 	if (type == PBLK_WRITE)
 		flags |= NVM_IO_SCRAMBLE_ENABLE;
@@ -1134,9 +1253,12 @@ static inline int pblk_set_read_mode(struct pblk *pblk, int type)
 	struct nvm_geo *geo = &dev->geo;
 	int flags;
 
+	if (geo->version == NVM_OCSSD_SPEC_20)
+		return 0;
+
 	flags = NVM_IO_SUSPEND | NVM_IO_SCRAMBLE_ENABLE;
 	if (type == PBLK_READ_SEQUENTIAL)
-		flags |= geo->plane_mode >> 1;
+		flags |= geo->pln_mode >> 1;
 
 	return flags;
 }
@@ -1147,16 +1269,21 @@ static inline int pblk_io_aligned(struct pblk *pblk, int nr_secs)
 }
 
 #ifdef CONFIG_NVM_DEBUG
-static inline void print_ppa(struct ppa_addr *p, char *msg, int error)
+static inline void print_ppa(struct nvm_geo *geo, struct ppa_addr *p,
+			     char *msg, int error)
 {
 	if (p->c.is_cached) {
 		pr_err("ppa: (%s: %x) cache line: %llu\n",
 				msg, error, (u64)p->c.line);
-	} else {
+	} else if (geo->version == NVM_OCSSD_SPEC_12) {
 		pr_err("ppa: (%s: %x):ch:%d,lun:%d,blk:%d,pg:%d,pl:%d,sec:%d\n",
 			msg, error,
 			p->g.ch, p->g.lun, p->g.blk,
 			p->g.pg, p->g.pl, p->g.sec);
+	} else {
+		pr_err("ppa: (%s: %x):ch:%d,lun:%d,chk:%d,sec:%d\n",
+			msg, error,
+			p->m.grp, p->m.pu, p->m.chk, p->m.sec);
 	}
 }
 
@@ -1166,13 +1293,13 @@ static inline void pblk_print_failed_rqd(struct pblk *pblk, struct nvm_rq *rqd,
 	int bit = -1;
 
 	if (rqd->nr_ppas ==  1) {
-		print_ppa(&rqd->ppa_addr, "rqd", error);
+		print_ppa(&pblk->dev->geo, &rqd->ppa_addr, "rqd", error);
 		return;
 	}
 
 	while ((bit = find_next_bit((void *)&rqd->ppa_status, rqd->nr_ppas,
 						bit + 1)) < rqd->nr_ppas) {
-		print_ppa(&rqd->ppa_list[bit], "rqd", error);
+		print_ppa(&pblk->dev->geo, &rqd->ppa_list[bit], "rqd", error);
 	}
 
 	pr_err("error:%d, ppa_status:%llx\n", error, rqd->ppa_status);
@@ -1188,16 +1315,25 @@ static inline int pblk_boundary_ppa_checks(struct nvm_tgt_dev *tgt_dev,
 	for (i = 0; i < nr_ppas; i++) {
 		ppa = &ppas[i];
 
-		if (!ppa->c.is_cached &&
-				ppa->g.ch < geo->nr_chnls &&
-				ppa->g.lun < geo->nr_luns &&
-				ppa->g.pl < geo->nr_planes &&
-				ppa->g.blk < geo->nr_chks &&
-				ppa->g.pg < geo->ws_per_chk &&
-				ppa->g.sec < geo->sec_per_pg)
-			continue;
+		if (geo->version == NVM_OCSSD_SPEC_12) {
+			if (!ppa->c.is_cached &&
+					ppa->g.ch < geo->num_ch &&
+					ppa->g.lun < geo->num_lun &&
+					ppa->g.pl < geo->num_pln &&
+					ppa->g.blk < geo->num_chk &&
+					ppa->g.pg < geo->num_pg &&
+					ppa->g.sec < geo->ws_min)
+				continue;
+		} else {
+			if (!ppa->c.is_cached &&
+					ppa->m.grp < geo->num_ch &&
+					ppa->m.pu < geo->num_lun &&
+					ppa->m.chk < geo->num_chk &&
+					ppa->m.sec < geo->clba)
+				continue;
+		}
 
-		print_ppa(ppa, "boundary", i);
+		print_ppa(geo, ppa, "boundary", i);
 
 		return 1;
 	}
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index 458e1d3..004cc3c 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -287,7 +287,8 @@ do {									\
 			break;						\
 									\
 		mutex_unlock(&(ca)->set->bucket_lock);			\
-		if (kthread_should_stop()) {				\
+		if (kthread_should_stop() ||				\
+		    test_bit(CACHE_SET_IO_DISABLE, &ca->set->flags)) {	\
 			set_current_state(TASK_RUNNING);		\
 			return 0;					\
 		}							\
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 12e5197..d338b70 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -188,6 +188,7 @@
 #include <linux/refcount.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
+#include <linux/kthread.h>
 
 #include "bset.h"
 #include "util.h"
@@ -258,10 +259,11 @@ struct bcache_device {
 	struct gendisk		*disk;
 
 	unsigned long		flags;
-#define BCACHE_DEV_CLOSING	0
-#define BCACHE_DEV_DETACHING	1
-#define BCACHE_DEV_UNLINK_DONE	2
-
+#define BCACHE_DEV_CLOSING		0
+#define BCACHE_DEV_DETACHING		1
+#define BCACHE_DEV_UNLINK_DONE		2
+#define BCACHE_DEV_WB_RUNNING		3
+#define BCACHE_DEV_RATE_DW_RUNNING	4
 	unsigned		nr_stripes;
 	unsigned		stripe_size;
 	atomic_t		*stripe_sectors_dirty;
@@ -286,6 +288,12 @@ struct io {
 	sector_t		last;
 };
 
+enum stop_on_failure {
+	BCH_CACHED_DEV_STOP_AUTO = 0,
+	BCH_CACHED_DEV_STOP_ALWAYS,
+	BCH_CACHED_DEV_STOP_MODE_MAX,
+};
+
 struct cached_dev {
 	struct list_head	list;
 	struct bcache_device	disk;
@@ -359,6 +367,7 @@ struct cached_dev {
 	unsigned		sequential_cutoff;
 	unsigned		readahead;
 
+	unsigned		io_disable:1;
 	unsigned		verify:1;
 	unsigned		bypass_torture_test:1;
 
@@ -378,6 +387,11 @@ struct cached_dev {
 	unsigned		writeback_rate_i_term_inverse;
 	unsigned		writeback_rate_p_term_inverse;
 	unsigned		writeback_rate_minimum;
+
+	enum stop_on_failure	stop_when_cache_set_failed;
+#define DEFAULT_CACHED_DEV_ERROR_LIMIT	64
+	atomic_t		io_errors;
+	unsigned		error_limit;
 };
 
 enum alloc_reserve {
@@ -474,10 +488,15 @@ struct gc_stat {
  *
  * CACHE_SET_RUNNING means all cache devices have been registered and journal
  * replay is complete.
+ *
+ * CACHE_SET_IO_DISABLE is set when bcache is stopping the whold cache set, all
+ * external and internal I/O should be denied when this flag is set.
+ *
  */
 #define CACHE_SET_UNREGISTERING		0
 #define	CACHE_SET_STOPPING		1
 #define	CACHE_SET_RUNNING		2
+#define CACHE_SET_IO_DISABLE		3
 
 struct cache_set {
 	struct closure		cl;
@@ -867,8 +886,36 @@ static inline void wake_up_allocators(struct cache_set *c)
 		wake_up_process(ca->alloc_thread);
 }
 
+static inline void closure_bio_submit(struct cache_set *c,
+				      struct bio *bio,
+				      struct closure *cl)
+{
+	closure_get(cl);
+	if (unlikely(test_bit(CACHE_SET_IO_DISABLE, &c->flags))) {
+		bio->bi_status = BLK_STS_IOERR;
+		bio_endio(bio);
+		return;
+	}
+	generic_make_request(bio);
+}
+
+/*
+ * Prevent the kthread exits directly, and make sure when kthread_stop()
+ * is called to stop a kthread, it is still alive. If a kthread might be
+ * stopped by CACHE_SET_IO_DISABLE bit set, wait_for_kthread_stop() is
+ * necessary before the kthread returns.
+ */
+static inline void wait_for_kthread_stop(void)
+{
+	while (!kthread_should_stop()) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
+	}
+}
+
 /* Forward declarations */
 
+void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio);
 void bch_count_io_errors(struct cache *, blk_status_t, int, const char *);
 void bch_bbio_count_io_errors(struct cache_set *, struct bio *,
 			      blk_status_t, const char *);
@@ -896,6 +943,7 @@ int bch_bucket_alloc_set(struct cache_set *, unsigned,
 			 struct bkey *, int, bool);
 bool bch_alloc_sectors(struct cache_set *, struct bkey *, unsigned,
 		       unsigned, unsigned, bool);
+bool bch_cached_dev_error(struct cached_dev *dc);
 
 __printf(2, 3)
 bool bch_cache_set_error(struct cache_set *, const char *, ...);
@@ -905,6 +953,7 @@ void bch_write_bdev_super(struct cached_dev *, struct closure *);
 
 extern struct workqueue_struct *bcache_wq;
 extern const char * const bch_cache_modes[];
+extern const char * const bch_stop_on_failure_modes[];
 extern struct mutex bch_register_lock;
 extern struct list_head bch_cache_sets;
 
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c
index e56d3ec..579c696 100644
--- a/drivers/md/bcache/bset.c
+++ b/drivers/md/bcache/bset.c
@@ -1072,7 +1072,7 @@ EXPORT_SYMBOL(bch_btree_iter_init);
 static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter,
 						 btree_iter_cmp_fn *cmp)
 {
-	struct btree_iter_set unused;
+	struct btree_iter_set b __maybe_unused;
 	struct bkey *ret = NULL;
 
 	if (!btree_iter_end(iter)) {
@@ -1087,7 +1087,7 @@ static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter,
 		}
 
 		if (iter->data->k == iter->data->end)
-			heap_pop(iter, unused, cmp);
+			heap_pop(iter, b, cmp);
 		else
 			heap_sift(iter, 0, cmp);
 	}
diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h
index fa506c1..0c24280 100644
--- a/drivers/md/bcache/bset.h
+++ b/drivers/md/bcache/bset.h
@@ -531,14 +531,15 @@ int __bch_keylist_realloc(struct keylist *, unsigned);
 #ifdef CONFIG_BCACHE_DEBUG
 
 int __bch_count_data(struct btree_keys *);
-void __bch_check_keys(struct btree_keys *, const char *, ...);
+void __printf(2, 3) __bch_check_keys(struct btree_keys *, const char *, ...);
 void bch_dump_bset(struct btree_keys *, struct bset *, unsigned);
 void bch_dump_bucket(struct btree_keys *);
 
 #else
 
 static inline int __bch_count_data(struct btree_keys *b) { return -1; }
-static inline void __bch_check_keys(struct btree_keys *b, const char *fmt, ...) {}
+static inline void __printf(2, 3)
+	__bch_check_keys(struct btree_keys *b, const char *fmt, ...) {}
 static inline void bch_dump_bucket(struct btree_keys *b) {}
 void bch_dump_bset(struct btree_keys *, struct bset *, unsigned);
 
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index fad9fe8..17936b2 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -665,6 +665,7 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
 	struct btree *b, *t;
 	unsigned long i, nr = sc->nr_to_scan;
 	unsigned long freed = 0;
+	unsigned int btree_cache_used;
 
 	if (c->shrinker_disabled)
 		return SHRINK_STOP;
@@ -689,9 +690,10 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
 	nr = min_t(unsigned long, nr, mca_can_free(c));
 
 	i = 0;
+	btree_cache_used = c->btree_cache_used;
 	list_for_each_entry_safe(b, t, &c->btree_cache_freeable, list) {
-		if (freed >= nr)
-			break;
+		if (nr <= 0)
+			goto out;
 
 		if (++i > 3 &&
 		    !mca_reap(b, 0, false)) {
@@ -699,9 +701,10 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
 			rw_unlock(true, b);
 			freed++;
 		}
+		nr--;
 	}
 
-	for (i = 0; (nr--) && i < c->btree_cache_used; i++) {
+	for (;  (nr--) && i < btree_cache_used; i++) {
 		if (list_empty(&c->btree_cache))
 			goto out;
 
@@ -719,7 +722,7 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
 	}
 out:
 	mutex_unlock(&c->bucket_lock);
-	return freed;
+	return freed * c->btree_pages;
 }
 
 static unsigned long bch_mca_count(struct shrinker *shrink,
@@ -959,7 +962,7 @@ static struct btree *mca_alloc(struct cache_set *c, struct btree_op *op,
 	return b;
 }
 
-/**
+/*
  * bch_btree_node_get - find a btree node in the cache and lock it, reading it
  * in from disk if necessary.
  *
@@ -1744,6 +1747,7 @@ static void bch_btree_gc(struct cache_set *c)
 
 	btree_gc_start(c);
 
+	/* if CACHE_SET_IO_DISABLE set, gc thread should stop too */
 	do {
 		ret = btree_root(gc_root, c, &op, &writes, &stats);
 		closure_sync(&writes);
@@ -1751,7 +1755,7 @@ static void bch_btree_gc(struct cache_set *c)
 
 		if (ret && ret != -EAGAIN)
 			pr_warn("gc failed!");
-	} while (ret);
+	} while (ret && !test_bit(CACHE_SET_IO_DISABLE, &c->flags));
 
 	bch_btree_gc_finish(c);
 	wake_up_allocators(c);
@@ -1789,15 +1793,19 @@ static int bch_gc_thread(void *arg)
 
 	while (1) {
 		wait_event_interruptible(c->gc_wait,
-			   kthread_should_stop() || gc_should_run(c));
+			   kthread_should_stop() ||
+			   test_bit(CACHE_SET_IO_DISABLE, &c->flags) ||
+			   gc_should_run(c));
 
-		if (kthread_should_stop())
+		if (kthread_should_stop() ||
+		    test_bit(CACHE_SET_IO_DISABLE, &c->flags))
 			break;
 
 		set_gc_sectors(c);
 		bch_btree_gc(c);
 	}
 
+	wait_for_kthread_stop();
 	return 0;
 }
 
@@ -2170,7 +2178,7 @@ int bch_btree_insert_check_key(struct btree *b, struct btree_op *op,
 
 		if (b->key.ptr[0] != btree_ptr ||
                    b->seq != seq + 1) {
-                       op->lock = b->level;
+			op->lock = b->level;
 			goto out;
                }
 	}
diff --git a/drivers/md/bcache/closure.c b/drivers/md/bcache/closure.c
index 7f12920..0e14969 100644
--- a/drivers/md/bcache/closure.c
+++ b/drivers/md/bcache/closure.c
@@ -46,7 +46,7 @@ void closure_sub(struct closure *cl, int v)
 }
 EXPORT_SYMBOL(closure_sub);
 
-/**
+/*
  * closure_put - decrement a closure's refcount
  */
 void closure_put(struct closure *cl)
@@ -55,7 +55,7 @@ void closure_put(struct closure *cl)
 }
 EXPORT_SYMBOL(closure_put);
 
-/**
+/*
  * closure_wake_up - wake up all closures on a wait list, without memory barrier
  */
 void __closure_wake_up(struct closure_waitlist *wait_list)
@@ -79,9 +79,9 @@ EXPORT_SYMBOL(__closure_wake_up);
 
 /**
  * closure_wait - add a closure to a waitlist
- *
- * @waitlist will own a ref on @cl, which will be released when
+ * @waitlist: will own a ref on @cl, which will be released when
  * closure_wake_up() is called on @waitlist.
+ * @cl: closure pointer.
  *
  */
 bool closure_wait(struct closure_waitlist *waitlist, struct closure *cl)
@@ -157,7 +157,7 @@ void closure_debug_destroy(struct closure *cl)
 }
 EXPORT_SYMBOL(closure_debug_destroy);
 
-static struct dentry *debug;
+static struct dentry *closure_debug;
 
 static int debug_seq_show(struct seq_file *f, void *data)
 {
@@ -199,11 +199,12 @@ static const struct file_operations debug_ops = {
 	.release	= single_release
 };
 
-void __init closure_debug_init(void)
+int __init closure_debug_init(void)
 {
-	debug = debugfs_create_file("closures", 0400, NULL, NULL, &debug_ops);
+	closure_debug = debugfs_create_file("closures",
+				0400, bcache_debug, NULL, &debug_ops);
+	return IS_ERR_OR_NULL(closure_debug);
 }
-
 #endif
 
 MODULE_AUTHOR("Kent Overstreet <koverstreet@google.com>");
diff --git a/drivers/md/bcache/closure.h b/drivers/md/bcache/closure.h
index 3b9dfc9..71427eb 100644
--- a/drivers/md/bcache/closure.h
+++ b/drivers/md/bcache/closure.h
@@ -105,6 +105,7 @@
 struct closure;
 struct closure_syncer;
 typedef void (closure_fn) (struct closure *);
+extern struct dentry *bcache_debug;
 
 struct closure_waitlist {
 	struct llist_head	list;
@@ -185,13 +186,13 @@ static inline void closure_sync(struct closure *cl)
 
 #ifdef CONFIG_BCACHE_CLOSURES_DEBUG
 
-void closure_debug_init(void);
+int closure_debug_init(void);
 void closure_debug_create(struct closure *cl);
 void closure_debug_destroy(struct closure *cl);
 
 #else
 
-static inline void closure_debug_init(void) {}
+static inline int closure_debug_init(void) { return 0; }
 static inline void closure_debug_create(struct closure *cl) {}
 static inline void closure_debug_destroy(struct closure *cl) {}
 
diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c
index af89408..028f7b3 100644
--- a/drivers/md/bcache/debug.c
+++ b/drivers/md/bcache/debug.c
@@ -17,7 +17,7 @@
 #include <linux/random.h>
 #include <linux/seq_file.h>
 
-static struct dentry *debug;
+struct dentry *bcache_debug;
 
 #ifdef CONFIG_BCACHE_DEBUG
 
@@ -232,11 +232,11 @@ static const struct file_operations cache_set_debug_ops = {
 
 void bch_debug_init_cache_set(struct cache_set *c)
 {
-	if (!IS_ERR_OR_NULL(debug)) {
+	if (!IS_ERR_OR_NULL(bcache_debug)) {
 		char name[50];
 		snprintf(name, 50, "bcache-%pU", c->sb.set_uuid);
 
-		c->debug = debugfs_create_file(name, 0400, debug, c,
+		c->debug = debugfs_create_file(name, 0400, bcache_debug, c,
 					       &cache_set_debug_ops);
 	}
 }
@@ -245,13 +245,13 @@ void bch_debug_init_cache_set(struct cache_set *c)
 
 void bch_debug_exit(void)
 {
-	if (!IS_ERR_OR_NULL(debug))
-		debugfs_remove_recursive(debug);
+	if (!IS_ERR_OR_NULL(bcache_debug))
+		debugfs_remove_recursive(bcache_debug);
 }
 
 int __init bch_debug_init(struct kobject *kobj)
 {
-	debug = debugfs_create_dir("bcache", NULL);
+	bcache_debug = debugfs_create_dir("bcache", NULL);
 
-	return IS_ERR_OR_NULL(debug);
+	return IS_ERR_OR_NULL(bcache_debug);
 }
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c
index f9d3917..c334e66 100644
--- a/drivers/md/bcache/extents.c
+++ b/drivers/md/bcache/extents.c
@@ -534,7 +534,6 @@ static bool bch_extent_bad_expensive(struct btree *b, const struct bkey *k,
 static bool bch_extent_bad(struct btree_keys *bk, const struct bkey *k)
 {
 	struct btree *b = container_of(bk, struct btree, keys);
-	struct bucket *g;
 	unsigned i, stale;
 
 	if (!KEY_PTRS(k) ||
@@ -549,7 +548,6 @@ static bool bch_extent_bad(struct btree_keys *bk, const struct bkey *k)
 		return false;
 
 	for (i = 0; i < KEY_PTRS(k); i++) {
-		g = PTR_BUCKET(b->c, k, i);
 		stale = ptr_stale(b->c, k, i);
 
 		btree_bug_on(stale > 96, b,
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index a783c5a..7fac97a 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -38,7 +38,7 @@ void __bch_submit_bbio(struct bio *bio, struct cache_set *c)
 	bio_set_dev(bio, PTR_CACHE(c, &b->key, 0)->bdev);
 
 	b->submit_time_us = local_clock_us();
-	closure_bio_submit(bio, bio->bi_private);
+	closure_bio_submit(c, bio, bio->bi_private);
 }
 
 void bch_submit_bbio(struct bio *bio, struct cache_set *c,
@@ -50,6 +50,20 @@ void bch_submit_bbio(struct bio *bio, struct cache_set *c,
 }
 
 /* IO errors */
+void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio)
+{
+	char buf[BDEVNAME_SIZE];
+	unsigned errors;
+
+	WARN_ONCE(!dc, "NULL pointer of struct cached_dev");
+
+	errors = atomic_add_return(1, &dc->io_errors);
+	if (errors < dc->error_limit)
+		pr_err("%s: IO error on backing device, unrecoverable",
+			bio_devname(bio, buf));
+	else
+		bch_cached_dev_error(dc);
+}
 
 void bch_count_io_errors(struct cache *ca,
 			 blk_status_t error,
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 1b736b8..18f1b52 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -62,7 +62,7 @@ reread:		left = ca->sb.bucket_size - offset;
 		bio_set_op_attrs(bio, REQ_OP_READ, 0);
 		bch_bio_map(bio, data);
 
-		closure_bio_submit(bio, &cl);
+		closure_bio_submit(ca->set, bio, &cl);
 		closure_sync(&cl);
 
 		/* This function could be simpler now since we no longer write
@@ -493,7 +493,7 @@ static void journal_reclaim(struct cache_set *c)
 	struct cache *ca;
 	uint64_t last_seq;
 	unsigned iter, n = 0;
-	atomic_t p;
+	atomic_t p __maybe_unused;
 
 	atomic_long_inc(&c->reclaim);
 
@@ -594,6 +594,7 @@ static void journal_write_done(struct closure *cl)
 }
 
 static void journal_write_unlock(struct closure *cl)
+	__releases(&c->journal.lock)
 {
 	struct cache_set *c = container_of(cl, struct cache_set, journal.io);
 
@@ -674,7 +675,7 @@ static void journal_write_unlocked(struct closure *cl)
 	spin_unlock(&c->journal.lock);
 
 	while ((bio = bio_list_pop(&list)))
-		closure_bio_submit(bio, cl);
+		closure_bio_submit(c, bio, cl);
 
 	continue_at(cl, journal_write_done, NULL);
 }
@@ -705,6 +706,7 @@ static void journal_try_write(struct cache_set *c)
 
 static struct journal_write *journal_wait_for_write(struct cache_set *c,
 						    unsigned nkeys)
+	__acquires(&c->journal.lock)
 {
 	size_t sectors;
 	struct closure cl;
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 6422846..a65e336 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -139,6 +139,7 @@ static void bch_data_invalidate(struct closure *cl)
 	}
 
 	op->insert_data_done = true;
+	/* get in bch_data_insert() */
 	bio_put(bio);
 out:
 	continue_at(cl, bch_data_insert_keys, op->wq);
@@ -295,6 +296,7 @@ static void bch_data_insert_start(struct closure *cl)
 
 /**
  * bch_data_insert - stick some data in the cache
+ * @cl: closure pointer.
  *
  * This is the starting point for any data to end up in a cache device; it could
  * be from a normal write, or a writeback write, or a write to a flash only
@@ -630,6 +632,41 @@ static void request_endio(struct bio *bio)
 	closure_put(cl);
 }
 
+static void backing_request_endio(struct bio *bio)
+{
+	struct closure *cl = bio->bi_private;
+
+	if (bio->bi_status) {
+		struct search *s = container_of(cl, struct search, cl);
+		struct cached_dev *dc = container_of(s->d,
+						     struct cached_dev, disk);
+		/*
+		 * If a bio has REQ_PREFLUSH for writeback mode, it is
+		 * speically assembled in cached_dev_write() for a non-zero
+		 * write request which has REQ_PREFLUSH. we don't set
+		 * s->iop.status by this failure, the status will be decided
+		 * by result of bch_data_insert() operation.
+		 */
+		if (unlikely(s->iop.writeback &&
+			     bio->bi_opf & REQ_PREFLUSH)) {
+			char buf[BDEVNAME_SIZE];
+
+			bio_devname(bio, buf);
+			pr_err("Can't flush %s: returned bi_status %i",
+				buf, bio->bi_status);
+		} else {
+			/* set to orig_bio->bi_status in bio_complete() */
+			s->iop.status = bio->bi_status;
+		}
+		s->recoverable = false;
+		/* should count I/O error for backing device here */
+		bch_count_backing_io_errors(dc, bio);
+	}
+
+	bio_put(bio);
+	closure_put(cl);
+}
+
 static void bio_complete(struct search *s)
 {
 	if (s->orig_bio) {
@@ -644,13 +681,21 @@ static void bio_complete(struct search *s)
 	}
 }
 
-static void do_bio_hook(struct search *s, struct bio *orig_bio)
+static void do_bio_hook(struct search *s,
+			struct bio *orig_bio,
+			bio_end_io_t *end_io_fn)
 {
 	struct bio *bio = &s->bio.bio;
 
 	bio_init(bio, NULL, 0);
 	__bio_clone_fast(bio, orig_bio);
-	bio->bi_end_io		= request_endio;
+	/*
+	 * bi_end_io can be set separately somewhere else, e.g. the
+	 * variants in,
+	 * - cache_bio->bi_end_io from cached_dev_cache_miss()
+	 * - n->bi_end_io from cache_lookup_fn()
+	 */
+	bio->bi_end_io		= end_io_fn;
 	bio->bi_private		= &s->cl;
 
 	bio_cnt_set(bio, 3);
@@ -676,7 +721,7 @@ static inline struct search *search_alloc(struct bio *bio,
 	s = mempool_alloc(d->c->search, GFP_NOIO);
 
 	closure_init(&s->cl, NULL);
-	do_bio_hook(s, bio);
+	do_bio_hook(s, bio, request_endio);
 
 	s->orig_bio		= bio;
 	s->cache_miss		= NULL;
@@ -743,11 +788,12 @@ static void cached_dev_read_error(struct closure *cl)
 		trace_bcache_read_retry(s->orig_bio);
 
 		s->iop.status = 0;
-		do_bio_hook(s, s->orig_bio);
+		do_bio_hook(s, s->orig_bio, backing_request_endio);
 
 		/* XXX: invalidate cache */
 
-		closure_bio_submit(bio, cl);
+		/* I/O request sent to backing device */
+		closure_bio_submit(s->iop.c, bio, cl);
 	}
 
 	continue_at(cl, cached_dev_cache_miss_done, NULL);
@@ -859,7 +905,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
 	bio_copy_dev(cache_bio, miss);
 	cache_bio->bi_iter.bi_size	= s->insert_bio_sectors << 9;
 
-	cache_bio->bi_end_io	= request_endio;
+	cache_bio->bi_end_io	= backing_request_endio;
 	cache_bio->bi_private	= &s->cl;
 
 	bch_bio_map(cache_bio, NULL);
@@ -872,15 +918,17 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
 	s->cache_miss	= miss;
 	s->iop.bio	= cache_bio;
 	bio_get(cache_bio);
-	closure_bio_submit(cache_bio, &s->cl);
+	/* I/O request sent to backing device */
+	closure_bio_submit(s->iop.c, cache_bio, &s->cl);
 
 	return ret;
 out_put:
 	bio_put(cache_bio);
 out_submit:
-	miss->bi_end_io		= request_endio;
+	miss->bi_end_io		= backing_request_endio;
 	miss->bi_private	= &s->cl;
-	closure_bio_submit(miss, &s->cl);
+	/* I/O request sent to backing device */
+	closure_bio_submit(s->iop.c, miss, &s->cl);
 	return ret;
 }
 
@@ -943,31 +991,46 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
 		s->iop.bio = s->orig_bio;
 		bio_get(s->iop.bio);
 
-		if ((bio_op(bio) != REQ_OP_DISCARD) ||
-		    blk_queue_discard(bdev_get_queue(dc->bdev)))
-			closure_bio_submit(bio, cl);
+		if (bio_op(bio) == REQ_OP_DISCARD &&
+		    !blk_queue_discard(bdev_get_queue(dc->bdev)))
+			goto insert_data;
+
+		/* I/O request sent to backing device */
+		bio->bi_end_io = backing_request_endio;
+		closure_bio_submit(s->iop.c, bio, cl);
+
 	} else if (s->iop.writeback) {
 		bch_writeback_add(dc);
 		s->iop.bio = bio;
 
 		if (bio->bi_opf & REQ_PREFLUSH) {
-			/* Also need to send a flush to the backing device */
-			struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0,
-							     dc->disk.bio_split);
+			/*
+			 * Also need to send a flush to the backing
+			 * device.
+			 */
+			struct bio *flush;
 
+			flush = bio_alloc_bioset(GFP_NOIO, 0,
+						 dc->disk.bio_split);
+			if (!flush) {
+				s->iop.status = BLK_STS_RESOURCE;
+				goto insert_data;
+			}
 			bio_copy_dev(flush, bio);
-			flush->bi_end_io = request_endio;
+			flush->bi_end_io = backing_request_endio;
 			flush->bi_private = cl;
 			flush->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
-
-			closure_bio_submit(flush, cl);
+			/* I/O request sent to backing device */
+			closure_bio_submit(s->iop.c, flush, cl);
 		}
 	} else {
 		s->iop.bio = bio_clone_fast(bio, GFP_NOIO, dc->disk.bio_split);
-
-		closure_bio_submit(bio, cl);
+		/* I/O request sent to backing device */
+		bio->bi_end_io = backing_request_endio;
+		closure_bio_submit(s->iop.c, bio, cl);
 	}
 
+insert_data:
 	closure_call(&s->iop.cl, bch_data_insert, NULL, cl);
 	continue_at(cl, cached_dev_write_complete, NULL);
 }
@@ -981,11 +1044,67 @@ static void cached_dev_nodata(struct closure *cl)
 		bch_journal_meta(s->iop.c, cl);
 
 	/* If it's a flush, we send the flush to the backing device too */
-	closure_bio_submit(bio, cl);
+	bio->bi_end_io = backing_request_endio;
+	closure_bio_submit(s->iop.c, bio, cl);
 
 	continue_at(cl, cached_dev_bio_complete, NULL);
 }
 
+struct detached_dev_io_private {
+	struct bcache_device	*d;
+	unsigned long		start_time;
+	bio_end_io_t		*bi_end_io;
+	void			*bi_private;
+};
+
+static void detached_dev_end_io(struct bio *bio)
+{
+	struct detached_dev_io_private *ddip;
+
+	ddip = bio->bi_private;
+	bio->bi_end_io = ddip->bi_end_io;
+	bio->bi_private = ddip->bi_private;
+
+	generic_end_io_acct(ddip->d->disk->queue,
+			    bio_data_dir(bio),
+			    &ddip->d->disk->part0, ddip->start_time);
+
+	if (bio->bi_status) {
+		struct cached_dev *dc = container_of(ddip->d,
+						     struct cached_dev, disk);
+		/* should count I/O error for backing device here */
+		bch_count_backing_io_errors(dc, bio);
+	}
+
+	kfree(ddip);
+	bio->bi_end_io(bio);
+}
+
+static void detached_dev_do_request(struct bcache_device *d, struct bio *bio)
+{
+	struct detached_dev_io_private *ddip;
+	struct cached_dev *dc = container_of(d, struct cached_dev, disk);
+
+	/*
+	 * no need to call closure_get(&dc->disk.cl),
+	 * because upper layer had already opened bcache device,
+	 * which would call closure_get(&dc->disk.cl)
+	 */
+	ddip = kzalloc(sizeof(struct detached_dev_io_private), GFP_NOIO);
+	ddip->d = d;
+	ddip->start_time = jiffies;
+	ddip->bi_end_io = bio->bi_end_io;
+	ddip->bi_private = bio->bi_private;
+	bio->bi_end_io = detached_dev_end_io;
+	bio->bi_private = ddip;
+
+	if ((bio_op(bio) == REQ_OP_DISCARD) &&
+	    !blk_queue_discard(bdev_get_queue(dc->bdev)))
+		bio->bi_end_io(bio);
+	else
+		generic_make_request(bio);
+}
+
 /* Cached devices - read & write stuff */
 
 static blk_qc_t cached_dev_make_request(struct request_queue *q,
@@ -996,6 +1115,13 @@ static blk_qc_t cached_dev_make_request(struct request_queue *q,
 	struct cached_dev *dc = container_of(d, struct cached_dev, disk);
 	int rw = bio_data_dir(bio);
 
+	if (unlikely((d->c && test_bit(CACHE_SET_IO_DISABLE, &d->c->flags)) ||
+		     dc->io_disable)) {
+		bio->bi_status = BLK_STS_IOERR;
+		bio_endio(bio);
+		return BLK_QC_T_NONE;
+	}
+
 	atomic_set(&dc->backing_idle, 0);
 	generic_start_io_acct(q, rw, bio_sectors(bio), &d->disk->part0);
 
@@ -1022,13 +1148,9 @@ static blk_qc_t cached_dev_make_request(struct request_queue *q,
 			else
 				cached_dev_read(dc, s);
 		}
-	} else {
-		if ((bio_op(bio) == REQ_OP_DISCARD) &&
-		    !blk_queue_discard(bdev_get_queue(dc->bdev)))
-			bio_endio(bio);
-		else
-			generic_make_request(bio);
-	}
+	} else
+		/* I/O request sent to backing device */
+		detached_dev_do_request(d, bio);
 
 	return BLK_QC_T_NONE;
 }
@@ -1112,6 +1234,12 @@ static blk_qc_t flash_dev_make_request(struct request_queue *q,
 	struct bcache_device *d = bio->bi_disk->private_data;
 	int rw = bio_data_dir(bio);
 
+	if (unlikely(d->c && test_bit(CACHE_SET_IO_DISABLE, &d->c->flags))) {
+		bio->bi_status = BLK_STS_IOERR;
+		bio_endio(bio);
+		return BLK_QC_T_NONE;
+	}
+
 	generic_start_io_acct(q, rw, bio_sectors(bio), &d->disk->part0);
 
 	s = search_alloc(bio, d);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index f227314..d90d9e5 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -47,6 +47,14 @@ const char * const bch_cache_modes[] = {
 	NULL
 };
 
+/* Default is -1; we skip past it for stop_when_cache_set_failed */
+const char * const bch_stop_on_failure_modes[] = {
+	"default",
+	"auto",
+	"always",
+	NULL
+};
+
 static struct kobject *bcache_kobj;
 struct mutex bch_register_lock;
 LIST_HEAD(bch_cache_sets);
@@ -265,6 +273,7 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
 	bio->bi_private = dc;
 
 	closure_get(cl);
+	/* I/O request sent to backing device */
 	__write_super(&dc->sb, bio);
 
 	closure_return_with_destructor(cl, bch_write_bdev_super_unlock);
@@ -521,7 +530,7 @@ static void prio_io(struct cache *ca, uint64_t bucket, int op,
 	bio_set_op_attrs(bio, op, REQ_SYNC|REQ_META|op_flags);
 	bch_bio_map(bio, ca->disk_buckets);
 
-	closure_bio_submit(bio, &ca->prio);
+	closure_bio_submit(ca->set, bio, &ca->prio);
 	closure_sync(cl);
 }
 
@@ -769,6 +778,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
 			      sector_t sectors)
 {
 	struct request_queue *q;
+	const size_t max_stripes = min_t(size_t, INT_MAX,
+					 SIZE_MAX / sizeof(atomic_t));
 	size_t n;
 	int idx;
 
@@ -777,9 +788,7 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
 
 	d->nr_stripes = DIV_ROUND_UP_ULL(sectors, d->stripe_size);
 
-	if (!d->nr_stripes ||
-	    d->nr_stripes > INT_MAX ||
-	    d->nr_stripes > SIZE_MAX / sizeof(atomic_t)) {
+	if (!d->nr_stripes || d->nr_stripes > max_stripes) {
 		pr_err("nr_stripes too large or invalid: %u (start sector beyond end of disk?)",
 			(unsigned)d->nr_stripes);
 		return -ENOMEM;
@@ -833,9 +842,9 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
 	q->limits.io_min		= block_size;
 	q->limits.logical_block_size	= block_size;
 	q->limits.physical_block_size	= block_size;
-	set_bit(QUEUE_FLAG_NONROT,	&d->disk->queue->queue_flags);
-	clear_bit(QUEUE_FLAG_ADD_RANDOM, &d->disk->queue->queue_flags);
-	set_bit(QUEUE_FLAG_DISCARD,	&d->disk->queue->queue_flags);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, d->disk->queue);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, d->disk->queue);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, d->disk->queue);
 
 	blk_queue_write_cache(q, true, true);
 
@@ -899,6 +908,31 @@ void bch_cached_dev_run(struct cached_dev *dc)
 		pr_debug("error creating sysfs link");
 }
 
+/*
+ * If BCACHE_DEV_RATE_DW_RUNNING is set, it means routine of the delayed
+ * work dc->writeback_rate_update is running. Wait until the routine
+ * quits (BCACHE_DEV_RATE_DW_RUNNING is clear), then continue to
+ * cancel it. If BCACHE_DEV_RATE_DW_RUNNING is not clear after time_out
+ * seconds, give up waiting here and continue to cancel it too.
+ */
+static void cancel_writeback_rate_update_dwork(struct cached_dev *dc)
+{
+	int time_out = WRITEBACK_RATE_UPDATE_SECS_MAX * HZ;
+
+	do {
+		if (!test_bit(BCACHE_DEV_RATE_DW_RUNNING,
+			      &dc->disk.flags))
+			break;
+		time_out--;
+		schedule_timeout_interruptible(1);
+	} while (time_out > 0);
+
+	if (time_out == 0)
+		pr_warn("give up waiting for dc->writeback_write_update to quit");
+
+	cancel_delayed_work_sync(&dc->writeback_rate_update);
+}
+
 static void cached_dev_detach_finish(struct work_struct *w)
 {
 	struct cached_dev *dc = container_of(w, struct cached_dev, detach);
@@ -911,7 +945,9 @@ static void cached_dev_detach_finish(struct work_struct *w)
 
 	mutex_lock(&bch_register_lock);
 
-	cancel_delayed_work_sync(&dc->writeback_rate_update);
+	if (test_and_clear_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags))
+		cancel_writeback_rate_update_dwork(dc);
+
 	if (!IS_ERR_OR_NULL(dc->writeback_thread)) {
 		kthread_stop(dc->writeback_thread);
 		dc->writeback_thread = NULL;
@@ -954,6 +990,7 @@ void bch_cached_dev_detach(struct cached_dev *dc)
 	closure_get(&dc->disk.cl);
 
 	bch_writeback_queue(dc);
+
 	cached_dev_put(dc);
 }
 
@@ -1065,7 +1102,6 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
 	if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
 		bch_sectors_dirty_init(&dc->disk);
 		atomic_set(&dc->has_dirty, 1);
-		refcount_inc(&dc->count);
 		bch_writeback_queue(dc);
 	}
 
@@ -1093,14 +1129,16 @@ static void cached_dev_free(struct closure *cl)
 {
 	struct cached_dev *dc = container_of(cl, struct cached_dev, disk.cl);
 
-	cancel_delayed_work_sync(&dc->writeback_rate_update);
+	mutex_lock(&bch_register_lock);
+
+	if (test_and_clear_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags))
+		cancel_writeback_rate_update_dwork(dc);
+
 	if (!IS_ERR_OR_NULL(dc->writeback_thread))
 		kthread_stop(dc->writeback_thread);
 	if (dc->writeback_write_wq)
 		destroy_workqueue(dc->writeback_write_wq);
 
-	mutex_lock(&bch_register_lock);
-
 	if (atomic_read(&dc->running))
 		bd_unlink_disk_holder(dc->bdev, dc->disk.disk);
 	bcache_device_free(&dc->disk);
@@ -1170,6 +1208,12 @@ static int cached_dev_init(struct cached_dev *dc, unsigned block_size)
 		max(dc->disk.disk->queue->backing_dev_info->ra_pages,
 		    q->backing_dev_info->ra_pages);
 
+	atomic_set(&dc->io_errors, 0);
+	dc->io_disable = false;
+	dc->error_limit = DEFAULT_CACHED_DEV_ERROR_LIMIT;
+	/* default to auto */
+	dc->stop_when_cache_set_failed = BCH_CACHED_DEV_STOP_AUTO;
+
 	bch_cached_dev_request_init(dc);
 	bch_cached_dev_writeback_init(dc);
 	return 0;
@@ -1321,6 +1365,24 @@ int bch_flash_dev_create(struct cache_set *c, uint64_t size)
 	return flash_dev_run(c, u);
 }
 
+bool bch_cached_dev_error(struct cached_dev *dc)
+{
+	char name[BDEVNAME_SIZE];
+
+	if (!dc || test_bit(BCACHE_DEV_CLOSING, &dc->disk.flags))
+		return false;
+
+	dc->io_disable = true;
+	/* make others know io_disable is true earlier */
+	smp_mb();
+
+	pr_err("stop %s: too many IO errors on backing device %s\n",
+		dc->disk.disk->disk_name, bdevname(dc->bdev, name));
+
+	bcache_device_stop(&dc->disk);
+	return true;
+}
+
 /* Cache set */
 
 __printf(2, 3)
@@ -1332,6 +1394,9 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...)
 	    test_bit(CACHE_SET_STOPPING, &c->flags))
 		return false;
 
+	if (test_and_set_bit(CACHE_SET_IO_DISABLE, &c->flags))
+		pr_warn("CACHE_SET_IO_DISABLE already set");
+
 	/* XXX: we can be called from atomic context
 	acquire_console_sem();
 	*/
@@ -1443,25 +1508,72 @@ static void cache_set_flush(struct closure *cl)
 	closure_return(cl);
 }
 
+/*
+ * This function is only called when CACHE_SET_IO_DISABLE is set, which means
+ * cache set is unregistering due to too many I/O errors. In this condition,
+ * the bcache device might be stopped, it depends on stop_when_cache_set_failed
+ * value and whether the broken cache has dirty data:
+ *
+ * dc->stop_when_cache_set_failed    dc->has_dirty   stop bcache device
+ *  BCH_CACHED_STOP_AUTO               0               NO
+ *  BCH_CACHED_STOP_AUTO               1               YES
+ *  BCH_CACHED_DEV_STOP_ALWAYS         0               YES
+ *  BCH_CACHED_DEV_STOP_ALWAYS         1               YES
+ *
+ * The expected behavior is, if stop_when_cache_set_failed is configured to
+ * "auto" via sysfs interface, the bcache device will not be stopped if the
+ * backing device is clean on the broken cache device.
+ */
+static void conditional_stop_bcache_device(struct cache_set *c,
+					   struct bcache_device *d,
+					   struct cached_dev *dc)
+{
+	if (dc->stop_when_cache_set_failed == BCH_CACHED_DEV_STOP_ALWAYS) {
+		pr_warn("stop_when_cache_set_failed of %s is \"always\", stop it for failed cache set %pU.",
+			d->disk->disk_name, c->sb.set_uuid);
+		bcache_device_stop(d);
+	} else if (atomic_read(&dc->has_dirty)) {
+		/*
+		 * dc->stop_when_cache_set_failed == BCH_CACHED_STOP_AUTO
+		 * and dc->has_dirty == 1
+		 */
+		pr_warn("stop_when_cache_set_failed of %s is \"auto\" and cache is dirty, stop it to avoid potential data corruption.",
+			d->disk->disk_name);
+			bcache_device_stop(d);
+	} else {
+		/*
+		 * dc->stop_when_cache_set_failed == BCH_CACHED_STOP_AUTO
+		 * and dc->has_dirty == 0
+		 */
+		pr_warn("stop_when_cache_set_failed of %s is \"auto\" and cache is clean, keep it alive.",
+			d->disk->disk_name);
+	}
+}
+
 static void __cache_set_unregister(struct closure *cl)
 {
 	struct cache_set *c = container_of(cl, struct cache_set, caching);
 	struct cached_dev *dc;
+	struct bcache_device *d;
 	size_t i;
 
 	mutex_lock(&bch_register_lock);
 
-	for (i = 0; i < c->devices_max_used; i++)
-		if (c->devices[i]) {
-			if (!UUID_FLASH_ONLY(&c->uuids[i]) &&
-			    test_bit(CACHE_SET_UNREGISTERING, &c->flags)) {
-				dc = container_of(c->devices[i],
-						  struct cached_dev, disk);
-				bch_cached_dev_detach(dc);
-			} else {
-				bcache_device_stop(c->devices[i]);
-			}
+	for (i = 0; i < c->devices_max_used; i++) {
+		d = c->devices[i];
+		if (!d)
+			continue;
+
+		if (!UUID_FLASH_ONLY(&c->uuids[i]) &&
+		    test_bit(CACHE_SET_UNREGISTERING, &c->flags)) {
+			dc = container_of(d, struct cached_dev, disk);
+			bch_cached_dev_detach(dc);
+			if (test_bit(CACHE_SET_IO_DISABLE, &c->flags))
+				conditional_stop_bcache_device(c, d, dc);
+		} else {
+			bcache_device_stop(d);
 		}
+	}
 
 	mutex_unlock(&bch_register_lock);
 
@@ -1567,6 +1679,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
 	c->congested_read_threshold_us	= 2000;
 	c->congested_write_threshold_us	= 20000;
 	c->error_limit	= DEFAULT_IO_ERROR_LIMIT;
+	WARN_ON(test_and_clear_bit(CACHE_SET_IO_DISABLE, &c->flags));
 
 	return c;
 err:
@@ -2148,7 +2261,6 @@ static int __init bcache_init(void)
 	mutex_init(&bch_register_lock);
 	init_waitqueue_head(&unregister_wait);
 	register_reboot_notifier(&reboot);
-	closure_debug_init();
 
 	bcache_major = register_blkdev(0, "bcache");
 	if (bcache_major < 0) {
@@ -2160,7 +2272,7 @@ static int __init bcache_init(void)
 	if (!(bcache_wq = alloc_workqueue("bcache", WQ_MEM_RECLAIM, 0)) ||
 	    !(bcache_kobj = kobject_create_and_add("bcache", fs_kobj)) ||
 	    bch_request_init() ||
-	    bch_debug_init(bcache_kobj) ||
+	    bch_debug_init(bcache_kobj) || closure_debug_init() ||
 	    sysfs_create_files(bcache_kobj, files))
 		goto err;
 
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 78cd7bd..dfeef58 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -78,6 +78,7 @@ rw_attribute(congested_write_threshold_us);
 rw_attribute(sequential_cutoff);
 rw_attribute(data_csum);
 rw_attribute(cache_mode);
+rw_attribute(stop_when_cache_set_failed);
 rw_attribute(writeback_metadata);
 rw_attribute(writeback_running);
 rw_attribute(writeback_percent);
@@ -95,6 +96,7 @@ read_attribute(partial_stripes_expensive);
 
 rw_attribute(synchronous);
 rw_attribute(journal_delay_ms);
+rw_attribute(io_disable);
 rw_attribute(discard);
 rw_attribute(running);
 rw_attribute(label);
@@ -125,6 +127,12 @@ SHOW(__bch_cached_dev)
 					       bch_cache_modes + 1,
 					       BDEV_CACHE_MODE(&dc->sb));
 
+	if (attr == &sysfs_stop_when_cache_set_failed)
+		return bch_snprint_string_list(buf, PAGE_SIZE,
+					       bch_stop_on_failure_modes + 1,
+					       dc->stop_when_cache_set_failed);
+
+
 	sysfs_printf(data_csum,		"%i", dc->disk.data_csum);
 	var_printf(verify,		"%i");
 	var_printf(bypass_torture_test,	"%i");
@@ -133,7 +141,9 @@ SHOW(__bch_cached_dev)
 	var_print(writeback_delay);
 	var_print(writeback_percent);
 	sysfs_hprint(writeback_rate,	dc->writeback_rate.rate << 9);
-
+	sysfs_hprint(io_errors,		atomic_read(&dc->io_errors));
+	sysfs_printf(io_error_limit,	"%i", dc->error_limit);
+	sysfs_printf(io_disable,	"%i", dc->io_disable);
 	var_print(writeback_rate_update_seconds);
 	var_print(writeback_rate_i_term_inverse);
 	var_print(writeback_rate_p_term_inverse);
@@ -173,7 +183,7 @@ SHOW(__bch_cached_dev)
 	sysfs_hprint(dirty_data,
 		     bcache_dev_sectors_dirty(&dc->disk) << 9);
 
-	sysfs_hprint(stripe_size,	dc->disk.stripe_size << 9);
+	sysfs_hprint(stripe_size,	 ((uint64_t)dc->disk.stripe_size) << 9);
 	var_printf(partial_stripes_expensive,	"%u");
 
 	var_hprint(sequential_cutoff);
@@ -224,6 +234,14 @@ STORE(__cached_dev)
 	d_strtoul(writeback_rate_i_term_inverse);
 	d_strtoul_nonzero(writeback_rate_p_term_inverse);
 
+	sysfs_strtoul_clamp(io_error_limit, dc->error_limit, 0, INT_MAX);
+
+	if (attr == &sysfs_io_disable) {
+		int v = strtoul_or_return(buf);
+
+		dc->io_disable = v ? 1 : 0;
+	}
+
 	d_strtoi_h(sequential_cutoff);
 	d_strtoi_h(readahead);
 
@@ -246,6 +264,15 @@ STORE(__cached_dev)
 		}
 	}
 
+	if (attr == &sysfs_stop_when_cache_set_failed) {
+		v = bch_read_string_list(buf, bch_stop_on_failure_modes + 1);
+
+		if (v < 0)
+			return v;
+
+		dc->stop_when_cache_set_failed = v;
+	}
+
 	if (attr == &sysfs_label) {
 		if (size > SB_LABEL_SIZE)
 			return -EINVAL;
@@ -309,7 +336,8 @@ STORE(bch_cached_dev)
 		bch_writeback_queue(dc);
 
 	if (attr == &sysfs_writeback_percent)
-		schedule_delayed_work(&dc->writeback_rate_update,
+		if (!test_and_set_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags))
+			schedule_delayed_work(&dc->writeback_rate_update,
 				      dc->writeback_rate_update_seconds * HZ);
 
 	mutex_unlock(&bch_register_lock);
@@ -324,6 +352,7 @@ static struct attribute *bch_cached_dev_files[] = {
 	&sysfs_data_csum,
 #endif
 	&sysfs_cache_mode,
+	&sysfs_stop_when_cache_set_failed,
 	&sysfs_writeback_metadata,
 	&sysfs_writeback_running,
 	&sysfs_writeback_delay,
@@ -333,6 +362,9 @@ static struct attribute *bch_cached_dev_files[] = {
 	&sysfs_writeback_rate_i_term_inverse,
 	&sysfs_writeback_rate_p_term_inverse,
 	&sysfs_writeback_rate_debug,
+	&sysfs_errors,
+	&sysfs_io_error_limit,
+	&sysfs_io_disable,
 	&sysfs_dirty_data,
 	&sysfs_stripe_size,
 	&sysfs_partial_stripes_expensive,
@@ -590,6 +622,8 @@ SHOW(__bch_cache_set)
 	sysfs_printf(gc_always_rewrite,		"%i", c->gc_always_rewrite);
 	sysfs_printf(btree_shrinker_disabled,	"%i", c->shrinker_disabled);
 	sysfs_printf(copy_gc_enabled,		"%i", c->copy_gc_enabled);
+	sysfs_printf(io_disable,		"%i",
+		     test_bit(CACHE_SET_IO_DISABLE, &c->flags));
 
 	if (attr == &sysfs_bset_tree_stats)
 		return bch_bset_print_stats(c, buf);
@@ -679,6 +713,20 @@ STORE(__bch_cache_set)
 	if (attr == &sysfs_io_error_halflife)
 		c->error_decay = strtoul_or_return(buf) / 88;
 
+	if (attr == &sysfs_io_disable) {
+		int v = strtoul_or_return(buf);
+
+		if (v) {
+			if (test_and_set_bit(CACHE_SET_IO_DISABLE,
+					     &c->flags))
+				pr_warn("CACHE_SET_IO_DISABLE already set");
+		} else {
+			if (!test_and_clear_bit(CACHE_SET_IO_DISABLE,
+						&c->flags))
+				pr_warn("CACHE_SET_IO_DISABLE already cleared");
+		}
+	}
+
 	sysfs_strtoul(journal_delay_ms,		c->journal_delay_ms);
 	sysfs_strtoul(verify,			c->verify);
 	sysfs_strtoul(key_merging_disabled,	c->key_merging_disabled);
@@ -764,6 +812,7 @@ static struct attribute *bch_cache_set_internal_files[] = {
 	&sysfs_gc_always_rewrite,
 	&sysfs_btree_shrinker_disabled,
 	&sysfs_copy_gc_enabled,
+	&sysfs_io_disable,
 	NULL
 };
 KTYPE(bch_cache_set_internal);
diff --git a/drivers/md/bcache/util.c b/drivers/md/bcache/util.c
index a23cd6a..74febd5 100644
--- a/drivers/md/bcache/util.c
+++ b/drivers/md/bcache/util.c
@@ -32,20 +32,27 @@ int bch_ ## name ## _h(const char *cp, type *res)		\
 	case 'y':						\
 	case 'z':						\
 		u++;						\
+		/* fall through */				\
 	case 'e':						\
 		u++;						\
+		/* fall through */				\
 	case 'p':						\
 		u++;						\
+		/* fall through */				\
 	case 't':						\
 		u++;						\
+		/* fall through */				\
 	case 'g':						\
 		u++;						\
+		/* fall through */				\
 	case 'm':						\
 		u++;						\
+		/* fall through */				\
 	case 'k':						\
 		u++;						\
 		if (e++ == cp)					\
 			return -EINVAL;				\
+		/* fall through */				\
 	case '\n':						\
 	case '\0':						\
 		if (*e == '\n')					\
@@ -75,10 +82,9 @@ STRTO_H(strtoll, long long)
 STRTO_H(strtoull, unsigned long long)
 
 /**
- * bch_hprint() - formats @v to human readable string for sysfs.
- *
- * @v - signed 64 bit integer
- * @buf - the (at least 8 byte) buffer to format the result into.
+ * bch_hprint - formats @v to human readable string for sysfs.
+ * @buf: the (at least 8 byte) buffer to format the result into.
+ * @v: signed 64 bit integer
  *
  * Returns the number of bytes used by format.
  */
@@ -218,13 +224,12 @@ void bch_time_stats_update(struct time_stats *stats, uint64_t start_time)
 }
 
 /**
- * bch_next_delay() - increment @d by the amount of work done, and return how
- * long to delay until the next time to do some work.
+ * bch_next_delay() - update ratelimiting statistics and calculate next delay
+ * @d: the struct bch_ratelimit to update
+ * @done: the amount of work done, in arbitrary units
  *
- * @d - the struct bch_ratelimit to update
- * @done - the amount of work done, in arbitrary units
- *
- * Returns the amount of time to delay by, in jiffies
+ * Increment @d by the amount of work done, and return how long to delay in
+ * jiffies until the next time to do some work.
  */
 uint64_t bch_next_delay(struct bch_ratelimit *d, uint64_t done)
 {
diff --git a/drivers/md/bcache/util.h b/drivers/md/bcache/util.h
index a6763db..2680245 100644
--- a/drivers/md/bcache/util.h
+++ b/drivers/md/bcache/util.h
@@ -567,12 +567,6 @@ static inline sector_t bdev_sectors(struct block_device *bdev)
 	return bdev->bd_inode->i_size >> 9;
 }
 
-#define closure_bio_submit(bio, cl)					\
-do {									\
-	closure_get(cl);						\
-	generic_make_request(bio);					\
-} while (0)
-
 uint64_t bch_crc64_update(uint64_t, const void *, size_t);
 uint64_t bch_crc64(const void *, size_t);
 
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index f1d2fc1..4a9547c 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -114,6 +114,27 @@ static void update_writeback_rate(struct work_struct *work)
 	struct cached_dev *dc = container_of(to_delayed_work(work),
 					     struct cached_dev,
 					     writeback_rate_update);
+	struct cache_set *c = dc->disk.c;
+
+	/*
+	 * should check BCACHE_DEV_RATE_DW_RUNNING before calling
+	 * cancel_delayed_work_sync().
+	 */
+	set_bit(BCACHE_DEV_RATE_DW_RUNNING, &dc->disk.flags);
+	/* paired with where BCACHE_DEV_RATE_DW_RUNNING is tested */
+	smp_mb();
+
+	/*
+	 * CACHE_SET_IO_DISABLE might be set via sysfs interface,
+	 * check it here too.
+	 */
+	if (!test_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags) ||
+	    test_bit(CACHE_SET_IO_DISABLE, &c->flags)) {
+		clear_bit(BCACHE_DEV_RATE_DW_RUNNING, &dc->disk.flags);
+		/* paired with where BCACHE_DEV_RATE_DW_RUNNING is tested */
+		smp_mb();
+		return;
+	}
 
 	down_read(&dc->writeback_lock);
 
@@ -123,8 +144,23 @@ static void update_writeback_rate(struct work_struct *work)
 
 	up_read(&dc->writeback_lock);
 
-	schedule_delayed_work(&dc->writeback_rate_update,
+	/*
+	 * CACHE_SET_IO_DISABLE might be set via sysfs interface,
+	 * check it here too.
+	 */
+	if (test_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags) &&
+	    !test_bit(CACHE_SET_IO_DISABLE, &c->flags)) {
+		schedule_delayed_work(&dc->writeback_rate_update,
 			      dc->writeback_rate_update_seconds * HZ);
+	}
+
+	/*
+	 * should check BCACHE_DEV_RATE_DW_RUNNING before calling
+	 * cancel_delayed_work_sync().
+	 */
+	clear_bit(BCACHE_DEV_RATE_DW_RUNNING, &dc->disk.flags);
+	/* paired with where BCACHE_DEV_RATE_DW_RUNNING is tested */
+	smp_mb();
 }
 
 static unsigned writeback_delay(struct cached_dev *dc, unsigned sectors)
@@ -253,7 +289,8 @@ static void write_dirty(struct closure *cl)
 		bio_set_dev(&io->bio, io->dc->bdev);
 		io->bio.bi_end_io	= dirty_endio;
 
-		closure_bio_submit(&io->bio, cl);
+		/* I/O request sent to backing device */
+		closure_bio_submit(io->dc->disk.c, &io->bio, cl);
 	}
 
 	atomic_set(&dc->writeback_sequence_next, next_sequence);
@@ -279,7 +316,7 @@ static void read_dirty_submit(struct closure *cl)
 {
 	struct dirty_io *io = container_of(cl, struct dirty_io, cl);
 
-	closure_bio_submit(&io->bio, cl);
+	closure_bio_submit(io->dc->disk.c, &io->bio, cl);
 
 	continue_at(cl, write_dirty, io->dc->writeback_write_wq);
 }
@@ -305,7 +342,9 @@ static void read_dirty(struct cached_dev *dc)
 
 	next = bch_keybuf_next(&dc->writeback_keys);
 
-	while (!kthread_should_stop() && next) {
+	while (!kthread_should_stop() &&
+	       !test_bit(CACHE_SET_IO_DISABLE, &dc->disk.c->flags) &&
+	       next) {
 		size = 0;
 		nk = 0;
 
@@ -402,7 +441,9 @@ static void read_dirty(struct cached_dev *dc)
 			}
 		}
 
-		while (!kthread_should_stop() && delay) {
+		while (!kthread_should_stop() &&
+		       !test_bit(CACHE_SET_IO_DISABLE, &dc->disk.c->flags) &&
+		       delay) {
 			schedule_timeout_interruptible(delay);
 			delay = writeback_delay(dc, 0);
 		}
@@ -558,21 +599,30 @@ static bool refill_dirty(struct cached_dev *dc)
 static int bch_writeback_thread(void *arg)
 {
 	struct cached_dev *dc = arg;
+	struct cache_set *c = dc->disk.c;
 	bool searched_full_index;
 
 	bch_ratelimit_reset(&dc->writeback_rate);
 
-	while (!kthread_should_stop()) {
+	while (!kthread_should_stop() &&
+	       !test_bit(CACHE_SET_IO_DISABLE, &c->flags)) {
 		down_write(&dc->writeback_lock);
 		set_current_state(TASK_INTERRUPTIBLE);
-		if (!atomic_read(&dc->has_dirty) ||
-		    (!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) &&
-		     !dc->writeback_running)) {
+		/*
+		 * If the bache device is detaching, skip here and continue
+		 * to perform writeback. Otherwise, if no dirty data on cache,
+		 * or there is dirty data on cache but writeback is disabled,
+		 * the writeback thread should sleep here and wait for others
+		 * to wake up it.
+		 */
+		if (!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) &&
+		    (!atomic_read(&dc->has_dirty) || !dc->writeback_running)) {
 			up_write(&dc->writeback_lock);
 
-			if (kthread_should_stop()) {
+			if (kthread_should_stop() ||
+			    test_bit(CACHE_SET_IO_DISABLE, &c->flags)) {
 				set_current_state(TASK_RUNNING);
-				return 0;
+				break;
 			}
 
 			schedule();
@@ -585,9 +635,16 @@ static int bch_writeback_thread(void *arg)
 		if (searched_full_index &&
 		    RB_EMPTY_ROOT(&dc->writeback_keys.keys)) {
 			atomic_set(&dc->has_dirty, 0);
-			cached_dev_put(dc);
 			SET_BDEV_STATE(&dc->sb, BDEV_STATE_CLEAN);
 			bch_write_bdev_super(dc, NULL);
+			/*
+			 * If bcache device is detaching via sysfs interface,
+			 * writeback thread should stop after there is no dirty
+			 * data on cache. BCACHE_DEV_DETACHING flag is set in
+			 * bch_cached_dev_detach().
+			 */
+			if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags))
+				break;
 		}
 
 		up_write(&dc->writeback_lock);
@@ -599,6 +656,7 @@ static int bch_writeback_thread(void *arg)
 
 			while (delay &&
 			       !kthread_should_stop() &&
+			       !test_bit(CACHE_SET_IO_DISABLE, &c->flags) &&
 			       !test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags))
 				delay = schedule_timeout_interruptible(delay);
 
@@ -606,6 +664,9 @@ static int bch_writeback_thread(void *arg)
 		}
 	}
 
+	cached_dev_put(dc);
+	wait_for_kthread_stop();
+
 	return 0;
 }
 
@@ -659,6 +720,7 @@ void bch_cached_dev_writeback_init(struct cached_dev *dc)
 	dc->writeback_rate_p_term_inverse = 40;
 	dc->writeback_rate_i_term_inverse = 10000;
 
+	WARN_ON(test_and_clear_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags));
 	INIT_DELAYED_WORK(&dc->writeback_rate_update, update_writeback_rate);
 }
 
@@ -669,11 +731,15 @@ int bch_cached_dev_writeback_start(struct cached_dev *dc)
 	if (!dc->writeback_write_wq)
 		return -ENOMEM;
 
+	cached_dev_get(dc);
 	dc->writeback_thread = kthread_create(bch_writeback_thread, dc,
 					      "bcache_writeback");
-	if (IS_ERR(dc->writeback_thread))
+	if (IS_ERR(dc->writeback_thread)) {
+		cached_dev_put(dc);
 		return PTR_ERR(dc->writeback_thread);
+	}
 
+	WARN_ON(test_and_set_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags));
 	schedule_delayed_work(&dc->writeback_rate_update,
 			      dc->writeback_rate_update_seconds * HZ);
 
diff --git a/drivers/md/bcache/writeback.h b/drivers/md/bcache/writeback.h
index 587b255..610fb01 100644
--- a/drivers/md/bcache/writeback.h
+++ b/drivers/md/bcache/writeback.h
@@ -39,7 +39,7 @@ static inline uint64_t  bcache_flash_devs_sectors_dirty(struct cache_set *c)
 
 		if (!d || !UUID_FLASH_ONLY(&c->uuids[i]))
 			continue;
-	   ret += bcache_dev_sectors_dirty(d);
+		ret += bcache_dev_sectors_dirty(d);
 	}
 
 	mutex_unlock(&bch_register_lock);
@@ -105,8 +105,6 @@ static inline void bch_writeback_add(struct cached_dev *dc)
 {
 	if (!atomic_read(&dc->has_dirty) &&
 	    !atomic_xchg(&dc->has_dirty, 1)) {
-		refcount_inc(&dc->count);
-
 		if (BDEV_STATE(&dc->sb) != BDEV_STATE_DIRTY) {
 			SET_BDEV_STATE(&dc->sb, BDEV_STATE_DIRTY);
 			/* XXX: should do this synchronously */
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index aa2032f..12aa9ca 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -6,7 +6,7 @@
  * This file is released under the GPL.
  */
 
-#include "dm-bufio.h"
+#include <linux/dm-bufio.h>
 
 #include <linux/device-mapper.h>
 #include <linux/dm-io.h>
@@ -51,19 +51,6 @@
 #define DM_BUFIO_DEFAULT_RETAIN_BYTES   (256 * 1024)
 
 /*
- * The number of bvec entries that are embedded directly in the buffer.
- * If the chunk size is larger, dm-io is used to do the io.
- */
-#define DM_BUFIO_INLINE_VECS		16
-
-/*
- * Don't try to use kmem_cache_alloc for blocks larger than this.
- * For explanation, see alloc_buffer_data below.
- */
-#define DM_BUFIO_BLOCK_SIZE_SLAB_LIMIT	(PAGE_SIZE >> 1)
-#define DM_BUFIO_BLOCK_SIZE_GFP_LIMIT	(PAGE_SIZE << (MAX_ORDER - 1))
-
-/*
  * Align buffer writes to this boundary.
  * Tests show that SSDs have the highest IOPS when using 4k writes.
  */
@@ -99,13 +86,12 @@ struct dm_bufio_client {
 
 	struct block_device *bdev;
 	unsigned block_size;
-	unsigned char sectors_per_block_bits;
-	unsigned char pages_per_block_bits;
-	unsigned char blocks_per_page_bits;
-	unsigned aux_size;
+	s8 sectors_per_block_bits;
 	void (*alloc_callback)(struct dm_buffer *);
 	void (*write_callback)(struct dm_buffer *);
 
+	struct kmem_cache *slab_buffer;
+	struct kmem_cache *slab_cache;
 	struct dm_io_client *dm_io;
 
 	struct list_head reserved_buffers;
@@ -148,11 +134,11 @@ struct dm_buffer {
 	struct list_head lru_list;
 	sector_t block;
 	void *data;
-	enum data_mode data_mode;
+	unsigned char data_mode;		/* DATA_MODE_* */
 	unsigned char list_mode;		/* LIST_* */
-	unsigned hold_count;
 	blk_status_t read_error;
 	blk_status_t write_error;
+	unsigned hold_count;
 	unsigned long state;
 	unsigned long last_accessed;
 	unsigned dirty_start;
@@ -161,8 +147,7 @@ struct dm_buffer {
 	unsigned write_end;
 	struct dm_bufio_client *c;
 	struct list_head write_list;
-	struct bio bio;
-	struct bio_vec bio_vec[DM_BUFIO_INLINE_VECS];
+	void (*end_io)(struct dm_buffer *, blk_status_t);
 #ifdef CONFIG_DM_DEBUG_BLOCK_STACK_TRACING
 #define MAX_STACK 10
 	struct stack_trace stack_trace;
@@ -172,21 +157,6 @@ struct dm_buffer {
 
 /*----------------------------------------------------------------*/
 
-static struct kmem_cache *dm_bufio_caches[PAGE_SHIFT - SECTOR_SHIFT];
-static char *dm_bufio_cache_names[PAGE_SHIFT - SECTOR_SHIFT];
-
-static inline int dm_bufio_cache_index(struct dm_bufio_client *c)
-{
-	unsigned ret = c->blocks_per_page_bits - 1;
-
-	BUG_ON(ret >= ARRAY_SIZE(dm_bufio_caches));
-
-	return ret;
-}
-
-#define DM_BUFIO_CACHE(c)	(dm_bufio_caches[dm_bufio_cache_index(c)])
-#define DM_BUFIO_CACHE_NAME(c)	(dm_bufio_cache_names[dm_bufio_cache_index(c)])
-
 #define dm_bufio_in_request()	(!!current->bio_list)
 
 static void dm_bufio_lock(struct dm_bufio_client *c)
@@ -319,7 +289,7 @@ static void __remove(struct dm_bufio_client *c, struct dm_buffer *b)
 
 /*----------------------------------------------------------------*/
 
-static void adjust_total_allocated(enum data_mode data_mode, long diff)
+static void adjust_total_allocated(unsigned char data_mode, long diff)
 {
 	static unsigned long * const class_ptr[DATA_MODE_LIMIT] = {
 		&dm_bufio_allocated_kmem_cache,
@@ -384,18 +354,18 @@ static void __cache_size_refresh(void)
  * space.
  */
 static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask,
-			       enum data_mode *data_mode)
+			       unsigned char *data_mode)
 {
-	if (c->block_size <= DM_BUFIO_BLOCK_SIZE_SLAB_LIMIT) {
+	if (unlikely(c->slab_cache != NULL)) {
 		*data_mode = DATA_MODE_SLAB;
-		return kmem_cache_alloc(DM_BUFIO_CACHE(c), gfp_mask);
+		return kmem_cache_alloc(c->slab_cache, gfp_mask);
 	}
 
-	if (c->block_size <= DM_BUFIO_BLOCK_SIZE_GFP_LIMIT &&
+	if (c->block_size <= KMALLOC_MAX_SIZE &&
 	    gfp_mask & __GFP_NORETRY) {
 		*data_mode = DATA_MODE_GET_FREE_PAGES;
 		return (void *)__get_free_pages(gfp_mask,
-						c->pages_per_block_bits);
+						c->sectors_per_block_bits - (PAGE_SHIFT - SECTOR_SHIFT));
 	}
 
 	*data_mode = DATA_MODE_VMALLOC;
@@ -424,15 +394,16 @@ static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask,
  * Free buffer's data.
  */
 static void free_buffer_data(struct dm_bufio_client *c,
-			     void *data, enum data_mode data_mode)
+			     void *data, unsigned char data_mode)
 {
 	switch (data_mode) {
 	case DATA_MODE_SLAB:
-		kmem_cache_free(DM_BUFIO_CACHE(c), data);
+		kmem_cache_free(c->slab_cache, data);
 		break;
 
 	case DATA_MODE_GET_FREE_PAGES:
-		free_pages((unsigned long)data, c->pages_per_block_bits);
+		free_pages((unsigned long)data,
+			   c->sectors_per_block_bits - (PAGE_SHIFT - SECTOR_SHIFT));
 		break;
 
 	case DATA_MODE_VMALLOC:
@@ -451,8 +422,7 @@ static void free_buffer_data(struct dm_bufio_client *c,
  */
 static struct dm_buffer *alloc_buffer(struct dm_bufio_client *c, gfp_t gfp_mask)
 {
-	struct dm_buffer *b = kmalloc(sizeof(struct dm_buffer) + c->aux_size,
-				      gfp_mask);
+	struct dm_buffer *b = kmem_cache_alloc(c->slab_buffer, gfp_mask);
 
 	if (!b)
 		return NULL;
@@ -461,7 +431,7 @@ static struct dm_buffer *alloc_buffer(struct dm_bufio_client *c, gfp_t gfp_mask)
 
 	b->data = alloc_buffer_data(c, gfp_mask, &b->data_mode);
 	if (!b->data) {
-		kfree(b);
+		kmem_cache_free(c->slab_buffer, b);
 		return NULL;
 	}
 
@@ -483,7 +453,7 @@ static void free_buffer(struct dm_buffer *b)
 	adjust_total_allocated(b->data_mode, -(long)c->block_size);
 
 	free_buffer_data(c, b->data, b->data_mode);
-	kfree(b);
+	kmem_cache_free(c->slab_buffer, b);
 }
 
 /*
@@ -540,10 +510,6 @@ static void __relink_lru(struct dm_buffer *b, int dirty)
  *
  *	the memory must be direct-mapped, not vmalloced;
  *
- *	the I/O driver can reject requests spuriously if it thinks that
- *	the requests are too big for the device or if they cross a
- *	controller-defined memory boundary.
- *
  * If the buffer is small enough (up to DM_BUFIO_INLINE_VECS pages) and
  * it is not vmalloced, try using the bio interface.
  *
@@ -561,12 +527,11 @@ static void dmio_complete(unsigned long error, void *context)
 {
 	struct dm_buffer *b = context;
 
-	b->bio.bi_status = error ? BLK_STS_IOERR : 0;
-	b->bio.bi_end_io(&b->bio);
+	b->end_io(b, unlikely(error != 0) ? BLK_STS_IOERR : 0);
 }
 
 static void use_dmio(struct dm_buffer *b, int rw, sector_t sector,
-		     unsigned n_sectors, unsigned offset, bio_end_io_t *end_io)
+		     unsigned n_sectors, unsigned offset)
 {
 	int r;
 	struct dm_io_request io_req = {
@@ -590,76 +555,77 @@ static void use_dmio(struct dm_buffer *b, int rw, sector_t sector,
 		io_req.mem.ptr.vma = (char *)b->data + offset;
 	}
 
-	b->bio.bi_end_io = end_io;
-
 	r = dm_io(&io_req, 1, &region, NULL);
-	if (r) {
-		b->bio.bi_status = errno_to_blk_status(r);
-		end_io(&b->bio);
-	}
+	if (unlikely(r))
+		b->end_io(b, errno_to_blk_status(r));
 }
 
-static void inline_endio(struct bio *bio)
+static void bio_complete(struct bio *bio)
 {
-	bio_end_io_t *end_fn = bio->bi_private;
+	struct dm_buffer *b = bio->bi_private;
 	blk_status_t status = bio->bi_status;
-
-	/*
-	 * Reset the bio to free any attached resources
-	 * (e.g. bio integrity profiles).
-	 */
-	bio_reset(bio);
-
-	bio->bi_status = status;
-	end_fn(bio);
+	bio_put(bio);
+	b->end_io(b, status);
 }
 
-static void use_inline_bio(struct dm_buffer *b, int rw, sector_t sector,
-			   unsigned n_sectors, unsigned offset, bio_end_io_t *end_io)
+static void use_bio(struct dm_buffer *b, int rw, sector_t sector,
+		    unsigned n_sectors, unsigned offset)
 {
+	struct bio *bio;
 	char *ptr;
-	unsigned len;
+	unsigned vec_size, len;
 
-	bio_init(&b->bio, b->bio_vec, DM_BUFIO_INLINE_VECS);
-	b->bio.bi_iter.bi_sector = sector;
-	bio_set_dev(&b->bio, b->c->bdev);
-	b->bio.bi_end_io = inline_endio;
-	/*
-	 * Use of .bi_private isn't a problem here because
-	 * the dm_buffer's inline bio is local to bufio.
-	 */
-	b->bio.bi_private = end_io;
-	bio_set_op_attrs(&b->bio, rw, 0);
+	vec_size = b->c->block_size >> PAGE_SHIFT;
+	if (unlikely(b->c->sectors_per_block_bits < PAGE_SHIFT - SECTOR_SHIFT))
+		vec_size += 2;
+
+	bio = bio_kmalloc(GFP_NOWAIT | __GFP_NORETRY | __GFP_NOWARN, vec_size);
+	if (!bio) {
+dmio:
+		use_dmio(b, rw, sector, n_sectors, offset);
+		return;
+	}
+
+	bio->bi_iter.bi_sector = sector;
+	bio_set_dev(bio, b->c->bdev);
+	bio_set_op_attrs(bio, rw, 0);
+	bio->bi_end_io = bio_complete;
+	bio->bi_private = b;
 
 	ptr = (char *)b->data + offset;
 	len = n_sectors << SECTOR_SHIFT;
 
 	do {
 		unsigned this_step = min((unsigned)(PAGE_SIZE - offset_in_page(ptr)), len);
-		if (!bio_add_page(&b->bio, virt_to_page(ptr), this_step,
+		if (!bio_add_page(bio, virt_to_page(ptr), this_step,
 				  offset_in_page(ptr))) {
-			BUG_ON(b->c->block_size <= PAGE_SIZE);
-			use_dmio(b, rw, sector, n_sectors, offset, end_io);
-			return;
+			bio_put(bio);
+			goto dmio;
 		}
 
 		len -= this_step;
 		ptr += this_step;
 	} while (len > 0);
 
-	submit_bio(&b->bio);
+	submit_bio(bio);
 }
 
-static void submit_io(struct dm_buffer *b, int rw, bio_end_io_t *end_io)
+static void submit_io(struct dm_buffer *b, int rw, void (*end_io)(struct dm_buffer *, blk_status_t))
 {
 	unsigned n_sectors;
 	sector_t sector;
 	unsigned offset, end;
 
-	sector = (b->block << b->c->sectors_per_block_bits) + b->c->start;
+	b->end_io = end_io;
+
+	if (likely(b->c->sectors_per_block_bits >= 0))
+		sector = b->block << b->c->sectors_per_block_bits;
+	else
+		sector = b->block * (b->c->block_size >> SECTOR_SHIFT);
+	sector += b->c->start;
 
 	if (rw != REQ_OP_WRITE) {
-		n_sectors = 1 << b->c->sectors_per_block_bits;
+		n_sectors = b->c->block_size >> SECTOR_SHIFT;
 		offset = 0;
 	} else {
 		if (b->c->write_callback)
@@ -676,11 +642,10 @@ static void submit_io(struct dm_buffer *b, int rw, bio_end_io_t *end_io)
 		n_sectors = (end - offset) >> SECTOR_SHIFT;
 	}
 
-	if (n_sectors <= ((DM_BUFIO_INLINE_VECS * PAGE_SIZE) >> SECTOR_SHIFT) &&
-	    b->data_mode != DATA_MODE_VMALLOC)
-		use_inline_bio(b, rw, sector, n_sectors, offset, end_io);
+	if (b->data_mode != DATA_MODE_VMALLOC)
+		use_bio(b, rw, sector, n_sectors, offset);
 	else
-		use_dmio(b, rw, sector, n_sectors, offset, end_io);
+		use_dmio(b, rw, sector, n_sectors, offset);
 }
 
 /*----------------------------------------------------------------
@@ -693,16 +658,14 @@ static void submit_io(struct dm_buffer *b, int rw, bio_end_io_t *end_io)
  * Set the error, clear B_WRITING bit and wake anyone who was waiting on
  * it.
  */
-static void write_endio(struct bio *bio)
+static void write_endio(struct dm_buffer *b, blk_status_t status)
 {
-	struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
-
-	b->write_error = bio->bi_status;
-	if (unlikely(bio->bi_status)) {
+	b->write_error = status;
+	if (unlikely(status)) {
 		struct dm_bufio_client *c = b->c;
 
 		(void)cmpxchg(&c->async_write_error, 0,
-				blk_status_to_errno(bio->bi_status));
+				blk_status_to_errno(status));
 	}
 
 	BUG_ON(!test_bit(B_WRITING, &b->state));
@@ -963,8 +926,11 @@ static void __get_memory_limit(struct dm_bufio_client *c,
 		}
 	}
 
-	buffers = dm_bufio_cache_size_per_client >>
-		  (c->sectors_per_block_bits + SECTOR_SHIFT);
+	buffers = dm_bufio_cache_size_per_client;
+	if (likely(c->sectors_per_block_bits >= 0))
+		buffers >>= c->sectors_per_block_bits + SECTOR_SHIFT;
+	else
+		buffers /= c->block_size;
 
 	if (buffers < c->minimum_buffers)
 		buffers = c->minimum_buffers;
@@ -1076,11 +1042,9 @@ static struct dm_buffer *__bufio_new(struct dm_bufio_client *c, sector_t block,
  * The endio routine for reading: set the error, clear the bit and wake up
  * anyone waiting on the buffer.
  */
-static void read_endio(struct bio *bio)
+static void read_endio(struct dm_buffer *b, blk_status_t status)
 {
-	struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
-
-	b->read_error = bio->bi_status;
+	b->read_error = status;
 
 	BUG_ON(!test_bit(B_READING, &b->state));
 
@@ -1482,13 +1446,13 @@ void dm_bufio_forget(struct dm_bufio_client *c, sector_t block)
 
 	dm_bufio_unlock(c);
 }
-EXPORT_SYMBOL(dm_bufio_forget);
+EXPORT_SYMBOL_GPL(dm_bufio_forget);
 
 void dm_bufio_set_minimum_buffers(struct dm_bufio_client *c, unsigned n)
 {
 	c->minimum_buffers = n;
 }
-EXPORT_SYMBOL(dm_bufio_set_minimum_buffers);
+EXPORT_SYMBOL_GPL(dm_bufio_set_minimum_buffers);
 
 unsigned dm_bufio_get_block_size(struct dm_bufio_client *c)
 {
@@ -1498,8 +1462,12 @@ EXPORT_SYMBOL_GPL(dm_bufio_get_block_size);
 
 sector_t dm_bufio_get_device_size(struct dm_bufio_client *c)
 {
-	return i_size_read(c->bdev->bd_inode) >>
-			   (SECTOR_SHIFT + c->sectors_per_block_bits);
+	sector_t s = i_size_read(c->bdev->bd_inode) >> SECTOR_SHIFT;
+	if (likely(c->sectors_per_block_bits >= 0))
+		s >>= c->sectors_per_block_bits;
+	else
+		sector_div(s, c->block_size >> SECTOR_SHIFT);
+	return s;
 }
 EXPORT_SYMBOL_GPL(dm_bufio_get_device_size);
 
@@ -1597,8 +1565,12 @@ static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp)
 
 static unsigned long get_retain_buffers(struct dm_bufio_client *c)
 {
-        unsigned long retain_bytes = READ_ONCE(dm_bufio_retain_bytes);
-        return retain_bytes >> (c->sectors_per_block_bits + SECTOR_SHIFT);
+	unsigned long retain_bytes = READ_ONCE(dm_bufio_retain_bytes);
+	if (likely(c->sectors_per_block_bits >= 0))
+		retain_bytes >>= c->sectors_per_block_bits + SECTOR_SHIFT;
+	else
+		retain_bytes /= c->block_size;
+	return retain_bytes;
 }
 
 static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
@@ -1662,9 +1634,13 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 	int r;
 	struct dm_bufio_client *c;
 	unsigned i;
+	char slab_name[27];
 
-	BUG_ON(block_size < 1 << SECTOR_SHIFT ||
-	       (block_size & (block_size - 1)));
+	if (!block_size || block_size & ((1 << SECTOR_SHIFT) - 1)) {
+		DMERR("%s: block size not specified or is not multiple of 512b", __func__);
+		r = -EINVAL;
+		goto bad_client;
+	}
 
 	c = kzalloc(sizeof(*c), GFP_KERNEL);
 	if (!c) {
@@ -1675,13 +1651,11 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 
 	c->bdev = bdev;
 	c->block_size = block_size;
-	c->sectors_per_block_bits = __ffs(block_size) - SECTOR_SHIFT;
-	c->pages_per_block_bits = (__ffs(block_size) >= PAGE_SHIFT) ?
-				  __ffs(block_size) - PAGE_SHIFT : 0;
-	c->blocks_per_page_bits = (__ffs(block_size) < PAGE_SHIFT ?
-				  PAGE_SHIFT - __ffs(block_size) : 0);
+	if (is_power_of_2(block_size))
+		c->sectors_per_block_bits = __ffs(block_size) - SECTOR_SHIFT;
+	else
+		c->sectors_per_block_bits = -1;
 
-	c->aux_size = aux_size;
 	c->alloc_callback = alloc_callback;
 	c->write_callback = write_callback;
 
@@ -1694,7 +1668,7 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 	INIT_LIST_HEAD(&c->reserved_buffers);
 	c->need_reserved_buffers = reserved_buffers;
 
-	c->minimum_buffers = DM_BUFIO_MIN_BUFFERS;
+	dm_bufio_set_minimum_buffers(c, DM_BUFIO_MIN_BUFFERS);
 
 	init_waitqueue_head(&c->free_buffer_wait);
 	c->async_write_error = 0;
@@ -1705,29 +1679,26 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 		goto bad_dm_io;
 	}
 
-	mutex_lock(&dm_bufio_clients_lock);
-	if (c->blocks_per_page_bits) {
-		if (!DM_BUFIO_CACHE_NAME(c)) {
-			DM_BUFIO_CACHE_NAME(c) = kasprintf(GFP_KERNEL, "dm_bufio_cache-%u", c->block_size);
-			if (!DM_BUFIO_CACHE_NAME(c)) {
-				r = -ENOMEM;
-				mutex_unlock(&dm_bufio_clients_lock);
-				goto bad;
-			}
-		}
-
-		if (!DM_BUFIO_CACHE(c)) {
-			DM_BUFIO_CACHE(c) = kmem_cache_create(DM_BUFIO_CACHE_NAME(c),
-							      c->block_size,
-							      c->block_size, 0, NULL);
-			if (!DM_BUFIO_CACHE(c)) {
-				r = -ENOMEM;
-				mutex_unlock(&dm_bufio_clients_lock);
-				goto bad;
-			}
+	if (block_size <= KMALLOC_MAX_SIZE &&
+	    (block_size < PAGE_SIZE || !is_power_of_2(block_size))) {
+		snprintf(slab_name, sizeof slab_name, "dm_bufio_cache-%u", c->block_size);
+		c->slab_cache = kmem_cache_create(slab_name, c->block_size, ARCH_KMALLOC_MINALIGN,
+						  SLAB_RECLAIM_ACCOUNT, NULL);
+		if (!c->slab_cache) {
+			r = -ENOMEM;
+			goto bad;
 		}
 	}
-	mutex_unlock(&dm_bufio_clients_lock);
+	if (aux_size)
+		snprintf(slab_name, sizeof slab_name, "dm_bufio_buffer-%u", aux_size);
+	else
+		snprintf(slab_name, sizeof slab_name, "dm_bufio_buffer");
+	c->slab_buffer = kmem_cache_create(slab_name, sizeof(struct dm_buffer) + aux_size,
+					   0, SLAB_RECLAIM_ACCOUNT, NULL);
+	if (!c->slab_buffer) {
+		r = -ENOMEM;
+		goto bad;
+	}
 
 	while (c->need_reserved_buffers) {
 		struct dm_buffer *b = alloc_buffer(c, GFP_KERNEL);
@@ -1762,6 +1733,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 		list_del(&b->lru_list);
 		free_buffer(b);
 	}
+	kmem_cache_destroy(c->slab_cache);
+	kmem_cache_destroy(c->slab_buffer);
 	dm_io_client_destroy(c->dm_io);
 bad_dm_io:
 	mutex_destroy(&c->lock);
@@ -1808,6 +1781,8 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c)
 	for (i = 0; i < LIST_SIZE; i++)
 		BUG_ON(c->n_buffers[i]);
 
+	kmem_cache_destroy(c->slab_cache);
+	kmem_cache_destroy(c->slab_buffer);
 	dm_io_client_destroy(c->dm_io);
 	mutex_destroy(&c->lock);
 	kfree(c);
@@ -1911,9 +1886,6 @@ static int __init dm_bufio_init(void)
 	dm_bufio_allocated_vmalloc = 0;
 	dm_bufio_current_allocated = 0;
 
-	memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches);
-	memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names);
-
 	mem = (__u64)mult_frac(totalram_pages - totalhigh_pages,
 			       DM_BUFIO_MEMORY_PERCENT, 100) << PAGE_SHIFT;
 
@@ -1948,17 +1920,10 @@ static int __init dm_bufio_init(void)
 static void __exit dm_bufio_exit(void)
 {
 	int bug = 0;
-	int i;
 
 	cancel_delayed_work_sync(&dm_bufio_work);
 	destroy_workqueue(dm_bufio_wq);
 
-	for (i = 0; i < ARRAY_SIZE(dm_bufio_caches); i++)
-		kmem_cache_destroy(dm_bufio_caches[i]);
-
-	for (i = 0; i < ARRAY_SIZE(dm_bufio_cache_names); i++)
-		kfree(dm_bufio_cache_names[i]);
-
 	if (dm_bufio_client_count) {
 		DMCRIT("%s: dm_bufio_client_count leaked: %d",
 			__func__, dm_bufio_client_count);
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index 47407e4..da20863 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -3387,7 +3387,8 @@ static int process_invalidate_cblocks_message(struct cache *cache, unsigned coun
  *
  * The key migration_threshold is supported by the cache target core.
  */
-static int cache_message(struct dm_target *ti, unsigned argc, char **argv)
+static int cache_message(struct dm_target *ti, unsigned argc, char **argv,
+			 char *result, unsigned maxlen)
 {
 	struct cache *cache = ti->private;
 
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 8168f73..44ff473 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -148,6 +148,8 @@ struct crypt_config {
 	mempool_t *tag_pool;
 	unsigned tag_pool_max_sectors;
 
+	struct percpu_counter n_allocated_pages;
+
 	struct bio_set *bs;
 	struct mutex bio_alloc_lock;
 
@@ -219,6 +221,12 @@ struct crypt_config {
 #define MAX_TAG_SIZE	480
 #define POOL_ENTRY_SIZE	512
 
+static DEFINE_SPINLOCK(dm_crypt_clients_lock);
+static unsigned dm_crypt_clients_n = 0;
+static volatile unsigned long dm_crypt_pages_per_client;
+#define DM_CRYPT_MEMORY_PERCENT			2
+#define DM_CRYPT_MIN_PAGES_PER_CLIENT		(BIO_MAX_PAGES * 16)
+
 static void clone_init(struct dm_crypt_io *, struct bio *);
 static void kcryptd_queue_crypt(struct dm_crypt_io *io);
 static struct scatterlist *crypt_get_sg_data(struct crypt_config *cc,
@@ -2155,6 +2163,43 @@ static int crypt_wipe_key(struct crypt_config *cc)
 	return r;
 }
 
+static void crypt_calculate_pages_per_client(void)
+{
+	unsigned long pages = (totalram_pages - totalhigh_pages) * DM_CRYPT_MEMORY_PERCENT / 100;
+
+	if (!dm_crypt_clients_n)
+		return;
+
+	pages /= dm_crypt_clients_n;
+	if (pages < DM_CRYPT_MIN_PAGES_PER_CLIENT)
+		pages = DM_CRYPT_MIN_PAGES_PER_CLIENT;
+	dm_crypt_pages_per_client = pages;
+}
+
+static void *crypt_page_alloc(gfp_t gfp_mask, void *pool_data)
+{
+	struct crypt_config *cc = pool_data;
+	struct page *page;
+
+	if (unlikely(percpu_counter_compare(&cc->n_allocated_pages, dm_crypt_pages_per_client) >= 0) &&
+	    likely(gfp_mask & __GFP_NORETRY))
+		return NULL;
+
+	page = alloc_page(gfp_mask);
+	if (likely(page != NULL))
+		percpu_counter_add(&cc->n_allocated_pages, 1);
+
+	return page;
+}
+
+static void crypt_page_free(void *page, void *pool_data)
+{
+	struct crypt_config *cc = pool_data;
+
+	__free_page(page);
+	percpu_counter_sub(&cc->n_allocated_pages, 1);
+}
+
 static void crypt_dtr(struct dm_target *ti)
 {
 	struct crypt_config *cc = ti->private;
@@ -2181,6 +2226,10 @@ static void crypt_dtr(struct dm_target *ti)
 	mempool_destroy(cc->req_pool);
 	mempool_destroy(cc->tag_pool);
 
+	if (cc->page_pool)
+		WARN_ON(percpu_counter_sum(&cc->n_allocated_pages) != 0);
+	percpu_counter_destroy(&cc->n_allocated_pages);
+
 	if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
 		cc->iv_gen_ops->dtr(cc);
 
@@ -2197,6 +2246,12 @@ static void crypt_dtr(struct dm_target *ti)
 
 	/* Must zero key material before freeing */
 	kzfree(cc);
+
+	spin_lock(&dm_crypt_clients_lock);
+	WARN_ON(!dm_crypt_clients_n);
+	dm_crypt_clients_n--;
+	crypt_calculate_pages_per_client();
+	spin_unlock(&dm_crypt_clients_lock);
 }
 
 static int crypt_ctr_ivmode(struct dm_target *ti, const char *ivmode)
@@ -2644,6 +2699,15 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
 	ti->private = cc;
 
+	spin_lock(&dm_crypt_clients_lock);
+	dm_crypt_clients_n++;
+	crypt_calculate_pages_per_client();
+	spin_unlock(&dm_crypt_clients_lock);
+
+	ret = percpu_counter_init(&cc->n_allocated_pages, 0, GFP_KERNEL);
+	if (ret < 0)
+		goto bad;
+
 	/* Optional parameters need to be read before cipher constructor */
 	if (argc > 5) {
 		ret = crypt_ctr_optional(ti, argc - 5, &argv[5]);
@@ -2698,7 +2762,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 		ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start + additional_req_size,
 		      ARCH_KMALLOC_MINALIGN);
 
-	cc->page_pool = mempool_create_page_pool(BIO_MAX_PAGES, 0);
+	cc->page_pool = mempool_create(BIO_MAX_PAGES, crypt_page_alloc, crypt_page_free, cc);
 	if (!cc->page_pool) {
 		ti->error = "Cannot allocate page mempool";
 		goto bad;
@@ -2942,7 +3006,8 @@ static void crypt_resume(struct dm_target *ti)
  *	key set <key>
  *	key wipe
  */
-static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
+static int crypt_message(struct dm_target *ti, unsigned argc, char **argv,
+			 char *result, unsigned maxlen)
 {
 	struct crypt_config *cc = ti->private;
 	int key_size, ret = -EINVAL;
diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c
index 73a5c19..8e48920 100644
--- a/drivers/md/dm-era-target.c
+++ b/drivers/md/dm-era-target.c
@@ -1635,7 +1635,8 @@ static void era_status(struct dm_target *ti, status_type_t type,
 	DMEMIT("Error");
 }
 
-static int era_message(struct dm_target *ti, unsigned argc, char **argv)
+static int era_message(struct dm_target *ti, unsigned argc, char **argv,
+		       char *result, unsigned maxlen)
 {
 	struct era *era = ti->private;
 
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
index 1b907b1..21d126a 100644
--- a/drivers/md/dm-flakey.c
+++ b/drivers/md/dm-flakey.c
@@ -442,8 +442,7 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
 	}
 }
 
-static int flakey_prepare_ioctl(struct dm_target *ti,
-		struct block_device **bdev, fmode_t *mode)
+static int flakey_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
 {
 	struct flakey_c *fc = ti->private;
 
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 46d7c87..77d9fe5 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -18,7 +18,7 @@
 #include <crypto/hash.h>
 #include <crypto/skcipher.h>
 #include <linux/async_tx.h>
-#include "dm-bufio.h"
+#include <linux/dm-bufio.h>
 
 #define DM_MSG_PREFIX "integrity"
 
@@ -2548,6 +2548,9 @@ static int get_mac(struct crypto_shash **hash, struct alg_spec *a, char **error,
 				*error = error_key;
 				return r;
 			}
+		} else if (crypto_shash_get_flags(*hash) & CRYPTO_TFM_NEED_KEY) {
+			*error = error_key;
+			return -ENOKEY;
 		}
 	}
 
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index a89fd8f..5acf77d 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1595,7 +1595,7 @@ static int target_message(struct file *filp, struct dm_ioctl *param, size_t para
 		DMWARN("Target message sector outside device.");
 		r = -EINVAL;
 	} else if (ti->type->message)
-		r = ti->type->message(ti, argc, argv);
+		r = ti->type->message(ti, argc, argv, result, maxlen);
 	else {
 		DMWARN("Target type does not support messages");
 		r = -EINVAL;
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index d5f8eff..9929721 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -59,6 +59,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
 	ti->num_flush_bios = 1;
 	ti->num_discard_bios = 1;
+	ti->num_secure_erase_bios = 1;
 	ti->num_write_same_bios = 1;
 	ti->num_write_zeroes_bios = 1;
 	ti->private = lc;
@@ -129,8 +130,7 @@ static void linear_status(struct dm_target *ti, status_type_t type,
 	}
 }
 
-static int linear_prepare_ioctl(struct dm_target *ti,
-		struct block_device **bdev, fmode_t *mode)
+static int linear_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
 {
 	struct linear_c *lc = (struct linear_c *) ti->private;
 	struct dm_dev *dev = lc->dev;
diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
index 3362d86..9de072b 100644
--- a/drivers/md/dm-log-writes.c
+++ b/drivers/md/dm-log-writes.c
@@ -52,10 +52,11 @@
  * in fact we want to do the data and the discard in the order that they
  * completed.
  */
-#define LOG_FLUSH_FLAG (1 << 0)
-#define LOG_FUA_FLAG (1 << 1)
-#define LOG_DISCARD_FLAG (1 << 2)
-#define LOG_MARK_FLAG (1 << 3)
+#define LOG_FLUSH_FLAG		(1 << 0)
+#define LOG_FUA_FLAG		(1 << 1)
+#define LOG_DISCARD_FLAG	(1 << 2)
+#define LOG_MARK_FLAG		(1 << 3)
+#define LOG_METADATA_FLAG	(1 << 4)
 
 #define WRITE_LOG_VERSION 1ULL
 #define WRITE_LOG_MAGIC 0x6a736677736872ULL
@@ -699,6 +700,7 @@ static int log_writes_map(struct dm_target *ti, struct bio *bio)
 	bool flush_bio = (bio->bi_opf & REQ_PREFLUSH);
 	bool fua_bio = (bio->bi_opf & REQ_FUA);
 	bool discard_bio = (bio_op(bio) == REQ_OP_DISCARD);
+	bool meta_bio = (bio->bi_opf & REQ_META);
 
 	pb->block = NULL;
 
@@ -743,6 +745,8 @@ static int log_writes_map(struct dm_target *ti, struct bio *bio)
 		block->flags |= LOG_FUA_FLAG;
 	if (discard_bio)
 		block->flags |= LOG_DISCARD_FLAG;
+	if (meta_bio)
+		block->flags |= LOG_METADATA_FLAG;
 
 	block->sector = bio_to_dev_sectors(lc, bio->bi_iter.bi_sector);
 	block->nr_sectors = bio_to_dev_sectors(lc, bio_sectors(bio));
@@ -860,7 +864,7 @@ static void log_writes_status(struct dm_target *ti, status_type_t type,
 }
 
 static int log_writes_prepare_ioctl(struct dm_target *ti,
-		struct block_device **bdev, fmode_t *mode)
+				    struct block_device **bdev)
 {
 	struct log_writes_c *lc = ti->private;
 	struct dm_dev *dev = lc->dev;
@@ -887,7 +891,8 @@ static int log_writes_iterate_devices(struct dm_target *ti,
  * Messages supported:
  *   mark <mark data> - specify the marked data.
  */
-static int log_writes_message(struct dm_target *ti, unsigned argc, char **argv)
+static int log_writes_message(struct dm_target *ti, unsigned argc, char **argv,
+			      char *result, unsigned maxlen)
 {
 	int r = -EINVAL;
 	struct log_writes_c *lc = ti->private;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index a6b7baf..203a041 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -714,7 +714,7 @@ static void process_queued_bios(struct work_struct *work)
 		case DM_MAPIO_REMAPPED:
 			generic_make_request(bio);
 			break;
-		case 0:
+		case DM_MAPIO_SUBMITTED:
 			break;
 		default:
 			WARN_ONCE(true, "__multipath_map_bio() returned %d\n", r);
@@ -1811,7 +1811,8 @@ static void multipath_status(struct dm_target *ti, status_type_t type,
 	spin_unlock_irqrestore(&m->lock, flags);
 }
 
-static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
+static int multipath_message(struct dm_target *ti, unsigned argc, char **argv,
+			     char *result, unsigned maxlen)
 {
 	int r = -EINVAL;
 	struct dm_dev *dev;
@@ -1875,7 +1876,7 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
 }
 
 static int multipath_prepare_ioctl(struct dm_target *ti,
-		struct block_device **bdev, fmode_t *mode)
+				   struct block_device **bdev)
 {
 	struct multipath *m = ti->private;
 	struct pgpath *current_pgpath;
@@ -1888,7 +1889,6 @@ static int multipath_prepare_ioctl(struct dm_target *ti,
 	if (current_pgpath) {
 		if (!test_bit(MPATHF_QUEUE_IO, &m->flags)) {
 			*bdev = current_pgpath->path.dev->bdev;
-			*mode = current_pgpath->path.dev->mode;
 			r = 0;
 		} else {
 			/* pg_init has not started or completed */
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index c1d1034..6f823f4 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -1370,19 +1370,18 @@ static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
 			 * In device-mapper, we specify things in sectors, but
 			 * MD records this value in kB
 			 */
-			value /= 2;
-			if (value > COUNTER_MAX) {
+			if (value < 0 || value / 2 > COUNTER_MAX) {
 				rs->ti->error = "Max write-behind limit out of range";
 				return -EINVAL;
 			}
 
-			rs->md.bitmap_info.max_write_behind = value;
+			rs->md.bitmap_info.max_write_behind = value / 2;
 		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_DAEMON_SLEEP))) {
 			if (test_and_set_bit(__CTR_FLAG_DAEMON_SLEEP, &rs->ctr_flags)) {
 				rs->ti->error = "Only one daemon_sleep argument pair allowed";
 				return -EINVAL;
 			}
-			if (!value || (value > MAX_SCHEDULE_TIMEOUT)) {
+			if (value < 0) {
 				rs->ti->error = "daemon sleep period out of range";
 				return -EINVAL;
 			}
@@ -1424,27 +1423,33 @@ static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
 				return -EINVAL;
 			}
 
+			if (value < 0) {
+				rs->ti->error = "Bogus stripe cache entries value";
+				return -EINVAL;
+			}
 			rs->stripe_cache_entries = value;
 		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MIN_RECOVERY_RATE))) {
 			if (test_and_set_bit(__CTR_FLAG_MIN_RECOVERY_RATE, &rs->ctr_flags)) {
 				rs->ti->error = "Only one min_recovery_rate argument pair allowed";
 				return -EINVAL;
 			}
-			if (value > INT_MAX) {
+
+			if (value < 0) {
 				rs->ti->error = "min_recovery_rate out of range";
 				return -EINVAL;
 			}
-			rs->md.sync_speed_min = (int)value;
+			rs->md.sync_speed_min = value;
 		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MAX_RECOVERY_RATE))) {
 			if (test_and_set_bit(__CTR_FLAG_MAX_RECOVERY_RATE, &rs->ctr_flags)) {
 				rs->ti->error = "Only one max_recovery_rate argument pair allowed";
 				return -EINVAL;
 			}
-			if (value > INT_MAX) {
+
+			if (value < 0) {
 				rs->ti->error = "max_recovery_rate out of range";
 				return -EINVAL;
 			}
-			rs->md.sync_speed_max = (int)value;
+			rs->md.sync_speed_max = value;
 		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_REGION_SIZE))) {
 			if (test_and_set_bit(__CTR_FLAG_REGION_SIZE, &rs->ctr_flags)) {
 				rs->ti->error = "Only one region_size argument pair allowed";
@@ -1490,6 +1495,12 @@ static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
 		return -EINVAL;
 	}
 
+	if (rs->md.sync_speed_max &&
+	    rs->md.sync_speed_min > rs->md.sync_speed_max) {
+		rs->ti->error = "Bogus recovery rates";
+		return -EINVAL;
+	}
+
 	if (validate_region_size(rs, region_size))
 		return -EINVAL;
 
@@ -3408,7 +3419,8 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
 		set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
 
 	} else {
-		if (!test_bit(MD_RECOVERY_INTR, &recovery) &&
+		if (!test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags) &&
+		    !test_bit(MD_RECOVERY_INTR, &recovery) &&
 		    (test_bit(MD_RECOVERY_NEEDED, &recovery) ||
 		     test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
 		     test_bit(MD_RECOVERY_RUNNING, &recovery)))
@@ -3663,7 +3675,8 @@ static void raid_status(struct dm_target *ti, status_type_t type,
 	}
 }
 
-static int raid_message(struct dm_target *ti, unsigned int argc, char **argv)
+static int raid_message(struct dm_target *ti, unsigned int argc, char **argv,
+			char *result, unsigned maxlen)
 {
 	struct raid_set *rs = ti->private;
 	struct mddev *mddev = &rs->md;
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index c5534d2..3c50c4e 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -14,7 +14,7 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/dm-io.h>
-#include "dm-bufio.h"
+#include <linux/dm-bufio.h>
 
 #define DM_MSG_PREFIX "persistent snapshot"
 #define DM_CHUNK_SIZE_DEFAULT_SECTORS 32	/* 16KB */
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index b5e8921..bb907cb 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -169,6 +169,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
 	ti->num_flush_bios = stripes;
 	ti->num_discard_bios = stripes;
+	ti->num_secure_erase_bios = stripes;
 	ti->num_write_same_bios = stripes;
 	ti->num_write_zeroes_bios = stripes;
 
@@ -295,6 +296,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
 		return DM_MAPIO_REMAPPED;
 	}
 	if (unlikely(bio_op(bio) == REQ_OP_DISCARD) ||
+	    unlikely(bio_op(bio) == REQ_OP_SECURE_ERASE) ||
 	    unlikely(bio_op(bio) == REQ_OP_WRITE_ZEROES) ||
 	    unlikely(bio_op(bio) == REQ_OP_WRITE_SAME)) {
 		target_bio_nr = dm_bio_get_target_bio_nr(bio);
@@ -368,7 +370,6 @@ static void stripe_status(struct dm_target *ti, status_type_t type,
 			  unsigned status_flags, char *result, unsigned maxlen)
 {
 	struct stripe_c *sc = (struct stripe_c *) ti->private;
-	char buffer[sc->stripes + 1];
 	unsigned int sz = 0;
 	unsigned int i;
 
@@ -377,11 +378,12 @@ static void stripe_status(struct dm_target *ti, status_type_t type,
 		DMEMIT("%d ", sc->stripes);
 		for (i = 0; i < sc->stripes; i++)  {
 			DMEMIT("%s ", sc->stripe[i].dev->name);
-			buffer[i] = atomic_read(&(sc->stripe[i].error_count)) ?
-				'D' : 'A';
 		}
-		buffer[i] = '\0';
-		DMEMIT("1 %s", buffer);
+		DMEMIT("1 ");
+		for (i = 0; i < sc->stripes; i++) {
+			DMEMIT("%c", atomic_read(&(sc->stripe[i].error_count)) ?
+			       'D' : 'A');
+		}
 		break;
 
 	case STATUSTYPE_TABLE:
diff --git a/drivers/md/dm-switch.c b/drivers/md/dm-switch.c
index 8d0ba87..7924a6a 100644
--- a/drivers/md/dm-switch.c
+++ b/drivers/md/dm-switch.c
@@ -466,7 +466,8 @@ static int process_set_region_mappings(struct switch_ctx *sctx,
  *
  * Only set_region_mappings is supported.
  */
-static int switch_message(struct dm_target *ti, unsigned argc, char **argv)
+static int switch_message(struct dm_target *ti, unsigned argc, char **argv,
+			  char *result, unsigned maxlen)
 {
 	static DEFINE_MUTEX(message_mutex);
 
@@ -511,8 +512,7 @@ static void switch_status(struct dm_target *ti, status_type_t type,
  *
  * Passthrough all ioctls to the path for sector 0
  */
-static int switch_prepare_ioctl(struct dm_target *ti,
-		struct block_device **bdev, fmode_t *mode)
+static int switch_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
 {
 	struct switch_ctx *sctx = ti->private;
 	unsigned path_nr;
@@ -520,7 +520,6 @@ static int switch_prepare_ioctl(struct dm_target *ti,
 	path_nr = switch_get_path_nr(sctx, 0);
 
 	*bdev = sctx->path_list[path_nr].dmdev->bdev;
-	*mode = sctx->path_list[path_nr].dmdev->mode;
 
 	/*
 	 * Only pass ioctls through if the device sizes match exactly.
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 7eb3e2a..0589a4d 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -1846,6 +1846,34 @@ static bool dm_table_supports_discards(struct dm_table *t)
 	return true;
 }
 
+static int device_not_secure_erase_capable(struct dm_target *ti,
+					   struct dm_dev *dev, sector_t start,
+					   sector_t len, void *data)
+{
+	struct request_queue *q = bdev_get_queue(dev->bdev);
+
+	return q && !blk_queue_secure_erase(q);
+}
+
+static bool dm_table_supports_secure_erase(struct dm_table *t)
+{
+	struct dm_target *ti;
+	unsigned int i;
+
+	for (i = 0; i < dm_table_get_num_targets(t); i++) {
+		ti = dm_table_get_target(t, i);
+
+		if (!ti->num_secure_erase_bios)
+			return false;
+
+		if (!ti->type->iterate_devices ||
+		    ti->type->iterate_devices(ti, device_not_secure_erase_capable, NULL))
+			return false;
+	}
+
+	return true;
+}
+
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
 			       struct queue_limits *limits)
 {
@@ -1857,7 +1885,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
 	q->limits = *limits;
 
 	if (!dm_table_supports_discards(t)) {
-		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
+		blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
 		/* Must also clear discard limits... */
 		q->limits.max_discard_sectors = 0;
 		q->limits.max_hw_discard_sectors = 0;
@@ -1865,7 +1893,10 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
 		q->limits.discard_alignment = 0;
 		q->limits.discard_misaligned = 0;
 	} else
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
+
+	if (dm_table_supports_secure_erase(t))
+		blk_queue_flag_set(QUEUE_FLAG_SECERASE, q);
 
 	if (dm_table_supports_flush(t, (1UL << QUEUE_FLAG_WC))) {
 		wc = true;
@@ -1875,15 +1906,15 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
 	blk_queue_write_cache(q, wc, fua);
 
 	if (dm_table_supports_dax(t))
-		queue_flag_set_unlocked(QUEUE_FLAG_DAX, q);
+		blk_queue_flag_set(QUEUE_FLAG_DAX, q);
 	if (dm_table_supports_dax_write_cache(t))
 		dax_write_cache(t->md->dax_dev, true);
 
 	/* Ensure that all underlying devices are non-rotational. */
 	if (dm_table_all_devices_attribute(t, device_is_nonrot))
-		queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
+		blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
 	else
-		queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q);
+		blk_queue_flag_clear(QUEUE_FLAG_NONROT, q);
 
 	if (!dm_table_supports_write_same(t))
 		q->limits.max_write_same_sectors = 0;
@@ -1891,9 +1922,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
 		q->limits.max_write_zeroes_sectors = 0;
 
 	if (dm_table_all_devices_attribute(t, queue_supports_sg_merge))
-		queue_flag_clear_unlocked(QUEUE_FLAG_NO_SG_MERGE, q);
+		blk_queue_flag_clear(QUEUE_FLAG_NO_SG_MERGE, q);
 	else
-		queue_flag_set_unlocked(QUEUE_FLAG_NO_SG_MERGE, q);
+		blk_queue_flag_set(QUEUE_FLAG_NO_SG_MERGE, q);
 
 	dm_table_verify_integrity(t);
 
@@ -1904,7 +1935,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
 	 * have it set.
 	 */
 	if (blk_queue_add_random(q) && dm_table_all_devices_attribute(t, device_is_not_random))
-		queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q);
+		blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q);
 }
 
 unsigned int dm_table_get_num_targets(struct dm_table *t)
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index c0d7e60..314d17c 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -16,8 +16,6 @@
 static LIST_HEAD(_targets);
 static DECLARE_RWSEM(_lock);
 
-#define DM_MOD_NAME_SIZE 32
-
 static inline struct target_type *__find_target_type(const char *name)
 {
 	struct target_type *tt;
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 629c555..b111074 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -3705,7 +3705,8 @@ static int process_release_metadata_snap_mesg(unsigned argc, char **argv, struct
  *   reserve_metadata_snap
  *   release_metadata_snap
  */
-static int pool_message(struct dm_target *ti, unsigned argc, char **argv)
+static int pool_message(struct dm_target *ti, unsigned argc, char **argv,
+			char *result, unsigned maxlen)
 {
 	int r = -EINVAL;
 	struct pool_c *pt = ti->private;
diff --git a/drivers/md/dm-unstripe.c b/drivers/md/dm-unstripe.c
index 65f838f..954b7ab 100644
--- a/drivers/md/dm-unstripe.c
+++ b/drivers/md/dm-unstripe.c
@@ -7,12 +7,6 @@
 #include "dm.h"
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/blkdev.h>
-#include <linux/bio.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-#include <linux/device-mapper.h>
 
 struct unstripe_c {
 	struct dm_dev *dev;
@@ -69,12 +63,6 @@ static int unstripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 		goto err;
 	}
 
-	// FIXME: must support non power of 2 chunk_size, dm-stripe.c does
-	if (!is_power_of_2(uc->chunk_size)) {
-		ti->error = "Non power of 2 chunk_size is not supported yet";
-		goto err;
-	}
-
 	if (kstrtouint(argv[2], 10, &uc->unstripe)) {
 		ti->error = "Invalid stripe number";
 		goto err;
@@ -98,7 +86,7 @@ static int unstripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
 	uc->unstripe_offset = uc->unstripe * uc->chunk_size;
 	uc->unstripe_width = (uc->stripes - 1) * uc->chunk_size;
-	uc->chunk_shift = fls(uc->chunk_size) - 1;
+	uc->chunk_shift = is_power_of_2(uc->chunk_size) ? fls(uc->chunk_size) - 1 : 0;
 
 	tmp_len = ti->len;
 	if (sector_div(tmp_len, uc->chunk_size)) {
@@ -129,14 +117,18 @@ static sector_t map_to_core(struct dm_target *ti, struct bio *bio)
 {
 	struct unstripe_c *uc = ti->private;
 	sector_t sector = bio->bi_iter.bi_sector;
+	sector_t tmp_sector = sector;
 
 	/* Shift us up to the right "row" on the stripe */
-	sector += uc->unstripe_width * (sector >> uc->chunk_shift);
+	if (uc->chunk_shift)
+		tmp_sector >>= uc->chunk_shift;
+	else
+		sector_div(tmp_sector, uc->chunk_size);
+
+	sector += uc->unstripe_width * tmp_sector;
 
 	/* Account for what stripe we're operating on */
-	sector += uc->unstripe_offset;
-
-	return sector;
+	return sector + uc->unstripe_offset;
 }
 
 static int unstripe_map(struct dm_target *ti, struct bio *bio)
@@ -185,7 +177,7 @@ static void unstripe_io_hints(struct dm_target *ti,
 
 static struct target_type unstripe_target = {
 	.name = "unstriped",
-	.version = {1, 0, 0},
+	.version = {1, 1, 0},
 	.module = THIS_MODULE,
 	.ctr = unstripe_ctr,
 	.dtr = unstripe_dtr,
@@ -197,13 +189,7 @@ static struct target_type unstripe_target = {
 
 static int __init dm_unstripe_init(void)
 {
-	int r;
-
-	r = dm_register_target(&unstripe_target);
-	if (r < 0)
-		DMERR("target registration failed");
-
-	return r;
+	return dm_register_target(&unstripe_target);
 }
 
 static void __exit dm_unstripe_exit(void)
@@ -215,5 +201,6 @@ module_init(dm_unstripe_init);
 module_exit(dm_unstripe_exit);
 
 MODULE_DESCRIPTION(DM_NAME " unstriped target");
+MODULE_ALIAS("dm-unstriped");
 MODULE_AUTHOR("Scott Bauer <scott.bauer@intel.com>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index aedb822..fc893f6 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -32,6 +32,7 @@
 #define DM_VERITY_OPT_LOGGING		"ignore_corruption"
 #define DM_VERITY_OPT_RESTART		"restart_on_corruption"
 #define DM_VERITY_OPT_IGN_ZEROES	"ignore_zero_blocks"
+#define DM_VERITY_OPT_AT_MOST_ONCE	"check_at_most_once"
 
 #define DM_VERITY_OPTS_MAX		(2 + DM_VERITY_OPTS_FEC)
 
@@ -347,8 +348,8 @@ int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
 /*
  * Calculates the digest for the given bio
  */
-int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
-			struct bvec_iter *iter, struct crypto_wait *wait)
+static int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
+			       struct bvec_iter *iter, struct crypto_wait *wait)
 {
 	unsigned int todo = 1 << v->data_dev_block_bits;
 	struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
@@ -433,6 +434,18 @@ static int verity_bv_zero(struct dm_verity *v, struct dm_verity_io *io,
 }
 
 /*
+ * Moves the bio iter one data block forward.
+ */
+static inline void verity_bv_skip_block(struct dm_verity *v,
+					struct dm_verity_io *io,
+					struct bvec_iter *iter)
+{
+	struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
+
+	bio_advance_iter(bio, iter, 1 << v->data_dev_block_bits);
+}
+
+/*
  * Verify one "dm_verity_io" structure.
  */
 static int verity_verify_io(struct dm_verity_io *io)
@@ -445,9 +458,16 @@ static int verity_verify_io(struct dm_verity_io *io)
 
 	for (b = 0; b < io->n_blocks; b++) {
 		int r;
+		sector_t cur_block = io->block + b;
 		struct ahash_request *req = verity_io_hash_req(v, io);
 
-		r = verity_hash_for_block(v, io, io->block + b,
+		if (v->validated_blocks &&
+		    likely(test_bit(cur_block, v->validated_blocks))) {
+			verity_bv_skip_block(v, io, &io->iter);
+			continue;
+		}
+
+		r = verity_hash_for_block(v, io, cur_block,
 					  verity_io_want_digest(v, io),
 					  &is_zero);
 		if (unlikely(r < 0))
@@ -481,13 +501,16 @@ static int verity_verify_io(struct dm_verity_io *io)
 			return r;
 
 		if (likely(memcmp(verity_io_real_digest(v, io),
-				  verity_io_want_digest(v, io), v->digest_size) == 0))
+				  verity_io_want_digest(v, io), v->digest_size) == 0)) {
+			if (v->validated_blocks)
+				set_bit(cur_block, v->validated_blocks);
 			continue;
+		}
 		else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA,
-					   io->block + b, NULL, &start) == 0)
+					   cur_block, NULL, &start) == 0)
 			continue;
 		else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA,
-					   io->block + b))
+					   cur_block))
 			return -EIO;
 	}
 
@@ -673,6 +696,8 @@ static void verity_status(struct dm_target *ti, status_type_t type,
 			args += DM_VERITY_OPTS_FEC;
 		if (v->zero_digest)
 			args++;
+		if (v->validated_blocks)
+			args++;
 		if (!args)
 			return;
 		DMEMIT(" %u", args);
@@ -691,13 +716,14 @@ static void verity_status(struct dm_target *ti, status_type_t type,
 		}
 		if (v->zero_digest)
 			DMEMIT(" " DM_VERITY_OPT_IGN_ZEROES);
+		if (v->validated_blocks)
+			DMEMIT(" " DM_VERITY_OPT_AT_MOST_ONCE);
 		sz = verity_fec_status_table(v, sz, result, maxlen);
 		break;
 	}
 }
 
-static int verity_prepare_ioctl(struct dm_target *ti,
-		struct block_device **bdev, fmode_t *mode)
+static int verity_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
 {
 	struct dm_verity *v = ti->private;
 
@@ -740,6 +766,7 @@ static void verity_dtr(struct dm_target *ti)
 	if (v->bufio)
 		dm_bufio_client_destroy(v->bufio);
 
+	kvfree(v->validated_blocks);
 	kfree(v->salt);
 	kfree(v->root_digest);
 	kfree(v->zero_digest);
@@ -760,6 +787,26 @@ static void verity_dtr(struct dm_target *ti)
 	kfree(v);
 }
 
+static int verity_alloc_most_once(struct dm_verity *v)
+{
+	struct dm_target *ti = v->ti;
+
+	/* the bitset can only handle INT_MAX blocks */
+	if (v->data_blocks > INT_MAX) {
+		ti->error = "device too large to use check_at_most_once";
+		return -E2BIG;
+	}
+
+	v->validated_blocks = kvzalloc(BITS_TO_LONGS(v->data_blocks) *
+				       sizeof(unsigned long), GFP_KERNEL);
+	if (!v->validated_blocks) {
+		ti->error = "failed to allocate bitset for check_at_most_once";
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
 static int verity_alloc_zero_digest(struct dm_verity *v)
 {
 	int r = -ENOMEM;
@@ -829,6 +876,12 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v)
 			}
 			continue;
 
+		} else if (!strcasecmp(arg_name, DM_VERITY_OPT_AT_MOST_ONCE)) {
+			r = verity_alloc_most_once(v);
+			if (r)
+				return r;
+			continue;
+
 		} else if (verity_is_fec_opt_arg(arg_name)) {
 			r = verity_fec_parse_opt_args(as, v, &argc, arg_name);
 			if (r)
@@ -1096,7 +1149,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
 static struct target_type verity_target = {
 	.name		= "verity",
-	.version	= {1, 3, 0},
+	.version	= {1, 4, 0},
 	.module		= THIS_MODULE,
 	.ctr		= verity_ctr,
 	.dtr		= verity_dtr,
diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
index b675bc0..3441c10 100644
--- a/drivers/md/dm-verity.h
+++ b/drivers/md/dm-verity.h
@@ -12,7 +12,7 @@
 #ifndef DM_VERITY_H
 #define DM_VERITY_H
 
-#include "dm-bufio.h"
+#include <linux/dm-bufio.h>
 #include <linux/device-mapper.h>
 #include <crypto/hash.h>
 
@@ -63,6 +63,7 @@ struct dm_verity {
 	sector_t hash_level_block[DM_VERITY_MAX_LEVELS];
 
 	struct dm_verity_fec *fec;	/* forward error correction */
+	unsigned long *validated_blocks; /* bitset blocks validated */
 };
 
 struct dm_verity_io {
diff --git a/drivers/md/dm-zoned-target.c b/drivers/md/dm-zoned-target.c
index caff02c..e73b077 100644
--- a/drivers/md/dm-zoned-target.c
+++ b/drivers/md/dm-zoned-target.c
@@ -898,8 +898,7 @@ static void dmz_io_hints(struct dm_target *ti, struct queue_limits *limits)
 /*
  * Pass on ioctl to the backend device.
  */
-static int dmz_prepare_ioctl(struct dm_target *ti,
-			     struct block_device **bdev, fmode_t *mode)
+static int dmz_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
 {
 	struct dmz_target *dmz = ti->private;
 
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 353ea0e..5a81c47 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -458,67 +458,56 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 	return dm_get_geometry(md, geo);
 }
 
-static char *_dm_claim_ptr = "I belong to device-mapper";
-
-static int dm_get_bdev_for_ioctl(struct mapped_device *md,
-				 struct block_device **bdev,
-				 fmode_t *mode)
+static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx,
+			    struct block_device **bdev)
+	__acquires(md->io_barrier)
 {
 	struct dm_target *tgt;
 	struct dm_table *map;
-	int srcu_idx, r, r2;
+	int r;
 
 retry:
 	r = -ENOTTY;
-	map = dm_get_live_table(md, &srcu_idx);
+	map = dm_get_live_table(md, srcu_idx);
 	if (!map || !dm_table_get_size(map))
-		goto out;
+		return r;
 
 	/* We only support devices that have a single target */
 	if (dm_table_get_num_targets(map) != 1)
-		goto out;
+		return r;
 
 	tgt = dm_table_get_target(map, 0);
 	if (!tgt->type->prepare_ioctl)
-		goto out;
+		return r;
 
-	if (dm_suspended_md(md)) {
-		r = -EAGAIN;
-		goto out;
-	}
+	if (dm_suspended_md(md))
+		return -EAGAIN;
 
-	r = tgt->type->prepare_ioctl(tgt, bdev, mode);
-	if (r < 0)
-		goto out;
-
-	bdgrab(*bdev);
-	r2 = blkdev_get(*bdev, *mode, _dm_claim_ptr);
-	if (r2 < 0) {
-		r = r2;
-		goto out;
-	}
-
-	dm_put_live_table(md, srcu_idx);
-	return r;
-
-out:
-	dm_put_live_table(md, srcu_idx);
+	r = tgt->type->prepare_ioctl(tgt, bdev);
 	if (r == -ENOTCONN && !fatal_signal_pending(current)) {
+		dm_put_live_table(md, *srcu_idx);
 		msleep(10);
 		goto retry;
 	}
+
 	return r;
 }
 
+static void dm_unprepare_ioctl(struct mapped_device *md, int srcu_idx)
+	__releases(md->io_barrier)
+{
+	dm_put_live_table(md, srcu_idx);
+}
+
 static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
 			unsigned int cmd, unsigned long arg)
 {
 	struct mapped_device *md = bdev->bd_disk->private_data;
-	int r;
+	int r, srcu_idx;
 
-	r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
+	r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
 	if (r < 0)
-		return r;
+		goto out;
 
 	if (r > 0) {
 		/*
@@ -536,7 +525,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
 
 	r =  __blkdev_driver_ioctl(bdev, mode, cmd, arg);
 out:
-	blkdev_put(bdev, mode);
+	dm_unprepare_ioctl(md, srcu_idx);
 	return r;
 }
 
@@ -710,6 +699,8 @@ static void dm_put_live_table_fast(struct mapped_device *md) __releases(RCU)
 	rcu_read_unlock();
 }
 
+static char *_dm_claim_ptr = "I belong to device-mapper";
+
 /*
  * Open a table device so we can use it as a map destination.
  */
@@ -1414,6 +1405,11 @@ static unsigned get_num_discard_bios(struct dm_target *ti)
 	return ti->num_discard_bios;
 }
 
+static unsigned get_num_secure_erase_bios(struct dm_target *ti)
+{
+	return ti->num_secure_erase_bios;
+}
+
 static unsigned get_num_write_same_bios(struct dm_target *ti)
 {
 	return ti->num_write_same_bios;
@@ -1467,6 +1463,11 @@ static int __send_discard(struct clone_info *ci, struct dm_target *ti)
 					   is_split_required_for_discard);
 }
 
+static int __send_secure_erase(struct clone_info *ci, struct dm_target *ti)
+{
+	return __send_changing_extent_only(ci, ti, get_num_secure_erase_bios, NULL);
+}
+
 static int __send_write_same(struct clone_info *ci, struct dm_target *ti)
 {
 	return __send_changing_extent_only(ci, ti, get_num_write_same_bios, NULL);
@@ -1477,6 +1478,25 @@ static int __send_write_zeroes(struct clone_info *ci, struct dm_target *ti)
 	return __send_changing_extent_only(ci, ti, get_num_write_zeroes_bios, NULL);
 }
 
+static bool __process_abnormal_io(struct clone_info *ci, struct dm_target *ti,
+				  int *result)
+{
+	struct bio *bio = ci->bio;
+
+	if (bio_op(bio) == REQ_OP_DISCARD)
+		*result = __send_discard(ci, ti);
+	else if (bio_op(bio) == REQ_OP_SECURE_ERASE)
+		*result = __send_secure_erase(ci, ti);
+	else if (bio_op(bio) == REQ_OP_WRITE_SAME)
+		*result = __send_write_same(ci, ti);
+	else if (bio_op(bio) == REQ_OP_WRITE_ZEROES)
+		*result = __send_write_zeroes(ci, ti);
+	else
+		return false;
+
+	return true;
+}
+
 /*
  * Select the correct strategy for processing a non-flush bio.
  */
@@ -1491,12 +1511,8 @@ static int __split_and_process_non_flush(struct clone_info *ci)
 	if (!dm_target_is_valid(ti))
 		return -EIO;
 
-	if (unlikely(bio_op(bio) == REQ_OP_DISCARD))
-		return __send_discard(ci, ti);
-	else if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
-		return __send_write_same(ci, ti);
-	else if (unlikely(bio_op(bio) == REQ_OP_WRITE_ZEROES))
-		return __send_write_zeroes(ci, ti);
+	if (unlikely(__process_abnormal_io(ci, ti, &r)))
+		return r;
 
 	if (bio_op(bio) == REQ_OP_ZONE_REPORT)
 		len = ci->sector_count;
@@ -1617,9 +1633,12 @@ static blk_qc_t __process_bio(struct mapped_device *md,
 			goto out;
 		}
 
-		tio = alloc_tio(&ci, ti, 0, GFP_NOIO);
 		ci.bio = bio;
 		ci.sector_count = bio_sectors(bio);
+		if (unlikely(__process_abnormal_io(&ci, ti, &error)))
+			goto out;
+
+		tio = alloc_tio(&ci, ti, 0, GFP_NOIO);
 		ret = __clone_and_map_simple_bio(&ci, tio, NULL);
 	}
 out:
@@ -1848,7 +1867,7 @@ static struct mapped_device *alloc_dev(int minor)
 	INIT_LIST_HEAD(&md->table_devices);
 	spin_lock_init(&md->uevent_lock);
 
-	md->queue = blk_alloc_queue_node(GFP_KERNEL, numa_node_id);
+	md->queue = blk_alloc_queue_node(GFP_KERNEL, numa_node_id, NULL);
 	if (!md->queue)
 		goto bad;
 	md->queue->queuedata = md;
@@ -3015,20 +3034,19 @@ static int dm_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type,
 {
 	struct mapped_device *md = bdev->bd_disk->private_data;
 	const struct pr_ops *ops;
-	fmode_t mode;
-	int r;
+	int r, srcu_idx;
 
-	r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
+	r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
 	if (r < 0)
-		return r;
+		goto out;
 
 	ops = bdev->bd_disk->fops->pr_ops;
 	if (ops && ops->pr_reserve)
 		r = ops->pr_reserve(bdev, key, type, flags);
 	else
 		r = -EOPNOTSUPP;
-
-	blkdev_put(bdev, mode);
+out:
+	dm_unprepare_ioctl(md, srcu_idx);
 	return r;
 }
 
@@ -3036,20 +3054,19 @@ static int dm_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
 {
 	struct mapped_device *md = bdev->bd_disk->private_data;
 	const struct pr_ops *ops;
-	fmode_t mode;
-	int r;
+	int r, srcu_idx;
 
-	r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
+	r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
 	if (r < 0)
-		return r;
+		goto out;
 
 	ops = bdev->bd_disk->fops->pr_ops;
 	if (ops && ops->pr_release)
 		r = ops->pr_release(bdev, key, type);
 	else
 		r = -EOPNOTSUPP;
-
-	blkdev_put(bdev, mode);
+out:
+	dm_unprepare_ioctl(md, srcu_idx);
 	return r;
 }
 
@@ -3058,20 +3075,19 @@ static int dm_pr_preempt(struct block_device *bdev, u64 old_key, u64 new_key,
 {
 	struct mapped_device *md = bdev->bd_disk->private_data;
 	const struct pr_ops *ops;
-	fmode_t mode;
-	int r;
+	int r, srcu_idx;
 
-	r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
+	r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
 	if (r < 0)
-		return r;
+		goto out;
 
 	ops = bdev->bd_disk->fops->pr_ops;
 	if (ops && ops->pr_preempt)
 		r = ops->pr_preempt(bdev, old_key, new_key, type, abort);
 	else
 		r = -EOPNOTSUPP;
-
-	blkdev_put(bdev, mode);
+out:
+	dm_unprepare_ioctl(md, srcu_idx);
 	return r;
 }
 
@@ -3079,20 +3095,19 @@ static int dm_pr_clear(struct block_device *bdev, u64 key)
 {
 	struct mapped_device *md = bdev->bd_disk->private_data;
 	const struct pr_ops *ops;
-	fmode_t mode;
-	int r;
+	int r, srcu_idx;
 
-	r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
+	r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
 	if (r < 0)
-		return r;
+		goto out;
 
 	ops = bdev->bd_disk->fops->pr_ops;
 	if (ops && ops->pr_clear)
 		r = ops->pr_clear(bdev, key);
 	else
 		r = -EOPNOTSUPP;
-
-	blkdev_put(bdev, mode);
+out:
+	dm_unprepare_ioctl(md, srcu_idx);
 	return r;
 }
 
diff --git a/drivers/md/md-linear.c b/drivers/md/md-linear.c
index 773fc70..4964323 100644
--- a/drivers/md/md-linear.c
+++ b/drivers/md/md-linear.c
@@ -138,9 +138,9 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
 	}
 
 	if (!discard_supported)
-		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+		blk_queue_flag_clear(QUEUE_FLAG_DISCARD, mddev->queue);
 	else
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, mddev->queue);
 
 	/*
 	 * Here we calculate the device offsets.
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 254e44e..3bea45e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5206,12 +5206,12 @@ static void md_free(struct kobject *ko)
 	if (mddev->sysfs_state)
 		sysfs_put(mddev->sysfs_state);
 
+	if (mddev->gendisk)
+		del_gendisk(mddev->gendisk);
 	if (mddev->queue)
 		blk_cleanup_queue(mddev->queue);
-	if (mddev->gendisk) {
-		del_gendisk(mddev->gendisk);
+	if (mddev->gendisk)
 		put_disk(mddev->gendisk);
-	}
 	percpu_ref_exit(&mddev->writes_pending);
 
 	kfree(mddev);
@@ -5619,9 +5619,9 @@ int md_run(struct mddev *mddev)
 		if (mddev->degraded)
 			nonrot = false;
 		if (nonrot)
-			queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mddev->queue);
+			blk_queue_flag_set(QUEUE_FLAG_NONROT, mddev->queue);
 		else
-			queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, mddev->queue);
+			blk_queue_flag_clear(QUEUE_FLAG_NONROT, mddev->queue);
 		mddev->queue->backing_dev_info->congested_data = mddev;
 		mddev->queue->backing_dev_info->congested_fn = md_congested;
 	}
diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c
index ea15d22..492a3f8 100644
--- a/drivers/md/persistent-data/dm-block-manager.c
+++ b/drivers/md/persistent-data/dm-block-manager.c
@@ -5,8 +5,8 @@
  */
 #include "dm-block-manager.h"
 #include "dm-persistent-data-internal.h"
-#include "../dm-bufio.h"
 
+#include <linux/dm-bufio.h>
 #include <linux/crc32c.h>
 #include <linux/module.h>
 #include <linux/slab.h>
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 5ecba9e..584c103 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -399,9 +399,9 @@ static int raid0_run(struct mddev *mddev)
 				discard_supported = true;
 		}
 		if (!discard_supported)
-			queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+			blk_queue_flag_clear(QUEUE_FLAG_DISCARD, mddev->queue);
 		else
-			queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+			blk_queue_flag_set(QUEUE_FLAG_DISCARD, mddev->queue);
 	}
 
 	/* calculate array device size */
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index fe872dc..e2943fb 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1760,7 +1760,7 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
 		}
 	}
 	if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, mddev->queue);
 	print_conf(conf);
 	return err;
 }
@@ -3110,10 +3110,10 @@ static int raid1_run(struct mddev *mddev)
 
 	if (mddev->queue) {
 		if (discard_supported)
-			queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+			blk_queue_flag_set(QUEUE_FLAG_DISCARD,
 						mddev->queue);
 		else
-			queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD,
+			blk_queue_flag_clear(QUEUE_FLAG_DISCARD,
 						  mddev->queue);
 	}
 
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c5e6c60..3c60774 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1845,7 +1845,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
 		break;
 	}
 	if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, mddev->queue);
 
 	print_conf(conf);
 	return err;
@@ -3846,10 +3846,10 @@ static int raid10_run(struct mddev *mddev)
 
 	if (mddev->queue) {
 		if (discard_supported)
-			queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+			blk_queue_flag_set(QUEUE_FLAG_DISCARD,
 						mddev->queue);
 		else
-			queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD,
+			blk_queue_flag_clear(QUEUE_FLAG_DISCARD,
 						  mddev->queue);
 	}
 	/* need to check that every block has at least one working mirror */
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index b5d2601..be117d0 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -7443,10 +7443,10 @@ static int raid5_run(struct mddev *mddev)
 		if (devices_handle_discard_safely &&
 		    mddev->queue->limits.max_discard_sectors >= (stripe >> 9) &&
 		    mddev->queue->limits.discard_granularity >= stripe)
-			queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+			blk_queue_flag_set(QUEUE_FLAG_DISCARD,
 						mddev->queue);
 		else
-			queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD,
+			blk_queue_flag_clear(QUEUE_FLAG_DISCARD,
 						mddev->queue);
 
 		blk_queue_max_hw_sectors(mddev->queue, UINT_MAX);
diff --git a/drivers/media/i2c/msp3400-kthreads.c b/drivers/media/i2c/msp3400-kthreads.c
index 4dd01e9..dc6cb8d 100644
--- a/drivers/media/i2c/msp3400-kthreads.c
+++ b/drivers/media/i2c/msp3400-kthreads.c
@@ -885,7 +885,7 @@ static int msp34xxg_modus(struct i2c_client *client)
 }
 
 static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
- {
+{
 	struct msp_state *state = to_state(i2c_get_clientdata(client));
 	int source, matrix;
 
diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c
index c3089bd..33d2987 100644
--- a/drivers/media/i2c/saa6588.c
+++ b/drivers/media/i2c/saa6588.c
@@ -411,9 +411,9 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 		break;
 		/* --- poll() for /dev/radio --- */
 	case SAA6588_CMD_POLL:
-		a->result = 0;
+		a->poll_mask = 0;
 		if (s->data_available_for_read)
-			a->result |= EPOLLIN | EPOLLRDNORM;
+			a->poll_mask |= EPOLLIN | EPOLLRDNORM;
 		poll_wait(a->instance, &s->read_queue, a->event_list);
 		break;
 
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index f697698..707f57a 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -3344,10 +3344,10 @@ static __poll_t radio_poll(struct file *file, poll_table *wait)
 	radio_enable(btv);
 	cmd.instance = file;
 	cmd.event_list = wait;
-	cmd.result = res;
+	cmd.poll_mask = res;
 	bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd);
 
-	return cmd.result;
+	return cmd.poll_mask;
 }
 
 static const struct v4l2_file_operations radio_fops =
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 4f1091a..1a50ec9 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1235,12 +1235,12 @@ static __poll_t radio_poll(struct file *file, poll_table *wait)
 
 	cmd.instance = file;
 	cmd.event_list = wait;
-	cmd.result = 0;
+	cmd.poll_mask = 0;
 	mutex_lock(&dev->lock);
 	saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
 	mutex_unlock(&dev->lock);
 
-	return rc | cmd.result;
+	return rc | cmd.poll_mask;
 }
 
 /* ------------------------------------------------------------------ */
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 04644e7..2f21444 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -127,7 +127,7 @@ static int emif_regdump_show(struct seq_file *s, void *unused)
 
 	for (i = 0; i < EMIF_MAX_NUM_FREQUENCIES && regs_cache[i]; i++) {
 		do_emif_regdump_show(s, emif, regs_cache[i]);
-		seq_printf(s, "\n");
+		seq_putc(s, '\n');
 	}
 
 	return 0;
diff --git a/drivers/memory/samsung/Kconfig b/drivers/memory/samsung/Kconfig
index 9de1222..79ce7ea 100644
--- a/drivers/memory/samsung/Kconfig
+++ b/drivers/memory/samsung/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 config SAMSUNG_MC
 	bool "Samsung Exynos Memory Controller support" if COMPILE_TEST
 	help
diff --git a/drivers/memory/samsung/Makefile b/drivers/memory/samsung/Makefile
index 9c554d5..00587be 100644
--- a/drivers/memory/samsung/Makefile
+++ b/drivers/memory/samsung/Makefile
@@ -1 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_EXYNOS_SROM)	+= exynos-srom.o
diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c
index bf827a6..7edd7fb 100644
--- a/drivers/memory/samsung/exynos-srom.c
+++ b/drivers/memory/samsung/exynos-srom.c
@@ -1,14 +1,10 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *	      http://www.samsung.com/
- *
- * EXYNOS - SROM Controller support
- * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2015 Samsung Electronics Co., Ltd.
+//	      http://www.samsung.com/
+//
+// EXYNOS - SROM Controller support
+// Author: Pankaj Dubey <pankaj.dubey@samsung.com>
 
 #include <linux/io.h>
 #include <linux/init.h>
diff --git a/drivers/memory/samsung/exynos-srom.h b/drivers/memory/samsung/exynos-srom.h
index 34660c6..da61279 100644
--- a/drivers/memory/samsung/exynos-srom.h
+++ b/drivers/memory/samsung/exynos-srom.h
@@ -1,13 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com
  *
  * Exynos SROMC register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
+ */
 
 #ifndef __EXYNOS_SROM_H
 #define __EXYNOS_SROM_H __FILE__
diff --git a/drivers/memory/ti-emif-pm.c b/drivers/memory/ti-emif-pm.c
index 62a86c4..632651f 100644
--- a/drivers/memory/ti-emif-pm.c
+++ b/drivers/memory/ti-emif-pm.c
@@ -271,7 +271,6 @@ static int ti_emif_probe(struct platform_device *pdev)
 	emif_data->pm_data.ti_emif_base_addr_virt = devm_ioremap_resource(dev,
 									  res);
 	if (IS_ERR(emif_data->pm_data.ti_emif_base_addr_virt)) {
-		dev_err(dev, "could not ioremap emif mem\n");
 		ret = PTR_ERR(emif_data->pm_data.ti_emif_base_addr_virt);
 		return ret;
 	}
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 439ee9c..231f3a1 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -2967,7 +2967,7 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
 	mutex_unlock(&ioc->sas_mgmt.mutex);
 out:
 	return ret;
- }
+}
 
 static void
 mptsas_parse_device_info(struct sas_identify *identify,
diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
index fd09b09..e8f1d4b 100644
--- a/drivers/misc/cardreader/rtsx_pcr.c
+++ b/drivers/misc/cardreader/rtsx_pcr.c
@@ -444,12 +444,12 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr,
 {
 	u64 *ptr = (u64 *)(pcr->host_sg_tbl_ptr) + pcr->sgi;
 	u64 val;
-	u8 option = SG_VALID | SG_TRANS_DATA;
+	u8 option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA;
 
 	pcr_dbg(pcr, "DMA addr: 0x%x, Len: 0x%x\n", (unsigned int)addr, len);
 
 	if (end)
-		option |= SG_END;
+		option |= RTSX_SG_END;
 	val = ((u64)addr << 32) | ((u64)len << 12) | option;
 
 	put_unaligned_le64(val, ptr);
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
index 8f2e644..8679e0b 100644
--- a/drivers/misc/genwqe/card_utils.c
+++ b/drivers/misc/genwqe/card_utils.c
@@ -453,7 +453,7 @@ int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
 		s += 8;		/* continue 8 elements further */
 	}
  fixup:
-	if (j == 1) {		/* combining happend on last entry! */
+	if (j == 1) {		/* combining happened on last entry! */
 		s -= 8;		/* full shift needed on previous sgl block */
 		j =  7;		/* shift all elements */
 	}
@@ -471,7 +471,7 @@ int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
  * genwqe_free_sync_sgl() - Free memory for sgl and overlapping pages
  *
  * After the DMA transfer has been completed we free the memory for
- * the sgl and the cached pages. Data is being transfered from cached
+ * the sgl and the cached pages. Data is being transferred from cached
  * pages into user-space buffers.
  */
 int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl)
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index a2b9c25..02485e3 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -2659,7 +2659,6 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
 		 * from being accepted.
 		 */
 		card = md->queue.card;
-		mmc_cleanup_queue(&md->queue);
 		if (md->disk->flags & GENHD_FL_UP) {
 			device_remove_file(disk_to_dev(md->disk), &md->force_ro);
 			if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&
@@ -2669,6 +2668,7 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
 
 			del_gendisk(md->disk);
 		}
+		mmc_cleanup_queue(&md->queue);
 		mmc_blk_put(md);
 	}
 }
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
index 421fab7..56e9a80 100644
--- a/drivers/mmc/core/queue.c
+++ b/drivers/mmc/core/queue.c
@@ -185,14 +185,14 @@ static void mmc_queue_setup_discard(struct request_queue *q,
 	if (!max_discard)
 		return;
 
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
 	blk_queue_max_discard_sectors(q, max_discard);
 	q->limits.discard_granularity = card->pref_erase << 9;
 	/* granularity must not be greater than max. discard */
 	if (card->pref_erase > max_discard)
 		q->limits.discard_granularity = 0;
 	if (mmc_can_secure_erase_trim(card))
-		queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q);
+		blk_queue_flag_set(QUEUE_FLAG_SECERASE, q);
 }
 
 /**
@@ -356,8 +356,8 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
 	if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
 		limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
 
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
-	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, mq->queue);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, mq->queue);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, mq->queue);
 	if (mmc_can_erase(card))
 		mmc_queue_setup_discard(mq->queue, card);
 
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 2a8ac68..46ab7fe 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -333,8 +333,6 @@
 
 source "drivers/mtd/nand/Kconfig"
 
-source "drivers/mtd/onenand/Kconfig"
-
 source "drivers/mtd/lpddr/Kconfig"
 
 source "drivers/mtd/spi-nor/Kconfig"
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index d6f8f62..93473d2 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -32,7 +32,7 @@
 nftl-objs		:= nftlcore.o nftlmount.o
 inftl-objs		:= inftlcore.o inftlmount.o
 
-obj-y		+= chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/
+obj-y		+= chips/ lpddr/ maps/ devices/ nand/ tests/
 
 obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor/
 obj-$(CONFIG_MTD_UBI)		+= ubi/
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 5e1b68c..d4c07b8 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -1993,20 +1993,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 
 static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
 {
-	unsigned long ofs, len;
-	int ret;
-
-	ofs = instr->addr;
-	len = instr->len;
-
-	ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL);
-	if (ret)
-		return ret;
-
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
-	return 0;
+	return cfi_varsize_frob(mtd, do_erase_oneblock, instr->addr,
+				instr->len, NULL);
 }
 
 static void cfi_intelext_sync (struct mtd_info *mtd)
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 56aa6b7..668e2cb 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -2415,20 +2415,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 
 static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
 {
-	unsigned long ofs, len;
-	int ret;
-
-	ofs = instr->addr;
-	len = instr->len;
-
-	ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL);
-	if (ret)
-		return ret;
-
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
-	return 0;
+	return cfi_varsize_frob(mtd, do_erase_oneblock, instr->addr,
+				instr->len, NULL);
 }
 
 
@@ -2436,7 +2424,6 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
-	int ret = 0;
 
 	if (instr->addr != 0)
 		return -EINVAL;
@@ -2444,14 +2431,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
 	if (instr->len != mtd->size)
 		return -EINVAL;
 
-	ret = do_erase_chip(map, &cfi->chips[0]);
-	if (ret)
-		return ret;
-
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
-	return 0;
+	return do_erase_chip(map, &cfi->chips[0]);
 }
 
 static int do_atmel_lock(struct map_info *map, struct flchip *chip,
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 7d34296..7b7658a 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -965,9 +965,6 @@ static int cfi_staa_erase_varsize(struct mtd_info *mtd,
 		}
 	}
 
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
 	return 0;
 }
 
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index b479bd8..6f7e7e1 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -53,6 +53,8 @@
 #define AT49BV32XT	0x00C9
 
 /* Eon */
+#define EN29LV400AT	0x22B9
+#define EN29LV400AB	0x22BA
 #define EN29SL800BB	0x226B
 #define EN29SL800BT	0x22EA
 
@@ -643,6 +645,36 @@ static const struct amd_flash_info jedec_table[] = {
 		}
 	}, {
 		.mfr_id		= CFI_MFR_EON,
+		.dev_id		= EN29LV400AT,
+		.name		= "Eon EN29LV400AT",
+		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
+		.uaddr		= MTD_UADDR_0x0AAA_0x0555,
+		.dev_size	= SIZE_512KiB,
+		.cmd_set	= P_ID_AMD_STD,
+		.nr_regions	= 4,
+		.regions	= {
+			ERASEINFO(0x10000,7),
+			ERASEINFO(0x08000,1),
+			ERASEINFO(0x02000,2),
+			ERASEINFO(0x04000,1),
+		}
+	}, {
+		.mfr_id		= CFI_MFR_EON,
+		.dev_id		= EN29LV400AB,
+		.name		= "Eon EN29LV400AB",
+		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
+		.uaddr		= MTD_UADDR_0x0AAA_0x0555,
+		.dev_size	= SIZE_512KiB,
+		.cmd_set	= P_ID_AMD_STD,
+		.nr_regions	= 4,
+		.regions	= {
+			ERASEINFO(0x04000,1),
+			ERASEINFO(0x02000,2),
+			ERASEINFO(0x08000,1),
+			ERASEINFO(0x10000,7),
+		}
+	}, {
+		.mfr_id		= CFI_MFR_EON,
 		.dev_id		= EN29SL800BT,
 		.name		= "Eon EN29SL800BT",
 		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index 1cd0fff..c37fce9 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -131,8 +131,6 @@ static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr)
 	allff = map_word_ff(map);
 	for (i=0; i<instr->len; i += map_bankwidth(map))
 		map_write(map, allff, instr->addr + i);
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
 	return 0;
 }
 
diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c
index e2bd818..9baa81b 100644
--- a/drivers/mtd/devices/bcm47xxsflash.c
+++ b/drivers/mtd/devices/bcm47xxsflash.c
@@ -68,7 +68,6 @@ static int bcm47xxsflash_poll(struct bcm47xxsflash *b47s, int timeout)
 static int bcm47xxsflash_erase(struct mtd_info *mtd, struct erase_info *erase)
 {
 	struct bcm47xxsflash *b47s = mtd->priv;
-	int err;
 
 	switch (b47s->type) {
 	case BCM47XXSFLASH_TYPE_ST:
@@ -89,16 +88,7 @@ static int bcm47xxsflash_erase(struct mtd_info *mtd, struct erase_info *erase)
 		break;
 	}
 
-	err = bcm47xxsflash_poll(b47s, HZ);
-	if (err)
-		erase->state = MTD_ERASE_FAILED;
-	else
-		erase->state = MTD_ERASE_DONE;
-
-	if (erase->callback)
-		erase->callback(erase);
-
-	return err;
+	return bcm47xxsflash_poll(b47s, HZ);
 }
 
 static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 62fd690..c9e4249 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -88,17 +88,12 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 	size_t len = instr->len;
 	int err;
 
-	instr->state = MTD_ERASING;
 	mutex_lock(&dev->write_mutex);
 	err = _block2mtd_erase(dev, from, len);
 	mutex_unlock(&dev->write_mutex);
-	if (err) {
+	if (err)
 		pr_err("erase failed err = %d\n", err);
-		instr->state = MTD_ERASE_FAILED;
-	} else
-		instr->state = MTD_ERASE_DONE;
 
-	mtd_erase_callback(instr);
 	return err;
 }
 
@@ -225,7 +220,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
 	int i;
 #endif
 	const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
-	struct block_device *bdev = ERR_PTR(-ENODEV);
+	struct block_device *bdev;
 	struct block2mtd_dev *dev;
 	char *name;
 
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index a85af23..c594fe5 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -1191,39 +1191,27 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info)
 {
 	struct docg3 *docg3 = mtd->priv;
 	uint64_t len;
-	int block0, block1, page, ret, ofs = 0;
+	int block0, block1, page, ret = 0, ofs = 0;
 
 	doc_dbg("doc_erase(from=%lld, len=%lld\n", info->addr, info->len);
 
-	info->state = MTD_ERASE_PENDING;
 	calc_block_sector(info->addr + info->len, &block0, &block1, &page,
 			  &ofs, docg3->reliable);
-	ret = -EINVAL;
 	if (info->addr + info->len > mtd->size || page || ofs)
-		goto reset_err;
+		return -EINVAL;
 
-	ret = 0;
 	calc_block_sector(info->addr, &block0, &block1, &page, &ofs,
 			  docg3->reliable);
 	mutex_lock(&docg3->cascade->lock);
 	doc_set_device_id(docg3, docg3->device_id);
 	doc_set_reliable_mode(docg3);
 	for (len = info->len; !ret && len > 0; len -= mtd->erasesize) {
-		info->state = MTD_ERASING;
 		ret = doc_erase_block(docg3, block0, block1);
 		block0 += 2;
 		block1 += 2;
 	}
 	mutex_unlock(&docg3->cascade->lock);
 
-	if (ret)
-		goto reset_err;
-
-	info->state = MTD_ERASE_DONE;
-	return 0;
-
-reset_err:
-	info->state = MTD_ERASE_FAILED;
 	return ret;
 }
 
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index 555b944..f67b653 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -414,10 +414,7 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
    while (len)
 	 {
 		if (!erase_block (addr))
-		  {
-			 instr->state = MTD_ERASE_FAILED;
 			 return (-EIO);
-		  }
 
 		addr += mtd->eraseregions[i].erasesize;
 		len -= mtd->eraseregions[i].erasesize;
@@ -425,9 +422,6 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
 		if (addr == mtd->eraseregions[i].offset + (mtd->eraseregions[i].erasesize * mtd->eraseregions[i].numblocks)) i++;
 	 }
 
-   instr->state = MTD_ERASE_DONE;
-   mtd_erase_callback(instr);
-
    return (0);
 }
 
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 5dc8bd0..aaaeaae 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -220,10 +220,6 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
 	}
 	mutex_unlock(&priv->lock);
 
-	/* Inform MTD subsystem that erase is complete */
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
 	return 0;
 }
 
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 0bf4aea..4623879 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -60,8 +60,7 @@ static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
 	if (check_offs_len(mtd, instr->addr, instr->len))
 		return -EINVAL;
 	memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
+
 	return 0;
 }
 
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 7287696..9ee04b5 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -39,13 +39,6 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 	memset(start + instr->addr, 0xff, instr->len);
 
-	/*
-	 * This'll catch a few races. Free the thing before returning :)
-	 * I don't feel at all ashamed. This kind of thing is possible anyway
-	 * with flash, but unlikely.
-	 */
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
 	return 0;
 }
 
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index cadea06..5d842cb 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -184,12 +184,10 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
 	}
 
       out:
-	instr->state = MTD_ERASE_DONE;
 #ifdef CONFIG_MTD_PMC551_DEBUG
 	printk(KERN_DEBUG "pmc551_erase() done\n");
 #endif
 
-	mtd_erase_callback(instr);
 	return 0;
 }
 
diff --git a/drivers/mtd/devices/powernv_flash.c b/drivers/mtd/devices/powernv_flash.c
index 26f9fea..c1312b1 100644
--- a/drivers/mtd/devices/powernv_flash.c
+++ b/drivers/mtd/devices/powernv_flash.c
@@ -175,19 +175,11 @@ static int powernv_flash_erase(struct mtd_info *mtd, struct erase_info *erase)
 {
 	int rc;
 
-	erase->state = MTD_ERASING;
-
-	/* todo: register our own notifier to do a true async implementation */
 	rc =  powernv_flash_async_op(mtd, FLASH_OP_ERASE, erase->addr,
 			erase->len, NULL, NULL);
-
-	if (rc) {
+	if (rc)
 		erase->fail_addr = erase->addr;
-		erase->state = MTD_ERASE_FAILED;
-	} else {
-		erase->state = MTD_ERASE_DONE;
-	}
-	mtd_erase_callback(erase);
+
 	return rc;
 }
 
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 0ec85f3..10183ee 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -84,12 +84,7 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
 	slram_priv_t *priv = mtd->priv;
 
 	memset(priv->start + instr->addr, 0xff, instr->len);
-	/* This'll catch a few races. Free the thing before returning :)
-	 * I don't feel at all ashamed. This kind of thing is possible anyway
-	 * with flash, but unlikely.
-	 */
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
+
 	return(0);
 }
 
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
index ddf4789..986f81d 100644
--- a/drivers/mtd/devices/spear_smi.c
+++ b/drivers/mtd/devices/spear_smi.c
@@ -518,7 +518,6 @@ static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info)
 		/* preparing the command for flash */
 		ret = spear_smi_erase_sector(dev, bank, command, 4);
 		if (ret) {
-			e_info->state = MTD_ERASE_FAILED;
 			mutex_unlock(&flash->lock);
 			return ret;
 		}
@@ -527,8 +526,6 @@ static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info)
 	}
 
 	mutex_unlock(&flash->lock);
-	e_info->state = MTD_ERASE_DONE;
-	mtd_erase_callback(e_info);
 
 	return 0;
 }
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index 5b84d71..1897f33 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -195,7 +195,6 @@ static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr)
 		err = sst25l_erase_sector(flash, addr);
 		if (err) {
 			mutex_unlock(&flash->lock);
-			instr->state = MTD_ERASE_FAILED;
 			dev_err(&flash->spi->dev, "Erase failed\n");
 			return err;
 		}
@@ -205,8 +204,6 @@ static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 	mutex_unlock(&flash->lock);
 
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
 	return 0;
 }
 
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 7bc29d7..55d4a77 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -1825,13 +1825,9 @@ static int stfsm_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 	mutex_unlock(&fsm->lock);
 
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
 	return 0;
 
 out1:
-	instr->state = MTD_ERASE_FAILED;
 	mutex_unlock(&fsm->lock);
 
 	return ret;
@@ -1868,8 +1864,7 @@ static struct flash_info *stfsm_jedec_probe(struct stfsm *fsm)
 	 */
 	ext_jedec = id[3] << 8  | id[4];
 
-	dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
-		jedec, id[0], id[1], id[2], id[3], id[4]);
+	dev_dbg(fsm->dev, "JEDEC =  0x%08x [%5ph]\n", jedec, id);
 
 	for (info = flash_types; info->name; info++) {
 		if (info->jedec_id == jedec) {
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index 664d206..ef6ad25 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -140,12 +140,6 @@ typedef struct partition_t {
 #define XFER_PREPARED	0x03
 #define XFER_FAILED	0x04
 
-/*====================================================================*/
-
-
-static void ftl_erase_callback(struct erase_info *done);
-
-
 /*======================================================================
 
     Scan_header() checks to see if a memory region contains an FTL
@@ -348,18 +342,19 @@ static int erase_xfer(partition_t *part,
     if (!erase)
             return -ENOMEM;
 
-    erase->mtd = part->mbd.mtd;
-    erase->callback = ftl_erase_callback;
     erase->addr = xfer->Offset;
     erase->len = 1 << part->header.EraseUnitSize;
-    erase->priv = (u_long)part;
 
     ret = mtd_erase(part->mbd.mtd, erase);
+    if (!ret) {
+	xfer->state = XFER_ERASED;
+	xfer->EraseCount++;
+    } else {
+	xfer->state = XFER_FAILED;
+	pr_notice("ftl_cs: erase failed: err = %d\n", ret);
+    }
 
-    if (!ret)
-	    xfer->EraseCount++;
-    else
-	    kfree(erase);
+    kfree(erase);
 
     return ret;
 } /* erase_xfer */
@@ -371,37 +366,6 @@ static int erase_xfer(partition_t *part,
 
 ======================================================================*/
 
-static void ftl_erase_callback(struct erase_info *erase)
-{
-    partition_t *part;
-    struct xfer_info_t *xfer;
-    int i;
-
-    /* Look up the transfer unit */
-    part = (partition_t *)(erase->priv);
-
-    for (i = 0; i < part->header.NumTransferUnits; i++)
-	if (part->XferInfo[i].Offset == erase->addr) break;
-
-    if (i == part->header.NumTransferUnits) {
-	printk(KERN_NOTICE "ftl_cs: internal error: "
-	       "erase lookup failed!\n");
-	return;
-    }
-
-    xfer = &part->XferInfo[i];
-    if (erase->state == MTD_ERASE_DONE)
-	xfer->state = XFER_ERASED;
-    else {
-	xfer->state = XFER_FAILED;
-	printk(KERN_NOTICE "ftl_cs: erase failed: state = %d\n",
-	       erase->state);
-    }
-
-    kfree(erase);
-
-} /* ftl_erase_callback */
-
 static int prepare_xfer(partition_t *part, int i)
 {
     erase_unit_header_t header;
@@ -429,8 +393,8 @@ static int prepare_xfer(partition_t *part, int i)
     }
 
     /* Write the BAM stub */
-    nbam = (part->BlocksPerUnit * sizeof(uint32_t) +
-	    le32_to_cpu(part->header.BAMOffset) + SECTOR_SIZE - 1) / SECTOR_SIZE;
+    nbam = DIV_ROUND_UP(part->BlocksPerUnit * sizeof(uint32_t) +
+			le32_to_cpu(part->header.BAMOffset), SECTOR_SIZE);
 
     offset = xfer->Offset + le32_to_cpu(part->header.BAMOffset);
     ctl = cpu_to_le32(BLOCK_CONTROL);
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index 8d6bb189..aab4f68 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -208,8 +208,6 @@ static int find_boot_record(struct INFTLrecord *inftl)
 			if (ip->Reserved0 != ip->firstUnit) {
 				struct erase_info *instr = &inftl->instr;
 
-				instr->mtd = inftl->mbd.mtd;
-
 				/*
 				 * 	Most likely this is using the
 				 * 	undocumented qiuck mount feature.
@@ -385,7 +383,6 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
 	   _first_? */
 
 	/* Use async erase interface, test return code */
-	instr->mtd = inftl->mbd.mtd;
 	instr->addr = block * inftl->EraseSize;
 	instr->len = inftl->mbd.mtd->erasesize;
 	/* Erase one physical eraseblock at a time, even though the NAND api
@@ -393,9 +390,10 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
 	   mark only the failed block in the bbt. */
 	for (physblock = 0; physblock < inftl->EraseSize;
 	     physblock += instr->len, instr->addr += instr->len) {
-		mtd_erase(inftl->mbd.mtd, instr);
+		int ret;
 
-		if (instr->state == MTD_ERASE_FAILED) {
+		ret = mtd_erase(inftl->mbd.mtd, instr);
+		if (ret) {
 			printk(KERN_WARNING "INFTL: error while formatting block %d\n",
 				block);
 			goto fail;
diff --git a/drivers/mtd/lpddr/lpddr2_nvm.c b/drivers/mtd/lpddr/lpddr2_nvm.c
index 2342277..5d73db2a 100644
--- a/drivers/mtd/lpddr/lpddr2_nvm.c
+++ b/drivers/mtd/lpddr/lpddr2_nvm.c
@@ -380,14 +380,8 @@ static int lpddr2_nvm_write(struct mtd_info *mtd, loff_t start_add,
  */
 static int lpddr2_nvm_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
-	int ret = lpddr2_nvm_do_block_op(mtd, instr->addr, instr->len,
-		LPDDR2_NVM_ERASE);
-	if (!ret) {
-		instr->state = MTD_ERASE_DONE;
-		mtd_erase_callback(instr);
-	}
-
-	return ret;
+	return lpddr2_nvm_do_block_op(mtd, instr->addr, instr->len,
+				      LPDDR2_NVM_ERASE);
 }
 
 /*
diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c
index 018c75f..5c5ba3c 100644
--- a/drivers/mtd/lpddr/lpddr_cmds.c
+++ b/drivers/mtd/lpddr/lpddr_cmds.c
@@ -693,8 +693,6 @@ static int lpddr_erase(struct mtd_info *mtd, struct erase_info *instr)
 		ofs += size;
 		len -= size;
 	}
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
 
 	return 0;
 }
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 542fdf8..bdc1283 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -334,16 +334,6 @@
 
 	  If unsure, say N.
 
-config MTD_BFIN_ASYNC
-	tristate "Blackfin BF533-STAMP Flash Chip Support"
-	depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS
-	default y
-	help
-	  Map driver which allows for simultaneous utilization of
-	  ethernet and CFI parallel flash.
-
-	  If compiled as a module, it will be called bfin-async-flash.
-
 config MTD_GPIO_ADDR
 	tristate "GPIO-assisted Flash Chip Support"
 	depends on GPIOLIB || COMPILE_TEST
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index b849aaf..51acf1f 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -42,7 +42,6 @@
 obj-$(CONFIG_MTD_IXP4XX)	+= ixp4xx.o
 obj-$(CONFIG_MTD_PLATRAM)	+= plat-ram.o
 obj-$(CONFIG_MTD_INTEL_VR_NOR)	+= intel_vr_nor.o
-obj-$(CONFIG_MTD_BFIN_ASYNC)	+= bfin-async-flash.o
 obj-$(CONFIG_MTD_RBTX4939)	+= rbtx4939-flash.o
 obj-$(CONFIG_MTD_VMU)		+= vmu-flash.o
 obj-$(CONFIG_MTD_GPIO_ADDR)	+= gpio-addr-flash.o
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c
deleted file mode 100644
index 41730fe..0000000
--- a/drivers/mtd/maps/bfin-async-flash.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * drivers/mtd/maps/bfin-async-flash.c
- *
- * Handle the case where flash memory and ethernet mac/phy are
- * mapped onto the same async bank.  The BF533-STAMP does this
- * for example.  All board-specific configuration goes in your
- * board resources file.
- *
- * Copyright 2000 Nicolas Pitre <nico@fluxnic.net>
- * Copyright 2005-2008 Analog Devices Inc.
- *
- * Enter bugs at http://blackfin.uclinux.org/
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-#include <asm/blackfin.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <asm/unaligned.h>
-
-#define pr_devinit(fmt, args...) \
-		({ static const char __fmt[] = fmt; printk(__fmt, ## args); })
-
-#define DRIVER_NAME "bfin-async-flash"
-
-struct async_state {
-	struct mtd_info *mtd;
-	struct map_info map;
-	int enet_flash_pin;
-	uint32_t flash_ambctl0, flash_ambctl1;
-	uint32_t save_ambctl0, save_ambctl1;
-	unsigned long irq_flags;
-};
-
-static void switch_to_flash(struct async_state *state)
-{
-	local_irq_save(state->irq_flags);
-
-	gpio_set_value(state->enet_flash_pin, 0);
-
-	state->save_ambctl0 = bfin_read_EBIU_AMBCTL0();
-	state->save_ambctl1 = bfin_read_EBIU_AMBCTL1();
-	bfin_write_EBIU_AMBCTL0(state->flash_ambctl0);
-	bfin_write_EBIU_AMBCTL1(state->flash_ambctl1);
-	SSYNC();
-}
-
-static void switch_back(struct async_state *state)
-{
-	bfin_write_EBIU_AMBCTL0(state->save_ambctl0);
-	bfin_write_EBIU_AMBCTL1(state->save_ambctl1);
-	SSYNC();
-
-	gpio_set_value(state->enet_flash_pin, 1);
-
-	local_irq_restore(state->irq_flags);
-}
-
-static map_word bfin_flash_read(struct map_info *map, unsigned long ofs)
-{
-	struct async_state *state = (struct async_state *)map->map_priv_1;
-	uint16_t word;
-	map_word test;
-
-	switch_to_flash(state);
-
-	word = readw(map->virt + ofs);
-
-	switch_back(state);
-
-	test.x[0] = word;
-	return test;
-}
-
-static void bfin_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
-	struct async_state *state = (struct async_state *)map->map_priv_1;
-
-	switch_to_flash(state);
-
-	memcpy(to, map->virt + from, len);
-
-	switch_back(state);
-}
-
-static void bfin_flash_write(struct map_info *map, map_word d1, unsigned long ofs)
-{
-	struct async_state *state = (struct async_state *)map->map_priv_1;
-	uint16_t d;
-
-	d = d1.x[0];
-
-	switch_to_flash(state);
-
-	writew(d, map->virt + ofs);
-	SSYNC();
-
-	switch_back(state);
-}
-
-static void bfin_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
-	struct async_state *state = (struct async_state *)map->map_priv_1;
-
-	switch_to_flash(state);
-
-	memcpy(map->virt + to, from, len);
-	SSYNC();
-
-	switch_back(state);
-}
-
-static const char * const part_probe_types[] = {
-	"cmdlinepart", "RedBoot", NULL };
-
-static int bfin_flash_probe(struct platform_device *pdev)
-{
-	struct physmap_flash_data *pdata = dev_get_platdata(&pdev->dev);
-	struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	struct async_state *state;
-
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return -ENOMEM;
-
-	state->map.name       = DRIVER_NAME;
-	state->map.read       = bfin_flash_read;
-	state->map.copy_from  = bfin_flash_copy_from;
-	state->map.write      = bfin_flash_write;
-	state->map.copy_to    = bfin_flash_copy_to;
-	state->map.bankwidth  = pdata->width;
-	state->map.size       = resource_size(memory);
-	state->map.virt       = (void __iomem *)memory->start;
-	state->map.phys       = memory->start;
-	state->map.map_priv_1 = (unsigned long)state;
-	state->enet_flash_pin = platform_get_irq(pdev, 0);
-	state->flash_ambctl0  = flash_ambctl->start;
-	state->flash_ambctl1  = flash_ambctl->end;
-
-	if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) {
-		pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin);
-		kfree(state);
-		return -EBUSY;
-	}
-	gpio_direction_output(state->enet_flash_pin, 1);
-
-	pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8);
-	state->mtd = do_map_probe(memory->name, &state->map);
-	if (!state->mtd) {
-		gpio_free(state->enet_flash_pin);
-		kfree(state);
-		return -ENXIO;
-	}
-
-	mtd_device_parse_register(state->mtd, part_probe_types, NULL,
-				  pdata->parts, pdata->nr_parts);
-
-	platform_set_drvdata(pdev, state);
-
-	return 0;
-}
-
-static int bfin_flash_remove(struct platform_device *pdev)
-{
-	struct async_state *state = platform_get_drvdata(pdev);
-	gpio_free(state->enet_flash_pin);
-	mtd_device_unregister(state->mtd);
-	map_destroy(state->mtd);
-	kfree(state);
-	return 0;
-}
-
-static struct platform_driver bfin_flash_driver = {
-	.probe		= bfin_flash_probe,
-	.remove		= bfin_flash_remove,
-	.driver		= {
-		.name	= DRIVER_NAME,
-	},
-};
-
-module_platform_driver(bfin_flash_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("MTD map driver for Blackfins with flash/ethernet on same async bank");
diff --git a/drivers/mtd/maps/physmap_of_core.c b/drivers/mtd/maps/physmap_of_core.c
index b1bd4fa..527b168 100644
--- a/drivers/mtd/maps/physmap_of_core.c
+++ b/drivers/mtd/maps/physmap_of_core.c
@@ -20,6 +20,7 @@
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/concat.h>
+#include <linux/mtd/cfi_endian.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
@@ -233,6 +234,11 @@ static int of_flash_probe(struct platform_device *dev)
 		info->list[i].map.bankwidth = be32_to_cpup(width);
 		info->list[i].map.device_node = dp;
 
+		if (of_property_read_bool(dp, "big-endian"))
+			info->list[i].map.swap = CFI_BIG_ENDIAN;
+		else if (of_property_read_bool(dp, "little-endian"))
+			info->list[i].map.swap = CFI_LITTLE_ENDIAN;
+
 		err = of_flash_probe_gemini(dev, dp, &info->list[i].map);
 		if (err)
 			goto err_out;
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 9ec8f03..16ae4ae 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -419,11 +419,11 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 	blk_queue_logical_block_size(new->rq, tr->blksize);
 
 	blk_queue_bounce_limit(new->rq, BLK_BOUNCE_HIGH);
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, new->rq);
-	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, new->rq);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, new->rq);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, new->rq);
 
 	if (tr->discard) {
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, new->rq);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, new->rq);
 		blk_queue_max_discard_sectors(new->rq, UINT_MAX);
 	}
 
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index bb4c14f..a5b1933 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -55,48 +55,27 @@ struct mtdblk_dev {
  * being written to until a different sector is required.
  */
 
-static void erase_callback(struct erase_info *done)
-{
-	wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
-	wake_up(wait_q);
-}
-
 static int erase_write (struct mtd_info *mtd, unsigned long pos,
 			int len, const char *buf)
 {
 	struct erase_info erase;
-	DECLARE_WAITQUEUE(wait, current);
-	wait_queue_head_t wait_q;
 	size_t retlen;
 	int ret;
 
 	/*
 	 * First, let's erase the flash block.
 	 */
-
-	init_waitqueue_head(&wait_q);
-	erase.mtd = mtd;
-	erase.callback = erase_callback;
 	erase.addr = pos;
 	erase.len = len;
-	erase.priv = (u_long)&wait_q;
-
-	set_current_state(TASK_INTERRUPTIBLE);
-	add_wait_queue(&wait_q, &wait);
 
 	ret = mtd_erase(mtd, &erase);
 	if (ret) {
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&wait_q, &wait);
 		printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] "
 				     "on \"%s\" failed\n",
 			pos, len, mtd->name);
 		return ret;
 	}
 
-	schedule();  /* Wait for erase to finish. */
-	remove_wait_queue(&wait_q, &wait);
-
 	/*
 	 * Next, write the data to flash.
 	 */
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 7d80a8b..cd67c85 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -324,10 +324,6 @@ static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t c
     IOCTL calls for getting device parameters.
 
 ======================================================================*/
-static void mtdchar_erase_callback (struct erase_info *instr)
-{
-	wake_up((wait_queue_head_t *)instr->priv);
-}
 
 static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
 {
@@ -709,11 +705,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 		if (!erase)
 			ret = -ENOMEM;
 		else {
-			wait_queue_head_t waitq;
-			DECLARE_WAITQUEUE(wait, current);
-
-			init_waitqueue_head(&waitq);
-
 			if (cmd == MEMERASE64) {
 				struct erase_info_user64 einfo64;
 
@@ -735,31 +726,8 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 				erase->addr = einfo32.start;
 				erase->len = einfo32.length;
 			}
-			erase->mtd = mtd;
-			erase->callback = mtdchar_erase_callback;
-			erase->priv = (unsigned long)&waitq;
 
-			/*
-			  FIXME: Allow INTERRUPTIBLE. Which means
-			  not having the wait_queue head on the stack.
-
-			  If the wq_head is on the stack, and we
-			  leave because we got interrupted, then the
-			  wq_head is no longer there when the
-			  callback routine tries to wake us up.
-			*/
 			ret = mtd_erase(mtd, erase);
-			if (!ret) {
-				set_current_state(TASK_UNINTERRUPTIBLE);
-				add_wait_queue(&waitq, &wait);
-				if (erase->state != MTD_ERASE_DONE &&
-				    erase->state != MTD_ERASE_FAILED)
-					schedule();
-				remove_wait_queue(&waitq, &wait);
-				set_current_state(TASK_RUNNING);
-
-				ret = (erase->state == MTD_ERASE_FAILED)?-EIO:0;
-			}
 			kfree(erase);
 		}
 		break;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 60bf53d..6b86d1a 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -333,45 +333,6 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
 	return -EINVAL;
 }
 
-static void concat_erase_callback(struct erase_info *instr)
-{
-	wake_up((wait_queue_head_t *) instr->priv);
-}
-
-static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
-{
-	int err;
-	wait_queue_head_t waitq;
-	DECLARE_WAITQUEUE(wait, current);
-
-	/*
-	 * This code was stol^H^H^H^Hinspired by mtdchar.c
-	 */
-	init_waitqueue_head(&waitq);
-
-	erase->mtd = mtd;
-	erase->callback = concat_erase_callback;
-	erase->priv = (unsigned long) &waitq;
-
-	/*
-	 * FIXME: Allow INTERRUPTIBLE. Which means
-	 * not having the wait_queue head on the stack.
-	 */
-	err = mtd_erase(mtd, erase);
-	if (!err) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(&waitq, &wait);
-		if (erase->state != MTD_ERASE_DONE
-		    && erase->state != MTD_ERASE_FAILED)
-			schedule();
-		remove_wait_queue(&waitq, &wait);
-		set_current_state(TASK_RUNNING);
-
-		err = (erase->state == MTD_ERASE_FAILED) ? -EIO : 0;
-	}
-	return err;
-}
-
 static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	struct mtd_concat *concat = CONCAT(mtd);
@@ -466,7 +427,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
 			erase->len = length;
 
 		length -= erase->len;
-		if ((err = concat_dev_erase(subdev, erase))) {
+		if ((err = mtd_erase(subdev, erase))) {
 			/* sanity check: should never happen since
 			 * block alignment has been checked above */
 			BUG_ON(err == -EINVAL);
@@ -485,14 +446,9 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
 		erase->addr = 0;
 		offset += subdev->size;
 	}
-	instr->state = erase->state;
 	kfree(erase);
-	if (err)
-		return err;
 
-	if (instr->callback)
-		instr->callback(instr);
-	return 0;
+	return err;
 }
 
 static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 28553c8..807d17d 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -419,7 +419,7 @@ int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
 EXPORT_SYMBOL_GPL(mtd_wunit_to_pairing_info);
 
 /**
- * mtd_wunit_to_pairing_info - get wunit from pairing information
+ * mtd_pairing_info_to_wunit - get wunit from pairing information
  * @mtd: pointer to new MTD device info structure
  * @info: pairing information struct
  *
@@ -641,29 +641,6 @@ int del_mtd_device(struct mtd_info *mtd)
 	return ret;
 }
 
-static int mtd_add_device_partitions(struct mtd_info *mtd,
-				     struct mtd_partitions *parts)
-{
-	const struct mtd_partition *real_parts = parts->parts;
-	int nbparts = parts->nr_parts;
-	int ret;
-
-	if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
-		ret = add_mtd_device(mtd);
-		if (ret)
-			return ret;
-	}
-
-	if (nbparts > 0) {
-		ret = add_mtd_partitions(mtd, real_parts, nbparts);
-		if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
-			del_mtd_device(mtd);
-		return ret;
-	}
-
-	return 0;
-}
-
 /*
  * Set a few defaults based on the parent devices, if not provided by the
  * driver
@@ -696,14 +673,13 @@ static void mtd_set_dev_defaults(struct mtd_info *mtd)
  * 'parse_mtd_partitions()') and MTD device and partitions registering. It
  * basically follows the most common pattern found in many MTD drivers:
  *
- * * It first tries to probe partitions on MTD device @mtd using parsers
+ * * If the MTD_PARTITIONED_MASTER option is set, then the device as a whole is
+ *   registered first.
+ * * Then It tries to probe partitions on MTD device @mtd using parsers
  *   specified in @types (if @types is %NULL, then the default list of parsers
  *   is used, see 'parse_mtd_partitions()' for more information). If none are
  *   found this functions tries to fallback to information specified in
  *   @parts/@nr_parts.
- * * If any partitioning info was found, this function registers the found
- *   partitions. If the MTD_PARTITIONED_MASTER option is set, then the device
- *   as a whole is registered first.
  * * If no partitions were found this function just registers the MTD device
  *   @mtd and exits.
  *
@@ -714,29 +690,31 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 			      const struct mtd_partition *parts,
 			      int nr_parts)
 {
-	struct mtd_partitions parsed;
+	struct mtd_partitions parsed = { };
 	int ret;
 
 	mtd_set_dev_defaults(mtd);
 
-	memset(&parsed, 0, sizeof(parsed));
-
-	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
-	if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
-		/* Fall back to driver-provided partitions */
-		parsed = (struct mtd_partitions){
-			.parts		= parts,
-			.nr_parts	= nr_parts,
-		};
-	} else if (ret < 0) {
-		/* Didn't come up with parsed OR fallback partitions */
-		pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
-			ret);
-		/* Don't abort on errors; we can still use unpartitioned MTD */
-		memset(&parsed, 0, sizeof(parsed));
+	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
+		ret = add_mtd_device(mtd);
+		if (ret)
+			return ret;
 	}
 
-	ret = mtd_add_device_partitions(mtd, &parsed);
+	/* Prefer parsed partitions over driver-provided fallback */
+	ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
+	if (!ret && parsed.nr_parts) {
+		parts = parsed.parts;
+		nr_parts = parsed.nr_parts;
+	}
+
+	if (nr_parts)
+		ret = add_mtd_partitions(mtd, parts, nr_parts);
+	else if (!device_is_registered(&mtd->dev))
+		ret = add_mtd_device(mtd);
+	else
+		ret = 0;
+
 	if (ret)
 		goto out;
 
@@ -758,6 +736,9 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 out:
 	/* Cleanup any parsed partitions */
 	mtd_part_parser_cleanup(&parsed);
+	if (ret && device_is_registered(&mtd->dev))
+		del_mtd_device(mtd);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(mtd_device_parse_register);
@@ -963,24 +944,25 @@ void __put_mtd_device(struct mtd_info *mtd)
 EXPORT_SYMBOL_GPL(__put_mtd_device);
 
 /*
- * Erase is an asynchronous operation.  Device drivers are supposed
- * to call instr->callback() whenever the operation completes, even
- * if it completes with a failure.
- * Callers are supposed to pass a callback function and wait for it
- * to be called before writing to the block.
+ * Erase is an synchronous operation. Device drivers are epected to return a
+ * negative error code if the operation failed and update instr->fail_addr
+ * to point the portion that was not properly erased.
  */
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
+	instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
+
+	if (!mtd->erasesize || !mtd->_erase)
+		return -ENOTSUPP;
+
 	if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr)
 		return -EINVAL;
 	if (!(mtd->flags & MTD_WRITEABLE))
 		return -EROFS;
-	instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
-	if (!instr->len) {
-		instr->state = MTD_ERASE_DONE;
-		mtd_erase_callback(instr);
+
+	if (!instr->len)
 		return 0;
-	}
+
 	ledtrig_mtd_activity();
 	return mtd->_erase(mtd, instr);
 }
@@ -1525,9 +1507,9 @@ int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
 EXPORT_SYMBOL_GPL(mtd_ooblayout_get_databytes);
 
 /**
- * mtd_ooblayout_get_eccbytes - set data bytes into the oob buffer
+ * mtd_ooblayout_set_databytes - set data bytes into the oob buffer
  * @mtd: mtd info structure
- * @eccbuf: source buffer to get data bytes from
+ * @databuf: source buffer to get data bytes from
  * @oobbuf: OOB buffer
  * @start: first ECC byte to set
  * @nbytes: number of ECC bytes to set
@@ -1559,7 +1541,7 @@ int mtd_ooblayout_count_freebytes(struct mtd_info *mtd)
 EXPORT_SYMBOL_GPL(mtd_ooblayout_count_freebytes);
 
 /**
- * mtd_ooblayout_count_freebytes - count the number of ECC bytes in OOB
+ * mtd_ooblayout_count_eccbytes - count the number of ECC bytes in OOB
  * @mtd: mtd info structure
  *
  * Works like mtd_ooblayout_count_bytes(), except it count ECC bytes.
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 97bb8f6..9f25111 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -84,12 +84,6 @@ static int page_is_used(struct mtdoops_context *cxt, int page)
 	return test_bit(page, cxt->oops_page_used);
 }
 
-static void mtdoops_erase_callback(struct erase_info *done)
-{
-	wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
-	wake_up(wait_q);
-}
-
 static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset)
 {
 	struct mtd_info *mtd = cxt->mtd;
@@ -97,34 +91,20 @@ static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset)
 	u32 start_page = start_page_offset / record_size;
 	u32 erase_pages = mtd->erasesize / record_size;
 	struct erase_info erase;
-	DECLARE_WAITQUEUE(wait, current);
-	wait_queue_head_t wait_q;
 	int ret;
 	int page;
 
-	init_waitqueue_head(&wait_q);
-	erase.mtd = mtd;
-	erase.callback = mtdoops_erase_callback;
 	erase.addr = offset;
 	erase.len = mtd->erasesize;
-	erase.priv = (u_long)&wait_q;
-
-	set_current_state(TASK_INTERRUPTIBLE);
-	add_wait_queue(&wait_q, &wait);
 
 	ret = mtd_erase(mtd, &erase);
 	if (ret) {
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&wait_q, &wait);
 		printk(KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] on \"%s\" failed\n",
 		       (unsigned long long)erase.addr,
 		       (unsigned long long)erase.len, mtddev);
 		return ret;
 	}
 
-	schedule();  /* Wait for erase to finish. */
-	remove_wait_queue(&wait_q, &wait);
-
 	/* Mark pages as unused */
 	for (page = start_page; page < start_page + erase_pages; page++)
 		mark_page_unused(cxt, page);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 76cd21d..023516a 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 #include "mtdcore.h"
 
@@ -205,28 +206,13 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 	instr->addr += part->offset;
 	ret = part->parent->_erase(part->parent, instr);
-	if (ret) {
-		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
-			instr->fail_addr -= part->offset;
-		instr->addr -= part->offset;
-	}
+	if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
+		instr->fail_addr -= part->offset;
+	instr->addr -= part->offset;
+
 	return ret;
 }
 
-void mtd_erase_callback(struct erase_info *instr)
-{
-	if (instr->mtd->_erase == part_erase) {
-		struct mtd_part *part = mtd_to_part(instr->mtd);
-
-		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
-			instr->fail_addr -= part->offset;
-		instr->addr -= part->offset;
-	}
-	if (instr->callback)
-		instr->callback(instr);
-}
-EXPORT_SYMBOL_GPL(mtd_erase_callback);
-
 static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
 	struct mtd_part *part = mtd_to_part(mtd);
@@ -861,6 +847,92 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
 }
 
 /**
+ * mtd_part_get_compatible_parser - find MTD parser by a compatible string
+ *
+ * @compat: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
+{
+	struct mtd_part_parser *p, *ret = NULL;
+
+	spin_lock(&part_parser_lock);
+
+	list_for_each_entry(p, &part_parsers, list) {
+		const struct of_device_id *matches;
+
+		matches = p->of_match_table;
+		if (!matches)
+			continue;
+
+		for (; matches->compatible[0]; matches++) {
+			if (!strcmp(matches->compatible, compat) &&
+			    try_module_get(p->owner)) {
+				ret = p;
+				break;
+			}
+		}
+
+		if (ret)
+			break;
+	}
+
+	spin_unlock(&part_parser_lock);
+
+	return ret;
+}
+
+static int mtd_part_of_parse(struct mtd_info *master,
+			     struct mtd_partitions *pparts)
+{
+	struct mtd_part_parser *parser;
+	struct device_node *np;
+	struct property *prop;
+	const char *compat;
+	const char *fixed = "fixed-partitions";
+	int ret, err = 0;
+
+	np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+	of_property_for_each_string(np, "compatible", prop, compat) {
+		parser = mtd_part_get_compatible_parser(compat);
+		if (!parser)
+			continue;
+		ret = mtd_part_do_parse(parser, master, pparts, NULL);
+		if (ret > 0) {
+			of_node_put(np);
+			return ret;
+		}
+		mtd_part_parser_put(parser);
+		if (ret < 0 && !err)
+			err = ret;
+	}
+	of_node_put(np);
+
+	/*
+	 * For backward compatibility we have to try the "fixed-partitions"
+	 * parser. It supports old DT format with partitions specified as a
+	 * direct subnodes of a flash device DT node without any compatibility
+	 * specified we could match.
+	 */
+	parser = mtd_part_parser_get(fixed);
+	if (!parser && !request_module("%s", fixed))
+		parser = mtd_part_parser_get(fixed);
+	if (parser) {
+		ret = mtd_part_do_parse(parser, master, pparts, NULL);
+		if (ret > 0)
+			return ret;
+		mtd_part_parser_put(parser);
+		if (ret < 0 && !err)
+			err = ret;
+	}
+
+	return err;
+}
+
+/**
  * parse_mtd_partitions - parse MTD partitions
  * @master: the master partition (describes whole MTD device)
  * @types: names of partition parsers to try or %NULL
@@ -892,19 +964,30 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
 		types = default_mtd_part_types;
 
 	for ( ; *types; types++) {
-		pr_debug("%s: parsing partitions %s\n", master->name, *types);
-		parser = mtd_part_parser_get(*types);
-		if (!parser && !request_module("%s", *types))
+		/*
+		 * ofpart is a special type that means OF partitioning info
+		 * should be used. It requires a bit different logic so it is
+		 * handled in a separated function.
+		 */
+		if (!strcmp(*types, "ofpart")) {
+			ret = mtd_part_of_parse(master, pparts);
+		} else {
+			pr_debug("%s: parsing partitions %s\n", master->name,
+				 *types);
 			parser = mtd_part_parser_get(*types);
-		pr_debug("%s: got parser %s\n", master->name,
-			 parser ? parser->name : NULL);
-		if (!parser)
-			continue;
-		ret = mtd_part_do_parse(parser, master, pparts, data);
+			if (!parser && !request_module("%s", *types))
+				parser = mtd_part_parser_get(*types);
+			pr_debug("%s: got parser %s\n", master->name,
+				parser ? parser->name : NULL);
+			if (!parser)
+				continue;
+			ret = mtd_part_do_parse(parser, master, pparts, data);
+			if (ret <= 0)
+				mtd_part_parser_put(parser);
+		}
 		/* Found partitions! */
 		if (ret > 0)
 			return 0;
-		mtd_part_parser_put(parser);
 		/*
 		 * Stash the first error we see; only report it if no parser
 		 * succeeds
diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
index 7eb0e1f..7161f8a 100644
--- a/drivers/mtd/mtdswap.c
+++ b/drivers/mtd/mtdswap.c
@@ -536,18 +536,10 @@ static void mtdswap_store_eb(struct mtdswap_dev *d, struct swap_eb *eb)
 		mtdswap_rb_add(d, eb, MTDSWAP_HIFRAG);
 }
 
-
-static void mtdswap_erase_callback(struct erase_info *done)
-{
-	wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
-	wake_up(wait_q);
-}
-
 static int mtdswap_erase_block(struct mtdswap_dev *d, struct swap_eb *eb)
 {
 	struct mtd_info *mtd = d->mtd;
 	struct erase_info erase;
-	wait_queue_head_t wq;
 	unsigned int retries = 0;
 	int ret;
 
@@ -556,14 +548,9 @@ static int mtdswap_erase_block(struct mtdswap_dev *d, struct swap_eb *eb)
 		d->max_erase_count = eb->erase_count;
 
 retry:
-	init_waitqueue_head(&wq);
 	memset(&erase, 0, sizeof(struct erase_info));
-
-	erase.mtd	= mtd;
-	erase.callback	= mtdswap_erase_callback;
 	erase.addr	= mtdswap_eb_offset(d, eb);
 	erase.len	= mtd->erasesize;
-	erase.priv	= (u_long)&wq;
 
 	ret = mtd_erase(mtd, &erase);
 	if (ret) {
@@ -582,27 +569,6 @@ static int mtdswap_erase_block(struct mtdswap_dev *d, struct swap_eb *eb)
 		return -EIO;
 	}
 
-	ret = wait_event_interruptible(wq, erase.state == MTD_ERASE_DONE ||
-					   erase.state == MTD_ERASE_FAILED);
-	if (ret) {
-		dev_err(d->dev, "Interrupted erase block %#llx erasure on %s\n",
-			erase.addr, mtd->name);
-		return -EINTR;
-	}
-
-	if (erase.state == MTD_ERASE_FAILED) {
-		if (retries++ < MTDSWAP_ERASE_RETRIES) {
-			dev_warn(d->dev,
-				"erase of erase block %#llx on %s failed",
-				erase.addr, mtd->name);
-			yield();
-			goto retry;
-		}
-
-		mtdswap_handle_badblock(d, eb);
-		return -EIO;
-	}
-
 	return 0;
 }
 
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 736ac88..88c7d3b 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,580 +1,6 @@
-config MTD_NAND_ECC
+config MTD_NAND_CORE
 	tristate
 
-config MTD_NAND_ECC_SMC
-	bool "NAND ECC Smart Media byte order"
-	depends on MTD_NAND_ECC
-	default n
-	help
-	  Software ECC according to the Smart Media Specification.
-	  The original Linux implementation had byte 0 and 1 swapped.
+source "drivers/mtd/nand/onenand/Kconfig"
 
-
-menuconfig MTD_NAND
-	tristate "NAND Device Support"
-	depends on MTD
-	select MTD_NAND_ECC
-	help
-	  This enables support for accessing all type of NAND flash
-	  devices. For further information see
-	  <http://www.linux-mtd.infradead.org/doc/nand.html>.
-
-if MTD_NAND
-
-config MTD_NAND_BCH
-	tristate
-	select BCH
-	depends on MTD_NAND_ECC_BCH
-	default MTD_NAND
-
-config MTD_NAND_ECC_BCH
-	bool "Support software BCH ECC"
-	default n
-	help
-	  This enables support for software BCH error correction. Binary BCH
-	  codes are more powerful and cpu intensive than traditional Hamming
-	  ECC codes. They are used with NAND devices requiring more than 1 bit
-	  of error correction.
-
-config MTD_SM_COMMON
-	tristate
-	default n
-
-config MTD_NAND_DENALI
-	tristate
-
-config MTD_NAND_DENALI_PCI
-        tristate "Support Denali NAND controller on Intel Moorestown"
-	select MTD_NAND_DENALI
-	depends on HAS_DMA && PCI
-        help
-          Enable the driver for NAND flash on Intel Moorestown, using the
-          Denali NAND controller core.
-
-config MTD_NAND_DENALI_DT
-	tristate "Support Denali NAND controller as a DT device"
-	select MTD_NAND_DENALI
-	depends on HAS_DMA && HAVE_CLK && OF
-	help
-	  Enable the driver for NAND flash on platforms using a Denali NAND
-	  controller as a DT device.
-
-config MTD_NAND_GPIO
-	tristate "GPIO assisted NAND Flash driver"
-	depends on GPIOLIB || COMPILE_TEST
-	depends on HAS_IOMEM
-	help
-	  This enables a NAND flash driver where control signals are
-	  connected to GPIO pins, and commands and data are communicated
-	  via a memory mapped interface.
-
-config MTD_NAND_AMS_DELTA
-	tristate "NAND Flash device on Amstrad E3"
-	depends on MACH_AMS_DELTA
-	default y
-	help
-	  Support for NAND flash on Amstrad E3 (Delta).
-
-config MTD_NAND_OMAP2
-	tristate "NAND Flash device on OMAP2, OMAP3, OMAP4 and Keystone"
-	depends on (ARCH_OMAP2PLUS || ARCH_KEYSTONE)
-	help
-          Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4
-	  and Keystone platforms.
-
-config MTD_NAND_OMAP_BCH
-	depends on MTD_NAND_OMAP2
-	bool "Support hardware based BCH error correction"
-	default n
-	select BCH
-	help
-	  This config enables the ELM hardware engine, which can be used to
-	  locate and correct errors when using BCH ECC scheme. This offloads
-	  the cpu from doing ECC error searching and correction. However some
-	  legacy OMAP families like OMAP2xxx, OMAP3xxx do not have ELM engine
-	  so this is optional for them.
-
-config MTD_NAND_OMAP_BCH_BUILD
-	def_tristate MTD_NAND_OMAP2 && MTD_NAND_OMAP_BCH
-
-config MTD_NAND_RICOH
-	tristate "Ricoh xD card reader"
-	default n
-	depends on PCI
-	select MTD_SM_COMMON
-	help
-	  Enable support for Ricoh R5C852 xD card reader
-	  You also need to enable ether
-	  NAND SSFDC (SmartMedia) read only translation layer' or new
-	  expermental, readwrite
-	  'SmartMedia/xD new translation layer'
-
-config MTD_NAND_AU1550
-	tristate "Au1550/1200 NAND support"
-	depends on MIPS_ALCHEMY
-	help
-	  This enables the driver for the NAND flash controller on the
-	  AMD/Alchemy 1550 SOC.
-
-config MTD_NAND_BF5XX
-	tristate "Blackfin on-chip NAND Flash Controller driver"
-	depends on BF54x || BF52x
-	help
-	  This enables the Blackfin on-chip NAND flash controller
-
-	  No board specific support is done by this driver, each board
-	  must advertise a platform_device for the driver to attach.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called bf5xx-nand.
-
-config MTD_NAND_BF5XX_HWECC
-	bool "BF5XX NAND Hardware ECC"
-	default y
-	depends on MTD_NAND_BF5XX
-	help
-	  Enable the use of the BF5XX's internal ECC generator when
-	  using NAND.
-
-config MTD_NAND_BF5XX_BOOTROM_ECC
-	bool "Use Blackfin BootROM ECC Layout"
-	default n
-	depends on MTD_NAND_BF5XX_HWECC
-	help
-	  If you wish to modify NAND pages and allow the Blackfin on-chip
-	  BootROM to boot from them, say Y here.  This is only necessary
-	  if you are booting U-Boot out of NAND and you wish to update
-	  U-Boot from Linux' userspace.  Otherwise, you should say N here.
-
-	  If unsure, say N.
-
-config MTD_NAND_S3C2410
-	tristate "NAND Flash support for Samsung S3C SoCs"
-	depends on ARCH_S3C24XX || ARCH_S3C64XX
-	help
-	  This enables the NAND flash controller on the S3C24xx and S3C64xx
-	  SoCs
-
-	  No board specific support is done by this driver, each board
-	  must advertise a platform_device for the driver to attach.
-
-config MTD_NAND_S3C2410_DEBUG
-	bool "Samsung S3C NAND driver debug"
-	depends on MTD_NAND_S3C2410
-	help
-	  Enable debugging of the S3C NAND driver
-
-config MTD_NAND_NDFC
-	tristate "NDFC NanD Flash Controller"
-	depends on 4xx
-	select MTD_NAND_ECC_SMC
-	help
-	 NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs
-
-config MTD_NAND_S3C2410_CLKSTOP
-	bool "Samsung S3C NAND IDLE clock stop"
-	depends on MTD_NAND_S3C2410
-	default n
-	help
-	  Stop the clock to the NAND controller when there is no chip
-	  selected to save power. This will mean there is a small delay
-	  when the is NAND chip selected or released, but will save
-	  approximately 5mA of power when there is nothing happening.
-
-config MTD_NAND_TANGO
-	tristate "NAND Flash support for Tango chips"
-	depends on ARCH_TANGO || COMPILE_TEST
-	depends on HAS_DMA
-	help
-	  Enables the NAND Flash controller on Tango chips.
-
-config MTD_NAND_DISKONCHIP
-	tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation)"
-	depends on HAS_IOMEM
-	select REED_SOLOMON
-	select REED_SOLOMON_DEC16
-	help
-	  This is a reimplementation of M-Systems DiskOnChip 2000,
-	  Millennium and Millennium Plus as a standard NAND device driver,
-	  as opposed to the earlier self-contained MTD device drivers.
-	  This should enable, among other things, proper JFFS2 operation on
-	  these devices.
-
-config MTD_NAND_DISKONCHIP_PROBE_ADVANCED
-        bool "Advanced detection options for DiskOnChip"
-        depends on MTD_NAND_DISKONCHIP
-        help
-          This option allows you to specify nonstandard address at which to
-          probe for a DiskOnChip, or to change the detection options.  You
-          are unlikely to need any of this unless you are using LinuxBIOS.
-          Say 'N'.
-
-config MTD_NAND_DISKONCHIP_PROBE_ADDRESS
-        hex "Physical address of DiskOnChip" if MTD_NAND_DISKONCHIP_PROBE_ADVANCED
-        depends on MTD_NAND_DISKONCHIP
-        default "0"
-        ---help---
-        By default, the probe for DiskOnChip devices will look for a
-        DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
-        This option allows you to specify a single address at which to probe
-        for the device, which is useful if you have other devices in that
-        range which get upset when they are probed.
-
-        (Note that on PowerPC, the normal probe will only check at
-        0xE4000000.)
-
-        Normally, you should leave this set to zero, to allow the probe at
-        the normal addresses.
-
-config MTD_NAND_DISKONCHIP_PROBE_HIGH
-        bool "Probe high addresses"
-        depends on MTD_NAND_DISKONCHIP_PROBE_ADVANCED
-        help
-          By default, the probe for DiskOnChip devices will look for a
-          DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
-          This option changes to make it probe between 0xFFFC8000 and
-          0xFFFEE000.  Unless you are using LinuxBIOS, this is unlikely to be
-          useful to you.  Say 'N'.
-
-config MTD_NAND_DISKONCHIP_BBTWRITE
-	bool "Allow BBT writes on DiskOnChip Millennium and 2000TSOP"
-	depends on MTD_NAND_DISKONCHIP
-	help
-	  On DiskOnChip devices shipped with the INFTL filesystem (Millennium
-	  and 2000 TSOP/Alon), Linux reserves some space at the end of the
-	  device for the Bad Block Table (BBT).  If you have existing INFTL
-	  data on your device (created by non-Linux tools such as M-Systems'
-	  DOS drivers), your data might overlap the area Linux wants to use for
-	  the BBT.  If this is a concern for you, leave this option disabled and
-	  Linux will not write BBT data into this area.
-	  The downside of leaving this option disabled is that if bad blocks
-	  are detected by Linux, they will not be recorded in the BBT, which
-	  could cause future problems.
-	  Once you enable this option, new filesystems (INFTL or others, created
-	  in Linux or other operating systems) will not use the reserved area.
-	  The only reason not to enable this option is to prevent damage to
-	  preexisting filesystems.
-	  Even if you leave this disabled, you can enable BBT writes at module
-	  load time (assuming you build diskonchip as a module) with the module
-	  parameter "inftl_bbt_write=1".
-
-config MTD_NAND_DOCG4
-	tristate "Support for DiskOnChip G4"
-	depends on HAS_IOMEM
-	select BCH
-	select BITREVERSE
-	help
-	  Support for diskonchip G4 nand flash, found in various smartphones and
-	  PDAs, among them the Palm Treo680, HTC Prophet and Wizard, Toshiba
-	  Portege G900, Asus P526, and O2 XDA Zinc.
-
-	  With this driver you will be able to use UBI and create a ubifs on the
-	  device, so you may wish to consider enabling UBI and UBIFS as well.
-
-	  These devices ship with the Mys/Sandisk SAFTL formatting, for which
-	  there is currently no mtd parser, so you may want to use command line
-	  partitioning to segregate write-protected blocks. On the Treo680, the
-	  first five erase blocks (256KiB each) are write-protected, followed
-	  by the block containing the saftl partition table.  This is probably
-	  typical.
-
-config MTD_NAND_SHARPSL
-	tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
-	depends on ARCH_PXA
-
-config MTD_NAND_CAFE
-	tristate "NAND support for OLPC CAFÉ chip"
-	depends on PCI
-	select REED_SOLOMON
-	select REED_SOLOMON_DEC16
-	help
-	  Use NAND flash attached to the CAFÉ chip designed for the OLPC
-	  laptop.
-
-config MTD_NAND_CS553X
-	tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
-	depends on X86_32
-	depends on !UML && HAS_IOMEM
-	help
-	  The CS553x companion chips for the AMD Geode processor
-	  include NAND flash controllers with built-in hardware ECC
-	  capabilities; enabling this option will allow you to use
-	  these. The driver will check the MSRs to verify that the
-	  controller is enabled for NAND, and currently requires that
-	  the controller be in MMIO mode.
-
-	  If you say "m", the module will be called cs553x_nand.
-
-config MTD_NAND_ATMEL
-	tristate "Support for NAND Flash / SmartMedia on AT91"
-	depends on ARCH_AT91
-	select MFD_ATMEL_SMC
-	help
-	  Enables support for NAND Flash / Smart Media Card interface
-	  on Atmel AT91 processors.
-
-config MTD_NAND_PXA3xx
-	tristate "NAND support on PXA3xx and Armada 370/XP"
-	depends on !MTD_NAND_MARVELL
-	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU
-	help
-
-	  This enables the driver for the NAND flash device found on
-	  PXA3xx processors (NFCv1) and also on 32-bit Armada
-	  platforms (XP, 370, 375, 38x, 39x) and 64-bit Armada
-	  platforms (7K, 8K) (NFCv2).
-
-config MTD_NAND_MARVELL
-	tristate "NAND controller support on Marvell boards"
-	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
-		   COMPILE_TEST
-	depends on HAS_IOMEM && HAS_DMA
-	help
-	  This enables the NAND flash controller driver for Marvell boards,
-	  including:
-	  - PXA3xx processors (NFCv1)
-	  - 32-bit Armada platforms (XP, 37x, 38x, 39x) (NFCv2)
-	  - 64-bit Aramda platforms (7k, 8k) (NFCv2)
-
-config MTD_NAND_SLC_LPC32XX
-	tristate "NXP LPC32xx SLC Controller"
-	depends on ARCH_LPC32XX
-	help
-	  Enables support for NXP's LPC32XX SLC (i.e. for Single Level Cell
-	  chips) NAND controller. This is the default for the PHYTEC 3250
-	  reference board which contains a NAND256R3A2CZA6 chip.
-
-	  Please check the actual NAND chip connected and its support
-	  by the SLC NAND controller.
-
-config MTD_NAND_MLC_LPC32XX
-	tristate "NXP LPC32xx MLC Controller"
-	depends on ARCH_LPC32XX
-	help
-	  Uses the LPC32XX MLC (i.e. for Multi Level Cell chips) NAND
-	  controller. This is the default for the WORK92105 controller
-	  board.
-
-	  Please check the actual NAND chip connected and its support
-	  by the MLC NAND controller.
-
-config MTD_NAND_CM_X270
-	tristate "Support for NAND Flash on CM-X270 modules"
-	depends on MACH_ARMCORE
-
-config MTD_NAND_PASEMI
-	tristate "NAND support for PA Semi PWRficient"
-	depends on PPC_PASEMI
-	help
-	  Enables support for NAND Flash interface on PA Semi PWRficient
-	  based boards
-
-config MTD_NAND_TMIO
-	tristate "NAND Flash device on Toshiba Mobile IO Controller"
-	depends on MFD_TMIO
-	help
-	  Support for NAND flash connected to a Toshiba Mobile IO
-	  Controller in some PDAs, including the Sharp SL6000x.
-
-config MTD_NAND_NANDSIM
-	tristate "Support for NAND Flash Simulator"
-	help
-	  The simulator may simulate various NAND flash chips for the
-	  MTD nand layer.
-
-config MTD_NAND_GPMI_NAND
-        tristate "GPMI NAND Flash Controller driver"
-        depends on MTD_NAND && MXS_DMA
-        help
-	 Enables NAND Flash support for IMX23, IMX28 or IMX6.
-	 The GPMI controller is very powerful, with the help of BCH
-	 module, it can do the hardware ECC. The GPMI supports several
-	 NAND flashs at the same time.
-
-config MTD_NAND_BRCMNAND
-	tristate "Broadcom STB NAND controller"
-	depends on ARM || ARM64 || MIPS
-	help
-	  Enables the Broadcom NAND controller driver. The controller was
-	  originally designed for Set-Top Box but is used on various BCM7xxx,
-	  BCM3xxx, BCM63xxx, iProc/Cygnus and more.
-
-config MTD_NAND_BCM47XXNFLASH
-	tristate "Support for NAND flash on BCM4706 BCMA bus"
-	depends on BCMA_NFLASH
-	help
-	  BCMA bus can have various flash memories attached, they are
-	  registered by bcma as platform devices. This enables driver for
-	  NAND flash memories. For now only BCM4706 is supported.
-
-config MTD_NAND_PLATFORM
-	tristate "Support for generic platform NAND driver"
-	depends on HAS_IOMEM
-	help
-	  This implements a generic NAND driver for on-SOC platform
-	  devices. You will need to provide platform-specific functions
-	  via platform_data.
-
-config MTD_NAND_ORION
-	tristate "NAND Flash support for Marvell Orion SoC"
-	depends on PLAT_ORION
-	help
-	  This enables the NAND flash controller on Orion machines.
-
-	  No board specific support is done by this driver, each board
-	  must advertise a platform_device for the driver to attach.
-
-config MTD_NAND_OXNAS
-	tristate "NAND Flash support for Oxford Semiconductor SoC"
-	depends on ARCH_OXNAS || COMPILE_TEST
-	depends on HAS_IOMEM
-	help
-	  This enables the NAND flash controller on Oxford Semiconductor SoCs.
-
-config MTD_NAND_FSL_ELBC
-	tristate "NAND support for Freescale eLBC controllers"
-	depends on FSL_SOC
-	select FSL_LBC
-	help
-	  Various Freescale chips, including the 8313, include a NAND Flash
-	  Controller Module with built-in hardware ECC capabilities.
-	  Enabling this option will enable you to use this to control
-	  external NAND devices.
-
-config MTD_NAND_FSL_IFC
-	tristate "NAND support for Freescale IFC controller"
-	depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A
-	select FSL_IFC
-	select MEMORY
-	help
-	  Various Freescale chips e.g P1010, include a NAND Flash machine
-	  with built-in hardware ECC capabilities.
-	  Enabling this option will enable you to use this to control
-	  external NAND devices.
-
-config MTD_NAND_FSL_UPM
-	tristate "Support for NAND on Freescale UPM"
-	depends on PPC_83xx || PPC_85xx
-	select FSL_LBC
-	help
-	  Enables support for NAND Flash chips wired onto Freescale PowerPC
-	  processor localbus with User-Programmable Machine support.
-
-config MTD_NAND_MPC5121_NFC
-	tristate "MPC5121 built-in NAND Flash Controller support"
-	depends on PPC_MPC512x
-	help
-	  This enables the driver for the NAND flash controller on the
-	  MPC5121 SoC.
-
-config MTD_NAND_VF610_NFC
-	tristate "Support for Freescale NFC for VF610/MPC5125"
-	depends on (SOC_VF610 || COMPILE_TEST)
-	depends on HAS_IOMEM
-	help
-	  Enables support for NAND Flash Controller on some Freescale
-	  processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
-	  The driver supports a maximum 2k page size. With 2k pages and
-	  64 bytes or more of OOB, hardware ECC with up to 32-bit error
-	  correction is supported. Hardware ECC is only enabled through
-	  device tree.
-
-config MTD_NAND_MXC
-	tristate "MXC NAND support"
-	depends on ARCH_MXC
-	help
-	  This enables the driver for the NAND flash controller on the
-	  MXC processors.
-
-config MTD_NAND_SH_FLCTL
-	tristate "Support for NAND on Renesas SuperH FLCTL"
-	depends on SUPERH || COMPILE_TEST
-	depends on HAS_IOMEM
-	depends on HAS_DMA
-	help
-	  Several Renesas SuperH CPU has FLCTL. This option enables support
-	  for NAND Flash using FLCTL.
-
-config MTD_NAND_DAVINCI
-        tristate "Support NAND on DaVinci/Keystone SoC"
-        depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF)
-        help
-	  Enable the driver for NAND flash chips on Texas Instruments
-	  DaVinci/Keystone processors.
-
-config MTD_NAND_TXX9NDFMC
-	tristate "NAND Flash support for TXx9 SoC"
-	depends on SOC_TX4938 || SOC_TX4939
-	help
-	  This enables the NAND flash controller on the TXx9 SoCs.
-
-config MTD_NAND_SOCRATES
-	tristate "Support for NAND on Socrates board"
-	depends on SOCRATES
-	help
-	  Enables support for NAND Flash chips wired onto Socrates board.
-
-config MTD_NAND_NUC900
-	tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards."
-	depends on ARCH_W90X900
-	help
-	  This enables the driver for the NAND Flash on evaluation board based
-	  on w90p910 / NUC9xx.
-
-config MTD_NAND_JZ4740
-	tristate "Support for JZ4740 SoC NAND controller"
-	depends on MACH_JZ4740
-	help
-		Enables support for NAND Flash on JZ4740 SoC based boards.
-
-config MTD_NAND_JZ4780
-	tristate "Support for NAND on JZ4780 SoC"
-	depends on MACH_JZ4780 && JZ4780_NEMC
-	help
-	  Enables support for NAND Flash connected to the NEMC on JZ4780 SoC
-	  based boards, using the BCH controller for hardware error correction.
-
-config MTD_NAND_FSMC
-	tristate "Support for NAND on ST Micros FSMC"
-	depends on OF
-	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)
-
-config MTD_NAND_XWAY
-	bool "Support for NAND on Lantiq XWAY SoC"
-	depends on LANTIQ && SOC_TYPE_XWAY
-	help
-	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
-	  to the External Bus Unit (EBU).
-
-config MTD_NAND_SUNXI
-	tristate "Support for NAND on Allwinner SoCs"
-	depends on ARCH_SUNXI
-	help
-	  Enables support for NAND Flash chips on Allwinner SoCs.
-
-config MTD_NAND_HISI504
-	tristate "Support for NAND controller on Hisilicon SoC Hip04"
-	depends on ARCH_HISI || COMPILE_TEST
-	depends on HAS_DMA
-	help
-	  Enables support for NAND controller on Hisilicon SoC Hip04.
-
-config MTD_NAND_QCOM
-	tristate "Support for NAND on QCOM SoCs"
-	depends on ARCH_QCOM
-	help
-	  Enables support for NAND flash chips on SoCs containing the EBI2 NAND
-	  controller. This controller is found on IPQ806x SoC.
-
-config MTD_NAND_MTK
-	tristate "Support for NAND controller on MTK SoCs"
-	depends on ARCH_MEDIATEK || COMPILE_TEST
-	depends on HAS_DMA
-	help
-	  Enables support for NAND controller on MTK SoCs.
-	  This controller is found on mt27xx, mt81xx, mt65xx SoCs.
-
-endif # MTD_NAND
+source "drivers/mtd/nand/raw/Kconfig"
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 921634b..3f0cb87 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -1,71 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
-#
-# linux/drivers/nand/Makefile
-#
 
-obj-$(CONFIG_MTD_NAND)			+= nand.o
-obj-$(CONFIG_MTD_NAND_ECC)		+= nand_ecc.o
-obj-$(CONFIG_MTD_NAND_BCH)		+= nand_bch.o
-obj-$(CONFIG_MTD_SM_COMMON) 		+= sm_common.o
+nandcore-objs := core.o bbt.o
+obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
 
-obj-$(CONFIG_MTD_NAND_CAFE)		+= cafe_nand.o
-obj-$(CONFIG_MTD_NAND_AMS_DELTA)	+= ams-delta.o
-obj-$(CONFIG_MTD_NAND_DENALI)		+= denali.o
-obj-$(CONFIG_MTD_NAND_DENALI_PCI)	+= denali_pci.o
-obj-$(CONFIG_MTD_NAND_DENALI_DT)	+= denali_dt.o
-obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550nd.o
-obj-$(CONFIG_MTD_NAND_BF5XX)		+= bf5xx_nand.o
-obj-$(CONFIG_MTD_NAND_S3C2410)		+= s3c2410.o
-obj-$(CONFIG_MTD_NAND_TANGO)		+= tango_nand.o
-obj-$(CONFIG_MTD_NAND_DAVINCI)		+= davinci_nand.o
-obj-$(CONFIG_MTD_NAND_DISKONCHIP)	+= diskonchip.o
-obj-$(CONFIG_MTD_NAND_DOCG4)		+= docg4.o
-obj-$(CONFIG_MTD_NAND_FSMC)		+= fsmc_nand.o
-obj-$(CONFIG_MTD_NAND_SHARPSL)		+= sharpsl.o
-obj-$(CONFIG_MTD_NAND_NANDSIM)		+= nandsim.o
-obj-$(CONFIG_MTD_NAND_CS553X)		+= cs553x_nand.o
-obj-$(CONFIG_MTD_NAND_NDFC)		+= ndfc.o
-obj-$(CONFIG_MTD_NAND_ATMEL)		+= atmel/
-obj-$(CONFIG_MTD_NAND_GPIO)		+= gpio.o
-omap2_nand-objs := omap2.o
-obj-$(CONFIG_MTD_NAND_OMAP2) 		+= omap2_nand.o
-obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD)	+= omap_elm.o
-obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270_nand.o
-obj-$(CONFIG_MTD_NAND_PXA3xx)		+= pxa3xx_nand.o
-obj-$(CONFIG_MTD_NAND_MARVELL)		+= marvell_nand.o
-obj-$(CONFIG_MTD_NAND_TMIO)		+= tmio_nand.o
-obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
-obj-$(CONFIG_MTD_NAND_PASEMI)		+= pasemi_nand.o
-obj-$(CONFIG_MTD_NAND_ORION)		+= orion_nand.o
-obj-$(CONFIG_MTD_NAND_OXNAS)		+= oxnas_nand.o
-obj-$(CONFIG_MTD_NAND_FSL_ELBC)		+= fsl_elbc_nand.o
-obj-$(CONFIG_MTD_NAND_FSL_IFC)		+= fsl_ifc_nand.o
-obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
-obj-$(CONFIG_MTD_NAND_SLC_LPC32XX)      += lpc32xx_slc.o
-obj-$(CONFIG_MTD_NAND_MLC_LPC32XX)      += lpc32xx_mlc.o
-obj-$(CONFIG_MTD_NAND_SH_FLCTL)		+= sh_flctl.o
-obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
-obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
-obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
-obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o
-obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mpc5121_nfc.o
-obj-$(CONFIG_MTD_NAND_VF610_NFC)	+= vf610_nfc.o
-obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
-obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
-obj-$(CONFIG_MTD_NAND_JZ4780)		+= jz4780_nand.o jz4780_bch.o
-obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
-obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
-obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
-obj-$(CONFIG_MTD_NAND_SUNXI)		+= sunxi_nand.o
-obj-$(CONFIG_MTD_NAND_HISI504)	        += hisi504_nand.o
-obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand/
-obj-$(CONFIG_MTD_NAND_QCOM)		+= qcom_nandc.o
-obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_ecc.o mtk_nand.o
-
-nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o
-nand-objs += nand_amd.o
-nand-objs += nand_hynix.o
-nand-objs += nand_macronix.o
-nand-objs += nand_micron.o
-nand-objs += nand_samsung.o
-nand-objs += nand_toshiba.o
+obj-y	+= onenand/
+obj-y	+= raw/
diff --git a/drivers/mtd/nand/bbt.c b/drivers/mtd/nand/bbt.c
new file mode 100644
index 0000000..56cde38
--- /dev/null
+++ b/drivers/mtd/nand/bbt.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017 Free Electrons
+ *
+ * Authors:
+ *	Boris Brezillon <boris.brezillon@free-electrons.com>
+ *	Peter Pan <peterpandong@micron.com>
+ */
+
+#define pr_fmt(fmt)	"nand-bbt: " fmt
+
+#include <linux/mtd/nand.h>
+#include <linux/slab.h>
+
+/**
+ * nanddev_bbt_init() - Initialize the BBT (Bad Block Table)
+ * @nand: NAND device
+ *
+ * Initialize the in-memory BBT.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int nanddev_bbt_init(struct nand_device *nand)
+{
+	unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
+	unsigned int nblocks = nanddev_neraseblocks(nand);
+	unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block,
+					   BITS_PER_LONG);
+
+	nand->bbt.cache = kzalloc(nwords, GFP_KERNEL);
+	if (!nand->bbt.cache)
+		return -ENOMEM;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nanddev_bbt_init);
+
+/**
+ * nanddev_bbt_cleanup() - Cleanup the BBT (Bad Block Table)
+ * @nand: NAND device
+ *
+ * Undoes what has been done in nanddev_bbt_init()
+ */
+void nanddev_bbt_cleanup(struct nand_device *nand)
+{
+	kfree(nand->bbt.cache);
+}
+EXPORT_SYMBOL_GPL(nanddev_bbt_cleanup);
+
+/**
+ * nanddev_bbt_update() - Update a BBT
+ * @nand: nand device
+ *
+ * Update the BBT. Currently a NOP function since on-flash bbt is not yet
+ * supported.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int nanddev_bbt_update(struct nand_device *nand)
+{
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nanddev_bbt_update);
+
+/**
+ * nanddev_bbt_get_block_status() - Return the status of an eraseblock
+ * @nand: nand device
+ * @entry: the BBT entry
+ *
+ * Return: a positive number nand_bbt_block_status status or -%ERANGE if @entry
+ *	   is bigger than the BBT size.
+ */
+int nanddev_bbt_get_block_status(const struct nand_device *nand,
+				 unsigned int entry)
+{
+	unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
+	unsigned long *pos = nand->bbt.cache +
+			     ((entry * bits_per_block) / BITS_PER_LONG);
+	unsigned int offs = (entry * bits_per_block) % BITS_PER_LONG;
+	unsigned long status;
+
+	if (entry >= nanddev_neraseblocks(nand))
+		return -ERANGE;
+
+	status = pos[0] >> offs;
+	if (bits_per_block + offs > BITS_PER_LONG)
+		status |= pos[1] << (BITS_PER_LONG - offs);
+
+	return status & GENMASK(bits_per_block - 1, 0);
+}
+EXPORT_SYMBOL_GPL(nanddev_bbt_get_block_status);
+
+/**
+ * nanddev_bbt_set_block_status() - Update the status of an eraseblock in the
+ *				    in-memory BBT
+ * @nand: nand device
+ * @entry: the BBT entry to update
+ * @status: the new status
+ *
+ * Update an entry of the in-memory BBT. If you want to push the updated BBT
+ * the NAND you should call nanddev_bbt_update().
+ *
+ * Return: 0 in case of success or -%ERANGE if @entry is bigger than the BBT
+ *	   size.
+ */
+int nanddev_bbt_set_block_status(struct nand_device *nand, unsigned int entry,
+				 enum nand_bbt_block_status status)
+{
+	unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
+	unsigned long *pos = nand->bbt.cache +
+			     ((entry * bits_per_block) / BITS_PER_LONG);
+	unsigned int offs = (entry * bits_per_block) % BITS_PER_LONG;
+	unsigned long val = status & GENMASK(bits_per_block - 1, 0);
+
+	if (entry >= nanddev_neraseblocks(nand))
+		return -ERANGE;
+
+	pos[0] &= ~GENMASK(offs + bits_per_block - 1, offs);
+	pos[0] |= val << offs;
+
+	if (bits_per_block + offs > BITS_PER_LONG) {
+		unsigned int rbits = bits_per_block + offs - BITS_PER_LONG;
+
+		pos[1] &= ~GENMASK(rbits - 1, 0);
+		pos[1] |= val >> rbits;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nanddev_bbt_set_block_status);
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
deleted file mode 100644
index 87bbd17..0000000
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ /dev/null
@@ -1,862 +0,0 @@
-/* linux/drivers/mtd/nand/bf5xx_nand.c
- *
- * Copyright 2006-2008 Analog Devices Inc.
- *	http://blackfin.uclinux.org/
- *	Bryan Wu <bryan.wu@analog.com>
- *
- * Blackfin BF5xx on-chip NAND flash controller driver
- *
- * Derived from drivers/mtd/nand/s3c2410.c
- * Copyright (c) 2007 Ben Dooks <ben@simtec.co.uk>
- *
- * Derived from drivers/mtd/nand/cafe.c
- * Copyright © 2006 Red Hat, Inc.
- * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
- *
- * Changelog:
- *	12-Jun-2007  Bryan Wu:  Initial version
- *	18-Jul-2007  Bryan Wu:
- *		- ECC_HW and ECC_SW supported
- *		- DMA supported in ECC_HW
- *		- YAFFS tested as rootfs in both ECC_HW and ECC_SW
- *
- * This program is free software; you can redistribute 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/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/bitops.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/rawnand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/blackfin.h>
-#include <asm/dma.h>
-#include <asm/cacheflush.h>
-#include <asm/nand.h>
-#include <asm/portmux.h>
-
-#define DRV_NAME	"bf5xx-nand"
-#define DRV_VERSION	"1.2"
-#define DRV_AUTHOR	"Bryan Wu <bryan.wu@analog.com>"
-#define DRV_DESC	"BF5xx on-chip NAND FLash Controller Driver"
-
-/* NFC_STAT Masks */
-#define NBUSY       0x01  /* Not Busy */
-#define WB_FULL     0x02  /* Write Buffer Full */
-#define PG_WR_STAT  0x04  /* Page Write Pending */
-#define PG_RD_STAT  0x08  /* Page Read Pending */
-#define WB_EMPTY    0x10  /* Write Buffer Empty */
-
-/* NFC_IRQSTAT Masks */
-#define NBUSYIRQ    0x01  /* Not Busy IRQ */
-#define WB_OVF      0x02  /* Write Buffer Overflow */
-#define WB_EDGE     0x04  /* Write Buffer Edge Detect */
-#define RD_RDY      0x08  /* Read Data Ready */
-#define WR_DONE     0x10  /* Page Write Done */
-
-/* NFC_RST Masks */
-#define ECC_RST     0x01  /* ECC (and NFC counters) Reset */
-
-/* NFC_PGCTL Masks */
-#define PG_RD_START 0x01  /* Page Read Start */
-#define PG_WR_START 0x02  /* Page Write Start */
-
-#ifdef CONFIG_MTD_NAND_BF5XX_HWECC
-static int hardware_ecc = 1;
-#else
-static int hardware_ecc;
-#endif
-
-static const unsigned short bfin_nfc_pin_req[] =
-	{P_NAND_CE,
-	 P_NAND_RB,
-	 P_NAND_D0,
-	 P_NAND_D1,
-	 P_NAND_D2,
-	 P_NAND_D3,
-	 P_NAND_D4,
-	 P_NAND_D5,
-	 P_NAND_D6,
-	 P_NAND_D7,
-	 P_NAND_WE,
-	 P_NAND_RE,
-	 P_NAND_CLE,
-	 P_NAND_ALE,
-	 0};
-
-#ifdef CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC
-static int bootrom_ooblayout_ecc(struct mtd_info *mtd, int section,
-				 struct mtd_oob_region *oobregion)
-{
-	if (section > 7)
-		return -ERANGE;
-
-	oobregion->offset = section * 8;
-	oobregion->length = 3;
-
-	return 0;
-}
-
-static int bootrom_ooblayout_free(struct mtd_info *mtd, int section,
-				  struct mtd_oob_region *oobregion)
-{
-	if (section > 7)
-		return -ERANGE;
-
-	oobregion->offset = (section * 8) + 3;
-	oobregion->length = 5;
-
-	return 0;
-}
-
-static const struct mtd_ooblayout_ops bootrom_ooblayout_ops = {
-	.ecc = bootrom_ooblayout_ecc,
-	.free = bootrom_ooblayout_free,
-};
-#endif
-
-/*
- * Data structures for bf5xx nand flash controller driver
- */
-
-/* bf5xx nand info */
-struct bf5xx_nand_info {
-	/* mtd info */
-	struct nand_hw_control		controller;
-	struct nand_chip		chip;
-
-	/* platform info */
-	struct bf5xx_nand_platform	*platform;
-
-	/* device info */
-	struct device			*device;
-
-	/* DMA stuff */
-	struct completion		dma_completion;
-};
-
-/*
- * Conversion functions
- */
-static struct bf5xx_nand_info *mtd_to_nand_info(struct mtd_info *mtd)
-{
-	return container_of(mtd_to_nand(mtd), struct bf5xx_nand_info,
-			    chip);
-}
-
-static struct bf5xx_nand_info *to_nand_info(struct platform_device *pdev)
-{
-	return platform_get_drvdata(pdev);
-}
-
-static struct bf5xx_nand_platform *to_nand_plat(struct platform_device *pdev)
-{
-	return dev_get_platdata(&pdev->dev);
-}
-
-/*
- * struct nand_chip interface function pointers
- */
-
-/*
- * bf5xx_nand_hwcontrol
- *
- * Issue command and address cycles to the chip
- */
-static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd,
-				   unsigned int ctrl)
-{
-	if (cmd == NAND_CMD_NONE)
-		return;
-
-	while (bfin_read_NFC_STAT() & WB_FULL)
-		cpu_relax();
-
-	if (ctrl & NAND_CLE)
-		bfin_write_NFC_CMD(cmd);
-	else if (ctrl & NAND_ALE)
-		bfin_write_NFC_ADDR(cmd);
-	SSYNC();
-}
-
-/*
- * bf5xx_nand_devready()
- *
- * returns 0 if the nand is busy, 1 if it is ready
- */
-static int bf5xx_nand_devready(struct mtd_info *mtd)
-{
-	unsigned short val = bfin_read_NFC_STAT();
-
-	if ((val & NBUSY) == NBUSY)
-		return 1;
-	else
-		return 0;
-}
-
-/*
- * ECC functions
- * These allow the bf5xx to use the controller's ECC
- * generator block to ECC the data as it passes through
- */
-
-/*
- * ECC error correction function
- */
-static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat,
-					u_char *read_ecc, u_char *calc_ecc)
-{
-	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-	u32 syndrome[5];
-	u32 calced, stored;
-	int i;
-	unsigned short failing_bit, failing_byte;
-	u_char data;
-
-	calced = calc_ecc[0] | (calc_ecc[1] << 8) | (calc_ecc[2] << 16);
-	stored = read_ecc[0] | (read_ecc[1] << 8) | (read_ecc[2] << 16);
-
-	syndrome[0] = (calced ^ stored);
-
-	/*
-	 * syndrome 0: all zero
-	 * No error in data
-	 * No action
-	 */
-	if (!syndrome[0] || !calced || !stored)
-		return 0;
-
-	/*
-	 * sysdrome 0: only one bit is one
-	 * ECC data was incorrect
-	 * No action
-	 */
-	if (hweight32(syndrome[0]) == 1) {
-		dev_err(info->device, "ECC data was incorrect!\n");
-		return -EBADMSG;
-	}
-
-	syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF);
-	syndrome[2] = (calced & 0x7FF) ^ ((calced >> 11) & 0x7FF);
-	syndrome[3] = (stored & 0x7FF) ^ ((stored >> 11) & 0x7FF);
-	syndrome[4] = syndrome[2] ^ syndrome[3];
-
-	for (i = 0; i < 5; i++)
-		dev_info(info->device, "syndrome[%d] 0x%08x\n", i, syndrome[i]);
-
-	dev_info(info->device,
-		"calced[0x%08x], stored[0x%08x]\n",
-		calced, stored);
-
-	/*
-	 * sysdrome 0: exactly 11 bits are one, each parity
-	 * and parity' pair is 1 & 0 or 0 & 1.
-	 * 1-bit correctable error
-	 * Correct the error
-	 */
-	if (hweight32(syndrome[0]) == 11 && syndrome[4] == 0x7FF) {
-		dev_info(info->device,
-			"1-bit correctable error, correct it.\n");
-		dev_info(info->device,
-			"syndrome[1] 0x%08x\n", syndrome[1]);
-
-		failing_bit = syndrome[1] & 0x7;
-		failing_byte = syndrome[1] >> 0x3;
-		data = *(dat + failing_byte);
-		data = data ^ (0x1 << failing_bit);
-		*(dat + failing_byte) = data;
-
-		return 1;
-	}
-
-	/*
-	 * sysdrome 0: random data
-	 * More than 1-bit error, non-correctable error
-	 * Discard data, mark bad block
-	 */
-	dev_err(info->device,
-		"More than 1-bit error, non-correctable error.\n");
-	dev_err(info->device,
-		"Please discard data, mark bad block\n");
-
-	return -EBADMSG;
-}
-
-static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat,
-					u_char *read_ecc, u_char *calc_ecc)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	int ret, bitflips = 0;
-
-	ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
-	if (ret < 0)
-		return ret;
-
-	bitflips = ret;
-
-	/* If ecc size is 512, correct second 256 bytes */
-	if (chip->ecc.size == 512) {
-		dat += 256;
-		read_ecc += 3;
-		calc_ecc += 3;
-		ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
-		if (ret < 0)
-			return ret;
-
-		bitflips += ret;
-	}
-
-	return bitflips;
-}
-
-static void bf5xx_nand_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-	return;
-}
-
-static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd,
-		const u_char *dat, u_char *ecc_code)
-{
-	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	u16 ecc0, ecc1;
-	u32 code[2];
-	u8 *p;
-
-	/* first 3 bytes ECC code for 256 page size */
-	ecc0 = bfin_read_NFC_ECC0();
-	ecc1 = bfin_read_NFC_ECC1();
-
-	code[0] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11);
-
-	dev_dbg(info->device, "returning ecc 0x%08x\n", code[0]);
-
-	p = (u8 *) code;
-	memcpy(ecc_code, p, 3);
-
-	/* second 3 bytes ECC code for 512 ecc size */
-	if (chip->ecc.size == 512) {
-		ecc0 = bfin_read_NFC_ECC2();
-		ecc1 = bfin_read_NFC_ECC3();
-		code[1] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11);
-
-		/* second 3 bytes in ecc_code for second 256
-		 * bytes of 512 page size
-		 */
-		p = (u8 *) (code + 1);
-		memcpy((ecc_code + 3), p, 3);
-		dev_dbg(info->device, "returning ecc 0x%08x\n", code[1]);
-	}
-
-	return 0;
-}
-
-/*
- * PIO mode for buffer writing and reading
- */
-static void bf5xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-{
-	int i;
-	unsigned short val;
-
-	/*
-	 * Data reads are requested by first writing to NFC_DATA_RD
-	 * and then reading back from NFC_READ.
-	 */
-	for (i = 0; i < len; i++) {
-		while (bfin_read_NFC_STAT() & WB_FULL)
-			cpu_relax();
-
-		/* Contents do not matter */
-		bfin_write_NFC_DATA_RD(0x0000);
-		SSYNC();
-
-		while ((bfin_read_NFC_IRQSTAT() & RD_RDY) != RD_RDY)
-			cpu_relax();
-
-		buf[i] = bfin_read_NFC_READ();
-
-		val = bfin_read_NFC_IRQSTAT();
-		val |= RD_RDY;
-		bfin_write_NFC_IRQSTAT(val);
-		SSYNC();
-	}
-}
-
-static uint8_t bf5xx_nand_read_byte(struct mtd_info *mtd)
-{
-	uint8_t val;
-
-	bf5xx_nand_read_buf(mtd, &val, 1);
-
-	return val;
-}
-
-static void bf5xx_nand_write_buf(struct mtd_info *mtd,
-				const uint8_t *buf, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++) {
-		while (bfin_read_NFC_STAT() & WB_FULL)
-			cpu_relax();
-
-		bfin_write_NFC_DATA_WR(buf[i]);
-		SSYNC();
-	}
-}
-
-static void bf5xx_nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
-{
-	int i;
-	u16 *p = (u16 *) buf;
-	len >>= 1;
-
-	/*
-	 * Data reads are requested by first writing to NFC_DATA_RD
-	 * and then reading back from NFC_READ.
-	 */
-	bfin_write_NFC_DATA_RD(0x5555);
-
-	SSYNC();
-
-	for (i = 0; i < len; i++)
-		p[i] = bfin_read_NFC_READ();
-}
-
-static void bf5xx_nand_write_buf16(struct mtd_info *mtd,
-				const uint8_t *buf, int len)
-{
-	int i;
-	u16 *p = (u16 *) buf;
-	len >>= 1;
-
-	for (i = 0; i < len; i++)
-		bfin_write_NFC_DATA_WR(p[i]);
-
-	SSYNC();
-}
-
-/*
- * DMA functions for buffer writing and reading
- */
-static irqreturn_t bf5xx_nand_dma_irq(int irq, void *dev_id)
-{
-	struct bf5xx_nand_info *info = dev_id;
-
-	clear_dma_irqstat(CH_NFC);
-	disable_dma(CH_NFC);
-	complete(&info->dma_completion);
-
-	return IRQ_HANDLED;
-}
-
-static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
-				uint8_t *buf, int is_read)
-{
-	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	unsigned short val;
-
-	dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n",
-			mtd, buf, is_read);
-
-	/*
-	 * Before starting a dma transfer, be sure to invalidate/flush
-	 * the cache over the address range of your DMA buffer to
-	 * prevent cache coherency problems. Otherwise very subtle bugs
-	 * can be introduced to your driver.
-	 */
-	if (is_read)
-		invalidate_dcache_range((unsigned int)buf,
-				(unsigned int)(buf + chip->ecc.size));
-	else
-		flush_dcache_range((unsigned int)buf,
-				(unsigned int)(buf + chip->ecc.size));
-
-	/*
-	 * This register must be written before each page is
-	 * transferred to generate the correct ECC register
-	 * values.
-	 */
-	bfin_write_NFC_RST(ECC_RST);
-	SSYNC();
-	while (bfin_read_NFC_RST() & ECC_RST)
-		cpu_relax();
-
-	disable_dma(CH_NFC);
-	clear_dma_irqstat(CH_NFC);
-
-	/* setup DMA register with Blackfin DMA API */
-	set_dma_config(CH_NFC, 0x0);
-	set_dma_start_addr(CH_NFC, (unsigned long) buf);
-
-	/* The DMAs have different size on BF52x and BF54x */
-#ifdef CONFIG_BF52x
-	set_dma_x_count(CH_NFC, (chip->ecc.size >> 1));
-	set_dma_x_modify(CH_NFC, 2);
-	val = DI_EN | WDSIZE_16;
-#endif
-
-#ifdef CONFIG_BF54x
-	set_dma_x_count(CH_NFC, (chip->ecc.size >> 2));
-	set_dma_x_modify(CH_NFC, 4);
-	val = DI_EN | WDSIZE_32;
-#endif
-	/* setup write or read operation */
-	if (is_read)
-		val |= WNR;
-	set_dma_config(CH_NFC, val);
-	enable_dma(CH_NFC);
-
-	/* Start PAGE read/write operation */
-	if (is_read)
-		bfin_write_NFC_PGCTL(PG_RD_START);
-	else
-		bfin_write_NFC_PGCTL(PG_WR_START);
-	wait_for_completion(&info->dma_completion);
-}
-
-static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
-					uint8_t *buf, int len)
-{
-	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-	struct nand_chip *chip = mtd_to_nand(mtd);
-
-	dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len);
-
-	if (len == chip->ecc.size)
-		bf5xx_nand_dma_rw(mtd, buf, 1);
-	else
-		bf5xx_nand_read_buf(mtd, buf, len);
-}
-
-static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
-				const uint8_t *buf, int len)
-{
-	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-	struct nand_chip *chip = mtd_to_nand(mtd);
-
-	dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len);
-
-	if (len == chip->ecc.size)
-		bf5xx_nand_dma_rw(mtd, (uint8_t *)buf, 0);
-	else
-		bf5xx_nand_write_buf(mtd, buf, len);
-}
-
-static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-		uint8_t *buf, int oob_required, int page)
-{
-	nand_read_page_op(chip, page, 0, NULL, 0);
-
-	bf5xx_nand_read_buf(mtd, buf, mtd->writesize);
-	bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	return 0;
-}
-
-static int bf5xx_nand_write_page_raw(struct mtd_info *mtd,
-		struct nand_chip *chip,	const uint8_t *buf, int oob_required,
-		int page)
-{
-	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
-	bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	return nand_prog_page_end_op(chip);
-}
-
-/*
- * System initialization functions
- */
-static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
-{
-	int ret;
-
-	/* Do not use dma */
-	if (!hardware_ecc)
-		return 0;
-
-	init_completion(&info->dma_completion);
-
-	/* Request NFC DMA channel */
-	ret = request_dma(CH_NFC, "BF5XX NFC driver");
-	if (ret < 0) {
-		dev_err(info->device, " unable to get DMA channel\n");
-		return ret;
-	}
-
-#ifdef CONFIG_BF54x
-	/* Setup DMAC1 channel mux for NFC which shared with SDH */
-	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() & ~1);
-	SSYNC();
-#endif
-
-	set_dma_callback(CH_NFC, bf5xx_nand_dma_irq, info);
-
-	/* Turn off the DMA channel first */
-	disable_dma(CH_NFC);
-	return 0;
-}
-
-static void bf5xx_nand_dma_remove(struct bf5xx_nand_info *info)
-{
-	/* Free NFC DMA channel */
-	if (hardware_ecc)
-		free_dma(CH_NFC);
-}
-
-/*
- * BF5XX NFC hardware initialization
- *  - pin mux setup
- *  - clear interrupt status
- */
-static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
-{
-	int err = 0;
-	unsigned short val;
-	struct bf5xx_nand_platform *plat = info->platform;
-
-	/* setup NFC_CTL register */
-	dev_info(info->device,
-		"data_width=%d, wr_dly=%d, rd_dly=%d\n",
-		(plat->data_width ? 16 : 8),
-		plat->wr_dly, plat->rd_dly);
-
-	val = (1 << NFC_PG_SIZE_OFFSET) |
-		(plat->data_width << NFC_NWIDTH_OFFSET) |
-		(plat->rd_dly << NFC_RDDLY_OFFSET) |
-		(plat->wr_dly << NFC_WRDLY_OFFSET);
-	dev_dbg(info->device, "NFC_CTL is 0x%04x\n", val);
-
-	bfin_write_NFC_CTL(val);
-	SSYNC();
-
-	/* clear interrupt status */
-	bfin_write_NFC_IRQMASK(0x0);
-	SSYNC();
-	val = bfin_read_NFC_IRQSTAT();
-	bfin_write_NFC_IRQSTAT(val);
-	SSYNC();
-
-	/* DMA initialization  */
-	if (bf5xx_nand_dma_init(info))
-		err = -ENXIO;
-
-	return err;
-}
-
-/*
- * Device management interface
- */
-static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
-{
-	struct mtd_info *mtd = nand_to_mtd(&info->chip);
-	struct mtd_partition *parts = info->platform->partitions;
-	int nr = info->platform->nr_partitions;
-
-	return mtd_device_register(mtd, parts, nr);
-}
-
-static int bf5xx_nand_remove(struct platform_device *pdev)
-{
-	struct bf5xx_nand_info *info = to_nand_info(pdev);
-
-	/* first thing we need to do is release all our mtds
-	 * and their partitions, then go through freeing the
-	 * resources used
-	 */
-	nand_release(nand_to_mtd(&info->chip));
-
-	peripheral_free_list(bfin_nfc_pin_req);
-	bf5xx_nand_dma_remove(info);
-
-	return 0;
-}
-
-static int bf5xx_nand_scan(struct mtd_info *mtd)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	int ret;
-
-	ret = nand_scan_ident(mtd, 1, NULL);
-	if (ret)
-		return ret;
-
-	if (hardware_ecc) {
-		/*
-		 * for nand with page size > 512B, think it as several sections with 512B
-		 */
-		if (likely(mtd->writesize >= 512)) {
-			chip->ecc.size = 512;
-			chip->ecc.bytes = 6;
-			chip->ecc.strength = 2;
-		} else {
-			chip->ecc.size = 256;
-			chip->ecc.bytes = 3;
-			chip->ecc.strength = 1;
-			bfin_write_NFC_CTL(bfin_read_NFC_CTL() & ~(1 << NFC_PG_SIZE_OFFSET));
-			SSYNC();
-		}
-	}
-
-	return	nand_scan_tail(mtd);
-}
-
-/*
- * bf5xx_nand_probe
- *
- * called by device layer when it finds a device matching
- * one our driver can handled. This code checks to see if
- * it can allocate all necessary resources then calls the
- * nand layer to look for devices
- */
-static int bf5xx_nand_probe(struct platform_device *pdev)
-{
-	struct bf5xx_nand_platform *plat = to_nand_plat(pdev);
-	struct bf5xx_nand_info *info = NULL;
-	struct nand_chip *chip = NULL;
-	struct mtd_info *mtd = NULL;
-	int err = 0;
-
-	dev_dbg(&pdev->dev, "(%p)\n", pdev);
-
-	if (!plat) {
-		dev_err(&pdev->dev, "no platform specific information\n");
-		return -EINVAL;
-	}
-
-	if (peripheral_request_list(bfin_nfc_pin_req, DRV_NAME)) {
-		dev_err(&pdev->dev, "requesting Peripherals failed\n");
-		return -EFAULT;
-	}
-
-	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
-	if (info == NULL) {
-		err = -ENOMEM;
-		goto out_err;
-	}
-
-	platform_set_drvdata(pdev, info);
-
-	nand_hw_control_init(&info->controller);
-
-	info->device     = &pdev->dev;
-	info->platform   = plat;
-
-	/* initialise chip data struct */
-	chip = &info->chip;
-	mtd = nand_to_mtd(&info->chip);
-
-	if (plat->data_width)
-		chip->options |= NAND_BUSWIDTH_16;
-
-	chip->options |= NAND_CACHEPRG | NAND_SKIP_BBTSCAN;
-
-	chip->read_buf = (plat->data_width) ?
-		bf5xx_nand_read_buf16 : bf5xx_nand_read_buf;
-	chip->write_buf = (plat->data_width) ?
-		bf5xx_nand_write_buf16 : bf5xx_nand_write_buf;
-
-	chip->read_byte    = bf5xx_nand_read_byte;
-
-	chip->cmd_ctrl     = bf5xx_nand_hwcontrol;
-	chip->dev_ready    = bf5xx_nand_devready;
-
-	nand_set_controller_data(chip, mtd);
-	chip->controller   = &info->controller;
-
-	chip->IO_ADDR_R    = (void __iomem *) NFC_READ;
-	chip->IO_ADDR_W    = (void __iomem *) NFC_DATA_WR;
-
-	chip->chip_delay   = 0;
-
-	/* initialise mtd info data struct */
-	mtd->dev.parent = &pdev->dev;
-
-	/* initialise the hardware */
-	err = bf5xx_nand_hw_init(info);
-	if (err)
-		goto out_err;
-
-	/* setup hardware ECC data struct */
-	if (hardware_ecc) {
-#ifdef CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC
-		mtd_set_ooblayout(mtd, &bootrom_ooblayout_ops);
-#endif
-		chip->read_buf      = bf5xx_nand_dma_read_buf;
-		chip->write_buf     = bf5xx_nand_dma_write_buf;
-		chip->ecc.calculate = bf5xx_nand_calculate_ecc;
-		chip->ecc.correct   = bf5xx_nand_correct_data;
-		chip->ecc.mode	    = NAND_ECC_HW;
-		chip->ecc.hwctl	    = bf5xx_nand_enable_hwecc;
-		chip->ecc.read_page_raw = bf5xx_nand_read_page_raw;
-		chip->ecc.write_page_raw = bf5xx_nand_write_page_raw;
-	} else {
-		chip->ecc.mode	    = NAND_ECC_SOFT;
-		chip->ecc.algo	= NAND_ECC_HAMMING;
-	}
-
-	/* scan hardware nand chip and setup mtd info data struct */
-	if (bf5xx_nand_scan(mtd)) {
-		err = -ENXIO;
-		goto out_err_nand_scan;
-	}
-
-#ifdef CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC
-	chip->badblockpos = 63;
-#endif
-
-	/* add NAND partition */
-	bf5xx_nand_add_partition(info);
-
-	dev_dbg(&pdev->dev, "initialised ok\n");
-	return 0;
-
-out_err_nand_scan:
-	bf5xx_nand_dma_remove(info);
-out_err:
-	peripheral_free_list(bfin_nfc_pin_req);
-
-	return err;
-}
-
-/* driver device registration */
-static struct platform_driver bf5xx_nand_driver = {
-	.probe		= bf5xx_nand_probe,
-	.remove		= bf5xx_nand_remove,
-	.driver		= {
-		.name	= DRV_NAME,
-	},
-};
-
-module_platform_driver(bf5xx_nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR(DRV_AUTHOR);
-MODULE_DESCRIPTION(DRV_DESC);
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
new file mode 100644
index 0000000..d0cd6f8
--- /dev/null
+++ b/drivers/mtd/nand/core.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017 Free Electrons
+ *
+ * Authors:
+ *	Boris Brezillon <boris.brezillon@free-electrons.com>
+ *	Peter Pan <peterpandong@micron.com>
+ */
+
+#define pr_fmt(fmt)	"nand: " fmt
+
+#include <linux/module.h>
+#include <linux/mtd/nand.h>
+
+/**
+ * nanddev_isbad() - Check if a block is bad
+ * @nand: NAND device
+ * @pos: position pointing to the block we want to check
+ *
+ * Return: true if the block is bad, false otherwise.
+ */
+bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos)
+{
+	if (nanddev_bbt_is_initialized(nand)) {
+		unsigned int entry;
+		int status;
+
+		entry = nanddev_bbt_pos_to_entry(nand, pos);
+		status = nanddev_bbt_get_block_status(nand, entry);
+		/* Lazy block status retrieval */
+		if (status == NAND_BBT_BLOCK_STATUS_UNKNOWN) {
+			if (nand->ops->isbad(nand, pos))
+				status = NAND_BBT_BLOCK_FACTORY_BAD;
+			else
+				status = NAND_BBT_BLOCK_GOOD;
+
+			nanddev_bbt_set_block_status(nand, entry, status);
+		}
+
+		if (status == NAND_BBT_BLOCK_WORN ||
+		    status == NAND_BBT_BLOCK_FACTORY_BAD)
+			return true;
+
+		return false;
+	}
+
+	return nand->ops->isbad(nand, pos);
+}
+EXPORT_SYMBOL_GPL(nanddev_isbad);
+
+/**
+ * nanddev_markbad() - Mark a block as bad
+ * @nand: NAND device
+ * @pos: position of the block to mark bad
+ *
+ * Mark a block bad. This function is updating the BBT if available and
+ * calls the low-level markbad hook (nand->ops->markbad()).
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos)
+{
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+	unsigned int entry;
+	int ret = 0;
+
+	if (nanddev_isbad(nand, pos))
+		return 0;
+
+	ret = nand->ops->markbad(nand, pos);
+	if (ret)
+		pr_warn("failed to write BBM to block @%llx (err = %d)\n",
+			nanddev_pos_to_offs(nand, pos), ret);
+
+	if (!nanddev_bbt_is_initialized(nand))
+		goto out;
+
+	entry = nanddev_bbt_pos_to_entry(nand, pos);
+	ret = nanddev_bbt_set_block_status(nand, entry, NAND_BBT_BLOCK_WORN);
+	if (ret)
+		goto out;
+
+	ret = nanddev_bbt_update(nand);
+
+out:
+	if (!ret)
+		mtd->ecc_stats.badblocks++;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(nanddev_markbad);
+
+/**
+ * nanddev_isreserved() - Check whether an eraseblock is reserved or not
+ * @nand: NAND device
+ * @pos: NAND position to test
+ *
+ * Checks whether the eraseblock pointed by @pos is reserved or not.
+ *
+ * Return: true if the eraseblock is reserved, false otherwise.
+ */
+bool nanddev_isreserved(struct nand_device *nand, const struct nand_pos *pos)
+{
+	unsigned int entry;
+	int status;
+
+	if (!nanddev_bbt_is_initialized(nand))
+		return false;
+
+	/* Return info from the table */
+	entry = nanddev_bbt_pos_to_entry(nand, pos);
+	status = nanddev_bbt_get_block_status(nand, entry);
+	return status == NAND_BBT_BLOCK_RESERVED;
+}
+EXPORT_SYMBOL_GPL(nanddev_isreserved);
+
+/**
+ * nanddev_erase() - Erase a NAND portion
+ * @nand: NAND device
+ * @pos: position of the block to erase
+ *
+ * Erases the block if it's not bad.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos)
+{
+	if (nanddev_isbad(nand, pos) || nanddev_isreserved(nand, pos)) {
+		pr_warn("attempt to erase a bad/reserved block @%llx\n",
+			nanddev_pos_to_offs(nand, pos));
+		return -EIO;
+	}
+
+	return nand->ops->erase(nand, pos);
+}
+EXPORT_SYMBOL_GPL(nanddev_erase);
+
+/**
+ * nanddev_mtd_erase() - Generic mtd->_erase() implementation for NAND devices
+ * @mtd: MTD device
+ * @einfo: erase request
+ *
+ * This is a simple mtd->_erase() implementation iterating over all blocks
+ * concerned by @einfo and calling nand->ops->erase() on each of them.
+ *
+ * Note that mtd->_erase should not be directly assigned to this helper,
+ * because there's no locking here. NAND specialized layers should instead
+ * implement there own wrapper around nanddev_mtd_erase() taking the
+ * appropriate lock before calling nanddev_mtd_erase().
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
+{
+	struct nand_device *nand = mtd_to_nanddev(mtd);
+	struct nand_pos pos, last;
+	int ret;
+
+	nanddev_offs_to_pos(nand, einfo->addr, &pos);
+	nanddev_offs_to_pos(nand, einfo->addr + einfo->len - 1, &last);
+	while (nanddev_pos_cmp(&pos, &last) <= 0) {
+		ret = nanddev_erase(nand, &pos);
+		if (ret) {
+			einfo->fail_addr = nanddev_pos_to_offs(nand, &pos);
+			einfo->state = MTD_ERASE_FAILED;
+
+			return ret;
+		}
+
+		nanddev_pos_next_eraseblock(nand, &pos);
+	}
+
+	einfo->state = MTD_ERASE_DONE;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nanddev_mtd_erase);
+
+/**
+ * nanddev_init() - Initialize a NAND device
+ * @nand: NAND device
+ * @ops: NAND device operations
+ * @owner: NAND device owner
+ *
+ * Initializes a NAND device object. Consistency checks are done on @ops and
+ * @nand->memorg. Also takes care of initializing the BBT.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int nanddev_init(struct nand_device *nand, const struct nand_ops *ops,
+		 struct module *owner)
+{
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+	struct nand_memory_organization *memorg = nanddev_get_memorg(nand);
+
+	if (!nand || !ops)
+		return -EINVAL;
+
+	if (!ops->erase || !ops->markbad || !ops->isbad)
+		return -EINVAL;
+
+	if (!memorg->bits_per_cell || !memorg->pagesize ||
+	    !memorg->pages_per_eraseblock || !memorg->eraseblocks_per_lun ||
+	    !memorg->planes_per_lun || !memorg->luns_per_target ||
+	    !memorg->ntargets)
+		return -EINVAL;
+
+	nand->rowconv.eraseblock_addr_shift =
+					fls(memorg->pages_per_eraseblock - 1);
+	nand->rowconv.lun_addr_shift = fls(memorg->eraseblocks_per_lun - 1) +
+				       nand->rowconv.eraseblock_addr_shift;
+
+	nand->ops = ops;
+
+	mtd->type = memorg->bits_per_cell == 1 ?
+		    MTD_NANDFLASH : MTD_MLCNANDFLASH;
+	mtd->flags = MTD_CAP_NANDFLASH;
+	mtd->erasesize = memorg->pagesize * memorg->pages_per_eraseblock;
+	mtd->writesize = memorg->pagesize;
+	mtd->writebufsize = memorg->pagesize;
+	mtd->oobsize = memorg->oobsize;
+	mtd->size = nanddev_size(nand);
+	mtd->owner = owner;
+
+	return nanddev_bbt_init(nand);
+}
+EXPORT_SYMBOL_GPL(nanddev_init);
+
+/**
+ * nanddev_cleanup() - Release resources allocated in nanddev_init()
+ * @nand: NAND device
+ *
+ * Basically undoes what has been done in nanddev_init().
+ */
+void nanddev_cleanup(struct nand_device *nand)
+{
+	if (nanddev_bbt_is_initialized(nand))
+		nanddev_bbt_cleanup(nand);
+}
+EXPORT_SYMBOL_GPL(nanddev_cleanup);
+
+MODULE_DESCRIPTION("Generic NAND framework");
+MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
deleted file mode 100644
index 9778724..0000000
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ /dev/null
@@ -1,1510 +0,0 @@
-/*
- * Freescale GPMI NAND Flash Driver
- *
- * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
- * Copyright (C) 2008 Embedded Alley Solutions, 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-
-#include "gpmi-nand.h"
-#include "gpmi-regs.h"
-#include "bch-regs.h"
-
-static struct timing_threshold timing_default_threshold = {
-	.max_data_setup_cycles       = (BM_GPMI_TIMING0_DATA_SETUP >>
-						BP_GPMI_TIMING0_DATA_SETUP),
-	.internal_data_setup_in_ns   = 0,
-	.max_sample_delay_factor     = (BM_GPMI_CTRL1_RDN_DELAY >>
-						BP_GPMI_CTRL1_RDN_DELAY),
-	.max_dll_clock_period_in_ns  = 32,
-	.max_dll_delay_in_ns         = 16,
-};
-
-#define MXS_SET_ADDR		0x4
-#define MXS_CLR_ADDR		0x8
-/*
- * Clear the bit and poll it cleared.  This is usually called with
- * a reset address and mask being either SFTRST(bit 31) or CLKGATE
- * (bit 30).
- */
-static int clear_poll_bit(void __iomem *addr, u32 mask)
-{
-	int timeout = 0x400;
-
-	/* clear the bit */
-	writel(mask, addr + MXS_CLR_ADDR);
-
-	/*
-	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
-	 * recommends to wait 1us.
-	 */
-	udelay(1);
-
-	/* poll the bit becoming clear */
-	while ((readl(addr) & mask) && --timeout)
-		/* nothing */;
-
-	return !timeout;
-}
-
-#define MODULE_CLKGATE		(1 << 30)
-#define MODULE_SFTRST		(1 << 31)
-/*
- * The current mxs_reset_block() will do two things:
- *  [1] enable the module.
- *  [2] reset the module.
- *
- * In most of the cases, it's ok.
- * But in MX23, there is a hardware bug in the BCH block (see erratum #2847).
- * If you try to soft reset the BCH block, it becomes unusable until
- * the next hard reset. This case occurs in the NAND boot mode. When the board
- * boots by NAND, the ROM of the chip will initialize the BCH blocks itself.
- * So If the driver tries to reset the BCH again, the BCH will not work anymore.
- * You will see a DMA timeout in this case. The bug has been fixed
- * in the following chips, such as MX28.
- *
- * To avoid this bug, just add a new parameter `just_enable` for
- * the mxs_reset_block(), and rewrite it here.
- */
-static int gpmi_reset_block(void __iomem *reset_addr, bool just_enable)
-{
-	int ret;
-	int timeout = 0x400;
-
-	/* clear and poll SFTRST */
-	ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
-	if (unlikely(ret))
-		goto error;
-
-	/* clear CLKGATE */
-	writel(MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
-
-	if (!just_enable) {
-		/* set SFTRST to reset the block */
-		writel(MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
-		udelay(1);
-
-		/* poll CLKGATE becoming set */
-		while ((!(readl(reset_addr) & MODULE_CLKGATE)) && --timeout)
-			/* nothing */;
-		if (unlikely(!timeout))
-			goto error;
-	}
-
-	/* clear and poll SFTRST */
-	ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
-	if (unlikely(ret))
-		goto error;
-
-	/* clear and poll CLKGATE */
-	ret = clear_poll_bit(reset_addr, MODULE_CLKGATE);
-	if (unlikely(ret))
-		goto error;
-
-	return 0;
-
-error:
-	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
-	return -ETIMEDOUT;
-}
-
-static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
-{
-	struct clk *clk;
-	int ret;
-	int i;
-
-	for (i = 0; i < GPMI_CLK_MAX; i++) {
-		clk = this->resources.clock[i];
-		if (!clk)
-			break;
-
-		if (v) {
-			ret = clk_prepare_enable(clk);
-			if (ret)
-				goto err_clk;
-		} else {
-			clk_disable_unprepare(clk);
-		}
-	}
-	return 0;
-
-err_clk:
-	for (; i > 0; i--)
-		clk_disable_unprepare(this->resources.clock[i - 1]);
-	return ret;
-}
-
-#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
-#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
-
-int gpmi_init(struct gpmi_nand_data *this)
-{
-	struct resources *r = &this->resources;
-	int ret;
-
-	ret = gpmi_enable_clk(this);
-	if (ret)
-		return ret;
-	ret = gpmi_reset_block(r->gpmi_regs, false);
-	if (ret)
-		goto err_out;
-
-	/*
-	 * Reset BCH here, too. We got failures otherwise :(
-	 * See later BCH reset for explanation of MX23 handling
-	 */
-	ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
-	if (ret)
-		goto err_out;
-
-
-	/* Choose NAND mode. */
-	writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR);
-
-	/* Set the IRQ polarity. */
-	writel(BM_GPMI_CTRL1_ATA_IRQRDY_POLARITY,
-				r->gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	/* Disable Write-Protection. */
-	writel(BM_GPMI_CTRL1_DEV_RESET, r->gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	/* Select BCH ECC. */
-	writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	/*
-	 * Decouple the chip select from dma channel. We use dma0 for all
-	 * the chips.
-	 */
-	writel(BM_GPMI_CTRL1_DECOUPLE_CS, r->gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	gpmi_disable_clk(this);
-	return 0;
-err_out:
-	gpmi_disable_clk(this);
-	return ret;
-}
-
-/* This function is very useful. It is called only when the bug occur. */
-void gpmi_dump_info(struct gpmi_nand_data *this)
-{
-	struct resources *r = &this->resources;
-	struct bch_geometry *geo = &this->bch_geometry;
-	u32 reg;
-	int i;
-
-	dev_err(this->dev, "Show GPMI registers :\n");
-	for (i = 0; i <= HW_GPMI_DEBUG / 0x10 + 1; i++) {
-		reg = readl(r->gpmi_regs + i * 0x10);
-		dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
-	}
-
-	/* start to print out the BCH info */
-	dev_err(this->dev, "Show BCH registers :\n");
-	for (i = 0; i <= HW_BCH_VERSION / 0x10 + 1; i++) {
-		reg = readl(r->bch_regs + i * 0x10);
-		dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
-	}
-	dev_err(this->dev, "BCH Geometry :\n"
-		"GF length              : %u\n"
-		"ECC Strength           : %u\n"
-		"Page Size in Bytes     : %u\n"
-		"Metadata Size in Bytes : %u\n"
-		"ECC Chunk Size in Bytes: %u\n"
-		"ECC Chunk Count        : %u\n"
-		"Payload Size in Bytes  : %u\n"
-		"Auxiliary Size in Bytes: %u\n"
-		"Auxiliary Status Offset: %u\n"
-		"Block Mark Byte Offset : %u\n"
-		"Block Mark Bit Offset  : %u\n",
-		geo->gf_len,
-		geo->ecc_strength,
-		geo->page_size,
-		geo->metadata_size,
-		geo->ecc_chunk_size,
-		geo->ecc_chunk_count,
-		geo->payload_size,
-		geo->auxiliary_size,
-		geo->auxiliary_status_offset,
-		geo->block_mark_byte_offset,
-		geo->block_mark_bit_offset);
-}
-
-/* Configures the geometry for BCH.  */
-int bch_set_geometry(struct gpmi_nand_data *this)
-{
-	struct resources *r = &this->resources;
-	struct bch_geometry *bch_geo = &this->bch_geometry;
-	unsigned int block_count;
-	unsigned int block_size;
-	unsigned int metadata_size;
-	unsigned int ecc_strength;
-	unsigned int page_size;
-	unsigned int gf_len;
-	int ret;
-
-	if (common_nfc_set_geometry(this))
-		return !0;
-
-	block_count   = bch_geo->ecc_chunk_count - 1;
-	block_size    = bch_geo->ecc_chunk_size;
-	metadata_size = bch_geo->metadata_size;
-	ecc_strength  = bch_geo->ecc_strength >> 1;
-	page_size     = bch_geo->page_size;
-	gf_len        = bch_geo->gf_len;
-
-	ret = gpmi_enable_clk(this);
-	if (ret)
-		return ret;
-
-	/*
-	* Due to erratum #2847 of the MX23, the BCH cannot be soft reset on this
-	* chip, otherwise it will lock up. So we skip resetting BCH on the MX23.
-	* On the other hand, the MX28 needs the reset, because one case has been
-	* seen where the BCH produced ECC errors constantly after 10000
-	* consecutive reboots. The latter case has not been seen on the MX23
-	* yet, still we don't know if it could happen there as well.
-	*/
-	ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
-	if (ret)
-		goto err_out;
-
-	/* Configure layout 0. */
-	writel(BF_BCH_FLASH0LAYOUT0_NBLOCKS(block_count)
-			| BF_BCH_FLASH0LAYOUT0_META_SIZE(metadata_size)
-			| BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength, this)
-			| BF_BCH_FLASH0LAYOUT0_GF(gf_len, this)
-			| BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size, this),
-			r->bch_regs + HW_BCH_FLASH0LAYOUT0);
-
-	writel(BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size)
-			| BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength, this)
-			| BF_BCH_FLASH0LAYOUT1_GF(gf_len, this)
-			| BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size, this),
-			r->bch_regs + HW_BCH_FLASH0LAYOUT1);
-
-	/* Set *all* chip selects to use layout 0. */
-	writel(0, r->bch_regs + HW_BCH_LAYOUTSELECT);
-
-	/* Enable interrupts. */
-	writel(BM_BCH_CTRL_COMPLETE_IRQ_EN,
-				r->bch_regs + HW_BCH_CTRL_SET);
-
-	gpmi_disable_clk(this);
-	return 0;
-err_out:
-	gpmi_disable_clk(this);
-	return ret;
-}
-
-/* Converts time in nanoseconds to cycles. */
-static unsigned int ns_to_cycles(unsigned int time,
-			unsigned int period, unsigned int min)
-{
-	unsigned int k;
-
-	k = (time + period - 1) / period;
-	return max(k, min);
-}
-
-#define DEF_MIN_PROP_DELAY	5
-#define DEF_MAX_PROP_DELAY	9
-/* Apply timing to current hardware conditions. */
-static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
-					struct gpmi_nfc_hardware_timing *hw)
-{
-	struct timing_threshold *nfc = &timing_default_threshold;
-	struct resources *r = &this->resources;
-	struct nand_chip *nand = &this->nand;
-	struct nand_timing target = this->timing;
-	bool improved_timing_is_available;
-	unsigned long clock_frequency_in_hz;
-	unsigned int clock_period_in_ns;
-	bool dll_use_half_periods;
-	unsigned int dll_delay_shift;
-	unsigned int max_sample_delay_in_ns;
-	unsigned int address_setup_in_cycles;
-	unsigned int data_setup_in_ns;
-	unsigned int data_setup_in_cycles;
-	unsigned int data_hold_in_cycles;
-	int ideal_sample_delay_in_ns;
-	unsigned int sample_delay_factor;
-	int tEYE;
-	unsigned int min_prop_delay_in_ns = DEF_MIN_PROP_DELAY;
-	unsigned int max_prop_delay_in_ns = DEF_MAX_PROP_DELAY;
-
-	/*
-	 * If there are multiple chips, we need to relax the timings to allow
-	 * for signal distortion due to higher capacitance.
-	 */
-	if (nand->numchips > 2) {
-		target.data_setup_in_ns    += 10;
-		target.data_hold_in_ns     += 10;
-		target.address_setup_in_ns += 10;
-	} else if (nand->numchips > 1) {
-		target.data_setup_in_ns    += 5;
-		target.data_hold_in_ns     += 5;
-		target.address_setup_in_ns += 5;
-	}
-
-	/* Check if improved timing information is available. */
-	improved_timing_is_available =
-		(target.tREA_in_ns  >= 0) &&
-		(target.tRLOH_in_ns >= 0) &&
-		(target.tRHOH_in_ns >= 0);
-
-	/* Inspect the clock. */
-	nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]);
-	clock_frequency_in_hz = nfc->clock_frequency_in_hz;
-	clock_period_in_ns    = NSEC_PER_SEC / clock_frequency_in_hz;
-
-	/*
-	 * The NFC quantizes setup and hold parameters in terms of clock cycles.
-	 * Here, we quantize the setup and hold timing parameters to the
-	 * next-highest clock period to make sure we apply at least the
-	 * specified times.
-	 *
-	 * For data setup and data hold, the hardware interprets a value of zero
-	 * as the largest possible delay. This is not what's intended by a zero
-	 * in the input parameter, so we impose a minimum of one cycle.
-	 */
-	data_setup_in_cycles    = ns_to_cycles(target.data_setup_in_ns,
-							clock_period_in_ns, 1);
-	data_hold_in_cycles     = ns_to_cycles(target.data_hold_in_ns,
-							clock_period_in_ns, 1);
-	address_setup_in_cycles = ns_to_cycles(target.address_setup_in_ns,
-							clock_period_in_ns, 0);
-
-	/*
-	 * The clock's period affects the sample delay in a number of ways:
-	 *
-	 * (1) The NFC HAL tells us the maximum clock period the sample delay
-	 *     DLL can tolerate. If the clock period is greater than half that
-	 *     maximum, we must configure the DLL to be driven by half periods.
-	 *
-	 * (2) We need to convert from an ideal sample delay, in ns, to a
-	 *     "sample delay factor," which the NFC uses. This factor depends on
-	 *     whether we're driving the DLL with full or half periods.
-	 *     Paraphrasing the reference manual:
-	 *
-	 *         AD = SDF x 0.125 x RP
-	 *
-	 * where:
-	 *
-	 *     AD   is the applied delay, in ns.
-	 *     SDF  is the sample delay factor, which is dimensionless.
-	 *     RP   is the reference period, in ns, which is a full clock period
-	 *          if the DLL is being driven by full periods, or half that if
-	 *          the DLL is being driven by half periods.
-	 *
-	 * Let's re-arrange this in a way that's more useful to us:
-	 *
-	 *                        8
-	 *         SDF  =  AD x ----
-	 *                       RP
-	 *
-	 * The reference period is either the clock period or half that, so this
-	 * is:
-	 *
-	 *                        8       AD x DDF
-	 *         SDF  =  AD x -----  =  --------
-	 *                      f x P        P
-	 *
-	 * where:
-	 *
-	 *       f  is 1 or 1/2, depending on how we're driving the DLL.
-	 *       P  is the clock period.
-	 *     DDF  is the DLL Delay Factor, a dimensionless value that
-	 *          incorporates all the constants in the conversion.
-	 *
-	 * DDF will be either 8 or 16, both of which are powers of two. We can
-	 * reduce the cost of this conversion by using bit shifts instead of
-	 * multiplication or division. Thus:
-	 *
-	 *                 AD << DDS
-	 *         SDF  =  ---------
-	 *                     P
-	 *
-	 *     or
-	 *
-	 *         AD  =  (SDF >> DDS) x P
-	 *
-	 * where:
-	 *
-	 *     DDS  is the DLL Delay Shift, the logarithm to base 2 of the DDF.
-	 */
-	if (clock_period_in_ns > (nfc->max_dll_clock_period_in_ns >> 1)) {
-		dll_use_half_periods = true;
-		dll_delay_shift      = 3 + 1;
-	} else {
-		dll_use_half_periods = false;
-		dll_delay_shift      = 3;
-	}
-
-	/*
-	 * Compute the maximum sample delay the NFC allows, under current
-	 * conditions. If the clock is running too slowly, no sample delay is
-	 * possible.
-	 */
-	if (clock_period_in_ns > nfc->max_dll_clock_period_in_ns)
-		max_sample_delay_in_ns = 0;
-	else {
-		/*
-		 * Compute the delay implied by the largest sample delay factor
-		 * the NFC allows.
-		 */
-		max_sample_delay_in_ns =
-			(nfc->max_sample_delay_factor * clock_period_in_ns) >>
-								dll_delay_shift;
-
-		/*
-		 * Check if the implied sample delay larger than the NFC
-		 * actually allows.
-		 */
-		if (max_sample_delay_in_ns > nfc->max_dll_delay_in_ns)
-			max_sample_delay_in_ns = nfc->max_dll_delay_in_ns;
-	}
-
-	/*
-	 * Check if improved timing information is available. If not, we have to
-	 * use a less-sophisticated algorithm.
-	 */
-	if (!improved_timing_is_available) {
-		/*
-		 * Fold the read setup time required by the NFC into the ideal
-		 * sample delay.
-		 */
-		ideal_sample_delay_in_ns = target.gpmi_sample_delay_in_ns +
-						nfc->internal_data_setup_in_ns;
-
-		/*
-		 * The ideal sample delay may be greater than the maximum
-		 * allowed by the NFC. If so, we can trade off sample delay time
-		 * for more data setup time.
-		 *
-		 * In each iteration of the following loop, we add a cycle to
-		 * the data setup time and subtract a corresponding amount from
-		 * the sample delay until we've satisified the constraints or
-		 * can't do any better.
-		 */
-		while ((ideal_sample_delay_in_ns > max_sample_delay_in_ns) &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-
-			data_setup_in_cycles++;
-			ideal_sample_delay_in_ns -= clock_period_in_ns;
-
-			if (ideal_sample_delay_in_ns < 0)
-				ideal_sample_delay_in_ns = 0;
-
-		}
-
-		/*
-		 * Compute the sample delay factor that corresponds most closely
-		 * to the ideal sample delay. If the result is too large for the
-		 * NFC, use the maximum value.
-		 *
-		 * Notice that we use the ns_to_cycles function to compute the
-		 * sample delay factor. We do this because the form of the
-		 * computation is the same as that for calculating cycles.
-		 */
-		sample_delay_factor =
-			ns_to_cycles(
-				ideal_sample_delay_in_ns << dll_delay_shift,
-							clock_period_in_ns, 0);
-
-		if (sample_delay_factor > nfc->max_sample_delay_factor)
-			sample_delay_factor = nfc->max_sample_delay_factor;
-
-		/* Skip to the part where we return our results. */
-		goto return_results;
-	}
-
-	/*
-	 * If control arrives here, we have more detailed timing information,
-	 * so we can use a better algorithm.
-	 */
-
-	/*
-	 * Fold the read setup time required by the NFC into the maximum
-	 * propagation delay.
-	 */
-	max_prop_delay_in_ns += nfc->internal_data_setup_in_ns;
-
-	/*
-	 * Earlier, we computed the number of clock cycles required to satisfy
-	 * the data setup time. Now, we need to know the actual nanoseconds.
-	 */
-	data_setup_in_ns = clock_period_in_ns * data_setup_in_cycles;
-
-	/*
-	 * Compute tEYE, the width of the data eye when reading from the NAND
-	 * Flash. The eye width is fundamentally determined by the data setup
-	 * time, perturbed by propagation delays and some characteristics of the
-	 * NAND Flash device.
-	 *
-	 * start of the eye = max_prop_delay + tREA
-	 * end of the eye   = min_prop_delay + tRHOH + data_setup
-	 */
-	tEYE = (int)min_prop_delay_in_ns + (int)target.tRHOH_in_ns +
-							(int)data_setup_in_ns;
-
-	tEYE -= (int)max_prop_delay_in_ns + (int)target.tREA_in_ns;
-
-	/*
-	 * The eye must be open. If it's not, we can try to open it by
-	 * increasing its main forcer, the data setup time.
-	 *
-	 * In each iteration of the following loop, we increase the data setup
-	 * time by a single clock cycle. We do this until either the eye is
-	 * open or we run into NFC limits.
-	 */
-	while ((tEYE <= 0) &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-		/* Give a cycle to data setup. */
-		data_setup_in_cycles++;
-		/* Synchronize the data setup time with the cycles. */
-		data_setup_in_ns += clock_period_in_ns;
-		/* Adjust tEYE accordingly. */
-		tEYE += clock_period_in_ns;
-	}
-
-	/*
-	 * When control arrives here, the eye is open. The ideal time to sample
-	 * the data is in the center of the eye:
-	 *
-	 *     end of the eye + start of the eye
-	 *     ---------------------------------  -  data_setup
-	 *                    2
-	 *
-	 * After some algebra, this simplifies to the code immediately below.
-	 */
-	ideal_sample_delay_in_ns =
-		((int)max_prop_delay_in_ns +
-			(int)target.tREA_in_ns +
-				(int)min_prop_delay_in_ns +
-					(int)target.tRHOH_in_ns -
-						(int)data_setup_in_ns) >> 1;
-
-	/*
-	 * The following figure illustrates some aspects of a NAND Flash read:
-	 *
-	 *
-	 *           __                   _____________________________________
-	 * RDN         \_________________/
-	 *
-	 *                                         <---- tEYE ----->
-	 *                                        /-----------------\
-	 * Read Data ----------------------------<                   >---------
-	 *                                        \-----------------/
-	 *             ^                 ^                 ^              ^
-	 *             |                 |                 |              |
-	 *             |<--Data Setup -->|<--Delay Time -->|              |
-	 *             |                 |                 |              |
-	 *             |                 |                                |
-	 *             |                 |<--   Quantized Delay Time   -->|
-	 *             |                 |                                |
-	 *
-	 *
-	 * We have some issues we must now address:
-	 *
-	 * (1) The *ideal* sample delay time must not be negative. If it is, we
-	 *     jam it to zero.
-	 *
-	 * (2) The *ideal* sample delay time must not be greater than that
-	 *     allowed by the NFC. If it is, we can increase the data setup
-	 *     time, which will reduce the delay between the end of the data
-	 *     setup and the center of the eye. It will also make the eye
-	 *     larger, which might help with the next issue...
-	 *
-	 * (3) The *quantized* sample delay time must not fall either before the
-	 *     eye opens or after it closes (the latter is the problem
-	 *     illustrated in the above figure).
-	 */
-
-	/* Jam a negative ideal sample delay to zero. */
-	if (ideal_sample_delay_in_ns < 0)
-		ideal_sample_delay_in_ns = 0;
-
-	/*
-	 * Extend the data setup as needed to reduce the ideal sample delay
-	 * below the maximum permitted by the NFC.
-	 */
-	while ((ideal_sample_delay_in_ns > max_sample_delay_in_ns) &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-
-		/* Give a cycle to data setup. */
-		data_setup_in_cycles++;
-		/* Synchronize the data setup time with the cycles. */
-		data_setup_in_ns += clock_period_in_ns;
-		/* Adjust tEYE accordingly. */
-		tEYE += clock_period_in_ns;
-
-		/*
-		 * Decrease the ideal sample delay by one half cycle, to keep it
-		 * in the middle of the eye.
-		 */
-		ideal_sample_delay_in_ns -= (clock_period_in_ns >> 1);
-
-		/* Jam a negative ideal sample delay to zero. */
-		if (ideal_sample_delay_in_ns < 0)
-			ideal_sample_delay_in_ns = 0;
-	}
-
-	/*
-	 * Compute the sample delay factor that corresponds to the ideal sample
-	 * delay. If the result is too large, then use the maximum allowed
-	 * value.
-	 *
-	 * Notice that we use the ns_to_cycles function to compute the sample
-	 * delay factor. We do this because the form of the computation is the
-	 * same as that for calculating cycles.
-	 */
-	sample_delay_factor =
-		ns_to_cycles(ideal_sample_delay_in_ns << dll_delay_shift,
-							clock_period_in_ns, 0);
-
-	if (sample_delay_factor > nfc->max_sample_delay_factor)
-		sample_delay_factor = nfc->max_sample_delay_factor;
-
-	/*
-	 * These macros conveniently encapsulate a computation we'll use to
-	 * continuously evaluate whether or not the data sample delay is inside
-	 * the eye.
-	 */
-	#define IDEAL_DELAY  ((int) ideal_sample_delay_in_ns)
-
-	#define QUANTIZED_DELAY  \
-		((int) ((sample_delay_factor * clock_period_in_ns) >> \
-							dll_delay_shift))
-
-	#define DELAY_ERROR  (abs(QUANTIZED_DELAY - IDEAL_DELAY))
-
-	#define SAMPLE_IS_NOT_WITHIN_THE_EYE  (DELAY_ERROR > (tEYE >> 1))
-
-	/*
-	 * While the quantized sample time falls outside the eye, reduce the
-	 * sample delay or extend the data setup to move the sampling point back
-	 * toward the eye. Do not allow the number of data setup cycles to
-	 * exceed the maximum allowed by the NFC.
-	 */
-	while (SAMPLE_IS_NOT_WITHIN_THE_EYE &&
-			(data_setup_in_cycles < nfc->max_data_setup_cycles)) {
-		/*
-		 * If control arrives here, the quantized sample delay falls
-		 * outside the eye. Check if it's before the eye opens, or after
-		 * the eye closes.
-		 */
-		if (QUANTIZED_DELAY > IDEAL_DELAY) {
-			/*
-			 * If control arrives here, the quantized sample delay
-			 * falls after the eye closes. Decrease the quantized
-			 * delay time and then go back to re-evaluate.
-			 */
-			if (sample_delay_factor != 0)
-				sample_delay_factor--;
-			continue;
-		}
-
-		/*
-		 * If control arrives here, the quantized sample delay falls
-		 * before the eye opens. Shift the sample point by increasing
-		 * data setup time. This will also make the eye larger.
-		 */
-
-		/* Give a cycle to data setup. */
-		data_setup_in_cycles++;
-		/* Synchronize the data setup time with the cycles. */
-		data_setup_in_ns += clock_period_in_ns;
-		/* Adjust tEYE accordingly. */
-		tEYE += clock_period_in_ns;
-
-		/*
-		 * Decrease the ideal sample delay by one half cycle, to keep it
-		 * in the middle of the eye.
-		 */
-		ideal_sample_delay_in_ns -= (clock_period_in_ns >> 1);
-
-		/* ...and one less period for the delay time. */
-		ideal_sample_delay_in_ns -= clock_period_in_ns;
-
-		/* Jam a negative ideal sample delay to zero. */
-		if (ideal_sample_delay_in_ns < 0)
-			ideal_sample_delay_in_ns = 0;
-
-		/*
-		 * We have a new ideal sample delay, so re-compute the quantized
-		 * delay.
-		 */
-		sample_delay_factor =
-			ns_to_cycles(
-				ideal_sample_delay_in_ns << dll_delay_shift,
-							clock_period_in_ns, 0);
-
-		if (sample_delay_factor > nfc->max_sample_delay_factor)
-			sample_delay_factor = nfc->max_sample_delay_factor;
-	}
-
-	/* Control arrives here when we're ready to return our results. */
-return_results:
-	hw->data_setup_in_cycles    = data_setup_in_cycles;
-	hw->data_hold_in_cycles     = data_hold_in_cycles;
-	hw->address_setup_in_cycles = address_setup_in_cycles;
-	hw->use_half_periods        = dll_use_half_periods;
-	hw->sample_delay_factor     = sample_delay_factor;
-	hw->device_busy_timeout     = GPMI_DEFAULT_BUSY_TIMEOUT;
-	hw->wrn_dly_sel             = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
-
-	/* Return success. */
-	return 0;
-}
-
-/*
- * <1> Firstly, we should know what's the GPMI-clock means.
- *     The GPMI-clock is the internal clock in the gpmi nand controller.
- *     If you set 100MHz to gpmi nand controller, the GPMI-clock's period
- *     is 10ns. Mark the GPMI-clock's period as GPMI-clock-period.
- *
- * <2> Secondly, we should know what's the frequency on the nand chip pins.
- *     The frequency on the nand chip pins is derived from the GPMI-clock.
- *     We can get it from the following equation:
- *
- *         F = G / (DS + DH)
- *
- *         F  : the frequency on the nand chip pins.
- *         G  : the GPMI clock, such as 100MHz.
- *         DS : GPMI_HW_GPMI_TIMING0:DATA_SETUP
- *         DH : GPMI_HW_GPMI_TIMING0:DATA_HOLD
- *
- * <3> Thirdly, when the frequency on the nand chip pins is above 33MHz,
- *     the nand EDO(extended Data Out) timing could be applied.
- *     The GPMI implements a feedback read strobe to sample the read data.
- *     The feedback read strobe can be delayed to support the nand EDO timing
- *     where the read strobe may deasserts before the read data is valid, and
- *     read data is valid for some time after read strobe.
- *
- *     The following figure illustrates some aspects of a NAND Flash read:
- *
- *                   |<---tREA---->|
- *                   |             |
- *                   |         |   |
- *                   |<--tRP-->|   |
- *                   |         |   |
- *                  __          ___|__________________________________
- *     RDN            \________/   |
- *                                 |
- *                                 /---------\
- *     Read Data    --------------<           >---------
- *                                 \---------/
- *                                |     |
- *                                |<-D->|
- *     FeedbackRDN  ________             ____________
- *                          \___________/
- *
- *          D stands for delay, set in the HW_GPMI_CTRL1:RDN_DELAY.
- *
- *
- * <4> Now, we begin to describe how to compute the right RDN_DELAY.
- *
- *  4.1) From the aspect of the nand chip pins:
- *        Delay = (tREA + C - tRP)               {1}
- *
- *        tREA : the maximum read access time. From the ONFI nand standards,
- *               we know that tREA is 16ns in mode 5, tREA is 20ns is mode 4.
- *               Please check it in : www.onfi.org
- *        C    : a constant for adjust the delay. default is 4.
- *        tRP  : the read pulse width.
- *               Specified by the HW_GPMI_TIMING0:DATA_SETUP:
- *                    tRP = (GPMI-clock-period) * DATA_SETUP
- *
- *  4.2) From the aspect of the GPMI nand controller:
- *         Delay = RDN_DELAY * 0.125 * RP        {2}
- *
- *         RP   : the DLL reference period.
- *            if (GPMI-clock-period > DLL_THRETHOLD)
- *                   RP = GPMI-clock-period / 2;
- *            else
- *                   RP = GPMI-clock-period;
- *
- *            Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period
- *            is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD
- *            is 16ns, but in mx6q, we use 12ns.
- *
- *  4.3) since {1} equals {2}, we get:
- *
- *                    (tREA + 4 - tRP) * 8
- *         RDN_DELAY = ---------------------     {3}
- *                           RP
- *
- *  4.4) We only support the fastest asynchronous mode of ONFI nand.
- *       For some ONFI nand, the mode 4 is the fastest mode;
- *       while for some ONFI nand, the mode 5 is the fastest mode.
- *       So we only support the mode 4 and mode 5. It is no need to
- *       support other modes.
- */
-static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
-			struct gpmi_nfc_hardware_timing *hw)
-{
-	struct resources *r = &this->resources;
-	unsigned long rate = clk_get_rate(r->clock[0]);
-	int mode = this->timing_mode;
-	int dll_threshold = this->devdata->max_chain_delay;
-	unsigned long delay;
-	unsigned long clk_period;
-	int t_rea;
-	int c = 4;
-	int t_rp;
-	int rp;
-
-	/*
-	 * [1] for GPMI_HW_GPMI_TIMING0:
-	 *     The async mode requires 40MHz for mode 4, 50MHz for mode 5.
-	 *     The GPMI can support 100MHz at most. So if we want to
-	 *     get the 40MHz or 50MHz, we have to set DS=1, DH=1.
-	 *     Set the ADDRESS_SETUP to 0 in mode 4.
-	 */
-	hw->data_setup_in_cycles = 1;
-	hw->data_hold_in_cycles = 1;
-	hw->address_setup_in_cycles = ((mode == 5) ? 1 : 0);
-
-	/* [2] for GPMI_HW_GPMI_TIMING1 */
-	hw->device_busy_timeout = 0x9000;
-
-	/* [3] for GPMI_HW_GPMI_CTRL1 */
-	hw->wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
-
-	/*
-	 * Enlarge 10 times for the numerator and denominator in {3}.
-	 * This make us to get more accurate result.
-	 */
-	clk_period = NSEC_PER_SEC / (rate / 10);
-	dll_threshold *= 10;
-	t_rea = ((mode == 5) ? 16 : 20) * 10;
-	c *= 10;
-
-	t_rp = clk_period * 1; /* DATA_SETUP is 1 */
-
-	if (clk_period > dll_threshold) {
-		hw->use_half_periods = 1;
-		rp = clk_period / 2;
-	} else {
-		hw->use_half_periods = 0;
-		rp = clk_period;
-	}
-
-	/*
-	 * Multiply the numerator with 10, we could do a round off:
-	 *      7.8 round up to 8; 7.4 round down to 7.
-	 */
-	delay  = (((t_rea + c - t_rp) * 8) * 10) / rp;
-	delay = (delay + 5) / 10;
-
-	hw->sample_delay_factor = delay;
-}
-
-static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
-{
-	struct resources  *r = &this->resources;
-	struct nand_chip *nand = &this->nand;
-	struct mtd_info	 *mtd = nand_to_mtd(nand);
-	uint8_t *feature;
-	unsigned long rate;
-	int ret;
-
-	feature = kzalloc(ONFI_SUBFEATURE_PARAM_LEN, GFP_KERNEL);
-	if (!feature)
-		return -ENOMEM;
-
-	nand->select_chip(mtd, 0);
-
-	/* [1] send SET FEATURE command to NAND */
-	feature[0] = mode;
-	ret = nand->onfi_set_features(mtd, nand,
-				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
-	if (ret)
-		goto err_out;
-
-	/* [2] send GET FEATURE command to double-check the timing mode */
-	memset(feature, 0, ONFI_SUBFEATURE_PARAM_LEN);
-	ret = nand->onfi_get_features(mtd, nand,
-				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
-	if (ret || feature[0] != mode)
-		goto err_out;
-
-	nand->select_chip(mtd, -1);
-
-	/* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
-	rate = (mode == 5) ? 100000000 : 80000000;
-	clk_set_rate(r->clock[0], rate);
-
-	/* Let the gpmi_begin() re-compute the timing again. */
-	this->flags &= ~GPMI_TIMING_INIT_OK;
-
-	this->flags |= GPMI_ASYNC_EDO_ENABLED;
-	this->timing_mode = mode;
-	kfree(feature);
-	dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
-	return 0;
-
-err_out:
-	nand->select_chip(mtd, -1);
-	kfree(feature);
-	dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
-	return -EINVAL;
-}
-
-int gpmi_extra_init(struct gpmi_nand_data *this)
-{
-	struct nand_chip *chip = &this->nand;
-
-	/* Enable the asynchronous EDO feature. */
-	if (GPMI_IS_MX6(this) && chip->onfi_version) {
-		int mode = onfi_get_async_timing_mode(chip);
-
-		/* We only support the timing mode 4 and mode 5. */
-		if (mode & ONFI_TIMING_MODE_5)
-			mode = 5;
-		else if (mode & ONFI_TIMING_MODE_4)
-			mode = 4;
-		else
-			return 0;
-
-		return enable_edo_mode(this, mode);
-	}
-	return 0;
-}
-
-/* Begin the I/O */
-void gpmi_begin(struct gpmi_nand_data *this)
-{
-	struct resources *r = &this->resources;
-	void __iomem *gpmi_regs = r->gpmi_regs;
-	unsigned int   clock_period_in_ns;
-	uint32_t       reg;
-	unsigned int   dll_wait_time_in_us;
-	struct gpmi_nfc_hardware_timing  hw;
-	int ret;
-
-	/* Enable the clock. */
-	ret = gpmi_enable_clk(this);
-	if (ret) {
-		dev_err(this->dev, "We failed in enable the clk\n");
-		goto err_out;
-	}
-
-	/* Only initialize the timing once */
-	if (this->flags & GPMI_TIMING_INIT_OK)
-		return;
-	this->flags |= GPMI_TIMING_INIT_OK;
-
-	if (this->flags & GPMI_ASYNC_EDO_ENABLED)
-		gpmi_compute_edo_timing(this, &hw);
-	else
-		gpmi_nfc_compute_hardware_timing(this, &hw);
-
-	/* [1] Set HW_GPMI_TIMING0 */
-	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
-		BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles)         |
-		BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles);
-
-	writel(reg, gpmi_regs + HW_GPMI_TIMING0);
-
-	/* [2] Set HW_GPMI_TIMING1 */
-	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw.device_busy_timeout),
-		gpmi_regs + HW_GPMI_TIMING1);
-
-	/* [3] The following code is to set the HW_GPMI_CTRL1. */
-
-	/* Set the WRN_DLY_SEL */
-	writel(BM_GPMI_CTRL1_WRN_DLY_SEL, gpmi_regs + HW_GPMI_CTRL1_CLR);
-	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw.wrn_dly_sel),
-					gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	/* DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD. */
-	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
-
-	/* Clear out the DLL control fields. */
-	reg = BM_GPMI_CTRL1_RDN_DELAY | BM_GPMI_CTRL1_HALF_PERIOD;
-	writel(reg, gpmi_regs + HW_GPMI_CTRL1_CLR);
-
-	/* If no sample delay is called for, return immediately. */
-	if (!hw.sample_delay_factor)
-		return;
-
-	/* Set RDN_DELAY or HALF_PERIOD. */
-	reg = ((hw.use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
-		| BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor);
-
-	writel(reg, gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	/* At last, we enable the DLL. */
-	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_SET);
-
-	/*
-	 * After we enable the GPMI DLL, we have to wait 64 clock cycles before
-	 * we can use the GPMI. Calculate the amount of time we need to wait,
-	 * in microseconds.
-	 */
-	clock_period_in_ns = NSEC_PER_SEC / clk_get_rate(r->clock[0]);
-	dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
-
-	if (!dll_wait_time_in_us)
-		dll_wait_time_in_us = 1;
-
-	/* Wait for the DLL to settle. */
-	udelay(dll_wait_time_in_us);
-
-err_out:
-	return;
-}
-
-void gpmi_end(struct gpmi_nand_data *this)
-{
-	gpmi_disable_clk(this);
-}
-
-/* Clears a BCH interrupt. */
-void gpmi_clear_bch(struct gpmi_nand_data *this)
-{
-	struct resources *r = &this->resources;
-	writel(BM_BCH_CTRL_COMPLETE_IRQ, r->bch_regs + HW_BCH_CTRL_CLR);
-}
-
-/* Returns the Ready/Busy status of the given chip. */
-int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
-{
-	struct resources *r = &this->resources;
-	uint32_t mask = 0;
-	uint32_t reg = 0;
-
-	if (GPMI_IS_MX23(this)) {
-		mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
-		reg = readl(r->gpmi_regs + HW_GPMI_DEBUG);
-	} else if (GPMI_IS_MX28(this) || GPMI_IS_MX6(this)) {
-		/*
-		 * In the imx6, all the ready/busy pins are bound
-		 * together. So we only need to check chip 0.
-		 */
-		if (GPMI_IS_MX6(this))
-			chip = 0;
-
-		/* MX28 shares the same R/B register as MX6Q. */
-		mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip);
-		reg = readl(r->gpmi_regs + HW_GPMI_STAT);
-	} else
-		dev_err(this->dev, "unknown arch.\n");
-	return reg & mask;
-}
-
-static inline void set_dma_type(struct gpmi_nand_data *this,
-					enum dma_ops_type type)
-{
-	this->last_dma_type = this->dma_type;
-	this->dma_type = type;
-}
-
-int gpmi_send_command(struct gpmi_nand_data *this)
-{
-	struct dma_chan *channel = get_dma_chan(this);
-	struct dma_async_tx_descriptor *desc;
-	struct scatterlist *sgl;
-	int chip = this->current_chip;
-	u32 pio[3];
-
-	/* [1] send out the PIO words */
-	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__WRITE)
-		| BM_GPMI_CTRL0_WORD_LENGTH
-		| BF_GPMI_CTRL0_CS(chip, this)
-		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
-		| BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_CLE)
-		| BM_GPMI_CTRL0_ADDRESS_INCREMENT
-		| BF_GPMI_CTRL0_XFER_COUNT(this->command_length);
-	pio[1] = pio[2] = 0;
-	desc = dmaengine_prep_slave_sg(channel,
-					(struct scatterlist *)pio,
-					ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
-	if (!desc)
-		return -EINVAL;
-
-	/* [2] send out the COMMAND + ADDRESS string stored in @buffer */
-	sgl = &this->cmd_sgl;
-
-	sg_init_one(sgl, this->cmd_buffer, this->command_length);
-	dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE);
-	desc = dmaengine_prep_slave_sg(channel,
-				sgl, 1, DMA_MEM_TO_DEV,
-				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-	if (!desc)
-		return -EINVAL;
-
-	/* [3] submit the DMA */
-	set_dma_type(this, DMA_FOR_COMMAND);
-	return start_dma_without_bch_irq(this, desc);
-}
-
-int gpmi_send_data(struct gpmi_nand_data *this)
-{
-	struct dma_async_tx_descriptor *desc;
-	struct dma_chan *channel = get_dma_chan(this);
-	int chip = this->current_chip;
-	uint32_t command_mode;
-	uint32_t address;
-	u32 pio[2];
-
-	/* [1] PIO */
-	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WRITE;
-	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
-
-	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
-		| BM_GPMI_CTRL0_WORD_LENGTH
-		| BF_GPMI_CTRL0_CS(chip, this)
-		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
-		| BF_GPMI_CTRL0_ADDRESS(address)
-		| BF_GPMI_CTRL0_XFER_COUNT(this->upper_len);
-	pio[1] = 0;
-	desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
-					ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
-	if (!desc)
-		return -EINVAL;
-
-	/* [2] send DMA request */
-	prepare_data_dma(this, DMA_TO_DEVICE);
-	desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
-					1, DMA_MEM_TO_DEV,
-					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-	if (!desc)
-		return -EINVAL;
-
-	/* [3] submit the DMA */
-	set_dma_type(this, DMA_FOR_WRITE_DATA);
-	return start_dma_without_bch_irq(this, desc);
-}
-
-int gpmi_read_data(struct gpmi_nand_data *this)
-{
-	struct dma_async_tx_descriptor *desc;
-	struct dma_chan *channel = get_dma_chan(this);
-	int chip = this->current_chip;
-	u32 pio[2];
-
-	/* [1] : send PIO */
-	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__READ)
-		| BM_GPMI_CTRL0_WORD_LENGTH
-		| BF_GPMI_CTRL0_CS(chip, this)
-		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
-		| BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA)
-		| BF_GPMI_CTRL0_XFER_COUNT(this->upper_len);
-	pio[1] = 0;
-	desc = dmaengine_prep_slave_sg(channel,
-					(struct scatterlist *)pio,
-					ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
-	if (!desc)
-		return -EINVAL;
-
-	/* [2] : send DMA request */
-	prepare_data_dma(this, DMA_FROM_DEVICE);
-	desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
-					1, DMA_DEV_TO_MEM,
-					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-	if (!desc)
-		return -EINVAL;
-
-	/* [3] : submit the DMA */
-	set_dma_type(this, DMA_FOR_READ_DATA);
-	return start_dma_without_bch_irq(this, desc);
-}
-
-int gpmi_send_page(struct gpmi_nand_data *this,
-			dma_addr_t payload, dma_addr_t auxiliary)
-{
-	struct bch_geometry *geo = &this->bch_geometry;
-	uint32_t command_mode;
-	uint32_t address;
-	uint32_t ecc_command;
-	uint32_t buffer_mask;
-	struct dma_async_tx_descriptor *desc;
-	struct dma_chan *channel = get_dma_chan(this);
-	int chip = this->current_chip;
-	u32 pio[6];
-
-	/* A DMA descriptor that does an ECC page read. */
-	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WRITE;
-	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
-	ecc_command  = BV_GPMI_ECCCTRL_ECC_CMD__BCH_ENCODE;
-	buffer_mask  = BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE |
-				BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY;
-
-	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
-		| BM_GPMI_CTRL0_WORD_LENGTH
-		| BF_GPMI_CTRL0_CS(chip, this)
-		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
-		| BF_GPMI_CTRL0_ADDRESS(address)
-		| BF_GPMI_CTRL0_XFER_COUNT(0);
-	pio[1] = 0;
-	pio[2] = BM_GPMI_ECCCTRL_ENABLE_ECC
-		| BF_GPMI_ECCCTRL_ECC_CMD(ecc_command)
-		| BF_GPMI_ECCCTRL_BUFFER_MASK(buffer_mask);
-	pio[3] = geo->page_size;
-	pio[4] = payload;
-	pio[5] = auxiliary;
-
-	desc = dmaengine_prep_slave_sg(channel,
-					(struct scatterlist *)pio,
-					ARRAY_SIZE(pio), DMA_TRANS_NONE,
-					DMA_CTRL_ACK);
-	if (!desc)
-		return -EINVAL;
-
-	set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE);
-	return start_dma_with_bch_irq(this, desc);
-}
-
-int gpmi_read_page(struct gpmi_nand_data *this,
-				dma_addr_t payload, dma_addr_t auxiliary)
-{
-	struct bch_geometry *geo = &this->bch_geometry;
-	uint32_t command_mode;
-	uint32_t address;
-	uint32_t ecc_command;
-	uint32_t buffer_mask;
-	struct dma_async_tx_descriptor *desc;
-	struct dma_chan *channel = get_dma_chan(this);
-	int chip = this->current_chip;
-	u32 pio[6];
-
-	/* [1] Wait for the chip to report ready. */
-	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY;
-	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
-
-	pio[0] =  BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
-		| BM_GPMI_CTRL0_WORD_LENGTH
-		| BF_GPMI_CTRL0_CS(chip, this)
-		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
-		| BF_GPMI_CTRL0_ADDRESS(address)
-		| BF_GPMI_CTRL0_XFER_COUNT(0);
-	pio[1] = 0;
-	desc = dmaengine_prep_slave_sg(channel,
-				(struct scatterlist *)pio, 2,
-				DMA_TRANS_NONE, 0);
-	if (!desc)
-		return -EINVAL;
-
-	/* [2] Enable the BCH block and read. */
-	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__READ;
-	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
-	ecc_command  = BV_GPMI_ECCCTRL_ECC_CMD__BCH_DECODE;
-	buffer_mask  = BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE
-			| BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY;
-
-	pio[0] =  BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
-		| BM_GPMI_CTRL0_WORD_LENGTH
-		| BF_GPMI_CTRL0_CS(chip, this)
-		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
-		| BF_GPMI_CTRL0_ADDRESS(address)
-		| BF_GPMI_CTRL0_XFER_COUNT(geo->page_size);
-
-	pio[1] = 0;
-	pio[2] =  BM_GPMI_ECCCTRL_ENABLE_ECC
-		| BF_GPMI_ECCCTRL_ECC_CMD(ecc_command)
-		| BF_GPMI_ECCCTRL_BUFFER_MASK(buffer_mask);
-	pio[3] = geo->page_size;
-	pio[4] = payload;
-	pio[5] = auxiliary;
-	desc = dmaengine_prep_slave_sg(channel,
-					(struct scatterlist *)pio,
-					ARRAY_SIZE(pio), DMA_TRANS_NONE,
-					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-	if (!desc)
-		return -EINVAL;
-
-	/* [3] Disable the BCH block */
-	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY;
-	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
-
-	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
-		| BM_GPMI_CTRL0_WORD_LENGTH
-		| BF_GPMI_CTRL0_CS(chip, this)
-		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
-		| BF_GPMI_CTRL0_ADDRESS(address)
-		| BF_GPMI_CTRL0_XFER_COUNT(geo->page_size);
-	pio[1] = 0;
-	pio[2] = 0; /* clear GPMI_HW_GPMI_ECCCTRL, disable the BCH. */
-	desc = dmaengine_prep_slave_sg(channel,
-				(struct scatterlist *)pio, 3,
-				DMA_TRANS_NONE,
-				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-	if (!desc)
-		return -EINVAL;
-
-	/* [4] submit the DMA */
-	set_dma_type(this, DMA_FOR_READ_ECC_PAGE);
-	return start_dma_with_bch_irq(this, desc);
-}
-
-/**
- * gpmi_copy_bits - copy bits from one memory region to another
- * @dst: destination buffer
- * @dst_bit_off: bit offset we're starting to write at
- * @src: source buffer
- * @src_bit_off: bit offset we're starting to read from
- * @nbits: number of bits to copy
- *
- * This functions copies bits from one memory region to another, and is used by
- * the GPMI driver to copy ECC sections which are not guaranteed to be byte
- * aligned.
- *
- * src and dst should not overlap.
- *
- */
-void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
-		    const u8 *src, size_t src_bit_off,
-		    size_t nbits)
-{
-	size_t i;
-	size_t nbytes;
-	u32 src_buffer = 0;
-	size_t bits_in_src_buffer = 0;
-
-	if (!nbits)
-		return;
-
-	/*
-	 * Move src and dst pointers to the closest byte pointer and store bit
-	 * offsets within a byte.
-	 */
-	src += src_bit_off / 8;
-	src_bit_off %= 8;
-
-	dst += dst_bit_off / 8;
-	dst_bit_off %= 8;
-
-	/*
-	 * Initialize the src_buffer value with bits available in the first
-	 * byte of data so that we end up with a byte aligned src pointer.
-	 */
-	if (src_bit_off) {
-		src_buffer = src[0] >> src_bit_off;
-		if (nbits >= (8 - src_bit_off)) {
-			bits_in_src_buffer += 8 - src_bit_off;
-		} else {
-			src_buffer &= GENMASK(nbits - 1, 0);
-			bits_in_src_buffer += nbits;
-		}
-		nbits -= bits_in_src_buffer;
-		src++;
-	}
-
-	/* Calculate the number of bytes that can be copied from src to dst. */
-	nbytes = nbits / 8;
-
-	/* Try to align dst to a byte boundary. */
-	if (dst_bit_off) {
-		if (bits_in_src_buffer < (8 - dst_bit_off) && nbytes) {
-			src_buffer |= src[0] << bits_in_src_buffer;
-			bits_in_src_buffer += 8;
-			src++;
-			nbytes--;
-		}
-
-		if (bits_in_src_buffer >= (8 - dst_bit_off)) {
-			dst[0] &= GENMASK(dst_bit_off - 1, 0);
-			dst[0] |= src_buffer << dst_bit_off;
-			src_buffer >>= (8 - dst_bit_off);
-			bits_in_src_buffer -= (8 - dst_bit_off);
-			dst_bit_off = 0;
-			dst++;
-			if (bits_in_src_buffer > 7) {
-				bits_in_src_buffer -= 8;
-				dst[0] = src_buffer;
-				dst++;
-				src_buffer >>= 8;
-			}
-		}
-	}
-
-	if (!bits_in_src_buffer && !dst_bit_off) {
-		/*
-		 * Both src and dst pointers are byte aligned, thus we can
-		 * just use the optimized memcpy function.
-		 */
-		if (nbytes)
-			memcpy(dst, src, nbytes);
-	} else {
-		/*
-		 * src buffer is not byte aligned, hence we have to copy each
-		 * src byte to the src_buffer variable before extracting a byte
-		 * to store in dst.
-		 */
-		for (i = 0; i < nbytes; i++) {
-			src_buffer |= src[i] << bits_in_src_buffer;
-			dst[i] = src_buffer;
-			src_buffer >>= 8;
-		}
-	}
-	/* Update dst and src pointers */
-	dst += nbytes;
-	src += nbytes;
-
-	/*
-	 * nbits is the number of remaining bits. It should not exceed 8 as
-	 * we've already copied as much bytes as possible.
-	 */
-	nbits %= 8;
-
-	/*
-	 * If there's no more bits to copy to the destination and src buffer
-	 * was already byte aligned, then we're done.
-	 */
-	if (!nbits && !bits_in_src_buffer)
-		return;
-
-	/* Copy the remaining bits to src_buffer */
-	if (nbits)
-		src_buffer |= (*src & GENMASK(nbits - 1, 0)) <<
-			      bits_in_src_buffer;
-	bits_in_src_buffer += nbits;
-
-	/*
-	 * In case there were not enough bits to get a byte aligned dst buffer
-	 * prepare the src_buffer variable to match the dst organization (shift
-	 * src_buffer by dst_bit_off and retrieve the least significant bits
-	 * from dst).
-	 */
-	if (dst_bit_off)
-		src_buffer = (src_buffer << dst_bit_off) |
-			     (*dst & GENMASK(dst_bit_off - 1, 0));
-	bits_in_src_buffer += dst_bit_off;
-
-	/*
-	 * Keep most significant bits from dst if we end up with an unaligned
-	 * number of bits.
-	 */
-	nbytes = bits_in_src_buffer / 8;
-	if (bits_in_src_buffer % 8) {
-		src_buffer |= (dst[nbytes] &
-			       GENMASK(7, bits_in_src_buffer % 8)) <<
-			      (nbytes * 8);
-		nbytes++;
-	}
-
-	/* Copy the remaining bytes to dst */
-	for (i = 0; i < nbytes; i++) {
-		dst[i] = src_buffer;
-		src_buffer >>= 8;
-	}
-}
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
deleted file mode 100644
index 06c1f99..0000000
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Freescale GPMI NAND Flash Driver
- *
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
- * Copyright (C) 2008 Embedded Alley Solutions, 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.
- */
-#ifndef __DRIVERS_MTD_NAND_GPMI_NAND_H
-#define __DRIVERS_MTD_NAND_GPMI_NAND_H
-
-#include <linux/mtd/rawnand.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/dmaengine.h>
-
-#define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */
-struct resources {
-	void __iomem  *gpmi_regs;
-	void __iomem  *bch_regs;
-	unsigned int  dma_low_channel;
-	unsigned int  dma_high_channel;
-	struct clk    *clock[GPMI_CLK_MAX];
-};
-
-/**
- * struct bch_geometry - BCH geometry description.
- * @gf_len:                   The length of Galois Field. (e.g., 13 or 14)
- * @ecc_strength:             A number that describes the strength of the ECC
- *                            algorithm.
- * @page_size:                The size, in bytes, of a physical page, including
- *                            both data and OOB.
- * @metadata_size:            The size, in bytes, of the metadata.
- * @ecc_chunk_size:           The size, in bytes, of a single ECC chunk. Note
- *                            the first chunk in the page includes both data and
- *                            metadata, so it's a bit larger than this value.
- * @ecc_chunk_count:          The number of ECC chunks in the page,
- * @payload_size:             The size, in bytes, of the payload buffer.
- * @auxiliary_size:           The size, in bytes, of the auxiliary buffer.
- * @auxiliary_status_offset:  The offset into the auxiliary buffer at which
- *                            the ECC status appears.
- * @block_mark_byte_offset:   The byte offset in the ECC-based page view at
- *                            which the underlying physical block mark appears.
- * @block_mark_bit_offset:    The bit offset into the ECC-based page view at
- *                            which the underlying physical block mark appears.
- */
-struct bch_geometry {
-	unsigned int  gf_len;
-	unsigned int  ecc_strength;
-	unsigned int  page_size;
-	unsigned int  metadata_size;
-	unsigned int  ecc_chunk_size;
-	unsigned int  ecc_chunk_count;
-	unsigned int  payload_size;
-	unsigned int  auxiliary_size;
-	unsigned int  auxiliary_status_offset;
-	unsigned int  block_mark_byte_offset;
-	unsigned int  block_mark_bit_offset;
-};
-
-/**
- * struct boot_rom_geometry - Boot ROM geometry description.
- * @stride_size_in_pages:        The size of a boot block stride, in pages.
- * @search_area_stride_exponent: The logarithm to base 2 of the size of a
- *                               search area in boot block strides.
- */
-struct boot_rom_geometry {
-	unsigned int  stride_size_in_pages;
-	unsigned int  search_area_stride_exponent;
-};
-
-/* DMA operations types */
-enum dma_ops_type {
-	DMA_FOR_COMMAND = 1,
-	DMA_FOR_READ_DATA,
-	DMA_FOR_WRITE_DATA,
-	DMA_FOR_READ_ECC_PAGE,
-	DMA_FOR_WRITE_ECC_PAGE
-};
-
-/**
- * struct nand_timing - Fundamental timing attributes for NAND.
- * @data_setup_in_ns:         The data setup time, in nanoseconds. Usually the
- *                            maximum of tDS and tWP. A negative value
- *                            indicates this characteristic isn't known.
- * @data_hold_in_ns:          The data hold time, in nanoseconds. Usually the
- *                            maximum of tDH, tWH and tREH. A negative value
- *                            indicates this characteristic isn't known.
- * @address_setup_in_ns:      The address setup time, in nanoseconds. Usually
- *                            the maximum of tCLS, tCS and tALS. A negative
- *                            value indicates this characteristic isn't known.
- * @gpmi_sample_delay_in_ns:  A GPMI-specific timing parameter. A negative value
- *                            indicates this characteristic isn't known.
- * @tREA_in_ns:               tREA, in nanoseconds, from the data sheet. A
- *                            negative value indicates this characteristic isn't
- *                            known.
- * @tRLOH_in_ns:              tRLOH, in nanoseconds, from the data sheet. A
- *                            negative value indicates this characteristic isn't
- *                            known.
- * @tRHOH_in_ns:              tRHOH, in nanoseconds, from the data sheet. A
- *                            negative value indicates this characteristic isn't
- *                            known.
- */
-struct nand_timing {
-	int8_t  data_setup_in_ns;
-	int8_t  data_hold_in_ns;
-	int8_t  address_setup_in_ns;
-	int8_t  gpmi_sample_delay_in_ns;
-	int8_t  tREA_in_ns;
-	int8_t  tRLOH_in_ns;
-	int8_t  tRHOH_in_ns;
-};
-
-enum gpmi_type {
-	IS_MX23,
-	IS_MX28,
-	IS_MX6Q,
-	IS_MX6SX,
-	IS_MX7D,
-};
-
-struct gpmi_devdata {
-	enum gpmi_type type;
-	int bch_max_ecc_strength;
-	int max_chain_delay; /* See the async EDO mode */
-	const char * const *clks;
-	const int clks_count;
-};
-
-struct gpmi_nand_data {
-	/* flags */
-#define GPMI_ASYNC_EDO_ENABLED	(1 << 0)
-#define GPMI_TIMING_INIT_OK	(1 << 1)
-	int			flags;
-	const struct gpmi_devdata *devdata;
-
-	/* System Interface */
-	struct device		*dev;
-	struct platform_device	*pdev;
-
-	/* Resources */
-	struct resources	resources;
-
-	/* Flash Hardware */
-	struct nand_timing	timing;
-	int			timing_mode;
-
-	/* BCH */
-	struct bch_geometry	bch_geometry;
-	struct completion	bch_done;
-
-	/* NAND Boot issue */
-	bool			swap_block_mark;
-	struct boot_rom_geometry rom_geometry;
-
-	/* MTD / NAND */
-	struct nand_chip	nand;
-
-	/* General-use Variables */
-	int			current_chip;
-	unsigned int		command_length;
-
-	/* passed from upper layer */
-	uint8_t			*upper_buf;
-	int			upper_len;
-
-	/* for DMA operations */
-	bool			direct_dma_map_ok;
-
-	struct scatterlist	cmd_sgl;
-	char			*cmd_buffer;
-
-	struct scatterlist	data_sgl;
-	char			*data_buffer_dma;
-
-	void			*page_buffer_virt;
-	dma_addr_t		page_buffer_phys;
-	unsigned int		page_buffer_size;
-
-	void			*payload_virt;
-	dma_addr_t		payload_phys;
-
-	void			*auxiliary_virt;
-	dma_addr_t		auxiliary_phys;
-
-	void			*raw_buffer;
-
-	/* DMA channels */
-#define DMA_CHANS		8
-	struct dma_chan		*dma_chans[DMA_CHANS];
-	enum dma_ops_type	last_dma_type;
-	enum dma_ops_type	dma_type;
-	struct completion	dma_done;
-
-	/* private */
-	void			*private;
-};
-
-/**
- * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
- * @data_setup_in_cycles:      The data setup time, in cycles.
- * @data_hold_in_cycles:       The data hold time, in cycles.
- * @address_setup_in_cycles:   The address setup time, in cycles.
- * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
- *                             this value is the number of cycles multiplied
- *                             by 4096.
- * @use_half_periods:          Indicates the clock is running slowly, so the
- *                             NFC DLL should use half-periods.
- * @sample_delay_factor:       The sample delay factor.
- * @wrn_dly_sel:               The delay on the GPMI write strobe.
- */
-struct gpmi_nfc_hardware_timing {
-	/* for HW_GPMI_TIMING0 */
-	uint8_t  data_setup_in_cycles;
-	uint8_t  data_hold_in_cycles;
-	uint8_t  address_setup_in_cycles;
-
-	/* for HW_GPMI_TIMING1 */
-	uint16_t device_busy_timeout;
-#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
-
-	/* for HW_GPMI_CTRL1 */
-	bool     use_half_periods;
-	uint8_t  sample_delay_factor;
-	uint8_t  wrn_dly_sel;
-};
-
-/**
- * struct timing_threshold - Timing threshold
- * @max_data_setup_cycles:       The maximum number of data setup cycles that
- *                               can be expressed in the hardware.
- * @internal_data_setup_in_ns:   The time, in ns, that the NFC hardware requires
- *                               for data read internal setup. In the Reference
- *                               Manual, see the chapter "High-Speed NAND
- *                               Timing" for more details.
- * @max_sample_delay_factor:     The maximum sample delay factor that can be
- *                               expressed in the hardware.
- * @max_dll_clock_period_in_ns:  The maximum period of the GPMI clock that the
- *                               sample delay DLL hardware can possibly work
- *                               with (the DLL is unusable with longer periods).
- *                               If the full-cycle period is greater than HALF
- *                               this value, the DLL must be configured to use
- *                               half-periods.
- * @max_dll_delay_in_ns:         The maximum amount of delay, in ns, that the
- *                               DLL can implement.
- * @clock_frequency_in_hz:       The clock frequency, in Hz, during the current
- *                               I/O transaction. If no I/O transaction is in
- *                               progress, this is the clock frequency during
- *                               the most recent I/O transaction.
- */
-struct timing_threshold {
-	const unsigned int      max_chip_count;
-	const unsigned int      max_data_setup_cycles;
-	const unsigned int      internal_data_setup_in_ns;
-	const unsigned int      max_sample_delay_factor;
-	const unsigned int      max_dll_clock_period_in_ns;
-	const unsigned int      max_dll_delay_in_ns;
-	unsigned long           clock_frequency_in_hz;
-
-};
-
-/* Common Services */
-int common_nfc_set_geometry(struct gpmi_nand_data *);
-struct dma_chan *get_dma_chan(struct gpmi_nand_data *);
-void prepare_data_dma(struct gpmi_nand_data *,
-		      enum dma_data_direction dr);
-int start_dma_without_bch_irq(struct gpmi_nand_data *,
-			      struct dma_async_tx_descriptor *);
-int start_dma_with_bch_irq(struct gpmi_nand_data *,
-			   struct dma_async_tx_descriptor *);
-
-/* GPMI-NAND helper function library */
-int gpmi_init(struct gpmi_nand_data *);
-int gpmi_extra_init(struct gpmi_nand_data *);
-void gpmi_clear_bch(struct gpmi_nand_data *);
-void gpmi_dump_info(struct gpmi_nand_data *);
-int bch_set_geometry(struct gpmi_nand_data *);
-int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip);
-int gpmi_send_command(struct gpmi_nand_data *);
-void gpmi_begin(struct gpmi_nand_data *);
-void gpmi_end(struct gpmi_nand_data *);
-int gpmi_read_data(struct gpmi_nand_data *);
-int gpmi_send_data(struct gpmi_nand_data *);
-int gpmi_send_page(struct gpmi_nand_data *,
-		   dma_addr_t payload, dma_addr_t auxiliary);
-int gpmi_read_page(struct gpmi_nand_data *,
-		   dma_addr_t payload, dma_addr_t auxiliary);
-
-void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
-		    const u8 *src, size_t src_bit_off,
-		    size_t nbits);
-
-/* BCH : Status Block Completion Codes */
-#define STATUS_GOOD		0x00
-#define STATUS_ERASED		0xff
-#define STATUS_UNCORRECTABLE	0xfe
-
-/* Use the devdata to distinguish different Archs. */
-#define GPMI_IS_MX23(x)		((x)->devdata->type == IS_MX23)
-#define GPMI_IS_MX28(x)		((x)->devdata->type == IS_MX28)
-#define GPMI_IS_MX6Q(x)		((x)->devdata->type == IS_MX6Q)
-#define GPMI_IS_MX6SX(x)	((x)->devdata->type == IS_MX6SX)
-#define GPMI_IS_MX7D(x)		((x)->devdata->type == IS_MX7D)
-
-#define GPMI_IS_MX6(x)		(GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) || \
-				 GPMI_IS_MX7D(x))
-#endif
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/nand/onenand/Kconfig
similarity index 100%
rename from drivers/mtd/onenand/Kconfig
rename to drivers/mtd/nand/onenand/Kconfig
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/nand/onenand/Makefile
similarity index 100%
rename from drivers/mtd/onenand/Makefile
rename to drivers/mtd/nand/onenand/Makefile
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/nand/onenand/generic.c
similarity index 98%
rename from drivers/mtd/onenand/generic.c
rename to drivers/mtd/nand/onenand/generic.c
index 125da34..d5ccaf9 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/nand/onenand/generic.c
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/mtd/onenand/generic.c
- *
  *  Copyright (c) 2005 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/nand/onenand/omap2.c
similarity index 99%
rename from drivers/mtd/onenand/omap2.c
rename to drivers/mtd/nand/onenand/omap2.c
index 87c34f6..9c159f0 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/nand/onenand/omap2.c
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/mtd/onenand/omap2.c
- *
  *  OneNAND driver for OMAP2 / OMAP3
  *
  *  Copyright © 2005-2006 Nokia Corporation
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/nand/onenand/onenand_base.c
similarity index 99%
rename from drivers/mtd/onenand/onenand_base.c
rename to drivers/mtd/nand/onenand/onenand_base.c
index 979f403..b710519 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/nand/onenand/onenand_base.c
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/mtd/onenand/onenand_base.c
- *
  *  Copyright © 2005-2009 Samsung Electronics
  *  Copyright © 2007 Nokia Corporation
  *
@@ -2143,7 +2141,6 @@ static int onenand_multiblock_erase_verify(struct mtd_info *mtd,
 		if (ret) {
 			printk(KERN_ERR "%s: Failed verify, block %d\n",
 			       __func__, onenand_block(this, addr));
-			instr->state = MTD_ERASE_FAILED;
 			instr->fail_addr = addr;
 			return -1;
 		}
@@ -2172,8 +2169,6 @@ static int onenand_multiblock_erase(struct mtd_info *mtd,
 	int ret = 0;
 	int bdry_block = 0;
 
-	instr->state = MTD_ERASING;
-
 	if (ONENAND_IS_DDP(this)) {
 		loff_t bdry_addr = this->chipsize >> 1;
 		if (addr < bdry_addr && (addr + len) > bdry_addr)
@@ -2187,7 +2182,6 @@ static int onenand_multiblock_erase(struct mtd_info *mtd,
 			printk(KERN_WARNING "%s: attempt to erase a bad block "
 			       "at addr 0x%012llx\n",
 			       __func__, (unsigned long long) addr);
-			instr->state = MTD_ERASE_FAILED;
 			return -EIO;
 		}
 		len -= block_size;
@@ -2227,7 +2221,6 @@ static int onenand_multiblock_erase(struct mtd_info *mtd,
 				printk(KERN_ERR "%s: Failed multiblock erase, "
 				       "block %d\n", __func__,
 				       onenand_block(this, addr));
-				instr->state = MTD_ERASE_FAILED;
 				instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
 				return -EIO;
 			}
@@ -2247,7 +2240,6 @@ static int onenand_multiblock_erase(struct mtd_info *mtd,
 		if (ret) {
 			printk(KERN_ERR "%s: Failed erase, block %d\n",
 			       __func__, onenand_block(this, addr));
-			instr->state = MTD_ERASE_FAILED;
 			instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
 			return -EIO;
 		}
@@ -2259,7 +2251,6 @@ static int onenand_multiblock_erase(struct mtd_info *mtd,
 		/* verify */
 		verify_instr.len = eb_count * block_size;
 		if (onenand_multiblock_erase_verify(mtd, &verify_instr)) {
-			instr->state = verify_instr.state;
 			instr->fail_addr = verify_instr.fail_addr;
 			return -EIO;
 		}
@@ -2294,8 +2285,6 @@ static int onenand_block_by_block_erase(struct mtd_info *mtd,
 		region_end = region->offset + region->erasesize * region->numblocks;
 	}
 
-	instr->state = MTD_ERASING;
-
 	/* Loop through the blocks */
 	while (len) {
 		cond_resched();
@@ -2305,7 +2294,6 @@ static int onenand_block_by_block_erase(struct mtd_info *mtd,
 			printk(KERN_WARNING "%s: attempt to erase a bad block "
 					"at addr 0x%012llx\n",
 					__func__, (unsigned long long) addr);
-			instr->state = MTD_ERASE_FAILED;
 			return -EIO;
 		}
 
@@ -2318,7 +2306,6 @@ static int onenand_block_by_block_erase(struct mtd_info *mtd,
 		if (ret) {
 			printk(KERN_ERR "%s: Failed erase, block %d\n",
 				__func__, onenand_block(this, addr));
-			instr->state = MTD_ERASE_FAILED;
 			instr->fail_addr = addr;
 			return -EIO;
 		}
@@ -2407,12 +2394,6 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
 	/* Deselect and wake up anyone waiting on the device */
 	onenand_release_device(mtd);
 
-	/* Do call back function */
-	if (!ret) {
-		instr->state = MTD_ERASE_DONE;
-		mtd_erase_callback(instr);
-	}
-
 	return ret;
 }
 
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/nand/onenand/onenand_bbt.c
similarity index 99%
rename from drivers/mtd/onenand/onenand_bbt.c
rename to drivers/mtd/nand/onenand/onenand_bbt.c
index 420260c..dde2048 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/nand/onenand/onenand_bbt.c
@@ -1,7 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- *  linux/drivers/mtd/onenand/onenand_bbt.c
- *
  *  Bad Block Table support for the OneNAND driver
  *
  *  Copyright(c) 2005 Samsung Electronics
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/nand/onenand/samsung.c
similarity index 100%
rename from drivers/mtd/onenand/samsung.c
rename to drivers/mtd/nand/onenand/samsung.c
diff --git a/drivers/mtd/onenand/samsung.h b/drivers/mtd/nand/onenand/samsung.h
similarity index 100%
rename from drivers/mtd/onenand/samsung.h
rename to drivers/mtd/nand/onenand/samsung.h
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
deleted file mode 100644
index d1979c7..0000000
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ /dev/null
@@ -1,2105 +0,0 @@
-/*
- * drivers/mtd/nand/pxa3xx_nand.c
- *
- * Copyright © 2005 Intel Corporation
- * Copyright © 2006 Marvell International Ltd.
- *
- * 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.
- *
- * See Documentation/mtd/nand/pxa3xx-nand.txt for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma/pxa-dma.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/rawnand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/io.h>
-#include <linux/iopoll.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_data/mtd-nand-pxa3xx.h>
-#include <linux/mfd/syscon.h>
-#include <linux/regmap.h>
-
-#define	CHIP_DELAY_TIMEOUT	msecs_to_jiffies(200)
-#define NAND_STOP_DELAY		msecs_to_jiffies(40)
-#define PAGE_CHUNK_SIZE		(2048)
-
-/*
- * Define a buffer size for the initial command that detects the flash device:
- * STATUS, READID and PARAM.
- * ONFI param page is 256 bytes, and there are three redundant copies
- * to be read. JEDEC param page is 512 bytes, and there are also three
- * redundant copies to be read.
- * Hence this buffer should be at least 512 x 3. Let's pick 2048.
- */
-#define INIT_BUFFER_SIZE	2048
-
-/* System control register and bit to enable NAND on some SoCs */
-#define GENCONF_SOC_DEVICE_MUX	0x208
-#define GENCONF_SOC_DEVICE_MUX_NFC_EN BIT(0)
-
-/* registers and bit definitions */
-#define NDCR		(0x00) /* Control register */
-#define NDTR0CS0	(0x04) /* Timing Parameter 0 for CS0 */
-#define NDTR1CS0	(0x0C) /* Timing Parameter 1 for CS0 */
-#define NDSR		(0x14) /* Status Register */
-#define NDPCR		(0x18) /* Page Count Register */
-#define NDBDR0		(0x1C) /* Bad Block Register 0 */
-#define NDBDR1		(0x20) /* Bad Block Register 1 */
-#define NDECCCTRL	(0x28) /* ECC control */
-#define NDDB		(0x40) /* Data Buffer */
-#define NDCB0		(0x48) /* Command Buffer0 */
-#define NDCB1		(0x4C) /* Command Buffer1 */
-#define NDCB2		(0x50) /* Command Buffer2 */
-
-#define NDCR_SPARE_EN		(0x1 << 31)
-#define NDCR_ECC_EN		(0x1 << 30)
-#define NDCR_DMA_EN		(0x1 << 29)
-#define NDCR_ND_RUN		(0x1 << 28)
-#define NDCR_DWIDTH_C		(0x1 << 27)
-#define NDCR_DWIDTH_M		(0x1 << 26)
-#define NDCR_PAGE_SZ		(0x1 << 24)
-#define NDCR_NCSX		(0x1 << 23)
-#define NDCR_ND_MODE		(0x3 << 21)
-#define NDCR_NAND_MODE   	(0x0)
-#define NDCR_CLR_PG_CNT		(0x1 << 20)
-#define NFCV1_NDCR_ARB_CNTL	(0x1 << 19)
-#define NFCV2_NDCR_STOP_ON_UNCOR	(0x1 << 19)
-#define NDCR_RD_ID_CNT_MASK	(0x7 << 16)
-#define NDCR_RD_ID_CNT(x)	(((x) << 16) & NDCR_RD_ID_CNT_MASK)
-
-#define NDCR_RA_START		(0x1 << 15)
-#define NDCR_PG_PER_BLK		(0x1 << 14)
-#define NDCR_ND_ARB_EN		(0x1 << 12)
-#define NDCR_INT_MASK           (0xFFF)
-
-#define NDSR_MASK		(0xfff)
-#define NDSR_ERR_CNT_OFF	(16)
-#define NDSR_ERR_CNT_MASK       (0x1f)
-#define NDSR_ERR_CNT(sr)	((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK)
-#define NDSR_RDY                (0x1 << 12)
-#define NDSR_FLASH_RDY          (0x1 << 11)
-#define NDSR_CS0_PAGED		(0x1 << 10)
-#define NDSR_CS1_PAGED		(0x1 << 9)
-#define NDSR_CS0_CMDD		(0x1 << 8)
-#define NDSR_CS1_CMDD		(0x1 << 7)
-#define NDSR_CS0_BBD		(0x1 << 6)
-#define NDSR_CS1_BBD		(0x1 << 5)
-#define NDSR_UNCORERR		(0x1 << 4)
-#define NDSR_CORERR		(0x1 << 3)
-#define NDSR_WRDREQ		(0x1 << 2)
-#define NDSR_RDDREQ		(0x1 << 1)
-#define NDSR_WRCMDREQ		(0x1)
-
-#define NDCB0_LEN_OVRD		(0x1 << 28)
-#define NDCB0_ST_ROW_EN         (0x1 << 26)
-#define NDCB0_AUTO_RS		(0x1 << 25)
-#define NDCB0_CSEL		(0x1 << 24)
-#define NDCB0_EXT_CMD_TYPE_MASK	(0x7 << 29)
-#define NDCB0_EXT_CMD_TYPE(x)	(((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK)
-#define NDCB0_CMD_TYPE_MASK	(0x7 << 21)
-#define NDCB0_CMD_TYPE(x)	(((x) << 21) & NDCB0_CMD_TYPE_MASK)
-#define NDCB0_NC		(0x1 << 20)
-#define NDCB0_DBC		(0x1 << 19)
-#define NDCB0_ADDR_CYC_MASK	(0x7 << 16)
-#define NDCB0_ADDR_CYC(x)	(((x) << 16) & NDCB0_ADDR_CYC_MASK)
-#define NDCB0_CMD2_MASK		(0xff << 8)
-#define NDCB0_CMD1_MASK		(0xff)
-#define NDCB0_ADDR_CYC_SHIFT	(16)
-
-#define EXT_CMD_TYPE_DISPATCH	6 /* Command dispatch */
-#define EXT_CMD_TYPE_NAKED_RW	5 /* Naked read or Naked write */
-#define EXT_CMD_TYPE_READ	4 /* Read */
-#define EXT_CMD_TYPE_DISP_WR	4 /* Command dispatch with write */
-#define EXT_CMD_TYPE_FINAL	3 /* Final command */
-#define EXT_CMD_TYPE_LAST_RW	1 /* Last naked read/write */
-#define EXT_CMD_TYPE_MONO	0 /* Monolithic read/write */
-
-/*
- * This should be large enough to read 'ONFI' and 'JEDEC'.
- * Let's use 7 bytes, which is the maximum ID count supported
- * by the controller (see NDCR_RD_ID_CNT_MASK).
- */
-#define READ_ID_BYTES		7
-
-/* macros for registers read/write */
-#define nand_writel(info, off, val)					\
-	do {								\
-		dev_vdbg(&info->pdev->dev,				\
-			 "%s():%d nand_writel(0x%x, 0x%04x)\n",		\
-			 __func__, __LINE__, (val), (off));		\
-		writel_relaxed((val), (info)->mmio_base + (off));	\
-	} while (0)
-
-#define nand_readl(info, off)						\
-	({								\
-		unsigned int _v;					\
-		_v = readl_relaxed((info)->mmio_base + (off));		\
-		dev_vdbg(&info->pdev->dev,				\
-			 "%s():%d nand_readl(0x%04x) = 0x%x\n",		\
-			 __func__, __LINE__, (off), _v);		\
-		_v;							\
-	})
-
-/* error code and state */
-enum {
-	ERR_NONE	= 0,
-	ERR_DMABUSERR	= -1,
-	ERR_SENDCMD	= -2,
-	ERR_UNCORERR	= -3,
-	ERR_BBERR	= -4,
-	ERR_CORERR	= -5,
-};
-
-enum {
-	STATE_IDLE = 0,
-	STATE_PREPARED,
-	STATE_CMD_HANDLE,
-	STATE_DMA_READING,
-	STATE_DMA_WRITING,
-	STATE_DMA_DONE,
-	STATE_PIO_READING,
-	STATE_PIO_WRITING,
-	STATE_CMD_DONE,
-	STATE_READY,
-};
-
-enum pxa3xx_nand_variant {
-	PXA3XX_NAND_VARIANT_PXA,
-	PXA3XX_NAND_VARIANT_ARMADA370,
-	PXA3XX_NAND_VARIANT_ARMADA_8K,
-};
-
-struct pxa3xx_nand_host {
-	struct nand_chip	chip;
-	void			*info_data;
-
-	/* page size of attached chip */
-	int			use_ecc;
-	int			cs;
-
-	/* calculated from pxa3xx_nand_flash data */
-	unsigned int		col_addr_cycles;
-	unsigned int		row_addr_cycles;
-};
-
-struct pxa3xx_nand_info {
-	struct nand_hw_control	controller;
-	struct platform_device	 *pdev;
-
-	struct clk		*clk;
-	void __iomem		*mmio_base;
-	unsigned long		mmio_phys;
-	struct completion	cmd_complete, dev_ready;
-
-	unsigned int 		buf_start;
-	unsigned int		buf_count;
-	unsigned int		buf_size;
-	unsigned int		data_buff_pos;
-	unsigned int		oob_buff_pos;
-
-	/* DMA information */
-	struct scatterlist	sg;
-	enum dma_data_direction	dma_dir;
-	struct dma_chan		*dma_chan;
-	dma_cookie_t		dma_cookie;
-	int			drcmr_dat;
-
-	unsigned char		*data_buff;
-	unsigned char		*oob_buff;
-	dma_addr_t 		data_buff_phys;
-	int 			data_dma_ch;
-
-	struct pxa3xx_nand_host *host[NUM_CHIP_SELECT];
-	unsigned int		state;
-
-	/*
-	 * This driver supports NFCv1 (as found in PXA SoC)
-	 * and NFCv2 (as found in Armada 370/XP SoC).
-	 */
-	enum pxa3xx_nand_variant variant;
-
-	int			cs;
-	int			use_ecc;	/* use HW ECC ? */
-	int			ecc_bch;	/* using BCH ECC? */
-	int			use_dma;	/* use DMA ? */
-	int			use_spare;	/* use spare ? */
-	int			need_wait;
-
-	/* Amount of real data per full chunk */
-	unsigned int		chunk_size;
-
-	/* Amount of spare data per full chunk */
-	unsigned int		spare_size;
-
-	/* Number of full chunks (i.e chunk_size + spare_size) */
-	unsigned int            nfullchunks;
-
-	/*
-	 * Total number of chunks. If equal to nfullchunks, then there
-	 * are only full chunks. Otherwise, there is one last chunk of
-	 * size (last_chunk_size + last_spare_size)
-	 */
-	unsigned int            ntotalchunks;
-
-	/* Amount of real data in the last chunk */
-	unsigned int		last_chunk_size;
-
-	/* Amount of spare data in the last chunk */
-	unsigned int		last_spare_size;
-
-	unsigned int		ecc_size;
-	unsigned int		ecc_err_cnt;
-	unsigned int		max_bitflips;
-	int 			retcode;
-
-	/*
-	 * Variables only valid during command
-	 * execution. step_chunk_size and step_spare_size is the
-	 * amount of real data and spare data in the current
-	 * chunk. cur_chunk is the current chunk being
-	 * read/programmed.
-	 */
-	unsigned int		step_chunk_size;
-	unsigned int		step_spare_size;
-	unsigned int            cur_chunk;
-
-	/* cached register value */
-	uint32_t		reg_ndcr;
-	uint32_t		ndtr0cs0;
-	uint32_t		ndtr1cs0;
-
-	/* generated NDCBx register values */
-	uint32_t		ndcb0;
-	uint32_t		ndcb1;
-	uint32_t		ndcb2;
-	uint32_t		ndcb3;
-};
-
-static bool use_dma = 1;
-module_param(use_dma, bool, 0444);
-MODULE_PARM_DESC(use_dma, "enable DMA for data transferring to/from NAND HW");
-
-struct pxa3xx_nand_timing {
-	unsigned int	tCH;  /* Enable signal hold time */
-	unsigned int	tCS;  /* Enable signal setup time */
-	unsigned int	tWH;  /* ND_nWE high duration */
-	unsigned int	tWP;  /* ND_nWE pulse time */
-	unsigned int	tRH;  /* ND_nRE high duration */
-	unsigned int	tRP;  /* ND_nRE pulse width */
-	unsigned int	tR;   /* ND_nWE high to ND_nRE low for read */
-	unsigned int	tWHR; /* ND_nWE high to ND_nRE low for status read */
-	unsigned int	tAR;  /* ND_ALE low to ND_nRE low delay */
-};
-
-struct pxa3xx_nand_flash {
-	uint32_t	chip_id;
-	unsigned int	flash_width;	/* Width of Flash memory (DWIDTH_M) */
-	unsigned int	dfc_width;	/* Width of flash controller(DWIDTH_C) */
-	struct pxa3xx_nand_timing *timing;	/* NAND Flash timing */
-};
-
-static struct pxa3xx_nand_timing timing[] = {
-	{ 40, 80, 60, 100, 80, 100, 90000, 400, 40, },
-	{ 10,  0, 20,  40, 30,  40, 11123, 110, 10, },
-	{ 10, 25, 15,  25, 15,  30, 25000,  60, 10, },
-	{ 10, 35, 15,  25, 15,  25, 25000,  60, 10, },
-};
-
-static struct pxa3xx_nand_flash builtin_flash_types[] = {
-	{ 0x46ec, 16, 16, &timing[1] },
-	{ 0xdaec,  8,  8, &timing[1] },
-	{ 0xd7ec,  8,  8, &timing[1] },
-	{ 0xa12c,  8,  8, &timing[2] },
-	{ 0xb12c, 16, 16, &timing[2] },
-	{ 0xdc2c,  8,  8, &timing[2] },
-	{ 0xcc2c, 16, 16, &timing[2] },
-	{ 0xba20, 16, 16, &timing[3] },
-};
-
-static int pxa3xx_ooblayout_ecc(struct mtd_info *mtd, int section,
-				struct mtd_oob_region *oobregion)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int nchunks = mtd->writesize / info->chunk_size;
-
-	if (section >= nchunks)
-		return -ERANGE;
-
-	oobregion->offset = ((info->ecc_size + info->spare_size) * section) +
-			    info->spare_size;
-	oobregion->length = info->ecc_size;
-
-	return 0;
-}
-
-static int pxa3xx_ooblayout_free(struct mtd_info *mtd, int section,
-				 struct mtd_oob_region *oobregion)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int nchunks = mtd->writesize / info->chunk_size;
-
-	if (section >= nchunks)
-		return -ERANGE;
-
-	if (!info->spare_size)
-		return 0;
-
-	oobregion->offset = section * (info->ecc_size + info->spare_size);
-	oobregion->length = info->spare_size;
-	if (!section) {
-		/*
-		 * Bootrom looks in bytes 0 & 5 for bad blocks for the
-		 * 4KB page / 4bit BCH combination.
-		 */
-		if (mtd->writesize == 4096 && info->chunk_size == 2048) {
-			oobregion->offset += 6;
-			oobregion->length -= 6;
-		} else {
-			oobregion->offset += 2;
-			oobregion->length -= 2;
-		}
-	}
-
-	return 0;
-}
-
-static const struct mtd_ooblayout_ops pxa3xx_ooblayout_ops = {
-	.ecc = pxa3xx_ooblayout_ecc,
-	.free = pxa3xx_ooblayout_free,
-};
-
-static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
-static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
-
-static struct nand_bbt_descr bbt_main_descr = {
-	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-		| NAND_BBT_2BIT | NAND_BBT_VERSION,
-	.offs =	8,
-	.len = 6,
-	.veroffs = 14,
-	.maxblocks = 8,		/* Last 8 blocks in each chip */
-	.pattern = bbt_pattern
-};
-
-static struct nand_bbt_descr bbt_mirror_descr = {
-	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-		| NAND_BBT_2BIT | NAND_BBT_VERSION,
-	.offs =	8,
-	.len = 6,
-	.veroffs = 14,
-	.maxblocks = 8,		/* Last 8 blocks in each chip */
-	.pattern = bbt_mirror_pattern
-};
-
-#define NDTR0_tCH(c)	(min((c), 7) << 19)
-#define NDTR0_tCS(c)	(min((c), 7) << 16)
-#define NDTR0_tWH(c)	(min((c), 7) << 11)
-#define NDTR0_tWP(c)	(min((c), 7) << 8)
-#define NDTR0_tRH(c)	(min((c), 7) << 3)
-#define NDTR0_tRP(c)	(min((c), 7) << 0)
-
-#define NDTR1_tR(c)	(min((c), 65535) << 16)
-#define NDTR1_tWHR(c)	(min((c), 15) << 4)
-#define NDTR1_tAR(c)	(min((c), 15) << 0)
-
-/* convert nano-seconds to nand flash controller clock cycles */
-#define ns2cycle(ns, clk)	(int)((ns) * (clk / 1000000) / 1000)
-
-static const struct of_device_id pxa3xx_nand_dt_ids[] = {
-	{
-		.compatible = "marvell,pxa3xx-nand",
-		.data       = (void *)PXA3XX_NAND_VARIANT_PXA,
-	},
-	{
-		.compatible = "marvell,armada370-nand",
-		.data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
-	},
-	{
-		.compatible = "marvell,armada-8k-nand",
-		.data       = (void *)PXA3XX_NAND_VARIANT_ARMADA_8K,
-	},
-	{}
-};
-MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
-
-static enum pxa3xx_nand_variant
-pxa3xx_nand_get_variant(struct platform_device *pdev)
-{
-	const struct of_device_id *of_id =
-			of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
-	if (!of_id)
-		return PXA3XX_NAND_VARIANT_PXA;
-	return (enum pxa3xx_nand_variant)of_id->data;
-}
-
-static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
-				   const struct pxa3xx_nand_timing *t)
-{
-	struct pxa3xx_nand_info *info = host->info_data;
-	unsigned long nand_clk = clk_get_rate(info->clk);
-	uint32_t ndtr0, ndtr1;
-
-	ndtr0 = NDTR0_tCH(ns2cycle(t->tCH, nand_clk)) |
-		NDTR0_tCS(ns2cycle(t->tCS, nand_clk)) |
-		NDTR0_tWH(ns2cycle(t->tWH, nand_clk)) |
-		NDTR0_tWP(ns2cycle(t->tWP, nand_clk)) |
-		NDTR0_tRH(ns2cycle(t->tRH, nand_clk)) |
-		NDTR0_tRP(ns2cycle(t->tRP, nand_clk));
-
-	ndtr1 = NDTR1_tR(ns2cycle(t->tR, nand_clk)) |
-		NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) |
-		NDTR1_tAR(ns2cycle(t->tAR, nand_clk));
-
-	info->ndtr0cs0 = ndtr0;
-	info->ndtr1cs0 = ndtr1;
-	nand_writel(info, NDTR0CS0, ndtr0);
-	nand_writel(info, NDTR1CS0, ndtr1);
-}
-
-static void pxa3xx_nand_set_sdr_timing(struct pxa3xx_nand_host *host,
-				       const struct nand_sdr_timings *t)
-{
-	struct pxa3xx_nand_info *info = host->info_data;
-	struct nand_chip *chip = &host->chip;
-	unsigned long nand_clk = clk_get_rate(info->clk);
-	uint32_t ndtr0, ndtr1;
-
-	u32 tCH_min = DIV_ROUND_UP(t->tCH_min, 1000);
-	u32 tCS_min = DIV_ROUND_UP(t->tCS_min, 1000);
-	u32 tWH_min = DIV_ROUND_UP(t->tWH_min, 1000);
-	u32 tWP_min = DIV_ROUND_UP(t->tWC_min - t->tWH_min, 1000);
-	u32 tREH_min = DIV_ROUND_UP(t->tREH_min, 1000);
-	u32 tRP_min = DIV_ROUND_UP(t->tRC_min - t->tREH_min, 1000);
-	u32 tR = chip->chip_delay * 1000;
-	u32 tWHR_min = DIV_ROUND_UP(t->tWHR_min, 1000);
-	u32 tAR_min = DIV_ROUND_UP(t->tAR_min, 1000);
-
-	/* fallback to a default value if tR = 0 */
-	if (!tR)
-		tR = 20000;
-
-	ndtr0 = NDTR0_tCH(ns2cycle(tCH_min, nand_clk)) |
-		NDTR0_tCS(ns2cycle(tCS_min, nand_clk)) |
-		NDTR0_tWH(ns2cycle(tWH_min, nand_clk)) |
-		NDTR0_tWP(ns2cycle(tWP_min, nand_clk)) |
-		NDTR0_tRH(ns2cycle(tREH_min, nand_clk)) |
-		NDTR0_tRP(ns2cycle(tRP_min, nand_clk));
-
-	ndtr1 = NDTR1_tR(ns2cycle(tR, nand_clk)) |
-		NDTR1_tWHR(ns2cycle(tWHR_min, nand_clk)) |
-		NDTR1_tAR(ns2cycle(tAR_min, nand_clk));
-
-	info->ndtr0cs0 = ndtr0;
-	info->ndtr1cs0 = ndtr1;
-	nand_writel(info, NDTR0CS0, ndtr0);
-	nand_writel(info, NDTR1CS0, ndtr1);
-}
-
-static int pxa3xx_nand_init_timings_compat(struct pxa3xx_nand_host *host,
-					   unsigned int *flash_width,
-					   unsigned int *dfc_width)
-{
-	struct nand_chip *chip = &host->chip;
-	struct pxa3xx_nand_info *info = host->info_data;
-	const struct pxa3xx_nand_flash *f = NULL;
-	int i, id, ntypes;
-	u8 idbuf[2];
-
-	ntypes = ARRAY_SIZE(builtin_flash_types);
-
-	nand_readid_op(chip, 0, idbuf, sizeof(idbuf));
-	id = idbuf[0] | (idbuf[1] << 8);
-
-	for (i = 0; i < ntypes; i++) {
-		f = &builtin_flash_types[i];
-
-		if (f->chip_id == id)
-			break;
-	}
-
-	if (i == ntypes) {
-		dev_err(&info->pdev->dev, "Error: timings not found\n");
-		return -EINVAL;
-	}
-
-	pxa3xx_nand_set_timing(host, f->timing);
-
-	*flash_width = f->flash_width;
-	*dfc_width = f->dfc_width;
-
-	return 0;
-}
-
-static int pxa3xx_nand_init_timings_onfi(struct pxa3xx_nand_host *host,
-					 int mode)
-{
-	const struct nand_sdr_timings *timings;
-
-	mode = fls(mode) - 1;
-	if (mode < 0)
-		mode = 0;
-
-	timings = onfi_async_timing_mode_to_sdr_timings(mode);
-	if (IS_ERR(timings))
-		return PTR_ERR(timings);
-
-	pxa3xx_nand_set_sdr_timing(host, timings);
-
-	return 0;
-}
-
-static int pxa3xx_nand_init(struct pxa3xx_nand_host *host)
-{
-	struct nand_chip *chip = &host->chip;
-	struct pxa3xx_nand_info *info = host->info_data;
-	unsigned int flash_width = 0, dfc_width = 0;
-	int mode, err;
-
-	mode = onfi_get_async_timing_mode(chip);
-	if (mode == ONFI_TIMING_MODE_UNKNOWN) {
-		err = pxa3xx_nand_init_timings_compat(host, &flash_width,
-						      &dfc_width);
-		if (err)
-			return err;
-
-		if (flash_width == 16) {
-			info->reg_ndcr |= NDCR_DWIDTH_M;
-			chip->options |= NAND_BUSWIDTH_16;
-		}
-
-		info->reg_ndcr |= (dfc_width == 16) ? NDCR_DWIDTH_C : 0;
-	} else {
-		err = pxa3xx_nand_init_timings_onfi(host, mode);
-		if (err)
-			return err;
-	}
-
-	return 0;
-}
-
-/**
- * NOTE: it is a must to set ND_RUN firstly, then write
- * command buffer, otherwise, it does not work.
- * We enable all the interrupt at the same time, and
- * let pxa3xx_nand_irq to handle all logic.
- */
-static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
-{
-	uint32_t ndcr;
-
-	ndcr = info->reg_ndcr;
-
-	if (info->use_ecc) {
-		ndcr |= NDCR_ECC_EN;
-		if (info->ecc_bch)
-			nand_writel(info, NDECCCTRL, 0x1);
-	} else {
-		ndcr &= ~NDCR_ECC_EN;
-		if (info->ecc_bch)
-			nand_writel(info, NDECCCTRL, 0x0);
-	}
-
-	if (info->use_dma)
-		ndcr |= NDCR_DMA_EN;
-	else
-		ndcr &= ~NDCR_DMA_EN;
-
-	if (info->use_spare)
-		ndcr |= NDCR_SPARE_EN;
-	else
-		ndcr &= ~NDCR_SPARE_EN;
-
-	ndcr |= NDCR_ND_RUN;
-
-	/* clear status bits and run */
-	nand_writel(info, NDSR, NDSR_MASK);
-	nand_writel(info, NDCR, 0);
-	nand_writel(info, NDCR, ndcr);
-}
-
-static void pxa3xx_nand_stop(struct pxa3xx_nand_info *info)
-{
-	uint32_t ndcr;
-	int timeout = NAND_STOP_DELAY;
-
-	/* wait RUN bit in NDCR become 0 */
-	ndcr = nand_readl(info, NDCR);
-	while ((ndcr & NDCR_ND_RUN) && (timeout-- > 0)) {
-		ndcr = nand_readl(info, NDCR);
-		udelay(1);
-	}
-
-	if (timeout <= 0) {
-		ndcr &= ~NDCR_ND_RUN;
-		nand_writel(info, NDCR, ndcr);
-	}
-	if (info->dma_chan)
-		dmaengine_terminate_all(info->dma_chan);
-
-	/* clear status bits */
-	nand_writel(info, NDSR, NDSR_MASK);
-}
-
-static void __maybe_unused
-enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
-{
-	uint32_t ndcr;
-
-	ndcr = nand_readl(info, NDCR);
-	nand_writel(info, NDCR, ndcr & ~int_mask);
-}
-
-static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
-{
-	uint32_t ndcr;
-
-	ndcr = nand_readl(info, NDCR);
-	nand_writel(info, NDCR, ndcr | int_mask);
-}
-
-static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len)
-{
-	if (info->ecc_bch) {
-		u32 val;
-		int ret;
-
-		/*
-		 * According to the datasheet, when reading from NDDB
-		 * with BCH enabled, after each 32 bytes reads, we
-		 * have to make sure that the NDSR.RDDREQ bit is set.
-		 *
-		 * Drain the FIFO 8 32 bits reads at a time, and skip
-		 * the polling on the last read.
-		 */
-		while (len > 8) {
-			ioread32_rep(info->mmio_base + NDDB, data, 8);
-
-			ret = readl_relaxed_poll_timeout(info->mmio_base + NDSR, val,
-							 val & NDSR_RDDREQ, 1000, 5000);
-			if (ret) {
-				dev_err(&info->pdev->dev,
-					"Timeout on RDDREQ while draining the FIFO\n");
-				return;
-			}
-
-			data += 32;
-			len -= 8;
-		}
-	}
-
-	ioread32_rep(info->mmio_base + NDDB, data, len);
-}
-
-static void handle_data_pio(struct pxa3xx_nand_info *info)
-{
-	switch (info->state) {
-	case STATE_PIO_WRITING:
-		if (info->step_chunk_size)
-			writesl(info->mmio_base + NDDB,
-				info->data_buff + info->data_buff_pos,
-				DIV_ROUND_UP(info->step_chunk_size, 4));
-
-		if (info->step_spare_size)
-			writesl(info->mmio_base + NDDB,
-				info->oob_buff + info->oob_buff_pos,
-				DIV_ROUND_UP(info->step_spare_size, 4));
-		break;
-	case STATE_PIO_READING:
-		if (info->step_chunk_size)
-			drain_fifo(info,
-				   info->data_buff + info->data_buff_pos,
-				   DIV_ROUND_UP(info->step_chunk_size, 4));
-
-		if (info->step_spare_size)
-			drain_fifo(info,
-				   info->oob_buff + info->oob_buff_pos,
-				   DIV_ROUND_UP(info->step_spare_size, 4));
-		break;
-	default:
-		dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
-				info->state);
-		BUG();
-	}
-
-	/* Update buffer pointers for multi-page read/write */
-	info->data_buff_pos += info->step_chunk_size;
-	info->oob_buff_pos += info->step_spare_size;
-}
-
-static void pxa3xx_nand_data_dma_irq(void *data)
-{
-	struct pxa3xx_nand_info *info = data;
-	struct dma_tx_state state;
-	enum dma_status status;
-
-	status = dmaengine_tx_status(info->dma_chan, info->dma_cookie, &state);
-	if (likely(status == DMA_COMPLETE)) {
-		info->state = STATE_DMA_DONE;
-	} else {
-		dev_err(&info->pdev->dev, "DMA error on data channel\n");
-		info->retcode = ERR_DMABUSERR;
-	}
-	dma_unmap_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir);
-
-	nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
-	enable_int(info, NDCR_INT_MASK);
-}
-
-static void start_data_dma(struct pxa3xx_nand_info *info)
-{
-	enum dma_transfer_direction direction;
-	struct dma_async_tx_descriptor *tx;
-
-	switch (info->state) {
-	case STATE_DMA_WRITING:
-		info->dma_dir = DMA_TO_DEVICE;
-		direction = DMA_MEM_TO_DEV;
-		break;
-	case STATE_DMA_READING:
-		info->dma_dir = DMA_FROM_DEVICE;
-		direction = DMA_DEV_TO_MEM;
-		break;
-	default:
-		dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
-				info->state);
-		BUG();
-	}
-	info->sg.length = info->chunk_size;
-	if (info->use_spare)
-		info->sg.length += info->spare_size + info->ecc_size;
-	dma_map_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir);
-
-	tx = dmaengine_prep_slave_sg(info->dma_chan, &info->sg, 1, direction,
-				     DMA_PREP_INTERRUPT);
-	if (!tx) {
-		dev_err(&info->pdev->dev, "prep_slave_sg() failed\n");
-		return;
-	}
-	tx->callback = pxa3xx_nand_data_dma_irq;
-	tx->callback_param = info;
-	info->dma_cookie = dmaengine_submit(tx);
-	dma_async_issue_pending(info->dma_chan);
-	dev_dbg(&info->pdev->dev, "%s(dir=%d cookie=%x size=%u)\n",
-		__func__, direction, info->dma_cookie, info->sg.length);
-}
-
-static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data)
-{
-	struct pxa3xx_nand_info *info = data;
-
-	handle_data_pio(info);
-
-	info->state = STATE_CMD_DONE;
-	nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
-{
-	struct pxa3xx_nand_info *info = devid;
-	unsigned int status, is_completed = 0, is_ready = 0;
-	unsigned int ready, cmd_done;
-	irqreturn_t ret = IRQ_HANDLED;
-
-	if (info->cs == 0) {
-		ready           = NDSR_FLASH_RDY;
-		cmd_done        = NDSR_CS0_CMDD;
-	} else {
-		ready           = NDSR_RDY;
-		cmd_done        = NDSR_CS1_CMDD;
-	}
-
-	status = nand_readl(info, NDSR);
-
-	if (status & NDSR_UNCORERR)
-		info->retcode = ERR_UNCORERR;
-	if (status & NDSR_CORERR) {
-		info->retcode = ERR_CORERR;
-		if ((info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
-		     info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) &&
-		    info->ecc_bch)
-			info->ecc_err_cnt = NDSR_ERR_CNT(status);
-		else
-			info->ecc_err_cnt = 1;
-
-		/*
-		 * Each chunk composing a page is corrected independently,
-		 * and we need to store maximum number of corrected bitflips
-		 * to return it to the MTD layer in ecc.read_page().
-		 */
-		info->max_bitflips = max_t(unsigned int,
-					   info->max_bitflips,
-					   info->ecc_err_cnt);
-	}
-	if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) {
-		/* whether use dma to transfer data */
-		if (info->use_dma) {
-			disable_int(info, NDCR_INT_MASK);
-			info->state = (status & NDSR_RDDREQ) ?
-				      STATE_DMA_READING : STATE_DMA_WRITING;
-			start_data_dma(info);
-			goto NORMAL_IRQ_EXIT;
-		} else {
-			info->state = (status & NDSR_RDDREQ) ?
-				      STATE_PIO_READING : STATE_PIO_WRITING;
-			ret = IRQ_WAKE_THREAD;
-			goto NORMAL_IRQ_EXIT;
-		}
-	}
-	if (status & cmd_done) {
-		info->state = STATE_CMD_DONE;
-		is_completed = 1;
-	}
-	if (status & ready) {
-		info->state = STATE_READY;
-		is_ready = 1;
-	}
-
-	/*
-	 * Clear all status bit before issuing the next command, which
-	 * can and will alter the status bits and will deserve a new
-	 * interrupt on its own. This lets the controller exit the IRQ
-	 */
-	nand_writel(info, NDSR, status);
-
-	if (status & NDSR_WRCMDREQ) {
-		status &= ~NDSR_WRCMDREQ;
-		info->state = STATE_CMD_HANDLE;
-
-		/*
-		 * Command buffer registers NDCB{0-2} (and optionally NDCB3)
-		 * must be loaded by writing directly either 12 or 16
-		 * bytes directly to NDCB0, four bytes at a time.
-		 *
-		 * Direct write access to NDCB1, NDCB2 and NDCB3 is ignored
-		 * but each NDCBx register can be read.
-		 */
-		nand_writel(info, NDCB0, info->ndcb0);
-		nand_writel(info, NDCB0, info->ndcb1);
-		nand_writel(info, NDCB0, info->ndcb2);
-
-		/* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */
-		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
-		    info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K)
-			nand_writel(info, NDCB0, info->ndcb3);
-	}
-
-	if (is_completed)
-		complete(&info->cmd_complete);
-	if (is_ready)
-		complete(&info->dev_ready);
-NORMAL_IRQ_EXIT:
-	return ret;
-}
-
-static inline int is_buf_blank(uint8_t *buf, size_t len)
-{
-	for (; len > 0; len--)
-		if (*buf++ != 0xff)
-			return 0;
-	return 1;
-}
-
-static void set_command_address(struct pxa3xx_nand_info *info,
-		unsigned int page_size, uint16_t column, int page_addr)
-{
-	/* small page addr setting */
-	if (page_size < PAGE_CHUNK_SIZE) {
-		info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
-				| (column & 0xFF);
-
-		info->ndcb2 = 0;
-	} else {
-		info->ndcb1 = ((page_addr & 0xFFFF) << 16)
-				| (column & 0xFFFF);
-
-		if (page_addr & 0xFF0000)
-			info->ndcb2 = (page_addr & 0xFF0000) >> 16;
-		else
-			info->ndcb2 = 0;
-	}
-}
-
-static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
-{
-	struct pxa3xx_nand_host *host = info->host[info->cs];
-	struct mtd_info *mtd = nand_to_mtd(&host->chip);
-
-	/* reset data and oob column point to handle data */
-	info->buf_start		= 0;
-	info->buf_count		= 0;
-	info->data_buff_pos	= 0;
-	info->oob_buff_pos	= 0;
-	info->step_chunk_size   = 0;
-	info->step_spare_size   = 0;
-	info->cur_chunk         = 0;
-	info->use_ecc		= 0;
-	info->use_spare		= 1;
-	info->retcode		= ERR_NONE;
-	info->ecc_err_cnt	= 0;
-	info->ndcb3		= 0;
-	info->need_wait		= 0;
-
-	switch (command) {
-	case NAND_CMD_READ0:
-	case NAND_CMD_READOOB:
-	case NAND_CMD_PAGEPROG:
-		info->use_ecc = 1;
-		break;
-	case NAND_CMD_PARAM:
-		info->use_spare = 0;
-		break;
-	default:
-		info->ndcb1 = 0;
-		info->ndcb2 = 0;
-		break;
-	}
-
-	/*
-	 * If we are about to issue a read command, or about to set
-	 * the write address, then clean the data buffer.
-	 */
-	if (command == NAND_CMD_READ0 ||
-	    command == NAND_CMD_READOOB ||
-	    command == NAND_CMD_SEQIN) {
-
-		info->buf_count = mtd->writesize + mtd->oobsize;
-		memset(info->data_buff, 0xFF, info->buf_count);
-	}
-
-}
-
-static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
-		int ext_cmd_type, uint16_t column, int page_addr)
-{
-	int addr_cycle, exec_cmd;
-	struct pxa3xx_nand_host *host;
-	struct mtd_info *mtd;
-
-	host = info->host[info->cs];
-	mtd = nand_to_mtd(&host->chip);
-	addr_cycle = 0;
-	exec_cmd = 1;
-
-	if (info->cs != 0)
-		info->ndcb0 = NDCB0_CSEL;
-	else
-		info->ndcb0 = 0;
-
-	if (command == NAND_CMD_SEQIN)
-		exec_cmd = 0;
-
-	addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles
-				    + host->col_addr_cycles);
-
-	switch (command) {
-	case NAND_CMD_READOOB:
-	case NAND_CMD_READ0:
-		info->buf_start = column;
-		info->ndcb0 |= NDCB0_CMD_TYPE(0)
-				| addr_cycle
-				| NAND_CMD_READ0;
-
-		if (command == NAND_CMD_READOOB)
-			info->buf_start += mtd->writesize;
-
-		if (info->cur_chunk < info->nfullchunks) {
-			info->step_chunk_size = info->chunk_size;
-			info->step_spare_size = info->spare_size;
-		} else {
-			info->step_chunk_size = info->last_chunk_size;
-			info->step_spare_size = info->last_spare_size;
-		}
-
-		/*
-		 * Multiple page read needs an 'extended command type' field,
-		 * which is either naked-read or last-read according to the
-		 * state.
-		 */
-		if (mtd->writesize == PAGE_CHUNK_SIZE) {
-			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
-		} else if (mtd->writesize > PAGE_CHUNK_SIZE) {
-			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8)
-					| NDCB0_LEN_OVRD
-					| NDCB0_EXT_CMD_TYPE(ext_cmd_type);
-			info->ndcb3 = info->step_chunk_size +
-				info->step_spare_size;
-		}
-
-		set_command_address(info, mtd->writesize, column, page_addr);
-		break;
-
-	case NAND_CMD_SEQIN:
-
-		info->buf_start = column;
-		set_command_address(info, mtd->writesize, 0, page_addr);
-
-		/*
-		 * Multiple page programming needs to execute the initial
-		 * SEQIN command that sets the page address.
-		 */
-		if (mtd->writesize > PAGE_CHUNK_SIZE) {
-			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
-				| NDCB0_EXT_CMD_TYPE(ext_cmd_type)
-				| addr_cycle
-				| command;
-			exec_cmd = 1;
-		}
-		break;
-
-	case NAND_CMD_PAGEPROG:
-		if (is_buf_blank(info->data_buff,
-					(mtd->writesize + mtd->oobsize))) {
-			exec_cmd = 0;
-			break;
-		}
-
-		if (info->cur_chunk < info->nfullchunks) {
-			info->step_chunk_size = info->chunk_size;
-			info->step_spare_size = info->spare_size;
-		} else {
-			info->step_chunk_size = info->last_chunk_size;
-			info->step_spare_size = info->last_spare_size;
-		}
-
-		/* Second command setting for large pages */
-		if (mtd->writesize > PAGE_CHUNK_SIZE) {
-			/*
-			 * Multiple page write uses the 'extended command'
-			 * field. This can be used to issue a command dispatch
-			 * or a naked-write depending on the current stage.
-			 */
-			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
-					| NDCB0_LEN_OVRD
-					| NDCB0_EXT_CMD_TYPE(ext_cmd_type);
-			info->ndcb3 = info->step_chunk_size +
-				      info->step_spare_size;
-
-			/*
-			 * This is the command dispatch that completes a chunked
-			 * page program operation.
-			 */
-			if (info->cur_chunk == info->ntotalchunks) {
-				info->ndcb0 = NDCB0_CMD_TYPE(0x1)
-					| NDCB0_EXT_CMD_TYPE(ext_cmd_type)
-					| command;
-				info->ndcb1 = 0;
-				info->ndcb2 = 0;
-				info->ndcb3 = 0;
-			}
-		} else {
-			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
-					| NDCB0_AUTO_RS
-					| NDCB0_ST_ROW_EN
-					| NDCB0_DBC
-					| (NAND_CMD_PAGEPROG << 8)
-					| NAND_CMD_SEQIN
-					| addr_cycle;
-		}
-		break;
-
-	case NAND_CMD_PARAM:
-		info->buf_count = INIT_BUFFER_SIZE;
-		info->ndcb0 |= NDCB0_CMD_TYPE(0)
-				| NDCB0_ADDR_CYC(1)
-				| NDCB0_LEN_OVRD
-				| command;
-		info->ndcb1 = (column & 0xFF);
-		info->ndcb3 = INIT_BUFFER_SIZE;
-		info->step_chunk_size = INIT_BUFFER_SIZE;
-		break;
-
-	case NAND_CMD_READID:
-		info->buf_count = READ_ID_BYTES;
-		info->ndcb0 |= NDCB0_CMD_TYPE(3)
-				| NDCB0_ADDR_CYC(1)
-				| command;
-		info->ndcb1 = (column & 0xFF);
-
-		info->step_chunk_size = 8;
-		break;
-	case NAND_CMD_STATUS:
-		info->buf_count = 1;
-		info->ndcb0 |= NDCB0_CMD_TYPE(4)
-				| NDCB0_ADDR_CYC(1)
-				| command;
-
-		info->step_chunk_size = 8;
-		break;
-
-	case NAND_CMD_ERASE1:
-		info->ndcb0 |= NDCB0_CMD_TYPE(2)
-				| NDCB0_AUTO_RS
-				| NDCB0_ADDR_CYC(3)
-				| NDCB0_DBC
-				| (NAND_CMD_ERASE2 << 8)
-				| NAND_CMD_ERASE1;
-		info->ndcb1 = page_addr;
-		info->ndcb2 = 0;
-
-		break;
-	case NAND_CMD_RESET:
-		info->ndcb0 |= NDCB0_CMD_TYPE(5)
-				| command;
-
-		break;
-
-	case NAND_CMD_ERASE2:
-		exec_cmd = 0;
-		break;
-
-	default:
-		exec_cmd = 0;
-		dev_err(&info->pdev->dev, "non-supported command %x\n",
-				command);
-		break;
-	}
-
-	return exec_cmd;
-}
-
-static void nand_cmdfunc(struct mtd_info *mtd, unsigned command,
-			 int column, int page_addr)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int exec_cmd;
-
-	/*
-	 * if this is a x16 device ,then convert the input
-	 * "byte" address into a "word" address appropriate
-	 * for indexing a word-oriented device
-	 */
-	if (info->reg_ndcr & NDCR_DWIDTH_M)
-		column /= 2;
-
-	/*
-	 * There may be different NAND chip hooked to
-	 * different chip select, so check whether
-	 * chip select has been changed, if yes, reset the timing
-	 */
-	if (info->cs != host->cs) {
-		info->cs = host->cs;
-		nand_writel(info, NDTR0CS0, info->ndtr0cs0);
-		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
-	}
-
-	prepare_start_command(info, command);
-
-	info->state = STATE_PREPARED;
-	exec_cmd = prepare_set_command(info, command, 0, column, page_addr);
-
-	if (exec_cmd) {
-		init_completion(&info->cmd_complete);
-		init_completion(&info->dev_ready);
-		info->need_wait = 1;
-		pxa3xx_nand_start(info);
-
-		if (!wait_for_completion_timeout(&info->cmd_complete,
-		    CHIP_DELAY_TIMEOUT)) {
-			dev_err(&info->pdev->dev, "Wait time out!!!\n");
-			/* Stop State Machine for next command cycle */
-			pxa3xx_nand_stop(info);
-		}
-	}
-	info->state = STATE_IDLE;
-}
-
-static void nand_cmdfunc_extended(struct mtd_info *mtd,
-				  const unsigned command,
-				  int column, int page_addr)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int exec_cmd, ext_cmd_type;
-
-	/*
-	 * if this is a x16 device then convert the input
-	 * "byte" address into a "word" address appropriate
-	 * for indexing a word-oriented device
-	 */
-	if (info->reg_ndcr & NDCR_DWIDTH_M)
-		column /= 2;
-
-	/*
-	 * There may be different NAND chip hooked to
-	 * different chip select, so check whether
-	 * chip select has been changed, if yes, reset the timing
-	 */
-	if (info->cs != host->cs) {
-		info->cs = host->cs;
-		nand_writel(info, NDTR0CS0, info->ndtr0cs0);
-		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
-	}
-
-	/* Select the extended command for the first command */
-	switch (command) {
-	case NAND_CMD_READ0:
-	case NAND_CMD_READOOB:
-		ext_cmd_type = EXT_CMD_TYPE_MONO;
-		break;
-	case NAND_CMD_SEQIN:
-		ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
-		break;
-	case NAND_CMD_PAGEPROG:
-		ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
-		break;
-	default:
-		ext_cmd_type = 0;
-		break;
-	}
-
-	prepare_start_command(info, command);
-
-	/*
-	 * Prepare the "is ready" completion before starting a command
-	 * transaction sequence. If the command is not executed the
-	 * completion will be completed, see below.
-	 *
-	 * We can do that inside the loop because the command variable
-	 * is invariant and thus so is the exec_cmd.
-	 */
-	info->need_wait = 1;
-	init_completion(&info->dev_ready);
-	do {
-		info->state = STATE_PREPARED;
-
-		exec_cmd = prepare_set_command(info, command, ext_cmd_type,
-					       column, page_addr);
-		if (!exec_cmd) {
-			info->need_wait = 0;
-			complete(&info->dev_ready);
-			break;
-		}
-
-		init_completion(&info->cmd_complete);
-		pxa3xx_nand_start(info);
-
-		if (!wait_for_completion_timeout(&info->cmd_complete,
-		    CHIP_DELAY_TIMEOUT)) {
-			dev_err(&info->pdev->dev, "Wait time out!!!\n");
-			/* Stop State Machine for next command cycle */
-			pxa3xx_nand_stop(info);
-			break;
-		}
-
-		/* Only a few commands need several steps */
-		if (command != NAND_CMD_PAGEPROG &&
-		    command != NAND_CMD_READ0    &&
-		    command != NAND_CMD_READOOB)
-			break;
-
-		info->cur_chunk++;
-
-		/* Check if the sequence is complete */
-		if (info->cur_chunk == info->ntotalchunks && command != NAND_CMD_PAGEPROG)
-			break;
-
-		/*
-		 * After a splitted program command sequence has issued
-		 * the command dispatch, the command sequence is complete.
-		 */
-		if (info->cur_chunk == (info->ntotalchunks + 1) &&
-		    command == NAND_CMD_PAGEPROG &&
-		    ext_cmd_type == EXT_CMD_TYPE_DISPATCH)
-			break;
-
-		if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
-			/* Last read: issue a 'last naked read' */
-			if (info->cur_chunk == info->ntotalchunks - 1)
-				ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
-			else
-				ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
-
-		/*
-		 * If a splitted program command has no more data to transfer,
-		 * the command dispatch must be issued to complete.
-		 */
-		} else if (command == NAND_CMD_PAGEPROG &&
-			   info->cur_chunk == info->ntotalchunks) {
-				ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
-		}
-	} while (1);
-
-	info->state = STATE_IDLE;
-}
-
-static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
-		struct nand_chip *chip, const uint8_t *buf, int oob_required,
-		int page)
-{
-	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
-	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	return nand_prog_page_end_op(chip);
-}
-
-static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
-		struct nand_chip *chip, uint8_t *buf, int oob_required,
-		int page)
-{
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-
-	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
-	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	if (info->retcode == ERR_CORERR && info->use_ecc) {
-		mtd->ecc_stats.corrected += info->ecc_err_cnt;
-
-	} else if (info->retcode == ERR_UNCORERR) {
-		/*
-		 * for blank page (all 0xff), HW will calculate its ECC as
-		 * 0, which is different from the ECC information within
-		 * OOB, ignore such uncorrectable errors
-		 */
-		if (is_buf_blank(buf, mtd->writesize))
-			info->retcode = ERR_NONE;
-		else
-			mtd->ecc_stats.failed++;
-	}
-
-	return info->max_bitflips;
-}
-
-static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	char retval = 0xFF;
-
-	if (info->buf_start < info->buf_count)
-		/* Has just send a new command? */
-		retval = info->data_buff[info->buf_start++];
-
-	return retval;
-}
-
-static u16 pxa3xx_nand_read_word(struct mtd_info *mtd)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	u16 retval = 0xFFFF;
-
-	if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) {
-		retval = *((u16 *)(info->data_buff+info->buf_start));
-		info->buf_start += 2;
-	}
-	return retval;
-}
-
-static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
-
-	memcpy(buf, info->data_buff + info->buf_start, real_len);
-	info->buf_start += real_len;
-}
-
-static void pxa3xx_nand_write_buf(struct mtd_info *mtd,
-		const uint8_t *buf, int len)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
-
-	memcpy(info->data_buff + info->buf_start, buf, real_len);
-	info->buf_start += real_len;
-}
-
-static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip)
-{
-	return;
-}
-
-static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-
-	if (info->need_wait) {
-		info->need_wait = 0;
-		if (!wait_for_completion_timeout(&info->dev_ready,
-		    CHIP_DELAY_TIMEOUT)) {
-			dev_err(&info->pdev->dev, "Ready time out!!!\n");
-			return NAND_STATUS_FAIL;
-		}
-	}
-
-	/* pxa3xx_nand_send_command has waited for command complete */
-	if (this->state == FL_WRITING || this->state == FL_ERASING) {
-		if (info->retcode == ERR_NONE)
-			return 0;
-		else
-			return NAND_STATUS_FAIL;
-	}
-
-	return NAND_STATUS_READY;
-}
-
-static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info)
-{
-	struct pxa3xx_nand_host *host = info->host[info->cs];
-	struct platform_device *pdev = info->pdev;
-	struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	const struct nand_sdr_timings *timings;
-
-	/* Configure default flash values */
-	info->chunk_size = PAGE_CHUNK_SIZE;
-	info->reg_ndcr = 0x0; /* enable all interrupts */
-	info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0;
-	info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES);
-	info->reg_ndcr |= NDCR_SPARE_EN;
-
-	/* use the common timing to make a try */
-	timings = onfi_async_timing_mode_to_sdr_timings(0);
-	if (IS_ERR(timings))
-		return PTR_ERR(timings);
-
-	pxa3xx_nand_set_sdr_timing(host, timings);
-	return 0;
-}
-
-static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info)
-{
-	struct pxa3xx_nand_host *host = info->host[info->cs];
-	struct nand_chip *chip = &host->chip;
-	struct mtd_info *mtd = nand_to_mtd(chip);
-
-	info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0;
-	info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0;
-	info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0;
-}
-
-static void pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
-{
-	struct platform_device *pdev = info->pdev;
-	struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	uint32_t ndcr = nand_readl(info, NDCR);
-
-	/* Set an initial chunk size */
-	info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
-	info->reg_ndcr = ndcr &
-		~(NDCR_INT_MASK | NDCR_ND_ARB_EN | NFCV1_NDCR_ARB_CNTL);
-	info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0;
-	info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
-	info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
-}
-
-static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
-{
-	struct platform_device *pdev = info->pdev;
-	struct dma_slave_config	config;
-	dma_cap_mask_t mask;
-	struct pxad_param param;
-	int ret;
-
-	info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
-	if (info->data_buff == NULL)
-		return -ENOMEM;
-	if (use_dma == 0)
-		return 0;
-
-	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-
-	sg_init_one(&info->sg, info->data_buff, info->buf_size);
-	dma_cap_zero(mask);
-	dma_cap_set(DMA_SLAVE, mask);
-	param.prio = PXAD_PRIO_LOWEST;
-	param.drcmr = info->drcmr_dat;
-	info->dma_chan = dma_request_slave_channel_compat(mask, pxad_filter_fn,
-							  &param, &pdev->dev,
-							  "data");
-	if (!info->dma_chan) {
-		dev_err(&pdev->dev, "unable to request data dma channel\n");
-		return -ENODEV;
-	}
-
-	memset(&config, 0, sizeof(config));
-	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	config.src_addr = info->mmio_phys + NDDB;
-	config.dst_addr = info->mmio_phys + NDDB;
-	config.src_maxburst = 32;
-	config.dst_maxburst = 32;
-	ret = dmaengine_slave_config(info->dma_chan, &config);
-	if (ret < 0) {
-		dev_err(&info->pdev->dev,
-			"dma channel configuration failed: %d\n",
-			ret);
-		return ret;
-	}
-
-	/*
-	 * Now that DMA buffers are allocated we turn on
-	 * DMA proper for I/O operations.
-	 */
-	info->use_dma = 1;
-	return 0;
-}
-
-static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
-{
-	if (info->use_dma) {
-		dmaengine_terminate_all(info->dma_chan);
-		dma_release_channel(info->dma_chan);
-	}
-	kfree(info->data_buff);
-}
-
-static int pxa_ecc_init(struct pxa3xx_nand_info *info,
-			struct mtd_info *mtd,
-			int strength, int ecc_stepsize, int page_size)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct nand_ecc_ctrl *ecc = &chip->ecc;
-
-	if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) {
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 2048;
-		info->spare_size = 40;
-		info->ecc_size = 24;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = 512;
-		ecc->strength = 1;
-
-	} else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) {
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 512;
-		info->spare_size = 8;
-		info->ecc_size = 8;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = 512;
-		ecc->strength = 1;
-
-	/*
-	 * Required ECC: 4-bit correction per 512 bytes
-	 * Select: 16-bit correction per 2048 bytes
-	 */
-	} else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 2048;
-		info->spare_size = 32;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops);
-		ecc->strength = 16;
-
-	} else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 2;
-		info->ntotalchunks = 2;
-		info->chunk_size = 2048;
-		info->spare_size = 32;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops);
-		ecc->strength = 16;
-
-	/*
-	 * Required ECC: 8-bit correction per 512 bytes
-	 * Select: 16-bit correction per 1024 bytes
-	 */
-	} else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 4;
-		info->ntotalchunks = 5;
-		info->chunk_size = 1024;
-		info->spare_size = 0;
-		info->last_chunk_size = 0;
-		info->last_spare_size = 64;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops);
-		ecc->strength = 16;
-	} else {
-		dev_err(&info->pdev->dev,
-			"ECC strength %d at page size %d is not supported\n",
-			strength, page_size);
-		return -ENODEV;
-	}
-
-	dev_info(&info->pdev->dev, "ECC strength %d, ECC step size %d\n",
-		 ecc->strength, ecc->size);
-	return 0;
-}
-
-static int pxa3xx_nand_scan(struct mtd_info *mtd)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
-	struct pxa3xx_nand_info *info = host->info_data;
-	struct platform_device *pdev = info->pdev;
-	struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	int ret;
-	uint16_t ecc_strength, ecc_step;
-
-	if (pdata->keep_config) {
-		pxa3xx_nand_detect_config(info);
-	} else {
-		ret = pxa3xx_nand_config_ident(info);
-		if (ret)
-			return ret;
-	}
-
-	if (info->reg_ndcr & NDCR_DWIDTH_M)
-		chip->options |= NAND_BUSWIDTH_16;
-
-	/* Device detection must be done with ECC disabled */
-	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
-	    info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K)
-		nand_writel(info, NDECCCTRL, 0x0);
-
-	if (pdata->flash_bbt)
-		chip->bbt_options |= NAND_BBT_USE_FLASH;
-
-	chip->ecc.strength = pdata->ecc_strength;
-	chip->ecc.size = pdata->ecc_step_size;
-
-	ret = nand_scan_ident(mtd, 1, NULL);
-	if (ret)
-		return ret;
-
-	if (!pdata->keep_config) {
-		ret = pxa3xx_nand_init(host);
-		if (ret) {
-			dev_err(&info->pdev->dev, "Failed to init nand: %d\n",
-				ret);
-			return ret;
-		}
-	}
-
-	if (chip->bbt_options & NAND_BBT_USE_FLASH) {
-		/*
-		 * We'll use a bad block table stored in-flash and don't
-		 * allow writing the bad block marker to the flash.
-		 */
-		chip->bbt_options |= NAND_BBT_NO_OOB_BBM;
-		chip->bbt_td = &bbt_main_descr;
-		chip->bbt_md = &bbt_mirror_descr;
-	}
-
-	/*
-	 * If the page size is bigger than the FIFO size, let's check
-	 * we are given the right variant and then switch to the extended
-	 * (aka splitted) command handling,
-	 */
-	if (mtd->writesize > PAGE_CHUNK_SIZE) {
-		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
-		    info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) {
-			chip->cmdfunc = nand_cmdfunc_extended;
-		} else {
-			dev_err(&info->pdev->dev,
-				"unsupported page size on this variant\n");
-			return -ENODEV;
-		}
-	}
-
-	ecc_strength = chip->ecc.strength;
-	ecc_step = chip->ecc.size;
-	if (!ecc_strength || !ecc_step) {
-		ecc_strength = chip->ecc_strength_ds;
-		ecc_step = chip->ecc_step_ds;
-	}
-
-	/* Set default ECC strength requirements on non-ONFI devices */
-	if (ecc_strength < 1 && ecc_step < 1) {
-		ecc_strength = 1;
-		ecc_step = 512;
-	}
-
-	ret = pxa_ecc_init(info, mtd, ecc_strength,
-			   ecc_step, mtd->writesize);
-	if (ret)
-		return ret;
-
-	/* calculate addressing information */
-	if (mtd->writesize >= 2048)
-		host->col_addr_cycles = 2;
-	else
-		host->col_addr_cycles = 1;
-
-	/* release the initial buffer */
-	kfree(info->data_buff);
-
-	/* allocate the real data + oob buffer */
-	info->buf_size = mtd->writesize + mtd->oobsize;
-	ret = pxa3xx_nand_init_buff(info);
-	if (ret)
-		return ret;
-	info->oob_buff = info->data_buff + mtd->writesize;
-
-	if ((mtd->size >> chip->page_shift) > 65536)
-		host->row_addr_cycles = 3;
-	else
-		host->row_addr_cycles = 2;
-
-	if (!pdata->keep_config)
-		pxa3xx_nand_config_tail(info);
-
-	return nand_scan_tail(mtd);
-}
-
-static int alloc_nand_resource(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	struct pxa3xx_nand_platform_data *pdata;
-	struct pxa3xx_nand_info *info;
-	struct pxa3xx_nand_host *host;
-	struct nand_chip *chip = NULL;
-	struct mtd_info *mtd;
-	struct resource *r;
-	int ret, irq, cs;
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (pdata->num_cs <= 0) {
-		dev_err(&pdev->dev, "invalid number of chip selects\n");
-		return -ENODEV;
-	}
-
-	info = devm_kzalloc(&pdev->dev,
-			    sizeof(*info) + sizeof(*host) * pdata->num_cs,
-			    GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	info->pdev = pdev;
-	info->variant = pxa3xx_nand_get_variant(pdev);
-	for (cs = 0; cs < pdata->num_cs; cs++) {
-		host = (void *)&info[1] + sizeof(*host) * cs;
-		chip = &host->chip;
-		nand_set_controller_data(chip, host);
-		mtd = nand_to_mtd(chip);
-		info->host[cs] = host;
-		host->cs = cs;
-		host->info_data = info;
-		mtd->dev.parent = &pdev->dev;
-		/* FIXME: all chips use the same device tree partitions */
-		nand_set_flash_node(chip, np);
-
-		nand_set_controller_data(chip, host);
-		chip->ecc.read_page	= pxa3xx_nand_read_page_hwecc;
-		chip->ecc.write_page	= pxa3xx_nand_write_page_hwecc;
-		chip->controller        = &info->controller;
-		chip->waitfunc		= pxa3xx_nand_waitfunc;
-		chip->select_chip	= pxa3xx_nand_select_chip;
-		chip->read_word		= pxa3xx_nand_read_word;
-		chip->read_byte		= pxa3xx_nand_read_byte;
-		chip->read_buf		= pxa3xx_nand_read_buf;
-		chip->write_buf		= pxa3xx_nand_write_buf;
-		chip->options		|= NAND_NO_SUBPAGE_WRITE;
-		chip->cmdfunc		= nand_cmdfunc;
-		chip->onfi_set_features	= nand_onfi_get_set_features_notsupp;
-		chip->onfi_get_features	= nand_onfi_get_set_features_notsupp;
-	}
-
-	nand_hw_control_init(chip->controller);
-	info->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(info->clk)) {
-		ret = PTR_ERR(info->clk);
-		dev_err(&pdev->dev, "failed to get nand clock: %d\n", ret);
-		return ret;
-	}
-	ret = clk_prepare_enable(info->clk);
-	if (ret < 0)
-		return ret;
-
-	if (!np && use_dma) {
-		r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-		if (r == NULL) {
-			dev_err(&pdev->dev,
-				"no resource defined for data DMA\n");
-			ret = -ENXIO;
-			goto fail_disable_clk;
-		}
-		info->drcmr_dat = r->start;
-	}
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "no IRQ resource defined\n");
-		ret = -ENXIO;
-		goto fail_disable_clk;
-	}
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	info->mmio_base = devm_ioremap_resource(&pdev->dev, r);
-	if (IS_ERR(info->mmio_base)) {
-		ret = PTR_ERR(info->mmio_base);
-		dev_err(&pdev->dev, "failed to map register space: %d\n", ret);
-		goto fail_disable_clk;
-	}
-	info->mmio_phys = r->start;
-
-	/* Allocate a buffer to allow flash detection */
-	info->buf_size = INIT_BUFFER_SIZE;
-	info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
-	if (info->data_buff == NULL) {
-		ret = -ENOMEM;
-		goto fail_disable_clk;
-	}
-
-	/* initialize all interrupts to be disabled */
-	disable_int(info, NDSR_MASK);
-
-	ret = request_threaded_irq(irq, pxa3xx_nand_irq,
-				   pxa3xx_nand_irq_thread, IRQF_ONESHOT,
-				   pdev->name, info);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret);
-		goto fail_free_buf;
-	}
-
-	platform_set_drvdata(pdev, info);
-
-	return 0;
-
-fail_free_buf:
-	free_irq(irq, info);
-	kfree(info->data_buff);
-fail_disable_clk:
-	clk_disable_unprepare(info->clk);
-	return ret;
-}
-
-static int pxa3xx_nand_remove(struct platform_device *pdev)
-{
-	struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
-	struct pxa3xx_nand_platform_data *pdata;
-	int irq, cs;
-
-	if (!info)
-		return 0;
-
-	pdata = dev_get_platdata(&pdev->dev);
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq >= 0)
-		free_irq(irq, info);
-	pxa3xx_nand_free_buff(info);
-
-	/*
-	 * In the pxa3xx case, the DFI bus is shared between the SMC and NFC.
-	 * In order to prevent a lockup of the system bus, the DFI bus
-	 * arbitration is granted to SMC upon driver removal. This is done by
-	 * setting the x_ARB_CNTL bit, which also prevents the NAND to have
-	 * access to the bus anymore.
-	 */
-	nand_writel(info, NDCR,
-		    (nand_readl(info, NDCR) & ~NDCR_ND_ARB_EN) |
-		    NFCV1_NDCR_ARB_CNTL);
-	clk_disable_unprepare(info->clk);
-
-	for (cs = 0; cs < pdata->num_cs; cs++)
-		nand_release(nand_to_mtd(&info->host[cs]->chip));
-	return 0;
-}
-
-static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
-{
-	struct pxa3xx_nand_platform_data *pdata;
-	struct device_node *np = pdev->dev.of_node;
-	const struct of_device_id *of_id =
-			of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
-
-	if (!of_id)
-		return 0;
-
-	/*
-	 * Some SoCs like A7k/A8k need to enable manually the NAND
-	 * controller to avoid being bootloader dependent. This is done
-	 * through the use of a single bit in the System Functions registers.
-	 */
-	if (pxa3xx_nand_get_variant(pdev) == PXA3XX_NAND_VARIANT_ARMADA_8K) {
-		struct regmap *sysctrl_base = syscon_regmap_lookup_by_phandle(
-			pdev->dev.of_node, "marvell,system-controller");
-		u32 reg;
-
-		if (IS_ERR(sysctrl_base))
-			return PTR_ERR(sysctrl_base);
-
-		regmap_read(sysctrl_base, GENCONF_SOC_DEVICE_MUX, &reg);
-		reg |= GENCONF_SOC_DEVICE_MUX_NFC_EN;
-		regmap_write(sysctrl_base, GENCONF_SOC_DEVICE_MUX, reg);
-	}
-
-	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata)
-		return -ENOMEM;
-
-	if (of_get_property(np, "marvell,nand-enable-arbiter", NULL))
-		pdata->enable_arbiter = 1;
-	if (of_get_property(np, "marvell,nand-keep-config", NULL))
-		pdata->keep_config = 1;
-	of_property_read_u32(np, "num-cs", &pdata->num_cs);
-
-	pdev->dev.platform_data = pdata;
-
-	return 0;
-}
-
-static int pxa3xx_nand_probe(struct platform_device *pdev)
-{
-	struct pxa3xx_nand_platform_data *pdata;
-	struct pxa3xx_nand_info *info;
-	int ret, cs, probe_success, dma_available;
-
-	dma_available = IS_ENABLED(CONFIG_ARM) &&
-		(IS_ENABLED(CONFIG_ARCH_PXA) || IS_ENABLED(CONFIG_ARCH_MMP));
-	if (use_dma && !dma_available) {
-		use_dma = 0;
-		dev_warn(&pdev->dev,
-			 "This platform can't do DMA on this device\n");
-	}
-
-	ret = pxa3xx_nand_probe_dt(pdev);
-	if (ret)
-		return ret;
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata) {
-		dev_err(&pdev->dev, "no platform data defined\n");
-		return -ENODEV;
-	}
-
-	ret = alloc_nand_resource(pdev);
-	if (ret)
-		return ret;
-
-	info = platform_get_drvdata(pdev);
-	probe_success = 0;
-	for (cs = 0; cs < pdata->num_cs; cs++) {
-		struct mtd_info *mtd = nand_to_mtd(&info->host[cs]->chip);
-
-		/*
-		 * The mtd name matches the one used in 'mtdparts' kernel
-		 * parameter. This name cannot be changed or otherwise
-		 * user's mtd partitions configuration would get broken.
-		 */
-		mtd->name = "pxa3xx_nand-0";
-		info->cs = cs;
-		ret = pxa3xx_nand_scan(mtd);
-		if (ret) {
-			dev_warn(&pdev->dev, "failed to scan nand at cs %d\n",
-				cs);
-			continue;
-		}
-
-		ret = mtd_device_register(mtd, pdata->parts[cs],
-					  pdata->nr_parts[cs]);
-		if (!ret)
-			probe_success = 1;
-	}
-
-	if (!probe_success) {
-		pxa3xx_nand_remove(pdev);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int pxa3xx_nand_suspend(struct device *dev)
-{
-	struct pxa3xx_nand_info *info = dev_get_drvdata(dev);
-
-	if (info->state) {
-		dev_err(dev, "driver busy, state = %d\n", info->state);
-		return -EAGAIN;
-	}
-
-	clk_disable(info->clk);
-	return 0;
-}
-
-static int pxa3xx_nand_resume(struct device *dev)
-{
-	struct pxa3xx_nand_info *info = dev_get_drvdata(dev);
-	int ret;
-
-	ret = clk_enable(info->clk);
-	if (ret < 0)
-		return ret;
-
-	/* We don't want to handle interrupt without calling mtd routine */
-	disable_int(info, NDCR_INT_MASK);
-
-	/*
-	 * Directly set the chip select to a invalid value,
-	 * then the driver would reset the timing according
-	 * to current chip select at the beginning of cmdfunc
-	 */
-	info->cs = 0xff;
-
-	/*
-	 * As the spec says, the NDSR would be updated to 0x1800 when
-	 * doing the nand_clk disable/enable.
-	 * To prevent it damaging state machine of the driver, clear
-	 * all status before resume
-	 */
-	nand_writel(info, NDSR, NDSR_MASK);
-
-	return 0;
-}
-#else
-#define pxa3xx_nand_suspend	NULL
-#define pxa3xx_nand_resume	NULL
-#endif
-
-static const struct dev_pm_ops pxa3xx_nand_pm_ops = {
-	.suspend	= pxa3xx_nand_suspend,
-	.resume		= pxa3xx_nand_resume,
-};
-
-static struct platform_driver pxa3xx_nand_driver = {
-	.driver = {
-		.name	= "pxa3xx-nand",
-		.of_match_table = pxa3xx_nand_dt_ids,
-		.pm	= &pxa3xx_nand_pm_ops,
-	},
-	.probe		= pxa3xx_nand_probe,
-	.remove		= pxa3xx_nand_remove,
-};
-
-module_platform_driver(pxa3xx_nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("PXA3xx NAND controller driver");
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
new file mode 100644
index 0000000..19a2b28
--- /dev/null
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -0,0 +1,537 @@
+config MTD_NAND_ECC
+	tristate
+
+config MTD_NAND_ECC_SMC
+	bool "NAND ECC Smart Media byte order"
+	depends on MTD_NAND_ECC
+	default n
+	help
+	  Software ECC according to the Smart Media Specification.
+	  The original Linux implementation had byte 0 and 1 swapped.
+
+
+menuconfig MTD_NAND
+	tristate "Raw/Parallel NAND Device Support"
+	depends on MTD
+	select MTD_NAND_ECC
+	help
+	  This enables support for accessing all type of raw/parallel
+	  NAND flash devices. For further information see
+	  <http://www.linux-mtd.infradead.org/doc/nand.html>.
+
+if MTD_NAND
+
+config MTD_NAND_BCH
+	tristate
+	select BCH
+	depends on MTD_NAND_ECC_BCH
+	default MTD_NAND
+
+config MTD_NAND_ECC_BCH
+	bool "Support software BCH ECC"
+	default n
+	help
+	  This enables support for software BCH error correction. Binary BCH
+	  codes are more powerful and cpu intensive than traditional Hamming
+	  ECC codes. They are used with NAND devices requiring more than 1 bit
+	  of error correction.
+
+config MTD_SM_COMMON
+	tristate
+	default n
+
+config MTD_NAND_DENALI
+	tristate
+
+config MTD_NAND_DENALI_PCI
+        tristate "Support Denali NAND controller on Intel Moorestown"
+	select MTD_NAND_DENALI
+	depends on HAS_DMA && PCI
+        help
+          Enable the driver for NAND flash on Intel Moorestown, using the
+          Denali NAND controller core.
+
+config MTD_NAND_DENALI_DT
+	tristate "Support Denali NAND controller as a DT device"
+	select MTD_NAND_DENALI
+	depends on HAS_DMA && HAVE_CLK && OF
+	help
+	  Enable the driver for NAND flash on platforms using a Denali NAND
+	  controller as a DT device.
+
+config MTD_NAND_GPIO
+	tristate "GPIO assisted NAND Flash driver"
+	depends on GPIOLIB || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  This enables a NAND flash driver where control signals are
+	  connected to GPIO pins, and commands and data are communicated
+	  via a memory mapped interface.
+
+config MTD_NAND_AMS_DELTA
+	tristate "NAND Flash device on Amstrad E3"
+	depends on MACH_AMS_DELTA
+	default y
+	help
+	  Support for NAND flash on Amstrad E3 (Delta).
+
+config MTD_NAND_OMAP2
+	tristate "NAND Flash device on OMAP2, OMAP3, OMAP4 and Keystone"
+	depends on (ARCH_OMAP2PLUS || ARCH_KEYSTONE)
+	help
+          Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4
+	  and Keystone platforms.
+
+config MTD_NAND_OMAP_BCH
+	depends on MTD_NAND_OMAP2
+	bool "Support hardware based BCH error correction"
+	default n
+	select BCH
+	help
+	  This config enables the ELM hardware engine, which can be used to
+	  locate and correct errors when using BCH ECC scheme. This offloads
+	  the cpu from doing ECC error searching and correction. However some
+	  legacy OMAP families like OMAP2xxx, OMAP3xxx do not have ELM engine
+	  so this is optional for them.
+
+config MTD_NAND_OMAP_BCH_BUILD
+	def_tristate MTD_NAND_OMAP2 && MTD_NAND_OMAP_BCH
+
+config MTD_NAND_RICOH
+	tristate "Ricoh xD card reader"
+	default n
+	depends on PCI
+	select MTD_SM_COMMON
+	help
+	  Enable support for Ricoh R5C852 xD card reader
+	  You also need to enable ether
+	  NAND SSFDC (SmartMedia) read only translation layer' or new
+	  expermental, readwrite
+	  'SmartMedia/xD new translation layer'
+
+config MTD_NAND_AU1550
+	tristate "Au1550/1200 NAND support"
+	depends on MIPS_ALCHEMY
+	help
+	  This enables the driver for the NAND flash controller on the
+	  AMD/Alchemy 1550 SOC.
+
+config MTD_NAND_S3C2410
+	tristate "NAND Flash support for Samsung S3C SoCs"
+	depends on ARCH_S3C24XX || ARCH_S3C64XX
+	help
+	  This enables the NAND flash controller on the S3C24xx and S3C64xx
+	  SoCs
+
+	  No board specific support is done by this driver, each board
+	  must advertise a platform_device for the driver to attach.
+
+config MTD_NAND_S3C2410_DEBUG
+	bool "Samsung S3C NAND driver debug"
+	depends on MTD_NAND_S3C2410
+	help
+	  Enable debugging of the S3C NAND driver
+
+config MTD_NAND_NDFC
+	tristate "NDFC NanD Flash Controller"
+	depends on 4xx
+	select MTD_NAND_ECC_SMC
+	help
+	 NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs
+
+config MTD_NAND_S3C2410_CLKSTOP
+	bool "Samsung S3C NAND IDLE clock stop"
+	depends on MTD_NAND_S3C2410
+	default n
+	help
+	  Stop the clock to the NAND controller when there is no chip
+	  selected to save power. This will mean there is a small delay
+	  when the is NAND chip selected or released, but will save
+	  approximately 5mA of power when there is nothing happening.
+
+config MTD_NAND_TANGO
+	tristate "NAND Flash support for Tango chips"
+	depends on ARCH_TANGO || COMPILE_TEST
+	depends on HAS_DMA
+	help
+	  Enables the NAND Flash controller on Tango chips.
+
+config MTD_NAND_DISKONCHIP
+	tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation)"
+	depends on HAS_IOMEM
+	select REED_SOLOMON
+	select REED_SOLOMON_DEC16
+	help
+	  This is a reimplementation of M-Systems DiskOnChip 2000,
+	  Millennium and Millennium Plus as a standard NAND device driver,
+	  as opposed to the earlier self-contained MTD device drivers.
+	  This should enable, among other things, proper JFFS2 operation on
+	  these devices.
+
+config MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+        bool "Advanced detection options for DiskOnChip"
+        depends on MTD_NAND_DISKONCHIP
+        help
+          This option allows you to specify nonstandard address at which to
+          probe for a DiskOnChip, or to change the detection options.  You
+          are unlikely to need any of this unless you are using LinuxBIOS.
+          Say 'N'.
+
+config MTD_NAND_DISKONCHIP_PROBE_ADDRESS
+        hex "Physical address of DiskOnChip" if MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+        depends on MTD_NAND_DISKONCHIP
+        default "0"
+        ---help---
+        By default, the probe for DiskOnChip devices will look for a
+        DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
+        This option allows you to specify a single address at which to probe
+        for the device, which is useful if you have other devices in that
+        range which get upset when they are probed.
+
+        (Note that on PowerPC, the normal probe will only check at
+        0xE4000000.)
+
+        Normally, you should leave this set to zero, to allow the probe at
+        the normal addresses.
+
+config MTD_NAND_DISKONCHIP_PROBE_HIGH
+        bool "Probe high addresses"
+        depends on MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+        help
+          By default, the probe for DiskOnChip devices will look for a
+          DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
+          This option changes to make it probe between 0xFFFC8000 and
+          0xFFFEE000.  Unless you are using LinuxBIOS, this is unlikely to be
+          useful to you.  Say 'N'.
+
+config MTD_NAND_DISKONCHIP_BBTWRITE
+	bool "Allow BBT writes on DiskOnChip Millennium and 2000TSOP"
+	depends on MTD_NAND_DISKONCHIP
+	help
+	  On DiskOnChip devices shipped with the INFTL filesystem (Millennium
+	  and 2000 TSOP/Alon), Linux reserves some space at the end of the
+	  device for the Bad Block Table (BBT).  If you have existing INFTL
+	  data on your device (created by non-Linux tools such as M-Systems'
+	  DOS drivers), your data might overlap the area Linux wants to use for
+	  the BBT.  If this is a concern for you, leave this option disabled and
+	  Linux will not write BBT data into this area.
+	  The downside of leaving this option disabled is that if bad blocks
+	  are detected by Linux, they will not be recorded in the BBT, which
+	  could cause future problems.
+	  Once you enable this option, new filesystems (INFTL or others, created
+	  in Linux or other operating systems) will not use the reserved area.
+	  The only reason not to enable this option is to prevent damage to
+	  preexisting filesystems.
+	  Even if you leave this disabled, you can enable BBT writes at module
+	  load time (assuming you build diskonchip as a module) with the module
+	  parameter "inftl_bbt_write=1".
+
+config MTD_NAND_DOCG4
+	tristate "Support for DiskOnChip G4"
+	depends on HAS_IOMEM
+	select BCH
+	select BITREVERSE
+	help
+	  Support for diskonchip G4 nand flash, found in various smartphones and
+	  PDAs, among them the Palm Treo680, HTC Prophet and Wizard, Toshiba
+	  Portege G900, Asus P526, and O2 XDA Zinc.
+
+	  With this driver you will be able to use UBI and create a ubifs on the
+	  device, so you may wish to consider enabling UBI and UBIFS as well.
+
+	  These devices ship with the Mys/Sandisk SAFTL formatting, for which
+	  there is currently no mtd parser, so you may want to use command line
+	  partitioning to segregate write-protected blocks. On the Treo680, the
+	  first five erase blocks (256KiB each) are write-protected, followed
+	  by the block containing the saftl partition table.  This is probably
+	  typical.
+
+config MTD_NAND_SHARPSL
+	tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
+	depends on ARCH_PXA
+
+config MTD_NAND_CAFE
+	tristate "NAND support for OLPC CAFÉ chip"
+	depends on PCI
+	select REED_SOLOMON
+	select REED_SOLOMON_DEC16
+	help
+	  Use NAND flash attached to the CAFÉ chip designed for the OLPC
+	  laptop.
+
+config MTD_NAND_CS553X
+	tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
+	depends on X86_32
+	depends on !UML && HAS_IOMEM
+	help
+	  The CS553x companion chips for the AMD Geode processor
+	  include NAND flash controllers with built-in hardware ECC
+	  capabilities; enabling this option will allow you to use
+	  these. The driver will check the MSRs to verify that the
+	  controller is enabled for NAND, and currently requires that
+	  the controller be in MMIO mode.
+
+	  If you say "m", the module will be called cs553x_nand.
+
+config MTD_NAND_ATMEL
+	tristate "Support for NAND Flash / SmartMedia on AT91"
+	depends on ARCH_AT91
+	select MFD_ATMEL_SMC
+	help
+	  Enables support for NAND Flash / Smart Media Card interface
+	  on Atmel AT91 processors.
+
+config MTD_NAND_MARVELL
+	tristate "NAND controller support on Marvell boards"
+	depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
+		   COMPILE_TEST
+	depends on HAS_IOMEM && HAS_DMA
+	help
+	  This enables the NAND flash controller driver for Marvell boards,
+	  including:
+	  - PXA3xx processors (NFCv1)
+	  - 32-bit Armada platforms (XP, 37x, 38x, 39x) (NFCv2)
+	  - 64-bit Aramda platforms (7k, 8k) (NFCv2)
+
+config MTD_NAND_SLC_LPC32XX
+	tristate "NXP LPC32xx SLC Controller"
+	depends on ARCH_LPC32XX
+	help
+	  Enables support for NXP's LPC32XX SLC (i.e. for Single Level Cell
+	  chips) NAND controller. This is the default for the PHYTEC 3250
+	  reference board which contains a NAND256R3A2CZA6 chip.
+
+	  Please check the actual NAND chip connected and its support
+	  by the SLC NAND controller.
+
+config MTD_NAND_MLC_LPC32XX
+	tristate "NXP LPC32xx MLC Controller"
+	depends on ARCH_LPC32XX
+	help
+	  Uses the LPC32XX MLC (i.e. for Multi Level Cell chips) NAND
+	  controller. This is the default for the WORK92105 controller
+	  board.
+
+	  Please check the actual NAND chip connected and its support
+	  by the MLC NAND controller.
+
+config MTD_NAND_CM_X270
+	tristate "Support for NAND Flash on CM-X270 modules"
+	depends on MACH_ARMCORE
+
+config MTD_NAND_PASEMI
+	tristate "NAND support for PA Semi PWRficient"
+	depends on PPC_PASEMI
+	help
+	  Enables support for NAND Flash interface on PA Semi PWRficient
+	  based boards
+
+config MTD_NAND_TMIO
+	tristate "NAND Flash device on Toshiba Mobile IO Controller"
+	depends on MFD_TMIO
+	help
+	  Support for NAND flash connected to a Toshiba Mobile IO
+	  Controller in some PDAs, including the Sharp SL6000x.
+
+config MTD_NAND_NANDSIM
+	tristate "Support for NAND Flash Simulator"
+	help
+	  The simulator may simulate various NAND flash chips for the
+	  MTD nand layer.
+
+config MTD_NAND_GPMI_NAND
+        tristate "GPMI NAND Flash Controller driver"
+        depends on MTD_NAND && MXS_DMA
+        help
+	 Enables NAND Flash support for IMX23, IMX28 or IMX6.
+	 The GPMI controller is very powerful, with the help of BCH
+	 module, it can do the hardware ECC. The GPMI supports several
+	 NAND flashs at the same time.
+
+config MTD_NAND_BRCMNAND
+	tristate "Broadcom STB NAND controller"
+	depends on ARM || ARM64 || MIPS
+	help
+	  Enables the Broadcom NAND controller driver. The controller was
+	  originally designed for Set-Top Box but is used on various BCM7xxx,
+	  BCM3xxx, BCM63xxx, iProc/Cygnus and more.
+
+config MTD_NAND_BCM47XXNFLASH
+	tristate "Support for NAND flash on BCM4706 BCMA bus"
+	depends on BCMA_NFLASH
+	help
+	  BCMA bus can have various flash memories attached, they are
+	  registered by bcma as platform devices. This enables driver for
+	  NAND flash memories. For now only BCM4706 is supported.
+
+config MTD_NAND_PLATFORM
+	tristate "Support for generic platform NAND driver"
+	depends on HAS_IOMEM
+	help
+	  This implements a generic NAND driver for on-SOC platform
+	  devices. You will need to provide platform-specific functions
+	  via platform_data.
+
+config MTD_NAND_ORION
+	tristate "NAND Flash support for Marvell Orion SoC"
+	depends on PLAT_ORION
+	help
+	  This enables the NAND flash controller on Orion machines.
+
+	  No board specific support is done by this driver, each board
+	  must advertise a platform_device for the driver to attach.
+
+config MTD_NAND_OXNAS
+	tristate "NAND Flash support for Oxford Semiconductor SoC"
+	depends on ARCH_OXNAS || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  This enables the NAND flash controller on Oxford Semiconductor SoCs.
+
+config MTD_NAND_FSL_ELBC
+	tristate "NAND support for Freescale eLBC controllers"
+	depends on FSL_SOC
+	select FSL_LBC
+	help
+	  Various Freescale chips, including the 8313, include a NAND Flash
+	  Controller Module with built-in hardware ECC capabilities.
+	  Enabling this option will enable you to use this to control
+	  external NAND devices.
+
+config MTD_NAND_FSL_IFC
+	tristate "NAND support for Freescale IFC controller"
+	depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A
+	select FSL_IFC
+	select MEMORY
+	help
+	  Various Freescale chips e.g P1010, include a NAND Flash machine
+	  with built-in hardware ECC capabilities.
+	  Enabling this option will enable you to use this to control
+	  external NAND devices.
+
+config MTD_NAND_FSL_UPM
+	tristate "Support for NAND on Freescale UPM"
+	depends on PPC_83xx || PPC_85xx
+	select FSL_LBC
+	help
+	  Enables support for NAND Flash chips wired onto Freescale PowerPC
+	  processor localbus with User-Programmable Machine support.
+
+config MTD_NAND_MPC5121_NFC
+	tristate "MPC5121 built-in NAND Flash Controller support"
+	depends on PPC_MPC512x
+	help
+	  This enables the driver for the NAND flash controller on the
+	  MPC5121 SoC.
+
+config MTD_NAND_VF610_NFC
+	tristate "Support for Freescale NFC for VF610/MPC5125"
+	depends on (SOC_VF610 || COMPILE_TEST)
+	depends on HAS_IOMEM
+	help
+	  Enables support for NAND Flash Controller on some Freescale
+	  processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
+	  The driver supports a maximum 2k page size. With 2k pages and
+	  64 bytes or more of OOB, hardware ECC with up to 32-bit error
+	  correction is supported. Hardware ECC is only enabled through
+	  device tree.
+
+config MTD_NAND_MXC
+	tristate "MXC NAND support"
+	depends on ARCH_MXC
+	help
+	  This enables the driver for the NAND flash controller on the
+	  MXC processors.
+
+config MTD_NAND_SH_FLCTL
+	tristate "Support for NAND on Renesas SuperH FLCTL"
+	depends on SUPERH || COMPILE_TEST
+	depends on HAS_IOMEM
+	depends on HAS_DMA
+	help
+	  Several Renesas SuperH CPU has FLCTL. This option enables support
+	  for NAND Flash using FLCTL.
+
+config MTD_NAND_DAVINCI
+        tristate "Support NAND on DaVinci/Keystone SoC"
+        depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF)
+        help
+	  Enable the driver for NAND flash chips on Texas Instruments
+	  DaVinci/Keystone processors.
+
+config MTD_NAND_TXX9NDFMC
+	tristate "NAND Flash support for TXx9 SoC"
+	depends on SOC_TX4938 || SOC_TX4939
+	help
+	  This enables the NAND flash controller on the TXx9 SoCs.
+
+config MTD_NAND_SOCRATES
+	tristate "Support for NAND on Socrates board"
+	depends on SOCRATES
+	help
+	  Enables support for NAND Flash chips wired onto Socrates board.
+
+config MTD_NAND_NUC900
+	tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards."
+	depends on ARCH_W90X900
+	help
+	  This enables the driver for the NAND Flash on evaluation board based
+	  on w90p910 / NUC9xx.
+
+config MTD_NAND_JZ4740
+	tristate "Support for JZ4740 SoC NAND controller"
+	depends on MACH_JZ4740
+	help
+		Enables support for NAND Flash on JZ4740 SoC based boards.
+
+config MTD_NAND_JZ4780
+	tristate "Support for NAND on JZ4780 SoC"
+	depends on MACH_JZ4780 && JZ4780_NEMC
+	help
+	  Enables support for NAND Flash connected to the NEMC on JZ4780 SoC
+	  based boards, using the BCH controller for hardware error correction.
+
+config MTD_NAND_FSMC
+	tristate "Support for NAND on ST Micros FSMC"
+	depends on OF
+	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)
+
+config MTD_NAND_XWAY
+	bool "Support for NAND on Lantiq XWAY SoC"
+	depends on LANTIQ && SOC_TYPE_XWAY
+	help
+	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
+	  to the External Bus Unit (EBU).
+
+config MTD_NAND_SUNXI
+	tristate "Support for NAND on Allwinner SoCs"
+	depends on ARCH_SUNXI
+	help
+	  Enables support for NAND Flash chips on Allwinner SoCs.
+
+config MTD_NAND_HISI504
+	tristate "Support for NAND controller on Hisilicon SoC Hip04"
+	depends on ARCH_HISI || COMPILE_TEST
+	depends on HAS_DMA
+	help
+	  Enables support for NAND controller on Hisilicon SoC Hip04.
+
+config MTD_NAND_QCOM
+	tristate "Support for NAND on QCOM SoCs"
+	depends on ARCH_QCOM
+	help
+	  Enables support for NAND flash chips on SoCs containing the EBI2 NAND
+	  controller. This controller is found on IPQ806x SoC.
+
+config MTD_NAND_MTK
+	tristate "Support for NAND controller on MTK SoCs"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on HAS_DMA
+	help
+	  Enables support for NAND controller on MTK SoCs.
+	  This controller is found on mt27xx, mt81xx, mt65xx SoCs.
+
+endif # MTD_NAND
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
new file mode 100644
index 0000000..165b7ef
--- /dev/null
+++ b/drivers/mtd/nand/raw/Makefile
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_MTD_NAND)			+= nand.o
+obj-$(CONFIG_MTD_NAND_ECC)		+= nand_ecc.o
+obj-$(CONFIG_MTD_NAND_BCH)		+= nand_bch.o
+obj-$(CONFIG_MTD_SM_COMMON) 		+= sm_common.o
+
+obj-$(CONFIG_MTD_NAND_CAFE)		+= cafe_nand.o
+obj-$(CONFIG_MTD_NAND_AMS_DELTA)	+= ams-delta.o
+obj-$(CONFIG_MTD_NAND_DENALI)		+= denali.o
+obj-$(CONFIG_MTD_NAND_DENALI_PCI)	+= denali_pci.o
+obj-$(CONFIG_MTD_NAND_DENALI_DT)	+= denali_dt.o
+obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550nd.o
+obj-$(CONFIG_MTD_NAND_S3C2410)		+= s3c2410.o
+obj-$(CONFIG_MTD_NAND_TANGO)		+= tango_nand.o
+obj-$(CONFIG_MTD_NAND_DAVINCI)		+= davinci_nand.o
+obj-$(CONFIG_MTD_NAND_DISKONCHIP)	+= diskonchip.o
+obj-$(CONFIG_MTD_NAND_DOCG4)		+= docg4.o
+obj-$(CONFIG_MTD_NAND_FSMC)		+= fsmc_nand.o
+obj-$(CONFIG_MTD_NAND_SHARPSL)		+= sharpsl.o
+obj-$(CONFIG_MTD_NAND_NANDSIM)		+= nandsim.o
+obj-$(CONFIG_MTD_NAND_CS553X)		+= cs553x_nand.o
+obj-$(CONFIG_MTD_NAND_NDFC)		+= ndfc.o
+obj-$(CONFIG_MTD_NAND_ATMEL)		+= atmel/
+obj-$(CONFIG_MTD_NAND_GPIO)		+= gpio.o
+omap2_nand-objs := omap2.o
+obj-$(CONFIG_MTD_NAND_OMAP2) 		+= omap2_nand.o
+obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD)	+= omap_elm.o
+obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270_nand.o
+obj-$(CONFIG_MTD_NAND_MARVELL)		+= marvell_nand.o
+obj-$(CONFIG_MTD_NAND_TMIO)		+= tmio_nand.o
+obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
+obj-$(CONFIG_MTD_NAND_PASEMI)		+= pasemi_nand.o
+obj-$(CONFIG_MTD_NAND_ORION)		+= orion_nand.o
+obj-$(CONFIG_MTD_NAND_OXNAS)		+= oxnas_nand.o
+obj-$(CONFIG_MTD_NAND_FSL_ELBC)		+= fsl_elbc_nand.o
+obj-$(CONFIG_MTD_NAND_FSL_IFC)		+= fsl_ifc_nand.o
+obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
+obj-$(CONFIG_MTD_NAND_SLC_LPC32XX)      += lpc32xx_slc.o
+obj-$(CONFIG_MTD_NAND_MLC_LPC32XX)      += lpc32xx_mlc.o
+obj-$(CONFIG_MTD_NAND_SH_FLCTL)		+= sh_flctl.o
+obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
+obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
+obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
+obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o
+obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mpc5121_nfc.o
+obj-$(CONFIG_MTD_NAND_VF610_NFC)	+= vf610_nfc.o
+obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
+obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
+obj-$(CONFIG_MTD_NAND_JZ4780)		+= jz4780_nand.o jz4780_bch.o
+obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
+obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
+obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
+obj-$(CONFIG_MTD_NAND_SUNXI)		+= sunxi_nand.o
+obj-$(CONFIG_MTD_NAND_HISI504)	        += hisi504_nand.o
+obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand/
+obj-$(CONFIG_MTD_NAND_QCOM)		+= qcom_nandc.o
+obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_ecc.o mtk_nand.o
+
+nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o
+nand-objs += nand_amd.o
+nand-objs += nand_hynix.o
+nand-objs += nand_macronix.o
+nand-objs += nand_micron.o
+nand-objs += nand_samsung.o
+nand-objs += nand_toshiba.o
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
similarity index 95%
rename from drivers/mtd/nand/ams-delta.c
rename to drivers/mtd/nand/raw/ams-delta.c
index d60ada4..37a3cc2 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -1,11 +1,12 @@
 /*
- *  drivers/mtd/nand/ams-delta.c
- *
  *  Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
  *
- *  Derived from drivers/mtd/toto.c
+ *  Derived from drivers/mtd/nand/toto.c (removed in v2.6.28)
+ *    Copyright (c) 2003 Texas Instruments
+ *    Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
+ *
  *  Converted to platform driver by Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
- *  Partially stolen from drivers/mtd/nand/plat_nand.c
+ *  Partially stolen from plat_nand.c
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -185,7 +186,7 @@ static int ams_delta_init(struct platform_device *pdev)
 	/* Allocate memory for MTD device structure and private data */
 	this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
 	if (!this) {
-		printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n");
+		pr_warn("Unable to allocate E3 NAND MTD device structure.\n");
 		err = -ENOMEM;
 		goto out;
 	}
@@ -219,7 +220,7 @@ static int ams_delta_init(struct platform_device *pdev)
 		this->dev_ready = ams_delta_nand_ready;
 	} else {
 		this->dev_ready = NULL;
-		printk(KERN_NOTICE "Couldn't request gpio for Delta NAND ready.\n");
+		pr_notice("Couldn't request gpio for Delta NAND ready.\n");
 	}
 	/* 25 us command delay time */
 	this->chip_delay = 30;
diff --git a/drivers/mtd/nand/atmel/Makefile b/drivers/mtd/nand/raw/atmel/Makefile
similarity index 100%
rename from drivers/mtd/nand/atmel/Makefile
rename to drivers/mtd/nand/raw/atmel/Makefile
diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
similarity index 99%
rename from drivers/mtd/nand/atmel/nand-controller.c
rename to drivers/mtd/nand/raw/atmel/nand-controller.c
index b2f00b3..12f6753 100644
--- a/drivers/mtd/nand/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -9,10 +9,10 @@
  *
  *   Copyright 2003 Rick Bronson
  *
- *   Derived from drivers/mtd/nand/autcpu12.c
+ *   Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8)
  *	Copyright 2001 Thomas Gleixner (gleixner@autronix.de)
  *
- *   Derived from drivers/mtd/spia.c
+ *   Derived from drivers/mtd/spia.c (removed in v3.8)
  *	Copyright 2000 Steven J. Hill (sjhill@cotw.com)
  *
  *
diff --git a/drivers/mtd/nand/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c
similarity index 99%
rename from drivers/mtd/nand/atmel/pmecc.c
rename to drivers/mtd/nand/raw/atmel/pmecc.c
index ca0a703..555a74e 100644
--- a/drivers/mtd/nand/atmel/pmecc.c
+++ b/drivers/mtd/nand/raw/atmel/pmecc.c
@@ -9,10 +9,10 @@
  *
  *   Copyright 2003 Rick Bronson
  *
- *   Derived from drivers/mtd/nand/autcpu12.c
+ *   Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8)
  *	Copyright 2001 Thomas Gleixner (gleixner@autronix.de)
  *
- *   Derived from drivers/mtd/spia.c
+ *   Derived from drivers/mtd/spia.c (removed in v3.8)
  *	Copyright 2000 Steven J. Hill (sjhill@cotw.com)
  *
  *   Add Hardware ECC support for AT91SAM9260 / AT91SAM9263
diff --git a/drivers/mtd/nand/atmel/pmecc.h b/drivers/mtd/nand/raw/atmel/pmecc.h
similarity index 94%
rename from drivers/mtd/nand/atmel/pmecc.h
rename to drivers/mtd/nand/raw/atmel/pmecc.h
index 817e0dd..808f1be 100644
--- a/drivers/mtd/nand/atmel/pmecc.h
+++ b/drivers/mtd/nand/raw/atmel/pmecc.h
@@ -9,10 +9,10 @@
  *
  *    Copyright © 2003 Rick Bronson
  *
- *    Derived from drivers/mtd/nand/autcpu12.c
+ *    Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8)
  *        Copyright © 2001 Thomas Gleixner (gleixner@autronix.de)
  *
- *    Derived from drivers/mtd/spia.c
+ *    Derived from drivers/mtd/spia.c (removed in v3.8)
  *        Copyright © 2000 Steven J. Hill (sjhill@cotw.com)
  *
  *
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/raw/au1550nd.c
similarity index 99%
rename from drivers/mtd/nand/au1550nd.c
rename to drivers/mtd/nand/raw/au1550nd.c
index 8ab827e..df0ef1f 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/raw/au1550nd.c
@@ -1,6 +1,4 @@
 /*
- *  drivers/mtd/nand/au1550nd.c
- *
  *  Copyright (C) 2004 Embedded Edge, LLC
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/nand/bcm47xxnflash/Makefile b/drivers/mtd/nand/raw/bcm47xxnflash/Makefile
similarity index 100%
rename from drivers/mtd/nand/bcm47xxnflash/Makefile
rename to drivers/mtd/nand/raw/bcm47xxnflash/Makefile
diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/raw/bcm47xxnflash/bcm47xxnflash.h
similarity index 100%
rename from drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
rename to drivers/mtd/nand/raw/bcm47xxnflash/bcm47xxnflash.h
diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/raw/bcm47xxnflash/main.c
similarity index 100%
rename from drivers/mtd/nand/bcm47xxnflash/main.c
rename to drivers/mtd/nand/raw/bcm47xxnflash/main.c
diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
similarity index 98%
rename from drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
rename to drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
index 54bac5b..60874de 100644
--- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
+++ b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
@@ -392,8 +392,8 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
 	b47n->nand_chip.read_byte = bcm47xxnflash_ops_bcm4706_read_byte;
 	b47n->nand_chip.read_buf = bcm47xxnflash_ops_bcm4706_read_buf;
 	b47n->nand_chip.write_buf = bcm47xxnflash_ops_bcm4706_write_buf;
-	b47n->nand_chip.onfi_set_features = nand_onfi_get_set_features_notsupp;
-	b47n->nand_chip.onfi_get_features = nand_onfi_get_set_features_notsupp;
+	b47n->nand_chip.set_features = nand_get_set_features_notsupp;
+	b47n->nand_chip.get_features = nand_get_set_features_notsupp;
 
 	nand_chip->chip_delay = 50;
 	b47n->nand_chip.bbt_options = NAND_BBT_USE_FLASH;
diff --git a/drivers/mtd/nand/brcmnand/Makefile b/drivers/mtd/nand/raw/brcmnand/Makefile
similarity index 100%
rename from drivers/mtd/nand/brcmnand/Makefile
rename to drivers/mtd/nand/raw/brcmnand/Makefile
diff --git a/drivers/mtd/nand/brcmnand/bcm63138_nand.c b/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
similarity index 100%
rename from drivers/mtd/nand/brcmnand/bcm63138_nand.c
rename to drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
diff --git a/drivers/mtd/nand/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c
similarity index 100%
rename from drivers/mtd/nand/brcmnand/bcm6368_nand.c
rename to drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
similarity index 99%
rename from drivers/mtd/nand/brcmnand/brcmnand.c
rename to drivers/mtd/nand/raw/brcmnand/brcmnand.c
index c28fd2b..1306aaa 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2297,7 +2297,11 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
 	if (ret)
 		return ret;
 
-	return mtd_device_register(mtd, NULL, 0);
+	ret = mtd_device_register(mtd, NULL, 0);
+	if (ret)
+		nand_cleanup(chip);
+
+	return ret;
 }
 
 static void brcmnand_save_restore_cs_config(struct brcmnand_host *host,
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
similarity index 100%
rename from drivers/mtd/nand/brcmnand/brcmnand.h
rename to drivers/mtd/nand/raw/brcmnand/brcmnand.h
diff --git a/drivers/mtd/nand/brcmnand/brcmstb_nand.c b/drivers/mtd/nand/raw/brcmnand/brcmstb_nand.c
similarity index 100%
rename from drivers/mtd/nand/brcmnand/brcmstb_nand.c
rename to drivers/mtd/nand/raw/brcmnand/brcmstb_nand.c
diff --git a/drivers/mtd/nand/brcmnand/iproc_nand.c b/drivers/mtd/nand/raw/brcmnand/iproc_nand.c
similarity index 100%
rename from drivers/mtd/nand/brcmnand/iproc_nand.c
rename to drivers/mtd/nand/raw/brcmnand/iproc_nand.c
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
similarity index 98%
rename from drivers/mtd/nand/cafe_nand.c
rename to drivers/mtd/nand/raw/cafe_nand.c
index 567ff97..d8c8c9d 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -645,8 +645,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	cafe->nand.read_buf = cafe_read_buf;
 	cafe->nand.write_buf = cafe_write_buf;
 	cafe->nand.select_chip = cafe_select_chip;
-	cafe->nand.onfi_set_features = nand_onfi_get_set_features_notsupp;
-	cafe->nand.onfi_get_features = nand_onfi_get_set_features_notsupp;
+	cafe->nand.set_features = nand_get_set_features_notsupp;
+	cafe->nand.get_features = nand_get_set_features_notsupp;
 
 	cafe->nand.chip_delay = 0;
 
@@ -751,8 +751,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 		cafe->nand.bbt_td = &cafe_bbt_main_descr_512;
 		cafe->nand.bbt_md = &cafe_bbt_mirror_descr_512;
 	} else {
-		printk(KERN_WARNING "Unexpected NAND flash writesize %d. Aborting\n",
-		       mtd->writesize);
+		pr_warn("Unexpected NAND flash writesize %d. Aborting\n",
+			mtd->writesize);
 		goto out_free_dma;
 	}
 	cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
@@ -774,10 +774,14 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	pci_set_drvdata(pdev, mtd);
 
 	mtd->name = "cafe_nand";
-	mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0);
+	err = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0);
+	if (err)
+		goto out_cleanup_nand;
 
 	goto out;
 
+ out_cleanup_nand:
+	nand_cleanup(&cafe->nand);
  out_free_dma:
 	dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr);
  out_irq:
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/raw/cmx270_nand.c
similarity index 98%
rename from drivers/mtd/nand/cmx270_nand.c
rename to drivers/mtd/nand/raw/cmx270_nand.c
index b01c980..02d6751 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/raw/cmx270_nand.c
@@ -1,10 +1,8 @@
 /*
- *  linux/drivers/mtd/nand/cmx270-nand.c
- *
  *  Copyright (C) 2006 Compulab, Ltd.
  *  Mike Rapoport <mike@compulab.co.il>
  *
- *  Derived from drivers/mtd/nand/h1910.c
+ *  Derived from drivers/mtd/nand/h1910.c (removed in v3.10)
  *       Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
  *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
  *
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/raw/cs553x_nand.c
similarity index 95%
rename from drivers/mtd/nand/cs553x_nand.c
rename to drivers/mtd/nand/raw/cs553x_nand.c
index d488775..82269fd 100644
--- a/drivers/mtd/nand/cs553x_nand.c
+++ b/drivers/mtd/nand/raw/cs553x_nand.c
@@ -1,6 +1,4 @@
 /*
- * drivers/mtd/nand/cs553x_nand.c
- *
  * (C) 2005, 2006 Red Hat Inc.
  *
  * Author: David Woodhouse <dwmw2@infradead.org>
@@ -189,10 +187,11 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
 	struct nand_chip *this;
 	struct mtd_info *new_mtd;
 
-	printk(KERN_NOTICE "Probing CS553x NAND controller CS#%d at %sIO 0x%08lx\n", cs, mmio?"MM":"P", adr);
+	pr_notice("Probing CS553x NAND controller CS#%d at %sIO 0x%08lx\n",
+		  cs, mmio ? "MM" : "P", adr);
 
 	if (!mmio) {
-		printk(KERN_NOTICE "PIO mode not yet implemented for CS553X NAND controller\n");
+		pr_notice("PIO mode not yet implemented for CS553X NAND controller\n");
 		return -ENXIO;
 	}
 
@@ -211,7 +210,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
 	/* map physical address */
 	this->IO_ADDR_R = this->IO_ADDR_W = ioremap(adr, 4096);
 	if (!this->IO_ADDR_R) {
-		printk(KERN_WARNING "ioremap cs553x NAND @0x%08lx failed\n", adr);
+		pr_warn("ioremap cs553x NAND @0x%08lx failed\n", adr);
 		err = -EIO;
 		goto out_mtd;
 	}
@@ -295,7 +294,7 @@ static int __init cs553x_init(void)
 	/* If it doesn't have the NAND controller enabled, abort */
 	rdmsrl(MSR_DIVIL_BALL_OPTS, val);
 	if (val & PIN_OPT_IDE) {
-		printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n");
+		pr_info("CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n");
 		return -ENXIO;
 	}
 
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c
similarity index 99%
rename from drivers/mtd/nand/davinci_nand.c
rename to drivers/mtd/nand/raw/davinci_nand.c
index ccc8c43..0f09518 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/raw/davinci_nand.c
@@ -826,7 +826,7 @@ static int nand_davinci_probe(struct platform_device *pdev)
 	else
 		ret = mtd_device_register(mtd, NULL, 0);
 	if (ret < 0)
-		goto err;
+		goto err_cleanup_nand;
 
 	val = davinci_nand_readl(info, NRCSR_OFFSET);
 	dev_info(&pdev->dev, "controller rev. %d.%d\n",
@@ -834,6 +834,9 @@ static int nand_davinci_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_cleanup_nand:
+	nand_cleanup(&info->chip);
+
 err:
 	clk_disable_unprepare(info->clk);
 
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/raw/denali.c
similarity index 99%
rename from drivers/mtd/nand/denali.c
rename to drivers/mtd/nand/raw/denali.c
index 313c7f5..2a302a1 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -1384,10 +1384,12 @@ int denali_init(struct denali_nand_info *denali)
 	ret = mtd_device_register(mtd, NULL, 0);
 	if (ret) {
 		dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
-		goto free_buf;
+		goto cleanup_nand;
 	}
 	return 0;
 
+cleanup_nand:
+	nand_cleanup(chip);
 free_buf:
 	kfree(denali->buf);
 disable_irq:
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/raw/denali.h
similarity index 100%
rename from drivers/mtd/nand/denali.h
rename to drivers/mtd/nand/raw/denali.h
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c
similarity index 100%
rename from drivers/mtd/nand/denali_dt.c
rename to drivers/mtd/nand/raw/denali_dt.c
diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/raw/denali_pci.c
similarity index 100%
rename from drivers/mtd/nand/denali_pci.c
rename to drivers/mtd/nand/raw/denali_pci.c
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c
similarity index 94%
rename from drivers/mtd/nand/diskonchip.c
rename to drivers/mtd/nand/raw/diskonchip.c
index 6bc93ea..86a258de 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/raw/diskonchip.c
@@ -1,6 +1,4 @@
 /*
- * drivers/mtd/nand/diskonchip.c
- *
  * (C) 2003 Red Hat, Inc.
  * (C) 2004 Dan Brown <dan_brown@ieee.org>
  * (C) 2004 Kalev Lember <kalev@smartlink.ee>
@@ -411,7 +409,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
 
 		ident.dword = readl(docptr + DoC_2k_CDSN_IO);
 		if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
-			printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n");
+			pr_info("DiskOnChip 2000 responds to DWORD access\n");
 			this->read_buf = &doc2000_readbuf_dword;
 		}
 	}
@@ -438,7 +436,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd)
 			break;
 	}
 	doc->chips_per_floor = i;
-	printk(KERN_DEBUG "Detected %d chips per floor.\n", i);
+	pr_debug("Detected %d chips per floor.\n", i);
 }
 
 static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this)
@@ -934,14 +932,15 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat,
 
 		ret = doc_ecc_decode(rs_decoder, dat, calc_ecc);
 		if (ret > 0)
-			printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
+			pr_err("doc200x_correct_data corrected %d errors\n",
+			       ret);
 	}
 	if (DoC_is_MillenniumPlus(doc))
 		WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
 	else
 		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
 	if (no_ecc_failures && mtd_is_eccerr(ret)) {
-		printk(KERN_ERR "suppressing ECC failure\n");
+		pr_err("suppressing ECC failure\n");
 		ret = 0;
 	}
 	return ret;
@@ -1014,11 +1013,11 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch
 		if (retlen != mtd->writesize)
 			continue;
 		if (ret) {
-			printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", offs);
+			pr_warn("ECC error scanning DOC at 0x%x\n", offs);
 		}
 		if (memcmp(buf, id, 6))
 			continue;
-		printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs);
+		pr_info("Found DiskOnChip %s Media Header at 0x%x\n", id, offs);
 		if (doc->mh0_page == -1) {
 			doc->mh0_page = offs >> this->page_shift;
 			if (!findmirror)
@@ -1029,7 +1028,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch
 		return 2;
 	}
 	if (doc->mh0_page == -1) {
-		printk(KERN_WARNING "DiskOnChip %s Media Header not found.\n", id);
+		pr_warn("DiskOnChip %s Media Header not found.\n", id);
 		return 0;
 	}
 	/* Only one mediaheader was found.  We want buf to contain a
@@ -1038,7 +1037,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch
 	ret = mtd_read(mtd, offs, mtd->writesize, &retlen, buf);
 	if (retlen != mtd->writesize) {
 		/* Insanity.  Give up. */
-		printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n");
+		pr_err("Read DiskOnChip Media Header once, but can't reread it???\n");
 		return 0;
 	}
 	return 1;
@@ -1068,11 +1067,11 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio
 	le16_to_cpus(&mh->FirstPhysicalEUN);
 	le32_to_cpus(&mh->FormattedSize);
 
-	printk(KERN_INFO "    DataOrgID        = %s\n"
-			 "    NumEraseUnits    = %d\n"
-			 "    FirstPhysicalEUN = %d\n"
-			 "    FormattedSize    = %d\n"
-			 "    UnitSizeFactor   = %d\n",
+	pr_info("    DataOrgID        = %s\n"
+		"    NumEraseUnits    = %d\n"
+		"    FirstPhysicalEUN = %d\n"
+		"    FormattedSize    = %d\n"
+		"    UnitSizeFactor   = %d\n",
 		mh->DataOrgID, mh->NumEraseUnits,
 		mh->FirstPhysicalEUN, mh->FormattedSize,
 		mh->UnitSizeFactor);
@@ -1092,7 +1091,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio
 			maxblocks = min(32768U, (maxblocks << 1) + psize);
 			mh->UnitSizeFactor--;
 		}
-		printk(KERN_WARNING "UnitSizeFactor=0x00 detected.  Correct value is assumed to be 0x%02x.\n", mh->UnitSizeFactor);
+		pr_warn("UnitSizeFactor=0x00 detected.  Correct value is assumed to be 0x%02x.\n", mh->UnitSizeFactor);
 	}
 
 	/* NOTE: The lines below modify internal variables of the NAND and MTD
@@ -1103,13 +1102,13 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio
 	if (mh->UnitSizeFactor != 0xff) {
 		this->bbt_erase_shift += (0xff - mh->UnitSizeFactor);
 		mtd->erasesize <<= (0xff - mh->UnitSizeFactor);
-		printk(KERN_INFO "Setting virtual erase size to %d\n", mtd->erasesize);
+		pr_info("Setting virtual erase size to %d\n", mtd->erasesize);
 		blocks = mtd->size >> this->bbt_erase_shift;
 		maxblocks = min(32768U, mtd->erasesize - psize);
 	}
 
 	if (blocks > maxblocks) {
-		printk(KERN_ERR "UnitSizeFactor of 0x%02x is inconsistent with device size.  Aborting.\n", mh->UnitSizeFactor);
+		pr_err("UnitSizeFactor of 0x%02x is inconsistent with device size.  Aborting.\n", mh->UnitSizeFactor);
 		goto out;
 	}
 
@@ -1180,14 +1179,14 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti
 	le32_to_cpus(&mh->FormatFlags);
 	le32_to_cpus(&mh->PercentUsed);
 
-	printk(KERN_INFO "    bootRecordID          = %s\n"
-			 "    NoOfBootImageBlocks   = %d\n"
-			 "    NoOfBinaryPartitions  = %d\n"
-			 "    NoOfBDTLPartitions    = %d\n"
-			 "    BlockMultiplerBits    = %d\n"
-			 "    FormatFlgs            = %d\n"
-			 "    OsakVersion           = %d.%d.%d.%d\n"
-			 "    PercentUsed           = %d\n",
+	pr_info("    bootRecordID          = %s\n"
+		"    NoOfBootImageBlocks   = %d\n"
+		"    NoOfBinaryPartitions  = %d\n"
+		"    NoOfBDTLPartitions    = %d\n"
+		"    BlockMultiplerBits    = %d\n"
+		"    FormatFlgs            = %d\n"
+		"    OsakVersion           = %d.%d.%d.%d\n"
+		"    PercentUsed           = %d\n",
 		mh->bootRecordID, mh->NoOfBootImageBlocks,
 		mh->NoOfBinaryPartitions,
 		mh->NoOfBDTLPartitions,
@@ -1202,13 +1201,13 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti
 
 	blocks = mtd->size >> vshift;
 	if (blocks > 32768) {
-		printk(KERN_ERR "BlockMultiplierBits=%d is inconsistent with device size.  Aborting.\n", mh->BlockMultiplierBits);
+		pr_err("BlockMultiplierBits=%d is inconsistent with device size.  Aborting.\n", mh->BlockMultiplierBits);
 		goto out;
 	}
 
 	blocks = doc->chips_per_floor << (this->chip_shift - this->phys_erase_shift);
 	if (inftl_bbt_write && (blocks > mtd->erasesize)) {
-		printk(KERN_ERR "Writeable BBTs spanning more than one erase block are not yet supported.  FIX ME!\n");
+		pr_err("Writeable BBTs spanning more than one erase block are not yet supported.  FIX ME!\n");
 		goto out;
 	}
 
@@ -1222,7 +1221,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti
 		le32_to_cpus(&ip->spareUnits);
 		le32_to_cpus(&ip->Reserved0);
 
-		printk(KERN_INFO	"    PARTITION[%d] ->\n"
+		pr_info("    PARTITION[%d] ->\n"
 			"        virtualUnits    = %d\n"
 			"        firstUnit       = %d\n"
 			"        lastUnit        = %d\n"
@@ -1308,7 +1307,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
 	struct mtd_partition parts[5];
 
 	if (this->numchips > doc->chips_per_floor) {
-		printk(KERN_ERR "Multi-floor INFTL devices not yet supported.\n");
+		pr_err("Multi-floor INFTL devices not yet supported.\n");
 		return -EIO;
 	}
 
@@ -1436,7 +1435,8 @@ static int __init doc_probe(unsigned long physadr)
 		return -EBUSY;
 	virtadr = ioremap(physadr, DOC_IOREMAP_LEN);
 	if (!virtadr) {
-		printk(KERN_ERR "Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n", DOC_IOREMAP_LEN, physadr);
+		pr_err("Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n",
+		       DOC_IOREMAP_LEN, physadr);
 		ret = -EIO;
 		goto error_ioremap;
 	}
@@ -1495,7 +1495,7 @@ static int __init doc_probe(unsigned long physadr)
 			reg = DoC_Mplus_Toggle;
 			break;
 		case DOC_ChipID_DocMilPlus32:
-			printk(KERN_ERR "DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n");
+			pr_err("DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n");
 		default:
 			ret = -ENODEV;
 			goto notfound;
@@ -1511,7 +1511,7 @@ static int __init doc_probe(unsigned long physadr)
 	tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
 	tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
 	if ((tmp == tmpb) || (tmp != tmpc)) {
-		printk(KERN_WARNING "Possible DiskOnChip at 0x%lx failed TOGGLE test, dropping.\n", physadr);
+		pr_warn("Possible DiskOnChip at 0x%lx failed TOGGLE test, dropping.\n", physadr);
 		ret = -ENODEV;
 		goto notfound;
 	}
@@ -1545,12 +1545,13 @@ static int __init doc_probe(unsigned long physadr)
 		}
 		newval = ~newval;
 		if (oldval == newval) {
-			printk(KERN_DEBUG "Found alias of DOC at 0x%lx to 0x%lx\n", doc->physadr, physadr);
+			pr_debug("Found alias of DOC at 0x%lx to 0x%lx\n",
+				 doc->physadr, physadr);
 			goto notfound;
 		}
 	}
 
-	printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr);
+	pr_notice("DiskOnChip found at 0x%lx\n", physadr);
 
 	len = sizeof(struct nand_chip) + sizeof(struct doc_priv) +
 	      (2 * sizeof(struct nand_bbt_descr));
@@ -1665,12 +1666,13 @@ static int __init init_nanddoc(void)
 	 */
 	rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS);
 	if (!rs_decoder) {
-		printk(KERN_ERR "DiskOnChip: Could not create a RS decoder\n");
+		pr_err("DiskOnChip: Could not create a RS decoder\n");
 		return -ENOMEM;
 	}
 
 	if (doc_config_location) {
-		printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
+		pr_info("Using configured DiskOnChip probe address 0x%lx\n",
+			doc_config_location);
 		ret = doc_probe(doc_config_location);
 		if (ret < 0)
 			goto outerr;
@@ -1682,7 +1684,7 @@ static int __init init_nanddoc(void)
 	/* No banner message any more. Print a message if no DiskOnChip
 	   found, so the user knows we at least tried. */
 	if (!doclist) {
-		printk(KERN_INFO "No valid DiskOnChip devices found\n");
+		pr_info("No valid DiskOnChip devices found\n");
 		ret = -ENODEV;
 		goto outerr;
 	}
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/raw/docg4.c
similarity index 99%
rename from drivers/mtd/nand/docg4.c
rename to drivers/mtd/nand/raw/docg4.c
index 72f1327..1314aa9 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/raw/docg4.c
@@ -1269,8 +1269,8 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
 	nand->read_buf = docg4_read_buf;
 	nand->write_buf = docg4_write_buf16;
 	nand->erase = docg4_erase_block;
-	nand->onfi_set_features = nand_onfi_get_set_features_notsupp;
-	nand->onfi_get_features = nand_onfi_get_set_features_notsupp;
+	nand->set_features = nand_get_set_features_notsupp;
+	nand->get_features = nand_get_set_features_notsupp;
 	nand->ecc.read_page = docg4_read_page;
 	nand->ecc.write_page = docg4_write_page;
 	nand->ecc.read_page_raw = docg4_read_page_raw;
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
similarity index 98%
rename from drivers/mtd/nand/fsl_elbc_nand.c
rename to drivers/mtd/nand/raw/fsl_elbc_nand.c
index 8b6dcd7..d28df99 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
@@ -775,8 +775,8 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
 	chip->select_chip = fsl_elbc_select_chip;
 	chip->cmdfunc = fsl_elbc_cmdfunc;
 	chip->waitfunc = fsl_elbc_wait;
-	chip->onfi_set_features = nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features = nand_onfi_get_set_features_notsupp;
+	chip->set_features = nand_get_set_features_notsupp;
+	chip->get_features = nand_get_set_features_notsupp;
 
 	chip->bbt_td = &bbt_main_descr;
 	chip->bbt_md = &bbt_mirror_descr;
@@ -929,8 +929,8 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev)
 	mtd_device_parse_register(mtd, part_probe_types, NULL,
 				  NULL, 0);
 
-	printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n",
-	       (unsigned long long)res.start, priv->bank);
+	pr_info("eLBC NAND device at 0x%llx, bank %d\n",
+		(unsigned long long)res.start, priv->bank);
 	return 0;
 
 err:
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
similarity index 99%
rename from drivers/mtd/nand/fsl_ifc_nand.c
rename to drivers/mtd/nand/raw/fsl_ifc_nand.c
index 5a9c2f0..61aae02 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -799,7 +799,7 @@ static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
 			   msecs_to_jiffies(IFC_TIMEOUT_MSECS));
 
 	if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
-		printk(KERN_ERR "fsl-ifc: Failed to Initialise SRAM\n");
+		pr_err("fsl-ifc: Failed to Initialise SRAM\n");
 
 	/* Restore CSOR and CSOR_ext */
 	ifc_out32(csor, &ifc_global->csor_cs[cs].csor);
@@ -832,8 +832,8 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
 	chip->select_chip = fsl_ifc_select_chip;
 	chip->cmdfunc = fsl_ifc_cmdfunc;
 	chip->waitfunc = fsl_ifc_wait;
-	chip->onfi_set_features = nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features = nand_onfi_get_set_features_notsupp;
+	chip->set_features = nand_get_set_features_notsupp;
+	chip->get_features = nand_get_set_features_notsupp;
 
 	chip->bbt_td = &bbt_main_descr;
 	chip->bbt_md = &bbt_mirror_descr;
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c
similarity index 100%
rename from drivers/mtd/nand/fsl_upm.c
rename to drivers/mtd/nand/raw/fsl_upm.c
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c
similarity index 85%
rename from drivers/mtd/nand/fsmc_nand.c
rename to drivers/mtd/nand/raw/fsmc_nand.c
index f49ed46..28c48dc 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/raw/fsmc_nand.c
@@ -1,6 +1,4 @@
 /*
- * drivers/mtd/nand/fsmc_nand.c
- *
  * ST Microelectronics
  * Flexible Static Memory Controller (FSMC)
  * Driver for NAND portions
@@ -9,7 +7,9 @@
  * Vipin Kumar <vipin.kumar@st.com>
  * Ashish Priyadarshi
  *
- * Based on drivers/mtd/nand/nomadik_nand.c
+ * Based on drivers/mtd/nand/nomadik_nand.c (removed in v3.8)
+ *  Copyright © 2007 STMicroelectronics Pvt. Ltd.
+ *  Copyright © 2009 Alessandro Rubini
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
@@ -103,10 +103,6 @@
 #define ECC3			0x1C
 #define FSMC_NAND_BANK_SZ	0x20
 
-#define FSMC_NAND_REG(base, bank, reg)		(base + FSMC_NOR_REG_SIZE + \
-						(FSMC_NAND_BANK_SZ * (bank)) + \
-						reg)
-
 #define FSMC_BUSY_WAIT_TIMEOUT	(1 * HZ)
 
 struct fsmc_nand_timings {
@@ -143,7 +139,7 @@ enum access_mode {
  * @data_va:		NAND port for Data.
  * @cmd_va:		NAND port for Command.
  * @addr_va:		NAND port for Address.
- * @regs_va:		FSMC regs base address.
+ * @regs_va:		Registers base address for a given bank.
  */
 struct fsmc_nand_data {
 	u32			pid;
@@ -258,45 +254,6 @@ static inline struct fsmc_nand_data *mtd_to_fsmc(struct mtd_info *mtd)
 }
 
 /*
- * fsmc_cmd_ctrl - For facilitaing Hardware access
- * This routine allows hardware specific access to control-lines(ALE,CLE)
- */
-static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
-{
-	struct nand_chip *this = mtd_to_nand(mtd);
-	struct fsmc_nand_data *host = mtd_to_fsmc(mtd);
-	void __iomem *regs = host->regs_va;
-	unsigned int bank = host->bank;
-
-	if (ctrl & NAND_CTRL_CHANGE) {
-		u32 pc;
-
-		if (ctrl & NAND_CLE) {
-			this->IO_ADDR_R = host->cmd_va;
-			this->IO_ADDR_W = host->cmd_va;
-		} else if (ctrl & NAND_ALE) {
-			this->IO_ADDR_R = host->addr_va;
-			this->IO_ADDR_W = host->addr_va;
-		} else {
-			this->IO_ADDR_R = host->data_va;
-			this->IO_ADDR_W = host->data_va;
-		}
-
-		pc = readl(FSMC_NAND_REG(regs, bank, PC));
-		if (ctrl & NAND_NCE)
-			pc |= FSMC_ENABLE;
-		else
-			pc &= ~FSMC_ENABLE;
-		writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC));
-	}
-
-	mb();
-
-	if (cmd != NAND_CMD_NONE)
-		writeb_relaxed(cmd, this->IO_ADDR_W);
-}
-
-/*
  * fsmc_nand_setup - FSMC (Flexible Static Memory Controller) init routine
  *
  * This routine initializes timing parameters related to NAND memory access in
@@ -307,8 +264,6 @@ static void fsmc_nand_setup(struct fsmc_nand_data *host,
 {
 	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
 	uint32_t tclr, tar, thiz, thold, twait, tset;
-	unsigned int bank = host->bank;
-	void __iomem *regs = host->regs_va;
 
 	tclr = (tims->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
 	tar = (tims->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
@@ -318,18 +273,14 @@ static void fsmc_nand_setup(struct fsmc_nand_data *host,
 	tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
 
 	if (host->nand.options & NAND_BUSWIDTH_16)
-		writel_relaxed(value | FSMC_DEVWID_16,
-				FSMC_NAND_REG(regs, bank, PC));
+		writel_relaxed(value | FSMC_DEVWID_16, host->regs_va + PC);
 	else
-		writel_relaxed(value | FSMC_DEVWID_8,
-				FSMC_NAND_REG(regs, bank, PC));
+		writel_relaxed(value | FSMC_DEVWID_8, host->regs_va + PC);
 
-	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar,
-			FSMC_NAND_REG(regs, bank, PC));
-	writel_relaxed(thiz | thold | twait | tset,
-			FSMC_NAND_REG(regs, bank, COMM));
-	writel_relaxed(thiz | thold | twait | tset,
-			FSMC_NAND_REG(regs, bank, ATTRIB));
+	writel_relaxed(readl(host->regs_va + PC) | tclr | tar,
+		       host->regs_va + PC);
+	writel_relaxed(thiz | thold | twait | tset, host->regs_va + COMM);
+	writel_relaxed(thiz | thold | twait | tset, host->regs_va + ATTRIB);
 }
 
 static int fsmc_calc_timings(struct fsmc_nand_data *host,
@@ -419,15 +370,13 @@ static int fsmc_setup_data_interface(struct mtd_info *mtd, int csline,
 static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
 {
 	struct fsmc_nand_data *host = mtd_to_fsmc(mtd);
-	void __iomem *regs = host->regs_va;
-	uint32_t bank = host->bank;
 
-	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256,
-			FSMC_NAND_REG(regs, bank, PC));
-	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN,
-			FSMC_NAND_REG(regs, bank, PC));
-	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN,
-			FSMC_NAND_REG(regs, bank, PC));
+	writel_relaxed(readl(host->regs_va + PC) & ~FSMC_ECCPLEN_256,
+		       host->regs_va + PC);
+	writel_relaxed(readl(host->regs_va + PC) & ~FSMC_ECCEN,
+		       host->regs_va + PC);
+	writel_relaxed(readl(host->regs_va + PC) | FSMC_ECCEN,
+		       host->regs_va + PC);
 }
 
 /*
@@ -439,13 +388,11 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
 				uint8_t *ecc)
 {
 	struct fsmc_nand_data *host = mtd_to_fsmc(mtd);
-	void __iomem *regs = host->regs_va;
-	uint32_t bank = host->bank;
 	uint32_t ecc_tmp;
 	unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
 
 	do {
-		if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY)
+		if (readl_relaxed(host->regs_va + STS) & FSMC_CODE_RDY)
 			break;
 		else
 			cond_resched();
@@ -456,25 +403,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
 		return -ETIMEDOUT;
 	}
 
-	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
+	ecc_tmp = readl_relaxed(host->regs_va + ECC1);
 	ecc[0] = (uint8_t) (ecc_tmp >> 0);
 	ecc[1] = (uint8_t) (ecc_tmp >> 8);
 	ecc[2] = (uint8_t) (ecc_tmp >> 16);
 	ecc[3] = (uint8_t) (ecc_tmp >> 24);
 
-	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
+	ecc_tmp = readl_relaxed(host->regs_va + ECC2);
 	ecc[4] = (uint8_t) (ecc_tmp >> 0);
 	ecc[5] = (uint8_t) (ecc_tmp >> 8);
 	ecc[6] = (uint8_t) (ecc_tmp >> 16);
 	ecc[7] = (uint8_t) (ecc_tmp >> 24);
 
-	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
+	ecc_tmp = readl_relaxed(host->regs_va + ECC3);
 	ecc[8] = (uint8_t) (ecc_tmp >> 0);
 	ecc[9] = (uint8_t) (ecc_tmp >> 8);
 	ecc[10] = (uint8_t) (ecc_tmp >> 16);
 	ecc[11] = (uint8_t) (ecc_tmp >> 24);
 
-	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
+	ecc_tmp = readl_relaxed(host->regs_va + STS);
 	ecc[12] = (uint8_t) (ecc_tmp >> 16);
 
 	return 0;
@@ -489,11 +436,9 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data,
 				uint8_t *ecc)
 {
 	struct fsmc_nand_data *host = mtd_to_fsmc(mtd);
-	void __iomem *regs = host->regs_va;
-	uint32_t bank = host->bank;
 	uint32_t ecc_tmp;
 
-	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
+	ecc_tmp = readl_relaxed(host->regs_va + ECC1);
 	ecc[0] = (uint8_t) (ecc_tmp >> 0);
 	ecc[1] = (uint8_t) (ecc_tmp >> 8);
 	ecc[2] = (uint8_t) (ecc_tmp >> 16);
@@ -598,18 +543,18 @@ static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len,
  */
 static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
+	struct fsmc_nand_data *host  = mtd_to_fsmc(mtd);
 	int i;
-	struct nand_chip *chip = mtd_to_nand(mtd);
 
 	if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) &&
 			IS_ALIGNED(len, sizeof(uint32_t))) {
 		uint32_t *p = (uint32_t *)buf;
 		len = len >> 2;
 		for (i = 0; i < len; i++)
-			writel_relaxed(p[i], chip->IO_ADDR_W);
+			writel_relaxed(p[i], host->data_va);
 	} else {
 		for (i = 0; i < len; i++)
-			writeb_relaxed(buf[i], chip->IO_ADDR_W);
+			writeb_relaxed(buf[i], host->data_va);
 	}
 }
 
@@ -621,18 +566,18 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
  */
 static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
+	struct fsmc_nand_data *host  = mtd_to_fsmc(mtd);
 	int i;
-	struct nand_chip *chip = mtd_to_nand(mtd);
 
 	if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) &&
 			IS_ALIGNED(len, sizeof(uint32_t))) {
 		uint32_t *p = (uint32_t *)buf;
 		len = len >> 2;
 		for (i = 0; i < len; i++)
-			p[i] = readl_relaxed(chip->IO_ADDR_R);
+			p[i] = readl_relaxed(host->data_va);
 	} else {
 		for (i = 0; i < len; i++)
-			buf[i] = readb_relaxed(chip->IO_ADDR_R);
+			buf[i] = readb_relaxed(host->data_va);
 	}
 }
 
@@ -663,6 +608,102 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf,
 	dma_xfer(host, (void *)buf, len, DMA_TO_DEVICE);
 }
 
+/* fsmc_select_chip - assert or deassert nCE */
+static void fsmc_select_chip(struct mtd_info *mtd, int chipnr)
+{
+	struct fsmc_nand_data *host = mtd_to_fsmc(mtd);
+	u32 pc;
+
+	/* Support only one CS */
+	if (chipnr > 0)
+		return;
+
+	pc = readl(host->regs_va + PC);
+	if (chipnr < 0)
+		writel_relaxed(pc & ~FSMC_ENABLE, host->regs_va + PC);
+	else
+		writel_relaxed(pc | FSMC_ENABLE, host->regs_va + PC);
+
+	/* nCE line must be asserted before starting any operation */
+	mb();
+}
+
+/*
+ * fsmc_exec_op - hook called by the core to execute NAND operations
+ *
+ * This controller is simple enough and thus does not need to use the parser
+ * provided by the core, instead, handle every situation here.
+ */
+static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op,
+			bool check_only)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct fsmc_nand_data *host = mtd_to_fsmc(mtd);
+	const struct nand_op_instr *instr = NULL;
+	int ret = 0;
+	unsigned int op_id;
+	int i;
+
+	pr_debug("Executing operation [%d instructions]:\n", op->ninstrs);
+	for (op_id = 0; op_id < op->ninstrs; op_id++) {
+		instr = &op->instrs[op_id];
+
+		switch (instr->type) {
+		case NAND_OP_CMD_INSTR:
+			pr_debug("  ->CMD      [0x%02x]\n",
+				 instr->ctx.cmd.opcode);
+
+			writeb_relaxed(instr->ctx.cmd.opcode, host->cmd_va);
+			break;
+
+		case NAND_OP_ADDR_INSTR:
+			pr_debug("  ->ADDR     [%d cyc]",
+				 instr->ctx.addr.naddrs);
+
+			for (i = 0; i < instr->ctx.addr.naddrs; i++)
+				writeb_relaxed(instr->ctx.addr.addrs[i],
+					       host->addr_va);
+			break;
+
+		case NAND_OP_DATA_IN_INSTR:
+			pr_debug("  ->DATA_IN  [%d B%s]\n", instr->ctx.data.len,
+				 instr->ctx.data.force_8bit ?
+				 ", force 8-bit" : "");
+
+			if (host->mode == USE_DMA_ACCESS)
+				fsmc_read_buf_dma(mtd, instr->ctx.data.buf.in,
+						  instr->ctx.data.len);
+			else
+				fsmc_read_buf(mtd, instr->ctx.data.buf.in,
+					      instr->ctx.data.len);
+			break;
+
+		case NAND_OP_DATA_OUT_INSTR:
+			pr_debug("  ->DATA_OUT [%d B%s]\n", instr->ctx.data.len,
+				 instr->ctx.data.force_8bit ?
+				 ", force 8-bit" : "");
+
+			if (host->mode == USE_DMA_ACCESS)
+				fsmc_write_buf_dma(mtd, instr->ctx.data.buf.out,
+						   instr->ctx.data.len);
+			else
+				fsmc_write_buf(mtd, instr->ctx.data.buf.out,
+					       instr->ctx.data.len);
+			break;
+
+		case NAND_OP_WAITRDY_INSTR:
+			pr_debug("  ->WAITRDY  [max %d ms]\n",
+				 instr->ctx.waitrdy.timeout_ms);
+
+			ret = nand_soft_waitrdy(chip,
+						instr->ctx.waitrdy.timeout_ms);
+			break;
+		}
+	}
+
+	return ret;
+}
+
 /*
  * fsmc_read_page_hwecc
  * @mtd:	mtd info structure
@@ -754,13 +795,11 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct fsmc_nand_data *host = mtd_to_fsmc(mtd);
-	void __iomem *regs = host->regs_va;
-	unsigned int bank = host->bank;
 	uint32_t err_idx[8];
 	uint32_t num_err, i;
 	uint32_t ecc1, ecc2, ecc3, ecc4;
 
-	num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF;
+	num_err = (readl_relaxed(host->regs_va + STS) >> 10) & 0xF;
 
 	/* no bit flipping */
 	if (likely(num_err == 0))
@@ -803,10 +842,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
 	 * uint64_t array and error offset indexes are populated in err_idx
 	 * array
 	 */
-	ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
-	ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
-	ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
-	ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
+	ecc1 = readl_relaxed(host->regs_va + ECC1);
+	ecc2 = readl_relaxed(host->regs_va + ECC2);
+	ecc3 = readl_relaxed(host->regs_va + ECC3);
+	ecc4 = readl_relaxed(host->regs_va + STS);
 
 	err_idx[0] = (ecc1 >> 0) & 0x1FFF;
 	err_idx[1] = (ecc1 >> 13) & 0x1FFF;
@@ -889,6 +928,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	struct mtd_info *mtd;
 	struct nand_chip *nand;
 	struct resource *res;
+	void __iomem *base;
 	dma_cap_mask_t mask;
 	int ret = 0;
 	u32 pid;
@@ -923,9 +963,12 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 		return PTR_ERR(host->cmd_va);
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fsmc_regs");
-	host->regs_va = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(host->regs_va))
-		return PTR_ERR(host->regs_va);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	host->regs_va = base + FSMC_NOR_REG_SIZE +
+		(host->bank * FSMC_NAND_BANK_SZ);
 
 	host->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(host->clk)) {
@@ -942,7 +985,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	 * AMBA PrimeCell bus. However it is not a PrimeCell.
 	 */
 	for (pid = 0, i = 0; i < 4; i++)
-		pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8);
+		pid |= (readl(base + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8);
 	host->pid = pid;
 	dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, "
 		 "revision %02x, config %02x\n",
@@ -960,9 +1003,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	nand_set_flash_node(nand, pdev->dev.of_node);
 
 	mtd->dev.parent = &pdev->dev;
-	nand->IO_ADDR_R = host->data_va;
-	nand->IO_ADDR_W = host->data_va;
-	nand->cmd_ctrl = fsmc_cmd_ctrl;
+	nand->exec_op = fsmc_exec_op;
+	nand->select_chip = fsmc_select_chip;
 	nand->chip_delay = 30;
 
 	/*
@@ -974,8 +1016,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	nand->ecc.size = 512;
 	nand->badblockbits = 7;
 
-	switch (host->mode) {
-	case USE_DMA_ACCESS:
+	if (host->mode == USE_DMA_ACCESS) {
 		dma_cap_zero(mask);
 		dma_cap_set(DMA_MEMCPY, mask);
 		host->read_dma_chan = dma_request_channel(mask, filter, NULL);
@@ -988,15 +1029,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev, "Unable to get write dma channel\n");
 			goto err_req_write_chnl;
 		}
-		nand->read_buf = fsmc_read_buf_dma;
-		nand->write_buf = fsmc_write_buf_dma;
-		break;
-
-	default:
-	case USE_WORD_ACCESS:
-		nand->read_buf = fsmc_read_buf;
-		nand->write_buf = fsmc_write_buf;
-		break;
 	}
 
 	if (host->dev_timings)
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/raw/gpio.c
similarity index 99%
rename from drivers/mtd/nand/gpio.c
rename to drivers/mtd/nand/raw/gpio.c
index a8bde66..2780af2 100644
--- a/drivers/mtd/nand/gpio.c
+++ b/drivers/mtd/nand/raw/gpio.c
@@ -1,6 +1,4 @@
 /*
- * drivers/mtd/nand/gpio.c
- *
  * Updated, and converted to generic GPIO based driver by Russell King.
  *
  * Written by Ben Dooks <ben@simtec.co.uk>
diff --git a/drivers/mtd/nand/gpmi-nand/Makefile b/drivers/mtd/nand/raw/gpmi-nand/Makefile
similarity index 100%
rename from drivers/mtd/nand/gpmi-nand/Makefile
rename to drivers/mtd/nand/raw/gpmi-nand/Makefile
diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/raw/gpmi-nand/bch-regs.h
similarity index 100%
rename from drivers/mtd/nand/gpmi-nand/bch-regs.h
rename to drivers/mtd/nand/raw/gpmi-nand/bch-regs.h
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c
new file mode 100644
index 0000000..e945567
--- /dev/null
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c
@@ -0,0 +1,943 @@
+/*
+ * Freescale GPMI NAND Flash Driver
+ *
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008 Embedded Alley Solutions, 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+
+#include "gpmi-nand.h"
+#include "gpmi-regs.h"
+#include "bch-regs.h"
+
+/* Converts time to clock cycles */
+#define TO_CYCLES(duration, period) DIV_ROUND_UP_ULL(duration, period)
+
+#define MXS_SET_ADDR		0x4
+#define MXS_CLR_ADDR		0x8
+/*
+ * Clear the bit and poll it cleared.  This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+	int timeout = 0x400;
+
+	/* clear the bit */
+	writel(mask, addr + MXS_CLR_ADDR);
+
+	/*
+	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
+	 * recommends to wait 1us.
+	 */
+	udelay(1);
+
+	/* poll the bit becoming clear */
+	while ((readl(addr) & mask) && --timeout)
+		/* nothing */;
+
+	return !timeout;
+}
+
+#define MODULE_CLKGATE		(1 << 30)
+#define MODULE_SFTRST		(1 << 31)
+/*
+ * The current mxs_reset_block() will do two things:
+ *  [1] enable the module.
+ *  [2] reset the module.
+ *
+ * In most of the cases, it's ok.
+ * But in MX23, there is a hardware bug in the BCH block (see erratum #2847).
+ * If you try to soft reset the BCH block, it becomes unusable until
+ * the next hard reset. This case occurs in the NAND boot mode. When the board
+ * boots by NAND, the ROM of the chip will initialize the BCH blocks itself.
+ * So If the driver tries to reset the BCH again, the BCH will not work anymore.
+ * You will see a DMA timeout in this case. The bug has been fixed
+ * in the following chips, such as MX28.
+ *
+ * To avoid this bug, just add a new parameter `just_enable` for
+ * the mxs_reset_block(), and rewrite it here.
+ */
+static int gpmi_reset_block(void __iomem *reset_addr, bool just_enable)
+{
+	int ret;
+	int timeout = 0x400;
+
+	/* clear and poll SFTRST */
+	ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
+	if (unlikely(ret))
+		goto error;
+
+	/* clear CLKGATE */
+	writel(MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
+
+	if (!just_enable) {
+		/* set SFTRST to reset the block */
+		writel(MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
+		udelay(1);
+
+		/* poll CLKGATE becoming set */
+		while ((!(readl(reset_addr) & MODULE_CLKGATE)) && --timeout)
+			/* nothing */;
+		if (unlikely(!timeout))
+			goto error;
+	}
+
+	/* clear and poll SFTRST */
+	ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
+	if (unlikely(ret))
+		goto error;
+
+	/* clear and poll CLKGATE */
+	ret = clear_poll_bit(reset_addr, MODULE_CLKGATE);
+	if (unlikely(ret))
+		goto error;
+
+	return 0;
+
+error:
+	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+	return -ETIMEDOUT;
+}
+
+static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
+{
+	struct clk *clk;
+	int ret;
+	int i;
+
+	for (i = 0; i < GPMI_CLK_MAX; i++) {
+		clk = this->resources.clock[i];
+		if (!clk)
+			break;
+
+		if (v) {
+			ret = clk_prepare_enable(clk);
+			if (ret)
+				goto err_clk;
+		} else {
+			clk_disable_unprepare(clk);
+		}
+	}
+	return 0;
+
+err_clk:
+	for (; i > 0; i--)
+		clk_disable_unprepare(this->resources.clock[i - 1]);
+	return ret;
+}
+
+int gpmi_enable_clk(struct gpmi_nand_data *this)
+{
+	return __gpmi_enable_clk(this, true);
+}
+
+int gpmi_disable_clk(struct gpmi_nand_data *this)
+{
+	return __gpmi_enable_clk(this, false);
+}
+
+int gpmi_init(struct gpmi_nand_data *this)
+{
+	struct resources *r = &this->resources;
+	int ret;
+
+	ret = gpmi_enable_clk(this);
+	if (ret)
+		return ret;
+	ret = gpmi_reset_block(r->gpmi_regs, false);
+	if (ret)
+		goto err_out;
+
+	/*
+	 * Reset BCH here, too. We got failures otherwise :(
+	 * See later BCH reset for explanation of MX23 handling
+	 */
+	ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
+	if (ret)
+		goto err_out;
+
+	/* Choose NAND mode. */
+	writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR);
+
+	/* Set the IRQ polarity. */
+	writel(BM_GPMI_CTRL1_ATA_IRQRDY_POLARITY,
+				r->gpmi_regs + HW_GPMI_CTRL1_SET);
+
+	/* Disable Write-Protection. */
+	writel(BM_GPMI_CTRL1_DEV_RESET, r->gpmi_regs + HW_GPMI_CTRL1_SET);
+
+	/* Select BCH ECC. */
+	writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET);
+
+	/*
+	 * Decouple the chip select from dma channel. We use dma0 for all
+	 * the chips.
+	 */
+	writel(BM_GPMI_CTRL1_DECOUPLE_CS, r->gpmi_regs + HW_GPMI_CTRL1_SET);
+
+	gpmi_disable_clk(this);
+	return 0;
+err_out:
+	gpmi_disable_clk(this);
+	return ret;
+}
+
+/* This function is very useful. It is called only when the bug occur. */
+void gpmi_dump_info(struct gpmi_nand_data *this)
+{
+	struct resources *r = &this->resources;
+	struct bch_geometry *geo = &this->bch_geometry;
+	u32 reg;
+	int i;
+
+	dev_err(this->dev, "Show GPMI registers :\n");
+	for (i = 0; i <= HW_GPMI_DEBUG / 0x10 + 1; i++) {
+		reg = readl(r->gpmi_regs + i * 0x10);
+		dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
+	}
+
+	/* start to print out the BCH info */
+	dev_err(this->dev, "Show BCH registers :\n");
+	for (i = 0; i <= HW_BCH_VERSION / 0x10 + 1; i++) {
+		reg = readl(r->bch_regs + i * 0x10);
+		dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
+	}
+	dev_err(this->dev, "BCH Geometry :\n"
+		"GF length              : %u\n"
+		"ECC Strength           : %u\n"
+		"Page Size in Bytes     : %u\n"
+		"Metadata Size in Bytes : %u\n"
+		"ECC Chunk Size in Bytes: %u\n"
+		"ECC Chunk Count        : %u\n"
+		"Payload Size in Bytes  : %u\n"
+		"Auxiliary Size in Bytes: %u\n"
+		"Auxiliary Status Offset: %u\n"
+		"Block Mark Byte Offset : %u\n"
+		"Block Mark Bit Offset  : %u\n",
+		geo->gf_len,
+		geo->ecc_strength,
+		geo->page_size,
+		geo->metadata_size,
+		geo->ecc_chunk_size,
+		geo->ecc_chunk_count,
+		geo->payload_size,
+		geo->auxiliary_size,
+		geo->auxiliary_status_offset,
+		geo->block_mark_byte_offset,
+		geo->block_mark_bit_offset);
+}
+
+/* Configures the geometry for BCH.  */
+int bch_set_geometry(struct gpmi_nand_data *this)
+{
+	struct resources *r = &this->resources;
+	struct bch_geometry *bch_geo = &this->bch_geometry;
+	unsigned int block_count;
+	unsigned int block_size;
+	unsigned int metadata_size;
+	unsigned int ecc_strength;
+	unsigned int page_size;
+	unsigned int gf_len;
+	int ret;
+
+	if (common_nfc_set_geometry(this))
+		return !0;
+
+	block_count   = bch_geo->ecc_chunk_count - 1;
+	block_size    = bch_geo->ecc_chunk_size;
+	metadata_size = bch_geo->metadata_size;
+	ecc_strength  = bch_geo->ecc_strength >> 1;
+	page_size     = bch_geo->page_size;
+	gf_len        = bch_geo->gf_len;
+
+	ret = gpmi_enable_clk(this);
+	if (ret)
+		return ret;
+
+	/*
+	* Due to erratum #2847 of the MX23, the BCH cannot be soft reset on this
+	* chip, otherwise it will lock up. So we skip resetting BCH on the MX23.
+	* On the other hand, the MX28 needs the reset, because one case has been
+	* seen where the BCH produced ECC errors constantly after 10000
+	* consecutive reboots. The latter case has not been seen on the MX23
+	* yet, still we don't know if it could happen there as well.
+	*/
+	ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
+	if (ret)
+		goto err_out;
+
+	/* Configure layout 0. */
+	writel(BF_BCH_FLASH0LAYOUT0_NBLOCKS(block_count)
+			| BF_BCH_FLASH0LAYOUT0_META_SIZE(metadata_size)
+			| BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength, this)
+			| BF_BCH_FLASH0LAYOUT0_GF(gf_len, this)
+			| BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size, this),
+			r->bch_regs + HW_BCH_FLASH0LAYOUT0);
+
+	writel(BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size)
+			| BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength, this)
+			| BF_BCH_FLASH0LAYOUT1_GF(gf_len, this)
+			| BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size, this),
+			r->bch_regs + HW_BCH_FLASH0LAYOUT1);
+
+	/* Set *all* chip selects to use layout 0. */
+	writel(0, r->bch_regs + HW_BCH_LAYOUTSELECT);
+
+	/* Enable interrupts. */
+	writel(BM_BCH_CTRL_COMPLETE_IRQ_EN,
+				r->bch_regs + HW_BCH_CTRL_SET);
+
+	gpmi_disable_clk(this);
+	return 0;
+err_out:
+	gpmi_disable_clk(this);
+	return ret;
+}
+
+/*
+ * <1> Firstly, we should know what's the GPMI-clock means.
+ *     The GPMI-clock is the internal clock in the gpmi nand controller.
+ *     If you set 100MHz to gpmi nand controller, the GPMI-clock's period
+ *     is 10ns. Mark the GPMI-clock's period as GPMI-clock-period.
+ *
+ * <2> Secondly, we should know what's the frequency on the nand chip pins.
+ *     The frequency on the nand chip pins is derived from the GPMI-clock.
+ *     We can get it from the following equation:
+ *
+ *         F = G / (DS + DH)
+ *
+ *         F  : the frequency on the nand chip pins.
+ *         G  : the GPMI clock, such as 100MHz.
+ *         DS : GPMI_HW_GPMI_TIMING0:DATA_SETUP
+ *         DH : GPMI_HW_GPMI_TIMING0:DATA_HOLD
+ *
+ * <3> Thirdly, when the frequency on the nand chip pins is above 33MHz,
+ *     the nand EDO(extended Data Out) timing could be applied.
+ *     The GPMI implements a feedback read strobe to sample the read data.
+ *     The feedback read strobe can be delayed to support the nand EDO timing
+ *     where the read strobe may deasserts before the read data is valid, and
+ *     read data is valid for some time after read strobe.
+ *
+ *     The following figure illustrates some aspects of a NAND Flash read:
+ *
+ *                   |<---tREA---->|
+ *                   |             |
+ *                   |         |   |
+ *                   |<--tRP-->|   |
+ *                   |         |   |
+ *                  __          ___|__________________________________
+ *     RDN            \________/   |
+ *                                 |
+ *                                 /---------\
+ *     Read Data    --------------<           >---------
+ *                                 \---------/
+ *                                |     |
+ *                                |<-D->|
+ *     FeedbackRDN  ________             ____________
+ *                          \___________/
+ *
+ *          D stands for delay, set in the HW_GPMI_CTRL1:RDN_DELAY.
+ *
+ *
+ * <4> Now, we begin to describe how to compute the right RDN_DELAY.
+ *
+ *  4.1) From the aspect of the nand chip pins:
+ *        Delay = (tREA + C - tRP)               {1}
+ *
+ *        tREA : the maximum read access time.
+ *        C    : a constant to adjust the delay. default is 4000ps.
+ *        tRP  : the read pulse width, which is exactly:
+ *                   tRP = (GPMI-clock-period) * DATA_SETUP
+ *
+ *  4.2) From the aspect of the GPMI nand controller:
+ *         Delay = RDN_DELAY * 0.125 * RP        {2}
+ *
+ *         RP   : the DLL reference period.
+ *            if (GPMI-clock-period > DLL_THRETHOLD)
+ *                   RP = GPMI-clock-period / 2;
+ *            else
+ *                   RP = GPMI-clock-period;
+ *
+ *            Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period
+ *            is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD
+ *            is 16000ps, but in mx6q, we use 12000ps.
+ *
+ *  4.3) since {1} equals {2}, we get:
+ *
+ *                     (tREA + 4000 - tRP) * 8
+ *         RDN_DELAY = -----------------------     {3}
+ *                           RP
+ */
+static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
+				     const struct nand_sdr_timings *sdr)
+{
+	struct gpmi_nfc_hardware_timing *hw = &this->hw;
+	unsigned int dll_threshold_ps = this->devdata->max_chain_delay;
+	unsigned int period_ps, reference_period_ps;
+	unsigned int data_setup_cycles, data_hold_cycles, addr_setup_cycles;
+	unsigned int tRP_ps;
+	bool use_half_period;
+	int sample_delay_ps, sample_delay_factor;
+	u16 busy_timeout_cycles;
+	u8 wrn_dly_sel;
+
+	if (sdr->tRC_min >= 30000) {
+		/* ONFI non-EDO modes [0-3] */
+		hw->clk_rate = 22000000;
+		wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
+	} else if (sdr->tRC_min >= 25000) {
+		/* ONFI EDO mode 4 */
+		hw->clk_rate = 80000000;
+		wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+	} else {
+		/* ONFI EDO mode 5 */
+		hw->clk_rate = 100000000;
+		wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+	}
+
+	/* SDR core timings are given in picoseconds */
+	period_ps = div_u64((u64)NSEC_PER_SEC * 1000, hw->clk_rate);
+
+	addr_setup_cycles = TO_CYCLES(sdr->tALS_min, period_ps);
+	data_setup_cycles = TO_CYCLES(sdr->tDS_min, period_ps);
+	data_hold_cycles = TO_CYCLES(sdr->tDH_min, period_ps);
+	busy_timeout_cycles = TO_CYCLES(sdr->tWB_max + sdr->tR_max, period_ps);
+
+	hw->timing0 = BF_GPMI_TIMING0_ADDRESS_SETUP(addr_setup_cycles) |
+		      BF_GPMI_TIMING0_DATA_HOLD(data_hold_cycles) |
+		      BF_GPMI_TIMING0_DATA_SETUP(data_setup_cycles);
+	hw->timing1 = BF_GPMI_TIMING1_BUSY_TIMEOUT(busy_timeout_cycles * 4096);
+
+	/*
+	 * Derive NFC ideal delay from {3}:
+	 *
+	 *                     (tREA + 4000 - tRP) * 8
+	 *         RDN_DELAY = -----------------------
+	 *                                RP
+	 */
+	if (period_ps > dll_threshold_ps) {
+		use_half_period = true;
+		reference_period_ps = period_ps / 2;
+	} else {
+		use_half_period = false;
+		reference_period_ps = period_ps;
+	}
+
+	tRP_ps = data_setup_cycles * period_ps;
+	sample_delay_ps = (sdr->tREA_max + 4000 - tRP_ps) * 8;
+	if (sample_delay_ps > 0)
+		sample_delay_factor = sample_delay_ps / reference_period_ps;
+	else
+		sample_delay_factor = 0;
+
+	hw->ctrl1n = BF_GPMI_CTRL1_WRN_DLY_SEL(wrn_dly_sel);
+	if (sample_delay_factor)
+		hw->ctrl1n |= BF_GPMI_CTRL1_RDN_DELAY(sample_delay_factor) |
+			      BM_GPMI_CTRL1_DLL_ENABLE |
+			      (use_half_period ? BM_GPMI_CTRL1_HALF_PERIOD : 0);
+}
+
+void gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
+{
+	struct gpmi_nfc_hardware_timing *hw = &this->hw;
+	struct resources *r = &this->resources;
+	void __iomem *gpmi_regs = r->gpmi_regs;
+	unsigned int dll_wait_time_us;
+
+	clk_set_rate(r->clock[0], hw->clk_rate);
+
+	writel(hw->timing0, gpmi_regs + HW_GPMI_TIMING0);
+	writel(hw->timing1, gpmi_regs + HW_GPMI_TIMING1);
+
+	/*
+	 * Clear several CTRL1 fields, DLL must be disabled when setting
+	 * RDN_DELAY or HALF_PERIOD.
+	 */
+	writel(BM_GPMI_CTRL1_CLEAR_MASK, gpmi_regs + HW_GPMI_CTRL1_CLR);
+	writel(hw->ctrl1n, gpmi_regs + HW_GPMI_CTRL1_SET);
+
+	/* Wait 64 clock cycles before using the GPMI after enabling the DLL */
+	dll_wait_time_us = USEC_PER_SEC / hw->clk_rate * 64;
+	if (!dll_wait_time_us)
+		dll_wait_time_us = 1;
+
+	/* Wait for the DLL to settle. */
+	udelay(dll_wait_time_us);
+}
+
+int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
+			      const struct nand_data_interface *conf)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct gpmi_nand_data *this = nand_get_controller_data(chip);
+	const struct nand_sdr_timings *sdr;
+
+	/* Retrieve required NAND timings */
+	sdr = nand_get_sdr_timings(conf);
+	if (IS_ERR(sdr))
+		return PTR_ERR(sdr);
+
+	/* Only MX6 GPMI controller can reach EDO timings */
+	if (sdr->tRC_min <= 25000 && !GPMI_IS_MX6(this))
+		return -ENOTSUPP;
+
+	/* Stop here if this call was just a check */
+	if (chipnr < 0)
+		return 0;
+
+	/* Do the actual derivation of the controller timings */
+	gpmi_nfc_compute_timings(this, sdr);
+
+	this->hw.must_apply_timings = true;
+
+	return 0;
+}
+
+/* Clears a BCH interrupt. */
+void gpmi_clear_bch(struct gpmi_nand_data *this)
+{
+	struct resources *r = &this->resources;
+	writel(BM_BCH_CTRL_COMPLETE_IRQ, r->bch_regs + HW_BCH_CTRL_CLR);
+}
+
+/* Returns the Ready/Busy status of the given chip. */
+int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
+{
+	struct resources *r = &this->resources;
+	uint32_t mask = 0;
+	uint32_t reg = 0;
+
+	if (GPMI_IS_MX23(this)) {
+		mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
+		reg = readl(r->gpmi_regs + HW_GPMI_DEBUG);
+	} else if (GPMI_IS_MX28(this) || GPMI_IS_MX6(this)) {
+		/*
+		 * In the imx6, all the ready/busy pins are bound
+		 * together. So we only need to check chip 0.
+		 */
+		if (GPMI_IS_MX6(this))
+			chip = 0;
+
+		/* MX28 shares the same R/B register as MX6Q. */
+		mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip);
+		reg = readl(r->gpmi_regs + HW_GPMI_STAT);
+	} else
+		dev_err(this->dev, "unknown arch.\n");
+	return reg & mask;
+}
+
+static inline void set_dma_type(struct gpmi_nand_data *this,
+					enum dma_ops_type type)
+{
+	this->last_dma_type = this->dma_type;
+	this->dma_type = type;
+}
+
+int gpmi_send_command(struct gpmi_nand_data *this)
+{
+	struct dma_chan *channel = get_dma_chan(this);
+	struct dma_async_tx_descriptor *desc;
+	struct scatterlist *sgl;
+	int chip = this->current_chip;
+	u32 pio[3];
+
+	/* [1] send out the PIO words */
+	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__WRITE)
+		| BM_GPMI_CTRL0_WORD_LENGTH
+		| BF_GPMI_CTRL0_CS(chip, this)
+		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+		| BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_CLE)
+		| BM_GPMI_CTRL0_ADDRESS_INCREMENT
+		| BF_GPMI_CTRL0_XFER_COUNT(this->command_length);
+	pio[1] = pio[2] = 0;
+	desc = dmaengine_prep_slave_sg(channel,
+					(struct scatterlist *)pio,
+					ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
+	if (!desc)
+		return -EINVAL;
+
+	/* [2] send out the COMMAND + ADDRESS string stored in @buffer */
+	sgl = &this->cmd_sgl;
+
+	sg_init_one(sgl, this->cmd_buffer, this->command_length);
+	dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE);
+	desc = dmaengine_prep_slave_sg(channel,
+				sgl, 1, DMA_MEM_TO_DEV,
+				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		return -EINVAL;
+
+	/* [3] submit the DMA */
+	set_dma_type(this, DMA_FOR_COMMAND);
+	return start_dma_without_bch_irq(this, desc);
+}
+
+int gpmi_send_data(struct gpmi_nand_data *this)
+{
+	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *channel = get_dma_chan(this);
+	int chip = this->current_chip;
+	uint32_t command_mode;
+	uint32_t address;
+	u32 pio[2];
+
+	/* [1] PIO */
+	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WRITE;
+	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+
+	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+		| BM_GPMI_CTRL0_WORD_LENGTH
+		| BF_GPMI_CTRL0_CS(chip, this)
+		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+		| BF_GPMI_CTRL0_ADDRESS(address)
+		| BF_GPMI_CTRL0_XFER_COUNT(this->upper_len);
+	pio[1] = 0;
+	desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
+					ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
+	if (!desc)
+		return -EINVAL;
+
+	/* [2] send DMA request */
+	prepare_data_dma(this, DMA_TO_DEVICE);
+	desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
+					1, DMA_MEM_TO_DEV,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		return -EINVAL;
+
+	/* [3] submit the DMA */
+	set_dma_type(this, DMA_FOR_WRITE_DATA);
+	return start_dma_without_bch_irq(this, desc);
+}
+
+int gpmi_read_data(struct gpmi_nand_data *this)
+{
+	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *channel = get_dma_chan(this);
+	int chip = this->current_chip;
+	u32 pio[2];
+
+	/* [1] : send PIO */
+	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__READ)
+		| BM_GPMI_CTRL0_WORD_LENGTH
+		| BF_GPMI_CTRL0_CS(chip, this)
+		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+		| BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA)
+		| BF_GPMI_CTRL0_XFER_COUNT(this->upper_len);
+	pio[1] = 0;
+	desc = dmaengine_prep_slave_sg(channel,
+					(struct scatterlist *)pio,
+					ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
+	if (!desc)
+		return -EINVAL;
+
+	/* [2] : send DMA request */
+	prepare_data_dma(this, DMA_FROM_DEVICE);
+	desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
+					1, DMA_DEV_TO_MEM,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		return -EINVAL;
+
+	/* [3] : submit the DMA */
+	set_dma_type(this, DMA_FOR_READ_DATA);
+	return start_dma_without_bch_irq(this, desc);
+}
+
+int gpmi_send_page(struct gpmi_nand_data *this,
+			dma_addr_t payload, dma_addr_t auxiliary)
+{
+	struct bch_geometry *geo = &this->bch_geometry;
+	uint32_t command_mode;
+	uint32_t address;
+	uint32_t ecc_command;
+	uint32_t buffer_mask;
+	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *channel = get_dma_chan(this);
+	int chip = this->current_chip;
+	u32 pio[6];
+
+	/* A DMA descriptor that does an ECC page read. */
+	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WRITE;
+	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+	ecc_command  = BV_GPMI_ECCCTRL_ECC_CMD__BCH_ENCODE;
+	buffer_mask  = BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE |
+				BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY;
+
+	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+		| BM_GPMI_CTRL0_WORD_LENGTH
+		| BF_GPMI_CTRL0_CS(chip, this)
+		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+		| BF_GPMI_CTRL0_ADDRESS(address)
+		| BF_GPMI_CTRL0_XFER_COUNT(0);
+	pio[1] = 0;
+	pio[2] = BM_GPMI_ECCCTRL_ENABLE_ECC
+		| BF_GPMI_ECCCTRL_ECC_CMD(ecc_command)
+		| BF_GPMI_ECCCTRL_BUFFER_MASK(buffer_mask);
+	pio[3] = geo->page_size;
+	pio[4] = payload;
+	pio[5] = auxiliary;
+
+	desc = dmaengine_prep_slave_sg(channel,
+					(struct scatterlist *)pio,
+					ARRAY_SIZE(pio), DMA_TRANS_NONE,
+					DMA_CTRL_ACK);
+	if (!desc)
+		return -EINVAL;
+
+	set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE);
+	return start_dma_with_bch_irq(this, desc);
+}
+
+int gpmi_read_page(struct gpmi_nand_data *this,
+				dma_addr_t payload, dma_addr_t auxiliary)
+{
+	struct bch_geometry *geo = &this->bch_geometry;
+	uint32_t command_mode;
+	uint32_t address;
+	uint32_t ecc_command;
+	uint32_t buffer_mask;
+	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *channel = get_dma_chan(this);
+	int chip = this->current_chip;
+	u32 pio[6];
+
+	/* [1] Wait for the chip to report ready. */
+	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY;
+	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+
+	pio[0] =  BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+		| BM_GPMI_CTRL0_WORD_LENGTH
+		| BF_GPMI_CTRL0_CS(chip, this)
+		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+		| BF_GPMI_CTRL0_ADDRESS(address)
+		| BF_GPMI_CTRL0_XFER_COUNT(0);
+	pio[1] = 0;
+	desc = dmaengine_prep_slave_sg(channel,
+				(struct scatterlist *)pio, 2,
+				DMA_TRANS_NONE, 0);
+	if (!desc)
+		return -EINVAL;
+
+	/* [2] Enable the BCH block and read. */
+	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__READ;
+	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+	ecc_command  = BV_GPMI_ECCCTRL_ECC_CMD__BCH_DECODE;
+	buffer_mask  = BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE
+			| BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY;
+
+	pio[0] =  BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+		| BM_GPMI_CTRL0_WORD_LENGTH
+		| BF_GPMI_CTRL0_CS(chip, this)
+		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+		| BF_GPMI_CTRL0_ADDRESS(address)
+		| BF_GPMI_CTRL0_XFER_COUNT(geo->page_size);
+
+	pio[1] = 0;
+	pio[2] =  BM_GPMI_ECCCTRL_ENABLE_ECC
+		| BF_GPMI_ECCCTRL_ECC_CMD(ecc_command)
+		| BF_GPMI_ECCCTRL_BUFFER_MASK(buffer_mask);
+	pio[3] = geo->page_size;
+	pio[4] = payload;
+	pio[5] = auxiliary;
+	desc = dmaengine_prep_slave_sg(channel,
+					(struct scatterlist *)pio,
+					ARRAY_SIZE(pio), DMA_TRANS_NONE,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		return -EINVAL;
+
+	/* [3] Disable the BCH block */
+	command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY;
+	address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+
+	pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+		| BM_GPMI_CTRL0_WORD_LENGTH
+		| BF_GPMI_CTRL0_CS(chip, this)
+		| BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+		| BF_GPMI_CTRL0_ADDRESS(address)
+		| BF_GPMI_CTRL0_XFER_COUNT(geo->page_size);
+	pio[1] = 0;
+	pio[2] = 0; /* clear GPMI_HW_GPMI_ECCCTRL, disable the BCH. */
+	desc = dmaengine_prep_slave_sg(channel,
+				(struct scatterlist *)pio, 3,
+				DMA_TRANS_NONE,
+				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		return -EINVAL;
+
+	/* [4] submit the DMA */
+	set_dma_type(this, DMA_FOR_READ_ECC_PAGE);
+	return start_dma_with_bch_irq(this, desc);
+}
+
+/**
+ * gpmi_copy_bits - copy bits from one memory region to another
+ * @dst: destination buffer
+ * @dst_bit_off: bit offset we're starting to write at
+ * @src: source buffer
+ * @src_bit_off: bit offset we're starting to read from
+ * @nbits: number of bits to copy
+ *
+ * This functions copies bits from one memory region to another, and is used by
+ * the GPMI driver to copy ECC sections which are not guaranteed to be byte
+ * aligned.
+ *
+ * src and dst should not overlap.
+ *
+ */
+void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
+		    const u8 *src, size_t src_bit_off,
+		    size_t nbits)
+{
+	size_t i;
+	size_t nbytes;
+	u32 src_buffer = 0;
+	size_t bits_in_src_buffer = 0;
+
+	if (!nbits)
+		return;
+
+	/*
+	 * Move src and dst pointers to the closest byte pointer and store bit
+	 * offsets within a byte.
+	 */
+	src += src_bit_off / 8;
+	src_bit_off %= 8;
+
+	dst += dst_bit_off / 8;
+	dst_bit_off %= 8;
+
+	/*
+	 * Initialize the src_buffer value with bits available in the first
+	 * byte of data so that we end up with a byte aligned src pointer.
+	 */
+	if (src_bit_off) {
+		src_buffer = src[0] >> src_bit_off;
+		if (nbits >= (8 - src_bit_off)) {
+			bits_in_src_buffer += 8 - src_bit_off;
+		} else {
+			src_buffer &= GENMASK(nbits - 1, 0);
+			bits_in_src_buffer += nbits;
+		}
+		nbits -= bits_in_src_buffer;
+		src++;
+	}
+
+	/* Calculate the number of bytes that can be copied from src to dst. */
+	nbytes = nbits / 8;
+
+	/* Try to align dst to a byte boundary. */
+	if (dst_bit_off) {
+		if (bits_in_src_buffer < (8 - dst_bit_off) && nbytes) {
+			src_buffer |= src[0] << bits_in_src_buffer;
+			bits_in_src_buffer += 8;
+			src++;
+			nbytes--;
+		}
+
+		if (bits_in_src_buffer >= (8 - dst_bit_off)) {
+			dst[0] &= GENMASK(dst_bit_off - 1, 0);
+			dst[0] |= src_buffer << dst_bit_off;
+			src_buffer >>= (8 - dst_bit_off);
+			bits_in_src_buffer -= (8 - dst_bit_off);
+			dst_bit_off = 0;
+			dst++;
+			if (bits_in_src_buffer > 7) {
+				bits_in_src_buffer -= 8;
+				dst[0] = src_buffer;
+				dst++;
+				src_buffer >>= 8;
+			}
+		}
+	}
+
+	if (!bits_in_src_buffer && !dst_bit_off) {
+		/*
+		 * Both src and dst pointers are byte aligned, thus we can
+		 * just use the optimized memcpy function.
+		 */
+		if (nbytes)
+			memcpy(dst, src, nbytes);
+	} else {
+		/*
+		 * src buffer is not byte aligned, hence we have to copy each
+		 * src byte to the src_buffer variable before extracting a byte
+		 * to store in dst.
+		 */
+		for (i = 0; i < nbytes; i++) {
+			src_buffer |= src[i] << bits_in_src_buffer;
+			dst[i] = src_buffer;
+			src_buffer >>= 8;
+		}
+	}
+	/* Update dst and src pointers */
+	dst += nbytes;
+	src += nbytes;
+
+	/*
+	 * nbits is the number of remaining bits. It should not exceed 8 as
+	 * we've already copied as much bytes as possible.
+	 */
+	nbits %= 8;
+
+	/*
+	 * If there's no more bits to copy to the destination and src buffer
+	 * was already byte aligned, then we're done.
+	 */
+	if (!nbits && !bits_in_src_buffer)
+		return;
+
+	/* Copy the remaining bits to src_buffer */
+	if (nbits)
+		src_buffer |= (*src & GENMASK(nbits - 1, 0)) <<
+			      bits_in_src_buffer;
+	bits_in_src_buffer += nbits;
+
+	/*
+	 * In case there were not enough bits to get a byte aligned dst buffer
+	 * prepare the src_buffer variable to match the dst organization (shift
+	 * src_buffer by dst_bit_off and retrieve the least significant bits
+	 * from dst).
+	 */
+	if (dst_bit_off)
+		src_buffer = (src_buffer << dst_bit_off) |
+			     (*dst & GENMASK(dst_bit_off - 1, 0));
+	bits_in_src_buffer += dst_bit_off;
+
+	/*
+	 * Keep most significant bits from dst if we end up with an unaligned
+	 * number of bits.
+	 */
+	nbytes = bits_in_src_buffer / 8;
+	if (bits_in_src_buffer % 8) {
+		src_buffer |= (dst[nbytes] &
+			       GENMASK(7, bits_in_src_buffer % 8)) <<
+			      (nbytes * 8);
+		nbytes++;
+	}
+
+	/* Copy the remaining bytes to dst */
+	for (i = 0; i < nbytes; i++) {
+		dst[i] = src_buffer;
+		src_buffer >>= 8;
+	}
+}
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
similarity index 97%
rename from drivers/mtd/nand/gpmi-nand/gpmi-nand.c
rename to drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 61fdd73..c2597c8 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -94,7 +94,7 @@ static const struct mtd_ooblayout_ops gpmi_ooblayout_ops = {
 static const struct gpmi_devdata gpmi_devdata_imx23 = {
 	.type = IS_MX23,
 	.bch_max_ecc_strength = 20,
-	.max_chain_delay = 16,
+	.max_chain_delay = 16000,
 	.clks = gpmi_clks_for_mx2x,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx2x),
 };
@@ -102,7 +102,7 @@ static const struct gpmi_devdata gpmi_devdata_imx23 = {
 static const struct gpmi_devdata gpmi_devdata_imx28 = {
 	.type = IS_MX28,
 	.bch_max_ecc_strength = 20,
-	.max_chain_delay = 16,
+	.max_chain_delay = 16000,
 	.clks = gpmi_clks_for_mx2x,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx2x),
 };
@@ -114,7 +114,7 @@ static const char * const gpmi_clks_for_mx6[] = {
 static const struct gpmi_devdata gpmi_devdata_imx6q = {
 	.type = IS_MX6Q,
 	.bch_max_ecc_strength = 40,
-	.max_chain_delay = 12,
+	.max_chain_delay = 12000,
 	.clks = gpmi_clks_for_mx6,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
 };
@@ -122,7 +122,7 @@ static const struct gpmi_devdata gpmi_devdata_imx6q = {
 static const struct gpmi_devdata gpmi_devdata_imx6sx = {
 	.type = IS_MX6SX,
 	.bch_max_ecc_strength = 62,
-	.max_chain_delay = 12,
+	.max_chain_delay = 12000,
 	.clks = gpmi_clks_for_mx6,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
 };
@@ -134,7 +134,7 @@ static const char * const gpmi_clks_for_mx7d[] = {
 static const struct gpmi_devdata gpmi_devdata_imx7d = {
 	.type = IS_MX7D,
 	.bch_max_ecc_strength = 62,
-	.max_chain_delay = 12,
+	.max_chain_delay = 12000,
 	.clks = gpmi_clks_for_mx7d,
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx7d),
 };
@@ -695,34 +695,6 @@ static void release_resources(struct gpmi_nand_data *this)
 	release_dma_channels(this);
 }
 
-static int init_hardware(struct gpmi_nand_data *this)
-{
-	int ret;
-
-	/*
-	 * This structure contains the "safe" GPMI timing that should succeed
-	 * with any NAND Flash device
-	 * (although, with less-than-optimal performance).
-	 */
-	struct nand_timing  safe_timing = {
-		.data_setup_in_ns        = 80,
-		.data_hold_in_ns         = 60,
-		.address_setup_in_ns     = 25,
-		.gpmi_sample_delay_in_ns =  6,
-		.tREA_in_ns              = -1,
-		.tRLOH_in_ns             = -1,
-		.tRHOH_in_ns             = -1,
-	};
-
-	/* Initialize the hardwares. */
-	ret = gpmi_init(this);
-	if (ret)
-		return ret;
-
-	this->timing = safe_timing;
-	return 0;
-}
-
 static int read_page_prepare(struct gpmi_nand_data *this,
 			void *destination, unsigned length,
 			void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
@@ -938,11 +910,32 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct gpmi_nand_data *this = nand_get_controller_data(chip);
+	int ret;
 
-	if ((this->current_chip < 0) && (chipnr >= 0))
-		gpmi_begin(this);
-	else if ((this->current_chip >= 0) && (chipnr < 0))
-		gpmi_end(this);
+	/*
+	 * For power consumption matters, disable/enable the clock each time a
+	 * die is selected/unselected.
+	 */
+	if (this->current_chip < 0 && chipnr >= 0) {
+		ret = gpmi_enable_clk(this);
+		if (ret)
+			dev_err(this->dev, "Failed to enable the clock\n");
+	} else if (this->current_chip >= 0 && chipnr < 0) {
+		ret = gpmi_disable_clk(this);
+		if (ret)
+			dev_err(this->dev, "Failed to disable the clock\n");
+	}
+
+	/*
+	 * This driver currently supports only one NAND chip. Plus, dies share
+	 * the same configuration. So once timings have been applied on the
+	 * controller side, they will not change anymore. When the time will
+	 * come, the check on must_apply_timings will have to be dropped.
+	 */
+	if (chipnr >= 0 && this->hw.must_apply_timings) {
+		this->hw.must_apply_timings = false;
+		gpmi_nfc_apply_timings(this);
+	}
 
 	this->current_chip = chipnr;
 }
@@ -1955,14 +1948,6 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
 		chip->options |= NAND_SUBPAGE_READ;
 	}
 
-	/*
-	 * Can we enable the extra features? such as EDO or Sync mode.
-	 *
-	 * We do not check the return value now. That's means if we fail in
-	 * enable the extra features, we still can run in the normal way.
-	 */
-	gpmi_extra_init(this);
-
 	return 0;
 }
 
@@ -1983,6 +1968,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
 	nand_set_controller_data(chip, this);
 	nand_set_flash_node(chip, this->pdev->dev.of_node);
 	chip->select_chip	= gpmi_select_chip;
+	chip->setup_data_interface = gpmi_setup_data_interface;
 	chip->cmd_ctrl		= gpmi_cmd_ctrl;
 	chip->dev_ready		= gpmi_dev_ready;
 	chip->read_byte		= gpmi_read_byte;
@@ -2093,7 +2079,7 @@ static int gpmi_nand_probe(struct platform_device *pdev)
 	if (ret)
 		goto exit_acquire_resources;
 
-	ret = init_hardware(this);
+	ret = gpmi_init(this);
 	if (ret)
 		goto exit_nfc_init;
 
@@ -2141,7 +2127,6 @@ static int gpmi_pm_resume(struct device *dev)
 		return ret;
 
 	/* re-init the GPMI registers */
-	this->flags &= ~GPMI_TIMING_INIT_OK;
 	ret = gpmi_init(this);
 	if (ret) {
 		dev_err(this->dev, "Error setting GPMI : %d\n", ret);
@@ -2155,9 +2140,6 @@ static int gpmi_pm_resume(struct device *dev)
 		return ret;
 	}
 
-	/* re-init others */
-	gpmi_extra_init(this);
-
 	return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h
new file mode 100644
index 0000000..62fde59
--- /dev/null
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h
@@ -0,0 +1,236 @@
+/*
+ * Freescale GPMI NAND Flash Driver
+ *
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008 Embedded Alley Solutions, 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.
+ */
+#ifndef __DRIVERS_MTD_NAND_GPMI_NAND_H
+#define __DRIVERS_MTD_NAND_GPMI_NAND_H
+
+#include <linux/mtd/rawnand.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+
+#define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */
+struct resources {
+	void __iomem  *gpmi_regs;
+	void __iomem  *bch_regs;
+	unsigned int  dma_low_channel;
+	unsigned int  dma_high_channel;
+	struct clk    *clock[GPMI_CLK_MAX];
+};
+
+/**
+ * struct bch_geometry - BCH geometry description.
+ * @gf_len:                   The length of Galois Field. (e.g., 13 or 14)
+ * @ecc_strength:             A number that describes the strength of the ECC
+ *                            algorithm.
+ * @page_size:                The size, in bytes, of a physical page, including
+ *                            both data and OOB.
+ * @metadata_size:            The size, in bytes, of the metadata.
+ * @ecc_chunk_size:           The size, in bytes, of a single ECC chunk. Note
+ *                            the first chunk in the page includes both data and
+ *                            metadata, so it's a bit larger than this value.
+ * @ecc_chunk_count:          The number of ECC chunks in the page,
+ * @payload_size:             The size, in bytes, of the payload buffer.
+ * @auxiliary_size:           The size, in bytes, of the auxiliary buffer.
+ * @auxiliary_status_offset:  The offset into the auxiliary buffer at which
+ *                            the ECC status appears.
+ * @block_mark_byte_offset:   The byte offset in the ECC-based page view at
+ *                            which the underlying physical block mark appears.
+ * @block_mark_bit_offset:    The bit offset into the ECC-based page view at
+ *                            which the underlying physical block mark appears.
+ */
+struct bch_geometry {
+	unsigned int  gf_len;
+	unsigned int  ecc_strength;
+	unsigned int  page_size;
+	unsigned int  metadata_size;
+	unsigned int  ecc_chunk_size;
+	unsigned int  ecc_chunk_count;
+	unsigned int  payload_size;
+	unsigned int  auxiliary_size;
+	unsigned int  auxiliary_status_offset;
+	unsigned int  block_mark_byte_offset;
+	unsigned int  block_mark_bit_offset;
+};
+
+/**
+ * struct boot_rom_geometry - Boot ROM geometry description.
+ * @stride_size_in_pages:        The size of a boot block stride, in pages.
+ * @search_area_stride_exponent: The logarithm to base 2 of the size of a
+ *                               search area in boot block strides.
+ */
+struct boot_rom_geometry {
+	unsigned int  stride_size_in_pages;
+	unsigned int  search_area_stride_exponent;
+};
+
+/* DMA operations types */
+enum dma_ops_type {
+	DMA_FOR_COMMAND = 1,
+	DMA_FOR_READ_DATA,
+	DMA_FOR_WRITE_DATA,
+	DMA_FOR_READ_ECC_PAGE,
+	DMA_FOR_WRITE_ECC_PAGE
+};
+
+enum gpmi_type {
+	IS_MX23,
+	IS_MX28,
+	IS_MX6Q,
+	IS_MX6SX,
+	IS_MX7D,
+};
+
+struct gpmi_devdata {
+	enum gpmi_type type;
+	int bch_max_ecc_strength;
+	int max_chain_delay; /* See the async EDO mode */
+	const char * const *clks;
+	const int clks_count;
+};
+
+/**
+ * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
+ * @must_apply_timings:        Whether controller timings have already been
+ *                             applied or not (useful only while there is
+ *                             support for only one chip select)
+ * @clk_rate:                  The clock rate that must be used to derive the
+ *                             following parameters
+ * @timing0:                   HW_GPMI_TIMING0 register
+ * @timing1:                   HW_GPMI_TIMING1 register
+ * @ctrl1n:                    HW_GPMI_CTRL1n register
+ */
+struct gpmi_nfc_hardware_timing {
+	bool must_apply_timings;
+	unsigned long int clk_rate;
+	u32 timing0;
+	u32 timing1;
+	u32 ctrl1n;
+};
+
+struct gpmi_nand_data {
+	/* Devdata */
+	const struct gpmi_devdata *devdata;
+
+	/* System Interface */
+	struct device		*dev;
+	struct platform_device	*pdev;
+
+	/* Resources */
+	struct resources	resources;
+
+	/* Flash Hardware */
+	struct gpmi_nfc_hardware_timing hw;
+
+	/* BCH */
+	struct bch_geometry	bch_geometry;
+	struct completion	bch_done;
+
+	/* NAND Boot issue */
+	bool			swap_block_mark;
+	struct boot_rom_geometry rom_geometry;
+
+	/* MTD / NAND */
+	struct nand_chip	nand;
+
+	/* General-use Variables */
+	int			current_chip;
+	unsigned int		command_length;
+
+	/* passed from upper layer */
+	uint8_t			*upper_buf;
+	int			upper_len;
+
+	/* for DMA operations */
+	bool			direct_dma_map_ok;
+
+	struct scatterlist	cmd_sgl;
+	char			*cmd_buffer;
+
+	struct scatterlist	data_sgl;
+	char			*data_buffer_dma;
+
+	void			*page_buffer_virt;
+	dma_addr_t		page_buffer_phys;
+	unsigned int		page_buffer_size;
+
+	void			*payload_virt;
+	dma_addr_t		payload_phys;
+
+	void			*auxiliary_virt;
+	dma_addr_t		auxiliary_phys;
+
+	void			*raw_buffer;
+
+	/* DMA channels */
+#define DMA_CHANS		8
+	struct dma_chan		*dma_chans[DMA_CHANS];
+	enum dma_ops_type	last_dma_type;
+	enum dma_ops_type	dma_type;
+	struct completion	dma_done;
+
+	/* private */
+	void			*private;
+};
+
+/* Common Services */
+int common_nfc_set_geometry(struct gpmi_nand_data *);
+struct dma_chan *get_dma_chan(struct gpmi_nand_data *);
+void prepare_data_dma(struct gpmi_nand_data *,
+		      enum dma_data_direction dr);
+int start_dma_without_bch_irq(struct gpmi_nand_data *,
+			      struct dma_async_tx_descriptor *);
+int start_dma_with_bch_irq(struct gpmi_nand_data *,
+			   struct dma_async_tx_descriptor *);
+
+/* GPMI-NAND helper function library */
+int gpmi_init(struct gpmi_nand_data *);
+void gpmi_clear_bch(struct gpmi_nand_data *);
+void gpmi_dump_info(struct gpmi_nand_data *);
+int bch_set_geometry(struct gpmi_nand_data *);
+int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip);
+int gpmi_send_command(struct gpmi_nand_data *);
+int gpmi_enable_clk(struct gpmi_nand_data *this);
+int gpmi_disable_clk(struct gpmi_nand_data *this);
+int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr,
+			      const struct nand_data_interface *conf);
+void gpmi_nfc_apply_timings(struct gpmi_nand_data *this);
+int gpmi_read_data(struct gpmi_nand_data *);
+int gpmi_send_data(struct gpmi_nand_data *);
+int gpmi_send_page(struct gpmi_nand_data *,
+		   dma_addr_t payload, dma_addr_t auxiliary);
+int gpmi_read_page(struct gpmi_nand_data *,
+		   dma_addr_t payload, dma_addr_t auxiliary);
+
+void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
+		    const u8 *src, size_t src_bit_off,
+		    size_t nbits);
+
+/* BCH : Status Block Completion Codes */
+#define STATUS_GOOD		0x00
+#define STATUS_ERASED		0xff
+#define STATUS_UNCORRECTABLE	0xfe
+
+/* Use the devdata to distinguish different Archs. */
+#define GPMI_IS_MX23(x)		((x)->devdata->type == IS_MX23)
+#define GPMI_IS_MX28(x)		((x)->devdata->type == IS_MX28)
+#define GPMI_IS_MX6Q(x)		((x)->devdata->type == IS_MX6Q)
+#define GPMI_IS_MX6SX(x)	((x)->devdata->type == IS_MX6SX)
+#define GPMI_IS_MX7D(x)		((x)->devdata->type == IS_MX7D)
+
+#define GPMI_IS_MX6(x)		(GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) || \
+				 GPMI_IS_MX7D(x))
+#endif
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h
similarity index 97%
rename from drivers/mtd/nand/gpmi-nand/gpmi-regs.h
rename to drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h
index 82114cd..d92bf32 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h
@@ -147,6 +147,11 @@
 
 #define BM_GPMI_CTRL1_GPMI_MODE				(1 << 0)
 
+#define BM_GPMI_CTRL1_CLEAR_MASK (BM_GPMI_CTRL1_WRN_DLY_SEL | \
+				  BM_GPMI_CTRL1_DLL_ENABLE |  \
+				  BM_GPMI_CTRL1_RDN_DELAY |   \
+				  BM_GPMI_CTRL1_HALF_PERIOD)
+
 #define HW_GPMI_TIMING0					0x00000070
 
 #define BP_GPMI_TIMING0_ADDRESS_SETUP			16
diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c
similarity index 99%
rename from drivers/mtd/nand/hisi504_nand.c
rename to drivers/mtd/nand/raw/hisi504_nand.c
index cb86279..27558a6 100644
--- a/drivers/mtd/nand/hisi504_nand.c
+++ b/drivers/mtd/nand/raw/hisi504_nand.c
@@ -762,8 +762,8 @@ static int hisi_nfc_probe(struct platform_device *pdev)
 	chip->write_buf		= hisi_nfc_write_buf;
 	chip->read_buf		= hisi_nfc_read_buf;
 	chip->chip_delay	= HINFC504_CHIP_DELAY;
-	chip->onfi_set_features	= nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features	= nand_onfi_get_set_features_notsupp;
+	chip->set_features	= nand_get_set_features_notsupp;
+	chip->get_features	= nand_get_set_features_notsupp;
 
 	hisi_nfc_host_init(host);
 
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
similarity index 100%
rename from drivers/mtd/nand/jz4740_nand.c
rename to drivers/mtd/nand/raw/jz4740_nand.c
diff --git a/drivers/mtd/nand/jz4780_bch.c b/drivers/mtd/nand/raw/jz4780_bch.c
similarity index 100%
rename from drivers/mtd/nand/jz4780_bch.c
rename to drivers/mtd/nand/raw/jz4780_bch.c
diff --git a/drivers/mtd/nand/jz4780_bch.h b/drivers/mtd/nand/raw/jz4780_bch.h
similarity index 100%
rename from drivers/mtd/nand/jz4780_bch.h
rename to drivers/mtd/nand/raw/jz4780_bch.h
diff --git a/drivers/mtd/nand/jz4780_nand.c b/drivers/mtd/nand/raw/jz4780_nand.c
similarity index 100%
rename from drivers/mtd/nand/jz4780_nand.c
rename to drivers/mtd/nand/raw/jz4780_nand.c
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c
similarity index 100%
rename from drivers/mtd/nand/lpc32xx_mlc.c
rename to drivers/mtd/nand/raw/lpc32xx_mlc.c
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c
similarity index 100%
rename from drivers/mtd/nand/lpc32xx_slc.c
rename to drivers/mtd/nand/raw/lpc32xx_slc.c
diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
similarity index 97%
rename from drivers/mtd/nand/marvell_nand.c
rename to drivers/mtd/nand/raw/marvell_nand.c
index 2196f2a..10e9532 100644
--- a/drivers/mtd/nand/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -307,7 +307,8 @@ struct marvell_nfc_caps {
  * @controller:		Base controller structure
  * @dev:		Parent device (used to print error messages)
  * @regs:		NAND controller registers
- * @ecc_clk:		ECC block clock, two times the NAND controller clock
+ * @core_clk:		Core clock
+ * @reg_clk:		Regiters clock
  * @complete:		Completion object to wait for NAND controller events
  * @assigned_cs:	Bitmask describing already assigned CS lines
  * @chips:		List containing all the NAND chips attached to
@@ -320,7 +321,8 @@ struct marvell_nfc {
 	struct nand_hw_control controller;
 	struct device *dev;
 	void __iomem *regs;
-	struct clk *ecc_clk;
+	struct clk *core_clk;
+	struct clk *reg_clk;
 	struct completion complete;
 	unsigned long assigned_cs;
 	struct list_head chips;
@@ -379,6 +381,8 @@ struct marvell_nfc_timings {
  * return the number of clock periods.
  */
 #define TO_CYCLES(ps, period_ns) (DIV_ROUND_UP(ps / 1000, period_ns))
+#define TO_CYCLES64(ps, period_ns) (DIV_ROUND_UP_ULL(div_u64(ps, 1000), \
+						     period_ns))
 
 /**
  * NAND driver structure filled during the parsing of the ->exec_op() subop
@@ -2189,7 +2193,7 @@ static int marvell_nfc_setup_data_interface(struct mtd_info *mtd, int chipnr,
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip);
 	struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
-	unsigned int period_ns = 1000000000 / clk_get_rate(nfc->ecc_clk) * 2;
+	unsigned int period_ns = 1000000000 / clk_get_rate(nfc->core_clk) * 2;
 	const struct nand_sdr_timings *sdr;
 	struct marvell_nfc_timings nfc_tmg;
 	int read_delay;
@@ -2236,8 +2240,20 @@ static int marvell_nfc_setup_data_interface(struct mtd_info *mtd, int chipnr,
 	nfc_tmg.tRHW = TO_CYCLES(max_t(int, sdr->tRHW_min, sdr->tCCS_min),
 				 period_ns);
 
-	/* Use WAIT_MODE (wait for RB line) instead of only relying on delays */
-	nfc_tmg.tR = TO_CYCLES(sdr->tWB_max, period_ns);
+	/*
+	 * NFCv2: Use WAIT_MODE (wait for RB line), do not rely only on delays.
+	 * NFCv1: No WAIT_MODE, tR must be maximal.
+	 */
+	if (nfc->caps->is_nfcv2) {
+		nfc_tmg.tR = TO_CYCLES(sdr->tWB_max, period_ns);
+	} else {
+		nfc_tmg.tR = TO_CYCLES64(sdr->tWB_max + sdr->tR_max,
+					 period_ns);
+		if (nfc_tmg.tR + 3 > nfc_tmg.tCH)
+			nfc_tmg.tR = nfc_tmg.tCH - 3;
+		else
+			nfc_tmg.tR = 0;
+	}
 
 	if (chipnr < 0)
 		return 0;
@@ -2249,18 +2265,24 @@ static int marvell_nfc_setup_data_interface(struct mtd_info *mtd, int chipnr,
 		NDTR0_TWP(nfc_tmg.tWP) |
 		NDTR0_TWH(nfc_tmg.tWH) |
 		NDTR0_TCS(nfc_tmg.tCS) |
-		NDTR0_TCH(nfc_tmg.tCH) |
-		NDTR0_RD_CNT_DEL(read_delay) |
-		NDTR0_SELCNTR |
-		NDTR0_TADL(nfc_tmg.tADL);
+		NDTR0_TCH(nfc_tmg.tCH);
 
 	marvell_nand->ndtr1 =
 		NDTR1_TAR(nfc_tmg.tAR) |
 		NDTR1_TWHR(nfc_tmg.tWHR) |
-		NDTR1_TRHW(nfc_tmg.tRHW) |
-		NDTR1_WAIT_MODE |
 		NDTR1_TR(nfc_tmg.tR);
 
+	if (nfc->caps->is_nfcv2) {
+		marvell_nand->ndtr0 |=
+			NDTR0_RD_CNT_DEL(read_delay) |
+			NDTR0_SELCNTR |
+			NDTR0_TADL(nfc_tmg.tADL);
+
+		marvell_nand->ndtr1 |=
+			NDTR1_TRHW(nfc_tmg.tRHW) |
+			NDTR1_WAIT_MODE;
+	}
+
 	return 0;
 }
 
@@ -2395,8 +2417,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
 
 	chip->exec_op = marvell_nfc_exec_op;
 	chip->select_chip = marvell_nfc_select_chip;
-	if (nfc->caps->is_nfcv2 &&
-	    !of_property_read_bool(np, "marvell,nand-keep-config"))
+	if (!of_property_read_bool(np, "marvell,nand-keep-config"))
 		chip->setup_data_interface = marvell_nfc_setup_data_interface;
 
 	mtd = nand_to_mtd(chip);
@@ -2520,8 +2541,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
 
 	if (pdata)
 		/* Legacy bindings support only one chip */
-		ret = mtd_device_register(mtd, pdata->parts[0],
-					  pdata->nr_parts[0]);
+		ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
 	else
 		ret = mtd_device_register(mtd, NULL, 0);
 	if (ret) {
@@ -2739,20 +2759,37 @@ static int marvell_nfc_probe(struct platform_device *pdev)
 		return irq;
 	}
 
-	nfc->ecc_clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(nfc->ecc_clk))
-		return PTR_ERR(nfc->ecc_clk);
+	nfc->core_clk = devm_clk_get(&pdev->dev, "core");
 
-	ret = clk_prepare_enable(nfc->ecc_clk);
+	/* Managed the legacy case (when the first clock was not named) */
+	if (nfc->core_clk == ERR_PTR(-ENOENT))
+		nfc->core_clk = devm_clk_get(&pdev->dev, NULL);
+
+	if (IS_ERR(nfc->core_clk))
+		return PTR_ERR(nfc->core_clk);
+
+	ret = clk_prepare_enable(nfc->core_clk);
 	if (ret)
 		return ret;
 
+	nfc->reg_clk = devm_clk_get(&pdev->dev, "reg");
+	if (PTR_ERR(nfc->reg_clk) != -ENOENT) {
+		if (!IS_ERR(nfc->reg_clk)) {
+			ret = clk_prepare_enable(nfc->reg_clk);
+			if (ret)
+				goto unprepare_core_clk;
+		} else {
+			ret = PTR_ERR(nfc->reg_clk);
+			goto unprepare_core_clk;
+		}
+	}
+
 	marvell_nfc_disable_int(nfc, NDCR_ALL_INT);
 	marvell_nfc_clear_int(nfc, NDCR_ALL_INT);
 	ret = devm_request_irq(dev, irq, marvell_nfc_isr,
 			       0, "marvell-nfc", nfc);
 	if (ret)
-		goto unprepare_clk;
+		goto unprepare_reg_clk;
 
 	/* Get NAND controller capabilities */
 	if (pdev->id_entry)
@@ -2763,24 +2800,26 @@ static int marvell_nfc_probe(struct platform_device *pdev)
 	if (!nfc->caps) {
 		dev_err(dev, "Could not retrieve NFC caps\n");
 		ret = -EINVAL;
-		goto unprepare_clk;
+		goto unprepare_reg_clk;
 	}
 
 	/* Init the controller and then probe the chips */
 	ret = marvell_nfc_init(nfc);
 	if (ret)
-		goto unprepare_clk;
+		goto unprepare_reg_clk;
 
 	platform_set_drvdata(pdev, nfc);
 
 	ret = marvell_nand_chips_init(dev, nfc);
 	if (ret)
-		goto unprepare_clk;
+		goto unprepare_reg_clk;
 
 	return 0;
 
-unprepare_clk:
-	clk_disable_unprepare(nfc->ecc_clk);
+unprepare_reg_clk:
+	clk_disable_unprepare(nfc->reg_clk);
+unprepare_core_clk:
+	clk_disable_unprepare(nfc->core_clk);
 
 	return ret;
 }
@@ -2796,7 +2835,8 @@ static int marvell_nfc_remove(struct platform_device *pdev)
 		dma_release_channel(nfc->dma_chan);
 	}
 
-	clk_disable_unprepare(nfc->ecc_clk);
+	clk_disable_unprepare(nfc->reg_clk);
+	clk_disable_unprepare(nfc->core_clk);
 
 	return 0;
 }
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/raw/mpc5121_nfc.c
similarity index 98%
rename from drivers/mtd/nand/mpc5121_nfc.c
rename to drivers/mtd/nand/raw/mpc5121_nfc.c
index b6b97cc9..6d1740d 100644
--- a/drivers/mtd/nand/mpc5121_nfc.c
+++ b/drivers/mtd/nand/raw/mpc5121_nfc.c
@@ -6,9 +6,8 @@
  * by OSADL membership fees in 2009;  for details see www.osadl.org.
  *
  * Based on original driver from Freescale Semiconductor
- * written by John Rigby <jrigby@freescale.com> on basis
- * of drivers/mtd/nand/mxc_nand.c. Reworked and extended
- * Piotr Ziecik <kosmo@semihalf.com>.
+ * written by John Rigby <jrigby@freescale.com> on basis of mxc_nand.c.
+ * Reworked and extended by Piotr Ziecik <kosmo@semihalf.com>.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -708,8 +707,8 @@ static int mpc5121_nfc_probe(struct platform_device *op)
 	chip->read_buf = mpc5121_nfc_read_buf;
 	chip->write_buf = mpc5121_nfc_write_buf;
 	chip->select_chip = mpc5121_nfc_select_chip;
-	chip->onfi_set_features	= nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features	= nand_onfi_get_set_features_notsupp;
+	chip->set_features	= nand_get_set_features_notsupp;
+	chip->get_features	= nand_get_set_features_notsupp;
 	chip->bbt_options = NAND_BBT_USE_FLASH;
 	chip->ecc.mode = NAND_ECC_SOFT;
 	chip->ecc.algo = NAND_ECC_HAMMING;
diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/raw/mtk_ecc.c
similarity index 100%
rename from drivers/mtd/nand/mtk_ecc.c
rename to drivers/mtd/nand/raw/mtk_ecc.c
diff --git a/drivers/mtd/nand/mtk_ecc.h b/drivers/mtd/nand/raw/mtk_ecc.h
similarity index 100%
rename from drivers/mtd/nand/mtk_ecc.h
rename to drivers/mtd/nand/raw/mtk_ecc.h
diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
similarity index 100%
rename from drivers/mtd/nand/mtk_nand.c
rename to drivers/mtd/nand/raw/mtk_nand.c
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/raw/mxc_nand.c
similarity index 87%
rename from drivers/mtd/nand/mxc_nand.c
rename to drivers/mtd/nand/raw/mxc_nand.c
index f3be0b2..45786e7 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/raw/mxc_nand.c
@@ -140,6 +140,8 @@ struct mxc_nand_host;
 
 struct mxc_nand_devtype_data {
 	void (*preset)(struct mtd_info *);
+	int (*read_page)(struct nand_chip *chip, void *buf, void *oob, bool ecc,
+			 int page);
 	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_page)(struct mtd_info *, unsigned int);
@@ -150,10 +152,9 @@ struct mxc_nand_devtype_data {
 	u32 (*get_ecc_status)(struct mxc_nand_host *);
 	const struct mtd_ooblayout_ops *ooblayout;
 	void (*select_chip)(struct mtd_info *mtd, int chip);
-	int (*correct_data)(struct mtd_info *mtd, u_char *dat,
-			u_char *read_ecc, u_char *calc_ecc);
 	int (*setup_data_interface)(struct mtd_info *mtd, int csline,
 				    const struct nand_data_interface *conf);
+	void (*enable_hwecc)(struct nand_chip *chip, bool enable);
 
 	/*
 	 * On i.MX21 the CONFIG2:INT bit cannot be read if interrupts are masked
@@ -252,6 +253,109 @@ static void memcpy16_toio(void __iomem *trg, const void *src, int size)
 		__raw_writew(*s++, t++);
 }
 
+/*
+ * The controller splits a page into data chunks of 512 bytes + partial oob.
+ * There are writesize / 512 such chunks, the size of the partial oob parts is
+ * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then
+ * contains additionally the byte lost by rounding (if any).
+ * This function handles the needed shuffling between host->data_buf (which
+ * holds a page in natural order, i.e. writesize bytes data + oobsize bytes
+ * spare) and the NFC buffer.
+ */
+static void copy_spare(struct mtd_info *mtd, bool bfrom, void *buf)
+{
+	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(this);
+	u16 i, oob_chunk_size;
+	u16 num_chunks = mtd->writesize / 512;
+
+	u8 *d = buf;
+	u8 __iomem *s = host->spare0;
+	u16 sparebuf_size = host->devtype_data->spare_len;
+
+	/* size of oob chunk for all but possibly the last one */
+	oob_chunk_size = (host->used_oobsize / num_chunks) & ~1;
+
+	if (bfrom) {
+		for (i = 0; i < num_chunks - 1; i++)
+			memcpy16_fromio(d + i * oob_chunk_size,
+					s + i * sparebuf_size,
+					oob_chunk_size);
+
+		/* the last chunk */
+		memcpy16_fromio(d + i * oob_chunk_size,
+				s + i * sparebuf_size,
+				host->used_oobsize - i * oob_chunk_size);
+	} else {
+		for (i = 0; i < num_chunks - 1; i++)
+			memcpy16_toio(&s[i * sparebuf_size],
+				      &d[i * oob_chunk_size],
+				      oob_chunk_size);
+
+		/* the last chunk */
+		memcpy16_toio(&s[i * sparebuf_size],
+			      &d[i * oob_chunk_size],
+			      host->used_oobsize - i * oob_chunk_size);
+	}
+}
+
+/*
+ * MXC NANDFC can only perform full page+spare or spare-only read/write.  When
+ * the upper layers perform a read/write buf operation, the saved column address
+ * is used to index into the full page. So usually this function is called with
+ * column == 0 (unless no column cycle is needed indicated by column == -1)
+ */
+static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
+{
+	struct nand_chip *nand_chip = mtd_to_nand(mtd);
+	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+
+	/* Write out column address, if necessary */
+	if (column != -1) {
+		host->devtype_data->send_addr(host, column & 0xff,
+					      page_addr == -1);
+		if (mtd->writesize > 512)
+			/* another col addr cycle for 2k page */
+			host->devtype_data->send_addr(host,
+						      (column >> 8) & 0xff,
+						      false);
+	}
+
+	/* Write out page address, if necessary */
+	if (page_addr != -1) {
+		/* paddr_0 - p_addr_7 */
+		host->devtype_data->send_addr(host, (page_addr & 0xff), false);
+
+		if (mtd->writesize > 512) {
+			if (mtd->size >= 0x10000000) {
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff,
+						false);
+				host->devtype_data->send_addr(host,
+						(page_addr >> 16) & 0xff,
+						true);
+			} else
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff, true);
+		} else {
+			if (nand_chip->options & NAND_ROW_ADDR_3) {
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff,
+						false);
+				host->devtype_data->send_addr(host,
+						(page_addr >> 16) & 0xff,
+						true);
+			} else
+				/* paddr_8 - paddr_15 */
+				host->devtype_data->send_addr(host,
+						(page_addr >> 8) & 0xff, true);
+		}
+	}
+}
+
 static int check_int_v3(struct mxc_nand_host *host)
 {
 	uint32_t tmp;
@@ -575,6 +679,42 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
 	return ret;
 }
 
+static void mxc_nand_enable_hwecc_v1_v2(struct nand_chip *chip, bool enable)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	uint16_t config1;
+
+	if (chip->ecc.mode != NAND_ECC_HW)
+		return;
+
+	config1 = readw(NFC_V1_V2_CONFIG1);
+
+	if (enable)
+		config1 |= NFC_V1_V2_CONFIG1_ECC_EN;
+	else
+		config1 &= ~NFC_V1_V2_CONFIG1_ECC_EN;
+
+	writew(config1, NFC_V1_V2_CONFIG1);
+}
+
+static void mxc_nand_enable_hwecc_v3(struct nand_chip *chip, bool enable)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	uint32_t config2;
+
+	if (chip->ecc.mode != NAND_ECC_HW)
+		return;
+
+	config2 = readl(NFC_V3_CONFIG2);
+
+	if (enable)
+		config2 |= NFC_V3_CONFIG2_ECC_EN;
+	else
+		config2 &= ~NFC_V3_CONFIG2_ECC_EN;
+
+	writel(config2, NFC_V3_CONFIG2);
+}
+
 /* This functions is used by upper layer to checks if device is ready */
 static int mxc_nand_dev_ready(struct mtd_info *mtd)
 {
@@ -585,45 +725,90 @@ static int mxc_nand_dev_ready(struct mtd_info *mtd)
 	return 1;
 }
 
-static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+static int mxc_nand_read_page_v1(struct nand_chip *chip, void *buf, void *oob,
+				 bool ecc, int page)
 {
-	/*
-	 * If HW ECC is enabled, we turn it on during init. There is
-	 * no need to enable again here.
-	 */
-}
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	unsigned int bitflips_corrected = 0;
+	int no_subpages;
+	int i;
 
-static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
-				 u_char *read_ecc, u_char *calc_ecc)
-{
-	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+	host->devtype_data->enable_hwecc(chip, ecc);
 
-	/*
-	 * 1-Bit errors are automatically corrected in HW.  No need for
-	 * additional correction.  2-Bit errors cannot be corrected by
-	 * HW ECC, so we need to return failure
-	 */
-	uint16_t ecc_status = get_ecc_status_v1(host);
+	host->devtype_data->send_cmd(host, NAND_CMD_READ0, false);
+	mxc_do_addr_cycle(mtd, 0, page);
 
-	if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
-		dev_dbg(host->dev, "HWECC uncorrectable 2-bit ECC error\n");
-		return -EBADMSG;
+	if (mtd->writesize > 512)
+		host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true);
+
+	no_subpages = mtd->writesize >> 9;
+
+	for (i = 0; i < no_subpages; i++) {
+		uint16_t ecc_stats;
+
+		/* NANDFC buffer 0 is used for page read/write */
+		writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR);
+
+		writew(NFC_OUTPUT, NFC_V1_V2_CONFIG2);
+
+		/* Wait for operation to complete */
+		wait_op_done(host, true);
+
+		ecc_stats = get_ecc_status_v1(host);
+
+		ecc_stats >>= 2;
+
+		if (buf && ecc) {
+			switch (ecc_stats & 0x3) {
+			case 0:
+			default:
+				break;
+			case 1:
+				mtd->ecc_stats.corrected++;
+				bitflips_corrected = 1;
+				break;
+			case 2:
+				mtd->ecc_stats.failed++;
+				break;
+			}
+		}
 	}
 
-	return 0;
+	if (buf)
+		memcpy32_fromio(buf, host->main_area0, mtd->writesize);
+	if (oob)
+		copy_spare(mtd, true, oob);
+
+	return bitflips_corrected;
 }
 
-static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
-				 u_char *read_ecc, u_char *calc_ecc)
+static int mxc_nand_read_page_v2_v3(struct nand_chip *chip, void *buf,
+				    void *oob, bool ecc, int page)
 {
-	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	unsigned int max_bitflips = 0;
 	u32 ecc_stat, err;
-	int no_subpages = 1;
-	int ret = 0;
+	int no_subpages;
 	u8 ecc_bit_mask, err_limit;
 
+	host->devtype_data->enable_hwecc(chip, ecc);
+
+	host->devtype_data->send_cmd(host, NAND_CMD_READ0, false);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	if (mtd->writesize > 512)
+		host->devtype_data->send_cmd(host,
+				NAND_CMD_READSTART, true);
+
+	host->devtype_data->send_page(mtd, NFC_OUTPUT);
+
+	if (buf)
+		memcpy32_fromio(buf, host->main_area0, mtd->writesize);
+	if (oob)
+		copy_spare(mtd, true, oob);
+
 	ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
 	err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
 
@@ -634,25 +819,99 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
 	do {
 		err = ecc_stat & ecc_bit_mask;
 		if (err > err_limit) {
-			dev_dbg(host->dev, "UnCorrectable RS-ECC Error\n");
-			return -EBADMSG;
+			mtd->ecc_stats.failed++;
 		} else {
-			ret += err;
+			mtd->ecc_stats.corrected += err;
+			max_bitflips = max_t(unsigned int, max_bitflips, err);
 		}
+
 		ecc_stat >>= 4;
 	} while (--no_subpages);
 
-	dev_dbg(host->dev, "%d Symbol Correctable RS-ECC Error\n", ret);
-
-	return ret;
+	return max_bitflips;
 }
 
-static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
-				  u_char *ecc_code)
+static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+			      uint8_t *buf, int oob_required, int page)
 {
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	void *oob_buf;
+
+	if (oob_required)
+		oob_buf = chip->oob_poi;
+	else
+		oob_buf = NULL;
+
+	return host->devtype_data->read_page(chip, buf, oob_buf, 1, page);
+}
+
+static int mxc_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				  uint8_t *buf, int oob_required, int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	void *oob_buf;
+
+	if (oob_required)
+		oob_buf = chip->oob_poi;
+	else
+		oob_buf = NULL;
+
+	return host->devtype_data->read_page(chip, buf, oob_buf, 0, page);
+}
+
+static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			     int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	return host->devtype_data->read_page(chip, NULL, chip->oob_poi, 0,
+					     page);
+}
+
+static int mxc_nand_write_page(struct nand_chip *chip, const uint8_t *buf,
+			       bool ecc, int page)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	host->devtype_data->enable_hwecc(chip, ecc);
+
+	host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false);
+	mxc_do_addr_cycle(mtd, 0, page);
+
+	memcpy32_toio(host->main_area0, buf, mtd->writesize);
+	copy_spare(mtd, false, chip->oob_poi);
+
+	host->devtype_data->send_page(mtd, NFC_INPUT);
+	host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true);
+	mxc_do_addr_cycle(mtd, 0, page);
+
 	return 0;
 }
 
+static int mxc_nand_write_page_ecc(struct mtd_info *mtd, struct nand_chip *chip,
+				   const uint8_t *buf, int oob_required,
+				   int page)
+{
+	return mxc_nand_write_page(chip, buf, true, page);
+}
+
+static int mxc_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				   const uint8_t *buf, int oob_required, int page)
+{
+	return mxc_nand_write_page(chip, buf, false, page);
+}
+
+static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			      int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+
+	memset(host->data_buf, 0xff, mtd->writesize);
+
+	return mxc_nand_write_page(chip, host->data_buf, false, page);
+}
+
 static u_char mxc_nand_read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
@@ -772,109 +1031,6 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip)
 	writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
 }
 
-/*
- * The controller splits a page into data chunks of 512 bytes + partial oob.
- * There are writesize / 512 such chunks, the size of the partial oob parts is
- * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then
- * contains additionally the byte lost by rounding (if any).
- * This function handles the needed shuffling between host->data_buf (which
- * holds a page in natural order, i.e. writesize bytes data + oobsize bytes
- * spare) and the NFC buffer.
- */
-static void copy_spare(struct mtd_info *mtd, bool bfrom)
-{
-	struct nand_chip *this = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(this);
-	u16 i, oob_chunk_size;
-	u16 num_chunks = mtd->writesize / 512;
-
-	u8 *d = host->data_buf + mtd->writesize;
-	u8 __iomem *s = host->spare0;
-	u16 sparebuf_size = host->devtype_data->spare_len;
-
-	/* size of oob chunk for all but possibly the last one */
-	oob_chunk_size = (host->used_oobsize / num_chunks) & ~1;
-
-	if (bfrom) {
-		for (i = 0; i < num_chunks - 1; i++)
-			memcpy16_fromio(d + i * oob_chunk_size,
-					s + i * sparebuf_size,
-					oob_chunk_size);
-
-		/* the last chunk */
-		memcpy16_fromio(d + i * oob_chunk_size,
-				s + i * sparebuf_size,
-				host->used_oobsize - i * oob_chunk_size);
-	} else {
-		for (i = 0; i < num_chunks - 1; i++)
-			memcpy16_toio(&s[i * sparebuf_size],
-				      &d[i * oob_chunk_size],
-				      oob_chunk_size);
-
-		/* the last chunk */
-		memcpy16_toio(&s[i * sparebuf_size],
-			      &d[i * oob_chunk_size],
-			      host->used_oobsize - i * oob_chunk_size);
-	}
-}
-
-/*
- * MXC NANDFC can only perform full page+spare or spare-only read/write.  When
- * the upper layers perform a read/write buf operation, the saved column address
- * is used to index into the full page. So usually this function is called with
- * column == 0 (unless no column cycle is needed indicated by column == -1)
- */
-static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
-{
-	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
-
-	/* Write out column address, if necessary */
-	if (column != -1) {
-		host->devtype_data->send_addr(host, column & 0xff,
-					      page_addr == -1);
-		if (mtd->writesize > 512)
-			/* another col addr cycle for 2k page */
-			host->devtype_data->send_addr(host,
-						      (column >> 8) & 0xff,
-						      false);
-	}
-
-	/* Write out page address, if necessary */
-	if (page_addr != -1) {
-		/* paddr_0 - p_addr_7 */
-		host->devtype_data->send_addr(host, (page_addr & 0xff), false);
-
-		if (mtd->writesize > 512) {
-			if (mtd->size >= 0x10000000) {
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff,
-						false);
-				host->devtype_data->send_addr(host,
-						(page_addr >> 16) & 0xff,
-						true);
-			} else
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff, true);
-		} else {
-			if (nand_chip->options & NAND_ROW_ADDR_3) {
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff,
-						false);
-				host->devtype_data->send_addr(host,
-						(page_addr >> 16) & 0xff,
-						true);
-			} else
-				/* paddr_8 - paddr_15 */
-				host->devtype_data->send_addr(host,
-						(page_addr >> 8) & 0xff, true);
-		}
-	}
-}
-
 #define MXC_V1_ECCBYTES		5
 
 static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section,
@@ -1235,57 +1391,6 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 
-	case NAND_CMD_READ0:
-	case NAND_CMD_READOOB:
-		if (command == NAND_CMD_READ0)
-			host->buf_start = column;
-		else
-			host->buf_start = column + mtd->writesize;
-
-		command = NAND_CMD_READ0; /* only READ0 is valid */
-
-		host->devtype_data->send_cmd(host, command, false);
-		WARN_ONCE(column < 0,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, 0, page_addr);
-
-		if (mtd->writesize > 512)
-			host->devtype_data->send_cmd(host,
-					NAND_CMD_READSTART, true);
-
-		host->devtype_data->send_page(mtd, NFC_OUTPUT);
-
-		memcpy32_fromio(host->data_buf, host->main_area0,
-				mtd->writesize);
-		copy_spare(mtd, true);
-		break;
-
-	case NAND_CMD_SEQIN:
-		if (column >= mtd->writesize)
-			/* call ourself to read a page */
-			mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr);
-
-		host->buf_start = column;
-
-		host->devtype_data->send_cmd(host, command, false);
-		WARN_ONCE(column < -1,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, 0, page_addr);
-		break;
-
-	case NAND_CMD_PAGEPROG:
-		memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize);
-		copy_spare(mtd, false);
-		host->devtype_data->send_page(mtd, NFC_INPUT);
-		host->devtype_data->send_cmd(host, command, true);
-		WARN_ONCE(column != -1 || page_addr != -1,
-			  "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n",
-			  command, column, page_addr);
-		mxc_do_addr_cycle(mtd, column, page_addr);
-		break;
-
 	case NAND_CMD_READID:
 		host->devtype_data->send_cmd(host, command, true);
 		mxc_do_addr_cycle(mtd, column, page_addr);
@@ -1316,19 +1421,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 	}
 }
 
-static int mxc_nand_onfi_set_features(struct mtd_info *mtd,
-				      struct nand_chip *chip, int addr,
-				      u8 *subfeature_param)
+static int mxc_nand_set_features(struct mtd_info *mtd, struct nand_chip *chip,
+				 int addr, u8 *subfeature_param)
 {
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
 	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
 	int i;
 
-	if (!chip->onfi_version ||
-	    !(le16_to_cpu(chip->onfi_params.opt_cmd)
-	      & ONFI_OPT_CMD_SET_GET_FEATURES))
-		return -EINVAL;
-
 	host->buf_start = 0;
 
 	for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
@@ -1342,19 +1441,13 @@ static int mxc_nand_onfi_set_features(struct mtd_info *mtd,
 	return 0;
 }
 
-static int mxc_nand_onfi_get_features(struct mtd_info *mtd,
-				      struct nand_chip *chip, int addr,
-				      u8 *subfeature_param)
+static int mxc_nand_get_features(struct mtd_info *mtd, struct nand_chip *chip,
+				 int addr, u8 *subfeature_param)
 {
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
 	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
 	int i;
 
-	if (!chip->onfi_version ||
-	    !(le16_to_cpu(chip->onfi_params.opt_cmd)
-	      & ONFI_OPT_CMD_SET_GET_FEATURES))
-		return -EINVAL;
-
 	host->devtype_data->send_cmd(host, NAND_CMD_GET_FEATURES, false);
 	mxc_do_addr_cycle(mtd, addr, -1);
 	host->devtype_data->send_page(mtd, NFC_OUTPUT);
@@ -1397,6 +1490,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 /* v1 + irqpending_quirk: i.MX21 */
 static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 	.preset = preset_v1,
+	.read_page = mxc_nand_read_page_v1,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v1,
@@ -1407,7 +1501,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v1,
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v1,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 1,
 	.needs_ip = 0,
 	.regs_offset = 0xe00,
@@ -1420,6 +1514,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
 /* v1 + !irqpending_quirk: i.MX27, i.MX31 */
 static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 	.preset = preset_v1,
+	.read_page = mxc_nand_read_page_v1,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v1,
@@ -1430,7 +1525,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v1,
 	.ooblayout = &mxc_v1_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v1,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
 	.regs_offset = 0xe00,
@@ -1444,6 +1539,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 /* v21: i.MX25, i.MX35 */
 static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.preset = preset_v2,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v2,
@@ -1454,8 +1550,8 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v2,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v2,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.setup_data_interface = mxc_nand_v2_setup_data_interface,
+	.enable_hwecc = mxc_nand_enable_hwecc_v1_v2,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
 	.regs_offset = 0x1e00,
@@ -1469,6 +1565,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 /* v3.2a: i.MX51 */
 static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.preset = preset_v3,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1479,7 +1576,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v3,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v2_v3,
+	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
 	.regs_offset = 0,
@@ -1494,6 +1591,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 /* v3.2b: i.MX53 */
 static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.preset = preset_v3,
+	.read_page = mxc_nand_read_page_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1504,7 +1602,7 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v3,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v2_v3,
+	.enable_hwecc = mxc_nand_enable_hwecc_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
 	.regs_offset = 0,
@@ -1642,8 +1740,8 @@ static int mxcnd_probe(struct platform_device *pdev)
 	this->read_word = mxc_nand_read_word;
 	this->write_buf = mxc_nand_write_buf;
 	this->read_buf = mxc_nand_read_buf;
-	this->onfi_set_features = mxc_nand_onfi_set_features;
-	this->onfi_get_features = mxc_nand_onfi_get_features;
+	this->set_features = mxc_nand_set_features;
+	this->get_features = mxc_nand_get_features;
 
 	host->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(host->clk))
@@ -1751,9 +1849,12 @@ static int mxcnd_probe(struct platform_device *pdev)
 
 	switch (this->ecc.mode) {
 	case NAND_ECC_HW:
-		this->ecc.calculate = mxc_nand_calculate_ecc;
-		this->ecc.hwctl = mxc_nand_enable_hwecc;
-		this->ecc.correct = host->devtype_data->correct_data;
+		this->ecc.read_page = mxc_nand_read_page;
+		this->ecc.read_page_raw = mxc_nand_read_page_raw;
+		this->ecc.read_oob = mxc_nand_read_oob;
+		this->ecc.write_page = mxc_nand_write_page_ecc;
+		this->ecc.write_page_raw = mxc_nand_write_page_raw;
+		this->ecc.write_oob = mxc_nand_write_oob;
 		break;
 
 	case NAND_ECC_SOFT:
@@ -1810,15 +1911,18 @@ static int mxcnd_probe(struct platform_device *pdev)
 		goto escan;
 
 	/* Register the partitions */
-	mtd_device_parse_register(mtd, part_probes,
-			NULL,
-			host->pdata.parts,
-			host->pdata.nr_parts);
+	err = mtd_device_parse_register(mtd, part_probes, NULL,
+					host->pdata.parts,
+					host->pdata.nr_parts);
+	if (err)
+		goto cleanup_nand;
 
 	platform_set_drvdata(pdev, host);
 
 	return 0;
 
+cleanup_nand:
+	nand_cleanup(this);
 escan:
 	if (host->clk_act)
 		clk_disable_unprepare(host->clk);
diff --git a/drivers/mtd/nand/nand_amd.c b/drivers/mtd/nand/raw/nand_amd.c
similarity index 100%
rename from drivers/mtd/nand/nand_amd.c
rename to drivers/mtd/nand/raw/nand_amd.c
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
similarity index 95%
rename from drivers/mtd/nand/nand_base.c
rename to drivers/mtd/nand/raw/nand_base.c
index e70ca16..72f3a89 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -349,7 +349,7 @@ static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
 	 *    8-bits of the data bus. During address transfers, the host shall
 	 *    set the upper 8-bits of the data bus to 00h.
 	 *
-	 * One user of the write_byte callback is nand_onfi_set_features. The
+	 * One user of the write_byte callback is nand_set_features. The
 	 * four parameters are specified to be written to I/O[7:0], but this is
 	 * neither an address nor a command transfer. Let's assume a 0 on the
 	 * upper I/O lines is OK.
@@ -527,7 +527,6 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
 
 		/* Attempt erase before marking OOB */
 		memset(&einfo, 0, sizeof(einfo));
-		einfo.mtd = mtd;
 		einfo.addr = ofs;
 		einfo.len = 1ULL << chip->phys_erase_shift;
 		nand_erase_nand(mtd, &einfo, 0);
@@ -1160,6 +1159,60 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 	return status;
 }
 
+static bool nand_supports_get_features(struct nand_chip *chip, int addr)
+{
+	return (chip->parameters.supports_set_get_features &&
+		test_bit(addr, chip->parameters.get_feature_list));
+}
+
+static bool nand_supports_set_features(struct nand_chip *chip, int addr)
+{
+	return (chip->parameters.supports_set_get_features &&
+		test_bit(addr, chip->parameters.set_feature_list));
+}
+
+/**
+ * nand_get_features - wrapper to perform a GET_FEATURE
+ * @chip: NAND chip info structure
+ * @addr: feature address
+ * @subfeature_param: the subfeature parameters, a four bytes array
+ *
+ * Returns 0 for success, a negative error otherwise. Returns -ENOTSUPP if the
+ * operation cannot be handled.
+ */
+int nand_get_features(struct nand_chip *chip, int addr,
+		      u8 *subfeature_param)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+
+	if (!nand_supports_get_features(chip, addr))
+		return -ENOTSUPP;
+
+	return chip->get_features(mtd, chip, addr, subfeature_param);
+}
+EXPORT_SYMBOL_GPL(nand_get_features);
+
+/**
+ * nand_set_features - wrapper to perform a SET_FEATURE
+ * @chip: NAND chip info structure
+ * @addr: feature address
+ * @subfeature_param: the subfeature parameters, a four bytes array
+ *
+ * Returns 0 for success, a negative error otherwise. Returns -ENOTSUPP if the
+ * operation cannot be handled.
+ */
+int nand_set_features(struct nand_chip *chip, int addr,
+		      u8 *subfeature_param)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+
+	if (!nand_supports_set_features(chip, addr))
+		return -ENOTSUPP;
+
+	return chip->set_features(mtd, chip, addr, subfeature_param);
+}
+EXPORT_SYMBOL_GPL(nand_set_features);
+
 /**
  * nand_reset_data_interface - Reset data interface and timings
  * @chip: The NAND chip
@@ -1215,31 +1268,59 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr)
 static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {
+		chip->onfi_timing_mode_default,
+	};
 	int ret;
 
 	if (!chip->setup_data_interface)
 		return 0;
 
-	/*
-	 * Ensure the timing mode has been changed on the chip side
-	 * before changing timings on the controller side.
-	 */
-	if (chip->onfi_version &&
-	    (le16_to_cpu(chip->onfi_params.opt_cmd) &
-	     ONFI_OPT_CMD_SET_GET_FEATURES)) {
-		u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {
-			chip->onfi_timing_mode_default,
-		};
-
-		ret = chip->onfi_set_features(mtd, chip,
-				ONFI_FEATURE_ADDR_TIMING_MODE,
-				tmode_param);
+	/* Change the mode on the chip side (if supported by the NAND chip) */
+	if (nand_supports_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE)) {
+		chip->select_chip(mtd, chipnr);
+		ret = nand_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE,
+					tmode_param);
+		chip->select_chip(mtd, -1);
 		if (ret)
-			goto err;
+			return ret;
 	}
 
+	/* Change the mode on the controller side */
 	ret = chip->setup_data_interface(mtd, chipnr, &chip->data_interface);
-err:
+	if (ret)
+		return ret;
+
+	/* Check the mode has been accepted by the chip, if supported */
+	if (!nand_supports_get_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE))
+		return 0;
+
+	memset(tmode_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
+	chip->select_chip(mtd, chipnr);
+	ret = nand_get_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE,
+				tmode_param);
+	chip->select_chip(mtd, -1);
+	if (ret)
+		goto err_reset_chip;
+
+	if (tmode_param[0] != chip->onfi_timing_mode_default) {
+		pr_warn("timing mode %d not acknowledged by the NAND chip\n",
+			chip->onfi_timing_mode_default);
+		goto err_reset_chip;
+	}
+
+	return 0;
+
+err_reset_chip:
+	/*
+	 * Fallback to mode 0 if the chip explicitly did not ack the chosen
+	 * timing mode.
+	 */
+	nand_reset_data_interface(chip, chipnr);
+	chip->select_chip(mtd, chipnr);
+	nand_reset_op(chip);
+	chip->select_chip(mtd, -1);
+
 	return ret;
 }
 
@@ -2739,10 +2820,18 @@ int nand_reset(struct nand_chip *chip, int chipnr)
 	if (ret)
 		return ret;
 
-	chip->select_chip(mtd, chipnr);
+	/*
+	 * A nand_reset_data_interface() put both the NAND chip and the NAND
+	 * controller in timings mode 0. If the default mode for this chip is
+	 * also 0, no need to proceed to the change again. Plus, at probe time,
+	 * nand_setup_data_interface() uses ->set/get_features() which would
+	 * fail anyway as the parameter page is not available yet.
+	 */
+	if (!chip->onfi_timing_mode_default)
+		return 0;
+
 	chip->data_interface = saved_data_intf;
 	ret = nand_setup_data_interface(chip, chipnr);
-	chip->select_chip(mtd, -1);
 	if (ret)
 		return ret;
 
@@ -4605,22 +4694,20 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 	if (nand_check_wp(mtd)) {
 		pr_debug("%s: device is write protected!\n",
 				__func__);
-		instr->state = MTD_ERASE_FAILED;
+		ret = -EIO;
 		goto erase_exit;
 	}
 
 	/* Loop through the pages */
 	len = instr->len;
 
-	instr->state = MTD_ERASING;
-
 	while (len) {
 		/* Check if we have a bad block, we do not erase bad blocks! */
 		if (nand_block_checkbad(mtd, ((loff_t) page) <<
 					chip->page_shift, allowbbt)) {
 			pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
 				    __func__, page);
-			instr->state = MTD_ERASE_FAILED;
+			ret = -EIO;
 			goto erase_exit;
 		}
 
@@ -4638,7 +4725,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 		if (status) {
 			pr_debug("%s: failed erase, page 0x%08x\n",
 					__func__, page);
-			instr->state = MTD_ERASE_FAILED;
+			ret = -EIO;
 			instr->fail_addr =
 				((loff_t)page << chip->page_shift);
 			goto erase_exit;
@@ -4655,20 +4742,14 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 			chip->select_chip(mtd, chipnr);
 		}
 	}
-	instr->state = MTD_ERASE_DONE;
 
+	ret = 0;
 erase_exit:
 
-	ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
-
 	/* Deselect and wake up anyone waiting on the device */
 	chip->select_chip(mtd, -1);
 	nand_release_device(mtd);
 
-	/* Do call back function */
-	if (!ret)
-		mtd_erase_callback(instr);
-
 	/* Return more or less happy */
 	return ret;
 }
@@ -4769,44 +4850,35 @@ static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
 }
 
 /**
- * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
+ * nand_default_set_features- [REPLACEABLE] set NAND chip features
  * @mtd: MTD device structure
  * @chip: nand chip info structure
  * @addr: feature address.
  * @subfeature_param: the subfeature parameters, a four bytes array.
  */
-static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
-			int addr, uint8_t *subfeature_param)
+static int nand_default_set_features(struct mtd_info *mtd,
+				     struct nand_chip *chip, int addr,
+				     uint8_t *subfeature_param)
 {
-	if (!chip->onfi_version ||
-	    !(le16_to_cpu(chip->onfi_params.opt_cmd)
-	      & ONFI_OPT_CMD_SET_GET_FEATURES))
-		return -EINVAL;
-
 	return nand_set_features_op(chip, addr, subfeature_param);
 }
 
 /**
- * nand_onfi_get_features- [REPLACEABLE] get features for ONFI nand
+ * nand_default_get_features- [REPLACEABLE] get NAND chip features
  * @mtd: MTD device structure
  * @chip: nand chip info structure
  * @addr: feature address.
  * @subfeature_param: the subfeature parameters, a four bytes array.
  */
-static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
-			int addr, uint8_t *subfeature_param)
+static int nand_default_get_features(struct mtd_info *mtd,
+				     struct nand_chip *chip, int addr,
+				     uint8_t *subfeature_param)
 {
-	if (!chip->onfi_version ||
-	    !(le16_to_cpu(chip->onfi_params.opt_cmd)
-	      & ONFI_OPT_CMD_SET_GET_FEATURES))
-		return -EINVAL;
-
 	return nand_get_features_op(chip, addr, subfeature_param);
 }
 
 /**
- * nand_onfi_get_set_features_notsupp - set/get features stub returning
- *					-ENOTSUPP
+ * nand_get_set_features_notsupp - set/get features stub returning -ENOTSUPP
  * @mtd: MTD device structure
  * @chip: nand chip info structure
  * @addr: feature address.
@@ -4815,13 +4887,12 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
  * Should be used by NAND controller drivers that do not support the SET/GET
  * FEATURES operations.
  */
-int nand_onfi_get_set_features_notsupp(struct mtd_info *mtd,
-				       struct nand_chip *chip, int addr,
-				       u8 *subfeature_param)
+int nand_get_set_features_notsupp(struct mtd_info *mtd, struct nand_chip *chip,
+				  int addr, u8 *subfeature_param)
 {
 	return -ENOTSUPP;
 }
-EXPORT_SYMBOL(nand_onfi_get_set_features_notsupp);
+EXPORT_SYMBOL(nand_get_set_features_notsupp);
 
 /**
  * nand_suspend - [MTD Interface] Suspend the NAND flash
@@ -4878,10 +4949,10 @@ static void nand_set_defaults(struct nand_chip *chip)
 		chip->select_chip = nand_select_chip;
 
 	/* set for ONFI nand */
-	if (!chip->onfi_set_features)
-		chip->onfi_set_features = nand_onfi_set_features;
-	if (!chip->onfi_get_features)
-		chip->onfi_get_features = nand_onfi_get_features;
+	if (!chip->set_features)
+		chip->set_features = nand_default_set_features;
+	if (!chip->get_features)
+		chip->get_features = nand_default_get_features;
 
 	/* If called twice, pointers that depend on busw may need to be reset */
 	if (!chip->read_byte || chip->read_byte == nand_read_byte)
@@ -5021,7 +5092,7 @@ static int nand_flash_detect_ext_param_page(struct nand_chip *chip,
 static int nand_flash_detect_onfi(struct nand_chip *chip)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
-	struct nand_onfi_params *p = &chip->onfi_params;
+	struct nand_onfi_params *p;
 	char id[4];
 	int i, ret, val;
 
@@ -5030,14 +5101,23 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
 	if (ret || strncmp(id, "ONFI", 4))
 		return 0;
 
+	/* ONFI chip: allocate a buffer to hold its parameter page */
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
 	ret = nand_read_param_page_op(chip, 0, NULL, 0);
-	if (ret)
-		return 0;
+	if (ret) {
+		ret = 0;
+		goto free_onfi_param_page;
+	}
 
 	for (i = 0; i < 3; i++) {
 		ret = nand_read_data_op(chip, p, sizeof(*p), true);
-		if (ret)
-			return 0;
+		if (ret) {
+			ret = 0;
+			goto free_onfi_param_page;
+		}
 
 		if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
 				le16_to_cpu(p->crc)) {
@@ -5047,31 +5127,33 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
 
 	if (i == 3) {
 		pr_err("Could not find valid ONFI parameter page; aborting\n");
-		return 0;
+		goto free_onfi_param_page;
 	}
 
 	/* Check version */
 	val = le16_to_cpu(p->revision);
 	if (val & (1 << 5))
-		chip->onfi_version = 23;
+		chip->parameters.onfi.version = 23;
 	else if (val & (1 << 4))
-		chip->onfi_version = 22;
+		chip->parameters.onfi.version = 22;
 	else if (val & (1 << 3))
-		chip->onfi_version = 21;
+		chip->parameters.onfi.version = 21;
 	else if (val & (1 << 2))
-		chip->onfi_version = 20;
+		chip->parameters.onfi.version = 20;
 	else if (val & (1 << 1))
-		chip->onfi_version = 10;
+		chip->parameters.onfi.version = 10;
 
-	if (!chip->onfi_version) {
+	if (!chip->parameters.onfi.version) {
 		pr_info("unsupported ONFI version: %d\n", val);
-		return 0;
+		goto free_onfi_param_page;
+	} else {
+		ret = 1;
 	}
 
 	sanitize_string(p->manufacturer, sizeof(p->manufacturer));
 	sanitize_string(p->model, sizeof(p->model));
-	if (!mtd->name)
-		mtd->name = p->model;
+	strncpy(chip->parameters.model, p->model,
+		sizeof(chip->parameters.model) - 1);
 
 	mtd->writesize = le32_to_cpu(p->byte_per_page);
 
@@ -5093,14 +5175,14 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
 	chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
 	chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
 
-	if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
+	if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS)
 		chip->options |= NAND_BUSWIDTH_16;
 
 	if (p->ecc_bits != 0xff) {
 		chip->ecc_strength_ds = p->ecc_bits;
 		chip->ecc_step_ds = 512;
-	} else if (chip->onfi_version >= 21 &&
-		(onfi_feature(chip) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
+	} else if (chip->parameters.onfi.version >= 21 &&
+		(le16_to_cpu(p->features) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
 
 		/*
 		 * The nand_flash_detect_ext_param_page() uses the
@@ -5118,7 +5200,28 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
 		pr_warn("Could not retrieve ONFI ECC requirements\n");
 	}
 
-	return 1;
+	/* Save some parameters from the parameter page for future use */
+	if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_SET_GET_FEATURES) {
+		chip->parameters.supports_set_get_features = true;
+		bitmap_set(chip->parameters.get_feature_list,
+			   ONFI_FEATURE_ADDR_TIMING_MODE, 1);
+		bitmap_set(chip->parameters.set_feature_list,
+			   ONFI_FEATURE_ADDR_TIMING_MODE, 1);
+	}
+	chip->parameters.onfi.tPROG = le16_to_cpu(p->t_prog);
+	chip->parameters.onfi.tBERS = le16_to_cpu(p->t_bers);
+	chip->parameters.onfi.tR = le16_to_cpu(p->t_r);
+	chip->parameters.onfi.tCCS = le16_to_cpu(p->t_ccs);
+	chip->parameters.onfi.async_timing_mode =
+		le16_to_cpu(p->async_timing_mode);
+	chip->parameters.onfi.vendor_revision =
+		le16_to_cpu(p->vendor_revision);
+	memcpy(chip->parameters.onfi.vendor, p->vendor,
+	       sizeof(p->vendor));
+
+free_onfi_param_page:
+	kfree(p);
+	return ret;
 }
 
 /*
@@ -5127,8 +5230,9 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
 static int nand_flash_detect_jedec(struct nand_chip *chip)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
-	struct nand_jedec_params *p = &chip->jedec_params;
+	struct nand_jedec_params *p;
 	struct jedec_ecc_info *ecc;
+	int jedec_version = 0;
 	char id[5];
 	int i, val, ret;
 
@@ -5137,14 +5241,23 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
 	if (ret || strncmp(id, "JEDEC", sizeof(id)))
 		return 0;
 
+	/* JEDEC chip: allocate a buffer to hold its parameter page */
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
 	ret = nand_read_param_page_op(chip, 0x40, NULL, 0);
-	if (ret)
-		return 0;
+	if (ret) {
+		ret = 0;
+		goto free_jedec_param_page;
+	}
 
 	for (i = 0; i < 3; i++) {
 		ret = nand_read_data_op(chip, p, sizeof(*p), true);
-		if (ret)
-			return 0;
+		if (ret) {
+			ret = 0;
+			goto free_jedec_param_page;
+		}
 
 		if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
 				le16_to_cpu(p->crc))
@@ -5153,25 +5266,25 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
 
 	if (i == 3) {
 		pr_err("Could not find valid JEDEC parameter page; aborting\n");
-		return 0;
+		goto free_jedec_param_page;
 	}
 
 	/* Check version */
 	val = le16_to_cpu(p->revision);
 	if (val & (1 << 2))
-		chip->jedec_version = 10;
+		jedec_version = 10;
 	else if (val & (1 << 1))
-		chip->jedec_version = 1; /* vendor specific version */
+		jedec_version = 1; /* vendor specific version */
 
-	if (!chip->jedec_version) {
+	if (!jedec_version) {
 		pr_info("unsupported JEDEC version: %d\n", val);
-		return 0;
+		goto free_jedec_param_page;
 	}
 
 	sanitize_string(p->manufacturer, sizeof(p->manufacturer));
 	sanitize_string(p->model, sizeof(p->model));
-	if (!mtd->name)
-		mtd->name = p->model;
+	strncpy(chip->parameters.model, p->model,
+		sizeof(chip->parameters.model) - 1);
 
 	mtd->writesize = le32_to_cpu(p->byte_per_page);
 
@@ -5186,7 +5299,7 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
 	chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
 	chip->bits_per_cell = p->bits_per_cell;
 
-	if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS)
+	if (le16_to_cpu(p->features) & JEDEC_FEATURE_16_BIT_BUS)
 		chip->options |= NAND_BUSWIDTH_16;
 
 	/* ECC info */
@@ -5199,7 +5312,9 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
 		pr_warn("Invalid codeword size\n");
 	}
 
-	return 1;
+free_jedec_param_page:
+	kfree(p);
+	return ret;
 }
 
 /*
@@ -5358,8 +5473,8 @@ static bool find_full_id_nand(struct nand_chip *chip,
 		chip->onfi_timing_mode_default =
 					type->onfi_timing_mode_default;
 
-		if (!mtd->name)
-			mtd->name = type->name;
+		strncpy(chip->parameters.model, type->name,
+			sizeof(chip->parameters.model) - 1);
 
 		return true;
 	}
@@ -5498,22 +5613,28 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 		}
 	}
 
-	chip->onfi_version = 0;
+	chip->parameters.onfi.version = 0;
 	if (!type->name || !type->pagesize) {
 		/* Check if the chip is ONFI compliant */
-		if (nand_flash_detect_onfi(chip))
+		ret = nand_flash_detect_onfi(chip);
+		if (ret < 0)
+			return ret;
+		else if (ret)
 			goto ident_done;
 
 		/* Check if the chip is JEDEC compliant */
-		if (nand_flash_detect_jedec(chip))
+		ret = nand_flash_detect_jedec(chip);
+		if (ret < 0)
+			return ret;
+		else if (ret)
 			goto ident_done;
 	}
 
 	if (!type->name)
 		return -ENODEV;
 
-	if (!mtd->name)
-		mtd->name = type->name;
+	strncpy(chip->parameters.model, type->name,
+		sizeof(chip->parameters.model) - 1);
 
 	chip->chipsize = (uint64_t)type->chipsize << 20;
 
@@ -5526,6 +5647,8 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	chip->options |= type->options;
 
 ident_done:
+	if (!mtd->name)
+		mtd->name = chip->parameters.model;
 
 	if (chip->options & NAND_BUSWIDTH_AUTO) {
 		WARN_ON(busw & NAND_BUSWIDTH_16);
@@ -5572,17 +5695,8 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 
 	pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
 		maf_id, dev_id);
-
-	if (chip->onfi_version)
-		pr_info("%s %s\n", nand_manufacturer_name(manufacturer),
-			chip->onfi_params.model);
-	else if (chip->jedec_version)
-		pr_info("%s %s\n", nand_manufacturer_name(manufacturer),
-			chip->jedec_params.model);
-	else
-		pr_info("%s %s\n", nand_manufacturer_name(manufacturer),
-			type->name);
-
+	pr_info("%s %s\n", nand_manufacturer_name(manufacturer),
+		chip->parameters.model);
 	pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n",
 		(int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
 		mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
@@ -6474,10 +6588,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 
 	/* Enter fastest possible mode on all dies. */
 	for (i = 0; i < chip->numchips; i++) {
-		chip->select_chip(mtd, i);
 		ret = nand_setup_data_interface(chip, i);
-		chip->select_chip(mtd, -1);
-
 		if (ret)
 			goto err_nand_manuf_cleanup;
 	}
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
similarity index 99%
rename from drivers/mtd/nand/nand_bbt.c
rename to drivers/mtd/nand/raw/nand_bbt.c
index 3609285..d9f4cef 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -852,7 +852,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 		}
 
 		memset(&einfo, 0, sizeof(einfo));
-		einfo.mtd = mtd;
 		einfo.addr = to;
 		einfo.len = 1 << this->bbt_erase_shift;
 		res = nand_erase_nand(mtd, &einfo, 1);
diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/raw/nand_bch.c
similarity index 95%
rename from drivers/mtd/nand/nand_bch.c
rename to drivers/mtd/nand/raw/nand_bch.c
index 505441c..7f11b68 100644
--- a/drivers/mtd/nand/nand_bch.c
+++ b/drivers/mtd/nand/raw/nand_bch.c
@@ -95,7 +95,7 @@ int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf,
 					errloc[i]);
 		}
 	} else if (count < 0) {
-		printk(KERN_ERR "ecc unrecoverable error\n");
+		pr_err("ecc unrecoverable error\n");
 		count = -EBADMSG;
 	}
 	return count;
@@ -134,7 +134,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
 	}
 
 	if (!eccsize || !eccbytes) {
-		printk(KERN_WARNING "ecc parameters not supplied\n");
+		pr_warn("ecc parameters not supplied\n");
 		goto fail;
 	}
 
@@ -151,8 +151,8 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
 
 	/* verify that eccbytes has the expected value */
 	if (nbc->bch->ecc_bytes != eccbytes) {
-		printk(KERN_WARNING "invalid eccbytes %u, should be %u\n",
-		       eccbytes, nbc->bch->ecc_bytes);
+		pr_warn("invalid eccbytes %u, should be %u\n",
+			eccbytes, nbc->bch->ecc_bytes);
 		goto fail;
 	}
 
@@ -166,7 +166,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
 
 	/* sanity checks */
 	if (8*(eccsize+eccbytes) >= (1 << m)) {
-		printk(KERN_WARNING "eccsize %u is too large\n", eccsize);
+		pr_warn("eccsize %u is too large\n", eccsize);
 		goto fail;
 	}
 
@@ -181,7 +181,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
 	nand->ecc.steps = eccsteps;
 	nand->ecc.total = eccsteps * eccbytes;
 	if (mtd_ooblayout_count_eccbytes(mtd) != (eccsteps*eccbytes)) {
-		printk(KERN_WARNING "invalid ecc layout\n");
+		pr_warn("invalid ecc layout\n");
 		goto fail;
 	}
 
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/raw/nand_ecc.c
similarity index 95%
rename from drivers/mtd/nand/nand_ecc.c
rename to drivers/mtd/nand/raw/nand_ecc.c
index 7613a03..8e132ed 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/raw/nand_ecc.c
@@ -2,8 +2,6 @@
  * This file contains an ECC algorithm that detects and corrects 1 bit
  * errors in a 256 byte block of data.
  *
- * drivers/mtd/nand/nand_ecc.c
- *
  * Copyright © 2008 Koninklijke Philips Electronics NV.
  *                  Author: Frans Meulenbroeks
  *
@@ -30,15 +28,6 @@
  *
  */
 
-/*
- * The STANDALONE macro is useful when running the code outside the kernel
- * e.g. when running the code in a testbed or a benchmark program.
- * When STANDALONE is used, the module related macros are commented out
- * as well as the linux include files.
- * Instead a private definition of mtd_info is given to satisfy the compiler
- * (the code does not use mtd_info, so the code does not care)
- */
-#ifndef STANDALONE
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -46,17 +35,6 @@
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <asm/byteorder.h>
-#else
-#include <stdint.h>
-struct mtd_info;
-#define EXPORT_SYMBOL(x)  /* x */
-
-#define MODULE_LICENSE(x)	/* x */
-#define MODULE_AUTHOR(x)	/* x */
-#define MODULE_DESCRIPTION(x)	/* x */
-
-#define pr_err printf
-#endif
 
 /*
  * invparity is a 256 byte table that contains the odd parity
diff --git a/drivers/mtd/nand/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
similarity index 100%
rename from drivers/mtd/nand/nand_hynix.c
rename to drivers/mtd/nand/raw/nand_hynix.c
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c
similarity index 100%
rename from drivers/mtd/nand/nand_ids.c
rename to drivers/mtd/nand/raw/nand_ids.c
diff --git a/drivers/mtd/nand/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c
similarity index 64%
rename from drivers/mtd/nand/nand_macronix.c
rename to drivers/mtd/nand/raw/nand_macronix.c
index d290ff2..7ed1f87 100644
--- a/drivers/mtd/nand/nand_macronix.c
+++ b/drivers/mtd/nand/raw/nand_macronix.c
@@ -22,6 +22,19 @@ static int macronix_nand_init(struct nand_chip *chip)
 	if (nand_is_slc(chip))
 		chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
 
+	/*
+	 * MX30LF2G18AC chip does not support using SET/GET_FEATURES to change
+	 * the timings unlike what is declared in the parameter page. Unflag
+	 * this feature to avoid unnecessary downturns.
+	 */
+	if (chip->parameters.supports_set_get_features &&
+	    !strcmp("MX30LF2G18AC", chip->parameters.model)) {
+		bitmap_clear(chip->parameters.get_feature_list,
+			     ONFI_FEATURE_ADDR_TIMING_MODE, 1);
+		bitmap_clear(chip->parameters.set_feature_list,
+			     ONFI_FEATURE_ADDR_TIMING_MODE, 1);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/mtd/nand/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c
similarity index 88%
rename from drivers/mtd/nand/nand_micron.c
rename to drivers/mtd/nand/raw/nand_micron.c
index 02e109a..0af45b1 100644
--- a/drivers/mtd/nand/nand_micron.c
+++ b/drivers/mtd/nand/raw/nand_micron.c
@@ -48,8 +48,7 @@ static int micron_nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	u8 feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode};
 
-	return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY,
-				       feature);
+	return nand_set_features(chip, ONFI_FEATURE_ADDR_READ_RETRY, feature);
 }
 
 /*
@@ -57,17 +56,18 @@ static int micron_nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
  */
 static int micron_nand_onfi_init(struct nand_chip *chip)
 {
-	struct nand_onfi_params *p = &chip->onfi_params;
-	struct nand_onfi_vendor_micron *micron = (void *)p->vendor;
+	struct nand_parameters *p = &chip->parameters;
+	struct nand_onfi_vendor_micron *micron = (void *)p->onfi.vendor;
 
-	if (!chip->onfi_version)
-		return 0;
+	if (chip->parameters.onfi.version && p->onfi.vendor_revision) {
+		chip->read_retries = micron->read_retry_options;
+		chip->setup_read_retry = micron_nand_setup_read_retry;
+	}
 
-	if (le16_to_cpu(p->vendor_revision) < 1)
-		return 0;
-
-	chip->read_retries = micron->read_retry_options;
-	chip->setup_read_retry = micron_nand_setup_read_retry;
+	if (p->supports_set_get_features) {
+		set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->set_feature_list);
+		set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->get_feature_list);
+	}
 
 	return 0;
 }
@@ -108,8 +108,7 @@ static int micron_nand_on_die_ecc_setup(struct nand_chip *chip, bool enable)
 	if (enable)
 		feature[0] |= ONFI_FEATURE_ON_DIE_ECC_EN;
 
-	return chip->onfi_set_features(nand_to_mtd(chip), chip,
-				       ONFI_FEATURE_ON_DIE_ECC, feature);
+	return nand_set_features(chip, ONFI_FEATURE_ON_DIE_ECC, feature);
 }
 
 static int
@@ -209,7 +208,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	u8 feature[ONFI_SUBFEATURE_PARAM_LEN] = { 0, };
 	int ret;
 
-	if (chip->onfi_version == 0)
+	if (!chip->parameters.onfi.version)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
 	if (chip->bits_per_cell != 1)
@@ -219,8 +218,10 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	if (ret)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
-	chip->onfi_get_features(nand_to_mtd(chip), chip,
-				ONFI_FEATURE_ON_DIE_ECC, feature);
+	ret = nand_get_features(chip, ONFI_FEATURE_ON_DIE_ECC, feature);
+	if (ret < 0)
+		return ret;
+
 	if ((feature[0] & ONFI_FEATURE_ON_DIE_ECC_EN) == 0)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
@@ -228,8 +229,10 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	if (ret)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
-	chip->onfi_get_features(nand_to_mtd(chip), chip,
-				ONFI_FEATURE_ON_DIE_ECC, feature);
+	ret = nand_get_features(chip, ONFI_FEATURE_ON_DIE_ECC, feature);
+	if (ret < 0)
+		return ret;
+
 	if (feature[0] & ONFI_FEATURE_ON_DIE_ECC_EN)
 		return MICRON_ON_DIE_MANDATORY;
 
@@ -237,7 +240,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	 * Some Micron NANDs have an on-die ECC of 4/512, some other
 	 * 8/512. We only support the former.
 	 */
-	if (chip->onfi_params.ecc_bits != 4)
+	if (chip->ecc_strength_ds != 4)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
 	return MICRON_ON_DIE_SUPPORTED;
diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c
similarity index 100%
rename from drivers/mtd/nand/nand_samsung.c
rename to drivers/mtd/nand/raw/nand_samsung.c
diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c
similarity index 95%
rename from drivers/mtd/nand/nand_timings.c
rename to drivers/mtd/nand/raw/nand_timings.c
index 9400d03..7c4e4a3 100644
--- a/drivers/mtd/nand/nand_timings.c
+++ b/drivers/mtd/nand/raw/nand_timings.c
@@ -306,17 +306,17 @@ int onfi_fill_data_interface(struct nand_chip *chip,
 	 * tR, tPROG, tCCS, ...
 	 * These information are part of the ONFI parameter page.
 	 */
-	if (chip->onfi_version) {
-		struct nand_onfi_params *params = &chip->onfi_params;
+	if (chip->parameters.onfi.version) {
+		struct nand_parameters *params = &chip->parameters;
 		struct nand_sdr_timings *timings = &iface->timings.sdr;
 
 		/* microseconds -> picoseconds */
-		timings->tPROG_max = 1000000ULL * le16_to_cpu(params->t_prog);
-		timings->tBERS_max = 1000000ULL * le16_to_cpu(params->t_bers);
-		timings->tR_max = 1000000ULL * le16_to_cpu(params->t_r);
+		timings->tPROG_max = 1000000ULL * params->onfi.tPROG;
+		timings->tBERS_max = 1000000ULL * params->onfi.tBERS;
+		timings->tR_max = 1000000ULL * params->onfi.tR;
 
 		/* nanoseconds -> picoseconds */
-		timings->tCCS_min = 1000UL * le16_to_cpu(params->t_ccs);
+		timings->tCCS_min = 1000UL * params->onfi.tCCS;
 	}
 
 	return 0;
diff --git a/drivers/mtd/nand/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c
similarity index 71%
rename from drivers/mtd/nand/nand_toshiba.c
rename to drivers/mtd/nand/raw/nand_toshiba.c
index 57df857..ab43f02 100644
--- a/drivers/mtd/nand/nand_toshiba.c
+++ b/drivers/mtd/nand/raw/nand_toshiba.c
@@ -35,6 +35,32 @@ static void toshiba_nand_decode_id(struct nand_chip *chip)
 	    (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
 	    !(chip->id.data[4] & 0x80) /* !BENAND */)
 		mtd->oobsize = 32 * mtd->writesize >> 9;
+
+	/*
+	 * Extract ECC requirements from 6th id byte.
+	 * For Toshiba SLC, ecc requrements are as follows:
+	 *  - 43nm: 1 bit ECC for each 512Byte is required.
+	 *  - 32nm: 4 bit ECC for each 512Byte is required.
+	 *  - 24nm: 8 bit ECC for each 512Byte is required.
+	 */
+	if (chip->id.len >= 6 && nand_is_slc(chip)) {
+		chip->ecc_step_ds = 512;
+		switch (chip->id.data[5] & 0x7) {
+		case 0x4:
+			chip->ecc_strength_ds = 1;
+			break;
+		case 0x5:
+			chip->ecc_strength_ds = 4;
+			break;
+		case 0x6:
+			chip->ecc_strength_ds = 8;
+			break;
+		default:
+			WARN(1, "Could not get ECC info");
+			chip->ecc_step_ds = 0;
+			break;
+		}
+	}
 }
 
 static int toshiba_nand_init(struct nand_chip *chip)
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
similarity index 99%
rename from drivers/mtd/nand/nandsim.c
rename to drivers/mtd/nand/raw/nandsim.c
index 44322a3..e027c6f 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/raw/nandsim.c
@@ -23,6 +23,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  */
 
+#define pr_fmt(fmt)  "[nandsim]" fmt
+
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/module.h>
@@ -179,20 +181,17 @@ MODULE_PARM_DESC(bch,		 "Enable BCH ecc and set how many bits should "
 /* The largest possible page size */
 #define NS_LARGEST_PAGE_SIZE	4096
 
-/* The prefix for simulator output */
-#define NS_OUTPUT_PREFIX "[nandsim]"
-
 /* Simulator's output macros (logging, debugging, warning, error) */
 #define NS_LOG(args...) \
-	do { if (log) printk(KERN_DEBUG NS_OUTPUT_PREFIX " log: " args); } while(0)
+	do { if (log) pr_debug(" log: " args); } while(0)
 #define NS_DBG(args...) \
-	do { if (dbg) printk(KERN_DEBUG NS_OUTPUT_PREFIX " debug: " args); } while(0)
+	do { if (dbg) pr_debug(" debug: " args); } while(0)
 #define NS_WARN(args...) \
-	do { printk(KERN_WARNING NS_OUTPUT_PREFIX " warning: " args); } while(0)
+	do { pr_warn(" warning: " args); } while(0)
 #define NS_ERR(args...) \
-	do { printk(KERN_ERR NS_OUTPUT_PREFIX " error: " args); } while(0)
+	do { pr_err(" error: " args); } while(0)
 #define NS_INFO(args...) \
-	do { printk(KERN_INFO NS_OUTPUT_PREFIX " " args); } while(0)
+	do { pr_info(" " args); } while(0)
 
 /* Busy-wait delay macros (microseconds, milliseconds) */
 #define NS_UDELAY(us) \
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/raw/ndfc.c
similarity index 100%
rename from drivers/mtd/nand/ndfc.c
rename to drivers/mtd/nand/raw/ndfc.c
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/raw/nuc900_nand.c
similarity index 100%
rename from drivers/mtd/nand/nuc900_nand.c
rename to drivers/mtd/nand/raw/nuc900_nand.c
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/raw/omap2.c
similarity index 99%
rename from drivers/mtd/nand/omap2.c
rename to drivers/mtd/nand/raw/omap2.c
index 8cdf7d3..e50c64a 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/raw/omap2.c
@@ -2263,12 +2263,15 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	err = mtd_device_register(mtd, NULL, 0);
 	if (err)
-		goto return_error;
+		goto cleanup_nand;
 
 	platform_set_drvdata(pdev, mtd);
 
 	return 0;
 
+cleanup_nand:
+	nand_cleanup(nand_chip);
+
 return_error:
 	if (!IS_ERR_OR_NULL(info->dma))
 		dma_release_channel(info->dma);
diff --git a/drivers/mtd/nand/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c
similarity index 100%
rename from drivers/mtd/nand/omap_elm.c
rename to drivers/mtd/nand/raw/omap_elm.c
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/raw/orion_nand.c
similarity index 99%
rename from drivers/mtd/nand/orion_nand.c
rename to drivers/mtd/nand/raw/orion_nand.c
index 5a5aa1f..7825fd3 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/raw/orion_nand.c
@@ -1,6 +1,4 @@
 /*
- * drivers/mtd/nand/orion_nand.c
- *
  * NAND support for Marvell Orion SoC platforms
  *
  * Tzachi Perelstein <tzachi@marvell.com>
diff --git a/drivers/mtd/nand/oxnas_nand.c b/drivers/mtd/nand/raw/oxnas_nand.c
similarity index 100%
rename from drivers/mtd/nand/oxnas_nand.c
rename to drivers/mtd/nand/raw/oxnas_nand.c
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/raw/pasemi_nand.c
similarity index 100%
rename from drivers/mtd/nand/pasemi_nand.c
rename to drivers/mtd/nand/raw/pasemi_nand.c
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/raw/plat_nand.c
similarity index 100%
rename from drivers/mtd/nand/plat_nand.c
rename to drivers/mtd/nand/raw/plat_nand.c
diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
similarity index 99%
rename from drivers/mtd/nand/qcom_nandc.c
rename to drivers/mtd/nand/raw/qcom_nandc.c
index 563b759..b554fb6 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -2651,8 +2651,8 @@ static int qcom_nand_host_init(struct qcom_nand_controller *nandc,
 	chip->read_byte		= qcom_nandc_read_byte;
 	chip->read_buf		= qcom_nandc_read_buf;
 	chip->write_buf		= qcom_nandc_write_buf;
-	chip->onfi_set_features	= nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features	= nand_onfi_get_set_features_notsupp;
+	chip->set_features	= nand_get_set_features_notsupp;
+	chip->get_features	= nand_get_set_features_notsupp;
 
 	/*
 	 * the bad block marker is readable only when we read the last codeword
diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/raw/r852.c
similarity index 99%
rename from drivers/mtd/nand/r852.c
rename to drivers/mtd/nand/raw/r852.c
index 595635b..dcdeb06 100644
--- a/drivers/mtd/nand/r852.c
+++ b/drivers/mtd/nand/raw/r852.c
@@ -7,6 +7,9 @@
  * published by the Free Software Foundation.
  */
 
+#define DRV_NAME "r852"
+#define pr_fmt(fmt)  DRV_NAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
@@ -932,7 +935,7 @@ static int  r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 		&dev->card_detect_work, 0);
 
 
-	printk(KERN_NOTICE DRV_NAME ": driver loaded successfully\n");
+	pr_notice("driver loaded successfully\n");
 	return 0;
 
 error10:
diff --git a/drivers/mtd/nand/r852.h b/drivers/mtd/nand/raw/r852.h
similarity index 95%
rename from drivers/mtd/nand/r852.h
rename to drivers/mtd/nand/raw/r852.h
index 8713c57..1eed2fc 100644
--- a/drivers/mtd/nand/r852.h
+++ b/drivers/mtd/nand/raw/r852.h
@@ -144,17 +144,14 @@ struct r852_device {
 	uint8_t ctlreg;			/* cached contents of control reg */
 };
 
-#define DRV_NAME "r852"
-
-
 #define dbg(format, ...) \
 	if (debug) \
-		printk(KERN_DEBUG DRV_NAME ": " format "\n", ## __VA_ARGS__)
+		pr_debug(format "\n", ## __VA_ARGS__)
 
 #define dbg_verbose(format, ...) \
 	if (debug > 1) \
-		printk(KERN_DEBUG DRV_NAME ": " format "\n", ## __VA_ARGS__)
+		pr_debug(format "\n", ## __VA_ARGS__)
 
 
 #define message(format, ...) \
-	printk(KERN_INFO DRV_NAME ": " format "\n", ## __VA_ARGS__)
+	pr_info(format "\n", ## __VA_ARGS__)
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/raw/s3c2410.c
similarity index 98%
rename from drivers/mtd/nand/s3c2410.c
rename to drivers/mtd/nand/raw/s3c2410.c
index 4c383ee..1bc0458 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/raw/s3c2410.c
@@ -1,5 +1,4 @@
-/* linux/drivers/mtd/nand/s3c2410.c
- *
+/*
  * Copyright © 2004-2008 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
@@ -125,13 +124,11 @@ struct s3c2410_nand_info;
  * @chip: The NAND chip information.
  * @set: The platform information supplied for this set of NAND chips.
  * @info: Link back to the hardware information.
- * @scan_res: The result from calling nand_scan_ident().
 */
 struct s3c2410_nand_mtd {
 	struct nand_chip		chip;
 	struct s3c2410_nand_set		*set;
 	struct s3c2410_nand_info	*info;
-	int				scan_res;
 };
 
 enum s3c_cpu_type {
@@ -1164,17 +1161,19 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
 		mtd->dev.parent = &pdev->dev;
 		s3c2410_nand_init_chip(info, nmtd, sets);
 
-		nmtd->scan_res = nand_scan_ident(mtd,
-						 (sets) ? sets->nr_chips : 1,
-						 NULL);
+		err = nand_scan_ident(mtd, (sets) ? sets->nr_chips : 1, NULL);
+		if (err)
+			goto exit_error;
 
-		if (nmtd->scan_res == 0) {
-			err = s3c2410_nand_update_chip(info, nmtd);
-			if (err < 0)
-				goto exit_error;
-			nand_scan_tail(mtd);
-			s3c2410_nand_add_partition(info, nmtd, sets);
-		}
+		err = s3c2410_nand_update_chip(info, nmtd);
+		if (err < 0)
+			goto exit_error;
+
+		err = nand_scan_tail(mtd);
+		if (err)
+			goto exit_error;
+
+		s3c2410_nand_add_partition(info, nmtd, sets);
 
 		if (sets != NULL)
 			sets++;
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
similarity index 99%
rename from drivers/mtd/nand/sh_flctl.c
rename to drivers/mtd/nand/raw/sh_flctl.c
index c4e7755..c7abcef 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/raw/sh_flctl.c
@@ -877,7 +877,7 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
 			else if (!flctl->seqin_column)
 				execmd_write_page_sector(mtd);
 			else
-				printk(KERN_ERR "Invalid address !?\n");
+				pr_err("Invalid address !?\n");
 			break;
 		}
 		set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN);
@@ -1180,8 +1180,8 @@ static int flctl_probe(struct platform_device *pdev)
 	nand->read_buf = flctl_read_buf;
 	nand->select_chip = flctl_select_chip;
 	nand->cmdfunc = flctl_cmdfunc;
-	nand->onfi_set_features = nand_onfi_get_set_features_notsupp;
-	nand->onfi_get_features = nand_onfi_get_set_features_notsupp;
+	nand->set_features = nand_get_set_features_notsupp;
+	nand->get_features = nand_get_set_features_notsupp;
 
 	if (pdata->flcmncr_val & SEL_16BIT)
 		nand->options |= NAND_BUSWIDTH_16;
@@ -1214,9 +1214,13 @@ static int flctl_probe(struct platform_device *pdev)
 		goto err_chip;
 
 	ret = mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
+	if (ret)
+		goto cleanup_nand;
 
 	return 0;
 
+cleanup_nand:
+	nand_cleanup(nand);
 err_chip:
 	flctl_release_dma(flctl);
 	pm_runtime_disable(&pdev->dev);
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/raw/sharpsl.c
similarity index 99%
rename from drivers/mtd/nand/sharpsl.c
rename to drivers/mtd/nand/raw/sharpsl.c
index f59c455..e93df02 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/raw/sharpsl.c
@@ -1,6 +1,4 @@
 /*
- * drivers/mtd/nand/sharpsl.c
- *
  *  Copyright (C) 2004 Richard Purdie
  *  Copyright (C) 2008 Dmitry Baryshkov
  *
diff --git a/drivers/mtd/nand/sm_common.c b/drivers/mtd/nand/raw/sm_common.c
similarity index 98%
rename from drivers/mtd/nand/sm_common.c
rename to drivers/mtd/nand/raw/sm_common.c
index c378705..7f5044a 100644
--- a/drivers/mtd/nand/sm_common.c
+++ b/drivers/mtd/nand/raw/sm_common.c
@@ -119,9 +119,8 @@ static int sm_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
 	ret = mtd_write_oob(mtd, ofs, &ops);
 	if (ret < 0 || ops.oobretlen != SM_OOB_SIZE) {
-		printk(KERN_NOTICE
-			"sm_common: can't mark sector at %i as bad\n",
-								(int)ofs);
+		pr_notice("sm_common: can't mark sector at %i as bad\n",
+			  (int)ofs);
 		return -EIO;
 	}
 
diff --git a/drivers/mtd/nand/sm_common.h b/drivers/mtd/nand/raw/sm_common.h
similarity index 100%
rename from drivers/mtd/nand/sm_common.h
rename to drivers/mtd/nand/raw/sm_common.h
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/raw/socrates_nand.c
similarity index 99%
rename from drivers/mtd/nand/socrates_nand.c
rename to drivers/mtd/nand/raw/socrates_nand.c
index 575997d..9824a99 100644
--- a/drivers/mtd/nand/socrates_nand.c
+++ b/drivers/mtd/nand/raw/socrates_nand.c
@@ -1,6 +1,4 @@
 /*
- * drivers/mtd/nand/socrates_nand.c
- *
  *  Copyright © 2008 Ilya Yanok, Emcraft Systems
  *
  *
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
similarity index 94%
rename from drivers/mtd/nand/sunxi_nand.c
rename to drivers/mtd/nand/raw/sunxi_nand.c
index f5a55c6..aad4281 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1475,92 +1475,18 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct mtd_info *mtd,
 	return sunxi_nfc_hw_ecc_write_page(mtd, chip, buf, oob_required, page);
 }
 
-static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
-					       struct nand_chip *chip,
-					       uint8_t *buf, int oob_required,
-					       int page)
-{
-	struct nand_ecc_ctrl *ecc = &chip->ecc;
-	unsigned int max_bitflips = 0;
-	int ret, i, cur_off = 0;
-	bool raw_mode = false;
-
-	nand_read_page_op(chip, page, 0, NULL, 0);
-
-	sunxi_nfc_hw_ecc_enable(mtd);
-
-	for (i = 0; i < ecc->steps; i++) {
-		int data_off = i * (ecc->size + ecc->bytes + 4);
-		int oob_off = data_off + ecc->size;
-		u8 *data = buf + (i * ecc->size);
-		u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
-
-		ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
-						  oob_off, &cur_off,
-						  &max_bitflips, !i,
-						  oob_required,
-						  page);
-		if (ret < 0)
-			return ret;
-		else if (ret)
-			raw_mode = true;
-	}
-
-	if (oob_required)
-		sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
-						!raw_mode, page);
-
-	sunxi_nfc_hw_ecc_disable(mtd);
-
-	return max_bitflips;
-}
-
-static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
-						struct nand_chip *chip,
-						const uint8_t *buf,
-						int oob_required, int page)
-{
-	struct nand_ecc_ctrl *ecc = &chip->ecc;
-	int ret, i, cur_off = 0;
-
-	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
-
-	sunxi_nfc_hw_ecc_enable(mtd);
-
-	for (i = 0; i < ecc->steps; i++) {
-		int data_off = i * (ecc->size + ecc->bytes + 4);
-		int oob_off = data_off + ecc->size;
-		const u8 *data = buf + (i * ecc->size);
-		const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
-
-		ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
-						   oob, oob_off, &cur_off,
-						   false, page);
-		if (ret)
-			return ret;
-	}
-
-	if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
-		sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
-						 &cur_off, page);
-
-	sunxi_nfc_hw_ecc_disable(mtd);
-
-	return nand_prog_page_end_op(chip);
-}
-
-static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd,
-					    struct nand_chip *chip,
-					    int page)
+static int sunxi_nfc_hw_ecc_read_oob(struct mtd_info *mtd,
+				     struct nand_chip *chip,
+				     int page)
 {
 	chip->pagebuf = -1;
 
 	return chip->ecc.read_page(mtd, chip, chip->data_buf, 1, page);
 }
 
-static int sunxi_nfc_hw_common_ecc_write_oob(struct mtd_info *mtd,
-					     struct nand_chip *chip,
-					     int page)
+static int sunxi_nfc_hw_ecc_write_oob(struct mtd_info *mtd,
+				      struct nand_chip *chip,
+				      int page)
 {
 	int ret;
 
@@ -1801,9 +1727,14 @@ static const struct mtd_ooblayout_ops sunxi_nand_ooblayout_ops = {
 	.free = sunxi_nand_ooblayout_free,
 };
 
-static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
-					      struct nand_ecc_ctrl *ecc,
-					      struct device_node *np)
+static void sunxi_nand_hw_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
+{
+	kfree(ecc->priv);
+}
+
+static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
+				       struct nand_ecc_ctrl *ecc,
+				       struct device_node *np)
 {
 	static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
 	struct nand_chip *nand = mtd_to_nand(mtd);
@@ -1889,37 +1820,11 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
 		goto err;
 	}
 
-	ecc->read_oob = sunxi_nfc_hw_common_ecc_read_oob;
-	ecc->write_oob = sunxi_nfc_hw_common_ecc_write_oob;
+	ecc->read_oob = sunxi_nfc_hw_ecc_read_oob;
+	ecc->write_oob = sunxi_nfc_hw_ecc_write_oob;
 	mtd_set_ooblayout(mtd, &sunxi_nand_ooblayout_ops);
 	ecc->priv = data;
 
-	return 0;
-
-err:
-	kfree(data);
-
-	return ret;
-}
-
-static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
-{
-	kfree(ecc->priv);
-}
-
-static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
-				       struct nand_ecc_ctrl *ecc,
-				       struct device_node *np)
-{
-	struct nand_chip *nand = mtd_to_nand(mtd);
-	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
-	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
-	int ret;
-
-	ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
-	if (ret)
-		return ret;
-
 	if (nfc->dmac) {
 		ecc->read_page = sunxi_nfc_hw_ecc_read_page_dma;
 		ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage_dma;
@@ -1937,33 +1842,18 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
 	ecc->write_oob_raw = nand_write_oob_std;
 
 	return 0;
-}
 
-static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
-						struct nand_ecc_ctrl *ecc,
-						struct device_node *np)
-{
-	int ret;
+err:
+	kfree(data);
 
-	ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np);
-	if (ret)
-		return ret;
-
-	ecc->prepad = 4;
-	ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
-	ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
-	ecc->read_oob_raw = nand_read_oob_syndrome;
-	ecc->write_oob_raw = nand_write_oob_syndrome;
-
-	return 0;
+	return ret;
 }
 
 static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
 {
 	switch (ecc->mode) {
 	case NAND_ECC_HW:
-	case NAND_ECC_HW_SYNDROME:
-		sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
+		sunxi_nand_hw_ecc_ctrl_cleanup(ecc);
 		break;
 	case NAND_ECC_NONE:
 	default:
@@ -1991,11 +1881,6 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
 		if (ret)
 			return ret;
 		break;
-	case NAND_ECC_HW_SYNDROME:
-		ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np);
-		if (ret)
-			return ret;
-		break;
 	case NAND_ECC_NONE:
 	case NAND_ECC_SOFT:
 		break;
diff --git a/drivers/mtd/nand/tango_nand.c b/drivers/mtd/nand/raw/tango_nand.c
similarity index 99%
rename from drivers/mtd/nand/tango_nand.c
rename to drivers/mtd/nand/raw/tango_nand.c
index c5bee00b..f54518f 100644
--- a/drivers/mtd/nand/tango_nand.c
+++ b/drivers/mtd/nand/raw/tango_nand.c
@@ -591,8 +591,10 @@ static int chip_init(struct device *dev, struct device_node *np)
 	tchip->bb_cfg = BB_CFG(mtd->writesize, BBM_SIZE);
 
 	err = mtd_device_register(mtd, NULL, 0);
-	if (err)
+	if (err) {
+		nand_cleanup(chip);
 		return err;
+	}
 
 	nfc->chips[cs] = tchip;
 
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/raw/tmio_nand.c
similarity index 100%
rename from drivers/mtd/nand/tmio_nand.c
rename to drivers/mtd/nand/raw/tmio_nand.c
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/raw/txx9ndfmc.c
similarity index 100%
rename from drivers/mtd/nand/txx9ndfmc.c
rename to drivers/mtd/nand/raw/txx9ndfmc.c
diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c
new file mode 100644
index 0000000..d5a22fc
--- /dev/null
+++ b/drivers/mtd/nand/raw/vf610_nfc.c
@@ -0,0 +1,962 @@
+/*
+ * Copyright 2009-2015 Freescale Semiconductor, Inc. and others
+ *
+ * Description: MPC5125, VF610, MCF54418 and Kinetis K70 Nand driver.
+ * Jason ported to M54418TWR and MVFA5 (VF610).
+ * Authors: Stefan Agner <stefan.agner@toradex.com>
+ *          Bill Pringlemeir <bpringlemeir@nbsps.com>
+ *          Shaohui Xie <b21989@freescale.com>
+ *          Jason Jin <Jason.jin@freescale.com>
+ *
+ * Based on original driver mpc5121_nfc.c.
+ *
+ * This is free software; you can redistribute 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.
+ *
+ * Limitations:
+ * - Untested on MPC5125 and M54418.
+ * - DMA and pipelining not used.
+ * - 2K pages or less.
+ * - HW ECC: Only 2K page with 64+ OOB.
+ * - HW ECC: Only 24 and 32-bit error correction implemented.
+ */
+
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/swab.h>
+
+#define	DRV_NAME		"vf610_nfc"
+
+/* Register Offsets */
+#define NFC_FLASH_CMD1			0x3F00
+#define NFC_FLASH_CMD2			0x3F04
+#define NFC_COL_ADDR			0x3F08
+#define NFC_ROW_ADDR			0x3F0c
+#define NFC_ROW_ADDR_INC		0x3F14
+#define NFC_FLASH_STATUS1		0x3F18
+#define NFC_FLASH_STATUS2		0x3F1c
+#define NFC_CACHE_SWAP			0x3F28
+#define NFC_SECTOR_SIZE			0x3F2c
+#define NFC_FLASH_CONFIG		0x3F30
+#define NFC_IRQ_STATUS			0x3F38
+
+/* Addresses for NFC MAIN RAM BUFFER areas */
+#define NFC_MAIN_AREA(n)		((n) *  0x1000)
+
+#define PAGE_2K				0x0800
+#define OOB_64				0x0040
+#define OOB_MAX				0x0100
+
+/* NFC_CMD2[CODE] controller cycle bit masks */
+#define COMMAND_CMD_BYTE1		BIT(14)
+#define COMMAND_CAR_BYTE1		BIT(13)
+#define COMMAND_CAR_BYTE2		BIT(12)
+#define COMMAND_RAR_BYTE1		BIT(11)
+#define COMMAND_RAR_BYTE2		BIT(10)
+#define COMMAND_RAR_BYTE3		BIT(9)
+#define COMMAND_NADDR_BYTES(x)		GENMASK(13, 13 - (x) + 1)
+#define COMMAND_WRITE_DATA		BIT(8)
+#define COMMAND_CMD_BYTE2		BIT(7)
+#define COMMAND_RB_HANDSHAKE		BIT(6)
+#define COMMAND_READ_DATA		BIT(5)
+#define COMMAND_CMD_BYTE3		BIT(4)
+#define COMMAND_READ_STATUS		BIT(3)
+#define COMMAND_READ_ID			BIT(2)
+
+/* NFC ECC mode define */
+#define ECC_BYPASS			0
+#define ECC_45_BYTE			6
+#define ECC_60_BYTE			7
+
+/*** Register Mask and bit definitions */
+
+/* NFC_FLASH_CMD1 Field */
+#define CMD_BYTE2_MASK				0xFF000000
+#define CMD_BYTE2_SHIFT				24
+
+/* NFC_FLASH_CM2 Field */
+#define CMD_BYTE1_MASK				0xFF000000
+#define CMD_BYTE1_SHIFT				24
+#define CMD_CODE_MASK				0x00FFFF00
+#define CMD_CODE_SHIFT				8
+#define BUFNO_MASK				0x00000006
+#define BUFNO_SHIFT				1
+#define START_BIT				BIT(0)
+
+/* NFC_COL_ADDR Field */
+#define COL_ADDR_MASK				0x0000FFFF
+#define COL_ADDR_SHIFT				0
+#define COL_ADDR(pos, val)			(((val) & 0xFF) << (8 * (pos)))
+
+/* NFC_ROW_ADDR Field */
+#define ROW_ADDR_MASK				0x00FFFFFF
+#define ROW_ADDR_SHIFT				0
+#define ROW_ADDR(pos, val)			(((val) & 0xFF) << (8 * (pos)))
+
+#define ROW_ADDR_CHIP_SEL_RB_MASK		0xF0000000
+#define ROW_ADDR_CHIP_SEL_RB_SHIFT		28
+#define ROW_ADDR_CHIP_SEL_MASK			0x0F000000
+#define ROW_ADDR_CHIP_SEL_SHIFT			24
+
+/* NFC_FLASH_STATUS2 Field */
+#define STATUS_BYTE1_MASK			0x000000FF
+
+/* NFC_FLASH_CONFIG Field */
+#define CONFIG_ECC_SRAM_ADDR_MASK		0x7FC00000
+#define CONFIG_ECC_SRAM_ADDR_SHIFT		22
+#define CONFIG_ECC_SRAM_REQ_BIT			BIT(21)
+#define CONFIG_DMA_REQ_BIT			BIT(20)
+#define CONFIG_ECC_MODE_MASK			0x000E0000
+#define CONFIG_ECC_MODE_SHIFT			17
+#define CONFIG_FAST_FLASH_BIT			BIT(16)
+#define CONFIG_16BIT				BIT(7)
+#define CONFIG_BOOT_MODE_BIT			BIT(6)
+#define CONFIG_ADDR_AUTO_INCR_BIT		BIT(5)
+#define CONFIG_BUFNO_AUTO_INCR_BIT		BIT(4)
+#define CONFIG_PAGE_CNT_MASK			0xF
+#define CONFIG_PAGE_CNT_SHIFT			0
+
+/* NFC_IRQ_STATUS Field */
+#define IDLE_IRQ_BIT				BIT(29)
+#define IDLE_EN_BIT				BIT(20)
+#define CMD_DONE_CLEAR_BIT			BIT(18)
+#define IDLE_CLEAR_BIT				BIT(17)
+
+/*
+ * ECC status - seems to consume 8 bytes (double word). The documented
+ * status byte is located in the lowest byte of the second word (which is
+ * the 4th or 7th byte depending on endianness).
+ * Calculate an offset to store the ECC status at the end of the buffer.
+ */
+#define ECC_SRAM_ADDR		(PAGE_2K + OOB_MAX - 8)
+
+#define ECC_STATUS		0x4
+#define ECC_STATUS_MASK		0x80
+#define ECC_STATUS_ERR_COUNT	0x3F
+
+enum vf610_nfc_variant {
+	NFC_VFC610 = 1,
+};
+
+struct vf610_nfc {
+	struct nand_chip chip;
+	struct device *dev;
+	void __iomem *regs;
+	struct completion cmd_done;
+	/* Status and ID are in alternate locations. */
+	enum vf610_nfc_variant variant;
+	struct clk *clk;
+	/*
+	 * Indicate that user data is accessed (full page/oob). This is
+	 * useful to indicate the driver whether to swap byte endianness.
+	 * See comments in vf610_nfc_rd_from_sram/vf610_nfc_wr_to_sram.
+	 */
+	bool data_access;
+	u32 ecc_mode;
+};
+
+static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info *mtd)
+{
+	return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip);
+}
+
+static inline struct vf610_nfc *chip_to_nfc(struct nand_chip *chip)
+{
+	return container_of(chip, struct vf610_nfc, chip);
+}
+
+static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
+{
+	return readl(nfc->regs + reg);
+}
+
+static inline void vf610_nfc_write(struct vf610_nfc *nfc, uint reg, u32 val)
+{
+	writel(val, nfc->regs + reg);
+}
+
+static inline void vf610_nfc_set(struct vf610_nfc *nfc, uint reg, u32 bits)
+{
+	vf610_nfc_write(nfc, reg, vf610_nfc_read(nfc, reg) | bits);
+}
+
+static inline void vf610_nfc_clear(struct vf610_nfc *nfc, uint reg, u32 bits)
+{
+	vf610_nfc_write(nfc, reg, vf610_nfc_read(nfc, reg) & ~bits);
+}
+
+static inline void vf610_nfc_set_field(struct vf610_nfc *nfc, u32 reg,
+				       u32 mask, u32 shift, u32 val)
+{
+	vf610_nfc_write(nfc, reg,
+			(vf610_nfc_read(nfc, reg) & (~mask)) | val << shift);
+}
+
+static inline bool vf610_nfc_kernel_is_little_endian(void)
+{
+#ifdef __LITTLE_ENDIAN
+	return true;
+#else
+	return false;
+#endif
+}
+
+/**
+ * Read accessor for internal SRAM buffer
+ * @dst: destination address in regular memory
+ * @src: source address in SRAM buffer
+ * @len: bytes to copy
+ * @fix_endian: Fix endianness if required
+ *
+ * Use this accessor for the internal SRAM buffers. On the ARM
+ * Freescale Vybrid SoC it's known that the driver can treat
+ * the SRAM buffer as if it's memory. Other platform might need
+ * to treat the buffers differently.
+ *
+ * The controller stores bytes from the NAND chip internally in big
+ * endianness. On little endian platforms such as Vybrid this leads
+ * to reversed byte order.
+ * For performance reason (and earlier probably due to unawareness)
+ * the driver avoids correcting endianness where it has control over
+ * write and read side (e.g. page wise data access).
+ */
+static inline void vf610_nfc_rd_from_sram(void *dst, const void __iomem *src,
+					  size_t len, bool fix_endian)
+{
+	if (vf610_nfc_kernel_is_little_endian() && fix_endian) {
+		unsigned int i;
+
+		for (i = 0; i < len; i += 4) {
+			u32 val = swab32(__raw_readl(src + i));
+
+			memcpy(dst + i, &val, min(sizeof(val), len - i));
+		}
+	} else {
+		memcpy_fromio(dst, src, len);
+	}
+}
+
+/**
+ * Write accessor for internal SRAM buffer
+ * @dst: destination address in SRAM buffer
+ * @src: source address in regular memory
+ * @len: bytes to copy
+ * @fix_endian: Fix endianness if required
+ *
+ * Use this accessor for the internal SRAM buffers. On the ARM
+ * Freescale Vybrid SoC it's known that the driver can treat
+ * the SRAM buffer as if it's memory. Other platform might need
+ * to treat the buffers differently.
+ *
+ * The controller stores bytes from the NAND chip internally in big
+ * endianness. On little endian platforms such as Vybrid this leads
+ * to reversed byte order.
+ * For performance reason (and earlier probably due to unawareness)
+ * the driver avoids correcting endianness where it has control over
+ * write and read side (e.g. page wise data access).
+ */
+static inline void vf610_nfc_wr_to_sram(void __iomem *dst, const void *src,
+					size_t len, bool fix_endian)
+{
+	if (vf610_nfc_kernel_is_little_endian() && fix_endian) {
+		unsigned int i;
+
+		for (i = 0; i < len; i += 4) {
+			u32 val;
+
+			memcpy(&val, src + i, min(sizeof(val), len - i));
+			__raw_writel(swab32(val), dst + i);
+		}
+	} else {
+		memcpy_toio(dst, src, len);
+	}
+}
+
+/* Clear flags for upcoming command */
+static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc)
+{
+	u32 tmp = vf610_nfc_read(nfc, NFC_IRQ_STATUS);
+
+	tmp |= CMD_DONE_CLEAR_BIT | IDLE_CLEAR_BIT;
+	vf610_nfc_write(nfc, NFC_IRQ_STATUS, tmp);
+}
+
+static void vf610_nfc_done(struct vf610_nfc *nfc)
+{
+	unsigned long timeout = msecs_to_jiffies(100);
+
+	/*
+	 * Barrier is needed after this write. This write need
+	 * to be done before reading the next register the first
+	 * time.
+	 * vf610_nfc_set implicates such a barrier by using writel
+	 * to write to the register.
+	 */
+	vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT);
+	vf610_nfc_set(nfc, NFC_FLASH_CMD2, START_BIT);
+
+	if (!wait_for_completion_timeout(&nfc->cmd_done, timeout))
+		dev_warn(nfc->dev, "Timeout while waiting for BUSY.\n");
+
+	vf610_nfc_clear_status(nfc);
+}
+
+static irqreturn_t vf610_nfc_irq(int irq, void *data)
+{
+	struct mtd_info *mtd = data;
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	vf610_nfc_clear(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT);
+	complete(&nfc->cmd_done);
+
+	return IRQ_HANDLED;
+}
+
+static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode)
+{
+	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
+			    CONFIG_ECC_MODE_MASK,
+			    CONFIG_ECC_MODE_SHIFT, ecc_mode);
+}
+
+static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
+{
+	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
+}
+
+static inline void vf610_nfc_run(struct vf610_nfc *nfc, u32 col, u32 row,
+				 u32 cmd1, u32 cmd2, u32 trfr_sz)
+{
+	vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
+			    COL_ADDR_SHIFT, col);
+
+	vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+			    ROW_ADDR_SHIFT, row);
+
+	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, trfr_sz);
+	vf610_nfc_write(nfc, NFC_FLASH_CMD1, cmd1);
+	vf610_nfc_write(nfc, NFC_FLASH_CMD2, cmd2);
+
+	dev_dbg(nfc->dev,
+		"col 0x%04x, row 0x%08x, cmd1 0x%08x, cmd2 0x%08x, len %d\n",
+		col, row, cmd1, cmd2, trfr_sz);
+
+	vf610_nfc_done(nfc);
+}
+
+static inline const struct nand_op_instr *
+vf610_get_next_instr(const struct nand_subop *subop, int *op_id)
+{
+	if (*op_id + 1 >= subop->ninstrs)
+		return NULL;
+
+	(*op_id)++;
+
+	return &subop->instrs[*op_id];
+}
+
+static int vf610_nfc_cmd(struct nand_chip *chip,
+			 const struct nand_subop *subop)
+{
+	const struct nand_op_instr *instr;
+	struct vf610_nfc *nfc = chip_to_nfc(chip);
+	int op_id = -1, trfr_sz = 0, offset;
+	u32 col = 0, row = 0, cmd1 = 0, cmd2 = 0, code = 0;
+	bool force8bit = false;
+
+	/*
+	 * Some ops are optional, but the hardware requires the operations
+	 * to be in this exact order.
+	 * The op parser enforces the order and makes sure that there isn't
+	 * a read and write element in a single operation.
+	 */
+	instr = vf610_get_next_instr(subop, &op_id);
+	if (!instr)
+		return -EINVAL;
+
+	if (instr && instr->type == NAND_OP_CMD_INSTR) {
+		cmd2 |= instr->ctx.cmd.opcode << CMD_BYTE1_SHIFT;
+		code |= COMMAND_CMD_BYTE1;
+
+		instr = vf610_get_next_instr(subop, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_ADDR_INSTR) {
+		int naddrs = nand_subop_get_num_addr_cyc(subop, op_id);
+		int i = nand_subop_get_addr_start_off(subop, op_id);
+
+		for (; i < naddrs; i++) {
+			u8 val = instr->ctx.addr.addrs[i];
+
+			if (i < 2)
+				col |= COL_ADDR(i, val);
+			else
+				row |= ROW_ADDR(i - 2, val);
+		}
+		code |= COMMAND_NADDR_BYTES(naddrs);
+
+		instr = vf610_get_next_instr(subop, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_DATA_OUT_INSTR) {
+		trfr_sz = nand_subop_get_data_len(subop, op_id);
+		offset = nand_subop_get_data_start_off(subop, op_id);
+		force8bit = instr->ctx.data.force_8bit;
+
+		/*
+		 * Don't fix endianness on page access for historical reasons.
+		 * See comment in vf610_nfc_wr_to_sram
+		 */
+		vf610_nfc_wr_to_sram(nfc->regs + NFC_MAIN_AREA(0) + offset,
+				     instr->ctx.data.buf.out + offset,
+				     trfr_sz, !nfc->data_access);
+		code |= COMMAND_WRITE_DATA;
+
+		instr = vf610_get_next_instr(subop, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_CMD_INSTR) {
+		cmd1 |= instr->ctx.cmd.opcode << CMD_BYTE2_SHIFT;
+		code |= COMMAND_CMD_BYTE2;
+
+		instr = vf610_get_next_instr(subop, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_WAITRDY_INSTR) {
+		code |= COMMAND_RB_HANDSHAKE;
+
+		instr = vf610_get_next_instr(subop, &op_id);
+	}
+
+	if (instr && instr->type == NAND_OP_DATA_IN_INSTR) {
+		trfr_sz = nand_subop_get_data_len(subop, op_id);
+		offset = nand_subop_get_data_start_off(subop, op_id);
+		force8bit = instr->ctx.data.force_8bit;
+
+		code |= COMMAND_READ_DATA;
+	}
+
+	if (force8bit && (chip->options & NAND_BUSWIDTH_16))
+		vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+
+	cmd2 |= code << CMD_CODE_SHIFT;
+
+	vf610_nfc_run(nfc, col, row, cmd1, cmd2, trfr_sz);
+
+	if (instr && instr->type == NAND_OP_DATA_IN_INSTR) {
+		/*
+		 * Don't fix endianness on page access for historical reasons.
+		 * See comment in vf610_nfc_rd_from_sram
+		 */
+		vf610_nfc_rd_from_sram(instr->ctx.data.buf.in + offset,
+				       nfc->regs + NFC_MAIN_AREA(0) + offset,
+				       trfr_sz, !nfc->data_access);
+	}
+
+	if (force8bit && (chip->options & NAND_BUSWIDTH_16))
+		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+
+	return 0;
+}
+
+static const struct nand_op_parser vf610_nfc_op_parser = NAND_OP_PARSER(
+	NAND_OP_PARSER_PATTERN(vf610_nfc_cmd,
+		NAND_OP_PARSER_PAT_CMD_ELEM(true),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(true, 5),
+		NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, PAGE_2K + OOB_MAX),
+		NAND_OP_PARSER_PAT_CMD_ELEM(true),
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)),
+	NAND_OP_PARSER_PATTERN(vf610_nfc_cmd,
+		NAND_OP_PARSER_PAT_CMD_ELEM(true),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(true, 5),
+		NAND_OP_PARSER_PAT_CMD_ELEM(true),
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, PAGE_2K + OOB_MAX)),
+	);
+
+static int vf610_nfc_exec_op(struct nand_chip *chip,
+			     const struct nand_operation *op,
+			     bool check_only)
+{
+	return nand_op_parser_exec_op(chip, &vf610_nfc_op_parser, op,
+				      check_only);
+}
+
+/*
+ * This function supports Vybrid only (MPC5125 would have full RB and four CS)
+ */
+static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
+
+	/* Vybrid only (MPC5125 would have full RB and four CS) */
+	if (nfc->variant != NFC_VFC610)
+		return;
+
+	tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
+
+	if (chip >= 0) {
+		tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
+		tmp |= BIT(chip) << ROW_ADDR_CHIP_SEL_SHIFT;
+	}
+
+	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
+}
+
+static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
+					 uint8_t *oob, int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	u32 ecc_status_off = NFC_MAIN_AREA(0) + ECC_SRAM_ADDR + ECC_STATUS;
+	u8 ecc_status;
+	u8 ecc_count;
+	int flips_threshold = nfc->chip.ecc.strength / 2;
+
+	ecc_status = vf610_nfc_read(nfc, ecc_status_off) & 0xff;
+	ecc_count = ecc_status & ECC_STATUS_ERR_COUNT;
+
+	if (!(ecc_status & ECC_STATUS_MASK))
+		return ecc_count;
+
+	nfc->data_access = true;
+	nand_read_oob_op(&nfc->chip, page, 0, oob, mtd->oobsize);
+	nfc->data_access = false;
+
+	/*
+	 * On an erased page, bit count (including OOB) should be zero or
+	 * at least less then half of the ECC strength.
+	 */
+	return nand_check_erased_ecc_chunk(dat, nfc->chip.ecc.size, oob,
+					   mtd->oobsize, NULL, 0,
+					   flips_threshold);
+}
+
+static void vf610_nfc_fill_row(struct nand_chip *chip, int page, u32 *code,
+			       u32 *row)
+{
+	*row = ROW_ADDR(0, page & 0xff) | ROW_ADDR(1, page >> 8);
+	*code |= COMMAND_RAR_BYTE1 | COMMAND_RAR_BYTE2;
+
+	if (chip->options & NAND_ROW_ADDR_3) {
+		*row |= ROW_ADDR(2, page >> 16);
+		*code |= COMMAND_RAR_BYTE3;
+	}
+}
+
+static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int oob_required, int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int trfr_sz = mtd->writesize + mtd->oobsize;
+	u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0;
+	int stat;
+
+	cmd2 |= NAND_CMD_READ0 << CMD_BYTE1_SHIFT;
+	code |= COMMAND_CMD_BYTE1 | COMMAND_CAR_BYTE1 | COMMAND_CAR_BYTE2;
+
+	vf610_nfc_fill_row(chip, page, &code, &row);
+
+	cmd1 |= NAND_CMD_READSTART << CMD_BYTE2_SHIFT;
+	code |= COMMAND_CMD_BYTE2 | COMMAND_RB_HANDSHAKE | COMMAND_READ_DATA;
+
+	cmd2 |= code << CMD_CODE_SHIFT;
+
+	vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
+	vf610_nfc_run(nfc, 0, row, cmd1, cmd2, trfr_sz);
+	vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
+
+	/*
+	 * Don't fix endianness on page access for historical reasons.
+	 * See comment in vf610_nfc_rd_from_sram
+	 */
+	vf610_nfc_rd_from_sram(buf, nfc->regs + NFC_MAIN_AREA(0),
+			       mtd->writesize, false);
+	if (oob_required)
+		vf610_nfc_rd_from_sram(chip->oob_poi,
+				       nfc->regs + NFC_MAIN_AREA(0) +
+						   mtd->writesize,
+				       mtd->oobsize, false);
+
+	stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, page);
+
+	if (stat < 0) {
+		mtd->ecc_stats.failed++;
+		return 0;
+	} else {
+		mtd->ecc_stats.corrected += stat;
+		return stat;
+	}
+}
+
+static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+				const uint8_t *buf, int oob_required, int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int trfr_sz = mtd->writesize + mtd->oobsize;
+	u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0;
+	u8 status;
+	int ret;
+
+	cmd2 |= NAND_CMD_SEQIN << CMD_BYTE1_SHIFT;
+	code |= COMMAND_CMD_BYTE1 | COMMAND_CAR_BYTE1 | COMMAND_CAR_BYTE2;
+
+	vf610_nfc_fill_row(chip, page, &code, &row);
+
+	cmd1 |= NAND_CMD_PAGEPROG << CMD_BYTE2_SHIFT;
+	code |= COMMAND_CMD_BYTE2 | COMMAND_WRITE_DATA;
+
+	/*
+	 * Don't fix endianness on page access for historical reasons.
+	 * See comment in vf610_nfc_wr_to_sram
+	 */
+	vf610_nfc_wr_to_sram(nfc->regs + NFC_MAIN_AREA(0), buf,
+			     mtd->writesize, false);
+
+	code |= COMMAND_RB_HANDSHAKE;
+	cmd2 |= code << CMD_CODE_SHIFT;
+
+	vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
+	vf610_nfc_run(nfc, 0, row, cmd1, cmd2, trfr_sz);
+	vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
+
+	ret = nand_status_op(chip, &status);
+	if (ret)
+		return ret;
+
+	if (status & NAND_STATUS_FAIL)
+		return -EIO;
+
+	return 0;
+}
+
+static int vf610_nfc_read_page_raw(struct mtd_info *mtd,
+				   struct nand_chip *chip, u8 *buf,
+				   int oob_required, int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int ret;
+
+	nfc->data_access = true;
+	ret = nand_read_page_raw(mtd, chip, buf, oob_required, page);
+	nfc->data_access = false;
+
+	return ret;
+}
+
+static int vf610_nfc_write_page_raw(struct mtd_info *mtd,
+				    struct nand_chip *chip, const u8 *buf,
+				    int oob_required, int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int ret;
+
+	nfc->data_access = true;
+	ret = nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
+	if (!ret && oob_required)
+		ret = nand_write_data_op(chip, chip->oob_poi, mtd->oobsize,
+					 false);
+	nfc->data_access = false;
+
+	if (ret)
+		return ret;
+
+	return nand_prog_page_end_op(chip);
+}
+
+static int vf610_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			      int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int ret;
+
+	nfc->data_access = true;
+	ret = nand_read_oob_std(mtd, chip, page);
+	nfc->data_access = false;
+
+	return ret;
+}
+
+static int vf610_nfc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			       int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int ret;
+
+	nfc->data_access = true;
+	ret = nand_prog_page_begin_op(chip, page, mtd->writesize,
+				      chip->oob_poi, mtd->oobsize);
+	nfc->data_access = false;
+
+	if (ret)
+		return ret;
+
+	return nand_prog_page_end_op(chip);
+}
+
+static const struct of_device_id vf610_nfc_dt_ids[] = {
+	{ .compatible = "fsl,vf610-nfc", .data = (void *)NFC_VFC610 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, vf610_nfc_dt_ids);
+
+static void vf610_nfc_preinit_controller(struct vf610_nfc *nfc)
+{
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BUFNO_AUTO_INCR_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BOOT_MODE_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT);
+	vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT);
+	vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
+
+	/* Disable virtual pages, only one elementary transfer unit */
+	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK,
+			    CONFIG_PAGE_CNT_SHIFT, 1);
+}
+
+static void vf610_nfc_init_controller(struct vf610_nfc *nfc)
+{
+	if (nfc->chip.options & NAND_BUSWIDTH_16)
+		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+	else
+		vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+
+	if (nfc->chip.ecc.mode == NAND_ECC_HW) {
+		/* Set ECC status offset in SRAM */
+		vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
+				    CONFIG_ECC_SRAM_ADDR_MASK,
+				    CONFIG_ECC_SRAM_ADDR_SHIFT,
+				    ECC_SRAM_ADDR >> 3);
+
+		/* Enable ECC status in SRAM */
+		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
+	}
+}
+
+static int vf610_nfc_probe(struct platform_device *pdev)
+{
+	struct vf610_nfc *nfc;
+	struct resource *res;
+	struct mtd_info *mtd;
+	struct nand_chip *chip;
+	struct device_node *child;
+	const struct of_device_id *of_id;
+	int err;
+	int irq;
+
+	nfc = devm_kzalloc(&pdev->dev, sizeof(*nfc), GFP_KERNEL);
+	if (!nfc)
+		return -ENOMEM;
+
+	nfc->dev = &pdev->dev;
+	chip = &nfc->chip;
+	mtd = nand_to_mtd(chip);
+
+	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = nfc->dev;
+	mtd->name = DRV_NAME;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0)
+		return -EINVAL;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	nfc->regs = devm_ioremap_resource(nfc->dev, res);
+	if (IS_ERR(nfc->regs))
+		return PTR_ERR(nfc->regs);
+
+	nfc->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(nfc->clk))
+		return PTR_ERR(nfc->clk);
+
+	err = clk_prepare_enable(nfc->clk);
+	if (err) {
+		dev_err(nfc->dev, "Unable to enable clock!\n");
+		return err;
+	}
+
+	of_id = of_match_device(vf610_nfc_dt_ids, &pdev->dev);
+	nfc->variant = (enum vf610_nfc_variant)of_id->data;
+
+	for_each_available_child_of_node(nfc->dev->of_node, child) {
+		if (of_device_is_compatible(child, "fsl,vf610-nfc-nandcs")) {
+
+			if (nand_get_flash_node(chip)) {
+				dev_err(nfc->dev,
+					"Only one NAND chip supported!\n");
+				err = -EINVAL;
+				goto err_disable_clk;
+			}
+
+			nand_set_flash_node(chip, child);
+		}
+	}
+
+	if (!nand_get_flash_node(chip)) {
+		dev_err(nfc->dev, "NAND chip sub-node missing!\n");
+		err = -ENODEV;
+		goto err_disable_clk;
+	}
+
+	chip->exec_op = vf610_nfc_exec_op;
+	chip->select_chip = vf610_nfc_select_chip;
+
+	chip->options |= NAND_NO_SUBPAGE_WRITE;
+
+	init_completion(&nfc->cmd_done);
+
+	err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
+	if (err) {
+		dev_err(nfc->dev, "Error requesting IRQ!\n");
+		goto err_disable_clk;
+	}
+
+	vf610_nfc_preinit_controller(nfc);
+
+	/* first scan to find the device and get the page size */
+	err = nand_scan_ident(mtd, 1, NULL);
+	if (err)
+		goto err_disable_clk;
+
+	vf610_nfc_init_controller(nfc);
+
+	/* Bad block options. */
+	if (chip->bbt_options & NAND_BBT_USE_FLASH)
+		chip->bbt_options |= NAND_BBT_NO_OOB;
+
+	/* Single buffer only, max 256 OOB minus ECC status */
+	if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
+		dev_err(nfc->dev, "Unsupported flash page size\n");
+		err = -ENXIO;
+		goto err_disable_clk;
+	}
+
+	if (chip->ecc.mode == NAND_ECC_HW) {
+		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
+			dev_err(nfc->dev, "Unsupported flash with hwecc\n");
+			err = -ENXIO;
+			goto err_disable_clk;
+		}
+
+		if (chip->ecc.size != mtd->writesize) {
+			dev_err(nfc->dev, "Step size needs to be page size\n");
+			err = -ENXIO;
+			goto err_disable_clk;
+		}
+
+		/* Only 64 byte ECC layouts known */
+		if (mtd->oobsize > 64)
+			mtd->oobsize = 64;
+
+		/* Use default large page ECC layout defined in NAND core */
+		mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
+		if (chip->ecc.strength == 32) {
+			nfc->ecc_mode = ECC_60_BYTE;
+			chip->ecc.bytes = 60;
+		} else if (chip->ecc.strength == 24) {
+			nfc->ecc_mode = ECC_45_BYTE;
+			chip->ecc.bytes = 45;
+		} else {
+			dev_err(nfc->dev, "Unsupported ECC strength\n");
+			err = -ENXIO;
+			goto err_disable_clk;
+		}
+
+		chip->ecc.read_page = vf610_nfc_read_page;
+		chip->ecc.write_page = vf610_nfc_write_page;
+		chip->ecc.read_page_raw = vf610_nfc_read_page_raw;
+		chip->ecc.write_page_raw = vf610_nfc_write_page_raw;
+		chip->ecc.read_oob = vf610_nfc_read_oob;
+		chip->ecc.write_oob = vf610_nfc_write_oob;
+
+		chip->ecc.size = PAGE_2K;
+	}
+
+	/* second phase scan */
+	err = nand_scan_tail(mtd);
+	if (err)
+		goto err_disable_clk;
+
+	platform_set_drvdata(pdev, mtd);
+
+	/* Register device in MTD */
+	err = mtd_device_register(mtd, NULL, 0);
+	if (err)
+		goto err_cleanup_nand;
+	return 0;
+
+err_cleanup_nand:
+	nand_cleanup(chip);
+err_disable_clk:
+	clk_disable_unprepare(nfc->clk);
+	return err;
+}
+
+static int vf610_nfc_remove(struct platform_device *pdev)
+{
+	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	nand_release(mtd);
+	clk_disable_unprepare(nfc->clk);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int vf610_nfc_suspend(struct device *dev)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	clk_disable_unprepare(nfc->clk);
+	return 0;
+}
+
+static int vf610_nfc_resume(struct device *dev)
+{
+	int err;
+
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	err = clk_prepare_enable(nfc->clk);
+	if (err)
+		return err;
+
+	vf610_nfc_preinit_controller(nfc);
+	vf610_nfc_init_controller(nfc);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(vf610_nfc_pm_ops, vf610_nfc_suspend, vf610_nfc_resume);
+
+static struct platform_driver vf610_nfc_driver = {
+	.driver		= {
+		.name	= DRV_NAME,
+		.of_match_table = vf610_nfc_dt_ids,
+		.pm	= &vf610_nfc_pm_ops,
+	},
+	.probe		= vf610_nfc_probe,
+	.remove		= vf610_nfc_remove,
+};
+
+module_platform_driver(vf610_nfc_driver);
+
+MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>");
+MODULE_DESCRIPTION("Freescale VF610/MPC5125 NFC MTD NAND driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c
similarity index 100%
rename from drivers/mtd/nand/xway_nand.c
rename to drivers/mtd/nand/raw/xway_nand.c
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
deleted file mode 100644
index f367144..0000000
--- a/drivers/mtd/nand/vf610_nfc.c
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * Copyright 2009-2015 Freescale Semiconductor, Inc. and others
- *
- * Description: MPC5125, VF610, MCF54418 and Kinetis K70 Nand driver.
- * Jason ported to M54418TWR and MVFA5 (VF610).
- * Authors: Stefan Agner <stefan.agner@toradex.com>
- *          Bill Pringlemeir <bpringlemeir@nbsps.com>
- *          Shaohui Xie <b21989@freescale.com>
- *          Jason Jin <Jason.jin@freescale.com>
- *
- * Based on original driver mpc5121_nfc.c.
- *
- * This is free software; you can redistribute 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.
- *
- * Limitations:
- * - Untested on MPC5125 and M54418.
- * - DMA and pipelining not used.
- * - 2K pages or less.
- * - HW ECC: Only 2K page with 64+ OOB.
- * - HW ECC: Only 24 and 32-bit error correction implemented.
- */
-
-#include <linux/module.h>
-#include <linux/bitops.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/rawnand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#define	DRV_NAME		"vf610_nfc"
-
-/* Register Offsets */
-#define NFC_FLASH_CMD1			0x3F00
-#define NFC_FLASH_CMD2			0x3F04
-#define NFC_COL_ADDR			0x3F08
-#define NFC_ROW_ADDR			0x3F0c
-#define NFC_ROW_ADDR_INC		0x3F14
-#define NFC_FLASH_STATUS1		0x3F18
-#define NFC_FLASH_STATUS2		0x3F1c
-#define NFC_CACHE_SWAP			0x3F28
-#define NFC_SECTOR_SIZE			0x3F2c
-#define NFC_FLASH_CONFIG		0x3F30
-#define NFC_IRQ_STATUS			0x3F38
-
-/* Addresses for NFC MAIN RAM BUFFER areas */
-#define NFC_MAIN_AREA(n)		((n) *  0x1000)
-
-#define PAGE_2K				0x0800
-#define OOB_64				0x0040
-#define OOB_MAX				0x0100
-
-/*
- * NFC_CMD2[CODE] values. See section:
- *  - 31.4.7 Flash Command Code Description, Vybrid manual
- *  - 23.8.6 Flash Command Sequencer, MPC5125 manual
- *
- * Briefly these are bitmasks of controller cycles.
- */
-#define READ_PAGE_CMD_CODE		0x7EE0
-#define READ_ONFI_PARAM_CMD_CODE	0x4860
-#define PROGRAM_PAGE_CMD_CODE		0x7FC0
-#define ERASE_CMD_CODE			0x4EC0
-#define READ_ID_CMD_CODE		0x4804
-#define RESET_CMD_CODE			0x4040
-#define STATUS_READ_CMD_CODE		0x4068
-
-/* NFC ECC mode define */
-#define ECC_BYPASS			0
-#define ECC_45_BYTE			6
-#define ECC_60_BYTE			7
-
-/*** Register Mask and bit definitions */
-
-/* NFC_FLASH_CMD1 Field */
-#define CMD_BYTE2_MASK				0xFF000000
-#define CMD_BYTE2_SHIFT				24
-
-/* NFC_FLASH_CM2 Field */
-#define CMD_BYTE1_MASK				0xFF000000
-#define CMD_BYTE1_SHIFT				24
-#define CMD_CODE_MASK				0x00FFFF00
-#define CMD_CODE_SHIFT				8
-#define BUFNO_MASK				0x00000006
-#define BUFNO_SHIFT				1
-#define START_BIT				BIT(0)
-
-/* NFC_COL_ADDR Field */
-#define COL_ADDR_MASK				0x0000FFFF
-#define COL_ADDR_SHIFT				0
-
-/* NFC_ROW_ADDR Field */
-#define ROW_ADDR_MASK				0x00FFFFFF
-#define ROW_ADDR_SHIFT				0
-#define ROW_ADDR_CHIP_SEL_RB_MASK		0xF0000000
-#define ROW_ADDR_CHIP_SEL_RB_SHIFT		28
-#define ROW_ADDR_CHIP_SEL_MASK			0x0F000000
-#define ROW_ADDR_CHIP_SEL_SHIFT			24
-
-/* NFC_FLASH_STATUS2 Field */
-#define STATUS_BYTE1_MASK			0x000000FF
-
-/* NFC_FLASH_CONFIG Field */
-#define CONFIG_ECC_SRAM_ADDR_MASK		0x7FC00000
-#define CONFIG_ECC_SRAM_ADDR_SHIFT		22
-#define CONFIG_ECC_SRAM_REQ_BIT			BIT(21)
-#define CONFIG_DMA_REQ_BIT			BIT(20)
-#define CONFIG_ECC_MODE_MASK			0x000E0000
-#define CONFIG_ECC_MODE_SHIFT			17
-#define CONFIG_FAST_FLASH_BIT			BIT(16)
-#define CONFIG_16BIT				BIT(7)
-#define CONFIG_BOOT_MODE_BIT			BIT(6)
-#define CONFIG_ADDR_AUTO_INCR_BIT		BIT(5)
-#define CONFIG_BUFNO_AUTO_INCR_BIT		BIT(4)
-#define CONFIG_PAGE_CNT_MASK			0xF
-#define CONFIG_PAGE_CNT_SHIFT			0
-
-/* NFC_IRQ_STATUS Field */
-#define IDLE_IRQ_BIT				BIT(29)
-#define IDLE_EN_BIT				BIT(20)
-#define CMD_DONE_CLEAR_BIT			BIT(18)
-#define IDLE_CLEAR_BIT				BIT(17)
-
-/*
- * ECC status - seems to consume 8 bytes (double word). The documented
- * status byte is located in the lowest byte of the second word (which is
- * the 4th or 7th byte depending on endianness).
- * Calculate an offset to store the ECC status at the end of the buffer.
- */
-#define ECC_SRAM_ADDR		(PAGE_2K + OOB_MAX - 8)
-
-#define ECC_STATUS		0x4
-#define ECC_STATUS_MASK		0x80
-#define ECC_STATUS_ERR_COUNT	0x3F
-
-enum vf610_nfc_alt_buf {
-	ALT_BUF_DATA = 0,
-	ALT_BUF_ID = 1,
-	ALT_BUF_STAT = 2,
-	ALT_BUF_ONFI = 3,
-};
-
-enum vf610_nfc_variant {
-	NFC_VFC610 = 1,
-};
-
-struct vf610_nfc {
-	struct nand_chip chip;
-	struct device *dev;
-	void __iomem *regs;
-	struct completion cmd_done;
-	uint buf_offset;
-	int write_sz;
-	/* Status and ID are in alternate locations. */
-	enum vf610_nfc_alt_buf alt_buf;
-	enum vf610_nfc_variant variant;
-	struct clk *clk;
-	bool use_hw_ecc;
-	u32 ecc_mode;
-};
-
-static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info *mtd)
-{
-	return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip);
-}
-
-static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
-{
-	return readl(nfc->regs + reg);
-}
-
-static inline void vf610_nfc_write(struct vf610_nfc *nfc, uint reg, u32 val)
-{
-	writel(val, nfc->regs + reg);
-}
-
-static inline void vf610_nfc_set(struct vf610_nfc *nfc, uint reg, u32 bits)
-{
-	vf610_nfc_write(nfc, reg, vf610_nfc_read(nfc, reg) | bits);
-}
-
-static inline void vf610_nfc_clear(struct vf610_nfc *nfc, uint reg, u32 bits)
-{
-	vf610_nfc_write(nfc, reg, vf610_nfc_read(nfc, reg) & ~bits);
-}
-
-static inline void vf610_nfc_set_field(struct vf610_nfc *nfc, u32 reg,
-				       u32 mask, u32 shift, u32 val)
-{
-	vf610_nfc_write(nfc, reg,
-			(vf610_nfc_read(nfc, reg) & (~mask)) | val << shift);
-}
-
-static inline void vf610_nfc_memcpy(void *dst, const void __iomem *src,
-				    size_t n)
-{
-	/*
-	 * Use this accessor for the internal SRAM buffers. On the ARM
-	 * Freescale Vybrid SoC it's known that the driver can treat
-	 * the SRAM buffer as if it's memory. Other platform might need
-	 * to treat the buffers differently.
-	 *
-	 * For the time being, use memcpy
-	 */
-	memcpy(dst, src, n);
-}
-
-/* Clear flags for upcoming command */
-static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc)
-{
-	u32 tmp = vf610_nfc_read(nfc, NFC_IRQ_STATUS);
-
-	tmp |= CMD_DONE_CLEAR_BIT | IDLE_CLEAR_BIT;
-	vf610_nfc_write(nfc, NFC_IRQ_STATUS, tmp);
-}
-
-static void vf610_nfc_done(struct vf610_nfc *nfc)
-{
-	unsigned long timeout = msecs_to_jiffies(100);
-
-	/*
-	 * Barrier is needed after this write. This write need
-	 * to be done before reading the next register the first
-	 * time.
-	 * vf610_nfc_set implicates such a barrier by using writel
-	 * to write to the register.
-	 */
-	vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT);
-	vf610_nfc_set(nfc, NFC_FLASH_CMD2, START_BIT);
-
-	if (!wait_for_completion_timeout(&nfc->cmd_done, timeout))
-		dev_warn(nfc->dev, "Timeout while waiting for BUSY.\n");
-
-	vf610_nfc_clear_status(nfc);
-}
-
-static u8 vf610_nfc_get_id(struct vf610_nfc *nfc, int col)
-{
-	u32 flash_id;
-
-	if (col < 4) {
-		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS1);
-		flash_id >>= (3 - col) * 8;
-	} else {
-		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS2);
-		flash_id >>= 24;
-	}
-
-	return flash_id & 0xff;
-}
-
-static u8 vf610_nfc_get_status(struct vf610_nfc *nfc)
-{
-	return vf610_nfc_read(nfc, NFC_FLASH_STATUS2) & STATUS_BYTE1_MASK;
-}
-
-static void vf610_nfc_send_command(struct vf610_nfc *nfc, u32 cmd_byte1,
-				   u32 cmd_code)
-{
-	u32 tmp;
-
-	vf610_nfc_clear_status(nfc);
-
-	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD2);
-	tmp &= ~(CMD_BYTE1_MASK | CMD_CODE_MASK | BUFNO_MASK);
-	tmp |= cmd_byte1 << CMD_BYTE1_SHIFT;
-	tmp |= cmd_code << CMD_CODE_SHIFT;
-	vf610_nfc_write(nfc, NFC_FLASH_CMD2, tmp);
-}
-
-static void vf610_nfc_send_commands(struct vf610_nfc *nfc, u32 cmd_byte1,
-				    u32 cmd_byte2, u32 cmd_code)
-{
-	u32 tmp;
-
-	vf610_nfc_send_command(nfc, cmd_byte1, cmd_code);
-
-	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD1);
-	tmp &= ~CMD_BYTE2_MASK;
-	tmp |= cmd_byte2 << CMD_BYTE2_SHIFT;
-	vf610_nfc_write(nfc, NFC_FLASH_CMD1, tmp);
-}
-
-static irqreturn_t vf610_nfc_irq(int irq, void *data)
-{
-	struct mtd_info *mtd = data;
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-
-	vf610_nfc_clear(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT);
-	complete(&nfc->cmd_done);
-
-	return IRQ_HANDLED;
-}
-
-static void vf610_nfc_addr_cycle(struct vf610_nfc *nfc, int column, int page)
-{
-	if (column != -1) {
-		if (nfc->chip.options & NAND_BUSWIDTH_16)
-			column = column / 2;
-		vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
-				    COL_ADDR_SHIFT, column);
-	}
-	if (page != -1)
-		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
-				    ROW_ADDR_SHIFT, page);
-}
-
-static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode)
-{
-	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
-			    CONFIG_ECC_MODE_MASK,
-			    CONFIG_ECC_MODE_SHIFT, ecc_mode);
-}
-
-static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
-{
-	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
-}
-
-static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
-			      int column, int page)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	int trfr_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
-
-	nfc->buf_offset = max(column, 0);
-	nfc->alt_buf = ALT_BUF_DATA;
-
-	switch (command) {
-	case NAND_CMD_SEQIN:
-		/* Use valid column/page from preread... */
-		vf610_nfc_addr_cycle(nfc, column, page);
-		nfc->buf_offset = 0;
-
-		/*
-		 * SEQIN => data => PAGEPROG sequence is done by the controller
-		 * hence we do not need to issue the command here...
-		 */
-		return;
-	case NAND_CMD_PAGEPROG:
-		trfr_sz += nfc->write_sz;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_SEQIN,
-					command, PROGRAM_PAGE_CMD_CODE);
-		if (nfc->use_hw_ecc)
-			vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
-		else
-			vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_RESET:
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, RESET_CMD_CODE);
-		break;
-
-	case NAND_CMD_READOOB:
-		trfr_sz += mtd->oobsize;
-		column = mtd->writesize;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
-					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_READ0:
-		trfr_sz += mtd->writesize + mtd->oobsize;
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
-					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
-		break;
-
-	case NAND_CMD_PARAM:
-		nfc->alt_buf = ALT_BUF_ONFI;
-		trfr_sz = 3 * sizeof(struct nand_onfi_params);
-		vf610_nfc_transfer_size(nfc, trfr_sz);
-		vf610_nfc_send_command(nfc, command, READ_ONFI_PARAM_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, -1, column);
-		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
-		break;
-
-	case NAND_CMD_ERASE1:
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_commands(nfc, command,
-					NAND_CMD_ERASE2, ERASE_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, column, page);
-		break;
-
-	case NAND_CMD_READID:
-		nfc->alt_buf = ALT_BUF_ID;
-		nfc->buf_offset = 0;
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, READ_ID_CMD_CODE);
-		vf610_nfc_addr_cycle(nfc, -1, column);
-		break;
-
-	case NAND_CMD_STATUS:
-		nfc->alt_buf = ALT_BUF_STAT;
-		vf610_nfc_transfer_size(nfc, 0);
-		vf610_nfc_send_command(nfc, command, STATUS_READ_CMD_CODE);
-		break;
-	default:
-		return;
-	}
-
-	vf610_nfc_done(nfc);
-
-	nfc->use_hw_ecc = false;
-	nfc->write_sz = 0;
-}
-
-static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	uint c = nfc->buf_offset;
-
-	/* Alternate buffers are only supported through read_byte */
-	WARN_ON(nfc->alt_buf);
-
-	vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
-
-	nfc->buf_offset += len;
-}
-
-static void vf610_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
-				int len)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	uint c = nfc->buf_offset;
-	uint l;
-
-	l = min_t(uint, len, mtd->writesize + mtd->oobsize - c);
-	vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
-
-	nfc->write_sz += l;
-	nfc->buf_offset += l;
-}
-
-static uint8_t vf610_nfc_read_byte(struct mtd_info *mtd)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	u8 tmp;
-	uint c = nfc->buf_offset;
-
-	switch (nfc->alt_buf) {
-	case ALT_BUF_ID:
-		tmp = vf610_nfc_get_id(nfc, c);
-		break;
-	case ALT_BUF_STAT:
-		tmp = vf610_nfc_get_status(nfc);
-		break;
-#ifdef __LITTLE_ENDIAN
-	case ALT_BUF_ONFI:
-		/* Reverse byte since the controller uses big endianness */
-		c = nfc->buf_offset ^ 0x3;
-		/* fall-through */
-#endif
-	default:
-		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
-		break;
-	}
-	nfc->buf_offset++;
-	return tmp;
-}
-
-static u16 vf610_nfc_read_word(struct mtd_info *mtd)
-{
-	u16 tmp;
-
-	vf610_nfc_read_buf(mtd, (u_char *)&tmp, sizeof(tmp));
-	return tmp;
-}
-
-/* If not provided, upper layers apply a fixed delay. */
-static int vf610_nfc_dev_ready(struct mtd_info *mtd)
-{
-	/* NFC handles R/B internally; always ready.  */
-	return 1;
-}
-
-/*
- * This function supports Vybrid only (MPC5125 would have full RB and four CS)
- */
-static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
-
-	/* Vybrid only (MPC5125 would have full RB and four CS) */
-	if (nfc->variant != NFC_VFC610)
-		return;
-
-	tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
-
-	if (chip >= 0) {
-		tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
-		tmp |= BIT(chip) << ROW_ADDR_CHIP_SEL_SHIFT;
-	}
-
-	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
-}
-
-/* Count the number of 0's in buff up to max_bits */
-static inline int count_written_bits(uint8_t *buff, int size, int max_bits)
-{
-	uint32_t *buff32 = (uint32_t *)buff;
-	int k, written_bits = 0;
-
-	for (k = 0; k < (size / 4); k++) {
-		written_bits += hweight32(~buff32[k]);
-		if (unlikely(written_bits > max_bits))
-			break;
-	}
-
-	return written_bits;
-}
-
-static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
-					 uint8_t *oob, int page)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-	u32 ecc_status_off = NFC_MAIN_AREA(0) + ECC_SRAM_ADDR + ECC_STATUS;
-	u8 ecc_status;
-	u8 ecc_count;
-	int flips_threshold = nfc->chip.ecc.strength / 2;
-
-	ecc_status = vf610_nfc_read(nfc, ecc_status_off) & 0xff;
-	ecc_count = ecc_status & ECC_STATUS_ERR_COUNT;
-
-	if (!(ecc_status & ECC_STATUS_MASK))
-		return ecc_count;
-
-	/* Read OOB without ECC unit enabled */
-	vf610_nfc_command(mtd, NAND_CMD_READOOB, 0, page);
-	vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
-
-	/*
-	 * On an erased page, bit count (including OOB) should be zero or
-	 * at least less then half of the ECC strength.
-	 */
-	return nand_check_erased_ecc_chunk(dat, nfc->chip.ecc.size, oob,
-					   mtd->oobsize, NULL, 0,
-					   flips_threshold);
-}
-
-static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
-				uint8_t *buf, int oob_required, int page)
-{
-	int eccsize = chip->ecc.size;
-	int stat;
-
-	nand_read_page_op(chip, page, 0, buf, eccsize);
-	if (oob_required)
-		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, page);
-
-	if (stat < 0) {
-		mtd->ecc_stats.failed++;
-		return 0;
-	} else {
-		mtd->ecc_stats.corrected += stat;
-		return stat;
-	}
-}
-
-static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-				const uint8_t *buf, int oob_required, int page)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-
-	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
-	if (oob_required)
-		vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-	/* Always write whole page including OOB due to HW ECC */
-	nfc->use_hw_ecc = true;
-	nfc->write_sz = mtd->writesize + mtd->oobsize;
-
-	return nand_prog_page_end_op(chip);
-}
-
-static const struct of_device_id vf610_nfc_dt_ids[] = {
-	{ .compatible = "fsl,vf610-nfc", .data = (void *)NFC_VFC610 },
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, vf610_nfc_dt_ids);
-
-static void vf610_nfc_preinit_controller(struct vf610_nfc *nfc)
-{
-	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
-	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT);
-	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BUFNO_AUTO_INCR_BIT);
-	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BOOT_MODE_BIT);
-	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT);
-	vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT);
-
-	/* Disable virtual pages, only one elementary transfer unit */
-	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK,
-			    CONFIG_PAGE_CNT_SHIFT, 1);
-}
-
-static void vf610_nfc_init_controller(struct vf610_nfc *nfc)
-{
-	if (nfc->chip.options & NAND_BUSWIDTH_16)
-		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
-	else
-		vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
-
-	if (nfc->chip.ecc.mode == NAND_ECC_HW) {
-		/* Set ECC status offset in SRAM */
-		vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
-				    CONFIG_ECC_SRAM_ADDR_MASK,
-				    CONFIG_ECC_SRAM_ADDR_SHIFT,
-				    ECC_SRAM_ADDR >> 3);
-
-		/* Enable ECC status in SRAM */
-		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
-	}
-}
-
-static int vf610_nfc_probe(struct platform_device *pdev)
-{
-	struct vf610_nfc *nfc;
-	struct resource *res;
-	struct mtd_info *mtd;
-	struct nand_chip *chip;
-	struct device_node *child;
-	const struct of_device_id *of_id;
-	int err;
-	int irq;
-
-	nfc = devm_kzalloc(&pdev->dev, sizeof(*nfc), GFP_KERNEL);
-	if (!nfc)
-		return -ENOMEM;
-
-	nfc->dev = &pdev->dev;
-	chip = &nfc->chip;
-	mtd = nand_to_mtd(chip);
-
-	mtd->owner = THIS_MODULE;
-	mtd->dev.parent = nfc->dev;
-	mtd->name = DRV_NAME;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq <= 0)
-		return -EINVAL;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	nfc->regs = devm_ioremap_resource(nfc->dev, res);
-	if (IS_ERR(nfc->regs))
-		return PTR_ERR(nfc->regs);
-
-	nfc->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(nfc->clk))
-		return PTR_ERR(nfc->clk);
-
-	err = clk_prepare_enable(nfc->clk);
-	if (err) {
-		dev_err(nfc->dev, "Unable to enable clock!\n");
-		return err;
-	}
-
-	of_id = of_match_device(vf610_nfc_dt_ids, &pdev->dev);
-	nfc->variant = (enum vf610_nfc_variant)of_id->data;
-
-	for_each_available_child_of_node(nfc->dev->of_node, child) {
-		if (of_device_is_compatible(child, "fsl,vf610-nfc-nandcs")) {
-
-			if (nand_get_flash_node(chip)) {
-				dev_err(nfc->dev,
-					"Only one NAND chip supported!\n");
-				err = -EINVAL;
-				goto error;
-			}
-
-			nand_set_flash_node(chip, child);
-		}
-	}
-
-	if (!nand_get_flash_node(chip)) {
-		dev_err(nfc->dev, "NAND chip sub-node missing!\n");
-		err = -ENODEV;
-		goto err_clk;
-	}
-
-	chip->dev_ready = vf610_nfc_dev_ready;
-	chip->cmdfunc = vf610_nfc_command;
-	chip->read_byte = vf610_nfc_read_byte;
-	chip->read_word = vf610_nfc_read_word;
-	chip->read_buf = vf610_nfc_read_buf;
-	chip->write_buf = vf610_nfc_write_buf;
-	chip->select_chip = vf610_nfc_select_chip;
-	chip->onfi_set_features = nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features = nand_onfi_get_set_features_notsupp;
-
-	chip->options |= NAND_NO_SUBPAGE_WRITE;
-
-	init_completion(&nfc->cmd_done);
-
-	err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
-	if (err) {
-		dev_err(nfc->dev, "Error requesting IRQ!\n");
-		goto error;
-	}
-
-	vf610_nfc_preinit_controller(nfc);
-
-	/* first scan to find the device and get the page size */
-	err = nand_scan_ident(mtd, 1, NULL);
-	if (err)
-		goto error;
-
-	vf610_nfc_init_controller(nfc);
-
-	/* Bad block options. */
-	if (chip->bbt_options & NAND_BBT_USE_FLASH)
-		chip->bbt_options |= NAND_BBT_NO_OOB;
-
-	/* Single buffer only, max 256 OOB minus ECC status */
-	if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
-		dev_err(nfc->dev, "Unsupported flash page size\n");
-		err = -ENXIO;
-		goto error;
-	}
-
-	if (chip->ecc.mode == NAND_ECC_HW) {
-		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
-			dev_err(nfc->dev, "Unsupported flash with hwecc\n");
-			err = -ENXIO;
-			goto error;
-		}
-
-		if (chip->ecc.size != mtd->writesize) {
-			dev_err(nfc->dev, "Step size needs to be page size\n");
-			err = -ENXIO;
-			goto error;
-		}
-
-		/* Only 64 byte ECC layouts known */
-		if (mtd->oobsize > 64)
-			mtd->oobsize = 64;
-
-		/* Use default large page ECC layout defined in NAND core */
-		mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
-		if (chip->ecc.strength == 32) {
-			nfc->ecc_mode = ECC_60_BYTE;
-			chip->ecc.bytes = 60;
-		} else if (chip->ecc.strength == 24) {
-			nfc->ecc_mode = ECC_45_BYTE;
-			chip->ecc.bytes = 45;
-		} else {
-			dev_err(nfc->dev, "Unsupported ECC strength\n");
-			err = -ENXIO;
-			goto error;
-		}
-
-		chip->ecc.read_page = vf610_nfc_read_page;
-		chip->ecc.write_page = vf610_nfc_write_page;
-
-		chip->ecc.size = PAGE_2K;
-	}
-
-	/* second phase scan */
-	err = nand_scan_tail(mtd);
-	if (err)
-		goto error;
-
-	platform_set_drvdata(pdev, mtd);
-
-	/* Register device in MTD */
-	return mtd_device_register(mtd, NULL, 0);
-
-error:
-	of_node_put(nand_get_flash_node(chip));
-err_clk:
-	clk_disable_unprepare(nfc->clk);
-	return err;
-}
-
-static int vf610_nfc_remove(struct platform_device *pdev)
-{
-	struct mtd_info *mtd = platform_get_drvdata(pdev);
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-
-	nand_release(mtd);
-	clk_disable_unprepare(nfc->clk);
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int vf610_nfc_suspend(struct device *dev)
-{
-	struct mtd_info *mtd = dev_get_drvdata(dev);
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-
-	clk_disable_unprepare(nfc->clk);
-	return 0;
-}
-
-static int vf610_nfc_resume(struct device *dev)
-{
-	int err;
-
-	struct mtd_info *mtd = dev_get_drvdata(dev);
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-
-	err = clk_prepare_enable(nfc->clk);
-	if (err)
-		return err;
-
-	vf610_nfc_preinit_controller(nfc);
-	vf610_nfc_init_controller(nfc);
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(vf610_nfc_pm_ops, vf610_nfc_suspend, vf610_nfc_resume);
-
-static struct platform_driver vf610_nfc_driver = {
-	.driver		= {
-		.name	= DRV_NAME,
-		.of_match_table = vf610_nfc_dt_ids,
-		.pm	= &vf610_nfc_pm_ops,
-	},
-	.probe		= vf610_nfc_probe,
-	.remove		= vf610_nfc_remove,
-};
-
-module_platform_driver(vf610_nfc_driver);
-
-MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>");
-MODULE_DESCRIPTION("Freescale VF610/MPC5125 NFC MTD NAND driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 184c8fb..a6fbfa4 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -122,8 +122,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
 		if (memcmp(buf, "ANAND", 6)) {
 			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n",
 			       block * nftl->EraseSize, nftl->mbd.mtd->index);
-			printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n",
-			       buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+			printk(KERN_NOTICE "New data are: %6ph\n", buf);
 			continue;
 		}
 #endif
@@ -328,12 +327,9 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
 	memset(instr, 0, sizeof(struct erase_info));
 
 	/* XXX: use async erase interface, XXX: test return code */
-	instr->mtd = nftl->mbd.mtd;
 	instr->addr = block * nftl->EraseSize;
 	instr->len = nftl->EraseSize;
-	mtd_erase(mtd, instr);
-
-	if (instr->state == MTD_ERASE_FAILED) {
+	if (mtd_erase(mtd, instr)) {
 		printk("Error while formatting block %d\n", block);
 		goto fail;
 	}
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 6bdf4e5..615f8c1 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -25,9 +25,9 @@ static bool node_has_compatible(struct device_node *pp)
 	return of_get_property(pp, "compatible", NULL);
 }
 
-static int parse_ofpart_partitions(struct mtd_info *master,
-				   const struct mtd_partition **pparts,
-				   struct mtd_part_parser_data *data)
+static int parse_fixed_partitions(struct mtd_info *master,
+				  const struct mtd_partition **pparts,
+				  struct mtd_part_parser_data *data)
 {
 	struct mtd_partition *parts;
 	struct device_node *mtd_node;
@@ -140,9 +140,16 @@ static int parse_ofpart_partitions(struct mtd_info *master,
 	return ret;
 }
 
+static const struct of_device_id parse_ofpart_match_table[] = {
+	{ .compatible = "fixed-partitions" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+
 static struct mtd_part_parser ofpart_parser = {
-	.parse_fn = parse_ofpart_partitions,
-	.name = "ofpart",
+	.parse_fn = parse_fixed_partitions,
+	.name = "fixed-partitions",
+	.of_match_table = parse_ofpart_match_table,
 };
 
 static int parse_ofoldpart_partitions(struct mtd_info *master,
@@ -229,4 +236,5 @@ MODULE_AUTHOR("Vitaly Wool, David Gibson");
  * with the same name. Since we provide the ofoldpart parser, we should have
  * the corresponding alias.
  */
+MODULE_ALIAS("fixed-partitions");
 MODULE_ALIAS("ofoldpart");
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index d1cbf26..df27f24 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -266,91 +266,54 @@ static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *b
 	return 0;
 }
 
-static void erase_callback(struct erase_info *erase)
-{
-	struct partition *part;
-	u16 magic;
-	int i, rc;
-	size_t retlen;
-
-	part = (struct partition*)erase->priv;
-
-	i = (u32)erase->addr / part->block_size;
-	if (i >= part->total_blocks || part->blocks[i].offset != erase->addr ||
-	    erase->addr > UINT_MAX) {
-		printk(KERN_ERR PREFIX "erase callback for unknown offset %llx "
-				"on '%s'\n", (unsigned long long)erase->addr, part->mbd.mtd->name);
-		return;
-	}
-
-	if (erase->state != MTD_ERASE_DONE) {
-		printk(KERN_WARNING PREFIX "erase failed at 0x%llx on '%s', "
-				"state %d\n", (unsigned long long)erase->addr,
-				part->mbd.mtd->name, erase->state);
-
-		part->blocks[i].state = BLOCK_FAILED;
-		part->blocks[i].free_sectors = 0;
-		part->blocks[i].used_sectors = 0;
-
-		kfree(erase);
-
-		return;
-	}
-
-	magic = cpu_to_le16(RFD_MAGIC);
-
-	part->blocks[i].state = BLOCK_ERASED;
-	part->blocks[i].free_sectors = part->data_sectors_per_block;
-	part->blocks[i].used_sectors = 0;
-	part->blocks[i].erases++;
-
-	rc = mtd_write(part->mbd.mtd, part->blocks[i].offset, sizeof(magic),
-		       &retlen, (u_char *)&magic);
-
-	if (!rc && retlen != sizeof(magic))
-		rc = -EIO;
-
-	if (rc) {
-		printk(KERN_ERR PREFIX "'%s': unable to write RFD "
-				"header at 0x%lx\n",
-				part->mbd.mtd->name,
-				part->blocks[i].offset);
-		part->blocks[i].state = BLOCK_FAILED;
-	}
-	else
-		part->blocks[i].state = BLOCK_OK;
-
-	kfree(erase);
-}
-
 static int erase_block(struct partition *part, int block)
 {
 	struct erase_info *erase;
-	int rc = -ENOMEM;
+	int rc;
 
 	erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
 	if (!erase)
-		goto err;
+		return -ENOMEM;
 
-	erase->mtd = part->mbd.mtd;
-	erase->callback = erase_callback;
 	erase->addr = part->blocks[block].offset;
 	erase->len = part->block_size;
-	erase->priv = (u_long)part;
 
 	part->blocks[block].state = BLOCK_ERASING;
 	part->blocks[block].free_sectors = 0;
 
 	rc = mtd_erase(part->mbd.mtd, erase);
-
 	if (rc) {
 		printk(KERN_ERR PREFIX "erase of region %llx,%llx on '%s' "
 				"failed\n", (unsigned long long)erase->addr,
 				(unsigned long long)erase->len, part->mbd.mtd->name);
-		kfree(erase);
+		part->blocks[block].state = BLOCK_FAILED;
+		part->blocks[block].free_sectors = 0;
+		part->blocks[block].used_sectors = 0;
+	} else {
+		u16 magic = cpu_to_le16(RFD_MAGIC);
+		size_t retlen;
+
+		part->blocks[block].state = BLOCK_ERASED;
+		part->blocks[block].free_sectors = part->data_sectors_per_block;
+		part->blocks[block].used_sectors = 0;
+		part->blocks[block].erases++;
+
+		rc = mtd_write(part->mbd.mtd, part->blocks[block].offset,
+			       sizeof(magic), &retlen, (u_char *)&magic);
+		if (!rc && retlen != sizeof(magic))
+			rc = -EIO;
+
+		if (rc) {
+			pr_err(PREFIX "'%s': unable to write RFD header at 0x%lx\n",
+			       part->mbd.mtd->name, part->blocks[block].offset);
+			part->blocks[block].state = BLOCK_FAILED;
+		} else {
+			part->blocks[block].state = BLOCK_OK;
+		}
 	}
 
-err:
+	kfree(erase);
+
 	return rc;
 }
 
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
index 4237c7c..7963634 100644
--- a/drivers/mtd/sm_ftl.c
+++ b/drivers/mtd/sm_ftl.c
@@ -17,7 +17,7 @@
 #include <linux/bitops.h>
 #include <linux/slab.h>
 #include <linux/mtd/nand_ecc.h>
-#include "nand/sm_common.h"
+#include "nand/raw/sm_common.h"
 #include "sm_ftl.h"
 
 
@@ -460,11 +460,8 @@ static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
 	struct mtd_info *mtd = ftl->trans->mtd;
 	struct erase_info erase;
 
-	erase.mtd = mtd;
-	erase.callback = sm_erase_callback;
 	erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
 	erase.len = ftl->block_size;
-	erase.priv = (u_long)ftl;
 
 	if (ftl->unstable)
 		return -EIO;
@@ -482,15 +479,6 @@ static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
 		goto error;
 	}
 
-	if (erase.state == MTD_ERASE_PENDING)
-		wait_for_completion(&ftl->erase_completion);
-
-	if (erase.state != MTD_ERASE_DONE) {
-		sm_printk("erase of block %d in zone %d failed after wait",
-			block, zone_num);
-		goto error;
-	}
-
 	if (put_free)
 		kfifo_in(&zone->free_sectors,
 			(const unsigned char *)&block, sizeof(block));
@@ -501,12 +489,6 @@ static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
 	return -EIO;
 }
 
-static void sm_erase_callback(struct erase_info *self)
-{
-	struct sm_ftl *ftl = (struct sm_ftl *)self->priv;
-	complete(&ftl->erase_completion);
-}
-
 /* Thoroughly test that block is valid. */
 static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
 {
@@ -1141,7 +1123,6 @@ static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 	mutex_init(&ftl->mutex);
 	timer_setup(&ftl->timer, sm_cache_flush_timer, 0);
 	INIT_WORK(&ftl->flush_work, sm_cache_flush_work);
-	init_completion(&ftl->erase_completion);
 
 	/* Read media information */
 	if (sm_get_media_info(ftl, mtd)) {
diff --git a/drivers/mtd/sm_ftl.h b/drivers/mtd/sm_ftl.h
index 43bb730..0a46d75 100644
--- a/drivers/mtd/sm_ftl.h
+++ b/drivers/mtd/sm_ftl.h
@@ -53,9 +53,6 @@ struct sm_ftl {
 	struct work_struct flush_work;
 	struct timer_list timer;
 
-	/* Async erase stuff */
-	struct completion erase_completion;
-
 	/* Geometry stuff */
 	int heads;
 	int sectors;
@@ -86,7 +83,6 @@ struct chs_entry {
 		printk(KERN_DEBUG "sm_ftl" ": " format "\n", ## __VA_ARGS__)
 
 
-static void sm_erase_callback(struct erase_info *self);
 static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
 								int put_free);
 static void sm_mark_block_bad(struct sm_ftl *ftl, int zone_num, int block);
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2901c7b..3e3c0bb 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -1051,6 +1051,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		spi_nor_set_flash_node(nor, np);
 		nor->priv = q;
 
+		if (q->nor_num > 1 && !mtd->name) {
+			int spiflash_idx;
+
+			ret = of_property_read_u32(np, "reg", &spiflash_idx);
+			if (!ret) {
+				mtd->name = devm_kasprintf(dev, GFP_KERNEL,
+							   "%s-%d",
+							   dev_name(dev),
+							   spiflash_idx);
+				if (!mtd->name) {
+					ret = -ENOMEM;
+					goto mutex_failed;
+				}
+			} else {
+				dev_warn(dev, "reg property is missing\n");
+			}
+		}
+
 		/* fill the hooks */
 		nor->read_reg = fsl_qspi_read_reg;
 		nor->write_reg = fsl_qspi_write_reg;
@@ -1174,7 +1192,6 @@ static int fsl_qspi_resume(struct platform_device *pdev)
 static struct platform_driver fsl_qspi_driver = {
 	.driver = {
 		.name	= "fsl-quadspi",
-		.bus	= &platform_bus_type,
 		.of_match_table = fsl_qspi_dt_ids,
 	},
 	.probe          = fsl_qspi_probe,
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index d445a4d..5bfa36e 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -560,9 +560,6 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 erase_err:
 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
 
-	instr->state = ret ? MTD_ERASE_FAILED : MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
 	return ret;
 }
 
diff --git a/drivers/mtd/tests/mtd_test.c b/drivers/mtd/tests/mtd_test.c
index 3d0b8b5..c84250b 100644
--- a/drivers/mtd/tests/mtd_test.c
+++ b/drivers/mtd/tests/mtd_test.c
@@ -14,7 +14,6 @@ int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum)
 	loff_t addr = (loff_t)ebnum * mtd->erasesize;
 
 	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
 	ei.addr = addr;
 	ei.len  = mtd->erasesize;
 
@@ -24,10 +23,6 @@ int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum)
 		return err;
 	}
 
-	if (ei.state == MTD_ERASE_FAILED) {
-		pr_info("some erase error occurred at EB %d\n", ebnum);
-		return -EIO;
-	}
 	return 0;
 }
 
diff --git a/drivers/mtd/tests/pagetest.c b/drivers/mtd/tests/pagetest.c
index ff1e056..bc303ca 100644
--- a/drivers/mtd/tests/pagetest.c
+++ b/drivers/mtd/tests/pagetest.c
@@ -435,9 +435,13 @@ static int __init mtd_pagetest_init(void)
 	if (err)
 		goto out;
 
-	err = erasecrosstest();
-	if (err)
-		goto out;
+	if (ebcnt > 1) {
+		err = erasecrosstest();
+		if (err)
+			goto out;
+	} else {
+		pr_info("skipping erasecrosstest, 2 erase blocks needed\n");
+	}
 
 	err = erasetest();
 	if (err)
diff --git a/drivers/mtd/tests/speedtest.c b/drivers/mtd/tests/speedtest.c
index 0b89418..20edb3b 100644
--- a/drivers/mtd/tests/speedtest.c
+++ b/drivers/mtd/tests/speedtest.c
@@ -59,7 +59,6 @@ static int multiblock_erase(int ebnum, int blocks)
 	loff_t addr = (loff_t)ebnum * mtd->erasesize;
 
 	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
 	ei.addr = addr;
 	ei.len  = mtd->erasesize * blocks;
 
@@ -70,12 +69,6 @@ static int multiblock_erase(int ebnum, int blocks)
 		return err;
 	}
 
-	if (ei.state == MTD_ERASE_FAILED) {
-		pr_err("some erase error occurred at EB %d,"
-		       "blocks %d\n", ebnum, blocks);
-		return -EIO;
-	}
-
 	return 0;
 }
 
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c
index 1cb287e..6b655a5 100644
--- a/drivers/mtd/ubi/gluebi.c
+++ b/drivers/mtd/ubi/gluebi.c
@@ -272,12 +272,9 @@ static int gluebi_erase(struct mtd_info *mtd, struct erase_info *instr)
 	if (err)
 		goto out_err;
 
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
 	return 0;
 
 out_err:
-	instr->state = MTD_ERASE_FAILED;
 	instr->fail_addr = (long long)lnum * mtd->erasesize;
 	return err;
 }
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 8290432..0e3a76a 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -309,18 +309,6 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
 }
 
 /**
- * erase_callback - MTD erasure call-back.
- * @ei: MTD erase information object.
- *
- * Note, even though MTD erase interface is asynchronous, all the current
- * implementations are synchronous anyway.
- */
-static void erase_callback(struct erase_info *ei)
-{
-	wake_up_interruptible((wait_queue_head_t *)ei->priv);
-}
-
-/**
  * do_sync_erase - synchronously erase a physical eraseblock.
  * @ubi: UBI device description object
  * @pnum: the physical eraseblock number to erase
@@ -333,7 +321,6 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum)
 {
 	int err, retries = 0;
 	struct erase_info ei;
-	wait_queue_head_t wq;
 
 	dbg_io("erase PEB %d", pnum);
 	ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
@@ -344,14 +331,10 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum)
 	}
 
 retry:
-	init_waitqueue_head(&wq);
 	memset(&ei, 0, sizeof(struct erase_info));
 
-	ei.mtd      = ubi->mtd;
 	ei.addr     = (loff_t)pnum * ubi->peb_size;
 	ei.len      = ubi->peb_size;
-	ei.callback = erase_callback;
-	ei.priv     = (unsigned long)&wq;
 
 	err = mtd_erase(ubi->mtd, &ei);
 	if (err) {
@@ -366,25 +349,6 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum)
 		return err;
 	}
 
-	err = wait_event_interruptible(wq, ei.state == MTD_ERASE_DONE ||
-					   ei.state == MTD_ERASE_FAILED);
-	if (err) {
-		ubi_err(ubi, "interrupted PEB %d erasure", pnum);
-		return -EINTR;
-	}
-
-	if (ei.state == MTD_ERASE_FAILED) {
-		if (retries++ < UBI_IO_RETRIES) {
-			ubi_warn(ubi, "error while erasing PEB %d, retry",
-				 pnum);
-			yield();
-			goto retry;
-		}
-		ubi_err(ubi, "cannot erase PEB %d", pnum);
-		dump_stack();
-		return -EIO;
-	}
-
 	err = ubi_self_check_all_ff(ubi, pnum, 0, ubi->peb_size);
 	if (err)
 		return err;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
index 3dd9734..0ea141e 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
@@ -603,7 +603,7 @@ static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section)
 
 static int
 netxen_nic_validate_header(struct netxen_adapter *adapter)
- {
+{
 	const u8 *unirom = adapter->fw->data;
 	struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
 	u32 fw_file_size = adapter->fw->size;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c
index d3eabcf..af3a28e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -321,7 +321,7 @@ static int qed_pglub_rbc_attn_cb(struct qed_hwfn *p_hwfn)
 	tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
 		     PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL);
 	if (tmp & PGLUE_ATTENTION_ICPL_VALID)
-		DP_INFO(p_hwfn, "ICPL eror - %08x\n", tmp);
+		DP_INFO(p_hwfn, "ICPL error - %08x\n", tmp);
 
 	tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
 		     PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS);
diff --git a/drivers/net/ethernet/sfc/falcon/mtd.c b/drivers/net/ethernet/sfc/falcon/mtd.c
index cde593c..2d67e46 100644
--- a/drivers/net/ethernet/sfc/falcon/mtd.c
+++ b/drivers/net/ethernet/sfc/falcon/mtd.c
@@ -24,17 +24,8 @@
 static int ef4_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
 {
 	struct ef4_nic *efx = mtd->priv;
-	int rc;
 
-	rc = efx->type->mtd_erase(mtd, erase->addr, erase->len);
-	if (rc == 0) {
-		erase->state = MTD_ERASE_DONE;
-	} else {
-		erase->state = MTD_ERASE_FAILED;
-		erase->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
-	}
-	mtd_erase_callback(erase);
-	return rc;
+	return efx->type->mtd_erase(mtd, erase->addr, erase->len);
 }
 
 static void ef4_mtd_sync(struct mtd_info *mtd)
diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c
index a77a8bd..4ac30b6 100644
--- a/drivers/net/ethernet/sfc/mtd.c
+++ b/drivers/net/ethernet/sfc/mtd.c
@@ -24,17 +24,8 @@
 static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
 {
 	struct efx_nic *efx = mtd->priv;
-	int rc;
 
-	rc = efx->type->mtd_erase(mtd, erase->addr, erase->len);
-	if (rc == 0) {
-		erase->state = MTD_ERASE_DONE;
-	} else {
-		erase->state = MTD_ERASE_FAILED;
-		erase->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
-	}
-	mtd_erase_callback(erase);
-	return rc;
+	return efx->type->mtd_erase(mtd, erase->addr, erase->len);
 }
 
 static void efx_mtd_sync(struct mtd_info *mtd)
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c
index 5a4e78f..c769cd9 100644
--- a/drivers/net/ethernet/ti/tlan.c
+++ b/drivers/net/ethernet/ti/tlan.c
@@ -1901,7 +1901,7 @@ ThunderLAN driver adapter related routines
  *		Nothing
  *	Parms:
  *		dev	The device structure with the list
- *			stuctures to be reset.
+ *			structures to be reset.
  *
  *	This routine sets the variables associated with managing
  *	the TLAN lists to their initial values.
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index d8b041f..7fdb152 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -252,7 +252,7 @@ ath_tid_pull(struct ath_atx_tid *tid)
 	}
 
 	return skb;
- }
+}
 
 
 static bool ath_tid_has_buffered(struct ath_atx_tid *tid)
diff --git a/drivers/net/wireless/atmel/atmel.c b/drivers/net/wireless/atmel/atmel.c
index c9dd5e4..d122386 100644
--- a/drivers/net/wireless/atmel/atmel.c
+++ b/drivers/net/wireless/atmel/atmel.c
@@ -3861,7 +3861,7 @@ static int reset_atmel_card(struct net_device *dev)
 
 	   set all the Mib values which matter in the card to match
 	   their settings in the atmel_private structure. Some of these
-	   can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
+	   can be altered on the fly, but many (WEP, infrastructure or ad-hoc)
 	   can only be changed by tearing down the world and coming back through
 	   here.
 
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index 7806a4d..718a73c 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -4431,7 +4431,7 @@ void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
 			timeout = page_thresh;
 		else if (rtl8xxxu_dma_agg_pages <= 6)
 			dev_err(&priv->udev->dev,
-				"%s: dma_agg_pages=%i too small, minium is 6\n",
+				"%s: dma_agg_pages=%i too small, minimum is 6\n",
 				__func__, rtl8xxxu_dma_agg_pages);
 		else
 			dev_err(&priv->udev->dev,
diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c
index 1bd7b37..62e9cb16 100644
--- a/drivers/nvdimm/blk.c
+++ b/drivers/nvdimm/blk.c
@@ -266,7 +266,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
 	blk_queue_make_request(q, nd_blk_make_request);
 	blk_queue_max_hw_sectors(q, UINT_MAX);
 	blk_queue_logical_block_size(q, nsblk_sector_size(nsblk));
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
 	q->queuedata = nsblk;
 
 	disk = alloc_disk(0);
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 4b95ac5..85de805 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -1542,7 +1542,7 @@ static int btt_blk_init(struct btt *btt)
 	blk_queue_make_request(btt->btt_queue, btt_make_request);
 	blk_queue_logical_block_size(btt->btt_queue, btt->sector_size);
 	blk_queue_max_hw_sectors(btt->btt_queue, UINT_MAX);
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, btt->btt_queue);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, btt->btt_queue);
 	btt->btt_queue->queuedata = btt;
 
 	if (btt_meta_size(btt)) {
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 8d6375e..184e070 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -29,7 +29,6 @@ enum {
 	 * BTT instance
 	 */
 	ND_MAX_LANES = 256,
-	SECTOR_SHIFT = 9,
 	INT_LBASIZE_ALIGNMENT = 64,
 	NVDIMM_IO_ATOMIC = 1,
 };
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 06f8dcc..5a96d30 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -343,7 +343,7 @@ static int pmem_attach_disk(struct device *dev,
 		return -EBUSY;
 	}
 
-	q = blk_alloc_queue_node(GFP_KERNEL, dev_to_node(dev));
+	q = blk_alloc_queue_node(GFP_KERNEL, dev_to_node(dev), NULL);
 	if (!q)
 		return -ENOMEM;
 
@@ -387,8 +387,8 @@ static int pmem_attach_disk(struct device *dev,
 	blk_queue_physical_block_size(q, PAGE_SIZE);
 	blk_queue_logical_block_size(q, pmem_sector_size(ndns));
 	blk_queue_max_hw_sectors(q, UINT_MAX);
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
-	queue_flag_set_unlocked(QUEUE_FLAG_DAX, q);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
+	blk_queue_flag_set(QUEUE_FLAG_DAX, q);
 	q->queuedata = pmem;
 
 	disk = alloc_disk_node(0, nid);
diff --git a/drivers/nvme/host/Makefile b/drivers/nvme/host/Makefile
index 441e67e..aea459c 100644
--- a/drivers/nvme/host/Makefile
+++ b/drivers/nvme/host/Makefile
@@ -12,6 +12,7 @@
 nvme-core-$(CONFIG_TRACING)		+= trace.o
 nvme-core-$(CONFIG_NVME_MULTIPATH)	+= multipath.o
 nvme-core-$(CONFIG_NVM)			+= lightnvm.o
+nvme-core-$(CONFIG_FAULT_INJECTION_DEBUG_FS)	+= fault_inject.o
 
 nvme-y					+= pci.o
 
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 7aeca5d..197a6ba 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -100,11 +100,6 @@ static struct class *nvme_subsys_class;
 static void nvme_ns_remove(struct nvme_ns *ns);
 static int nvme_revalidate_disk(struct gendisk *disk);
 
-static __le32 nvme_get_log_dw10(u8 lid, size_t size)
-{
-	return cpu_to_le32((((size / 4) - 1) << 16) | lid);
-}
-
 int nvme_reset_ctrl(struct nvme_ctrl *ctrl)
 {
 	if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING))
@@ -135,6 +130,9 @@ static void nvme_delete_ctrl_work(struct work_struct *work)
 	struct nvme_ctrl *ctrl =
 		container_of(work, struct nvme_ctrl, delete_work);
 
+	dev_info(ctrl->device,
+		 "Removing ctrl: NQN \"%s\"\n", ctrl->opts->subsysnqn);
+
 	flush_work(&ctrl->reset_work);
 	nvme_stop_ctrl(ctrl);
 	nvme_remove_namespaces(ctrl);
@@ -948,7 +946,8 @@ static int nvme_identify_ns_list(struct nvme_ctrl *dev, unsigned nsid, __le32 *n
 	c.identify.opcode = nvme_admin_identify;
 	c.identify.cns = NVME_ID_CNS_NS_ACTIVE_LIST;
 	c.identify.nsid = cpu_to_le32(nsid);
-	return nvme_submit_sync_cmd(dev->admin_q, &c, ns_list, 0x1000);
+	return nvme_submit_sync_cmd(dev->admin_q, &c, ns_list,
+				    NVME_IDENTIFY_DATA_SIZE);
 }
 
 static struct nvme_id_ns *nvme_identify_ns(struct nvme_ctrl *ctrl,
@@ -1124,13 +1123,13 @@ static void nvme_update_formats(struct nvme_ctrl *ctrl)
 	struct nvme_ns *ns, *next;
 	LIST_HEAD(rm_list);
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_write(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list) {
 		if (ns->disk && nvme_revalidate_disk(ns->disk)) {
 			list_move_tail(&ns->list, &rm_list);
 		}
 	}
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_write(&ctrl->namespaces_rwsem);
 
 	list_for_each_entry_safe(ns, next, &rm_list, list)
 		nvme_ns_remove(ns);
@@ -1358,7 +1357,7 @@ static void nvme_config_discard(struct nvme_ctrl *ctrl,
 
 	blk_queue_max_discard_sectors(queue, UINT_MAX);
 	blk_queue_max_discard_segments(queue, NVME_DSM_MAX_RANGES);
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, queue);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, queue);
 
 	if (ctrl->quirks & NVME_QUIRK_DEALLOCATE_ZEROES)
 		blk_queue_max_write_zeroes_sectors(queue, UINT_MAX);
@@ -1449,6 +1448,8 @@ static void __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)
 	if (ns->noiob)
 		nvme_set_chunk_size(ns);
 	nvme_update_disk_info(disk, ns, id);
+	if (ns->ndev)
+		nvme_nvm_update_nvm_info(ns);
 #ifdef CONFIG_NVME_MULTIPATH
 	if (ns->head->disk)
 		nvme_update_disk_info(ns->head->disk, ns, id);
@@ -2217,16 +2218,33 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
 	return ret;
 }
 
+int nvme_get_log_ext(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+		     u8 log_page, void *log,
+		     size_t size, size_t offset)
+{
+	struct nvme_command c = { };
+	unsigned long dwlen = size / 4 - 1;
+
+	c.get_log_page.opcode = nvme_admin_get_log_page;
+
+	if (ns)
+		c.get_log_page.nsid = cpu_to_le32(ns->head->ns_id);
+	else
+		c.get_log_page.nsid = cpu_to_le32(NVME_NSID_ALL);
+
+	c.get_log_page.lid = log_page;
+	c.get_log_page.numdl = cpu_to_le16(dwlen & ((1 << 16) - 1));
+	c.get_log_page.numdu = cpu_to_le16(dwlen >> 16);
+	c.get_log_page.lpol = cpu_to_le32(offset & ((1ULL << 32) - 1));
+	c.get_log_page.lpou = cpu_to_le32(offset >> 32ULL);
+
+	return nvme_submit_sync_cmd(ctrl->admin_q, &c, log, size);
+}
+
 static int nvme_get_log(struct nvme_ctrl *ctrl, u8 log_page, void *log,
 			size_t size)
 {
-	struct nvme_command c = { };
-
-	c.common.opcode = nvme_admin_get_log_page;
-	c.common.nsid = cpu_to_le32(NVME_NSID_ALL);
-	c.common.cdw10[0] = nvme_get_log_dw10(log_page, size);
-
-	return nvme_submit_sync_cmd(ctrl->admin_q, &c, log, size);
+	return nvme_get_log_ext(ctrl, NULL, log_page, log, size, 0);
 }
 
 static int nvme_get_effects_log(struct nvme_ctrl *ctrl)
@@ -2440,7 +2458,7 @@ static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp)
 	struct nvme_ns *ns;
 	int ret;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	if (list_empty(&ctrl->namespaces)) {
 		ret = -ENOTTY;
 		goto out_unlock;
@@ -2457,14 +2475,14 @@ static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp)
 	dev_warn(ctrl->device,
 		"using deprecated NVME_IOCTL_IO_CMD ioctl on the char device!\n");
 	kref_get(&ns->kref);
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 
 	ret = nvme_user_cmd(ctrl, ns, argp);
 	nvme_put_ns(ns);
 	return ret;
 
 out_unlock:
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 	return ret;
 }
 
@@ -2793,6 +2811,7 @@ static int __nvme_check_ids(struct nvme_subsystem *subsys,
 
 	list_for_each_entry(h, &subsys->nsheads, entry) {
 		if (nvme_ns_ids_valid(&new->ids) &&
+		    !list_empty(&h->list) &&
 		    nvme_ns_ids_equal(&new->ids, &h->ids))
 			return -EINVAL;
 	}
@@ -2893,7 +2912,7 @@ static struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 {
 	struct nvme_ns *ns, *ret = NULL;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list) {
 		if (ns->head->ns_id == nsid) {
 			if (!kref_get_unless_zero(&ns->kref))
@@ -2904,7 +2923,7 @@ static struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 		if (ns->head->ns_id > nsid)
 			break;
 	}
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 	return ret;
 }
 
@@ -2949,7 +2968,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 	ns->queue = blk_mq_init_queue(ctrl->tagset);
 	if (IS_ERR(ns->queue))
 		goto out_free_ns;
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, ns->queue);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, ns->queue);
 	ns->queue->queuedata = ns;
 	ns->ctrl = ctrl;
 
@@ -3015,9 +3034,9 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 
 	__nvme_revalidate_disk(disk, id);
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_write(&ctrl->namespaces_rwsem);
 	list_add_tail(&ns->list, &ctrl->namespaces);
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_write(&ctrl->namespaces_rwsem);
 
 	nvme_get_ctrl(ctrl);
 
@@ -3033,6 +3052,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 			ns->disk->disk_name);
 
 	nvme_mpath_add_disk(ns->head);
+	nvme_fault_inject_init(ns);
 	return;
  out_unlink_ns:
 	mutex_lock(&ctrl->subsys->lock);
@@ -3051,6 +3071,7 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 	if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags))
 		return;
 
+	nvme_fault_inject_fini(ns);
 	if (ns->disk && ns->disk->flags & GENHD_FL_UP) {
 		sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
 					&nvme_ns_id_attr_group);
@@ -3067,9 +3088,9 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 	list_del_rcu(&ns->siblings);
 	mutex_unlock(&ns->ctrl->subsys->lock);
 
-	mutex_lock(&ns->ctrl->namespaces_mutex);
+	down_write(&ns->ctrl->namespaces_rwsem);
 	list_del_init(&ns->list);
-	mutex_unlock(&ns->ctrl->namespaces_mutex);
+	up_write(&ns->ctrl->namespaces_rwsem);
 
 	synchronize_srcu(&ns->head->srcu);
 	nvme_mpath_check_last_path(ns);
@@ -3093,11 +3114,18 @@ static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
 					unsigned nsid)
 {
 	struct nvme_ns *ns, *next;
+	LIST_HEAD(rm_list);
 
+	down_write(&ctrl->namespaces_rwsem);
 	list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) {
 		if (ns->head->ns_id > nsid)
-			nvme_ns_remove(ns);
+			list_move_tail(&ns->list, &rm_list);
 	}
+	up_write(&ctrl->namespaces_rwsem);
+
+	list_for_each_entry_safe(ns, next, &rm_list, list)
+		nvme_ns_remove(ns);
+
 }
 
 static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
@@ -3107,7 +3135,7 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
 	unsigned i, j, nsid, prev = 0, num_lists = DIV_ROUND_UP(nn, 1024);
 	int ret = 0;
 
-	ns_list = kzalloc(0x1000, GFP_KERNEL);
+	ns_list = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
 	if (!ns_list)
 		return -ENOMEM;
 
@@ -3173,9 +3201,9 @@ static void nvme_scan_work(struct work_struct *work)
 	}
 	nvme_scan_ns_sequential(ctrl, nn);
  done:
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_write(&ctrl->namespaces_rwsem);
 	list_sort(NULL, &ctrl->namespaces, ns_cmp);
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_write(&ctrl->namespaces_rwsem);
 	kfree(id);
 }
 
@@ -3197,6 +3225,7 @@ EXPORT_SYMBOL_GPL(nvme_queue_scan);
 void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns, *next;
+	LIST_HEAD(ns_list);
 
 	/*
 	 * The dead states indicates the controller was not gracefully
@@ -3207,7 +3236,11 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
 	if (ctrl->state == NVME_CTRL_DEAD)
 		nvme_kill_queues(ctrl);
 
-	list_for_each_entry_safe(ns, next, &ctrl->namespaces, list)
+	down_write(&ctrl->namespaces_rwsem);
+	list_splice_init(&ctrl->namespaces, &ns_list);
+	up_write(&ctrl->namespaces_rwsem);
+
+	list_for_each_entry_safe(ns, next, &ns_list, list)
 		nvme_ns_remove(ns);
 }
 EXPORT_SYMBOL_GPL(nvme_remove_namespaces);
@@ -3337,6 +3370,8 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl)
 	flush_work(&ctrl->async_event_work);
 	flush_work(&ctrl->scan_work);
 	cancel_work_sync(&ctrl->fw_act_work);
+	if (ctrl->ops->stop_ctrl)
+		ctrl->ops->stop_ctrl(ctrl);
 }
 EXPORT_SYMBOL_GPL(nvme_stop_ctrl);
 
@@ -3394,7 +3429,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
 	ctrl->state = NVME_CTRL_NEW;
 	spin_lock_init(&ctrl->lock);
 	INIT_LIST_HEAD(&ctrl->namespaces);
-	mutex_init(&ctrl->namespaces_mutex);
+	init_rwsem(&ctrl->namespaces_rwsem);
 	ctrl->dev = dev;
 	ctrl->ops = ops;
 	ctrl->quirks = quirks;
@@ -3455,7 +3490,7 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 
 	/* Forcibly unquiesce queues to avoid blocking dispatch */
 	if (ctrl->admin_q)
@@ -3474,7 +3509,7 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl)
 		/* Forcibly unquiesce queues to avoid blocking dispatch */
 		blk_mq_unquiesce_queue(ns->queue);
 	}
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 }
 EXPORT_SYMBOL_GPL(nvme_kill_queues);
 
@@ -3482,10 +3517,10 @@ void nvme_unfreeze(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list)
 		blk_mq_unfreeze_queue(ns->queue);
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 }
 EXPORT_SYMBOL_GPL(nvme_unfreeze);
 
@@ -3493,13 +3528,13 @@ void nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout)
 {
 	struct nvme_ns *ns;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list) {
 		timeout = blk_mq_freeze_queue_wait_timeout(ns->queue, timeout);
 		if (timeout <= 0)
 			break;
 	}
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 }
 EXPORT_SYMBOL_GPL(nvme_wait_freeze_timeout);
 
@@ -3507,10 +3542,10 @@ void nvme_wait_freeze(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list)
 		blk_mq_freeze_queue_wait(ns->queue);
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 }
 EXPORT_SYMBOL_GPL(nvme_wait_freeze);
 
@@ -3518,10 +3553,10 @@ void nvme_start_freeze(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list)
 		blk_freeze_queue_start(ns->queue);
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 }
 EXPORT_SYMBOL_GPL(nvme_start_freeze);
 
@@ -3529,10 +3564,10 @@ void nvme_stop_queues(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list)
 		blk_mq_quiesce_queue(ns->queue);
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 }
 EXPORT_SYMBOL_GPL(nvme_stop_queues);
 
@@ -3540,10 +3575,10 @@ void nvme_start_queues(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list)
 		blk_mq_unquiesce_queue(ns->queue);
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 }
 EXPORT_SYMBOL_GPL(nvme_start_queues);
 
diff --git a/drivers/nvme/host/fault_inject.c b/drivers/nvme/host/fault_inject.c
new file mode 100644
index 0000000..0263226
--- /dev/null
+++ b/drivers/nvme/host/fault_inject.c
@@ -0,0 +1,79 @@
+/*
+ * fault injection support for nvme.
+ *
+ * Copyright (c) 2018, Oracle and/or its affiliates
+ *
+ */
+
+#include <linux/moduleparam.h>
+#include "nvme.h"
+
+static DECLARE_FAULT_ATTR(fail_default_attr);
+/* optional fault injection attributes boot time option:
+ * nvme_core.fail_request=<interval>,<probability>,<space>,<times>
+ */
+static char *fail_request;
+module_param(fail_request, charp, 0000);
+
+void nvme_fault_inject_init(struct nvme_ns *ns)
+{
+	struct dentry *dir, *parent;
+	char *name = ns->disk->disk_name;
+	struct nvme_fault_inject *fault_inj = &ns->fault_inject;
+	struct fault_attr *attr = &fault_inj->attr;
+
+	/* set default fault injection attribute */
+	if (fail_request)
+		setup_fault_attr(&fail_default_attr, fail_request);
+
+	/* create debugfs directory and attribute */
+	parent = debugfs_create_dir(name, NULL);
+	if (!parent) {
+		pr_warn("%s: failed to create debugfs directory\n", name);
+		return;
+	}
+
+	*attr = fail_default_attr;
+	dir = fault_create_debugfs_attr("fault_inject", parent, attr);
+	if (IS_ERR(dir)) {
+		pr_warn("%s: failed to create debugfs attr\n", name);
+		debugfs_remove_recursive(parent);
+		return;
+	}
+	ns->fault_inject.parent = parent;
+
+	/* create debugfs for status code and dont_retry */
+	fault_inj->status = NVME_SC_INVALID_OPCODE;
+	fault_inj->dont_retry = true;
+	debugfs_create_x16("status", 0600, dir,	&fault_inj->status);
+	debugfs_create_bool("dont_retry", 0600, dir, &fault_inj->dont_retry);
+}
+
+void nvme_fault_inject_fini(struct nvme_ns *ns)
+{
+	/* remove debugfs directories */
+	debugfs_remove_recursive(ns->fault_inject.parent);
+}
+
+void nvme_should_fail(struct request *req)
+{
+	struct gendisk *disk = req->rq_disk;
+	struct nvme_ns *ns = NULL;
+	u16 status;
+
+	/*
+	 * make sure this request is coming from a valid namespace
+	 */
+	if (!disk)
+		return;
+
+	ns = disk->private_data;
+	if (ns && should_fail(&ns->fault_inject.attr, 1)) {
+		/* inject status code and DNR bit */
+		status = ns->fault_inject.status;
+		if (ns->fault_inject.dont_retry)
+			status |= NVME_SC_DNR;
+		nvme_req(req)->status =	status;
+	}
+}
+EXPORT_SYMBOL_GPL(nvme_should_fail);
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 1dc1387..c6e719b 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -588,6 +588,8 @@ nvme_fc_attach_to_suspended_rport(struct nvme_fc_lport *lport,
 			return ERR_PTR(-ESTALE);
 		}
 
+		rport->remoteport.port_role = pinfo->port_role;
+		rport->remoteport.port_id = pinfo->port_id;
 		rport->remoteport.port_state = FC_OBJSTATE_ONLINE;
 		rport->dev_loss_end = 0;
 
@@ -768,8 +770,7 @@ nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctrl)
 		 */
 		if (nvme_reset_ctrl(&ctrl->ctrl)) {
 			dev_warn(ctrl->ctrl.device,
-				"NVME-FC{%d}: Couldn't schedule reset. "
-				"Deleting controller.\n",
+				"NVME-FC{%d}: Couldn't schedule reset.\n",
 				ctrl->cnum);
 			nvme_delete_ctrl(&ctrl->ctrl);
 		}
@@ -836,8 +837,7 @@ nvme_fc_unregister_remoteport(struct nvme_fc_remote_port *portptr)
 		/* if dev_loss_tmo==0, dev loss is immediate */
 		if (!portptr->dev_loss_tmo) {
 			dev_warn(ctrl->ctrl.device,
-				"NVME-FC{%d}: controller connectivity lost. "
-				"Deleting controller.\n",
+				"NVME-FC{%d}: controller connectivity lost.\n",
 				ctrl->cnum);
 			nvme_delete_ctrl(&ctrl->ctrl);
 		} else
@@ -2076,20 +2076,10 @@ nvme_fc_timeout(struct request *rq, bool reserved)
 {
 	struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq);
 	struct nvme_fc_ctrl *ctrl = op->ctrl;
-	int ret;
-
-	if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE ||
-			atomic_read(&op->state) == FCPOP_STATE_ABORTED)
-		return BLK_EH_RESET_TIMER;
-
-	ret = __nvme_fc_abort_op(ctrl, op);
-	if (ret)
-		/* io wasn't active to abort */
-		return BLK_EH_NOT_HANDLED;
 
 	/*
 	 * we can't individually ABTS an io without affecting the queue,
-	 * thus killing the queue, adn thus the association.
+	 * thus killing the queue, and thus the association.
 	 * So resolve by performing a controller reset, which will stop
 	 * the host/io stack, terminate the association on the link,
 	 * and recreate an association on the link.
@@ -2191,7 +2181,7 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
 	struct nvme_fc_cmd_iu *cmdiu = &op->cmd_iu;
 	struct nvme_command *sqe = &cmdiu->sqe;
 	u32 csn;
-	int ret;
+	int ret, opstate;
 
 	/*
 	 * before attempting to send the io, check to see if we believe
@@ -2269,6 +2259,9 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
 					queue->lldd_handle, &op->fcp_req);
 
 	if (ret) {
+		opstate = atomic_xchg(&op->state, FCPOP_STATE_COMPLETE);
+		__nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate);
+
 		if (!(op->flags & FCOP_FLAGS_AEN))
 			nvme_fc_unmap_data(ctrl, op->rq, op);
 
@@ -2889,14 +2882,13 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status)
 		if (portptr->port_state == FC_OBJSTATE_ONLINE)
 			dev_warn(ctrl->ctrl.device,
 				"NVME-FC{%d}: Max reconnect attempts (%d) "
-				"reached. Removing controller\n",
+				"reached.\n",
 				ctrl->cnum, ctrl->ctrl.nr_reconnects);
 		else
 			dev_warn(ctrl->ctrl.device,
 				"NVME-FC{%d}: dev_loss_tmo (%d) expired "
-				"while waiting for remoteport connectivity. "
-				"Removing controller\n", ctrl->cnum,
-				portptr->dev_loss_tmo);
+				"while waiting for remoteport connectivity.\n",
+				ctrl->cnum, portptr->dev_loss_tmo);
 		WARN_ON(nvme_delete_ctrl(&ctrl->ctrl));
 	}
 }
@@ -3133,6 +3125,10 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
 	}
 
 	if (ret) {
+		nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING);
+		cancel_work_sync(&ctrl->ctrl.reset_work);
+		cancel_delayed_work_sync(&ctrl->connect_work);
+
 		/* couldn't schedule retry - fail out */
 		dev_err(ctrl->ctrl.device,
 			"NVME-FC{%d}: Connect retry failed\n", ctrl->cnum);
diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index 50ef71ee..41279da 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -35,6 +35,10 @@ enum nvme_nvm_admin_opcode {
 	nvme_nvm_admin_set_bb_tbl	= 0xf1,
 };
 
+enum nvme_nvm_log_page {
+	NVME_NVM_LOG_REPORT_CHUNK	= 0xca,
+};
+
 struct nvme_nvm_ph_rw {
 	__u8			opcode;
 	__u8			flags;
@@ -51,6 +55,21 @@ struct nvme_nvm_ph_rw {
 	__le64			resv;
 };
 
+struct nvme_nvm_erase_blk {
+	__u8			opcode;
+	__u8			flags;
+	__u16			command_id;
+	__le32			nsid;
+	__u64			rsvd[2];
+	__le64			prp1;
+	__le64			prp2;
+	__le64			spba;
+	__le16			length;
+	__le16			control;
+	__le32			dsmgmt;
+	__le64			resv;
+};
+
 struct nvme_nvm_identity {
 	__u8			opcode;
 	__u8			flags;
@@ -59,8 +78,7 @@ struct nvme_nvm_identity {
 	__u64			rsvd[2];
 	__le64			prp1;
 	__le64			prp2;
-	__le32			chnl_off;
-	__u32			rsvd11[5];
+	__u32			rsvd11[6];
 };
 
 struct nvme_nvm_getbbtbl {
@@ -90,44 +108,18 @@ struct nvme_nvm_setbbtbl {
 	__u32			rsvd4[3];
 };
 
-struct nvme_nvm_erase_blk {
-	__u8			opcode;
-	__u8			flags;
-	__u16			command_id;
-	__le32			nsid;
-	__u64			rsvd[2];
-	__le64			prp1;
-	__le64			prp2;
-	__le64			spba;
-	__le16			length;
-	__le16			control;
-	__le32			dsmgmt;
-	__le64			resv;
-};
-
 struct nvme_nvm_command {
 	union {
 		struct nvme_common_command common;
-		struct nvme_nvm_identity identity;
 		struct nvme_nvm_ph_rw ph_rw;
+		struct nvme_nvm_erase_blk erase;
+		struct nvme_nvm_identity identity;
 		struct nvme_nvm_getbbtbl get_bb;
 		struct nvme_nvm_setbbtbl set_bb;
-		struct nvme_nvm_erase_blk erase;
 	};
 };
 
-#define NVME_NVM_LP_MLC_PAIRS 886
-struct nvme_nvm_lp_mlc {
-	__le16			num_pairs;
-	__u8			pairs[NVME_NVM_LP_MLC_PAIRS];
-};
-
-struct nvme_nvm_lp_tbl {
-	__u8			id[8];
-	struct nvme_nvm_lp_mlc	mlc;
-};
-
-struct nvme_nvm_id_group {
+struct nvme_nvm_id12_grp {
 	__u8			mtype;
 	__u8			fmtype;
 	__le16			res16;
@@ -150,11 +142,10 @@ struct nvme_nvm_id_group {
 	__le32			mpos;
 	__le32			mccap;
 	__le16			cpar;
-	__u8			reserved[10];
-	struct nvme_nvm_lp_tbl lptbl;
+	__u8			reserved[906];
 } __packed;
 
-struct nvme_nvm_addr_format {
+struct nvme_nvm_id12_addrf {
 	__u8			ch_offset;
 	__u8			ch_len;
 	__u8			lun_offset;
@@ -165,21 +156,22 @@ struct nvme_nvm_addr_format {
 	__u8			blk_len;
 	__u8			pg_offset;
 	__u8			pg_len;
-	__u8			sect_offset;
-	__u8			sect_len;
+	__u8			sec_offset;
+	__u8			sec_len;
 	__u8			res[4];
 } __packed;
 
-struct nvme_nvm_id {
+struct nvme_nvm_id12 {
 	__u8			ver_id;
 	__u8			vmnt;
 	__u8			cgrps;
 	__u8			res;
 	__le32			cap;
 	__le32			dom;
-	struct nvme_nvm_addr_format ppaf;
+	struct nvme_nvm_id12_addrf ppaf;
 	__u8			resv[228];
-	struct nvme_nvm_id_group groups[4];
+	struct nvme_nvm_id12_grp grp;
+	__u8			resv2[2880];
 } __packed;
 
 struct nvme_nvm_bb_tbl {
@@ -196,6 +188,68 @@ struct nvme_nvm_bb_tbl {
 	__u8	blk[0];
 };
 
+struct nvme_nvm_id20_addrf {
+	__u8			grp_len;
+	__u8			pu_len;
+	__u8			chk_len;
+	__u8			lba_len;
+	__u8			resv[4];
+};
+
+struct nvme_nvm_id20 {
+	__u8			mjr;
+	__u8			mnr;
+	__u8			resv[6];
+
+	struct nvme_nvm_id20_addrf lbaf;
+
+	__le32			mccap;
+	__u8			resv2[12];
+
+	__u8			wit;
+	__u8			resv3[31];
+
+	/* Geometry */
+	__le16			num_grp;
+	__le16			num_pu;
+	__le32			num_chk;
+	__le32			clba;
+	__u8			resv4[52];
+
+	/* Write data requirements */
+	__le32			ws_min;
+	__le32			ws_opt;
+	__le32			mw_cunits;
+	__le32			maxoc;
+	__le32			maxocpu;
+	__u8			resv5[44];
+
+	/* Performance related metrics */
+	__le32			trdt;
+	__le32			trdm;
+	__le32			twrt;
+	__le32			twrm;
+	__le32			tcrst;
+	__le32			tcrsm;
+	__u8			resv6[40];
+
+	/* Reserved area */
+	__u8			resv7[2816];
+
+	/* Vendor specific */
+	__u8			vs[1024];
+};
+
+struct nvme_nvm_chk_meta {
+	__u8	state;
+	__u8	type;
+	__u8	wi;
+	__u8	rsvd[5];
+	__le64	slba;
+	__le64	cnlb;
+	__le64	wp;
+};
+
 /*
  * Check we didn't inadvertently grow the command struct
  */
@@ -203,105 +257,238 @@ static inline void _nvme_nvm_check_size(void)
 {
 	BUILD_BUG_ON(sizeof(struct nvme_nvm_identity) != 64);
 	BUILD_BUG_ON(sizeof(struct nvme_nvm_ph_rw) != 64);
+	BUILD_BUG_ON(sizeof(struct nvme_nvm_erase_blk) != 64);
 	BUILD_BUG_ON(sizeof(struct nvme_nvm_getbbtbl) != 64);
 	BUILD_BUG_ON(sizeof(struct nvme_nvm_setbbtbl) != 64);
-	BUILD_BUG_ON(sizeof(struct nvme_nvm_erase_blk) != 64);
-	BUILD_BUG_ON(sizeof(struct nvme_nvm_id_group) != 960);
-	BUILD_BUG_ON(sizeof(struct nvme_nvm_addr_format) != 16);
-	BUILD_BUG_ON(sizeof(struct nvme_nvm_id) != NVME_IDENTIFY_DATA_SIZE);
+	BUILD_BUG_ON(sizeof(struct nvme_nvm_id12_grp) != 960);
+	BUILD_BUG_ON(sizeof(struct nvme_nvm_id12_addrf) != 16);
+	BUILD_BUG_ON(sizeof(struct nvme_nvm_id12) != NVME_IDENTIFY_DATA_SIZE);
 	BUILD_BUG_ON(sizeof(struct nvme_nvm_bb_tbl) != 64);
+	BUILD_BUG_ON(sizeof(struct nvme_nvm_id20_addrf) != 8);
+	BUILD_BUG_ON(sizeof(struct nvme_nvm_id20) != NVME_IDENTIFY_DATA_SIZE);
+	BUILD_BUG_ON(sizeof(struct nvme_nvm_chk_meta) != 32);
+	BUILD_BUG_ON(sizeof(struct nvme_nvm_chk_meta) !=
+						sizeof(struct nvm_chk_meta));
 }
 
-static int init_grps(struct nvm_id *nvm_id, struct nvme_nvm_id *nvme_nvm_id)
+static void nvme_nvm_set_addr_12(struct nvm_addrf_12 *dst,
+				 struct nvme_nvm_id12_addrf *src)
 {
-	struct nvme_nvm_id_group *src;
-	struct nvm_id_group *grp;
+	dst->ch_len = src->ch_len;
+	dst->lun_len = src->lun_len;
+	dst->blk_len = src->blk_len;
+	dst->pg_len = src->pg_len;
+	dst->pln_len = src->pln_len;
+	dst->sec_len = src->sec_len;
+
+	dst->ch_offset = src->ch_offset;
+	dst->lun_offset = src->lun_offset;
+	dst->blk_offset = src->blk_offset;
+	dst->pg_offset = src->pg_offset;
+	dst->pln_offset = src->pln_offset;
+	dst->sec_offset = src->sec_offset;
+
+	dst->ch_mask = ((1ULL << dst->ch_len) - 1) << dst->ch_offset;
+	dst->lun_mask = ((1ULL << dst->lun_len) - 1) << dst->lun_offset;
+	dst->blk_mask = ((1ULL << dst->blk_len) - 1) << dst->blk_offset;
+	dst->pg_mask = ((1ULL << dst->pg_len) - 1) << dst->pg_offset;
+	dst->pln_mask = ((1ULL << dst->pln_len) - 1) << dst->pln_offset;
+	dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
+}
+
+static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id,
+			     struct nvm_geo *geo)
+{
+	struct nvme_nvm_id12_grp *src;
 	int sec_per_pg, sec_per_pl, pg_per_blk;
 
-	if (nvme_nvm_id->cgrps != 1)
+	if (id->cgrps != 1)
 		return -EINVAL;
 
-	src = &nvme_nvm_id->groups[0];
-	grp = &nvm_id->grp;
+	src = &id->grp;
 
-	grp->mtype = src->mtype;
-	grp->fmtype = src->fmtype;
-
-	grp->num_ch = src->num_ch;
-	grp->num_lun = src->num_lun;
-
-	grp->num_chk = le16_to_cpu(src->num_chk);
-	grp->csecs = le16_to_cpu(src->csecs);
-	grp->sos = le16_to_cpu(src->sos);
-
-	pg_per_blk = le16_to_cpu(src->num_pg);
-	sec_per_pg = le16_to_cpu(src->fpg_sz) / grp->csecs;
-	sec_per_pl = sec_per_pg * src->num_pln;
-	grp->clba = sec_per_pl * pg_per_blk;
-	grp->ws_per_chk = pg_per_blk;
-
-	grp->mpos = le32_to_cpu(src->mpos);
-	grp->cpar = le16_to_cpu(src->cpar);
-	grp->mccap = le32_to_cpu(src->mccap);
-
-	grp->ws_opt = grp->ws_min = sec_per_pg;
-	grp->ws_seq = NVM_IO_SNGL_ACCESS;
-
-	if (grp->mpos & 0x020202) {
-		grp->ws_seq = NVM_IO_DUAL_ACCESS;
-		grp->ws_opt <<= 1;
-	} else if (grp->mpos & 0x040404) {
-		grp->ws_seq = NVM_IO_QUAD_ACCESS;
-		grp->ws_opt <<= 2;
+	if (src->mtype != 0) {
+		pr_err("nvm: memory type not supported\n");
+		return -EINVAL;
 	}
 
-	grp->trdt = le32_to_cpu(src->trdt);
-	grp->trdm = le32_to_cpu(src->trdm);
-	grp->tprt = le32_to_cpu(src->tprt);
-	grp->tprm = le32_to_cpu(src->tprm);
-	grp->tbet = le32_to_cpu(src->tbet);
-	grp->tbem = le32_to_cpu(src->tbem);
+	/* 1.2 spec. only reports a single version id - unfold */
+	geo->major_ver_id = id->ver_id;
+	geo->minor_ver_id = 2;
+
+	/* Set compacted version for upper layers */
+	geo->version = NVM_OCSSD_SPEC_12;
+
+	geo->num_ch = src->num_ch;
+	geo->num_lun = src->num_lun;
+	geo->all_luns = geo->num_ch * geo->num_lun;
+
+	geo->num_chk = le16_to_cpu(src->num_chk);
+
+	geo->csecs = le16_to_cpu(src->csecs);
+	geo->sos = le16_to_cpu(src->sos);
+
+	pg_per_blk = le16_to_cpu(src->num_pg);
+	sec_per_pg = le16_to_cpu(src->fpg_sz) / geo->csecs;
+	sec_per_pl = sec_per_pg * src->num_pln;
+	geo->clba = sec_per_pl * pg_per_blk;
+
+	geo->all_chunks = geo->all_luns * geo->num_chk;
+	geo->total_secs = geo->clba * geo->all_chunks;
+
+	geo->ws_min = sec_per_pg;
+	geo->ws_opt = sec_per_pg;
+	geo->mw_cunits = geo->ws_opt << 3;	/* default to MLC safe values */
+
+	/* Do not impose values for maximum number of open blocks as it is
+	 * unspecified in 1.2. Users of 1.2 must be aware of this and eventually
+	 * specify these values through a quirk if restrictions apply.
+	 */
+	geo->maxoc = geo->all_luns * geo->num_chk;
+	geo->maxocpu = geo->num_chk;
+
+	geo->mccap = le32_to_cpu(src->mccap);
+
+	geo->trdt = le32_to_cpu(src->trdt);
+	geo->trdm = le32_to_cpu(src->trdm);
+	geo->tprt = le32_to_cpu(src->tprt);
+	geo->tprm = le32_to_cpu(src->tprm);
+	geo->tbet = le32_to_cpu(src->tbet);
+	geo->tbem = le32_to_cpu(src->tbem);
 
 	/* 1.2 compatibility */
-	grp->num_pln = src->num_pln;
-	grp->num_pg = le16_to_cpu(src->num_pg);
-	grp->fpg_sz = le16_to_cpu(src->fpg_sz);
+	geo->vmnt = id->vmnt;
+	geo->cap = le32_to_cpu(id->cap);
+	geo->dom = le32_to_cpu(id->dom);
+
+	geo->mtype = src->mtype;
+	geo->fmtype = src->fmtype;
+
+	geo->cpar = le16_to_cpu(src->cpar);
+	geo->mpos = le32_to_cpu(src->mpos);
+
+	geo->pln_mode = NVM_PLANE_SINGLE;
+
+	if (geo->mpos & 0x020202) {
+		geo->pln_mode = NVM_PLANE_DOUBLE;
+		geo->ws_opt <<= 1;
+	} else if (geo->mpos & 0x040404) {
+		geo->pln_mode = NVM_PLANE_QUAD;
+		geo->ws_opt <<= 2;
+	}
+
+	geo->num_pln = src->num_pln;
+	geo->num_pg = le16_to_cpu(src->num_pg);
+	geo->fpg_sz = le16_to_cpu(src->fpg_sz);
+
+	nvme_nvm_set_addr_12((struct nvm_addrf_12 *)&geo->addrf, &id->ppaf);
 
 	return 0;
 }
 
-static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id)
+static void nvme_nvm_set_addr_20(struct nvm_addrf *dst,
+				 struct nvme_nvm_id20_addrf *src)
+{
+	dst->ch_len = src->grp_len;
+	dst->lun_len = src->pu_len;
+	dst->chk_len = src->chk_len;
+	dst->sec_len = src->lba_len;
+
+	dst->sec_offset = 0;
+	dst->chk_offset = dst->sec_len;
+	dst->lun_offset = dst->chk_offset + dst->chk_len;
+	dst->ch_offset = dst->lun_offset + dst->lun_len;
+
+	dst->ch_mask = ((1ULL << dst->ch_len) - 1) << dst->ch_offset;
+	dst->lun_mask = ((1ULL << dst->lun_len) - 1) << dst->lun_offset;
+	dst->chk_mask = ((1ULL << dst->chk_len) - 1) << dst->chk_offset;
+	dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset;
+}
+
+static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id,
+			     struct nvm_geo *geo)
+{
+	geo->major_ver_id = id->mjr;
+	geo->minor_ver_id = id->mnr;
+
+	/* Set compacted version for upper layers */
+	geo->version = NVM_OCSSD_SPEC_20;
+
+	if (!(geo->major_ver_id == 2 && geo->minor_ver_id == 0)) {
+		pr_err("nvm: OCSSD version not supported (v%d.%d)\n",
+				geo->major_ver_id, geo->minor_ver_id);
+		return -EINVAL;
+	}
+
+	geo->num_ch = le16_to_cpu(id->num_grp);
+	geo->num_lun = le16_to_cpu(id->num_pu);
+	geo->all_luns = geo->num_ch * geo->num_lun;
+
+	geo->num_chk = le32_to_cpu(id->num_chk);
+	geo->clba = le32_to_cpu(id->clba);
+
+	geo->all_chunks = geo->all_luns * geo->num_chk;
+	geo->total_secs = geo->clba * geo->all_chunks;
+
+	geo->ws_min = le32_to_cpu(id->ws_min);
+	geo->ws_opt = le32_to_cpu(id->ws_opt);
+	geo->mw_cunits = le32_to_cpu(id->mw_cunits);
+	geo->maxoc = le32_to_cpu(id->maxoc);
+	geo->maxocpu = le32_to_cpu(id->maxocpu);
+
+	geo->trdt = le32_to_cpu(id->trdt);
+	geo->trdm = le32_to_cpu(id->trdm);
+	geo->tprt = le32_to_cpu(id->twrt);
+	geo->tprm = le32_to_cpu(id->twrm);
+	geo->tbet = le32_to_cpu(id->tcrst);
+	geo->tbem = le32_to_cpu(id->tcrsm);
+
+	nvme_nvm_set_addr_20(&geo->addrf, &id->lbaf);
+
+	return 0;
+}
+
+static int nvme_nvm_identity(struct nvm_dev *nvmdev)
 {
 	struct nvme_ns *ns = nvmdev->q->queuedata;
-	struct nvme_nvm_id *nvme_nvm_id;
+	struct nvme_nvm_id12 *id;
 	struct nvme_nvm_command c = {};
 	int ret;
 
 	c.identity.opcode = nvme_nvm_admin_identity;
 	c.identity.nsid = cpu_to_le32(ns->head->ns_id);
-	c.identity.chnl_off = 0;
 
-	nvme_nvm_id = kmalloc(sizeof(struct nvme_nvm_id), GFP_KERNEL);
-	if (!nvme_nvm_id)
+	id = kmalloc(sizeof(struct nvme_nvm_id12), GFP_KERNEL);
+	if (!id)
 		return -ENOMEM;
 
 	ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *)&c,
-				nvme_nvm_id, sizeof(struct nvme_nvm_id));
+				id, sizeof(struct nvme_nvm_id12));
 	if (ret) {
 		ret = -EIO;
 		goto out;
 	}
 
-	nvm_id->ver_id = nvme_nvm_id->ver_id;
-	nvm_id->vmnt = nvme_nvm_id->vmnt;
-	nvm_id->cap = le32_to_cpu(nvme_nvm_id->cap);
-	nvm_id->dom = le32_to_cpu(nvme_nvm_id->dom);
-	memcpy(&nvm_id->ppaf, &nvme_nvm_id->ppaf,
-					sizeof(struct nvm_addr_format));
+	/*
+	 * The 1.2 and 2.0 specifications share the first byte in their geometry
+	 * command to make it possible to know what version a device implements.
+	 */
+	switch (id->ver_id) {
+	case 1:
+		ret = nvme_nvm_setup_12(id, &nvmdev->geo);
+		break;
+	case 2:
+		ret = nvme_nvm_setup_20((struct nvme_nvm_id20 *)id,
+							&nvmdev->geo);
+		break;
+	default:
+		dev_err(ns->ctrl->device, "OCSSD revision not supported (%d)\n",
+							id->ver_id);
+		ret = -EINVAL;
+	}
 
-	ret = init_grps(nvm_id, nvme_nvm_id);
 out:
-	kfree(nvme_nvm_id);
+	kfree(id);
 	return ret;
 }
 
@@ -314,7 +501,7 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa,
 	struct nvme_ctrl *ctrl = ns->ctrl;
 	struct nvme_nvm_command c = {};
 	struct nvme_nvm_bb_tbl *bb_tbl;
-	int nr_blks = geo->nr_chks * geo->plane_mode;
+	int nr_blks = geo->num_chk * geo->num_pln;
 	int tblsz = sizeof(struct nvme_nvm_bb_tbl) + nr_blks;
 	int ret = 0;
 
@@ -355,7 +542,7 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa,
 		goto out;
 	}
 
-	memcpy(blks, bb_tbl->blk, geo->nr_chks * geo->plane_mode);
+	memcpy(blks, bb_tbl->blk, geo->num_chk * geo->num_pln);
 out:
 	kfree(bb_tbl);
 	return ret;
@@ -382,6 +569,61 @@ static int nvme_nvm_set_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr *ppas,
 	return ret;
 }
 
+/*
+ * Expect the lba in device format
+ */
+static int nvme_nvm_get_chk_meta(struct nvm_dev *ndev,
+				 struct nvm_chk_meta *meta,
+				 sector_t slba, int nchks)
+{
+	struct nvm_geo *geo = &ndev->geo;
+	struct nvme_ns *ns = ndev->q->queuedata;
+	struct nvme_ctrl *ctrl = ns->ctrl;
+	struct nvme_nvm_chk_meta *dev_meta = (struct nvme_nvm_chk_meta *)meta;
+	struct ppa_addr ppa;
+	size_t left = nchks * sizeof(struct nvme_nvm_chk_meta);
+	size_t log_pos, offset, len;
+	int ret, i;
+
+	/* Normalize lba address space to obtain log offset */
+	ppa.ppa = slba;
+	ppa = dev_to_generic_addr(ndev, ppa);
+
+	log_pos = ppa.m.chk;
+	log_pos += ppa.m.pu * geo->num_chk;
+	log_pos += ppa.m.grp * geo->num_lun * geo->num_chk;
+
+	offset = log_pos * sizeof(struct nvme_nvm_chk_meta);
+
+	while (left) {
+		len = min_t(unsigned int, left, ctrl->max_hw_sectors << 9);
+
+		ret = nvme_get_log_ext(ctrl, ns, NVME_NVM_LOG_REPORT_CHUNK,
+				dev_meta, len, offset);
+		if (ret) {
+			dev_err(ctrl->device, "Get REPORT CHUNK log error\n");
+			break;
+		}
+
+		for (i = 0; i < len; i += sizeof(struct nvme_nvm_chk_meta)) {
+			meta->state = dev_meta->state;
+			meta->type = dev_meta->type;
+			meta->wi = dev_meta->wi;
+			meta->slba = le64_to_cpu(dev_meta->slba);
+			meta->cnlb = le64_to_cpu(dev_meta->cnlb);
+			meta->wp = le64_to_cpu(dev_meta->wp);
+
+			meta++;
+			dev_meta++;
+		}
+
+		offset += len;
+		left -= len;
+	}
+
+	return ret;
+}
+
 static inline void nvme_nvm_rqtocmd(struct nvm_rq *rqd, struct nvme_ns *ns,
 				    struct nvme_nvm_command *c)
 {
@@ -513,6 +755,8 @@ static struct nvm_dev_ops nvme_nvm_dev_ops = {
 	.get_bb_tbl		= nvme_nvm_get_bb_tbl,
 	.set_bb_tbl		= nvme_nvm_set_bb_tbl,
 
+	.get_chk_meta		= nvme_nvm_get_chk_meta,
+
 	.submit_io		= nvme_nvm_submit_io,
 	.submit_io_sync		= nvme_nvm_submit_io_sync,
 
@@ -520,8 +764,6 @@ static struct nvm_dev_ops nvme_nvm_dev_ops = {
 	.destroy_dma_pool	= nvme_nvm_destroy_dma_pool,
 	.dev_dma_alloc		= nvme_nvm_dev_dma_alloc,
 	.dev_dma_free		= nvme_nvm_dev_dma_free,
-
-	.max_phys_sect		= 64,
 };
 
 static int nvme_nvm_submit_user_cmd(struct request_queue *q,
@@ -722,6 +964,15 @@ int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg)
 	}
 }
 
+void nvme_nvm_update_nvm_info(struct nvme_ns *ns)
+{
+	struct nvm_dev *ndev = ns->ndev;
+	struct nvm_geo *geo = &ndev->geo;
+
+	geo->csecs = 1 << ns->lba_shift;
+	geo->sos = ns->ms;
+}
+
 int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node)
 {
 	struct request_queue *q = ns->queue;
@@ -748,125 +999,205 @@ void nvme_nvm_unregister(struct nvme_ns *ns)
 }
 
 static ssize_t nvm_dev_attr_show(struct device *dev,
-				 struct device_attribute *dattr, char *page)
+		struct device_attribute *dattr, char *page)
 {
 	struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
 	struct nvm_dev *ndev = ns->ndev;
-	struct nvm_id *id;
-	struct nvm_id_group *grp;
+	struct nvm_geo *geo = &ndev->geo;
 	struct attribute *attr;
 
 	if (!ndev)
 		return 0;
 
-	id = &ndev->identity;
-	grp = &id->grp;
 	attr = &dattr->attr;
 
 	if (strcmp(attr->name, "version") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", id->ver_id);
-	} else if (strcmp(attr->name, "vendor_opcode") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", id->vmnt);
+		if (geo->major_ver_id == 1)
+			return scnprintf(page, PAGE_SIZE, "%u\n",
+						geo->major_ver_id);
+		else
+			return scnprintf(page, PAGE_SIZE, "%u.%u\n",
+						geo->major_ver_id,
+						geo->minor_ver_id);
 	} else if (strcmp(attr->name, "capabilities") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", id->cap);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->cap);
+	} else if (strcmp(attr->name, "read_typ") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->trdt);
+	} else if (strcmp(attr->name, "read_max") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->trdm);
+	} else {
+		return scnprintf(page,
+				 PAGE_SIZE,
+				 "Unhandled attr(%s) in `%s`\n",
+				 attr->name, __func__);
+	}
+}
+
+static ssize_t nvm_dev_attr_show_ppaf(struct nvm_addrf_12 *ppaf, char *page)
+{
+	return scnprintf(page, PAGE_SIZE,
+		"0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+				ppaf->ch_offset, ppaf->ch_len,
+				ppaf->lun_offset, ppaf->lun_len,
+				ppaf->pln_offset, ppaf->pln_len,
+				ppaf->blk_offset, ppaf->blk_len,
+				ppaf->pg_offset, ppaf->pg_len,
+				ppaf->sec_offset, ppaf->sec_len);
+}
+
+static ssize_t nvm_dev_attr_show_12(struct device *dev,
+		struct device_attribute *dattr, char *page)
+{
+	struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
+	struct nvm_dev *ndev = ns->ndev;
+	struct nvm_geo *geo = &ndev->geo;
+	struct attribute *attr;
+
+	if (!ndev)
+		return 0;
+
+	attr = &dattr->attr;
+
+	if (strcmp(attr->name, "vendor_opcode") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->vmnt);
 	} else if (strcmp(attr->name, "device_mode") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", id->dom);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->dom);
 	/* kept for compatibility */
 	} else if (strcmp(attr->name, "media_manager") == 0) {
 		return scnprintf(page, PAGE_SIZE, "%s\n", "gennvm");
 	} else if (strcmp(attr->name, "ppa_format") == 0) {
-		return scnprintf(page, PAGE_SIZE,
-			"0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-			id->ppaf.ch_offset, id->ppaf.ch_len,
-			id->ppaf.lun_offset, id->ppaf.lun_len,
-			id->ppaf.pln_offset, id->ppaf.pln_len,
-			id->ppaf.blk_offset, id->ppaf.blk_len,
-			id->ppaf.pg_offset, id->ppaf.pg_len,
-			id->ppaf.sect_offset, id->ppaf.sect_len);
+		return nvm_dev_attr_show_ppaf((void *)&geo->addrf, page);
 	} else if (strcmp(attr->name, "media_type") == 0) {	/* u8 */
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->mtype);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->mtype);
 	} else if (strcmp(attr->name, "flash_media_type") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->fmtype);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->fmtype);
 	} else if (strcmp(attr->name, "num_channels") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_ch);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_ch);
 	} else if (strcmp(attr->name, "num_luns") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_lun);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_lun);
 	} else if (strcmp(attr->name, "num_planes") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_pln);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_pln);
 	} else if (strcmp(attr->name, "num_blocks") == 0) {	/* u16 */
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_chk);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_chk);
 	} else if (strcmp(attr->name, "num_pages") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_pg);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_pg);
 	} else if (strcmp(attr->name, "page_size") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->fpg_sz);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->fpg_sz);
 	} else if (strcmp(attr->name, "hw_sector_size") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->csecs);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->csecs);
 	} else if (strcmp(attr->name, "oob_sector_size") == 0) {/* u32 */
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->sos);
-	} else if (strcmp(attr->name, "read_typ") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->trdt);
-	} else if (strcmp(attr->name, "read_max") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->trdm);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->sos);
 	} else if (strcmp(attr->name, "prog_typ") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->tprt);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->tprt);
 	} else if (strcmp(attr->name, "prog_max") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->tprm);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->tprm);
 	} else if (strcmp(attr->name, "erase_typ") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->tbet);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->tbet);
 	} else if (strcmp(attr->name, "erase_max") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n", grp->tbem);
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->tbem);
 	} else if (strcmp(attr->name, "multiplane_modes") == 0) {
-		return scnprintf(page, PAGE_SIZE, "0x%08x\n", grp->mpos);
+		return scnprintf(page, PAGE_SIZE, "0x%08x\n", geo->mpos);
 	} else if (strcmp(attr->name, "media_capabilities") == 0) {
-		return scnprintf(page, PAGE_SIZE, "0x%08x\n", grp->mccap);
+		return scnprintf(page, PAGE_SIZE, "0x%08x\n", geo->mccap);
 	} else if (strcmp(attr->name, "max_phys_secs") == 0) {
-		return scnprintf(page, PAGE_SIZE, "%u\n",
-				ndev->ops->max_phys_sect);
+		return scnprintf(page, PAGE_SIZE, "%u\n", NVM_MAX_VLBA);
 	} else {
-		return scnprintf(page,
-				 PAGE_SIZE,
-				 "Unhandled attr(%s) in `nvm_dev_attr_show`\n",
-				 attr->name);
+		return scnprintf(page, PAGE_SIZE,
+			"Unhandled attr(%s) in `%s`\n",
+			attr->name, __func__);
 	}
 }
 
-#define NVM_DEV_ATTR_RO(_name)						\
+static ssize_t nvm_dev_attr_show_20(struct device *dev,
+		struct device_attribute *dattr, char *page)
+{
+	struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
+	struct nvm_dev *ndev = ns->ndev;
+	struct nvm_geo *geo = &ndev->geo;
+	struct attribute *attr;
+
+	if (!ndev)
+		return 0;
+
+	attr = &dattr->attr;
+
+	if (strcmp(attr->name, "groups") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_ch);
+	} else if (strcmp(attr->name, "punits") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_lun);
+	} else if (strcmp(attr->name, "chunks") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_chk);
+	} else if (strcmp(attr->name, "clba") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->clba);
+	} else if (strcmp(attr->name, "ws_min") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->ws_min);
+	} else if (strcmp(attr->name, "ws_opt") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->ws_opt);
+	} else if (strcmp(attr->name, "maxoc") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->maxoc);
+	} else if (strcmp(attr->name, "maxocpu") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->maxocpu);
+	} else if (strcmp(attr->name, "mw_cunits") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->mw_cunits);
+	} else if (strcmp(attr->name, "write_typ") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->tprt);
+	} else if (strcmp(attr->name, "write_max") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->tprm);
+	} else if (strcmp(attr->name, "reset_typ") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->tbet);
+	} else if (strcmp(attr->name, "reset_max") == 0) {
+		return scnprintf(page, PAGE_SIZE, "%u\n", geo->tbem);
+	} else {
+		return scnprintf(page, PAGE_SIZE,
+			"Unhandled attr(%s) in `%s`\n",
+			attr->name, __func__);
+	}
+}
+
+#define NVM_DEV_ATTR_RO(_name)					\
 	DEVICE_ATTR(_name, S_IRUGO, nvm_dev_attr_show, NULL)
+#define NVM_DEV_ATTR_12_RO(_name)					\
+	DEVICE_ATTR(_name, S_IRUGO, nvm_dev_attr_show_12, NULL)
+#define NVM_DEV_ATTR_20_RO(_name)					\
+	DEVICE_ATTR(_name, S_IRUGO, nvm_dev_attr_show_20, NULL)
 
+/* general attributes */
 static NVM_DEV_ATTR_RO(version);
-static NVM_DEV_ATTR_RO(vendor_opcode);
 static NVM_DEV_ATTR_RO(capabilities);
-static NVM_DEV_ATTR_RO(device_mode);
-static NVM_DEV_ATTR_RO(ppa_format);
-static NVM_DEV_ATTR_RO(media_manager);
 
-static NVM_DEV_ATTR_RO(media_type);
-static NVM_DEV_ATTR_RO(flash_media_type);
-static NVM_DEV_ATTR_RO(num_channels);
-static NVM_DEV_ATTR_RO(num_luns);
-static NVM_DEV_ATTR_RO(num_planes);
-static NVM_DEV_ATTR_RO(num_blocks);
-static NVM_DEV_ATTR_RO(num_pages);
-static NVM_DEV_ATTR_RO(page_size);
-static NVM_DEV_ATTR_RO(hw_sector_size);
-static NVM_DEV_ATTR_RO(oob_sector_size);
 static NVM_DEV_ATTR_RO(read_typ);
 static NVM_DEV_ATTR_RO(read_max);
-static NVM_DEV_ATTR_RO(prog_typ);
-static NVM_DEV_ATTR_RO(prog_max);
-static NVM_DEV_ATTR_RO(erase_typ);
-static NVM_DEV_ATTR_RO(erase_max);
-static NVM_DEV_ATTR_RO(multiplane_modes);
-static NVM_DEV_ATTR_RO(media_capabilities);
-static NVM_DEV_ATTR_RO(max_phys_secs);
 
-static struct attribute *nvm_dev_attrs[] = {
+/* 1.2 values */
+static NVM_DEV_ATTR_12_RO(vendor_opcode);
+static NVM_DEV_ATTR_12_RO(device_mode);
+static NVM_DEV_ATTR_12_RO(ppa_format);
+static NVM_DEV_ATTR_12_RO(media_manager);
+static NVM_DEV_ATTR_12_RO(media_type);
+static NVM_DEV_ATTR_12_RO(flash_media_type);
+static NVM_DEV_ATTR_12_RO(num_channels);
+static NVM_DEV_ATTR_12_RO(num_luns);
+static NVM_DEV_ATTR_12_RO(num_planes);
+static NVM_DEV_ATTR_12_RO(num_blocks);
+static NVM_DEV_ATTR_12_RO(num_pages);
+static NVM_DEV_ATTR_12_RO(page_size);
+static NVM_DEV_ATTR_12_RO(hw_sector_size);
+static NVM_DEV_ATTR_12_RO(oob_sector_size);
+static NVM_DEV_ATTR_12_RO(prog_typ);
+static NVM_DEV_ATTR_12_RO(prog_max);
+static NVM_DEV_ATTR_12_RO(erase_typ);
+static NVM_DEV_ATTR_12_RO(erase_max);
+static NVM_DEV_ATTR_12_RO(multiplane_modes);
+static NVM_DEV_ATTR_12_RO(media_capabilities);
+static NVM_DEV_ATTR_12_RO(max_phys_secs);
+
+static struct attribute *nvm_dev_attrs_12[] = {
 	&dev_attr_version.attr,
-	&dev_attr_vendor_opcode.attr,
 	&dev_attr_capabilities.attr,
+
+	&dev_attr_vendor_opcode.attr,
 	&dev_attr_device_mode.attr,
 	&dev_attr_media_manager.attr,
-
 	&dev_attr_ppa_format.attr,
 	&dev_attr_media_type.attr,
 	&dev_attr_flash_media_type.attr,
@@ -887,22 +1218,92 @@ static struct attribute *nvm_dev_attrs[] = {
 	&dev_attr_multiplane_modes.attr,
 	&dev_attr_media_capabilities.attr,
 	&dev_attr_max_phys_secs.attr,
+
 	NULL,
 };
 
-static const struct attribute_group nvm_dev_attr_group = {
+static const struct attribute_group nvm_dev_attr_group_12 = {
 	.name		= "lightnvm",
-	.attrs		= nvm_dev_attrs,
+	.attrs		= nvm_dev_attrs_12,
+};
+
+/* 2.0 values */
+static NVM_DEV_ATTR_20_RO(groups);
+static NVM_DEV_ATTR_20_RO(punits);
+static NVM_DEV_ATTR_20_RO(chunks);
+static NVM_DEV_ATTR_20_RO(clba);
+static NVM_DEV_ATTR_20_RO(ws_min);
+static NVM_DEV_ATTR_20_RO(ws_opt);
+static NVM_DEV_ATTR_20_RO(maxoc);
+static NVM_DEV_ATTR_20_RO(maxocpu);
+static NVM_DEV_ATTR_20_RO(mw_cunits);
+static NVM_DEV_ATTR_20_RO(write_typ);
+static NVM_DEV_ATTR_20_RO(write_max);
+static NVM_DEV_ATTR_20_RO(reset_typ);
+static NVM_DEV_ATTR_20_RO(reset_max);
+
+static struct attribute *nvm_dev_attrs_20[] = {
+	&dev_attr_version.attr,
+	&dev_attr_capabilities.attr,
+
+	&dev_attr_groups.attr,
+	&dev_attr_punits.attr,
+	&dev_attr_chunks.attr,
+	&dev_attr_clba.attr,
+	&dev_attr_ws_min.attr,
+	&dev_attr_ws_opt.attr,
+	&dev_attr_maxoc.attr,
+	&dev_attr_maxocpu.attr,
+	&dev_attr_mw_cunits.attr,
+
+	&dev_attr_read_typ.attr,
+	&dev_attr_read_max.attr,
+	&dev_attr_write_typ.attr,
+	&dev_attr_write_max.attr,
+	&dev_attr_reset_typ.attr,
+	&dev_attr_reset_max.attr,
+
+	NULL,
+};
+
+static const struct attribute_group nvm_dev_attr_group_20 = {
+	.name		= "lightnvm",
+	.attrs		= nvm_dev_attrs_20,
 };
 
 int nvme_nvm_register_sysfs(struct nvme_ns *ns)
 {
-	return sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
-					&nvm_dev_attr_group);
+	struct nvm_dev *ndev = ns->ndev;
+	struct nvm_geo *geo = &ndev->geo;
+
+	if (!ndev)
+		return -EINVAL;
+
+	switch (geo->major_ver_id) {
+	case 1:
+		return sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
+					&nvm_dev_attr_group_12);
+	case 2:
+		return sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
+					&nvm_dev_attr_group_20);
+	}
+
+	return -EINVAL;
 }
 
 void nvme_nvm_unregister_sysfs(struct nvme_ns *ns)
 {
-	sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
-					&nvm_dev_attr_group);
+	struct nvm_dev *ndev = ns->ndev;
+	struct nvm_geo *geo = &ndev->geo;
+
+	switch (geo->major_ver_id) {
+	case 1:
+		sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
+					&nvm_dev_attr_group_12);
+		break;
+	case 2:
+		sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
+					&nvm_dev_attr_group_20);
+		break;
+	}
 }
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 060f69e..956e0b8 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -44,12 +44,12 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
 
-	mutex_lock(&ctrl->namespaces_mutex);
+	down_read(&ctrl->namespaces_rwsem);
 	list_for_each_entry(ns, &ctrl->namespaces, list) {
 		if (ns->head->disk)
 			kblockd_schedule_work(&ns->head->requeue_work);
 	}
-	mutex_unlock(&ctrl->namespaces_mutex);
+	up_read(&ctrl->namespaces_rwsem);
 }
 
 static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head)
@@ -162,13 +162,13 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
 	if (!(ctrl->subsys->cmic & (1 << 1)) || !multipath)
 		return 0;
 
-	q = blk_alloc_queue_node(GFP_KERNEL, NUMA_NO_NODE);
+	q = blk_alloc_queue_node(GFP_KERNEL, NUMA_NO_NODE, NULL);
 	if (!q)
 		goto out;
 	q->queuedata = head;
 	blk_queue_make_request(q, nvme_ns_head_make_request);
 	q->poll_fn = nvme_ns_head_poll;
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
 	/* set to a default value for 512 until disk is validated */
 	blk_queue_logical_block_size(q, 512);
 
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index d733b14..cf93690 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -21,6 +21,7 @@
 #include <linux/blk-mq.h>
 #include <linux/lightnvm.h>
 #include <linux/sed-opal.h>
+#include <linux/fault-inject.h>
 
 extern unsigned int nvme_io_timeout;
 #define NVME_IO_TIMEOUT	(nvme_io_timeout * HZ)
@@ -140,7 +141,7 @@ struct nvme_ctrl {
 	struct blk_mq_tag_set *tagset;
 	struct blk_mq_tag_set *admin_tagset;
 	struct list_head namespaces;
-	struct mutex namespaces_mutex;
+	struct rw_semaphore namespaces_rwsem;
 	struct device ctrl_device;
 	struct device *device;	/* char device */
 	struct cdev cdev;
@@ -261,6 +262,15 @@ struct nvme_ns_head {
 	int			instance;
 };
 
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+struct nvme_fault_inject {
+	struct fault_attr attr;
+	struct dentry *parent;
+	bool dont_retry;	/* DNR, do not retry */
+	u16 status;		/* status code */
+};
+#endif
+
 struct nvme_ns {
 	struct list_head list;
 
@@ -282,6 +292,11 @@ struct nvme_ns {
 #define NVME_NS_REMOVING 0
 #define NVME_NS_DEAD     1
 	u16 noiob;
+
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+	struct nvme_fault_inject fault_inject;
+#endif
+
 };
 
 struct nvme_ctrl_ops {
@@ -298,8 +313,19 @@ struct nvme_ctrl_ops {
 	void (*delete_ctrl)(struct nvme_ctrl *ctrl);
 	int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
 	int (*reinit_request)(void *data, struct request *rq);
+	void (*stop_ctrl)(struct nvme_ctrl *ctrl);
 };
 
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+void nvme_fault_inject_init(struct nvme_ns *ns);
+void nvme_fault_inject_fini(struct nvme_ns *ns);
+void nvme_should_fail(struct request *req);
+#else
+static inline void nvme_fault_inject_init(struct nvme_ns *ns) {}
+static inline void nvme_fault_inject_fini(struct nvme_ns *ns) {}
+static inline void nvme_should_fail(struct request *req) {}
+#endif
+
 static inline bool nvme_ctrl_ready(struct nvme_ctrl *ctrl)
 {
 	u32 val = 0;
@@ -336,6 +362,8 @@ static inline void nvme_end_request(struct request *req, __le16 status,
 
 	rq->status = le16_to_cpu(status) >> 1;
 	rq->result = result;
+	/* inject error when permitted by fault injection framework */
+	nvme_should_fail(req);
 	blk_mq_complete_request(req);
 }
 
@@ -401,6 +429,9 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl);
 int nvme_delete_ctrl(struct nvme_ctrl *ctrl);
 int nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl);
 
+int nvme_get_log_ext(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+		u8 log_page, void *log, size_t size, size_t offset);
+
 extern const struct attribute_group nvme_ns_id_attr_group;
 extern const struct block_device_operations nvme_ns_head_ops;
 
@@ -461,12 +492,14 @@ static inline void nvme_mpath_check_last_path(struct nvme_ns *ns)
 #endif /* CONFIG_NVME_MULTIPATH */
 
 #ifdef CONFIG_NVM
+void nvme_nvm_update_nvm_info(struct nvme_ns *ns);
 int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node);
 void nvme_nvm_unregister(struct nvme_ns *ns);
 int nvme_nvm_register_sysfs(struct nvme_ns *ns);
 void nvme_nvm_unregister_sysfs(struct nvme_ns *ns);
 int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg);
 #else
+static inline void nvme_nvm_update_nvm_info(struct nvme_ns *ns) {};
 static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name,
 				    int node)
 {
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index b6f43b7..295fbec 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -414,7 +414,7 @@ static int nvme_pci_map_queues(struct blk_mq_tag_set *set)
 {
 	struct nvme_dev *dev = set->driver_data;
 
-	return blk_mq_pci_map_queues(set, to_pci_dev(dev->dev));
+	return blk_mq_pci_map_queues(set, to_pci_dev(dev->dev), 0);
 }
 
 /**
@@ -2197,7 +2197,11 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
 	if (!dead) {
 		if (shutdown)
 			nvme_wait_freeze_timeout(&dev->ctrl, NVME_IO_TIMEOUT);
+	}
 
+	nvme_stop_queues(&dev->ctrl);
+
+	if (!dead) {
 		/*
 		 * If the controller is still alive tell it to stop using the
 		 * host memory buffer.  In theory the shutdown / reset should
@@ -2206,11 +2210,6 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
 		 */
 		if (dev->host_mem_descs)
 			nvme_set_host_mem(dev, 0);
-
-	}
-	nvme_stop_queues(&dev->ctrl);
-
-	if (!dead) {
 		nvme_disable_io_queues(dev);
 		nvme_disable_admin_queue(dev, shutdown);
 	}
@@ -2416,6 +2415,13 @@ static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
 	return 0;
 }
 
+static int nvme_pci_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
+{
+	struct pci_dev *pdev = to_pci_dev(to_nvme_dev(ctrl)->dev);
+
+	return snprintf(buf, size, "%s", dev_name(&pdev->dev));
+}
+
 static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
 	.name			= "pcie",
 	.module			= THIS_MODULE,
@@ -2425,6 +2431,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
 	.reg_read64		= nvme_pci_reg_read64,
 	.free_ctrl		= nvme_pci_free_ctrl,
 	.submit_async_event	= nvme_pci_submit_async_event,
+	.get_address		= nvme_pci_get_address,
 };
 
 static int nvme_dev_map(struct nvme_dev *dev)
@@ -2461,10 +2468,13 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev)
 	} else if (pdev->vendor == 0x144d && pdev->device == 0xa804) {
 		/*
 		 * Samsung SSD 960 EVO drops off the PCIe bus after system
-		 * suspend on a Ryzen board, ASUS PRIME B350M-A.
+		 * suspend on a Ryzen board, ASUS PRIME B350M-A, as well as
+		 * within few minutes after bootup on a Coffee Lake board -
+		 * ASUS PRIME Z370-A
 		 */
 		if (dmi_match(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC.") &&
-		    dmi_match(DMI_BOARD_NAME, "PRIME B350M-A"))
+		    (dmi_match(DMI_BOARD_NAME, "PRIME B350M-A") ||
+		     dmi_match(DMI_BOARD_NAME, "PRIME Z370-A")))
 			return NVME_QUIRK_NO_APST;
 	}
 
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 4d84a73..758537e 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -867,6 +867,14 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new)
 	return ret;
 }
 
+static void nvme_rdma_stop_ctrl(struct nvme_ctrl *nctrl)
+{
+	struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl);
+
+	cancel_work_sync(&ctrl->err_work);
+	cancel_delayed_work_sync(&ctrl->reconnect_work);
+}
+
 static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl)
 {
 	struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl);
@@ -899,7 +907,6 @@ static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl)
 		queue_delayed_work(nvme_wq, &ctrl->reconnect_work,
 				ctrl->ctrl.opts->reconnect_delay * HZ);
 	} else {
-		dev_info(ctrl->ctrl.device, "Removing controller...\n");
 		nvme_delete_ctrl(&ctrl->ctrl);
 	}
 }
@@ -974,8 +981,8 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)
 	nvme_start_queues(&ctrl->ctrl);
 
 	if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
-		/* state change failure should never happen */
-		WARN_ON_ONCE(1);
+		/* state change failure is ok if we're in DELETING state */
+		WARN_ON_ONCE(ctrl->ctrl.state != NVME_CTRL_DELETING);
 		return;
 	}
 
@@ -1719,9 +1726,6 @@ static const struct blk_mq_ops nvme_rdma_admin_mq_ops = {
 
 static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown)
 {
-	cancel_work_sync(&ctrl->err_work);
-	cancel_delayed_work_sync(&ctrl->reconnect_work);
-
 	if (ctrl->ctrl.queue_count > 1) {
 		nvme_stop_queues(&ctrl->ctrl);
 		blk_mq_tagset_busy_iter(&ctrl->tag_set,
@@ -1799,6 +1803,7 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {
 	.submit_async_event	= nvme_rdma_submit_async_event,
 	.delete_ctrl		= nvme_rdma_delete_ctrl,
 	.get_address		= nvmf_get_address,
+	.stop_ctrl		= nvme_rdma_stop_ctrl,
 };
 
 static inline bool
@@ -2025,15 +2030,26 @@ static struct nvmf_transport_ops nvme_rdma_transport = {
 static void nvme_rdma_remove_one(struct ib_device *ib_device, void *client_data)
 {
 	struct nvme_rdma_ctrl *ctrl;
+	struct nvme_rdma_device *ndev;
+	bool found = false;
+
+	mutex_lock(&device_list_mutex);
+	list_for_each_entry(ndev, &device_list, entry) {
+		if (ndev->dev == ib_device) {
+			found = true;
+			break;
+		}
+	}
+	mutex_unlock(&device_list_mutex);
+
+	if (!found)
+		return;
 
 	/* Delete all controllers using this device */
 	mutex_lock(&nvme_rdma_ctrl_mutex);
 	list_for_each_entry(ctrl, &nvme_rdma_ctrl_list, list) {
 		if (ctrl->device->dev != ib_device)
 			continue;
-		dev_info(ctrl->ctrl.device,
-			"Removing ctrl: NQN \"%s\", addr %pISp\n",
-			ctrl->ctrl.opts->subsysnqn, &ctrl->addr);
 		nvme_delete_ctrl(&ctrl->ctrl);
 	}
 	mutex_unlock(&nvme_rdma_ctrl_mutex);
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index e6b2d2a..ad9ff27 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -23,6 +23,15 @@
 static const struct config_item_type nvmet_host_type;
 static const struct config_item_type nvmet_subsys_type;
 
+static const struct nvmet_transport_name {
+	u8		type;
+	const char	*name;
+} nvmet_transport_names[] = {
+	{ NVMF_TRTYPE_RDMA,	"rdma" },
+	{ NVMF_TRTYPE_FC,	"fc" },
+	{ NVMF_TRTYPE_LOOP,	"loop" },
+};
+
 /*
  * nvmet_port Generic ConfigFS definitions.
  * Used in any place in the ConfigFS tree that refers to an address.
@@ -208,43 +217,30 @@ CONFIGFS_ATTR(nvmet_, addr_trsvcid);
 static ssize_t nvmet_addr_trtype_show(struct config_item *item,
 		char *page)
 {
-	switch (to_nvmet_port(item)->disc_addr.trtype) {
-	case NVMF_TRTYPE_RDMA:
-		return sprintf(page, "rdma\n");
-	case NVMF_TRTYPE_LOOP:
-		return sprintf(page, "loop\n");
-	case NVMF_TRTYPE_FC:
-		return sprintf(page, "fc\n");
-	default:
-		return sprintf(page, "\n");
+	struct nvmet_port *port = to_nvmet_port(item);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
+		if (port->disc_addr.trtype != nvmet_transport_names[i].type)
+			continue;
+		return sprintf(page, "%s\n", nvmet_transport_names[i].name);
 	}
+
+	return sprintf(page, "\n");
 }
 
 static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
 {
-	port->disc_addr.trtype = NVMF_TRTYPE_RDMA;
-	memset(&port->disc_addr.tsas.rdma, 0, NVMF_TSAS_SIZE);
 	port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED;
 	port->disc_addr.tsas.rdma.prtype = NVMF_RDMA_PRTYPE_NOT_SPECIFIED;
 	port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM;
 }
 
-static void nvmet_port_init_tsas_loop(struct nvmet_port *port)
-{
-	port->disc_addr.trtype = NVMF_TRTYPE_LOOP;
-	memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
-}
-
-static void nvmet_port_init_tsas_fc(struct nvmet_port *port)
-{
-	port->disc_addr.trtype = NVMF_TRTYPE_FC;
-	memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
-}
-
 static ssize_t nvmet_addr_trtype_store(struct config_item *item,
 		const char *page, size_t count)
 {
 	struct nvmet_port *port = to_nvmet_port(item);
+	int i;
 
 	if (port->enabled) {
 		pr_err("Cannot modify address while enabled\n");
@@ -252,17 +248,18 @@ static ssize_t nvmet_addr_trtype_store(struct config_item *item,
 		return -EACCES;
 	}
 
-	if (sysfs_streq(page, "rdma")) {
-		nvmet_port_init_tsas_rdma(port);
-	} else if (sysfs_streq(page, "loop")) {
-		nvmet_port_init_tsas_loop(port);
-	} else if (sysfs_streq(page, "fc")) {
-		nvmet_port_init_tsas_fc(port);
-	} else {
-		pr_err("Invalid value '%s' for trtype\n", page);
-		return -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
+		if (sysfs_streq(page, nvmet_transport_names[i].name))
+			goto found;
 	}
 
+	pr_err("Invalid value '%s' for trtype\n", page);
+	return -EINVAL;
+found:
+	memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
+	port->disc_addr.trtype = nvmet_transport_names[i].type;
+	if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
+		nvmet_port_init_tsas_rdma(port);
 	return count;
 }
 
@@ -333,13 +330,13 @@ static ssize_t nvmet_ns_device_uuid_store(struct config_item *item,
 	return ret ? ret : count;
 }
 
+CONFIGFS_ATTR(nvmet_ns_, device_uuid);
+
 static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
 {
 	return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
 }
 
-CONFIGFS_ATTR(nvmet_ns_, device_uuid);
-
 static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
 		const char *page, size_t count)
 {
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index a78029e..e95424f 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -18,7 +18,7 @@
 
 #include "nvmet.h"
 
-static struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX];
+static const struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX];
 static DEFINE_IDA(cntlid_ida);
 
 /*
@@ -137,7 +137,7 @@ static void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
 	schedule_work(&ctrl->async_event_work);
 }
 
-int nvmet_register_transport(struct nvmet_fabrics_ops *ops)
+int nvmet_register_transport(const struct nvmet_fabrics_ops *ops)
 {
 	int ret = 0;
 
@@ -152,7 +152,7 @@ int nvmet_register_transport(struct nvmet_fabrics_ops *ops)
 }
 EXPORT_SYMBOL_GPL(nvmet_register_transport);
 
-void nvmet_unregister_transport(struct nvmet_fabrics_ops *ops)
+void nvmet_unregister_transport(const struct nvmet_fabrics_ops *ops)
 {
 	down_write(&nvmet_config_sem);
 	nvmet_transports[ops->type] = NULL;
@@ -162,7 +162,7 @@ EXPORT_SYMBOL_GPL(nvmet_unregister_transport);
 
 int nvmet_enable_port(struct nvmet_port *port)
 {
-	struct nvmet_fabrics_ops *ops;
+	const struct nvmet_fabrics_ops *ops;
 	int ret;
 
 	lockdep_assert_held(&nvmet_config_sem);
@@ -195,7 +195,7 @@ int nvmet_enable_port(struct nvmet_port *port)
 
 void nvmet_disable_port(struct nvmet_port *port)
 {
-	struct nvmet_fabrics_ops *ops;
+	const struct nvmet_fabrics_ops *ops;
 
 	lockdep_assert_held(&nvmet_config_sem);
 
@@ -500,7 +500,7 @@ int nvmet_sq_init(struct nvmet_sq *sq)
 EXPORT_SYMBOL_GPL(nvmet_sq_init);
 
 bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
-		struct nvmet_sq *sq, struct nvmet_fabrics_ops *ops)
+		struct nvmet_sq *sq, const struct nvmet_fabrics_ops *ops)
 {
 	u8 flags = req->cmd->common.flags;
 	u16 status;
diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c
index 8f3b57b..a72425d 100644
--- a/drivers/nvme/target/discovery.c
+++ b/drivers/nvme/target/discovery.c
@@ -43,7 +43,8 @@ void nvmet_referral_disable(struct nvmet_port *port)
 }
 
 static void nvmet_format_discovery_entry(struct nvmf_disc_rsp_page_hdr *hdr,
-		struct nvmet_port *port, char *subsys_nqn, u8 type, u32 numrec)
+		struct nvmet_port *port, char *subsys_nqn, char *traddr,
+		u8 type, u32 numrec)
 {
 	struct nvmf_disc_rsp_page_entry *e = &hdr->entries[numrec];
 
@@ -56,11 +57,30 @@ static void nvmet_format_discovery_entry(struct nvmf_disc_rsp_page_hdr *hdr,
 	e->asqsz = cpu_to_le16(NVME_AQ_DEPTH);
 	e->subtype = type;
 	memcpy(e->trsvcid, port->disc_addr.trsvcid, NVMF_TRSVCID_SIZE);
-	memcpy(e->traddr, port->disc_addr.traddr, NVMF_TRADDR_SIZE);
+	memcpy(e->traddr, traddr, NVMF_TRADDR_SIZE);
 	memcpy(e->tsas.common, port->disc_addr.tsas.common, NVMF_TSAS_SIZE);
 	memcpy(e->subnqn, subsys_nqn, NVMF_NQN_SIZE);
 }
 
+/*
+ * nvmet_set_disc_traddr - set a correct discovery log entry traddr
+ *
+ * IP based transports (e.g RDMA) can listen on "any" ipv4/ipv6 addresses
+ * (INADDR_ANY or IN6ADDR_ANY_INIT). The discovery log page traddr reply
+ * must not contain that "any" IP address. If the transport implements
+ * .disc_traddr, use it. this callback will set the discovery traddr
+ * from the req->port address in case the port in question listens
+ * "any" IP address.
+ */
+static void nvmet_set_disc_traddr(struct nvmet_req *req, struct nvmet_port *port,
+		char *traddr)
+{
+	if (req->ops->disc_traddr)
+		req->ops->disc_traddr(req, port, traddr);
+	else
+		memcpy(traddr, port->disc_addr.traddr, NVMF_TRADDR_SIZE);
+}
+
 static void nvmet_execute_get_disc_log_page(struct nvmet_req *req)
 {
 	const int entry_size = sizeof(struct nvmf_disc_rsp_page_entry);
@@ -90,8 +110,11 @@ static void nvmet_execute_get_disc_log_page(struct nvmet_req *req)
 		if (!nvmet_host_allowed(req, p->subsys, ctrl->hostnqn))
 			continue;
 		if (residual_len >= entry_size) {
+			char traddr[NVMF_TRADDR_SIZE];
+
+			nvmet_set_disc_traddr(req, req->port, traddr);
 			nvmet_format_discovery_entry(hdr, req->port,
-					p->subsys->subsysnqn,
+					p->subsys->subsysnqn, traddr,
 					NVME_NQN_NVME, numrec);
 			residual_len -= entry_size;
 		}
@@ -102,6 +125,7 @@ static void nvmet_execute_get_disc_log_page(struct nvmet_req *req)
 		if (residual_len >= entry_size) {
 			nvmet_format_discovery_entry(hdr, r,
 					NVME_DISC_SUBSYS_NAME,
+					r->disc_addr.traddr,
 					NVME_NQN_DISC, numrec);
 			residual_len -= entry_size;
 		}
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
index 9b39a6c..33ee8d3 100644
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -87,6 +87,7 @@ struct nvmet_fc_fcp_iod {
 	struct nvmet_req		req;
 	struct work_struct		work;
 	struct work_struct		done_work;
+	struct work_struct		defer_work;
 
 	struct nvmet_fc_tgtport		*tgtport;
 	struct nvmet_fc_tgt_queue	*queue;
@@ -224,6 +225,7 @@ static DEFINE_IDA(nvmet_fc_tgtport_cnt);
 static void nvmet_fc_handle_ls_rqst_work(struct work_struct *work);
 static void nvmet_fc_handle_fcp_rqst_work(struct work_struct *work);
 static void nvmet_fc_fcp_rqst_op_done_work(struct work_struct *work);
+static void nvmet_fc_fcp_rqst_op_defer_work(struct work_struct *work);
 static void nvmet_fc_tgt_a_put(struct nvmet_fc_tgt_assoc *assoc);
 static int nvmet_fc_tgt_a_get(struct nvmet_fc_tgt_assoc *assoc);
 static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue);
@@ -429,6 +431,7 @@ nvmet_fc_prep_fcp_iodlist(struct nvmet_fc_tgtport *tgtport,
 	for (i = 0; i < queue->sqsize; fod++, i++) {
 		INIT_WORK(&fod->work, nvmet_fc_handle_fcp_rqst_work);
 		INIT_WORK(&fod->done_work, nvmet_fc_fcp_rqst_op_done_work);
+		INIT_WORK(&fod->defer_work, nvmet_fc_fcp_rqst_op_defer_work);
 		fod->tgtport = tgtport;
 		fod->queue = queue;
 		fod->active = false;
@@ -512,6 +515,17 @@ nvmet_fc_queue_fcp_req(struct nvmet_fc_tgtport *tgtport,
 }
 
 static void
+nvmet_fc_fcp_rqst_op_defer_work(struct work_struct *work)
+{
+	struct nvmet_fc_fcp_iod *fod =
+		container_of(work, struct nvmet_fc_fcp_iod, defer_work);
+
+	/* Submit deferred IO for processing */
+	nvmet_fc_queue_fcp_req(fod->tgtport, fod->queue, fod->fcpreq);
+
+}
+
+static void
 nvmet_fc_free_fcp_iod(struct nvmet_fc_tgt_queue *queue,
 			struct nvmet_fc_fcp_iod *fod)
 {
@@ -568,13 +582,12 @@ nvmet_fc_free_fcp_iod(struct nvmet_fc_tgt_queue *queue,
 	/* inform LLDD IO is now being processed */
 	tgtport->ops->defer_rcv(&tgtport->fc_target_port, fcpreq);
 
-	/* Submit deferred IO for processing */
-	nvmet_fc_queue_fcp_req(tgtport, queue, fcpreq);
-
 	/*
 	 * Leave the queue lookup get reference taken when
 	 * fod was originally allocated.
 	 */
+
+	queue_work(queue->work_q, &fod->defer_work);
 }
 
 static int
@@ -1550,7 +1563,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
 
 static void nvmet_fc_fcp_nvme_cmd_done(struct nvmet_req *nvme_req);
 
-static struct nvmet_fabrics_ops nvmet_fc_tgt_fcp_ops;
+static const struct nvmet_fabrics_ops nvmet_fc_tgt_fcp_ops;
 
 static void
 nvmet_fc_xmt_ls_rsp_done(struct nvmefc_tgt_ls_req *lsreq)
@@ -2505,7 +2518,7 @@ nvmet_fc_remove_port(struct nvmet_port *port)
 	/* nothing to do */
 }
 
-static struct nvmet_fabrics_ops nvmet_fc_tgt_fcp_ops = {
+static const struct nvmet_fabrics_ops nvmet_fc_tgt_fcp_ops = {
 	.owner			= THIS_MODULE,
 	.type			= NVMF_TRTYPE_FC,
 	.msdbd			= 1,
diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c
index 861d150..a350765 100644
--- a/drivers/nvme/target/loop.c
+++ b/drivers/nvme/target/loop.c
@@ -71,7 +71,7 @@ static DEFINE_MUTEX(nvme_loop_ctrl_mutex);
 static void nvme_loop_queue_response(struct nvmet_req *nvme_req);
 static void nvme_loop_delete_ctrl(struct nvmet_ctrl *ctrl);
 
-static struct nvmet_fabrics_ops nvme_loop_ops;
+static const struct nvmet_fabrics_ops nvme_loop_ops;
 
 static inline int nvme_loop_queue_idx(struct nvme_loop_queue *queue)
 {
@@ -675,7 +675,7 @@ static void nvme_loop_remove_port(struct nvmet_port *port)
 		nvmet_loop_port = NULL;
 }
 
-static struct nvmet_fabrics_ops nvme_loop_ops = {
+static const struct nvmet_fabrics_ops nvme_loop_ops = {
 	.owner		= THIS_MODULE,
 	.type		= NVMF_TRTYPE_LOOP,
 	.add_port	= nvme_loop_add_port,
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 417f6c0..15fd84a 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -130,7 +130,7 @@ struct nvmet_ctrl {
 	struct delayed_work	ka_work;
 	struct work_struct	fatal_err_work;
 
-	struct nvmet_fabrics_ops *ops;
+	const struct nvmet_fabrics_ops *ops;
 
 	char			subsysnqn[NVMF_NQN_FIELD_LEN];
 	char			hostnqn[NVMF_NQN_FIELD_LEN];
@@ -209,6 +209,8 @@ struct nvmet_fabrics_ops {
 	int (*add_port)(struct nvmet_port *port);
 	void (*remove_port)(struct nvmet_port *port);
 	void (*delete_ctrl)(struct nvmet_ctrl *ctrl);
+	void (*disc_traddr)(struct nvmet_req *req,
+			struct nvmet_port *port, char *traddr);
 };
 
 #define NVMET_MAX_INLINE_BIOVEC	8
@@ -231,7 +233,7 @@ struct nvmet_req {
 	struct nvmet_port	*port;
 
 	void (*execute)(struct nvmet_req *req);
-	struct nvmet_fabrics_ops *ops;
+	const struct nvmet_fabrics_ops *ops;
 };
 
 static inline void nvmet_set_status(struct nvmet_req *req, u16 status)
@@ -267,7 +269,7 @@ u16 nvmet_parse_discovery_cmd(struct nvmet_req *req);
 u16 nvmet_parse_fabrics_cmd(struct nvmet_req *req);
 
 bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
-		struct nvmet_sq *sq, struct nvmet_fabrics_ops *ops);
+		struct nvmet_sq *sq, const struct nvmet_fabrics_ops *ops);
 void nvmet_req_uninit(struct nvmet_req *req);
 void nvmet_req_execute(struct nvmet_req *req);
 void nvmet_req_complete(struct nvmet_req *req, u16 status);
@@ -301,8 +303,8 @@ void nvmet_ns_disable(struct nvmet_ns *ns);
 struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid);
 void nvmet_ns_free(struct nvmet_ns *ns);
 
-int nvmet_register_transport(struct nvmet_fabrics_ops *ops);
-void nvmet_unregister_transport(struct nvmet_fabrics_ops *ops);
+int nvmet_register_transport(const struct nvmet_fabrics_ops *ops);
+void nvmet_unregister_transport(const struct nvmet_fabrics_ops *ops);
 
 int nvmet_enable_port(struct nvmet_port *port);
 void nvmet_disable_port(struct nvmet_port *port);
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 978e169..52e0c5d 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -77,7 +77,6 @@ enum nvmet_rdma_queue_state {
 	NVMET_RDMA_Q_CONNECTING,
 	NVMET_RDMA_Q_LIVE,
 	NVMET_RDMA_Q_DISCONNECTING,
-	NVMET_RDMA_IN_DEVICE_REMOVAL,
 };
 
 struct nvmet_rdma_queue {
@@ -137,7 +136,7 @@ static void nvmet_rdma_read_data_done(struct ib_cq *cq, struct ib_wc *wc);
 static void nvmet_rdma_qp_event(struct ib_event *event, void *priv);
 static void nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue);
 
-static struct nvmet_fabrics_ops nvmet_rdma_ops;
+static const struct nvmet_fabrics_ops nvmet_rdma_ops;
 
 /* XXX: really should move to a generic header sooner or later.. */
 static inline u32 get_unaligned_le24(const u8 *p)
@@ -914,8 +913,11 @@ static int nvmet_rdma_create_queue_ib(struct nvmet_rdma_queue *queue)
 
 static void nvmet_rdma_destroy_queue_ib(struct nvmet_rdma_queue *queue)
 {
-	ib_drain_qp(queue->cm_id->qp);
-	rdma_destroy_qp(queue->cm_id);
+	struct ib_qp *qp = queue->cm_id->qp;
+
+	ib_drain_qp(qp);
+	rdma_destroy_id(queue->cm_id);
+	ib_destroy_qp(qp);
 	ib_free_cq(queue->cq);
 }
 
@@ -940,15 +942,10 @@ static void nvmet_rdma_release_queue_work(struct work_struct *w)
 {
 	struct nvmet_rdma_queue *queue =
 		container_of(w, struct nvmet_rdma_queue, release_work);
-	struct rdma_cm_id *cm_id = queue->cm_id;
 	struct nvmet_rdma_device *dev = queue->dev;
-	enum nvmet_rdma_queue_state state = queue->state;
 
 	nvmet_rdma_free_queue(queue);
 
-	if (state != NVMET_RDMA_IN_DEVICE_REMOVAL)
-		rdma_destroy_id(cm_id);
-
 	kref_put(&dev->ref, nvmet_rdma_free_dev);
 }
 
@@ -1153,8 +1150,11 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
 	}
 
 	ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn);
-	if (ret)
-		goto release_queue;
+	if (ret) {
+		schedule_work(&queue->release_work);
+		/* Destroying rdma_cm id is not needed here */
+		return 0;
+	}
 
 	mutex_lock(&nvmet_rdma_queue_mutex);
 	list_add_tail(&queue->queue_list, &nvmet_rdma_queue_list);
@@ -1162,8 +1162,6 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
 
 	return 0;
 
-release_queue:
-	nvmet_rdma_free_queue(queue);
 put_device:
 	kref_put(&ndev->ref, nvmet_rdma_free_dev);
 
@@ -1209,7 +1207,6 @@ static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue)
 	case NVMET_RDMA_Q_CONNECTING:
 	case NVMET_RDMA_Q_LIVE:
 		queue->state = NVMET_RDMA_Q_DISCONNECTING;
-	case NVMET_RDMA_IN_DEVICE_REMOVAL:
 		disconnect = true;
 		break;
 	case NVMET_RDMA_Q_DISCONNECTING:
@@ -1322,13 +1319,7 @@ static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id,
 	case RDMA_CM_EVENT_ADDR_CHANGE:
 	case RDMA_CM_EVENT_DISCONNECTED:
 	case RDMA_CM_EVENT_TIMEWAIT_EXIT:
-		/*
-		 * We might end up here when we already freed the qp
-		 * which means queue release sequence is in progress,
-		 * so don't get in the way...
-		 */
-		if (queue)
-			nvmet_rdma_queue_disconnect(queue);
+		nvmet_rdma_queue_disconnect(queue);
 		break;
 	case RDMA_CM_EVENT_DEVICE_REMOVAL:
 		ret = nvmet_rdma_device_removal(cm_id, queue);
@@ -1445,7 +1436,24 @@ static void nvmet_rdma_remove_port(struct nvmet_port *port)
 		rdma_destroy_id(cm_id);
 }
 
-static struct nvmet_fabrics_ops nvmet_rdma_ops = {
+static void nvmet_rdma_disc_port_addr(struct nvmet_req *req,
+		struct nvmet_port *port, char *traddr)
+{
+	struct rdma_cm_id *cm_id = port->priv;
+
+	if (inet_addr_is_any((struct sockaddr *)&cm_id->route.addr.src_addr)) {
+		struct nvmet_rdma_rsp *rsp =
+			container_of(req, struct nvmet_rdma_rsp, req);
+		struct rdma_cm_id *req_cm_id = rsp->queue->cm_id;
+		struct sockaddr *addr = (void *)&req_cm_id->route.addr.src_addr;
+
+		sprintf(traddr, "%pISc", addr);
+	} else {
+		memcpy(traddr, port->disc_addr.traddr, NVMF_TRADDR_SIZE);
+	}
+}
+
+static const struct nvmet_fabrics_ops nvmet_rdma_ops = {
 	.owner			= THIS_MODULE,
 	.type			= NVMF_TRTYPE_RDMA,
 	.sqe_inline_size	= NVMET_RDMA_INLINE_DATA_SIZE,
@@ -1455,13 +1463,31 @@ static struct nvmet_fabrics_ops nvmet_rdma_ops = {
 	.remove_port		= nvmet_rdma_remove_port,
 	.queue_response		= nvmet_rdma_queue_response,
 	.delete_ctrl		= nvmet_rdma_delete_ctrl,
+	.disc_traddr		= nvmet_rdma_disc_port_addr,
 };
 
 static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data)
 {
 	struct nvmet_rdma_queue *queue, *tmp;
+	struct nvmet_rdma_device *ndev;
+	bool found = false;
 
-	/* Device is being removed, delete all queues using this device */
+	mutex_lock(&device_list_mutex);
+	list_for_each_entry(ndev, &device_list, entry) {
+		if (ndev->device == ib_device) {
+			found = true;
+			break;
+		}
+	}
+	mutex_unlock(&device_list_mutex);
+
+	if (!found)
+		return;
+
+	/*
+	 * IB Device that is used by nvmet controllers is being removed,
+	 * delete all queues using this device.
+	 */
 	mutex_lock(&nvmet_rdma_queue_mutex);
 	list_for_each_entry_safe(queue, tmp, &nvmet_rdma_queue_list,
 				 queue_list) {
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ad28de9..848f549 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -91,10 +91,72 @@ int __weak of_node_to_nid(struct device_node *np)
 }
 #endif
 
+static struct device_node **phandle_cache;
+static u32 phandle_cache_mask;
+
+/*
+ * Assumptions behind phandle_cache implementation:
+ *   - phandle property values are in a contiguous range of 1..n
+ *
+ * If the assumptions do not hold, then
+ *   - the phandle lookup overhead reduction provided by the cache
+ *     will likely be less
+ */
+static void of_populate_phandle_cache(void)
+{
+	unsigned long flags;
+	u32 cache_entries;
+	struct device_node *np;
+	u32 phandles = 0;
+
+	raw_spin_lock_irqsave(&devtree_lock, flags);
+
+	kfree(phandle_cache);
+	phandle_cache = NULL;
+
+	for_each_of_allnodes(np)
+		if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
+			phandles++;
+
+	cache_entries = roundup_pow_of_two(phandles);
+	phandle_cache_mask = cache_entries - 1;
+
+	phandle_cache = kcalloc(cache_entries, sizeof(*phandle_cache),
+				GFP_ATOMIC);
+	if (!phandle_cache)
+		goto out;
+
+	for_each_of_allnodes(np)
+		if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
+			phandle_cache[np->phandle & phandle_cache_mask] = np;
+
+out:
+	raw_spin_unlock_irqrestore(&devtree_lock, flags);
+}
+
+#ifndef CONFIG_MODULES
+static int __init of_free_phandle_cache(void)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&devtree_lock, flags);
+
+	kfree(phandle_cache);
+	phandle_cache = NULL;
+
+	raw_spin_unlock_irqrestore(&devtree_lock, flags);
+
+	return 0;
+}
+late_initcall_sync(of_free_phandle_cache);
+#endif
+
 void __init of_core_init(void)
 {
 	struct device_node *np;
 
+	of_populate_phandle_cache();
+
 	/* Create the kset, and register existing nodes */
 	mutex_lock(&of_mutex);
 	of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
@@ -1021,16 +1083,32 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
  */
 struct device_node *of_find_node_by_phandle(phandle handle)
 {
-	struct device_node *np;
+	struct device_node *np = NULL;
 	unsigned long flags;
+	phandle masked_handle;
 
 	if (!handle)
 		return NULL;
 
 	raw_spin_lock_irqsave(&devtree_lock, flags);
-	for_each_of_allnodes(np)
-		if (np->phandle == handle)
-			break;
+
+	masked_handle = handle & phandle_cache_mask;
+
+	if (phandle_cache) {
+		if (phandle_cache[masked_handle] &&
+		    handle == phandle_cache[masked_handle]->phandle)
+			np = phandle_cache[masked_handle];
+	}
+
+	if (!np) {
+		for_each_of_allnodes(np)
+			if (np->phandle == handle) {
+				if (phandle_cache)
+					phandle_cache[masked_handle] = np;
+				break;
+			}
+	}
+
 	of_node_get(np);
 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
 	return np;
@@ -1284,6 +1362,190 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
 EXPORT_SYMBOL(of_parse_phandle_with_args);
 
 /**
+ * of_parse_phandle_with_args_map() - Find a node pointed by phandle in a list and remap it
+ * @np:		pointer to a device tree node containing a list
+ * @list_name:	property name that contains a list
+ * @stem_name:	stem of property names that specify phandles' arguments count
+ * @index:	index of a phandle to parse out
+ * @out_args:	optional pointer to output arguments structure (will be filled)
+ *
+ * This function is useful to parse lists of phandles and their arguments.
+ * Returns 0 on success and fills out_args, on error returns appropriate errno
+ * value. The difference between this function and of_parse_phandle_with_args()
+ * is that this API remaps a phandle if the node the phandle points to has
+ * a <@stem_name>-map property.
+ *
+ * Caller is responsible to call of_node_put() on the returned out_args->np
+ * pointer.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ *	#list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ *	#list-cells = <1>;
+ * }
+ *
+ * phandle3: node3 {
+ * 	#list-cells = <1>;
+ * 	list-map = <0 &phandle2 3>,
+ * 		   <1 &phandle2 2>,
+ * 		   <2 &phandle1 5 1>;
+ *	list-map-mask = <0x3>;
+ * };
+ *
+ * node4 {
+ *	list = <&phandle1 1 2 &phandle3 0>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * of_parse_phandle_with_args(node4, "list", "list", 1, &args);
+ */
+int of_parse_phandle_with_args_map(const struct device_node *np,
+				   const char *list_name,
+				   const char *stem_name,
+				   int index, struct of_phandle_args *out_args)
+{
+	char *cells_name, *map_name = NULL, *mask_name = NULL;
+	char *pass_name = NULL;
+	struct device_node *cur, *new = NULL;
+	const __be32 *map, *mask, *pass;
+	static const __be32 dummy_mask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 };
+	static const __be32 dummy_pass[] = { [0 ... MAX_PHANDLE_ARGS] = 0 };
+	__be32 initial_match_array[MAX_PHANDLE_ARGS];
+	const __be32 *match_array = initial_match_array;
+	int i, ret, map_len, match;
+	u32 list_size, new_size;
+
+	if (index < 0)
+		return -EINVAL;
+
+	cells_name = kasprintf(GFP_KERNEL, "#%s-cells", stem_name);
+	if (!cells_name)
+		return -ENOMEM;
+
+	ret = -ENOMEM;
+	map_name = kasprintf(GFP_KERNEL, "%s-map", stem_name);
+	if (!map_name)
+		goto free;
+
+	mask_name = kasprintf(GFP_KERNEL, "%s-map-mask", stem_name);
+	if (!mask_name)
+		goto free;
+
+	pass_name = kasprintf(GFP_KERNEL, "%s-map-pass-thru", stem_name);
+	if (!pass_name)
+		goto free;
+
+	ret = __of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
+					   out_args);
+	if (ret)
+		goto free;
+
+	/* Get the #<list>-cells property */
+	cur = out_args->np;
+	ret = of_property_read_u32(cur, cells_name, &list_size);
+	if (ret < 0)
+		goto put;
+
+	/* Precalculate the match array - this simplifies match loop */
+	for (i = 0; i < list_size; i++)
+		initial_match_array[i] = cpu_to_be32(out_args->args[i]);
+
+	ret = -EINVAL;
+	while (cur) {
+		/* Get the <list>-map property */
+		map = of_get_property(cur, map_name, &map_len);
+		if (!map) {
+			ret = 0;
+			goto free;
+		}
+		map_len /= sizeof(u32);
+
+		/* Get the <list>-map-mask property (optional) */
+		mask = of_get_property(cur, mask_name, NULL);
+		if (!mask)
+			mask = dummy_mask;
+		/* Iterate through <list>-map property */
+		match = 0;
+		while (map_len > (list_size + 1) && !match) {
+			/* Compare specifiers */
+			match = 1;
+			for (i = 0; i < list_size; i++, map_len--)
+				match &= !((match_array[i] ^ *map++) & mask[i]);
+
+			of_node_put(new);
+			new = of_find_node_by_phandle(be32_to_cpup(map));
+			map++;
+			map_len--;
+
+			/* Check if not found */
+			if (!new)
+				goto put;
+
+			if (!of_device_is_available(new))
+				match = 0;
+
+			ret = of_property_read_u32(new, cells_name, &new_size);
+			if (ret)
+				goto put;
+
+			/* Check for malformed properties */
+			if (WARN_ON(new_size > MAX_PHANDLE_ARGS))
+				goto put;
+			if (map_len < new_size)
+				goto put;
+
+			/* Move forward by new node's #<list>-cells amount */
+			map += new_size;
+			map_len -= new_size;
+		}
+		if (!match)
+			goto put;
+
+		/* Get the <list>-map-pass-thru property (optional) */
+		pass = of_get_property(cur, pass_name, NULL);
+		if (!pass)
+			pass = dummy_pass;
+
+		/*
+		 * Successfully parsed a <list>-map translation; copy new
+		 * specifier into the out_args structure, keeping the
+		 * bits specified in <list>-map-pass-thru.
+		 */
+		match_array = map - new_size;
+		for (i = 0; i < new_size; i++) {
+			__be32 val = *(map - new_size + i);
+
+			if (i < list_size) {
+				val &= ~pass[i];
+				val |= cpu_to_be32(out_args->args[i]) & pass[i];
+			}
+
+			out_args->args[i] = be32_to_cpu(val);
+		}
+		out_args->args_count = list_size = new_size;
+		/* Iterate again with new provider */
+		out_args->np = new;
+		of_node_put(cur);
+		cur = new;
+	}
+put:
+	of_node_put(cur);
+	of_node_put(new);
+free:
+	kfree(mask_name);
+	kfree(map_name);
+	kfree(cells_name);
+	kfree(pass_name);
+
+	return ret;
+}
+EXPORT_SYMBOL(of_parse_phandle_with_args_map);
+
+/**
  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
  * @np:		pointer to a device tree node containing a list
  * @list_name:	property name that contains a list
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 7bb33d2..f4f8ed9 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -383,25 +383,24 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
 
 /**
  * __of_node_dup() - Duplicate or create an empty device node dynamically.
- * @fmt: Format string (plus vargs) for new full name of the device node
+ * @np:		if not NULL, contains properties to be duplicated in new node
+ * @full_name:	string value to be duplicated into new node's full_name field
  *
- * Create an device tree node, either by duplicating an empty node or by allocating
- * an empty one suitable for further modification.  The node data are
- * dynamically allocated and all the node flags have the OF_DYNAMIC &
- * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of
- * memory error.
+ * Create a device tree node, optionally duplicating the properties of
+ * another node.  The node data are dynamically allocated and all the node
+ * flags have the OF_DYNAMIC & OF_DETACHED bits set.
+ *
+ * Returns the newly allocated node or NULL on out of memory error.
  */
-struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...)
+struct device_node *__of_node_dup(const struct device_node *np,
+				  const char *full_name)
 {
-	va_list vargs;
 	struct device_node *node;
 
 	node = kzalloc(sizeof(*node), GFP_KERNEL);
 	if (!node)
 		return NULL;
-	va_start(vargs, fmt);
-	node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs);
-	va_end(vargs);
+	node->full_name = kstrdup(full_name, GFP_KERNEL);
 	if (!node->full_name) {
 		kfree(node);
 		return NULL;
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 0c609e7d..891d780 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -104,7 +104,8 @@ extern void *__unflatten_device_tree(const void *blob,
  * own the devtree lock or work on detached trees only.
  */
 struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags);
-__printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...);
+struct device_node *__of_node_dup(const struct device_node *np,
+				  const char *full_name);
 
 struct device_node *__of_find_node_by_path(struct device_node *parent,
 						const char *path);
@@ -131,6 +132,9 @@ extern void __of_detach_node_sysfs(struct device_node *np);
 extern void __of_sysfs_remove_bin_file(struct device_node *np,
 				       struct property *prop);
 
+/* illegal phandle value (set when unresolved) */
+#define OF_PHANDLE_ILLEGAL	0xdeadbeef
+
 /* iterators for transactions, used for overlays */
 /* forward iterator */
 #define for_each_transaction_entry(_oft, _te) \
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index b930e05..b35fe88 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -312,7 +312,20 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
  * If @node has child nodes, add the children recursively via
  * build_changeset_next_level().
  *
- * NOTE: Multiple mods of created nodes not supported.
+ * NOTE_1: A live devicetree created from a flattened device tree (FDT) will
+ *       not contain the full path in node->full_name.  Thus an overlay
+ *       created from an FDT also will not contain the full path in
+ *       node->full_name.  However, a live devicetree created from Open
+ *       Firmware may have the full path in node->full_name.
+ *
+ *       add_changeset_node() follows the FDT convention and does not include
+ *       the full path in node->full_name.  Even though it expects the overlay
+ *       to not contain the full path, it uses kbasename() to remove the
+ *       full path should it exist.  It also uses kbasename() in comparisons
+ *       to nodes in the live devicetree so that it can apply an overlay to
+ *       a live devicetree created from Open Firmware.
+ *
+ * NOTE_2: Multiple mods of created nodes not supported.
  *       If more than one fragment contains a node that does not already exist
  *       in the live tree, then for each fragment of_changeset_attach_node()
  *       will add a changeset entry to add the node.  When the changeset is
@@ -339,8 +352,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
 			break;
 
 	if (!tchild) {
-		tchild = __of_node_dup(node, "%pOF/%s",
-				       target_node, node_kbasename);
+		tchild = __of_node_dup(node, node_kbasename);
 		if (!tchild)
 			return -ENOMEM;
 
@@ -958,7 +970,7 @@ static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
  * @ovcs_id:	Pointer to overlay changeset id
  *
  * Removes an overlay if it is permissible.  @ovcs_id was previously returned
- * by of_overlay_apply().
+ * by of_overlay_fdt_apply().
  *
  * If an error occurred while attempting to revert the overlay changeset,
  * then an attempt is made to re-apply any changeset entry that was
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index b2f6451..65d0b7a 100644
--- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c
@@ -19,9 +19,6 @@
 
 #include "of_private.h"
 
-/* illegal phandle value (set when unresolved) */
-#define OF_PHANDLE_ILLEGAL	0xdeadbeef
-
 static phandle live_tree_max_phandle(void)
 {
 	struct device_node *node;
diff --git a/drivers/of/unittest-data/tests-phandle.dtsi b/drivers/of/unittest-data/tests-phandle.dtsi
index 3c2f09e..6b33be4 100644
--- a/drivers/of/unittest-data/tests-phandle.dtsi
+++ b/drivers/of/unittest-data/tests-phandle.dtsi
@@ -26,6 +26,18 @@
 				#phandle-cells = <3>;
 			};
 
+			provider4: provider4 {
+				#phandle-cells = <2>;
+				phandle-map = <0 1 &provider1 3>,
+					      <4 0 &provider0>,
+					      <16 5 &provider3 3 5 0>,
+					      <200 8 &provider2 23 6>,
+					      <19 0 &provider2 15 0>,
+					      <2 3 &provider3 2 5 3>;
+				phandle-map-mask = <0xff 0xf>;
+				phandle-map-pass-thru = <0x0 0xf0>;
+			};
+
 			consumer-a {
 				phandle-list =	<&provider1 1>,
 						<&provider2 2 0>,
@@ -44,6 +56,19 @@
 				unterminated-string = [40 41 42 43];
 				unterminated-string-list = "first", "second", [40 41 42 43];
 			};
+
+			consumer-b {
+				phandle-list =	<&provider1 1>,
+						<&provider4 2 3>,
+						<0>,
+						<&provider4 4 0x100>,
+						<&provider4 0 0x61>,
+						<&provider0>,
+						<&provider4 19 0x20>;
+				phandle-list-bad-phandle = <12345678 0 0>;
+				phandle-list-bad-args = <&provider2 1 0>,
+							<&provider4 0>;
+			};
 		};
 	};
 };
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index a23b547..02c5984 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -45,8 +45,6 @@ static struct unittest_results {
 	failed; \
 })
 
-static int __init overlay_data_apply(const char *overlay_name, int *overlay_id);
-
 static void __init of_unittest_find_node_by_name(void)
 {
 	struct device_node *np;
@@ -254,12 +252,18 @@ static void __init of_unittest_check_tree_linkage(void)
 static void __init of_unittest_printf_one(struct device_node *np, const char *fmt,
 					  const char *expected)
 {
-	unsigned char buf[strlen(expected)+10];
+	unsigned char *buf;
+	int buf_size;
 	int size, i;
 
+	buf_size = strlen(expected) + 10;
+	buf = kmalloc(buf_size, GFP_KERNEL);
+	if (!buf)
+		return;
+
 	/* Baseline; check conversion with a large size limit */
-	memset(buf, 0xff, sizeof(buf));
-	size = snprintf(buf, sizeof(buf) - 2, fmt, np);
+	memset(buf, 0xff, buf_size);
+	size = snprintf(buf, buf_size - 2, fmt, np);
 
 	/* use strcmp() instead of strncmp() here to be absolutely sure strings match */
 	unittest((strcmp(buf, expected) == 0) && (buf[size+1] == 0xff),
@@ -270,12 +274,13 @@ static void __init of_unittest_printf_one(struct device_node *np, const char *fm
 	size++;
 	for (i = 0; i < 2; i++, size--) {
 		/* Clear the buffer, and make sure it works correctly still */
-		memset(buf, 0xff, sizeof(buf));
+		memset(buf, 0xff, buf_size);
 		snprintf(buf, size+1, fmt, np);
 		unittest(strncmp(buf, expected, size) == 0 && (buf[size+1] == 0xff),
 			"snprintf failed; size=%i fmt='%s' expected='%s' rslt='%s'\n",
 			size, fmt, expected, buf);
 	}
+	kfree(buf);
 }
 
 static void __init of_unittest_printf(void)
@@ -455,6 +460,125 @@ static void __init of_unittest_parse_phandle_with_args(void)
 	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
 }
 
+static void __init of_unittest_parse_phandle_with_args_map(void)
+{
+	struct device_node *np, *p0, *p1, *p2, *p3;
+	struct of_phandle_args args;
+	int i, rc;
+
+	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b");
+	if (!np) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0");
+	if (!p0) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1");
+	if (!p1) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2");
+	if (!p2) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3");
+	if (!p3) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");
+	unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);
+
+	for (i = 0; i < 8; i++) {
+		bool passed = true;
+
+		rc = of_parse_phandle_with_args_map(np, "phandle-list",
+						    "phandle", i, &args);
+
+		/* Test the values from tests-phandle.dtsi */
+		switch (i) {
+		case 0:
+			passed &= !rc;
+			passed &= (args.np == p1);
+			passed &= (args.args_count == 1);
+			passed &= (args.args[0] == 1);
+			break;
+		case 1:
+			passed &= !rc;
+			passed &= (args.np == p3);
+			passed &= (args.args_count == 3);
+			passed &= (args.args[0] == 2);
+			passed &= (args.args[1] == 5);
+			passed &= (args.args[2] == 3);
+			break;
+		case 2:
+			passed &= (rc == -ENOENT);
+			break;
+		case 3:
+			passed &= !rc;
+			passed &= (args.np == p0);
+			passed &= (args.args_count == 0);
+			break;
+		case 4:
+			passed &= !rc;
+			passed &= (args.np == p1);
+			passed &= (args.args_count == 1);
+			passed &= (args.args[0] == 3);
+			break;
+		case 5:
+			passed &= !rc;
+			passed &= (args.np == p0);
+			passed &= (args.args_count == 0);
+			break;
+		case 6:
+			passed &= !rc;
+			passed &= (args.np == p2);
+			passed &= (args.args_count == 2);
+			passed &= (args.args[0] == 15);
+			passed &= (args.args[1] == 0x20);
+			break;
+		case 7:
+			passed &= (rc == -ENOENT);
+			break;
+		default:
+			passed = false;
+		}
+
+		unittest(passed, "index %i - data error on node %s rc=%i\n",
+			 i, args.np->full_name, rc);
+	}
+
+	/* Check for missing list property */
+	rc = of_parse_phandle_with_args_map(np, "phandle-list-missing",
+					    "phandle", 0, &args);
+	unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
+
+	/* Check for missing cells,map,mask property */
+	rc = of_parse_phandle_with_args_map(np, "phandle-list",
+					    "phandle-missing", 0, &args);
+	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
+
+	/* Check for bad phandle in list */
+	rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-phandle",
+					    "phandle", 0, &args);
+	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
+
+	/* Check for incorrectly formed argument list */
+	rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-args",
+					    "phandle", 1, &args);
+	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
+}
+
 static void __init of_unittest_property_string(void)
 {
 	const char *strings[4];
@@ -564,42 +688,72 @@ static void __init of_unittest_property_copy(void)
 static void __init of_unittest_changeset(void)
 {
 #ifdef CONFIG_OF_DYNAMIC
-	struct property *ppadd, padd = { .name = "prop-add", .length = 0, .value = "" };
+	struct property *ppadd, padd = { .name = "prop-add", .length = 1, .value = "" };
+	struct property *ppname_n1,  pname_n1  = { .name = "name", .length = 3, .value = "n1"  };
+	struct property *ppname_n2,  pname_n2  = { .name = "name", .length = 3, .value = "n2"  };
+	struct property *ppname_n21, pname_n21 = { .name = "name", .length = 3, .value = "n21" };
 	struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" };
 	struct property *ppremove;
-	struct device_node *n1, *n2, *n21, *nremove, *parent, *np;
+	struct device_node *n1, *n2, *n21, *nchangeset, *nremove, *parent, *np;
 	struct of_changeset chgset;
 
-	n1 = __of_node_dup(NULL, "/testcase-data/changeset/n1");
+	n1 = __of_node_dup(NULL, "n1");
 	unittest(n1, "testcase setup failure\n");
-	n2 = __of_node_dup(NULL, "/testcase-data/changeset/n2");
+
+	n2 = __of_node_dup(NULL, "n2");
 	unittest(n2, "testcase setup failure\n");
-	n21 = __of_node_dup(NULL, "%s/%s", "/testcase-data/changeset/n2", "n21");
+
+	n21 = __of_node_dup(NULL, "n21");
 	unittest(n21, "testcase setup failure %p\n", n21);
-	nremove = of_find_node_by_path("/testcase-data/changeset/node-remove");
+
+	nchangeset = of_find_node_by_path("/testcase-data/changeset");
+	nremove = of_get_child_by_name(nchangeset, "node-remove");
 	unittest(nremove, "testcase setup failure\n");
+
 	ppadd = __of_prop_dup(&padd, GFP_KERNEL);
 	unittest(ppadd, "testcase setup failure\n");
+
+	ppname_n1  = __of_prop_dup(&pname_n1, GFP_KERNEL);
+	unittest(ppname_n1, "testcase setup failure\n");
+
+	ppname_n2  = __of_prop_dup(&pname_n2, GFP_KERNEL);
+	unittest(ppname_n2, "testcase setup failure\n");
+
+	ppname_n21 = __of_prop_dup(&pname_n21, GFP_KERNEL);
+	unittest(ppname_n21, "testcase setup failure\n");
+
 	ppupdate = __of_prop_dup(&pupdate, GFP_KERNEL);
 	unittest(ppupdate, "testcase setup failure\n");
-	parent = nremove->parent;
+
+	parent = nchangeset;
 	n1->parent = parent;
 	n2->parent = parent;
 	n21->parent = n2;
-	n2->child = n21;
+
 	ppremove = of_find_property(parent, "prop-remove", NULL);
 	unittest(ppremove, "failed to find removal prop");
 
 	of_changeset_init(&chgset);
+
 	unittest(!of_changeset_attach_node(&chgset, n1), "fail attach n1\n");
+	unittest(!of_changeset_add_property(&chgset, n1, ppname_n1), "fail add prop name\n");
+
 	unittest(!of_changeset_attach_node(&chgset, n2), "fail attach n2\n");
+	unittest(!of_changeset_add_property(&chgset, n2, ppname_n2), "fail add prop name\n");
+
 	unittest(!of_changeset_detach_node(&chgset, nremove), "fail remove node\n");
+	unittest(!of_changeset_add_property(&chgset, n21, ppname_n21), "fail add prop name\n");
+
 	unittest(!of_changeset_attach_node(&chgset, n21), "fail attach n21\n");
-	unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop\n");
+
+	unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop prop-add\n");
 	unittest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n");
 	unittest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n");
+
 	unittest(!of_changeset_apply(&chgset), "apply failed\n");
 
+	of_node_put(nchangeset);
+
 	/* Make sure node names are constructed correctly */
 	unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")),
 		 "'%pOF' not added\n", n21);
@@ -1036,6 +1190,7 @@ static int __init unittest_data_add(void)
 }
 
 #ifdef CONFIG_OF_OVERLAY
+static int __init overlay_data_apply(const char *overlay_name, int *overlay_id);
 
 static int unittest_probe(struct platform_device *pdev)
 {
@@ -1267,26 +1422,18 @@ static void of_unittest_destroy_tracked_overlays(void)
 static int __init of_unittest_apply_overlay(int overlay_nr, int unittest_nr,
 		int *overlay_id)
 {
-	struct device_node *np = NULL;
 	const char *overlay_name;
-	int ret;
 
 	overlay_name = overlay_name_from_nr(overlay_nr);
 
-	ret = overlay_data_apply(overlay_name, overlay_id);
-	if (!ret) {
+	if (!overlay_data_apply(overlay_name, overlay_id)) {
 		unittest(0, "could not apply overlay \"%s\"\n",
 				overlay_name);
-		goto out;
+		return -EFAULT;
 	}
 	of_unittest_track_overlay(*overlay_id);
 
-	ret = 0;
-
-out:
-	of_node_put(np);
-
-	return ret;
+	return 0;
 }
 
 /* apply an overlay while checking before and after states */
@@ -1380,11 +1527,8 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,
 /* test activation of device */
 static void __init of_unittest_overlay_0(void)
 {
-	int ret;
-
 	/* device should enable */
-	ret = of_unittest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 0);
@@ -1393,11 +1537,8 @@ static void __init of_unittest_overlay_0(void)
 /* test deactivation of device */
 static void __init of_unittest_overlay_1(void)
 {
-	int ret;
-
 	/* device should disable */
-	ret = of_unittest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 1);
@@ -1406,11 +1547,8 @@ static void __init of_unittest_overlay_1(void)
 /* test activation of device */
 static void __init of_unittest_overlay_2(void)
 {
-	int ret;
-
 	/* device should enable */
-	ret = of_unittest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 2);
@@ -1419,11 +1557,8 @@ static void __init of_unittest_overlay_2(void)
 /* test deactivation of device */
 static void __init of_unittest_overlay_3(void)
 {
-	int ret;
-
 	/* device should disable */
-	ret = of_unittest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 3);
@@ -1432,11 +1567,8 @@ static void __init of_unittest_overlay_3(void)
 /* test activation of a full device node */
 static void __init of_unittest_overlay_4(void)
 {
-	int ret;
-
 	/* device should disable */
-	ret = of_unittest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 4);
@@ -1445,11 +1577,8 @@ static void __init of_unittest_overlay_4(void)
 /* test overlay apply/revert sequence */
 static void __init of_unittest_overlay_5(void)
 {
-	int ret;
-
 	/* device should disable */
-	ret = of_unittest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 5);
@@ -1458,7 +1587,7 @@ static void __init of_unittest_overlay_5(void)
 /* test overlay application in sequence */
 static void __init of_unittest_overlay_6(void)
 {
-	int ret, i, ov_id[2], ovcs_id;
+	int i, ov_id[2], ovcs_id;
 	int overlay_nr = 6, unittest_nr = 6;
 	int before = 0, after = 1;
 	const char *overlay_name;
@@ -1481,8 +1610,7 @@ static void __init of_unittest_overlay_6(void)
 
 		overlay_name = overlay_name_from_nr(overlay_nr + i);
 
-		ret = overlay_data_apply(overlay_name, &ovcs_id);
-		if (!ret)  {
+		if (!overlay_data_apply(overlay_name, &ovcs_id)) {
 			unittest(0, "could not apply overlay \"%s\"\n",
 					overlay_name);
 			return;
@@ -1506,8 +1634,7 @@ static void __init of_unittest_overlay_6(void)
 
 	for (i = 1; i >= 0; i--) {
 		ovcs_id = ov_id[i];
-		ret = of_overlay_remove(&ovcs_id);
-		if (ret != 0) {
+		if (of_overlay_remove(&ovcs_id)) {
 			unittest(0, "%s failed destroy @\"%s\"\n",
 					overlay_name_from_nr(overlay_nr + i),
 					unittest_path(unittest_nr + i,
@@ -1536,7 +1663,7 @@ static void __init of_unittest_overlay_6(void)
 /* test overlay application in sequence */
 static void __init of_unittest_overlay_8(void)
 {
-	int ret, i, ov_id[2], ovcs_id;
+	int i, ov_id[2], ovcs_id;
 	int overlay_nr = 8, unittest_nr = 8;
 	const char *overlay_name;
 
@@ -1547,8 +1674,7 @@ static void __init of_unittest_overlay_8(void)
 
 		overlay_name = overlay_name_from_nr(overlay_nr + i);
 
-		ret = overlay_data_apply(overlay_name, &ovcs_id);
-		if (ret < 0)  {
+		if (!overlay_data_apply(overlay_name, &ovcs_id)) {
 			unittest(0, "could not apply overlay \"%s\"\n",
 					overlay_name);
 			return;
@@ -1559,8 +1685,7 @@ static void __init of_unittest_overlay_8(void)
 
 	/* now try to remove first overlay (it should fail) */
 	ovcs_id = ov_id[0];
-	ret = of_overlay_remove(&ovcs_id);
-	if (ret == 0) {
+	if (!of_overlay_remove(&ovcs_id)) {
 		unittest(0, "%s was destroyed @\"%s\"\n",
 				overlay_name_from_nr(overlay_nr + 0),
 				unittest_path(unittest_nr,
@@ -1571,8 +1696,7 @@ static void __init of_unittest_overlay_8(void)
 	/* removing them in order should work */
 	for (i = 1; i >= 0; i--) {
 		ovcs_id = ov_id[i];
-		ret = of_overlay_remove(&ovcs_id);
-		if (ret != 0) {
+		if (of_overlay_remove(&ovcs_id)) {
 			unittest(0, "%s not destroyed @\"%s\"\n",
 					overlay_name_from_nr(overlay_nr + i),
 					unittest_path(unittest_nr,
@@ -1604,8 +1728,8 @@ static void __init of_unittest_overlay_10(void)
 
 	ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);
 	kfree(child_path);
-	if (unittest(ret, "overlay test %d failed; no child device\n", 10))
-		return;
+
+	unittest(ret, "overlay test %d failed; no child device\n", 10);
 }
 
 /* test insertion of a bus with parent devices (and revert) */
@@ -1616,9 +1740,7 @@ static void __init of_unittest_overlay_11(void)
 	/* device should disable */
 	ret = of_unittest_apply_revert_overlay_check(11, 11, 0, 1,
 			PDEV_OVERLAY);
-	if (unittest(ret == 0,
-			"overlay test %d failed; overlay application\n", 11))
-		return;
+	unittest(ret == 0, "overlay test %d failed; overlay apply\n", 11);
 }
 
 #if IS_BUILTIN(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)
@@ -1769,7 +1891,7 @@ static int unittest_i2c_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
 static int unittest_i2c_mux_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
-	int ret, i, nchans;
+	int i, nchans;
 	struct device *dev = &client->dev;
 	struct i2c_adapter *adap = to_i2c_adapter(dev->parent);
 	struct device_node *np = client->dev.of_node, *child;
@@ -1785,8 +1907,7 @@ static int unittest_i2c_mux_probe(struct i2c_client *client,
 
 	max_reg = (u32)-1;
 	for_each_child_of_node(np, child) {
-		ret = of_property_read_u32(child, "reg", &reg);
-		if (ret)
+		if (of_property_read_u32(child, "reg", &reg))
 			continue;
 		if (max_reg == (u32)-1 || reg > max_reg)
 			max_reg = reg;
@@ -1802,8 +1923,7 @@ static int unittest_i2c_mux_probe(struct i2c_client *client,
 	if (!muxc)
 		return -ENOMEM;
 	for (i = 0; i < nchans; i++) {
-		ret = i2c_mux_add_adapter(muxc, 0, i, 0);
-		if (ret) {
+		if (i2c_mux_add_adapter(muxc, 0, i, 0)) {
 			dev_err(dev, "Failed to register mux #%d\n", i);
 			i2c_mux_del_adapters(muxc);
 			return -ENODEV;
@@ -1877,11 +1997,8 @@ static void of_unittest_overlay_i2c_cleanup(void)
 
 static void __init of_unittest_overlay_i2c_12(void)
 {
-	int ret;
-
 	/* device should enable */
-	ret = of_unittest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 12);
@@ -1890,11 +2007,8 @@ static void __init of_unittest_overlay_i2c_12(void)
 /* test deactivation of device */
 static void __init of_unittest_overlay_i2c_13(void)
 {
-	int ret;
-
 	/* device should disable */
-	ret = of_unittest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 13);
@@ -1907,11 +2021,8 @@ static void of_unittest_overlay_i2c_14(void)
 
 static void __init of_unittest_overlay_i2c_15(void)
 {
-	int ret;
-
 	/* device should enable */
-	ret = of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY);
-	if (ret != 0)
+	if (of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY))
 		return;
 
 	unittest(1, "overlay test %d passed\n", 15);
@@ -1927,10 +2038,8 @@ static inline void of_unittest_overlay_i2c_15(void) { }
 static void __init of_unittest_overlay(void)
 {
 	struct device_node *bus_np = NULL;
-	int ret;
 
-	ret = platform_driver_register(&unittest_driver);
-	if (ret != 0) {
+	if (platform_driver_register(&unittest_driver)) {
 		unittest(0, "could not register unittest driver\n");
 		goto out;
 	}
@@ -1941,8 +2050,7 @@ static void __init of_unittest_overlay(void)
 		goto out;
 	}
 
-	ret = of_platform_default_populate(bus_np, NULL, NULL);
-	if (ret != 0) {
+	if (of_platform_default_populate(bus_np, NULL, NULL)) {
 		unittest(0, "could not populate bus @ \"%s\"\n", bus_path);
 		goto out;
 	}
@@ -2156,10 +2264,8 @@ static int __init overlay_data_apply(const char *overlay_name, int *overlay_id)
 	}
 
 	size = info->dtb_end - info->dtb_begin;
-	if (!size) {
+	if (!size)
 		pr_err("no overlay data for %s\n", overlay_name);
-		ret = 0;
-	}
 
 	ret = of_overlay_fdt_apply(info->dtb_begin, size, &info->overlay_id);
 	if (overlay_id)
@@ -2193,7 +2299,6 @@ static __init void of_unittest_overlay_high_level(void)
 	struct device_node *overlay_base_symbols;
 	struct device_node **pprev;
 	struct property *prop;
-	int ret;
 
 	if (!overlay_base_root) {
 		unittest(0, "overlay_base_root not initialized\n");
@@ -2284,19 +2389,15 @@ static __init void of_unittest_overlay_high_level(void)
 					 prop->name);
 				goto err_unlock;
 			}
-			ret = __of_add_property(of_symbols, new_prop);
-			if (ret) {
-				if (!strcmp(new_prop->name, "name")) {
-					/* auto-generated by unflatten */
-					ret = 0;
+			if (__of_add_property(of_symbols, new_prop)) {
+				/* "name" auto-generated by unflatten */
+				if (!strcmp(new_prop->name, "name"))
 					continue;
-				}
 				unittest(0, "duplicate property '%s' in overlay_base node __symbols__",
 					 prop->name);
 				goto err_unlock;
 			}
-			ret = __of_add_property_sysfs(of_symbols, new_prop);
-			if (ret) {
+			if (__of_add_property_sysfs(of_symbols, new_prop)) {
 				unittest(0, "unable to add property '%s' in overlay_base node __symbols__ to sysfs",
 					 prop->name);
 				goto err_unlock;
@@ -2355,6 +2456,7 @@ static int __init of_unittest(void)
 	of_unittest_find_node_by_name();
 	of_unittest_dynamic();
 	of_unittest_parse_phandle_with_args();
+	of_unittest_parse_phandle_with_args_map();
 	of_unittest_printf();
 	of_unittest_property_string();
 	of_unittest_property_copy();
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index da5724c..28bb5a0 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -5,6 +5,39 @@
 menu "Performance monitor support"
 	depends on PERF_EVENTS
 
+config ARM_CCI_PMU
+	bool
+	select ARM_CCI
+
+config ARM_CCI400_PMU
+	bool "ARM CCI400 PMU support"
+	depends on (ARM && CPU_V7) || ARM64
+	select ARM_CCI400_COMMON
+	select ARM_CCI_PMU
+	help
+	  Support for PMU events monitoring on the ARM CCI-400 (cache coherent
+	  interconnect). CCI-400 supports counting events related to the
+	  connected slave/master interfaces.
+
+config ARM_CCI5xx_PMU
+	bool "ARM CCI-500/CCI-550 PMU support"
+	depends on (ARM && CPU_V7) || ARM64
+	select ARM_CCI_PMU
+	help
+	  Support for PMU events monitoring on the ARM CCI-500/CCI-550 cache
+	  coherent interconnects. Both of them provide 8 independent event counters,
+	  which can count events pertaining to the slave/master interfaces as well
+	  as the internal events to the CCI.
+
+	  If unsure, say Y
+
+config ARM_CCN
+	tristate "ARM CCN driver support"
+	depends on ARM || ARM64
+	help
+	  PMU (perf) driver supporting the ARM CCN (Cache Coherent Network)
+	  interconnect.
+
 config ARM_PMU
 	depends on ARM || ARM64
 	bool "ARM PMU framework"
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index c2f2741..b3902bd 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_ARM_CCI_PMU) += arm-cci.o
+obj-$(CONFIG_ARM_CCN) += arm-ccn.o
 obj-$(CONFIG_ARM_DSU_PMU) += arm_dsu_pmu.o
 obj-$(CONFIG_ARM_PMU) += arm_pmu.o arm_pmu_platform.o
 obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
new file mode 100644
index 0000000..383b2d3
--- /dev/null
+++ b/drivers/perf/arm-cci.c
@@ -0,0 +1,1722 @@
+// SPDX-License-Identifier: GPL-2.0
+// CCI Cache Coherent Interconnect PMU driver
+// Copyright (C) 2013-2018 Arm Ltd.
+// Author: Punit Agrawal <punit.agrawal@arm.com>, Suzuki Poulose <suzuki.poulose@arm.com>
+
+#include <linux/arm-cci.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#define DRIVER_NAME		"ARM-CCI PMU"
+
+#define CCI_PMCR		0x0100
+#define CCI_PID2		0x0fe8
+
+#define CCI_PMCR_CEN		0x00000001
+#define CCI_PMCR_NCNT_MASK	0x0000f800
+#define CCI_PMCR_NCNT_SHIFT	11
+
+#define CCI_PID2_REV_MASK	0xf0
+#define CCI_PID2_REV_SHIFT	4
+
+#define CCI_PMU_EVT_SEL		0x000
+#define CCI_PMU_CNTR		0x004
+#define CCI_PMU_CNTR_CTRL	0x008
+#define CCI_PMU_OVRFLW		0x00c
+
+#define CCI_PMU_OVRFLW_FLAG	1
+
+#define CCI_PMU_CNTR_SIZE(model)	((model)->cntr_size)
+#define CCI_PMU_CNTR_BASE(model, idx)	((idx) * CCI_PMU_CNTR_SIZE(model))
+#define CCI_PMU_CNTR_MASK		((1ULL << 32) -1)
+#define CCI_PMU_CNTR_LAST(cci_pmu)	(cci_pmu->num_cntrs - 1)
+
+#define CCI_PMU_MAX_HW_CNTRS(model) \
+	((model)->num_hw_cntrs + (model)->fixed_hw_cntrs)
+
+/* Types of interfaces that can generate events */
+enum {
+	CCI_IF_SLAVE,
+	CCI_IF_MASTER,
+#ifdef CONFIG_ARM_CCI5xx_PMU
+	CCI_IF_GLOBAL,
+#endif
+	CCI_IF_MAX,
+};
+
+struct event_range {
+	u32 min;
+	u32 max;
+};
+
+struct cci_pmu_hw_events {
+	struct perf_event **events;
+	unsigned long *used_mask;
+	raw_spinlock_t pmu_lock;
+};
+
+struct cci_pmu;
+/*
+ * struct cci_pmu_model:
+ * @fixed_hw_cntrs - Number of fixed event counters
+ * @num_hw_cntrs - Maximum number of programmable event counters
+ * @cntr_size - Size of an event counter mapping
+ */
+struct cci_pmu_model {
+	char *name;
+	u32 fixed_hw_cntrs;
+	u32 num_hw_cntrs;
+	u32 cntr_size;
+	struct attribute **format_attrs;
+	struct attribute **event_attrs;
+	struct event_range event_ranges[CCI_IF_MAX];
+	int (*validate_hw_event)(struct cci_pmu *, unsigned long);
+	int (*get_event_idx)(struct cci_pmu *, struct cci_pmu_hw_events *, unsigned long);
+	void (*write_counters)(struct cci_pmu *, unsigned long *);
+};
+
+static struct cci_pmu_model cci_pmu_models[];
+
+struct cci_pmu {
+	void __iomem *base;
+	void __iomem *ctrl_base;
+	struct pmu pmu;
+	int cpu;
+	int nr_irqs;
+	int *irqs;
+	unsigned long active_irqs;
+	const struct cci_pmu_model *model;
+	struct cci_pmu_hw_events hw_events;
+	struct platform_device *plat_device;
+	int num_cntrs;
+	atomic_t active_events;
+	struct mutex reserve_mutex;
+};
+
+#define to_cci_pmu(c)	(container_of(c, struct cci_pmu, pmu))
+
+static struct cci_pmu *g_cci_pmu;
+
+enum cci_models {
+#ifdef CONFIG_ARM_CCI400_PMU
+	CCI400_R0,
+	CCI400_R1,
+#endif
+#ifdef CONFIG_ARM_CCI5xx_PMU
+	CCI500_R0,
+	CCI550_R0,
+#endif
+	CCI_MODEL_MAX
+};
+
+static void pmu_write_counters(struct cci_pmu *cci_pmu,
+				 unsigned long *mask);
+static ssize_t cci_pmu_format_show(struct device *dev,
+			struct device_attribute *attr, char *buf);
+static ssize_t cci_pmu_event_show(struct device *dev,
+			struct device_attribute *attr, char *buf);
+
+#define CCI_EXT_ATTR_ENTRY(_name, _func, _config) 				\
+	&((struct dev_ext_attribute[]) {					\
+		{ __ATTR(_name, S_IRUGO, _func, NULL), (void *)_config }	\
+	})[0].attr.attr
+
+#define CCI_FORMAT_EXT_ATTR_ENTRY(_name, _config) \
+	CCI_EXT_ATTR_ENTRY(_name, cci_pmu_format_show, (char *)_config)
+#define CCI_EVENT_EXT_ATTR_ENTRY(_name, _config) \
+	CCI_EXT_ATTR_ENTRY(_name, cci_pmu_event_show, (unsigned long)_config)
+
+/* CCI400 PMU Specific definitions */
+
+#ifdef CONFIG_ARM_CCI400_PMU
+
+/* Port ids */
+#define CCI400_PORT_S0		0
+#define CCI400_PORT_S1		1
+#define CCI400_PORT_S2		2
+#define CCI400_PORT_S3		3
+#define CCI400_PORT_S4		4
+#define CCI400_PORT_M0		5
+#define CCI400_PORT_M1		6
+#define CCI400_PORT_M2		7
+
+#define CCI400_R1_PX		5
+
+/*
+ * Instead of an event id to monitor CCI cycles, a dedicated counter is
+ * provided. Use 0xff to represent CCI cycles and hope that no future revisions
+ * make use of this event in hardware.
+ */
+enum cci400_perf_events {
+	CCI400_PMU_CYCLES = 0xff
+};
+
+#define CCI400_PMU_CYCLE_CNTR_IDX	0
+#define CCI400_PMU_CNTR0_IDX		1
+
+/*
+ * CCI PMU event id is an 8-bit value made of two parts - bits 7:5 for one of 8
+ * ports and bits 4:0 are event codes. There are different event codes
+ * associated with each port type.
+ *
+ * Additionally, the range of events associated with the port types changed
+ * between Rev0 and Rev1.
+ *
+ * The constants below define the range of valid codes for each port type for
+ * the different revisions and are used to validate the event to be monitored.
+ */
+
+#define CCI400_PMU_EVENT_MASK		0xffUL
+#define CCI400_PMU_EVENT_SOURCE_SHIFT	5
+#define CCI400_PMU_EVENT_SOURCE_MASK	0x7
+#define CCI400_PMU_EVENT_CODE_SHIFT	0
+#define CCI400_PMU_EVENT_CODE_MASK	0x1f
+#define CCI400_PMU_EVENT_SOURCE(event) \
+	((event >> CCI400_PMU_EVENT_SOURCE_SHIFT) & \
+			CCI400_PMU_EVENT_SOURCE_MASK)
+#define CCI400_PMU_EVENT_CODE(event) \
+	((event >> CCI400_PMU_EVENT_CODE_SHIFT) & CCI400_PMU_EVENT_CODE_MASK)
+
+#define CCI400_R0_SLAVE_PORT_MIN_EV	0x00
+#define CCI400_R0_SLAVE_PORT_MAX_EV	0x13
+#define CCI400_R0_MASTER_PORT_MIN_EV	0x14
+#define CCI400_R0_MASTER_PORT_MAX_EV	0x1a
+
+#define CCI400_R1_SLAVE_PORT_MIN_EV	0x00
+#define CCI400_R1_SLAVE_PORT_MAX_EV	0x14
+#define CCI400_R1_MASTER_PORT_MIN_EV	0x00
+#define CCI400_R1_MASTER_PORT_MAX_EV	0x11
+
+#define CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(_name, _config) \
+	CCI_EXT_ATTR_ENTRY(_name, cci400_pmu_cycle_event_show, \
+					(unsigned long)_config)
+
+static ssize_t cci400_pmu_cycle_event_show(struct device *dev,
+			struct device_attribute *attr, char *buf);
+
+static struct attribute *cci400_pmu_format_attrs[] = {
+	CCI_FORMAT_EXT_ATTR_ENTRY(event, "config:0-4"),
+	CCI_FORMAT_EXT_ATTR_ENTRY(source, "config:5-7"),
+	NULL
+};
+
+static struct attribute *cci400_r0_pmu_event_attrs[] = {
+	/* Slave events */
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_any, 0x0),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_device, 0x01),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_normal_or_nonshareable, 0x2),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_inner_or_outershareable, 0x3),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maintenance, 0x4),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_mem_barrier, 0x5),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_sync_barrier, 0x6),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg_sync, 0x8),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_tt_full, 0x9),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_last_hs_snoop, 0xA),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall_rvalids_h_rready_l, 0xB),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_any, 0xC),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_device, 0xD),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_normal_or_nonshareable, 0xE),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_inner_or_outershare_wback_wclean, 0xF),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_unique, 0x10),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_line_unique, 0x11),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_evict, 0x12),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall_tt_full, 0x13),
+	/* Master events */
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_retry_speculative_fetch, 0x14),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_addr_hazard, 0x15),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_id_hazard, 0x16),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_tt_full, 0x17),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_barrier_hazard, 0x18),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_barrier_hazard, 0x19),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_tt_full, 0x1A),
+	/* Special event for cycles counter */
+	CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(cycles, 0xff),
+	NULL
+};
+
+static struct attribute *cci400_r1_pmu_event_attrs[] = {
+	/* Slave events */
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_any, 0x0),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_device, 0x01),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_normal_or_nonshareable, 0x2),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_inner_or_outershareable, 0x3),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maintenance, 0x4),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_mem_barrier, 0x5),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_sync_barrier, 0x6),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg_sync, 0x8),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_tt_full, 0x9),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_last_hs_snoop, 0xA),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall_rvalids_h_rready_l, 0xB),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_any, 0xC),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_device, 0xD),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_normal_or_nonshareable, 0xE),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_inner_or_outershare_wback_wclean, 0xF),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_unique, 0x10),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_write_line_unique, 0x11),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_evict, 0x12),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall_tt_full, 0x13),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_slave_id_hazard, 0x14),
+	/* Master events */
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_retry_speculative_fetch, 0x0),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_stall_cycle_addr_hazard, 0x1),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_master_id_hazard, 0x2),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_hi_prio_rtq_full, 0x3),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_barrier_hazard, 0x4),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_barrier_hazard, 0x5),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_wtq_full, 0x6),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_low_prio_rtq_full, 0x7),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_mid_prio_rtq_full, 0x8),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn0, 0x9),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn1, 0xA),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn2, 0xB),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall_qvn_vn3, 0xC),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn0, 0xD),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn1, 0xE),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn2, 0xF),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_qvn_vn3, 0x10),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_unique_or_line_unique_addr_hazard, 0x11),
+	/* Special event for cycles counter */
+	CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(cycles, 0xff),
+	NULL
+};
+
+static ssize_t cci400_pmu_cycle_event_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct dev_ext_attribute *eattr = container_of(attr,
+				struct dev_ext_attribute, attr);
+	return snprintf(buf, PAGE_SIZE, "config=0x%lx\n", (unsigned long)eattr->var);
+}
+
+static int cci400_get_event_idx(struct cci_pmu *cci_pmu,
+				struct cci_pmu_hw_events *hw,
+				unsigned long cci_event)
+{
+	int idx;
+
+	/* cycles event idx is fixed */
+	if (cci_event == CCI400_PMU_CYCLES) {
+		if (test_and_set_bit(CCI400_PMU_CYCLE_CNTR_IDX, hw->used_mask))
+			return -EAGAIN;
+
+		return CCI400_PMU_CYCLE_CNTR_IDX;
+	}
+
+	for (idx = CCI400_PMU_CNTR0_IDX; idx <= CCI_PMU_CNTR_LAST(cci_pmu); ++idx)
+		if (!test_and_set_bit(idx, hw->used_mask))
+			return idx;
+
+	/* No counters available */
+	return -EAGAIN;
+}
+
+static int cci400_validate_hw_event(struct cci_pmu *cci_pmu, unsigned long hw_event)
+{
+	u8 ev_source = CCI400_PMU_EVENT_SOURCE(hw_event);
+	u8 ev_code = CCI400_PMU_EVENT_CODE(hw_event);
+	int if_type;
+
+	if (hw_event & ~CCI400_PMU_EVENT_MASK)
+		return -ENOENT;
+
+	if (hw_event == CCI400_PMU_CYCLES)
+		return hw_event;
+
+	switch (ev_source) {
+	case CCI400_PORT_S0:
+	case CCI400_PORT_S1:
+	case CCI400_PORT_S2:
+	case CCI400_PORT_S3:
+	case CCI400_PORT_S4:
+		/* Slave Interface */
+		if_type = CCI_IF_SLAVE;
+		break;
+	case CCI400_PORT_M0:
+	case CCI400_PORT_M1:
+	case CCI400_PORT_M2:
+		/* Master Interface */
+		if_type = CCI_IF_MASTER;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
+		ev_code <= cci_pmu->model->event_ranges[if_type].max)
+		return hw_event;
+
+	return -ENOENT;
+}
+
+static int probe_cci400_revision(struct cci_pmu *cci_pmu)
+{
+	int rev;
+	rev = readl_relaxed(cci_pmu->ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK;
+	rev >>= CCI_PID2_REV_SHIFT;
+
+	if (rev < CCI400_R1_PX)
+		return CCI400_R0;
+	else
+		return CCI400_R1;
+}
+
+static const struct cci_pmu_model *probe_cci_model(struct cci_pmu *cci_pmu)
+{
+	if (platform_has_secure_cci_access())
+		return &cci_pmu_models[probe_cci400_revision(cci_pmu)];
+	return NULL;
+}
+#else	/* !CONFIG_ARM_CCI400_PMU */
+static inline struct cci_pmu_model *probe_cci_model(struct cci_pmu *cci_pmu)
+{
+	return NULL;
+}
+#endif	/* CONFIG_ARM_CCI400_PMU */
+
+#ifdef CONFIG_ARM_CCI5xx_PMU
+
+/*
+ * CCI5xx PMU event id is an 9-bit value made of two parts.
+ *	 bits [8:5] - Source for the event
+ *	 bits [4:0] - Event code (specific to type of interface)
+ *
+ *
+ */
+
+/* Port ids */
+#define CCI5xx_PORT_S0			0x0
+#define CCI5xx_PORT_S1			0x1
+#define CCI5xx_PORT_S2			0x2
+#define CCI5xx_PORT_S3			0x3
+#define CCI5xx_PORT_S4			0x4
+#define CCI5xx_PORT_S5			0x5
+#define CCI5xx_PORT_S6			0x6
+
+#define CCI5xx_PORT_M0			0x8
+#define CCI5xx_PORT_M1			0x9
+#define CCI5xx_PORT_M2			0xa
+#define CCI5xx_PORT_M3			0xb
+#define CCI5xx_PORT_M4			0xc
+#define CCI5xx_PORT_M5			0xd
+#define CCI5xx_PORT_M6			0xe
+
+#define CCI5xx_PORT_GLOBAL		0xf
+
+#define CCI5xx_PMU_EVENT_MASK		0x1ffUL
+#define CCI5xx_PMU_EVENT_SOURCE_SHIFT	0x5
+#define CCI5xx_PMU_EVENT_SOURCE_MASK	0xf
+#define CCI5xx_PMU_EVENT_CODE_SHIFT	0x0
+#define CCI5xx_PMU_EVENT_CODE_MASK	0x1f
+
+#define CCI5xx_PMU_EVENT_SOURCE(event)	\
+	((event >> CCI5xx_PMU_EVENT_SOURCE_SHIFT) & CCI5xx_PMU_EVENT_SOURCE_MASK)
+#define CCI5xx_PMU_EVENT_CODE(event)	\
+	((event >> CCI5xx_PMU_EVENT_CODE_SHIFT) & CCI5xx_PMU_EVENT_CODE_MASK)
+
+#define CCI5xx_SLAVE_PORT_MIN_EV	0x00
+#define CCI5xx_SLAVE_PORT_MAX_EV	0x1f
+#define CCI5xx_MASTER_PORT_MIN_EV	0x00
+#define CCI5xx_MASTER_PORT_MAX_EV	0x06
+#define CCI5xx_GLOBAL_PORT_MIN_EV	0x00
+#define CCI5xx_GLOBAL_PORT_MAX_EV	0x0f
+
+
+#define CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(_name, _config) \
+	CCI_EXT_ATTR_ENTRY(_name, cci5xx_pmu_global_event_show, \
+					(unsigned long) _config)
+
+static ssize_t cci5xx_pmu_global_event_show(struct device *dev,
+				struct device_attribute *attr, char *buf);
+
+static struct attribute *cci5xx_pmu_format_attrs[] = {
+	CCI_FORMAT_EXT_ATTR_ENTRY(event, "config:0-4"),
+	CCI_FORMAT_EXT_ATTR_ENTRY(source, "config:5-8"),
+	NULL,
+};
+
+static struct attribute *cci5xx_pmu_event_attrs[] = {
+	/* Slave events */
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_arvalid, 0x0),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_dev, 0x1),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_nonshareable, 0x2),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_shareable_non_alloc, 0x3),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_shareable_alloc, 0x4),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_invalidate, 0x5),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_cache_maint, 0x6),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_dvm_msg, 0x7),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_rval, 0x8),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_rlast_snoop, 0x9),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_hs_awalid, 0xA),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_dev, 0xB),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_non_shareable, 0xC),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wb, 0xD),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wlu, 0xE),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_share_wunique, 0xF),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_evict, 0x10),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_wrevict, 0x11),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_w_data_beat, 0x12),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_acvalid, 0x13),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_read, 0x14),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_clean, 0x15),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_data_transfer_low, 0x16),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_stall_arvalid, 0x17),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_r_data_stall, 0x18),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_wrq_stall, 0x19),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_w_data_stall, 0x1A),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_w_resp_stall, 0x1B),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_srq_stall, 0x1C),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_s_data_stall, 0x1D),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_rq_stall_ot_limit, 0x1E),
+	CCI_EVENT_EXT_ATTR_ENTRY(si_r_stall_arbit, 0x1F),
+
+	/* Master events */
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_r_data_beat_any, 0x0),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_data_beat_any, 0x1),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_rrq_stall, 0x2),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_r_data_stall, 0x3),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall, 0x4),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_data_stall, 0x5),
+	CCI_EVENT_EXT_ATTR_ENTRY(mi_w_resp_stall, 0x6),
+
+	/* Global events */
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_0_1, 0x0),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_2_3, 0x1),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_4_5, 0x2),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_6_7, 0x3),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_0_1, 0x4),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_2_3, 0x5),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_4_5, 0x6),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_6_7, 0x7),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_back_invalidation, 0x8),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_alloc_busy, 0x9),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_tt_full, 0xA),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_wrq, 0xB),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_cd_hs, 0xC),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_rq_stall_addr_hazard, 0xD),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_stall_tt_full, 0xE),
+	CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_tzmp1_prot, 0xF),
+	NULL
+};
+
+static ssize_t cci5xx_pmu_global_event_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct dev_ext_attribute *eattr = container_of(attr,
+					struct dev_ext_attribute, attr);
+	/* Global events have single fixed source code */
+	return snprintf(buf, PAGE_SIZE, "event=0x%lx,source=0x%x\n",
+				(unsigned long)eattr->var, CCI5xx_PORT_GLOBAL);
+}
+
+/*
+ * CCI500 provides 8 independent event counters that can count
+ * any of the events available.
+ * CCI500 PMU event source ids
+ *	0x0-0x6 - Slave interfaces
+ *	0x8-0xD - Master interfaces
+ *	0xf     - Global Events
+ *	0x7,0xe - Reserved
+ */
+static int cci500_validate_hw_event(struct cci_pmu *cci_pmu,
+					unsigned long hw_event)
+{
+	u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event);
+	u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event);
+	int if_type;
+
+	if (hw_event & ~CCI5xx_PMU_EVENT_MASK)
+		return -ENOENT;
+
+	switch (ev_source) {
+	case CCI5xx_PORT_S0:
+	case CCI5xx_PORT_S1:
+	case CCI5xx_PORT_S2:
+	case CCI5xx_PORT_S3:
+	case CCI5xx_PORT_S4:
+	case CCI5xx_PORT_S5:
+	case CCI5xx_PORT_S6:
+		if_type = CCI_IF_SLAVE;
+		break;
+	case CCI5xx_PORT_M0:
+	case CCI5xx_PORT_M1:
+	case CCI5xx_PORT_M2:
+	case CCI5xx_PORT_M3:
+	case CCI5xx_PORT_M4:
+	case CCI5xx_PORT_M5:
+		if_type = CCI_IF_MASTER;
+		break;
+	case CCI5xx_PORT_GLOBAL:
+		if_type = CCI_IF_GLOBAL;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
+		ev_code <= cci_pmu->model->event_ranges[if_type].max)
+		return hw_event;
+
+	return -ENOENT;
+}
+
+/*
+ * CCI550 provides 8 independent event counters that can count
+ * any of the events available.
+ * CCI550 PMU event source ids
+ *	0x0-0x6 - Slave interfaces
+ *	0x8-0xe - Master interfaces
+ *	0xf     - Global Events
+ *	0x7	- Reserved
+ */
+static int cci550_validate_hw_event(struct cci_pmu *cci_pmu,
+					unsigned long hw_event)
+{
+	u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event);
+	u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event);
+	int if_type;
+
+	if (hw_event & ~CCI5xx_PMU_EVENT_MASK)
+		return -ENOENT;
+
+	switch (ev_source) {
+	case CCI5xx_PORT_S0:
+	case CCI5xx_PORT_S1:
+	case CCI5xx_PORT_S2:
+	case CCI5xx_PORT_S3:
+	case CCI5xx_PORT_S4:
+	case CCI5xx_PORT_S5:
+	case CCI5xx_PORT_S6:
+		if_type = CCI_IF_SLAVE;
+		break;
+	case CCI5xx_PORT_M0:
+	case CCI5xx_PORT_M1:
+	case CCI5xx_PORT_M2:
+	case CCI5xx_PORT_M3:
+	case CCI5xx_PORT_M4:
+	case CCI5xx_PORT_M5:
+	case CCI5xx_PORT_M6:
+		if_type = CCI_IF_MASTER;
+		break;
+	case CCI5xx_PORT_GLOBAL:
+		if_type = CCI_IF_GLOBAL;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
+		ev_code <= cci_pmu->model->event_ranges[if_type].max)
+		return hw_event;
+
+	return -ENOENT;
+}
+
+#endif	/* CONFIG_ARM_CCI5xx_PMU */
+
+/*
+ * Program the CCI PMU counters which have PERF_HES_ARCH set
+ * with the event period and mark them ready before we enable
+ * PMU.
+ */
+static void cci_pmu_sync_counters(struct cci_pmu *cci_pmu)
+{
+	int i;
+	struct cci_pmu_hw_events *cci_hw = &cci_pmu->hw_events;
+
+	DECLARE_BITMAP(mask, cci_pmu->num_cntrs);
+
+	bitmap_zero(mask, cci_pmu->num_cntrs);
+	for_each_set_bit(i, cci_pmu->hw_events.used_mask, cci_pmu->num_cntrs) {
+		struct perf_event *event = cci_hw->events[i];
+
+		if (WARN_ON(!event))
+			continue;
+
+		/* Leave the events which are not counting */
+		if (event->hw.state & PERF_HES_STOPPED)
+			continue;
+		if (event->hw.state & PERF_HES_ARCH) {
+			set_bit(i, mask);
+			event->hw.state &= ~PERF_HES_ARCH;
+		}
+	}
+
+	pmu_write_counters(cci_pmu, mask);
+}
+
+/* Should be called with cci_pmu->hw_events->pmu_lock held */
+static void __cci_pmu_enable_nosync(struct cci_pmu *cci_pmu)
+{
+	u32 val;
+
+	/* Enable all the PMU counters. */
+	val = readl_relaxed(cci_pmu->ctrl_base + CCI_PMCR) | CCI_PMCR_CEN;
+	writel(val, cci_pmu->ctrl_base + CCI_PMCR);
+}
+
+/* Should be called with cci_pmu->hw_events->pmu_lock held */
+static void __cci_pmu_enable_sync(struct cci_pmu *cci_pmu)
+{
+	cci_pmu_sync_counters(cci_pmu);
+	__cci_pmu_enable_nosync(cci_pmu);
+}
+
+/* Should be called with cci_pmu->hw_events->pmu_lock held */
+static void __cci_pmu_disable(struct cci_pmu *cci_pmu)
+{
+	u32 val;
+
+	/* Disable all the PMU counters. */
+	val = readl_relaxed(cci_pmu->ctrl_base + CCI_PMCR) & ~CCI_PMCR_CEN;
+	writel(val, cci_pmu->ctrl_base + CCI_PMCR);
+}
+
+static ssize_t cci_pmu_format_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct dev_ext_attribute *eattr = container_of(attr,
+				struct dev_ext_attribute, attr);
+	return snprintf(buf, PAGE_SIZE, "%s\n", (char *)eattr->var);
+}
+
+static ssize_t cci_pmu_event_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct dev_ext_attribute *eattr = container_of(attr,
+				struct dev_ext_attribute, attr);
+	/* source parameter is mandatory for normal PMU events */
+	return snprintf(buf, PAGE_SIZE, "source=?,event=0x%lx\n",
+					 (unsigned long)eattr->var);
+}
+
+static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
+{
+	return 0 <= idx && idx <= CCI_PMU_CNTR_LAST(cci_pmu);
+}
+
+static u32 pmu_read_register(struct cci_pmu *cci_pmu, int idx, unsigned int offset)
+{
+	return readl_relaxed(cci_pmu->base +
+			     CCI_PMU_CNTR_BASE(cci_pmu->model, idx) + offset);
+}
+
+static void pmu_write_register(struct cci_pmu *cci_pmu, u32 value,
+			       int idx, unsigned int offset)
+{
+	writel_relaxed(value, cci_pmu->base +
+		       CCI_PMU_CNTR_BASE(cci_pmu->model, idx) + offset);
+}
+
+static void pmu_disable_counter(struct cci_pmu *cci_pmu, int idx)
+{
+	pmu_write_register(cci_pmu, 0, idx, CCI_PMU_CNTR_CTRL);
+}
+
+static void pmu_enable_counter(struct cci_pmu *cci_pmu, int idx)
+{
+	pmu_write_register(cci_pmu, 1, idx, CCI_PMU_CNTR_CTRL);
+}
+
+static bool __maybe_unused
+pmu_counter_is_enabled(struct cci_pmu *cci_pmu, int idx)
+{
+	return (pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR_CTRL) & 0x1) != 0;
+}
+
+static void pmu_set_event(struct cci_pmu *cci_pmu, int idx, unsigned long event)
+{
+	pmu_write_register(cci_pmu, event, idx, CCI_PMU_EVT_SEL);
+}
+
+/*
+ * For all counters on the CCI-PMU, disable any 'enabled' counters,
+ * saving the changed counters in the mask, so that we can restore
+ * it later using pmu_restore_counters. The mask is private to the
+ * caller. We cannot rely on the used_mask maintained by the CCI_PMU
+ * as it only tells us if the counter is assigned to perf_event or not.
+ * The state of the perf_event cannot be locked by the PMU layer, hence
+ * we check the individual counter status (which can be locked by
+ * cci_pm->hw_events->pmu_lock).
+ *
+ * @mask should be initialised to empty by the caller.
+ */
+static void __maybe_unused
+pmu_save_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
+{
+	int i;
+
+	for (i = 0; i < cci_pmu->num_cntrs; i++) {
+		if (pmu_counter_is_enabled(cci_pmu, i)) {
+			set_bit(i, mask);
+			pmu_disable_counter(cci_pmu, i);
+		}
+	}
+}
+
+/*
+ * Restore the status of the counters. Reversal of the pmu_save_counters().
+ * For each counter set in the mask, enable the counter back.
+ */
+static void __maybe_unused
+pmu_restore_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
+{
+	int i;
+
+	for_each_set_bit(i, mask, cci_pmu->num_cntrs)
+		pmu_enable_counter(cci_pmu, i);
+}
+
+/*
+ * Returns the number of programmable counters actually implemented
+ * by the cci
+ */
+static u32 pmu_get_max_counters(struct cci_pmu *cci_pmu)
+{
+	return (readl_relaxed(cci_pmu->ctrl_base + CCI_PMCR) &
+		CCI_PMCR_NCNT_MASK) >> CCI_PMCR_NCNT_SHIFT;
+}
+
+static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, struct perf_event *event)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	unsigned long cci_event = event->hw.config_base;
+	int idx;
+
+	if (cci_pmu->model->get_event_idx)
+		return cci_pmu->model->get_event_idx(cci_pmu, hw, cci_event);
+
+	/* Generic code to find an unused idx from the mask */
+	for(idx = 0; idx <= CCI_PMU_CNTR_LAST(cci_pmu); idx++)
+		if (!test_and_set_bit(idx, hw->used_mask))
+			return idx;
+
+	/* No counters available */
+	return -EAGAIN;
+}
+
+static int pmu_map_event(struct perf_event *event)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+
+	if (event->attr.type < PERF_TYPE_MAX ||
+			!cci_pmu->model->validate_hw_event)
+		return -ENOENT;
+
+	return	cci_pmu->model->validate_hw_event(cci_pmu, event->attr.config);
+}
+
+static int pmu_request_irq(struct cci_pmu *cci_pmu, irq_handler_t handler)
+{
+	int i;
+	struct platform_device *pmu_device = cci_pmu->plat_device;
+
+	if (unlikely(!pmu_device))
+		return -ENODEV;
+
+	if (cci_pmu->nr_irqs < 1) {
+		dev_err(&pmu_device->dev, "no irqs for CCI PMUs defined\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * Register all available CCI PMU interrupts. In the interrupt handler
+	 * we iterate over the counters checking for interrupt source (the
+	 * overflowing counter) and clear it.
+	 *
+	 * This should allow handling of non-unique interrupt for the counters.
+	 */
+	for (i = 0; i < cci_pmu->nr_irqs; i++) {
+		int err = request_irq(cci_pmu->irqs[i], handler, IRQF_SHARED,
+				"arm-cci-pmu", cci_pmu);
+		if (err) {
+			dev_err(&pmu_device->dev, "unable to request IRQ%d for ARM CCI PMU counters\n",
+				cci_pmu->irqs[i]);
+			return err;
+		}
+
+		set_bit(i, &cci_pmu->active_irqs);
+	}
+
+	return 0;
+}
+
+static void pmu_free_irq(struct cci_pmu *cci_pmu)
+{
+	int i;
+
+	for (i = 0; i < cci_pmu->nr_irqs; i++) {
+		if (!test_and_clear_bit(i, &cci_pmu->active_irqs))
+			continue;
+
+		free_irq(cci_pmu->irqs[i], cci_pmu);
+	}
+}
+
+static u32 pmu_read_counter(struct perf_event *event)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	struct hw_perf_event *hw_counter = &event->hw;
+	int idx = hw_counter->idx;
+	u32 value;
+
+	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
+		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
+		return 0;
+	}
+	value = pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR);
+
+	return value;
+}
+
+static void pmu_write_counter(struct cci_pmu *cci_pmu, u32 value, int idx)
+{
+	pmu_write_register(cci_pmu, value, idx, CCI_PMU_CNTR);
+}
+
+static void __pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
+{
+	int i;
+	struct cci_pmu_hw_events *cci_hw = &cci_pmu->hw_events;
+
+	for_each_set_bit(i, mask, cci_pmu->num_cntrs) {
+		struct perf_event *event = cci_hw->events[i];
+
+		if (WARN_ON(!event))
+			continue;
+		pmu_write_counter(cci_pmu, local64_read(&event->hw.prev_count), i);
+	}
+}
+
+static void pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
+{
+	if (cci_pmu->model->write_counters)
+		cci_pmu->model->write_counters(cci_pmu, mask);
+	else
+		__pmu_write_counters(cci_pmu, mask);
+}
+
+#ifdef CONFIG_ARM_CCI5xx_PMU
+
+/*
+ * CCI-500/CCI-550 has advanced power saving policies, which could gate the
+ * clocks to the PMU counters, which makes the writes to them ineffective.
+ * The only way to write to those counters is when the global counters
+ * are enabled and the particular counter is enabled.
+ *
+ * So we do the following :
+ *
+ * 1) Disable all the PMU counters, saving their current state
+ * 2) Enable the global PMU profiling, now that all counters are
+ *    disabled.
+ *
+ * For each counter to be programmed, repeat steps 3-7:
+ *
+ * 3) Write an invalid event code to the event control register for the
+      counter, so that the counters are not modified.
+ * 4) Enable the counter control for the counter.
+ * 5) Set the counter value
+ * 6) Disable the counter
+ * 7) Restore the event in the target counter
+ *
+ * 8) Disable the global PMU.
+ * 9) Restore the status of the rest of the counters.
+ *
+ * We choose an event which for CCI-5xx is guaranteed not to count.
+ * We use the highest possible event code (0x1f) for the master interface 0.
+ */
+#define CCI5xx_INVALID_EVENT	((CCI5xx_PORT_M0 << CCI5xx_PMU_EVENT_SOURCE_SHIFT) | \
+				 (CCI5xx_PMU_EVENT_CODE_MASK << CCI5xx_PMU_EVENT_CODE_SHIFT))
+static void cci5xx_pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
+{
+	int i;
+	DECLARE_BITMAP(saved_mask, cci_pmu->num_cntrs);
+
+	bitmap_zero(saved_mask, cci_pmu->num_cntrs);
+	pmu_save_counters(cci_pmu, saved_mask);
+
+	/*
+	 * Now that all the counters are disabled, we can safely turn the PMU on,
+	 * without syncing the status of the counters
+	 */
+	__cci_pmu_enable_nosync(cci_pmu);
+
+	for_each_set_bit(i, mask, cci_pmu->num_cntrs) {
+		struct perf_event *event = cci_pmu->hw_events.events[i];
+
+		if (WARN_ON(!event))
+			continue;
+
+		pmu_set_event(cci_pmu, i, CCI5xx_INVALID_EVENT);
+		pmu_enable_counter(cci_pmu, i);
+		pmu_write_counter(cci_pmu, local64_read(&event->hw.prev_count), i);
+		pmu_disable_counter(cci_pmu, i);
+		pmu_set_event(cci_pmu, i, event->hw.config_base);
+	}
+
+	__cci_pmu_disable(cci_pmu);
+
+	pmu_restore_counters(cci_pmu, saved_mask);
+}
+
+#endif	/* CONFIG_ARM_CCI5xx_PMU */
+
+static u64 pmu_event_update(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 delta, prev_raw_count, new_raw_count;
+
+	do {
+		prev_raw_count = local64_read(&hwc->prev_count);
+		new_raw_count = pmu_read_counter(event);
+	} while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+		 new_raw_count) != prev_raw_count);
+
+	delta = (new_raw_count - prev_raw_count) & CCI_PMU_CNTR_MASK;
+
+	local64_add(delta, &event->count);
+
+	return new_raw_count;
+}
+
+static void pmu_read(struct perf_event *event)
+{
+	pmu_event_update(event);
+}
+
+static void pmu_event_set_period(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	/*
+	 * The CCI PMU counters have a period of 2^32. To account for the
+	 * possiblity of extreme interrupt latency we program for a period of
+	 * half that. Hopefully we can handle the interrupt before another 2^31
+	 * events occur and the counter overtakes its previous value.
+	 */
+	u64 val = 1ULL << 31;
+	local64_set(&hwc->prev_count, val);
+
+	/*
+	 * CCI PMU uses PERF_HES_ARCH to keep track of the counters, whose
+	 * values needs to be sync-ed with the s/w state before the PMU is
+	 * enabled.
+	 * Mark this counter for sync.
+	 */
+	hwc->state |= PERF_HES_ARCH;
+}
+
+static irqreturn_t pmu_handle_irq(int irq_num, void *dev)
+{
+	unsigned long flags;
+	struct cci_pmu *cci_pmu = dev;
+	struct cci_pmu_hw_events *events = &cci_pmu->hw_events;
+	int idx, handled = IRQ_NONE;
+
+	raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+	/* Disable the PMU while we walk through the counters */
+	__cci_pmu_disable(cci_pmu);
+	/*
+	 * Iterate over counters and update the corresponding perf events.
+	 * This should work regardless of whether we have per-counter overflow
+	 * interrupt or a combined overflow interrupt.
+	 */
+	for (idx = 0; idx <= CCI_PMU_CNTR_LAST(cci_pmu); idx++) {
+		struct perf_event *event = events->events[idx];
+
+		if (!event)
+			continue;
+
+		/* Did this counter overflow? */
+		if (!(pmu_read_register(cci_pmu, idx, CCI_PMU_OVRFLW) &
+		      CCI_PMU_OVRFLW_FLAG))
+			continue;
+
+		pmu_write_register(cci_pmu, CCI_PMU_OVRFLW_FLAG, idx,
+							CCI_PMU_OVRFLW);
+
+		pmu_event_update(event);
+		pmu_event_set_period(event);
+		handled = IRQ_HANDLED;
+	}
+
+	/* Enable the PMU and sync possibly overflowed counters */
+	__cci_pmu_enable_sync(cci_pmu);
+	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+
+	return IRQ_RETVAL(handled);
+}
+
+static int cci_pmu_get_hw(struct cci_pmu *cci_pmu)
+{
+	int ret = pmu_request_irq(cci_pmu, pmu_handle_irq);
+	if (ret) {
+		pmu_free_irq(cci_pmu);
+		return ret;
+	}
+	return 0;
+}
+
+static void cci_pmu_put_hw(struct cci_pmu *cci_pmu)
+{
+	pmu_free_irq(cci_pmu);
+}
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	atomic_t *active_events = &cci_pmu->active_events;
+	struct mutex *reserve_mutex = &cci_pmu->reserve_mutex;
+
+	if (atomic_dec_and_mutex_lock(active_events, reserve_mutex)) {
+		cci_pmu_put_hw(cci_pmu);
+		mutex_unlock(reserve_mutex);
+	}
+}
+
+static void cci_pmu_enable(struct pmu *pmu)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
+	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
+	int enabled = bitmap_weight(hw_events->used_mask, cci_pmu->num_cntrs);
+	unsigned long flags;
+
+	if (!enabled)
+		return;
+
+	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
+	__cci_pmu_enable_sync(cci_pmu);
+	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
+
+}
+
+static void cci_pmu_disable(struct pmu *pmu)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
+	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
+	__cci_pmu_disable(cci_pmu);
+	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
+}
+
+/*
+ * Check if the idx represents a non-programmable counter.
+ * All the fixed event counters are mapped before the programmable
+ * counters.
+ */
+static bool pmu_fixed_hw_idx(struct cci_pmu *cci_pmu, int idx)
+{
+	return (idx >= 0) && (idx < cci_pmu->model->fixed_hw_cntrs);
+}
+
+static void cci_pmu_start(struct perf_event *event, int pmu_flags)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+	unsigned long flags;
+
+	/*
+	 * To handle interrupt latency, we always reprogram the period
+	 * regardlesss of PERF_EF_RELOAD.
+	 */
+	if (pmu_flags & PERF_EF_RELOAD)
+		WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+
+	hwc->state = 0;
+
+	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
+		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
+		return;
+	}
+
+	raw_spin_lock_irqsave(&hw_events->pmu_lock, flags);
+
+	/* Configure the counter unless you are counting a fixed event */
+	if (!pmu_fixed_hw_idx(cci_pmu, idx))
+		pmu_set_event(cci_pmu, idx, hwc->config_base);
+
+	pmu_event_set_period(event);
+	pmu_enable_counter(cci_pmu, idx);
+
+	raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags);
+}
+
+static void cci_pmu_stop(struct perf_event *event, int pmu_flags)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	if (hwc->state & PERF_HES_STOPPED)
+		return;
+
+	if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) {
+		dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx);
+		return;
+	}
+
+	/*
+	 * We always reprogram the counter, so ignore PERF_EF_UPDATE. See
+	 * cci_pmu_start()
+	 */
+	pmu_disable_counter(cci_pmu, idx);
+	pmu_event_update(event);
+	hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+}
+
+static int cci_pmu_add(struct perf_event *event, int flags)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+	int err = 0;
+
+	perf_pmu_disable(event->pmu);
+
+	/* If we don't have a space for the counter then finish early. */
+	idx = pmu_get_event_idx(hw_events, event);
+	if (idx < 0) {
+		err = idx;
+		goto out;
+	}
+
+	event->hw.idx = idx;
+	hw_events->events[idx] = event;
+
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+	if (flags & PERF_EF_START)
+		cci_pmu_start(event, PERF_EF_RELOAD);
+
+	/* Propagate our changes to the userspace mapping. */
+	perf_event_update_userpage(event);
+
+out:
+	perf_pmu_enable(event->pmu);
+	return err;
+}
+
+static void cci_pmu_del(struct perf_event *event, int flags)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	cci_pmu_stop(event, PERF_EF_UPDATE);
+	hw_events->events[idx] = NULL;
+	clear_bit(idx, hw_events->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+static int validate_event(struct pmu *cci_pmu,
+			  struct cci_pmu_hw_events *hw_events,
+			  struct perf_event *event)
+{
+	if (is_software_event(event))
+		return 1;
+
+	/*
+	 * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
+	 * core perf code won't check that the pmu->ctx == leader->ctx
+	 * until after pmu->event_init(event).
+	 */
+	if (event->pmu != cci_pmu)
+		return 0;
+
+	if (event->state < PERF_EVENT_STATE_OFF)
+		return 1;
+
+	if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
+		return 1;
+
+	return pmu_get_event_idx(hw_events, event) >= 0;
+}
+
+static int validate_group(struct perf_event *event)
+{
+	struct perf_event *sibling, *leader = event->group_leader;
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	unsigned long mask[BITS_TO_LONGS(cci_pmu->num_cntrs)];
+	struct cci_pmu_hw_events fake_pmu = {
+		/*
+		 * Initialise the fake PMU. We only need to populate the
+		 * used_mask for the purposes of validation.
+		 */
+		.used_mask = mask,
+	};
+	memset(mask, 0, BITS_TO_LONGS(cci_pmu->num_cntrs) * sizeof(unsigned long));
+
+	if (!validate_event(event->pmu, &fake_pmu, leader))
+		return -EINVAL;
+
+	for_each_sibling_event(sibling, leader) {
+		if (!validate_event(event->pmu, &fake_pmu, sibling))
+			return -EINVAL;
+	}
+
+	if (!validate_event(event->pmu, &fake_pmu, event))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int __hw_perf_event_init(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int mapping;
+
+	mapping = pmu_map_event(event);
+
+	if (mapping < 0) {
+		pr_debug("event %x:%llx not supported\n", event->attr.type,
+			 event->attr.config);
+		return mapping;
+	}
+
+	/*
+	 * We don't assign an index until we actually place the event onto
+	 * hardware. Use -1 to signify that we haven't decided where to put it
+	 * yet.
+	 */
+	hwc->idx		= -1;
+	hwc->config_base	= 0;
+	hwc->config		= 0;
+	hwc->event_base		= 0;
+
+	/*
+	 * Store the event encoding into the config_base field.
+	 */
+	hwc->config_base	    |= (unsigned long)mapping;
+
+	/*
+	 * Limit the sample_period to half of the counter width. That way, the
+	 * new counter value is far less likely to overtake the previous one
+	 * unless you have some serious IRQ latency issues.
+	 */
+	hwc->sample_period  = CCI_PMU_CNTR_MASK >> 1;
+	hwc->last_period    = hwc->sample_period;
+	local64_set(&hwc->period_left, hwc->sample_period);
+
+	if (event->group_leader != event) {
+		if (validate_group(event) != 0)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int cci_pmu_event_init(struct perf_event *event)
+{
+	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
+	atomic_t *active_events = &cci_pmu->active_events;
+	int err = 0;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/* Shared by all CPUs, no meaningful state to sample */
+	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+		return -EOPNOTSUPP;
+
+	/* We have no filtering of any kind */
+	if (event->attr.exclude_user	||
+	    event->attr.exclude_kernel	||
+	    event->attr.exclude_hv	||
+	    event->attr.exclude_idle	||
+	    event->attr.exclude_host	||
+	    event->attr.exclude_guest)
+		return -EINVAL;
+
+	/*
+	 * Following the example set by other "uncore" PMUs, we accept any CPU
+	 * and rewrite its affinity dynamically rather than having perf core
+	 * handle cpu == -1 and pid == -1 for this case.
+	 *
+	 * The perf core will pin online CPUs for the duration of this call and
+	 * the event being installed into its context, so the PMU's CPU can't
+	 * change under our feet.
+	 */
+	if (event->cpu < 0)
+		return -EINVAL;
+	event->cpu = cci_pmu->cpu;
+
+	event->destroy = hw_perf_event_destroy;
+	if (!atomic_inc_not_zero(active_events)) {
+		mutex_lock(&cci_pmu->reserve_mutex);
+		if (atomic_read(active_events) == 0)
+			err = cci_pmu_get_hw(cci_pmu);
+		if (!err)
+			atomic_inc(active_events);
+		mutex_unlock(&cci_pmu->reserve_mutex);
+	}
+	if (err)
+		return err;
+
+	err = __hw_perf_event_init(event);
+	if (err)
+		hw_perf_event_destroy(event);
+
+	return err;
+}
+
+static ssize_t pmu_cpumask_attr_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct pmu *pmu = dev_get_drvdata(dev);
+	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
+
+	return cpumap_print_to_pagebuf(true, buf, cpumask_of(cci_pmu->cpu));
+}
+
+static struct device_attribute pmu_cpumask_attr =
+	__ATTR(cpumask, S_IRUGO, pmu_cpumask_attr_show, NULL);
+
+static struct attribute *pmu_attrs[] = {
+	&pmu_cpumask_attr.attr,
+	NULL,
+};
+
+static struct attribute_group pmu_attr_group = {
+	.attrs = pmu_attrs,
+};
+
+static struct attribute_group pmu_format_attr_group = {
+	.name = "format",
+	.attrs = NULL,		/* Filled in cci_pmu_init_attrs */
+};
+
+static struct attribute_group pmu_event_attr_group = {
+	.name = "events",
+	.attrs = NULL,		/* Filled in cci_pmu_init_attrs */
+};
+
+static const struct attribute_group *pmu_attr_groups[] = {
+	&pmu_attr_group,
+	&pmu_format_attr_group,
+	&pmu_event_attr_group,
+	NULL
+};
+
+static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
+{
+	const struct cci_pmu_model *model = cci_pmu->model;
+	char *name = model->name;
+	u32 num_cntrs;
+
+	pmu_event_attr_group.attrs = model->event_attrs;
+	pmu_format_attr_group.attrs = model->format_attrs;
+
+	cci_pmu->pmu = (struct pmu) {
+		.name		= cci_pmu->model->name,
+		.task_ctx_nr	= perf_invalid_context,
+		.pmu_enable	= cci_pmu_enable,
+		.pmu_disable	= cci_pmu_disable,
+		.event_init	= cci_pmu_event_init,
+		.add		= cci_pmu_add,
+		.del		= cci_pmu_del,
+		.start		= cci_pmu_start,
+		.stop		= cci_pmu_stop,
+		.read		= pmu_read,
+		.attr_groups	= pmu_attr_groups,
+	};
+
+	cci_pmu->plat_device = pdev;
+	num_cntrs = pmu_get_max_counters(cci_pmu);
+	if (num_cntrs > cci_pmu->model->num_hw_cntrs) {
+		dev_warn(&pdev->dev,
+			"PMU implements more counters(%d) than supported by"
+			" the model(%d), truncated.",
+			num_cntrs, cci_pmu->model->num_hw_cntrs);
+		num_cntrs = cci_pmu->model->num_hw_cntrs;
+	}
+	cci_pmu->num_cntrs = num_cntrs + cci_pmu->model->fixed_hw_cntrs;
+
+	return perf_pmu_register(&cci_pmu->pmu, name, -1);
+}
+
+static int cci_pmu_offline_cpu(unsigned int cpu)
+{
+	int target;
+
+	if (!g_cci_pmu || cpu != g_cci_pmu->cpu)
+		return 0;
+
+	target = cpumask_any_but(cpu_online_mask, cpu);
+	if (target >= nr_cpu_ids)
+		return 0;
+
+	perf_pmu_migrate_context(&g_cci_pmu->pmu, cpu, target);
+	g_cci_pmu->cpu = target;
+	return 0;
+}
+
+static struct cci_pmu_model cci_pmu_models[] = {
+#ifdef CONFIG_ARM_CCI400_PMU
+	[CCI400_R0] = {
+		.name = "CCI_400",
+		.fixed_hw_cntrs = 1,	/* Cycle counter */
+		.num_hw_cntrs = 4,
+		.cntr_size = SZ_4K,
+		.format_attrs = cci400_pmu_format_attrs,
+		.event_attrs = cci400_r0_pmu_event_attrs,
+		.event_ranges = {
+			[CCI_IF_SLAVE] = {
+				CCI400_R0_SLAVE_PORT_MIN_EV,
+				CCI400_R0_SLAVE_PORT_MAX_EV,
+			},
+			[CCI_IF_MASTER] = {
+				CCI400_R0_MASTER_PORT_MIN_EV,
+				CCI400_R0_MASTER_PORT_MAX_EV,
+			},
+		},
+		.validate_hw_event = cci400_validate_hw_event,
+		.get_event_idx = cci400_get_event_idx,
+	},
+	[CCI400_R1] = {
+		.name = "CCI_400_r1",
+		.fixed_hw_cntrs = 1,	/* Cycle counter */
+		.num_hw_cntrs = 4,
+		.cntr_size = SZ_4K,
+		.format_attrs = cci400_pmu_format_attrs,
+		.event_attrs = cci400_r1_pmu_event_attrs,
+		.event_ranges = {
+			[CCI_IF_SLAVE] = {
+				CCI400_R1_SLAVE_PORT_MIN_EV,
+				CCI400_R1_SLAVE_PORT_MAX_EV,
+			},
+			[CCI_IF_MASTER] = {
+				CCI400_R1_MASTER_PORT_MIN_EV,
+				CCI400_R1_MASTER_PORT_MAX_EV,
+			},
+		},
+		.validate_hw_event = cci400_validate_hw_event,
+		.get_event_idx = cci400_get_event_idx,
+	},
+#endif
+#ifdef CONFIG_ARM_CCI5xx_PMU
+	[CCI500_R0] = {
+		.name = "CCI_500",
+		.fixed_hw_cntrs = 0,
+		.num_hw_cntrs = 8,
+		.cntr_size = SZ_64K,
+		.format_attrs = cci5xx_pmu_format_attrs,
+		.event_attrs = cci5xx_pmu_event_attrs,
+		.event_ranges = {
+			[CCI_IF_SLAVE] = {
+				CCI5xx_SLAVE_PORT_MIN_EV,
+				CCI5xx_SLAVE_PORT_MAX_EV,
+			},
+			[CCI_IF_MASTER] = {
+				CCI5xx_MASTER_PORT_MIN_EV,
+				CCI5xx_MASTER_PORT_MAX_EV,
+			},
+			[CCI_IF_GLOBAL] = {
+				CCI5xx_GLOBAL_PORT_MIN_EV,
+				CCI5xx_GLOBAL_PORT_MAX_EV,
+			},
+		},
+		.validate_hw_event = cci500_validate_hw_event,
+		.write_counters	= cci5xx_pmu_write_counters,
+	},
+	[CCI550_R0] = {
+		.name = "CCI_550",
+		.fixed_hw_cntrs = 0,
+		.num_hw_cntrs = 8,
+		.cntr_size = SZ_64K,
+		.format_attrs = cci5xx_pmu_format_attrs,
+		.event_attrs = cci5xx_pmu_event_attrs,
+		.event_ranges = {
+			[CCI_IF_SLAVE] = {
+				CCI5xx_SLAVE_PORT_MIN_EV,
+				CCI5xx_SLAVE_PORT_MAX_EV,
+			},
+			[CCI_IF_MASTER] = {
+				CCI5xx_MASTER_PORT_MIN_EV,
+				CCI5xx_MASTER_PORT_MAX_EV,
+			},
+			[CCI_IF_GLOBAL] = {
+				CCI5xx_GLOBAL_PORT_MIN_EV,
+				CCI5xx_GLOBAL_PORT_MAX_EV,
+			},
+		},
+		.validate_hw_event = cci550_validate_hw_event,
+		.write_counters	= cci5xx_pmu_write_counters,
+	},
+#endif
+};
+
+static const struct of_device_id arm_cci_pmu_matches[] = {
+#ifdef CONFIG_ARM_CCI400_PMU
+	{
+		.compatible = "arm,cci-400-pmu",
+		.data	= NULL,
+	},
+	{
+		.compatible = "arm,cci-400-pmu,r0",
+		.data	= &cci_pmu_models[CCI400_R0],
+	},
+	{
+		.compatible = "arm,cci-400-pmu,r1",
+		.data	= &cci_pmu_models[CCI400_R1],
+	},
+#endif
+#ifdef CONFIG_ARM_CCI5xx_PMU
+	{
+		.compatible = "arm,cci-500-pmu,r0",
+		.data = &cci_pmu_models[CCI500_R0],
+	},
+	{
+		.compatible = "arm,cci-550-pmu,r0",
+		.data = &cci_pmu_models[CCI550_R0],
+	},
+#endif
+	{},
+};
+
+static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs)
+{
+	int i;
+
+	for (i = 0; i < nr_irqs; i++)
+		if (irq == irqs[i])
+			return true;
+
+	return false;
+}
+
+static struct cci_pmu *cci_pmu_alloc(struct device *dev)
+{
+	struct cci_pmu *cci_pmu;
+	const struct cci_pmu_model *model;
+
+	/*
+	 * All allocations are devm_* hence we don't have to free
+	 * them explicitly on an error, as it would end up in driver
+	 * detach.
+	 */
+	cci_pmu = devm_kzalloc(dev, sizeof(*cci_pmu), GFP_KERNEL);
+	if (!cci_pmu)
+		return ERR_PTR(-ENOMEM);
+
+	cci_pmu->ctrl_base = *(void __iomem **)dev->platform_data;
+
+	model = of_device_get_match_data(dev);
+	if (!model) {
+		dev_warn(dev,
+			 "DEPRECATED compatible property, requires secure access to CCI registers");
+		model = probe_cci_model(cci_pmu);
+	}
+	if (!model) {
+		dev_warn(dev, "CCI PMU version not supported\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	cci_pmu->model = model;
+	cci_pmu->irqs = devm_kcalloc(dev, CCI_PMU_MAX_HW_CNTRS(model),
+					sizeof(*cci_pmu->irqs), GFP_KERNEL);
+	if (!cci_pmu->irqs)
+		return ERR_PTR(-ENOMEM);
+	cci_pmu->hw_events.events = devm_kcalloc(dev,
+					     CCI_PMU_MAX_HW_CNTRS(model),
+					     sizeof(*cci_pmu->hw_events.events),
+					     GFP_KERNEL);
+	if (!cci_pmu->hw_events.events)
+		return ERR_PTR(-ENOMEM);
+	cci_pmu->hw_events.used_mask = devm_kcalloc(dev,
+						BITS_TO_LONGS(CCI_PMU_MAX_HW_CNTRS(model)),
+						sizeof(*cci_pmu->hw_events.used_mask),
+						GFP_KERNEL);
+	if (!cci_pmu->hw_events.used_mask)
+		return ERR_PTR(-ENOMEM);
+
+	return cci_pmu;
+}
+
+static int cci_pmu_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct cci_pmu *cci_pmu;
+	int i, ret, irq;
+
+	cci_pmu = cci_pmu_alloc(&pdev->dev);
+	if (IS_ERR(cci_pmu))
+		return PTR_ERR(cci_pmu);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	cci_pmu->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(cci_pmu->base))
+		return -ENOMEM;
+
+	/*
+	 * CCI PMU has one overflow interrupt per counter; but some may be tied
+	 * together to a common interrupt.
+	 */
+	cci_pmu->nr_irqs = 0;
+	for (i = 0; i < CCI_PMU_MAX_HW_CNTRS(cci_pmu->model); i++) {
+		irq = platform_get_irq(pdev, i);
+		if (irq < 0)
+			break;
+
+		if (is_duplicate_irq(irq, cci_pmu->irqs, cci_pmu->nr_irqs))
+			continue;
+
+		cci_pmu->irqs[cci_pmu->nr_irqs++] = irq;
+	}
+
+	/*
+	 * Ensure that the device tree has as many interrupts as the number
+	 * of counters.
+	 */
+	if (i < CCI_PMU_MAX_HW_CNTRS(cci_pmu->model)) {
+		dev_warn(&pdev->dev, "In-correct number of interrupts: %d, should be %d\n",
+			i, CCI_PMU_MAX_HW_CNTRS(cci_pmu->model));
+		return -EINVAL;
+	}
+
+	raw_spin_lock_init(&cci_pmu->hw_events.pmu_lock);
+	mutex_init(&cci_pmu->reserve_mutex);
+	atomic_set(&cci_pmu->active_events, 0);
+	cci_pmu->cpu = get_cpu();
+
+	ret = cci_pmu_init(cci_pmu, pdev);
+	if (ret) {
+		put_cpu();
+		return ret;
+	}
+
+	cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_CCI_ONLINE,
+				  "perf/arm/cci:online", NULL,
+				  cci_pmu_offline_cpu);
+	put_cpu();
+	g_cci_pmu = cci_pmu;
+	pr_info("ARM %s PMU driver probed", cci_pmu->model->name);
+	return 0;
+}
+
+static struct platform_driver cci_pmu_driver = {
+	.driver = {
+		   .name = DRIVER_NAME,
+		   .of_match_table = arm_cci_pmu_matches,
+		  },
+	.probe = cci_pmu_probe,
+};
+
+builtin_platform_driver(cci_pmu_driver);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ARM CCI PMU support");
diff --git a/drivers/bus/arm-ccn.c b/drivers/perf/arm-ccn.c
similarity index 100%
rename from drivers/bus/arm-ccn.c
rename to drivers/perf/arm-ccn.c
diff --git a/drivers/phy/ti/phy-da8xx-usb.c b/drivers/phy/ti/phy-da8xx-usb.c
index 1b82bff..befb886 100644
--- a/drivers/phy/ti/phy-da8xx-usb.c
+++ b/drivers/phy/ti/phy-da8xx-usb.c
@@ -20,6 +20,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/phy/phy.h>
+#include <linux/platform_data/phy-da8xx-usb.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
@@ -145,6 +146,7 @@ static struct phy *da8xx_usb_phy_of_xlate(struct device *dev,
 static int da8xx_usb_phy_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct da8xx_usb_phy_platform_data *pdata = dev->platform_data;
 	struct device_node	*node = dev->of_node;
 	struct da8xx_usb_phy	*d_phy;
 
@@ -152,25 +154,25 @@ static int da8xx_usb_phy_probe(struct platform_device *pdev)
 	if (!d_phy)
 		return -ENOMEM;
 
-	if (node)
+	if (pdata)
+		d_phy->regmap = pdata->cfgchip;
+	else
 		d_phy->regmap = syscon_regmap_lookup_by_compatible(
 							"ti,da830-cfgchip");
-	else
-		d_phy->regmap = syscon_regmap_lookup_by_pdevname("syscon");
 	if (IS_ERR(d_phy->regmap)) {
 		dev_err(dev, "Failed to get syscon\n");
 		return PTR_ERR(d_phy->regmap);
 	}
 
-	d_phy->usb11_clk = devm_clk_get(dev, "usb11_phy");
+	d_phy->usb11_clk = devm_clk_get(dev, "usb1_clk48");
 	if (IS_ERR(d_phy->usb11_clk)) {
-		dev_err(dev, "Failed to get usb11_phy clock\n");
+		dev_err(dev, "Failed to get usb1_clk48\n");
 		return PTR_ERR(d_phy->usb11_clk);
 	}
 
-	d_phy->usb20_clk = devm_clk_get(dev, "usb20_phy");
+	d_phy->usb20_clk = devm_clk_get(dev, "usb0_clk48");
 	if (IS_ERR(d_phy->usb20_clk)) {
-		dev_err(dev, "Failed to get usb20_phy clock\n");
+		dev_err(dev, "Failed to get usb0_clk48\n");
 		return PTR_ERR(d_phy->usb20_clk);
 	}
 
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 95e5c5e..ad80a17 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -105,6 +105,14 @@ static const struct pinctrl_ops msm_pinctrl_ops = {
 	.dt_free_map		= pinctrl_utils_free_map,
 };
 
+static int msm_pinmux_request(struct pinctrl_dev *pctldev, unsigned offset)
+{
+	struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	struct gpio_chip *chip = &pctrl->chip;
+
+	return gpiochip_line_is_valid(chip, offset) ? 0 : -EINVAL;
+}
+
 static int msm_get_functions_count(struct pinctrl_dev *pctldev)
 {
 	struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@@ -166,6 +174,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
 }
 
 static const struct pinmux_ops msm_pinmux_ops = {
+	.request		= msm_pinmux_request,
 	.get_functions_count	= msm_get_functions_count,
 	.get_function_name	= msm_get_function_name,
 	.get_function_groups	= msm_get_function_groups,
@@ -506,6 +515,9 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
 		"pull up"
 	};
 
+	if (!gpiochip_line_is_valid(chip, offset))
+		return;
+
 	g = &pctrl->soc->groups[offset];
 	ctl_reg = readl(pctrl->regs + g->ctl_reg);
 
@@ -517,6 +529,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
 	seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
 	seq_printf(s, " %dmA", msm_regval_to_drive(drive));
 	seq_printf(s, " %s", pulls[pull]);
+	seq_puts(s, "\n");
 }
 
 static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
@@ -524,10 +537,8 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 	unsigned gpio = chip->base;
 	unsigned i;
 
-	for (i = 0; i < chip->ngpio; i++, gpio++) {
+	for (i = 0; i < chip->ngpio; i++, gpio++)
 		msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
-		seq_puts(s, "\n");
-	}
 }
 
 #else
@@ -808,6 +819,46 @@ static void msm_gpio_irq_handler(struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 }
 
+static int msm_gpio_init_valid_mask(struct gpio_chip *chip,
+				    struct msm_pinctrl *pctrl)
+{
+	int ret;
+	unsigned int len, i;
+	unsigned int max_gpios = pctrl->soc->ngpios;
+	u16 *tmp;
+
+	/* The number of GPIOs in the ACPI tables */
+	len = ret = device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0);
+	if (ret < 0)
+		return 0;
+
+	if (ret > max_gpios)
+		return -EINVAL;
+
+	tmp = kmalloc_array(len, sizeof(*tmp), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	ret = device_property_read_u16_array(pctrl->dev, "gpios", tmp, len);
+	if (ret < 0) {
+		dev_err(pctrl->dev, "could not read list of GPIOs\n");
+		goto out;
+	}
+
+	bitmap_zero(chip->valid_mask, max_gpios);
+	for (i = 0; i < len; i++)
+		set_bit(tmp[i], chip->valid_mask);
+
+out:
+	kfree(tmp);
+	return ret;
+}
+
+static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl)
+{
+	return device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0) > 0;
+}
+
 static int msm_gpio_init(struct msm_pinctrl *pctrl)
 {
 	struct gpio_chip *chip;
@@ -824,6 +875,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
 	chip->parent = pctrl->dev;
 	chip->owner = THIS_MODULE;
 	chip->of_node = pctrl->dev->of_node;
+	chip->need_valid_mask = msm_gpio_needs_valid_mask(pctrl);
 
 	ret = gpiochip_add_data(&pctrl->chip, pctrl);
 	if (ret) {
@@ -831,6 +883,13 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
 		return ret;
 	}
 
+	ret = msm_gpio_init_valid_mask(chip, pctrl);
+	if (ret) {
+		dev_err(pctrl->dev, "Failed to setup irq valid bits\n");
+		gpiochip_remove(&pctrl->chip);
+		return ret;
+	}
+
 	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
 	if (ret) {
 		dev_err(pctrl->dev, "Failed to add pin range\n");
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 5a68196..4c38904 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -492,7 +492,7 @@ static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
  * potentially bad time, such as a timer interrupt.
  */
 static void tpd_led_update(struct work_struct *work)
- {
+{
 	struct eeepc_laptop *eeepc;
 
 	eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c
index 89bf4d6..cb02371 100644
--- a/drivers/power/avs/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -132,12 +132,16 @@ static void sr_set_clk_length(struct omap_sr *sr)
 	struct clk *fck;
 	u32 fclk_speed;
 
-	fck = clk_get(&sr->pdev->dev, "fck");
-
+	/* Try interconnect target module fck first if it already exists */
+	fck = clk_get(sr->pdev->dev.parent, "fck");
 	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;
+		fck = clk_get(&sr->pdev->dev, "fck");
+		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;
+		}
 	}
 
 	fclk_speed = clk_get_rate(fck);
@@ -838,7 +842,7 @@ static int omap_sr_autocomp_store(void *data, u64 val)
 DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
 			omap_sr_autocomp_store, "%llu\n");
 
-static int __init omap_sr_probe(struct platform_device *pdev)
+static int omap_sr_probe(struct platform_device *pdev)
 {
 	struct omap_sr *sr_info;
 	struct omap_sr_data *pdata = pdev->dev.platform_data;
@@ -898,6 +902,12 @@ static int __init omap_sr_probe(struct platform_device *pdev)
 
 	list_add(&sr_info->node, &sr_list);
 
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&pdev->dev);
+		goto err_list_del;
+	}
+
 	/*
 	 * Call into late init to do initializations that require
 	 * both sr driver and sr class driver to be initiallized.
@@ -966,12 +976,17 @@ static int __init omap_sr_probe(struct platform_device *pdev)
 
 	}
 
+	pm_runtime_put_sync(&pdev->dev);
+
 	return ret;
 
 err_debugfs:
 	debugfs_remove_recursive(sr_info->dbg_dir);
 err_list_del:
 	list_del(&sr_info->node);
+
+	pm_runtime_put_sync(&pdev->dev);
+
 	return ret;
 }
 
@@ -1025,11 +1040,23 @@ static void omap_sr_shutdown(struct platform_device *pdev)
 	return;
 }
 
+static const struct of_device_id omap_sr_match[] = {
+	{ .compatible = "ti,omap3-smartreflex-core", },
+	{ .compatible = "ti,omap3-smartreflex-mpu-iva", },
+	{ .compatible = "ti,omap4-smartreflex-core", },
+	{ .compatible = "ti,omap4-smartreflex-mpu", },
+	{ .compatible = "ti,omap4-smartreflex-iva", },
+	{  },
+};
+MODULE_DEVICE_TABLE(of, omap_sr_match);
+
 static struct platform_driver smartreflex_driver = {
+	.probe		= omap_sr_probe,
 	.remove         = omap_sr_remove,
 	.shutdown	= omap_sr_shutdown,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.of_match_table	= omap_sr_match,
 	},
 };
 
@@ -1048,7 +1075,7 @@ static int __init sr_init(void)
 	else
 		pr_warn("%s: No PMIC hook to init smartreflex\n", __func__);
 
-	ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe);
+	ret = platform_driver_register(&smartreflex_driver);
 	if (ret) {
 		pr_err("%s: platform driver register failed for SR\n",
 		       __func__);
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..665da3c 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/dmtimer-omap.h>
 #include <linux/platform_data/pwm_omap_dmtimer.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
 	struct pwm_chip chip;
 	struct mutex mutex;
 	pwm_omap_dmtimer *dm_timer;
-	struct pwm_omap_dmtimer_pdata *pdata;
+	const struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
 };
 
@@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *timer;
+	struct platform_device *timer_pdev;
 	struct pwm_omap_dmtimer_chip *omap;
-	struct pwm_omap_dmtimer_pdata *pdata;
+	struct dmtimer_platform_data *timer_pdata;
+	const struct omap_dm_timer_ops *pdata;
 	pwm_omap_dmtimer *dm_timer;
 	u32 v;
-	int status;
+	int ret = 0;
 
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata) {
-		dev_err(&pdev->dev, "Missing dmtimer platform data\n");
-		return -EINVAL;
+	timer = of_parse_phandle(np, "ti,timers", 0);
+	if (!timer)
+		return -ENODEV;
+
+	timer_pdev = of_find_device_by_node(timer);
+	if (!timer_pdev) {
+		dev_err(&pdev->dev, "Unable to find Timer pdev\n");
+		ret = -ENODEV;
+		goto put;
 	}
 
-	if (!pdata->request_by_node ||
+	timer_pdata = dev_get_platdata(&timer_pdev->dev);
+	if (!timer_pdata) {
+		dev_err(&pdev->dev, "dmtimer pdata structure NULL\n");
+		ret = -EINVAL;
+		goto put;
+	}
+
+	pdata = timer_pdata->timer_ops;
+
+	if (!pdata || !pdata->request_by_node ||
 	    !pdata->free ||
 	    !pdata->enable ||
 	    !pdata->disable ||
@@ -267,21 +284,26 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	    !pdata->set_prescaler ||
 	    !pdata->write_counter) {
 		dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto put;
 	}
 
-	timer = of_parse_phandle(np, "ti,timers", 0);
-	if (!timer)
-		return -ENODEV;
-
 	if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
 		dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto put;
 	}
 
 	dm_timer = pdata->request_by_node(timer);
-	if (!dm_timer)
-		return -EPROBE_DEFER;
+	if (!dm_timer) {
+		ret = -EPROBE_DEFER;
+		goto put;
+	}
+
+put:
+	of_node_put(timer);
+	if (ret < 0)
+		return ret;
 
 	omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
 	if (!omap) {
@@ -291,13 +313,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 
 	omap->pdata = pdata;
 	omap->dm_timer = dm_timer;
-
-	omap->dm_timer_pdev = of_find_device_by_node(timer);
-	if (!omap->dm_timer_pdev) {
-		dev_err(&pdev->dev, "Unable to find timer pdev\n");
-		omap->pdata->free(dm_timer);
-		return -EINVAL;
-	}
+	omap->dm_timer_pdev = timer_pdev;
 
 	/*
 	 * Ensure that the timer is stopped before we allow PWM core to call
@@ -322,11 +338,11 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 
 	mutex_init(&omap->mutex);
 
-	status = pwmchip_add(&omap->chip);
-	if (status < 0) {
+	ret = pwmchip_add(&omap->chip);
+	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to register PWM\n");
 		omap->pdata->free(omap->dm_timer);
-		return status;
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, omap);
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 7fc7769..c0b292b 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -49,6 +49,7 @@
 
 config RESET_IMX7
 	bool "i.MX7 Reset Driver" if COMPILE_TEST
+	depends on HAS_IOMEM
 	default SOC_IMX7D
 	select MFD_SYSCON
 	help
@@ -83,14 +84,24 @@
 
 config RESET_SIMPLE
 	bool "Simple Reset Controller Driver" if COMPILE_TEST
-	default ARCH_SOCFPGA || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX
+	default ARCH_SOCFPGA || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED
 	help
 	  This enables a simple reset controller driver for reset lines that
 	  that can be asserted and deasserted by toggling bits in a contiguous,
 	  exclusive register space.
 
-	  Currently this driver supports Altera SoCFPGAs, the RCC reset
-	  controller in STM32 MCUs, Allwinner SoCs, and ZTE's zx2967 family.
+	  Currently this driver supports:
+	   - Altera SoCFPGAs
+	   - ASPEED BMC SoCs
+	   - RCC reset controller in STM32 MCUs
+	   - Allwinner SoCs
+	   - ZTE's zx2967 family
+
+config RESET_STM32MP157
+	bool "STM32MP157 Reset Driver" if COMPILE_TEST
+	default MACH_STM32MP157
+	help
+	  This enables the RCC reset controller driver for STM32 MPUs.
 
 config RESET_SUNXI
 	bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 132c24f..c1261dc 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -15,6 +15,7 @@
 obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
 obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
+obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
 obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index da4292e..6488292 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -23,6 +23,9 @@
 static DEFINE_MUTEX(reset_list_mutex);
 static LIST_HEAD(reset_controller_list);
 
+static DEFINE_MUTEX(reset_lookup_mutex);
+static LIST_HEAD(reset_lookup_list);
+
 /**
  * struct reset_control - a reset control
  * @rcdev: a pointer to the reset controller device
@@ -148,6 +151,33 @@ int devm_reset_controller_register(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_reset_controller_register);
 
+/**
+ * reset_controller_add_lookup - register a set of lookup entries
+ * @lookup: array of reset lookup entries
+ * @num_entries: number of entries in the lookup array
+ */
+void reset_controller_add_lookup(struct reset_control_lookup *lookup,
+				 unsigned int num_entries)
+{
+	struct reset_control_lookup *entry;
+	unsigned int i;
+
+	mutex_lock(&reset_lookup_mutex);
+	for (i = 0; i < num_entries; i++) {
+		entry = &lookup[i];
+
+		if (!entry->dev_id || !entry->provider) {
+			pr_warn("%s(): reset lookup entry badly specified, skipping\n",
+				__func__);
+			continue;
+		}
+
+		list_add_tail(&entry->list, &reset_lookup_list);
+	}
+	mutex_unlock(&reset_lookup_mutex);
+}
+EXPORT_SYMBOL_GPL(reset_controller_add_lookup);
+
 static inline struct reset_control_array *
 rstc_to_array(struct reset_control *rstc) {
 	return container_of(rstc, struct reset_control_array, base);
@@ -493,6 +523,70 @@ struct reset_control *__of_reset_control_get(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(__of_reset_control_get);
 
+static struct reset_controller_dev *
+__reset_controller_by_name(const char *name)
+{
+	struct reset_controller_dev *rcdev;
+
+	lockdep_assert_held(&reset_list_mutex);
+
+	list_for_each_entry(rcdev, &reset_controller_list, list) {
+		if (!rcdev->dev)
+			continue;
+
+		if (!strcmp(name, dev_name(rcdev->dev)))
+			return rcdev;
+	}
+
+	return NULL;
+}
+
+static struct reset_control *
+__reset_control_get_from_lookup(struct device *dev, const char *con_id,
+				bool shared, bool optional)
+{
+	const struct reset_control_lookup *lookup;
+	struct reset_controller_dev *rcdev;
+	const char *dev_id = dev_name(dev);
+	struct reset_control *rstc = NULL;
+
+	if (!dev)
+		return ERR_PTR(-EINVAL);
+
+	mutex_lock(&reset_lookup_mutex);
+
+	list_for_each_entry(lookup, &reset_lookup_list, list) {
+		if (strcmp(lookup->dev_id, dev_id))
+			continue;
+
+		if ((!con_id && !lookup->con_id) ||
+		    ((con_id && lookup->con_id) &&
+		     !strcmp(con_id, lookup->con_id))) {
+			mutex_lock(&reset_list_mutex);
+			rcdev = __reset_controller_by_name(lookup->provider);
+			if (!rcdev) {
+				mutex_unlock(&reset_list_mutex);
+				mutex_unlock(&reset_lookup_mutex);
+				/* Reset provider may not be ready yet. */
+				return ERR_PTR(-EPROBE_DEFER);
+			}
+
+			rstc = __reset_control_get_internal(rcdev,
+							    lookup->index,
+							    shared);
+			mutex_unlock(&reset_list_mutex);
+			break;
+		}
+	}
+
+	mutex_unlock(&reset_lookup_mutex);
+
+	if (!rstc)
+		return optional ? NULL : ERR_PTR(-ENOENT);
+
+	return rstc;
+}
+
 struct reset_control *__reset_control_get(struct device *dev, const char *id,
 					  int index, bool shared, bool optional)
 {
@@ -500,7 +594,7 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
 		return __of_reset_control_get(dev->of_node, id, index, shared,
 					      optional);
 
-	return optional ? NULL : ERR_PTR(-EINVAL);
+	return __reset_control_get_from_lookup(dev, id, shared, optional);
 }
 EXPORT_SYMBOL_GPL(__reset_control_get);
 
diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c
index 93cbee1..5242e06 100644
--- a/drivers/reset/reset-meson.c
+++ b/drivers/reset/reset-meson.c
@@ -124,29 +124,21 @@ static int meson_reset_deassert(struct reset_controller_dev *rcdev,
 	return meson_reset_level(rcdev, id, false);
 }
 
-static const struct reset_control_ops meson_reset_meson8_ops = {
-	.reset		= meson_reset_reset,
-};
-
-static const struct reset_control_ops meson_reset_gx_ops = {
+static const struct reset_control_ops meson_reset_ops = {
 	.reset		= meson_reset_reset,
 	.assert		= meson_reset_assert,
 	.deassert	= meson_reset_deassert,
 };
 
 static const struct of_device_id meson_reset_dt_ids[] = {
-	 { .compatible = "amlogic,meson8b-reset",
-	   .data = &meson_reset_meson8_ops, },
-	 { .compatible = "amlogic,meson-gxbb-reset",
-	   .data = &meson_reset_gx_ops, },
-	 { .compatible = "amlogic,meson-axg-reset",
-	   .data = &meson_reset_gx_ops, },
+	 { .compatible = "amlogic,meson8b-reset" },
+	 { .compatible = "amlogic,meson-gxbb-reset" },
+	 { .compatible = "amlogic,meson-axg-reset" },
 	 { /* sentinel */ },
 };
 
 static int meson_reset_probe(struct platform_device *pdev)
 {
-	const struct reset_control_ops *ops;
 	struct meson_reset *data;
 	struct resource *res;
 
@@ -154,10 +146,6 @@ static int meson_reset_probe(struct platform_device *pdev)
 	if (!data)
 		return -ENOMEM;
 
-	ops = of_device_get_match_data(&pdev->dev);
-	if (!ops)
-		return -EINVAL;
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	data->reg_base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(data->reg_base))
@@ -169,7 +157,7 @@ static int meson_reset_probe(struct platform_device *pdev)
 
 	data->rcdev.owner = THIS_MODULE;
 	data->rcdev.nr_resets = REG_COUNT * BITS_PER_REG;
-	data->rcdev.ops = ops;
+	data->rcdev.ops = &meson_reset_ops;
 	data->rcdev.of_node = pdev->dev.of_node;
 
 	return devm_reset_controller_register(&pdev->dev, &data->rcdev);
diff --git a/drivers/reset/reset-simple.c b/drivers/reset/reset-simple.c
index 2d4f362..f7ce891 100644
--- a/drivers/reset/reset-simple.c
+++ b/drivers/reset/reset-simple.c
@@ -125,6 +125,8 @@ static const struct of_device_id reset_simple_dt_ids[] = {
 		.data = &reset_simple_active_low },
 	{ .compatible = "zte,zx296718-reset",
 		.data = &reset_simple_active_low },
+	{ .compatible = "aspeed,ast2400-lpc-reset" },
+	{ .compatible = "aspeed,ast2500-lpc-reset" },
 	{ /* sentinel */ },
 };
 
diff --git a/drivers/reset/reset-stm32mp1.c b/drivers/reset/reset-stm32mp1.c
new file mode 100644
index 0000000..b221a28
--- /dev/null
+++ b/drivers/reset/reset-stm32mp1.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+#define CLR_OFFSET 0x4
+
+struct stm32_reset_data {
+	struct reset_controller_dev	rcdev;
+	void __iomem			*membase;
+};
+
+static inline struct stm32_reset_data *
+to_stm32_reset_data(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct stm32_reset_data, rcdev);
+}
+
+static int stm32_reset_update(struct reset_controller_dev *rcdev,
+			      unsigned long id, bool assert)
+{
+	struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
+	int reg_width = sizeof(u32);
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	void __iomem *addr;
+
+	addr = data->membase + (bank * reg_width);
+	if (!assert)
+		addr += CLR_OFFSET;
+
+	writel(BIT(offset), addr);
+
+	return 0;
+}
+
+static int stm32_reset_assert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	return stm32_reset_update(rcdev, id, true);
+}
+
+static int stm32_reset_deassert(struct reset_controller_dev *rcdev,
+				unsigned long id)
+{
+	return stm32_reset_update(rcdev, id, false);
+}
+
+static int stm32_reset_status(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
+	int reg_width = sizeof(u32);
+	int bank = id / (reg_width * BITS_PER_BYTE);
+	int offset = id % (reg_width * BITS_PER_BYTE);
+	u32 reg;
+
+	reg = readl(data->membase + (bank * reg_width));
+
+	return !!(reg & BIT(offset));
+}
+
+static const struct reset_control_ops stm32_reset_ops = {
+	.assert		= stm32_reset_assert,
+	.deassert	= stm32_reset_deassert,
+	.status		= stm32_reset_status,
+};
+
+static const struct of_device_id stm32_reset_dt_ids[] = {
+	{ .compatible = "st,stm32mp1-rcc"},
+	{ /* sentinel */ },
+};
+
+static int stm32_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct stm32_reset_data *data;
+	void __iomem *membase;
+	struct resource *res;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	membase = devm_ioremap_resource(dev, res);
+	if (IS_ERR(membase))
+		return PTR_ERR(membase);
+
+	data->membase = membase;
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = resource_size(res) * BITS_PER_BYTE;
+	data->rcdev.ops = &stm32_reset_ops;
+	data->rcdev.of_node = dev->of_node;
+
+	return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static struct platform_driver stm32_reset_driver = {
+	.probe	= stm32_reset_probe,
+	.driver = {
+		.name		= "stm32mp1-reset",
+		.of_match_table	= stm32_reset_dt_ids,
+	},
+};
+
+builtin_platform_driver(stm32_reset_driver);
diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c
index e8bb023..360e06b 100644
--- a/drivers/reset/reset-uniphier.c
+++ b/drivers/reset/reset-uniphier.c
@@ -63,6 +63,7 @@ static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = {
 	UNIPHIER_RESETX(12, 0x2000, 6),		/* GIO (Ether, SATA, USB3) */
 	UNIPHIER_RESETX(14, 0x2000, 17),	/* USB30 */
 	UNIPHIER_RESETX(15, 0x2004, 17),	/* USB31 */
+	UNIPHIER_RESETX(40, 0x2000, 13),	/* AIO */
 	UNIPHIER_RESET_END,
 };
 
@@ -72,6 +73,7 @@ static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = {
 	UNIPHIER_RESETX(12, 0x2000, 6),		/* GIO (PCIe, USB3) */
 	UNIPHIER_RESETX(14, 0x2000, 17),	/* USB30 */
 	UNIPHIER_RESETX(15, 0x2004, 17),	/* USB31 */
+	UNIPHIER_RESETX(40, 0x2000, 13),	/* AIO */
 	UNIPHIER_RESET_END,
 };
 
@@ -88,6 +90,7 @@ static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
 	UNIPHIER_RESETX(21, 0x2014, 1),		/* USB31-PHY1 */
 	UNIPHIER_RESETX(28, 0x2014, 12),	/* SATA */
 	UNIPHIER_RESET(29, 0x2014, 8),		/* SATA-PHY (active high) */
+	UNIPHIER_RESETX(40, 0x2000, 13),	/* AIO */
 	UNIPHIER_RESET_END,
 };
 
@@ -121,6 +124,8 @@ static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
 static const struct uniphier_reset_data uniphier_pxs3_sys_reset_data[] = {
 	UNIPHIER_RESETX(2, 0x200c, 0),		/* NAND */
 	UNIPHIER_RESETX(4, 0x200c, 2),		/* eMMC */
+	UNIPHIER_RESETX(6, 0x200c, 9),		/* Ether0 */
+	UNIPHIER_RESETX(7, 0x200c, 10),		/* Ether1 */
 	UNIPHIER_RESETX(8, 0x200c, 12),		/* STDMAC */
 	UNIPHIER_RESETX(12, 0x200c, 4),		/* USB30 link (GIO0) */
 	UNIPHIER_RESETX(13, 0x200c, 5),		/* USB31 link (GIO1) */
diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c
index a319bf1..ef5c16d 100644
--- a/drivers/rtc/rtc-ab-b5ze-s3.c
+++ b/drivers/rtc/rtc-ab-b5ze-s3.c
@@ -648,7 +648,7 @@ static int abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 			ret);
 
 	return ret;
- }
+}
 
 /* Enable or disable battery low irq generation */
 static inline int _abb5zes3_rtc_battery_low_irq_enable(struct regmap *regmap,
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index ecef8e7..b5692a2 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -3208,7 +3208,7 @@ static void dasd_setup_queue(struct dasd_block *block)
 	} else {
 		max = block->base->discipline->max_blocks << block->s2b_shift;
 	}
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
 	q->limits.max_dev_sectors = max;
 	blk_queue_logical_block_size(q, logical_block_size);
 	blk_queue_max_hw_sectors(q, max);
@@ -3231,7 +3231,7 @@ static void dasd_setup_queue(struct dasd_block *block)
 
 		blk_queue_max_discard_sectors(q, max_discard_sectors);
 		blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+		blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
 	}
 }
 
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 9cae08b..0a312e4 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -633,7 +633,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
 	dev_info->gd->private_data = dev_info;
 	blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request);
 	blk_queue_logical_block_size(dev_info->dcssblk_queue, 4096);
-	queue_flag_set_unlocked(QUEUE_FLAG_DAX, dev_info->dcssblk_queue);
+	blk_queue_flag_set(QUEUE_FLAG_DAX, dev_info->dcssblk_queue);
 
 	seg_byte_size = (dev_info->end - dev_info->start + 1);
 	set_capacity(dev_info->gd, seg_byte_size >> 9); // size in sectors
diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c
index b4130c7..b1fcb76 100644
--- a/drivers/s390/block/scm_blk.c
+++ b/drivers/s390/block/scm_blk.c
@@ -472,8 +472,8 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev)
 	blk_queue_logical_block_size(rq, 1 << 12);
 	blk_queue_max_hw_sectors(rq, nr_max_blk << 3); /* 8 * 512 = blk_size */
 	blk_queue_max_segments(rq, nr_max_blk);
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, rq);
-	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, rq);
+	blk_queue_flag_set(QUEUE_FLAG_NONROT, rq);
+	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, rq);
 
 	bdev->gendisk = alloc_disk(SCM_NR_PARTS);
 	if (!bdev->gendisk) {
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 2a6334c..3df5d68 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -348,8 +348,8 @@ static int __init xpram_setup_blkdev(void)
 			put_disk(xpram_disks[i]);
 			goto out;
 		}
-		queue_flag_set_unlocked(QUEUE_FLAG_NONROT, xpram_queues[i]);
-		queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, xpram_queues[i]);
+		blk_queue_flag_set(QUEUE_FLAG_NONROT, xpram_queues[i]);
+		blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, xpram_queues[i]);
 		blk_queue_make_request(xpram_queues[i], xpram_make_request);
 		blk_queue_logical_block_size(xpram_queues[i], 4096);
 	}
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index ca218c8..6162cf5 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -961,7 +961,7 @@ static int zfcp_fc_exec_els_job(struct bsg_job *job,
 		d_id = ntoh24(bsg_request->rqst_data.h_els.port_id);
 
 	els->handler = zfcp_fc_ct_els_job_handler;
-	return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ);
+	return zfcp_fsf_send_els(adapter, d_id, els, job->timeout / HZ);
 }
 
 static int zfcp_fc_exec_ct_job(struct bsg_job *job,
@@ -980,7 +980,7 @@ static int zfcp_fc_exec_ct_job(struct bsg_job *job,
 		return ret;
 
 	ct->handler = zfcp_fc_ct_job_handler;
-	ret = zfcp_fsf_send_ct(wka_port, ct, NULL, job->req->timeout / HZ);
+	ret = zfcp_fsf_send_ct(wka_port, ct, NULL, job->timeout / HZ);
 	if (ret)
 		zfcp_fc_wka_port_put(wka_port);
 
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 8a739b7..11e89e5 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -640,88 +640,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called dmx3191d.
 
-config SCSI_EATA
-	tristate "EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support"
-	depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API
-	---help---
-	  This driver supports all EATA/DMA-compliant SCSI host adapters.  DPT
-	  ISA and all EISA I/O addresses are probed looking for the "EATA"
-	  signature. The addresses of all the PCI SCSI controllers reported
-          by the PCI subsystem are probed as well.
-
-	  You want to read the start of <file:drivers/scsi/eata.c> and the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called eata.
-
-config SCSI_EATA_TAGGED_QUEUE
-	bool "enable tagged command queueing"
-	depends on SCSI_EATA
-	help
-	  This is a feature of SCSI-2 which improves performance: the host
-	  adapter can send several SCSI commands to a device's queue even if
-	  previous commands haven't finished yet.
-	  This is equivalent to the "eata=tc:y" boot option.
-
-config SCSI_EATA_LINKED_COMMANDS
-	bool "enable elevator sorting"
-	depends on SCSI_EATA
-	help
-	  This option enables elevator sorting for all probed SCSI disks and
-	  CD-ROMs. It definitely reduces the average seek distance when doing
-	  random seeks, but this does not necessarily result in a noticeable
-	  performance improvement: your mileage may vary...
-	  This is equivalent to the "eata=lc:y" boot option.
-
-config SCSI_EATA_MAX_TAGS
-	int "maximum number of queued commands"
-	depends on SCSI_EATA
-	default "16"
-	help
-	  This specifies how many SCSI commands can be maximally queued for
-	  each probed SCSI device. You should reduce the default value of 16
-	  only if you have disks with buggy or limited tagged command support.
-	  Minimum is 2 and maximum is 62. This value is also the window size
-	  used by the elevator sorting option above. The effective value used
-	  by the driver for each probed SCSI device is reported at boot time.
-	  This is equivalent to the "eata=mq:8" boot option.
-
-config SCSI_EATA_PIO
-	tristate "EATA-PIO (old DPT PM2001, PM2012A) support"
-	depends on (ISA || EISA || PCI) && SCSI && BROKEN
-	---help---
-	  This driver supports all EATA-PIO protocol compliant SCSI Host
-	  Adapters like the DPT PM2001 and the PM2012A.  EATA-DMA compliant
-	  host adapters could also use this driver but are discouraged from
-	  doing so, since this driver only supports hard disks and lacks
-	  numerous features.  You might want to have a look at the SCSI-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called eata_pio.
-
-config SCSI_FUTURE_DOMAIN
-	tristate "Future Domain 16xx SCSI/AHA-2920A support"
-	depends on (ISA || PCI) && SCSI
-	select CHECK_SIGNATURE
-	---help---
-	  This is support for Future Domain's 16-bit SCSI host adapters
-	  (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and
-	  other adapters based on the Future Domain chipsets (Quantum
-	  ISA-200S, ISA-250MG; Adaptec AHA-2920A; and at least one IBM board).
-	  It is explained in section 3.7 of the SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip
-	  and should use the aic7xxx driver ("Adaptec AIC7xxx chipset SCSI
-	  controller support"). This Future Domain driver works with the older
-	  Adaptec AHA-2920A boards with a Future Domain chip on them.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called fdomain.
-
 config SCSI_GDTH
 	tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
 	depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API
@@ -923,18 +841,6 @@
 
 	  Generally, saying N is fine.
 
-config SCSI_NCR53C406A
-	tristate "NCR53c406a SCSI support"
-	depends on ISA && SCSI
-	help
-	  This is support for the NCR53c406a SCSI host adapter.  For user
-	  configurable parameters, check out <file:drivers/scsi/NCR53c406a.c>
-	  in the kernel source.  Also read the SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called NCR53c406.
-
 config SCSI_NCR_D700
 	tristate "NCR Dual 700 MCA SCSI support"
 	depends on MCA && SCSI
@@ -1059,6 +965,7 @@
 	depends on PCI && SCSI && ATA
 	select FW_LOADER
 	select IRQ_POLL
+	select SGL_ALLOC
 	---help---
 	  This driver supports the IBM Power Linux family RAID adapters.
 	  This includes IBM pSeries 5712, 5703, 5709, and 570A, as well
@@ -1265,24 +1172,6 @@
 
 	  It currently supports Compaq EISA cards and NCR MCA cards
 
-config SCSI_SYM53C416
-	tristate "Symbios 53c416 SCSI support"
-	depends on ISA && SCSI
-	---help---
-	  This is support for the sym53c416 SCSI host adapter, the SCSI
-	  adapter that comes with some HP scanners. This driver requires that
-	  the sym53c416 is configured first using some sort of PnP
-	  configuration program (e.g. isapnp) or by a PnP aware BIOS. If you
-	  are using isapnp then you need to compile this driver as a module
-	  and then load it using insmod after isapnp has run. The parameters
-	  of the configured card(s) should be passed to the driver. The format
-	  is:
-
-	  insmod sym53c416 sym53c416=<base>,<irq> [sym53c416_1=<base>,<irq>]
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called sym53c416.
-
 config SCSI_DC395x
 	tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support"
 	depends on PCI && SCSI
@@ -1576,6 +1465,7 @@
 config SCSI_PMCRAID
 	tristate "PMC SIERRA Linux MaxRAID adapter support"
 	depends on PCI && SCSI && NET
+	select SGL_ALLOC
 	---help---
 	  This driver supports the PMC SIERRA MaxRAID adapters.
 
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index de1b3fc..e29f9b8 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -74,12 +74,9 @@
 obj-$(CONFIG_SCSI_PM8001)	+= pm8001/
 obj-$(CONFIG_SCSI_ISCI)		+= isci/
 obj-$(CONFIG_SCSI_IPS)		+= ips.o
-obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
-obj-$(CONFIG_SCSI_NCR53C406A)	+= NCR53c406a.o
 obj-$(CONFIG_SCSI_NCR_D700)	+= 53c700.o NCR_D700.o
 obj-$(CONFIG_SCSI_NCR_Q720)	+= NCR_Q720_mod.o
-obj-$(CONFIG_SCSI_SYM53C416)	+= sym53c416.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)	+= qlogicfas408.o	qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)	+= qlogicfas408.o
 obj-$(CONFIG_SCSI_QLOGIC_1280)	+= qla1280.o 
@@ -93,8 +90,6 @@
 obj-$(CONFIG_SCSI_SMARTPQI)	+= smartpqi/
 obj-$(CONFIG_SCSI_SYM53C8XX_2)	+= sym53c8xx_2/
 obj-$(CONFIG_SCSI_ZALON)	+= zalon7xx.o
-obj-$(CONFIG_SCSI_EATA_PIO)	+= eata_pio.o
-obj-$(CONFIG_SCSI_EATA)		+= eata.o
 obj-$(CONFIG_SCSI_DC395x)	+= dc395x.o
 obj-$(CONFIG_SCSI_AM53C974)	+= esp_scsi.o	am53c974.o
 obj-$(CONFIG_CXLFLASH)		+= cxlflash/
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
deleted file mode 100644
index 6e110c6..0000000
--- a/drivers/scsi/NCR53c406a.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/* 
- *  NCR53c406.c
- *  Low-level SCSI driver for NCR53c406a chip.
- *  Copyright (C) 1994, 1995, 1996 Normunds Saumanis (normunds@fi.ibm.com)
- * 
- *  LILO command line usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]
- *  Specify IRQ = 0 for non-interrupt driven mode.
- *  FASTPIO = 1 for fast pio mode, 0 for slow mode.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2, or (at your option) any
- *  later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- */
-
-#define NCR53C406A_DEBUG 0
-#define VERBOSE_NCR53C406A_DEBUG 0
-
-/* Set this to 1 for PIO mode (recommended) or to 0 for DMA mode */
-#define USE_PIO 1
-
-#define USE_BIOS 0
-				/* #define BIOS_ADDR 0xD8000 *//* define this if autoprobe fails */
-				/* #define PORT_BASE 0x330 *//* define this if autoprobe fails */
-				/* #define IRQ_LEV   0	*//* define this if autoprobe fails */
-#define DMA_CHAN  5		/* this is ignored if DMA is disabled */
-
-/* Set this to 0 if you encounter kernel lockups while transferring 
- * data in PIO mode */
-#define USE_FAST_PIO 1
-
-/* ============= End of user configurable parameters ============= */
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-
-#include <linux/blkdev.h>
-#include <linux/spinlock.h>
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-
-/* ============================================================= */
-
-#define WATCHDOG 5000000
-
-#define SYNC_MODE 0		/* Synchronous transfer mode */
-
-#ifdef DEBUG
-#undef NCR53C406A_DEBUG
-#define NCR53C406A_DEBUG 1
-#endif
-
-#if USE_PIO
-#define USE_DMA 0
-#else
-#define USE_DMA 1
-#endif
-
-/* Default configuration */
-#define C1_IMG   0x07		/* ID=7 */
-#define C2_IMG   0x48		/* FE SCSI2 */
-#if USE_DMA
-#define C3_IMG   0x21		/* CDB TE */
-#else
-#define C3_IMG   0x20		/* CDB */
-#endif
-#define C4_IMG   0x04		/* ANE */
-#define C5_IMG   0xb6		/* AA PI SIE POL */
-
-#define REG0 (outb(C4_IMG, CONFIG4))
-#define REG1 (outb(C5_IMG, CONFIG5))
-
-#if NCR53C406A_DEBUG
-#define DEB(x) x
-#else
-#define DEB(x)
-#endif
-
-#if VERBOSE_NCR53C406A_DEBUG
-#define VDEB(x) x
-#else
-#define VDEB(x)
-#endif
-
-#define LOAD_DMA_COUNT(count) \
-  outb(count & 0xff, TC_LSB); \
-  outb((count >> 8) & 0xff, TC_MSB); \
-  outb((count >> 16) & 0xff, TC_HIGH);
-
-/* Chip commands */
-#define DMA_OP               0x80
-
-#define SCSI_NOP             0x00
-#define FLUSH_FIFO           0x01
-#define CHIP_RESET           0x02
-#define SCSI_RESET           0x03
-#define RESELECT             0x40
-#define SELECT_NO_ATN        0x41
-#define SELECT_ATN           0x42
-#define SELECT_ATN_STOP      0x43
-#define ENABLE_SEL           0x44
-#define DISABLE_SEL          0x45
-#define SELECT_ATN3          0x46
-#define RESELECT3            0x47
-#define TRANSFER_INFO        0x10
-#define INIT_CMD_COMPLETE    0x11
-#define MSG_ACCEPT           0x12
-#define TRANSFER_PAD         0x18
-#define SET_ATN              0x1a
-#define RESET_ATN            0x1b
-#define SEND_MSG             0x20
-#define SEND_STATUS          0x21
-#define SEND_DATA            0x22
-#define DISCONN_SEQ          0x23
-#define TERMINATE_SEQ        0x24
-#define TARG_CMD_COMPLETE    0x25
-#define DISCONN              0x27
-#define RECV_MSG             0x28
-#define RECV_CMD             0x29
-#define RECV_DATA            0x2a
-#define RECV_CMD_SEQ         0x2b
-#define TARGET_ABORT_DMA     0x04
-
-/*----------------------------------------------------------------*/
-/* the following will set the monitor border color (useful to find
-   where something crashed or gets stuck at */
-/* 1 = blue
-   2 = green
-   3 = cyan
-   4 = red
-   5 = magenta
-   6 = yellow
-   7 = white
-*/
-
-#if NCR53C406A_DEBUG
-#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
-#else
-#define rtrc(i) {}
-#endif
-/*----------------------------------------------------------------*/
-
-enum Phase {
-	idle,
-	data_out,
-	data_in,
-	command_ph,
-	status_ph,
-	message_out,
-	message_in
-};
-
-/* Static function prototypes */
-static void NCR53c406a_intr(void *);
-static irqreturn_t do_NCR53c406a_intr(int, void *);
-static void chip_init(void);
-static void calc_port_addr(void);
-#ifndef IRQ_LEV
-static int irq_probe(void);
-#endif
-
-/* ================================================================= */
-
-#if USE_BIOS
-static void *bios_base;
-#endif
-
-#ifdef PORT_BASE
-static int port_base = PORT_BASE;
-#else
-static int port_base;
-#endif
-
-#ifdef IRQ_LEV
-static int irq_level = IRQ_LEV;
-#else
-static int irq_level = -1;	/* 0 is 'no irq', so use -1 for 'uninitialized' */
-#endif
-
-#if USE_DMA
-static int dma_chan;
-#endif
-
-#if USE_PIO
-static int fast_pio = USE_FAST_PIO;
-#endif
-
-static Scsi_Cmnd *current_SC;
-static char info_msg[256];
-
-/* ================================================================= */
-
-/* possible BIOS locations */
-#if USE_BIOS
-static void *addresses[] = {
-	(void *) 0xd8000,
-	(void *) 0xc8000
-};
-#define ADDRESS_COUNT ARRAY_SIZE(addresses)
-#endif				/* USE_BIOS */
-
-/* possible i/o port addresses */
-static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 };
-#define PORT_COUNT ARRAY_SIZE(ports)
-
-#ifndef MODULE
-/* possible interrupt channels */
-static unsigned short intrs[] = { 10, 11, 12, 15 };
-#define INTR_COUNT ARRAY_SIZE(intrs)
-#endif /* !MODULE */
-
-/* signatures for NCR 53c406a based controllers */
-#if USE_BIOS
-struct signature {
-	char *signature;
-	int sig_offset;
-	int sig_length;
-} signatures[] __initdata = {
-	/*          1         2         3         4         5         6 */
-	/* 123456789012345678901234567890123456789012345678901234567890 */
-	{
-"Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82},};
-
-#define SIGNATURE_COUNT ARRAY_SIZE(signatures)
-#endif				/* USE_BIOS */
-
-/* ============================================================ */
-
-/* Control Register Set 0 */
-static int TC_LSB;		/* transfer counter lsb         */
-static int TC_MSB;		/* transfer counter msb */
-static int SCSI_FIFO;		/* scsi fifo register   */
-static int CMD_REG;		/* command register             */
-static int STAT_REG;		/* status register              */
-static int DEST_ID;		/* selection/reselection bus id */
-static int INT_REG;		/* interrupt status register    */
-static int SRTIMOUT;		/* select/reselect timeout reg  */
-static int SEQ_REG;		/* sequence step register       */
-static int SYNCPRD;		/* synchronous transfer period  */
-static int FIFO_FLAGS;		/* indicates # of bytes in fifo */
-static int SYNCOFF;		/* synchronous offset register  */
-static int CONFIG1;		/* configuration register       */
-static int CLKCONV;		/* clock conversion reg */
-				/*static int TESTREG;*//* test mode register           */
-static int CONFIG2;		/* Configuration 2 Register     */
-static int CONFIG3;		/* Configuration 3 Register     */
-static int CONFIG4;		/* Configuration 4 Register     */
-static int TC_HIGH;		/* Transfer Counter High */
-				/*static int FIFO_BOTTOM;*//* Reserve FIFO byte register   */
-
-/* Control Register Set 1 */
-				/*static int JUMPER_SENSE;*//* Jumper sense port reg (r/w) */
-				/*static int SRAM_PTR;*//* SRAM address pointer reg (r/w) */
-				/*static int SRAM_DATA;*//* SRAM data register (r/w) */
-static int PIO_FIFO;		/* PIO FIFO registers (r/w) */
-				/*static int PIO_FIFO1;*//*  */
-				/*static int PIO_FIFO2;*//*  */
-				/*static int PIO_FIFO3;*//*  */
-static int PIO_STATUS;		/* PIO status (r/w) */
-				/*static int ATA_CMD;*//* ATA command/status reg (r/w) */
-				/*static int ATA_ERR;*//* ATA features/error register (r/w) */
-static int PIO_FLAG;		/* PIO flag interrupt enable (r/w) */
-static int CONFIG5;		/* Configuration 5 register (r/w) */
-				/*static int SIGNATURE;*//* Signature Register (r) */
-				/*static int CONFIG6;*//* Configuration 6 register (r) */
-
-/* ============================================================== */
-
-#if USE_DMA
-static __inline__ int NCR53c406a_dma_setup(unsigned char *ptr, unsigned int count, unsigned char mode)
-{
-	unsigned limit;
-	unsigned long flags = 0;
-
-	VDEB(printk("dma: before count=%d   ", count));
-	if (dma_chan <= 3) {
-		if (count > 65536)
-			count = 65536;
-		limit = 65536 - (((unsigned) ptr) & 0xFFFF);
-	} else {
-		if (count > (65536 << 1))
-			count = (65536 << 1);
-		limit = (65536 << 1) - (((unsigned) ptr) & 0x1FFFF);
-	}
-
-	if (count > limit)
-		count = limit;
-
-	VDEB(printk("after count=%d\n", count));
-	if ((count & 1) || (((unsigned) ptr) & 1))
-		panic("NCR53c406a: attempted unaligned DMA transfer\n");
-
-	flags = claim_dma_lock();
-	disable_dma(dma_chan);
-	clear_dma_ff(dma_chan);
-	set_dma_addr(dma_chan, (long) ptr);
-	set_dma_count(dma_chan, count);
-	set_dma_mode(dma_chan, mode);
-	enable_dma(dma_chan);
-	release_dma_lock(flags);
-
-	return count;
-}
-
-static __inline__ int NCR53c406a_dma_write(unsigned char *src, unsigned int count)
-{
-	return NCR53c406a_dma_setup(src, count, DMA_MODE_WRITE);
-}
-
-static __inline__ int NCR53c406a_dma_read(unsigned char *src, unsigned int count)
-{
-	return NCR53c406a_dma_setup(src, count, DMA_MODE_READ);
-}
-
-static __inline__ int NCR53c406a_dma_residual(void)
-{
-	register int tmp;
-	unsigned long flags;
-
-	flags = claim_dma_lock();
-	clear_dma_ff(dma_chan);
-	tmp = get_dma_residue(dma_chan);
-	release_dma_lock(flags);
-
-	return tmp;
-}
-#endif				/* USE_DMA */
-
-#if USE_PIO
-static __inline__ int NCR53c406a_pio_read(unsigned char *request, unsigned int reqlen)
-{
-	int i;
-	int len;		/* current scsi fifo size */
-
-	REG1;
-	while (reqlen) {
-		i = inb(PIO_STATUS);
-		/*    VDEB(printk("pio_status=%x\n", i)); */
-		if (i & 0x80)
-			return 0;
-
-		switch (i & 0x1e) {
-		default:
-		case 0x10:
-			len = 0;
-			break;
-		case 0x0:
-			len = 1;
-			break;
-		case 0x8:
-			len = 42;
-			break;
-		case 0xc:
-			len = 84;
-			break;
-		case 0xe:
-			len = 128;
-			break;
-		}
-
-		if ((i & 0x40) && len == 0) {	/* fifo empty and interrupt occurred */
-			return 0;
-		}
-
-		if (len) {
-			if (len > reqlen)
-				len = reqlen;
-
-			if (fast_pio && len > 3) {
-				insl(PIO_FIFO, request, len >> 2);
-				request += len & 0xfc;
-				reqlen -= len & 0xfc;
-			} else {
-				while (len--) {
-					*request++ = inb(PIO_FIFO);
-					reqlen--;
-				}
-			}
-		}
-	}
-	return 0;
-}
-
-static __inline__ int NCR53c406a_pio_write(unsigned char *request, unsigned int reqlen)
-{
-	int i = 0;
-	int len;		/* current scsi fifo size */
-
-	REG1;
-	while (reqlen && !(i & 0x40)) {
-		i = inb(PIO_STATUS);
-		/*    VDEB(printk("pio_status=%x\n", i)); */
-		if (i & 0x80)	/* error */
-			return 0;
-
-		switch (i & 0x1e) {
-		case 0x10:
-			len = 128;
-			break;
-		case 0x0:
-			len = 84;
-			break;
-		case 0x8:
-			len = 42;
-			break;
-		case 0xc:
-			len = 1;
-			break;
-		default:
-		case 0xe:
-			len = 0;
-			break;
-		}
-
-		if (len) {
-			if (len > reqlen)
-				len = reqlen;
-
-			if (fast_pio && len > 3) {
-				outsl(PIO_FIFO, request, len >> 2);
-				request += len & 0xfc;
-				reqlen -= len & 0xfc;
-			} else {
-				while (len--) {
-					outb(*request++, PIO_FIFO);
-					reqlen--;
-				}
-			}
-		}
-	}
-	return 0;
-}
-#endif				/* USE_PIO */
-
-static int __init NCR53c406a_detect(struct scsi_host_template * tpnt)
-{
-	int present = 0;
-	struct Scsi_Host *shpnt = NULL;
-#ifndef PORT_BASE
-	int i;
-#endif
-
-#if USE_BIOS
-	int ii, jj;
-	bios_base = 0;
-	/* look for a valid signature */
-	for (ii = 0; ii < ADDRESS_COUNT && !bios_base; ii++)
-		for (jj = 0; (jj < SIGNATURE_COUNT) && !bios_base; jj++)
-			if (!memcmp((void *) addresses[ii] + signatures[jj].sig_offset, (void *) signatures[jj].signature, (int) signatures[jj].sig_length))
-				bios_base = addresses[ii];
-
-	if (!bios_base) {
-		printk("NCR53c406a: BIOS signature not found\n");
-		return 0;
-	}
-
-	DEB(printk("NCR53c406a BIOS found at 0x%x\n", (unsigned int) bios_base);
-	    );
-#endif				/* USE_BIOS */
-
-#ifdef PORT_BASE
-	if (!request_region(port_base, 0x10, "NCR53c406a"))	/* ports already snatched */
-		port_base = 0;
-
-#else				/* autodetect */
-	if (port_base) {	/* LILO override */
-		if (!request_region(port_base, 0x10, "NCR53c406a"))
-			port_base = 0;
-	} else {
-		for (i = 0; i < PORT_COUNT && !port_base; i++) {
-			if (!request_region(ports[i], 0x10, "NCR53c406a")) {
-				DEB(printk("NCR53c406a: port 0x%x in use\n", ports[i]));
-			} else {
-				VDEB(printk("NCR53c406a: port 0x%x available\n", ports[i]));
-				outb(C5_IMG, ports[i] + 0x0d);	/* reg set 1 */
-				if ((inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7 && (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7 && (inb(ports[i] + 0x0e) & 0xf8) == 0x58) {
-					port_base = ports[i];
-					VDEB(printk("NCR53c406a: Sig register valid\n"));
-					VDEB(printk("port_base=0x%x\n", port_base));
-					break;
-				}
-				release_region(ports[i], 0x10);
-			}
-		}
-	}
-#endif				/* PORT_BASE */
-
-	if (!port_base) {	/* no ports found */
-		printk("NCR53c406a: no available ports found\n");
-		return 0;
-	}
-
-	DEB(printk("NCR53c406a detected\n"));
-
-	calc_port_addr();
-	chip_init();
-
-#ifndef IRQ_LEV
-	if (irq_level < 0) {	/* LILO override if >= 0 */
-		irq_level = irq_probe();
-		if (irq_level < 0) {	/* Trouble */
-			printk("NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level);
-			goto err_release;
-		}
-	}
-#endif
-
-	DEB(printk("NCR53c406a: using port_base 0x%x\n", port_base));
-
-	present = 1;
-	tpnt->proc_name = "NCR53c406a";
-
-	shpnt = scsi_register(tpnt, 0);
-	if (!shpnt) {
-		printk("NCR53c406a: Unable to register host, giving up.\n");
-		goto err_release;
-	}
-
-	if (irq_level > 0) {
-		if (request_irq(irq_level, do_NCR53c406a_intr, 0, "NCR53c406a", shpnt)) {
-			printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level);
-			goto err_free_scsi;
-		}
-		tpnt->can_queue = 1;
-		DEB(printk("NCR53c406a: allocated IRQ %d\n", irq_level));
-	} else if (irq_level == 0) {
-		tpnt->can_queue = 0;
-		DEB(printk("NCR53c406a: No interrupts detected\n"));
-		printk("NCR53c406a driver no longer supports polling interface\n");
-		printk("Please email linux-scsi@vger.kernel.org\n");
-                        
-#if USE_DMA
-		printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
-#endif				/* USE_DMA */
-		goto err_free_scsi;
-	} else {
-		DEB(printk("NCR53c406a: Shouldn't get here!\n"));
-		goto err_free_scsi;
-	}
-
-#if USE_DMA
-	dma_chan = DMA_CHAN;
-	if (request_dma(dma_chan, "NCR53c406a") != 0) {
-		printk("NCR53c406a: unable to allocate DMA channel %d\n", dma_chan);
-		goto err_free_irq;
-	}
-
-	DEB(printk("Allocated DMA channel %d\n", dma_chan));
-#endif				/* USE_DMA */
-
-	shpnt->irq = irq_level;
-	shpnt->io_port = port_base;
-	shpnt->n_io_port = 0x10;
-#if USE_DMA
-	shpnt->dma = dma_chan;
-#endif
-
-#if USE_DMA
-	sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, DMA channel %d.", port_base, irq_level, dma_chan);
-#else
-	sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.", port_base, irq_level, fast_pio ? "fast" : "slow");
-#endif
-
-	return (present);
-
-#if USE_DMA
-      err_free_irq:
-	if (irq_level)
-		free_irq(irq_level, shpnt);
-#endif
-      err_free_scsi:
-	scsi_unregister(shpnt);
-      err_release:
-	release_region(port_base, 0x10);
-	return 0;
-}
-
-static int NCR53c406a_release(struct Scsi_Host *shost)
-{
-	if (shost->irq)
-		free_irq(shost->irq, NULL);
-#if USE_DMA
-	if (shost->dma_channel != 0xff)
-		free_dma(shost->dma_channel);
-#endif
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
-
-	scsi_unregister(shost);
-	return 0;
-}
-
-#ifndef MODULE
-/* called from init/main.c */
-static int __init NCR53c406a_setup(char *str)
-{
-	static size_t setup_idx = 0;
-	size_t i;
-	int ints[4];
-
-	DEB(printk("NCR53c406a: Setup called\n");
-	    );
-
-	if (setup_idx >= PORT_COUNT - 1) {
-		printk("NCR53c406a: Setup called too many times.  Bad LILO params?\n");
-		return 0;
-	}
-	get_options(str, 4, ints);
-	if (ints[0] < 1 || ints[0] > 3) {
-		printk("NCR53c406a: Malformed command line\n");
-		printk("NCR53c406a: Usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]\n");
-		return 0;
-	}
-	for (i = 0; i < PORT_COUNT && !port_base; i++)
-		if (ports[i] == ints[1]) {
-			port_base = ints[1];
-			DEB(printk("NCR53c406a: Specified port_base 0x%x\n", port_base);
-			    )
-		}
-	if (!port_base) {
-		printk("NCR53c406a: Invalid PORTBASE 0x%x specified\n", ints[1]);
-		return 0;
-	}
-
-	if (ints[0] > 1) {
-		if (ints[2] == 0) {
-			irq_level = 0;
-			DEB(printk("NCR53c406a: Specified irq %d\n", irq_level);
-			    )
-		} else
-			for (i = 0; i < INTR_COUNT && irq_level < 0; i++)
-				if (intrs[i] == ints[2]) {
-					irq_level = ints[2];
-					DEB(printk("NCR53c406a: Specified irq %d\n", port_base);
-					    )
-				}
-		if (irq_level < 0)
-			printk("NCR53c406a: Invalid IRQ %d specified\n", ints[2]);
-	}
-
-	if (ints[0] > 2)
-		fast_pio = ints[3];
-
-	DEB(printk("NCR53c406a: port_base=0x%x, irq=%d, fast_pio=%d\n", port_base, irq_level, fast_pio);)
-	return 1;
-}
-
-__setup("ncr53c406a=", NCR53c406a_setup);
-
-#endif /* !MODULE */
-
-static const char *NCR53c406a_info(struct Scsi_Host *SChost)
-{
-	DEB(printk("NCR53c406a_info called\n"));
-	return (info_msg);
-}
-
-#if 0
-static void wait_intr(void)
-{
-	unsigned long i = jiffies + WATCHDOG;
-
-	while (time_after(i, jiffies) && !(inb(STAT_REG) & 0xe0)) {	/* wait for a pseudo-interrupt */
-		cpu_relax();
-		barrier();
-	}
-
-	if (time_before_eq(i, jiffies)) {	/* Timed out */
-		rtrc(0);
-		current_SC->result = DID_TIME_OUT << 16;
-		current_SC->SCp.phase = idle;
-		current_SC->scsi_done(current_SC);
-		return;
-	}
-
-	NCR53c406a_intr(NULL);
-}
-#endif
-
-static int NCR53c406a_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
-{
-	int i;
-
-	VDEB(printk("NCR53c406a_queue called\n"));
-        DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->device->target, (u8)SCpnt->device->lun, scsi_bufflen(SCpnt)));
-
-#if 0
-	VDEB(for (i = 0; i < SCpnt->cmd_len; i++)
-	     printk("cmd[%d]=%02x  ", i, SCpnt->cmnd[i]));
-	VDEB(printk("\n"));
-#endif
-
-	current_SC = SCpnt;
-	current_SC->scsi_done = done;
-	current_SC->SCp.phase = command_ph;
-	current_SC->SCp.Status = 0;
-	current_SC->SCp.Message = 0;
-
-	/* We are locked here already by the mid layer */
-	REG0;
-	outb(scmd_id(SCpnt), DEST_ID);	/* set destination */
-	outb(FLUSH_FIFO, CMD_REG);	/* reset the fifos */
-
-	for (i = 0; i < SCpnt->cmd_len; i++) {
-		outb(SCpnt->cmnd[i], SCSI_FIFO);
-	}
-	outb(SELECT_NO_ATN, CMD_REG);
-
-	rtrc(1);
-	return 0;
-}
-
-static DEF_SCSI_QCMD(NCR53c406a_queue)
-
-static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("NCR53c406a_reset called\n"));
-
-	spin_lock_irq(SCpnt->device->host->host_lock);
-
-	outb(C4_IMG, CONFIG4);	/* Select reg set 0 */
-	outb(CHIP_RESET, CMD_REG);
-	outb(SCSI_NOP, CMD_REG);	/* required after reset */
-	outb(SCSI_RESET, CMD_REG);
-	chip_init();
-
-	rtrc(2);
-
-	spin_unlock_irq(SCpnt->device->host->host_lock);
-
-	return SUCCESS;
-}
-
-static int NCR53c406a_biosparm(struct scsi_device *disk,
-                               struct block_device *dev,
-			       sector_t capacity, int *info_array)
-{
-	int size;
-
-	DEB(printk("NCR53c406a_biosparm called\n"));
-
-	size = capacity;
-	info_array[0] = 64;	/* heads */
-	info_array[1] = 32;	/* sectors */
-	info_array[2] = size >> 11;	/* cylinders */
-	if (info_array[2] > 1024) {	/* big disk */
-		info_array[0] = 255;
-		info_array[1] = 63;
-		info_array[2] = size / (255 * 63);
-	}
-	return 0;
-}
-
-static irqreturn_t do_NCR53c406a_intr(int unused, void *dev_id)
-{
-	unsigned long flags;
-	struct Scsi_Host *dev = dev_id;
-
-	spin_lock_irqsave(dev->host_lock, flags);
-	NCR53c406a_intr(dev_id);
-	spin_unlock_irqrestore(dev->host_lock, flags);
-	return IRQ_HANDLED;
-}
-
-static void NCR53c406a_intr(void *dev_id)
-{
-	DEB(unsigned char fifo_size;
-	    )
-	    DEB(unsigned char seq_reg;
-	    )
-	unsigned char status, int_reg;
-#if USE_PIO
-	unsigned char pio_status;
-	struct scatterlist *sg;
-        int i;
-#endif
-
-	VDEB(printk("NCR53c406a_intr called\n"));
-
-#if USE_PIO
-	REG1;
-	pio_status = inb(PIO_STATUS);
-#endif
-	REG0;
-	status = inb(STAT_REG);
-	DEB(seq_reg = inb(SEQ_REG));
-	int_reg = inb(INT_REG);
-	DEB(fifo_size = inb(FIFO_FLAGS) & 0x1f);
-
-#if NCR53C406A_DEBUG
-	printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x", status, seq_reg, int_reg, fifo_size);
-#if (USE_DMA)
-	printk("\n");
-#else
-	printk(", pio=%02x\n", pio_status);
-#endif				/* USE_DMA */
-#endif				/* NCR53C406A_DEBUG */
-
-	if (int_reg & 0x80) {	/* SCSI reset intr */
-		rtrc(3);
-		DEB(printk("NCR53c406a: reset intr received\n"));
-		current_SC->SCp.phase = idle;
-		current_SC->result = DID_RESET << 16;
-		current_SC->scsi_done(current_SC);
-		return;
-	}
-#if USE_PIO
-	if (pio_status & 0x80) {
-		printk("NCR53C406A: Warning: PIO error!\n");
-		current_SC->SCp.phase = idle;
-		current_SC->result = DID_ERROR << 16;
-		current_SC->scsi_done(current_SC);
-		return;
-	}
-#endif				/* USE_PIO */
-
-	if (status & 0x20) {	/* Parity error */
-		printk("NCR53c406a: Warning: parity error!\n");
-		current_SC->SCp.phase = idle;
-		current_SC->result = DID_PARITY << 16;
-		current_SC->scsi_done(current_SC);
-		return;
-	}
-
-	if (status & 0x40) {	/* Gross error */
-		printk("NCR53c406a: Warning: gross error!\n");
-		current_SC->SCp.phase = idle;
-		current_SC->result = DID_ERROR << 16;
-		current_SC->scsi_done(current_SC);
-		return;
-	}
-
-	if (int_reg & 0x20) {	/* Disconnect */
-		DEB(printk("NCR53c406a: disconnect intr received\n"));
-		if (current_SC->SCp.phase != message_in) {	/* Unexpected disconnect */
-			current_SC->result = DID_NO_CONNECT << 16;
-		} else {	/* Command complete, return status and message */
-			current_SC->result = (current_SC->SCp.Status & 0xff)
-			    | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16);
-		}
-
-		rtrc(0);
-		current_SC->SCp.phase = idle;
-		current_SC->scsi_done(current_SC);
-		return;
-	}
-
-	switch (status & 0x07) {	/* scsi phase */
-	case 0x00:		/* DATA-OUT */
-		if (int_reg & 0x10) {	/* Target requesting info transfer */
-			rtrc(5);
-			current_SC->SCp.phase = data_out;
-			VDEB(printk("NCR53c406a: Data-Out phase\n"));
-			outb(FLUSH_FIFO, CMD_REG);
-			LOAD_DMA_COUNT(scsi_bufflen(current_SC));	/* Max transfer size */
-#if USE_DMA			/* No s/g support for DMA */
-			NCR53c406a_dma_write(scsi_sglist(current_SC),
-                                             scsdi_bufflen(current_SC));
-
-#endif				/* USE_DMA */
-			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
-#if USE_PIO
-                        scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_write(sg_virt(sg), sg->length);
-                        }
-			REG0;
-#endif				/* USE_PIO */
-		}
-		break;
-
-	case 0x01:		/* DATA-IN */
-		if (int_reg & 0x10) {	/* Target requesting info transfer */
-			rtrc(6);
-			current_SC->SCp.phase = data_in;
-			VDEB(printk("NCR53c406a: Data-In phase\n"));
-			outb(FLUSH_FIFO, CMD_REG);
-			LOAD_DMA_COUNT(scsi_bufflen(current_SC));	/* Max transfer size */
-#if USE_DMA			/* No s/g support for DMA */
-			NCR53c406a_dma_read(scsi_sglist(current_SC),
-                                            scsdi_bufflen(current_SC));
-#endif				/* USE_DMA */
-			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
-#if USE_PIO
-                        scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_read(sg_virt(sg), sg->length);
-                        }
-			REG0;
-#endif				/* USE_PIO */
-		}
-		break;
-
-	case 0x02:		/* COMMAND */
-		current_SC->SCp.phase = command_ph;
-		printk("NCR53c406a: Warning: Unknown interrupt occurred in command phase!\n");
-		break;
-
-	case 0x03:		/* STATUS */
-		rtrc(7);
-		current_SC->SCp.phase = status_ph;
-		VDEB(printk("NCR53c406a: Status phase\n"));
-		outb(FLUSH_FIFO, CMD_REG);
-		outb(INIT_CMD_COMPLETE, CMD_REG);
-		break;
-
-	case 0x04:		/* Reserved */
-	case 0x05:		/* Reserved */
-		printk("NCR53c406a: WARNING: Reserved phase!!!\n");
-		break;
-
-	case 0x06:		/* MESSAGE-OUT */
-		DEB(printk("NCR53c406a: Message-Out phase\n"));
-		current_SC->SCp.phase = message_out;
-		outb(SET_ATN, CMD_REG);	/* Reject the message */
-		outb(MSG_ACCEPT, CMD_REG);
-		break;
-
-	case 0x07:		/* MESSAGE-IN */
-		rtrc(4);
-		VDEB(printk("NCR53c406a: Message-In phase\n"));
-		current_SC->SCp.phase = message_in;
-
-		current_SC->SCp.Status = inb(SCSI_FIFO);
-		current_SC->SCp.Message = inb(SCSI_FIFO);
-
-		VDEB(printk("SCSI FIFO size=%d\n", inb(FIFO_FLAGS) & 0x1f));
-		DEB(printk("Status = %02x  Message = %02x\n", current_SC->SCp.Status, current_SC->SCp.Message));
-
-		if (current_SC->SCp.Message == SAVE_POINTERS || current_SC->SCp.Message == DISCONNECT) {
-			outb(SET_ATN, CMD_REG);	/* Reject message */
-			DEB(printk("Discarding SAVE_POINTERS message\n"));
-		}
-		outb(MSG_ACCEPT, CMD_REG);
-		break;
-	}
-}
-
-#ifndef IRQ_LEV
-static int irq_probe(void)
-{
-	int irqs, irq;
-	unsigned long i;
-
-	inb(INT_REG);		/* clear the interrupt register */
-	irqs = probe_irq_on();
-
-	/* Invalid command will cause an interrupt */
-	REG0;
-	outb(0xff, CMD_REG);
-
-	/* Wait for the interrupt to occur */
-	i = jiffies + WATCHDOG;
-	while (time_after(i, jiffies) && !(inb(STAT_REG) & 0x80))
-		barrier();
-	if (time_before_eq(i, jiffies)) {	/* Timed out, must be hardware trouble */
-		probe_irq_off(irqs);
-		return -1;
-	}
-
-	irq = probe_irq_off(irqs);
-
-	/* Kick the chip */
-	outb(CHIP_RESET, CMD_REG);
-	outb(SCSI_NOP, CMD_REG);
-	chip_init();
-
-	return irq;
-}
-#endif				/* IRQ_LEV */
-
-static void chip_init(void)
-{
-	REG1;
-#if USE_DMA
-	outb(0x00, PIO_STATUS);
-#else				/* USE_PIO */
-	outb(0x01, PIO_STATUS);
-#endif
-	outb(0x00, PIO_FLAG);
-
-	outb(C4_IMG, CONFIG4);	/* REG0; */
-	outb(C3_IMG, CONFIG3);
-	outb(C2_IMG, CONFIG2);
-	outb(C1_IMG, CONFIG1);
-
-	outb(0x05, CLKCONV);	/* clock conversion factor */
-	outb(0x9C, SRTIMOUT);	/* Selection timeout */
-	outb(0x05, SYNCPRD);	/* Synchronous transfer period */
-	outb(SYNC_MODE, SYNCOFF);	/* synchronous mode */
-}
-
-static void __init calc_port_addr(void)
-{
-	/* Control Register Set 0 */
-	TC_LSB = (port_base + 0x00);
-	TC_MSB = (port_base + 0x01);
-	SCSI_FIFO = (port_base + 0x02);
-	CMD_REG = (port_base + 0x03);
-	STAT_REG = (port_base + 0x04);
-	DEST_ID = (port_base + 0x04);
-	INT_REG = (port_base + 0x05);
-	SRTIMOUT = (port_base + 0x05);
-	SEQ_REG = (port_base + 0x06);
-	SYNCPRD = (port_base + 0x06);
-	FIFO_FLAGS = (port_base + 0x07);
-	SYNCOFF = (port_base + 0x07);
-	CONFIG1 = (port_base + 0x08);
-	CLKCONV = (port_base + 0x09);
-	/* TESTREG          = (port_base+0x0A); */
-	CONFIG2 = (port_base + 0x0B);
-	CONFIG3 = (port_base + 0x0C);
-	CONFIG4 = (port_base + 0x0D);
-	TC_HIGH = (port_base + 0x0E);
-	/* FIFO_BOTTOM      = (port_base+0x0F); */
-
-	/* Control Register Set 1 */
-	/* JUMPER_SENSE     = (port_base+0x00); */
-	/* SRAM_PTR         = (port_base+0x01); */
-	/* SRAM_DATA        = (port_base+0x02); */
-	PIO_FIFO = (port_base + 0x04);
-	/* PIO_FIFO1        = (port_base+0x05); */
-	/* PIO_FIFO2        = (port_base+0x06); */
-	/* PIO_FIFO3        = (port_base+0x07); */
-	PIO_STATUS = (port_base + 0x08);
-	/* ATA_CMD          = (port_base+0x09); */
-	/* ATA_ERR          = (port_base+0x0A); */
-	PIO_FLAG = (port_base + 0x0B);
-	CONFIG5 = (port_base + 0x0D);
-	/* SIGNATURE        = (port_base+0x0E); */
-	/* CONFIG6          = (port_base+0x0F); */
-}
-
-MODULE_LICENSE("GPL");
-
-/* NOTE:  scatter-gather support only works in PIO mode.
- * Use SG_NONE if DMA mode is enabled!
- */
-
-static struct scsi_host_template driver_template =
-{
-     .proc_name         	= "NCR53c406a"		/* proc_name */,        
-     .name              	= "NCR53c406a"		/* name */,             
-     .detect            	= NCR53c406a_detect	/* detect */,           
-     .release            	= NCR53c406a_release,
-     .info              	= NCR53c406a_info		/* info */,             
-     .queuecommand      	= NCR53c406a_queue	/* queuecommand */,     
-     .eh_host_reset_handler     = NCR53c406a_host_reset	/* reset */,            
-     .bios_param        	= NCR53c406a_biosparm	/* biosparm */,         
-     .can_queue         	= 1			/* can_queue */,        
-     .this_id           	= 7			/* SCSI ID of the chip */,
-     .sg_tablesize      	= 32			/*SG_ALL*/ /*SG_NONE*/, 
-     .unchecked_isa_dma 	= 1			/* unchecked_isa_dma */,
-     .use_clustering    	= ENABLE_CLUSTERING,
-};
-
-#include "scsi_module.c"
-
-/*
- * Overrides for Emacs so that we get a uniform tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 0095fcb..29bf1e6 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1231,6 +1231,7 @@ struct src_registers {
 
 #define SRC_ODR_SHIFT		12
 #define SRC_IDR_SHIFT		9
+#define SRC_MSI_READ_MASK	0x1000
 
 typedef void (*fib_callback)(void *ctxt, struct fib *fibctx);
 
@@ -1528,6 +1529,7 @@ struct aac_bus_info_response {
 #define AAC_COMM_MESSAGE_TYPE3		5
 
 #define AAC_EXTOPT_SA_FIRMWARE		cpu_to_le32(1<<1)
+#define AAC_EXTOPT_SOFT_RESET		cpu_to_le32(1<<16)
 
 /* MSIX context */
 struct aac_msix_ctx {
@@ -1662,6 +1664,7 @@ struct aac_dev
 	u8			raw_io_64;
 	u8			printf_enabled;
 	u8			in_reset;
+	u8			in_soft_reset;
 	u8			msi;
 	u8			sa_firmware;
 	int			management_fib_count;
@@ -2504,6 +2507,7 @@ struct aac_hba_info {
 #define RCV_TEMP_READINGS		0x00000025
 #define GET_COMM_PREFERRED_SETTINGS	0x00000026
 #define IOP_RESET_FW_FIB_DUMP		0x00000034
+#define DROP_IO			0x00000035
 #define IOP_RESET			0x00001000
 #define IOP_RESET_ALWAYS		0x00001001
 #define RE_INIT_ADAPTER		0x000000ee
@@ -2539,6 +2543,7 @@ struct aac_hba_info {
 #define	FLASH_UPD_PENDING		0x00002000
 #define	FLASH_UPD_SUCCESS		0x00004000
 #define	FLASH_UPD_FAILED		0x00008000
+#define	INVALID_OMR			0xffffffff
 #define	FWUPD_TIMEOUT			(5 * 60)
 
 /*
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index fde6b6a..4ebb35a 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -255,7 +255,8 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
 	 */
 	src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
 
-	if (!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) {
+	if ((!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) &&
+		!dev->in_soft_reset) {
 		ok = 0;
 		start = jiffies;
 
@@ -679,6 +680,25 @@ void aac_set_intx_mode(struct aac_dev *dev)
 	}
 }
 
+static void aac_clear_omr(struct aac_dev *dev)
+{
+	u32 omr_value = 0;
+
+	omr_value = src_readl(dev, MUnit.OMR);
+
+	/*
+	 * Check for PCI Errors or Kernel Panic
+	 */
+	if ((omr_value == INVALID_OMR) || (omr_value & KERNEL_PANIC))
+		omr_value = 0;
+
+	/*
+	 * Preserve MSIX Value if any
+	 */
+	src_writel(dev, MUnit.OMR, omr_value & AAC_INT_MODE_MSIX);
+	src_readl(dev, MUnit.OMR);
+}
+
 static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev)
 {
 	__le32 supported_options3;
@@ -739,6 +759,8 @@ static void aac_send_iop_reset(struct aac_dev *dev)
 
 	aac_set_intx_mode(dev);
 
+	aac_clear_omr(dev);
+
 	src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK);
 
 	msleep(5000);
@@ -748,6 +770,7 @@ static void aac_send_hardware_soft_reset(struct aac_dev *dev)
 {
 	u_int32_t val;
 
+	aac_clear_omr(dev);
 	val = readl(((char *)(dev->base) + IBW_SWR_OFFSET));
 	val |= 0x01;
 	writel(val, ((char *)(dev->base) + IBW_SWR_OFFSET));
@@ -786,7 +809,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
 		if (!is_ctrl_up)
 			dev_err(&dev->pdev->dev, "IOP reset failed\n");
 		else {
-			dev_info(&dev->pdev->dev, "IOP reset succeded\n");
+			dev_info(&dev->pdev->dev, "IOP reset succeeded\n");
 			goto set_startup;
 		}
 	}
@@ -808,7 +831,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
 			ret = -ENODEV;
 			goto out;
 		} else
-			dev_info(&dev->pdev->dev, "SOFT reset succeded\n");
+			dev_info(&dev->pdev->dev, "SOFT reset succeeded\n");
 	}
 
 set_startup:
@@ -992,6 +1015,148 @@ int aac_src_init(struct aac_dev *dev)
 	return -1;
 }
 
+static int aac_src_wait_sync(struct aac_dev *dev, int *status)
+{
+	unsigned long start = jiffies;
+	unsigned long usecs = 0;
+	int delay = 5 * HZ;
+	int rc = 1;
+
+	while (time_before(jiffies, start+delay)) {
+		/*
+		 * Delay 5 microseconds to let Mon960 get info.
+		 */
+		udelay(5);
+
+		/*
+		 * Mon960 will set doorbell0 bit when it has completed the
+		 * command.
+		 */
+		if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) {
+			/*
+			 * Clear: the doorbell.
+			 */
+			if (dev->msi_enabled)
+				aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT);
+			else
+				src_writel(dev, MUnit.ODR_C,
+					OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+			rc = 0;
+
+			break;
+		}
+
+		/*
+		 * Yield the processor in case we are slow
+		 */
+		usecs = 1 * USEC_PER_MSEC;
+		usleep_range(usecs, usecs + 50);
+	}
+	/*
+	 * Pull the synch status from Mailbox 0.
+	 */
+	if (status && !rc) {
+		status[0] = readl(&dev->IndexRegs->Mailbox[0]);
+		status[1] = readl(&dev->IndexRegs->Mailbox[1]);
+		status[2] = readl(&dev->IndexRegs->Mailbox[2]);
+		status[3] = readl(&dev->IndexRegs->Mailbox[3]);
+		status[4] = readl(&dev->IndexRegs->Mailbox[4]);
+	}
+
+	return rc;
+}
+
+/**
+ *  aac_src_soft_reset	-	perform soft reset to speed up
+ *  access
+ *
+ *  Assumptions: That the controller is in a state where we can
+ *  bring it back to life with an init struct. We can only use
+ *  fast sync commands, as the timeout is 5 seconds.
+ *
+ *  @dev: device to configure
+ *
+ */
+
+static int aac_src_soft_reset(struct aac_dev *dev)
+{
+	u32 status_omr = src_readl(dev, MUnit.OMR);
+	u32 status[5];
+	int rc = 1;
+	int state = 0;
+	char *state_str[7] = {
+		"GET_ADAPTER_PROPERTIES Failed",
+		"GET_ADAPTER_PROPERTIES timeout",
+		"SOFT_RESET not supported",
+		"DROP_IO Failed",
+		"DROP_IO timeout",
+		"Check Health failed"
+	};
+
+	if (status_omr == INVALID_OMR)
+		return 1;       // pcie hosed
+
+	if (!(status_omr & KERNEL_UP_AND_RUNNING))
+		return 1;       // not up and running
+
+	/*
+	 * We go into soft reset mode to allow us to handle response
+	 */
+	dev->in_soft_reset = 1;
+	dev->msi_enabled = status_omr & AAC_INT_MODE_MSIX;
+
+	/* Get adapter properties */
+	rc = aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, 0, 0, 0,
+		0, 0, 0, status+0, status+1, status+2, status+3, status+4);
+	if (rc)
+		goto out;
+
+	state++;
+	if (aac_src_wait_sync(dev, status)) {
+		rc = 1;
+		goto out;
+	}
+
+	state++;
+	if (!(status[1] & le32_to_cpu(AAC_OPT_EXTENDED) &&
+		(status[4] & le32_to_cpu(AAC_EXTOPT_SOFT_RESET)))) {
+		rc = 2;
+		goto out;
+	}
+
+	if ((status[1] & le32_to_cpu(AAC_OPT_EXTENDED)) &&
+		(status[4] & le32_to_cpu(AAC_EXTOPT_SA_FIRMWARE)))
+		dev->sa_firmware = 1;
+
+	state++;
+	rc = aac_adapter_sync_cmd(dev, DROP_IO, 0, 0, 0, 0, 0, 0,
+		 status+0, status+1, status+2, status+3, status+4);
+
+	if (rc)
+		goto out;
+
+	state++;
+	if (aac_src_wait_sync(dev, status)) {
+		rc = 3;
+		goto out;
+	}
+
+	if (status[1])
+		dev_err(&dev->pdev->dev, "%s: %d outstanding I/O pending\n",
+			__func__, status[1]);
+
+	state++;
+	rc = aac_src_check_health(dev);
+
+out:
+	dev->in_soft_reset = 0;
+	dev->msi_enabled = 0;
+	if (rc)
+		dev_err(&dev->pdev->dev, "%s: %s status = %d", __func__,
+			state_str[state], rc);
+
+return rc;
+}
 /**
  *  aac_srcv_init	-	initialize an SRCv card
  *  @dev: device to configure
@@ -1021,8 +1186,10 @@ int aac_srcv_init(struct aac_dev *dev)
 
 	if (dev->init_reset) {
 		dev->init_reset = false;
-		if (!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
+		if (aac_src_soft_reset(dev)) {
+			aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET);
 			++restart;
+		}
 	}
 
 	/*
@@ -1072,13 +1239,16 @@ int aac_srcv_init(struct aac_dev *dev)
 		printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
 		goto error_iounmap;
 	}
+
 	start = jiffies;
 	/*
 	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
 	 */
-	while (!((status = src_readl(dev, MUnit.OMR)) &
-		KERNEL_UP_AND_RUNNING) ||
-		status == 0xffffffff) {
+	do {
+		status = src_readl(dev, MUnit.OMR);
+		if (status == INVALID_OMR)
+			status = 0;
+
 		if ((restart &&
 		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
 		  time_after(jiffies, start+HZ*startup_timeout)) {
@@ -1098,7 +1268,8 @@ int aac_srcv_init(struct aac_dev *dev)
 			++restart;
 		}
 		msleep(1);
-	}
+	} while (!(status & KERNEL_UP_AND_RUNNING));
+
 	if (restart && aac_commit)
 		aac_commit = 1;
 	/*
@@ -1234,13 +1405,23 @@ void aac_src_access_devreg(struct aac_dev *dev, int mode)
 
 static int aac_src_get_sync_status(struct aac_dev *dev)
 {
+	int msix_val = 0;
+	int legacy_val = 0;
 
-	int val;
+	msix_val = src_readl(dev, MUnit.ODR_MSI) & SRC_MSI_READ_MASK ? 1 : 0;
 
-	if (dev->msi_enabled)
-		val = src_readl(dev, MUnit.ODR_MSI) & 0x1000 ? 1 : 0;
-	else
-		val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT;
+	if (!dev->msi_enabled) {
+		/*
+		 * if Legacy int status indicates cmd is not complete
+		 * sample MSIx register to see if it indiactes cmd complete,
+		 * if yes set the controller in MSIx mode and consider cmd
+		 * completed
+		 */
+		legacy_val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT;
+		if (!(legacy_val & 1) && msix_val)
+			dev->msi_enabled = 1;
+		return legacy_val;
+	}
 
-	return val;
+	return msix_val;
 }
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index bad35ff..b48d543 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -592,7 +592,7 @@ static int aha1740_probe (struct device *dev)
 					     DMA_BIDIRECTIONAL);
 	if (!host->ecb_dma_addr) {
 		printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n");
-		scsi_unregister (shpnt);
+		scsi_host_put (shpnt);
 		goto err_host_put;
 	}
 	
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index b560f39..034f4ee 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -9338,9 +9338,9 @@ ahd_dumpseq(struct ahd_softc* ahd)
 static void
 ahd_loadseq(struct ahd_softc *ahd)
 {
-	struct	cs cs_table[num_critical_sections];
-	u_int	begin_set[num_critical_sections];
-	u_int	end_set[num_critical_sections];
+	struct	cs cs_table[NUM_CRITICAL_SECTIONS];
+	u_int	begin_set[NUM_CRITICAL_SECTIONS];
+	u_int	end_set[NUM_CRITICAL_SECTIONS];
 	const struct patch *cur_patch;
 	u_int	cs_count;
 	u_int	cur_cs;
@@ -9456,7 +9456,7 @@ ahd_loadseq(struct ahd_softc *ahd)
 		 * Move through the CS table until we find a CS
 		 * that might apply to this instruction.
 		 */
-		for (; cur_cs < num_critical_sections; cur_cs++) {
+		for (; cur_cs < NUM_CRITICAL_SECTIONS; cur_cs++) {
 			if (critical_sections[cur_cs].end <= i) {
 				if (begin_set[cs_count] == TRUE
 				 && end_set[cs_count] == FALSE) {
diff --git a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
index 4b51e23..fd64a95 100644
--- a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
+++ b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
@@ -1186,5 +1186,4 @@
 	{ 759, 763 }
 };
 
-static const int num_critical_sections = sizeof(critical_sections)
-				       / sizeof(*critical_sections);
+#define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections)
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 6612ff3..e97ecea 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -6848,9 +6848,9 @@ ahc_dumpseq(struct ahc_softc* ahc)
 static int
 ahc_loadseq(struct ahc_softc *ahc)
 {
-	struct	cs cs_table[num_critical_sections];
-	u_int	begin_set[num_critical_sections];
-	u_int	end_set[num_critical_sections];
+	struct	cs cs_table[NUM_CRITICAL_SECTIONS];
+	u_int	begin_set[NUM_CRITICAL_SECTIONS];
+	u_int	end_set[NUM_CRITICAL_SECTIONS];
 	const struct patch *cur_patch;
 	u_int	cs_count;
 	u_int	cur_cs;
@@ -6915,7 +6915,7 @@ ahc_loadseq(struct ahc_softc *ahc)
 		 * Move through the CS table until we find a CS
 		 * that might apply to this instruction.
 		 */
-		for (; cur_cs < num_critical_sections; cur_cs++) {
+		for (; cur_cs < NUM_CRITICAL_SECTIONS; cur_cs++) {
 			if (critical_sections[cur_cs].end <= i) {
 				if (begin_set[cs_count] == TRUE
 				 && end_set[cs_count] == FALSE) {
diff --git a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
index 07e93fb..f37362b 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
+++ b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
@@ -1304,5 +1304,4 @@
 	{ 875, 877 }
 };
 
-static const int num_critical_sections = sizeof(critical_sections)
-				       / sizeof(*critical_sections);
+#define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections)
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c
index 21ac265..5f474e4 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm.c
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c
@@ -451,8 +451,7 @@ output_code()
 	fprintf(ofile, "\n};\n\n");
 
 	fprintf(ofile,
-"static const int num_critical_sections = sizeof(critical_sections)\n"
-"				       / sizeof(*critical_sections);\n");
+	"#define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections)\n");
 
 	fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);
 }
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index f375f35..2e51ccc 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -49,7 +49,7 @@ struct device_attribute;
 #define ARCMSR_MAX_OUTSTANDING_CMD	1024
 #define ARCMSR_DEFAULT_OUTSTANDING_CMD	128
 #define ARCMSR_MIN_OUTSTANDING_CMD	32
-#define ARCMSR_DRIVER_VERSION		"v1.40.00.04-20171130"
+#define ARCMSR_DRIVER_VERSION		"v1.40.00.05-20180309"
 #define ARCMSR_SCSI_INITIATOR_ID	255
 #define ARCMSR_MAX_XFER_SECTORS		512
 #define ARCMSR_MAX_XFER_SECTORS_B	4096
@@ -779,12 +779,12 @@ struct AdapterControlBlock
 /* message clear rqbuffer */
 #define ACB_F_MESSAGE_WQBUFFER_READED   0x0040
 #define ACB_F_BUS_RESET               	0x0080
-#define ACB_F_BUS_HANG_ON		0x0800/* need hardware reset bus */
 
 #define ACB_F_IOP_INITED              	0x0100
 /* iop init */
 #define ACB_F_ABORT			0x0200
 #define ACB_F_FIRMWARE_TRAP           	0x0400
+#define ACB_F_ADAPTER_REMOVED		0x0800
 #define ACB_F_MSG_GET_CONFIG		0x1000
 	struct CommandControlBlock *	pccb_pool[ARCMSR_MAX_FREECCB_NUM];
 	/* used for memory free */
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 75e828b..732b5d9 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1446,12 +1446,80 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
 	}
 }
 
+static void arcmsr_remove_scsi_devices(struct AdapterControlBlock *acb)
+{
+	char *acb_dev_map = (char *)acb->device_map;
+	int target, lun, i;
+	struct scsi_device *psdev;
+	struct CommandControlBlock *ccb;
+	char temp;
+
+	for (i = 0; i < acb->maxFreeCCB; i++) {
+		ccb = acb->pccb_pool[i];
+		if (ccb->startdone == ARCMSR_CCB_START) {
+			ccb->pcmd->result = DID_NO_CONNECT << 16;
+			arcmsr_pci_unmap_dma(ccb);
+			ccb->pcmd->scsi_done(ccb->pcmd);
+		}
+	}
+	for (target = 0; target < ARCMSR_MAX_TARGETID; target++) {
+		temp = *acb_dev_map;
+		if (temp) {
+			for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) {
+				if (temp & 1) {
+					psdev = scsi_device_lookup(acb->host,
+						0, target, lun);
+					if (psdev != NULL) {
+						scsi_remove_device(psdev);
+						scsi_device_put(psdev);
+					}
+				}
+				temp >>= 1;
+			}
+			*acb_dev_map = 0;
+		}
+		acb_dev_map++;
+	}
+}
+
+static void arcmsr_free_pcidev(struct AdapterControlBlock *acb)
+{
+	struct pci_dev *pdev;
+	struct Scsi_Host *host;
+
+	host = acb->host;
+	arcmsr_free_sysfs_attr(acb);
+	scsi_remove_host(host);
+	flush_work(&acb->arcmsr_do_message_isr_bh);
+	del_timer_sync(&acb->eternal_timer);
+	if (set_date_time)
+		del_timer_sync(&acb->refresh_timer);
+	pdev = acb->pdev;
+	arcmsr_free_irq(pdev, acb);
+	arcmsr_free_ccb_pool(acb);
+	arcmsr_free_mu(acb);
+	arcmsr_unmap_pciregion(acb);
+	pci_release_regions(pdev);
+	scsi_host_put(host);
+	pci_disable_device(pdev);
+}
+
 static void arcmsr_remove(struct pci_dev *pdev)
 {
 	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	struct AdapterControlBlock *acb =
 		(struct AdapterControlBlock *) host->hostdata;
 	int poll_count = 0;
+	uint16_t dev_id;
+
+	pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id);
+	if (dev_id == 0xffff) {
+		acb->acb_flags &= ~ACB_F_IOP_INITED;
+		acb->acb_flags |= ACB_F_ADAPTER_REMOVED;
+		arcmsr_remove_scsi_devices(acb);
+		arcmsr_free_pcidev(acb);
+		return;
+	}
 	arcmsr_free_sysfs_attr(acb);
 	scsi_remove_host(host);
 	flush_work(&acb->arcmsr_do_message_isr_bh);
@@ -1499,6 +1567,8 @@ static void arcmsr_shutdown(struct pci_dev *pdev)
 	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	struct AdapterControlBlock *acb =
 		(struct AdapterControlBlock *)host->hostdata;
+	if (acb->acb_flags & ACB_F_ADAPTER_REMOVED)
+		return;
 	del_timer_sync(&acb->eternal_timer);
 	if (set_date_time)
 		del_timer_sync(&acb->refresh_timer);
@@ -2931,6 +3001,12 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
 	struct CommandControlBlock *ccb;
 	int target = cmd->device->id;
+
+	if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) {
+		cmd->result = (DID_NO_CONNECT << 16);
+		cmd->scsi_done(cmd);
+		return 0;
+	}
 	cmd->scsi_done = done;
 	cmd->host_scribble = NULL;
 	cmd->result = 0;
@@ -3731,6 +3807,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
 	case ACB_ADAPTER_TYPE_A: {
 		struct MessageUnit_A __iomem *reg = acb->pmuA;
 		do {
+			if (!(acb->acb_flags & ACB_F_IOP_INITED))
+				msleep(20);
 			firmware_state = readl(&reg->outbound_msgaddr1);
 		} while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0);
 		}
@@ -3739,6 +3817,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
 	case ACB_ADAPTER_TYPE_B: {
 		struct MessageUnit_B *reg = acb->pmuB;
 		do {
+			if (!(acb->acb_flags & ACB_F_IOP_INITED))
+				msleep(20);
 			firmware_state = readl(reg->iop2drv_doorbell);
 		} while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0);
 		writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell);
@@ -3747,6 +3827,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
 	case ACB_ADAPTER_TYPE_C: {
 		struct MessageUnit_C __iomem *reg = acb->pmuC;
 		do {
+			if (!(acb->acb_flags & ACB_F_IOP_INITED))
+				msleep(20);
 			firmware_state = readl(&reg->outbound_msgaddr1);
 		} while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0);
 		}
@@ -3754,6 +3836,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
 	case ACB_ADAPTER_TYPE_D: {
 		struct MessageUnit_D *reg = acb->pmuD;
 		do {
+			if (!(acb->acb_flags & ACB_F_IOP_INITED))
+				msleep(20);
 			firmware_state = readl(reg->outbound_msgaddr1);
 		} while ((firmware_state &
 			ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK) == 0);
@@ -3762,6 +3846,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
 	case ACB_ADAPTER_TYPE_E: {
 		struct MessageUnit_E __iomem *reg = acb->pmuE;
 		do {
+			if (!(acb->acb_flags & ACB_F_IOP_INITED))
+				msleep(20);
 			firmware_state = readl(&reg->outbound_msgaddr1);
 		} while ((firmware_state & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0);
 		}
@@ -4177,6 +4263,8 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
 	int retry_count = 0;
 	int rtn = FAILED;
 	acb = (struct AdapterControlBlock *) cmd->device->host->hostdata;
+	if (acb->acb_flags & ACB_F_ADAPTER_REMOVED)
+		return SUCCESS;
 	pr_notice("arcmsr: executing bus reset eh.....num_resets = %d,"
 		" num_aborts = %d \n", acb->num_resets, acb->num_aborts);
 	acb->num_resets++;
@@ -4243,6 +4331,8 @@ static int arcmsr_abort(struct scsi_cmnd *cmd)
 	int rtn = FAILED;
 	uint32_t intmask_org;
 
+	if (acb->acb_flags & ACB_F_ADAPTER_REMOVED)
+		return SUCCESS;
 	printk(KERN_NOTICE
 		"arcmsr%d: abort device command of scsi id = %d lun = %d\n",
 		acb->host->host_no, cmd->device->id, (u32)cmd->device->lun);
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index 8b52a9d..b46997c 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -1413,11 +1413,11 @@ static void atp885_init(struct Scsi_Host *shpnt)
 			atpdev->global_map[m] = 0;
 			for (k = 0; k < 4; k++) {
 				atp_writew_base(atpdev, 0x3c, n++);
-				((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38);
+				((u32 *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38);
 			}
 			for (k = 0; k < 4; k++) {
 				atp_writew_base(atpdev, 0x3c, n++);
-				((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38);
+				((u32 *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38);
 			}
 			n += 8;
 		}
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 3976e78..7c884f8 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -891,7 +891,7 @@ bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd,
 
 	if (bfad_chk_iocmd_sz(payload_len,
 		sizeof(struct bfa_bsg_fabric_get_lports_s),
-		sizeof(wwn_t[iocmd->nports])) != BFA_STATUS_OK) {
+		sizeof(wwn_t) * iocmd->nports) != BFA_STATUS_OK) {
 		iocmd->status = BFA_STATUS_VERSION_FAIL;
 		goto out;
 	}
diff --git a/drivers/scsi/csiostor/csio_attr.c b/drivers/scsi/csiostor/csio_attr.c
index 2d1c4eb..8a00403 100644
--- a/drivers/scsi/csiostor/csio_attr.c
+++ b/drivers/scsi/csiostor/csio_attr.c
@@ -274,12 +274,24 @@ csio_get_host_speed(struct Scsi_Host *shost)
 
 	spin_lock_irq(&hw->lock);
 	switch (hw->pport[ln->portid].link_speed) {
-	case FW_PORT_CAP_SPEED_1G:
+	case FW_PORT_CAP32_SPEED_1G:
 		fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
 		break;
-	case FW_PORT_CAP_SPEED_10G:
+	case FW_PORT_CAP32_SPEED_10G:
 		fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
 		break;
+	case FW_PORT_CAP32_SPEED_25G:
+		fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
+		break;
+	case FW_PORT_CAP32_SPEED_40G:
+		fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
+		break;
+	case FW_PORT_CAP32_SPEED_50G:
+		fc_host_speed(shost) = FC_PORTSPEED_50GBIT;
+		break;
+	case FW_PORT_CAP32_SPEED_100G:
+		fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
+		break;
 	default:
 		fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
 		break;
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index 0bd1131..96bbb82 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -1409,6 +1409,235 @@ csio_config_device_caps(struct csio_hw *hw)
 	return rv;
 }
 
+static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
+{
+	enum cc_fec cc_fec = 0;
+
+	if (fw_fec & FW_PORT_CAP32_FEC_RS)
+		cc_fec |= FEC_RS;
+	if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
+		cc_fec |= FEC_BASER_RS;
+
+	return cc_fec;
+}
+
+static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
+{
+	fw_port_cap32_t fw_pause = 0;
+
+	if (cc_pause & PAUSE_RX)
+		fw_pause |= FW_PORT_CAP32_FC_RX;
+	if (cc_pause & PAUSE_TX)
+		fw_pause |= FW_PORT_CAP32_FC_TX;
+
+	return fw_pause;
+}
+
+static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
+{
+	fw_port_cap32_t fw_fec = 0;
+
+	if (cc_fec & FEC_RS)
+		fw_fec |= FW_PORT_CAP32_FEC_RS;
+	if (cc_fec & FEC_BASER_RS)
+		fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
+
+	return fw_fec;
+}
+
+/**
+ * fwcap_to_fwspeed - return highest speed in Port Capabilities
+ * @acaps: advertised Port Capabilities
+ *
+ * Get the highest speed for the port from the advertised Port
+ * Capabilities.
+ */
+fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps)
+{
+	#define TEST_SPEED_RETURN(__caps_speed) \
+		do { \
+			if (acaps & FW_PORT_CAP32_SPEED_##__caps_speed) \
+				return FW_PORT_CAP32_SPEED_##__caps_speed; \
+		} while (0)
+
+	TEST_SPEED_RETURN(400G);
+	TEST_SPEED_RETURN(200G);
+	TEST_SPEED_RETURN(100G);
+	TEST_SPEED_RETURN(50G);
+	TEST_SPEED_RETURN(40G);
+	TEST_SPEED_RETURN(25G);
+	TEST_SPEED_RETURN(10G);
+	TEST_SPEED_RETURN(1G);
+	TEST_SPEED_RETURN(100M);
+
+	#undef TEST_SPEED_RETURN
+
+	return 0;
+}
+
+/**
+ *      fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits
+ *      @caps16: a 16-bit Port Capabilities value
+ *
+ *      Returns the equivalent 32-bit Port Capabilities value.
+ */
+fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
+{
+	fw_port_cap32_t caps32 = 0;
+
+	#define CAP16_TO_CAP32(__cap) \
+		do { \
+			if (caps16 & FW_PORT_CAP_##__cap) \
+				caps32 |= FW_PORT_CAP32_##__cap; \
+		} while (0)
+
+	CAP16_TO_CAP32(SPEED_100M);
+	CAP16_TO_CAP32(SPEED_1G);
+	CAP16_TO_CAP32(SPEED_25G);
+	CAP16_TO_CAP32(SPEED_10G);
+	CAP16_TO_CAP32(SPEED_40G);
+	CAP16_TO_CAP32(SPEED_100G);
+	CAP16_TO_CAP32(FC_RX);
+	CAP16_TO_CAP32(FC_TX);
+	CAP16_TO_CAP32(ANEG);
+	CAP16_TO_CAP32(MDIX);
+	CAP16_TO_CAP32(MDIAUTO);
+	CAP16_TO_CAP32(FEC_RS);
+	CAP16_TO_CAP32(FEC_BASER_RS);
+	CAP16_TO_CAP32(802_3_PAUSE);
+	CAP16_TO_CAP32(802_3_ASM_DIR);
+
+	#undef CAP16_TO_CAP32
+
+	return caps32;
+}
+
+/**
+ *      lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities
+ *      @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value
+ *
+ *      Translates old FW_PORT_ACTION_GET_PORT_INFO lstatus field into new
+ *      32-bit Port Capabilities value.
+ */
+fw_port_cap32_t lstatus_to_fwcap(u32 lstatus)
+{
+	fw_port_cap32_t linkattr = 0;
+
+	/* The format of the Link Status in the old
+	 * 16-bit Port Information message isn't the same as the
+	 * 16-bit Port Capabilities bitfield used everywhere else.
+	 */
+	if (lstatus & FW_PORT_CMD_RXPAUSE_F)
+		linkattr |= FW_PORT_CAP32_FC_RX;
+	if (lstatus & FW_PORT_CMD_TXPAUSE_F)
+		linkattr |= FW_PORT_CAP32_FC_TX;
+	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
+		linkattr |= FW_PORT_CAP32_SPEED_100M;
+	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
+		linkattr |= FW_PORT_CAP32_SPEED_1G;
+	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
+		linkattr |= FW_PORT_CAP32_SPEED_10G;
+	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
+		linkattr |= FW_PORT_CAP32_SPEED_25G;
+	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
+		linkattr |= FW_PORT_CAP32_SPEED_40G;
+	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
+		linkattr |= FW_PORT_CAP32_SPEED_100G;
+
+	return linkattr;
+}
+
+/**
+ *      csio_init_link_config - initialize a link's SW state
+ *      @lc: pointer to structure holding the link state
+ *      @pcaps: link Port Capabilities
+ *      @acaps: link current Advertised Port Capabilities
+ *
+ *      Initializes the SW state maintained for each link, including the link's
+ *      capabilities and default speed/flow-control/autonegotiation settings.
+ */
+static void csio_init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
+				  fw_port_cap32_t acaps)
+{
+	lc->pcaps = pcaps;
+	lc->def_acaps = acaps;
+	lc->lpacaps = 0;
+	lc->speed_caps = 0;
+	lc->speed = 0;
+	lc->requested_fc = PAUSE_RX | PAUSE_TX;
+	lc->fc = lc->requested_fc;
+
+	/*
+	 * For Forward Error Control, we default to whatever the Firmware
+	 * tells us the Link is currently advertising.
+	 */
+	lc->requested_fec = FEC_AUTO;
+	lc->fec = fwcap_to_cc_fec(lc->def_acaps);
+
+	/* If the Port is capable of Auto-Negtotiation, initialize it as
+	 * "enabled" and copy over all of the Physical Port Capabilities
+	 * to the Advertised Port Capabilities.  Otherwise mark it as
+	 * Auto-Negotiate disabled and select the highest supported speed
+	 * for the link.  Note parallel structure in t4_link_l1cfg_core()
+	 * and t4_handle_get_port_info().
+	 */
+	if (lc->pcaps & FW_PORT_CAP32_ANEG) {
+		lc->acaps = lc->pcaps & ADVERT_MASK;
+		lc->autoneg = AUTONEG_ENABLE;
+		lc->requested_fc |= PAUSE_AUTONEG;
+	} else {
+		lc->acaps = 0;
+		lc->autoneg = AUTONEG_DISABLE;
+	}
+}
+
+static void csio_link_l1cfg(struct link_config *lc, uint16_t fw_caps,
+			    uint32_t *rcaps)
+{
+	unsigned int fw_mdi = FW_PORT_CAP32_MDI_V(FW_PORT_CAP32_MDI_AUTO);
+	fw_port_cap32_t fw_fc, cc_fec, fw_fec, lrcap;
+
+	lc->link_ok = 0;
+
+	/*
+	 * Convert driver coding of Pause Frame Flow Control settings into the
+	 * Firmware's API.
+	 */
+	fw_fc = cc_to_fwcap_pause(lc->requested_fc);
+
+	/*
+	 * Convert Common Code Forward Error Control settings into the
+	 * Firmware's API.  If the current Requested FEC has "Automatic"
+	 * (IEEE 802.3) specified, then we use whatever the Firmware
+	 * sent us as part of it's IEEE 802.3-based interpratation of
+	 * the Transceiver Module EPROM FEC parameters.  Otherwise we
+	 * use whatever is in the current Requested FEC settings.
+	 */
+	if (lc->requested_fec & FEC_AUTO)
+		cc_fec = fwcap_to_cc_fec(lc->def_acaps);
+	else
+		cc_fec = lc->requested_fec;
+	fw_fec = cc_to_fwcap_fec(cc_fec);
+
+	/* Figure out what our Requested Port Capabilities are going to be.
+	 * Note parallel structure in t4_handle_get_port_info() and
+	 * init_link_config().
+	 */
+	if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
+		lrcap = (lc->pcaps & ADVERT_MASK) | fw_fc | fw_fec;
+		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
+		lc->fec = cc_fec;
+	} else if (lc->autoneg == AUTONEG_DISABLE) {
+		lrcap = lc->speed_caps | fw_fc | fw_fec | fw_mdi;
+		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
+		lc->fec = cc_fec;
+	} else {
+		lrcap = lc->acaps | fw_fc | fw_fec | fw_mdi;
+	}
+
+	*rcaps = lrcap;
+}
+
 /*
  * csio_enable_ports - Bring up all available ports.
  * @hw: HW module.
@@ -1418,8 +1647,10 @@ static int
 csio_enable_ports(struct csio_hw *hw)
 {
 	struct csio_mb  *mbp;
+	u16 fw_caps = FW_CAPS_UNKNOWN;
 	enum fw_retval retval;
 	uint8_t portid;
+	fw_port_cap32_t pcaps, acaps, rcaps;
 	int i;
 
 	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
@@ -1431,9 +1662,39 @@ csio_enable_ports(struct csio_hw *hw)
 	for (i = 0; i < hw->num_pports; i++) {
 		portid = hw->pport[i].portid;
 
+		if (fw_caps == FW_CAPS_UNKNOWN) {
+			u32 param, val;
+
+			param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) |
+			 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
+			val = 1;
+
+			csio_mb_params(hw, mbp, CSIO_MB_DEFAULT_TMO,
+				       hw->pfn, 0, 1, &param, &val, false,
+				       NULL);
+
+			if (csio_mb_issue(hw, mbp)) {
+				csio_err(hw, "failed to issue FW_PARAMS_CMD(r) port:%d\n",
+					 portid);
+				mempool_free(mbp, hw->mb_mempool);
+				return -EINVAL;
+			}
+
+			csio_mb_process_read_params_rsp(hw, mbp, &retval, 1,
+							&val);
+			if (retval != FW_SUCCESS) {
+				csio_err(hw, "FW_PARAMS_CMD(r) port:%d failed: 0x%x\n",
+					 portid, retval);
+				mempool_free(mbp, hw->mb_mempool);
+				return -EINVAL;
+			}
+
+			fw_caps = val;
+		}
+
 		/* Read PORT information */
 		csio_mb_port(hw, mbp, CSIO_MB_DEFAULT_TMO, portid,
-			     false, 0, 0, NULL);
+			     false, 0, fw_caps, NULL);
 
 		if (csio_mb_issue(hw, mbp)) {
 			csio_err(hw, "failed to issue FW_PORT_CMD(r) port:%d\n",
@@ -1442,8 +1703,8 @@ csio_enable_ports(struct csio_hw *hw)
 			return -EINVAL;
 		}
 
-		csio_mb_process_read_port_rsp(hw, mbp, &retval,
-					      &hw->pport[i].pcap);
+		csio_mb_process_read_port_rsp(hw, mbp, &retval, fw_caps,
+					      &pcaps, &acaps);
 		if (retval != FW_SUCCESS) {
 			csio_err(hw, "FW_PORT_CMD(r) port:%d failed: 0x%x\n",
 				 portid, retval);
@@ -1451,9 +1712,13 @@ csio_enable_ports(struct csio_hw *hw)
 			return -EINVAL;
 		}
 
+		csio_init_link_config(&hw->pport[i].link_cfg, pcaps, acaps);
+
+		csio_link_l1cfg(&hw->pport[i].link_cfg, fw_caps, &rcaps);
+
 		/* Write back PORT information */
-		csio_mb_port(hw, mbp, CSIO_MB_DEFAULT_TMO, portid, true,
-			     (PAUSE_RX | PAUSE_TX), hw->pport[i].pcap, NULL);
+		csio_mb_port(hw, mbp, CSIO_MB_DEFAULT_TMO, portid,
+			     true, rcaps, fw_caps, NULL);
 
 		if (csio_mb_issue(hw, mbp)) {
 			csio_err(hw, "failed to issue FW_PORT_CMD(w) port:%d\n",
diff --git a/drivers/scsi/csiostor/csio_hw.h b/drivers/scsi/csiostor/csio_hw.h
index 30f5f52..9e73ef7 100644
--- a/drivers/scsi/csiostor/csio_hw.h
+++ b/drivers/scsi/csiostor/csio_hw.h
@@ -268,8 +268,62 @@ struct csio_vpd {
 	uint8_t id[ID_LEN + 1];
 };
 
+/* Firmware Port Capabilities types. */
+
+typedef u16 fw_port_cap16_t;    /* 16-bit Port Capabilities integral value */
+typedef u32 fw_port_cap32_t;    /* 32-bit Port Capabilities integral value */
+
+enum fw_caps {
+	FW_CAPS_UNKNOWN = 0,    /* 0'ed out initial state */
+	FW_CAPS16       = 1,    /* old Firmware: 16-bit Port Capabilities */
+	FW_CAPS32       = 2,    /* new Firmware: 32-bit Port Capabilities */
+};
+
+enum cc_pause {
+	PAUSE_RX      = 1 << 0,
+	PAUSE_TX      = 1 << 1,
+	PAUSE_AUTONEG = 1 << 2
+};
+
+enum cc_fec {
+	FEC_AUTO	= 1 << 0,  /* IEEE 802.3 "automatic" */
+	FEC_RS		= 1 << 1,  /* Reed-Solomon */
+	FEC_BASER_RS	= 1 << 2   /* BaseR/Reed-Solomon */
+};
+
+struct link_config {
+	fw_port_cap32_t pcaps;		/* link capabilities */
+	fw_port_cap32_t def_acaps;	/* default advertised capabilities */
+	fw_port_cap32_t acaps;		/* advertised capabilities */
+	fw_port_cap32_t lpacaps;	/* peer advertised capabilities */
+
+	fw_port_cap32_t speed_caps;	/* speed(s) user has requested */
+	unsigned int   speed;		/* actual link speed (Mb/s) */
+
+	enum cc_pause  requested_fc;	/* flow control user has requested */
+	enum cc_pause  fc;		/* actual link flow control */
+
+	enum cc_fec    requested_fec;	/* Forward Error Correction: */
+	enum cc_fec    fec;		/* requested and actual in use */
+
+	unsigned char  autoneg;		/* autonegotiating? */
+
+	unsigned char  link_ok;		/* link up? */
+	unsigned char  link_down_rc;	/* link down reason */
+};
+
+#define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16)
+
+#define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \
+		     FW_PORT_CAP32_ANEG)
+
+/* Enable or disable autonegotiation. */
+#define AUTONEG_DISABLE	0x00
+#define AUTONEG_ENABLE	0x01
+
 struct csio_pport {
 	uint16_t	pcap;
+	uint16_t	acap;
 	uint8_t		portid;
 	uint8_t		link_status;
 	uint16_t	link_speed;
@@ -278,6 +332,7 @@ struct csio_pport {
 	uint8_t		rsvd1;
 	uint8_t		rsvd2;
 	uint8_t		rsvd3;
+	struct link_config link_cfg;
 };
 
 /* fcoe resource information */
@@ -582,6 +637,10 @@ int csio_hw_slow_intr_handler(struct csio_hw *);
 int csio_handle_intr_status(struct csio_hw *, unsigned int,
 			    const struct intr_info *);
 
+fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps);
+fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16);
+fw_port_cap32_t lstatus_to_fwcap(u32 lstatus);
+
 int csio_hw_start(struct csio_hw *);
 int csio_hw_stop(struct csio_hw *);
 int csio_hw_reset(struct csio_hw *);
diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c
index 7dbbbb8..cc5611e 100644
--- a/drivers/scsi/csiostor/csio_lnode.c
+++ b/drivers/scsi/csiostor/csio_lnode.c
@@ -352,6 +352,14 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
 		val = htonl(FC_PORTSPEED_1GBIT);
 	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP_SPEED_10G)
 		val = htonl(FC_PORTSPEED_10GBIT);
+	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_25G)
+		val = htonl(FC_PORTSPEED_25GBIT);
+	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_40G)
+		val = htonl(FC_PORTSPEED_40GBIT);
+	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_50G)
+		val = htonl(FC_PORTSPEED_50GBIT);
+	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_100G)
+		val = htonl(FC_PORTSPEED_100GBIT);
 	else
 		val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN);
 	csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c
index 5f4e0a7..c026417 100644
--- a/drivers/scsi/csiostor/csio_mb.c
+++ b/drivers/scsi/csiostor/csio_mb.c
@@ -326,10 +326,6 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
 		cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_TARGET);
 }
 
-#define CSIO_ADVERT_MASK     (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
-			      FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G |\
-			      FW_PORT_CAP_ANEG)
-
 /*
  * csio_mb_port- FW PORT command helper
  * @hw: The HW structure
@@ -344,11 +340,10 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
  */
 void
 csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
-	     uint8_t portid, bool wr, uint32_t fc, uint16_t caps,
+	     u8 portid, bool wr, uint32_t fc, uint16_t fw_caps,
 	     void (*cbfn) (struct csio_hw *, struct csio_mb *))
 {
 	struct fw_port_cmd *cmdp = (struct fw_port_cmd *)(mbp->mb);
-	unsigned int lfc = 0, mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO);
 
 	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn,  1);
 
@@ -358,26 +353,24 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
 				   FW_PORT_CMD_PORTID_V(portid));
 	if (!wr) {
 		cmdp->action_to_len16 = htonl(
-			FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
+			FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
+			? FW_PORT_ACTION_GET_PORT_INFO
+			: FW_PORT_ACTION_GET_PORT_INFO32) |
 			FW_CMD_LEN16_V(sizeof(*cmdp) / 16));
 		return;
 	}
 
 	/* Set port */
 	cmdp->action_to_len16 = htonl(
-			FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) |
+			FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
+			? FW_PORT_ACTION_L1_CFG
+			: FW_PORT_ACTION_L1_CFG32) |
 			FW_CMD_LEN16_V(sizeof(*cmdp) / 16));
 
-	if (fc & PAUSE_RX)
-		lfc |= FW_PORT_CAP_FC_RX;
-	if (fc & PAUSE_TX)
-		lfc |= FW_PORT_CAP_FC_TX;
-
-	if (!(caps & FW_PORT_CAP_ANEG))
-		cmdp->u.l1cfg.rcap = htonl((caps & CSIO_ADVERT_MASK) | lfc);
+	if (fw_caps == FW_CAPS16)
+		cmdp->u.l1cfg.rcap = cpu_to_be32(fc);
 	else
-		cmdp->u.l1cfg.rcap = htonl((caps & CSIO_ADVERT_MASK) |
-								lfc | mdi);
+		cmdp->u.l1cfg32.rcap32 = cpu_to_be32(fc);
 }
 
 /*
@@ -390,14 +383,22 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
  */
 void
 csio_mb_process_read_port_rsp(struct csio_hw *hw, struct csio_mb *mbp,
-			 enum fw_retval *retval, uint16_t *caps)
+			 enum fw_retval *retval, uint16_t fw_caps,
+			 u32 *pcaps, u32 *acaps)
 {
 	struct fw_port_cmd *rsp = (struct fw_port_cmd *)(mbp->mb);
 
 	*retval = FW_CMD_RETVAL_G(ntohl(rsp->action_to_len16));
 
-	if (*retval == FW_SUCCESS)
-		*caps = ntohs(rsp->u.info.pcap);
+	if (*retval == FW_SUCCESS) {
+		if (fw_caps == FW_CAPS16) {
+			*pcaps = fwcaps16_to_caps32(ntohs(rsp->u.info.pcap));
+			*acaps = fwcaps16_to_caps32(ntohs(rsp->u.info.acap));
+		} else {
+			*pcaps = ntohs(rsp->u.info32.pcaps32);
+			*acaps = ntohs(rsp->u.info32.acaps32);
+		}
+	}
 }
 
 /*
@@ -1409,6 +1410,7 @@ csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd)
 	uint32_t link_status;
 	uint16_t action;
 	uint8_t mod_type;
+	fw_port_cap32_t linkattr;
 
 	if (opcode == FW_PORT_CMD) {
 		pcmd = (struct fw_port_cmd *)cmd;
@@ -1416,22 +1418,34 @@ csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd)
 				ntohl(pcmd->op_to_portid));
 		action = FW_PORT_CMD_ACTION_G(
 				ntohl(pcmd->action_to_len16));
-		if (action != FW_PORT_ACTION_GET_PORT_INFO) {
+		if (action != FW_PORT_ACTION_GET_PORT_INFO &&
+		    action != FW_PORT_ACTION_GET_PORT_INFO32) {
 			csio_err(hw, "Unhandled FW_PORT_CMD action: %u\n",
 				action);
 			return -EINVAL;
 		}
 
-		link_status = ntohl(pcmd->u.info.lstatus_to_modtype);
-		mod_type = FW_PORT_CMD_MODTYPE_G(link_status);
+		if (action == FW_PORT_ACTION_GET_PORT_INFO) {
+			link_status = ntohl(pcmd->u.info.lstatus_to_modtype);
+			mod_type = FW_PORT_CMD_MODTYPE_G(link_status);
+			linkattr = lstatus_to_fwcap(link_status);
 
-		hw->pport[port_id].link_status =
-			FW_PORT_CMD_LSTATUS_G(link_status);
-		hw->pport[port_id].link_speed =
-			FW_PORT_CMD_LSPEED_G(link_status);
+			hw->pport[port_id].link_status =
+				FW_PORT_CMD_LSTATUS_G(link_status);
+		} else {
+			link_status =
+				ntohl(pcmd->u.info32.lstatus32_to_cbllen32);
+			mod_type = FW_PORT_CMD_MODTYPE32_G(link_status);
+			linkattr = ntohl(pcmd->u.info32.linkattr32);
+
+			hw->pport[port_id].link_status =
+				FW_PORT_CMD_LSTATUS32_G(link_status);
+		}
+
+		hw->pport[port_id].link_speed = fwcap_to_fwspeed(linkattr);
 
 		csio_info(hw, "Port:%x - LINK %s\n", port_id,
-			FW_PORT_CMD_LSTATUS_G(link_status) ? "UP" : "DOWN");
+			hw->pport[port_id].link_status ? "UP" : "DOWN");
 
 		if (mod_type != hw->pport[port_id].mod_type) {
 			hw->pport[port_id].mod_type = mod_type;
diff --git a/drivers/scsi/csiostor/csio_mb.h b/drivers/scsi/csiostor/csio_mb.h
index a6823df..b07e891 100644
--- a/drivers/scsi/csiostor/csio_mb.h
+++ b/drivers/scsi/csiostor/csio_mb.h
@@ -88,12 +88,6 @@ enum csio_dev_state {
 	 FW_PARAMS_PARAM_Y_V(0) | \
 	 FW_PARAMS_PARAM_Z_V(0))
 
-enum {
-	PAUSE_RX      = 1 << 0,
-	PAUSE_TX      = 1 << 1,
-	PAUSE_AUTONEG = 1 << 2
-};
-
 #define CSIO_INIT_MBP(__mbp, __cp,  __tmo, __priv, __fn, __clear)	\
 do {									\
 	if (__clear)							\
@@ -189,7 +183,8 @@ void csio_mb_port(struct csio_hw *, struct csio_mb *, uint32_t,
 		  void (*) (struct csio_hw *, struct csio_mb *));
 
 void csio_mb_process_read_port_rsp(struct csio_hw *, struct csio_mb *,
-				   enum fw_retval *, uint16_t *);
+				   enum fw_retval *, uint16_t,
+				   uint32_t *, uint32_t *);
 
 void csio_mb_initialize(struct csio_hw *, struct csio_mb *, uint32_t,
 			void (*)(struct csio_hw *, struct csio_mb *));
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 4b44325..12dc710 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -138,12 +138,12 @@ static void release_port_group(struct kref *kref)
 static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
 		       int bufflen, struct scsi_sense_hdr *sshdr, int flags)
 {
-	u8 cdb[COMMAND_SIZE(MAINTENANCE_IN)];
+	u8 cdb[MAX_COMMAND_SIZE];
 	int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
 		REQ_FAILFAST_DRIVER;
 
 	/* Prepare the command. */
-	memset(cdb, 0x0, COMMAND_SIZE(MAINTENANCE_IN));
+	memset(cdb, 0x0, MAX_COMMAND_SIZE);
 	cdb[0] = MAINTENANCE_IN;
 	if (!(flags & ALUA_RTPG_EXT_HDR_UNSUPP))
 		cdb[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
@@ -166,7 +166,7 @@ static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
 static int submit_stpg(struct scsi_device *sdev, int group_id,
 		       struct scsi_sense_hdr *sshdr)
 {
-	u8 cdb[COMMAND_SIZE(MAINTENANCE_OUT)];
+	u8 cdb[MAX_COMMAND_SIZE];
 	unsigned char stpg_data[8];
 	int stpg_len = 8;
 	int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
@@ -178,7 +178,7 @@ static int submit_stpg(struct scsi_device *sdev, int group_id,
 	put_unaligned_be16(group_id, &stpg_data[6]);
 
 	/* Prepare the command. */
-	memset(cdb, 0x0, COMMAND_SIZE(MAINTENANCE_OUT));
+	memset(cdb, 0x0, MAX_COMMAND_SIZE);
 	cdb[0] = MAINTENANCE_OUT;
 	cdb[1] = MO_SET_TARGET_PGS;
 	put_unaligned_be32(stpg_len, &cdb[6]);
@@ -214,8 +214,8 @@ static struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
 /*
  * alua_alloc_pg - Allocate a new port_group structure
  * @sdev: scsi device
- * @h: alua device_handler data
  * @group_id: port group id
+ * @tpgs: target port group settings
  *
  * Allocate a new port_group structure for a given
  * device.
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index 6a2792f..95c4790 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -249,7 +249,7 @@ static int send_trespass_cmd(struct scsi_device *sdev,
 			    struct clariion_dh_data *csdev)
 {
 	unsigned char *page22;
-	unsigned char cdb[COMMAND_SIZE(MODE_SELECT)];
+	unsigned char cdb[MAX_COMMAND_SIZE];
 	int err, res = SCSI_DH_OK, len;
 	struct scsi_sense_hdr sshdr;
 	u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 7af31a1..d27faba 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -533,7 +533,7 @@ static void send_mode_select(struct work_struct *work)
 	int err = SCSI_DH_OK, retry_cnt = RDAC_RETRY_COUNT;
 	struct rdac_queue_data *tmp, *qdata;
 	LIST_HEAD(list);
-	unsigned char cdb[COMMAND_SIZE(MODE_SELECT_10)];
+	unsigned char cdb[MAX_COMMAND_SIZE];
 	struct scsi_sense_hdr sshdr;
 	unsigned int data_size;
 	u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index fd172b0..6866975 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -302,16 +302,14 @@ static int adpt_detect(struct scsi_host_template* sht)
 }
 
 
-/*
- * scsi_unregister will be called AFTER we return.
- */
-static int adpt_release(struct Scsi_Host *host)
+static void adpt_release(adpt_hba *pHba)
 {
-	adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
+	struct Scsi_Host *shost = pHba->host;
+
+	scsi_remove_host(shost);
 //	adpt_i2o_quiesce_hba(pHba);
 	adpt_i2o_delete_hba(pHba);
-	scsi_unregister(host);
-	return 0;
+	scsi_host_put(shost);
 }
 
 
@@ -801,14 +799,17 @@ static int __adpt_reset(struct scsi_cmnd* cmd)
 {
 	adpt_hba* pHba;
 	int rcode;
+	char name[32];
+
 	pHba = (adpt_hba*)cmd->device->host->hostdata[0];
-	printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->device->channel,pHba->channel[cmd->device->channel].tid );
+	strncpy(name, pHba->name, sizeof(name));
+	printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n", name, cmd->device->channel, pHba->channel[cmd->device->channel].tid);
 	rcode =  adpt_hba_reset(pHba);
 	if(rcode == 0){
-		printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);
+		printk(KERN_WARNING"%s: HBA reset complete\n", name);
 		return SUCCESS;
 	} else {
-		printk(KERN_WARNING"%s: HBA reset failed (%x)\n",pHba->name, rcode);
+		printk(KERN_WARNING"%s: HBA reset failed (%x)\n", name, rcode);
 		return FAILED;
 	}
 }
@@ -1087,8 +1088,6 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
 
 
 	mutex_lock(&adpt_configuration_lock);
-	// scsi_unregister calls our adpt_release which
-	// does a quiese
 	if(pHba->host){
 		free_irq(pHba->host->irq, pHba);
 	}
@@ -3524,7 +3523,7 @@ static int adpt_i2o_systab_send(adpt_hba* pHba)
 #endif
 
 	return ret;	
- }
+}
 
 
 /*============================================================================
@@ -3595,11 +3594,9 @@ static void __exit adpt_exit(void)
 {
 	adpt_hba	*pHba, *next;
 
-	for (pHba = hba_chain; pHba; pHba = pHba->next)
-		scsi_remove_host(pHba->host);
 	for (pHba = hba_chain; pHba; pHba = next) {
 		next = pHba->next;
-		adpt_release(pHba->host);
+		adpt_release(pHba);
 	}
 }
 
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index 1fa345a..dfc8d2e 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -32,7 +32,6 @@ static int adpt_detect(struct scsi_host_template * sht);
 static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd);
 static int adpt_abort(struct scsi_cmnd * cmd);
 static int adpt_reset(struct scsi_cmnd* cmd);
-static int adpt_release(struct Scsi_Host *host);
 static int adpt_slave_configure(struct scsi_device *);
 
 static const char *adpt_info(struct Scsi_Host *pSHost);
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
deleted file mode 100644
index 6501c33..0000000
--- a/drivers/scsi/eata.c
+++ /dev/null
@@ -1,2571 +0,0 @@
-/*
- *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
- *
- *      03 Jun 2003 Rev. 8.10 for linux-2.5.70
- *        + Update for new IRQ API.
- *        + Use "goto" when appropriate.
- *        + Drop eata.h.
- *        + Update for new module_param API.
- *        + Module parameters  can now be specified only in the
- *          same format as the kernel boot options.
- *
- *             boot option    old module param 
- *             -----------    ------------------
- *             addr,...       io_port=addr,...
- *             lc:[y|n]       linked_comm=[1|0]
- *             mq:xx          max_queue_depth=xx
- *             tm:[0|1|2]     tag_mode=[0|1|2]
- *             et:[y|n]       ext_tran=[1|0]
- *             rs:[y|n]       rev_scan=[1|0]
- *             ip:[y|n]       isa_probe=[1|0]
- *             ep:[y|n]       eisa_probe=[1|0]
- *             pp:[y|n]       pci_probe=[1|0]
- *
- *          A valid example using the new parameter format is:
- *          modprobe eata "eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n"
- *
- *          which is equivalent to the old format:
- *          modprobe eata io_port=0x7410,0x230 linked_comm=1 tag_mode=0 \
- *                        max_queue_depth=4 eisa_probe=0
- *
- *      12 Feb 2003 Rev. 8.04 for linux 2.5.60
- *        + Release irq before calling scsi_register.
- *
- *      12 Nov 2002 Rev. 8.02 for linux 2.5.47
- *        + Release driver_lock before calling scsi_register.
- *
- *      11 Nov 2002 Rev. 8.01 for linux 2.5.47
- *        + Fixed bios_param and scsicam_bios_param calling parameters.
- *
- *      28 Oct 2002 Rev. 8.00 for linux 2.5.44-ac4
- *        + Use new tcq and adjust_queue_depth api.
- *        + New command line option (tm:[0-2]) to choose the type of tags:
- *          0 -> disable tagging ; 1 -> simple tags  ; 2 -> ordered tags.
- *          Default is tm:0 (tagged commands disabled).
- *          For compatibility the "tc:" option is an alias of the "tm:"
- *          option; tc:n is equivalent to tm:0 and tc:y is equivalent to
- *          tm:1.
- *        + The tagged_comm module parameter has been removed, use tag_mode
- *          instead, equivalent to the "tm:" boot option.
- *
- *      10 Oct 2002 Rev. 7.70 for linux 2.5.42
- *        + Foreport from revision 6.70.
- *
- *      25 Jun 2002 Rev. 6.70 for linux 2.4.19
- *        + This release is the first one tested on a Big Endian platform:
- *          fixed endian-ness problem due to bitfields;
- *          fixed endian-ness problem in read_pio.
- *        + Added new options for selectively probing ISA, EISA and PCI bus:
- *
- *          Boot option   Parameter name    Default according to
- *
- *          ip:[y|n]      isa_probe=[1|0]   CONFIG_ISA  defined
- *          ep:[y|n]      eisa_probe=[1|0]  CONFIG_EISA defined
- *          pp:[y|n]      pci_probe=[1|0]   CONFIG_PCI  defined
- *
- *          The default action is to perform probing if the corresponding
- *          bus is configured and to skip probing otherwise.
- *
- *        + If pci_probe is in effect and a list of I/O  ports is specified
- *          as parameter or boot option, pci_enable_device() is performed
- *          on all pci devices matching PCI_CLASS_STORAGE_SCSI.
- *
- *      21 Feb 2002 Rev. 6.52 for linux 2.4.18
- *        + Backport from rev. 7.22 (use io_request_lock).
- *
- *      20 Feb 2002 Rev. 7.22 for linux 2.5.5
- *        + Remove any reference to virt_to_bus().
- *        + Fix pio hang while detecting multiple HBAs.
- *        + Fixed a board detection bug: in a system with
- *          multiple ISA/EISA boards, all but the first one
- *          were erroneously detected as PCI.
- *
- *      01 Jan 2002 Rev. 7.20 for linux 2.5.1
- *        + Use the dynamic DMA mapping API.
- *
- *      19 Dec 2001 Rev. 7.02 for linux 2.5.1
- *        + Use SCpnt->sc_data_direction if set.
- *        + Use sglist.page instead of sglist.address.
- *
- *      11 Dec 2001 Rev. 7.00 for linux 2.5.1
- *        + Use host->host_lock instead of io_request_lock.
- *
- *       1 May 2001 Rev. 6.05 for linux 2.4.4
- *        + Clean up all pci related routines.
- *        + Fix data transfer direction for opcode SEND_CUE_SHEET (0x5d)
- *
- *      30 Jan 2001 Rev. 6.04 for linux 2.4.1
- *        + Call pci_resource_start after pci_enable_device.
- *
- *      25 Jan 2001 Rev. 6.03 for linux 2.4.0
- *        + "check_region" call replaced by "request_region".
- *
- *      22 Nov 2000 Rev. 6.02 for linux 2.4.0-test11
- *        + Return code checked when calling pci_enable_device.
- *        + Removed old scsi error handling support.
- *        + The obsolete boot option flag eh:n is silently ignored.
- *        + Removed error messages while a disk drive is powered up at
- *          boot time.
- *        + Improved boot messages: all tagged capable device are
- *          indicated as "tagged" or "soft-tagged" :
- *          - "soft-tagged"  means that the driver is trying to do its
- *            own tagging (i.e. the tc:y option is in effect);
- *          - "tagged" means that the device supports tagged commands,
- *            but the driver lets the HBA be responsible for tagging
- *            support.
- *
- *      16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18
- *        + Updated to the new __setup interface for boot command line options.
- *        + When loaded as a module, accepts the new parameter boot_options
- *          which value is a string with the same format of the kernel boot
- *          command line options. A valid example is:
- *          modprobe eata 'boot_options="0x7410,0x230,lc:y,tc:n,mq:4"'
- *
- *       9 Sep 1999 Rev. 5.10 for linux 2.2.12 and 2.3.17
- *        + 64bit cleanup for Linux/Alpha platform support
- *          (contribution from H.J. Lu).
- *
- *      22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11
- *        + Removed pre-2.2 source code compatibility.
- *        + Added call to pci_set_master.
- *
- *      26 Jul 1998 Rev. 4.33 for linux 2.0.35 and 2.1.111
- *        + Added command line option (rs:[y|n]) to reverse the scan order
- *          of PCI boards. The default is rs:y, which reverses the BIOS order
- *          while registering PCI boards. The default value rs:y generates
- *          the same order of all previous revisions of this driver.
- *          Pls. note that "BIOS order" might have been reversed itself
- *          after the 2.1.9x PCI modifications in the linux kernel.
- *          The rs value is ignored when the explicit list of addresses
- *          is used by the "eata=port0,port1,..." command line option.
- *        + Added command line option (et:[y|n]) to force use of extended
- *          translation (255 heads, 63 sectors) as disk geometry.
- *          The default is et:n, which uses the disk geometry returned
- *          by scsicam_bios_param. The default value et:n is compatible with
- *          all previous revisions of this driver.
- *
- *      28 May 1998 Rev. 4.32 for linux 2.0.33 and 2.1.104
- *          Increased busy timeout from 10 msec. to 200 msec. while
- *          processing interrupts.
- *
- *      16 May 1998 Rev. 4.31 for linux 2.0.33 and 2.1.102
- *          Improved abort handling during the eh recovery process.
- *
- *      13 May 1998 Rev. 4.30 for linux 2.0.33 and 2.1.101
- *          The driver is now fully SMP safe, including the
- *          abort and reset routines.
- *          Added command line options (eh:[y|n]) to choose between
- *          new_eh_code and the old scsi code.
- *          If linux version >= 2.1.101 the default is eh:y, while the eh
- *          option is ignored for previous releases and the old scsi code
- *          is used.
- *
- *      18 Apr 1998 Rev. 4.20 for linux 2.0.33 and 2.1.97
- *          Reworked interrupt handler.
- *
- *      11 Apr 1998 rev. 4.05 for linux 2.0.33 and 2.1.95
- *          Major reliability improvement: when a batch with overlapping
- *          requests is detected, requests are queued one at a time
- *          eliminating any possible board or drive reordering.
- *
- *      10 Apr 1998 rev. 4.04 for linux 2.0.33 and 2.1.95
- *          Improved SMP support (if linux version >= 2.1.95).
- *
- *       9 Apr 1998 rev. 4.03 for linux 2.0.33 and 2.1.94
- *          Added support for new PCI code and IO-APIC remapping of irqs.
- *          Performance improvement: when sequential i/o is detected,
- *          always use direct sort instead of reverse sort.
- *
- *       4 Apr 1998 rev. 4.02 for linux 2.0.33 and 2.1.92
- *          io_port is now unsigned long.
- *
- *      17 Mar 1998 rev. 4.01 for linux 2.0.33 and 2.1.88
- *          Use new scsi error handling code (if linux version >= 2.1.88).
- *          Use new interrupt code.
- *
- *      12 Sep 1997 rev. 3.11 for linux 2.0.30 and 2.1.55
- *          Use of udelay inside the wait loops to avoid timeout
- *          problems with fast cpus.
- *          Removed check about useless calls to the interrupt service
- *          routine (reported on SMP systems only).
- *          At initialization time "sorted/unsorted" is displayed instead
- *          of "linked/unlinked" to reinforce the fact that "linking" is
- *          nothing but "elevator sorting" in the actual implementation.
- *
- *      17 May 1997 rev. 3.10 for linux 2.0.30 and 2.1.38
- *          Use of serial_number_at_timeout in abort and reset processing.
- *          Use of the __initfunc and __initdata macro in setup code.
- *          Minor cleanups in the list_statistics code.
- *          Increased controller busy timeout in order to better support
- *          slow SCSI devices.
- *
- *      24 Feb 1997 rev. 3.00 for linux 2.0.29 and 2.1.26
- *          When loading as a module, parameter passing is now supported
- *          both in 2.0 and in 2.1 style.
- *          Fixed data transfer direction for some SCSI opcodes.
- *          Immediate acknowledge to request sense commands.
- *          Linked commands to each disk device are now reordered by elevator
- *          sorting. Rare cases in which reordering of write requests could
- *          cause wrong results are managed.
- *          Fixed spurious timeouts caused by long simple queue tag sequences.
- *          New command line option (tm:[0-3]) to choose the type of tags:
- *          0 -> mixed (default); 1 -> simple; 2 -> head; 3 -> ordered.
- *
- *      18 Jan 1997 rev. 2.60 for linux 2.1.21 and 2.0.28
- *          Added command line options to enable/disable linked commands
- *          (lc:[y|n]), tagged commands (tc:[y|n]) and to set the max queue
- *          depth (mq:xx). Default is "eata=lc:n,tc:n,mq:16".
- *          Improved command linking.
- *          Documented how to setup RAID-0 with DPT SmartRAID boards.
- *
- *       8 Jan 1997 rev. 2.50 for linux 2.1.20 and 2.0.27
- *          Added linked command support.
- *          Improved detection of PCI boards using ISA base addresses.
- *
- *       3 Dec 1996 rev. 2.40 for linux 2.1.14 and 2.0.27
- *          Added support for tagged commands and queue depth adjustment.
- *
- *      22 Nov 1996 rev. 2.30 for linux 2.1.12 and 2.0.26
- *          When CONFIG_PCI is defined, BIOS32 is used to include in the
- *          list of i/o ports to be probed all the PCI SCSI controllers.
- *          The list of i/o ports to be probed can be overwritten by the
- *          "eata=port0,port1,...." boot command line option.
- *          Scatter/gather lists are now allocated by a number of kmalloc
- *          calls, in order to avoid the previous size limit of 64Kb.
- *
- *      16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25
- *          Added support for EATA 2.0C, PCI, multichannel and wide SCSI.
- *
- *      27 Sep 1996 rev. 2.12 for linux 2.1.0
- *          Portability cleanups (virtual/bus addressing, little/big endian
- *          support).
- *
- *      09 Jul 1996 rev. 2.11 for linux 2.0.4
- *          Number of internal retries is now limited.
- *
- *      16 Apr 1996 rev. 2.10 for linux 1.3.90
- *          New argument "reset_flags" to the reset routine.
- *
- *       6 Jul 1995 rev. 2.01 for linux 1.3.7
- *          Update required by the new /proc/scsi support.
- *
- *      11 Mar 1995 rev. 2.00 for linux 1.2.0
- *          Fixed a bug which prevented media change detection for removable
- *          disk drives.
- *
- *      23 Feb 1995 rev. 1.18 for linux 1.1.94
- *          Added a check for scsi_register returning NULL.
- *
- *      11 Feb 1995 rev. 1.17 for linux 1.1.91
- *          Now DEBUG_RESET is disabled by default.
- *          Register a board even if it does not assert DMA protocol support
- *          (DPT SK2011B does not report correctly the dmasup bit).
- *
- *       9 Feb 1995 rev. 1.16 for linux 1.1.90
- *          Use host->wish_block instead of host->block.
- *          New list of Data Out SCSI commands.
- *
- *       8 Feb 1995 rev. 1.15 for linux 1.1.89
- *          Cleared target_time_out counter while performing a reset.
- *          All external symbols renamed to avoid possible name conflicts.
- *
- *      28 Jan 1995 rev. 1.14 for linux 1.1.86
- *          Added module support.
- *          Log and do a retry when a disk drive returns a target status
- *          different from zero on a recovered error.
- *
- *      24 Jan 1995 rev. 1.13 for linux 1.1.85
- *          Use optimized board configuration, with a measured performance
- *          increase in the range 10%-20% on i/o throughput.
- *
- *      16 Jan 1995 rev. 1.12 for linux 1.1.81
- *          Fix mscp structure comments (no functional change).
- *          Display a message if check_region detects a port address
- *          already in use.
- *
- *      17 Dec 1994 rev. 1.11 for linux 1.1.74
- *          Use the scsicam_bios_param routine. This allows an easy
- *          migration path from disk partition tables created using
- *          different SCSI drivers and non optimal disk geometry.
- *
- *      15 Dec 1994 rev. 1.10 for linux 1.1.74
- *          Added support for ISA EATA boards (DPT PM2011, DPT PM2021).
- *          The host->block flag is set for all the detected ISA boards.
- *          The detect routine no longer enforces LEVEL triggering
- *          for EISA boards, it just prints a warning message.
- *
- *      30 Nov 1994 rev. 1.09 for linux 1.1.68
- *          Redo i/o on target status CHECK_CONDITION for TYPE_DISK only.
- *          Added optional support for using a single board at a time.
- *
- *      18 Nov 1994 rev. 1.08 for linux 1.1.64
- *          Forces sg_tablesize = 64 and can_queue = 64 if these
- *          values are not correctly detected (DPT PM2012).
- *
- *      14 Nov 1994 rev. 1.07 for linux 1.1.63  Final BETA release.
- *      04 Aug 1994 rev. 1.00 for linux 1.1.39  First BETA release.
- *
- *
- *          This driver is based on the CAM (Common Access Method Committee)
- *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
- *
- *  Copyright (C) 1994-2003 Dario Ballabio (ballabio_dario@emc.com)
- *
- *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that redistributions of source
- *  code retain the above copyright notice and this comment without
- *  modification.
- *
- */
-
-/*
- *
- *  Here is a brief description of the DPT SCSI host adapters.
- *  All these boards provide an EATA/DMA compatible programming interface
- *  and are fully supported by this driver in any configuration, including
- *  multiple SCSI channels:
- *
- *  PM2011B/9X -  Entry Level ISA
- *  PM2021A/9X -  High Performance ISA
- *  PM2012A       Old EISA
- *  PM2012B       Old EISA
- *  PM2022A/9X -  Entry Level EISA
- *  PM2122A/9X -  High Performance EISA
- *  PM2322A/9X -  Extra High Performance EISA
- *  PM3021     -  SmartRAID Adapter for ISA
- *  PM3222     -  SmartRAID Adapter for EISA (PM3222W is 16-bit wide SCSI)
- *  PM3224     -  SmartRAID Adapter for PCI  (PM3224W is 16-bit wide SCSI)
- *  PM33340UW  -  SmartRAID Adapter for PCI  ultra wide multichannel
- *
- *  The above list is just an indication: as a matter of fact all DPT
- *  boards using the EATA/DMA protocol are supported by this driver,
- *  since they use exactely the same programming interface.
- *
- *  The DPT PM2001 provides only the EATA/PIO interface and hence is not
- *  supported by this driver.
- *
- *  This code has been tested with up to 3 Distributed Processing Technology
- *  PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) EISA controllers,
- *  in any combination of private and shared IRQ.
- *  PCI support has been tested using up to 2 DPT PM3224W (DPT SCSI BIOS
- *  v003.D0, firmware v07G.0).
- *
- *  DPT SmartRAID boards support "Hardware Array" - a group of disk drives
- *  which are all members of the same RAID-0, RAID-1 or RAID-5 array implemented
- *  in host adapter hardware. Hardware Arrays are fully compatible with this
- *  driver, since they look to it as a single disk drive.
- *
- *  WARNING: to create a RAID-0 "Hardware Array" you must select "Other Unix"
- *  as the current OS in the DPTMGR "Initial System Installation" menu.
- *  Otherwise RAID-0 is generated as an "Array Group" (i.e. software RAID-0),
- *  which is not supported by the actual SCSI subsystem.
- *  To get the "Array Group" functionality, the Linux MD driver must be used
- *  instead of the DPT "Array Group" feature.
- *
- *  Multiple ISA, EISA and PCI boards can be configured in the same system.
- *  It is suggested to put all the EISA boards on the same IRQ level, all
- *  the PCI  boards on another IRQ level, while ISA boards cannot share
- *  interrupts.
- *
- *  If you configure multiple boards on the same IRQ, the interrupt must
- *  be _level_ triggered (not _edge_ triggered).
- *
- *  This driver detects EATA boards by probes at fixed port addresses,
- *  so no BIOS32 or PCI BIOS support is required.
- *  The suggested way to detect a generic EATA PCI board is to force on it
- *  any unused EISA address, even if there are other controllers on the EISA
- *  bus, or even if you system has no EISA bus at all.
- *  Do not force any ISA address on EATA PCI boards.
- *
- *  If PCI bios support is configured into the kernel, BIOS32 is used to
- *  include in the list of i/o ports to be probed all the PCI SCSI controllers.
- *
- *  Due to a DPT BIOS "feature", it might not be possible to force an EISA
- *  address on more than a single DPT PCI board, so in this case you have to
- *  let the PCI BIOS assign the addresses.
- *
- *  The sequence of detection probes is:
- *
- *  - ISA 0x1F0;
- *  - PCI SCSI controllers (only if BIOS32 is available);
- *  - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15);
- *  - ISA  0x170, 0x230, 0x330.
- *
- *  The above list of detection probes can be totally replaced by the
- *  boot command line option: "eata=port0,port1,port2,...", where the
- *  port0, port1... arguments are ISA/EISA/PCI addresses to be probed.
- *  For example using "eata=0x7410,0x7450,0x230", the driver probes
- *  only the two PCI addresses 0x7410 and 0x7450 and the ISA address 0x230,
- *  in this order; "eata=0" totally disables this driver.
- *
- *  After the optional list of detection probes, other possible command line
- *  options are:
- *
- *  et:y  force use of extended translation (255 heads, 63 sectors);
- *  et:n  use disk geometry detected by scsicam_bios_param;
- *  rs:y  reverse scan order while detecting PCI boards;
- *  rs:n  use BIOS order while detecting PCI boards;
- *  lc:y  enables linked commands;
- *  lc:n  disables linked commands;
- *  tm:0  disables tagged commands (same as tc:n);
- *  tm:1  use simple queue tags (same as tc:y);
- *  tm:2  use ordered queue tags (same as tc:2);
- *  mq:xx set the max queue depth to the value xx (2 <= xx <= 32).
- *
- *  The default value is: "eata=lc:n,mq:16,tm:0,et:n,rs:n".
- *  An example using the list of detection probes could be:
- *  "eata=0x7410,0x230,lc:y,tm:2,mq:4,et:n".
- *
- *  When loading as a module, parameters can be specified as well.
- *  The above example would be (use 1 in place of y and 0 in place of n):
- *
- *  modprobe eata io_port=0x7410,0x230 linked_comm=1 \
- *                max_queue_depth=4 ext_tran=0 tag_mode=2 \
- *                rev_scan=1
- *
- *  ----------------------------------------------------------------------------
- *  In this implementation, linked commands are designed to work with any DISK
- *  or CD-ROM, since this linking has only the intent of clustering (time-wise)
- *  and reordering by elevator sorting commands directed to each device,
- *  without any relation with the actual SCSI protocol between the controller
- *  and the device.
- *  If Q is the queue depth reported at boot time for each device (also named
- *  cmds/lun) and Q > 2, whenever there is already an active command to the
- *  device all other commands to the same device  (up to Q-1) are kept waiting
- *  in the elevator sorting queue. When the active command completes, the
- *  commands in this queue are sorted by sector address. The sort is chosen
- *  between increasing or decreasing by minimizing the seek distance between
- *  the sector of the commands just completed and the sector of the first
- *  command in the list to be sorted.
- *  Trivial math assures that the unsorted average seek distance when doing
- *  random seeks over S sectors is S/3.
- *  When (Q-1) requests are uniformly distributed over S sectors, the average
- *  distance between two adjacent requests is S/((Q-1) + 1), so the sorted
- *  average seek distance for (Q-1) random requests over S sectors is S/Q.
- *  The elevator sorting hence divides the seek distance by a factor Q/3.
- *  The above pure geometric remarks are valid in all cases and the
- *  driver effectively reduces the seek distance by the predicted factor
- *  when there are Q concurrent read i/o operations on the device, but this
- *  does not necessarily results in a noticeable performance improvement:
- *  your mileage may vary....
- *
- *  Note: command reordering inside a batch of queued commands could cause
- *        wrong results only if there is at least one write request and the
- *        intersection (sector-wise) of all requests is not empty.
- *        When the driver detects a batch including overlapping requests
- *        (a really rare event) strict serial (pid) order is enforced.
- *  ----------------------------------------------------------------------------
- *  The extended translation option (et:y) is useful when using large physical
- *  disks/arrays. It could also be useful when switching between Adaptec boards
- *  and DPT boards without reformatting the disk.
- *  When a boot disk is partitioned with extended translation, in order to
- *  be able to boot it with a DPT board is could be necessary to add to
- *  lilo.conf additional commands as in the following example:
- *
- *  fix-table
- *  disk=/dev/sda bios=0x80 sectors=63 heads=128 cylindres=546
- *
- *  where the above geometry should be replaced with the one reported at
- *  power up by the DPT controller.
- *  ----------------------------------------------------------------------------
- *
- *  The boards are named EATA0, EATA1,... according to the detection order.
- *
- *  In order to support multiple ISA boards in a reliable way,
- *  the driver sets host->wish_block = 1 for all ISA boards.
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/blkdev.h>
-#include <linux/interrupt.h>
-#include <linux/stat.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/spinlock.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsicam.h>
-
-static int eata2x_detect(struct scsi_host_template *);
-static int eata2x_release(struct Scsi_Host *);
-static int eata2x_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
-static int eata2x_eh_abort(struct scsi_cmnd *);
-static int eata2x_eh_host_reset(struct scsi_cmnd *);
-static int eata2x_bios_param(struct scsi_device *, struct block_device *,
-			     sector_t, int *);
-static int eata2x_slave_configure(struct scsi_device *);
-
-static struct scsi_host_template driver_template = {
-	.name = "EATA/DMA 2.0x rev. 8.10.00 ",
-	.detect = eata2x_detect,
-	.release = eata2x_release,
-	.queuecommand = eata2x_queuecommand,
-	.eh_abort_handler = eata2x_eh_abort,
-	.eh_host_reset_handler = eata2x_eh_host_reset,
-	.bios_param = eata2x_bios_param,
-	.slave_configure = eata2x_slave_configure,
-	.this_id = 7,
-	.unchecked_isa_dma = 1,
-	.use_clustering = ENABLE_CLUSTERING,
-};
-
-#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
-
-/* Subversion values */
-#define ISA  0
-#define ESA 1
-
-#undef  FORCE_CONFIG
-
-#undef  DEBUG_LINKED_COMMANDS
-#undef  DEBUG_DETECT
-#undef  DEBUG_PCI_DETECT
-#undef  DEBUG_INTERRUPT
-#undef  DEBUG_RESET
-#undef  DEBUG_GENERATE_ERRORS
-#undef  DEBUG_GENERATE_ABORTS
-#undef  DEBUG_GEOMETRY
-
-#define MAX_ISA 4
-#define MAX_VESA 0
-#define MAX_EISA 15
-#define MAX_PCI 16
-#define MAX_BOARDS (MAX_ISA + MAX_VESA + MAX_EISA + MAX_PCI)
-#define MAX_CHANNEL 4
-#define MAX_LUN 32
-#define MAX_TARGET 32
-#define MAX_MAILBOXES 64
-#define MAX_SGLIST 64
-#define MAX_LARGE_SGLIST 122
-#define MAX_INTERNAL_RETRIES 64
-#define MAX_CMD_PER_LUN 2
-#define MAX_TAGGED_CMD_PER_LUN (MAX_MAILBOXES - MAX_CMD_PER_LUN)
-
-#define SKIP ULONG_MAX
-#define FREE 0
-#define IN_USE   1
-#define LOCKED   2
-#define IN_RESET 3
-#define IGNORE   4
-#define READY    5
-#define ABORTING 6
-#define NO_DMA  0xff
-#define MAXLOOP  10000
-#define TAG_DISABLED 0
-#define TAG_SIMPLE   1
-#define TAG_ORDERED  2
-
-#define REG_CMD         7
-#define REG_STATUS      7
-#define REG_AUX_STATUS  8
-#define REG_DATA        0
-#define REG_DATA2       1
-#define REG_SEE         6
-#define REG_LOW         2
-#define REG_LM          3
-#define REG_MID         4
-#define REG_MSB         5
-#define REGION_SIZE     9UL
-#define MAX_ISA_ADDR    0x03ff
-#define MIN_EISA_ADDR   0x1c88
-#define MAX_EISA_ADDR   0xfc88
-#define BSY_ASSERTED      0x80
-#define DRQ_ASSERTED      0x08
-#define ABSY_ASSERTED     0x01
-#define IRQ_ASSERTED      0x02
-#define READ_CONFIG_PIO   0xf0
-#define SET_CONFIG_PIO    0xf1
-#define SEND_CP_PIO       0xf2
-#define RECEIVE_SP_PIO    0xf3
-#define TRUNCATE_XFR_PIO  0xf4
-#define RESET_PIO         0xf9
-#define READ_CONFIG_DMA   0xfd
-#define SET_CONFIG_DMA    0xfe
-#define SEND_CP_DMA       0xff
-#define ASOK              0x00
-#define ASST              0x01
-
-#define YESNO(a) ((a) ? 'y' : 'n')
-#define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM)
-
-/* "EATA", in Big Endian format */
-#define EATA_SIG_BE 0x45415441
-
-/* Number of valid bytes in the board config structure for EATA 2.0x */
-#define EATA_2_0A_SIZE 28
-#define EATA_2_0B_SIZE 30
-#define EATA_2_0C_SIZE 34
-
-/* Board info structure */
-struct eata_info {
-	u_int32_t data_len;	/* Number of valid bytes after this field */
-	u_int32_t sign;		/* ASCII "EATA" signature */
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-	unchar version	: 4,
-	       		: 4;
-	unchar haaval	: 1,
-	       ata	: 1,
-	       drqvld	: 1,
-	       dmasup	: 1,
-	       morsup	: 1,
-	       trnxfr	: 1,
-	       tarsup	: 1,
-	       ocsena	: 1;
-#else
-	unchar		: 4,	/* unused low nibble */
-	 	version	: 4;	/* EATA version, should be 0x1 */
-	unchar ocsena	: 1,	/* Overlap Command Support Enabled */
-	       tarsup	: 1,	/* Target Mode Supported */
-	       trnxfr	: 1,	/* Truncate Transfer Cmd NOT Necessary */
-	       morsup	: 1,	/* More Supported */
-	       dmasup	: 1,	/* DMA Supported */
-	       drqvld	: 1,	/* DRQ Index (DRQX) is valid */
-	       ata	: 1,	/* This is an ATA device */
-	       haaval	: 1;	/* Host Adapter Address Valid */
-#endif
-
-	ushort cp_pad_len;	/* Number of pad bytes after cp_len */
-	unchar host_addr[4];	/* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
-	u_int32_t cp_len;	/* Number of valid bytes in cp */
-	u_int32_t sp_len;	/* Number of valid bytes in sp */
-	ushort queue_size;	/* Max number of cp that can be queued */
-	ushort unused;
-	ushort scatt_size;	/* Max number of entries in scatter/gather table */
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-	unchar drqx	: 2,
-	       second	: 1,
-	       irq_tr	: 1,
-	       irq	: 4;
-	unchar sync;
-	unchar		: 4,
-	       res1	: 1,
-	       large_sg	: 1,
-	       forcaddr	: 1,
-	       isaena	: 1;
-	unchar max_chan	: 3,
-	       max_id	: 5;
-	unchar max_lun;
-	unchar eisa	: 1,
-	       pci	: 1,
-	       idquest	: 1,
-	       m1	: 1,
-	       		: 4;
-#else
-	unchar irq	: 4,	/* Interrupt Request assigned to this controller */
-	       irq_tr	: 1,	/* 0 for edge triggered, 1 for level triggered */
-	       second	: 1,	/* 1 if this is a secondary (not primary) controller */
-	       drqx	: 2;	/* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
-	unchar sync;		/* 1 if scsi target id 7...0 is running sync scsi */
-
-	/* Structure extension defined in EATA 2.0B */
-	unchar isaena	: 1,	/* ISA i/o addressing is disabled/enabled */
-	       forcaddr	: 1,	/* Port address has been forced */
-	       large_sg	: 1,	/* 1 if large SG lists are supported */
-	       res1	: 1,
-	       		: 4;
-	unchar max_id	: 5,	/* Max SCSI target ID number */
-	       max_chan	: 3;	/* Max SCSI channel number on this board */
-
-	/* Structure extension defined in EATA 2.0C */
-	unchar max_lun;		/* Max SCSI LUN number */
-	unchar
-			: 4,
-	       m1	: 1,	/* This is a PCI with an M1 chip installed */
-	       idquest	: 1,	/* RAIDNUM returned is questionable */
-	       pci	: 1,	/* This board is PCI */
-	       eisa	: 1;	/* This board is EISA */
-#endif
-
-	unchar raidnum;		/* Uniquely identifies this HBA in a system */
-	unchar notused;
-
-	ushort ipad[247];
-};
-
-/* Board config structure */
-struct eata_config {
-	ushort len;		/* Number of bytes following this field */
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-	unchar		: 4,
-	       tarena	: 1,
-	       mdpena	: 1,
-	       ocena	: 1,
-	       edis	: 1;
-#else
-	unchar edis	: 1,	/* Disable EATA interface after config command */
-	       ocena	: 1,	/* Overlapped Commands Enabled */
-	       mdpena	: 1,	/* Transfer all Modified Data Pointer Messages */
-	       tarena	: 1,	/* Target Mode Enabled for this controller */
-	       		: 4;
-#endif
-	unchar cpad[511];
-};
-
-/* Returned status packet structure */
-struct mssp {
-#if defined(__BIG_ENDIAN_BITFIELD)
-	unchar eoc	: 1,
-	       adapter_status : 7;
-#else
-	unchar adapter_status : 7,	/* State related to current command */
-	       eoc	: 1;		/* End Of Command (1 = command completed) */
-#endif
-	unchar target_status;	/* SCSI status received after data transfer */
-	unchar unused[2];
-	u_int32_t inv_res_len;	/* Number of bytes not transferred */
-	u_int32_t cpp_index;	/* Index of address set in cp */
-	char mess[12];
-};
-
-struct sg_list {
-	unsigned int address;	/* Segment Address */
-	unsigned int num_bytes;	/* Segment Length */
-};
-
-/* MailBox SCSI Command Packet */
-struct mscp {
-#if defined(__BIG_ENDIAN_BITFIELD)
-	unchar din	: 1,
-	       dout	: 1,
-	       interp	: 1,
-	       		: 1,
-		sg	: 1,
-		reqsen	:1,
-		init	: 1,
-		sreset	: 1;
-	unchar sense_len;
-	unchar unused[3];
-	unchar		: 7,
-	       fwnest	: 1;
-	unchar		: 5,
-	       hbaci	: 1,
-	       iat	: 1,
-	       phsunit	: 1;
-	unchar channel	: 3,
-	       target	: 5;
-	unchar one	: 1,
-	       dispri	: 1,
-	       luntar	: 1,
-	       lun	: 5;
-#else
-	unchar sreset	:1,	/* SCSI Bus Reset Signal should be asserted */
-	       init	:1,	/* Re-initialize controller and self test */
-	       reqsen	:1,	/* Transfer Request Sense Data to addr using DMA */
-	       sg	:1,	/* Use Scatter/Gather */
-	       		:1,
-	       interp	:1,	/* The controller interprets cp, not the target */
-	       dout	:1,	/* Direction of Transfer is Out (Host to Target) */
-	       din	:1;	/* Direction of Transfer is In (Target to Host) */
-	unchar sense_len;	/* Request Sense Length */
-	unchar unused[3];
-	unchar fwnest	: 1,	/* Send command to a component of an Array Group */
-			: 7;
-	unchar phsunit	: 1,	/* Send to Target Physical Unit (bypass RAID) */
-	       iat	: 1,	/* Inhibit Address Translation */
-	       hbaci	: 1,	/* Inhibit HBA Caching for this command */
-	       		: 5;
-	unchar target	: 5,	/* SCSI target ID */
-	       channel	: 3;	/* SCSI channel number */
-	unchar lun	: 5,	/* SCSI logical unit number */
-	       luntar	: 1,	/* This cp is for Target (not LUN) */
-	       dispri	: 1,	/* Disconnect Privilege granted */
-	       one	: 1;	/* 1 */
-#endif
-
-	unchar mess[3];		/* Massage to/from Target */
-	unchar cdb[12];		/* Command Descriptor Block */
-	u_int32_t data_len;	/* If sg=0 Data Length, if sg=1 sglist length */
-	u_int32_t cpp_index;	/* Index of address to be returned in sp */
-	u_int32_t data_address;	/* If sg=0 Data Address, if sg=1 sglist address */
-	u_int32_t sp_dma_addr;	/* Address where sp is DMA'ed when cp completes */
-	u_int32_t sense_addr;	/* Address where Sense Data is DMA'ed on error */
-
-	/* Additional fields begin here. */
-	struct scsi_cmnd *SCpnt;
-
-	/* All the cp structure is zero filled by queuecommand except the
-	   following CP_TAIL_SIZE bytes, initialized by detect */
-	dma_addr_t cp_dma_addr;	/* dma handle for this cp structure */
-	struct sg_list *sglist;	/* pointer to the allocated SG list */
-};
-
-#define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t))
-
-struct hostdata {
-	struct mscp cp[MAX_MAILBOXES];	/* Mailboxes for this board */
-	unsigned int cp_stat[MAX_MAILBOXES];	/* FREE, IN_USE, LOCKED, IN_RESET */
-	unsigned int last_cp_used;	/* Index of last mailbox used */
-	unsigned int iocount;	/* Total i/o done for this board */
-	int board_number;	/* Number of this board */
-	char board_name[16];	/* Name of this board */
-	int in_reset;		/* True if board is doing a reset */
-	int target_to[MAX_TARGET][MAX_CHANNEL];	/* N. of timeout errors on target */
-	int target_redo[MAX_TARGET][MAX_CHANNEL];	/* If 1 redo i/o on target */
-	unsigned int retries;	/* Number of internal retries */
-	unsigned long last_retried_pid;	/* Pid of last retried command */
-	unsigned char subversion;	/* Bus type, either ISA or EISA/PCI */
-	unsigned char protocol_rev;	/* EATA 2.0 rev., 'A' or 'B' or 'C' */
-	unsigned char is_pci;	/* 1 is bus type is PCI */
-	struct pci_dev *pdev;	/* pdev for PCI bus, NULL otherwise */
-	struct mssp *sp_cpu_addr;	/* cpu addr for DMA buffer sp */
-	dma_addr_t sp_dma_addr;	/* dma handle for DMA buffer sp */
-	struct mssp sp;		/* Local copy of sp buffer */
-};
-
-static struct Scsi_Host *sh[MAX_BOARDS];
-static const char *driver_name = "EATA";
-static char sha[MAX_BOARDS];
-
-/* Initialize num_boards so that ihdlr can work while detect is in progress */
-static unsigned int num_boards = MAX_BOARDS;
-
-static unsigned long io_port[] = {
-
-	/* Space for MAX_INT_PARAM ports usable while loading as a module */
-	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
-	SKIP, SKIP,
-
-	/* First ISA */
-	0x1f0,
-
-	/* Space for MAX_PCI ports possibly reported by PCI_BIOS */
-	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
-	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
-
-	/* MAX_EISA ports */
-	0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
-	0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,
-
-	/* Other (MAX_ISA - 1) ports */
-	0x170, 0x230, 0x330,
-
-	/* End of list */
-	0x0
-};
-
-/* Device is Big Endian */
-#define H2DEV(x)   cpu_to_be32(x)
-#define DEV2H(x)   be32_to_cpu(x)
-#define H2DEV16(x) cpu_to_be16(x)
-#define DEV2H16(x) be16_to_cpu(x)
-
-/* But transfer orientation from the 16 bit data register is Little Endian */
-#define REG2H(x)   le16_to_cpu(x)
-
-static irqreturn_t do_interrupt_handler(int, void *);
-static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *,
-		      unsigned int);
-static int do_trace = 0;
-static int setup_done = 0;
-static int link_statistics;
-static int ext_tran = 0;
-static int rev_scan = 1;
-
-#if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE)
-static int tag_mode = TAG_SIMPLE;
-#else
-static int tag_mode = TAG_DISABLED;
-#endif
-
-#if defined(CONFIG_SCSI_EATA_LINKED_COMMANDS)
-static int linked_comm = 1;
-#else
-static int linked_comm = 0;
-#endif
-
-#if defined(CONFIG_SCSI_EATA_MAX_TAGS)
-static int max_queue_depth = CONFIG_SCSI_EATA_MAX_TAGS;
-#else
-static int max_queue_depth = MAX_CMD_PER_LUN;
-#endif
-
-#if defined(CONFIG_ISA)
-static int isa_probe = 1;
-#else
-static int isa_probe = 0;
-#endif
-
-#if defined(CONFIG_EISA)
-static int eisa_probe = 1;
-#else
-static int eisa_probe = 0;
-#endif
-
-#if defined(CONFIG_PCI)
-static int pci_probe = 1;
-#else
-static int pci_probe = 0;
-#endif
-
-#define MAX_INT_PARAM 10
-#define MAX_BOOT_OPTIONS_SIZE 256
-static char boot_options[MAX_BOOT_OPTIONS_SIZE];
-
-#if defined(MODULE)
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-
-module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0);
-MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option."
-		 "            Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\"");
-MODULE_AUTHOR("Dario Ballabio");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("EATA/DMA SCSI Driver");
-
-#endif
-
-static int eata2x_slave_configure(struct scsi_device *dev)
-{
-	int tqd, utqd;
-	char *tag_suffix, *link_suffix;
-
-	utqd = MAX_CMD_PER_LUN;
-	tqd = max_queue_depth;
-
-	if (TLDEV(dev->type) && dev->tagged_supported) {
-		if (tag_mode == TAG_SIMPLE) {
-			tag_suffix = ", simple tags";
-		} else if (tag_mode == TAG_ORDERED) {
-			tag_suffix = ", ordered tags";
-		} else {
-			tag_suffix = ", no tags";
-		}
-		scsi_change_queue_depth(dev, tqd);
-	} else if (TLDEV(dev->type) && linked_comm) {
-		scsi_change_queue_depth(dev, tqd);
-		tag_suffix = ", untagged";
-	} else {
-		scsi_change_queue_depth(dev, utqd);
-		tag_suffix = "";
-	}
-
-	if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2)
-		link_suffix = ", sorted";
-	else if (TLDEV(dev->type))
-		link_suffix = ", unsorted";
-	else
-		link_suffix = "";
-
-	sdev_printk(KERN_INFO, dev,
-		"cmds/lun %d%s%s.\n",
-	       dev->queue_depth, link_suffix, tag_suffix);
-
-	return 0;
-}
-
-static int wait_on_busy(unsigned long iobase, unsigned int loop)
-{
-	while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) {
-		udelay(1L);
-		if (--loop == 0)
-			return 1;
-	}
-	return 0;
-}
-
-static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd)
-{
-	unsigned char *byaddr;
-	unsigned long devaddr;
-
-	if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP)))
-		return 1;
-
-	if (addr) {
-		devaddr = H2DEV(addr);
-		byaddr = (unsigned char *)&devaddr;
-		outb(byaddr[3], iobase + REG_LOW);
-		outb(byaddr[2], iobase + REG_LM);
-		outb(byaddr[1], iobase + REG_MID);
-		outb(byaddr[0], iobase + REG_MSB);
-	}
-
-	outb(cmd, iobase + REG_CMD);
-	return 0;
-}
-
-static int read_pio(unsigned long iobase, ushort * start, ushort * end)
-{
-	unsigned int loop = MAXLOOP;
-	ushort *p;
-
-	for (p = start; p <= end; p++) {
-		while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) {
-			udelay(1L);
-			if (--loop == 0)
-				return 1;
-		}
-		loop = MAXLOOP;
-		*p = REG2H(inw(iobase));
-	}
-
-	return 0;
-}
-
-static struct pci_dev *get_pci_dev(unsigned long port_base)
-{
-#if defined(CONFIG_PCI)
-	unsigned int addr;
-	struct pci_dev *dev = NULL;
-
-	while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
-		addr = pci_resource_start(dev, 0);
-
-#if defined(DEBUG_PCI_DETECT)
-		printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n",
-		       driver_name, dev->bus->number, dev->devfn, addr);
-#endif
-
-		/* we are in so much trouble for a pci hotplug system with this driver
-		 * anyway, so doing this at least lets people unload the driver and not
-		 * cause memory problems, but in general this is a bad thing to do (this
-		 * driver needs to be converted to the proper PCI api someday... */
-		pci_dev_put(dev);
-		if (addr + PCI_BASE_ADDRESS_0 == port_base)
-			return dev;
-	}
-#endif				/* end CONFIG_PCI */
-	return NULL;
-}
-
-static void enable_pci_ports(void)
-{
-#if defined(CONFIG_PCI)
-	struct pci_dev *dev = NULL;
-
-	while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
-#if defined(DEBUG_PCI_DETECT)
-		printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n",
-		       driver_name, dev->bus->number, dev->devfn);
-#endif
-
-		if (pci_enable_device(dev))
-			printk
-			    ("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n",
-			     driver_name, dev->bus->number, dev->devfn);
-	}
-
-#endif				/* end CONFIG_PCI */
-}
-
-static int port_detect(unsigned long port_base, unsigned int j,
-		struct scsi_host_template *tpnt)
-{
-	unsigned char irq, dma_channel, subversion, i, is_pci = 0;
-	unsigned char protocol_rev;
-	struct eata_info info;
-	char *bus_type, dma_name[16];
-	struct pci_dev *pdev;
-	/* Allowed DMA channels for ISA (0 indicates reserved) */
-	unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
-	struct Scsi_Host *shost;
-	struct hostdata *ha;
-	char name[16];
-
-	sprintf(name, "%s%d", driver_name, j);
-
-	if (!request_region(port_base, REGION_SIZE, driver_name)) {
-#if defined(DEBUG_DETECT)
-		printk("%s: address 0x%03lx in use, skipping probe.\n", name,
-		       port_base);
-#endif
-		goto fail;
-	}
-
-	if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
-#if defined(DEBUG_DETECT)
-		printk("%s: detect, do_dma failed at 0x%03lx.\n", name,
-		       port_base);
-#endif
-		goto freelock;
-	}
-
-	/* Read the info structure */
-	if (read_pio(port_base, (ushort *) & info, (ushort *) & info.ipad[0])) {
-#if defined(DEBUG_DETECT)
-		printk("%s: detect, read_pio failed at 0x%03lx.\n", name,
-		       port_base);
-#endif
-		goto freelock;
-	}
-
-	info.data_len = DEV2H(info.data_len);
-	info.sign = DEV2H(info.sign);
-	info.cp_pad_len = DEV2H16(info.cp_pad_len);
-	info.cp_len = DEV2H(info.cp_len);
-	info.sp_len = DEV2H(info.sp_len);
-	info.scatt_size = DEV2H16(info.scatt_size);
-	info.queue_size = DEV2H16(info.queue_size);
-
-	/* Check the controller "EATA" signature */
-	if (info.sign != EATA_SIG_BE) {
-#if defined(DEBUG_DETECT)
-		printk("%s: signature 0x%04x discarded.\n", name, info.sign);
-#endif
-		goto freelock;
-	}
-
-	if (info.data_len < EATA_2_0A_SIZE) {
-		printk
-		    ("%s: config structure size (%d bytes) too short, detaching.\n",
-		     name, info.data_len);
-		goto freelock;
-	} else if (info.data_len == EATA_2_0A_SIZE)
-		protocol_rev = 'A';
-	else if (info.data_len == EATA_2_0B_SIZE)
-		protocol_rev = 'B';
-	else
-		protocol_rev = 'C';
-
-	if (protocol_rev != 'A' && info.forcaddr) {
-		printk("%s: warning, port address has been forced.\n", name);
-		bus_type = "PCI";
-		is_pci = 1;
-		subversion = ESA;
-	} else if (port_base > MAX_EISA_ADDR
-		   || (protocol_rev == 'C' && info.pci)) {
-		bus_type = "PCI";
-		is_pci = 1;
-		subversion = ESA;
-	} else if (port_base >= MIN_EISA_ADDR
-		   || (protocol_rev == 'C' && info.eisa)) {
-		bus_type = "EISA";
-		subversion = ESA;
-	} else if (protocol_rev == 'C' && !info.eisa && !info.pci) {
-		bus_type = "ISA";
-		subversion = ISA;
-	} else if (port_base > MAX_ISA_ADDR) {
-		bus_type = "PCI";
-		is_pci = 1;
-		subversion = ESA;
-	} else {
-		bus_type = "ISA";
-		subversion = ISA;
-	}
-
-	if (!info.haaval || info.ata) {
-		printk
-		    ("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
-		     name, port_base, bus_type, info.haaval, info.ata);
-		goto freelock;
-	}
-
-	if (info.drqvld) {
-		if (subversion == ESA)
-			printk("%s: warning, weird %s board using DMA.\n", name,
-			       bus_type);
-
-		subversion = ISA;
-		dma_channel = dma_channel_table[3 - info.drqx];
-	} else {
-		if (subversion == ISA)
-			printk("%s: warning, weird %s board not using DMA.\n",
-			       name, bus_type);
-
-		subversion = ESA;
-		dma_channel = NO_DMA;
-	}
-
-	if (!info.dmasup)
-		printk("%s: warning, DMA protocol support not asserted.\n",
-		       name);
-
-	irq = info.irq;
-
-	if (subversion == ESA && !info.irq_tr)
-		printk
-		    ("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
-		     name, irq);
-
-	if (is_pci) {
-		pdev = get_pci_dev(port_base);
-		if (!pdev)
-			printk
-			    ("%s: warning, failed to get pci_dev structure.\n",
-			     name);
-	} else
-		pdev = NULL;
-
-	if (pdev && (irq != pdev->irq)) {
-		printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq,
-		       pdev->irq);
-		irq = pdev->irq;
-	}
-
-	/* Board detected, allocate its IRQ */
-	if (request_irq(irq, do_interrupt_handler,
-			(subversion == ESA) ? IRQF_SHARED : 0,
-			driver_name, (void *)&sha[j])) {
-		printk("%s: unable to allocate IRQ %u, detaching.\n", name,
-		       irq);
-		goto freelock;
-	}
-
-	if (subversion == ISA && request_dma(dma_channel, driver_name)) {
-		printk("%s: unable to allocate DMA channel %u, detaching.\n",
-		       name, dma_channel);
-		goto freeirq;
-	}
-#if defined(FORCE_CONFIG)
-	{
-		struct eata_config *cf;
-		dma_addr_t cf_dma_addr;
-
-		cf = pci_zalloc_consistent(pdev, sizeof(struct eata_config),
-					   &cf_dma_addr);
-
-		if (!cf) {
-			printk
-			    ("%s: config, pci_alloc_consistent failed, detaching.\n",
-			     name);
-			goto freedma;
-		}
-
-		/* Set board configuration */
-		cf->len = (ushort) H2DEV16((ushort) 510);
-		cf->ocena = 1;
-
-		if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
-			printk
-			    ("%s: busy timeout sending configuration, detaching.\n",
-			     name);
-			pci_free_consistent(pdev, sizeof(struct eata_config),
-					    cf, cf_dma_addr);
-			goto freedma;
-		}
-
-	}
-#endif
-
-	sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata));
-	if (shost == NULL) {
-		printk("%s: unable to register host, detaching.\n", name);
-		goto freedma;
-	}
-
-	shost->io_port = port_base;
-	shost->unique_id = port_base;
-	shost->n_io_port = REGION_SIZE;
-	shost->dma_channel = dma_channel;
-	shost->irq = irq;
-	shost->sg_tablesize = (ushort) info.scatt_size;
-	shost->this_id = (ushort) info.host_addr[3];
-	shost->can_queue = (ushort) info.queue_size;
-	shost->cmd_per_lun = MAX_CMD_PER_LUN;
-
-	ha = (struct hostdata *)shost->hostdata;
-	
-	memset(ha, 0, sizeof(struct hostdata));
-	ha->subversion = subversion;
-	ha->protocol_rev = protocol_rev;
-	ha->is_pci = is_pci;
-	ha->pdev = pdev;
-	ha->board_number = j;
-
-	if (ha->subversion == ESA)
-		shost->unchecked_isa_dma = 0;
-	else {
-		unsigned long flags;
-		shost->unchecked_isa_dma = 1;
-
-		flags = claim_dma_lock();
-		disable_dma(dma_channel);
-		clear_dma_ff(dma_channel);
-		set_dma_mode(dma_channel, DMA_MODE_CASCADE);
-		enable_dma(dma_channel);
-		release_dma_lock(flags);
-
-	}
-
-	strcpy(ha->board_name, name);
-
-	/* DPT PM2012 does not allow to detect sg_tablesize correctly */
-	if (shost->sg_tablesize > MAX_SGLIST || shost->sg_tablesize < 2) {
-		printk("%s: detect, wrong n. of SG lists %d, fixed.\n",
-		       ha->board_name, shost->sg_tablesize);
-		shost->sg_tablesize = MAX_SGLIST;
-	}
-
-	/* DPT PM2012 does not allow to detect can_queue correctly */
-	if (shost->can_queue > MAX_MAILBOXES || shost->can_queue < 2) {
-		printk("%s: detect, wrong n. of mbox %d, fixed.\n",
-		       ha->board_name, shost->can_queue);
-		shost->can_queue = MAX_MAILBOXES;
-	}
-
-	if (protocol_rev != 'A') {
-		if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
-			shost->max_channel = info.max_chan;
-
-		if (info.max_id > 7 && info.max_id < MAX_TARGET)
-			shost->max_id = info.max_id + 1;
-
-		if (info.large_sg && shost->sg_tablesize == MAX_SGLIST)
-			shost->sg_tablesize = MAX_LARGE_SGLIST;
-	}
-
-	if (protocol_rev == 'C') {
-		if (info.max_lun > 7 && info.max_lun < MAX_LUN)
-			shost->max_lun = info.max_lun + 1;
-	}
-
-	if (dma_channel == NO_DMA)
-		sprintf(dma_name, "%s", "BMST");
-	else
-		sprintf(dma_name, "DMA %u", dma_channel);
-
-	for (i = 0; i < shost->can_queue; i++)
-		ha->cp[i].cp_dma_addr = pci_map_single(ha->pdev,
-							  &ha->cp[i],
-							  sizeof(struct mscp),
-							  PCI_DMA_BIDIRECTIONAL);
-
-	for (i = 0; i < shost->can_queue; i++) {
-		size_t sz = shost->sg_tablesize *sizeof(struct sg_list);
-		gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
-		ha->cp[i].sglist = kmalloc(sz, gfp_mask);
-		if (!ha->cp[i].sglist) {
-			printk
-			    ("%s: kmalloc SGlist failed, mbox %d, detaching.\n",
-			     ha->board_name, i);
-			goto release;
-		}
-	}
-
-	if (!(ha->sp_cpu_addr = pci_alloc_consistent(ha->pdev,
-							sizeof(struct mssp),
-							&ha->sp_dma_addr))) {
-		printk("%s: pci_alloc_consistent failed, detaching.\n", ha->board_name);
-		goto release;
-	}
-
-	if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
-		max_queue_depth = MAX_TAGGED_CMD_PER_LUN;
-
-	if (max_queue_depth < MAX_CMD_PER_LUN)
-		max_queue_depth = MAX_CMD_PER_LUN;
-
-	if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
-		tag_mode = TAG_ORDERED;
-
-	if (j == 0) {
-		printk
-		    ("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");
-		printk
-		    ("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "
-		     "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
-		     YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
-		     YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe),
-		     YESNO(pci_probe));
-	}
-
-	printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n",
-	       ha->board_name, ha->protocol_rev, bus_type,
-	       (unsigned long)shost->io_port, shost->irq, dma_name,
-	       shost->sg_tablesize, shost->can_queue);
-
-	if (shost->max_id > 8 || shost->max_lun > 8)
-		printk
-		    ("%s: wide SCSI support enabled, max_id %u, max_lun %llu.\n",
-		     ha->board_name, shost->max_id, shost->max_lun);
-
-	for (i = 0; i <= shost->max_channel; i++)
-		printk("%s: SCSI channel %u enabled, host target ID %d.\n",
-		       ha->board_name, i, info.host_addr[3 - i]);
-
-#if defined(DEBUG_DETECT)
-	printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "
-	       "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,
-	       info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,
-	       info.second, info.data_len, info.cp_len, info.sp_len);
-
-	if (protocol_rev == 'B' || protocol_rev == 'C')
-		printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "
-		       "large_sg %u, res1 %u.\n", name, info.isaena,
-		       info.forcaddr, info.max_id, info.max_chan, info.large_sg,
-		       info.res1);
-
-	if (protocol_rev == 'C')
-		printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, "
-		       "raidnum %u.\n", name, info.max_lun, info.m1,
-		       info.idquest, info.pci, info.eisa, info.raidnum);
-#endif
-
-	if (ha->pdev) {
-		pci_set_master(ha->pdev);
-		if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(32)))
-			printk("%s: warning, pci_set_dma_mask failed.\n",
-			       ha->board_name);
-	}
-
-	return 1;
-
-      freedma:
-	if (subversion == ISA)
-		free_dma(dma_channel);
-      freeirq:
-	free_irq(irq, &sha[j]);
-      freelock:
-	release_region(port_base, REGION_SIZE);
-      fail:
-	return 0;
-
-      release:
-	eata2x_release(shost);
-	return 0;
-}
-
-static void internal_setup(char *str, int *ints)
-{
-	int i, argc = ints[0];
-	char *cur = str, *pc;
-
-	if (argc > 0) {
-		if (argc > MAX_INT_PARAM)
-			argc = MAX_INT_PARAM;
-
-		for (i = 0; i < argc; i++)
-			io_port[i] = ints[i + 1];
-
-		io_port[i] = 0;
-		setup_done = 1;
-	}
-
-	while (cur && (pc = strchr(cur, ':'))) {
-		int val = 0, c = *++pc;
-
-		if (c == 'n' || c == 'N')
-			val = 0;
-		else if (c == 'y' || c == 'Y')
-			val = 1;
-		else
-			val = (int)simple_strtoul(pc, NULL, 0);
-
-		if (!strncmp(cur, "lc:", 3))
-			linked_comm = val;
-		else if (!strncmp(cur, "tm:", 3))
-			tag_mode = val;
-		else if (!strncmp(cur, "tc:", 3))
-			tag_mode = val;
-		else if (!strncmp(cur, "mq:", 3))
-			max_queue_depth = val;
-		else if (!strncmp(cur, "ls:", 3))
-			link_statistics = val;
-		else if (!strncmp(cur, "et:", 3))
-			ext_tran = val;
-		else if (!strncmp(cur, "rs:", 3))
-			rev_scan = val;
-		else if (!strncmp(cur, "ip:", 3))
-			isa_probe = val;
-		else if (!strncmp(cur, "ep:", 3))
-			eisa_probe = val;
-		else if (!strncmp(cur, "pp:", 3))
-			pci_probe = val;
-
-		if ((cur = strchr(cur, ',')))
-			++cur;
-	}
-
-	return;
-}
-
-static int option_setup(char *str)
-{
-	int ints[MAX_INT_PARAM];
-	char *cur = str;
-	int i = 1;
-
-	while (cur && isdigit(*cur) && i < MAX_INT_PARAM) {
-		ints[i++] = simple_strtoul(cur, NULL, 0);
-
-		if ((cur = strchr(cur, ',')) != NULL)
-			cur++;
-	}
-
-	ints[0] = i - 1;
-	internal_setup(cur, ints);
-	return 1;
-}
-
-static void add_pci_ports(void)
-{
-#if defined(CONFIG_PCI)
-	unsigned int addr, k;
-	struct pci_dev *dev = NULL;
-
-	for (k = 0; k < MAX_PCI; k++) {
-
-		if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev)))
-			break;
-
-		if (pci_enable_device(dev)) {
-#if defined(DEBUG_PCI_DETECT)
-			printk
-			    ("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n",
-			     driver_name, dev->bus->number, dev->devfn);
-#endif
-
-			continue;
-		}
-
-		addr = pci_resource_start(dev, 0);
-
-#if defined(DEBUG_PCI_DETECT)
-		printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
-		       driver_name, k, dev->bus->number, dev->devfn, addr);
-#endif
-
-		/* Order addresses according to rev_scan value */
-		io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] =
-		    addr + PCI_BASE_ADDRESS_0;
-	}
-
-	pci_dev_put(dev);
-#endif				/* end CONFIG_PCI */
-}
-
-static int eata2x_detect(struct scsi_host_template *tpnt)
-{
-	unsigned int j = 0, k;
-
-	tpnt->proc_name = "eata2x";
-
-	if (strlen(boot_options))
-		option_setup(boot_options);
-
-#if defined(MODULE)
-	/* io_port could have been modified when loading as a module */
-	if (io_port[0] != SKIP) {
-		setup_done = 1;
-		io_port[MAX_INT_PARAM] = 0;
-	}
-#endif
-
-	for (k = MAX_INT_PARAM; io_port[k]; k++)
-		if (io_port[k] == SKIP)
-			continue;
-		else if (io_port[k] <= MAX_ISA_ADDR) {
-			if (!isa_probe)
-				io_port[k] = SKIP;
-		} else if (io_port[k] >= MIN_EISA_ADDR
-			   && io_port[k] <= MAX_EISA_ADDR) {
-			if (!eisa_probe)
-				io_port[k] = SKIP;
-		}
-
-	if (pci_probe) {
-		if (!setup_done)
-			add_pci_ports();
-		else
-			enable_pci_ports();
-	}
-
-	for (k = 0; io_port[k]; k++) {
-
-		if (io_port[k] == SKIP)
-			continue;
-
-		if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt))
-			j++;
-	}
-
-	num_boards = j;
-	return j;
-}
-
-static void map_dma(unsigned int i, struct hostdata *ha)
-{
-	unsigned int k, pci_dir;
-	int count;
-	struct scatterlist *sg;
-	struct mscp *cpp;
-	struct scsi_cmnd *SCpnt;
-
-	cpp = &ha->cp[i];
-	SCpnt = cpp->SCpnt;
-	pci_dir = SCpnt->sc_data_direction;
-
-	if (SCpnt->sense_buffer)
-		cpp->sense_addr =
-		    H2DEV(pci_map_single(ha->pdev, SCpnt->sense_buffer,
-			   SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE));
-
-	cpp->sense_len = SCSI_SENSE_BUFFERSIZE;
-
-	if (!scsi_sg_count(SCpnt)) {
-		cpp->data_len = 0;
-		return;
-	}
-
-	count = pci_map_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt),
-			   pci_dir);
-	BUG_ON(!count);
-
-	scsi_for_each_sg(SCpnt, sg, count, k) {
-		cpp->sglist[k].address = H2DEV(sg_dma_address(sg));
-		cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg));
-	}
-
-	cpp->sg = 1;
-	cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist,
-						 scsi_sg_count(SCpnt) *
-						 sizeof(struct sg_list),
-						 pci_dir));
-	cpp->data_len = H2DEV((scsi_sg_count(SCpnt) * sizeof(struct sg_list)));
-}
-
-static void unmap_dma(unsigned int i, struct hostdata *ha)
-{
-	unsigned int pci_dir;
-	struct mscp *cpp;
-	struct scsi_cmnd *SCpnt;
-
-	cpp = &ha->cp[i];
-	SCpnt = cpp->SCpnt;
-	pci_dir = SCpnt->sc_data_direction;
-
-	if (DEV2H(cpp->sense_addr))
-		pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr),
-				 DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
-
-	if (scsi_sg_count(SCpnt))
-		pci_unmap_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt),
-			     pci_dir);
-
-	if (!DEV2H(cpp->data_len))
-		pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-	if (DEV2H(cpp->data_address))
-		pci_unmap_single(ha->pdev, DEV2H(cpp->data_address),
-				 DEV2H(cpp->data_len), pci_dir);
-}
-
-static void sync_dma(unsigned int i, struct hostdata *ha)
-{
-	unsigned int pci_dir;
-	struct mscp *cpp;
-	struct scsi_cmnd *SCpnt;
-
-	cpp = &ha->cp[i];
-	SCpnt = cpp->SCpnt;
-	pci_dir = SCpnt->sc_data_direction;
-
-	if (DEV2H(cpp->sense_addr))
-		pci_dma_sync_single_for_cpu(ha->pdev, DEV2H(cpp->sense_addr),
-					    DEV2H(cpp->sense_len),
-					    PCI_DMA_FROMDEVICE);
-
-	if (scsi_sg_count(SCpnt))
-		pci_dma_sync_sg_for_cpu(ha->pdev, scsi_sglist(SCpnt),
-					scsi_sg_count(SCpnt), pci_dir);
-
-	if (!DEV2H(cpp->data_len))
-		pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-	if (DEV2H(cpp->data_address))
-		pci_dma_sync_single_for_cpu(ha->pdev,
-					    DEV2H(cpp->data_address),
-					    DEV2H(cpp->data_len), pci_dir);
-}
-
-static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha)
-{
-	unsigned int k;
-
-	static const unsigned char data_out_cmds[] = {
-		0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e,
-		0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40,
-		0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d
-	};
-
-	static const unsigned char data_none_cmds[] = {
-		0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e,
-		0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47,
-		0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00
-	};
-
-	struct mscp *cpp;
-	struct scsi_cmnd *SCpnt;
-
-	cpp = &ha->cp[i];
-	SCpnt = cpp->SCpnt;
-
-	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
-		cpp->din = 1;
-		cpp->dout = 0;
-		return;
-	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
-		cpp->din = 0;
-		cpp->dout = 1;
-		return;
-	} else if (SCpnt->sc_data_direction == DMA_NONE) {
-		cpp->din = 0;
-		cpp->dout = 0;
-		return;
-	}
-
-	if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL)
-		panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n",
-				ha->board_name);
-
-	for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
-		if (SCpnt->cmnd[0] == data_out_cmds[k]) {
-			cpp->dout = 1;
-			break;
-		}
-
-	if ((cpp->din = !cpp->dout))
-		for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
-			if (SCpnt->cmnd[0] == data_none_cmds[k]) {
-				cpp->din = 0;
-				break;
-			}
-
-}
-
-static int eata2x_queuecommand_lck(struct scsi_cmnd *SCpnt,
-			       void (*done) (struct scsi_cmnd *))
-{
-	struct Scsi_Host *shost = SCpnt->device->host;
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
-	unsigned int i, k;
-	struct mscp *cpp;
-
-	if (SCpnt->host_scribble)
-		panic("%s: qcomm, SCpnt %p already active.\n",
-		      ha->board_name, SCpnt);
-
-	/* i is the mailbox number, look for the first free mailbox
-	   starting from last_cp_used */
-	i = ha->last_cp_used + 1;
-
-	for (k = 0; k < shost->can_queue; k++, i++) {
-		if (i >= shost->can_queue)
-			i = 0;
-		if (ha->cp_stat[i] == FREE) {
-			ha->last_cp_used = i;
-			break;
-		}
-	}
-
-	if (k == shost->can_queue) {
-		printk("%s: qcomm, no free mailbox.\n", ha->board_name);
-		return 1;
-	}
-
-	/* Set pointer to control packet structure */
-	cpp = &ha->cp[i];
-
-	memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE);
-
-	/* Set pointer to status packet structure, Big Endian format */
-	cpp->sp_dma_addr = H2DEV(ha->sp_dma_addr);
-
-	SCpnt->scsi_done = done;
-	cpp->cpp_index = i;
-	SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index;
-
-	if (do_trace)
-		scmd_printk(KERN_INFO, SCpnt,
-			"qcomm, mbox %d.\n", i);
-
-	cpp->reqsen = 1;
-	cpp->dispri = 1;
-#if 0
-	if (SCpnt->device->type == TYPE_TAPE)
-		cpp->hbaci = 1;
-#endif
-	cpp->one = 1;
-	cpp->channel = SCpnt->device->channel;
-	cpp->target = SCpnt->device->id;
-	cpp->lun = SCpnt->device->lun;
-	cpp->SCpnt = SCpnt;
-	memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
-
-	/* Use data transfer direction SCpnt->sc_data_direction */
-	scsi_to_dev_dir(i, ha);
-
-	/* Map DMA buffers and SG list */
-	map_dma(i, ha);
-
-	if (linked_comm && SCpnt->device->queue_depth > 2
-	    && TLDEV(SCpnt->device->type)) {
-		ha->cp_stat[i] = READY;
-		flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 0);
-		return 0;
-	}
-
-	/* Send control packet to the board */
-	if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
-		unmap_dma(i, ha);
-		SCpnt->host_scribble = NULL;
-		scmd_printk(KERN_INFO, SCpnt, "qcomm, adapter busy.\n");
-		return 1;
-	}
-
-	ha->cp_stat[i] = IN_USE;
-	return 0;
-}
-
-static DEF_SCSI_QCMD(eata2x_queuecommand)
-
-static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
-{
-	struct Scsi_Host *shost = SCarg->device->host;
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
-	unsigned int i;
-
-	if (SCarg->host_scribble == NULL) {
-		scmd_printk(KERN_INFO, SCarg, "abort, cmd inactive.\n");
-		return SUCCESS;
-	}
-
-	i = *(unsigned int *)SCarg->host_scribble;
-	scmd_printk(KERN_WARNING, SCarg, "abort, mbox %d.\n", i);
-
-	if (i >= shost->can_queue)
-		panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name);
-
-	if (wait_on_busy(shost->io_port, MAXLOOP)) {
-		printk("%s: abort, timeout error.\n", ha->board_name);
-		return FAILED;
-	}
-
-	if (ha->cp_stat[i] == FREE) {
-		printk("%s: abort, mbox %d is free.\n", ha->board_name, i);
-		return SUCCESS;
-	}
-
-	if (ha->cp_stat[i] == IN_USE) {
-		printk("%s: abort, mbox %d is in use.\n", ha->board_name, i);
-
-		if (SCarg != ha->cp[i].SCpnt)
-			panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
-			      ha->board_name, i, SCarg, ha->cp[i].SCpnt);
-
-		if (inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)
-			printk("%s: abort, mbox %d, interrupt pending.\n",
-			       ha->board_name, i);
-
-		return FAILED;
-	}
-
-	if (ha->cp_stat[i] == IN_RESET) {
-		printk("%s: abort, mbox %d is in reset.\n", ha->board_name, i);
-		return FAILED;
-	}
-
-	if (ha->cp_stat[i] == LOCKED) {
-		printk("%s: abort, mbox %d is locked.\n", ha->board_name, i);
-		return SUCCESS;
-	}
-
-	if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) {
-		unmap_dma(i, ha);
-		SCarg->result = DID_ABORT << 16;
-		SCarg->host_scribble = NULL;
-		ha->cp_stat[i] = FREE;
-		printk("%s, abort, mbox %d ready, DID_ABORT, done.\n",
-		       ha->board_name, i);
-		SCarg->scsi_done(SCarg);
-		return SUCCESS;
-	}
-
-	panic("%s: abort, mbox %d, invalid cp_stat.\n", ha->board_name, i);
-}
-
-static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
-{
-	unsigned int i, time, k, c, limit = 0;
-	struct scsi_cmnd *SCpnt;
-	struct Scsi_Host *shost = SCarg->device->host;
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
-
-	scmd_printk(KERN_INFO, SCarg, "reset, enter.\n");
-
-	spin_lock_irq(shost->host_lock);
-
-	if (SCarg->host_scribble == NULL)
-		printk("%s: reset, inactive.\n", ha->board_name);
-
-	if (ha->in_reset) {
-		printk("%s: reset, exit, already in reset.\n", ha->board_name);
-		spin_unlock_irq(shost->host_lock);
-		return FAILED;
-	}
-
-	if (wait_on_busy(shost->io_port, MAXLOOP)) {
-		printk("%s: reset, exit, timeout error.\n", ha->board_name);
-		spin_unlock_irq(shost->host_lock);
-		return FAILED;
-	}
-
-	ha->retries = 0;
-
-	for (c = 0; c <= shost->max_channel; c++)
-		for (k = 0; k < shost->max_id; k++) {
-			ha->target_redo[k][c] = 1;
-			ha->target_to[k][c] = 0;
-		}
-
-	for (i = 0; i < shost->can_queue; i++) {
-
-		if (ha->cp_stat[i] == FREE)
-			continue;
-
-		if (ha->cp_stat[i] == LOCKED) {
-			ha->cp_stat[i] = FREE;
-			printk("%s: reset, locked mbox %d forced free.\n",
-			       ha->board_name, i);
-			continue;
-		}
-
-		if (!(SCpnt = ha->cp[i].SCpnt))
-			panic("%s: reset, mbox %d, SCpnt == NULL.\n", ha->board_name, i);
-
-		if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) {
-			ha->cp_stat[i] = ABORTING;
-			printk("%s: reset, mbox %d aborting.\n",
-			       ha->board_name, i);
-		}
-
-		else {
-			ha->cp_stat[i] = IN_RESET;
-			printk("%s: reset, mbox %d in reset.\n",
-			       ha->board_name, i);
-		}
-
-		if (SCpnt->host_scribble == NULL)
-			panic("%s: reset, mbox %d, garbled SCpnt.\n", ha->board_name, i);
-
-		if (*(unsigned int *)SCpnt->host_scribble != i)
-			panic("%s: reset, mbox %d, index mismatch.\n", ha->board_name, i);
-
-		if (SCpnt->scsi_done == NULL)
-			panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n",
-			      ha->board_name, i);
-	}
-
-	if (do_dma(shost->io_port, 0, RESET_PIO)) {
-		printk("%s: reset, cannot reset, timeout error.\n", ha->board_name);
-		spin_unlock_irq(shost->host_lock);
-		return FAILED;
-	}
-
-	printk("%s: reset, board reset done, enabling interrupts.\n", ha->board_name);
-
-#if defined(DEBUG_RESET)
-	do_trace = 1;
-#endif
-
-	ha->in_reset = 1;
-
-	spin_unlock_irq(shost->host_lock);
-
-	/* FIXME: use a sleep instead */
-	time = jiffies;
-	while ((jiffies - time) < (10 * HZ) && limit++ < 200000)
-		udelay(100L);
-
-	spin_lock_irq(shost->host_lock);
-
-	printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit);
-
-	for (i = 0; i < shost->can_queue; i++) {
-
-		if (ha->cp_stat[i] == IN_RESET) {
-			SCpnt = ha->cp[i].SCpnt;
-			unmap_dma(i, ha);
-			SCpnt->result = DID_RESET << 16;
-			SCpnt->host_scribble = NULL;
-
-			/* This mailbox is still waiting for its interrupt */
-			ha->cp_stat[i] = LOCKED;
-
-			printk
-			    ("%s, reset, mbox %d locked, DID_RESET, done.\n",
-			     ha->board_name, i);
-		}
-
-		else if (ha->cp_stat[i] == ABORTING) {
-			SCpnt = ha->cp[i].SCpnt;
-			unmap_dma(i, ha);
-			SCpnt->result = DID_RESET << 16;
-			SCpnt->host_scribble = NULL;
-
-			/* This mailbox was never queued to the adapter */
-			ha->cp_stat[i] = FREE;
-
-			printk
-			    ("%s, reset, mbox %d aborting, DID_RESET, done.\n",
-			     ha->board_name, i);
-		}
-
-		else
-			/* Any other mailbox has already been set free by interrupt */
-			continue;
-
-		SCpnt->scsi_done(SCpnt);
-	}
-
-	ha->in_reset = 0;
-	do_trace = 0;
-
-	printk("%s: reset, exit.\n", ha->board_name);
-
-	spin_unlock_irq(shost->host_lock);
-	return SUCCESS;
-}
-
-int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev,
-		      sector_t capacity, int *dkinfo)
-{
-	unsigned int size = capacity;
-
-	if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
-		dkinfo[0] = 255;
-		dkinfo[1] = 63;
-		dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
-	}
-#if defined (DEBUG_GEOMETRY)
-	printk("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
-	       dkinfo[0], dkinfo[1], dkinfo[2]);
-#endif
-
-	return 0;
-}
-
-static void sort(unsigned long sk[], unsigned int da[], unsigned int n,
-		 unsigned int rev)
-{
-	unsigned int i, j, k, y;
-	unsigned long x;
-
-	for (i = 0; i < n - 1; i++) {
-		k = i;
-
-		for (j = k + 1; j < n; j++)
-			if (rev) {
-				if (sk[j] > sk[k])
-					k = j;
-			} else {
-				if (sk[j] < sk[k])
-					k = j;
-			}
-
-		if (k != i) {
-			x = sk[k];
-			sk[k] = sk[i];
-			sk[i] = x;
-			y = da[k];
-			da[k] = da[i];
-			da[i] = y;
-		}
-	}
-
-	return;
-}
-
-static int reorder(struct hostdata *ha, unsigned long cursec,
-		   unsigned int ihdlr, unsigned int il[], unsigned int n_ready)
-{
-	struct scsi_cmnd *SCpnt;
-	struct mscp *cpp;
-	unsigned int k, n;
-	unsigned int rev = 0, s = 1, r = 1;
-	unsigned int input_only = 1, overlap = 0;
-	unsigned long sl[n_ready], pl[n_ready], ll[n_ready];
-	unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0;
-	unsigned long ioseek = 0;
-
-	static unsigned int flushcount = 0, batchcount = 0, sortcount = 0;
-	static unsigned int readycount = 0, ovlcount = 0, inputcount = 0;
-	static unsigned int readysorted = 0, revcount = 0;
-	static unsigned long seeksorted = 0, seeknosort = 0;
-
-	if (link_statistics && !(++flushcount % link_statistics))
-		printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"
-		       " av %ldK as %ldK.\n", flushcount, batchcount,
-		       inputcount, ovlcount, readycount, readysorted, sortcount,
-		       revcount, seeknosort / (readycount + 1),
-		       seeksorted / (readycount + 1));
-
-	if (n_ready <= 1)
-		return 0;
-
-	for (n = 0; n < n_ready; n++) {
-		k = il[n];
-		cpp = &ha->cp[k];
-		SCpnt = cpp->SCpnt;
-
-		if (!cpp->din)
-			input_only = 0;
-
-		if (blk_rq_pos(SCpnt->request) < minsec)
-			minsec = blk_rq_pos(SCpnt->request);
-		if (blk_rq_pos(SCpnt->request) > maxsec)
-			maxsec = blk_rq_pos(SCpnt->request);
-
-		sl[n] = blk_rq_pos(SCpnt->request);
-		ioseek += blk_rq_sectors(SCpnt->request);
-
-		if (!n)
-			continue;
-
-		if (sl[n] < sl[n - 1])
-			s = 0;
-		if (sl[n] > sl[n - 1])
-			r = 0;
-
-		if (link_statistics) {
-			if (sl[n] > sl[n - 1])
-				seek += sl[n] - sl[n - 1];
-			else
-				seek += sl[n - 1] - sl[n];
-		}
-
-	}
-
-	if (link_statistics) {
-		if (cursec > sl[0])
-			seek += cursec - sl[0];
-		else
-			seek += sl[0] - cursec;
-	}
-
-	if (cursec > ((maxsec + minsec) / 2))
-		rev = 1;
-
-	if (ioseek > ((maxsec - minsec) / 2))
-		rev = 0;
-
-	if (!((rev && r) || (!rev && s)))
-		sort(sl, il, n_ready, rev);
-
-	if (!input_only)
-		for (n = 0; n < n_ready; n++) {
-			k = il[n];
-			cpp = &ha->cp[k];
-			SCpnt = cpp->SCpnt;
-			ll[n] = blk_rq_sectors(SCpnt->request);
-			pl[n] = SCpnt->serial_number;
-
-			if (!n)
-				continue;
-
-			if ((sl[n] == sl[n - 1])
-			    || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n]))
-			    || (rev && ((sl[n] + ll[n]) > sl[n - 1])))
-				overlap = 1;
-		}
-
-	if (overlap)
-		sort(pl, il, n_ready, 0);
-
-	if (link_statistics) {
-		if (cursec > sl[0])
-			iseek = cursec - sl[0];
-		else
-			iseek = sl[0] - cursec;
-		batchcount++;
-		readycount += n_ready;
-		seeknosort += seek / 1024;
-		if (input_only)
-			inputcount++;
-		if (overlap) {
-			ovlcount++;
-			seeksorted += iseek / 1024;
-		} else
-			seeksorted += (iseek + maxsec - minsec) / 1024;
-		if (rev && !r) {
-			revcount++;
-			readysorted += n_ready;
-		}
-		if (!rev && !s) {
-			sortcount++;
-			readysorted += n_ready;
-		}
-	}
-#if defined(DEBUG_LINKED_COMMANDS)
-	if (link_statistics && (overlap || !(flushcount % link_statistics)))
-		for (n = 0; n < n_ready; n++) {
-			k = il[n];
-			cpp = &ha->cp[k];
-			SCpnt = cpp->SCpnt;
-			scmd_printk(KERN_INFO, SCpnt,
-			    "%s mb %d fc %d nr %d sec %ld ns %u"
-			     " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
-			     (ihdlr ? "ihdlr" : "qcomm"),
-			     k, flushcount,
-			     n_ready, blk_rq_pos(SCpnt->request),
-			     blk_rq_sectors(SCpnt->request), cursec, YESNO(s),
-			     YESNO(r), YESNO(rev), YESNO(input_only),
-			     YESNO(overlap), cpp->din);
-		}
-#endif
-	return overlap;
-}
-
-static void flush_dev(struct scsi_device *dev, unsigned long cursec,
-		      struct hostdata *ha, unsigned int ihdlr)
-{
-	struct scsi_cmnd *SCpnt;
-	struct mscp *cpp;
-	unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES];
-
-	for (k = 0; k < dev->host->can_queue; k++) {
-
-		if (ha->cp_stat[k] != READY && ha->cp_stat[k] != IN_USE)
-			continue;
-
-		cpp = &ha->cp[k];
-		SCpnt = cpp->SCpnt;
-
-		if (SCpnt->device != dev)
-			continue;
-
-		if (ha->cp_stat[k] == IN_USE)
-			return;
-
-		il[n_ready++] = k;
-	}
-
-	if (reorder(ha, cursec, ihdlr, il, n_ready))
-		n_ready = 1;
-
-	for (n = 0; n < n_ready; n++) {
-		k = il[n];
-		cpp = &ha->cp[k];
-		SCpnt = cpp->SCpnt;
-
-		if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
-			scmd_printk(KERN_INFO, SCpnt,
-			    "%s, mbox %d, adapter"
-			     " busy, will abort.\n",
-			     (ihdlr ? "ihdlr" : "qcomm"),
-			     k);
-			ha->cp_stat[k] = ABORTING;
-			continue;
-		}
-
-		ha->cp_stat[k] = IN_USE;
-	}
-}
-
-static irqreturn_t ihdlr(struct Scsi_Host *shost)
-{
-	struct scsi_cmnd *SCpnt;
-	unsigned int i, k, c, status, tstatus, reg;
-	struct mssp *spp;
-	struct mscp *cpp;
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
-	int irq = shost->irq;
-
-	/* Check if this board need to be serviced */
-	if (!(inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED))
-		goto none;
-
-	ha->iocount++;
-
-	if (do_trace)
-		printk("%s: ihdlr, enter, irq %d, count %d.\n", ha->board_name, irq,
-		       ha->iocount);
-
-	/* Check if this board is still busy */
-	if (wait_on_busy(shost->io_port, 20 * MAXLOOP)) {
-		reg = inb(shost->io_port + REG_STATUS);
-		printk
-		    ("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
-		     ha->board_name, irq, reg, ha->iocount);
-		goto none;
-	}
-
-	spp = &ha->sp;
-
-	/* Make a local copy just before clearing the interrupt indication */
-	memcpy(spp, ha->sp_cpu_addr, sizeof(struct mssp));
-
-	/* Clear the completion flag and cp pointer on the dynamic copy of sp */
-	memset(ha->sp_cpu_addr, 0, sizeof(struct mssp));
-
-	/* Read the status register to clear the interrupt indication */
-	reg = inb(shost->io_port + REG_STATUS);
-
-#if defined (DEBUG_INTERRUPT)
-	{
-		unsigned char *bytesp;
-		int cnt;
-		bytesp = (unsigned char *)spp;
-		if (ha->iocount < 200) {
-			printk("sp[] =");
-			for (cnt = 0; cnt < 15; cnt++)
-				printk(" 0x%x", bytesp[cnt]);
-			printk("\n");
-		}
-	}
-#endif
-
-	/* Reject any sp with supspect data */
-	if (spp->eoc == 0 && ha->iocount > 1)
-		printk
-		    ("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n",
-		     ha->board_name, irq, reg, ha->iocount);
-	if (spp->cpp_index < 0 || spp->cpp_index >= shost->can_queue)
-		printk
-		    ("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
-		     ha->board_name, spp->cpp_index, irq, reg, ha->iocount);
-	if (spp->eoc == 0 || spp->cpp_index < 0
-	    || spp->cpp_index >= shost->can_queue)
-		goto handled;
-
-	/* Find the mailbox to be serviced on this board */
-	i = spp->cpp_index;
-
-	cpp = &(ha->cp[i]);
-
-#if defined(DEBUG_GENERATE_ABORTS)
-	if ((ha->iocount > 500) && ((ha->iocount % 500) < 3))
-		goto handled;
-#endif
-
-	if (ha->cp_stat[i] == IGNORE) {
-		ha->cp_stat[i] = FREE;
-		goto handled;
-	} else if (ha->cp_stat[i] == LOCKED) {
-		ha->cp_stat[i] = FREE;
-		printk("%s: ihdlr, mbox %d unlocked, count %d.\n", ha->board_name, i,
-		       ha->iocount);
-		goto handled;
-	} else if (ha->cp_stat[i] == FREE) {
-		printk("%s: ihdlr, mbox %d is free, count %d.\n", ha->board_name, i,
-		       ha->iocount);
-		goto handled;
-	} else if (ha->cp_stat[i] == IN_RESET)
-		printk("%s: ihdlr, mbox %d is in reset.\n", ha->board_name, i);
-	else if (ha->cp_stat[i] != IN_USE)
-		panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n",
-		      ha->board_name, i, ha->cp_stat[i]);
-
-	ha->cp_stat[i] = FREE;
-	SCpnt = cpp->SCpnt;
-
-	if (SCpnt == NULL)
-		panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", ha->board_name, i);
-
-	if (SCpnt->host_scribble == NULL)
-		panic("%s: ihdlr, mbox %d, SCpnt %p garbled.\n", ha->board_name,
-		      i, SCpnt);
-
-	if (*(unsigned int *)SCpnt->host_scribble != i)
-		panic("%s: ihdlr, mbox %d, index mismatch %d.\n",
-		      ha->board_name, i,
-		      *(unsigned int *)SCpnt->host_scribble);
-
-	sync_dma(i, ha);
-
-	if (linked_comm && SCpnt->device->queue_depth > 2
-	    && TLDEV(SCpnt->device->type))
-		flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 1);
-
-	tstatus = status_byte(spp->target_status);
-
-#if defined(DEBUG_GENERATE_ERRORS)
-	if ((ha->iocount > 500) && ((ha->iocount % 200) < 2))
-		spp->adapter_status = 0x01;
-#endif
-
-	switch (spp->adapter_status) {
-	case ASOK:		/* status OK */
-
-		/* Forces a reset if a disk drive keeps returning BUSY */
-		if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE)
-			status = DID_ERROR << 16;
-
-		/* If there was a bus reset, redo operation on each target */
-		else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
-			 && ha->target_redo[SCpnt->device->id][SCpnt->
-								  device->
-								  channel])
-			status = DID_BUS_BUSY << 16;
-
-		/* Works around a flaw in scsi.c */
-		else if (tstatus == CHECK_CONDITION
-			 && SCpnt->device->type == TYPE_DISK
-			 && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
-			status = DID_BUS_BUSY << 16;
-
-		else
-			status = DID_OK << 16;
-
-		if (tstatus == GOOD)
-			ha->target_redo[SCpnt->device->id][SCpnt->device->
-							      channel] = 0;
-
-		if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
-		    (!(tstatus == CHECK_CONDITION && ha->iocount <= 1000 &&
-		       (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
-			printk("%s: ihdlr, target %d.%d:%d, "
-			       "target_status 0x%x, sense key 0x%x.\n",
-			       ha->board_name,
-			       SCpnt->device->channel, SCpnt->device->id,
-			       (u8)SCpnt->device->lun,
-			       spp->target_status, SCpnt->sense_buffer[2]);
-
-		ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
-
-		if (ha->last_retried_pid == SCpnt->serial_number)
-			ha->retries = 0;
-
-		break;
-	case ASST:		/* Selection Time Out */
-	case 0x02:		/* Command Time Out   */
-
-		if (ha->target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
-			status = DID_ERROR << 16;
-		else {
-			status = DID_TIME_OUT << 16;
-			ha->target_to[SCpnt->device->id][SCpnt->device->
-							    channel]++;
-		}
-
-		break;
-
-		/* Perform a limited number of internal retries */
-	case 0x03:		/* SCSI Bus Reset Received */
-	case 0x04:		/* Initial Controller Power-up */
-
-		for (c = 0; c <= shost->max_channel; c++)
-			for (k = 0; k < shost->max_id; k++)
-				ha->target_redo[k][c] = 1;
-
-		if (SCpnt->device->type != TYPE_TAPE
-		    && ha->retries < MAX_INTERNAL_RETRIES) {
-
-#if defined(DID_SOFT_ERROR)
-			status = DID_SOFT_ERROR << 16;
-#else
-			status = DID_BUS_BUSY << 16;
-#endif
-
-			ha->retries++;
-			ha->last_retried_pid = SCpnt->serial_number;
-		} else
-			status = DID_ERROR << 16;
-
-		break;
-	case 0x05:		/* Unexpected Bus Phase */
-	case 0x06:		/* Unexpected Bus Free */
-	case 0x07:		/* Bus Parity Error */
-	case 0x08:		/* SCSI Hung */
-	case 0x09:		/* Unexpected Message Reject */
-	case 0x0a:		/* SCSI Bus Reset Stuck */
-	case 0x0b:		/* Auto Request-Sense Failed */
-	case 0x0c:		/* Controller Ram Parity Error */
-	default:
-		status = DID_ERROR << 16;
-		break;
-	}
-
-	SCpnt->result = status | spp->target_status;
-
-#if defined(DEBUG_INTERRUPT)
-	if (SCpnt->result || do_trace)
-#else
-	if ((spp->adapter_status != ASOK && ha->iocount > 1000) ||
-	    (spp->adapter_status != ASOK &&
-	     spp->adapter_status != ASST && ha->iocount <= 1000) ||
-	    do_trace || msg_byte(spp->target_status))
-#endif
-		scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"
-		       " reg 0x%x, count %d.\n",
-		       i, spp->adapter_status, spp->target_status,
-		       reg, ha->iocount);
-
-	unmap_dma(i, ha);
-
-	/* Set the command state to inactive */
-	SCpnt->host_scribble = NULL;
-
-	SCpnt->scsi_done(SCpnt);
-
-	if (do_trace)
-		printk("%s: ihdlr, exit, irq %d, count %d.\n", ha->board_name,
-				irq, ha->iocount);
-
-      handled:
-	return IRQ_HANDLED;
-      none:
-	return IRQ_NONE;
-}
-
-static irqreturn_t do_interrupt_handler(int dummy, void *shap)
-{
-	struct Scsi_Host *shost;
-	unsigned int j;
-	unsigned long spin_flags;
-	irqreturn_t ret;
-
-	/* Check if the interrupt must be processed by this handler */
-	if ((j = (unsigned int)((char *)shap - sha)) >= num_boards)
-		return IRQ_NONE;
-	shost = sh[j];
-
-	spin_lock_irqsave(shost->host_lock, spin_flags);
-	ret = ihdlr(shost);
-	spin_unlock_irqrestore(shost->host_lock, spin_flags);
-	return ret;
-}
-
-static int eata2x_release(struct Scsi_Host *shost)
-{
-	struct hostdata *ha = (struct hostdata *)shost->hostdata;
-	unsigned int i;
-
-	for (i = 0; i < shost->can_queue; i++)
-		kfree((&ha->cp[i])->sglist);
-
-	for (i = 0; i < shost->can_queue; i++)
-		pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr,
-				 sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
-
-	if (ha->sp_cpu_addr)
-		pci_free_consistent(ha->pdev, sizeof(struct mssp),
-				    ha->sp_cpu_addr, ha->sp_dma_addr);
-
-	free_irq(shost->irq, &sha[ha->board_number]);
-
-	if (shost->dma_channel != NO_DMA)
-		free_dma(shost->dma_channel);
-
-	release_region(shost->io_port, shost->n_io_port);
-	scsi_unregister(shost);
-	return 0;
-}
-
-#include "scsi_module.c"
-
-#ifndef MODULE
-__setup("eata=", option_setup);
-#endif				/* end MODULE */
diff --git a/drivers/scsi/eata_generic.h b/drivers/scsi/eata_generic.h
deleted file mode 100644
index 1a396c5..0000000
--- a/drivers/scsi/eata_generic.h
+++ /dev/null
@@ -1,401 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/********************************************************
-* Header file for eata_dma.c and eata_pio.c		*
-* Linux EATA SCSI drivers				*
-* (c) 1993-96 Michael Neuffer                           *
-*             mike@i-Connect.Net                        *
-*             neuffer@mail.uni-mainz.de                 *
-*********************************************************
-* last change: 96/08/14                                 *
-********************************************************/
-
-
-#ifndef _EATA_GENERIC_H
-#define _EATA_GENERIC_H
-
-
-
-/*********************************************
- * Misc. definitions			     *
- *********************************************/
-
-#define R_LIMIT 0x20000
-
-#define MAXISA	   4
-#define MAXEISA	  16  
-#define MAXPCI	  16
-#define MAXIRQ	  16 
-#define MAXTARGET 16
-#define MAXCHANNEL 3
-
-#define IS_ISA	   'I'
-#define IS_EISA	   'E'
-#define IS_PCI	   'P'
-
-#define BROKEN_INQUIRY	1
-
-#define BUSMASTER       0xff
-#define PIO             0xfe
-
-#define EATA_SIGNATURE	0x45415441     /* BIG ENDIAN coded "EATA" sig.	 */
-
-#define DPT_ID1         0x12
-#define DPT_ID2         0x14
-
-#define ATT_ID1         0x06
-#define ATT_ID2         0x94
-#define ATT_ID3         0x0
-
-#define NEC_ID1         0x38
-#define NEC_ID2         0xa3
-#define NEC_ID3         0x82
-
- 
-#define EATA_CP_SIZE	 44
-
-#define MAX_PCI_DEVICES  32	       /* Maximum # Of Devices Per Bus	 */
-#define MAX_METHOD_2	 16	       /* Max Devices For Method 2	 */
-#define MAX_PCI_BUS	 16	       /* Maximum # Of Busses Allowed	 */
-
-#define SG_SIZE		 64 
-#define SG_SIZE_BIG	 252	       /* max. 8096 elements, 64k */
-
-#define UPPER_DEVICE_QUEUE_LIMIT 64    /* The limit we have to set for the 
-					* device queue to keep the broken 
-					* midlevel SCSI code from producing
-					* bogus timeouts
-					*/
-
-#define TYPE_DISK_QUEUE  16
-#define TYPE_TAPE_QUEUE  4
-#define TYPE_ROM_QUEUE   4
-#define TYPE_OTHER_QUEUE 2
-
-#define FREE	         0
-#define OK	         0
-#define NO_TIMEOUT       0
-#define USED	         1
-#define TIMEOUT	         2
-#define RESET	         4
-#define LOCKED	         8
-#define ABORTED          16
-
-#define READ             0
-#define WRITE            1
-#define OTHER            2
-
-#define HD(cmd)	 ((hostdata *)&(cmd->device->host->hostdata))
-#define CD(cmd)	 ((struct eata_ccb *)(cmd->host_scribble))
-#define SD(host) ((hostdata *)&(host->hostdata))
-
-/***********************************************
- *    EATA Command & Register definitions      *
- ***********************************************/
-#define PCI_REG_DPTconfig	 0x40	 
-#define PCI_REG_PumpModeAddress	 0x44	 
-#define PCI_REG_PumpModeData	 0x48	 
-#define PCI_REG_ConfigParam1	 0x50	 
-#define PCI_REG_ConfigParam2	 0x54	 
-
-
-#define EATA_CMD_PIO_SETUPTEST	 0xc6
-#define EATA_CMD_PIO_READ_CONFIG 0xf0
-#define EATA_CMD_PIO_SET_CONFIG	 0xf1
-#define EATA_CMD_PIO_SEND_CP	 0xf2
-#define EATA_CMD_PIO_RECEIVE_SP	 0xf3
-#define EATA_CMD_PIO_TRUNC	 0xf4
-
-#define EATA_CMD_RESET		 0xf9
-#define EATA_CMD_IMMEDIATE	 0xfa
-
-#define EATA_CMD_DMA_READ_CONFIG 0xfd
-#define EATA_CMD_DMA_SET_CONFIG	 0xfe
-#define EATA_CMD_DMA_SEND_CP	 0xff
-
-#define ECS_EMULATE_SENSE	 0xd4
-
-#define EATA_GENERIC_ABORT       0x00 
-#define EATA_SPECIFIC_RESET      0x01
-#define EATA_BUS_RESET           0x02
-#define EATA_SPECIFIC_ABORT      0x03
-#define EATA_QUIET_INTR          0x04
-#define EATA_COLD_BOOT_HBA       0x06	   /* Only as a last resort	*/
-#define EATA_FORCE_IO            0x07
-
-#define HA_CTRLREG     0x206       /* control register for HBA    */
-#define HA_CTRL_DISINT 0x02        /* CTRLREG: disable interrupts */
-#define HA_CTRL_RESCPU 0x04        /* CTRLREG: reset processor    */
-#define HA_CTRL_8HEADS 0x08        /* CTRLREG: set for drives with* 
-				    * >=8 heads (WD1003 rudimentary :-) */
-
-#define HA_WCOMMAND    0x07	   /* command register offset	*/
-#define HA_WIFC        0x06	   /* immediate command offset  */
-#define HA_WCODE       0x05 
-#define HA_WCODE2      0x04 
-#define HA_WDMAADDR    0x02	   /* DMA address LSB offset	*/  
-#define HA_RAUXSTAT    0x08	   /* aux status register offset*/
-#define HA_RSTATUS     0x07	   /* status register offset	*/
-#define HA_RDATA       0x00	   /* data register (16bit)	*/
-#define HA_WDATA       0x00	   /* data register (16bit)	*/
-
-#define HA_ABUSY       0x01	   /* aux busy bit		*/
-#define HA_AIRQ	       0x02	   /* aux IRQ pending bit	*/
-#define HA_SERROR      0x01	   /* pr. command ended in error*/
-#define HA_SMORE       0x02	   /* more data soon to come	*/
-#define HA_SCORR       0x04	   /* data corrected		*/
-#define HA_SDRQ	       0x08	   /* data request active	*/
-#define HA_SSC	       0x10	   /* seek complete		*/
-#define HA_SFAULT      0x20	   /* write fault		*/
-#define HA_SREADY      0x40	   /* drive ready		*/
-#define HA_SBUSY       0x80	   /* drive busy		*/
-#define HA_SDRDY       HA_SSC+HA_SREADY+HA_SDRQ 
-
-/**********************************************
- * Message definitions			      *
- **********************************************/
-
-#define HA_NO_ERROR	 0x00	/* No Error				*/
-#define HA_ERR_SEL_TO	 0x01	/* Selection Timeout			*/
-#define HA_ERR_CMD_TO	 0x02	/* Command Timeout			*/
-#define HA_BUS_RESET	 0x03	/* SCSI Bus Reset Received		*/
-#define HA_INIT_POWERUP	 0x04	/* Initial Controller Power-up		*/
-#define HA_UNX_BUSPHASE	 0x05	/* Unexpected Bus Phase			*/
-#define HA_UNX_BUS_FREE	 0x06	/* Unexpected Bus Free			*/
-#define HA_BUS_PARITY	 0x07	/* Bus Parity Error			*/
-#define HA_SCSI_HUNG	 0x08	/* SCSI Hung				*/
-#define HA_UNX_MSGRJCT	 0x09	/* Unexpected Message Rejected		*/
-#define HA_RESET_STUCK	 0x0a	/* SCSI Bus Reset Stuck			*/
-#define HA_RSENSE_FAIL	 0x0b	/* Auto Request-Sense Failed		*/
-#define HA_PARITY_ERR	 0x0c	/* Controller Ram Parity Error		*/
-#define HA_CP_ABORT_NA	 0x0d	/* Abort Message sent to non-active cmd */
-#define HA_CP_ABORTED	 0x0e	/* Abort Message sent to active cmd	*/
-#define HA_CP_RESET_NA	 0x0f	/* Reset Message sent to non-active cmd */
-#define HA_CP_RESET	 0x10	/* Reset Message sent to active cmd	*/
-#define HA_ECC_ERR	 0x11	/* Controller Ram ECC Error		*/
-#define HA_PCI_PARITY	 0x12	/* PCI Parity Error			*/
-#define HA_PCI_MABORT	 0x13	/* PCI Master Abort			*/
-#define HA_PCI_TABORT	 0x14	/* PCI Target Abort			*/
-#define HA_PCI_STABORT	 0x15	/* PCI Signaled Target Abort		*/
-
-/**********************************************
- *  Other  definitions			      *
- **********************************************/
-
-struct reg_bit {      /* reading this one will clear the interrupt    */
-    __u8 error:1;     /* previous command ended in an error	      */
-    __u8 more:1;      /* more DATA coming soon, poll BSY & DRQ (PIO)  */
-    __u8 corr:1;      /* data read was successfully corrected with ECC*/
-    __u8 drq:1;	      /* data request active  */     
-    __u8 sc:1;	      /* seek complete	      */
-    __u8 fault:1;     /* write fault	      */
-    __u8 ready:1;     /* drive ready	      */
-    __u8 busy:1;      /* controller busy      */
-};
-
-struct reg_abit {     /* reading this won't clear the interrupt */
-    __u8 abusy:1;     /* auxiliary busy				*/
-    __u8 irq:1;	      /* set when drive interrupt is asserted	*/
-    __u8 dummy:6;
-};
-
-struct eata_register {	    /* EATA register set */
-    __u8 data_reg[2];	    /* R, couldn't figure this one out		*/
-    __u8 cp_addr[4];	    /* W, CP address register			*/
-    union { 
-	__u8 command;	    /* W, command code: [read|set] conf, send CP*/
-	struct reg_bit status;	/* R, see register_bit1			*/
-	__u8 statusbyte;
-    } ovr;   
-    struct reg_abit aux_stat; /* R, see register_bit2			*/
-};
-
-struct get_conf {	      /* Read Configuration Array		*/
-    __u32  len;		      /* Should return 0x22, 0x24, etc		*/
-    __u32 signature;	      /* Signature MUST be "EATA"		*/
-    __u8    version2:4,
-	     version:4;	      /* EATA Version level			*/
-    __u8 OCS_enabled:1,	      /* Overlap Command Support enabled	*/
-	 TAR_support:1,	      /* SCSI Target Mode supported		*/
-	      TRNXFR:1,	      /* Truncate Transfer Cmd not necessary	*
-			       * Only used in PIO Mode			*/
-	MORE_support:1,	      /* MORE supported (only PIO Mode)		*/
-	 DMA_support:1,	      /* DMA supported Driver uses only		*
-			       * this mode				*/
-	   DMA_valid:1,	      /* DRQ value in Byte 30 is valid		*/
-		 ATA:1,	      /* ATA device connected (not supported)	*/
-	   HAA_valid:1;	      /* Hostadapter Address is valid		*/
-
-    __u16 cppadlen;	      /* Number of pad bytes send after CD data *
-			       * set to zero for DMA commands		*/
-    __u8 scsi_id[4];	      /* SCSI ID of controller 2-0 Byte 0 res.	*
-			       * if not, zero is returned		*/
-    __u32  cplen;	      /* CP length: number of valid cp bytes	*/
-    __u32  splen;	      /* Number of bytes returned after		* 
-			       * Receive SP command			*/
-    __u16 queuesiz;	      /* max number of queueable CPs		*/
-    __u16 dummy;
-    __u16 SGsiz;	      /* max number of SG table entries		*/
-    __u8    IRQ:4,	      /* IRQ used this HA			*/
-	 IRQ_TR:1,	      /* IRQ Trigger: 0=edge, 1=level		*/
-	 SECOND:1,	      /* This is a secondary controller		*/
-    DMA_channel:2;	      /* DRQ index, DRQ is 2comp of DRQX	*/
-    __u8 sync;		      /* device at ID 7 tru 0 is running in	*
-			       * synchronous mode, this will disappear	*/
-    __u8   DSBLE:1,	      /* ISA i/o addressing is disabled		*/
-	 FORCADR:1,	      /* i/o address has been forced		*/
-	  SG_64K:1,
-	  SG_UAE:1,
-		:4;
-    __u8  MAX_ID:5,	      /* Max number of SCSI target IDs		*/
-	MAX_CHAN:3;	      /* Number of SCSI busses on HBA		*/
-    __u8 MAX_LUN;	      /* Max number of LUNs			*/
-    __u8	:3,
-	 AUTOTRM:1,
-	 M1_inst:1,
-	 ID_qest:1,	      /* Raidnum ID is questionable		*/
-	  is_PCI:1,	      /* HBA is PCI				*/
-	 is_EISA:1;	      /* HBA is EISA				*/
-    __u8 RAIDNUM;             /* unique HBA identifier                  */
-    __u8 unused[474]; 
-};
-
-struct eata_sg_list
-{
-    __u32 data;
-    __u32 len;
-};
-
-struct eata_ccb {	      /* Send Command Packet structure	    */
- 
-    __u8 SCSI_Reset:1,	      /* Cause a SCSI Bus reset on the cmd	*/
-	   HBA_Init:1,	      /* Cause Controller to reinitialize	*/
-       Auto_Req_Sen:1,	      /* Do Auto Request Sense on errors	*/
-	    scatter:1,	      /* Data Ptr points to a SG Packet		*/
-	     Resrvd:1,	      /* RFU					*/
-	  Interpret:1,	      /* Interpret the SCSI cdb of own use	*/
-	    DataOut:1,	      /* Data Out phase with command		*/
-	     DataIn:1;	      /* Data In phase with command		*/
-    __u8 reqlen;	      /* Request Sense Length			* 
-			       * Valid if Auto_Req_Sen=1		*/
-    __u8 unused[3];
-    __u8  FWNEST:1,	      /* send cmd to phys RAID component	*/
-	 unused2:7;
-    __u8 Phsunit:1,	      /* physical unit on mirrored pair		*/
-	    I_AT:1,	      /* inhibit address translation		*/
-	 I_HBA_C:1,	      /* HBA inhibit caching			*/
-	 unused3:5;
-
-    __u8     cp_id:5,	      /* SCSI Device ID of target		*/ 
-	cp_channel:3;	      /* SCSI Channel # of HBA			*/
-    __u8    cp_lun:3,
-		  :2,
-	 cp_luntar:1,	      /* CP is for target ROUTINE		*/
-	 cp_dispri:1,	      /* Grant disconnect privilege		*/
-       cp_identify:1;	      /* Always TRUE				*/
-    __u8 cp_msg1;	      /* Message bytes 0-3			*/
-    __u8 cp_msg2;
-    __u8 cp_msg3;
-    __u8 cp_cdb[12];	      /* Command Descriptor Block		*/
-    __u32 cp_datalen;	      /* Data Transfer Length			*
-			       * If scatter=1 len of sg package		*/
-    void *cp_viraddr;	      /* address of this ccb			*/
-    __u32 cp_dataDMA;	      /* Data Address, if scatter=1		*
-			       * address of scatter packet		*/
-    __u32 cp_statDMA;	      /* address for Status Packet		*/ 
-    __u32 cp_reqDMA;	      /* Request Sense Address, used if		*
-			       * CP command ends with error		*/
-    /* Additional CP info begins here */
-    __u32 timestamp;	      /* Needed to measure command latency	*/
-    __u32 timeout;
-    __u8 sizeindex;
-    __u8 rw_latency;
-    __u8 retries;
-    __u8 status;	      /* status of this queueslot		*/
-    struct scsi_cmnd *cmd;    /* address of cmd				*/
-    struct eata_sg_list *sg_list;
-};
-
-
-struct eata_sp {
-    __u8 hba_stat:7,	      /* HBA status				*/
-	      EOC:1;	      /* True if command finished		*/
-    __u8 scsi_stat;	      /* Target SCSI status			*/
-    __u8 reserved[2];
-    __u32  residue_len;	      /* Number of bytes not transferred	*/
-    struct eata_ccb *ccb;     /* Address set in COMMAND PACKET		*/
-    __u8 msg[12];
-};
-
-typedef struct hstd {
-    __u8   vendor[9];
-    __u8   name[18];
-    __u8   revision[6];
-    __u8   EATA_revision;
-    __u32  firmware_revision;
-    __u8   HBA_number;
-    __u8   bustype;		 /* bustype of HBA	       */
-    __u8   channel;		 /* # of avail. scsi channels  */
-    __u8   state;		 /* state of HBA	       */
-    __u8   primary;		 /* true if primary	       */
-    __u8        more_support:1,  /* HBA supports MORE flag     */
-           immediate_support:1,  /* HBA supports IMMEDIATE CMDs*/
-              broken_INQUIRY:1;	 /* This is an EISA HBA with   *
-				  * broken INQUIRY	       */
-    __u8   do_latency;		 /* Latency measurement flag   */
-    __u32  reads[13];
-    __u32  writes[13];
-    __u32  reads_lat[12][4];
-    __u32  writes_lat[12][4];
-    __u32  all_lat[4];
-    __u8   resetlevel[MAXCHANNEL]; 
-    __u32  last_ccb;		 /* Last used ccb	       */
-    __u32  cplen;		 /* size of CP in words	       */
-    __u16  cppadlen;		 /* pad length of cp in words  */
-    __u16  queuesize;
-    __u16  sgsize;               /* # of entries in the SG list*/
-    __u16  devflags;		 /* bits set for detected devices */
-    __u8   hostid;		 /* SCSI ID of HBA	       */
-    __u8   moresupport;		 /* HBA supports MORE flag     */
-    struct Scsi_Host *next;	    
-    struct Scsi_Host *prev;
-    struct pci_dev *pdev;	/* PCI device or NULL for non PCI */
-    struct eata_sp sp;		 /* status packet	       */ 
-    struct eata_ccb ccb[0];	 /* ccb array begins here      */
-}hostdata;
-
-/* structure for max. 2 emulated drives */
-struct drive_geom_emul {
-    __u8  trans;		 /* translation flag 1=transl */
-    __u8  channel;		 /* SCSI channel number	      */
-    __u8  HBA;			 /* HBA number (prim/sec)     */
-    __u8  id;			 /* drive id		      */
-    __u8  lun;			 /* drive lun		      */
-    __u32 heads;		 /* number of heads	      */
-    __u32 sectors;		 /* number of sectors	      */
-    __u32 cylinder;		 /* number of cylinders	      */
-};
-
-struct geom_emul {
-    __u8 bios_drives;		 /* number of emulated drives */
-    struct drive_geom_emul drv[2]; /* drive structures	      */
-};
-
-#endif /* _EATA_GENERIC_H */
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * tab-width: 8
- * End:
- */
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
deleted file mode 100644
index 4299fa4..0000000
--- a/drivers/scsi/eata_pio.c
+++ /dev/null
@@ -1,966 +0,0 @@
-/************************************************************
- *                                                          *
- *               Linux EATA SCSI PIO driver                 *
- *                                                          *
- *  based on the CAM document CAM/89-004 rev. 2.0c,         *
- *  DPT's driver kit, some internal documents and source,   *
- *  and several other Linux scsi drivers and kernel docs.   *
- *                                                          *
- *  The driver currently:                                   *
- *      -supports all EATA-PIO boards                       *
- *      -only supports DASD devices                         *
- *                                                          *
- *  (c)1993-96 Michael Neuffer, Alfred Arnold               *
- *             neuffer@goofy.zdv.uni-mainz.de               *
- *             a.arnold@kfa-juelich.de                      * 
- *                                                          *
- *  Updated 2002 by Alan Cox <alan@lxorguk.ukuu.org.uk> for *
- *   Linux 2.5.x and the newer locking and error handling   *
- *                                                          *
- *  This program is free software; you can redistribute 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 kernel; if not, write to *
- *  the Free Software Foundation, Inc., 675 Mass Ave,       *
- *  Cambridge, MA 02139, USA.                               *
- *							    *
- *  For the avoidance of doubt the "preferred form" of this *
- *  code is one which is in an open non patent encumbered   *
- *  format. Where cryptographic key signing forms part of   *
- *  the process of creating an executable the information   *
- *  including keys needed to generate an equivalently       *
- *  functional executable are deemed to be part of the 	    *
- *  source code are deemed to be part of the source code.   *
- *                                                          *
- ************************************************************
- *  last change: 2002/11/02               OS: Linux 2.5.45  *
- ************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-
-#include "eata_generic.h"
-#include "eata_pio.h"
-
-
-static unsigned int ISAbases[MAXISA] =	{
-	 0x1F0, 0x170, 0x330, 0x230
-};
-
-static unsigned int ISAirqs[MAXISA] = {
-	14, 12, 15, 11
-};
-
-static unsigned char EISAbases[] = { 
-	1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 1, 1, 1, 1 
-};
-
-static unsigned int registered_HBAs;
-static struct Scsi_Host *last_HBA;
-static struct Scsi_Host *first_HBA;
-static unsigned char reg_IRQ[16];
-static unsigned char reg_IRQL[16];
-static unsigned long int_counter;
-static unsigned long queue_counter;
-
-static struct scsi_host_template driver_template;
-
-static int eata_pio_show_info(struct seq_file *m, struct Scsi_Host *shost)
-{
-	seq_printf(m, "EATA (Extended Attachment) PIO driver version: "
-		   "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB);
-	seq_printf(m, "queued commands:     %10ld\n"
-		   "processed interrupts:%10ld\n", queue_counter, int_counter);
-	seq_printf(m, "\nscsi%-2d: HBA %.10s\n",
-		   shost->host_no, SD(shost)->name);
-	seq_printf(m, "Firmware revision: v%s\n",
-		   SD(shost)->revision);
-	seq_puts(m, "IO: PIO\n");
-	seq_printf(m, "Base IO : %#.4x\n", (u32) shost->base);
-	seq_printf(m, "Host Bus: %s\n",
-		   (SD(shost)->bustype == 'P')?"PCI ":
-		   (SD(shost)->bustype == 'E')?"EISA":"ISA ");
-	return 0;
-}
-
-static int eata_pio_release(struct Scsi_Host *sh)
-{
-	hostdata *hd = SD(sh);
-	if (sh->irq && reg_IRQ[sh->irq] == 1)
-		free_irq(sh->irq, NULL);
-	else
-		reg_IRQ[sh->irq]--;
-	if (SD(sh)->channel == 0) {
-		if (sh->io_port && sh->n_io_port)
-			release_region(sh->io_port, sh->n_io_port);
-	}
-	/* At this point the PCI reference can go */
-	if (hd->pdev)
-		pci_dev_put(hd->pdev);
-	return 1;
-}
-
-static void IncStat(struct scsi_pointer *SCp, unsigned int Increment)
-{
-	SCp->ptr += Increment;
-	if ((SCp->this_residual -= Increment) == 0) {
-		if ((--SCp->buffers_residual) == 0)
-			SCp->Status = 0;
-		else {
-			SCp->buffer++;
-			SCp->ptr = sg_virt(SCp->buffer);
-			SCp->this_residual = SCp->buffer->length;
-		}
-	}
-}
-
-static irqreturn_t eata_pio_int_handler(int irq, void *dev_id);
-
-static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id)
-{
-	unsigned long flags;
-	struct Scsi_Host *dev = dev_id;
-	irqreturn_t ret;
-
-	spin_lock_irqsave(dev->host_lock, flags);
-	ret = eata_pio_int_handler(irq, dev_id);
-	spin_unlock_irqrestore(dev->host_lock, flags);
-	return ret;
-}
-
-static irqreturn_t eata_pio_int_handler(int irq, void *dev_id)
-{
-	unsigned int eata_stat = 0xfffff;
-	struct scsi_cmnd *cmd;
-	hostdata *hd;
-	struct eata_ccb *cp;
-	unsigned long base;
-	unsigned int x, z;
-	struct Scsi_Host *sh;
-	unsigned short zwickel = 0;
-	unsigned char stat, odd;
-	irqreturn_t ret = IRQ_NONE;
-
-	for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) 
-	{
-		if (sh->irq != irq)
-			continue;
-		if (inb(sh->base + HA_RSTATUS) & HA_SBUSY)
-			continue;
-
-		int_counter++;
-		ret = IRQ_HANDLED;
-
-		hd = SD(sh);
-
-		cp = &hd->ccb[0];
-		cmd = cp->cmd;
-		base = cmd->device->host->base;
-
-		do {
-			stat = inb(base + HA_RSTATUS);
-			if (stat & HA_SDRQ) {
-				if (cp->DataIn) {
-					z = 256;
-					odd = 0;
-					while ((cmd->SCp.Status) && ((z > 0) || (odd))) {
-						if (odd) {
-							*(cmd->SCp.ptr) = zwickel >> 8;
-							IncStat(&cmd->SCp, 1);
-							odd = 0;
-						}
-						x = min_t(unsigned int, z, cmd->SCp.this_residual / 2);
-						insw(base + HA_RDATA, cmd->SCp.ptr, x);
-						z -= x;
-						IncStat(&cmd->SCp, 2 * x);
-						if ((z > 0) && (cmd->SCp.this_residual == 1)) {
-							zwickel = inw(base + HA_RDATA);
-							*(cmd->SCp.ptr) = zwickel & 0xff;
-							IncStat(&cmd->SCp, 1);
-							z--;
-							odd = 1;
-						}
-					}
-					while (z > 0) {
-						zwickel = inw(base + HA_RDATA);
-						z--;
-					}
-				} else {	/* cp->DataOut */
-
-					odd = 0;
-					z = 256;
-					while ((cmd->SCp.Status) && ((z > 0) || (odd))) {
-						if (odd) {
-							zwickel += *(cmd->SCp.ptr) << 8;
-							IncStat(&cmd->SCp, 1);
-							outw(zwickel, base + HA_RDATA);
-							z--;
-							odd = 0;
-						}
-						x = min_t(unsigned int, z, cmd->SCp.this_residual / 2);
-						outsw(base + HA_RDATA, cmd->SCp.ptr, x);
-						z -= x;
-						IncStat(&cmd->SCp, 2 * x);
-						if ((z > 0) && (cmd->SCp.this_residual == 1)) {
-							zwickel = *(cmd->SCp.ptr);
-							zwickel &= 0xff;
-							IncStat(&cmd->SCp, 1);
-							odd = 1;
-						}
-					}
-					while (z > 0 || odd) {
-						outw(zwickel, base + HA_RDATA);
-						z--;
-						odd = 0;
-					}
-				}
-			}
-		}
-		while ((stat & HA_SDRQ) || ((stat & HA_SMORE) && hd->moresupport));
-
-		/* terminate handler if HBA goes busy again, i.e. transfers
-		 * more data */
-
-		if (stat & HA_SBUSY)
-			break;
-
-		/* OK, this is quite stupid, but I haven't found any correct
-		 * way to get HBA&SCSI status so far */
-
-		if (!(inb(base + HA_RSTATUS) & HA_SERROR)) {
-			cmd->result = (DID_OK << 16);
-			hd->devflags |= (1 << cp->cp_id);
-		} else if (hd->devflags & (1 << cp->cp_id))
-			cmd->result = (DID_OK << 16) + 0x02;
-		else
-			cmd->result = (DID_NO_CONNECT << 16);
-
-		if (cp->status == LOCKED) {
-			cp->status = FREE;
-			eata_stat = inb(base + HA_RSTATUS);
-			printk(KERN_CRIT "eata_pio: int_handler, freeing locked " "queueslot\n");
-			return ret;
-		}
-#if DBG_INTR2
-		if (stat != 0x50)
-			printk(KERN_DEBUG "stat: %#.2x, result: %#.8x\n", stat, cmd->result);
-#endif
-
-		cp->status = FREE;	/* now we can release the slot  */
-
-		cmd->scsi_done(cmd);
-	}
-
-	return ret;
-}
-
-static inline unsigned int eata_pio_send_command(unsigned long base, unsigned char command)
-{
-	unsigned int loop = 50;
-
-	while (inb(base + HA_RSTATUS) & HA_SBUSY)
-		if (--loop == 0)
-			return 1;
-
-	/* Enable interrupts for HBA.  It is not the best way to do it at this
-	 * place, but I hope that it doesn't interfere with the IDE driver 
-	 * initialization this way */
-
-	outb(HA_CTRL_8HEADS, base + HA_CTRLREG);
-
-	outb(command, base + HA_WCOMMAND);
-	return 0;
-}
-
-static int eata_pio_queue_lck(struct scsi_cmnd *cmd,
-		void (*done)(struct scsi_cmnd *))
-{
-	unsigned int x, y;
-	unsigned long base;
-
-	hostdata *hd;
-	struct Scsi_Host *sh;
-	struct eata_ccb *cp;
-
-	queue_counter++;
-
-	hd = HD(cmd);
-	sh = cmd->device->host;
-	base = sh->base;
-
-	/* use only slot 0, as 2001 can handle only one cmd at a time */
-
-	y = x = 0;
-
-	if (hd->ccb[y].status != FREE) {
-
-		DBG(DBG_QUEUE, printk(KERN_EMERG "can_queue %d, x %d, y %d\n", sh->can_queue, x, y));
-#if DEBUG_EATA
-		panic(KERN_EMERG "eata_pio: run out of queue slots cmdno:%ld " "intrno: %ld\n", queue_counter, int_counter);
-#else
-		panic(KERN_EMERG "eata_pio: run out of queue slots....\n");
-#endif
-	}
-
-	cp = &hd->ccb[y];
-
-	memset(cp, 0, sizeof(struct eata_ccb));
-
-	cp->status = USED;	/* claim free slot */
-
-	DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd,
-		"eata_pio_queue 0x%p, y %d\n", cmd, y));
-
-	cmd->scsi_done = (void *) done;
-
-	if (cmd->sc_data_direction == DMA_TO_DEVICE)
-		cp->DataOut = 1;	/* Output mode */
-	else
-		cp->DataIn = 0;	/* Input mode  */
-
-	cp->Interpret = (cmd->device->id == hd->hostid);
-	cp->cp_datalen = cpu_to_be32(scsi_bufflen(cmd));
-	cp->Auto_Req_Sen = 0;
-	cp->cp_reqDMA = 0;
-	cp->reqlen = 0;
-
-	cp->cp_id = cmd->device->id;
-	cp->cp_lun = cmd->device->lun;
-	cp->cp_dispri = 0;
-	cp->cp_identify = 1;
-	memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
-
-	cp->cp_statDMA = 0;
-
-	cp->cp_viraddr = cp;
-	cp->cmd = cmd;
-	cmd->host_scribble = (char *) &hd->ccb[y];
-
-	if (!scsi_bufflen(cmd)) {
-		cmd->SCp.buffers_residual = 1;
-		cmd->SCp.ptr = NULL;
-		cmd->SCp.this_residual = 0;
-		cmd->SCp.buffer = NULL;
-	} else {
-		cmd->SCp.buffer = scsi_sglist(cmd);
-		cmd->SCp.buffers_residual = scsi_sg_count(cmd);
-		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-		cmd->SCp.this_residual = cmd->SCp.buffer->length;
-	}
-	cmd->SCp.Status = (cmd->SCp.this_residual != 0);	/* TRUE as long as bytes 
-								 * are to transfer */
-
-	if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) {
-		cmd->result = DID_BUS_BUSY << 16;
-		scmd_printk(KERN_NOTICE, cmd,
-			"eata_pio_queue pid 0x%p, HBA busy, "
-			"returning DID_BUS_BUSY, done.\n", cmd);
-		done(cmd);
-		cp->status = FREE;
-		return 0;
-	}
-	/* FIXME: timeout */
-	while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
-		cpu_relax();
-	outsw(base + HA_RDATA, cp, hd->cplen);
-	outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
-	for (x = 0; x < hd->cppadlen; x++)
-		outw(0, base + HA_RDATA);
-
-	DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd,
-		"Queued base %#.4lx cmd: 0x%p "
-		"slot %d irq %d\n", sh->base, cmd, y, sh->irq));
-
-	return 0;
-}
-
-static DEF_SCSI_QCMD(eata_pio_queue)
-
-static int eata_pio_abort(struct scsi_cmnd *cmd)
-{
-	unsigned int loop = 100;
-
-	DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
-		"eata_pio_abort called pid: 0x%p\n", cmd));
-
-	while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY)
-		if (--loop == 0) {
-			printk(KERN_WARNING "eata_pio: abort, timeout error.\n");
-			return FAILED;
-		}
-	if (CD(cmd)->status == FREE) {
-		DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_NOT_RUNNING\n"));
-		return FAILED;
-	}
-	if (CD(cmd)->status == USED) {
-		DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_BUSY\n"));
-		/* We want to sleep a bit more here */
-		return FAILED;		/* SNOOZE */
-	}
-	if (CD(cmd)->status == RESET) {
-		printk(KERN_WARNING "eata_pio: abort, command reset error.\n");
-		return FAILED;
-	}
-	if (CD(cmd)->status == LOCKED) {
-		DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio: abort, queue slot " "locked.\n"));
-		return FAILED;
-	}
-	panic("eata_pio: abort: invalid slot status\n");
-}
-
-static int eata_pio_host_reset(struct scsi_cmnd *cmd)
-{
-	unsigned int x, limit = 0;
-	unsigned char success = 0;
-	struct scsi_cmnd *sp;
-	struct Scsi_Host *host = cmd->device->host;
-
-	DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
-		"eata_pio_reset called\n"));
-
-	spin_lock_irq(host->host_lock);
-
-	if (HD(cmd)->state == RESET) {
-		printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n");
-		spin_unlock_irq(host->host_lock);
-		return FAILED;
-	}
-
-	/* force all slots to be free */
-
-	for (x = 0; x < cmd->device->host->can_queue; x++) {
-
-		if (HD(cmd)->ccb[x].status == FREE)
-			continue;
-
-		sp = HD(cmd)->ccb[x].cmd;
-		HD(cmd)->ccb[x].status = RESET;
-		printk(KERN_WARNING "eata_pio_reset: slot %d in reset.\n", x);
-
-		if (sp == NULL)
-			panic("eata_pio_reset: slot %d, sp==NULL.\n", x);
-	}
-
-	/* hard reset the HBA  */
-	outb(EATA_CMD_RESET, cmd->device->host->base + HA_WCOMMAND);
-
-	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n"));
-	HD(cmd)->state = RESET;
-
-	spin_unlock_irq(host->host_lock);
-	msleep(3000);
-	spin_lock_irq(host->host_lock);
-
-	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, " "loops %d.\n", limit));
-
-	for (x = 0; x < cmd->device->host->can_queue; x++) {
-
-		/* Skip slots already set free by interrupt */
-		if (HD(cmd)->ccb[x].status != RESET)
-			continue;
-
-		sp = HD(cmd)->ccb[x].cmd;
-		sp->result = DID_RESET << 16;
-
-		/* This mailbox is terminated */
-		printk(KERN_WARNING "eata_pio_reset: reset ccb %d.\n", x);
-		HD(cmd)->ccb[x].status = FREE;
-
-		sp->scsi_done(sp);
-	}
-
-	HD(cmd)->state = 0;
-
-	spin_unlock_irq(host->host_lock);
-
-	if (success) {		/* hmmm... */
-		DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n"));
-		return SUCCESS;
-	} else {
-		DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, wakeup.\n"));
-		return FAILED;
-	}
-}
-
-static char *get_pio_board_data(unsigned long base, unsigned int irq, unsigned int id, unsigned long cplen, unsigned short cppadlen)
-{
-	struct eata_ccb cp;
-	static char buff[256];
-	int z;
-
-	memset(&cp, 0, sizeof(struct eata_ccb));
-	memset(buff, 0, sizeof(buff));
-
-	cp.DataIn = 1;
-	cp.Interpret = 1;	/* Interpret command */
-
-	cp.cp_datalen = cpu_to_be32(254);
-	cp.cp_dataDMA = cpu_to_be32(0);
-
-	cp.cp_id = id;
-	cp.cp_lun = 0;
-
-	cp.cp_cdb[0] = INQUIRY;
-	cp.cp_cdb[1] = 0;
-	cp.cp_cdb[2] = 0;
-	cp.cp_cdb[3] = 0;
-	cp.cp_cdb[4] = 254;
-	cp.cp_cdb[5] = 0;
-
-	if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP))
-		return NULL;
-
-	while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
-		cpu_relax();
-
-	outsw(base + HA_RDATA, &cp, cplen);
-	outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
-	for (z = 0; z < cppadlen; z++)
-		outw(0, base + HA_RDATA);
-
-	while (inb(base + HA_RSTATUS) & HA_SBUSY)
-		cpu_relax();
-
-	if (inb(base + HA_RSTATUS) & HA_SERROR)
-		return NULL;
-	else if (!(inb(base + HA_RSTATUS) & HA_SDRQ))
-		return NULL;
-	else {
-		insw(base + HA_RDATA, &buff, 127);
-		while (inb(base + HA_RSTATUS) & HA_SDRQ)
-			inw(base + HA_RDATA);
-		return buff;
-	}
-}
-
-static int get_pio_conf_PIO(unsigned long base, struct get_conf *buf)
-{
-	unsigned long loop = HZ / 2;
-	int z;
-	unsigned short *p;
-
-	if (!request_region(base, 9, "eata_pio"))
-		return 0;
-
-	memset(buf, 0, sizeof(struct get_conf));
-
-	while (inb(base + HA_RSTATUS) & HA_SBUSY)
-		if (--loop == 0)
-			goto fail;
-
-	DBG(DBG_PIO && DBG_PROBE, printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#lx\n", base));
-	eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG);
-
-	loop = 50;
-	for (p = (unsigned short *) buf; (long) p <= ((long) buf + (sizeof(struct get_conf) / 2)); p++) {
-		while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
-			if (--loop == 0)
-				goto fail;
-
-		loop = 50;
-		*p = inw(base + HA_RDATA);
-	}
-	if (inb(base + HA_RSTATUS) & HA_SERROR) {
-		DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during "
-					"transfer for HBA at %lx\n", base));
-		goto fail;
-	}
-
-	if (cpu_to_be32(EATA_SIGNATURE) != buf->signature)
-		goto fail;
-
-	DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found "
-				"at %#4lx EATA Level: %x\n",
-				base, (unsigned int) (buf->version)));
-
-	while (inb(base + HA_RSTATUS) & HA_SDRQ)
-		inw(base + HA_RDATA);
-
-	if (!ALLOW_DMA_BOARDS) {
-		for (z = 0; z < MAXISA; z++)
-			if (base == ISAbases[z]) {
-				buf->IRQ = ISAirqs[z];
-				break;
-			}
-	}
-
-	return 1;
-
- fail:
-	release_region(base, 9);
-	return 0;
-}
-
-static void print_pio_config(struct get_conf *gc)
-{
-	printk("Please check values: (read config data)\n");
-	printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d\n", be32_to_cpu(gc->len), gc->version, gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support);
-	printk("HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n", gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2], gc->scsi_id[1], be16_to_cpu(gc->queuesiz), be16_to_cpu(gc->SGsiz), gc->SECOND);
-	printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n", gc->IRQ, gc->IRQ_TR, gc->FORCADR, gc->MAX_CHAN, gc->ID_qest);
-}
-
-static unsigned int print_selftest(unsigned int base)
-{
-	unsigned char buffer[512];
-#ifdef VERBOSE_SETUP
-	int z;
-#endif
-
-	printk("eata_pio: executing controller self test & setup...\n");
-	while (inb(base + HA_RSTATUS) & HA_SBUSY);
-	outb(EATA_CMD_PIO_SETUPTEST, base + HA_WCOMMAND);
-	do {
-		while (inb(base + HA_RSTATUS) & HA_SBUSY)
-			/* nothing */ ;
-		if (inb(base + HA_RSTATUS) & HA_SDRQ) {
-			insw(base + HA_RDATA, &buffer, 256);
-#ifdef VERBOSE_SETUP
-			/* no beeps please... */
-			for (z = 0; z < 511 && buffer[z]; z++)
-				if (buffer[z] != 7)
-					printk("%c", buffer[z]);
-#endif
-		}
-	} while (inb(base + HA_RSTATUS) & (HA_SBUSY | HA_SDRQ));
-
-	return (!(inb(base + HA_RSTATUS) & HA_SERROR));
-}
-
-static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev)
-{
-	unsigned long size = 0;
-	char *buff;
-	unsigned long cplen;
-	unsigned short cppadlen;
-	struct Scsi_Host *sh;
-	hostdata *hd;
-
-	DBG(DBG_REGISTER, print_pio_config(gc));
-
-	if (gc->DMA_support) {
-		printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n", base);
-		if (!ALLOW_DMA_BOARDS)
-			return 0;
-	}
-
-	if ((buff = get_pio_board_data(base, gc->IRQ, gc->scsi_id[3], cplen = (cpu_to_be32(gc->cplen) + 1) / 2, cppadlen = (cpu_to_be16(gc->cppadlen) + 1) / 2)) == NULL) {
-		printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", base);
-		return 0;
-	}
-
-	if (!print_selftest(base) && !ALLOW_DMA_BOARDS) {
-		printk("HBA at %#lx failed while performing self test & setup.\n", base);
-		return 0;
-	}
-
-	size = sizeof(hostdata) + (sizeof(struct eata_ccb) * be16_to_cpu(gc->queuesiz));
-
-	sh = scsi_register(&driver_template, size);
-	if (sh == NULL)
-		return 0;
-
-	if (!reg_IRQ[gc->IRQ]) {	/* Interrupt already registered ? */
-		if (!request_irq(gc->IRQ, do_eata_pio_int_handler, 0, "EATA-PIO", sh)) {
-			reg_IRQ[gc->IRQ]++;
-			if (!gc->IRQ_TR)
-				reg_IRQL[gc->IRQ] = 1;	/* IRQ is edge triggered */
-		} else {
-			printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ);
-			return 0;
-		}
-	} else {		/* More than one HBA on this IRQ */
-		if (reg_IRQL[gc->IRQ]) {
-			printk("Can't support more than one HBA on this IRQ,\n" "  if the IRQ is edge triggered. Sorry.\n");
-			return 0;
-		} else
-			reg_IRQ[gc->IRQ]++;
-	}
-
-	hd = SD(sh);
-
-	memset(hd->ccb, 0, (sizeof(struct eata_ccb) * be16_to_cpu(gc->queuesiz)));
-	memset(hd->reads, 0, sizeof(hd->reads));
-
-	strlcpy(SD(sh)->vendor, &buff[8], sizeof(SD(sh)->vendor));
-	strlcpy(SD(sh)->name, &buff[16], sizeof(SD(sh)->name));
-	SD(sh)->revision[0] = buff[32];
-	SD(sh)->revision[1] = buff[33];
-	SD(sh)->revision[2] = buff[34];
-	SD(sh)->revision[3] = '.';
-	SD(sh)->revision[4] = buff[35];
-	SD(sh)->revision[5] = 0;
-
-	switch (be32_to_cpu(gc->len)) {
-	case 0x1c:
-		SD(sh)->EATA_revision = 'a';
-		break;
-	case 0x1e:
-		SD(sh)->EATA_revision = 'b';
-		break;
-	case 0x22:
-		SD(sh)->EATA_revision = 'c';
-		break;
-	case 0x24:
-		SD(sh)->EATA_revision = 'z';
-		break;
-	default:
-		SD(sh)->EATA_revision = '?';
-	}
-
-	if (be32_to_cpu(gc->len) >= 0x22) {
-		if (gc->is_PCI)
-			hd->bustype = IS_PCI;
-		else if (gc->is_EISA)
-			hd->bustype = IS_EISA;
-		else
-			hd->bustype = IS_ISA;
-	} else {
-		if (buff[21] == '4')
-			hd->bustype = IS_PCI;
-		else if (buff[21] == '2')
-			hd->bustype = IS_EISA;
-		else
-			hd->bustype = IS_ISA;
-	}
-
-	SD(sh)->cplen = cplen;
-	SD(sh)->cppadlen = cppadlen;
-	SD(sh)->hostid = gc->scsi_id[3];
-	SD(sh)->devflags = 1 << gc->scsi_id[3];
-	SD(sh)->moresupport = gc->MORE_support;
-	sh->unique_id = base;
-	sh->base = base;
-	sh->io_port = base;
-	sh->n_io_port = 9;
-	sh->irq = gc->IRQ;
-	sh->dma_channel = PIO;
-	sh->this_id = gc->scsi_id[3];
-	sh->can_queue = 1;
-	sh->cmd_per_lun = 1;
-	sh->sg_tablesize = SG_ALL;
-
-	hd->channel = 0;
-
-	hd->pdev = pci_dev_get(pdev);	/* Keep a PCI reference */
-
-	sh->max_id = 8;
-	sh->max_lun = 8;
-
-	if (gc->SECOND)
-		hd->primary = 0;
-	else
-		hd->primary = 1;
-
-	hd->next = NULL;	/* build a linked list of all HBAs */
-	hd->prev = last_HBA;
-	if (hd->prev != NULL)
-		SD(hd->prev)->next = sh;
-	last_HBA = sh;
-	if (first_HBA == NULL)
-		first_HBA = sh;
-	registered_HBAs++;
-	return (1);
-}
-
-static void find_pio_ISA(struct get_conf *buf)
-{
-	int i;
-
-	for (i = 0; i < MAXISA; i++) {
-		if (!ISAbases[i])
-			continue;
-		if (!get_pio_conf_PIO(ISAbases[i], buf))
-			continue;
-		if (!register_pio_HBA(ISAbases[i], buf, NULL))
-			release_region(ISAbases[i], 9);
-		else
-			ISAbases[i] = 0;
-	}
-	return;
-}
-
-static void find_pio_EISA(struct get_conf *buf)
-{
-	u32 base;
-	int i;
-
-#ifdef CHECKPAL
-	u8 pal1, pal2, pal3;
-#endif
-
-	for (i = 0; i < MAXEISA; i++) {
-		if (EISAbases[i]) {	/* Still a possibility ?          */
-
-			base = 0x1c88 + (i * 0x1000);
-#ifdef CHECKPAL
-			pal1 = inb((u16) base - 8);
-			pal2 = inb((u16) base - 7);
-			pal3 = inb((u16) base - 6);
-
-			if (((pal1 == 0x12) && (pal2 == 0x14)) || ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) {
-				DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " "%x %x %x \n", (int) pal1, (int) pal2, (int) pal3));
-#endif
-				if (get_pio_conf_PIO(base, buf)) {
-					DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf));
-					if (buf->IRQ) {
-						if (!register_pio_HBA(base, buf, NULL))
-							release_region(base, 9);
-					} else {
-						printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " "removed from list\n");
-						release_region(base, 9);
-					}
-				}
-				/* Nothing found here so we take it from the list */
-				EISAbases[i] = 0;
-#ifdef CHECKPAL
-			}
-#endif
-		}
-	}
-	return;
-}
-
-static void find_pio_PCI(struct get_conf *buf)
-{
-#ifndef CONFIG_PCI
-	printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
-#else
-	struct pci_dev *dev = NULL;
-	unsigned long base, x;
-
-	while ((dev = pci_get_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) {
-		DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", pci_name(dev)));
-		if (pci_enable_device(dev))
-			continue;
-		pci_set_master(dev);
-		base = pci_resource_flags(dev, 0);
-		if (base & IORESOURCE_MEM) {
-			printk("eata_pio: invalid base address of device %s\n", pci_name(dev));
-			continue;
-		}
-		base = pci_resource_start(dev, 0);
-		/* EISA tag there ? */
-		if ((inb(base) == 0x12) && (inb(base + 1) == 0x14))
-			continue;	/* Jep, it's forced, so move on  */
-		base += 0x10;	/* Now, THIS is the real address */
-		if (base != 0x1f8) {
-			/* We didn't find it in the primary search */
-			if (get_pio_conf_PIO(base, buf)) {
-				if (buf->FORCADR) {	/* If the address is forced */
-					release_region(base, 9);
-					continue;	/* we'll find it later      */
-				}
-
-				/* OK. We made it till here, so we can go now  
-				 * and register it. We  only have to check and 
-				 * eventually remove it from the EISA and ISA list 
-				 */
-
-				if (!register_pio_HBA(base, buf, dev)) {
-					release_region(base, 9);
-					continue;
-				}
-
-				if (base < 0x1000) {
-					for (x = 0; x < MAXISA; ++x) {
-						if (ISAbases[x] == base) {
-							ISAbases[x] = 0;
-							break;
-						}
-					}
-				} else if ((base & 0x0fff) == 0x0c88) {
-					x = (base >> 12) & 0x0f;
-					EISAbases[x] = 0;
-				}
-			}
-#ifdef CHECK_BLINK
-			else if (check_blink_state(base)) {
-				printk("eata_pio: HBA is in BLINK state.\n" "Consult your HBAs manual to correct this.\n");
-			}
-#endif
-		}
-	}
-#endif				/* #ifndef CONFIG_PCI */
-}
-
-static int eata_pio_detect(struct scsi_host_template *tpnt)
-{
-	struct Scsi_Host *HBA_ptr;
-	struct get_conf gc;
-	int i;
-
-	find_pio_PCI(&gc);
-	find_pio_EISA(&gc);
-	find_pio_ISA(&gc);
-
-	for (i = 0; i < MAXIRQ; i++)
-		if (reg_IRQ[i])
-			request_irq(i, do_eata_pio_int_handler, 0, "EATA-PIO", NULL);
-
-	HBA_ptr = first_HBA;
-
-	if (registered_HBAs != 0) {
-		printk("EATA (Extended Attachment) PIO driver version: %d.%d%s\n"
-		       "(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n" "            Alfred Arnold,   a.arnold@kfa-juelich.de\n" "This release only supports DASD devices (harddisks)\n", VER_MAJOR, VER_MINOR, VER_SUB);
-
-		printk("Registered HBAs:\n");
-		printk("HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr:" " QS: SG: CPL:\n");
-		for (i = 1; i <= registered_HBAs; i++) {
-			printk("scsi%-2d: %.10s v%s 2.0%c  %s %#.4lx   %2d   %d   %d   %c"
-			       "  %2d  %2d  %2d\n",
-			       HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
-			       SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P') ?
-			       "PCI " : (SD(HBA_ptr)->bustype == 'E') ? "EISA" : "ISA ",
-			       HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id,
-			       SD(HBA_ptr)->primary ? 'Y' : 'N', HBA_ptr->can_queue,
-			       HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
-			HBA_ptr = SD(HBA_ptr)->next;
-		}
-	}
-	return (registered_HBAs);
-}
-
-static struct scsi_host_template driver_template = {
-	.proc_name		= "eata_pio",
-	.name              	= "EATA (Extended Attachment) PIO driver",
-	.show_info         	= eata_pio_show_info,
-	.detect            	= eata_pio_detect,
-	.release           	= eata_pio_release,
-	.queuecommand      	= eata_pio_queue,
-	.eh_abort_handler  	= eata_pio_abort,
-	.eh_host_reset_handler	= eata_pio_host_reset,
-	.use_clustering    	= ENABLE_CLUSTERING,
-};
-
-MODULE_AUTHOR("Michael Neuffer, Alfred Arnold");
-MODULE_DESCRIPTION("EATA SCSI PIO driver");
-MODULE_LICENSE("GPL");
-
-#include "scsi_module.c"
diff --git a/drivers/scsi/eata_pio.h b/drivers/scsi/eata_pio.h
deleted file mode 100644
index 5b5e3d1..0000000
--- a/drivers/scsi/eata_pio.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/********************************************************
-* Header file for eata_pio.c Linux EATA-PIO SCSI driver *
-* (c) 1993-96 Michael Neuffer  	                        *
-*********************************************************
-* last change: 2002/11/02				*
-********************************************************/
-
-
-#ifndef _EATA_PIO_H
-#define _EATA_PIO_H
-
-#define VER_MAJOR 0
-#define VER_MINOR 0
-#define VER_SUB	  "1b"
-
-/************************************************************************
- * Here you can switch parts of the code on and of			*
- ************************************************************************/
-
-#define VERBOSE_SETUP		/* show startup screen of 2001 */
-#define ALLOW_DMA_BOARDS 1
-
-/************************************************************************
- * Debug options.							* 
- * Enable DEBUG and whichever options you require.			*
- ************************************************************************/
-#define DEBUG_EATA	1	/* Enable debug code.                       */
-#define DPT_DEBUG	0	/* Bobs special                             */
-#define DBG_DELAY	0	/* Build in delays so debug messages can be
-				 * be read before they vanish of the top of
-				 * the screen!
-				 */
-#define DBG_PROBE	0	/* Debug probe routines.                    */
-#define DBG_ISA		0	/* Trace ISA routines                       */
-#define DBG_EISA	0	/* Trace EISA routines                      */
-#define DBG_PCI		0	/* Trace PCI routines                       */
-#define DBG_PIO		0	/* Trace get_config_PIO                     */
-#define DBG_COM		0	/* Trace command call                       */
-#define DBG_QUEUE	0	/* Trace command queueing.                  */
-#define DBG_INTR	0	/* Trace interrupt service routine.         */
-#define DBG_INTR2	0	/* Trace interrupt service routine.         */
-#define DBG_PROC	0	/* Debug proc-fs related statistics         */
-#define DBG_PROC_WRITE	0
-#define DBG_REGISTER	0	/* */
-#define DBG_ABNORM	1	/* Debug abnormal actions (reset, abort)    */
-
-#if DEBUG_EATA
-#define DBG(x, y)   if ((x)) {y;}
-#else
-#define DBG(x, y)
-#endif
-
-#endif				/* _EATA_PIO_H */
diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h
index 1da6407..858c3b3 100644
--- a/drivers/scsi/esas2r/esas2r.h
+++ b/drivers/scsi/esas2r/esas2r.h
@@ -962,7 +962,6 @@ struct esas2r_adapter {
  * Function Declarations
  * SCSI functions
  */
-int esas2r_release(struct Scsi_Host *);
 const char *esas2r_info(struct Scsi_Host *);
 int esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq,
 			struct esas2r_sas_nvram *data);
@@ -984,7 +983,6 @@ int esas2r_target_reset(struct scsi_cmnd *cmd);
 /* Internal functions */
 int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 			int index);
-int esas2r_cleanup(struct Scsi_Host *host);
 int esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count);
 int esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off,
 		    int count);
diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c
index 5b14dd2..9dffcb2 100644
--- a/drivers/scsi/esas2r/esas2r_init.c
+++ b/drivers/scsi/esas2r/esas2r_init.c
@@ -661,27 +661,6 @@ void esas2r_kill_adapter(int i)
 	}
 }
 
-int esas2r_cleanup(struct Scsi_Host *host)
-{
-	struct esas2r_adapter *a;
-	int index;
-
-	if (host == NULL) {
-		int i;
-
-		esas2r_debug("esas2r_cleanup everything");
-		for (i = 0; i < MAX_ADAPTERS; i++)
-			esas2r_kill_adapter(i);
-		return -1;
-	}
-
-	esas2r_debug("esas2r_cleanup called for host %p", host);
-	a = (struct esas2r_adapter *)host->hostdata;
-	index = a->index;
-	esas2r_kill_adapter(index);
-	return index;
-}
-
 int esas2r_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct Scsi_Host *host = pci_get_drvdata(pdev);
diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c
index 4eb1430..e07eac5 100644
--- a/drivers/scsi/esas2r/esas2r_main.c
+++ b/drivers/scsi/esas2r/esas2r_main.c
@@ -235,7 +235,6 @@ static struct scsi_host_template driver_template = {
 	.module				= THIS_MODULE,
 	.show_info			= esas2r_show_info,
 	.name				= ESAS2R_LONGNAME,
-	.release			= esas2r_release,
 	.info				= esas2r_info,
 	.ioctl				= esas2r_ioctl,
 	.queuecommand			= esas2r_queuecommand,
@@ -520,44 +519,16 @@ static int esas2r_probe(struct pci_dev *pcid,
 
 static void esas2r_remove(struct pci_dev *pdev)
 {
-	struct Scsi_Host *host;
-	int index;
-
-	if (pdev == NULL) {
-		esas2r_log(ESAS2R_LOG_WARN, "esas2r_remove pdev==NULL");
-		return;
-	}
-
-	host = pci_get_drvdata(pdev);
-
-	if (host == NULL) {
-		/*
-		 * this can happen if pci_set_drvdata was already called
-		 * to clear the host pointer.  if this is the case, we
-		 * are okay; this channel has already been cleaned up.
-		 */
-
-		return;
-	}
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	struct esas2r_adapter *a = (struct esas2r_adapter *)host->hostdata;
 
 	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev),
 		       "esas2r_remove(%p) called; "
 		       "host:%p", pdev,
 		       host);
 
-	index = esas2r_cleanup(host);
-
-	if (index < 0)
-		esas2r_log_dev(ESAS2R_LOG_WARN, &(pdev->dev),
-			       "unknown host in %s",
-			       __func__);
-
+	esas2r_kill_adapter(a->index);
 	found_adapters--;
-
-	/* if this was the last adapter, clean up the rest of the driver */
-
-	if (found_adapters == 0)
-		esas2r_cleanup(NULL);
 }
 
 static int __init esas2r_init(void)
@@ -638,30 +609,7 @@ static int __init esas2r_init(void)
 	for (i = 0; i < MAX_ADAPTERS; i++)
 		esas2r_adapters[i] = NULL;
 
-	/* initialize */
-
-	driver_template.module = THIS_MODULE;
-
-	if (pci_register_driver(&esas2r_pci_driver) != 0)
-		esas2r_log(ESAS2R_LOG_CRIT, "pci_register_driver FAILED");
-	else
-		esas2r_log(ESAS2R_LOG_INFO, "pci_register_driver() OK");
-
-	if (!found_adapters) {
-		pci_unregister_driver(&esas2r_pci_driver);
-		esas2r_cleanup(NULL);
-
-		esas2r_log(ESAS2R_LOG_CRIT,
-			   "driver will not be loaded because no ATTO "
-			   "%s devices were found",
-			   ESAS2R_DRVR_NAME);
-		return -1;
-	} else {
-		esas2r_log(ESAS2R_LOG_INFO, "found %d adapters",
-			   found_adapters);
-	}
-
-	return 0;
+	return pci_register_driver(&esas2r_pci_driver);
 }
 
 /* Handle ioctl calls to "/proc/scsi/esas2r/ATTOnode" */
@@ -753,18 +701,6 @@ int esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh)
 
 }
 
-int esas2r_release(struct Scsi_Host *sh)
-{
-	esas2r_log_dev(ESAS2R_LOG_INFO, &(sh->shost_gendev),
-		       "esas2r_release() called");
-
-	esas2r_cleanup(sh);
-	if (sh->irq)
-		free_irq(sh->irq, NULL);
-	scsi_unregister(sh);
-	return 0;
-}
-
 const char *esas2r_info(struct Scsi_Host *sh)
 {
 	struct esas2r_adapter *a = (struct esas2r_adapter *)sh->hostdata;
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
deleted file mode 100644
index ebbe5a3..0000000
--- a/drivers/scsi/fdomain.c
+++ /dev/null
@@ -1,1783 +0,0 @@
-/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
- * Created: Sun May  3 18:53:19 1992 by faith@cs.unc.edu
- * Revised: Mon Dec 28 21:59:02 1998 by faith@acm.org
- * Author: Rickard E. Faith, faith@cs.unc.edu
- * Copyright 1992-1996, 1998 Rickard E. Faith (faith@acm.org)
- * Shared IRQ supported added 7/7/2001  Alan Cox <alan@lxorguk.ukuu.org.uk>
-
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
-
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
-
- **************************************************************************
-
- SUMMARY:
-
- Future Domain BIOS versions supported for autodetect:
-    2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
- Chips are supported:
-    TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
- Boards supported:
-    Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
-    Future Domain TMC-3260 (PCI)
-    Quantum ISA-200S, ISA-250MG
-    Adaptec AHA-2920A (PCI) [BUT *NOT* AHA-2920C -- use aic7xxx instead]
-    IBM ?
- LILO/INSMOD command-line options:
-    fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]
-
-
-    
- NOTE:
-
- The Adaptec AHA-2920C has an Adaptec AIC-7850 chip on it.
- Use the aic7xxx driver for this board.
-       
- The Adaptec AHA-2920A has a Future Domain chip on it, so this is the right
- driver for that card.  Unfortunately, the boxes will probably just say
- "2920", so you'll have to look on the card for a Future Domain logo, or a
- letter after the 2920.
-
- 
- 
- THANKS:
-
- Thanks to Adaptec for providing PCI boards for testing.  This finally
- enabled me to test the PCI detection and correct it for PCI boards that do
- not have a BIOS at a standard ISA location.  For PCI boards, LILO/INSMOD
- command-line options should no longer be needed.  --RF 18Nov98
-
-
- 
- DESCRIPTION:
- 
- This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
- TMC-1650/1670, and TMC-3260 SCSI host adapters.  The 1650 and 1670 have a
- 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
- high-density external connector.  The 1670 and 1680 have floppy disk
- controllers built in.  The TMC-3260 is a PCI bus card.
-
- Future Domain's older boards are based on the TMC-1800 chip, and this
- driver was originally written for a TMC-1680 board with the TMC-1800 chip.
- More recently, boards are being produced with the TMC-18C50 and TMC-18C30
- chips.  The latest and greatest board may not work with this driver.  If
- you have to patch this driver so that it will recognize your board's BIOS
- signature, then the driver may fail to function after the board is
- detected.
-
- Please note that the drive ordering that Future Domain implemented in BIOS
- versions 3.4 and 3.5 is the opposite of the order (currently) used by the
- rest of the SCSI industry.  If you have BIOS version 3.4 or 3.5, and have
- more than one drive, then the drive ordering will be the reverse of that
- which you see under DOS.  For example, under DOS SCSI ID 0 will be D: and
- SCSI ID 1 will be C: (the boot device).  Under Linux, SCSI ID 0 will be
- /dev/sda and SCSI ID 1 will be /dev/sdb.  The Linux ordering is consistent
- with that provided by all the other SCSI drivers for Linux.  If you want
- this changed, you will probably have to patch the higher level SCSI code.
- If you do so, please send me patches that are protected by #ifdefs.
-
- If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
- your board.  Please refer to the Seagate driver for more information and
- possible support.
-
- 
- 
- HISTORY:
-
- Linux       Driver      Driver
- Version     Version     Date         Support/Notes
-
-             0.0          3 May 1992  V2.0 BIOS; 1800 chip
- 0.97        1.9         28 Jul 1992
- 0.98.6      3.1         27 Nov 1992
- 0.99        3.2          9 Dec 1992
-
- 0.99.3      3.3         10 Jan 1993  V3.0 BIOS
- 0.99.5      3.5         18 Feb 1993
- 0.99.10     3.6         15 May 1993  V3.2 BIOS; 18C50 chip
- 0.99.11     3.17         3 Jul 1993  (now under RCS)
- 0.99.12     3.18        13 Aug 1993
- 0.99.14     5.6         31 Oct 1993  (reselection code removed)
-
- 0.99.15     5.9         23 Jan 1994  V3.4 BIOS (preliminary)
- 1.0.8/1.1.1 5.15         1 Apr 1994  V3.4 BIOS; 18C30 chip (preliminary)
- 1.0.9/1.1.3 5.16         7 Apr 1994  V3.4 BIOS; 18C30 chip
- 1.1.38      5.18        30 Jul 1994  36C70 chip (PCI version of 18C30)
- 1.1.62      5.20         2 Nov 1994  V3.5 BIOS
- 1.1.73      5.22         7 Dec 1994  Quantum ISA-200S board; V2.0 BIOS
-
- 1.1.82      5.26        14 Jan 1995  V3.5 BIOS; TMC-1610M/MER/MEX board
- 1.2.10      5.28         5 Jun 1995  Quantum ISA-250MG board; V2.0, V2.01 BIOS
- 1.3.4       5.31        23 Jun 1995  PCI BIOS-32 detection (preliminary)
- 1.3.7       5.33         4 Jul 1995  PCI BIOS-32 detection
- 1.3.28      5.36        17 Sep 1995  V3.61 BIOS; LILO command-line support
- 1.3.34      5.39        12 Oct 1995  V3.60 BIOS; /proc
- 1.3.72      5.39         8 Feb 1996  Adaptec AHA-2920 board
- 1.3.85      5.41         4 Apr 1996
- 2.0.12      5.44         8 Aug 1996  Use ID 7 for all PCI cards
- 2.1.1       5.45         2 Oct 1996  Update ROM accesses for 2.1.x
- 2.1.97      5.46	 23 Apr 1998  Rewritten PCI detection routines [mj]
- 2.1.11x     5.47	  9 Aug 1998  Touched for 8 SCSI disk majors support
-             5.48        18 Nov 1998  BIOS no longer needed for PCI detection
- 2.2.0       5.50        28 Dec 1998  Support insmod parameters
- 
-
- REFERENCES USED:
-
- "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
- 1990.
-
- "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
- Corporation, January 1992.
-
- "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
- B/September 1991)", Maxtor Corporation, 1991.
-
- "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
-
- "Draft Proposed American National Standard: Small Computer System
- Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
- revision 10h, October 17, 1991)
-
- Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
- Youngdale (ericy@cais.com), 1992.
-
- Private communication, Tuong Le (Future Domain Engineering department),
- 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
- TMC-18C30 detection.)
-
- Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
- 60 (2.39: Disk Partition Table Layout).
-
- "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
- 6-1.
-
-
- 
- NOTES ON REFERENCES:
-
- The Maxtor manuals were free.  Maxtor telephone technical support is
- great!
-
- The Future Domain manuals were $25 and $35.  They document the chip, not
- the TMC-16x0 boards, so some information I had to guess at.  In 1992,
- Future Domain sold DOS BIOS source for $250 and the UN*X driver source was
- $750, but these required a non-disclosure agreement, so even if I could
- have afforded them, they would *not* have been useful for writing this
- publicly distributable driver.  Future Domain technical support has
- provided some information on the phone and have sent a few useful FAXs.
- They have been much more helpful since they started to recognize that the
- word "Linux" refers to an operating system :-).
-
- 
-
- ALPHA TESTERS:
-
- There are many other alpha testers that come and go as the driver
- develops.  The people listed here were most helpful in times of greatest
- need (mostly early on -- I've probably left out a few worthy people in
- more recent times):
-
- Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken
- Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari
- Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad
- Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com).
-
- Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me
- his 18C50-based card for debugging.  He is the sole reason that this
- driver works with the 18C50 chip.
-
- Thanks to Dave Newman (dnewman@crl.com) for providing initial patches for
- the version 3.4 BIOS.
-
- Thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for providing
- patches that support the TMC-3260, a PCI bus card with the 36C70 chip.
- The 36C70 chip appears to be "completely compatible" with the 18C30 chip.
-
- Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the
- patch for the version 3.5 BIOS.
-
- Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the
- patch for the Quantum ISA-200S SCSI adapter.
- 
- Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to
- Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to some
- random TMC-1680 repackaged by IBM; and to Mintak Ng (mintak@panix.com) for
- the version 3.61 BIOS signature.
-
- Thanks for Mark Singer (elf@netcom.com) and Richard Simpson
- (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective
- work on the Quantum RAM layout.
-
- Special thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for
- providing patches for proper PCI BIOS32-mediated detection of the TMC-3260
- card (a PCI bus card with the 36C70 chip).  Please send James PCI-related
- bug reports.
-
- Thanks to Tom Cavin (tec@usa1.com) for preliminary command-line option
- patches.
-
- New PCI detection code written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
-
- Insmod parameter code based on patches from Daniel Graham
- <graham@balance.uoregon.edu>. 
- 
- All of the alpha testers deserve much thanks.
-
-
-
- NOTES ON USER DEFINABLE OPTIONS:
-
- DEBUG: This turns on the printing of various debug information.
-
- ENABLE_PARITY: This turns on SCSI parity checking.  With the current
- driver, all attached devices must support SCSI parity.  If none of your
- devices support parity, then you can probably get the driver to work by
- turning this option off.  I have no way of testing this, however, and it
- would appear that no one ever uses this option.
-
- FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the
- 18C30 chip have a 2k cache).  When this many 512 byte blocks are filled by
- the SCSI device, an interrupt will be raised.  Therefore, this could be as
- low as 0, or as high as 16.  Note, however, that values which are too high
- or too low seem to prevent any interrupts from occurring, and thereby lock
- up the machine.  I have found that 2 is a good number, but throughput may
- be increased by changing this value to values which are close to 2.
- Please let me know if you try any different values.
-
- RESELECTION: This is no longer an option, since I gave up trying to
- implement it in version 4.x of this driver.  It did not improve
- performance at all and made the driver unstable (because I never found one
- of the two race conditions which were introduced by the multiple
- outstanding command code).  The instability seems a very high price to pay
- just so that you don't have to wait for the tape to rewind.  If you want
- this feature implemented, send me patches.  I'll be happy to send a copy
- of my (broken) driver to anyone who would like to see a copy.
-
- **************************************************************************/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/proc_fs.h>
-#include <linux/pci.h>
-#include <linux/stat.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <scsi/scsicam.h>
-
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_ioctl.h>
-#include "fdomain.h"
-
-#ifndef PCMCIA
-MODULE_AUTHOR("Rickard E. Faith");
-MODULE_DESCRIPTION("Future domain SCSI driver");
-MODULE_LICENSE("GPL");
-#endif
-
-  
-#define VERSION          "$Revision: 5.51 $"
-
-/* START OF USER DEFINABLE OPTIONS */
-
-#define DEBUG            0	/* Enable debugging output */
-#define ENABLE_PARITY    1	/* Enable SCSI Parity */
-#define FIFO_COUNT       2	/* Number of 512 byte blocks before INTR */
-
-/* END OF USER DEFINABLE OPTIONS */
-
-#if DEBUG
-#define EVERY_ACCESS     0	/* Write a line on every scsi access */
-#define ERRORS_ONLY      1	/* Only write a line if there is an error */
-#define DEBUG_DETECT     0	/* Debug fdomain_16x0_detect() */
-#define DEBUG_MESSAGES   1	/* Debug MESSAGE IN phase */
-#define DEBUG_ABORT      1	/* Debug abort() routine */
-#define DEBUG_RESET      1	/* Debug reset() routine */
-#define DEBUG_RACE       1      /* Debug interrupt-driven race condition */
-#else
-#define EVERY_ACCESS     0	/* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
-#define ERRORS_ONLY      0
-#define DEBUG_DETECT     0
-#define DEBUG_MESSAGES   0
-#define DEBUG_ABORT      0
-#define DEBUG_RESET      0
-#define DEBUG_RACE       0
-#endif
-
-/* Errors are reported on the line, so we don't need to report them again */
-#if EVERY_ACCESS
-#undef ERRORS_ONLY
-#define ERRORS_ONLY      0
-#endif
-
-#if ENABLE_PARITY
-#define PARITY_MASK      0x08
-#else
-#define PARITY_MASK      0x00
-#endif
-
-enum chip_type {
-   unknown          = 0x00,
-   tmc1800          = 0x01,
-   tmc18c50         = 0x02,
-   tmc18c30         = 0x03,
-};
-
-enum {
-   in_arbitration   = 0x02,
-   in_selection     = 0x04,
-   in_other         = 0x08,
-   disconnect       = 0x10,
-   aborted          = 0x20,
-   sent_ident       = 0x40,
-};
-
-enum in_port_type {
-   Read_SCSI_Data   =  0,
-   SCSI_Status      =  1,
-   TMC_Status       =  2,
-   FIFO_Status      =  3,	/* tmc18c50/tmc18c30 only */
-   Interrupt_Cond   =  4,	/* tmc18c50/tmc18c30 only */
-   LSB_ID_Code      =  5,
-   MSB_ID_Code      =  6,
-   Read_Loopback    =  7,
-   SCSI_Data_NoACK  =  8,
-   Interrupt_Status =  9,
-   Configuration1   = 10,
-   Configuration2   = 11,	/* tmc18c50/tmc18c30 only */
-   Read_FIFO        = 12,
-   FIFO_Data_Count  = 14
-};
-
-enum out_port_type {
-   Write_SCSI_Data  =  0,
-   SCSI_Cntl        =  1,
-   Interrupt_Cntl   =  2,
-   SCSI_Mode_Cntl   =  3,
-   TMC_Cntl         =  4,
-   Memory_Cntl      =  5,	/* tmc18c50/tmc18c30 only */
-   Write_Loopback   =  7,
-   IO_Control       = 11,	/* tmc18c30 only */
-   Write_FIFO       = 12
-};
-
-/* .bss will zero all the static variables below */
-static int               port_base;
-static unsigned long     bios_base;
-static void __iomem *    bios_mem;
-static int               bios_major;
-static int               bios_minor;
-static int               PCI_bus;
-#ifdef CONFIG_PCI
-static struct pci_dev	*PCI_dev;
-#endif
-static int               Quantum;	/* Quantum board variant */
-static int               interrupt_level;
-static volatile int      in_command;
-static struct scsi_cmnd  *current_SC;
-static enum chip_type    chip              = unknown;
-static int               adapter_mask;
-static int               this_id;
-static int               setup_called;
-
-#if DEBUG_RACE
-static volatile int      in_interrupt_flag;
-#endif
-
-static int               FIFO_Size = 0x2000; /* 8k FIFO for
-						pre-tmc18c30 chips */
-
-static irqreturn_t       do_fdomain_16x0_intr( int irq, void *dev_id );
-/* Allow insmod parameters to be like LILO parameters.  For example:
-   insmod fdomain fdomain=0x140,11 */
-static char * fdomain = NULL;
-module_param(fdomain, charp, 0);
-
-#ifndef PCMCIA
-
-static unsigned long addresses[] = {
-   0xc8000,
-   0xca000,
-   0xce000,
-   0xde000,
-   0xcc000,		/* Extra addresses for PCI boards */
-   0xd0000,
-   0xe0000,
-};
-#define ADDRESS_COUNT ARRAY_SIZE(addresses)
-
-static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
-#define PORT_COUNT ARRAY_SIZE(ports)
-
-static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
-
-#endif /* !PCMCIA */
-
-/*
-
-  READ THIS BEFORE YOU ADD A SIGNATURE!
-
-  READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
-
-  READ EVERY WORD, ESPECIALLY THE WORD *NOT*
-
-  This driver works *ONLY* for Future Domain cards using the TMC-1800,
-  TMC-18C50, or TMC-18C30 chip.  This includes models TMC-1650, 1660, 1670,
-  and 1680.  These are all 16-bit cards.
-
-  The following BIOS signature signatures are for boards which do *NOT*
-  work with this driver (these TMC-8xx and TMC-9xx boards may work with the
-  Seagate driver):
-
-  FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
-  FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
-  FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
-  FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
-  FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
-  FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
-  FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
-
-  (The cards which do *NOT* work are all 8-bit cards -- although some of
-  them have a 16-bit form-factor, the upper 8-bits are used only for IRQs
-  and are *NOT* used for data.  You can tell the difference by following
-  the tracings on the circuit board -- if only the IRQ lines are involved,
-  you have a "8-bit" card, and should *NOT* use this driver.)
-
-*/
-
-#ifndef PCMCIA
-
-static struct signature {
-   const char *signature;
-   int  sig_offset;
-   int  sig_length;
-   int  major_bios_version;
-   int  minor_bios_version;
-   int  flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */
-} signatures[] = {
-   /*          1         2         3         4         5         6 */
-   /* 123456789012345678901234567890123456789012345678901234567890 */
-   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89",  5, 50,  2,  0, 0 },
-   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89",  5, 50,  2,  0, 0 },
-   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50,  2,  0, 2 },
-   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0",        73, 43,  2,  0, 3 },
-   { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.",            72, 39,  2,  0, 4 },
-   { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92",        5, 44,  3,  0, 0 },
-   { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93",        5, 44,  3,  2, 0 },
-   { "IBM F1 P2 BIOS v1.0104/29/93",                        5, 28,  3, -1, 0 },
-   { "Future Domain Corp. V1.0008/18/93",                   5, 33,  3,  4, 0 },
-   { "Future Domain Corp. V1.0008/18/93",                  26, 33,  3,  4, 1 },
-   { "Adaptec AHA-2920 PCI-SCSI Card",                     42, 31,  3, -1, 1 },
-   { "IBM F1 P264/32",                                      5, 14,  3, -1, 1 },
-				/* This next signature may not be a 3.5 bios */
-   { "Future Domain Corp. V2.0108/18/93",                   5, 33,  3,  5, 0 },
-   { "FUTURE DOMAIN CORP.  V3.5008/18/93",                  5, 34,  3,  5, 0 },
-   { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5",        5, 44,  3,  5, 0 },
-   { "FUTURE DOMAIN CORP.  V3.6008/18/93",                  5, 34,  3,  6, 0 },
-   { "FUTURE DOMAIN CORP.  V3.6108/18/93",                  5, 34,  3,  6, 0 },
-   { "FUTURE DOMAIN TMC-18XX",                              5, 22, -1, -1, 0 },
-
-   /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE
-    Also, fix the disk geometry code for your signature and send your
-    changes for faith@cs.unc.edu.  Above all, do *NOT* change any old
-    signatures!
-
-    Note that the last line will match a "generic" 18XX bios.  Because
-    Future Domain has changed the host SCSI ID and/or the location of the
-    geometry information in the on-board RAM area for each of the first
-    three BIOS's, it is still important to enter a fully qualified
-    signature in the table for any new BIOS's (after the host SCSI ID and
-    geometry location are verified). */
-};
-
-#define SIGNATURE_COUNT ARRAY_SIZE(signatures)
-
-#endif /* !PCMCIA */
-
-static void print_banner( struct Scsi_Host *shpnt )
-{
-   if (!shpnt) return;		/* This won't ever happen */
-
-   if (bios_major < 0 && bios_minor < 0) {
-      printk(KERN_INFO "scsi%d: <fdomain> No BIOS; using scsi id %d\n",
-	      shpnt->host_no, shpnt->this_id);
-   } else {
-      printk(KERN_INFO "scsi%d: <fdomain> BIOS version ", shpnt->host_no);
-
-      if (bios_major >= 0) printk("%d.", bios_major);
-      else                 printk("?.");
-
-      if (bios_minor >= 0) printk("%d", bios_minor);
-      else                 printk("?.");
-
-      printk( " at 0x%lx using scsi id %d\n",
-	      bios_base, shpnt->this_id );
-   }
-
-				/* If this driver works for later FD PCI
-				   boards, we will have to modify banner
-				   for additional PCI cards, but for now if
-				   it's PCI it's a TMC-3260 - JTM */
-   printk(KERN_INFO "scsi%d: <fdomain> %s chip at 0x%x irq ",
-	   shpnt->host_no,
-	   chip == tmc1800 ? "TMC-1800" : (chip == tmc18c50 ? "TMC-18C50" : (chip == tmc18c30 ? (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30") : "Unknown")),
-	   port_base);
-
-   if (interrupt_level)
-   	printk("%d", interrupt_level);
-   else
-        printk("<none>");
-
-   printk( "\n" );
-}
-
-int fdomain_setup(char *str)
-{
-	int ints[4];
-
-	(void)get_options(str, ARRAY_SIZE(ints), ints);
-
-	if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
-		printk(KERN_INFO "scsi: <fdomain> Usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n");
-		printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
-		return 0;
-	}
-
-	port_base       = ints[0] >= 1 ? ints[1] : 0;
-	interrupt_level = ints[0] >= 2 ? ints[2] : 0;
-	this_id         = ints[0] >= 3 ? ints[3] : 0;
-   
-	bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */
-	++setup_called;
-	return 1;
-}
-
-__setup("fdomain=", fdomain_setup);
-
-
-static void do_pause(unsigned amount)	/* Pause for amount*10 milliseconds */
-{
-	mdelay(10*amount);
-}
-
-static inline void fdomain_make_bus_idle( void )
-{
-   outb(0, port_base + SCSI_Cntl);
-   outb(0, port_base + SCSI_Mode_Cntl);
-   if (chip == tmc18c50 || chip == tmc18c30)
-	 outb(0x21 | PARITY_MASK, port_base + TMC_Cntl); /* Clear forced intr. */
-   else
-	 outb(0x01 | PARITY_MASK, port_base + TMC_Cntl);
-}
-
-static int fdomain_is_valid_port( int port )
-{
-#if DEBUG_DETECT 
-   printk( " (%x%x),",
-	   inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
-#endif
-
-   /* The MCA ID is a unique id for each MCA compatible board.  We
-      are using ISA boards, but Future Domain provides the MCA ID
-      anyway.  We can use this ID to ensure that this is a Future
-      Domain TMC-1660/TMC-1680.
-    */
-
-   if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
-      if (inb( port + LSB_ID_Code ) != 0x27) return 0;
-      if (inb( port + MSB_ID_Code ) != 0x61) return 0;
-      chip = tmc1800;
-   } else {				    /* test for 0xe960 id */
-      if (inb( port + MSB_ID_Code ) != 0x60) return 0;
-      chip = tmc18c50;
-
-				/* Try to toggle 32-bit mode.  This only
-				   works on an 18c30 chip.  (User reports
-				   say this works, so we should switch to
-				   it in the near future.) */
-
-      outb( 0x80, port + IO_Control );
-      if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
-	 outb( 0x00, port + IO_Control );
-	 if ((inb( port + Configuration2 ) & 0x80) == 0x00) {
-	    chip = tmc18c30;
-	    FIFO_Size = 0x800;	/* 2k FIFO */
-	 }
-      }
-				/* If that failed, we are an 18c50. */
-   }
-
-   return 1;
-}
-
-static int fdomain_test_loopback( void )
-{
-   int i;
-   int result;
-
-   for (i = 0; i < 255; i++) {
-      outb( i, port_base + Write_Loopback );
-      result = inb( port_base + Read_Loopback );
-      if (i != result)
-	    return 1;
-   }
-   return 0;
-}
-
-#ifndef PCMCIA
-
-/* fdomain_get_irq assumes that we have a valid MCA ID for a
-   TMC-1660/TMC-1680 Future Domain board.  Now, check to be sure the
-   bios_base matches these ports.  If someone was unlucky enough to have
-   purchased more than one Future Domain board, then they will have to
-   modify this code, as we only detect one board here.  [The one with the
-   lowest bios_base.]
-
-   Note that this routine is only used for systems without a PCI BIOS32
-   (e.g., ISA bus).  For PCI bus systems, this routine will likely fail
-   unless one of the IRQs listed in the ints array is used by the board.
-   Sometimes it is possible to use the computer's BIOS setup screen to
-   configure a PCI system so that one of these IRQs will be used by the
-   Future Domain card. */
-
-static int fdomain_get_irq( int base )
-{
-   int options = inb(base + Configuration1);
-
-#if DEBUG_DETECT
-   printk("scsi: <fdomain> Options = %x\n", options);
-#endif
- 
-   /* Check for board with lowest bios_base --
-      this isn't valid for the 18c30 or for
-      boards on the PCI bus, so just assume we
-      have the right board. */
-
-   if (chip != tmc18c30 && !PCI_bus && addresses[(options & 0xc0) >> 6 ] != bios_base)
-   	return 0;
-   return ints[(options & 0x0e) >> 1];
-}
-
-static int fdomain_isa_detect( int *irq, int *iobase )
-{
-   int i, j;
-   int base = 0xdeadbeef;
-   int flag = 0;
-
-#if DEBUG_DETECT
-   printk( "scsi: <fdomain> fdomain_isa_detect:" );
-#endif
-
-   for (i = 0; i < ADDRESS_COUNT; i++) {
-      void __iomem *p = ioremap(addresses[i], 0x2000);
-      if (!p)
-	continue;
-#if DEBUG_DETECT
-      printk( " %lx(%lx),", addresses[i], bios_base );
-#endif
-      for (j = 0; j < SIGNATURE_COUNT; j++) {
-	 if (check_signature(p + signatures[j].sig_offset,
-			     signatures[j].signature,
-			     signatures[j].sig_length )) {
-	    bios_major = signatures[j].major_bios_version;
-	    bios_minor = signatures[j].minor_bios_version;
-	    PCI_bus    = (signatures[j].flag == 1);
-	    Quantum    = (signatures[j].flag > 1) ? signatures[j].flag : 0;
-	    bios_base  = addresses[i];
-	    bios_mem   = p;
-	    goto found;
-	 }
-      }
-      iounmap(p);
-   }
- 
-found:
-   if (bios_major == 2) {
-      /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
-	 Assuming the ROM is enabled (otherwise we wouldn't have been
-	 able to read the ROM signature :-), then the ROM sets up the
-	 RAM area with some magic numbers, such as a list of port
-	 base addresses and a list of the disk "geometry" reported to
-	 DOS (this geometry has nothing to do with physical geometry).
-       */
-
-      switch (Quantum) {
-      case 2:			/* ISA_200S */
-      case 3:			/* ISA_250MG */
-	 base = readb(bios_mem + 0x1fa2) + (readb(bios_mem + 0x1fa3) << 8);
-	 break;
-      case 4:			/* ISA_200S (another one) */
-	 base = readb(bios_mem + 0x1fa3) + (readb(bios_mem + 0x1fa4) << 8);
-	 break;
-      default:
-	 base = readb(bios_mem + 0x1fcc) + (readb(bios_mem + 0x1fcd) << 8);
-	 break;
-      }
-   
-#if DEBUG_DETECT
-      printk( " %x,", base );
-#endif
-
-      for (i = 0; i < PORT_COUNT; i++) {
-	if (base == ports[i]) {
-		if (!request_region(base, 0x10, "fdomain"))
-			break;
-		if (!fdomain_is_valid_port(base)) {
-			release_region(base, 0x10);
-			break;
-		}
-		*irq    = fdomain_get_irq( base );
-		*iobase = base;
-		return 1;
-	}
-      }
-
-      /* This is a bad sign.  It usually means that someone patched the
-	 BIOS signature list (the signatures variable) to contain a BIOS
-	 signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */
-      
-#if DEBUG_DETECT
-      printk( " RAM FAILED, " );
-#endif
-   }
-
-   /* Anyway, the alternative to finding the address in the RAM is to just
-      search through every possible port address for one that is attached
-      to the Future Domain card.  Don't panic, though, about reading all
-      these random port addresses -- there are rumors that the Future
-      Domain BIOS does something very similar.
-
-      Do not, however, check ports which the kernel knows are being used by
-      another driver. */
-
-   for (i = 0; i < PORT_COUNT; i++) {
-      base = ports[i];
-      if (!request_region(base, 0x10, "fdomain")) {
-#if DEBUG_DETECT
-	 printk( " (%x inuse),", base );
-#endif
-	 continue;
-      }
-#if DEBUG_DETECT
-      printk( " %x,", base );
-#endif
-      flag = fdomain_is_valid_port(base);
-      if (flag)
-	break;
-      release_region(base, 0x10);
-   }
-
-#if DEBUG_DETECT
-   if (flag) printk( " SUCCESS\n" );
-   else      printk( " FAILURE\n" );
-#endif
-
-   if (!flag) return 0;		/* iobase not found */
-
-   *irq    = fdomain_get_irq( base );
-   *iobase = base;
-
-   return 1;			/* success */
-}
-
-#else /* PCMCIA */
-
-static int fdomain_isa_detect( int *irq, int *iobase )
-{
-	if (irq)
-		*irq = 0;
-	if (iobase)
-		*iobase = 0;
-	return 0;
-}
-
-#endif /* !PCMCIA */
-
-
-/* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
-   iobase) This function gets the Interrupt Level and I/O base address from
-   the PCI configuration registers. */
-
-#ifdef CONFIG_PCI
-static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_pdev )
-{
-   unsigned int     pci_irq;                /* PCI interrupt line */
-   unsigned long    pci_base;               /* PCI I/O base address */
-   struct pci_dev   *pdev = NULL;
-
-#if DEBUG_DETECT
-   /* Tell how to print a list of the known PCI devices from bios32 and
-      list vendor and device IDs being used if in debug mode.  */
-      
-   printk( "scsi: <fdomain> INFO: use lspci -v to see list of PCI devices\n" );
-   printk( "scsi: <fdomain> TMC-3260 detect:"
-	   " Using Vendor ID: 0x%x and Device ID: 0x%x\n",
-	   PCI_VENDOR_ID_FD, 
-	   PCI_DEVICE_ID_FD_36C70 );
-#endif 
-
-   if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
-		return 0;
-   if (pci_enable_device(pdev))
-   	goto fail;
-       
-#if DEBUG_DETECT
-   printk( "scsi: <fdomain> TMC-3260 detect:"
-	   " PCI bus %u, device %u, function %u\n",
-	   pdev->bus->number,
-	   PCI_SLOT(pdev->devfn),
-	   PCI_FUNC(pdev->devfn));
-#endif
-
-   /* We now have the appropriate device function for the FD board so we
-      just read the PCI config info from the registers.  */
-
-   pci_base = pci_resource_start(pdev, 0);
-   pci_irq = pdev->irq;
-
-   if (!request_region( pci_base, 0x10, "fdomain" ))
-   	goto fail;
-
-   /* Now we have the I/O base address and interrupt from the PCI
-      configuration registers. */
-
-   *irq    = pci_irq;
-   *iobase = pci_base;
-   *ret_pdev = pdev;
-
-#if DEBUG_DETECT
-   printk( "scsi: <fdomain> TMC-3260 detect:"
-	   " IRQ = %d, I/O base = 0x%x [0x%lx]\n", *irq, *iobase, pci_base );
-#endif
-
-   if (!fdomain_is_valid_port(pci_base)) {
-      printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" );
-      release_region(pci_base, 0x10);
-      goto fail;
-   }
-
-				/* Fill in a few global variables.  Ugh. */
-   bios_major = bios_minor = -1;
-   PCI_bus    = 1;
-   PCI_dev    = pdev;
-   Quantum    = 0;
-   bios_base  = 0;
-   
-   return 1;
-fail:
-   pci_dev_put(pdev);
-   return 0;
-}
-
-#endif
-
-struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt )
-{
-   int              retcode;
-   struct Scsi_Host *shpnt;
-   struct pci_dev *pdev = NULL;
-
-   if (setup_called) {
-#if DEBUG_DETECT
-      printk( "scsi: <fdomain> No BIOS, using port_base = 0x%x, irq = %d\n",
-	      port_base, interrupt_level );
-#endif
-      if (!request_region(port_base, 0x10, "fdomain")) {
-	 printk( "scsi: <fdomain> port 0x%x is busy\n", port_base );
-	 printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
-	 return NULL;
-      }
-      if (!fdomain_is_valid_port( port_base )) {
-	 printk( "scsi: <fdomain> Cannot locate chip at port base 0x%x\n",
-		 port_base );
-	 printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
-	 release_region(port_base, 0x10);
-	 return NULL;
-      }
-   } else {
-      int flag = 0;
-
-#ifdef CONFIG_PCI
-				/* Try PCI detection first */
-      flag = fdomain_pci_bios_detect( &interrupt_level, &port_base, &pdev );
-#endif
-      if (!flag) {
-				/* Then try ISA bus detection */
-	 flag = fdomain_isa_detect( &interrupt_level, &port_base );
-
-	 if (!flag) {
-	    printk( "scsi: <fdomain> Detection failed (no card)\n" );
-	    return NULL;
-	 }
-      }
-   }
-
-   fdomain_16x0_host_reset(NULL);
-
-   if (fdomain_test_loopback()) {
-      printk(KERN_ERR  "scsi: <fdomain> Detection failed (loopback test failed at port base 0x%x)\n", port_base);
-      if (setup_called) {
-	 printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
-      }
-      goto fail;
-   }
-
-   if (this_id) {
-      tpnt->this_id = (this_id & 0x07);
-      adapter_mask  = (1 << tpnt->this_id);
-   } else {
-      if (PCI_bus || (bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
-	 tpnt->this_id = 7;
-	 adapter_mask  = 0x80;
-      } else {
-	 tpnt->this_id = 6;
-	 adapter_mask  = 0x40;
-      }
-   }
-
-/* Print out a banner here in case we can't
-   get resources.  */
-
-   shpnt = scsi_register( tpnt, 0 );
-   if(shpnt == NULL) {
-	release_region(port_base, 0x10);
-   	return NULL;
-   }
-   shpnt->irq = interrupt_level;
-   shpnt->io_port = port_base;
-   shpnt->n_io_port = 0x10;
-   print_banner( shpnt );
-
-   /* Log IRQ with kernel */   
-   if (!interrupt_level) {
-      printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" );
-      goto fail;
-   } else {
-      /* Register the IRQ with the kernel */
-
-      retcode = request_irq( interrupt_level,
-			     do_fdomain_16x0_intr, pdev?IRQF_SHARED:0, "fdomain", shpnt);
-
-      if (retcode < 0) {
-	 if (retcode == -EINVAL) {
-	    printk(KERN_ERR "scsi: <fdomain> IRQ %d is bad!\n", interrupt_level );
-	    printk(KERN_ERR "                This shouldn't happen!\n" );
-	    printk(KERN_ERR "                Send mail to faith@acm.org\n" );
-	 } else if (retcode == -EBUSY) {
-	    printk(KERN_ERR "scsi: <fdomain> IRQ %d is already in use!\n", interrupt_level );
-	    printk(KERN_ERR "                Please use another IRQ!\n" );
-	 } else {
-	    printk(KERN_ERR "scsi: <fdomain> Error getting IRQ %d\n", interrupt_level );
-	    printk(KERN_ERR "                This shouldn't happen!\n" );
-	    printk(KERN_ERR "                Send mail to faith@acm.org\n" );
-	 }
-	 printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" );
-	 goto fail;
-      }
-   }
-   return shpnt;
-fail:
-   pci_dev_put(pdev);
-   release_region(port_base, 0x10);
-   return NULL;
-}
-
-static int fdomain_16x0_detect(struct scsi_host_template *tpnt)
-{
-	if (fdomain)
-		fdomain_setup(fdomain);
-	return (__fdomain_16x0_detect(tpnt) != NULL);
-}
-
-static const char *fdomain_16x0_info( struct Scsi_Host *ignore )
-{
-   static char buffer[128];
-   char        *pt;
-   
-   strcpy( buffer, "Future Domain 16-bit SCSI Driver Version" );
-   if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
-      strcat( buffer, strchr( VERSION, ':' ) + 1 );
-      pt = strrchr( buffer, '$') - 1;
-      if (!pt)  		/* Stripped RCS Revision string? */
-	    pt = buffer + strlen( buffer ) - 1;
-      if (*pt != ' ')
-	    ++pt;
-      *pt = '\0';
-   } else {			/* Assume VERSION is a number */
-      strcat( buffer, " " VERSION );
-   }
-      
-   return buffer;
-}
-
-#if 0
-static int fdomain_arbitrate( void )
-{
-   int           status = 0;
-   unsigned long timeout;
-
-#if EVERY_ACCESS
-   printk( "fdomain_arbitrate()\n" );
-#endif
-   
-   outb(0x00, port_base + SCSI_Cntl);              /* Disable data drivers */
-   outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */
-   outb(0x04 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
-
-   timeout = 500;
-   do {
-      status = inb(port_base + TMC_Status);        /* Read adapter status */
-      if (status & 0x02)		      /* Arbitration complete */
-	    return 0;
-      mdelay(1);			/* Wait one millisecond */
-   } while (--timeout);
-
-   /* Make bus idle */
-   fdomain_make_bus_idle();
-
-#if EVERY_ACCESS
-   printk( "Arbitration failed, status = %x\n", status );
-#endif
-#if ERRORS_ONLY
-   printk( "scsi: <fdomain> Arbitration failed, status = %x\n", status );
-#endif
-   return 1;
-}
-#endif
-
-static int fdomain_select( int target )
-{
-   int           status;
-   unsigned long timeout;
-#if ERRORS_ONLY
-   static int    flag = 0;
-#endif
-
-   outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
-   outb(adapter_mask | (1 << target), port_base + SCSI_Data_NoACK);
-
-   /* Stop arbitration and enable parity */
-   outb(PARITY_MASK, port_base + TMC_Cntl); 
-
-   timeout = 350;			/* 350 msec */
-
-   do {
-      status = inb(port_base + SCSI_Status); /* Read adapter status */
-      if (status & 1) {			/* Busy asserted */
-	 /* Enable SCSI Bus (on error, should make bus idle with 0) */
-	 outb(0x80, port_base + SCSI_Cntl);
-	 return 0;
-      }
-      mdelay(1);			/* wait one msec */
-   } while (--timeout);
-   /* Make bus idle */
-   fdomain_make_bus_idle();
-#if EVERY_ACCESS
-   if (!target) printk( "Selection failed\n" );
-#endif
-#if ERRORS_ONLY
-   if (!target) {
-      if (!flag) /* Skip first failure for all chips. */
-	    ++flag;
-      else
-	    printk( "scsi: <fdomain> Selection failed\n" );
-   }
-#endif
-   return 1;
-}
-
-static void my_done(int error)
-{
-   if (in_command) {
-      in_command = 0;
-      outb(0x00, port_base + Interrupt_Cntl);
-      fdomain_make_bus_idle();
-      current_SC->result = error;
-      if (current_SC->scsi_done)
-	    current_SC->scsi_done( current_SC );
-      else panic( "scsi: <fdomain> current_SC->scsi_done() == NULL" );
-   } else {
-      panic( "scsi: <fdomain> my_done() called outside of command\n" );
-   }
-#if DEBUG_RACE
-   in_interrupt_flag = 0;
-#endif
-}
-
-static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
-{
-   unsigned long flags;
-   int      status;
-   int      done = 0;
-   unsigned data_count;
-
-				/* The fdomain_16x0_intr is only called via
-				   the interrupt handler.  The goal of the
-				   sti() here is to allow other
-				   interruptions while this routine is
-				   running. */
-
-   /* Check for other IRQ sources */
-   if ((inb(port_base + TMC_Status) & 0x01) == 0)
-   	return IRQ_NONE;
-
-   /* It is our IRQ */   	
-   outb(0x00, port_base + Interrupt_Cntl);
-
-   /* We usually have one spurious interrupt after each command.  Ignore it. */
-   if (!in_command || !current_SC) {	/* Spurious interrupt */
-#if EVERY_ACCESS
-      printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
-	      in_command, current_SC );
-#endif
-      return IRQ_NONE;
-   }
-
-   /* Abort calls my_done, so we do nothing here. */
-   if (current_SC->SCp.phase & aborted) {
-#if DEBUG_ABORT
-      printk( "scsi: <fdomain> Interrupt after abort, ignoring\n" );
-#endif
-      /*
-      return IRQ_HANDLED; */
-   }
-
-#if DEBUG_RACE
-   ++in_interrupt_flag;
-#endif
-
-   if (current_SC->SCp.phase & in_arbitration) {
-      status = inb(port_base + TMC_Status);        /* Read adapter status */
-      if (!(status & 0x02)) {
-#if EVERY_ACCESS
-	 printk( " AFAIL " );
-#endif
-         spin_lock_irqsave(current_SC->device->host->host_lock, flags);
-	 my_done( DID_BUS_BUSY << 16 );
-         spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
-	 return IRQ_HANDLED;
-      }
-      current_SC->SCp.phase = in_selection;
-      
-      outb(0x40 | FIFO_COUNT, port_base + Interrupt_Cntl);
-
-      outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
-      outb(adapter_mask | (1 << scmd_id(current_SC)), port_base + SCSI_Data_NoACK);
-      
-      /* Stop arbitration and enable parity */
-      outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
-#if DEBUG_RACE
-      in_interrupt_flag = 0;
-#endif
-      return IRQ_HANDLED;
-   } else if (current_SC->SCp.phase & in_selection) {
-      status = inb(port_base + SCSI_Status);
-      if (!(status & 0x01)) {
-	 /* Try again, for slow devices */
-	 if (fdomain_select( scmd_id(current_SC) )) {
-#if EVERY_ACCESS
-	    printk( " SFAIL " );
-#endif
-            spin_lock_irqsave(current_SC->device->host->host_lock, flags);
-	    my_done( DID_NO_CONNECT << 16 );
-            spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
-	    return IRQ_HANDLED;
-	 } else {
-#if EVERY_ACCESS
-	    printk( " AltSel " );
-#endif
-	    /* Stop arbitration and enable parity */
-	    outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
-	 }
-      }
-      current_SC->SCp.phase = in_other;
-      outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl);
-      outb(0x80, port_base + SCSI_Cntl);
-#if DEBUG_RACE
-      in_interrupt_flag = 0;
-#endif
-      return IRQ_HANDLED;
-   }
-   
-   /* current_SC->SCp.phase == in_other: this is the body of the routine */
-   
-   status = inb(port_base + SCSI_Status);
-   
-   if (status & 0x10) {	/* REQ */
-      
-      switch (status & 0x0e) {
-       
-      case 0x08:		/* COMMAND OUT */
-	 outb(current_SC->cmnd[current_SC->SCp.sent_command++],
-	      port_base + Write_SCSI_Data);
-#if EVERY_ACCESS
-	 printk( "CMD = %x,",
-		 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
-#endif
-	 break;
-      case 0x00:		/* DATA OUT -- tmc18c50/tmc18c30 only */
-	 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
-	    current_SC->SCp.have_data_in = -1;
-	    outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl);
-	 }
-	 break;
-      case 0x04:		/* DATA IN -- tmc18c50/tmc18c30 only */
-	 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
-	    current_SC->SCp.have_data_in = 1;
-	    outb(0x90 | PARITY_MASK, port_base + TMC_Cntl);
-	 }
-	 break;
-      case 0x0c:		/* STATUS IN */
-	 current_SC->SCp.Status = inb(port_base + Read_SCSI_Data);
-#if EVERY_ACCESS
-	 printk( "Status = %x, ", current_SC->SCp.Status );
-#endif
-#if ERRORS_ONLY
-	 if (current_SC->SCp.Status
-	     && current_SC->SCp.Status != 2
-	     && current_SC->SCp.Status != 8) {
-	    printk( "scsi: <fdomain> target = %d, command = %x, status = %x\n",
-		    current_SC->device->id,
-		    current_SC->cmnd[0],
-		    current_SC->SCp.Status );
-	 }
-#endif
-	       break;
-      case 0x0a:		/* MESSAGE OUT */
-	 outb(MESSAGE_REJECT, port_base + Write_SCSI_Data); /* Reject */
-	 break;
-      case 0x0e:		/* MESSAGE IN */
-	 current_SC->SCp.Message = inb(port_base + Read_SCSI_Data);
-#if EVERY_ACCESS
-	 printk( "Message = %x, ", current_SC->SCp.Message );
-#endif
-	 if (!current_SC->SCp.Message) ++done;
-#if DEBUG_MESSAGES || EVERY_ACCESS
-	 if (current_SC->SCp.Message) {
-	    printk( "scsi: <fdomain> message = %x\n",
-		    current_SC->SCp.Message );
-	 }
-#endif
-	 break;
-      }
-   }
-
-   if (chip == tmc1800 && !current_SC->SCp.have_data_in
-       && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {
-      
-      if(current_SC->sc_data_direction == DMA_TO_DEVICE)
-      {
-	 current_SC->SCp.have_data_in = -1;
-	 outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl);
-      }
-      else
-      {
-	 current_SC->SCp.have_data_in = 1;
-	 outb(0x90 | PARITY_MASK, port_base + TMC_Cntl);
-      }
-   }
-
-   if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
-      while ((data_count = FIFO_Size - inw(port_base + FIFO_Data_Count)) > 512) {
-#if EVERY_ACCESS
-	 printk( "DC=%d, ", data_count ) ;
-#endif
-	 if (data_count > current_SC->SCp.this_residual)
-	       data_count = current_SC->SCp.this_residual;
-	 if (data_count > 0) {
-#if EVERY_ACCESS
-	    printk( "%d OUT, ", data_count );
-#endif
-	    if (data_count == 1) {
-	       outb(*current_SC->SCp.ptr++, port_base + Write_FIFO);
-	       --current_SC->SCp.this_residual;
-	    } else {
-	       data_count >>= 1;
-	       outsw(port_base + Write_FIFO, current_SC->SCp.ptr, data_count);
-	       current_SC->SCp.ptr += 2 * data_count;
-	       current_SC->SCp.this_residual -= 2 * data_count;
-	    }
-	 }
-	 if (!current_SC->SCp.this_residual) {
-	    if (current_SC->SCp.buffers_residual) {
-	       --current_SC->SCp.buffers_residual;
-	       ++current_SC->SCp.buffer;
-	       current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
-	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
-	    } else
-		  break;
-	 }
-      }
-   }
-   
-   if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
-      while ((data_count = inw(port_base + FIFO_Data_Count)) > 0) {
-#if EVERY_ACCESS
-	 printk( "DC=%d, ", data_count );
-#endif
-	 if (data_count > current_SC->SCp.this_residual)
-	       data_count = current_SC->SCp.this_residual;
-	 if (data_count) {
-#if EVERY_ACCESS
-	    printk( "%d IN, ", data_count );
-#endif
-	    if (data_count == 1) {
-	       *current_SC->SCp.ptr++ = inb(port_base + Read_FIFO);
-	       --current_SC->SCp.this_residual;
-	    } else {
-	       data_count >>= 1; /* Number of words */
-	       insw(port_base + Read_FIFO, current_SC->SCp.ptr, data_count);
-	       current_SC->SCp.ptr += 2 * data_count;
-	       current_SC->SCp.this_residual -= 2 * data_count;
-	    }
-	 }
-	 if (!current_SC->SCp.this_residual
-	     && current_SC->SCp.buffers_residual) {
-	    --current_SC->SCp.buffers_residual;
-	    ++current_SC->SCp.buffer;
-	    current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
-	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
-	 }
-      }
-   }
-   
-   if (done) {
-#if EVERY_ACCESS
-      printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
-#endif
-
-#if ERRORS_ONLY
-      if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
-	      char *buf = scsi_sglist(current_SC);
-	 if ((unsigned char)(*(buf + 2)) & 0x0f) {
-	    unsigned char key;
-	    unsigned char code;
-	    unsigned char qualifier;
-
-	    key = (unsigned char)(*(buf + 2)) & 0x0f;
-	    code = (unsigned char)(*(buf + 12));
-	    qualifier = (unsigned char)(*(buf + 13));
-
-	    if (key != UNIT_ATTENTION
-		&& !(key == NOT_READY
-		     && code == 0x04
-		     && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
-		&& !(key == ILLEGAL_REQUEST && (code == 0x25
-						|| code == 0x24
-						|| !code)))
-		  
-		  printk( "scsi: <fdomain> REQUEST SENSE"
-			  " Key = %x, Code = %x, Qualifier = %x\n",
-			  key, code, qualifier );
-	 }
-      }
-#endif
-#if EVERY_ACCESS
-      printk( "BEFORE MY_DONE. . ." );
-#endif
-      spin_lock_irqsave(current_SC->device->host->host_lock, flags);
-      my_done( (current_SC->SCp.Status & 0xff)
-	       | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
-      spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
-#if EVERY_ACCESS
-      printk( "RETURNING.\n" );
-#endif
-      
-   } else {
-      if (current_SC->SCp.phase & disconnect) {
-	 outb(0xd0 | FIFO_COUNT, port_base + Interrupt_Cntl);
-	 outb(0x00, port_base + SCSI_Cntl);
-      } else {
-	 outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl);
-      }
-   }
-#if DEBUG_RACE
-   in_interrupt_flag = 0;
-#endif
-   return IRQ_HANDLED;
-}
-
-static int fdomain_16x0_queue_lck(struct scsi_cmnd *SCpnt,
-		void (*done)(struct scsi_cmnd *))
-{
-   if (in_command) {
-      panic( "scsi: <fdomain> fdomain_16x0_queue() NOT REENTRANT!\n" );
-   }
-#if EVERY_ACCESS
-   printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
-	   SCpnt->target,
-	   *(unsigned char *)SCpnt->cmnd,
-	   scsi_sg_count(SCpnt),
-	   scsi_bufflen(SCpnt));
-#endif
-
-   fdomain_make_bus_idle();
-
-   current_SC            = SCpnt; /* Save this for the done function */
-   current_SC->scsi_done = done;
-
-   /* Initialize static data */
-
-   if (scsi_sg_count(current_SC)) {
-	   current_SC->SCp.buffer = scsi_sglist(current_SC);
-	   current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
-	   current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
-	   current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
-   } else {
-	   current_SC->SCp.ptr              = NULL;
-	   current_SC->SCp.this_residual    = 0;
-	   current_SC->SCp.buffer           = NULL;
-	   current_SC->SCp.buffers_residual = 0;
-   }
-
-   current_SC->SCp.Status              = 0;
-   current_SC->SCp.Message             = 0;
-   current_SC->SCp.have_data_in        = 0;
-   current_SC->SCp.sent_command        = 0;
-   current_SC->SCp.phase               = in_arbitration;
-
-   /* Start arbitration */
-   outb(0x00, port_base + Interrupt_Cntl);
-   outb(0x00, port_base + SCSI_Cntl);              /* Disable data drivers */
-   outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */
-   ++in_command;
-   outb(0x20, port_base + Interrupt_Cntl);
-   outb(0x14 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
-
-   return 0;
-}
-
-static DEF_SCSI_QCMD(fdomain_16x0_queue)
-
-#if DEBUG_ABORT
-static void print_info(struct scsi_cmnd *SCpnt)
-{
-   unsigned int imr;
-   unsigned int irr;
-   unsigned int isr;
-
-   if (!SCpnt || !SCpnt->device || !SCpnt->device->host) {
-      printk(KERN_WARNING "scsi: <fdomain> Cannot provide detailed information\n");
-      return;
-   }
-   
-   printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->device->host ) );
-   print_banner(SCpnt->device->host);
-   switch (SCpnt->SCp.phase) {
-   case in_arbitration: printk("arbitration"); break;
-   case in_selection:   printk("selection");   break;
-   case in_other:       printk("other");       break;
-   default:             printk("unknown");     break;
-   }
-
-   printk( " (%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
-	   SCpnt->SCp.phase,
-	   SCpnt->device->id,
-	   *(unsigned char *)SCpnt->cmnd,
-	   scsi_sg_count(SCpnt),
-	   scsi_bufflen(SCpnt));
-   printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
-	   SCpnt->SCp.sent_command,
-	   SCpnt->SCp.have_data_in,
-	   SCpnt->timeout );
-#if DEBUG_RACE
-   printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
-#endif
-
-   imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
-   outb( 0x0a, 0xa0 );
-   irr = inb( 0xa0 ) << 8;
-   outb( 0x0a, 0x20 );
-   irr += inb( 0x20 );
-   outb( 0x0b, 0xa0 );
-   isr = inb( 0xa0 ) << 8;
-   outb( 0x0b, 0x20 );
-   isr += inb( 0x20 );
-
-				/* Print out interesting information */
-   printk( "IMR = 0x%04x", imr );
-   if (imr & (1 << interrupt_level))
-	 printk( " (masked)" );
-   printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
-
-   printk( "SCSI Status      = 0x%02x\n", inb(port_base + SCSI_Status));
-   printk( "TMC Status       = 0x%02x", inb(port_base + TMC_Status));
-   if (inb((port_base + TMC_Status) & 1))
-	 printk( " (interrupt)" );
-   printk( "\n" );
-   printk("Interrupt Status = 0x%02x", inb(port_base + Interrupt_Status));
-   if (inb(port_base + Interrupt_Status) & 0x08)
-	 printk( " (enabled)" );
-   printk( "\n" );
-   if (chip == tmc18c50 || chip == tmc18c30) {
-      printk("FIFO Status      = 0x%02x\n", inb(port_base + FIFO_Status));
-      printk( "Int. Condition   = 0x%02x\n",
-	      inb( port_base + Interrupt_Cond ) );
-   }
-   printk( "Configuration 1  = 0x%02x\n", inb( port_base + Configuration1 ) );
-   if (chip == tmc18c50 || chip == tmc18c30)
-	 printk( "Configuration 2  = 0x%02x\n",
-		 inb( port_base + Configuration2 ) );
-}
-#endif
-
-static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt)
-{
-#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
-   printk( "scsi: <fdomain> abort " );
-#endif
-
-   if (!in_command) {
-#if EVERY_ACCESS || ERRORS_ONLY
-      printk( " (not in command)\n" );
-#endif
-      return FAILED;
-   } else printk( "\n" );
-
-#if DEBUG_ABORT
-   print_info( SCpnt );
-#endif
-
-   fdomain_make_bus_idle();
-   current_SC->SCp.phase |= aborted;
-   current_SC->result = DID_ABORT << 16;
-   
-   /* Aborts are not done well. . . */
-   my_done(DID_ABORT << 16);
-   return SUCCESS;
-}
-
-int fdomain_16x0_host_reset(struct scsi_cmnd *SCpnt)
-{
-   unsigned long flags;
-
-   local_irq_save(flags);
-
-   outb(1, port_base + SCSI_Cntl);
-   do_pause( 2 );
-   outb(0, port_base + SCSI_Cntl);
-   do_pause( 115 );
-   outb(0, port_base + SCSI_Mode_Cntl);
-   outb(PARITY_MASK, port_base + TMC_Cntl);
-
-   local_irq_restore(flags);
-   return SUCCESS;
-}
-
-static int fdomain_16x0_biosparam(struct scsi_device *sdev,
-		struct block_device *bdev,
-		sector_t capacity, int *info_array)
-{
-   int              drive;
-   int		    size      = capacity;
-   unsigned long    offset;
-   struct drive_info {
-      unsigned short cylinders;
-      unsigned char  heads;
-      unsigned char  sectors;
-   } i;
-   
-   /* NOTES:
-      The RAM area starts at 0x1f00 from the bios_base address.
-
-      For BIOS Version 2.0:
-      
-      The drive parameter table seems to start at 0x1f30.
-      The first byte's purpose is not known.
-      Next is the cylinder, head, and sector information.
-      The last 4 bytes appear to be the drive's size in sectors.
-      The other bytes in the drive parameter table are unknown.
-      If anyone figures them out, please send me mail, and I will
-      update these notes.
-
-      Tape drives do not get placed in this table.
-
-      There is another table at 0x1fea:
-      If the byte is 0x01, then the SCSI ID is not in use.
-      If the byte is 0x18 or 0x48, then the SCSI ID is in use,
-      although tapes don't seem to be in this table.  I haven't
-      seen any other numbers (in a limited sample).
-
-      0x1f2d is a drive count (i.e., not including tapes)
-
-      The table at 0x1fcc are I/O ports addresses for the various
-      operations.  I calculate these by hand in this driver code.
-
-      
-      
-      For the ISA-200S version of BIOS Version 2.0:
-
-      The drive parameter table starts at 0x1f33.
-
-      WARNING: Assume that the table entry is 25 bytes long.  Someone needs
-      to check this for the Quantum ISA-200S card.
-
-      
-      
-      For BIOS Version 3.2:
-
-      The drive parameter table starts at 0x1f70.  Each entry is
-      0x0a bytes long.  Heads are one less than we need to report.
-    */
-
-   if (MAJOR(bdev->bd_dev) != SCSI_DISK0_MAJOR) {
-      printk("scsi: <fdomain> fdomain_16x0_biosparam: too many disks");
-      return 0;
-   }
-   drive = MINOR(bdev->bd_dev) >> 4;
-
-   if (bios_major == 2) {
-      switch (Quantum) {
-      case 2:			/* ISA_200S */
-				/* The value of 25 has never been verified.
-				   It should probably be 15. */
-	 offset = 0x1f33 + drive * 25;
-	 break;
-      case 3:			/* ISA_250MG */
-	 offset = 0x1f36 + drive * 15;
-	 break;
-      case 4:			/* ISA_200S (another one) */
-	 offset = 0x1f34 + drive * 15;
-	 break;
-      default:
-	 offset = 0x1f31 + drive * 25;
-	 break;
-      }
-      memcpy_fromio( &i, bios_mem + offset, sizeof( struct drive_info ) );
-      info_array[0] = i.heads;
-      info_array[1] = i.sectors;
-      info_array[2] = i.cylinders;
-   } else if (bios_major == 3
-	      && bios_minor >= 0
-	      && bios_minor < 4) { /* 3.0 and 3.2 BIOS */
-      memcpy_fromio( &i, bios_mem + 0x1f71 + drive * 10,
-		     sizeof( struct drive_info ) );
-      info_array[0] = i.heads + 1;
-      info_array[1] = i.sectors;
-      info_array[2] = i.cylinders;
-   } else {			/* 3.4 BIOS (and up?) */
-      /* This algorithm was provided by Future Domain (much thanks!). */
-      unsigned char *p = scsi_bios_ptable(bdev);
-
-      if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
-	  && p[4]) {			    /* Partition type */
-
-	 /* The partition table layout is as follows:
-
-	    Start: 0x1b3h
-	    Offset: 0 = partition status
-		    1 = starting head
-		    2 = starting sector and cylinder (word, encoded)
-		    4 = partition type
-		    5 = ending head
-		    6 = ending sector and cylinder (word, encoded)
-		    8 = starting absolute sector (double word)
-		    c = number of sectors (double word)
-	    Signature: 0x1fe = 0x55aa
-
-	    So, this algorithm assumes:
-	    1) the first partition table is in use,
-	    2) the data in the first entry is correct, and
-	    3) partitions never divide cylinders
-
-	    Note that (1) may be FALSE for NetBSD (and other BSD flavors),
-	    as well as for Linux.  Note also, that Linux doesn't pay any
-	    attention to the fields that are used by this algorithm -- it
-	    only uses the absolute sector data.  Recent versions of Linux's
-	    fdisk(1) will fill this data in correctly, and forthcoming
-	    versions will check for consistency.
-
-	    Checking for a non-zero partition type is not part of the
-	    Future Domain algorithm, but it seemed to be a reasonable thing
-	    to do, especially in the Linux and BSD worlds. */
-
-	 info_array[0] = p[5] + 1;	    /* heads */
-	 info_array[1] = p[6] & 0x3f;	    /* sectors */
-      } else {
-
- 	 /* Note that this new method guarantees that there will always be
-	    less than 1024 cylinders on a platter.  This is good for drives
-	    up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
-
-	 if ((unsigned int)size >= 0x7e0000U) {
-	    info_array[0] = 0xff; /* heads   = 255 */
-	    info_array[1] = 0x3f; /* sectors =  63 */
-	 } else if ((unsigned int)size >= 0x200000U) {
-	    info_array[0] = 0x80; /* heads   = 128 */
-	    info_array[1] = 0x3f; /* sectors =  63 */
-	 } else {
-	    info_array[0] = 0x40; /* heads   =  64 */
-	    info_array[1] = 0x20; /* sectors =  32 */
-	 }
-      }
-				/* For both methods, compute the cylinders */
-      info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
-      kfree(p);
-   }
-   
-   return 0;
-}
-
-static int fdomain_16x0_release(struct Scsi_Host *shpnt)
-{
-	if (shpnt->irq)
-		free_irq(shpnt->irq, shpnt);
-	if (shpnt->io_port && shpnt->n_io_port)
-		release_region(shpnt->io_port, shpnt->n_io_port);
-	if (PCI_bus)
-		pci_dev_put(PCI_dev);
-	return 0;
-}
-
-struct scsi_host_template fdomain_driver_template = {
-	.module			= THIS_MODULE,
-	.name			= "fdomain",
-	.proc_name		= "fdomain",
-	.detect			= fdomain_16x0_detect,
-	.info			= fdomain_16x0_info,
-	.queuecommand		= fdomain_16x0_queue,
-	.eh_abort_handler	= fdomain_16x0_abort,
-	.eh_host_reset_handler	= fdomain_16x0_host_reset,
-	.bios_param		= fdomain_16x0_biosparam,
-	.release		= fdomain_16x0_release,
-	.can_queue		= 1,
-	.this_id		= 6,
-	.sg_tablesize		= 64,
-	.use_clustering		= DISABLE_CLUSTERING,
-};
-
-#ifndef PCMCIA
-#if defined(CONFIG_PCI) && defined(MODULE)
-
-static struct pci_device_id fdomain_pci_tbl[] = {
-	{ PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl);
-#endif
-#define driver_template fdomain_driver_template
-#include "scsi_module.c"
-
-#endif
diff --git a/drivers/scsi/fdomain.h b/drivers/scsi/fdomain.h
deleted file mode 100644
index 5cbe86b..0000000
--- a/drivers/scsi/fdomain.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * fdomain.c -- Future Domain TMC-16x0 SCSI driver
- * Author: Rickard E. Faith, faith@cs.unc.edu
- * Copyright 1992-1996, 1998 Rickard E. Faith (faith@acm.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, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-extern struct scsi_host_template fdomain_driver_template;
-extern int fdomain_setup(char *str);
-extern struct Scsi_Host *__fdomain_16x0_detect(struct  scsi_host_template *tpnt );
-extern int fdomain_16x0_host_reset(struct scsi_cmnd *SCpnt);
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
index 95fc720..e6e5ccb 100644
--- a/drivers/scsi/gdth.h
+++ b/drivers/scsi/gdth.h
@@ -178,9 +178,6 @@
 #define MSG_SIZE        34                      /* size of message structure */
 #define MSG_REQUEST     0                       /* async. event: message */
 
-/* cacheservice defines */
-#define SECTOR_SIZE     0x200                   /* always 512 bytes per sec. */
-
 /* DPMEM constants */
 #define DPMEM_MAGIC     0xC0FFEE11
 #define IC_HEADER_BYTES 48
diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig
index d42f29a..57183fc 100644
--- a/drivers/scsi/hisi_sas/Kconfig
+++ b/drivers/scsi/hisi_sas/Kconfig
@@ -1,6 +1,6 @@
 config SCSI_HISI_SAS
 	tristate "HiSilicon SAS"
-	depends on HAS_DMA && HAS_IOMEM
+	depends on HAS_IOMEM
 	depends on ARM64 || COMPILE_TEST
 	select SCSI_SAS_LIBSAS
 	select BLK_DEV_INTEGRITY
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index e7fd287..d1153e8 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -175,7 +175,6 @@ struct hisi_sas_device {
 	struct hisi_sas_dq	*dq;
 	struct list_head	list;
 	u64 attached_phy;
-	atomic64_t running_req;
 	enum sas_device_type	dev_type;
 	int device_id;
 	int sata_idx;
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 2d4dbed..49c1fa6 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -33,7 +33,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
 	case ATA_CMD_FPDMA_RECV:
 	case ATA_CMD_FPDMA_SEND:
 	case ATA_CMD_NCQ_NON_DATA:
-	return HISI_SAS_SATA_PROTOCOL_FPDMA;
+		return HISI_SAS_SATA_PROTOCOL_FPDMA;
 
 	case ATA_CMD_DOWNLOAD_MICRO:
 	case ATA_CMD_ID_ATA:
@@ -45,7 +45,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
 	case ATA_CMD_WRITE_LOG_EXT:
 	case ATA_CMD_PIO_WRITE:
 	case ATA_CMD_PIO_WRITE_EXT:
-	return HISI_SAS_SATA_PROTOCOL_PIO;
+		return HISI_SAS_SATA_PROTOCOL_PIO;
 
 	case ATA_CMD_DSM:
 	case ATA_CMD_DOWNLOAD_MICRO_DMA:
@@ -64,7 +64,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
 	case ATA_CMD_WRITE_LOG_DMA_EXT:
 	case ATA_CMD_WRITE_STREAM_DMA_EXT:
 	case ATA_CMD_ZAC_MGMT_IN:
-	return HISI_SAS_SATA_PROTOCOL_DMA;
+		return HISI_SAS_SATA_PROTOCOL_DMA;
 
 	case ATA_CMD_CHK_POWER:
 	case ATA_CMD_DEV_RESET:
@@ -77,21 +77,21 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
 	case ATA_CMD_STANDBY:
 	case ATA_CMD_STANDBYNOW1:
 	case ATA_CMD_ZAC_MGMT_OUT:
-	return HISI_SAS_SATA_PROTOCOL_NONDATA;
+		return HISI_SAS_SATA_PROTOCOL_NONDATA;
 	default:
 	{
 		if (fis->command == ATA_CMD_SET_MAX) {
 			switch (fis->features) {
 			case ATA_SET_MAX_PASSWD:
 			case ATA_SET_MAX_LOCK:
-			return HISI_SAS_SATA_PROTOCOL_PIO;
+				return HISI_SAS_SATA_PROTOCOL_PIO;
 
 			case ATA_SET_MAX_PASSWD_DMA:
 			case ATA_SET_MAX_UNLOCK_DMA:
-			return HISI_SAS_SATA_PROTOCOL_DMA;
+				return HISI_SAS_SATA_PROTOCOL_DMA;
 
 			default:
-			return HISI_SAS_SATA_PROTOCOL_NONDATA;
+				return HISI_SAS_SATA_PROTOCOL_NONDATA;
 			}
 		}
 		if (direction == DMA_NONE)
@@ -200,8 +200,6 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
 
 	if (task) {
 		struct device *dev = hisi_hba->dev;
-		struct domain_device *device = task->dev;
-		struct hisi_sas_device *sas_dev = device->lldd_dev;
 
 		if (!task->lldd_task)
 			return;
@@ -213,9 +211,6 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
 				dma_unmap_sg(dev, task->scatter,
 					     task->num_scatter,
 					     task->data_dir);
-
-		if (sas_dev)
-			atomic64_dec(&sas_dev->running_req);
 	}
 
 	if (slot->buf)
@@ -321,7 +316,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
 		 */
 		if (device->dev_type != SAS_SATA_DEV)
 			task->task_done(task);
-		return SAS_PHY_DOWN;
+		return -ECOMM;
 	}
 
 	if (DEV_IS_GONE(sas_dev)) {
@@ -332,7 +327,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
 			dev_info(dev, "task prep: device %016llx not ready\n",
 				 SAS_ADDR(device->sas_addr));
 
-		return SAS_PHY_DOWN;
+		return -ECOMM;
 	}
 
 	port = to_hisi_sas_port(sas_port);
@@ -342,7 +337,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
 			 "SATA/STP" : "SAS",
 			 device->port->id);
 
-		return SAS_PHY_DOWN;
+		return -ECOMM;
 	}
 
 	if (!sas_protocol_ata(task->task_proto)) {
@@ -431,8 +426,6 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
 	spin_unlock_irqrestore(&task->task_state_lock, flags);
 
 	dq->slot_prep = slot;
-
-	atomic64_inc(&sas_dev->running_req);
 	++(*pass);
 
 	return 0;
@@ -683,6 +676,8 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no)
 
 	phy->hisi_hba = hisi_hba;
 	phy->port = NULL;
+	phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
+	phy->maximum_linkrate = hisi_hba->hw->phy_get_max_linkrate();
 	sas_phy->enabled = (phy_no < hisi_hba->n_phy) ? 1 : 0;
 	sas_phy->class = SAS;
 	sas_phy->iproto = SAS_PROTOCOL_ALL;
@@ -869,6 +864,7 @@ static void hisi_sas_tmf_timedout(struct timer_list *t)
 
 #define TASK_TIMEOUT 20
 #define TASK_RETRY 3
+#define INTERNAL_ABORT_TIMEOUT 6
 static int hisi_sas_exec_internal_tmf_task(struct domain_device *device,
 					   void *parameter, u32 para_len,
 					   struct hisi_sas_tmf_task *tmf)
@@ -1514,8 +1510,6 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
 
 	dq->slot_prep = slot;
 
-	atomic64_inc(&sas_dev->running_req);
-
 	/* send abort command to the chip */
 	hisi_hba->hw->start_delivery(dq);
 	spin_unlock_irqrestore(&dq->lock, flags_dq);
@@ -1572,7 +1566,7 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
 	task->task_proto = device->tproto;
 	task->task_done = hisi_sas_task_done;
 	task->slow_task->timer.function = hisi_sas_tmf_timedout;
-	task->slow_task->timer.expires = jiffies + msecs_to_jiffies(110);
+	task->slow_task->timer.expires = jiffies + INTERNAL_ABORT_TIMEOUT*HZ;
 	add_timer(&task->slow_task->timer);
 
 	res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id,
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 679e76f..84a0ccc 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -651,8 +651,10 @@ static int reset_hw_v1_hw(struct hisi_hba *hisi_hba)
 			dev_err(dev, "De-reset failed\n");
 			return -EIO;
 		}
-	} else
+	} else {
 		dev_warn(dev, "no reset method\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -873,7 +875,6 @@ static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no,
 	sas_phy->phy->maximum_linkrate = max;
 	sas_phy->phy->minimum_linkrate = min;
 
-	min -= SAS_LINK_RATE_1_5_GBPS;
 	max -= SAS_LINK_RATE_1_5_GBPS;
 
 	for (i = 0; i <= max; i++)
@@ -882,10 +883,11 @@ static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no,
 	prog_phy_link_rate &= ~0xff;
 	prog_phy_link_rate |= rate_mask;
 
+	disable_phy_v1_hw(hisi_hba, phy_no);
+	msleep(100);
 	hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
 			prog_phy_link_rate);
-
-	phy_hard_reset_v1_hw(hisi_hba, phy_no);
+	start_phy_v1_hw(hisi_hba, phy_no);
 }
 
 static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id)
@@ -1407,9 +1409,6 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba,
 	}
 
 out:
-	if (sas_dev)
-		atomic64_dec(&sas_dev->running_req);
-
 	hisi_sas_slot_task_free(hisi_hba, task, slot);
 	sts = ts->stat;
 
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 4ccb61e..f89fb9a 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -406,6 +406,17 @@ struct hisi_sas_err_record_v2 {
 	__le32 dma_rx_err_type;
 };
 
+struct signal_attenuation_s {
+	u32 de_emphasis;
+	u32 preshoot;
+	u32 boost;
+};
+
+struct sig_atten_lu_s {
+	const struct signal_attenuation_s *att;
+	u32 sas_phy_ctrl;
+};
+
 static const struct hisi_sas_hw_error one_bit_ecc_errors[] = {
 	{
 		.irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF),
@@ -1084,8 +1095,10 @@ static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
 			dev_err(dev, "SAS de-reset fail.\n");
 			return -EIO;
 		}
-	} else
-		dev_warn(dev, "no reset method\n");
+	} else {
+		dev_err(dev, "no reset method\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -1130,9 +1143,16 @@ static void phys_try_accept_stp_links_v2_hw(struct hisi_hba *hisi_hba)
 	}
 }
 
+static const struct signal_attenuation_s x6000 = {9200, 0, 10476};
+static const struct sig_atten_lu_s sig_atten_lu[] = {
+	{ &x6000, 0x3016a68 },
+};
+
 static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
 {
 	struct device *dev = hisi_hba->dev;
+	u32 sas_phy_ctrl = 0x30b9908;
+	u32 signal[3];
 	int i;
 
 	/* Global registers init */
@@ -1176,9 +1196,28 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
 	hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 1);
 	hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1);
 
+	/* Get sas_phy_ctrl value to deal with TX FFE issue. */
+	if (!device_property_read_u32_array(dev, "hisilicon,signal-attenuation",
+					    signal, ARRAY_SIZE(signal))) {
+		for (i = 0; i < ARRAY_SIZE(sig_atten_lu); i++) {
+			const struct sig_atten_lu_s *lookup = &sig_atten_lu[i];
+			const struct signal_attenuation_s *att = lookup->att;
+
+			if ((signal[0] == att->de_emphasis) &&
+			    (signal[1] == att->preshoot) &&
+			    (signal[2] == att->boost)) {
+				sas_phy_ctrl = lookup->sas_phy_ctrl;
+				break;
+			}
+		}
+
+		if (i == ARRAY_SIZE(sig_atten_lu))
+			dev_warn(dev, "unknown signal attenuation values, using default PHY ctrl config\n");
+	}
+
 	for (i = 0; i < hisi_hba->n_phy; i++) {
 		hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855);
-		hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, 0x30b9908);
+		hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, sas_phy_ctrl);
 		hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d);
 		hisi_sas_phy_write32(hisi_hba, i, SL_CONTROL, 0x0);
 		hisi_sas_phy_write32(hisi_hba, i, TXID_AUTO, 0x2);
@@ -1566,7 +1605,6 @@ static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no,
 	sas_phy->phy->maximum_linkrate = max;
 	sas_phy->phy->minimum_linkrate = min;
 
-	min -= SAS_LINK_RATE_1_5_GBPS;
 	max -= SAS_LINK_RATE_1_5_GBPS;
 
 	for (i = 0; i <= max; i++)
@@ -1575,10 +1613,11 @@ static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no,
 	prog_phy_link_rate &= ~0xff;
 	prog_phy_link_rate |= rate_mask;
 
+	disable_phy_v2_hw(hisi_hba, phy_no);
+	msleep(100);
 	hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
 			prog_phy_link_rate);
-
-	phy_hard_reset_v2_hw(hisi_hba, phy_no);
+	start_phy_v2_hw(hisi_hba, phy_no);
 }
 
 static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)
@@ -2371,7 +2410,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
 		spin_lock_irqsave(&hisi_hba->lock, flags);
 		hisi_sas_slot_task_free(hisi_hba, task, slot);
 		spin_unlock_irqrestore(&hisi_hba->lock, flags);
-		return -1;
+		return ts->stat;
 	}
 
 	if (unlikely(!sas_dev)) {
@@ -2630,7 +2669,7 @@ static int prep_abort_v2_hw(struct hisi_hba *hisi_hba,
 	/* dw0 */
 	hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/
 			       (port->id << CMD_HDR_PORT_OFF) |
-			       ((dev_is_sata(dev) ? 1:0) <<
+			       (dev_is_sata(dev) <<
 				CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
 			       (abort_flag << CMD_HDR_ABORT_FLAG_OFF));
 
@@ -2647,7 +2686,7 @@ static int prep_abort_v2_hw(struct hisi_hba *hisi_hba,
 static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
 {
 	int i, res = IRQ_HANDLED;
-	u32 port_id, link_rate, hard_phy_linkrate;
+	u32 port_id, link_rate;
 	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
 	struct asd_sas_phy *sas_phy = &phy->sas_phy;
 	struct device *dev = hisi_hba->dev;
@@ -2686,11 +2725,6 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
 	}
 
 	sas_phy->linkrate = link_rate;
-	hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,
-						HARD_PHY_LINKRATE);
-	phy->maximum_linkrate = hard_phy_linkrate & 0xf;
-	phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;
-
 	sas_phy->oob_mode = SAS_OOB_MODE;
 	memcpy(sas_phy->attached_sas_addr, &id->sas_addr, SAS_ADDR_SIZE);
 	dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index a1f1868..6f3e5ba 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -172,6 +172,7 @@
 #define CHL_INT1_MSK			(PORT_BASE + 0x1c4)
 #define CHL_INT2_MSK			(PORT_BASE + 0x1c8)
 #define CHL_INT_COAL_EN			(PORT_BASE + 0x1d0)
+#define SAS_RX_TRAIN_TIMER		(PORT_BASE + 0x2a4)
 #define PHY_CTRL_RDY_MSK		(PORT_BASE + 0x2b0)
 #define PHYCTRL_NOT_RDY_MSK		(PORT_BASE + 0x2b4)
 #define PHYCTRL_DWS_RESET_MSK		(PORT_BASE + 0x2b8)
@@ -184,6 +185,8 @@
 #define DMA_RX_STATUS			(PORT_BASE + 0x2e8)
 #define DMA_RX_STATUS_BUSY_OFF		0
 #define DMA_RX_STATUS_BUSY_MSK		(0x1 << DMA_RX_STATUS_BUSY_OFF)
+
+#define COARSETUNE_TIME			(PORT_BASE + 0x304)
 #define ERR_CNT_DWS_LOST		(PORT_BASE + 0x380)
 #define ERR_CNT_RESET_PROB		(PORT_BASE + 0x384)
 #define ERR_CNT_INVLD_DW		(PORT_BASE + 0x390)
@@ -340,12 +343,6 @@ struct hisi_sas_err_record_v3 {
 #define HISI_SAS_COMMAND_ENTRIES_V3_HW 4096
 #define HISI_SAS_MSI_COUNT_V3_HW 32
 
-enum {
-	HISI_SAS_PHY_PHY_UPDOWN,
-	HISI_SAS_PHY_CHNL_INT,
-	HISI_SAS_PHY_INT_NR
-};
-
 #define DIR_NO_DATA 0
 #define DIR_TO_INI 1
 #define DIR_TO_DEVICE 2
@@ -423,10 +420,10 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
 		hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0);
 
 	hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1);
-	hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE, 0x30000);
 
 	for (i = 0; i < hisi_hba->n_phy; i++) {
-		hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x801);
+		hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855);
+		hisi_sas_phy_write32(hisi_hba, i, SAS_RX_TRAIN_TIMER, 0x13e80);
 		hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff);
 		hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
 		hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff);
@@ -438,17 +435,13 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
 		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);
 		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0);
 		hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0);
-		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x0);
-		hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, 0x199b4fa);
-		hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG,
-				     0xa03e8);
-		hisi_sas_phy_write32(hisi_hba, i, SAS_STP_CON_TIMER_CFG,
-				     0xa03e8);
-		hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER,
-				     0x7f7a120);
-		hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER,
-				     0x2a0a80);
+		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1);
+		hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120);
+
+		/* used for 12G negotiate */
+		hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e);
 	}
+
 	for (i = 0; i < hisi_hba->queue_count; i++) {
 		/* Delivery queue */
 		hisi_sas_write32(hisi_hba,
@@ -676,8 +669,10 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba)
 			dev_err(dev, "Reset failed\n");
 			return -EIO;
 		}
-	} else
+	} else {
 		dev_err(dev, "no reset method!\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -737,7 +732,7 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
 	start_phy_v3_hw(hisi_hba, phy_no);
 }
 
-enum sas_linkrate phy_get_max_linkrate_v3_hw(void)
+static enum sas_linkrate phy_get_max_linkrate_v3_hw(void)
 {
 	return SAS_LINK_RATE_12_0_GBPS;
 }
@@ -1102,7 +1097,7 @@ static int prep_abort_v3_hw(struct hisi_hba *hisi_hba,
 	/* dw0 */
 	hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/
 			       (port->id << CMD_HDR_PORT_OFF) |
-				   ((dev_is_sata(dev) ? 1:0)
+				   (dev_is_sata(dev)
 					<< CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
 					(abort_flag
 					 << CMD_HDR_ABORT_FLAG_OFF));
@@ -1118,10 +1113,10 @@ static int prep_abort_v3_hw(struct hisi_hba *hisi_hba,
 	return 0;
 }
 
-static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
 {
-	int i, res = 0;
-	u32 context, port_id, link_rate, hard_phy_linkrate;
+	int i, res;
+	u32 context, port_id, link_rate;
 	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
 	struct asd_sas_phy *sas_phy = &phy->sas_phy;
 	struct device *dev = hisi_hba->dev;
@@ -1139,10 +1134,6 @@ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
 		goto end;
 	}
 	sas_phy->linkrate = link_rate;
-	hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,
-						HARD_PHY_LINKRATE);
-	phy->maximum_linkrate = hard_phy_linkrate & 0xf;
-	phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;
 	phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
 
 	/* Check for SATA dev */
@@ -1196,7 +1187,7 @@ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
 	phy->port_id = port_id;
 	phy->phy_attached = 1;
 	hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
-
+	res = IRQ_HANDLED;
 end:
 	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
 			     CHL_INT0_SL_PHY_ENABLE_MSK);
@@ -1205,7 +1196,7 @@ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
 	return res;
 }
 
-static int phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
 {
 	u32 phy_state, sl_ctrl, txid_auto;
 	struct device *dev = hisi_hba->dev;
@@ -1227,10 +1218,10 @@ static int phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
 	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_NOT_RDY_MSK);
 	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 0);
 
-	return 0;
+	return IRQ_HANDLED;
 }
 
-static void phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
 {
 	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
 	struct asd_sas_phy *sas_phy = &phy->sas_phy;
@@ -1241,6 +1232,8 @@ static void phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
 	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
 			     CHL_INT0_SL_RX_BCST_ACK_MSK);
 	hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
+
+	return IRQ_HANDLED;
 }
 
 static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p)
@@ -1267,7 +1260,9 @@ static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p)
 						res = IRQ_HANDLED;
 				if (irq_value & CHL_INT0_SL_RX_BCST_ACK_MSK)
 					/* phy bcast */
-					phy_bcast_v3_hw(phy_no, hisi_hba);
+					if (phy_bcast_v3_hw(phy_no, hisi_hba)
+							== IRQ_HANDLED)
+						res = IRQ_HANDLED;
 			} else {
 				if (irq_value & CHL_INT0_NOT_RDY_MSK)
 					/* phy down */
@@ -1583,7 +1578,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
 		spin_lock_irqsave(&hisi_hba->lock, flags);
 		hisi_sas_slot_task_free(hisi_hba, task, slot);
 		spin_unlock_irqrestore(&hisi_hba->lock, flags);
-		return -1;
+		return ts->stat;
 	}
 
 	if (unlikely(!sas_dev)) {
@@ -1864,7 +1859,6 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no,
 	sas_phy->phy->maximum_linkrate = max;
 	sas_phy->phy->minimum_linkrate = min;
 
-	min -= SAS_LINK_RATE_1_5_GBPS;
 	max -= SAS_LINK_RATE_1_5_GBPS;
 
 	for (i = 0; i <= max; i++)
@@ -1873,10 +1867,11 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no,
 	prog_phy_link_rate &= ~0xff;
 	prog_phy_link_rate |= rate_mask;
 
+	disable_phy_v3_hw(hisi_hba, phy_no);
+	msleep(100);
 	hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
 			prog_phy_link_rate);
-
-	phy_hard_reset_v3_hw(hisi_hba, phy_no);
+	start_phy_v3_hw(hisi_hba, phy_no);
 }
 
 static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba)
@@ -2399,6 +2394,7 @@ static const struct pci_device_id sas_v3_pci_table[] = {
 	{ PCI_VDEVICE(HUAWEI, 0xa230), hip08 },
 	{}
 };
+MODULE_DEVICE_TABLE(pci, sas_v3_pci_table);
 
 static const struct pci_error_handlers hisi_sas_err_handler = {
 	.error_detected	= hisi_sas_error_detected_v3_hw,
@@ -2421,4 +2417,4 @@ module_pci_driver(sas_v3_pci_driver);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
 MODULE_DESCRIPTION("HISILICON SAS controller v3 hw driver based on pci device");
-MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_ALIAS("pci:" DRV_NAME);
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index ef22b27..7649d63 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -42,6 +42,12 @@
 #include "scsi_logging.h"
 
 
+static int shost_eh_deadline = -1;
+
+module_param_named(eh_deadline, shost_eh_deadline, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(eh_deadline,
+		 "SCSI EH timeout in seconds (should be between 0 and 2^31-1)");
+
 static DEFINE_IDA(host_index_ida);
 
 
@@ -148,7 +154,6 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
 					     scsi_host_state_name(state)));
 	return -EINVAL;
 }
-EXPORT_SYMBOL(scsi_host_set_state);
 
 /**
  * scsi_remove_host - remove a scsi host
@@ -356,12 +361,6 @@ static void scsi_host_dev_release(struct device *dev)
 	kfree(shost);
 }
 
-static int shost_eh_deadline = -1;
-
-module_param_named(eh_deadline, shost_eh_deadline, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(eh_deadline,
-		 "SCSI EH timeout in seconds (should be between 0 and 2^31-1)");
-
 static struct device_type scsi_host_type = {
 	.name =		"scsi_host",
 	.release =	scsi_host_dev_release,
@@ -517,29 +516,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 }
 EXPORT_SYMBOL(scsi_host_alloc);
 
-struct Scsi_Host *scsi_register(struct scsi_host_template *sht, int privsize)
-{
-	struct Scsi_Host *shost = scsi_host_alloc(sht, privsize);
-
-	if (!sht->detect) {
-		printk(KERN_WARNING "scsi_register() called on new-style "
-				    "template for driver %s\n", sht->name);
-		dump_stack();
-	}
-
-	if (shost)
-		list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts);
-	return shost;
-}
-EXPORT_SYMBOL(scsi_register);
-
-void scsi_unregister(struct Scsi_Host *shost)
-{
-	list_del(&shost->sht_legacy_list);
-	scsi_host_put(shost);
-}
-EXPORT_SYMBOL(scsi_unregister);
-
 static int __scsi_host_match(struct device *dev, const void *data)
 {
 	struct Scsi_Host *p;
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index e07dd99..dda1a64 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3816,10 +3816,8 @@ static struct device_attribute ipr_iopoll_weight_attr = {
  **/
 static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 {
-	int sg_size, order, bsize_elem, num_elem, i, j;
+	int sg_size, order;
 	struct ipr_sglist *sglist;
-	struct scatterlist *scatterlist;
-	struct page *page;
 
 	/* Get the minimum size per scatter/gather element */
 	sg_size = buf_len / (IPR_MAX_SGLIST - 1);
@@ -3827,45 +3825,18 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 	/* Get the actual size per element */
 	order = get_order(sg_size);
 
-	/* Determine the actual number of bytes per element */
-	bsize_elem = PAGE_SIZE * (1 << order);
-
-	/* Determine the actual number of sg entries needed */
-	if (buf_len % bsize_elem)
-		num_elem = (buf_len / bsize_elem) + 1;
-	else
-		num_elem = buf_len / bsize_elem;
-
 	/* Allocate a scatter/gather list for the DMA */
-	sglist = kzalloc(sizeof(struct ipr_sglist) +
-			 (sizeof(struct scatterlist) * (num_elem - 1)),
-			 GFP_KERNEL);
-
+	sglist = kzalloc(sizeof(struct ipr_sglist), GFP_KERNEL);
 	if (sglist == NULL) {
 		ipr_trace;
 		return NULL;
 	}
-
-	scatterlist = sglist->scatterlist;
-	sg_init_table(scatterlist, num_elem);
-
 	sglist->order = order;
-	sglist->num_sg = num_elem;
-
-	/* Allocate a bunch of sg elements */
-	for (i = 0; i < num_elem; i++) {
-		page = alloc_pages(GFP_KERNEL, order);
-		if (!page) {
-			ipr_trace;
-
-			/* Free up what we already allocated */
-			for (j = i - 1; j >= 0; j--)
-				__free_pages(sg_page(&scatterlist[j]), order);
-			kfree(sglist);
-			return NULL;
-		}
-
-		sg_set_page(&scatterlist[i], page, 0, 0);
+	sglist->scatterlist = sgl_alloc_order(buf_len, order, false, GFP_KERNEL,
+					      &sglist->num_sg);
+	if (!sglist->scatterlist) {
+		kfree(sglist);
+		return NULL;
 	}
 
 	return sglist;
@@ -3883,11 +3854,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
  **/
 static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
 {
-	int i;
-
-	for (i = 0; i < sglist->num_sg; i++)
-		__free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
-
+	sgl_free_order(sglist->scatterlist, sglist->order);
 	kfree(sglist);
 }
 
@@ -9684,14 +9651,14 @@ static int ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
 	}
 
 	for (i = 0; i < IPR_NUM_CMD_BLKS; i++) {
-		ipr_cmd = dma_pool_alloc(ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr);
+		ipr_cmd = dma_pool_zalloc(ioa_cfg->ipr_cmd_pool,
+				GFP_KERNEL, &dma_addr);
 
 		if (!ipr_cmd) {
 			ipr_free_cmd_blks(ioa_cfg);
 			return -ENOMEM;
 		}
 
-		memset(ipr_cmd, 0, sizeof(*ipr_cmd));
 		ioa_cfg->ipr_cmnd_list[i] = ipr_cmd;
 		ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr;
 
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index c7f0e9e..9357073 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1454,7 +1454,7 @@ struct ipr_sglist {
 	u32 num_sg;
 	u32 num_dma_sg;
 	u32 buffer_len;
-	struct scatterlist scatterlist[1];
+	struct scatterlist *scatterlist;
 };
 
 enum ipr_sdt_state {
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 6762130..e3c8857 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -224,8 +224,6 @@ module_param(ips, charp, 0);
 /*
  * Function prototypes
  */
-static int ips_detect(struct scsi_host_template *);
-static int ips_release(struct Scsi_Host *);
 static int ips_eh_abort(struct scsi_cmnd *);
 static int ips_eh_reset(struct scsi_cmnd *);
 static int ips_queue(struct Scsi_Host *, struct scsi_cmnd *);
@@ -355,8 +353,6 @@ static dma_addr_t ips_flashbusaddr;
 static long ips_FlashDataInUse;		/* CD Boot - Flash Data In Use Flag */
 static uint32_t MaxLiteCmds = 32;	/* Max Active Cmds for a Lite Adapter */
 static struct scsi_host_template ips_driver_template = {
-	.detect			= ips_detect,
-	.release		= ips_release,
 	.info			= ips_info,
 	.queuecommand		= ips_queue,
 	.eh_abort_handler	= ips_eh_abort,
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 13b37cd..1ee3868 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -2766,7 +2766,7 @@ static int sci_write_gpio_tx_gp(struct isci_host *ihost, u8 reg_index, u8 reg_co
 		int i;
 
 		for (i = 0; i < 3; i++) {
-			int bit = (i << 2) + 2;
+			int bit;
 
 			bit = try_test_sas_gpio_gp_bit(to_sas_gpio_od(d, i),
 						       write_data, reg_index,
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 6d886b1..2ba4b68 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -949,7 +949,7 @@ static umode_t iscsi_sw_tcp_attr_is_visible(int param_type, int param)
 
 static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev)
 {
-	set_bit(QUEUE_FLAG_BIDI, &sdev->request_queue->queue_flags);
+	blk_queue_flag_set(QUEUE_FLAG_BIDI, sdev->request_queue);
 	return 0;
 }
 
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
index 9aaa74e..6eb5ff3 100644
--- a/drivers/scsi/jazz_esp.c
+++ b/drivers/scsi/jazz_esp.c
@@ -147,7 +147,7 @@ static int esp_jazz_probe(struct platform_device *dev)
 	esp = shost_priv(host);
 
 	esp->host = host;
-	esp->dev = dev;
+	esp->dev = &dev->dev;
 	esp->ops = &jazz_esp_ops;
 
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index 8660f92..3f3569e 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -731,7 +731,7 @@ static void fc_disc_stop_final(struct fc_lport *lport)
  */
 void fc_disc_config(struct fc_lport *lport, void *priv)
 {
-	struct fc_disc *disc = &lport->disc;
+	struct fc_disc *disc;
 
 	if (!lport->tt.disc_start)
 		lport->tt.disc_start = fc_disc_start;
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 2b3637b..0cc1567 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -709,7 +709,7 @@ void sas_resume_sata(struct asd_sas_port *port)
 }
 
 /**
- * sas_discover_sata -- discover an STP/SATA domain device
+ * sas_discover_sata - discover an STP/SATA domain device
  * @dev: pointer to struct domain_device of interest
  *
  * Devices directly attached to a HA port, have no parents.  All other
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index e4fd078..a0fa7ef 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -55,7 +55,7 @@ void sas_init_dev(struct domain_device *dev)
 /* ---------- Domain device discovery ---------- */
 
 /**
- * sas_get_port_device -- Discover devices which caused port creation
+ * sas_get_port_device - Discover devices which caused port creation
  * @port: pointer to struct sas_port of interest
  *
  * Devices directly attached to a HA port, have no parent.  This is
@@ -278,8 +278,8 @@ static void sas_resume_devices(struct work_struct *work)
 }
 
 /**
- * sas_discover_end_dev -- discover an end device (SSP, etc)
- * @end: pointer to domain device of interest
+ * sas_discover_end_dev - discover an end device (SSP, etc)
+ * @dev: pointer to domain device of interest
  *
  * See comment in sas_discover_sata().
  */
@@ -428,8 +428,8 @@ void sas_device_set_phy(struct domain_device *dev, struct sas_port *port)
 /* ---------- Discovery and Revalidation ---------- */
 
 /**
- * sas_discover_domain -- discover the domain
- * @port: port to the domain of interest
+ * sas_discover_domain - discover the domain
+ * @work: work structure embedded in port domain device.
  *
  * NOTE: this process _must_ quit (return) as soon as any connection
  * errors are encountered.  Connection recovery is done elsewhere.
@@ -572,7 +572,8 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev)
 }
 
 /**
- * sas_init_disc -- initialize the discovery struct in the port
+ * sas_init_disc - initialize the discovery struct in the port
+ * @disc: port discovery structure
  * @port: pointer to struct port
  *
  * Called when the ports are being initialized.
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 6a4f819..8b71143 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -1170,9 +1170,9 @@ static int sas_check_level_subtractive_boundary(struct domain_device *dev)
 	return 0;
 }
 /**
- * sas_ex_discover_devices -- discover devices attached to this expander
- * dev: pointer to the expander domain device
- * single: if you want to do a single phy, else set to -1;
+ * sas_ex_discover_devices - discover devices attached to this expander
+ * @dev: pointer to the expander domain device
+ * @single: if you want to do a single phy, else set to -1;
  *
  * Configure this expander for use with its devices and register the
  * devices of this expander.
@@ -1528,10 +1528,11 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id,
 }
 
 /**
- * sas_configure_parent -- configure routing table of parent
- * parent: parent expander
- * child: child expander
- * sas_addr: SAS port identifier of device directly attached to child
+ * sas_configure_parent - configure routing table of parent
+ * @parent: parent expander
+ * @child: child expander
+ * @sas_addr: SAS port identifier of device directly attached to child
+ * @include: whether or not to include @child in the expander routing table
  */
 static int sas_configure_parent(struct domain_device *parent,
 				struct domain_device *child,
@@ -1570,9 +1571,9 @@ static int sas_configure_parent(struct domain_device *parent,
 }
 
 /**
- * sas_configure_routing -- configure routing
- * dev: expander device
- * sas_addr: port identifier of device directly attached to the expander device
+ * sas_configure_routing - configure routing
+ * @dev: expander device
+ * @sas_addr: port identifier of device directly attached to the expander device
  */
 static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr)
 {
@@ -1589,8 +1590,8 @@ static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr)
 }
 
 /**
- * sas_discover_expander -- expander discovery
- * @ex: pointer to expander domain device
+ * sas_discover_expander - expander discovery
+ * @dev: pointer to expander domain device
  *
  * See comment in sas_discover_sata().
  */
@@ -2111,8 +2112,8 @@ static int sas_rediscover(struct domain_device *dev, const int phy_id)
 }
 
 /**
- * sas_revalidate_domain -- revalidate the domain
- * @port: port to the domain of interest
+ * sas_ex_revalidate_domain - revalidate the domain
+ * @port_dev: port domain device.
  *
  * NOTE: this process _must_ quit (return) as soon as any connection
  * errors are encountered.  Connection recovery is done elsewhere.
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index c81a63b..ede0af7 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -234,7 +234,7 @@ int sas_try_ata_reset(struct asd_sas_phy *asd_phy)
 	return -ENODEV;
 }
 
-/**
+/*
  * transport_sas_phy_reset - reset a phy and permit libata to manage the link
  *
  * phy reset request via sysfs in host workqueue context so we know we
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index f07e55d..fad23dd3 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -84,7 +84,7 @@ static void sas_resume_port(struct asd_sas_phy *phy)
 }
 
 /**
- * sas_form_port -- add this phy to a port
+ * sas_form_port - add this phy to a port
  * @phy: the phy of interest
  *
  * This function adds this phy to an existing port, thus creating a wide
@@ -197,8 +197,9 @@ static void sas_form_port(struct asd_sas_phy *phy)
 }
 
 /**
- * sas_deform_port -- remove this phy from the port it belongs to
+ * sas_deform_port - remove this phy from the port it belongs to
  * @phy: the phy of interest
+ * @gone: whether or not the PHY is gone
  *
  * This is called when the physical link to the other phy has been
  * lost (on this phy), in Event thread context. We cannot delay here.
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 61fb46d..6c0d351 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -544,16 +544,10 @@ struct unsol_rcv_ct_ctx {
 #define LPFC_USER_LINK_SPEED_10G	10	/* 10 Gigabaud */
 #define LPFC_USER_LINK_SPEED_16G	16	/* 16 Gigabaud */
 #define LPFC_USER_LINK_SPEED_32G	32	/* 32 Gigabaud */
-#define LPFC_USER_LINK_SPEED_MAX	LPFC_USER_LINK_SPEED_32G
-#define LPFC_USER_LINK_SPEED_BITMAP  ((1ULL << LPFC_USER_LINK_SPEED_32G) | \
-				     (1 << LPFC_USER_LINK_SPEED_16G) | \
-				     (1 << LPFC_USER_LINK_SPEED_10G) | \
-				     (1 << LPFC_USER_LINK_SPEED_8G) | \
-				     (1 << LPFC_USER_LINK_SPEED_4G) | \
-				     (1 << LPFC_USER_LINK_SPEED_2G) | \
-				     (1 << LPFC_USER_LINK_SPEED_1G) | \
-				     (1 << LPFC_USER_LINK_SPEED_AUTO))
-#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32"
+#define LPFC_USER_LINK_SPEED_64G	64	/* 64 Gigabaud */
+#define LPFC_USER_LINK_SPEED_MAX	LPFC_USER_LINK_SPEED_64G
+
+#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32, 64"
 
 enum nemb_type {
 	nemb_mse = 1,
@@ -760,6 +754,7 @@ struct lpfc_hba {
 	uint8_t  mds_diags_support;
 	uint32_t initial_imax;
 	uint8_t  bbcredit_support;
+	uint8_t  enab_exp_wqcq_pages;
 
 	/* HBA Config Parameters */
 	uint32_t cfg_ack0;
@@ -787,6 +782,7 @@ struct lpfc_hba {
 	uint32_t cfg_fcp_io_channel;
 	uint32_t cfg_suppress_rsp;
 	uint32_t cfg_nvme_oas;
+	uint32_t cfg_nvme_embed_cmd;
 	uint32_t cfg_nvme_io_channel;
 	uint32_t cfg_nvmet_mrq;
 	uint32_t cfg_enable_nvmet;
@@ -839,11 +835,14 @@ struct lpfc_hba {
 	uint32_t cfg_enable_SmartSAN;
 	uint32_t cfg_enable_mds_diags;
 	uint32_t cfg_enable_fc4_type;
-	uint32_t cfg_enable_bbcr;	/*Enable BB Credit Recovery*/
+	uint32_t cfg_enable_bbcr;	/* Enable BB Credit Recovery */
+	uint32_t cfg_enable_dpp;	/* Enable Direct Packet Push */
 	uint32_t cfg_xri_split;
 #define LPFC_ENABLE_FCP  1
 #define LPFC_ENABLE_NVME 2
 #define LPFC_ENABLE_BOTH 3
+	uint32_t nvme_embed_pbde;
+	uint32_t fcp_embed_pbde;
 	uint32_t io_channel_irqs;	/* number of irqs for io channels */
 	struct nvmet_fc_target_port *targetport;
 	lpfc_vpd_t vpd;		/* vital product data */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index ac77081..2ac1d21c 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -259,6 +259,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
 				atomic_read(&tgtp->xmt_abort_rsp),
 				atomic_read(&tgtp->xmt_abort_rsp_error));
 
+		len += snprintf(buf + len, PAGE_SIZE - len,
+				"DELAY: ctx %08x  fod %08x wqfull %08x\n",
+				atomic_read(&tgtp->defer_ctx),
+				atomic_read(&tgtp->defer_fod),
+				atomic_read(&tgtp->defer_wqfull));
+
 		/* Calculate outstanding IOs */
 		tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
 		tot += atomic_read(&tgtp->xmt_fcp_release);
@@ -905,7 +911,12 @@ lpfc_issue_lip(struct Scsi_Host *shost)
 	LPFC_MBOXQ_t *pmboxq;
 	int mbxstatus = MBXERR_ERROR;
 
+	/*
+	 * If the link is offline, disabled or BLOCK_MGMT_IO
+	 * it doesn't make any sense to allow issue_lip
+	 */
 	if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+	    (phba->hba_flag & LINK_DISABLED) ||
 	    (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
 		return -EPERM;
 
@@ -3458,8 +3469,8 @@ LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 512,
 # tgt_queue_depth:  This parameter is used to limit the number of outstanding
 # commands per target port. Value range is [10,65535]. Default value is 65535.
 */
-LPFC_VPORT_ATTR_R(tgt_queue_depth, 65535, 10, 65535,
-		  "Max number of FCP commands we can queue to a specific target port");
+LPFC_VPORT_ATTR_RW(tgt_queue_depth, 65535, 10, 65535,
+		   "Max number of FCP commands we can queue to a specific target port");
 
 /*
 # hba_queue_depth:  This parameter is used to limit the number of outstanding
@@ -4104,23 +4115,32 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
 	    ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
 	    ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
 	    ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
-	    ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb))) {
+	    ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
+	    ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2879 lpfc_link_speed attribute cannot be set "
 				"to %d. Speed is not supported by this port.\n",
 				val);
 		return -EINVAL;
 	}
-	if (val == LPFC_USER_LINK_SPEED_16G &&
-		 phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
+	if (val >= LPFC_USER_LINK_SPEED_16G &&
+	    phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"3112 lpfc_link_speed attribute cannot be set "
 				"to %d. Speed is not supported in loop mode.\n",
 				val);
 		return -EINVAL;
 	}
-	if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
-	    (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
+
+	switch (val) {
+	case LPFC_USER_LINK_SPEED_AUTO:
+	case LPFC_USER_LINK_SPEED_1G:
+	case LPFC_USER_LINK_SPEED_2G:
+	case LPFC_USER_LINK_SPEED_4G:
+	case LPFC_USER_LINK_SPEED_8G:
+	case LPFC_USER_LINK_SPEED_16G:
+	case LPFC_USER_LINK_SPEED_32G:
+	case LPFC_USER_LINK_SPEED_64G:
 		prev_val = phba->cfg_link_speed;
 		phba->cfg_link_speed = val;
 		if (nolip)
@@ -4130,13 +4150,18 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
 		if (err) {
 			phba->cfg_link_speed = prev_val;
 			return -EINVAL;
-		} else
-			return strlen(buf);
+		}
+		return strlen(buf);
+	default:
+		break;
 	}
+
 	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-		"0469 lpfc_link_speed attribute cannot be set to %d, "
-		"allowed values are ["LPFC_LINK_SPEED_STRING"]\n", val);
+			"0469 lpfc_link_speed attribute cannot be set to %d, "
+			"allowed values are [%s]\n",
+			val, LPFC_LINK_SPEED_STRING);
 	return -EINVAL;
+
 }
 
 static int lpfc_link_speed = 0;
@@ -4163,24 +4188,33 @@ lpfc_param_show(link_speed)
 static int
 lpfc_link_speed_init(struct lpfc_hba *phba, int val)
 {
-	if (val == LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
+	if (val >= LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 			"3111 lpfc_link_speed of %d cannot "
 			"support loop mode, setting topology to default.\n",
 			 val);
 		phba->cfg_topology = 0;
 	}
-	if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
-	    (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
+
+	switch (val) {
+	case LPFC_USER_LINK_SPEED_AUTO:
+	case LPFC_USER_LINK_SPEED_1G:
+	case LPFC_USER_LINK_SPEED_2G:
+	case LPFC_USER_LINK_SPEED_4G:
+	case LPFC_USER_LINK_SPEED_8G:
+	case LPFC_USER_LINK_SPEED_16G:
+	case LPFC_USER_LINK_SPEED_32G:
+	case LPFC_USER_LINK_SPEED_64G:
 		phba->cfg_link_speed = val;
 		return 0;
+	default:
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"0405 lpfc_link_speed attribute cannot "
+				"be set to %d, allowed values are "
+				"["LPFC_LINK_SPEED_STRING"]\n", val);
+		phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
+		return -EINVAL;
 	}
-	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-			"0405 lpfc_link_speed attribute cannot "
-			"be set to %d, allowed values are "
-			"["LPFC_LINK_SPEED_STRING"]\n", val);
-	phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
-	return -EINVAL;
 }
 
 static DEVICE_ATTR_RW(lpfc_link_speed);
@@ -5008,6 +5042,18 @@ LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
 	     "Use OAS bit on NVME IOs");
 
 /*
+ * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
+ *
+ *      0  = Put NVME Command in SGL
+ *      1  = Embed NVME Command in WQE (unless G7)
+ *      2 =  Embed NVME Command in WQE (force)
+ *
+ * Value range is [0,2]. Default value is 1.
+ */
+LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
+	     "Embed NVME Command in WQE");
+
+/*
  * lpfc_fcp_io_channel: Set the number of FCP IO channels the driver
  * will advertise it supports to the SCSI layer. This also will map to
  * the number of WQs the driver will create.
@@ -5175,6 +5221,14 @@ LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
  */
 LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
 
+/*
+ * lpfc_enable_dpp: Enable DPP on G7
+ *       0  = DPP on G7 disabled
+ *       1  = DPP on G7 enabled (default)
+ * Value range is [0,1]. Default value is 1.
+ */
+LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
+
 struct device_attribute *lpfc_hba_attrs[] = {
 	&dev_attr_nvme_info,
 	&dev_attr_bg_info,
@@ -5240,6 +5294,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
 	&dev_attr_lpfc_task_mgmt_tmo,
 	&dev_attr_lpfc_use_msi,
 	&dev_attr_lpfc_nvme_oas,
+	&dev_attr_lpfc_nvme_embed_cmd,
 	&dev_attr_lpfc_auto_imax,
 	&dev_attr_lpfc_fcp_imax,
 	&dev_attr_lpfc_fcp_cpu_map,
@@ -5283,6 +5338,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
 	&dev_attr_lpfc_xlane_supported,
 	&dev_attr_lpfc_enable_mds_diags,
 	&dev_attr_lpfc_enable_bbcr,
+	&dev_attr_lpfc_enable_dpp,
 	NULL,
 };
 
@@ -5696,6 +5752,9 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
 		case LPFC_LINK_SPEED_32GHZ:
 			fc_host_speed(shost) = FC_PORTSPEED_32GBIT;
 			break;
+		case LPFC_LINK_SPEED_64GHZ:
+			fc_host_speed(shost) = FC_PORTSPEED_64GBIT;
+			break;
 		default:
 			fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
 			break;
@@ -6260,6 +6319,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 	lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
 	lpfc_use_msi_init(phba, lpfc_use_msi);
 	lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
+	lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
 	lpfc_auto_imax_init(phba, lpfc_auto_imax);
 	lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
 	lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
@@ -6284,6 +6344,10 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 		phba->cfg_poll = 0;
 	else
 		phba->cfg_poll = lpfc_poll;
+
+	if (phba->cfg_enable_bg)
+		phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
+
 	lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);
 
 	lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
@@ -6295,6 +6359,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 	lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
 	lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel);
 	lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
+	lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
 
 	if (phba->sli_rev != LPFC_SLI_REV4) {
 		/* NVME only supported on SLI4 */
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index d898162..0f174ca 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2009-2015 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -3867,7 +3867,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job,
 				"ext_buf_cnt:%d\n", ext_buf_cnt);
 	} else {
 		/* sanity check on interface type for support */
-		if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+		if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
 		    LPFC_SLI_INTF_IF_TYPE_2) {
 			rc = -ENODEV;
 			goto job_error;
@@ -4053,7 +4053,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job,
 				"ext_buf_cnt:%d\n", ext_buf_cnt);
 	} else {
 		/* sanity check on interface type for support */
-		if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+		if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
 		    LPFC_SLI_INTF_IF_TYPE_2)
 			return -ENODEV;
 		/* nemb_tp == nemb_hbd */
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 559f9aa..4ae9ba42 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -254,6 +254,7 @@ void lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba,
 			    struct lpfc_nvmet_ctxbuf *ctxp);
 int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
 			       struct fc_frame_header *fc_hdr);
+void lpfc_nvmet_wqfull_process(struct lpfc_hba *phba, struct lpfc_queue *wq);
 void lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba);
 void lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba);
 void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
@@ -564,6 +565,8 @@ void lpfc_nvme_mod_param_dep(struct lpfc_hba *phba);
 void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba,
 				struct lpfc_iocbq *cmdiocb,
 				struct lpfc_wcqe_complete *abts_cmpl);
+void lpfc_nvme_cmd_template(void);
+void lpfc_nvmet_cmd_template(void);
 extern int lpfc_enable_nvmet_cnt;
 extern unsigned long long lpfc_enable_nvmet[];
 extern int lpfc_no_hba_reset_cnt;
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 9d20d2c2..0617c8e 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -471,7 +471,6 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
 				"Parse GID_FTrsp: did:x%x flg:x%x x%x",
 				Did, ndlp->nlp_flag, vport->fc_flag);
 
-			ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
 			/* By default, the driver expects to support FCP FC4 */
 			if (fc4_type == FC_TYPE_FCP)
 				ndlp->nlp_fc4_type |= NLP_FC4_FCP;
@@ -2130,6 +2129,8 @@ lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport,
 
 	ae->un.AttrInt = 0;
 	if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+		if (phba->lmt & LMT_64Gb)
+			ae->un.AttrInt |= HBA_PORTSPEED_64GFC;
 		if (phba->lmt & LMT_32Gb)
 			ae->un.AttrInt |= HBA_PORTSPEED_32GFC;
 		if (phba->lmt & LMT_16Gb)
@@ -2201,6 +2202,9 @@ lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport,
 		case LPFC_LINK_SPEED_32GHZ:
 			ae->un.AttrInt = HBA_PORTSPEED_32GFC;
 			break;
+		case LPFC_LINK_SPEED_64GHZ:
+			ae->un.AttrInt = HBA_PORTSPEED_64GFC;
+			break;
 		default:
 			ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
 			break;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 17ea3bb..fb0dc2a 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2007-2015 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -3944,10 +3944,15 @@ lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
 		return 0;
 
 	switch (drbregid) {
-	case LPFC_DRB_EQCQ:
-		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
-				"EQCQ-DRB-REG: 0x%08x\n",
-				readl(phba->sli4_hba.EQCQDBregaddr));
+	case LPFC_DRB_EQ:
+		len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len,
+				"EQ-DRB-REG: 0x%08x\n",
+				readl(phba->sli4_hba.EQDBregaddr));
+		break;
+	case LPFC_DRB_CQ:
+		len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len,
+				"CQ-DRB-REG: 0x%08x\n",
+				readl(phba->sli4_hba.CQDBregaddr));
 		break;
 	case LPFC_DRB_MQ:
 		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
@@ -4086,8 +4091,11 @@ lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
 	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
 	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
 		switch (drb_reg_id) {
-		case LPFC_DRB_EQCQ:
-			drb_reg = phba->sli4_hba.EQCQDBregaddr;
+		case LPFC_DRB_EQ:
+			drb_reg = phba->sli4_hba.EQDBregaddr;
+			break;
+		case LPFC_DRB_CQ:
+			drb_reg = phba->sli4_hba.CQDBregaddr;
 			break;
 		case LPFC_DRB_MQ:
 			drb_reg = phba->sli4_hba.MQDBregaddr;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index c4edd87..f32eaeb 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2007-2011 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -126,12 +126,13 @@
 #define LPFC_DRB_ACC_WR_CMD_ARG 2
 #define LPFC_DRB_ACC_BUF_SIZE 256
 
-#define LPFC_DRB_EQCQ 1
-#define LPFC_DRB_MQ   2
-#define LPFC_DRB_WQ   3
-#define LPFC_DRB_RQ   4
+#define LPFC_DRB_EQ   1
+#define LPFC_DRB_CQ   2
+#define LPFC_DRB_MQ   3
+#define LPFC_DRB_WQ   4
+#define LPFC_DRB_RQ   5
 
-#define LPFC_DRB_MAX  4
+#define LPFC_DRB_MAX  5
 
 #define IDIAG_DRBACC_REGID_INDX 0
 #define IDIAG_DRBACC_VALUE_INDX 1
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 234c7c0..74895e6 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -1661,6 +1661,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 		if (ndlp->nrport) {
 			ndlp->nrport = NULL;
 			lpfc_nlp_put(ndlp);
+			new_ndlp->nlp_fc4_type = ndlp->nlp_fc4_type;
 		}
 
 		/* We shall actually free the ndlp with both nlp_DID and
@@ -2293,10 +2294,11 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		if (phba->nvmet_support) {
 			bf_set(prli_tgt, npr_nvme, 1);
 			bf_set(prli_disc, npr_nvme, 1);
-
 		} else {
 			bf_set(prli_init, npr_nvme, 1);
+			bf_set(prli_conf, npr_nvme, 1);
 		}
+
 		npr_nvme->word1 = cpu_to_be32(npr_nvme->word1);
 		npr_nvme->word4 = cpu_to_be32(npr_nvme->word4);
 		elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ;
@@ -5269,6 +5271,9 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
 	case LPFC_LINK_SPEED_32GHZ:
 		rdp_speed = RDP_PS_32GB;
 		break;
+	case LPFC_LINK_SPEED_64GHZ:
+		rdp_speed = RDP_PS_64GB;
+		break;
 	default:
 		rdp_speed = RDP_PS_UNKNOWN;
 		break;
@@ -5276,6 +5281,8 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
 
 	desc->info.port_speed.speed = cpu_to_be16(rdp_speed);
 
+	if (phba->lmt & LMT_64Gb)
+		rdp_cap |= RDP_PS_64GB;
 	if (phba->lmt & LMT_32Gb)
 		rdp_cap |= RDP_PS_32GB;
 	if (phba->lmt & LMT_16Gb)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index b159a5c..3e7712c 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -696,8 +696,9 @@ lpfc_work_done(struct lpfc_hba *phba)
 		      phba->hba_flag & HBA_SP_QUEUE_EVT)) {
 		if (pring->flag & LPFC_STOP_IOCB_EVENT) {
 			pring->flag |= LPFC_DEFERRED_RING_EVENT;
-			/* Set the lpfc data pending flag */
-			set_bit(LPFC_DATA_READY, &phba->data_flags);
+			/* Preserve legacy behavior. */
+			if (!(phba->hba_flag & HBA_SP_QUEUE_EVT))
+				set_bit(LPFC_DATA_READY, &phba->data_flags);
 		} else {
 			if (phba->link_state >= LPFC_LINK_UP ||
 			    phba->link_flag & LS_MDS_LOOPBACK) {
@@ -958,6 +959,7 @@ lpfc_linkup_cleanup_nodes(struct lpfc_vport *vport)
 	struct lpfc_nodelist *ndlp;
 
 	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+		ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
 		if (!NLP_CHK_NODE_ACT(ndlp))
 			continue;
 		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
@@ -3083,6 +3085,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
 		case LPFC_LINK_SPEED_10GHZ:
 		case LPFC_LINK_SPEED_16GHZ:
 		case LPFC_LINK_SPEED_32GHZ:
+		case LPFC_LINK_SPEED_64GHZ:
 			break;
 		default:
 			phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN;
@@ -3873,6 +3876,10 @@ int
 lpfc_issue_gidft(struct lpfc_vport *vport)
 {
 	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_nodelist *ndlp;
+
+	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
+		ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
 
 	/* Good status, issue CT Request to NameServer */
 	if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index bdc1f18..08a3f15 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -1177,6 +1177,9 @@ struct fc_rdp_link_error_status_desc {
 #define RDP_PS_8GB             0x0800
 #define RDP_PS_16GB            0x0400
 #define RDP_PS_32GB            0x0200
+#define RDP_PS_64GB            0x0100
+#define RDP_PS_128GB           0x0080
+#define RDP_PS_256GB           0x0040
 
 #define RDP_CAP_USER_CONFIGURED 0x0002
 #define RDP_CAP_UNKNOWN         0x0001
@@ -1580,6 +1583,7 @@ struct lpfc_fdmi_reg_portattr {
 #define PCI_DEVICE_ID_LANCER_FCOE   0xe260
 #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268
 #define PCI_DEVICE_ID_LANCER_G6_FC  0xe300
+#define PCI_DEVICE_ID_LANCER_G7_FC  0xf400
 #define PCI_DEVICE_ID_SAT_SMB       0xf011
 #define PCI_DEVICE_ID_SAT_MID       0xf015
 #define PCI_DEVICE_ID_RFLY          0xf095
@@ -2257,6 +2261,9 @@ typedef struct {
 #define LINK_SPEED_10G  0x10    /* 10 Gigabaud */
 #define LINK_SPEED_16G  0x11    /* 16 Gigabaud */
 #define LINK_SPEED_32G  0x14    /* 32 Gigabaud */
+#define LINK_SPEED_64G  0x17    /* 64 Gigabaud */
+#define LINK_SPEED_128G 0x1A    /* 128 Gigabaud */
+#define LINK_SPEED_256G 0x1D    /* 256 Gigabaud */
 
 } INIT_LINK_VAR;
 
@@ -2441,6 +2448,9 @@ typedef struct {
 #define LMT_10Gb      0x100
 #define LMT_16Gb      0x200
 #define LMT_32Gb      0x400
+#define LMT_64Gb      0x800
+#define LMT_128Gb     0x1000
+#define LMT_256Gb     0x2000
 	uint32_t rsvd2;
 	uint32_t rsvd3;
 	uint32_t max_xri;
@@ -2965,6 +2975,9 @@ struct lpfc_mbx_read_top {
 #define LPFC_LINK_SPEED_10GHZ	0x40
 #define LPFC_LINK_SPEED_16GHZ	0x80
 #define LPFC_LINK_SPEED_32GHZ	0x90
+#define LPFC_LINK_SPEED_64GHZ	0xA0
+#define LPFC_LINK_SPEED_128GHZ	0xB0
+#define LPFC_LINK_SPEED_256GHZ	0xC0
 };
 
 /* Structure for MB Command CLEAR_LA (22) */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 73c2f69..98b8055 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2009-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -84,6 +84,7 @@ struct lpfc_sli_intf {
 #define LPFC_SLI_INTF_IF_TYPE_0		0
 #define LPFC_SLI_INTF_IF_TYPE_1		1
 #define LPFC_SLI_INTF_IF_TYPE_2		2
+#define LPFC_SLI_INTF_IF_TYPE_6		6
 #define lpfc_sli_intf_sli_family_SHIFT		8
 #define lpfc_sli_intf_sli_family_MASK		0x0000000F
 #define lpfc_sli_intf_sli_family_WORD		word0
@@ -731,11 +732,13 @@ struct lpfc_register {
  * register sets depending on the UCNA Port's reported if_type
  * value.  For UCNA ports running SLI4 and if_type 0, they reside in
  * BAR4.  For UCNA ports running SLI4 and if_type 2, they reside in
- * BAR0.  The offsets are the same so the driver must account for
- * any base address difference.
+ * BAR0.  For FC ports running SLI4 and if_type 6, they reside in
+ * BAR2. The offsets and base address are different,  so the driver
+ * has to compute the register addresses accordingly
  */
 #define LPFC_ULP0_RQ_DOORBELL		0x00A0
 #define LPFC_ULP1_RQ_DOORBELL		0x00C0
+#define LPFC_IF6_RQ_DOORBELL		0x0080
 #define lpfc_rq_db_list_fm_num_posted_SHIFT	24
 #define lpfc_rq_db_list_fm_num_posted_MASK	0x00FF
 #define lpfc_rq_db_list_fm_num_posted_WORD	word0
@@ -770,6 +773,20 @@ struct lpfc_register {
 #define lpfc_wq_db_ring_fm_id_MASK              0xFFFF
 #define lpfc_wq_db_ring_fm_id_WORD              word0
 
+#define LPFC_IF6_WQ_DOORBELL		0x0040
+#define lpfc_if6_wq_db_list_fm_num_posted_SHIFT	24
+#define lpfc_if6_wq_db_list_fm_num_posted_MASK	0x00FF
+#define lpfc_if6_wq_db_list_fm_num_posted_WORD	word0
+#define lpfc_if6_wq_db_list_fm_dpp_SHIFT	23
+#define lpfc_if6_wq_db_list_fm_dpp_MASK		0x0001
+#define lpfc_if6_wq_db_list_fm_dpp_WORD		word0
+#define lpfc_if6_wq_db_list_fm_dpp_id_SHIFT	16
+#define lpfc_if6_wq_db_list_fm_dpp_id_MASK	0x001F
+#define lpfc_if6_wq_db_list_fm_dpp_id_WORD	word0
+#define lpfc_if6_wq_db_list_fm_id_SHIFT		0
+#define lpfc_if6_wq_db_list_fm_id_MASK		0xFFFF
+#define lpfc_if6_wq_db_list_fm_id_WORD		word0
+
 #define LPFC_EQCQ_DOORBELL		0x0120
 #define lpfc_eqcq_doorbell_se_SHIFT		31
 #define lpfc_eqcq_doorbell_se_MASK		0x0001
@@ -805,6 +822,38 @@ struct lpfc_register {
 #define LPFC_CQID_HI_FIELD_SHIFT		10
 #define LPFC_EQID_HI_FIELD_SHIFT		9
 
+#define LPFC_IF6_CQ_DOORBELL			0x00C0
+#define lpfc_if6_cq_doorbell_se_SHIFT		31
+#define lpfc_if6_cq_doorbell_se_MASK		0x0001
+#define lpfc_if6_cq_doorbell_se_WORD		word0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_OFF		0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_ON		1
+#define lpfc_if6_cq_doorbell_arm_SHIFT		29
+#define lpfc_if6_cq_doorbell_arm_MASK		0x0001
+#define lpfc_if6_cq_doorbell_arm_WORD		word0
+#define lpfc_if6_cq_doorbell_num_released_SHIFT	16
+#define lpfc_if6_cq_doorbell_num_released_MASK	0x1FFF
+#define lpfc_if6_cq_doorbell_num_released_WORD	word0
+#define lpfc_if6_cq_doorbell_cqid_SHIFT		0
+#define lpfc_if6_cq_doorbell_cqid_MASK		0xFFFF
+#define lpfc_if6_cq_doorbell_cqid_WORD		word0
+
+#define LPFC_IF6_EQ_DOORBELL			0x0120
+#define lpfc_if6_eq_doorbell_io_SHIFT		31
+#define lpfc_if6_eq_doorbell_io_MASK		0x0001
+#define lpfc_if6_eq_doorbell_io_WORD		word0
+#define LPFC_IF6_EQ_INTR_OVERRIDE_OFF		0
+#define LPFC_IF6_EQ_INTR_OVERRIDE_ON		1
+#define lpfc_if6_eq_doorbell_arm_SHIFT		29
+#define lpfc_if6_eq_doorbell_arm_MASK		0x0001
+#define lpfc_if6_eq_doorbell_arm_WORD		word0
+#define lpfc_if6_eq_doorbell_num_released_SHIFT	16
+#define lpfc_if6_eq_doorbell_num_released_MASK	0x1FFF
+#define lpfc_if6_eq_doorbell_num_released_WORD	word0
+#define lpfc_if6_eq_doorbell_eqid_SHIFT		0
+#define lpfc_if6_eq_doorbell_eqid_MASK		0x0FFF
+#define lpfc_if6_eq_doorbell_eqid_WORD		word0
+
 #define LPFC_BMBX			0x0160
 #define lpfc_bmbx_addr_SHIFT		2
 #define lpfc_bmbx_addr_MASK		0x3FFFFFFF
@@ -817,6 +866,7 @@ struct lpfc_register {
 #define lpfc_bmbx_rdy_WORD		word0
 
 #define LPFC_MQ_DOORBELL			0x0140
+#define LPFC_IF6_MQ_DOORBELL			0x0160
 #define lpfc_mq_doorbell_num_posted_SHIFT	16
 #define lpfc_mq_doorbell_num_posted_MASK	0x3FFF
 #define lpfc_mq_doorbell_num_posted_WORD	word0
@@ -990,6 +1040,9 @@ struct eq_context {
 #define lpfc_eq_context_valid_SHIFT	29
 #define lpfc_eq_context_valid_MASK	0x00000001
 #define lpfc_eq_context_valid_WORD	word0
+#define lpfc_eq_context_autovalid_SHIFT 28
+#define lpfc_eq_context_autovalid_MASK  0x00000001
+#define lpfc_eq_context_autovalid_WORD  word0
 	uint32_t word1;
 #define lpfc_eq_context_count_SHIFT	26
 #define lpfc_eq_context_count_MASK	0x00000003
@@ -1123,6 +1176,9 @@ struct cq_context {
 #define LPFC_CQ_CNT_512		0x1
 #define LPFC_CQ_CNT_1024	0x2
 #define LPFC_CQ_CNT_WORD7	0x3
+#define lpfc_cq_context_autovalid_SHIFT 15
+#define lpfc_cq_context_autovalid_MASK  0x00000001
+#define lpfc_cq_context_autovalid_WORD  word0
 	uint32_t word1;
 #define lpfc_cq_eq_id_SHIFT		22	/* Version 0 Only */
 #define lpfc_cq_eq_id_MASK		0x000000FF
@@ -1181,9 +1237,9 @@ struct lpfc_mbx_cq_create_set {
 #define lpfc_mbx_cq_create_set_cqe_size_SHIFT	25
 #define lpfc_mbx_cq_create_set_cqe_size_MASK	0x00000003
 #define lpfc_mbx_cq_create_set_cqe_size_WORD	word1
-#define lpfc_mbx_cq_create_set_auto_SHIFT	15
-#define lpfc_mbx_cq_create_set_auto_MASK	0x0000001
-#define lpfc_mbx_cq_create_set_auto_WORD	word1
+#define lpfc_mbx_cq_create_set_autovalid_SHIFT	15
+#define lpfc_mbx_cq_create_set_autovalid_MASK	0x0000001
+#define lpfc_mbx_cq_create_set_autovalid_WORD	word1
 #define lpfc_mbx_cq_create_set_nodelay_SHIFT	14
 #define lpfc_mbx_cq_create_set_nodelay_MASK	0x00000001
 #define lpfc_mbx_cq_create_set_nodelay_WORD	word1
@@ -1322,6 +1378,15 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_page_size_MASK	0x000000FF
 #define lpfc_mbx_wq_create_page_size_WORD	word1
 #define LPFC_WQ_PAGE_SIZE_4096	0x1
+#define lpfc_mbx_wq_create_dpp_req_SHIFT	15
+#define lpfc_mbx_wq_create_dpp_req_MASK		0x00000001
+#define lpfc_mbx_wq_create_dpp_req_WORD		word1
+#define lpfc_mbx_wq_create_doe_SHIFT		14
+#define lpfc_mbx_wq_create_doe_MASK		0x00000001
+#define lpfc_mbx_wq_create_doe_WORD		word1
+#define lpfc_mbx_wq_create_toe_SHIFT		13
+#define lpfc_mbx_wq_create_toe_MASK		0x00000001
+#define lpfc_mbx_wq_create_toe_WORD		word1
 #define lpfc_mbx_wq_create_wqe_size_SHIFT	8
 #define lpfc_mbx_wq_create_wqe_size_MASK	0x0000000F
 #define lpfc_mbx_wq_create_wqe_size_WORD	word1
@@ -1350,6 +1415,28 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_db_format_MASK	0x0000FFFF
 #define lpfc_mbx_wq_create_db_format_WORD	word2
 		} response;
+		struct {
+			uint32_t word0;
+#define lpfc_mbx_wq_create_dpp_rsp_SHIFT	31
+#define lpfc_mbx_wq_create_dpp_rsp_MASK		0x00000001
+#define lpfc_mbx_wq_create_dpp_rsp_WORD		word0
+#define lpfc_mbx_wq_create_v1_q_id_SHIFT	0
+#define lpfc_mbx_wq_create_v1_q_id_MASK		0x0000FFFF
+#define lpfc_mbx_wq_create_v1_q_id_WORD		word0
+			uint32_t word1;
+#define lpfc_mbx_wq_create_v1_bar_set_SHIFT	0
+#define lpfc_mbx_wq_create_v1_bar_set_MASK	0x0000000F
+#define lpfc_mbx_wq_create_v1_bar_set_WORD	word1
+			uint32_t doorbell_offset;
+			uint32_t word3;
+#define lpfc_mbx_wq_create_dpp_id_SHIFT		16
+#define lpfc_mbx_wq_create_dpp_id_MASK		0x0000001F
+#define lpfc_mbx_wq_create_dpp_id_WORD		word3
+#define lpfc_mbx_wq_create_dpp_bar_SHIFT	0
+#define lpfc_mbx_wq_create_dpp_bar_MASK		0x0000000F
+#define lpfc_mbx_wq_create_dpp_bar_WORD		word3
+			uint32_t dpp_offset;
+		} response_1;
 	} u;
 };
 
@@ -2154,6 +2241,7 @@ struct lpfc_mbx_redisc_fcf_tbl {
  * command.
  */
 #define ADD_STATUS_OPERATION_ALREADY_ACTIVE		0x67
+#define ADD_STATUS_FW_NOT_SUPPORTED			0xEB
 
 struct lpfc_mbx_sli4_config {
 	struct mbox_header header;
@@ -2590,6 +2678,7 @@ struct lpfc_mbx_read_rev {
 #define lpfc_mbx_rd_rev_vpd_MASK		0x00000001
 #define lpfc_mbx_rd_rev_vpd_WORD		word1
 	uint32_t first_hw_rev;
+#define LPFC_G7_ASIC_1				0xd
 	uint32_t second_hw_rev;
 	uint32_t word4_rsvd;
 	uint32_t third_hw_rev;
@@ -3207,11 +3296,20 @@ struct lpfc_sli4_parameters {
 #define cfg_sli_hint_2_MASK			0x0000001f
 #define cfg_sli_hint_2_WORD			word1
 	uint32_t word2;
+#define cfg_eqav_SHIFT				31
+#define cfg_eqav_MASK				0x00000001
+#define cfg_eqav_WORD				word2
 	uint32_t word3;
 	uint32_t word4;
 #define cfg_cqv_SHIFT				14
 #define cfg_cqv_MASK				0x00000003
 #define cfg_cqv_WORD				word4
+#define cfg_cqpsize_SHIFT			16
+#define cfg_cqpsize_MASK			0x000000ff
+#define cfg_cqpsize_WORD			word4
+#define cfg_cqav_SHIFT				31
+#define cfg_cqav_MASK				0x00000001
+#define cfg_cqav_WORD				word4
 	uint32_t word5;
 	uint32_t word6;
 #define cfg_mqv_SHIFT				14
@@ -3290,6 +3388,9 @@ struct lpfc_sli4_parameters {
 #define cfg_eqdr_SHIFT				8
 #define cfg_eqdr_MASK				0x00000001
 #define cfg_eqdr_WORD				word19
+#define cfg_nosr_SHIFT				9
+#define cfg_nosr_MASK				0x00000001
+#define cfg_nosr_WORD				word19
 #define LPFC_NODELAY_MAX_IO		32
 };
 
@@ -3874,6 +3975,9 @@ struct lpfc_acqe_fc_la {
 #define LPFC_FC_LA_SPEED_10G		0xA
 #define LPFC_FC_LA_SPEED_16G		0x10
 #define LPFC_FC_LA_SPEED_32G            0x20
+#define LPFC_FC_LA_SPEED_64G            0x21
+#define LPFC_FC_LA_SPEED_128G           0x22
+#define LPFC_FC_LA_SPEED_256G           0x23
 #define lpfc_acqe_fc_la_topology_SHIFT		16
 #define lpfc_acqe_fc_la_topology_MASK		0x000000FF
 #define lpfc_acqe_fc_la_topology_WORD		word0
@@ -4079,6 +4183,7 @@ struct wqe_common {
 #define wqe_iod_SHIFT         13
 #define wqe_iod_MASK          0x00000001
 #define wqe_iod_WORD          word10
+#define LPFC_WQE_IOD_NONE	0
 #define LPFC_WQE_IOD_WRITE	0
 #define LPFC_WQE_IOD_READ	1
 #define wqe_dbde_SHIFT        14
@@ -4123,6 +4228,9 @@ struct wqe_common {
 #define wqe_irsp_SHIFT        4
 #define wqe_irsp_MASK         0x00000001
 #define wqe_irsp_WORD         word11
+#define wqe_pbde_SHIFT        5
+#define wqe_pbde_MASK         0x00000001
+#define wqe_pbde_WORD         word11
 #define wqe_sup_SHIFT         6
 #define wqe_sup_MASK          0x00000001
 #define wqe_sup_WORD          word11
@@ -4343,9 +4451,9 @@ struct lpfc_nvme_prli {
 #define prli_init_SHIFT                 5
 #define prli_init_MASK                  0x00000001
 #define prli_init_WORD                  word4
-#define prli_recov_SHIFT                8
-#define prli_recov_MASK                 0x00000001
-#define prli_recov_WORD                 word4
+#define prli_conf_SHIFT                 7
+#define prli_conf_MASK                  0x00000001
+#define prli_conf_WORD                  word4
 	uint32_t word5;
 #define prli_fb_sz_SHIFT                0
 #define prli_fb_sz_MASK                 0x0000ffff
@@ -4494,17 +4602,20 @@ union lpfc_wqe128 {
 	struct fcp_icmnd64_wqe fcp_icmd;
 	struct fcp_iread64_wqe fcp_iread;
 	struct fcp_iwrite64_wqe fcp_iwrite;
+	struct abort_cmd_wqe abort_cmd;
+	struct create_xri_wqe create_xri;
+	struct xmit_bcast64_wqe xmit_bcast64;
+	struct xmit_seq64_wqe xmit_sequence;
+	struct xmit_bls_rsp64_wqe xmit_bls_rsp;
+	struct xmit_els_rsp64_wqe xmit_els_rsp;
+	struct els_request64_wqe els_req;
+	struct gen_req64_wqe gen_req;
 	struct fcp_trsp64_wqe fcp_trsp;
 	struct fcp_tsend64_wqe fcp_tsend;
 	struct fcp_treceive64_wqe fcp_treceive;
-	struct xmit_seq64_wqe xmit_sequence;
-	struct gen_req64_wqe gen_req;
+	struct send_frame_wqe send_frame;
 };
 
-#define LPFC_GROUP_OJECT_MAGIC_G5		0xfeaa0001
-#define LPFC_GROUP_OJECT_MAGIC_G6		0xfeaa0003
-#define LPFC_FILE_TYPE_GROUP			0xf7
-#define LPFC_FILE_ID_GROUP			0xa2
 struct lpfc_grp_hdr {
 	uint32_t size;
 	uint32_t magic_number;
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 0ba3733..07ee340 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -116,6 +116,8 @@ const struct pci_device_id lpfc_id_table[] = {
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G6_FC,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7_FC,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index f539c55..7887468 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -731,7 +731,9 @@ lpfc_hba_init_link_fc_topology(struct lpfc_hba *phba, uint32_t fc_topology,
 	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G) &&
 	     !(phba->lmt & LMT_16Gb)) ||
 	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_32G) &&
-	     !(phba->lmt & LMT_32Gb))) {
+	     !(phba->lmt & LMT_32Gb)) ||
+	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_64G) &&
+	     !(phba->lmt & LMT_64Gb))) {
 		/* Reset link speed to auto */
 		lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
 			"1302 Invalid speed for this board:%d "
@@ -958,6 +960,7 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba)
 	struct lpfc_sli_ring *pring;
 	LIST_HEAD(completions);
 	int i;
+	struct lpfc_iocbq *piocb, *next_iocb;
 
 	if (phba->sli_rev != LPFC_SLI_REV4) {
 		for (i = 0; i < psli->num_rings; i++) {
@@ -983,6 +986,9 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba)
 		if (!pring)
 			continue;
 		spin_lock_irq(&pring->ring_lock);
+		list_for_each_entry_safe(piocb, next_iocb,
+					 &pring->txcmplq, list)
+			piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
 		list_splice_init(&pring->txcmplq, &completions);
 		pring->txcmplq_cnt = 0;
 		spin_unlock_irq(&pring->ring_lock);
@@ -1757,7 +1763,7 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action,
 	int rc;
 	uint32_t intr_mode;
 
-	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >=
 	    LPFC_SLI_INTF_IF_TYPE_2) {
 		/*
 		 * On error status condition, driver need to wait for port
@@ -1888,6 +1894,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
 		break;
 
 	case LPFC_SLI_INTF_IF_TYPE_2:
+	case LPFC_SLI_INTF_IF_TYPE_6:
 		pci_rd_rc1 = lpfc_readl(
 				phba->sli4_hba.u.if_type2.STATUSregaddr,
 				&portstat_reg.word0);
@@ -2269,7 +2276,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
 		&& descp && descp[0] != '\0')
 		return;
 
-	if (phba->lmt & LMT_32Gb)
+	if (phba->lmt & LMT_64Gb)
+		max_speed = 64;
+	else if (phba->lmt & LMT_32Gb)
 		max_speed = 32;
 	else if (phba->lmt & LMT_16Gb)
 		max_speed = 16;
@@ -2468,6 +2477,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
 	case PCI_DEVICE_ID_LANCER_G6_FC:
 		m = (typeof(m)){"LPe32000", "PCIe", "Fibre Channel Adapter"};
 		break;
+	case PCI_DEVICE_ID_LANCER_G7_FC:
+		m = (typeof(m)){"LPe36000", "PCIe", "Fibre Channel Adapter"};
+		break;
 	case PCI_DEVICE_ID_SKYHAWK:
 	case PCI_DEVICE_ID_SKYHAWK_VF:
 		oneConnect = 1;
@@ -4104,6 +4116,8 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost)
 				 sizeof fc_host_symbolic_name(shost));
 
 	fc_host_supported_speeds(shost) = 0;
+	if (phba->lmt & LMT_64Gb)
+		fc_host_supported_speeds(shost) |= FC_PORTSPEED_64GBIT;
 	if (phba->lmt & LMT_32Gb)
 		fc_host_supported_speeds(shost) |= FC_PORTSPEED_32GBIT;
 	if (phba->lmt & LMT_16Gb)
@@ -4440,6 +4454,9 @@ lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code,
 		case LPFC_FC_LA_SPEED_32G:
 			port_speed = 32000;
 			break;
+		case LPFC_FC_LA_SPEED_64G:
+			port_speed = 64000;
+			break;
 		default:
 			port_speed = 0;
 		}
@@ -5895,7 +5912,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
 	 * Since lpfc_sg_seg_cnt is module param, the sg_dma_buf_size
 	 * used to create the sg_dma_buf_pool must be calculated.
 	 */
-	if (phba->cfg_enable_bg) {
+	if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) {
 		/*
 		 * The scsi_buf for a T10-DIF I/O holds the FCP cmnd,
 		 * the FCP rsp, and a SGE. Sice we have no control
@@ -6014,7 +6031,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
 		return -ENOMEM;
 
 	/* IF Type 2 ports get initialized now. */
-	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >=
 	    LPFC_SLI_INTF_IF_TYPE_2) {
 		rc = lpfc_pci_function_reset(phba);
 		if (unlikely(rc)) {
@@ -7344,6 +7361,7 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
 			}
 			break;
 		case LPFC_SLI_INTF_IF_TYPE_2:
+		case LPFC_SLI_INTF_IF_TYPE_6:
 			/* Final checks.  The port status should be clean. */
 			if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
 				&reg_data.word0) ||
@@ -7426,13 +7444,36 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type)
 		phba->sli4_hba.WQDBregaddr =
 			phba->sli4_hba.conf_regs_memmap_p +
 						LPFC_ULP0_WQ_DOORBELL;
-		phba->sli4_hba.EQCQDBregaddr =
+		phba->sli4_hba.CQDBregaddr =
 			phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL;
+		phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
 		phba->sli4_hba.MQDBregaddr =
 			phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL;
 		phba->sli4_hba.BMBXregaddr =
 			phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX;
 		break;
+	case LPFC_SLI_INTF_IF_TYPE_6:
+		phba->sli4_hba.u.if_type2.EQDregaddr =
+			phba->sli4_hba.conf_regs_memmap_p +
+						LPFC_CTL_PORT_EQ_DELAY_OFFSET;
+		phba->sli4_hba.u.if_type2.ERR1regaddr =
+			phba->sli4_hba.conf_regs_memmap_p +
+						LPFC_CTL_PORT_ER1_OFFSET;
+		phba->sli4_hba.u.if_type2.ERR2regaddr =
+			phba->sli4_hba.conf_regs_memmap_p +
+						LPFC_CTL_PORT_ER2_OFFSET;
+		phba->sli4_hba.u.if_type2.CTRLregaddr =
+			phba->sli4_hba.conf_regs_memmap_p +
+						LPFC_CTL_PORT_CTL_OFFSET;
+		phba->sli4_hba.u.if_type2.STATUSregaddr =
+			phba->sli4_hba.conf_regs_memmap_p +
+						LPFC_CTL_PORT_STA_OFFSET;
+		phba->sli4_hba.PSMPHRregaddr =
+			phba->sli4_hba.conf_regs_memmap_p +
+						LPFC_CTL_PORT_SEM_OFFSET;
+		phba->sli4_hba.BMBXregaddr =
+			phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX;
+		break;
 	case LPFC_SLI_INTF_IF_TYPE_1:
 	default:
 		dev_printk(KERN_ERR, &phba->pcidev->dev,
@@ -7446,20 +7487,43 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type)
  * lpfc_sli4_bar1_register_memmap - Set up SLI4 BAR1 register memory map.
  * @phba: pointer to lpfc hba data structure.
  *
- * This routine is invoked to set up SLI4 BAR1 control status register (CSR)
- * memory map.
+ * This routine is invoked to set up SLI4 BAR1 register memory map.
  **/
 static void
-lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba)
+lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba, uint32_t if_type)
 {
-	phba->sli4_hba.PSMPHRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
-		LPFC_SLIPORT_IF0_SMPHR;
-	phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
-		LPFC_HST_ISR0;
-	phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
-		LPFC_HST_IMR0;
-	phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
-		LPFC_HST_ISCR0;
+	switch (if_type) {
+	case LPFC_SLI_INTF_IF_TYPE_0:
+		phba->sli4_hba.PSMPHRregaddr =
+			phba->sli4_hba.ctrl_regs_memmap_p +
+			LPFC_SLIPORT_IF0_SMPHR;
+		phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
+			LPFC_HST_ISR0;
+		phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
+			LPFC_HST_IMR0;
+		phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
+			LPFC_HST_ISCR0;
+		break;
+	case LPFC_SLI_INTF_IF_TYPE_6:
+		phba->sli4_hba.RQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
+			LPFC_IF6_RQ_DOORBELL;
+		phba->sli4_hba.WQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
+			LPFC_IF6_WQ_DOORBELL;
+		phba->sli4_hba.CQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
+			LPFC_IF6_CQ_DOORBELL;
+		phba->sli4_hba.EQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
+			LPFC_IF6_EQ_DOORBELL;
+		phba->sli4_hba.MQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
+			LPFC_IF6_MQ_DOORBELL;
+		break;
+	case LPFC_SLI_INTF_IF_TYPE_2:
+	case LPFC_SLI_INTF_IF_TYPE_1:
+	default:
+		dev_err(&phba->pcidev->dev,
+			   "FATAL - unsupported SLI4 interface type - %d\n",
+			   if_type);
+		break;
+	}
 }
 
 /**
@@ -7484,8 +7548,10 @@ lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, uint32_t vf)
 	phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
 				vf * LPFC_VFR_PAGE_SIZE +
 					LPFC_ULP0_WQ_DOORBELL);
-	phba->sli4_hba.EQCQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
-				vf * LPFC_VFR_PAGE_SIZE + LPFC_EQCQ_DOORBELL);
+	phba->sli4_hba.CQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
+				vf * LPFC_VFR_PAGE_SIZE +
+					LPFC_EQCQ_DOORBELL);
+	phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
 	phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
 				vf * LPFC_VFR_PAGE_SIZE + LPFC_MQ_DOORBELL);
 	phba->sli4_hba.BMBXregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
@@ -7722,7 +7788,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
 
 	/* Update link speed if forced link speed is supported */
 	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
-	if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
+	if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
 		forced_link_speed =
 			bf_get(lpfc_mbx_rd_conf_link_speed, rd_config);
 		if (forced_link_speed) {
@@ -7757,6 +7823,10 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
 				phba->cfg_link_speed =
 					LPFC_USER_LINK_SPEED_32G;
 				break;
+			case LINK_SPEED_64G:
+				phba->cfg_link_speed =
+					LPFC_USER_LINK_SPEED_64G;
+				break;
 			case 0xffff:
 				phba->cfg_link_speed =
 					LPFC_USER_LINK_SPEED_AUTO;
@@ -7782,7 +7852,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
 		phba->cfg_hba_queue_depth = length;
 	}
 
-	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
 	    LPFC_SLI_INTF_IF_TYPE_2)
 		goto read_cfg_out;
 
@@ -7896,6 +7966,7 @@ lpfc_setup_endian_order(struct lpfc_hba *phba)
 		}
 		mempool_free(mboxq, phba->mbox_mem_pool);
 		break;
+	case LPFC_SLI_INTF_IF_TYPE_6:
 	case LPFC_SLI_INTF_IF_TYPE_2:
 	case LPFC_SLI_INTF_IF_TYPE_1:
 	default:
@@ -7992,6 +8063,7 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx)
 				wqidx);
 		return 1;
 	}
+	qdesc->qe_valid = 1;
 	phba->sli4_hba.nvme_cq[wqidx] = qdesc;
 
 	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
@@ -8011,9 +8083,10 @@ static int
 lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
 {
 	struct lpfc_queue *qdesc;
+	uint32_t wqesize;
 
 	/* Create Fast Path FCP CQs */
-	if (phba->fcp_embed_io)
+	if (phba->enab_exp_wqcq_pages)
 		/* Increase the CQ size when WQEs contain an embedded cdb */
 		qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
 					      phba->sli4_hba.cq_esize,
@@ -8028,18 +8101,22 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
 			"0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx);
 		return 1;
 	}
+	qdesc->qe_valid = 1;
 	phba->sli4_hba.fcp_cq[wqidx] = qdesc;
 
 	/* Create Fast Path FCP WQs */
-	if (phba->fcp_embed_io)
+	if (phba->enab_exp_wqcq_pages) {
 		/* Increase the WQ size when WQEs contain an embedded cdb */
+		wqesize = (phba->fcp_embed_io) ?
+			LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;
 		qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
-					      LPFC_WQE128_SIZE,
+					      wqesize,
 					      LPFC_WQE_EXP_COUNT);
-	else
+	} else
 		qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
 					      phba->sli4_hba.wq_esize,
 					      phba->sli4_hba.wq_ecount);
+
 	if (!qdesc) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"0503 Failed allocate fast-path FCP WQ (%d)\n",
@@ -8218,6 +8295,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
 					"0497 Failed allocate EQ (%d)\n", idx);
 			goto out_error;
 		}
+		qdesc->qe_valid = 1;
 		phba->sli4_hba.hba_eq[idx] = qdesc;
 	}
 
@@ -8243,6 +8321,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
 					"CQ Set (%d)\n", idx);
 				goto out_error;
 			}
+			qdesc->qe_valid = 1;
 			phba->sli4_hba.nvmet_cqset[idx] = qdesc;
 		}
 	}
@@ -8260,6 +8339,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
 				"0500 Failed allocate slow-path mailbox CQ\n");
 		goto out_error;
 	}
+	qdesc->qe_valid = 1;
 	phba->sli4_hba.mbx_cq = qdesc;
 
 	/* Create slow-path ELS Complete Queue */
@@ -8271,6 +8351,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
 				"0501 Failed allocate slow-path ELS CQ\n");
 		goto out_error;
 	}
+	qdesc->qe_valid = 1;
 	phba->sli4_hba.els_cq = qdesc;
 
 
@@ -8316,6 +8397,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
 					"6079 Failed allocate NVME LS CQ\n");
 			goto out_error;
 		}
+		qdesc->qe_valid = 1;
 		phba->sli4_hba.nvmels_cq = qdesc;
 
 		/* Create NVME LS Work Queue */
@@ -9303,6 +9385,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
 		}
 		break;
 	case LPFC_SLI_INTF_IF_TYPE_2:
+	case LPFC_SLI_INTF_IF_TYPE_6:
 wait:
 		/*
 		 * Poll the Port Status Register and wait for RDY for
@@ -9458,7 +9541,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
 	} else {
 		phba->pci_bar0_map = pci_resource_start(pdev, 1);
 		bar0map_len = pci_resource_len(pdev, 1);
-		if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
+		if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
 			dev_printk(KERN_ERR, &pdev->dev,
 			   "FATAL - No BAR0 mapping for SLI4, if_type 2\n");
 			goto out;
@@ -9495,13 +9578,32 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
 			}
 			phba->pci_bar2_memmap_p =
 					 phba->sli4_hba.ctrl_regs_memmap_p;
-			lpfc_sli4_bar1_register_memmap(phba);
+			lpfc_sli4_bar1_register_memmap(phba, if_type);
 		} else {
 			error = -ENOMEM;
 			goto out_iounmap_conf;
 		}
 	}
 
+	if ((if_type == LPFC_SLI_INTF_IF_TYPE_6) &&
+	    (pci_resource_start(pdev, PCI_64BIT_BAR2))) {
+		/*
+		 * Map SLI4 if type 6 HBA Doorbell Register base to a kernel
+		 * virtual address and setup the registers.
+		 */
+		phba->pci_bar1_map = pci_resource_start(pdev, PCI_64BIT_BAR2);
+		bar1map_len = pci_resource_len(pdev, PCI_64BIT_BAR2);
+		phba->sli4_hba.drbl_regs_memmap_p =
+				ioremap(phba->pci_bar1_map, bar1map_len);
+		if (!phba->sli4_hba.drbl_regs_memmap_p) {
+			dev_err(&pdev->dev,
+			   "ioremap failed for SLI4 HBA doorbell registers.\n");
+			goto out_iounmap_conf;
+		}
+		phba->pci_bar2_memmap_p = phba->sli4_hba.drbl_regs_memmap_p;
+		lpfc_sli4_bar1_register_memmap(phba, if_type);
+	}
+
 	if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
 		if (pci_resource_start(pdev, PCI_64BIT_BAR4)) {
 			/*
@@ -9532,6 +9634,41 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
 		}
 	}
 
+	if (if_type == LPFC_SLI_INTF_IF_TYPE_6 &&
+	    pci_resource_start(pdev, PCI_64BIT_BAR4)) {
+		/*
+		 * Map SLI4 if type 6 HBA DPP Register base to a kernel
+		 * virtual address and setup the registers.
+		 */
+		phba->pci_bar2_map = pci_resource_start(pdev, PCI_64BIT_BAR4);
+		bar2map_len = pci_resource_len(pdev, PCI_64BIT_BAR4);
+		phba->sli4_hba.dpp_regs_memmap_p =
+				ioremap(phba->pci_bar2_map, bar2map_len);
+		if (!phba->sli4_hba.dpp_regs_memmap_p) {
+			dev_err(&pdev->dev,
+			   "ioremap failed for SLI4 HBA dpp registers.\n");
+			goto out_iounmap_ctrl;
+		}
+		phba->pci_bar4_memmap_p = phba->sli4_hba.dpp_regs_memmap_p;
+	}
+
+	/* Set up the EQ/CQ register handeling functions now */
+	switch (if_type) {
+	case LPFC_SLI_INTF_IF_TYPE_0:
+	case LPFC_SLI_INTF_IF_TYPE_2:
+		phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_eq_clr_intr;
+		phba->sli4_hba.sli4_eq_release = lpfc_sli4_eq_release;
+		phba->sli4_hba.sli4_cq_release = lpfc_sli4_cq_release;
+		break;
+	case LPFC_SLI_INTF_IF_TYPE_6:
+		phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_if6_eq_clr_intr;
+		phba->sli4_hba.sli4_eq_release = lpfc_sli4_if6_eq_release;
+		phba->sli4_hba.sli4_cq_release = lpfc_sli4_if6_cq_release;
+		break;
+	default:
+		break;
+	}
+
 	return 0;
 
 out_iounmap_all:
@@ -9566,6 +9703,10 @@ lpfc_sli4_pci_mem_unset(struct lpfc_hba *phba)
 	case LPFC_SLI_INTF_IF_TYPE_2:
 		iounmap(phba->sli4_hba.conf_regs_memmap_p);
 		break;
+	case LPFC_SLI_INTF_IF_TYPE_6:
+		iounmap(phba->sli4_hba.drbl_regs_memmap_p);
+		iounmap(phba->sli4_hba.conf_regs_memmap_p);
+		break;
 	case LPFC_SLI_INTF_IF_TYPE_1:
 	default:
 		dev_printk(KERN_ERR, &phba->pcidev->dev,
@@ -10435,6 +10576,8 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 	sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters);
 	sli4_params->wqv = bf_get(cfg_wqv, mbx_sli4_parameters);
 	sli4_params->rqv = bf_get(cfg_rqv, mbx_sli4_parameters);
+	sli4_params->eqav = bf_get(cfg_eqav, mbx_sli4_parameters);
+	sli4_params->cqav = bf_get(cfg_cqav, mbx_sli4_parameters);
 	sli4_params->wqsize = bf_get(cfg_wqsize, mbx_sli4_parameters);
 	sli4_params->sgl_pages_max = bf_get(cfg_sgl_page_cnt,
 					    mbx_sli4_parameters);
@@ -10465,8 +10608,32 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 		phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
 	}
 
-	if (bf_get(cfg_xib, mbx_sli4_parameters) && phba->cfg_suppress_rsp)
+	/* Only embed PBDE for if_type 6 */
+	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+	    LPFC_SLI_INTF_IF_TYPE_6) {
+		phba->fcp_embed_pbde = 1;
+		phba->nvme_embed_pbde = 1;
+	}
+
+	/* PBDE support requires xib be set */
+	if (!bf_get(cfg_xib, mbx_sli4_parameters)) {
+		phba->fcp_embed_pbde = 0;
+		phba->nvme_embed_pbde = 0;
+	}
+
+	/*
+	 * To support Suppress Response feature we must satisfy 3 conditions.
+	 * lpfc_suppress_rsp module parameter must be set (default).
+	 * In SLI4-Parameters Descriptor:
+	 * Extended Inline Buffers (XIB) must be supported.
+	 * Suppress Response IU Not Supported (SRIUNS) must NOT be supported
+	 * (double negative).
+	 */
+	if (phba->cfg_suppress_rsp && bf_get(cfg_xib, mbx_sli4_parameters) &&
+	    !(bf_get(cfg_nosr, mbx_sli4_parameters)))
 		phba->sli.sli_flag |= LPFC_SLI_SUPPRESS_RSP;
+	else
+		phba->cfg_suppress_rsp = 0;
 
 	if (bf_get(cfg_eqdr, mbx_sli4_parameters))
 		phba->sli.sli_flag |= LPFC_SLI_USE_EQDR;
@@ -10476,15 +10643,28 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 		sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
 
 	/*
-	 * Issue IOs with CDB embedded in WQE to minimized the number
-	 * of DMAs the firmware has to do. Setting this to 1 also forces
-	 * the driver to use 128 bytes WQEs for FCP IOs.
+	 * Check whether the adapter supports an embedded copy of the
+	 * FCP CMD IU within the WQE for FCP_Ixxx commands. In order
+	 * to use this option, 128-byte WQEs must be used.
 	 */
 	if (bf_get(cfg_ext_embed_cb, mbx_sli4_parameters))
 		phba->fcp_embed_io = 1;
 	else
 		phba->fcp_embed_io = 0;
 
+	lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME,
+			"6422 XIB %d: FCP %d %d NVME %d %d %d %d\n",
+			bf_get(cfg_xib, mbx_sli4_parameters),
+			phba->fcp_embed_pbde, phba->fcp_embed_io,
+			phba->nvme_support, phba->nvme_embed_pbde,
+			phba->cfg_nvme_embed_cmd, phba->cfg_suppress_rsp);
+
+	if ((bf_get(cfg_cqpsize, mbx_sli4_parameters) & LPFC_CQ_16K_PAGE_SZ) &&
+	    (bf_get(cfg_wqpsize, mbx_sli4_parameters) & LPFC_WQ_16K_PAGE_SZ) &&
+	    (sli4_params->wqsize & LPFC_WQ_SZ128_SUPPORT))
+		phba->enab_exp_wqcq_pages = 1;
+	else
+		phba->enab_exp_wqcq_pages = 0;
 	/*
 	 * Check if the SLI port supports MDS Diagnostics
 	 */
@@ -11137,6 +11317,27 @@ lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba)
 }
 
 
+static void
+lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset,
+	uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize,
+	const struct firmware *fw)
+{
+	if (offset == ADD_STATUS_FW_NOT_SUPPORTED)
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"3030 This firmware version is not supported on "
+			"this HBA model. Device:%x Magic:%x Type:%x "
+			"ID:%x Size %d %zd\n",
+			phba->pcidev->device, magic_number, ftype, fid,
+			fsize, fw->size);
+	else
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"3022 FW Download failed. Device:%x Magic:%x Type:%x "
+			"ID:%x Size %d %zd\n",
+			phba->pcidev->device, magic_number, ftype, fid,
+			fsize, fw->size);
+}
+
+
 /**
  * lpfc_write_firmware - attempt to write a firmware image to the port
  * @fw: pointer to firmware image returned from request_firmware.
@@ -11164,20 +11365,10 @@ lpfc_write_firmware(const struct firmware *fw, void *context)
 
 	magic_number = be32_to_cpu(image->magic_number);
 	ftype = bf_get_be32(lpfc_grp_hdr_file_type, image);
-	fid = bf_get_be32(lpfc_grp_hdr_id, image),
+	fid = bf_get_be32(lpfc_grp_hdr_id, image);
 	fsize = be32_to_cpu(image->size);
 
 	INIT_LIST_HEAD(&dma_buffer_list);
-	if ((magic_number != LPFC_GROUP_OJECT_MAGIC_G5 &&
-	     magic_number != LPFC_GROUP_OJECT_MAGIC_G6) ||
-	    ftype != LPFC_FILE_TYPE_GROUP || fsize != fw->size) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"3022 Invalid FW image found. "
-				"Magic:%x Type:%x ID:%x Size %d %zd\n",
-				magic_number, ftype, fid, fsize, fw->size);
-		rc = -EINVAL;
-		goto release_out;
-	}
 	lpfc_decode_firmware_rev(phba, fwrev, 1);
 	if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -11218,11 +11409,18 @@ lpfc_write_firmware(const struct firmware *fw, void *context)
 			}
 			rc = lpfc_wr_object(phba, &dma_buffer_list,
 				    (fw->size - offset), &offset);
-			if (rc)
+			if (rc) {
+				lpfc_log_write_firmware_error(phba, offset,
+					magic_number, ftype, fid, fsize, fw);
 				goto release_out;
+			}
 		}
 		rc = offset;
-	}
+	} else
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"3029 Skipped Firmware update, Current "
+				"Version:%s New Version:%s\n",
+				fwrev, image->revision);
 
 release_out:
 	list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) {
@@ -11253,7 +11451,7 @@ lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade)
 	const struct firmware *fw;
 
 	/* Only supported on SLI4 interface type 2 for now */
-	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
 	    LPFC_SLI_INTF_IF_TYPE_2)
 		return -EPERM;
 
@@ -11493,13 +11691,6 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
 	/* Remove FC host and then SCSI host with the physical port */
 	fc_remove_host(shost);
 	scsi_remove_host(shost);
-	/*
-	 * Bring down the SLI Layer. This step disables all interrupts,
-	 * clears the rings, discards all mailbox commands, and resets
-	 * the HBA FCoE function.
-	 */
-	lpfc_debugfs_terminate(vport);
-	lpfc_sli4_hba_unset(phba);
 
 	/* Perform ndlp cleanup on the physical port.  The nvme and nvmet
 	 * localports are destroyed after to cleanup all transport memory.
@@ -11508,6 +11699,13 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
 	lpfc_nvmet_destroy_targetport(phba);
 	lpfc_nvme_destroy_localport(vport);
 
+	/*
+	 * Bring down the SLI Layer. This step disables all interrupts,
+	 * clears the rings, discards all mailbox commands, and resets
+	 * the HBA FCoE function.
+	 */
+	lpfc_debugfs_terminate(vport);
+	lpfc_sli4_hba_unset(phba);
 
 	lpfc_stop_hba_timers(phba);
 	spin_lock_irq(&phba->hbalock);
@@ -12227,6 +12425,7 @@ int
 lpfc_fof_queue_create(struct lpfc_hba *phba)
 {
 	struct lpfc_queue *qdesc;
+	uint32_t wqesize;
 
 	/* Create FOF EQ */
 	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
@@ -12235,12 +12434,13 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
 	if (!qdesc)
 		goto out_error;
 
+	qdesc->qe_valid = 1;
 	phba->sli4_hba.fof_eq = qdesc;
 
 	if (phba->cfg_fof) {
 
 		/* Create OAS CQ */
-		if (phba->fcp_embed_io)
+		if (phba->enab_exp_wqcq_pages)
 			qdesc = lpfc_sli4_queue_alloc(phba,
 						      LPFC_EXPANDED_PAGE_SIZE,
 						      phba->sli4_hba.cq_esize,
@@ -12253,19 +12453,23 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
 		if (!qdesc)
 			goto out_error;
 
+		qdesc->qe_valid = 1;
 		phba->sli4_hba.oas_cq = qdesc;
 
 		/* Create OAS WQ */
-		if (phba->fcp_embed_io)
+		if (phba->enab_exp_wqcq_pages) {
+			wqesize = (phba->fcp_embed_io) ?
+				LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;
 			qdesc = lpfc_sli4_queue_alloc(phba,
 						      LPFC_EXPANDED_PAGE_SIZE,
-						      LPFC_WQE128_SIZE,
+						      wqesize,
 						      LPFC_WQE_EXP_COUNT);
-		else
+		} else
 			qdesc = lpfc_sli4_queue_alloc(phba,
 						      LPFC_DEFAULT_PAGE_SIZE,
 						      phba->sli4_hba.wq_esize,
 						      phba->sli4_hba.wq_ecount);
+
 		if (!qdesc)
 			goto out_error;
 
@@ -12379,6 +12583,8 @@ lpfc_init(void)
 		fc_release_transport(lpfc_transport_template);
 		return -ENOMEM;
 	}
+	lpfc_nvme_cmd_template();
+	lpfc_nvmet_cmd_template();
 
 	/* Initialize in case vector mapping is needed */
 	lpfc_used_cpu = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 81fb929..47c02da 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -557,6 +557,10 @@ lpfc_init_link(struct lpfc_hba * phba,
 			mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
 			mb->un.varInitLnk.link_speed = LINK_SPEED_32G;
 			break;
+		case LPFC_USER_LINK_SPEED_64G:
+			mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+			mb->un.varInitLnk.link_speed = LINK_SPEED_64G;
+			break;
 		case LPFC_USER_LINK_SPEED_AUTO:
 		default:
 			mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
@@ -2170,10 +2174,8 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
 	/* Only FC supports upd bit */
 	if ((phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) &&
 	    (vport->fc_flag & FC_VFI_REGISTERED) &&
-	    (!phba->fc_topology_changed)) {
-		bf_set(lpfc_reg_vfi_vp, reg_vfi, 0);
+	    (!phba->fc_topology_changed))
 		bf_set(lpfc_reg_vfi_upd, reg_vfi, 1);
-	}
 
 	bf_set(lpfc_reg_vfi_bbcr, reg_vfi, 0);
 	bf_set(lpfc_reg_vfi_bbscn, reg_vfi, 0);
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 87c08ff..4136166 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2014 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -753,12 +753,16 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
 	drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys);
 	rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe);
 	if (rc < 0) {
+		(rqbp->rqb_free_buffer)(phba, rqb_entry);
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"6409 Cannot post to RQ %d: %x %x\n",
+				"6409 Cannot post to HRQ %d: %x %x %x "
+				"DRQ %x %x\n",
 				rqb_entry->hrq->queue_id,
 				rqb_entry->hrq->host_index,
-				rqb_entry->hrq->hba_index);
-		(rqbp->rqb_free_buffer)(phba, rqb_entry);
+				rqb_entry->hrq->hba_index,
+				rqb_entry->hrq->entry_count,
+				rqb_entry->drq->host_index,
+				rqb_entry->drq->hba_index);
 	} else {
 		list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list);
 		rqbp->buffer_count++;
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index d841aa4..0220606 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1,7 +1,7 @@
- /*******************************************************************
+/*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -1998,8 +1998,14 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 			ndlp->nlp_type |= NLP_NVME_TARGET;
 			if (bf_get_be32(prli_disc, nvpr))
 				ndlp->nlp_type |= NLP_NVME_DISCOVERY;
+
+			/*
+			 * If prli_fba is set, the Target supports FirstBurst.
+			 * If prli_fb_sz is 0, the FirstBurst size is unlimited,
+			 * otherwise it defines the actual size supported by
+			 * the NVME Target.
+			 */
 			if ((bf_get_be32(prli_fba, nvpr) == 1) &&
-			    (bf_get_be32(prli_fb_sz, nvpr) > 0) &&
 			    (phba->cfg_nvme_enable_fb) &&
 			    (!phba->nvmet_support)) {
 				/* Both sides support FB. The target's first
@@ -2008,12 +2014,16 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 				ndlp->nlp_flag |= NLP_FIRSTBURST;
 				ndlp->nvme_fb_size = bf_get_be32(prli_fb_sz,
 								 nvpr);
+
+				/* Expressed in units of 512 bytes */
+				if (ndlp->nvme_fb_size)
+					ndlp->nvme_fb_size <<=
+						LPFC_NVME_FB_SHIFT;
+				else
+					ndlp->nvme_fb_size = LPFC_NVME_MAX_FB;
 			}
 		}
 
-		if (bf_get_be32(prli_recov, nvpr))
-			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
-
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
 				 "6029 NVME PRLI Cmpl w1 x%08x "
 				 "w4 x%08x w5 x%08x flag x%x, "
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 81e3a4f..378dca4 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -65,6 +65,136 @@ lpfc_release_nvme_buf(struct lpfc_hba *, struct lpfc_nvme_buf *);
 
 static struct nvme_fc_port_template lpfc_nvme_template;
 
+static union lpfc_wqe128 lpfc_iread_cmd_template;
+static union lpfc_wqe128 lpfc_iwrite_cmd_template;
+static union lpfc_wqe128 lpfc_icmnd_cmd_template;
+
+/* Setup WQE templates for NVME IOs */
+void
+lpfc_nvme_cmd_template(void)
+{
+	union lpfc_wqe128 *wqe;
+
+	/* IREAD template */
+	wqe = &lpfc_iread_cmd_template;
+	memset(wqe, 0, sizeof(union lpfc_wqe128));
+
+	/* Word 0, 1, 2 - BDE is variable */
+
+	/* Word 3 - cmd_buff_len, payload_offset_len is zero */
+
+	/* Word 4 - total_xfer_len is variable */
+
+	/* Word 5 - is zero */
+
+	/* Word 6 - ctxt_tag, xri_tag is variable */
+
+	/* Word 7 */
+	bf_set(wqe_cmnd, &wqe->fcp_iread.wqe_com, CMD_FCP_IREAD64_WQE);
+	bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, PARM_READ_CHECK);
+	bf_set(wqe_class, &wqe->fcp_iread.wqe_com, CLASS3);
+	bf_set(wqe_ct, &wqe->fcp_iread.wqe_com, SLI4_CT_RPI);
+
+	/* Word 8 - abort_tag is variable */
+
+	/* Word 9  - reqtag is variable */
+
+	/* Word 10 - dbde, wqes is variable */
+	bf_set(wqe_qosd, &wqe->fcp_iread.wqe_com, 0);
+	bf_set(wqe_nvme, &wqe->fcp_iread.wqe_com, 1);
+	bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ);
+	bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, LPFC_WQE_LENLOC_WORD4);
+	bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 0);
+	bf_set(wqe_wqes, &wqe->fcp_iread.wqe_com, 1);
+
+	/* Word 11 - pbde is variable */
+	bf_set(wqe_cmd_type, &wqe->fcp_iread.wqe_com, NVME_READ_CMD);
+	bf_set(wqe_cqid, &wqe->fcp_iread.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
+	bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 1);
+
+	/* Word 12 - is zero */
+
+	/* Word 13, 14, 15 - PBDE is variable */
+
+	/* IWRITE template */
+	wqe = &lpfc_iwrite_cmd_template;
+	memset(wqe, 0, sizeof(union lpfc_wqe128));
+
+	/* Word 0, 1, 2 - BDE is variable */
+
+	/* Word 3 - cmd_buff_len, payload_offset_len is zero */
+
+	/* Word 4 - total_xfer_len is variable */
+
+	/* Word 5 - initial_xfer_len is variable */
+
+	/* Word 6 - ctxt_tag, xri_tag is variable */
+
+	/* Word 7 */
+	bf_set(wqe_cmnd, &wqe->fcp_iwrite.wqe_com, CMD_FCP_IWRITE64_WQE);
+	bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, PARM_READ_CHECK);
+	bf_set(wqe_class, &wqe->fcp_iwrite.wqe_com, CLASS3);
+	bf_set(wqe_ct, &wqe->fcp_iwrite.wqe_com, SLI4_CT_RPI);
+
+	/* Word 8 - abort_tag is variable */
+
+	/* Word 9  - reqtag is variable */
+
+	/* Word 10 - dbde, wqes is variable */
+	bf_set(wqe_qosd, &wqe->fcp_iwrite.wqe_com, 0);
+	bf_set(wqe_nvme, &wqe->fcp_iwrite.wqe_com, 1);
+	bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE);
+	bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_LENLOC_WORD4);
+	bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 0);
+	bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1);
+
+	/* Word 11 - pbde is variable */
+	bf_set(wqe_cmd_type, &wqe->fcp_iwrite.wqe_com, NVME_WRITE_CMD);
+	bf_set(wqe_cqid, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
+	bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 1);
+
+	/* Word 12 - is zero */
+
+	/* Word 13, 14, 15 - PBDE is variable */
+
+	/* ICMND template */
+	wqe = &lpfc_icmnd_cmd_template;
+	memset(wqe, 0, sizeof(union lpfc_wqe128));
+
+	/* Word 0, 1, 2 - BDE is variable */
+
+	/* Word 3 - payload_offset_len is variable */
+
+	/* Word 4, 5 - is zero */
+
+	/* Word 6 - ctxt_tag, xri_tag is variable */
+
+	/* Word 7 */
+	bf_set(wqe_cmnd, &wqe->fcp_icmd.wqe_com, CMD_FCP_ICMND64_WQE);
+	bf_set(wqe_pu, &wqe->fcp_icmd.wqe_com, 0);
+	bf_set(wqe_class, &wqe->fcp_icmd.wqe_com, CLASS3);
+	bf_set(wqe_ct, &wqe->fcp_icmd.wqe_com, SLI4_CT_RPI);
+
+	/* Word 8 - abort_tag is variable */
+
+	/* Word 9  - reqtag is variable */
+
+	/* Word 10 - dbde, wqes is variable */
+	bf_set(wqe_qosd, &wqe->fcp_icmd.wqe_com, 1);
+	bf_set(wqe_nvme, &wqe->fcp_icmd.wqe_com, 1);
+	bf_set(wqe_iod, &wqe->fcp_icmd.wqe_com, LPFC_WQE_IOD_NONE);
+	bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com, LPFC_WQE_LENLOC_NONE);
+	bf_set(wqe_dbde, &wqe->fcp_icmd.wqe_com, 0);
+	bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 1);
+
+	/* Word 11 */
+	bf_set(wqe_cmd_type, &wqe->fcp_icmd.wqe_com, FCP_COMMAND);
+	bf_set(wqe_cqid, &wqe->fcp_icmd.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
+	bf_set(wqe_pbde, &wqe->fcp_icmd.wqe_com, 0);
+
+	/* Word 12, 13, 14, 15 - is zero */
+}
+
 /**
  * lpfc_nvme_create_queue -
  * @lpfc_pnvme: Pointer to the driver's nvme instance data
@@ -241,10 +371,11 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
 	ndlp = (struct lpfc_nodelist *)cmdwqe->context1;
 	lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
 			 "6047 nvme cmpl Enter "
-			 "Data %p DID %x Xri: %x status %x cmd:%p lsreg:%p "
-			 "bmp:%p ndlp:%p\n",
+			 "Data %p DID %x Xri: %x status %x reason x%x cmd:%p "
+			 "lsreg:%p bmp:%p ndlp:%p\n",
 			 pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0,
 			 cmdwqe->sli4_xritag, status,
+			 (wcqe->parameter & 0xffff),
 			 cmdwqe, pnvme_lsreq, cmdwqe->context3, ndlp);
 
 	lpfc_nvmeio_data(phba, "NVME LS  CMPL: xri x%x stat x%x parm x%x\n",
@@ -274,14 +405,14 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
 static int
 lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
 		  struct lpfc_dmabuf *inp,
-		 struct nvmefc_ls_req *pnvme_lsreq,
-	     void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,
-			   struct lpfc_wcqe_complete *),
-	     struct lpfc_nodelist *ndlp, uint32_t num_entry,
-	     uint32_t tmo, uint8_t retry)
+		  struct nvmefc_ls_req *pnvme_lsreq,
+		  void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,
+			       struct lpfc_wcqe_complete *),
+		  struct lpfc_nodelist *ndlp, uint32_t num_entry,
+		  uint32_t tmo, uint8_t retry)
 {
-	struct lpfc_hba  *phba = vport->phba;
-	union lpfc_wqe *wqe;
+	struct lpfc_hba *phba = vport->phba;
+	union lpfc_wqe128 *wqe;
 	struct lpfc_iocbq *genwqe;
 	struct ulp_bde64 *bpl;
 	struct ulp_bde64 bde;
@@ -419,6 +550,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 {
 	int ret = 0;
 	struct lpfc_nvme_lport *lport;
+	struct lpfc_nvme_rport *rport;
 	struct lpfc_vport *vport;
 	struct lpfc_nodelist *ndlp;
 	struct ulp_bde64 *bpl;
@@ -437,19 +569,18 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 	 */
 
 	lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
+	rport = (struct lpfc_nvme_rport *)pnvme_rport->private;
 	vport = lport->vport;
 
 	if (vport->load_flag & FC_UNLOADING)
 		return -ENODEV;
 
-	if (vport->load_flag & FC_UNLOADING)
-		return -ENODEV;
-
-	ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
+	/* Need the ndlp.  It is stored in the driver's rport. */
+	ndlp = rport->ndlp;
 	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR,
-				 "6051 DID x%06x not an active rport.\n",
-				 pnvme_rport->port_id);
+				 "6051 Remoteport %p, rport has invalid ndlp. "
+				 "Failing LS Req\n", pnvme_rport);
 		return -ENODEV;
 	}
 
@@ -500,8 +631,9 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 
 	/* Expand print to include key fields. */
 	lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
-			 "6149 ENTER.  lport %p, rport %p lsreq%p rqstlen:%d "
-			 "rsplen:%d %pad %pad\n",
+			 "6149 Issue LS Req to DID 0x%06x lport %p, rport %p "
+			 "lsreq%p rqstlen:%d rsplen:%d %pad %pad\n",
+			 ndlp->nlp_DID,
 			 pnvme_lport, pnvme_rport,
 			 pnvme_lsreq, pnvme_lsreq->rqstlen,
 			 pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma,
@@ -517,7 +649,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 				ndlp, 2, 30, 0);
 	if (ret != WQE_SUCCESS) {
 		atomic_inc(&lport->xmt_ls_err);
-		lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
 				 "6052 EXIT. issue ls wqe failed lport %p, "
 				 "rport %p lsreq%p Status %x DID %x\n",
 				 pnvme_lport, pnvme_rport, pnvme_lsreq,
@@ -610,16 +742,25 @@ lpfc_nvme_ls_abort(struct nvme_fc_local_port *pnvme_lport,
 }
 
 /* Fix up the existing sgls for NVME IO. */
-static void
+static inline void
 lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
 		       struct lpfc_nvme_buf *lpfc_ncmd,
 		       struct nvmefc_fcp_req *nCmd)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	struct sli4_sge *sgl;
 	union lpfc_wqe128 *wqe;
 	uint32_t *wptr, *dptr;
 
 	/*
+	 * Get a local pointer to the built-in wqe and correct
+	 * the cmd size to match NVME's 96 bytes and fix
+	 * the dma address.
+	 */
+
+	wqe = &lpfc_ncmd->cur_iocbq.wqe;
+
+	/*
 	 * Adjust the FCP_CMD and FCP_RSP DMA data and sge_len to
 	 * match NVME.  NVME sends 96 bytes. Also, use the
 	 * nvme commands command and response dma addresses
@@ -628,6 +769,60 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
 	 */
 	sgl = lpfc_ncmd->nvme_sgl;
 	sgl->sge_len = cpu_to_le32(nCmd->cmdlen);
+	if (phba->cfg_nvme_embed_cmd) {
+		sgl->addr_hi = 0;
+		sgl->addr_lo = 0;
+
+		/* Word 0-2 - NVME CMND IU (embedded payload) */
+		wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED;
+		wqe->generic.bde.tus.f.bdeSize = 56;
+		wqe->generic.bde.addrHigh = 0;
+		wqe->generic.bde.addrLow =  64;  /* Word 16 */
+
+		/* Word 10  - dbde is 0, wqes is 1 in template */
+
+		/*
+		 * Embed the payload in the last half of the WQE
+		 * WQE words 16-30 get the NVME CMD IU payload
+		 *
+		 * WQE words 16-19 get payload Words 1-4
+		 * WQE words 20-21 get payload Words 6-7
+		 * WQE words 22-29 get payload Words 16-23
+		 */
+		wptr = &wqe->words[16];  /* WQE ptr */
+		dptr = (uint32_t *)nCmd->cmdaddr;  /* payload ptr */
+		dptr++;			/* Skip Word 0 in payload */
+
+		*wptr++ = *dptr++;	/* Word 1 */
+		*wptr++ = *dptr++;	/* Word 2 */
+		*wptr++ = *dptr++;	/* Word 3 */
+		*wptr++ = *dptr++;	/* Word 4 */
+		dptr++;			/* Skip Word 5 in payload */
+		*wptr++ = *dptr++;	/* Word 6 */
+		*wptr++ = *dptr++;	/* Word 7 */
+		dptr += 8;		/* Skip Words 8-15 in payload */
+		*wptr++ = *dptr++;	/* Word 16 */
+		*wptr++ = *dptr++;	/* Word 17 */
+		*wptr++ = *dptr++;	/* Word 18 */
+		*wptr++ = *dptr++;	/* Word 19 */
+		*wptr++ = *dptr++;	/* Word 20 */
+		*wptr++ = *dptr++;	/* Word 21 */
+		*wptr++ = *dptr++;	/* Word 22 */
+		*wptr   = *dptr;	/* Word 23 */
+	} else {
+		sgl->addr_hi = cpu_to_le32(putPaddrHigh(nCmd->cmddma));
+		sgl->addr_lo = cpu_to_le32(putPaddrLow(nCmd->cmddma));
+
+		/* Word 0-2 - NVME CMND IU Inline BDE */
+		wqe->generic.bde.tus.f.bdeFlags =  BUFF_TYPE_BDE_64;
+		wqe->generic.bde.tus.f.bdeSize = nCmd->cmdlen;
+		wqe->generic.bde.addrHigh = sgl->addr_hi;
+		wqe->generic.bde.addrLow =  sgl->addr_lo;
+
+		/* Word 10 */
+		bf_set(wqe_dbde, &wqe->generic.wqe_com, 1);
+		bf_set(wqe_wqes, &wqe->generic.wqe_com, 0);
+	}
 
 	sgl++;
 
@@ -641,58 +836,6 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
 		bf_set(lpfc_sli4_sge_last, sgl, 1);
 	sgl->word2 = cpu_to_le32(sgl->word2);
 	sgl->sge_len = cpu_to_le32(nCmd->rsplen);
-
-	/*
-	 * Get a local pointer to the built-in wqe and correct
-	 * the cmd size to match NVME's 96 bytes and fix
-	 * the dma address.
-	 */
-
-	/* 128 byte wqe support here */
-	wqe = (union lpfc_wqe128 *)&lpfc_ncmd->cur_iocbq.wqe;
-
-	/* Word 0-2 - NVME CMND IU (embedded payload) */
-	wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED;
-	wqe->generic.bde.tus.f.bdeSize = 60;
-	wqe->generic.bde.addrHigh = 0;
-	wqe->generic.bde.addrLow =  64;  /* Word 16 */
-
-	/* Word 3 */
-	bf_set(payload_offset_len, &wqe->fcp_icmd,
-	       (nCmd->rsplen + nCmd->cmdlen));
-
-	/* Word 10 */
-	bf_set(wqe_nvme, &wqe->fcp_icmd.wqe_com, 1);
-	bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 1);
-
-	/*
-	 * Embed the payload in the last half of the WQE
-	 * WQE words 16-30 get the NVME CMD IU payload
-	 *
-	 * WQE words 16-19 get payload Words 1-4
-	 * WQE words 20-21 get payload Words 6-7
-	 * WQE words 22-29 get payload Words 16-23
-	 */
-	wptr = &wqe->words[16];  /* WQE ptr */
-	dptr = (uint32_t *)nCmd->cmdaddr;  /* payload ptr */
-	dptr++;			/* Skip Word 0 in payload */
-
-	*wptr++ = *dptr++;	/* Word 1 */
-	*wptr++ = *dptr++;	/* Word 2 */
-	*wptr++ = *dptr++;	/* Word 3 */
-	*wptr++ = *dptr++;	/* Word 4 */
-	dptr++;			/* Skip Word 5 in payload */
-	*wptr++ = *dptr++;	/* Word 6 */
-	*wptr++ = *dptr++;	/* Word 7 */
-	dptr += 8;		/* Skip Words 8-15 in payload */
-	*wptr++ = *dptr++;	/* Word 16 */
-	*wptr++ = *dptr++;	/* Word 17 */
-	*wptr++ = *dptr++;	/* Word 18 */
-	*wptr++ = *dptr++;	/* Word 19 */
-	*wptr++ = *dptr++;	/* Word 20 */
-	*wptr++ = *dptr++;	/* Word 21 */
-	*wptr++ = *dptr++;	/* Word 22 */
-	*wptr   = *dptr;	/* Word 23 */
 }
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
@@ -980,14 +1123,14 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
 			phba->cpucheck_cmpl_io[lpfc_ncmd->cpu]++;
 	}
 #endif
-	freqpriv = nCmd->private;
-	freqpriv->nvme_buf = NULL;
 
 	/* NVME targets need completion held off until the abort exchange
 	 * completes unless the NVME Rport is getting unregistered.
 	 */
 
 	if (!(lpfc_ncmd->flags & LPFC_SBUF_XBUSY)) {
+		freqpriv = nCmd->private;
+		freqpriv->nvme_buf = NULL;
 		nCmd->done(nCmd);
 		lpfc_ncmd->nvmeCmd = NULL;
 	}
@@ -1025,7 +1168,7 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
 	struct lpfc_hba *phba = vport->phba;
 	struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd;
 	struct lpfc_iocbq *pwqeq = &(lpfc_ncmd->cur_iocbq);
-	union lpfc_wqe128 *wqe = (union lpfc_wqe128 *)&pwqeq->wqe;
+	union lpfc_wqe128 *wqe = &pwqeq->wqe;
 	uint32_t req_len;
 
 	if (!pnode || !NLP_CHK_NODE_ACT(pnode))
@@ -1035,9 +1178,16 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
 	 * There are three possibilities here - use scatter-gather segment, use
 	 * the single mapping, or neither.
 	 */
-	wqe->fcp_iwrite.initial_xfer_len = 0;
 	if (nCmd->sg_cnt) {
 		if (nCmd->io_dir == NVMEFC_FCP_WRITE) {
+			/* From the iwrite template, initialize words 7 - 11 */
+			memcpy(&wqe->words[7],
+			       &lpfc_iwrite_cmd_template.words[7],
+			       sizeof(uint32_t) * 5);
+
+			/* Word 4 */
+			wqe->fcp_iwrite.total_xfer_len = nCmd->payload_length;
+
 			/* Word 5 */
 			if ((phba->cfg_nvme_enable_fb) &&
 			    (pnode->nlp_flag & NLP_FIRSTBURST)) {
@@ -1048,69 +1198,28 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
 				else
 					wqe->fcp_iwrite.initial_xfer_len =
 						pnode->nvme_fb_size;
+			} else {
+				wqe->fcp_iwrite.initial_xfer_len = 0;
 			}
-
-			/* Word 7 */
-			bf_set(wqe_cmnd, &wqe->generic.wqe_com,
-			       CMD_FCP_IWRITE64_WQE);
-			bf_set(wqe_pu, &wqe->generic.wqe_com,
-			       PARM_READ_CHECK);
-
-			/* Word 10 */
-			bf_set(wqe_qosd, &wqe->fcp_iwrite.wqe_com, 0);
-			bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com,
-			       LPFC_WQE_IOD_WRITE);
-			bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com,
-			       LPFC_WQE_LENLOC_WORD4);
-			if (phba->cfg_nvme_oas)
-				bf_set(wqe_oas, &wqe->fcp_iwrite.wqe_com, 1);
-
-			/* Word 11 */
-			bf_set(wqe_cmd_type, &wqe->generic.wqe_com,
-			       NVME_WRITE_CMD);
-
 			atomic_inc(&phba->fc4NvmeOutputRequests);
 		} else {
-			/* Word 7 */
-			bf_set(wqe_cmnd, &wqe->generic.wqe_com,
-			       CMD_FCP_IREAD64_WQE);
-			bf_set(wqe_pu, &wqe->generic.wqe_com,
-			       PARM_READ_CHECK);
+			/* From the iread template, initialize words 7 - 11 */
+			memcpy(&wqe->words[7],
+			       &lpfc_iread_cmd_template.words[7],
+			       sizeof(uint32_t) * 5);
 
-			/* Word 10 */
-			bf_set(wqe_qosd, &wqe->fcp_iread.wqe_com, 0);
-			bf_set(wqe_iod, &wqe->fcp_iread.wqe_com,
-			       LPFC_WQE_IOD_READ);
-			bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com,
-			       LPFC_WQE_LENLOC_WORD4);
-			if (phba->cfg_nvme_oas)
-				bf_set(wqe_oas, &wqe->fcp_iread.wqe_com, 1);
+			/* Word 4 */
+			wqe->fcp_iread.total_xfer_len = nCmd->payload_length;
 
-			/* Word 11 */
-			bf_set(wqe_cmd_type, &wqe->generic.wqe_com,
-			       NVME_READ_CMD);
+			/* Word 5 */
+			wqe->fcp_iread.rsrvd5 = 0;
 
 			atomic_inc(&phba->fc4NvmeInputRequests);
 		}
 	} else {
-		/* Word 4 */
-		wqe->fcp_icmd.rsrvd4 = 0;
-
-		/* Word 7 */
-		bf_set(wqe_cmnd, &wqe->generic.wqe_com, CMD_FCP_ICMND64_WQE);
-		bf_set(wqe_pu, &wqe->generic.wqe_com, 0);
-
-		/* Word 10 */
-		bf_set(wqe_qosd, &wqe->fcp_icmd.wqe_com, 1);
-		bf_set(wqe_iod, &wqe->fcp_icmd.wqe_com, LPFC_WQE_IOD_WRITE);
-		bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com,
-		       LPFC_WQE_LENLOC_NONE);
-		if (phba->cfg_nvme_oas)
-			bf_set(wqe_oas, &wqe->fcp_icmd.wqe_com, 1);
-
-		/* Word 11 */
-		bf_set(wqe_cmd_type, &wqe->generic.wqe_com, NVME_READ_CMD);
-
+		/* From the icmnd template, initialize words 4 - 11 */
+		memcpy(&wqe->words[4], &lpfc_icmnd_cmd_template.words[4],
+		       sizeof(uint32_t) * 8);
 		atomic_inc(&phba->fc4NvmeControlRequests);
 	}
 	/*
@@ -1118,25 +1227,21 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
 	 * of the nvme_cmnd request_buffer
 	 */
 
+	/* Word 3 */
+	bf_set(payload_offset_len, &wqe->fcp_icmd,
+	       (nCmd->rsplen + nCmd->cmdlen));
+
 	/* Word 6 */
 	bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com,
 	       phba->sli4_hba.rpi_ids[pnode->nlp_rpi]);
 	bf_set(wqe_xri_tag, &wqe->generic.wqe_com, pwqeq->sli4_xritag);
 
-	/* Word 7 */
-	/* Preserve Class data in the ndlp. */
-	bf_set(wqe_class, &wqe->generic.wqe_com,
-	       (pnode->nlp_fcp_info & 0x0f));
-
 	/* Word 8 */
 	wqe->generic.wqe_com.abort_tag = pwqeq->iotag;
 
 	/* Word 9 */
 	bf_set(wqe_reqtag, &wqe->generic.wqe_com, pwqeq->iotag);
 
-	/* Word 11 */
-	bf_set(wqe_cqid, &wqe->generic.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
-
 	pwqeq->vport = vport;
 	return 0;
 }
@@ -1164,10 +1269,11 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
 {
 	struct lpfc_hba *phba = vport->phba;
 	struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd;
-	union lpfc_wqe128 *wqe = (union lpfc_wqe128 *)&lpfc_ncmd->cur_iocbq.wqe;
+	union lpfc_wqe128 *wqe = &lpfc_ncmd->cur_iocbq.wqe;
 	struct sli4_sge *sgl = lpfc_ncmd->nvme_sgl;
 	struct scatterlist *data_sg;
 	struct sli4_sge *first_data_sgl;
+	struct ulp_bde64 *bde;
 	dma_addr_t physaddr;
 	uint32_t num_bde = 0;
 	uint32_t dma_len;
@@ -1235,7 +1341,26 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
 			data_sg = sg_next(data_sg);
 			sgl++;
 		}
+		if (phba->nvme_embed_pbde) {
+			/* Use PBDE support for first SGL only, offset == 0 */
+			/* Words 13-15 */
+			bde = (struct ulp_bde64 *)
+				&wqe->words[13];
+			bde->addrLow = first_data_sgl->addr_lo;
+			bde->addrHigh = first_data_sgl->addr_hi;
+			bde->tus.f.bdeSize =
+				le32_to_cpu(first_data_sgl->sge_len);
+			bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+			bde->tus.w = cpu_to_le32(bde->tus.w);
+			/* wqe_pbde is 1 in template */
+		} else {
+			memset(&wqe->words[13], 0, (sizeof(uint32_t) * 3));
+			bf_set(wqe_pbde, &wqe->generic.wqe_com, 0);
+		}
 	} else {
+		bf_set(wqe_pbde, &wqe->generic.wqe_com, 0);
+		memset(&wqe->words[13], 0, (sizeof(uint32_t) * 3));
+
 		/* For this clause to be valid, the payload_length
 		 * and sg_cnt must zero.
 		 */
@@ -1247,12 +1372,6 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
 			return 1;
 		}
 	}
-
-	/*
-	 * Due to difference in data length between DIF/non-DIF paths,
-	 * we need to set word 4 of WQE here
-	 */
-	wqe->fcp_iread.total_xfer_len = nCmd->payload_length;
 	return 0;
 }
 
@@ -1554,7 +1673,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport,
 	struct lpfc_iocbq *abts_buf;
 	struct lpfc_iocbq *nvmereq_wqe;
 	struct lpfc_nvme_fcpreq_priv *freqpriv;
-	union lpfc_wqe *abts_wqe;
+	union lpfc_wqe128 *abts_wqe;
 	unsigned long flags;
 	int ret_val;
 
@@ -2098,7 +2217,7 @@ lpfc_new_nvme_buf(struct lpfc_vport *vport, int num_to_alloc)
 			break;
 		}
 		pwqeq = &(lpfc_ncmd->cur_iocbq);
-		wqe = (union lpfc_wqe128 *)&pwqeq->wqe;
+		wqe = &pwqeq->wqe;
 
 		/* Allocate iotag for lpfc_ncmd->cur_iocbq. */
 		iotag = lpfc_sli_next_iotag(phba, pwqeq);
@@ -2135,14 +2254,8 @@ lpfc_new_nvme_buf(struct lpfc_vport *vport, int num_to_alloc)
 
 		lpfc_ncmd->cur_iocbq.context1 = lpfc_ncmd;
 
-		/* Word 7 */
-		bf_set(wqe_erp, &wqe->generic.wqe_com, 0);
-		/* NVME upper layers will time things out, if needed */
-		bf_set(wqe_tmo, &wqe->generic.wqe_com, 0);
-
-		/* Word 10 */
-		bf_set(wqe_ebde_cnt, &wqe->generic.wqe_com, 0);
-		bf_set(wqe_dbde, &wqe->generic.wqe_com, 1);
+		/* Initialize WQE */
+		memset(wqe, 0, sizeof(union lpfc_wqe));
 
 		/* add the nvme buffer to a post list */
 		list_add_tail(&lpfc_ncmd->list, &post_nblist);
diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h
index e79f8f7..9216653 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.h
+++ b/drivers/scsi/lpfc/lpfc_nvme.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -27,6 +27,8 @@
 
 #define LPFC_NVME_WAIT_TMO              10
 #define LPFC_NVME_EXPEDITE_XRICNT	8
+#define LPFC_NVME_FB_SHIFT		9
+#define LPFC_NVME_MAX_FB		(1 << 20)	/* 1M */
 
 struct lpfc_nvme_qhandle {
 	uint32_t index;		/* WQ index to use */
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 8dbf5c9..7271c9d 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channsel Host Bus Adapters.                               *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -36,7 +36,7 @@
 #include <scsi/scsi_transport_fc.h>
 #include <scsi/fc/fc_fs.h>
 
-#include <../drivers/nvme/host/nvme.h>
+#include <linux/nvme.h>
 #include <linux/nvme-fc-driver.h>
 #include <linux/nvme-fc.h>
 
@@ -71,6 +71,151 @@ static int lpfc_nvmet_unsol_fcp_issue_abort(struct lpfc_hba *,
 static int lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *,
 					   struct lpfc_nvmet_rcv_ctx *,
 					   uint32_t, uint16_t);
+static void lpfc_nvmet_wqfull_flush(struct lpfc_hba *, struct lpfc_queue *,
+				    struct lpfc_nvmet_rcv_ctx *);
+
+static union lpfc_wqe128 lpfc_tsend_cmd_template;
+static union lpfc_wqe128 lpfc_treceive_cmd_template;
+static union lpfc_wqe128 lpfc_trsp_cmd_template;
+
+/* Setup WQE templates for NVME IOs */
+void
+lpfc_nvmet_cmd_template(void)
+{
+	union lpfc_wqe128 *wqe;
+
+	/* TSEND template */
+	wqe = &lpfc_tsend_cmd_template;
+	memset(wqe, 0, sizeof(union lpfc_wqe128));
+
+	/* Word 0, 1, 2 - BDE is variable */
+
+	/* Word 3 - payload_offset_len is zero */
+
+	/* Word 4 - relative_offset is variable */
+
+	/* Word 5 - is zero */
+
+	/* Word 6 - ctxt_tag, xri_tag is variable */
+
+	/* Word 7 - wqe_ar is variable */
+	bf_set(wqe_cmnd, &wqe->fcp_tsend.wqe_com, CMD_FCP_TSEND64_WQE);
+	bf_set(wqe_pu, &wqe->fcp_tsend.wqe_com, PARM_REL_OFF);
+	bf_set(wqe_class, &wqe->fcp_tsend.wqe_com, CLASS3);
+	bf_set(wqe_ct, &wqe->fcp_tsend.wqe_com, SLI4_CT_RPI);
+	bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 1);
+
+	/* Word 8 - abort_tag is variable */
+
+	/* Word 9  - reqtag, rcvoxid is variable */
+
+	/* Word 10 - wqes, xc is variable */
+	bf_set(wqe_nvme, &wqe->fcp_tsend.wqe_com, 1);
+	bf_set(wqe_dbde, &wqe->fcp_tsend.wqe_com, 1);
+	bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 0);
+	bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, 1);
+	bf_set(wqe_iod, &wqe->fcp_tsend.wqe_com, LPFC_WQE_IOD_WRITE);
+	bf_set(wqe_lenloc, &wqe->fcp_tsend.wqe_com, LPFC_WQE_LENLOC_WORD12);
+
+	/* Word 11 - sup, irsp, irsplen is variable */
+	bf_set(wqe_cmd_type, &wqe->fcp_tsend.wqe_com, FCP_COMMAND_TSEND);
+	bf_set(wqe_cqid, &wqe->fcp_tsend.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
+	bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0);
+	bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0);
+	bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0);
+	bf_set(wqe_pbde, &wqe->fcp_tsend.wqe_com, 0);
+
+	/* Word 12 - fcp_data_len is variable */
+
+	/* Word 13, 14, 15 - PBDE is zero */
+
+	/* TRECEIVE template */
+	wqe = &lpfc_treceive_cmd_template;
+	memset(wqe, 0, sizeof(union lpfc_wqe128));
+
+	/* Word 0, 1, 2 - BDE is variable */
+
+	/* Word 3 */
+	wqe->fcp_treceive.payload_offset_len = TXRDY_PAYLOAD_LEN;
+
+	/* Word 4 - relative_offset is variable */
+
+	/* Word 5 - is zero */
+
+	/* Word 6 - ctxt_tag, xri_tag is variable */
+
+	/* Word 7 */
+	bf_set(wqe_cmnd, &wqe->fcp_treceive.wqe_com, CMD_FCP_TRECEIVE64_WQE);
+	bf_set(wqe_pu, &wqe->fcp_treceive.wqe_com, PARM_REL_OFF);
+	bf_set(wqe_class, &wqe->fcp_treceive.wqe_com, CLASS3);
+	bf_set(wqe_ct, &wqe->fcp_treceive.wqe_com, SLI4_CT_RPI);
+	bf_set(wqe_ar, &wqe->fcp_treceive.wqe_com, 0);
+
+	/* Word 8 - abort_tag is variable */
+
+	/* Word 9  - reqtag, rcvoxid is variable */
+
+	/* Word 10 - xc is variable */
+	bf_set(wqe_dbde, &wqe->fcp_treceive.wqe_com, 1);
+	bf_set(wqe_wqes, &wqe->fcp_treceive.wqe_com, 0);
+	bf_set(wqe_nvme, &wqe->fcp_treceive.wqe_com, 1);
+	bf_set(wqe_iod, &wqe->fcp_treceive.wqe_com, LPFC_WQE_IOD_READ);
+	bf_set(wqe_lenloc, &wqe->fcp_treceive.wqe_com, LPFC_WQE_LENLOC_WORD12);
+	bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, 1);
+
+	/* Word 11 - pbde is variable */
+	bf_set(wqe_cmd_type, &wqe->fcp_treceive.wqe_com, FCP_COMMAND_TRECEIVE);
+	bf_set(wqe_cqid, &wqe->fcp_treceive.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
+	bf_set(wqe_sup, &wqe->fcp_treceive.wqe_com, 0);
+	bf_set(wqe_irsp, &wqe->fcp_treceive.wqe_com, 0);
+	bf_set(wqe_irsplen, &wqe->fcp_treceive.wqe_com, 0);
+	bf_set(wqe_pbde, &wqe->fcp_treceive.wqe_com, 1);
+
+	/* Word 12 - fcp_data_len is variable */
+
+	/* Word 13, 14, 15 - PBDE is variable */
+
+	/* TRSP template */
+	wqe = &lpfc_trsp_cmd_template;
+	memset(wqe, 0, sizeof(union lpfc_wqe128));
+
+	/* Word 0, 1, 2 - BDE is variable */
+
+	/* Word 3 - response_len is variable */
+
+	/* Word 4, 5 - is zero */
+
+	/* Word 6 - ctxt_tag, xri_tag is variable */
+
+	/* Word 7 */
+	bf_set(wqe_cmnd, &wqe->fcp_trsp.wqe_com, CMD_FCP_TRSP64_WQE);
+	bf_set(wqe_pu, &wqe->fcp_trsp.wqe_com, PARM_UNUSED);
+	bf_set(wqe_class, &wqe->fcp_trsp.wqe_com, CLASS3);
+	bf_set(wqe_ct, &wqe->fcp_trsp.wqe_com, SLI4_CT_RPI);
+	bf_set(wqe_ag, &wqe->fcp_trsp.wqe_com, 1); /* wqe_ar */
+
+	/* Word 8 - abort_tag is variable */
+
+	/* Word 9  - reqtag is variable */
+
+	/* Word 10 wqes, xc is variable */
+	bf_set(wqe_dbde, &wqe->fcp_trsp.wqe_com, 1);
+	bf_set(wqe_nvme, &wqe->fcp_trsp.wqe_com, 1);
+	bf_set(wqe_wqes, &wqe->fcp_trsp.wqe_com, 0);
+	bf_set(wqe_xc, &wqe->fcp_trsp.wqe_com, 0);
+	bf_set(wqe_iod, &wqe->fcp_trsp.wqe_com, LPFC_WQE_IOD_NONE);
+	bf_set(wqe_lenloc, &wqe->fcp_trsp.wqe_com, LPFC_WQE_LENLOC_WORD3);
+
+	/* Word 11 irsp, irsplen is variable */
+	bf_set(wqe_cmd_type, &wqe->fcp_trsp.wqe_com, FCP_COMMAND_TRSP);
+	bf_set(wqe_cqid, &wqe->fcp_trsp.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
+	bf_set(wqe_sup, &wqe->fcp_trsp.wqe_com, 0);
+	bf_set(wqe_irsp, &wqe->fcp_trsp.wqe_com, 0);
+	bf_set(wqe_irsplen, &wqe->fcp_trsp.wqe_com, 0);
+	bf_set(wqe_pbde, &wqe->fcp_trsp.wqe_com, 0);
+
+	/* Word 12, 13, 14, 15 - is zero */
+}
 
 void
 lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp)
@@ -130,7 +275,7 @@ lpfc_nvmet_xmt_ls_rsp_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
 	if (tgtp) {
 		if (status) {
 			atomic_inc(&tgtp->xmt_ls_rsp_error);
-			if (status == IOERR_ABORT_REQUESTED)
+			if (result == IOERR_ABORT_REQUESTED)
 				atomic_inc(&tgtp->xmt_ls_rsp_aborted);
 			if (bf_get(lpfc_wcqe_c_xb, wcqe))
 				atomic_inc(&tgtp->xmt_ls_rsp_xb_set);
@@ -268,8 +413,6 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf)
 					 "NVMET RCV BUSY: xri x%x sz %d "
 					 "from %06x\n",
 					 oxid, size, sid);
-			/* defer repost rcv buffer till .defer_rcv callback */
-			ctxp->flag &= ~LPFC_NVMET_DEFER_RCV_REPOST;
 			atomic_inc(&tgtp->rcv_fcp_cmd_out);
 			return;
 		}
@@ -541,7 +684,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
 		rsp->transferred_length = 0;
 		if (tgtp) {
 			atomic_inc(&tgtp->xmt_fcp_rsp_error);
-			if (status == IOERR_ABORT_REQUESTED)
+			if (result == IOERR_ABORT_REQUESTED)
 				atomic_inc(&tgtp->xmt_fcp_rsp_aborted);
 		}
 
@@ -741,7 +884,10 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
 	struct lpfc_nvmet_rcv_ctx *ctxp =
 		container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req);
 	struct lpfc_hba *phba = ctxp->phba;
+	struct lpfc_queue *wq;
 	struct lpfc_iocbq *nvmewqeq;
+	struct lpfc_sli_ring *pring;
+	unsigned long iflags;
 	int rc;
 
 	if (phba->pport->load_flag & FC_UNLOADING) {
@@ -820,6 +966,22 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
 		return 0;
 	}
 
+	if (rc == -EBUSY) {
+		/*
+		 * WQ was full, so queue nvmewqeq to be sent after
+		 * WQE release CQE
+		 */
+		ctxp->flag |= LPFC_NVMET_DEFER_WQFULL;
+		wq = phba->sli4_hba.nvme_wq[rsp->hwqid];
+		pring = wq->pring;
+		spin_lock_irqsave(&pring->ring_lock, iflags);
+		list_add_tail(&nvmewqeq->list, &wq->wqfull_list);
+		wq->q_flag |= HBA_NVMET_WQFULL;
+		spin_unlock_irqrestore(&pring->ring_lock, iflags);
+		atomic_inc(&lpfc_nvmep->defer_wqfull);
+		return 0;
+	}
+
 	/* Give back resources */
 	atomic_inc(&lpfc_nvmep->xmt_fcp_drop);
 	lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
@@ -851,6 +1013,7 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport,
 	struct lpfc_nvmet_rcv_ctx *ctxp =
 		container_of(req, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req);
 	struct lpfc_hba *phba = ctxp->phba;
+	struct lpfc_queue *wq;
 	unsigned long flags;
 
 	if (phba->pport->load_flag & FC_UNLOADING)
@@ -880,6 +1043,15 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport,
 	}
 	ctxp->flag |= LPFC_NVMET_ABORT_OP;
 
+	if (ctxp->flag & LPFC_NVMET_DEFER_WQFULL) {
+		lpfc_nvmet_unsol_fcp_issue_abort(phba, ctxp, ctxp->sid,
+						 ctxp->oxid);
+		wq = phba->sli4_hba.nvme_wq[ctxp->wqeq->hba_wqidx];
+		spin_unlock_irqrestore(&ctxp->ctxlock, flags);
+		lpfc_nvmet_wqfull_flush(phba, wq, ctxp);
+		return;
+	}
+
 	/* An state of LPFC_NVMET_STE_RCV means we have just received
 	 * the NVME command and have not started processing it.
 	 * (by issuing any IO WQEs on this exchange yet)
@@ -946,11 +1118,9 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
 
 	tgtp = phba->targetport->private;
 	atomic_inc(&tgtp->rcv_fcp_cmd_defer);
-	if (ctxp->flag & LPFC_NVMET_DEFER_RCV_REPOST)
-		lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */
-	else
-		nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
-	ctxp->flag &= ~LPFC_NVMET_DEFER_RCV_REPOST;
+
+	/* Free the nvmebuf since a new buffer already replaced it */
+	nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
 }
 
 static struct nvmet_fc_target_template lpfc_tgttemplate = {
@@ -1124,16 +1294,10 @@ lpfc_nvmet_setup_io_context(struct lpfc_hba *phba)
 		}
 		ctx_buf->iocbq->iocb_flag = LPFC_IO_NVMET;
 		nvmewqe = ctx_buf->iocbq;
-		wqe = (union lpfc_wqe128 *)&nvmewqe->wqe;
+		wqe = &nvmewqe->wqe;
+
 		/* Initialize WQE */
 		memset(wqe, 0, sizeof(union lpfc_wqe));
-		/* Word 7 */
-		bf_set(wqe_ct, &wqe->generic.wqe_com, SLI4_CT_RPI);
-		bf_set(wqe_class, &wqe->generic.wqe_com, CLASS3);
-		/* Word 10 */
-		bf_set(wqe_nvme, &wqe->fcp_tsend.wqe_com, 1);
-		bf_set(wqe_ebde_cnt, &wqe->generic.wqe_com, 0);
-		bf_set(wqe_qosd, &wqe->generic.wqe_com, 0);
 
 		ctx_buf->iocbq->context1 = NULL;
 		spin_lock(&phba->sli4_hba.sgl_list_lock);
@@ -1280,6 +1444,9 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba)
 		atomic_set(&tgtp->xmt_abort_sol, 0);
 		atomic_set(&tgtp->xmt_abort_rsp, 0);
 		atomic_set(&tgtp->xmt_abort_rsp_error, 0);
+		atomic_set(&tgtp->defer_ctx, 0);
+		atomic_set(&tgtp->defer_fod, 0);
+		atomic_set(&tgtp->defer_wqfull, 0);
 	}
 	return error;
 }
@@ -1435,16 +1602,103 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
 	return 0;
 }
 
+static void
+lpfc_nvmet_wqfull_flush(struct lpfc_hba *phba, struct lpfc_queue *wq,
+			struct lpfc_nvmet_rcv_ctx *ctxp)
+{
+	struct lpfc_sli_ring *pring;
+	struct lpfc_iocbq *nvmewqeq;
+	struct lpfc_iocbq *next_nvmewqeq;
+	unsigned long iflags;
+	struct lpfc_wcqe_complete wcqe;
+	struct lpfc_wcqe_complete *wcqep;
+
+	pring = wq->pring;
+	wcqep = &wcqe;
+
+	/* Fake an ABORT error code back to cmpl routine */
+	memset(wcqep, 0, sizeof(struct lpfc_wcqe_complete));
+	bf_set(lpfc_wcqe_c_status, wcqep, IOSTAT_LOCAL_REJECT);
+	wcqep->parameter = IOERR_ABORT_REQUESTED;
+
+	spin_lock_irqsave(&pring->ring_lock, iflags);
+	list_for_each_entry_safe(nvmewqeq, next_nvmewqeq,
+				 &wq->wqfull_list, list) {
+		if (ctxp) {
+			/* Checking for a specific IO to flush */
+			if (nvmewqeq->context2 == ctxp) {
+				list_del(&nvmewqeq->list);
+				spin_unlock_irqrestore(&pring->ring_lock,
+						       iflags);
+				lpfc_nvmet_xmt_fcp_op_cmp(phba, nvmewqeq,
+							  wcqep);
+				return;
+			}
+			continue;
+		} else {
+			/* Flush all IOs */
+			list_del(&nvmewqeq->list);
+			spin_unlock_irqrestore(&pring->ring_lock, iflags);
+			lpfc_nvmet_xmt_fcp_op_cmp(phba, nvmewqeq, wcqep);
+			spin_lock_irqsave(&pring->ring_lock, iflags);
+		}
+	}
+	if (!ctxp)
+		wq->q_flag &= ~HBA_NVMET_WQFULL;
+	spin_unlock_irqrestore(&pring->ring_lock, iflags);
+}
+
+void
+lpfc_nvmet_wqfull_process(struct lpfc_hba *phba,
+			  struct lpfc_queue *wq)
+{
+#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
+	struct lpfc_sli_ring *pring;
+	struct lpfc_iocbq *nvmewqeq;
+	unsigned long iflags;
+	int rc;
+
+	/*
+	 * Some WQE slots are available, so try to re-issue anything
+	 * on the WQ wqfull_list.
+	 */
+	pring = wq->pring;
+	spin_lock_irqsave(&pring->ring_lock, iflags);
+	while (!list_empty(&wq->wqfull_list)) {
+		list_remove_head(&wq->wqfull_list, nvmewqeq, struct lpfc_iocbq,
+				 list);
+		spin_unlock_irqrestore(&pring->ring_lock, iflags);
+		rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq);
+		spin_lock_irqsave(&pring->ring_lock, iflags);
+		if (rc == -EBUSY) {
+			/* WQ was full again, so put it back on the list */
+			list_add(&nvmewqeq->list, &wq->wqfull_list);
+			spin_unlock_irqrestore(&pring->ring_lock, iflags);
+			return;
+		}
+	}
+	wq->q_flag &= ~HBA_NVMET_WQFULL;
+	spin_unlock_irqrestore(&pring->ring_lock, iflags);
+
+#endif
+}
+
 void
 lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba)
 {
 #if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
 	struct lpfc_nvmet_tgtport *tgtp;
+	struct lpfc_queue *wq;
+	uint32_t qidx;
 
 	if (phba->nvmet_support == 0)
 		return;
 	if (phba->targetport) {
 		tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
+		for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++) {
+			wq = phba->sli4_hba.nvme_wq[qidx];
+			lpfc_nvmet_wqfull_flush(phba, wq, NULL);
+		}
 		init_completion(&tgtp->tport_unreg_done);
 		nvmet_fc_unregister_targetport(phba->targetport);
 		wait_for_completion_timeout(&tgtp->tport_unreg_done, 5);
@@ -1694,6 +1948,8 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
 	lpfc_nvmeio_data(phba, "NVMET FCP  RCV: xri x%x sz %d CPU %02x\n",
 			 oxid, size, smp_processor_id());
 
+	tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
+
 	if (!ctx_buf) {
 		/* Queue this NVME IO to process later */
 		spin_lock_irqsave(&phba->sli4_hba.nvmet_io_wait_lock, iflag);
@@ -1709,10 +1965,11 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
 		lpfc_post_rq_buffer(
 			phba, phba->sli4_hba.nvmet_mrq_hdr[qno],
 			phba->sli4_hba.nvmet_mrq_data[qno], 1, qno);
+
+		atomic_inc(&tgtp->defer_ctx);
 		return;
 	}
 
-	tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
 	payload = (uint32_t *)(nvmebuf->dbuf.virt);
 	sid = sli4_sid_from_fc_hdr(fc_hdr);
 
@@ -1776,12 +2033,20 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
 
 	/* Processing of FCP command is deferred */
 	if (rc == -EOVERFLOW) {
+		/*
+		 * Post a brand new DMA buffer to RQ and defer
+		 * freeing rcv buffer till .defer_rcv callback
+		 */
+		qno = nvmebuf->idx;
+		lpfc_post_rq_buffer(
+			phba, phba->sli4_hba.nvmet_mrq_hdr[qno],
+			phba->sli4_hba.nvmet_mrq_data[qno], 1, qno);
+
 		lpfc_nvmeio_data(phba,
 				 "NVMET RCV BUSY: xri x%x sz %d from %06x\n",
 				 oxid, size, sid);
-		/* defer reposting rcv buffer till .defer_rcv callback */
-		ctxp->flag |= LPFC_NVMET_DEFER_RCV_REPOST;
 		atomic_inc(&tgtp->rcv_fcp_cmd_out);
+		atomic_inc(&tgtp->defer_fod);
 		return;
 	}
 	ctxp->rqb_buffer = nvmebuf;
@@ -1897,7 +2162,7 @@ lpfc_nvmet_prep_ls_wqe(struct lpfc_hba *phba,
 {
 	struct lpfc_nodelist *ndlp;
 	struct lpfc_iocbq *nvmewqe;
-	union lpfc_wqe *wqe;
+	union lpfc_wqe128 *wqe;
 
 	if (!lpfc_is_link_up(phba)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC,
@@ -2023,9 +2288,11 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 	struct lpfc_iocbq *nvmewqe;
 	struct scatterlist *sgel;
 	union lpfc_wqe128 *wqe;
+	struct ulp_bde64 *bde;
 	uint32_t *txrdy;
 	dma_addr_t physaddr;
 	int i, cnt;
+	int do_pbde;
 	int xc = 1;
 
 	if (!lpfc_is_link_up(phba)) {
@@ -2078,7 +2345,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 	if (((ctxp->state == LPFC_NVMET_STE_RCV) &&
 	    (ctxp->entry_cnt == 1)) ||
 	    (ctxp->state == LPFC_NVMET_STE_DATA)) {
-		wqe = (union lpfc_wqe128 *)&nvmewqe->wqe;
+		wqe = &nvmewqe->wqe;
 	} else {
 		lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
 				"6111 Wrong state NVMET FCP: %d  cnt %d\n",
@@ -2090,6 +2357,11 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 	switch (rsp->op) {
 	case NVMET_FCOP_READDATA:
 	case NVMET_FCOP_READDATA_RSP:
+		/* From the tsend template, initialize words 7 - 11 */
+		memcpy(&wqe->words[7],
+		       &lpfc_tsend_cmd_template.words[7],
+		       sizeof(uint32_t) * 5);
+
 		/* Words 0 - 2 : The first sg segment */
 		sgel = &rsp->sg[0];
 		physaddr = sg_dma_address(sgel);
@@ -2106,6 +2378,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		wqe->fcp_tsend.relative_offset = ctxp->offset;
 
 		/* Word 5 */
+		wqe->fcp_tsend.reserved = 0;
 
 		/* Word 6 */
 		bf_set(wqe_ctxt_tag, &wqe->fcp_tsend.wqe_com,
@@ -2113,9 +2386,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		bf_set(wqe_xri_tag, &wqe->fcp_tsend.wqe_com,
 		       nvmewqe->sli4_xritag);
 
-		/* Word 7 */
-		bf_set(wqe_pu, &wqe->fcp_tsend.wqe_com, 1);
-		bf_set(wqe_cmnd, &wqe->fcp_tsend.wqe_com, CMD_FCP_TSEND64_WQE);
+		/* Word 7 - set ar later */
 
 		/* Word 8 */
 		wqe->fcp_tsend.wqe_com.abort_tag = nvmewqe->iotag;
@@ -2124,23 +2395,12 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		bf_set(wqe_reqtag, &wqe->fcp_tsend.wqe_com, nvmewqe->iotag);
 		bf_set(wqe_rcvoxid, &wqe->fcp_tsend.wqe_com, ctxp->oxid);
 
-		/* Word 10 */
-		bf_set(wqe_nvme, &wqe->fcp_tsend.wqe_com, 1);
-		bf_set(wqe_dbde, &wqe->fcp_tsend.wqe_com, 1);
-		bf_set(wqe_iod, &wqe->fcp_tsend.wqe_com, LPFC_WQE_IOD_WRITE);
-		bf_set(wqe_lenloc, &wqe->fcp_tsend.wqe_com,
-		       LPFC_WQE_LENLOC_WORD12);
-		bf_set(wqe_ebde_cnt, &wqe->fcp_tsend.wqe_com, 0);
-		bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, xc);
-		bf_set(wqe_nvme, &wqe->fcp_tsend.wqe_com, 1);
-		if (phba->cfg_nvme_oas)
-			bf_set(wqe_oas, &wqe->fcp_tsend.wqe_com, 1);
+		/* Word 10 - set wqes later, in template xc=1 */
+		if (!xc)
+			bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, 0);
 
-		/* Word 11 */
-		bf_set(wqe_cqid, &wqe->fcp_tsend.wqe_com,
-		       LPFC_WQE_CQ_ID_DEFAULT);
-		bf_set(wqe_cmd_type, &wqe->fcp_tsend.wqe_com,
-		       FCP_COMMAND_TSEND);
+		/* Word 11 - set sup, irsp, irsplen later */
+		do_pbde = 0;
 
 		/* Word 12 */
 		wqe->fcp_tsend.fcp_data_len = rsp->transfer_length;
@@ -2162,15 +2422,14 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		sgl++;
 		if (rsp->op == NVMET_FCOP_READDATA_RSP) {
 			atomic_inc(&tgtp->xmt_fcp_read_rsp);
-			bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 1);
-			if ((ndlp->nlp_flag & NLP_SUPPRESS_RSP) &&
-			    (rsp->rsplen == 12)) {
-				bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 1);
-				bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 0);
-				bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0);
-				bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0);
+
+			/* In template ar=1 wqes=0 sup=0 irsp=0 irsplen=0 */
+
+			if (rsp->rsplen == LPFC_NVMET_SUCCESS_LEN) {
+				if (ndlp->nlp_flag & NLP_SUPPRESS_RSP)
+					bf_set(wqe_sup,
+					       &wqe->fcp_tsend.wqe_com, 1);
 			} else {
-				bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0);
 				bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 1);
 				bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 1);
 				bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com,
@@ -2181,15 +2440,17 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		} else {
 			atomic_inc(&tgtp->xmt_fcp_read);
 
-			bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0);
-			bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 0);
-			bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0);
+			/* In template ar=1 wqes=0 sup=0 irsp=0 irsplen=0 */
 			bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 0);
-			bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0);
 		}
 		break;
 
 	case NVMET_FCOP_WRITEDATA:
+		/* From the treceive template, initialize words 3 - 11 */
+		memcpy(&wqe->words[3],
+		       &lpfc_treceive_cmd_template.words[3],
+		       sizeof(uint32_t) * 9);
+
 		/* Words 0 - 2 : The first sg segment */
 		txrdy = dma_pool_alloc(phba->txrdy_payload_pool,
 				       GFP_KERNEL, &physaddr);
@@ -2208,14 +2469,9 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		wqe->fcp_treceive.bde.addrHigh =
 			cpu_to_le32(putPaddrHigh(physaddr));
 
-		/* Word 3 */
-		wqe->fcp_treceive.payload_offset_len = TXRDY_PAYLOAD_LEN;
-
 		/* Word 4 */
 		wqe->fcp_treceive.relative_offset = ctxp->offset;
 
-		/* Word 5 */
-
 		/* Word 6 */
 		bf_set(wqe_ctxt_tag, &wqe->fcp_treceive.wqe_com,
 		       phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
@@ -2223,10 +2479,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		       nvmewqe->sli4_xritag);
 
 		/* Word 7 */
-		bf_set(wqe_pu, &wqe->fcp_treceive.wqe_com, 1);
-		bf_set(wqe_ar, &wqe->fcp_treceive.wqe_com, 0);
-		bf_set(wqe_cmnd, &wqe->fcp_treceive.wqe_com,
-		       CMD_FCP_TRECEIVE64_WQE);
 
 		/* Word 8 */
 		wqe->fcp_treceive.wqe_com.abort_tag = nvmewqe->iotag;
@@ -2235,26 +2487,17 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		bf_set(wqe_reqtag, &wqe->fcp_treceive.wqe_com, nvmewqe->iotag);
 		bf_set(wqe_rcvoxid, &wqe->fcp_treceive.wqe_com, ctxp->oxid);
 
-		/* Word 10 */
-		bf_set(wqe_nvme, &wqe->fcp_treceive.wqe_com, 1);
-		bf_set(wqe_dbde, &wqe->fcp_treceive.wqe_com, 1);
-		bf_set(wqe_iod, &wqe->fcp_treceive.wqe_com, LPFC_WQE_IOD_READ);
-		bf_set(wqe_lenloc, &wqe->fcp_treceive.wqe_com,
-		       LPFC_WQE_LENLOC_WORD12);
-		bf_set(wqe_xc, &wqe->fcp_treceive.wqe_com, xc);
-		bf_set(wqe_wqes, &wqe->fcp_treceive.wqe_com, 0);
-		bf_set(wqe_irsp, &wqe->fcp_treceive.wqe_com, 0);
-		bf_set(wqe_irsplen, &wqe->fcp_treceive.wqe_com, 0);
-		bf_set(wqe_nvme, &wqe->fcp_treceive.wqe_com, 1);
-		if (phba->cfg_nvme_oas)
-			bf_set(wqe_oas, &wqe->fcp_treceive.wqe_com, 1);
+		/* Word 10 - in template xc=1 */
+		if (!xc)
+			bf_set(wqe_xc, &wqe->fcp_treceive.wqe_com, 0);
 
-		/* Word 11 */
-		bf_set(wqe_cqid, &wqe->fcp_treceive.wqe_com,
-		       LPFC_WQE_CQ_ID_DEFAULT);
-		bf_set(wqe_cmd_type, &wqe->fcp_treceive.wqe_com,
-		       FCP_COMMAND_TRECEIVE);
-		bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0);
+		/* Word 11 - set pbde later */
+		if (phba->nvme_embed_pbde) {
+			do_pbde = 1;
+		} else {
+			bf_set(wqe_pbde, &wqe->fcp_treceive.wqe_com, 0);
+			do_pbde = 0;
+		}
 
 		/* Word 12 */
 		wqe->fcp_tsend.fcp_data_len = rsp->transfer_length;
@@ -2282,6 +2525,11 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		break;
 
 	case NVMET_FCOP_RSP:
+		/* From the treceive template, initialize words 4 - 11 */
+		memcpy(&wqe->words[4],
+		       &lpfc_trsp_cmd_template.words[4],
+		       sizeof(uint32_t) * 8);
+
 		/* Words 0 - 2 */
 		physaddr = rsp->rspdma;
 		wqe->fcp_trsp.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
@@ -2294,12 +2542,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		/* Word 3 */
 		wqe->fcp_trsp.response_len = rsp->rsplen;
 
-		/* Word 4 */
-		wqe->fcp_trsp.rsvd_4_5[0] = 0;
-
-
-		/* Word 5 */
-
 		/* Word 6 */
 		bf_set(wqe_ctxt_tag, &wqe->fcp_trsp.wqe_com,
 		       phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
@@ -2307,9 +2549,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		       nvmewqe->sli4_xritag);
 
 		/* Word 7 */
-		bf_set(wqe_pu, &wqe->fcp_trsp.wqe_com, 0);
-		bf_set(wqe_ag, &wqe->fcp_trsp.wqe_com, 1);
-		bf_set(wqe_cmnd, &wqe->fcp_trsp.wqe_com, CMD_FCP_TRSP64_WQE);
 
 		/* Word 8 */
 		wqe->fcp_trsp.wqe_com.abort_tag = nvmewqe->iotag;
@@ -2319,35 +2558,23 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 		bf_set(wqe_rcvoxid, &wqe->fcp_trsp.wqe_com, ctxp->oxid);
 
 		/* Word 10 */
-		bf_set(wqe_nvme, &wqe->fcp_trsp.wqe_com, 1);
-		bf_set(wqe_dbde, &wqe->fcp_trsp.wqe_com, 0);
-		bf_set(wqe_iod, &wqe->fcp_trsp.wqe_com, LPFC_WQE_IOD_WRITE);
-		bf_set(wqe_lenloc, &wqe->fcp_trsp.wqe_com,
-		       LPFC_WQE_LENLOC_WORD3);
-		bf_set(wqe_xc, &wqe->fcp_trsp.wqe_com, xc);
-		bf_set(wqe_nvme, &wqe->fcp_trsp.wqe_com, 1);
-		if (phba->cfg_nvme_oas)
-			bf_set(wqe_oas, &wqe->fcp_trsp.wqe_com, 1);
+		if (xc)
+			bf_set(wqe_xc, &wqe->fcp_trsp.wqe_com, 1);
 
 		/* Word 11 */
-		bf_set(wqe_cqid, &wqe->fcp_trsp.wqe_com,
-		       LPFC_WQE_CQ_ID_DEFAULT);
-		bf_set(wqe_cmd_type, &wqe->fcp_trsp.wqe_com,
-		       FCP_COMMAND_TRSP);
-		bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0);
-
-		if (rsp->rsplen == LPFC_NVMET_SUCCESS_LEN) {
-			/* Good response - all zero's on wire */
-			bf_set(wqe_wqes, &wqe->fcp_trsp.wqe_com, 0);
-			bf_set(wqe_irsp, &wqe->fcp_trsp.wqe_com, 0);
-			bf_set(wqe_irsplen, &wqe->fcp_trsp.wqe_com, 0);
-		} else {
+		/* In template wqes=0 irsp=0 irsplen=0 - good response */
+		if (rsp->rsplen != LPFC_NVMET_SUCCESS_LEN) {
+			/* Bad response - embed it */
 			bf_set(wqe_wqes, &wqe->fcp_trsp.wqe_com, 1);
 			bf_set(wqe_irsp, &wqe->fcp_trsp.wqe_com, 1);
 			bf_set(wqe_irsplen, &wqe->fcp_trsp.wqe_com,
 			       ((rsp->rsplen >> 2) - 1));
 			memcpy(&wqe->words[16], rsp->rspaddr, rsp->rsplen);
 		}
+		do_pbde = 0;
+
+		/* Word 12 */
+		wqe->fcp_trsp.rsvd_12_15[0] = 0;
 
 		/* Use rspbuf, NOT sg list */
 		rsp->sg_cnt = 0;
@@ -2380,6 +2607,17 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
 			bf_set(lpfc_sli4_sge_last, sgl, 1);
 		sgl->word2 = cpu_to_le32(sgl->word2);
 		sgl->sge_len = cpu_to_le32(cnt);
+		if (do_pbde && i == 0) {
+			bde = (struct ulp_bde64 *)&wqe->words[13];
+			memset(bde, 0, sizeof(struct ulp_bde64));
+			/* Words 13-15  (PBDE)*/
+			bde->addrLow = sgl->addr_lo;
+			bde->addrHigh = sgl->addr_hi;
+			bde->tus.f.bdeSize =
+				le32_to_cpu(sgl->sge_len);
+			bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+			bde->tus.w = cpu_to_le32(bde->tus.w);
+		}
 		sgl++;
 		ctxp->offset += cnt;
 	}
@@ -2597,7 +2835,7 @@ lpfc_nvmet_unsol_issue_abort(struct lpfc_hba *phba,
 {
 	struct lpfc_nvmet_tgtport *tgtp;
 	struct lpfc_iocbq *abts_wqeq;
-	union lpfc_wqe *wqe_abts;
+	union lpfc_wqe128 *wqe_abts;
 	struct lpfc_nodelist *ndlp;
 
 	lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS,
@@ -2692,7 +2930,7 @@ lpfc_nvmet_sol_fcp_issue_abort(struct lpfc_hba *phba,
 {
 	struct lpfc_nvmet_tgtport *tgtp;
 	struct lpfc_iocbq *abts_wqeq;
-	union lpfc_wqe *abts_wqe;
+	union lpfc_wqe128 *abts_wqe;
 	struct lpfc_nodelist *ndlp;
 	unsigned long flags;
 	int rc;
@@ -2882,7 +3120,7 @@ lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *phba,
 {
 	struct lpfc_nvmet_tgtport *tgtp;
 	struct lpfc_iocbq *abts_wqeq;
-	union lpfc_wqe *wqe_abts;
+	union lpfc_wqe128 *wqe_abts;
 	unsigned long flags;
 	int rc;
 
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.h b/drivers/scsi/lpfc/lpfc_nvmet.h
index 5b32c9e..c1bcef3 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.h
+++ b/drivers/scsi/lpfc/lpfc_nvmet.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -72,7 +72,6 @@ struct lpfc_nvmet_tgtport {
 	atomic_t xmt_fcp_rsp_aborted;
 	atomic_t xmt_fcp_rsp_drop;
 
-
 	/* Stats counters - lpfc_nvmet_xmt_fcp_abort */
 	atomic_t xmt_fcp_xri_abort_cqe;
 	atomic_t xmt_fcp_abort;
@@ -81,6 +80,11 @@ struct lpfc_nvmet_tgtport {
 	atomic_t xmt_abort_unsol;
 	atomic_t xmt_abort_rsp;
 	atomic_t xmt_abort_rsp_error;
+
+	/* Stats counters - defer IO */
+	atomic_t defer_ctx;
+	atomic_t defer_fod;
+	atomic_t defer_wqfull;
 };
 
 struct lpfc_nvmet_ctx_info {
@@ -131,7 +135,7 @@ struct lpfc_nvmet_rcv_ctx {
 #define LPFC_NVMET_XBUSY		0x4  /* XB bit set on IO cmpl */
 #define LPFC_NVMET_CTX_RLS		0x8  /* ctx free requested */
 #define LPFC_NVMET_ABTS_RCV		0x10  /* ABTS received on exchange */
-#define LPFC_NVMET_DEFER_RCV_REPOST	0x20  /* repost to RQ on defer rcv */
+#define LPFC_NVMET_DEFER_WQFULL		0x40  /* Waiting on a free WQE */
 	struct rqb_dmabuf *rqb_buffer;
 	struct lpfc_nvmet_ctxbuf *ctxbuf;
 
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c0cdaef4..050f044 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -837,8 +837,13 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
 		 * 4K Page alignment is CRITICAL to BlockGuard, double check
 		 * to be sure.
 		 */
-		if (phba->cfg_enable_bg  && (((unsigned long)(psb->data) &
+		if ((phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
+		    (((unsigned long)(psb->data) &
 		    (unsigned long)(SLI4_PAGE_SIZE - 1)) != 0)) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+					"3369 Memory alignment error "
+					"addr=%lx\n",
+					(unsigned long)psb->data);
 			dma_pool_free(phba->lpfc_sg_dma_buf_pool,
 				      psb->data, psb->dma_handle);
 			kfree(psb);
@@ -3304,8 +3309,12 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
 			dma_offset += dma_len;
 			sgl++;
 		}
-		/* setup the performance hint (first data BDE) if enabled */
-		if (phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) {
+		/*
+		 * Setup the first Payload BDE. For FCoE we just key off
+		 * Performance Hints, for FC we utilize fcp_embed_pbde.
+		 */
+		if ((phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) ||
+		    phba->fcp_embed_pbde) {
 			bde = (struct ulp_bde64 *)
 					&(iocb_cmd->unsli3.sli3Words[5]);
 			bde->addrLow = first_data_sgl->addr_lo;
@@ -3772,20 +3781,18 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
 		scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
 
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER,
-				 "9025 FCP Read Underrun, expected %d, "
+				 "9025 FCP Underrun, expected %d, "
 				 "residual %d Data: x%x x%x x%x\n",
 				 fcpDl,
 				 scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0],
 				 cmnd->underflow);
 
 		/*
-		 * If there is an under run check if under run reported by
+		 * If there is an under run, check if under run reported by
 		 * storage array is same as the under run reported by HBA.
 		 * If this is not same, there is a dropped frame.
 		 */
-		if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) &&
-			fcpi_parm &&
-			(scsi_get_resid(cmnd) != fcpi_parm)) {
+		if (fcpi_parm && (scsi_get_resid(cmnd) != fcpi_parm)) {
 			lpfc_printf_vlog(vport, KERN_WARNING,
 					 LOG_FCP | LOG_FCP_ERROR,
 					 "9026 FCP Read Check Error "
@@ -3926,7 +3933,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 	struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
 	struct lpfc_nodelist *pnode = rdata->pnode;
 	struct scsi_cmnd *cmd;
-	int depth;
 	unsigned long flags;
 	struct lpfc_fast_path_event *fast_path_evt;
 	struct Scsi_Host *shost;
@@ -4132,16 +4138,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 		}
 		spin_unlock_irqrestore(shost->host_lock, flags);
 	} else if (pnode && NLP_CHK_NODE_ACT(pnode)) {
-		if ((pnode->cmd_qdepth < vport->cfg_tgt_queue_depth) &&
-		   time_after(jiffies, pnode->last_change_time +
+		if ((pnode->cmd_qdepth != vport->cfg_tgt_queue_depth) &&
+		    time_after(jiffies, pnode->last_change_time +
 			      msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) {
 			spin_lock_irqsave(shost->host_lock, flags);
-			depth = pnode->cmd_qdepth * LPFC_TGTQ_RAMPUP_PCENT
-				/ 100;
-			depth = depth ? depth : 1;
-			pnode->cmd_qdepth += depth;
-			if (pnode->cmd_qdepth > vport->cfg_tgt_queue_depth)
-				pnode->cmd_qdepth = vport->cfg_tgt_queue_depth;
+			pnode->cmd_qdepth = vport->cfg_tgt_queue_depth;
 			pnode->last_change_time = jiffies;
 			spin_unlock_irqrestore(shost->host_lock, flags);
 		}
@@ -4564,9 +4565,32 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
 	 */
 	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
 		goto out_tgt_busy;
-	if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
+	if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth) {
+		lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_ERROR,
+				 "3377 Target Queue Full, scsi Id:%d Qdepth:%d"
+				 " Pending command:%d"
+				 " WWNN:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, "
+				 " WWPN:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+				 ndlp->nlp_sid, ndlp->cmd_qdepth,
+				 atomic_read(&ndlp->cmd_pending),
+				 ndlp->nlp_nodename.u.wwn[0],
+				 ndlp->nlp_nodename.u.wwn[1],
+				 ndlp->nlp_nodename.u.wwn[2],
+				 ndlp->nlp_nodename.u.wwn[3],
+				 ndlp->nlp_nodename.u.wwn[4],
+				 ndlp->nlp_nodename.u.wwn[5],
+				 ndlp->nlp_nodename.u.wwn[6],
+				 ndlp->nlp_nodename.u.wwn[7],
+				 ndlp->nlp_portname.u.wwn[0],
+				 ndlp->nlp_portname.u.wwn[1],
+				 ndlp->nlp_portname.u.wwn[2],
+				 ndlp->nlp_portname.u.wwn[3],
+				 ndlp->nlp_portname.u.wwn[4],
+				 ndlp->nlp_portname.u.wwn[5],
+				 ndlp->nlp_portname.u.wwn[6],
+				 ndlp->nlp_portname.u.wwn[7]);
 		goto out_tgt_busy;
-
+	}
 	lpfc_cmd = lpfc_get_scsi_buf(phba, ndlp);
 	if (lpfc_cmd == NULL) {
 		lpfc_rampdown_queue_depth(phba);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h
index 5da7e15..8e38e02 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.h
+++ b/drivers/scsi/lpfc/lpfc_scsi.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 5f5528a..cb17e2b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1,8 +1,7 @@
-
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -36,6 +35,9 @@
 #include <scsi/scsi_transport_fc.h>
 #include <scsi/fc/fc_fs.h>
 #include <linux/aer.h>
+#ifdef CONFIG_X86
+#include <asm/set_memory.h>
+#endif
 
 #include <linux/nvme-fc-driver.h>
 
@@ -107,12 +109,14 @@ lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq)
  * The caller is expected to hold the hbalock when calling this routine.
  **/
 static int
-lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
+lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe128 *wqe)
 {
 	union lpfc_wqe *temp_wqe;
 	struct lpfc_register doorbell;
 	uint32_t host_index;
 	uint32_t idx;
+	uint32_t i = 0;
+	uint8_t *tmp;
 
 	/* sanity check on queue memory */
 	if (unlikely(!q))
@@ -129,10 +133,25 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
 	/* set consumption flag every once in a while */
 	if (!((q->host_index + 1) % q->entry_repost))
 		bf_set(wqe_wqec, &wqe->generic.wqe_com, 1);
+	else
+		bf_set(wqe_wqec, &wqe->generic.wqe_com, 0);
 	if (q->phba->sli3_options & LPFC_SLI4_PHWQ_ENABLED)
 		bf_set(wqe_wqid, &wqe->generic.wqe_com, q->queue_id);
 	lpfc_sli_pcimem_bcopy(wqe, temp_wqe, q->entry_size);
-	/* ensure WQE bcopy flushed before doorbell write */
+	if (q->dpp_enable && q->phba->cfg_enable_dpp) {
+		/* write to DPP aperture taking advatage of Combined Writes */
+		tmp = (uint8_t *)temp_wqe;
+#ifdef __raw_writeq
+		for (i = 0; i < q->entry_size; i += sizeof(uint64_t))
+			__raw_writeq(*((uint64_t *)(tmp + i)),
+					q->dpp_regaddr + i);
+#else
+		for (i = 0; i < q->entry_size; i += sizeof(uint32_t))
+			__raw_writel(*((uint32_t *)(tmp + i)),
+					q->dpp_regaddr + i);
+#endif
+	}
+	/* ensure WQE bcopy and DPP flushed before doorbell write */
 	wmb();
 
 	/* Update the host index before invoking device */
@@ -143,9 +162,18 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
 	/* Ring Doorbell */
 	doorbell.word0 = 0;
 	if (q->db_format == LPFC_DB_LIST_FORMAT) {
-		bf_set(lpfc_wq_db_list_fm_num_posted, &doorbell, 1);
-		bf_set(lpfc_wq_db_list_fm_index, &doorbell, host_index);
-		bf_set(lpfc_wq_db_list_fm_id, &doorbell, q->queue_id);
+		if (q->dpp_enable && q->phba->cfg_enable_dpp) {
+			bf_set(lpfc_if6_wq_db_list_fm_num_posted, &doorbell, 1);
+			bf_set(lpfc_if6_wq_db_list_fm_dpp, &doorbell, 1);
+			bf_set(lpfc_if6_wq_db_list_fm_dpp_id, &doorbell,
+			    q->dpp_id);
+			bf_set(lpfc_if6_wq_db_list_fm_id, &doorbell,
+			    q->queue_id);
+		} else {
+			bf_set(lpfc_wq_db_list_fm_num_posted, &doorbell, 1);
+			bf_set(lpfc_wq_db_list_fm_index, &doorbell, host_index);
+			bf_set(lpfc_wq_db_list_fm_id, &doorbell, q->queue_id);
+		}
 	} else if (q->db_format == LPFC_DB_RING_FORMAT) {
 		bf_set(lpfc_wq_db_ring_fm_num_posted, &doorbell, 1);
 		bf_set(lpfc_wq_db_ring_fm_id, &doorbell, q->queue_id);
@@ -262,16 +290,18 @@ lpfc_sli4_mq_release(struct lpfc_queue *q)
 static struct lpfc_eqe *
 lpfc_sli4_eq_get(struct lpfc_queue *q)
 {
+	struct lpfc_hba *phba;
 	struct lpfc_eqe *eqe;
 	uint32_t idx;
 
 	/* sanity check on queue memory */
 	if (unlikely(!q))
 		return NULL;
+	phba = q->phba;
 	eqe = q->qe[q->hba_index].eqe;
 
 	/* If the next EQE is not valid then we are done */
-	if (!bf_get_le32(lpfc_eqe_valid, eqe))
+	if (bf_get_le32(lpfc_eqe_valid, eqe) != q->qe_valid)
 		return NULL;
 	/* If the host has not yet processed the next entry then we are done */
 	idx = ((q->hba_index + 1) % q->entry_count);
@@ -279,6 +309,10 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
 		return NULL;
 
 	q->hba_index = idx;
+	/* if the index wrapped around, toggle the valid bit */
+	if (phba->sli4_hba.pc_sli4_params.eqav && !q->hba_index)
+		q->qe_valid = (q->qe_valid) ? 0 : 1;
+
 
 	/*
 	 * insert barrier for instruction interlock : data from the hardware
@@ -298,7 +332,7 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
  * @q: The Event Queue to disable interrupts
  *
  **/
-static inline void
+inline void
 lpfc_sli4_eq_clr_intr(struct lpfc_queue *q)
 {
 	struct lpfc_register doorbell;
@@ -309,7 +343,26 @@ lpfc_sli4_eq_clr_intr(struct lpfc_queue *q)
 	bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell,
 		(q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT));
 	bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id);
-	writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
+	writel(doorbell.word0, q->phba->sli4_hba.EQDBregaddr);
+}
+
+/**
+ * lpfc_sli4_if6_eq_clr_intr - Turn off interrupts from this EQ
+ * @q: The Event Queue to disable interrupts
+ *
+ **/
+inline void
+lpfc_sli4_if6_eq_clr_intr(struct lpfc_queue *q)
+{
+	struct lpfc_register doorbell;
+
+	doorbell.word0 = 0;
+	bf_set(lpfc_eqcq_doorbell_eqci, &doorbell, 1);
+	bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT);
+	bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell,
+		(q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT));
+	bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id);
+	writel(doorbell.word0, q->phba->sli4_hba.EQDBregaddr);
 }
 
 /**
@@ -331,17 +384,21 @@ uint32_t
 lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm)
 {
 	uint32_t released = 0;
+	struct lpfc_hba *phba;
 	struct lpfc_eqe *temp_eqe;
 	struct lpfc_register doorbell;
 
 	/* sanity check on queue memory */
 	if (unlikely(!q))
 		return 0;
+	phba = q->phba;
 
 	/* while there are valid entries */
 	while (q->hba_index != q->host_index) {
-		temp_eqe = q->qe[q->host_index].eqe;
-		bf_set_le32(lpfc_eqe_valid, temp_eqe, 0);
+		if (!phba->sli4_hba.pc_sli4_params.eqav) {
+			temp_eqe = q->qe[q->host_index].eqe;
+			bf_set_le32(lpfc_eqe_valid, temp_eqe, 0);
+		}
 		released++;
 		q->host_index = ((q->host_index + 1) % q->entry_count);
 	}
@@ -359,10 +416,63 @@ lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm)
 	bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell,
 			(q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT));
 	bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id);
-	writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
+	writel(doorbell.word0, q->phba->sli4_hba.EQDBregaddr);
 	/* PCI read to flush PCI pipeline on re-arming for INTx mode */
 	if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM))
-		readl(q->phba->sli4_hba.EQCQDBregaddr);
+		readl(q->phba->sli4_hba.EQDBregaddr);
+	return released;
+}
+
+/**
+ * lpfc_sli4_if6_eq_release - Indicates the host has finished processing an EQ
+ * @q: The Event Queue that the host has completed processing for.
+ * @arm: Indicates whether the host wants to arms this CQ.
+ *
+ * This routine will mark all Event Queue Entries on @q, from the last
+ * known completed entry to the last entry that was processed, as completed
+ * by clearing the valid bit for each completion queue entry. Then it will
+ * notify the HBA, by ringing the doorbell, that the EQEs have been processed.
+ * The internal host index in the @q will be updated by this routine to indicate
+ * that the host has finished processing the entries. The @arm parameter
+ * indicates that the queue should be rearmed when ringing the doorbell.
+ *
+ * This function will return the number of EQEs that were popped.
+ **/
+uint32_t
+lpfc_sli4_if6_eq_release(struct lpfc_queue *q, bool arm)
+{
+	uint32_t released = 0;
+	struct lpfc_hba *phba;
+	struct lpfc_eqe *temp_eqe;
+	struct lpfc_register doorbell;
+
+	/* sanity check on queue memory */
+	if (unlikely(!q))
+		return 0;
+	phba = q->phba;
+
+	/* while there are valid entries */
+	while (q->hba_index != q->host_index) {
+		if (!phba->sli4_hba.pc_sli4_params.eqav) {
+			temp_eqe = q->qe[q->host_index].eqe;
+			bf_set_le32(lpfc_eqe_valid, temp_eqe, 0);
+		}
+		released++;
+		q->host_index = ((q->host_index + 1) % q->entry_count);
+	}
+	if (unlikely(released == 0 && !arm))
+		return 0;
+
+	/* ring doorbell for number popped */
+	doorbell.word0 = 0;
+	if (arm)
+		bf_set(lpfc_if6_eq_doorbell_arm, &doorbell, 1);
+	bf_set(lpfc_if6_eq_doorbell_num_released, &doorbell, released);
+	bf_set(lpfc_if6_eq_doorbell_eqid, &doorbell, q->queue_id);
+	writel(doorbell.word0, q->phba->sli4_hba.EQDBregaddr);
+	/* PCI read to flush PCI pipeline on re-arming for INTx mode */
+	if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM))
+		readl(q->phba->sli4_hba.EQDBregaddr);
 	return released;
 }
 
@@ -378,23 +488,28 @@ lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm)
 static struct lpfc_cqe *
 lpfc_sli4_cq_get(struct lpfc_queue *q)
 {
+	struct lpfc_hba *phba;
 	struct lpfc_cqe *cqe;
 	uint32_t idx;
 
 	/* sanity check on queue memory */
 	if (unlikely(!q))
 		return NULL;
+	phba = q->phba;
+	cqe = q->qe[q->hba_index].cqe;
 
 	/* If the next CQE is not valid then we are done */
-	if (!bf_get_le32(lpfc_cqe_valid, q->qe[q->hba_index].cqe))
+	if (bf_get_le32(lpfc_cqe_valid, cqe) != q->qe_valid)
 		return NULL;
 	/* If the host has not yet processed the next entry then we are done */
 	idx = ((q->hba_index + 1) % q->entry_count);
 	if (idx == q->host_index)
 		return NULL;
 
-	cqe = q->qe[q->hba_index].cqe;
 	q->hba_index = idx;
+	/* if the index wrapped around, toggle the valid bit */
+	if (phba->sli4_hba.pc_sli4_params.cqav && !q->hba_index)
+		q->qe_valid = (q->qe_valid) ? 0 : 1;
 
 	/*
 	 * insert barrier for instruction interlock : data from the hardware
@@ -427,16 +542,21 @@ uint32_t
 lpfc_sli4_cq_release(struct lpfc_queue *q, bool arm)
 {
 	uint32_t released = 0;
+	struct lpfc_hba *phba;
 	struct lpfc_cqe *temp_qe;
 	struct lpfc_register doorbell;
 
 	/* sanity check on queue memory */
 	if (unlikely(!q))
 		return 0;
+	phba = q->phba;
+
 	/* while there are valid entries */
 	while (q->hba_index != q->host_index) {
-		temp_qe = q->qe[q->host_index].cqe;
-		bf_set_le32(lpfc_cqe_valid, temp_qe, 0);
+		if (!phba->sli4_hba.pc_sli4_params.cqav) {
+			temp_qe = q->qe[q->host_index].cqe;
+			bf_set_le32(lpfc_cqe_valid, temp_qe, 0);
+		}
 		released++;
 		q->host_index = ((q->host_index + 1) % q->entry_count);
 	}
@@ -452,7 +572,57 @@ lpfc_sli4_cq_release(struct lpfc_queue *q, bool arm)
 	bf_set(lpfc_eqcq_doorbell_cqid_hi, &doorbell,
 			(q->queue_id >> LPFC_CQID_HI_FIELD_SHIFT));
 	bf_set(lpfc_eqcq_doorbell_cqid_lo, &doorbell, q->queue_id);
-	writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
+	writel(doorbell.word0, q->phba->sli4_hba.CQDBregaddr);
+	return released;
+}
+
+/**
+ * lpfc_sli4_if6_cq_release - Indicates the host has finished processing a CQ
+ * @q: The Completion Queue that the host has completed processing for.
+ * @arm: Indicates whether the host wants to arms this CQ.
+ *
+ * This routine will mark all Completion queue entries on @q, from the last
+ * known completed entry to the last entry that was processed, as completed
+ * by clearing the valid bit for each completion queue entry. Then it will
+ * notify the HBA, by ringing the doorbell, that the CQEs have been processed.
+ * The internal host index in the @q will be updated by this routine to indicate
+ * that the host has finished processing the entries. The @arm parameter
+ * indicates that the queue should be rearmed when ringing the doorbell.
+ *
+ * This function will return the number of CQEs that were released.
+ **/
+uint32_t
+lpfc_sli4_if6_cq_release(struct lpfc_queue *q, bool arm)
+{
+	uint32_t released = 0;
+	struct lpfc_hba *phba;
+	struct lpfc_cqe *temp_qe;
+	struct lpfc_register doorbell;
+
+	/* sanity check on queue memory */
+	if (unlikely(!q))
+		return 0;
+	phba = q->phba;
+
+	/* while there are valid entries */
+	while (q->hba_index != q->host_index) {
+		if (!phba->sli4_hba.pc_sli4_params.cqav) {
+			temp_qe = q->qe[q->host_index].cqe;
+			bf_set_le32(lpfc_cqe_valid, temp_qe, 0);
+		}
+		released++;
+		q->host_index = ((q->host_index + 1) % q->entry_count);
+	}
+	if (unlikely(released == 0 && !arm))
+		return 0;
+
+	/* ring doorbell for number popped */
+	doorbell.word0 = 0;
+	if (arm)
+		bf_set(lpfc_if6_cq_doorbell_arm, &doorbell, 1);
+	bf_set(lpfc_if6_cq_doorbell_num_released, &doorbell, released);
+	bf_set(lpfc_if6_cq_doorbell_cqid, &doorbell, q->queue_id);
+	writel(doorbell.word0, q->phba->sli4_hba.CQDBregaddr);
 	return released;
 }
 
@@ -2218,18 +2388,18 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
 void
 lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 {
-	wait_queue_head_t *pdone_q;
 	unsigned long drvr_flag;
+	struct completion *pmbox_done;
 
 	/*
-	 * If pdone_q is empty, the driver thread gave up waiting and
+	 * If pmbox_done is empty, the driver thread gave up waiting and
 	 * continued running.
 	 */
 	pmboxq->mbox_flag |= LPFC_MBX_WAKE;
 	spin_lock_irqsave(&phba->hbalock, drvr_flag);
-	pdone_q = (wait_queue_head_t *) pmboxq->context1;
-	if (pdone_q)
-		wake_up_interruptible(pdone_q);
+	pmbox_done = (struct completion *)pmboxq->context3;
+	if (pmbox_done)
+		complete(pmbox_done);
 	spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 	return;
 }
@@ -2330,7 +2500,7 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 	if (pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) {
 		if (phba->sli_rev == LPFC_SLI_REV4 &&
 		    (bf_get(lpfc_sli_intf_if_type,
-		     &phba->sli4_hba.sli_intf) ==
+		     &phba->sli4_hba.sli_intf) >=
 		     LPFC_SLI_INTF_IF_TYPE_2)) {
 			if (ndlp) {
 				lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
@@ -3776,6 +3946,7 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
 	struct lpfc_sli *psli = &phba->sli;
 	struct lpfc_sli_ring  *pring;
 	uint32_t i;
+	struct lpfc_iocbq *piocb, *next_iocb;
 
 	spin_lock_irq(&phba->hbalock);
 	/* Indicate the I/O queues are flushed */
@@ -3790,6 +3961,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
 			spin_lock_irq(&pring->ring_lock);
 			/* Retrieve everything on txq */
 			list_splice_init(&pring->txq, &txq);
+			list_for_each_entry_safe(piocb, next_iocb,
+						 &pring->txcmplq, list)
+				piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
 			/* Retrieve everything on the txcmplq */
 			list_splice_init(&pring->txcmplq, &txcmplq);
 			pring->txq_cnt = 0;
@@ -3811,6 +3985,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
 		spin_lock_irq(&phba->hbalock);
 		/* Retrieve everything on txq */
 		list_splice_init(&pring->txq, &txq);
+		list_for_each_entry_safe(piocb, next_iocb,
+					 &pring->txcmplq, list)
+			piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
 		/* Retrieve everything on the txcmplq */
 		list_splice_init(&pring->txcmplq, &txcmplq);
 		pring->txq_cnt = 0;
@@ -3842,6 +4019,7 @@ lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba)
 	LIST_HEAD(txcmplq);
 	struct lpfc_sli_ring  *pring;
 	uint32_t i;
+	struct lpfc_iocbq *piocb, *next_iocb;
 
 	if (phba->sli_rev < LPFC_SLI_REV4)
 		return;
@@ -3858,8 +4036,11 @@ lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba)
 	for (i = 0; i < phba->cfg_nvme_io_channel; i++) {
 		pring = phba->sli4_hba.nvme_wq[i]->pring;
 
-		/* Retrieve everything on the txcmplq */
 		spin_lock_irq(&pring->ring_lock);
+		list_for_each_entry_safe(piocb, next_iocb,
+					 &pring->txcmplq, list)
+			piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
+		/* Retrieve everything on the txcmplq */
 		list_splice_init(&pring->txcmplq, &txcmplq);
 		pring->txcmplq_cnt = 0;
 		spin_unlock_irq(&pring->ring_lock);
@@ -4812,13 +4993,14 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode)
 		phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get;
 		phba->port_gp = phba->mbox->us.s3_pgp.port;
 
-		if (phba->cfg_enable_bg) {
-			if (pmb->u.mb.un.varCfgPort.gbg)
-				phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
-			else
+		if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) {
+			if (pmb->u.mb.un.varCfgPort.gbg == 0) {
+				phba->cfg_enable_bg = 0;
+				phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED;
 				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 						"0443 Adapter did not grant "
 						"BlockGuard\n");
+			}
 		}
 	} else {
 		phba->hbq_get = NULL;
@@ -5290,41 +5472,42 @@ static void
 lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
 {
 	int qidx;
+	struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
 
-	lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM);
-	lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
-	if (phba->sli4_hba.nvmels_cq)
-		lpfc_sli4_cq_release(phba->sli4_hba.nvmels_cq,
+	sli4_hba->sli4_cq_release(sli4_hba->mbx_cq, LPFC_QUEUE_REARM);
+	sli4_hba->sli4_cq_release(sli4_hba->els_cq, LPFC_QUEUE_REARM);
+	if (sli4_hba->nvmels_cq)
+		sli4_hba->sli4_cq_release(sli4_hba->nvmels_cq,
 						LPFC_QUEUE_REARM);
 
-	if (phba->sli4_hba.fcp_cq)
+	if (sli4_hba->fcp_cq)
 		for (qidx = 0; qidx < phba->cfg_fcp_io_channel; qidx++)
-			lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[qidx],
+			sli4_hba->sli4_cq_release(sli4_hba->fcp_cq[qidx],
 						LPFC_QUEUE_REARM);
 
-	if (phba->sli4_hba.nvme_cq)
+	if (sli4_hba->nvme_cq)
 		for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++)
-			lpfc_sli4_cq_release(phba->sli4_hba.nvme_cq[qidx],
+			sli4_hba->sli4_cq_release(sli4_hba->nvme_cq[qidx],
 						LPFC_QUEUE_REARM);
 
 	if (phba->cfg_fof)
-		lpfc_sli4_cq_release(phba->sli4_hba.oas_cq, LPFC_QUEUE_REARM);
+		sli4_hba->sli4_cq_release(sli4_hba->oas_cq, LPFC_QUEUE_REARM);
 
-	if (phba->sli4_hba.hba_eq)
+	if (sli4_hba->hba_eq)
 		for (qidx = 0; qidx < phba->io_channel_irqs; qidx++)
-			lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[qidx],
-						LPFC_QUEUE_REARM);
+			sli4_hba->sli4_eq_release(sli4_hba->hba_eq[qidx],
+							LPFC_QUEUE_REARM);
 
 	if (phba->nvmet_support) {
 		for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++) {
-			lpfc_sli4_cq_release(
-				phba->sli4_hba.nvmet_cqset[qidx],
+			sli4_hba->sli4_cq_release(
+				sli4_hba->nvmet_cqset[qidx],
 				LPFC_QUEUE_REARM);
 		}
 	}
 
 	if (phba->cfg_fof)
-		lpfc_sli4_eq_release(phba->sli4_hba.fof_eq, LPFC_QUEUE_REARM);
+		sli4_hba->sli4_eq_release(sli4_hba->fof_eq, LPFC_QUEUE_REARM);
 }
 
 /**
@@ -6533,9 +6716,11 @@ lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
 	struct lpfc_rqe hrqe;
 	struct lpfc_rqe drqe;
 	struct lpfc_rqb *rqbp;
+	unsigned long flags;
 	struct rqb_dmabuf *rqb_buffer;
 	LIST_HEAD(rqb_buf_list);
 
+	spin_lock_irqsave(&phba->hbalock, flags);
 	rqbp = hrq->rqbp;
 	for (i = 0; i < count; i++) {
 		/* IF RQ is already full, don't bother */
@@ -6559,6 +6744,15 @@ lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
 		drqe.address_hi = putPaddrHigh(rqb_buffer->dbuf.phys);
 		rc = lpfc_sli4_rq_put(hrq, drq, &hrqe, &drqe);
 		if (rc < 0) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"6421 Cannot post to HRQ %d: %x %x %x "
+					"DRQ %x %x\n",
+					hrq->queue_id,
+					hrq->host_index,
+					hrq->hba_index,
+					hrq->entry_count,
+					drq->host_index,
+					drq->hba_index);
 			rqbp->rqb_free_buffer(phba, rqb_buffer);
 		} else {
 			list_add_tail(&rqb_buffer->hbuf.list,
@@ -6566,6 +6760,7 @@ lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
 			rqbp->buffer_count++;
 		}
 	}
+	spin_unlock_irqrestore(&phba->hbalock, flags);
 	return 1;
 }
 
@@ -6693,6 +6888,18 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
 	/* Save information as VPD data */
 	phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev;
 	phba->vpd.rev.smRev = mqe->un.read_rev.second_hw_rev;
+
+	/*
+	 * This is because first G7 ASIC doesn't support the standard
+	 * 0x5a NVME cmd descriptor type/subtype
+	 */
+	if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+			LPFC_SLI_INTF_IF_TYPE_6) &&
+	    (phba->vpd.rev.biuRev == LPFC_G7_ASIC_1) &&
+	    (phba->vpd.rev.smRev == 0) &&
+	    (phba->cfg_nvme_embed_cmd == 1))
+		phba->cfg_nvme_embed_cmd = 0;
+
 	phba->vpd.rev.endecRev = mqe->un.read_rev.third_hw_rev;
 	phba->vpd.rev.fcphHigh = bf_get(lpfc_mbx_rd_rev_fcph_high,
 					 &mqe->un.read_rev);
@@ -6771,21 +6978,26 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
 				"0378 No support for fcpi mode.\n");
 		ftr_rsp++;
 	}
-	if (bf_get(lpfc_mbx_rq_ftr_rsp_perfh, &mqe->un.req_ftrs))
-		phba->sli3_options |= LPFC_SLI4_PERFH_ENABLED;
-	else
-		phba->sli3_options &= ~LPFC_SLI4_PERFH_ENABLED;
+
+	/* Performance Hints are ONLY for FCoE */
+	if (phba->hba_flag & HBA_FCOE_MODE) {
+		if (bf_get(lpfc_mbx_rq_ftr_rsp_perfh, &mqe->un.req_ftrs))
+			phba->sli3_options |= LPFC_SLI4_PERFH_ENABLED;
+		else
+			phba->sli3_options &= ~LPFC_SLI4_PERFH_ENABLED;
+	}
+
 	/*
 	 * If the port cannot support the host's requested features
 	 * then turn off the global config parameters to disable the
 	 * feature in the driver.  This is not a fatal error.
 	 */
-	phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED;
-	if (phba->cfg_enable_bg) {
-		if (bf_get(lpfc_mbx_rq_ftr_rsp_dif, &mqe->un.req_ftrs))
-			phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
-		else
+	if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) {
+		if (!(bf_get(lpfc_mbx_rq_ftr_rsp_dif, &mqe->un.req_ftrs))) {
+			phba->cfg_enable_bg = 0;
+			phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED;
 			ftr_rsp++;
+		}
 	}
 
 	if (phba->max_vpi && phba->cfg_enable_npiv &&
@@ -7209,6 +7421,7 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
 	struct lpfc_queue *mcq;
 	struct lpfc_mcqe *mcqe;
 	bool pending_completions = false;
+	uint8_t	qe_valid;
 
 	if (unlikely(!phba) || (phba->sli_rev != LPFC_SLI_REV4))
 		return false;
@@ -7217,7 +7430,8 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
 
 	mcq = phba->sli4_hba.mbx_cq;
 	idx = mcq->hba_index;
-	while (bf_get_le32(lpfc_cqe_valid, mcq->qe[idx].cqe)) {
+	qe_valid = mcq->qe_valid;
+	while (bf_get_le32(lpfc_cqe_valid, mcq->qe[idx].cqe) == qe_valid) {
 		mcqe = (struct lpfc_mcqe *)mcq->qe[idx].cqe;
 		if (bf_get_le32(lpfc_trailer_completed, mcqe) &&
 		    (!bf_get_le32(lpfc_trailer_async, mcqe))) {
@@ -7227,6 +7441,10 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
 		idx = (idx + 1) % mcq->entry_count;
 		if (mcq->hba_index == idx)
 			break;
+
+		/* if the index wrapped around, toggle the valid bit */
+		if (phba->sli4_hba.pc_sli4_params.cqav && !idx)
+			qe_valid = (qe_valid) ? 0 : 1;
 	}
 	return pending_completions;
 
@@ -7246,7 +7464,7 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
 bool
 lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
 {
-
+	struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
 	uint32_t eqidx;
 	struct lpfc_queue *fpeq = NULL;
 	struct lpfc_eqe *eqe;
@@ -7257,11 +7475,11 @@ lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
 
 	/* Find the eq associated with the mcq */
 
-	if (phba->sli4_hba.hba_eq)
+	if (sli4_hba->hba_eq)
 		for (eqidx = 0; eqidx < phba->io_channel_irqs; eqidx++)
-			if (phba->sli4_hba.hba_eq[eqidx]->queue_id ==
-			    phba->sli4_hba.mbx_cq->assoc_qid) {
-				fpeq = phba->sli4_hba.hba_eq[eqidx];
+			if (sli4_hba->hba_eq[eqidx]->queue_id ==
+			    sli4_hba->mbx_cq->assoc_qid) {
+				fpeq = sli4_hba->hba_eq[eqidx];
 				break;
 			}
 	if (!fpeq)
@@ -7269,7 +7487,7 @@ lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
 
 	/* Turn off interrupts from this EQ */
 
-	lpfc_sli4_eq_clr_intr(fpeq);
+	sli4_hba->sli4_eq_clr_intr(fpeq);
 
 	/* Check to see if a mbox completion is pending */
 
@@ -7290,7 +7508,7 @@ lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
 
 	/* Always clear and re-arm the EQ */
 
-	lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_REARM);
+	sli4_hba->sli4_eq_release(fpeq, LPFC_QUEUE_REARM);
 
 	return mbox_pending;
 
@@ -8100,7 +8318,7 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
 	} else if (flag == MBX_POLL) {
 		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
 				"(%d):2542 Try to issue mailbox command "
-				"x%x (x%x/x%x) synchronously ahead of async"
+				"x%x (x%x/x%x) synchronously ahead of async "
 				"mailbox command queue: x%x x%x\n",
 				mboxq->vport ? mboxq->vport->vpi : 0,
 				mboxq->u.mb.mbxCommand,
@@ -8664,7 +8882,7 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
  **/
 static int
 lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
-		union lpfc_wqe *wqe)
+		union lpfc_wqe128 *wqe)
 {
 	uint32_t xmit_len = 0, total_len = 0;
 	uint8_t ct = 0;
@@ -8767,7 +8985,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 					iocbq->context2)->virt);
 		if_type = bf_get(lpfc_sli_intf_if_type,
 					&phba->sli4_hba.sli_intf);
-		if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
+		if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
 			if (pcmd && (*pcmd == ELS_CMD_FLOGI ||
 				*pcmd == ELS_CMD_SCR ||
 				*pcmd == ELS_CMD_FDISC ||
@@ -8870,31 +9088,36 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		}
 		/* Note, word 10 is already initialized to 0 */
 
+		/* Don't set PBDE for Perf hints, just fcp_embed_pbde */
+		if (phba->fcp_embed_pbde)
+			bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 1);
+		else
+			bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 0);
+
 		if (phba->fcp_embed_io) {
 			struct lpfc_scsi_buf *lpfc_cmd;
 			struct sli4_sge *sgl;
-			union lpfc_wqe128 *wqe128;
 			struct fcp_cmnd *fcp_cmnd;
 			uint32_t *ptr;
 
 			/* 128 byte wqe support here */
-			wqe128 = (union lpfc_wqe128 *)wqe;
 
 			lpfc_cmd = iocbq->context1;
 			sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
 			fcp_cmnd = lpfc_cmd->fcp_cmnd;
 
 			/* Word 0-2 - FCP_CMND */
-			wqe128->generic.bde.tus.f.bdeFlags =
+			wqe->generic.bde.tus.f.bdeFlags =
 				BUFF_TYPE_BDE_IMMED;
-			wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len;
-			wqe128->generic.bde.addrHigh = 0;
-			wqe128->generic.bde.addrLow =  88;  /* Word 22 */
+			wqe->generic.bde.tus.f.bdeSize = sgl->sge_len;
+			wqe->generic.bde.addrHigh = 0;
+			wqe->generic.bde.addrLow =  88;  /* Word 22 */
 
-			bf_set(wqe_wqes, &wqe128->fcp_iwrite.wqe_com, 1);
+			bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1);
+			bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 0);
 
 			/* Word 22-29  FCP CMND Payload */
-			ptr = &wqe128->words[22];
+			ptr = &wqe->words[22];
 			memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd));
 		}
 		break;
@@ -8929,31 +9152,36 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		}
 		/* Note, word 10 is already initialized to 0 */
 
+		/* Don't set PBDE for Perf hints, just fcp_embed_pbde */
+		if (phba->fcp_embed_pbde)
+			bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 1);
+		else
+			bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 0);
+
 		if (phba->fcp_embed_io) {
 			struct lpfc_scsi_buf *lpfc_cmd;
 			struct sli4_sge *sgl;
-			union lpfc_wqe128 *wqe128;
 			struct fcp_cmnd *fcp_cmnd;
 			uint32_t *ptr;
 
 			/* 128 byte wqe support here */
-			wqe128 = (union lpfc_wqe128 *)wqe;
 
 			lpfc_cmd = iocbq->context1;
 			sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
 			fcp_cmnd = lpfc_cmd->fcp_cmnd;
 
 			/* Word 0-2 - FCP_CMND */
-			wqe128->generic.bde.tus.f.bdeFlags =
+			wqe->generic.bde.tus.f.bdeFlags =
 				BUFF_TYPE_BDE_IMMED;
-			wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len;
-			wqe128->generic.bde.addrHigh = 0;
-			wqe128->generic.bde.addrLow =  88;  /* Word 22 */
+			wqe->generic.bde.tus.f.bdeSize = sgl->sge_len;
+			wqe->generic.bde.addrHigh = 0;
+			wqe->generic.bde.addrLow =  88;  /* Word 22 */
 
-			bf_set(wqe_wqes, &wqe128->fcp_iread.wqe_com, 1);
+			bf_set(wqe_wqes, &wqe->fcp_iread.wqe_com, 1);
+			bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 0);
 
 			/* Word 22-29  FCP CMND Payload */
-			ptr = &wqe128->words[22];
+			ptr = &wqe->words[22];
 			memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd));
 		}
 		break;
@@ -8990,28 +9218,27 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		if (phba->fcp_embed_io) {
 			struct lpfc_scsi_buf *lpfc_cmd;
 			struct sli4_sge *sgl;
-			union lpfc_wqe128 *wqe128;
 			struct fcp_cmnd *fcp_cmnd;
 			uint32_t *ptr;
 
 			/* 128 byte wqe support here */
-			wqe128 = (union lpfc_wqe128 *)wqe;
 
 			lpfc_cmd = iocbq->context1;
 			sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
 			fcp_cmnd = lpfc_cmd->fcp_cmnd;
 
 			/* Word 0-2 - FCP_CMND */
-			wqe128->generic.bde.tus.f.bdeFlags =
+			wqe->generic.bde.tus.f.bdeFlags =
 				BUFF_TYPE_BDE_IMMED;
-			wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len;
-			wqe128->generic.bde.addrHigh = 0;
-			wqe128->generic.bde.addrLow =  88;  /* Word 22 */
+			wqe->generic.bde.tus.f.bdeSize = sgl->sge_len;
+			wqe->generic.bde.addrHigh = 0;
+			wqe->generic.bde.addrLow =  88;  /* Word 22 */
 
-			bf_set(wqe_wqes, &wqe128->fcp_icmd.wqe_com, 1);
+			bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 1);
+			bf_set(wqe_dbde, &wqe->fcp_icmd.wqe_com, 0);
 
 			/* Word 22-29  FCP CMND Payload */
-			ptr = &wqe128->words[22];
+			ptr = &wqe->words[22];
 			memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd));
 		}
 		break;
@@ -9064,7 +9291,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 
 		if_type = bf_get(lpfc_sli_intf_if_type,
 					&phba->sli4_hba.sli_intf);
-		if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
+		if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
 			if (iocbq->vport->fc_flag & FC_PT2PT) {
 				bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
 				bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
@@ -9249,8 +9476,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
 			 struct lpfc_iocbq *piocb, uint32_t flag)
 {
 	struct lpfc_sglq *sglq;
-	union lpfc_wqe *wqe;
-	union lpfc_wqe128 wqe128;
+	union lpfc_wqe128 wqe;
 	struct lpfc_queue *wq;
 	struct lpfc_sli_ring *pring;
 
@@ -9270,9 +9496,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
 
 	/*
 	 * The WQE can be either 64 or 128 bytes,
-	 * so allocate space on the stack assuming the largest.
 	 */
-	wqe = (union lpfc_wqe *)&wqe128;
 
 	lockdep_assert_held(&phba->hbalock);
 
@@ -9322,10 +9546,10 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
 			return IOCB_ERROR;
 	}
 
-	if (lpfc_sli4_iocb2wqe(phba, piocb, wqe))
+	if (lpfc_sli4_iocb2wqe(phba, piocb, &wqe))
 		return IOCB_ERROR;
 
-	if (lpfc_sli4_wq_put(wq, wqe))
+	if (lpfc_sli4_wq_put(wq, &wqe))
 		return IOCB_ERROR;
 	lpfc_sli_ringtxcmpl_put(phba, pring, piocb);
 
@@ -9470,7 +9694,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number,
 				fpeq = phba->sli4_hba.hba_eq[idx];
 
 				/* Turn off interrupts from this EQ */
-				lpfc_sli4_eq_clr_intr(fpeq);
+				phba->sli4_hba.sli4_eq_clr_intr(fpeq);
 
 				/*
 				 * Process all the events on FCP EQ
@@ -9482,7 +9706,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number,
 				}
 
 				/* Always clear and re-arm the EQ */
-				lpfc_sli4_eq_release(fpeq,
+				phba->sli4_hba.sli4_eq_release(fpeq,
 					LPFC_QUEUE_REARM);
 			}
 			atomic_inc(&hba_eq_hdl->hba_eq_in_use);
@@ -10695,7 +10919,7 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 {
 	struct lpfc_vport *vport = cmdiocb->vport;
 	struct lpfc_iocbq *abtsiocbp;
-	union lpfc_wqe *abts_wqe;
+	union lpfc_wqe128 *abts_wqe;
 	int retval;
 
 	/*
@@ -11442,31 +11666,25 @@ int
 lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
 			 uint32_t timeout)
 {
-	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
-	MAILBOX_t *mb = NULL;
+	struct completion mbox_done;
 	int retval;
 	unsigned long flag;
 
-	/* The caller might set context1 for extended buffer */
-	if (pmboxq->context1)
-		mb = (MAILBOX_t *)pmboxq->context1;
-
 	pmboxq->mbox_flag &= ~LPFC_MBX_WAKE;
 	/* setup wake call as IOCB callback */
 	pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait;
-	/* setup context field to pass wait_queue pointer to wake function  */
-	pmboxq->context1 = &done_q;
 
+	/* setup context3 field to pass wait_queue pointer to wake function  */
+	init_completion(&mbox_done);
+	pmboxq->context3 = &mbox_done;
 	/* now issue the command */
 	retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
 	if (retval == MBX_BUSY || retval == MBX_SUCCESS) {
-		wait_event_interruptible_timeout(done_q,
-				pmboxq->mbox_flag & LPFC_MBX_WAKE,
-				msecs_to_jiffies(timeout * 1000));
+		wait_for_completion_timeout(&mbox_done,
+					    msecs_to_jiffies(timeout * 1000));
 
 		spin_lock_irqsave(&phba->hbalock, flag);
-		/* restore the possible extended buffer for free resource */
-		pmboxq->context1 = (uint8_t *)mb;
+		pmboxq->context3 = NULL;
 		/*
 		 * if LPFC_MBX_WAKE flag is set the mailbox is completed
 		 * else do not free the resources.
@@ -11478,11 +11696,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
 			pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 		}
 		spin_unlock_irqrestore(&phba->hbalock, flag);
-	} else {
-		/* restore the possible extended buffer for free resource */
-		pmboxq->context1 = (uint8_t *)mb;
 	}
-
 	return retval;
 }
 
@@ -11648,6 +11862,7 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba)
 		}
 		break;
 	case LPFC_SLI_INTF_IF_TYPE_2:
+	case LPFC_SLI_INTF_IF_TYPE_6:
 		if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
 			&portstat_reg.word0) ||
 			lpfc_readl(phba->sli4_hba.PSMPHRregaddr,
@@ -13112,7 +13327,7 @@ lpfc_sli4_sp_process_cq(struct work_struct *work)
 				"(x%x), type (%d)\n", cq->queue_id, cq->type);
 
 	/* In any case, flash and re-arm the RCQ */
-	lpfc_sli4_cq_release(cq, LPFC_QUEUE_REARM);
+	phba->sli4_hba.sli4_cq_release(cq, LPFC_QUEUE_REARM);
 
 	/* wake up worker thread if there are works to be done */
 	if (workposted)
@@ -13230,6 +13445,8 @@ lpfc_sli4_fp_handle_rel_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
 		if (childwq->queue_id == hba_wqid) {
 			lpfc_sli4_wq_release(childwq,
 					bf_get(lpfc_wcqe_r_wqe_index, wcqe));
+			if (childwq->q_flag & HBA_NVMET_WQFULL)
+				lpfc_nvmet_wqfull_process(phba, childwq);
 			wqid_matched = true;
 			break;
 		}
@@ -13542,7 +13759,7 @@ lpfc_sli4_hba_process_cq(struct work_struct *work)
 				"queue fcpcqid=%d\n", cq->queue_id);
 
 	/* In any case, flash and re-arm the CQ */
-	lpfc_sli4_cq_release(cq, LPFC_QUEUE_REARM);
+	phba->sli4_hba.sli4_cq_release(cq, LPFC_QUEUE_REARM);
 
 	/* wake up worker thread if there are works to be done */
 	if (workposted)
@@ -13559,7 +13776,7 @@ lpfc_sli4_eq_flush(struct lpfc_hba *phba, struct lpfc_queue *eq)
 		;
 
 	/* Clear and re-arm the EQ */
-	lpfc_sli4_eq_release(eq, LPFC_QUEUE_REARM);
+	phba->sli4_hba.sli4_eq_release(eq, LPFC_QUEUE_REARM);
 }
 
 
@@ -13707,7 +13924,7 @@ lpfc_sli4_fof_intr_handler(int irq, void *dev_id)
 		}
 	}
 	/* Always clear and re-arm the fast-path EQ */
-	lpfc_sli4_eq_release(eq, LPFC_QUEUE_REARM);
+	phba->sli4_hba.sli4_eq_release(eq, LPFC_QUEUE_REARM);
 	return IRQ_HANDLED;
 }
 
@@ -13765,7 +13982,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id)
 
 	if (lpfc_fcp_look_ahead) {
 		if (atomic_dec_and_test(&hba_eq_hdl->hba_eq_in_use))
-			lpfc_sli4_eq_clr_intr(fpeq);
+			phba->sli4_hba.sli4_eq_clr_intr(fpeq);
 		else {
 			atomic_inc(&hba_eq_hdl->hba_eq_in_use);
 			return IRQ_NONE;
@@ -13800,7 +14017,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id)
 		fpeq->EQ_max_eqe = ecount;
 
 	/* Always clear and re-arm the fast-path EQ */
-	lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_REARM);
+	phba->sli4_hba.sli4_eq_release(fpeq, LPFC_QUEUE_REARM);
 
 	if (unlikely(ecount == 0)) {
 		fpeq->EQ_no_entry++;
@@ -13948,6 +14165,7 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t page_size,
 
 	INIT_LIST_HEAD(&queue->list);
 	INIT_LIST_HEAD(&queue->wq_list);
+	INIT_LIST_HEAD(&queue->wqfull_list);
 	INIT_LIST_HEAD(&queue->page_list);
 	INIT_LIST_HEAD(&queue->child_list);
 
@@ -14173,11 +14391,21 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint32_t imax)
 			 LPFC_MBOX_OPCODE_EQ_CREATE,
 			 length, LPFC_SLI4_MBX_EMBED);
 	eq_create = &mbox->u.mqe.un.eq_create;
+	shdr = (union lpfc_sli4_cfg_shdr *) &eq_create->header.cfg_shdr;
 	bf_set(lpfc_mbx_eq_create_num_pages, &eq_create->u.request,
 	       eq->page_count);
 	bf_set(lpfc_eq_context_size, &eq_create->u.request.context,
 	       LPFC_EQE_SIZE);
 	bf_set(lpfc_eq_context_valid, &eq_create->u.request.context, 1);
+
+	/* Use version 2 of CREATE_EQ if eqav is set */
+	if (phba->sli4_hba.pc_sli4_params.eqav) {
+		bf_set(lpfc_mbox_hdr_version, &shdr->request,
+		       LPFC_Q_CREATE_VERSION_2);
+		bf_set(lpfc_eq_context_autovalid, &eq_create->u.request.context,
+		       phba->sli4_hba.pc_sli4_params.eqav);
+	}
+
 	/* don't setup delay multiplier using EQ_CREATE */
 	dmult = 0;
 	bf_set(lpfc_eq_context_delay_multi, &eq_create->u.request.context,
@@ -14222,7 +14450,6 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint32_t imax)
 	mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 	mbox->context1 = NULL;
 	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
-	shdr = (union lpfc_sli4_cfg_shdr *) &eq_create->header.cfg_shdr;
 	shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
 	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
 	if (shdr_status || shdr_add_status || rc) {
@@ -14305,6 +14532,8 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
 		       (cq->page_size / SLI4_PAGE_SIZE));
 		bf_set(lpfc_cq_eq_id_2, &cq_create->u.request.context,
 		       eq->queue_id);
+		bf_set(lpfc_cq_context_autovalid, &cq_create->u.request.context,
+		       phba->sli4_hba.pc_sli4_params.cqav);
 	} else {
 		bf_set(lpfc_cq_eq_id, &cq_create->u.request.context,
 		       eq->queue_id);
@@ -14476,6 +14705,9 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
 			       &cq_set->u.request, 0);
 			bf_set(lpfc_mbx_cq_create_set_num_cq,
 			       &cq_set->u.request, numcq);
+			bf_set(lpfc_mbx_cq_create_set_autovalid,
+			       &cq_set->u.request,
+			       phba->sli4_hba.pc_sli4_params.cqav);
 			switch (cq->entry_count) {
 			case 2048:
 			case 4096:
@@ -14881,6 +15113,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
 	void __iomem *bar_memmap_p;
 	uint32_t db_offset;
 	uint16_t pci_barset;
+	uint8_t dpp_barset;
+	uint32_t dpp_offset;
+	unsigned long pg_addr;
 	uint8_t wq_create_version;
 
 	/* sanity check on queue memory */
@@ -14908,43 +15143,19 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
 	bf_set(lpfc_mbox_hdr_version, &shdr->request,
 	       phba->sli4_hba.pc_sli4_params.wqv);
 
+	if ((phba->sli4_hba.pc_sli4_params.wqsize & LPFC_WQ_SZ128_SUPPORT) ||
+	    (wq->page_size > SLI4_PAGE_SIZE))
+		wq_create_version = LPFC_Q_CREATE_VERSION_1;
+	else
+		wq_create_version = LPFC_Q_CREATE_VERSION_0;
+
+
 	if (phba->sli4_hba.pc_sli4_params.wqsize & LPFC_WQ_SZ128_SUPPORT)
 		wq_create_version = LPFC_Q_CREATE_VERSION_1;
 	else
 		wq_create_version = LPFC_Q_CREATE_VERSION_0;
 
 	switch (wq_create_version) {
-	case LPFC_Q_CREATE_VERSION_0:
-		switch (wq->entry_size) {
-		default:
-		case 64:
-			/* Nothing to do, version 0 ONLY supports 64 byte */
-			page = wq_create->u.request.page;
-			break;
-		case 128:
-			if (!(phba->sli4_hba.pc_sli4_params.wqsize &
-			    LPFC_WQ_SZ128_SUPPORT)) {
-				status = -ERANGE;
-				goto out;
-			}
-			/* If we get here the HBA MUST also support V1 and
-			 * we MUST use it
-			 */
-			bf_set(lpfc_mbox_hdr_version, &shdr->request,
-			       LPFC_Q_CREATE_VERSION_1);
-
-			bf_set(lpfc_mbx_wq_create_wqe_count,
-			       &wq_create->u.request_1, wq->entry_count);
-			bf_set(lpfc_mbx_wq_create_wqe_size,
-			       &wq_create->u.request_1,
-			       LPFC_WQ_WQE_SIZE_128);
-			bf_set(lpfc_mbx_wq_create_page_size,
-			       &wq_create->u.request_1,
-			       LPFC_WQ_PAGE_SIZE_4096);
-			page = wq_create->u.request_1.page;
-			break;
-		}
-		break;
 	case LPFC_Q_CREATE_VERSION_1:
 		bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1,
 		       wq->entry_count);
@@ -14959,24 +15170,21 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
 			       LPFC_WQ_WQE_SIZE_64);
 			break;
 		case 128:
-			if (!(phba->sli4_hba.pc_sli4_params.wqsize &
-				LPFC_WQ_SZ128_SUPPORT)) {
-				status = -ERANGE;
-				goto out;
-			}
 			bf_set(lpfc_mbx_wq_create_wqe_size,
 			       &wq_create->u.request_1,
 			       LPFC_WQ_WQE_SIZE_128);
 			break;
 		}
+		/* Request DPP by default */
+		bf_set(lpfc_mbx_wq_create_dpp_req, &wq_create->u.request_1, 1);
 		bf_set(lpfc_mbx_wq_create_page_size,
 		       &wq_create->u.request_1,
 		       (wq->page_size / SLI4_PAGE_SIZE));
 		page = wq_create->u.request_1.page;
 		break;
 	default:
-		status = -ERANGE;
-		goto out;
+		page = wq_create->u.request.page;
+		break;
 	}
 
 	list_for_each_entry(dmabuf, &wq->page_list, list) {
@@ -15000,52 +15208,120 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
 		status = -ENXIO;
 		goto out;
 	}
-	wq->queue_id = bf_get(lpfc_mbx_wq_create_q_id, &wq_create->u.response);
+
+	if (wq_create_version == LPFC_Q_CREATE_VERSION_0)
+		wq->queue_id = bf_get(lpfc_mbx_wq_create_q_id,
+					&wq_create->u.response);
+	else
+		wq->queue_id = bf_get(lpfc_mbx_wq_create_v1_q_id,
+					&wq_create->u.response_1);
+
 	if (wq->queue_id == 0xFFFF) {
 		status = -ENXIO;
 		goto out;
 	}
-	if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) {
-		wq->db_format = bf_get(lpfc_mbx_wq_create_db_format,
-				       &wq_create->u.response);
-		if ((wq->db_format != LPFC_DB_LIST_FORMAT) &&
-		    (wq->db_format != LPFC_DB_RING_FORMAT)) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-					"3265 WQ[%d] doorbell format not "
-					"supported: x%x\n", wq->queue_id,
-					wq->db_format);
-			status = -EINVAL;
-			goto out;
-		}
-		pci_barset = bf_get(lpfc_mbx_wq_create_bar_set,
-				    &wq_create->u.response);
-		bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba, pci_barset);
-		if (!bar_memmap_p) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-					"3263 WQ[%d] failed to memmap pci "
-					"barset:x%x\n", wq->queue_id,
-					pci_barset);
-			status = -ENOMEM;
-			goto out;
-		}
-		db_offset = wq_create->u.response.doorbell_offset;
-		if ((db_offset != LPFC_ULP0_WQ_DOORBELL) &&
-		    (db_offset != LPFC_ULP1_WQ_DOORBELL)) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-					"3252 WQ[%d] doorbell offset not "
-					"supported: x%x\n", wq->queue_id,
-					db_offset);
-			status = -EINVAL;
-			goto out;
-		}
-		wq->db_regaddr = bar_memmap_p + db_offset;
-		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-				"3264 WQ[%d]: barset:x%x, offset:x%x, "
-				"format:x%x\n", wq->queue_id, pci_barset,
-				db_offset, wq->db_format);
+
+	wq->db_format = LPFC_DB_LIST_FORMAT;
+	if (wq_create_version == LPFC_Q_CREATE_VERSION_0) {
+		if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) {
+			wq->db_format = bf_get(lpfc_mbx_wq_create_db_format,
+					       &wq_create->u.response);
+			if ((wq->db_format != LPFC_DB_LIST_FORMAT) &&
+			    (wq->db_format != LPFC_DB_RING_FORMAT)) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+						"3265 WQ[%d] doorbell format "
+						"not supported: x%x\n",
+						wq->queue_id, wq->db_format);
+				status = -EINVAL;
+				goto out;
+			}
+			pci_barset = bf_get(lpfc_mbx_wq_create_bar_set,
+					    &wq_create->u.response);
+			bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba,
+								   pci_barset);
+			if (!bar_memmap_p) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+						"3263 WQ[%d] failed to memmap "
+						"pci barset:x%x\n",
+						wq->queue_id, pci_barset);
+				status = -ENOMEM;
+				goto out;
+			}
+			db_offset = wq_create->u.response.doorbell_offset;
+			if ((db_offset != LPFC_ULP0_WQ_DOORBELL) &&
+			    (db_offset != LPFC_ULP1_WQ_DOORBELL)) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+						"3252 WQ[%d] doorbell offset "
+						"not supported: x%x\n",
+						wq->queue_id, db_offset);
+				status = -EINVAL;
+				goto out;
+			}
+			wq->db_regaddr = bar_memmap_p + db_offset;
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+					"3264 WQ[%d]: barset:x%x, offset:x%x, "
+					"format:x%x\n", wq->queue_id,
+					pci_barset, db_offset, wq->db_format);
+		} else
+			wq->db_regaddr = phba->sli4_hba.WQDBregaddr;
 	} else {
-		wq->db_format = LPFC_DB_LIST_FORMAT;
-		wq->db_regaddr = phba->sli4_hba.WQDBregaddr;
+		/* Check if DPP was honored by the firmware */
+		wq->dpp_enable = bf_get(lpfc_mbx_wq_create_dpp_rsp,
+				    &wq_create->u.response_1);
+		if (wq->dpp_enable) {
+			pci_barset = bf_get(lpfc_mbx_wq_create_v1_bar_set,
+					    &wq_create->u.response_1);
+			bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba,
+								   pci_barset);
+			if (!bar_memmap_p) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+						"3267 WQ[%d] failed to memmap "
+						"pci barset:x%x\n",
+						wq->queue_id, pci_barset);
+				status = -ENOMEM;
+				goto out;
+			}
+			db_offset = wq_create->u.response_1.doorbell_offset;
+			wq->db_regaddr = bar_memmap_p + db_offset;
+			wq->dpp_id = bf_get(lpfc_mbx_wq_create_dpp_id,
+					    &wq_create->u.response_1);
+			dpp_barset = bf_get(lpfc_mbx_wq_create_dpp_bar,
+					    &wq_create->u.response_1);
+			bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba,
+								   dpp_barset);
+			if (!bar_memmap_p) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+						"3268 WQ[%d] failed to memmap "
+						"pci barset:x%x\n",
+						wq->queue_id, dpp_barset);
+				status = -ENOMEM;
+				goto out;
+			}
+			dpp_offset = wq_create->u.response_1.dpp_offset;
+			wq->dpp_regaddr = bar_memmap_p + dpp_offset;
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+					"3271 WQ[%d]: barset:x%x, offset:x%x, "
+					"dpp_id:x%x dpp_barset:x%x "
+					"dpp_offset:x%x\n",
+					wq->queue_id, pci_barset, db_offset,
+					wq->dpp_id, dpp_barset, dpp_offset);
+
+			/* Enable combined writes for DPP aperture */
+			pg_addr = (unsigned long)(wq->dpp_regaddr) & PAGE_MASK;
+#ifdef CONFIG_X86
+			rc = set_memory_wc(pg_addr, 1);
+			if (rc) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"3272 Cannot setup Combined "
+					"Write on WQ[%d] - disable DPP\n",
+					wq->queue_id);
+				phba->cfg_enable_dpp = 0;
+			}
+#else
+			phba->cfg_enable_dpp = 0;
+#endif
+		} else
+			wq->db_regaddr = phba->sli4_hba.WQDBregaddr;
 	}
 	wq->pring = kzalloc(sizeof(struct lpfc_sli_ring), GFP_KERNEL);
 	if (wq->pring == NULL) {
@@ -18616,6 +18892,7 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
 				"status x%x add_status x%x, mbx status x%x\n",
 				shdr_status, shdr_add_status, rc);
 		rc = -ENXIO;
+		*offset = shdr_add_status;
 	} else
 		*offset += wr_object->u.response.actual_write_length;
 	return rc;
@@ -18753,8 +19030,7 @@ lpfc_drain_txq(struct lpfc_hba *phba)
 	unsigned long iflags = 0;
 	char *fail_msg = NULL;
 	struct lpfc_sglq *sglq;
-	union lpfc_wqe128 wqe128;
-	union lpfc_wqe *wqe = (union lpfc_wqe *) &wqe128;
+	union lpfc_wqe128 wqe;
 	uint32_t txq_cnt = 0;
 
 	pring = lpfc_phba_elsring(phba);
@@ -18797,9 +19073,9 @@ lpfc_drain_txq(struct lpfc_hba *phba)
 		piocbq->sli4_xritag = sglq->sli4_xritag;
 		if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocbq, sglq))
 			fail_msg = "to convert bpl to sgl";
-		else if (lpfc_sli4_iocb2wqe(phba, piocbq, wqe))
+		else if (lpfc_sli4_iocb2wqe(phba, piocbq, &wqe))
 			fail_msg = "to convert iocb to wqe";
-		else if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, wqe))
+		else if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe))
 			fail_msg = " - Wq is full";
 		else
 			lpfc_sli_ringtxcmpl_put(phba, pring, piocbq);
@@ -18849,7 +19125,7 @@ lpfc_wqe_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeq,
 	struct ulp_bde64 bde;
 	struct sli4_sge *sgl  = NULL;
 	struct lpfc_dmabuf *dmabuf;
-	union lpfc_wqe *wqe;
+	union lpfc_wqe128 *wqe;
 	int numBdes = 0;
 	int i = 0;
 	uint32_t offset = 0; /* accumulated offset in the sg request list */
@@ -18958,7 +19234,7 @@ int
 lpfc_sli4_issue_wqe(struct lpfc_hba *phba, uint32_t ring_number,
 		    struct lpfc_iocbq *pwqe)
 {
-	union lpfc_wqe *wqe = &pwqe->wqe;
+	union lpfc_wqe128 *wqe = &pwqe->wqe;
 	struct lpfc_nvmet_rcv_ctx *ctxp;
 	struct lpfc_queue *wq;
 	struct lpfc_sglq *sglq;
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index a3b1b51..4317541 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -61,9 +61,8 @@ struct lpfc_iocbq {
 	struct lpfc_wcqe_complete wcqe_cmpl;	/* WQE cmpl */
 	uint64_t isr_timestamp;
 
-	/* Be careful here */
-	union lpfc_wqe wqe;	/* WQE cmd */
-	IOCB_t iocb;		/* For IOCB cmd or if we want 128 byte WQE */
+	union lpfc_wqe128 wqe;	/* SLI-4 */
+	IOCB_t iocb;		/* SLI-3 */
 
 	uint8_t rsvd2;
 	uint8_t priority;	/* OAS priority */
@@ -148,6 +147,7 @@ typedef struct lpfcMboxq {
 	struct lpfc_vport *vport;/* virtual port pointer */
 	void *context1;		/* caller context information */
 	void *context2;		/* caller context information */
+	void *context3;
 
 	void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *);
 	uint8_t mbox_flag;
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 81fb58e..cf64aca 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2009-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -145,6 +145,7 @@ struct lpfc_rqb {
 struct lpfc_queue {
 	struct list_head list;
 	struct list_head wq_list;
+	struct list_head wqfull_list;
 	enum lpfc_sli4_queue_type type;
 	enum lpfc_sli4_queue_subtype subtype;
 	struct lpfc_hba *phba;
@@ -173,10 +174,16 @@ struct lpfc_queue {
 #define LPFC_EXPANDED_PAGE_SIZE	16384
 #define LPFC_DEFAULT_PAGE_SIZE	4096
 	uint16_t chann;		/* IO channel this queue is associated with */
-	uint16_t db_format;
+	uint8_t db_format;
 #define LPFC_DB_RING_FORMAT	0x01
 #define LPFC_DB_LIST_FORMAT	0x02
+	uint8_t q_flag;
+#define HBA_NVMET_WQFULL	0x1 /* We hit WQ Full condition for NVMET */
 	void __iomem *db_regaddr;
+	uint16_t dpp_enable;
+	uint16_t dpp_id;
+	void __iomem *dpp_regaddr;
+
 	/* For q stats */
 	uint32_t q_cnt_1;
 	uint32_t q_cnt_2;
@@ -209,6 +216,7 @@ struct lpfc_queue {
 	struct work_struct spwork;
 
 	uint64_t isr_timestamp;
+	uint8_t	qe_valid;
 	struct lpfc_queue *assoc_qp;
 	union sli4_qe qe[1];	/* array to index entries (must be last) */
 };
@@ -479,12 +487,19 @@ struct lpfc_pc_sli4_params {
 	uint8_t mqv;
 	uint8_t wqv;
 	uint8_t rqv;
+	uint8_t eqav;
+	uint8_t cqav;
 	uint8_t wqsize;
 #define LPFC_WQ_SZ64_SUPPORT	1
 #define LPFC_WQ_SZ128_SUPPORT	2
 	uint8_t wqpcnt;
 };
 
+#define LPFC_CQ_4K_PAGE_SZ	0x1
+#define LPFC_CQ_16K_PAGE_SZ	0x4
+#define LPFC_WQ_4K_PAGE_SZ	0x1
+#define LPFC_WQ_16K_PAGE_SZ	0x4
+
 struct lpfc_iov {
 	uint32_t pf_number;
 	uint32_t vf_number;
@@ -516,11 +531,17 @@ struct lpfc_vector_map_info {
 /* SLI4 HBA data structure entries */
 struct lpfc_sli4_hba {
 	void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for
-					     PCI BAR0, config space registers */
+					   * config space registers
+					   */
 	void __iomem *ctrl_regs_memmap_p; /* Kernel memory mapped address for
-					     PCI BAR1, control registers */
+					   * control registers
+					   */
 	void __iomem *drbl_regs_memmap_p; /* Kernel memory mapped address for
-					     PCI BAR2, doorbell registers */
+					   * doorbell registers
+					   */
+	void __iomem *dpp_regs_memmap_p;  /* Kernel memory mapped address for
+					   * dpp registers
+					   */
 	union {
 		struct {
 			/* IF Type 0, BAR 0 PCI cfg space reg mem map */
@@ -561,7 +582,8 @@ struct lpfc_sli4_hba {
 	/* IF type 0, BAR 0 and if type 2, BAR 0 doorbell register memory map */
 	void __iomem *RQDBregaddr;	/* RQ_DOORBELL register */
 	void __iomem *WQDBregaddr;	/* WQ_DOORBELL register */
-	void __iomem *EQCQDBregaddr;	/* EQCQ_DOORBELL register */
+	void __iomem *CQDBregaddr;	/* CQ_DOORBELL register */
+	void __iomem *EQDBregaddr;	/* EQ_DOORBELL register */
 	void __iomem *MQDBregaddr;	/* MQ_DOORBELL register */
 	void __iomem *BMBXregaddr;	/* BootStrap MBX register */
 
@@ -574,6 +596,10 @@ struct lpfc_sli4_hba {
 	struct lpfc_bbscn_params bbscn_params;
 	struct lpfc_hba_eq_hdl *hba_eq_hdl; /* HBA per-WQ handle */
 
+	void (*sli4_eq_clr_intr)(struct lpfc_queue *q);
+	uint32_t (*sli4_eq_release)(struct lpfc_queue *q, bool arm);
+	uint32_t (*sli4_cq_release)(struct lpfc_queue *q, bool arm);
+
 	/* Pointers to the constructed SLI4 queues */
 	struct lpfc_queue **hba_eq;  /* Event queues for HBA */
 	struct lpfc_queue **fcp_cq;  /* Fast-path FCP compl queue */
@@ -840,8 +866,12 @@ void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *);
 int lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *);
 int lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba);
 int lpfc_sli4_init_vpi(struct lpfc_vport *);
+inline void lpfc_sli4_eq_clr_intr(struct lpfc_queue *);
 uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool);
 uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool);
+inline void lpfc_sli4_if6_eq_clr_intr(struct lpfc_queue *q);
+uint32_t lpfc_sli4_if6_cq_release(struct lpfc_queue *q, bool arm);
+uint32_t lpfc_sli4_if6_eq_release(struct lpfc_queue *q, bool arm);
 void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t);
 int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t);
 int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t);
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index c232bf0..e8b089a 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term      *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -20,7 +20,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "11.4.0.6"
+#define LPFC_DRIVER_VERSION "12.0.0.1"
 #define LPFC_DRIVER_NAME		"lpfc"
 
 /* Used for SLI 2/3 */
@@ -32,6 +32,6 @@
 
 #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
 		LPFC_DRIVER_VERSION
-#define LPFC_COPYRIGHT "Copyright (C) 2017 Broadcom. All Rights Reserved. " \
-		"The term \"Broadcom\" refers to Broadcom Limited " \
+#define LPFC_COPYRIGHT "Copyright (C) 2017-2018 Broadcom. All Rights " \
+		"Reserved. The term \"Broadcom\" refers to Broadcom Limited " \
 		"and/or its subsidiaries."
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index dde0798..b89c6e6 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1864,7 +1864,7 @@ megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size)
 
 	blk_queue_max_hw_sectors(sdev->request_queue, (max_io_size / 512));
 
-	queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, sdev->request_queue);
+	blk_queue_flag_set(QUEUE_FLAG_NOMERGES, sdev->request_queue);
 	blk_queue_virt_boundary(sdev->request_queue, mr_nvme_pg_size - 1);
 }
 
@@ -4022,7 +4022,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
 
 		cmd = instance->cmd_list[i];
 
-		cmd->frame = dma_pool_alloc(instance->frame_dma_pool,
+		cmd->frame = dma_pool_zalloc(instance->frame_dma_pool,
 					    GFP_KERNEL, &cmd->frame_phys_addr);
 
 		cmd->sense = dma_pool_alloc(instance->sense_dma_pool,
@@ -4038,7 +4038,6 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
 			return -ENOMEM;
 		}
 
-		memset(cmd->frame, 0, instance->mfi_frame_size);
 		cmd->frame->io.context = cpu_to_le32(cmd->index);
 		cmd->frame->io.pad_0 = 0;
 		if ((instance->adapter_type == MFI_SERIES) && reset_devices)
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 5ec3b74..ce97cde 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1894,7 +1894,7 @@ megasas_is_prp_possible(struct megasas_instance *instance,
  * then sending IOs with holes.
  *
  * Though driver can request block layer to disable IO merging by calling-
- * queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, sdev->request_queue) but
+ * blk_queue_flag_set(QUEUE_FLAG_NOMERGES, sdev->request_queue) but
  * user may tune sysfs parameter- nomerges again to 0 or 1.
  *
  * If in future IO scheduling is enabled with SCSI BLK MQ,
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index ee11710..0ad88de 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -524,6 +524,7 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI2_MFGPAGE_DEVID_SAS2308_1                (0x0086)
 #define MPI2_MFGPAGE_DEVID_SAS2308_2                (0x0087)
 #define MPI2_MFGPAGE_DEVID_SAS2308_3                (0x006E)
+#define MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP           (0x02B0)
 
 /*MPI v2.5 SAS products */
 #define MPI25_MFGPAGE_DEVID_SAS3004                 (0x0096)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0aafbfd..61f93a1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -126,6 +126,362 @@ module_param_call(mpt3sas_fwfault_debug, _scsih_set_fwfault_debug,
 	param_get_int, &mpt3sas_fwfault_debug, 0644);
 
 /**
+ * _base_clone_reply_to_sys_mem - copies reply to reply free iomem
+ *				  in BAR0 space.
+ *
+ * @ioc: per adapter object
+ * @reply: reply message frame(lower 32bit addr)
+ * @index: System request message index.
+ *
+ * @Returns - Nothing
+ */
+static void
+_base_clone_reply_to_sys_mem(struct MPT3SAS_ADAPTER *ioc, u32 reply,
+		u32 index)
+{
+	/*
+	 * 256 is offset within sys register.
+	 * 256 offset MPI frame starts. Max MPI frame supported is 32.
+	 * 32 * 128 = 4K. From here, Clone of reply free for mcpu starts
+	 */
+	u16 cmd_credit = ioc->facts.RequestCredit + 1;
+	void __iomem *reply_free_iomem = (void __iomem *)ioc->chip +
+			MPI_FRAME_START_OFFSET +
+			(cmd_credit * ioc->request_sz) + (index * sizeof(u32));
+
+	writel(reply, reply_free_iomem);
+}
+
+/**
+ * _base_clone_mpi_to_sys_mem - Writes/copies MPI frames
+ *				to system/BAR0 region.
+ *
+ * @dst_iomem: Pointer to the destinaltion location in BAR0 space.
+ * @src: Pointer to the Source data.
+ * @size: Size of data to be copied.
+ */
+static void
+_base_clone_mpi_to_sys_mem(void *dst_iomem, void *src, u32 size)
+{
+	int i;
+	u32 *src_virt_mem = (u32 *)src;
+
+	for (i = 0; i < size/4; i++)
+		writel((u32)src_virt_mem[i],
+				(void __iomem *)dst_iomem + (i * 4));
+}
+
+/**
+ * _base_clone_to_sys_mem - Writes/copies data to system/BAR0 region
+ *
+ * @dst_iomem: Pointer to the destination location in BAR0 space.
+ * @src: Pointer to the Source data.
+ * @size: Size of data to be copied.
+ */
+static void
+_base_clone_to_sys_mem(void __iomem *dst_iomem, void *src, u32 size)
+{
+	int i;
+	u32 *src_virt_mem = (u32 *)(src);
+
+	for (i = 0; i < size/4; i++)
+		writel((u32)src_virt_mem[i],
+			(void __iomem *)dst_iomem + (i * 4));
+}
+
+/**
+ * _base_get_chain - Calculates and Returns virtual chain address
+ *			 for the provided smid in BAR0 space.
+ *
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @sge_chain_count: Scatter gather chain count.
+ *
+ * @Return: chain address.
+ */
+static inline void __iomem*
+_base_get_chain(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+		u8 sge_chain_count)
+{
+	void __iomem *base_chain, *chain_virt;
+	u16 cmd_credit = ioc->facts.RequestCredit + 1;
+
+	base_chain  = (void __iomem *)ioc->chip + MPI_FRAME_START_OFFSET +
+		(cmd_credit * ioc->request_sz) +
+		REPLY_FREE_POOL_SIZE;
+	chain_virt = base_chain + (smid * ioc->facts.MaxChainDepth *
+			ioc->request_sz) + (sge_chain_count * ioc->request_sz);
+	return chain_virt;
+}
+
+/**
+ * _base_get_chain_phys - Calculates and Returns physical address
+ *			in BAR0 for scatter gather chains, for
+ *			the provided smid.
+ *
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @sge_chain_count: Scatter gather chain count.
+ *
+ * @Return - Physical chain address.
+ */
+static inline phys_addr_t
+_base_get_chain_phys(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+		u8 sge_chain_count)
+{
+	phys_addr_t base_chain_phys, chain_phys;
+	u16 cmd_credit = ioc->facts.RequestCredit + 1;
+
+	base_chain_phys  = ioc->chip_phys + MPI_FRAME_START_OFFSET +
+		(cmd_credit * ioc->request_sz) +
+		REPLY_FREE_POOL_SIZE;
+	chain_phys = base_chain_phys + (smid * ioc->facts.MaxChainDepth *
+			ioc->request_sz) + (sge_chain_count * ioc->request_sz);
+	return chain_phys;
+}
+
+/**
+ * _base_get_buffer_bar0 - Calculates and Returns BAR0 mapped Host
+ *			buffer address for the provided smid.
+ *			(Each smid can have 64K starts from 17024)
+ *
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * @Returns - Pointer to buffer location in BAR0.
+ */
+
+static void __iomem *
+_base_get_buffer_bar0(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+	u16 cmd_credit = ioc->facts.RequestCredit + 1;
+	// Added extra 1 to reach end of chain.
+	void __iomem *chain_end = _base_get_chain(ioc,
+			cmd_credit + 1,
+			ioc->facts.MaxChainDepth);
+	return chain_end + (smid * 64 * 1024);
+}
+
+/**
+ * _base_get_buffer_phys_bar0 - Calculates and Returns BAR0 mapped
+ *		Host buffer Physical address for the provided smid.
+ *		(Each smid can have 64K starts from 17024)
+ *
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * @Returns - Pointer to buffer location in BAR0.
+ */
+static phys_addr_t
+_base_get_buffer_phys_bar0(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+	u16 cmd_credit = ioc->facts.RequestCredit + 1;
+	phys_addr_t chain_end_phys = _base_get_chain_phys(ioc,
+			cmd_credit + 1,
+			ioc->facts.MaxChainDepth);
+	return chain_end_phys + (smid * 64 * 1024);
+}
+
+/**
+ * _base_get_chain_buffer_dma_to_chain_buffer - Iterates chain
+ *			lookup list and Provides chain_buffer
+ *			address for the matching dma address.
+ *			(Each smid can have 64K starts from 17024)
+ *
+ * @ioc: per adapter object
+ * @chain_buffer_dma: Chain buffer dma address.
+ *
+ * @Returns - Pointer to chain buffer. Or Null on Failure.
+ */
+static void *
+_base_get_chain_buffer_dma_to_chain_buffer(struct MPT3SAS_ADAPTER *ioc,
+		dma_addr_t chain_buffer_dma)
+{
+	u16 index;
+
+	for (index = 0; index < ioc->chain_depth; index++) {
+		if (ioc->chain_lookup[index].chain_buffer_dma ==
+				chain_buffer_dma)
+			return ioc->chain_lookup[index].chain_buffer;
+	}
+	pr_info(MPT3SAS_FMT
+	    "Provided chain_buffer_dma address is not in the lookup list\n",
+	    ioc->name);
+	return NULL;
+}
+
+/**
+ * _clone_sg_entries -	MPI EP's scsiio and config requests
+ *			are handled here. Base function for
+ *			double buffering, before submitting
+ *			the requests.
+ *
+ * @ioc: per adapter object.
+ * @mpi_request: mf request pointer.
+ * @smid: system request message index.
+ *
+ * @Returns: Nothing.
+ */
+static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
+		void *mpi_request, u16 smid)
+{
+	Mpi2SGESimple32_t *sgel, *sgel_next;
+	u32  sgl_flags, sge_chain_count = 0;
+	bool is_write = 0;
+	u16 i = 0;
+	void __iomem *buffer_iomem;
+	phys_addr_t buffer_iomem_phys;
+	void __iomem *buff_ptr;
+	phys_addr_t buff_ptr_phys;
+	void __iomem *dst_chain_addr[MCPU_MAX_CHAINS_PER_IO];
+	void *src_chain_addr[MCPU_MAX_CHAINS_PER_IO];
+	phys_addr_t dst_addr_phys;
+	MPI2RequestHeader_t *request_hdr;
+	struct scsi_cmnd *scmd;
+	struct scatterlist *sg_scmd = NULL;
+	int is_scsiio_req = 0;
+
+	request_hdr = (MPI2RequestHeader_t *) mpi_request;
+
+	if (request_hdr->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) {
+		Mpi25SCSIIORequest_t *scsiio_request =
+			(Mpi25SCSIIORequest_t *)mpi_request;
+		sgel = (Mpi2SGESimple32_t *) &scsiio_request->SGL;
+		is_scsiio_req = 1;
+	} else if (request_hdr->Function == MPI2_FUNCTION_CONFIG) {
+		Mpi2ConfigRequest_t  *config_req =
+			(Mpi2ConfigRequest_t *)mpi_request;
+		sgel = (Mpi2SGESimple32_t *) &config_req->PageBufferSGE;
+	} else
+		return;
+
+	/* From smid we can get scsi_cmd, once we have sg_scmd,
+	 * we just need to get sg_virt and sg_next to get virual
+	 * address associated with sgel->Address.
+	 */
+
+	if (is_scsiio_req) {
+		/* Get scsi_cmd using smid */
+		scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
+		if (scmd == NULL) {
+			pr_err(MPT3SAS_FMT "scmd is NULL\n", ioc->name);
+			return;
+		}
+
+		/* Get sg_scmd from scmd provided */
+		sg_scmd = scsi_sglist(scmd);
+	}
+
+	/*
+	 * 0 - 255	System register
+	 * 256 - 4352	MPI Frame. (This is based on maxCredit 32)
+	 * 4352 - 4864	Reply_free pool (512 byte is reserved
+	 *		considering maxCredit 32. Reply need extra
+	 *		room, for mCPU case kept four times of
+	 *		maxCredit).
+	 * 4864 - 17152	SGE chain element. (32cmd * 3 chain of
+	 *		128 byte size = 12288)
+	 * 17152 - x	Host buffer mapped with smid.
+	 *		(Each smid can have 64K Max IO.)
+	 * BAR0+Last 1K MSIX Addr and Data
+	 * Total size in use 2113664 bytes of 4MB BAR0
+	 */
+
+	buffer_iomem = _base_get_buffer_bar0(ioc, smid);
+	buffer_iomem_phys = _base_get_buffer_phys_bar0(ioc, smid);
+
+	buff_ptr = buffer_iomem;
+	buff_ptr_phys = buffer_iomem_phys;
+	WARN_ON(buff_ptr_phys > U32_MAX);
+
+	if (sgel->FlagsLength &
+			(MPI2_SGE_FLAGS_HOST_TO_IOC << MPI2_SGE_FLAGS_SHIFT))
+		is_write = 1;
+
+	for (i = 0; i < MPT_MIN_PHYS_SEGMENTS + ioc->facts.MaxChainDepth; i++) {
+
+		sgl_flags = (sgel->FlagsLength >> MPI2_SGE_FLAGS_SHIFT);
+
+		switch (sgl_flags & MPI2_SGE_FLAGS_ELEMENT_MASK) {
+		case MPI2_SGE_FLAGS_CHAIN_ELEMENT:
+			/*
+			 * Helper function which on passing
+			 * chain_buffer_dma returns chain_buffer. Get
+			 * the virtual address for sgel->Address
+			 */
+			sgel_next =
+				_base_get_chain_buffer_dma_to_chain_buffer(ioc,
+						sgel->Address);
+			if (sgel_next == NULL)
+				return;
+			/*
+			 * This is coping 128 byte chain
+			 * frame (not a host buffer)
+			 */
+			dst_chain_addr[sge_chain_count] =
+				_base_get_chain(ioc,
+					smid, sge_chain_count);
+			src_chain_addr[sge_chain_count] =
+						(void *) sgel_next;
+			dst_addr_phys = _base_get_chain_phys(ioc,
+						smid, sge_chain_count);
+			WARN_ON(dst_addr_phys > U32_MAX);
+			sgel->Address = (u32)dst_addr_phys;
+			sgel = sgel_next;
+			sge_chain_count++;
+			break;
+		case MPI2_SGE_FLAGS_SIMPLE_ELEMENT:
+			if (is_write) {
+				if (is_scsiio_req) {
+					_base_clone_to_sys_mem(buff_ptr,
+					    sg_virt(sg_scmd),
+					    (sgel->FlagsLength & 0x00ffffff));
+					/*
+					 * FIXME: this relies on a a zero
+					 * PCI mem_offset.
+					 */
+					sgel->Address = (u32)buff_ptr_phys;
+				} else {
+					_base_clone_to_sys_mem(buff_ptr,
+					    ioc->config_vaddr,
+					    (sgel->FlagsLength & 0x00ffffff));
+					sgel->Address = (u32)buff_ptr_phys;
+				}
+			}
+			buff_ptr += (sgel->FlagsLength & 0x00ffffff);
+			buff_ptr_phys += (sgel->FlagsLength & 0x00ffffff);
+			if ((sgel->FlagsLength &
+			    (MPI2_SGE_FLAGS_END_OF_BUFFER
+					<< MPI2_SGE_FLAGS_SHIFT)))
+				goto eob_clone_chain;
+			else {
+				/*
+				 * Every single element in MPT will have
+				 * associated sg_next. Better to sanity that
+				 * sg_next is not NULL, but it will be a bug
+				 * if it is null.
+				 */
+				if (is_scsiio_req) {
+					sg_scmd = sg_next(sg_scmd);
+					if (sg_scmd)
+						sgel++;
+					else
+						goto eob_clone_chain;
+				}
+			}
+			break;
+		}
+	}
+
+eob_clone_chain:
+	for (i = 0; i < sge_chain_count; i++) {
+		if (is_scsiio_req)
+			_base_clone_to_sys_mem(dst_chain_addr[i],
+				src_chain_addr[i], ioc->request_sz);
+	}
+}
+
+/**
  *  mpt3sas_remove_dead_ioc_func - kthread context to remove dead ioc
  * @arg: input argument, used to derive ioc
  *
@@ -875,7 +1231,7 @@ _base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
 	ack_request->EventContext = mpi_reply->EventContext;
 	ack_request->VF_ID = 0;  /* TODO */
 	ack_request->VP_ID = 0;
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 
  out:
 
@@ -1075,6 +1431,10 @@ _base_interrupt(int irq, void *bus_id)
 				    0 : ioc->reply_free_host_index + 1;
 				ioc->reply_free[ioc->reply_free_host_index] =
 				    cpu_to_le32(reply);
+				if (ioc->is_mcpu_endpoint)
+					_base_clone_reply_to_sys_mem(ioc,
+						cpu_to_le32(reply),
+						ioc->reply_free_host_index);
 				writel(ioc->reply_free_host_index,
 				    &ioc->chip->ReplyFreeHostIndex);
 			}
@@ -2214,6 +2574,9 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
 	struct sysinfo s;
 	u64 consistent_dma_mask;
 
+	if (ioc->is_mcpu_endpoint)
+		goto try_32bit;
+
 	if (ioc->dma_mask)
 		consistent_dma_mask = DMA_BIT_MASK(64);
 	else
@@ -2232,6 +2595,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
 		}
 	}
 
+ try_32bit:
 	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
 	    && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		ioc->base_add_sg_single = &_base_add_sg_single_32;
@@ -2581,7 +2945,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
 	u32 pio_sz;
 	int i, r = 0;
 	u64 pio_chip = 0;
-	u64 chip_phys = 0;
+	phys_addr_t chip_phys = 0;
 	struct adapter_reply_queue *reply_q;
 
 	dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n",
@@ -2629,7 +2993,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
 			if (memap_sz)
 				continue;
 			ioc->chip_phys = pci_resource_start(pdev, i);
-			chip_phys = (u64)ioc->chip_phys;
+			chip_phys = ioc->chip_phys;
 			memap_sz = pci_resource_len(pdev, i);
 			ioc->chip = ioremap(ioc->chip_phys, memap_sz);
 		}
@@ -2704,8 +3068,8 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
 		    "IO-APIC enabled"),
 		    pci_irq_vector(ioc->pdev, reply_q->msix_index));
 
-	pr_info(MPT3SAS_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n",
-	    ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz);
+	pr_info(MPT3SAS_FMT "iomem(%pap), mapped(0x%p), size(%d)\n",
+	    ioc->name, &chip_phys, ioc->chip, memap_sz);
 	pr_info(MPT3SAS_FMT "ioport(0x%016llx), size(%d)\n",
 	    ioc->name, (unsigned long long)pio_chip, pio_sz);
 
@@ -2961,6 +3325,29 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 }
 
 /**
+ * _base_mpi_ep_writeq - 32 bit write to MMIO
+ * @b: data payload
+ * @addr: address in MMIO space
+ * @writeq_lock: spin lock
+ *
+ * This special handling for MPI EP to take care of 32 bit
+ * environment where its not quarenteed to send the entire word
+ * in one transfer.
+ */
+static inline void
+_base_mpi_ep_writeq(__u64 b, volatile void __iomem *addr,
+					spinlock_t *writeq_lock)
+{
+	unsigned long flags;
+	__u64 data_out = cpu_to_le64(b);
+
+	spin_lock_irqsave(writeq_lock, flags);
+	writel((u32)(data_out), addr);
+	writel((u32)(data_out >> 32), (addr + 4));
+	spin_unlock_irqrestore(writeq_lock, flags);
+}
+
+/**
  * _base_writeq - 64 bit write to MMIO
  * @ioc: per adapter object
  * @b: data payload
@@ -2981,17 +3368,41 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock)
 static inline void
 _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock)
 {
-	unsigned long flags;
-	__u64 data_out = cpu_to_le64(b);
-
-	spin_lock_irqsave(writeq_lock, flags);
-	writel((u32)(data_out), addr);
-	writel((u32)(data_out >> 32), (addr + 4));
-	spin_unlock_irqrestore(writeq_lock, flags);
+	_base_mpi_ep_writeq(b, addr, writeq_lock);
 }
 #endif
 
 /**
+ * _base_put_smid_mpi_ep_scsi_io - send SCSI_IO request to firmware
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @handle: device handle
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_mpi_ep_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle)
+{
+	Mpi2RequestDescriptorUnion_t descriptor;
+	u64 *request = (u64 *)&descriptor;
+	void *mpi_req_iomem;
+	__le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid);
+
+	_clone_sg_entries(ioc, (void *) mfp, smid);
+	mpi_req_iomem = (void *)ioc->chip +
+			MPI_FRAME_START_OFFSET + (smid * ioc->request_sz);
+	_base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp,
+					ioc->request_sz);
+	descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
+	descriptor.SCSIIO.MSIxIndex =  _base_get_msix_index(ioc);
+	descriptor.SCSIIO.SMID = cpu_to_le16(smid);
+	descriptor.SCSIIO.DevHandle = cpu_to_le16(handle);
+	descriptor.SCSIIO.LMID = 0;
+	_base_mpi_ep_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+	    &ioc->scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_scsi_io - send SCSI_IO request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
@@ -3016,15 +3427,15 @@ _base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle)
 }
 
 /**
- * _base_put_smid_fast_path - send fast path request to firmware
+ * mpt3sas_base_put_smid_fast_path - send fast path request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
  * @handle: device handle
  *
  * Return nothing.
  */
-static void
-_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+void
+mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 	u16 handle)
 {
 	Mpi2RequestDescriptorUnion_t descriptor;
@@ -3041,18 +3452,34 @@ _base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 }
 
 /**
- * _base_put_smid_hi_priority - send Task Management request to firmware
+ * mpt3sas_base_put_smid_hi_priority - send Task Management request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
  * @msix_task: msix_task will be same as msix of IO incase of task abort else 0.
  * Return nothing.
  */
-static void
-_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+void
+mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 	u16 msix_task)
 {
 	Mpi2RequestDescriptorUnion_t descriptor;
-	u64 *request = (u64 *)&descriptor;
+	void *mpi_req_iomem;
+	u64 *request;
+
+	if (ioc->is_mcpu_endpoint) {
+		MPI2RequestHeader_t *request_hdr;
+
+		__le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid);
+
+		request_hdr = (MPI2RequestHeader_t *)mfp;
+		/* TBD 256 is offset within sys register. */
+		mpi_req_iomem = (void *)ioc->chip + MPI_FRAME_START_OFFSET
+					+ (smid * ioc->request_sz);
+		_base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp,
+							ioc->request_sz);
+	}
+
+	request = (u64 *)&descriptor;
 
 	descriptor.HighPriority.RequestFlags =
 	    MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
@@ -3060,20 +3487,25 @@ _base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 	descriptor.HighPriority.SMID = cpu_to_le16(smid);
 	descriptor.HighPriority.LMID = 0;
 	descriptor.HighPriority.Reserved1 = 0;
-	_base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
-	    &ioc->scsi_lookup_lock);
+	if (ioc->is_mcpu_endpoint)
+		_base_mpi_ep_writeq(*request,
+				&ioc->chip->RequestDescriptorPostLow,
+				&ioc->scsi_lookup_lock);
+	else
+		_base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+		    &ioc->scsi_lookup_lock);
 }
 
 /**
- * _base_put_smid_nvme_encap - send NVMe encapsulated request to
+ * mpt3sas_base_put_smid_nvme_encap - send NVMe encapsulated request to
  *  firmware
  * @ioc: per adapter object
  * @smid: system request message index
  *
  * Return nothing.
  */
-static void
-_base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+void
+mpt3sas_base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 {
 	Mpi2RequestDescriptorUnion_t descriptor;
 	u64 *request = (u64 *)&descriptor;
@@ -3089,135 +3521,45 @@ _base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 }
 
 /**
- * _base_put_smid_default - Default, primarily used for config pages
+ * mpt3sas_base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
  *
  * Return nothing.
  */
-static void
-_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+void
+mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 {
 	Mpi2RequestDescriptorUnion_t descriptor;
-	u64 *request = (u64 *)&descriptor;
+	void *mpi_req_iomem;
+	u64 *request;
+	MPI2RequestHeader_t *request_hdr;
 
+	if (ioc->is_mcpu_endpoint) {
+		__le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid);
+
+		request_hdr = (MPI2RequestHeader_t *)mfp;
+
+		_clone_sg_entries(ioc, (void *) mfp, smid);
+		/* TBD 256 is offset within sys register */
+		mpi_req_iomem = (void *)ioc->chip +
+			MPI_FRAME_START_OFFSET + (smid * ioc->request_sz);
+		_base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp,
+							ioc->request_sz);
+	}
+	request = (u64 *)&descriptor;
 	descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
 	descriptor.Default.SMID = cpu_to_le16(smid);
 	descriptor.Default.LMID = 0;
 	descriptor.Default.DescriptorTypeDependent = 0;
-	_base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
-	    &ioc->scsi_lookup_lock);
-}
-
-/**
-* _base_put_smid_scsi_io_atomic - send SCSI_IO request to firmware using
-*   Atomic Request Descriptor
-* @ioc: per adapter object
-* @smid: system request message index
-* @handle: device handle, unused in this function, for function type match
-*
-* Return nothing.
-*/
-static void
-_base_put_smid_scsi_io_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
-	u16 handle)
-{
-	Mpi26AtomicRequestDescriptor_t descriptor;
-	u32 *request = (u32 *)&descriptor;
-
-	descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
-	descriptor.MSIxIndex = _base_get_msix_index(ioc);
-	descriptor.SMID = cpu_to_le16(smid);
-
-	writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
-}
-
-/**
- * _base_put_smid_fast_path_atomic - send fast path request to firmware
- * using Atomic Request Descriptor
- * @ioc: per adapter object
- * @smid: system request message index
- * @handle: device handle, unused in this function, for function type match
- * Return nothing
- */
-static void
-_base_put_smid_fast_path_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
-	u16 handle)
-{
-	Mpi26AtomicRequestDescriptor_t descriptor;
-	u32 *request = (u32 *)&descriptor;
-
-	descriptor.RequestFlags = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
-	descriptor.MSIxIndex = _base_get_msix_index(ioc);
-	descriptor.SMID = cpu_to_le16(smid);
-
-	writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
-}
-
-/**
- * _base_put_smid_hi_priority_atomic - send Task Management request to
- * firmware using Atomic Request Descriptor
- * @ioc: per adapter object
- * @smid: system request message index
- * @msix_task: msix_task will be same as msix of IO incase of task abort else 0
- *
- * Return nothing.
- */
-static void
-_base_put_smid_hi_priority_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
-	u16 msix_task)
-{
-	Mpi26AtomicRequestDescriptor_t descriptor;
-	u32 *request = (u32 *)&descriptor;
-
-	descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
-	descriptor.MSIxIndex = msix_task;
-	descriptor.SMID = cpu_to_le16(smid);
-
-	writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
-}
-
-/**
- * _base_put_smid_nvme_encap_atomic - send NVMe encapsulated request to
- *   firmware using Atomic Request Descriptor
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Return nothing.
- */
-static void
-_base_put_smid_nvme_encap_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid)
-{
-	Mpi26AtomicRequestDescriptor_t descriptor;
-	u32 *request = (u32 *)&descriptor;
-
-	descriptor.RequestFlags = MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
-	descriptor.MSIxIndex = _base_get_msix_index(ioc);
-	descriptor.SMID = cpu_to_le16(smid);
-
-	writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
-}
-
-/**
- * _base_put_smid_default - Default, primarily used for config pages
- * use Atomic Request Descriptor
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Return nothing.
- */
-static void
-_base_put_smid_default_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid)
-{
-	Mpi26AtomicRequestDescriptor_t descriptor;
-	u32 *request = (u32 *)&descriptor;
-
-	descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
-	descriptor.MSIxIndex = _base_get_msix_index(ioc);
-	descriptor.SMID = cpu_to_le16(smid);
-
-	writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+	if (ioc->is_mcpu_endpoint)
+		_base_mpi_ep_writeq(*request,
+				&ioc->chip->RequestDescriptorPostLow,
+				&ioc->scsi_lookup_lock);
+	else
+		_base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+				&ioc->scsi_lookup_lock);
 }
 
 /**
@@ -3890,17 +4232,21 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 		sg_tablesize = min_t(unsigned short, sg_tablesize,
 		   MPT_KDUMP_MIN_PHYS_SEGMENTS);
 
-	if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS)
-		sg_tablesize = MPT_MIN_PHYS_SEGMENTS;
-	else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) {
-		sg_tablesize = min_t(unsigned short, sg_tablesize,
-				      SG_MAX_SEGMENTS);
-		pr_warn(MPT3SAS_FMT
-		 "sg_tablesize(%u) is bigger than kernel"
-		 " defined SG_CHUNK_SIZE(%u)\n", ioc->name,
-		 sg_tablesize, MPT_MAX_PHYS_SEGMENTS);
+	if (ioc->is_mcpu_endpoint)
+		ioc->shost->sg_tablesize = MPT_MIN_PHYS_SEGMENTS;
+	else {
+		if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS)
+			sg_tablesize = MPT_MIN_PHYS_SEGMENTS;
+		else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) {
+			sg_tablesize = min_t(unsigned short, sg_tablesize,
+					SG_MAX_SEGMENTS);
+			pr_warn(MPT3SAS_FMT
+				"sg_tablesize(%u) is bigger than kernel "
+				"defined SG_CHUNK_SIZE(%u)\n", ioc->name,
+				sg_tablesize, MPT_MAX_PHYS_SEGMENTS);
+		}
+		ioc->shost->sg_tablesize = sg_tablesize;
 	}
-	ioc->shost->sg_tablesize = sg_tablesize;
 
 	ioc->internal_depth = min_t(int, (facts->HighPriorityCredit + (5)),
 		(facts->RequestCredit / 4));
@@ -3985,13 +4331,18 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 	/* reply free queue sizing - taking into account for 64 FW events */
 	ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
 
-	/* calculate reply descriptor post queue depth */
-	ioc->reply_post_queue_depth = ioc->hba_queue_depth +
-				ioc->reply_free_queue_depth +  1 ;
-	/* align the reply post queue on the next 16 count boundary */
-	if (ioc->reply_post_queue_depth % 16)
-		ioc->reply_post_queue_depth += 16 -
-		(ioc->reply_post_queue_depth % 16);
+	/* mCPU manage single counters for simplicity */
+	if (ioc->is_mcpu_endpoint)
+		ioc->reply_post_queue_depth = ioc->reply_free_queue_depth;
+	else {
+		/* calculate reply descriptor post queue depth */
+		ioc->reply_post_queue_depth = ioc->hba_queue_depth +
+			ioc->reply_free_queue_depth +  1;
+		/* align the reply post queue on the next 16 count boundary */
+		if (ioc->reply_post_queue_depth % 16)
+			ioc->reply_post_queue_depth += 16 -
+				(ioc->reply_post_queue_depth % 16);
+	}
 
 	if (ioc->reply_post_queue_depth >
 	    facts->MaxReplyDescriptorPostQueueDepth) {
@@ -4789,7 +5140,7 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc,
 	    mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET)
 		ioc->ioc_link_reset_in_progress = 1;
 	init_completion(&ioc->base_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->base_cmds.done,
 	    msecs_to_jiffies(10000));
 	if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
@@ -4889,7 +5240,7 @@ mpt3sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc,
 	ioc->base_cmds.smid = smid;
 	memcpy(request, mpi_request, sizeof(Mpi2SepReply_t));
 	init_completion(&ioc->base_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->base_cmds.done,
 	    msecs_to_jiffies(10000));
 	if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) {
@@ -5074,8 +5425,6 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc)
 	if ((facts->IOCCapabilities &
 	      MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE) && (!reset_devices))
 		ioc->rdpq_array_capable = 1;
-	if (facts->IOCCapabilities & MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ)
-		ioc->atomic_desc_capable = 1;
 	facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word);
 	facts->IOCRequestFrameSize =
 	    le16_to_cpu(mpi_reply.IOCRequestFrameSize);
@@ -5317,7 +5666,7 @@ _base_send_port_enable(struct MPT3SAS_ADAPTER *ioc)
 	mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
 
 	init_completion(&ioc->port_enable_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->port_enable_cmds.done, 300*HZ);
 	if (!(ioc->port_enable_cmds.status & MPT3_CMD_COMPLETE)) {
 		pr_err(MPT3SAS_FMT "%s: timeout\n",
@@ -5380,7 +5729,7 @@ mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc)
 	memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
 	mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
 
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	return 0;
 }
 
@@ -5499,7 +5848,7 @@ _base_event_notification(struct MPT3SAS_ADAPTER *ioc)
 		mpi_request->EventMasks[i] =
 		    cpu_to_le32(ioc->event_masks[i]);
 	init_completion(&ioc->base_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ);
 	if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) {
 		pr_err(MPT3SAS_FMT "%s: timeout\n",
@@ -5819,8 +6168,12 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc)
 	/* initialize Reply Free Queue */
 	for (i = 0, reply_address = (u32)ioc->reply_dma ;
 	    i < ioc->reply_free_queue_depth ; i++, reply_address +=
-	    ioc->reply_sz)
+	    ioc->reply_sz) {
 		ioc->reply_free[i] = cpu_to_le32(reply_address);
+		if (ioc->is_mcpu_endpoint)
+			_base_clone_reply_to_sys_mem(ioc,
+					(__le32)reply_address, i);
+	}
 
 	/* initialize reply queues */
 	if (ioc->is_driver_loading)
@@ -6009,20 +6362,10 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
 		break;
 	}
 
-	if (ioc->atomic_desc_capable) {
-		ioc->put_smid_default = &_base_put_smid_default_atomic;
-		ioc->put_smid_scsi_io = &_base_put_smid_scsi_io_atomic;
-		ioc->put_smid_fast_path = &_base_put_smid_fast_path_atomic;
-		ioc->put_smid_hi_priority = &_base_put_smid_hi_priority_atomic;
-		ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap_atomic;
-	} else {
-		ioc->put_smid_default = &_base_put_smid_default;
+	if (ioc->is_mcpu_endpoint)
+		ioc->put_smid_scsi_io = &_base_put_smid_mpi_ep_scsi_io;
+	else
 		ioc->put_smid_scsi_io = &_base_put_smid_scsi_io;
-		ioc->put_smid_fast_path = &_base_put_smid_fast_path;
-		ioc->put_smid_hi_priority = &_base_put_smid_hi_priority;
-		ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap;
-	}
-
 
 	/*
 	 * These function pointers for other requests that don't
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 99ccf83..ae36d8f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -95,6 +95,8 @@
 #define MPT_MIN_PHYS_SEGMENTS	16
 #define MPT_KDUMP_MIN_PHYS_SEGMENTS	32
 
+#define MCPU_MAX_CHAINS_PER_IO	3
+
 #ifdef CONFIG_SCSI_MPT3SAS_MAX_SGE
 #define MPT3SAS_SG_DEPTH		CONFIG_SCSI_MPT3SAS_MAX_SGE
 #else
@@ -120,6 +122,8 @@
 #define MPT3SAS_NVME_QUEUE_DEPTH	128
 #define MPT_NAME_LENGTH			32	/* generic length of strings */
 #define MPT_STRING_LENGTH		64
+#define MPI_FRAME_START_OFFSET		256
+#define REPLY_FREE_POOL_SIZE		512 /*(32 maxcredix *4)*(4 times)*/
 
 #define MPT_MAX_CALLBACKS		32
 
@@ -1099,7 +1103,7 @@ struct MPT3SAS_ADAPTER {
 	char		tmp_string[MPT_STRING_LENGTH];
 	struct pci_dev	*pdev;
 	Mpi2SystemInterfaceRegs_t __iomem *chip;
-	resource_size_t	chip_phys;
+	phys_addr_t	chip_phys;
 	int		logging_level;
 	int		fwfault_debug;
 	u8		ir_firmware;
@@ -1236,6 +1240,7 @@ struct MPT3SAS_ADAPTER {
 	u16		config_page_sz;
 	void		*config_page;
 	dma_addr_t	config_page_dma;
+	void		*config_vaddr;
 
 	/* scsiio request */
 	u16		hba_queue_depth;
@@ -1336,6 +1341,7 @@ struct MPT3SAS_ADAPTER {
 	u32		ring_buffer_offset;
 	u32		ring_buffer_sz;
 	u8		is_warpdrive;
+	u8		is_mcpu_endpoint;
 	u8		hide_ir_msg;
 	u8		mfg_pg10_hide_flag;
 	u8		hide_drives;
@@ -1348,12 +1354,7 @@ struct MPT3SAS_ADAPTER {
 	void		*device_remove_in_progress;
 	u16		device_remove_in_progress_sz;
 	u8		is_gen35_ioc;
-	u8		atomic_desc_capable;
 	PUT_SMID_IO_FP_HIP put_smid_scsi_io;
-	PUT_SMID_IO_FP_HIP put_smid_fast_path;
-	PUT_SMID_IO_FP_HIP put_smid_hi_priority;
-	PUT_SMID_DEFAULT put_smid_default;
-	PUT_SMID_DEFAULT put_smid_nvme_encap;
 
 };
 
@@ -1394,6 +1395,12 @@ void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 dma_addr_t mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
 
+void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+	u16 handle);
+void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+	u16 msix_task);
+void mpt3sas_base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid);
+void mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 /* hi-priority queue */
 u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx);
 u16 mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c
index 1c747cf4..e87c76a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -219,6 +219,7 @@ _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
 		mem->page = ioc->config_page;
 		mem->page_dma = ioc->config_page_dma;
 	}
+	ioc->config_vaddr = mem->page;
 	return r;
 }
 
@@ -402,7 +403,7 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
 	memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
 	_config_display_some_debug(ioc, smid, "config_request", NULL);
 	init_completion(&ioc->config_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
 	if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
 		pr_err(MPT3SAS_FMT "%s: timeout\n",
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 523971a..d3cb387 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -820,7 +820,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 			ret = -EINVAL;
 			goto out;
 		}
-		ioc->put_smid_nvme_encap(ioc, smid);
+		mpt3sas_base_put_smid_nvme_encap(ioc, smid);
 		break;
 	}
 	case MPI2_FUNCTION_SCSI_IO_REQUEST:
@@ -845,7 +845,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 		if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)
 			ioc->put_smid_scsi_io(ioc, smid, device_handle);
 		else
-			ioc->put_smid_default(ioc, smid);
+			mpt3sas_base_put_smid_default(ioc, smid);
 		break;
 	}
 	case MPI2_FUNCTION_SCSI_TASK_MGMT:
@@ -882,7 +882,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 		    tm_request->DevHandle));
 		ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
 		    data_in_dma, data_in_sz);
-		ioc->put_smid_hi_priority(ioc, smid, 0);
+		mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
 		break;
 	}
 	case MPI2_FUNCTION_SMP_PASSTHROUGH:
@@ -913,7 +913,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 		}
 		ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,
 		    data_in_sz);
-		ioc->put_smid_default(ioc, smid);
+		mpt3sas_base_put_smid_default(ioc, smid);
 		break;
 	}
 	case MPI2_FUNCTION_SATA_PASSTHROUGH:
@@ -928,7 +928,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 		}
 		ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,
 		    data_in_sz);
-		ioc->put_smid_default(ioc, smid);
+		mpt3sas_base_put_smid_default(ioc, smid);
 		break;
 	}
 	case MPI2_FUNCTION_FW_DOWNLOAD:
@@ -936,7 +936,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 	{
 		ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,
 		    data_in_sz);
-		ioc->put_smid_default(ioc, smid);
+		mpt3sas_base_put_smid_default(ioc, smid);
 		break;
 	}
 	case MPI2_FUNCTION_TOOLBOX:
@@ -951,7 +951,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 			ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
 				data_in_dma, data_in_sz);
 		}
-		ioc->put_smid_default(ioc, smid);
+		mpt3sas_base_put_smid_default(ioc, smid);
 		break;
 	}
 	case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
@@ -970,7 +970,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 	default:
 		ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
 		    data_in_dma, data_in_sz);
-		ioc->put_smid_default(ioc, smid);
+		mpt3sas_base_put_smid_default(ioc, smid);
 		break;
 	}
 
@@ -1601,7 +1601,7 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
 			cpu_to_le32(ioc->product_specific[buffer_type][i]);
 
 	init_completion(&ioc->ctl_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->ctl_cmds.done,
 	    MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
 
@@ -1948,7 +1948,7 @@ mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type,
 	mpi_request->VP_ID = 0;
 
 	init_completion(&ioc->ctl_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->ctl_cmds.done,
 	    MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
 
@@ -2215,7 +2215,7 @@ _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
 	mpi_request->VP_ID = 0;
 
 	init_completion(&ioc->ctl_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->ctl_cmds.done,
 	    MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index a1cb023..8cd3782 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2352,7 +2352,7 @@ scsih_slave_configure(struct scsi_device *sdev)
 		 ** merged and can eliminate holes created during merging
 		 ** operation.
 		 **/
-		queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES,
+		blk_queue_flag_set(QUEUE_FLAG_NOMERGES,
 				sdev->request_queue);
 		blk_queue_virt_boundary(sdev->request_queue,
 				ioc->page_size - 1);
@@ -2679,7 +2679,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 	int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
 	mpt3sas_scsih_set_tm_flag(ioc, handle);
 	init_completion(&ioc->tm_cmds.done);
-	ioc->put_smid_hi_priority(ioc, smid, msix_task);
+	mpt3sas_base_put_smid_hi_priority(ioc, smid, msix_task);
 	wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
 	if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) {
 		pr_err(MPT3SAS_FMT "%s: timeout\n",
@@ -3641,7 +3641,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	mpi_request->DevHandle = cpu_to_le16(handle);
 	mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
 	set_bit(handle, ioc->device_remove_in_progress);
-	ioc->put_smid_hi_priority(ioc, smid, 0);
+	mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
 	mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
 
 out:
@@ -3742,7 +3742,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
 	mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
 	mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
 	mpi_request->DevHandle = mpi_request_tm->DevHandle;
-	ioc->put_smid_default(ioc, smid_sas_ctrl);
+	mpt3sas_base_put_smid_default(ioc, smid_sas_ctrl);
 
 	return _scsih_check_for_pending_tm(ioc, smid);
 }
@@ -3837,7 +3837,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
 	mpi_request->DevHandle = cpu_to_le16(handle);
 	mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-	ioc->put_smid_hi_priority(ioc, smid, 0);
+	mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
 }
 
 /**
@@ -3929,7 +3929,7 @@ _scsih_issue_delayed_event_ack(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 event,
 	ack_request->EventContext = event_context;
 	ack_request->VF_ID = 0;  /* TODO */
 	ack_request->VP_ID = 0;
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 }
 
 /**
@@ -3986,7 +3986,7 @@ _scsih_issue_delayed_sas_io_unit_ctrl(struct MPT3SAS_ADAPTER *ioc,
 	mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
 	mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
 	mpi_request->DevHandle = handle;
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 }
 
 /**
@@ -4715,12 +4715,12 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 		if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) {
 			mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len |
 			    MPI25_SCSIIO_IOFLAGS_FAST_PATH);
-			ioc->put_smid_fast_path(ioc, smid, handle);
+			mpt3sas_base_put_smid_fast_path(ioc, smid, handle);
 		} else
 			ioc->put_smid_scsi_io(ioc, smid,
 			    le16_to_cpu(mpi_request->DevHandle));
 	} else
-		ioc->put_smid_default(ioc, smid);
+		mpt3sas_base_put_smid_default(ioc, smid);
 	return 0;
 
  out:
@@ -7609,7 +7609,7 @@ _scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num)
 	    handle, phys_disk_num));
 
 	init_completion(&ioc->scsih_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
 
 	if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) {
@@ -9700,7 +9700,7 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
 	if (!ioc->hide_ir_msg)
 		pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name);
 	init_completion(&ioc->scsih_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
 
 	if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) {
@@ -10346,6 +10346,7 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev)
 	case MPI2_MFGPAGE_DEVID_SAS2308_1:
 	case MPI2_MFGPAGE_DEVID_SAS2308_2:
 	case MPI2_MFGPAGE_DEVID_SAS2308_3:
+	case MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP:
 		return MPI2_VERSION;
 	case MPI25_MFGPAGE_DEVID_SAS3004:
 	case MPI25_MFGPAGE_DEVID_SAS3008:
@@ -10423,11 +10424,18 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 		ioc->hba_mpi_version_belonged = hba_mpi_version;
 		ioc->id = mpt2_ids++;
 		sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME);
-		if (pdev->device == MPI2_MFGPAGE_DEVID_SSS6200) {
+		switch (pdev->device) {
+		case MPI2_MFGPAGE_DEVID_SSS6200:
 			ioc->is_warpdrive = 1;
 			ioc->hide_ir_msg = 1;
-		} else
+			break;
+		case MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP:
+			ioc->is_mcpu_endpoint = 1;
+			break;
+		default:
 			ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
+			break;
+		}
 		break;
 	case MPI25_VERSION:
 	case MPI26_VERSION:
@@ -10524,26 +10532,34 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	shost->transportt = mpt3sas_transport_template;
 	shost->unique_id = ioc->id;
 
-	if (max_sectors != 0xFFFF) {
-		if (max_sectors < 64) {
-			shost->max_sectors = 64;
-			pr_warn(MPT3SAS_FMT "Invalid value %d passed " \
-			    "for max_sectors, range is 64 to 32767. Assigning "
-			    "value of 64.\n", ioc->name, max_sectors);
-		} else if (max_sectors > 32767) {
-			shost->max_sectors = 32767;
-			pr_warn(MPT3SAS_FMT "Invalid value %d passed " \
-			    "for max_sectors, range is 64 to 32767. Assigning "
-			    "default value of 32767.\n", ioc->name,
-			    max_sectors);
-		} else {
-			shost->max_sectors = max_sectors & 0xFFFE;
-			pr_info(MPT3SAS_FMT
+	if (ioc->is_mcpu_endpoint) {
+		/* mCPU MPI support 64K max IO */
+		shost->max_sectors = 128;
+		pr_info(MPT3SAS_FMT
 				"The max_sectors value is set to %d\n",
 				ioc->name, shost->max_sectors);
+	} else {
+		if (max_sectors != 0xFFFF) {
+			if (max_sectors < 64) {
+				shost->max_sectors = 64;
+				pr_warn(MPT3SAS_FMT "Invalid value %d passed " \
+				    "for max_sectors, range is 64 to 32767. " \
+				    "Assigning value of 64.\n", \
+				    ioc->name, max_sectors);
+			} else if (max_sectors > 32767) {
+				shost->max_sectors = 32767;
+				pr_warn(MPT3SAS_FMT "Invalid value %d passed " \
+				    "for max_sectors, range is 64 to 32767." \
+				    "Assigning default value of 32767.\n", \
+				    ioc->name, max_sectors);
+			} else {
+				shost->max_sectors = max_sectors & 0xFFFE;
+				pr_info(MPT3SAS_FMT
+					"The max_sectors value is set to %d\n",
+					ioc->name, shost->max_sectors);
+			}
 		}
 	}
-
 	/* register EEDP capabilities with SCSI layer */
 	if (prot_mask > 0)
 		scsi_host_set_prot(shost, prot_mask);
@@ -10856,6 +10872,8 @@ static const struct pci_device_id mpt3sas_pci_table[] = {
 		PCI_ANY_ID, PCI_ANY_ID },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
 		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP,
+		PCI_ANY_ID, PCI_ANY_ID },
 	/* SSS6200 */
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
 		PCI_ANY_ID, PCI_ANY_ID },
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index d3940c5..3a143bb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -392,7 +392,7 @@ _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc,
 		"report_manufacture - send to sas_addr(0x%016llx)\n",
 		ioc->name, (unsigned long long)sas_address));
 	init_completion(&ioc->transport_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
 
 	if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
@@ -1198,7 +1198,7 @@ _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc,
 		ioc->name, (unsigned long long)phy->identify.sas_address,
 		phy->number));
 	init_completion(&ioc->transport_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
 
 	if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
@@ -1514,7 +1514,7 @@ _transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc,
 		ioc->name, (unsigned long long)phy->identify.sas_address,
 		phy->number, phy_operation));
 	init_completion(&ioc->transport_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
 
 	if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
@@ -2014,7 +2014,7 @@ _transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
 		"%s - sending smp request\n", ioc->name, __func__));
 
 	init_completion(&ioc->transport_cmds.done);
-	ioc->put_smid_default(ioc, smid);
+	mpt3sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
 
 	if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index e6b2b68..7d1ab41 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -3,6 +3,9 @@
 #include <linux/mm.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -14,9 +17,6 @@
 #include "wd33c93.h"
 #include "mvme147.h"
 
-#include <linux/stat.h>
-
-
 static irqreturn_t mvme147_intr(int irq, void *data)
 {
 	struct Scsi_Host *instance = data;
@@ -65,40 +65,57 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
 	m147_pcc->dma_cntrl = 0;
 }
 
-int mvme147_detect(struct scsi_host_template *tpnt)
+static struct scsi_host_template mvme147_host_template = {
+	.module			= THIS_MODULE,
+	.proc_name		= "MVME147",
+	.name			= "MVME147 built-in SCSI",
+	.queuecommand		= wd33c93_queuecommand,
+	.eh_abort_handler	= wd33c93_abort,
+	.eh_host_reset_handler	= wd33c93_host_reset,
+	.show_info		= wd33c93_show_info,
+	.write_info		= wd33c93_write_info,
+	.can_queue		= CAN_QUEUE,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= CMD_PER_LUN,
+	.use_clustering		= ENABLE_CLUSTERING
+};
+
+static struct Scsi_Host *mvme147_shost;
+
+static int __init mvme147_init(void)
 {
-	static unsigned char called = 0;
-	struct Scsi_Host *instance;
 	wd33c93_regs regs;
 	struct WD33C93_hostdata *hdata;
+	int error = -ENOMEM;
 
-	if (!MACH_IS_MVME147 || called)
+	if (!MACH_IS_MVME147)
 		return 0;
-	called++;
 
-	tpnt->proc_name = "MVME147";
-	tpnt->show_info = wd33c93_show_info,
-	tpnt->write_info = wd33c93_write_info,
-
-	instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
-	if (!instance)
+	mvme147_shost = scsi_host_alloc(&mvme147_host_template,
+			sizeof(struct WD33C93_hostdata));
+	if (!mvme147_shost)
 		goto err_out;
+	mvme147_shost->base = 0xfffe4000;
+	mvme147_shost->irq = MVME147_IRQ_SCSI_PORT;
 
-	instance->base = 0xfffe4000;
-	instance->irq = MVME147_IRQ_SCSI_PORT;
 	regs.SASR = (volatile unsigned char *)0xfffe4000;
 	regs.SCMD = (volatile unsigned char *)0xfffe4001;
-	hdata = shost_priv(instance);
+
+	hdata = shost_priv(mvme147_shost);
 	hdata->no_sync = 0xff;
 	hdata->fast = 0;
 	hdata->dma_mode = CTRL_DMA;
-	wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
 
-	if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
-			"MVME147 SCSI PORT", instance))
+	wd33c93_init(mvme147_shost, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
+
+	error = request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
+			"MVME147 SCSI PORT", mvme147_shost);
+	if (error)
 		goto err_unregister;
-	if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
-			"MVME147 SCSI DMA", instance))
+	error = request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
+			"MVME147 SCSI DMA", mvme147_shost);
+	if (error)
 		goto err_free_irq;
 #if 0	/* Disabled; causes problems booting */
 	m147_pcc->scsi_interrupt = 0x10;	/* Assert SCSI bus reset */
@@ -112,40 +129,30 @@ int mvme147_detect(struct scsi_host_template *tpnt)
 	m147_pcc->dma_cntrl = 0x00;	/* ensure DMA is stopped */
 	m147_pcc->dma_intr = 0x89;	/* Ack and enable ints */
 
-	return 1;
+	error = scsi_add_host(mvme147_shost, NULL);
+	if (error)
+		goto err_free_irq;
+	scsi_scan_host(mvme147_shost);
+	return 0;
 
 err_free_irq:
-	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr);
+	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost);
 err_unregister:
-	scsi_unregister(instance);
+	scsi_host_put(mvme147_shost);
 err_out:
-	return 0;
+	return error;
 }
 
-static struct scsi_host_template driver_template = {
-	.proc_name		= "MVME147",
-	.name			= "MVME147 built-in SCSI",
-	.detect			= mvme147_detect,
-	.release		= mvme147_release,
-	.queuecommand		= wd33c93_queuecommand,
-	.eh_abort_handler	= wd33c93_abort,
-	.eh_host_reset_handler	= wd33c93_host_reset,
-	.can_queue		= CAN_QUEUE,
-	.this_id		= 7,
-	.sg_tablesize		= SG_ALL,
-	.cmd_per_lun		= CMD_PER_LUN,
-	.use_clustering		= ENABLE_CLUSTERING
-};
-
-
-#include "scsi_module.c"
-
-int mvme147_release(struct Scsi_Host *instance)
+static void __exit mvme147_exit(void)
 {
-#ifdef MODULE
+	scsi_remove_host(mvme147_shost);
+
 	/* XXX Make sure DMA is stopped! */
-	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr);
-	free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr);
-#endif
-	return 1;
+	free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost);
+	free_irq(MVME147_IRQ_SCSI_DMA, mvme147_shost);
+
+	scsi_host_put(mvme147_shost);
 }
+
+module_init(mvme147_init);
+module_exit(mvme147_exit);
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c
index 7de5d8d..eb5471b 100644
--- a/drivers/scsi/mvsas/mv_94xx.c
+++ b/drivers/scsi/mvsas/mv_94xx.c
@@ -1080,16 +1080,16 @@ static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv,
 			void __iomem *regs = mvi->regs_ex - 0x10200;
 
 			int drive = (i/3) & (4-1); /* drive number on host */
-			u32 block = mr32(MVS_SGPIO_DCTRL +
+			int driveshift = drive * 8; /* bit offset of drive */
+			u32 block = ioread32be(regs + MVS_SGPIO_DCTRL +
 				MVS_SGPIO_HOST_OFFSET * mvi->id);
 
-
 			/*
 			* if bit is set then create a mask with the first
 			* bit of the drive set in the mask ...
 			*/
-			u32 bit = (write_data[i/8] & (1 << (i&(8-1)))) ?
-				1<<(24-drive*8) : 0;
+			u32 bit = get_unaligned_be32(write_data) & (1 << i) ?
+				1 << driveshift : 0;
 
 			/*
 			* ... and then shift it to the right position based
@@ -1098,26 +1098,27 @@ static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv,
 			switch (i%3) {
 			case 0: /* activity */
 				block &= ~((0x7 << MVS_SGPIO_DCTRL_ACT_SHIFT)
-					<< (24-drive*8));
+					<< driveshift);
 					/* hardwire activity bit to SOF */
 				block |= LED_BLINKA_SOF << (
 					MVS_SGPIO_DCTRL_ACT_SHIFT +
-					(24-drive*8));
+					driveshift);
 				break;
 			case 1: /* id */
 				block &= ~((0x3 << MVS_SGPIO_DCTRL_LOC_SHIFT)
-					<< (24-drive*8));
+					<< driveshift);
 				block |= bit << MVS_SGPIO_DCTRL_LOC_SHIFT;
 				break;
 			case 2: /* fail */
 				block &= ~((0x7 << MVS_SGPIO_DCTRL_ERR_SHIFT)
-					<< (24-drive*8));
+					<< driveshift);
 				block |= bit << MVS_SGPIO_DCTRL_ERR_SHIFT;
 				break;
 			}
 
-			mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
-				block);
+			iowrite32be(block,
+				regs + MVS_SGPIO_DCTRL +
+				MVS_SGPIO_HOST_OFFSET * mvi->id);
 
 		}
 
@@ -1132,7 +1133,7 @@ static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv,
 			void __iomem *regs = mvi->regs_ex - 0x10200;
 
 			mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
-				be32_to_cpu(((u32 *) write_data)[i]));
+				((u32 *) write_data)[i]);
 		}
 		return reg_count;
 	}
diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig
index ecc855c..2d435f1 100644
--- a/drivers/scsi/pcmcia/Kconfig
+++ b/drivers/scsi/pcmcia/Kconfig
@@ -19,15 +19,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called aha152x_cs.
 
-config PCMCIA_FDOMAIN
-	tristate "Future Domain PCMCIA support"
-	help
-	  Say Y here if you intend to attach this type of PCMCIA SCSI host
-	  adapter to your computer.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called fdomain_cs.
-
 config PCMCIA_NINJA_SCSI
 	tristate "NinjaSCSI-3 / NinjaSCSI-32Bi (16bit) PCMCIA support"
 	depends on !64BIT
diff --git a/drivers/scsi/pcmcia/Makefile b/drivers/scsi/pcmcia/Makefile
index 44eea2d..faa87a4 100644
--- a/drivers/scsi/pcmcia/Makefile
+++ b/drivers/scsi/pcmcia/Makefile
@@ -4,11 +4,9 @@
 
 # 16-bit client drivers
 obj-$(CONFIG_PCMCIA_QLOGIC)	+= qlogic_cs.o
-obj-$(CONFIG_PCMCIA_FDOMAIN)	+= fdomain_cs.o
 obj-$(CONFIG_PCMCIA_AHA152X)	+= aha152x_cs.o
 obj-$(CONFIG_PCMCIA_NINJA_SCSI)	+= nsp_cs.o
 obj-$(CONFIG_PCMCIA_SYM53C500)	+= sym53c500_cs.o
 
 aha152x_cs-objs	:= aha152x_stub.o aha152x_core.o
-fdomain_cs-objs	:= fdomain_stub.o fdomain_core.o
 qlogic_cs-objs	:= qlogic_stub.o
diff --git a/drivers/scsi/pcmcia/fdomain_core.c b/drivers/scsi/pcmcia/fdomain_core.c
deleted file mode 100644
index a489137..0000000
--- a/drivers/scsi/pcmcia/fdomain_core.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define PCMCIA 1
-#include "fdomain.c"
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
deleted file mode 100644
index 953a792..0000000
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*======================================================================
-
-    A driver for Future Domain-compatible PCMCIA SCSI cards
-
-    fdomain_cs.c 1.47 2001/10/13 00:08:52
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in
-    which case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <scsi/scsi.h>
-#include <linux/major.h>
-#include <linux/blkdev.h>
-#include <scsi/scsi_ioctl.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "fdomain.h"
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-/*====================================================================*/
-
-/* Module parameters */
-
-MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
-MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
-MODULE_LICENSE("Dual MPL/GPL");
-
-/*====================================================================*/
-
-typedef struct scsi_info_t {
-	struct pcmcia_device	*p_dev;
-    struct Scsi_Host	*host;
-} scsi_info_t;
-
-
-static void fdomain_release(struct pcmcia_device *link);
-static void fdomain_detach(struct pcmcia_device *p_dev);
-static int fdomain_config(struct pcmcia_device *link);
-
-static int fdomain_probe(struct pcmcia_device *link)
-{
-	scsi_info_t *info;
-
-	dev_dbg(&link->dev, "fdomain_attach()\n");
-
-	/* Create new SCSI device */
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	info->p_dev = link;
-	link->priv = info;
-	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-	link->config_regs = PRESENT_OPTION;
-
-	return fdomain_config(link);
-} /* fdomain_attach */
-
-/*====================================================================*/
-
-static void fdomain_detach(struct pcmcia_device *link)
-{
-	dev_dbg(&link->dev, "fdomain_detach\n");
-
-	fdomain_release(link);
-
-	kfree(link->priv);
-} /* fdomain_detach */
-
-/*====================================================================*/
-
-static int fdomain_config_check(struct pcmcia_device *p_dev, void *priv_data)
-{
-	p_dev->io_lines = 10;
-	p_dev->resource[0]->end = 0x10;
-	p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
-	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
-	return pcmcia_request_io(p_dev);
-}
-
-
-static int fdomain_config(struct pcmcia_device *link)
-{
-    scsi_info_t *info = link->priv;
-    int ret;
-    char str[22];
-    struct Scsi_Host *host;
-
-    dev_dbg(&link->dev, "fdomain_config\n");
-
-    ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
-    if (ret)
-	    goto failed;
-
-    if (!link->irq)
-	    goto failed;
-    ret = pcmcia_enable_device(link);
-    if (ret)
-	    goto failed;
-
-    /* A bad hack... */
-    release_region(link->resource[0]->start, resource_size(link->resource[0]));
-
-    /* Set configuration options for the fdomain driver */
-    sprintf(str, "%d,%d", (unsigned int) link->resource[0]->start, link->irq);
-    fdomain_setup(str);
-
-    host = __fdomain_16x0_detect(&fdomain_driver_template);
-    if (!host) {
-        printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
-	goto failed;
-    }
-
-    if (scsi_add_host(host, NULL))
-	    goto failed;
-    scsi_scan_host(host);
-
-    info->host = host;
-
-    return 0;
-
-failed:
-    fdomain_release(link);
-    return -ENODEV;
-} /* fdomain_config */
-
-/*====================================================================*/
-
-static void fdomain_release(struct pcmcia_device *link)
-{
-	scsi_info_t *info = link->priv;
-
-	dev_dbg(&link->dev, "fdomain_release\n");
-
-	scsi_remove_host(info->host);
-	pcmcia_disable_device(link);
-	scsi_unregister(info->host);
-}
-
-/*====================================================================*/
-
-static int fdomain_resume(struct pcmcia_device *link)
-{
-	fdomain_16x0_host_reset(NULL);
-
-	return 0;
-}
-
-static const struct pcmcia_device_id fdomain_ids[] = {
-	PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20),
-	PCMCIA_DEVICE_PROD_ID1("SCSI PCMCIA Adapter Card", 0x8dacb57e),
-	PCMCIA_DEVICE_PROD_ID12(" SIMPLE TECHNOLOGY Corporation", "SCSI PCMCIA Credit Card Controller", 0x182bdafe, 0xc80d106f),
-	PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, fdomain_ids);
-
-static struct pcmcia_driver fdomain_cs_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "fdomain_cs",
-	.probe		= fdomain_probe,
-	.remove		= fdomain_detach,
-	.id_table       = fdomain_ids,
-	.resume		= fdomain_resume,
-};
-
-static int __init init_fdomain_cs(void)
-{
-	return pcmcia_register_driver(&fdomain_cs_driver);
-}
-
-static void __exit exit_fdomain_cs(void)
-{
-	pcmcia_unregister_driver(&fdomain_cs_driver);
-}
-
-module_init(init_fdomain_cs);
-module_exit(exit_fdomain_cs);
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 201c8de..9553039 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -1025,7 +1025,7 @@ static void pmcraid_get_fwversion_done(struct pmcraid_cmd *cmd)
 static void pmcraid_get_fwversion(struct pmcraid_cmd *cmd)
 {
 	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
-	struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+	struct pmcraid_ioadl_desc *ioadl;
 	struct pmcraid_instance *pinstance = cmd->drv_inst;
 	u16 data_size = sizeof(struct pmcraid_inquiry_data);
 
@@ -3175,7 +3175,7 @@ static int pmcraid_build_ioadl(
 
 	struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
 	struct pmcraid_ioarcb *ioarcb = &(cmd->ioa_cb->ioarcb);
-	struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+	struct pmcraid_ioadl_desc *ioadl;
 
 	u32 length = scsi_bufflen(scsi_cmd);
 
@@ -3225,12 +3225,7 @@ static int pmcraid_build_ioadl(
  */
 static void pmcraid_free_sglist(struct pmcraid_sglist *sglist)
 {
-	int i;
-
-	for (i = 0; i < sglist->num_sg; i++)
-		__free_pages(sg_page(&(sglist->scatterlist[i])),
-			     sglist->order);
-
+	sgl_free_order(sglist->scatterlist, sglist->order);
 	kfree(sglist);
 }
 
@@ -3247,50 +3242,20 @@ static void pmcraid_free_sglist(struct pmcraid_sglist *sglist)
 static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen)
 {
 	struct pmcraid_sglist *sglist;
-	struct scatterlist *scatterlist;
-	struct page *page;
-	int num_elem, i, j;
 	int sg_size;
 	int order;
-	int bsize_elem;
 
 	sg_size = buflen / (PMCRAID_MAX_IOADLS - 1);
 	order = (sg_size > 0) ? get_order(sg_size) : 0;
-	bsize_elem = PAGE_SIZE * (1 << order);
-
-	/* Determine the actual number of sg entries needed */
-	if (buflen % bsize_elem)
-		num_elem = (buflen / bsize_elem) + 1;
-	else
-		num_elem = buflen / bsize_elem;
 
 	/* Allocate a scatter/gather list for the DMA */
-	sglist = kzalloc(sizeof(struct pmcraid_sglist) +
-			 (sizeof(struct scatterlist) * (num_elem - 1)),
-			 GFP_KERNEL);
-
+	sglist = kzalloc(sizeof(struct pmcraid_sglist), GFP_KERNEL);
 	if (sglist == NULL)
 		return NULL;
 
-	scatterlist = sglist->scatterlist;
-	sg_init_table(scatterlist, num_elem);
 	sglist->order = order;
-	sglist->num_sg = num_elem;
-	sg_size = buflen;
-
-	for (i = 0; i < num_elem; i++) {
-		page = alloc_pages(GFP_KERNEL|GFP_DMA|__GFP_ZERO, order);
-		if (!page) {
-			for (j = i - 1; j >= 0; j--)
-				__free_pages(sg_page(&scatterlist[j]), order);
-			kfree(sglist);
-			return NULL;
-		}
-
-		sg_set_page(&scatterlist[i], page,
-			sg_size < bsize_elem ? sg_size : bsize_elem, 0);
-		sg_size -= bsize_elem;
-	}
+	sgl_alloc_order(buflen, order, false,
+			GFP_KERNEL | GFP_DMA | __GFP_ZERO, &sglist->num_sg);
 
 	return sglist;
 }
@@ -5492,7 +5457,7 @@ static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd)
 	struct pmcraid_instance *pinstance = cmd->drv_inst;
 	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
 	__be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN);
-	struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+	struct pmcraid_ioadl_desc *ioadl;
 	u64 timestamp;
 
 	timestamp = ktime_get_real_seconds() * 1000;
@@ -5665,7 +5630,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
 static void pmcraid_querycfg(struct pmcraid_cmd *cmd)
 {
 	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
-	struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+	struct pmcraid_ioadl_desc *ioadl;
 	struct pmcraid_instance *pinstance = cmd->drv_inst;
 	__be32 cfg_table_size = cpu_to_be32(sizeof(struct pmcraid_config_table));
 
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index 8bfac72..754ef30 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -542,8 +542,7 @@ struct pmcraid_sglist {
 	u32 order;
 	u32 num_sg;
 	u32 num_dma_sg;
-	u32 buffer_len;
-	struct scatterlist scatterlist[1];
+	struct scatterlist *scatterlist;
 };
 
 /* page D0 inquiry data of focal point resource */
diff --git a/drivers/scsi/qedf/qedf_dbg.c b/drivers/scsi/qedf/qedf_dbg.c
index e023f5d..bd1cef25 100644
--- a/drivers/scsi/qedf/qedf_dbg.c
+++ b/drivers/scsi/qedf/qedf_dbg.c
@@ -160,7 +160,7 @@ qedf_uevent_emit(struct Scsi_Host *shost, u32 code, char *msg)
 	switch (code) {
 	case QEDF_UEVENT_CODE_GRCDUMP:
 		if (msg)
-			strncpy(event_string, msg, strlen(msg));
+			strscpy(event_string, msg, sizeof(event_string));
 		else
 			sprintf(event_string, "GRCDUMP=%u", shost->host_no);
 		break;
diff --git a/drivers/scsi/qedf/qedf_dbg.h b/drivers/scsi/qedf/qedf_dbg.h
index 50083ca..77c27e8 100644
--- a/drivers/scsi/qedf/qedf_dbg.h
+++ b/drivers/scsi/qedf/qedf_dbg.h
@@ -116,6 +116,14 @@ extern int qedf_create_sysfs_attr(struct Scsi_Host *shost,
 extern void qedf_remove_sysfs_attr(struct Scsi_Host *shost,
 				    struct sysfs_bin_attrs *iter);
 
+struct qedf_debugfs_ops {
+	char *name;
+	struct qedf_list_of_funcs *qedf_funcs;
+};
+
+extern const struct qedf_debugfs_ops qedf_debugfs_ops[];
+extern const struct file_operations qedf_dbg_fops[];
+
 #ifdef CONFIG_DEBUG_FS
 /* DebugFS related code */
 struct qedf_list_of_funcs {
@@ -123,11 +131,6 @@ struct qedf_list_of_funcs {
 	ssize_t (*oper_func)(struct qedf_dbg_ctx *qedf);
 };
 
-struct qedf_debugfs_ops {
-	char *name;
-	struct qedf_list_of_funcs *qedf_funcs;
-};
-
 #define qedf_dbg_fileops(drv, ops) \
 { \
 	.owner  = THIS_MODULE, \
@@ -147,8 +150,8 @@ struct qedf_debugfs_ops {
 }
 
 extern void qedf_dbg_host_init(struct qedf_dbg_ctx *qedf,
-				struct qedf_debugfs_ops *dops,
-				struct file_operations *fops);
+				const struct qedf_debugfs_ops *dops,
+				const struct file_operations *fops);
 extern void qedf_dbg_host_exit(struct qedf_dbg_ctx *qedf);
 extern void qedf_dbg_init(char *drv_name);
 extern void qedf_dbg_exit(void);
diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c
index 2b1ef30..c539a7a 100644
--- a/drivers/scsi/qedf/qedf_debugfs.c
+++ b/drivers/scsi/qedf/qedf_debugfs.c
@@ -23,8 +23,8 @@ static struct dentry *qedf_dbg_root;
  **/
 void
 qedf_dbg_host_init(struct qedf_dbg_ctx *qedf,
-		    struct qedf_debugfs_ops *dops,
-		    struct file_operations *fops)
+		    const struct qedf_debugfs_ops *dops,
+		    const struct file_operations *fops)
 {
 	char host_dirname[32];
 	struct dentry *file_dentry = NULL;
@@ -99,7 +99,7 @@ qedf_dbg_exit(void)
 	qedf_dbg_root = NULL;
 }
 
-struct qedf_debugfs_ops qedf_debugfs_ops[] = {
+const struct qedf_debugfs_ops qedf_debugfs_ops[] = {
 	{ "fp_int", NULL },
 	{ "io_trace", NULL },
 	{ "debug", NULL },
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c
index b15e695..50a50c4 100644
--- a/drivers/scsi/qedf/qedf_io.c
+++ b/drivers/scsi/qedf/qedf_io.c
@@ -917,7 +917,7 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd)
 	struct qedf_ctx *qedf = lport_priv(lport);
 	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
 	struct fc_rport_libfc_priv *rp = rport->dd_data;
-	struct qedf_rport *fcport = rport->dd_data;
+	struct qedf_rport *fcport;
 	struct qedf_ioreq *io_req;
 	int rc = 0;
 	int rval;
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index ccd9a08..284ccb5 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -23,6 +23,7 @@
 #include <linux/if_vlan.h>
 #include <linux/cpu.h>
 #include "qedf.h"
+#include "qedf_dbg.h"
 #include <uapi/linux/pci_regs.h>
 
 const struct qed_fcoe_ops *qed_ops;
@@ -30,9 +31,6 @@ const struct qed_fcoe_ops *qed_ops;
 static int qedf_probe(struct pci_dev *pdev, const struct pci_device_id *id);
 static void qedf_remove(struct pci_dev *pdev);
 
-extern struct qedf_debugfs_ops qedf_debugfs_ops;
-extern struct file_operations qedf_dbg_fops;
-
 /*
  * Driver module parameters.
  */
@@ -3155,8 +3153,8 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	}
 
 #ifdef CONFIG_DEBUG_FS
-	qedf_dbg_host_init(&(qedf->dbg_ctx), &qedf_debugfs_ops,
-			    &qedf_dbg_fops);
+	qedf_dbg_host_init(&(qedf->dbg_ctx), qedf_debugfs_ops,
+			    qedf_dbg_fops);
 #endif
 
 	/* Start LL2 */
diff --git a/drivers/scsi/qedi/qedi_dbg.h b/drivers/scsi/qedi/qedi_dbg.h
index c55572b..0bc9c31 100644
--- a/drivers/scsi/qedi/qedi_dbg.h
+++ b/drivers/scsi/qedi/qedi_dbg.h
@@ -103,7 +103,6 @@ int qedi_create_sysfs_attr(struct Scsi_Host *shost,
 void qedi_remove_sysfs_attr(struct Scsi_Host *shost,
 			    struct sysfs_bin_attrs *iter);
 
-#ifdef CONFIG_DEBUG_FS
 /* DebugFS related code */
 struct qedi_list_of_funcs {
 	char *oper_str;
@@ -134,11 +133,10 @@ struct qedi_debugfs_ops {
 }
 
 void qedi_dbg_host_init(struct qedi_dbg_ctx *qedi,
-			struct qedi_debugfs_ops *dops,
+			const struct qedi_debugfs_ops *dops,
 			const struct file_operations *fops);
 void qedi_dbg_host_exit(struct qedi_dbg_ctx *qedi);
 void qedi_dbg_init(char *drv_name);
 void qedi_dbg_exit(void);
-#endif /* CONFIG_DEBUG_FS */
 
 #endif /* _QEDI_DBG_H_ */
diff --git a/drivers/scsi/qedi/qedi_debugfs.c b/drivers/scsi/qedi/qedi_debugfs.c
index fd8a1ee..fd914ca 100644
--- a/drivers/scsi/qedi/qedi_debugfs.c
+++ b/drivers/scsi/qedi/qedi_debugfs.c
@@ -19,7 +19,7 @@ static struct dentry *qedi_dbg_root;
 
 void
 qedi_dbg_host_init(struct qedi_dbg_ctx *qedi,
-		   struct qedi_debugfs_ops *dops,
+		   const struct qedi_debugfs_ops *dops,
 		   const struct file_operations *fops)
 {
 	char host_dirname[32];
@@ -99,7 +99,7 @@ static struct qedi_list_of_funcs qedi_dbg_do_not_recover_ops[] = {
 	{ NULL, NULL }
 };
 
-struct qedi_debugfs_ops qedi_debugfs_ops[] = {
+const struct qedi_debugfs_ops qedi_debugfs_ops[] = {
 	{ "gbl_ctx", NULL },
 	{ "do_not_recover", qedi_dbg_do_not_recover_ops},
 	{ "io_trace", NULL },
diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c
index d09afe1..25d763a 100644
--- a/drivers/scsi/qedi/qedi_fw.c
+++ b/drivers/scsi/qedi/qedi_fw.c
@@ -1882,7 +1882,7 @@ static int qedi_map_scsi_sg(struct qedi_ctx *qedi, struct qedi_cmd *cmd)
 		bd[bd_count].sge_len = (u16)sg_len;
 
 		QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_IO,
-			  "single-cashed-sgl: bd_count:%d addr=%llx, len=%x",
+			  "single-cached-sgl: bd_count:%d addr=%llx, len=%x",
 			  sg_count, addr, sg_len);
 
 		return ++bd_count;
diff --git a/drivers/scsi/qedi/qedi_gbl.h b/drivers/scsi/qedi/qedi_gbl.h
index f5b5a31..a2aa06e 100644
--- a/drivers/scsi/qedi/qedi_gbl.h
+++ b/drivers/scsi/qedi/qedi_gbl.h
@@ -23,8 +23,8 @@ extern uint qedi_io_tracing;
 extern struct scsi_host_template qedi_host_template;
 extern struct iscsi_transport qedi_iscsi_transport;
 extern const struct qed_iscsi_ops *qedi_ops;
-extern struct qedi_debugfs_ops qedi_debugfs_ops;
-extern const struct file_operations qedi_dbg_fops;
+extern const struct qedi_debugfs_ops qedi_debugfs_ops[];
+extern const struct file_operations qedi_dbg_fops[];
 extern struct device_attribute *qedi_shost_attrs[];
 
 int qedi_alloc_sq(struct qedi_ctx *qedi, struct qedi_endpoint *ep);
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
index f57a94b..4da3592 100644
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -2300,8 +2300,8 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)
 	}
 
 #ifdef CONFIG_DEBUG_FS
-	qedi_dbg_host_init(&qedi->dbg_ctx, &qedi_debugfs_ops,
-			   &qedi_dbg_fops);
+	qedi_dbg_host_init(&qedi->dbg_ctx, qedi_debugfs_ops,
+			   qedi_dbg_fops);
 #endif
 	QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
 		  "QLogic FastLinQ iSCSI Module qedi %s, FW %d.%d.%d.%d\n",
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index e2d5d3c..c11a89b 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1035,7 +1035,7 @@ qla84xx_updatefw(struct bsg_job *bsg_job)
 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
 		bsg_job->request_payload.sg_cnt, fw_buf, data_len);
 
-	mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
+	mn = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
 	if (!mn) {
 		ql_log(ql_log_warn, vha, 0x7036,
 		    "DMA alloc failed for fw buffer.\n");
@@ -1046,7 +1046,6 @@ qla84xx_updatefw(struct bsg_job *bsg_job)
 	flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 	fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2)));
 
-	memset(mn, 0, sizeof(struct access_chip_84xx));
 	mn->entry_type = VERIFY_CHIP_IOCB_TYPE;
 	mn->entry_count = 1;
 
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 3e9dc54..5fd44c5 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -14,7 +14,7 @@
  * | Module Init and Probe        |       0x0193       | 0x0146         |
  * |                              |                    | 0x015b-0x0160	|
  * |                              |                    | 0x016e		|
- * | Mailbox commands             |       0x1205       | 0x11a2-0x11ff	|
+ * | Mailbox commands             |       0x1206       | 0x11a2-0x11ff	|
  * | Device Discovery             |       0x2134       | 0x210e-0x2116  |
  * |				  | 		       | 0x211a         |
  * |                              |                    | 0x211c-0x2128  |
@@ -60,7 +60,7 @@
  * |                              |                    | 0xb13c-0xb140  |
  * |                              |                    | 0xb149		|
  * | MultiQ                       |       0xc010       |		|
- * | Misc                         |       0xd302       | 0xd031-0xd0ff	|
+ * | Misc                         |       0xd303       | 0xd031-0xd0ff	|
  * |                              |                    | 0xd101-0xd1fe	|
  * |                              |                    | 0xd214-0xd2fe	|
  * | Target Mode		  |	  0xe081       |		|
@@ -717,7 +717,7 @@ qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
 
 /**
  * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
- * @ha: HA context
+ * @vha: HA context
  * @hardware_locked: Called with the hardware_lock
  */
 void
@@ -887,7 +887,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 /**
  * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware.
- * @ha: HA context
+ * @vha: HA context
  * @hardware_locked: Called with the hardware_lock
  */
 void
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c9689f9..eb2ec1f 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2356,6 +2356,8 @@ typedef struct fc_port {
 #define NVME_PRLI_SP_DISCOVERY  BIT_3
 	uint8_t nvme_flag;
 #define NVME_FLAG_REGISTERED 4
+#define NVME_FLAG_DELETING 2
+#define NVME_FLAG_RESETTING 1
 
 	struct fc_port *conflict;
 	unsigned char logout_completed;
@@ -2981,8 +2983,14 @@ enum scan_flags_t {
 	SF_QUEUED = BIT_1,
 };
 
+enum fc4type_t {
+	FS_FC4TYPE_FCP	= BIT_0,
+	FS_FC4TYPE_NVME	= BIT_1,
+};
+
 struct fab_scan_rp {
 	port_id_t id;
+	enum fc4type_t fc4type;
 	u8 port_name[8];
 	u8 node_name[8];
 };
@@ -3274,6 +3282,7 @@ struct qla_work_evt {
 		} nack;
 		struct {
 			u8 fc4_type;
+			srb_t *sp;
 		} gpnft;
 	 } u;
 };
@@ -3463,7 +3472,6 @@ struct qla_qpair {
 	struct work_struct q_work;
 	struct list_head qp_list_elem; /* vha->qp_list */
 	struct list_head hints_list;
-	struct list_head nvme_done_list;
 	uint16_t cpuid;
 	struct qla_tgt_counters tgt_counters;
 };
@@ -4281,8 +4289,6 @@ typedef struct scsi_qla_host {
 	struct		nvme_fc_local_port *nvme_local_port;
 	struct completion nvme_del_done;
 	struct list_head nvme_rport_list;
-	atomic_t 	nvme_active_aen_cnt;
-	uint16_t	nvme_last_rptd_aen;
 
 	uint16_t	fcoe_vlan_id;
 	uint16_t	fcoe_fcf_idx;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index e929539..3c4c84e 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -658,7 +658,7 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *);
 int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
 int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
-int qla24xx_async_gpnft(scsi_qla_host_t *, u8);
+int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *);
 void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *);
 void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *);
 int qla24xx_async_gnnid(scsi_qla_host_t *, fc_port_t *);
@@ -896,6 +896,4 @@ void qlt_update_host_map(struct scsi_qla_host *, port_id_t);
 void qlt_remove_target_resources(struct qla_hw_data *);
 void qlt_clr_qp_table(struct scsi_qla_host *vha);
 
-void qla_nvme_cmpl_io(struct srb_iocb *);
-
 #endif /* _QLA_GBL_H */
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 403fa09..2288757 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -21,11 +21,10 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *);
 
 /**
  * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
- * @ha: HA context
- * @req_size: request size in bytes
- * @rsp_size: response size in bytes
+ * @vha: HA context
+ * @arg: CT arguments
  *
- * Returns a pointer to the @ha's ms_iocb.
+ * Returns a pointer to the @vha's ms_iocb.
  */
 void *
 qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
@@ -61,9 +60,8 @@ qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
 
 /**
  * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
- * @ha: HA context
- * @req_size: request size in bytes
- * @rsp_size: response size in bytes
+ * @vha: HA context
+ * @arg: CT arguments
  *
  * Returns a pointer to the @ha's ms_iocb.
  */
@@ -101,7 +99,7 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
 
 /**
  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
- * @ct_req: CT request buffer
+ * @p: CT request buffer
  * @cmd: GS command
  * @rsp_size: response size in bytes
  *
@@ -196,7 +194,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
 
 /**
  * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
- * @ha: HA context
+ * @vha: HA context
  * @fcport: fcport entry to updated
  *
  * Returns 0 on success.
@@ -283,7 +281,7 @@ qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  * NOTE: Non-Nx_Ports are not requested.
@@ -371,7 +369,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 
 /**
  * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  * Returns 0 on success.
@@ -441,7 +439,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 
 /**
  * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  * Returns 0 on success.
@@ -583,7 +581,7 @@ static void qla2x00_async_sns_sp_done(void *s, int rc)
 
 /**
  * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -675,7 +673,8 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
 
 /**
  * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
- * @ha: HA context
+ * @vha: HA context
+ * @type: not used
  *
  * Returns 0 on success.
  */
@@ -769,7 +768,7 @@ static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id,
 
 /**
  * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -874,7 +873,7 @@ qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size)
 
 /**
  * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -970,7 +969,7 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
- * @ha: HA context
+ * @vha: HA context
  * @cmd: GS command
  * @scmd_len: Subcommand length
  * @data_size: response size in bytes
@@ -1003,7 +1002,7 @@ qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
 
 /**
  * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
- * @ha: HA context
+ * @vha: HA context
  * @fcport: fcport entry to updated
  *
  * This command uses the old Exectute SNS Command mailbox routine.
@@ -1067,7 +1066,7 @@ qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
 
 /**
  * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  * This command uses the old Exectute SNS Command mailbox routine.
@@ -1140,7 +1139,7 @@ qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 
 /**
  * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  * This command uses the old Exectute SNS Command mailbox routine.
@@ -1196,7 +1195,7 @@ qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 
 /**
  * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  * This command uses the old Exectute SNS Command mailbox routine.
@@ -1259,7 +1258,7 @@ qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
 
 /**
  * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
- * @ha: HA context
+ * @vha: HA context
  *
  * This command uses the old Exectute SNS Command mailbox routine.
  *
@@ -1308,8 +1307,7 @@ qla2x00_sns_rft_id(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
- * HBA.
- * @ha: HA context
+ * @vha: HA context
  *
  * This command uses the old Exectute SNS Command mailbox routine.
  *
@@ -1365,7 +1363,7 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -1401,7 +1399,7 @@ qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
- * @ha: HA context
+ * @vha: HA context
  * @req_size: request size in bytes
  * @rsp_size: response size in bytes
  *
@@ -1439,7 +1437,7 @@ qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
 
 /**
  * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
- * @ha: HA context
+ * @vha: HA context
  * @req_size: request size in bytes
  * @rsp_size: response size in bytes
  *
@@ -1496,7 +1494,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
 
 /**
  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
- * @ct_req: CT request buffer
+ * @p: CT request buffer
  * @cmd: GS command
  * @rsp_size: response size in bytes
  *
@@ -1518,8 +1516,8 @@ qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
 }
 
 /**
- * qla2x00_fdmi_rhba() -
- * @ha: HA context
+ * qla2x00_fdmi_rhba() - perform RHBA FDMI registration
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -1728,8 +1726,8 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
 }
 
 /**
- * qla2x00_fdmi_rpa() -
- * @ha: HA context
+ * qla2x00_fdmi_rpa() - perform RPA registration
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -1940,8 +1938,8 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
 }
 
 /**
- * qla2x00_fdmiv2_rhba() -
- * @ha: HA context
+ * qla2x00_fdmiv2_rhba() - perform RHBA FDMI v2 registration
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2257,7 +2255,7 @@ qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_fdmi_dhba() -
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2305,7 +2303,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_fdmiv2_rpa() -
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2635,7 +2633,7 @@ qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_fdmi_register() -
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2693,7 +2691,7 @@ qla2x00_fdmi_register(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  * Returns 0 on success.
@@ -2778,7 +2776,7 @@ qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
 
 /**
  * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  * Returns 0 on success.
@@ -2892,7 +2890,7 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
 /**
  * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
  *
- * @ha: HA context
+ * @vha: HA context
  * @list: switch info entries to populate
  *
  */
@@ -3862,7 +3860,6 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
 	fc_port_t *fcport;
 	u32 i, rc;
 	bool found;
-	u8 fc4type = sp->gen2;
 	struct fab_scan_rp *rp;
 	unsigned long flags;
 
@@ -3935,7 +3932,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
 			    "%s %d %8phC post new sess\n",
 			    __func__, __LINE__, rp->port_name);
 			qla24xx_post_newsess_work(vha, &rp->id, rp->port_name,
-			    rp->node_name, NULL, fc4type);
+			    rp->node_name, NULL, rp->fc4type);
 		}
 	}
 
@@ -3973,9 +3970,102 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
 	spin_lock_irqsave(&vha->work_lock, flags);
 	vha->scan.scan_flags &= ~SF_SCANNING;
 	spin_unlock_irqrestore(&vha->work_lock, flags);
+}
 
-	if ((fc4type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled)
-		qla24xx_async_gpnft(vha, FC4_TYPE_NVME);
+static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
+	struct srb *sp)
+{
+	struct qla_hw_data *ha = vha->hw;
+	int num_fibre_dev = ha->max_fibre_devices;
+	struct ct_sns_req *ct_req =
+		(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
+	struct ct_sns_gpnft_rsp *ct_rsp =
+		(struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
+	struct ct_sns_gpn_ft_data *d;
+	struct fab_scan_rp *rp;
+	u16 cmd = be16_to_cpu(ct_req->command);
+	u8 fc4_type = sp->gen2;
+	int i, j, k;
+	port_id_t id;
+	u8 found;
+	u64 wwn;
+
+	j = 0;
+	for (i = 0; i < num_fibre_dev; i++) {
+		d  = &ct_rsp->entries[i];
+
+		id.b.rsvd_1 = 0;
+		id.b.domain = d->port_id[0];
+		id.b.area   = d->port_id[1];
+		id.b.al_pa  = d->port_id[2];
+		wwn = wwn_to_u64(d->port_name);
+
+		if (id.b24 == 0 || wwn == 0)
+			continue;
+
+		if (fc4_type == FC4_TYPE_FCP_SCSI) {
+			if (cmd == GPN_FT_CMD) {
+				rp = &vha->scan.l[j];
+				rp->id = id;
+				memcpy(rp->port_name, d->port_name, 8);
+				j++;
+				rp->fc4type = FS_FC4TYPE_FCP;
+			} else {
+				for (k = 0; k < num_fibre_dev; k++) {
+					rp = &vha->scan.l[k];
+					if (id.b24 == rp->id.b24) {
+						memcpy(rp->node_name,
+						    d->port_name, 8);
+						break;
+					}
+				}
+			}
+		} else {
+			/* Search if the fibre device supports FC4_TYPE_NVME */
+			if (cmd == GPN_FT_CMD) {
+				found = 0;
+
+				for (k = 0; k < num_fibre_dev; k++) {
+					rp = &vha->scan.l[k];
+					if (!memcmp(rp->port_name,
+					    d->port_name, 8)) {
+						/*
+						 * Supports FC-NVMe & FCP
+						 */
+						rp->fc4type |= FS_FC4TYPE_NVME;
+						found = 1;
+						break;
+					}
+				}
+
+				/* We found new FC-NVMe only port */
+				if (!found) {
+					for (k = 0; k < num_fibre_dev; k++) {
+						rp = &vha->scan.l[k];
+						if (wwn_to_u64(rp->port_name)) {
+							continue;
+						} else {
+							rp->id = id;
+							memcpy(rp->port_name,
+							    d->port_name, 8);
+							rp->fc4type =
+							    FS_FC4TYPE_NVME;
+							break;
+						}
+					}
+				}
+			} else {
+				for (k = 0; k < num_fibre_dev; k++) {
+					rp = &vha->scan.l[k];
+					if (id.b24 == rp->id.b24) {
+						memcpy(rp->node_name,
+						    d->port_name, 8);
+						break;
+					}
+				}
+			}
+		}
+	}
 }
 
 static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
@@ -3985,12 +4075,9 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
 	struct qla_work_evt *e;
 	struct ct_sns_req *ct_req =
 		(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
-	struct ct_sns_gpnft_rsp *ct_rsp =
-		(struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
-	struct ct_sns_gpn_ft_data *d;
-	struct fab_scan_rp *rp;
-	int i, j, k;
 	u16 cmd = be16_to_cpu(ct_req->command);
+	u8 fc4_type = sp->gen2;
+	unsigned long flags;
 
 	/* gen2 field is holding the fc4type */
 	ql_dbg(ql_dbg_disc, vha, 0xffff,
@@ -4018,40 +4105,51 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
 		return;
 	}
 
-	if (!res) {
-		port_id_t id;
-		u64 wwn;
+	if (!res)
+		qla2x00_find_free_fcp_nvme_slot(vha, sp);
 
-		j = 0;
-		for (i = 0; i < vha->hw->max_fibre_devices; i++) {
-			d  = &ct_rsp->entries[i];
+	if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled &&
+	    cmd == GNN_FT_CMD) {
+		del_timer(&sp->u.iocb_cmd.timer);
+		spin_lock_irqsave(&vha->work_lock, flags);
+		vha->scan.scan_flags &= ~SF_SCANNING;
+		spin_unlock_irqrestore(&vha->work_lock, flags);
 
-			id.b.rsvd_1 = 0;
-			id.b.domain = d->port_id[0];
-			id.b.area   = d->port_id[1];
-			id.b.al_pa  = d->port_id[2];
-			wwn = wwn_to_u64(d->port_name);
-
-			if (id.b24 == 0 || wwn == 0)
-				continue;
-
-			if (cmd == GPN_FT_CMD) {
-				rp = &vha->scan.l[j];
-				rp->id = id;
-				memcpy(rp->port_name, d->port_name, 8);
-				j++;
-			} else {/* GNN_FT_CMD */
-				for (k = 0; k < vha->hw->max_fibre_devices;
-				    k++) {
-					rp = &vha->scan.l[k];
-					if (id.b24 == rp->id.b24) {
-						memcpy(rp->node_name,
-						    d->port_name, 8);
-						break;
-					}
-				}
+		e = qla2x00_alloc_work(vha, QLA_EVT_GPNFT);
+		if (!e) {
+			/*
+			 * please ignore kernel warning. Otherwise,
+			 * we have mem leak.
+			 */
+			if (sp->u.iocb_cmd.u.ctarg.req) {
+				dma_free_coherent(&vha->hw->pdev->dev,
+				    sizeof(struct ct_sns_pkt),
+				    sp->u.iocb_cmd.u.ctarg.req,
+				    sp->u.iocb_cmd.u.ctarg.req_dma);
+				sp->u.iocb_cmd.u.ctarg.req = NULL;
 			}
+			if (sp->u.iocb_cmd.u.ctarg.rsp) {
+				dma_free_coherent(&vha->hw->pdev->dev,
+				    sizeof(struct ct_sns_pkt),
+				    sp->u.iocb_cmd.u.ctarg.rsp,
+				    sp->u.iocb_cmd.u.ctarg.rsp_dma);
+				sp->u.iocb_cmd.u.ctarg.rsp = NULL;
+			}
+
+			ql_dbg(ql_dbg_disc, vha, 0xffff,
+			    "Async done-%s unable to alloc work element\n",
+			    sp->name);
+			sp->free(sp);
+			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+			return;
 		}
+		e->u.gpnft.fc4_type = FC4_TYPE_NVME;
+		sp->rc = res;
+		e->u.gpnft.sp = sp;
+
+		qla2x00_post_work(vha, e);
+		return;
 	}
 
 	if (cmd == GPN_FT_CMD)
@@ -4102,9 +4200,12 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
 	int rval = QLA_FUNCTION_FAILED;
 	struct ct_sns_req *ct_req;
 	struct ct_sns_pkt *ct_sns;
+	unsigned long flags;
 
 	if (!vha->flags.online) {
+		spin_lock_irqsave(&vha->work_lock, flags);
 		vha->scan.scan_flags &= ~SF_SCANNING;
+		spin_unlock_irqrestore(&vha->work_lock, flags);
 		goto done_free_sp;
 	}
 
@@ -4113,10 +4214,18 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
 		    "%s: req %p rsp %p are not setup\n",
 		    __func__, sp->u.iocb_cmd.u.ctarg.req,
 		    sp->u.iocb_cmd.u.ctarg.rsp);
+		spin_lock_irqsave(&vha->work_lock, flags);
 		vha->scan.scan_flags &= ~SF_SCANNING;
+		spin_unlock_irqrestore(&vha->work_lock, flags);
 		WARN_ON(1);
 		goto done_free_sp;
 	}
+
+	ql_dbg(ql_dbg_disc, vha, 0xfffff,
+	    "%s: FC4Type %x, CT-PASSTRHU %s command ctarg rsp size %d, ctarg req size %d\n",
+	    __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size,
+	     sp->u.iocb_cmd.u.ctarg.req_size);
+
 	sp->type = SRB_CT_PTHRU_CMD;
 	sp->name = "gnnft";
 	sp->gen1 = vha->hw->base_qpair->chip_reset;
@@ -4179,15 +4288,17 @@ void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
 }
 
 /* Get WWPN list for certain fc4_type */
-int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
+int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
 {
 	int rval = QLA_FUNCTION_FAILED;
 	struct ct_sns_req       *ct_req;
-	srb_t *sp;
 	struct ct_sns_pkt *ct_sns;
 	u32 rspsz;
 	unsigned long flags;
 
+	ql_dbg(ql_dbg_disc, vha, 0xffff,
+	    "%s enter\n", __func__);
+
 	if (!vha->flags.online)
 		return rval;
 
@@ -4200,9 +4311,58 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
 	vha->scan.scan_flags |= SF_SCANNING;
 	spin_unlock_irqrestore(&vha->work_lock, flags);
 
-	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
-	if (!sp) {
-		vha->scan.scan_flags &= ~SF_SCANNING;
+	if (fc4_type == FC4_TYPE_FCP_SCSI) {
+		ql_dbg(ql_dbg_disc, vha, 0xffff,
+		    "%s: Performing FCP Scan\n", __func__);
+
+		if (sp)
+			sp->free(sp); /* should not happen */
+
+		sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
+		if (!sp) {
+			spin_lock_irqsave(&vha->work_lock, flags);
+			vha->scan.scan_flags &= ~SF_SCANNING;
+			spin_unlock_irqrestore(&vha->work_lock, flags);
+			return rval;
+		}
+
+		sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent(
+			&vha->hw->pdev->dev, sizeof(struct ct_sns_pkt),
+			&sp->u.iocb_cmd.u.ctarg.req_dma, GFP_KERNEL);
+		if (!sp->u.iocb_cmd.u.ctarg.req) {
+			ql_log(ql_log_warn, vha, 0xffff,
+			    "Failed to allocate ct_sns request.\n");
+			spin_lock_irqsave(&vha->work_lock, flags);
+			vha->scan.scan_flags &= ~SF_SCANNING;
+			spin_unlock_irqrestore(&vha->work_lock, flags);
+			goto done_free_sp;
+		}
+		sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
+
+		rspsz = sizeof(struct ct_sns_gpnft_rsp) +
+			((vha->hw->max_fibre_devices - 1) *
+			    sizeof(struct ct_sns_gpn_ft_data));
+
+		sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent(
+			&vha->hw->pdev->dev, rspsz,
+			&sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL);
+		if (!sp->u.iocb_cmd.u.ctarg.rsp) {
+			ql_log(ql_log_warn, vha, 0xffff,
+			    "Failed to allocate ct_sns request.\n");
+			spin_lock_irqsave(&vha->work_lock, flags);
+			vha->scan.scan_flags &= ~SF_SCANNING;
+			spin_unlock_irqrestore(&vha->work_lock, flags);
+			goto done_free_sp;
+		}
+		sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
+
+		ql_dbg(ql_dbg_disc, vha, 0xffff,
+		    "%s scan list size %d\n", __func__, vha->scan.size);
+
+		memset(vha->scan.l, 0, vha->scan.size);
+	} else if (!sp) {
+		ql_dbg(ql_dbg_disc, vha, 0xffff,
+		    "NVME scan did not provide SP\n");
 		return rval;
 	}
 
@@ -4212,31 +4372,10 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
 	sp->gen2 = fc4_type;
 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
-	sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent(&vha->hw->pdev->dev,
-	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
-	    GFP_KERNEL);
-	if (!sp->u.iocb_cmd.u.ctarg.req) {
-		ql_log(ql_log_warn, vha, 0xffff,
-		    "Failed to allocate ct_sns request.\n");
-		vha->scan.scan_flags &= ~SF_SCANNING;
-		goto done_free_sp;
-	}
-
 	rspsz = sizeof(struct ct_sns_gpnft_rsp) +
 		((vha->hw->max_fibre_devices - 1) *
 		    sizeof(struct ct_sns_gpn_ft_data));
 
-	sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent(&vha->hw->pdev->dev,
-	    rspsz, &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL);
-	if (!sp->u.iocb_cmd.u.ctarg.rsp) {
-		ql_log(ql_log_warn, vha, 0xffff,
-		    "Failed to allocate ct_sns request.\n");
-		vha->scan.scan_flags &= ~SF_SCANNING;
-		goto done_free_sp;
-	}
-
-	memset(vha->scan.l, 0, vha->scan.size);
-
 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
 	/* CT_IU preamble  */
 	ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
@@ -4244,8 +4383,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
 	/* GPN_FT req */
 	ct_req->req.gpn_ft.port_type = fc4_type;
 
-	sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
-	sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
 
 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
@@ -4253,7 +4390,9 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
 
 	rval = qla2x00_start_sp(sp);
 	if (rval != QLA_SUCCESS) {
+		spin_lock_irqsave(&vha->work_lock, flags);
 		vha->scan.scan_flags &= ~SF_SCANNING;
+		spin_unlock_irqrestore(&vha->work_lock, flags);
 		goto done_free_sp;
 	}
 
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 8d7fab3..8aeb0ed 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -875,7 +875,6 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
 		return rval;
 
 	if (fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
-	    fcport->fw_login_state == DSC_LS_PLOGI_COMP ||
 	    fcport->fw_login_state == DSC_LS_PRLI_PEND)
 		return rval;
 
@@ -1240,6 +1239,11 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
 		qla2x00_post_async_adisc_work(vha, fcport, data);
 		break;
 
+	case DSC_LOGIN_PEND:
+		if (fcport->fw_login_state == DSC_LS_PLOGI_COMP)
+			qla24xx_post_prli_work(vha, fcport);
+		break;
+
 	default:
 		break;
 	}
@@ -1643,6 +1647,13 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
 		qla24xx_post_gpdb_work(vha, ea->fcport, 0);
 		break;
 	default:
+		if ((ea->iop[0] == LSC_SCODE_ELS_REJECT) &&
+		    (ea->iop[1] == 0x50000)) {   /* reson 5=busy expl:0x0 */
+			set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+			ea->fcport->fw_login_state = DSC_LS_PLOGI_COMP;
+			break;
+		}
+
 		if (ea->fcport->n2n_flag) {
 			ql_dbg(ql_dbg_disc, vha, 0x2118,
 				"%s %d %8phC post fc4 prli\n",
@@ -2049,7 +2060,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
 
 /**
  * qla2100_pci_config() - Setup ISP21xx PCI configuration registers.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2080,7 +2091,7 @@ qla2100_pci_config(scsi_qla_host_t *vha)
 
 /**
  * qla2300_pci_config() - Setup ISP23xx PCI configuration registers.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2162,7 +2173,7 @@ qla2300_pci_config(scsi_qla_host_t *vha)
 
 /**
  * qla24xx_pci_config() - Setup ISP24xx PCI configuration registers.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2206,7 +2217,7 @@ qla24xx_pci_config(scsi_qla_host_t *vha)
 
 /**
  * qla25xx_pci_config() - Setup ISP25xx PCI configuration registers.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2237,7 +2248,7 @@ qla25xx_pci_config(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_isp_firmware() - Choose firmware image.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2273,7 +2284,7 @@ qla2x00_isp_firmware(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_reset_chip() - Reset ISP chip.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2417,6 +2428,7 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
 
 /**
  * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC.
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2433,7 +2445,7 @@ qla81xx_reset_mpi(scsi_qla_host_t *vha)
 
 /**
  * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2648,7 +2660,7 @@ qla25xx_manipulate_risc_semaphore(scsi_qla_host_t *vha)
 
 /**
  * qla24xx_reset_chip() - Reset ISP24xx chip.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2672,7 +2684,7 @@ qla24xx_reset_chip(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_chip_diag() - Test chip for proper operation.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2691,8 +2703,8 @@ qla2x00_chip_diag(scsi_qla_host_t *vha)
 	/* Assume a failed state */
 	rval = QLA_FUNCTION_FAILED;
 
-	ql_dbg(ql_dbg_init, vha, 0x007b,
-	    "Testing device at %lx.\n", (u_long)&reg->flash_address);
+	ql_dbg(ql_dbg_init, vha, 0x007b, "Testing device at %p.\n",
+	       &reg->flash_address);
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
@@ -2796,7 +2808,7 @@ qla2x00_chip_diag(scsi_qla_host_t *vha)
 
 /**
  * qla24xx_chip_diag() - Test ISP24xx for proper operation.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -3264,7 +3276,7 @@ qla24xx_detect_sfp(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_setup_chip() - Load and start RISC firmware.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -3419,7 +3431,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_init_response_q_entries() - Initializes response queue entries.
- * @ha: HA context
+ * @rsp: response queue
  *
  * Beginning of request ring has initialization control block already built
  * by nvram config routine.
@@ -3444,7 +3456,7 @@ qla2x00_init_response_q_entries(struct rsp_que *rsp)
 
 /**
  * qla2x00_update_fw_options() - Read and process firmware options.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -3707,7 +3719,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
 
 /**
  * qla2x00_init_rings() - Initializes firmware.
- * @ha: HA context
+ * @vha: HA context
  *
  * Beginning of request ring has initialization control block already built
  * by nvram config routine.
@@ -3815,7 +3827,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
 
 /**
  * qla2x00_fw_ready() - Waits for firmware ready.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -4483,7 +4495,7 @@ qla2x00_rport_del(void *data)
 
 /**
  * qla2x00_alloc_fcport() - Allocate a generic fcport.
- * @ha: HA context
+ * @vha: HA context
  * @flags: allocation flags
  *
  * Returns a pointer to the allocated fcport, or NULL, if none available.
@@ -5027,9 +5039,9 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
 		    fcport->port_name, rval, fcport->fp_speed, mb[0], mb[1]);
 	} else {
 		ql_dbg(ql_dbg_disc, vha, 0x2005,
-		    "iIDMA adjusted to %s GB/s on %8phN.\n",
+		    "iIDMA adjusted to %s GB/s (%X) on %8phN.\n",
 		    qla2x00_get_link_speed_str(ha, fcport->fp_speed),
-		    fcport->port_name);
+		    fcport->fp_speed, fcport->port_name);
 	}
 }
 
@@ -5109,13 +5121,14 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
 	fcport->deleted = 0;
 	fcport->logout_on_delete = 1;
 
+	qla2x00_set_fcport_state(fcport, FCS_ONLINE);
+	qla2x00_iidma_fcport(vha, fcport);
+
 	if (fcport->fc4f_nvme) {
 		qla_nvme_register_remote(vha, fcport);
 		return;
 	}
 
-	qla2x00_set_fcport_state(fcport, FCS_ONLINE);
-	qla2x00_iidma_fcport(vha, fcport);
 	qla24xx_update_fcport_fcp_prio(vha, fcport);
 
 reg_port:
@@ -5254,8 +5267,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
 		qlt_do_generation_tick(vha, &discovery_gen);
 
 		if (USE_ASYNC_SCAN(ha)) {
-			rval = QLA_SUCCESS;
-			rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI);
+			rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI,
+			    NULL);
 			if (rval)
 				set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
 		} else  {
@@ -5518,6 +5531,14 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
 			break;
 		}
 
+		if (fcport->fc4f_nvme) {
+			if (fcport->disc_state == DSC_DELETE_PEND) {
+				fcport->disc_state = DSC_GNL;
+				vha->fcport_count--;
+				fcport->login_succ = 0;
+			}
+		}
+
 		if (found) {
 			spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 			continue;
@@ -8398,7 +8419,6 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
 		qpair->vp_idx = vp_idx;
 		qpair->fw_started = ha->flags.fw_started;
 		INIT_LIST_HEAD(&qpair->hints_list);
-		INIT_LIST_HEAD(&qpair->nvme_done_list);
 		qpair->chip_reset = ha->base_qpair->chip_reset;
 		qpair->enable_class_2 = ha->base_qpair->enable_class_2;
 		qpair->enable_explicit_conf =
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 4d32426..b7a05ae 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -10,6 +10,7 @@
  * qla24xx_calc_iocbs() - Determine number of Command Type 3 and
  * Continuation Type 1 IOCBs to allocate.
  *
+ * @vha: HA context
  * @dsds: number of data segment decriptors needed
  *
  * Returns the number of IOCB entries needed to store @dsds.
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 8d00d55..f74ff7b 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -14,7 +14,7 @@
 
 /**
  * qla2x00_get_cmd_direction() - Determine control_flag data direction.
- * @cmd: SCSI command
+ * @sp: SCSI command
  *
  * Returns the proper CF_* direction based on CDB.
  */
@@ -86,7 +86,7 @@ qla2x00_calc_iocbs_64(uint16_t dsds)
 
 /**
  * qla2x00_prep_cont_type0_iocb() - Initialize a Continuation Type 0 IOCB.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns a pointer to the Continuation Type 0 IOCB packet.
  */
@@ -114,7 +114,8 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha)
 
 /**
  * qla2x00_prep_cont_type1_iocb() - Initialize a Continuation Type 1 IOCB.
- * @ha: HA context
+ * @vha: HA context
+ * @req: request queue
  *
  * Returns a pointer to the continuation type 1 IOCB packet.
  */
@@ -445,6 +446,8 @@ qla2x00_start_scsi(srb_t *sp)
 
 /**
  * qla2x00_start_iocbs() - Execute the IOCB command
+ * @vha: HA context
+ * @req: request queue
  */
 void
 qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
@@ -486,7 +489,9 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
 
 /**
  * qla2x00_marker() - Send a marker IOCB to the firmware.
- * @ha: HA context
+ * @vha: HA context
+ * @req: request queue
+ * @rsp: response queue
  * @loop_id: loop ID
  * @lun: LUN
  * @type: marker modifier
@@ -1190,6 +1195,8 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
  * @sp: SRB command to process
  * @cmd_pkt: Command type 3 IOCB
  * @tot_dsds: Total number of segments to transfer
+ * @tot_prot_dsds:
+ * @fw_prot_opts:
  */
 inline int
 qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
@@ -1203,7 +1210,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
 	uint32_t		dif_bytes;
 	uint8_t			bundling = 1;
 	uint16_t		blk_size;
-	uint8_t			*clr_ptr;
 	struct crc_context	*crc_ctx_pkt = NULL;
 	struct qla_hw_data	*ha;
 	uint8_t			additional_fcpcdb_len;
@@ -1245,15 +1251,11 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
 
 	/* Allocate CRC context from global pool */
 	crc_ctx_pkt = sp->u.scmd.ctx =
-	    dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
+	    dma_pool_zalloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
 
 	if (!crc_ctx_pkt)
 		goto crc_queuing_error;
 
-	/* Zero out CTX area. */
-	clr_ptr = (uint8_t *)crc_ctx_pkt;
-	memset(clr_ptr, 0, sizeof(*crc_ctx_pkt));
-
 	crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma;
 
 	sp->flags |= SRB_CRC_CTX_DMA_VALID;
@@ -3067,7 +3069,7 @@ qla82xx_start_scsi(srb_t *sp)
 		}
 
 		memset(ctx, 0, sizeof(struct ct6_dsd));
-		ctx->fcp_cmnd = dma_pool_alloc(ha->fcp_cmnd_dma_pool,
+		ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool,
 			GFP_ATOMIC, &ctx->fcp_cmnd_dma);
 		if (!ctx->fcp_cmnd) {
 			ql_log(ql_log_fatal, vha, 0x3011,
@@ -3120,7 +3122,6 @@ qla82xx_start_scsi(srb_t *sp)
 		host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
 
 		/* build FCP_CMND IU */
-		memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
 		int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun);
 		ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;
 
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 89f93eb..7cacdc3 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -259,7 +259,7 @@ qla2300_intr_handler(int irq, void *dev_id)
 
 /**
  * qla2x00_mbx_completion() - Process mailbox command completions.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
  * @mb0: Mailbox0 register
  */
 static void
@@ -613,7 +613,8 @@ qla2x00_find_fcport_by_nportid(scsi_qla_host_t *vha, port_id_t *id,
 
 /**
  * qla2x00_async_event() - Process aynchronous events.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @rsp: response queue
  * @mb: Mailbox registers (0 - 3)
  */
 void
@@ -767,7 +768,6 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
 
 	case MBA_LIP_OCCURRED:		/* Loop Initialization Procedure */
 		ha->flags.lip_ae = 1;
-		ha->flags.n2n_ae = 0;
 
 		ql_dbg(ql_dbg_async, vha, 0x5009,
 		    "LIP occurred (%x).\n", mb[1]);
@@ -811,7 +811,6 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
 
 	case MBA_LOOP_DOWN:		/* Loop Down Event */
 		SAVE_TOPO(ha);
-		ha->flags.n2n_ae = 0;
 		ha->flags.lip_ae = 0;
 		ha->current_topology = 0;
 
@@ -885,7 +884,6 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
 	/* case MBA_DCBX_COMPLETE: */
 	case MBA_POINT_TO_POINT:	/* Point-to-Point */
 		ha->flags.lip_ae = 0;
-		ha->flags.n2n_ae = 1;
 
 		if (IS_QLA2100(ha))
 			break;
@@ -1256,7 +1254,8 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
 
 /**
  * qla2x00_process_completed_request() - Process a Fast Post response.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @req: request queue
  * @index: SRB index
  */
 void
@@ -1839,31 +1838,23 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
 	sp->done(sp, 0);
 }
 
-static void
-qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
+static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
+    void *tsk, srb_t *sp)
 {
-	const char func[] = "NVME-IOCB";
 	fc_port_t *fcport;
-	srb_t *sp;
 	struct srb_iocb *iocb;
 	struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
 	uint16_t        state_flags;
 	struct nvmefc_fcp_req *fd;
 	uint16_t        ret = 0;
-	struct srb_iocb *nvme;
-
-	sp = qla2x00_get_sp_from_handle(vha, func, req, tsk);
-	if (!sp)
-		return;
 
 	iocb = &sp->u.iocb_cmd;
 	fcport = sp->fcport;
 	iocb->u.nvme.comp_status = le16_to_cpu(sts->comp_status);
 	state_flags  = le16_to_cpu(sts->state_flags);
 	fd = iocb->u.nvme.desc;
-	nvme = &sp->u.iocb_cmd;
 
-	if (unlikely(nvme->u.nvme.aen_op))
+	if (unlikely(iocb->u.nvme.aen_op))
 		atomic_dec(&sp->vha->hw->nvme_active_aen_cnt);
 
 	/*
@@ -1897,42 +1888,30 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
 	fd->transferred_length = fd->payload_length -
 	    le32_to_cpu(sts->residual_len);
 
-	/*
-	 * If transport error then Failure (HBA rejects request)
-	 * otherwise transport will handle.
-	 */
-	if (sts->entry_status) {
-		ql_log(ql_log_warn, fcport->vha, 0x5038,
-		    "NVME-%s error - hdl=%x entry-status(%x).\n",
-		    sp->name, sp->handle, sts->entry_status);
+	switch (le16_to_cpu(sts->comp_status)) {
+	case CS_COMPLETE:
+		ret = QLA_SUCCESS;
+		break;
+	case CS_ABORTED:
+	case CS_RESET:
+	case CS_PORT_UNAVAILABLE:
+	case CS_PORT_LOGGED_OUT:
+	case CS_PORT_BUSY:
+		ql_log(ql_log_warn, fcport->vha, 0x5060,
+		    "NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x  ox_id=%x\n",
+		    sp->name, sp->handle, sts->comp_status,
+		    le32_to_cpu(sts->residual_len), sts->ox_id);
+		fd->transferred_length = 0;
+		iocb->u.nvme.rsp_pyld_len = 0;
+		ret = QLA_ABORTED;
+		break;
+	default:
+		ql_log(ql_log_warn, fcport->vha, 0x5060,
+		    "NVME-%s error - hdl=%x completion status(%x) resid=%x  ox_id=%x\n",
+		    sp->name, sp->handle, sts->comp_status,
+		    le32_to_cpu(sts->residual_len), sts->ox_id);
 		ret = QLA_FUNCTION_FAILED;
-	} else  {
-		switch (le16_to_cpu(sts->comp_status)) {
-			case CS_COMPLETE:
-				ret = 0;
-			break;
-
-			case CS_ABORTED:
-			case CS_RESET:
-			case CS_PORT_UNAVAILABLE:
-			case CS_PORT_LOGGED_OUT:
-			case CS_PORT_BUSY:
-				ql_log(ql_log_warn, fcport->vha, 0x5060,
-				"NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x  ox_id=%x\n",
-				sp->name, sp->handle, sts->comp_status,
-				le32_to_cpu(sts->residual_len), sts->ox_id);
-				fd->transferred_length = fd->payload_length;
-				ret = QLA_ABORTED;
-			break;
-
-			default:
-				ql_log(ql_log_warn, fcport->vha, 0x5060,
-				"NVME-%s error - hdl=%x completion status(%x) resid=%x  ox_id=%x\n",
-				sp->name, sp->handle, sts->comp_status,
-				le32_to_cpu(sts->residual_len), sts->ox_id);
-				ret = QLA_FUNCTION_FAILED;
-				break;
-		}
+		break;
 	}
 	sp->done(sp, ret);
 }
@@ -1970,7 +1949,7 @@ static void qla_ctrlvp_completed(scsi_qla_host_t *vha, struct req_que *req,
 
 /**
  * qla2x00_process_response_queue() - Process response queue entries.
- * @ha: SCSI driver HA context
+ * @rsp: response queue
  */
 void
 qla2x00_process_response_queue(struct rsp_que *rsp)
@@ -2374,7 +2353,8 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
 
 /**
  * qla2x00_status_entry() - Process a Status IOCB entry.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @rsp: response queue
  * @pkt: Entry pointer
  */
 static void
@@ -2459,7 +2439,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 
 	/* NVME completion. */
 	if (sp->type == SRB_NVME_CMD) {
-		qla24xx_nvme_iocb_entry(vha, req, pkt);
+		req->outstanding_cmds[handle] = NULL;
+		qla24xx_nvme_iocb_entry(vha, req, pkt, sp);
 		return;
 	}
 
@@ -2751,7 +2732,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 
 /**
  * qla2x00_status_cont_entry() - Process a Status Continuations entry.
- * @ha: SCSI driver HA context
+ * @rsp: response queue
  * @pkt: Entry pointer
  *
  * Extended sense data.
@@ -2809,7 +2790,8 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
 
 /**
  * qla2x00_error_entry() - Process an error entry.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @rsp: response queue
  * @pkt: Entry pointer
  * return : 1=allow further error analysis. 0=no additional error analysis.
  */
@@ -2868,7 +2850,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
 
 /**
  * qla24xx_mbx_completion() - Process mailbox command completions.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
  * @mb0: Mailbox0 register
  */
 static void
@@ -2937,7 +2919,8 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha,
 
 /**
  * qla24xx_process_response_queue() - Process response queue entries.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @rsp: response queue
  */
 void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 	struct rsp_que *rsp)
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 7397aed..5db0262 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -503,11 +503,19 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 				}
 			pr_warn(" cmd=%x ****\n", command);
 		}
-		ql_dbg(ql_dbg_mbx, vha, 0x1198,
-		    "host_status=%#x intr_ctrl=%#x intr_status=%#x\n",
-		    RD_REG_DWORD(&reg->isp24.host_status),
-		    RD_REG_DWORD(&reg->isp24.ictrl),
-		    RD_REG_DWORD(&reg->isp24.istatus));
+		if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) {
+			ql_dbg(ql_dbg_mbx, vha, 0x1198,
+			    "host_status=%#x intr_ctrl=%#x intr_status=%#x\n",
+			    RD_REG_DWORD(&reg->isp24.host_status),
+			    RD_REG_DWORD(&reg->isp24.ictrl),
+			    RD_REG_DWORD(&reg->isp24.istatus));
+		} else {
+			ql_dbg(ql_dbg_mbx, vha, 0x1206,
+			    "ctrl_status=%#x ictrl=%#x istatus=%#x\n",
+			    RD_REG_WORD(&reg->isp.ctrl_status),
+			    RD_REG_WORD(&reg->isp.ictrl),
+			    RD_REG_WORD(&reg->isp.istatus));
+		}
 	} else {
 		ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
 	}
@@ -1025,9 +1033,12 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
 		 * FW supports nvme and driver load parameter requested nvme.
 		 * BIT 26 of fw_attributes indicates NVMe support.
 		 */
-		if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable)
+		if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable) {
 			vha->flags.nvme_enabled = 1;
-
+			ql_log(ql_log_info, vha, 0xd302,
+			    "%s: FC-NVMe is Enabled (0x%x)\n",
+			     __func__, ha->fw_attributes_h);
+		}
 	}
 
 	if (IS_QLA27XX(ha)) {
@@ -3385,7 +3396,10 @@ qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
 
 /**
  * qla2x00_set_serdes_params() -
- * @ha: HA context
+ * @vha: HA context
+ * @sw_em_1g:
+ * @sw_em_2g:
+ * @sw_em_4g:
  *
  * Returns
  */
@@ -3744,6 +3758,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
 	id.b.area   = rptid_entry->port_id[1];
 	id.b.al_pa  = rptid_entry->port_id[0];
 	id.b.rsvd_1 = 0;
+	ha->flags.n2n_ae = 0;
 
 	if (rptid_entry->format == 0) {
 		/* loop */
@@ -3796,6 +3811,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
 			set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
 			set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
 			set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
+			ha->flags.n2n_ae = 1;
 			return;
 		}
 
@@ -3872,6 +3888,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
 		vha->d_id.b.area = rptid_entry->port_id[1];
 		vha->d_id.b.al_pa = rptid_entry->port_id[0];
 
+		ha->flags.n2n_ae = 1;
 		spin_lock_irqsave(&ha->vport_slock, flags);
 		qlt_update_vp_map(vha, SET_AL_PA);
 		spin_unlock_irqrestore(&ha->vport_slock, flags);
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index e965b16..da85cd8 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -778,18 +778,12 @@ static void qla_do_work(struct work_struct *work)
 	struct qla_qpair *qpair = container_of(work, struct qla_qpair, q_work);
 	struct scsi_qla_host *vha;
 	struct qla_hw_data *ha = qpair->hw;
-	struct srb_iocb	*nvme, *nxt_nvme;
 
 	spin_lock_irqsave(&qpair->qp_lock, flags);
 	vha = pci_get_drvdata(ha->pdev);
 	qla24xx_process_response_queue(vha, qpair->rsp);
 	spin_unlock_irqrestore(&qpair->qp_lock, flags);
 
-	list_for_each_entry_safe(nvme, nxt_nvme, &qpair->nvme_done_list,
-		    u.nvme.entry) {
-		list_del_init(&nvme->u.nvme.entry);
-		qla_nvme_cmpl_io(nvme);
-	}
 }
 
 /* create response queue */
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index d5da398..7113acf 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -490,7 +490,7 @@ qlafx00_mbx_reg_test(scsi_qla_host_t *vha)
 
 /**
  * qlafx00_pci_config() - Setup ISPFx00 PCI configuration registers.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -519,9 +519,9 @@ qlafx00_pci_config(scsi_qla_host_t *vha)
 
 /**
  * qlafx00_warm_reset() - Perform warm reset of iSA(CPUs being reset on SOC).
- * @ha: HA context
+ * @vha: HA context
  *
-  */
+ */
 static inline void
 qlafx00_soc_cpu_reset(scsi_qla_host_t *vha)
 {
@@ -625,7 +625,7 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha)
 
 /**
  * qlafx00_soft_reset() - Soft Reset ISPFx00.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -644,7 +644,7 @@ qlafx00_soft_reset(scsi_qla_host_t *vha)
 
 /**
  * qlafx00_chip_diag() - Test ISPFx00 for proper operation.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -1408,7 +1408,7 @@ qlafx00_abort_isp_cleanup(scsi_qla_host_t *vha, bool critemp)
 
 /**
  * qlafx00_init_response_q_entries() - Initializes response queue entries.
- * @ha: HA context
+ * @rsp: response queue
  *
  * Beginning of request ring has initialization control block already built
  * by nvram config routine.
@@ -2269,7 +2269,8 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
 
 /**
  * qlafx00_status_entry() - Process a Status IOCB entry.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @rsp: response queue
  * @pkt: Entry pointer
  */
 static void
@@ -2542,7 +2543,7 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 
 /**
  * qlafx00_status_cont_entry() - Process a Status Continuations entry.
- * @ha: SCSI driver HA context
+ * @rsp: response queue
  * @pkt: Entry pointer
  *
  * Extended sense data.
@@ -2620,7 +2621,9 @@ qlafx00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
 
 /**
  * qlafx00_multistatus_entry() - Process Multi response queue entries.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @rsp: response queue
+ * @pkt:
  */
 static void
 qlafx00_multistatus_entry(struct scsi_qla_host *vha,
@@ -2674,8 +2677,11 @@ qlafx00_multistatus_entry(struct scsi_qla_host *vha,
 
 /**
  * qlafx00_error_entry() - Process an error entry.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @rsp: response queue
  * @pkt: Entry pointer
+ * @estatus:
+ * @etype:
  */
 static void
 qlafx00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp,
@@ -2705,7 +2711,8 @@ qlafx00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp,
 
 /**
  * qlafx00_process_response_queue() - Process response queue entries.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
+ * @rsp: response queue
  */
 static void
 qlafx00_process_response_queue(struct scsi_qla_host *vha,
@@ -2781,7 +2788,7 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha,
 
 /**
  * qlafx00_async_event() - Process aynchronous events.
- * @ha: SCSI driver HA context
+ * @vha: SCSI driver HA context
  */
 static void
 qlafx00_async_event(scsi_qla_host_t *vha)
@@ -2857,10 +2864,9 @@ qlafx00_async_event(scsi_qla_host_t *vha)
 }
 
 /**
- *
  * qlafx00x_mbx_completion() - Process mailbox command completions.
- * @ha: SCSI driver HA context
- * @mb16: Mailbox16 register
+ * @vha: SCSI driver HA context
+ * @mb0:
  */
 static void
 qlafx00_mbx_completion(scsi_qla_host_t *vha, uint32_t mb0)
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
index 6b33a1f..c5a963c 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -16,15 +16,13 @@ static void qla_nvme_unregister_remote_port(struct work_struct *);
 
 int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
 {
-	struct nvme_rport *rport;
+	struct qla_nvme_rport *rport;
+	struct nvme_fc_port_info req;
 	int ret;
 
 	if (!IS_ENABLED(CONFIG_NVME_FC))
 		return 0;
 
-	if (fcport->nvme_flag & NVME_FLAG_REGISTERED)
-		return 0;
-
 	if (!vha->flags.nvme_enabled) {
 		ql_log(ql_log_info, vha, 0x2100,
 		    "%s: Not registering target since Host NVME is not enabled\n",
@@ -33,38 +31,36 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
 	}
 
 	if (!(fcport->nvme_prli_service_param &
-	    (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)))
+	    (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) ||
+		(fcport->nvme_flag & NVME_FLAG_REGISTERED))
 		return 0;
 
 	INIT_WORK(&fcport->nvme_del_work, qla_nvme_unregister_remote_port);
-	rport = kzalloc(sizeof(*rport), GFP_KERNEL);
-	if (!rport) {
-		ql_log(ql_log_warn, vha, 0x2101,
-		    "%s: unable to alloc memory\n", __func__);
-		return -ENOMEM;
-	}
+	fcport->nvme_flag &= ~NVME_FLAG_RESETTING;
 
-	rport->req.port_name = wwn_to_u64(fcport->port_name);
-	rport->req.node_name = wwn_to_u64(fcport->node_name);
-	rport->req.port_role = 0;
+	memset(&req, 0, sizeof(struct nvme_fc_port_info));
+	req.port_name = wwn_to_u64(fcport->port_name);
+	req.node_name = wwn_to_u64(fcport->node_name);
+	req.port_role = 0;
+	req.dev_loss_tmo = NVME_FC_DEV_LOSS_TMO;
 
 	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR)
-		rport->req.port_role = FC_PORT_ROLE_NVME_INITIATOR;
+		req.port_role = FC_PORT_ROLE_NVME_INITIATOR;
 
 	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET)
-		rport->req.port_role |= FC_PORT_ROLE_NVME_TARGET;
+		req.port_role |= FC_PORT_ROLE_NVME_TARGET;
 
 	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY)
-		rport->req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY;
+		req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY;
 
-	rport->req.port_id = fcport->d_id.b24;
+	req.port_id = fcport->d_id.b24;
 
 	ql_log(ql_log_info, vha, 0x2102,
 	    "%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n",
-	    __func__, rport->req.node_name, rport->req.port_name,
-	    rport->req.port_id);
+	    __func__, req.node_name, req.port_name,
+	    req.port_id);
 
-	ret = nvme_fc_register_remoteport(vha->nvme_local_port, &rport->req,
+	ret = nvme_fc_register_remoteport(vha->nvme_local_port, &req,
 	    &fcport->nvme_remote_port);
 	if (ret) {
 		ql_log(ql_log_warn, vha, 0x212e,
@@ -73,10 +69,11 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
 		return ret;
 	}
 
-	fcport->nvme_remote_port->private = fcport;
-	fcport->nvme_flag |= NVME_FLAG_REGISTERED;
+	rport = fcport->nvme_remote_port->private;
 	rport->fcport = fcport;
 	list_add_tail(&rport->list, &vha->nvme_rport_list);
+
+	fcport->nvme_flag |= NVME_FLAG_REGISTERED;
 	return 0;
 }
 
@@ -113,8 +110,6 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport,
 		return 0;
 	}
 
-	ql_log(ql_log_warn, vha, 0xffff,
-	    "allocating q for idx=%x w/o cpu mask\n", qidx);
 	qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true);
 	if (qpair == NULL) {
 		ql_log(ql_log_warn, vha, 0x2122,
@@ -154,16 +149,6 @@ static void qla_nvme_sp_ls_done(void *ptr, int res)
 	qla2x00_rel_sp(sp);
 }
 
-void qla_nvme_cmpl_io(struct srb_iocb *nvme)
-{
-	srb_t *sp;
-	struct nvmefc_fcp_req *fd = nvme->u.nvme.desc;
-
-	sp = container_of(nvme, srb_t, u.iocb_cmd);
-	fd->done(fd);
-	qla2xxx_rel_qpair_sp(sp->qpair, sp);
-}
-
 static void qla_nvme_sp_done(void *ptr, int res)
 {
 	srb_t *sp = ptr;
@@ -176,36 +161,42 @@ static void qla_nvme_sp_done(void *ptr, int res)
 	if (!atomic_dec_and_test(&sp->ref_count))
 		return;
 
-	if (!(sp->fcport->nvme_flag & NVME_FLAG_REGISTERED))
-		goto rel;
-
-	if (unlikely(res == QLA_FUNCTION_FAILED))
-		fd->status = NVME_SC_INTERNAL;
-	else
+	if (res == QLA_SUCCESS)
 		fd->status = 0;
+	else
+		fd->status = NVME_SC_INTERNAL;
 
 	fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len;
-	list_add_tail(&nvme->u.nvme.entry, &sp->qpair->nvme_done_list);
-	return;
-rel:
+	fd->done(fd);
 	qla2xxx_rel_qpair_sp(sp->qpair, sp);
+
+	return;
+}
+
+static void qla_nvme_abort_work(struct work_struct *work)
+{
+	struct nvme_private *priv =
+		container_of(work, struct nvme_private, abort_work);
+	srb_t *sp = priv->sp;
+	fc_port_t *fcport = sp->fcport;
+	struct qla_hw_data *ha = fcport->vha->hw;
+	int rval;
+
+	rval = ha->isp_ops->abort_command(sp);
+
+	ql_dbg(ql_dbg_io, fcport->vha, 0x212b,
+	    "%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n",
+	    __func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
+	    sp, sp->handle, fcport, rval);
 }
 
 static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport,
     struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
 {
 	struct nvme_private *priv = fd->private;
-	fc_port_t *fcport = rport->private;
-	srb_t *sp = priv->sp;
-	int rval;
-	struct qla_hw_data *ha = fcport->vha->hw;
 
-	rval = ha->isp_ops->abort_command(sp);
-
-	ql_dbg(ql_dbg_io, fcport->vha, 0x212b,
-	    "%s: %s LS command for sp=%p on fcport=%p rval=%x\n", __func__,
-	    (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
-	    sp, fcport, rval);
+	INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
+	schedule_work(&priv->abort_work);
 }
 
 static void qla_nvme_ls_complete(struct work_struct *work)
@@ -220,7 +211,8 @@ static void qla_nvme_ls_complete(struct work_struct *work)
 static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
     struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
 {
-	fc_port_t *fcport = rport->private;
+	struct qla_nvme_rport *qla_rport = rport->private;
+	fc_port_t *fcport = qla_rport->fcport;
 	struct srb_iocb   *nvme;
 	struct nvme_private *priv = fd->private;
 	struct scsi_qla_host *vha;
@@ -228,9 +220,6 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
 	struct qla_hw_data *ha;
 	srb_t           *sp;
 
-	if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))
-		return rval;
-
 	vha = fcport->vha;
 	ha = vha->hw;
 	/* Alloc SRB structure */
@@ -275,32 +264,23 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
     struct nvmefc_fcp_req *fd)
 {
 	struct nvme_private *priv = fd->private;
-	srb_t *sp = priv->sp;
-	int rval;
-	fc_port_t *fcport = rport->private;
-	struct qla_hw_data *ha = fcport->vha->hw;
 
-	rval = ha->isp_ops->abort_command(sp);
-
-	ql_dbg(ql_dbg_io, fcport->vha, 0x2127,
-	    "%s: %s command for sp=%p on fcport=%p rval=%x\n", __func__,
-	    (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
-	    sp, fcport, rval);
+	INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
+	schedule_work(&priv->abort_work);
 }
 
 static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle)
 {
-	struct scsi_qla_host *vha = lport->private;
-	unsigned long flags;
 	struct qla_qpair *qpair = hw_queue_handle;
+	unsigned long flags;
+	struct scsi_qla_host *vha = lport->private;
 
-	/* Acquire ring specific lock */
 	spin_lock_irqsave(&qpair->qp_lock, flags);
 	qla24xx_process_response_queue(vha, qpair->rsp);
 	spin_unlock_irqrestore(&qpair->qp_lock, flags);
 }
 
-static int qla2x00_start_nvme_mq(srb_t *sp)
+static inline int qla2x00_start_nvme_mq(srb_t *sp)
 {
 	unsigned long   flags;
 	uint32_t        *clr_ptr;
@@ -313,7 +293,6 @@ static int qla2x00_start_nvme_mq(srb_t *sp)
 	uint16_t	avail_dsds;
 	uint32_t	*cur_dsd;
 	struct req_que *req = NULL;
-	struct rsp_que *rsp = NULL;
 	struct scsi_qla_host *vha = sp->fcport->vha;
 	struct qla_hw_data *ha = vha->hw;
 	struct qla_qpair *qpair = sp->qpair;
@@ -322,15 +301,13 @@ static int qla2x00_start_nvme_mq(srb_t *sp)
 	struct nvmefc_fcp_req *fd = nvme->u.nvme.desc;
 	uint32_t        rval = QLA_SUCCESS;
 
+	/* Setup qpair pointers */
+	req = qpair->req;
 	tot_dsds = fd->sg_cnt;
 
 	/* Acquire qpair specific lock */
 	spin_lock_irqsave(&qpair->qp_lock, flags);
 
-	/* Setup qpair pointers */
-	req = qpair->req;
-	rsp = qpair->rsp;
-
 	/* Check for room in outstanding command list. */
 	handle = req->current_outstanding_cmd;
 	for (index = 1; index < req->num_outstanding_cmds; index++) {
@@ -342,7 +319,7 @@ static int qla2x00_start_nvme_mq(srb_t *sp)
 	}
 
 	if (index == req->num_outstanding_cmds) {
-		rval = -1;
+		rval = -EBUSY;
 		goto queuing_error;
 	}
 	req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
@@ -356,7 +333,7 @@ static int qla2x00_start_nvme_mq(srb_t *sp)
 			req->cnt = req->length - (req->ring_index - cnt);
 
 		if (req->cnt < (req_cnt + 2)){
-			rval = -1;
+			rval = -EBUSY;
 			goto queuing_error;
 		}
 	}
@@ -365,7 +342,7 @@ static int qla2x00_start_nvme_mq(srb_t *sp)
 		struct nvme_fc_cmd_iu *cmd = fd->cmdaddr;
 		if (cmd->sqe.common.opcode == nvme_admin_async_event) {
 			nvme->u.nvme.aen_op = 1;
-			atomic_inc(&vha->hw->nvme_active_aen_cnt);
+			atomic_inc(&ha->nvme_active_aen_cnt);
 		}
 	}
 
@@ -478,11 +455,6 @@ static int qla2x00_start_nvme_mq(srb_t *sp)
 	/* Set chip new ring index. */
 	WRT_REG_DWORD(req->req_q_in, req->ring_index);
 
-	/* Manage unprocessed RIO/ZIO commands in response queue. */
-	if (vha->flags.process_response_queue &&
-	    rsp->ring_ptr->signature != RESPONSE_PROCESSED)
-		qla24xx_process_response_queue(vha, rsp);
-
 queuing_error:
 	spin_unlock_irqrestore(&qpair->qp_lock, flags);
 	return rval;
@@ -496,31 +468,44 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
 	fc_port_t *fcport;
 	struct srb_iocb *nvme;
 	struct scsi_qla_host *vha;
-	int rval = QLA_FUNCTION_FAILED;
+	int rval = -ENODEV;
 	srb_t *sp;
 	struct qla_qpair *qpair = hw_queue_handle;
 	struct nvme_private *priv;
+	struct qla_nvme_rport *qla_rport = rport->private;
 
-	if (!fd) {
-		ql_log(ql_log_warn, NULL, 0x2134, "NO NVMe FCP request\n");
+	if (!fd || !qpair) {
+		ql_log(ql_log_warn, NULL, 0x2134,
+		    "NO NVMe request or Queue Handle\n");
 		return rval;
 	}
 
 	priv = fd->private;
-	fcport = rport->private;
+	fcport = qla_rport->fcport;
 	if (!fcport) {
 		ql_log(ql_log_warn, NULL, 0x210e, "No fcport ptr\n");
 		return rval;
 	}
 
 	vha = fcport->vha;
-	if ((!qpair) || (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)))
+
+	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
+		return rval;
+
+	/*
+	 * If we know the dev is going away while the transport is still sending
+	 * IO's return busy back to stall the IO Q.  This happens when the
+	 * link goes away and fw hasn't notified us yet, but IO's are being
+	 * returned. If the dev comes back quickly we won't exhaust the IO
+	 * retry count at the core.
+	 */
+	if (fcport->nvme_flag & NVME_FLAG_RESETTING)
 		return -EBUSY;
 
 	/* Alloc SRB structure */
 	sp = qla2xxx_get_qpair_sp(qpair, fcport, GFP_ATOMIC);
 	if (!sp)
-		return -EIO;
+		return -EBUSY;
 
 	atomic_set(&sp->ref_count, 1);
 	init_waitqueue_head(&sp->nvme_ls_waitq);
@@ -538,7 +523,6 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
 		    "qla2x00_start_nvme_mq failed = %d\n", rval);
 		atomic_dec(&sp->ref_count);
 		wake_up(&sp->nvme_ls_waitq);
-		return -EIO;
 	}
 
 	return rval;
@@ -557,22 +541,27 @@ static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport)
 static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
 {
 	fc_port_t *fcport;
-	struct nvme_rport *r_port, *trport;
+	struct qla_nvme_rport *qla_rport = rport->private, *trport;
 
-	fcport = rport->private;
+	fcport = qla_rport->fcport;
 	fcport->nvme_remote_port = NULL;
 	fcport->nvme_flag &= ~NVME_FLAG_REGISTERED;
 
-	list_for_each_entry_safe(r_port, trport,
+	list_for_each_entry_safe(qla_rport, trport,
 	    &fcport->vha->nvme_rport_list, list) {
-		if (r_port->fcport == fcport) {
-			list_del(&r_port->list);
+		if (qla_rport->fcport == fcport) {
+			list_del(&qla_rport->list);
 			break;
 		}
 	}
-	kfree(r_port);
 	complete(&fcport->nvme_del_done);
 
+	if (!test_bit(UNLOADING, &fcport->vha->dpc_flags)) {
+		INIT_WORK(&fcport->free_work, qlt_free_session_done);
+		schedule_work(&fcport->free_work);
+	}
+
+	fcport->nvme_flag &= ~(NVME_FLAG_REGISTERED | NVME_FLAG_DELETING);
 	ql_log(ql_log_info, fcport->vha, 0x2110,
 	    "remoteport_delete of %p completed.\n", fcport);
 }
@@ -592,7 +581,7 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = {
 	.max_dif_sgl_segments = 64,
 	.dma_boundary = 0xFFFFFFFF,
 	.local_priv_sz  = 8,
-	.remote_priv_sz = 0,
+	.remote_priv_sz = sizeof(struct qla_nvme_rport),
 	.lsrqst_priv_sz = sizeof(struct nvme_private),
 	.fcprqst_priv_sz = sizeof(struct nvme_private),
 };
@@ -611,37 +600,25 @@ static int qla_nvme_wait_on_command(srb_t *sp)
 	return ret;
 }
 
-static int qla_nvme_wait_on_rport_del(fc_port_t *fcport)
-{
-	int ret = QLA_SUCCESS;
-	int timeout;
-
-	timeout = wait_for_completion_timeout(&fcport->nvme_del_done,
-	    msecs_to_jiffies(2000));
-	if (!timeout) {
-		ret = QLA_FUNCTION_FAILED;
-		ql_log(ql_log_info, fcport->vha, 0x2111,
-		    "timed out waiting for fcport=%p to delete\n", fcport);
-	}
-
-	return ret;
-}
-
-void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp)
+void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp, int res)
 {
 	int rval;
 
-	rval = ha->isp_ops->abort_command(sp);
-	if (!rval && !qla_nvme_wait_on_command(sp))
-		ql_log(ql_log_warn, NULL, 0x2112,
-		    "nvme_wait_on_comand timed out waiting on sp=%p\n", sp);
+	if (!test_bit(ABORT_ISP_ACTIVE, &sp->vha->dpc_flags)) {
+		rval = ha->isp_ops->abort_command(sp);
+		if (!rval && !qla_nvme_wait_on_command(sp))
+			ql_log(ql_log_warn, NULL, 0x2112,
+			    "timed out waiting on sp=%p\n", sp);
+	} else {
+		sp->done(sp, res);
+	}
 }
 
 static void qla_nvme_unregister_remote_port(struct work_struct *work)
 {
 	struct fc_port *fcport = container_of(work, struct fc_port,
 	    nvme_del_work);
-	struct nvme_rport *rport, *trport;
+	struct qla_nvme_rport *qla_rport, *trport;
 
 	if (!IS_ENABLED(CONFIG_NVME_FC))
 		return;
@@ -649,51 +626,53 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work)
 	ql_log(ql_log_warn, NULL, 0x2112,
 	    "%s: unregister remoteport on %p\n",__func__, fcport);
 
-	list_for_each_entry_safe(rport, trport,
+	list_for_each_entry_safe(qla_rport, trport,
 	    &fcport->vha->nvme_rport_list, list) {
-		if (rport->fcport == fcport) {
+		if (qla_rport->fcport == fcport) {
 			ql_log(ql_log_info, fcport->vha, 0x2113,
 			    "%s: fcport=%p\n", __func__, fcport);
 			init_completion(&fcport->nvme_del_done);
 			nvme_fc_unregister_remoteport(
 			    fcport->nvme_remote_port);
-			qla_nvme_wait_on_rport_del(fcport);
+			wait_for_completion(&fcport->nvme_del_done);
+			break;
 		}
 	}
 }
 
 void qla_nvme_delete(struct scsi_qla_host *vha)
 {
-	struct nvme_rport *rport, *trport;
+	struct qla_nvme_rport *qla_rport, *trport;
 	fc_port_t *fcport;
 	int nv_ret;
 
 	if (!IS_ENABLED(CONFIG_NVME_FC))
 		return;
 
-	list_for_each_entry_safe(rport, trport, &vha->nvme_rport_list, list) {
-		fcport = rport->fcport;
+	list_for_each_entry_safe(qla_rport, trport,
+	    &vha->nvme_rport_list, list) {
+		fcport = qla_rport->fcport;
 
 		ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n",
 		    __func__, fcport);
 
+		nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0);
 		init_completion(&fcport->nvme_del_done);
 		nvme_fc_unregister_remoteport(fcport->nvme_remote_port);
-		qla_nvme_wait_on_rport_del(fcport);
+		wait_for_completion(&fcport->nvme_del_done);
 	}
 
 	if (vha->nvme_local_port) {
 		init_completion(&vha->nvme_del_done);
+		ql_log(ql_log_info, vha, 0x2116,
+			"unregister localport=%p\n",
+			vha->nvme_local_port);
 		nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port);
-		if (nv_ret == 0)
-			ql_log(ql_log_info, vha, 0x2116,
-			    "unregistered localport=%p\n",
-			    vha->nvme_local_port);
-		else
+		if (nv_ret)
 			ql_log(ql_log_info, vha, 0x2115,
 			    "Unregister of localport failed\n");
-		wait_for_completion_timeout(&vha->nvme_del_done,
-		    msecs_to_jiffies(5000));
+		else
+			wait_for_completion(&vha->nvme_del_done);
 	}
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_nvme.h b/drivers/scsi/qla2xxx/qla_nvme.h
index 7f05fa1..816854a 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.h
+++ b/drivers/scsi/qla2xxx/qla_nvme.h
@@ -14,6 +14,9 @@
 
 #include "qla_def.h"
 
+/* default dev loss time (seconds) before transport tears down ctrl */
+#define NVME_FC_DEV_LOSS_TMO  30
+
 #define NVME_ATIO_CMD_OFF 32
 #define NVME_FIRST_PACKET_CMDLEN (64 - NVME_ATIO_CMD_OFF)
 #define Q2T_NVME_NUM_TAGS 2048
@@ -28,11 +31,11 @@ struct nvme_private {
 	struct srb	*sp;
 	struct nvmefc_ls_req *fd;
 	struct work_struct ls_work;
+	struct work_struct abort_work;
 	int comp_status;
 };
 
-struct nvme_rport {
-	struct nvme_fc_port_info req;
+struct qla_nvme_rport {
 	struct list_head list;
 	struct fc_port *fcport;
 };
@@ -142,7 +145,7 @@ struct pt_ls4_rx_unsol {
 void qla_nvme_register_hba(struct scsi_qla_host *);
 int  qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *);
 void qla_nvme_delete(struct scsi_qla_host *);
-void qla_nvme_abort(struct qla_hw_data *, struct srb *sp);
+void qla_nvme_abort(struct qla_hw_data *, struct srb *sp, int res);
 void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *,
     struct req_que *);
 void qla24xx_async_gffid_sp_done(void *, int);
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index a77c339..872d66d 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1732,7 +1732,7 @@ qla82xx_iospace_config(struct qla_hw_data *ha)
 
 /**
  * qla82xx_pci_config() - Setup ISP82xx PCI configuration registers.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
 */
@@ -1753,7 +1753,7 @@ qla82xx_pci_config(scsi_qla_host_t *vha)
 
 /**
  * qla82xx_reset_chip() - Setup ISP82xx PCI configuration registers.
- * @ha: HA context
+ * @vha: HA context
  *
  * Returns 0 on success.
  */
@@ -2008,11 +2008,10 @@ qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
 		    "MBX pointer ERROR.\n");
 }
 
-/*
+/**
  * qla82xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
  * @irq:
  * @dev_id: SCSI driver HA context
- * @regs:
  *
  * Called by system whenever the host adapter generates an interrupt.
  *
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c
index 525ac35..3a2b028 100644
--- a/drivers/scsi/qla2xxx/qla_nx2.c
+++ b/drivers/scsi/qla2xxx/qla_nx2.c
@@ -280,9 +280,8 @@ qla8044_clear_qsnt_ready(struct scsi_qla_host *vha)
 }
 
 /**
- *
  * qla8044_lock_recovery - Recovers the idc_lock.
- * @ha : Pointer to adapter structure
+ * @vha : Pointer to adapter structure
  *
  * Lock Recovery Register
  * 5-2	Lock recovery owner: Function ID of driver doing lock recovery,
@@ -1639,10 +1638,10 @@ qla8044_set_rst_ready(struct scsi_qla_host *vha)
 
 /**
  * qla8044_need_reset_handler - Code to start reset sequence
- * @ha: pointer to adapter structure
+ * @vha: pointer to adapter structure
  *
  * Note: IDC lock must be held upon entry
- **/
+ */
 static void
 qla8044_need_reset_handler(struct scsi_qla_host *vha)
 {
@@ -1859,8 +1858,8 @@ qla8044_update_idc_reg(struct scsi_qla_host *vha)
 
 /**
  * qla8044_need_qsnt_handler - Code to start qsnt
- * @ha: pointer to adapter structure
- **/
+ * @vha: pointer to adapter structure
+ */
 static void
 qla8044_need_qsnt_handler(struct scsi_qla_host *vha)
 {
@@ -2031,10 +2030,10 @@ qla8044_device_state_handler(struct scsi_qla_host *vha)
 
 /**
  * qla4_8xxx_check_temp - Check the ISP82XX temperature.
- * @ha: adapter block pointer.
+ * @vha: adapter block pointer.
  *
  * Note: The caller should not hold the idc lock.
- **/
+ */
 static int
 qla8044_check_temp(struct scsi_qla_host *vha)
 {
@@ -2071,10 +2070,10 @@ int qla8044_read_temperature(scsi_qla_host_t *vha)
 
 /**
  * qla8044_check_fw_alive  - Check firmware health
- * @ha: Pointer to host adapter structure.
+ * @vha: Pointer to host adapter structure.
  *
  * Context: Interrupt
- **/
+ */
 int
 qla8044_check_fw_alive(struct scsi_qla_host *vha)
 {
diff --git a/drivers/scsi/qla2xxx/qla_nx2.h b/drivers/scsi/qla2xxx/qla_nx2.h
index 83c1b7e..8ba7c1d 100644
--- a/drivers/scsi/qla2xxx/qla_nx2.h
+++ b/drivers/scsi/qla2xxx/qla_nx2.h
@@ -23,10 +23,6 @@
 #define MD_MIU_TEST_AGT_WRDATA_HI		0x410000A4
 #define MD_MIU_TEST_AGT_WRDATA_ULO		0x410000B0
 #define MD_MIU_TEST_AGT_WRDATA_UHI		0x410000B4
-#define MD_MIU_TEST_AGT_RDDATA_LO		0x410000A8
-#define MD_MIU_TEST_AGT_RDDATA_HI		0x410000AC
-#define MD_MIU_TEST_AGT_RDDATA_ULO		0x410000B8
-#define MD_MIU_TEST_AGT_RDDATA_UHI		0x410000BC
 
 /* MIU_TEST_AGT_CTRL flags. work for SIU as well */
 #define MIU_TA_CTL_WRITE_ENABLE	(MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE)
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 5c5dcca4..2bbf0bf 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -397,7 +397,6 @@ static void qla_init_base_qpair(struct scsi_qla_host *vha, struct req_que *req,
 	ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
 	ha->base_qpair->msix = &ha->msix_entries[QLA_MSIX_RSP_Q];
 	INIT_LIST_HEAD(&ha->base_qpair->hints_list);
-	INIT_LIST_HEAD(&ha->base_qpair->nvme_done_list);
 	ha->base_qpair->enable_class_2 = ql2xenableclass2;
 	/* init qpair to this cpu. Will adjust at run time. */
 	qla_cpu_update(rsp->qpair, raw_smp_processor_id());
@@ -496,7 +495,7 @@ static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp)
 		return;
 
 	if (IS_QLAFX00(ha)) {
-		if (rsp && rsp->ring)
+		if (rsp && rsp->ring_fx00)
 			dma_free_coherent(&ha->pdev->dev,
 			    (rsp->length_fx00 + 1) * sizeof(request_t),
 			    rsp->ring_fx00, rsp->dma_fx00);
@@ -1744,7 +1743,7 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
 					sp_get(sp);
 					spin_unlock_irqrestore(qp->qp_lock_ptr,
 					    flags);
-					qla_nvme_abort(ha, sp);
+					qla_nvme_abort(ha, sp, res);
 					spin_lock_irqsave(qp->qp_lock_ptr,
 					    flags);
 				} else if (GET_CMD_SP(sp) &&
@@ -4822,12 +4821,14 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
 			fcport->d_id = e->u.new_sess.id;
 			fcport->flags |= FCF_FABRIC_DEVICE;
 			fcport->fw_login_state = DSC_LS_PLOGI_PEND;
-			if (e->u.new_sess.fc4_type == FC4_TYPE_FCP_SCSI) {
+			if (e->u.new_sess.fc4_type & FS_FC4TYPE_FCP)
 				fcport->fc4_type = FC4_TYPE_FCP_SCSI;
-			} else if (e->u.new_sess.fc4_type == FC4_TYPE_NVME) {
+
+			if (e->u.new_sess.fc4_type & FS_FC4TYPE_NVME) {
 				fcport->fc4_type = FC4_TYPE_OTHER;
 				fcport->fc4f_nvme = FC4_TYPE_NVME;
 			}
+
 			memcpy(fcport->port_name, e->u.new_sess.port_name,
 			    WWN_SIZE);
 		} else {
@@ -5047,7 +5048,8 @@ qla2x00_do_work(struct scsi_qla_host *vha)
 			    e->u.logio.data);
 			break;
 		case QLA_EVT_GPNFT:
-			qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type);
+			qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type,
+			    e->u.gpnft.sp);
 			break;
 		case QLA_EVT_GPNFT_DONE:
 			qla24xx_async_gpnft_done(vha, e->u.iosb.sp);
@@ -6830,7 +6832,7 @@ static int qla2xxx_map_queues(struct Scsi_Host *shost)
 	if (USER_CTRL_IRQ(vha->hw))
 		rc = blk_mq_map_queues(&shost->tag_set);
 	else
-		rc = blk_mq_pci_map_queues(&shost->tag_set, vha->hw->pdev);
+		rc = blk_mq_pci_map_queues(&shost->tag_set, vha->hw->pdev, 0);
 	return rc;
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index d2db86e..04458eb 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -2226,6 +2226,7 @@ qla2x00_erase_flash_sector(struct qla_hw_data *ha, uint32_t addr,
 
 /**
  * qla2x00_get_flash_manufacturer() - Read manufacturer ID from flash chip.
+ * @ha:
  * @man_id: Flash manufacturer ID
  * @flash_id: Flash ID
  */
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index b49ac85..5546ac9 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -961,7 +961,7 @@ qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo)
 	    logo->cmd_count, res);
 }
 
-static void qlt_free_session_done(struct work_struct *work)
+void qlt_free_session_done(struct work_struct *work)
 {
 	struct fc_port *sess = container_of(work, struct fc_port,
 	    free_work);
@@ -1169,11 +1169,14 @@ void qlt_unreg_sess(struct fc_port *sess)
 	sess->last_rscn_gen = sess->rscn_gen;
 	sess->last_login_gen = sess->login_gen;
 
-	if (sess->nvme_flag & NVME_FLAG_REGISTERED)
+	if (sess->nvme_flag & NVME_FLAG_REGISTERED &&
+	    !(sess->nvme_flag & NVME_FLAG_DELETING)) {
+		sess->nvme_flag |= NVME_FLAG_DELETING;
 		schedule_work(&sess->nvme_del_work);
-
-	INIT_WORK(&sess->free_work, qlt_free_session_done);
-	schedule_work(&sess->free_work);
+	} else {
+		INIT_WORK(&sess->free_work, qlt_free_session_done);
+		schedule_work(&sess->free_work);
+	}
 }
 EXPORT_SYMBOL(qlt_unreg_sess);
 
@@ -2023,7 +2026,7 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
 	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
 	if (!sess) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012,
-		    "qla_target(%d): task abort for non-existant session\n",
+		    "qla_target(%d): task abort for non-existent session\n",
 		    vha->vp_idx);
 		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
@@ -2866,7 +2869,6 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm)
 	uint32_t		data_bytes;
 	uint32_t		dif_bytes;
 	uint8_t			bundling = 1;
-	uint8_t			*clr_ptr;
 	struct crc_context	*crc_ctx_pkt = NULL;
 	struct qla_hw_data	*ha;
 	struct ctio_crc2_to_fw	*pkt;
@@ -2995,15 +2997,11 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm)
 
 	/* Allocate CRC context from global pool */
 	crc_ctx_pkt = cmd->ctx =
-	    dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
+	    dma_pool_zalloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
 
 	if (!crc_ctx_pkt)
 		goto crc_queuing_error;
 
-	/* Zero out CTX area. */
-	clr_ptr = (uint8_t *)crc_ctx_pkt;
-	memset(clr_ptr, 0, sizeof(*crc_ctx_pkt));
-
 	crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma;
 	INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list);
 
@@ -6292,10 +6290,11 @@ static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn,
 /**
  * qla_tgt_lport_register - register lport with external module
  *
- * @qla_tgt_ops: Pointer for tcm_qla2xxx qla_tgt_ops
- * @wwpn: Passwd FC target WWPN
- * @callback:  lport initialization callback for tcm_qla2xxx code
  * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data
+ * @phys_wwpn:
+ * @npiv_wwpn:
+ * @npiv_wwnn:
+ * @callback:  lport initialization callback for tcm_qla2xxx code
  */
 int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn,
 		       u64 npiv_wwpn, u64 npiv_wwnn,
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index bb67b5a..728ce74 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -1016,7 +1016,7 @@ extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *, int);
 extern int __init qlt_init(void);
 extern void qlt_exit(void);
 extern void qlt_update_vp_map(struct scsi_qla_host *, int);
-
+extern void qlt_free_session_done(struct work_struct *);
 /*
  * This macro is used during early initializations when host->active_mode
  * is not set. Right now, ha value is ignored.
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 549bef9..0c55d70 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "10.00.00.05-k"
+#define QLA2XXX_VERSION      "10.00.00.06-k"
 
 #define QLA_DRIVER_MAJOR_VER	10
 #define QLA_DRIVER_MINOR_VER	0
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index bda2e64..5d56904 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1584,12 +1584,11 @@ int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
 	struct ql4_chap_table *chap_table;
 	dma_addr_t chap_dma;
 
-	chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
+	chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
 	if (chap_table == NULL)
 		return -ENOMEM;
 
 	chap_size = sizeof(struct ql4_chap_table);
-	memset(chap_table, 0, chap_size);
 
 	if (is_qla40XX(ha))
 		offset = FLASH_CHAP_OFFSET | (idx * chap_size);
@@ -1648,13 +1647,12 @@ int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, char *password,
 	uint32_t chap_size = 0;
 	dma_addr_t chap_dma;
 
-	chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
+	chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
 	if (chap_table == NULL) {
 		ret =  -ENOMEM;
 		goto exit_set_chap;
 	}
 
-	memset(chap_table, 0, sizeof(struct ql4_chap_table));
 	if (bidi)
 		chap_table->flags |= BIT_6; /* peer */
 	else
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 968bd85..43f7358 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -45,6 +45,8 @@ qla4_8xxx_pci_base_offsetfset(struct scsi_qla_host *ha, unsigned long off)
 	return NULL;
 }
 
+static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8,
+				0x410000AC, 0x410000B8, 0x410000BC };
 #define MAX_CRB_XFORM 60
 static unsigned long crb_addr_xform[MAX_CRB_XFORM];
 static int qla4_8xxx_crb_table_initialized;
diff --git a/drivers/scsi/qla4xxx/ql4_nx.h b/drivers/scsi/qla4xxx/ql4_nx.h
index 337d9fc..98fe786 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.h
+++ b/drivers/scsi/qla4xxx/ql4_nx.h
@@ -1022,11 +1022,4 @@ struct qla8xxx_minidump_entry_queue {
 #define MD_MIU_TEST_AGT_WRDATA_ULO		0x410000B0
 #define MD_MIU_TEST_AGT_WRDATA_UHI		0x410000B4
 
-#define MD_MIU_TEST_AGT_RDDATA_LO		0x410000A8
-#define MD_MIU_TEST_AGT_RDDATA_HI		0x410000AC
-#define MD_MIU_TEST_AGT_RDDATA_ULO		0x410000B8
-#define MD_MIU_TEST_AGT_RDDATA_UHI		0x410000BC
-
-static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8,
-				0x410000AC, 0x410000B8, 0x410000BC };
 #endif
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index fc2c97d..94c14ce 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -843,12 +843,10 @@ static int qla4xxx_delete_chap(struct Scsi_Host *shost, uint16_t chap_tbl_idx)
 	uint32_t chap_size;
 	int ret = 0;
 
-	chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
+	chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
 	if (chap_table == NULL)
 		return -ENOMEM;
 
-	memset(chap_table, 0, sizeof(struct ql4_chap_table));
-
 	if (is_qla80XX(ha))
 		max_chap_entries = (ha->hw.flt_chap_size / 2) /
 				   sizeof(struct ql4_chap_table);
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index 2c146b4..ea88906 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -157,6 +157,7 @@ static struct {
 	{ RAID_LEVEL_5, "raid5" },
 	{ RAID_LEVEL_50, "raid50" },
 	{ RAID_LEVEL_6, "raid6" },
+	{ RAID_LEVEL_JBOD, "jbod" },
 };
 
 static const char *raid_level_name(enum raid_level level)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a7e4fba..4c60c26 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -231,7 +231,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
 				"(result %x)\n", cmd->result));
 
 	good_bytes = scsi_bufflen(cmd);
-        if (!blk_rq_is_passthrough(cmd->request)) {
+	if (!blk_rq_is_passthrough(cmd->request)) {
 		int old_good_bytes = good_bytes;
 		drv = scsi_cmd_to_driver(cmd);
 		if (drv->done)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index a5986da..9ef5e3b 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -6,7 +6,7 @@
  *  anything out of the ordinary is seen.
  * ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  *
- * Copyright (C) 2001 - 2017 Douglas Gilbert
+ * Copyright (C) 2001 - 2018 Douglas Gilbert
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -61,8 +61,8 @@
 #include "scsi_logging.h"
 
 /* make sure inq_product_rev string corresponds to this version */
-#define SDEBUG_VERSION "0187"	/* format to fit INQUIRY revision field */
-static const char *sdebug_version_date = "20171202";
+#define SDEBUG_VERSION "0188"	/* format to fit INQUIRY revision field */
+static const char *sdebug_version_date = "20180128";
 
 #define MY_NAME "scsi_debug"
 
@@ -234,6 +234,7 @@ static const char *sdebug_version_date = "20171202";
 #define F_INV_OP		0x200
 #define F_FAKE_RW		0x400
 #define F_M_ACCESS		0x800	/* media access */
+#define F_LONG_DELAY		0x1000
 
 #define FF_RESPOND (F_RL_WLUN_OK | F_SKIP_UA | F_DELAY_OVERR)
 #define FF_MEDIA_IO (F_M_ACCESS | F_FAKE_RW)
@@ -349,7 +350,7 @@ enum sdeb_opcode_index {
 	SDEB_I_XDWRITEREAD = 25,	/* 10 only */
 	SDEB_I_WRITE_BUFFER = 26,
 	SDEB_I_WRITE_SAME = 27,		/* 10, 16 */
-	SDEB_I_SYNC_CACHE = 28,		/* 10 only */
+	SDEB_I_SYNC_CACHE = 28,		/* 10, 16 */
 	SDEB_I_COMP_WRITE = 29,
 	SDEB_I_LAST_ELEMENT = 30,	/* keep this last (previous + 1) */
 };
@@ -382,7 +383,7 @@ static const unsigned char opcode_ind_arr[256] = {
 /* 0x80; 0x80->0x9f: 16 byte cdbs */
 	0, 0, 0, 0, 0, SDEB_I_ATA_PT, 0, 0,
 	SDEB_I_READ, SDEB_I_COMP_WRITE, SDEB_I_WRITE, 0, 0, 0, 0, 0,
-	0, 0, 0, SDEB_I_WRITE_SAME, 0, 0, 0, 0,
+	0, SDEB_I_SYNC_CACHE, 0, SDEB_I_WRITE_SAME, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, SDEB_I_SERV_ACT_IN_16, SDEB_I_SERV_ACT_OUT_16,
 /* 0xa0; 0xa0->0xbf: 12 byte cdbs */
 	SDEB_I_REPORT_LUNS, SDEB_I_ATA_PT, 0, SDEB_I_MAINT_IN,
@@ -398,6 +399,14 @@ static const unsigned char opcode_ind_arr[256] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 };
 
+/*
+ * The following "response" functions return the SCSI mid-level's 4 byte
+ * tuple-in-an-int. To handle commands with an IMMED bit, for a faster
+ * command completion, they can mask their return value with
+ * SDEG_RES_IMMED_MASK .
+ */
+#define SDEG_RES_IMMED_MASK 0x40000000
+
 static int resp_inquiry(struct scsi_cmnd *, struct sdebug_dev_info *);
 static int resp_report_luns(struct scsi_cmnd *, struct sdebug_dev_info *);
 static int resp_requests(struct scsi_cmnd *, struct sdebug_dev_info *);
@@ -420,6 +429,7 @@ static int resp_write_same_16(struct scsi_cmnd *, struct sdebug_dev_info *);
 static int resp_xdwriteread_10(struct scsi_cmnd *, struct sdebug_dev_info *);
 static int resp_comp_write(struct scsi_cmnd *, struct sdebug_dev_info *);
 static int resp_write_buffer(struct scsi_cmnd *, struct sdebug_dev_info *);
+static int resp_sync_cache(struct scsi_cmnd *, struct sdebug_dev_info *);
 
 /*
  * The following are overflow arrays for cdbs that "hit" the same index in
@@ -499,6 +509,12 @@ static const struct opcode_info_t release_iarr[] = {
 	    {6,  0x1f, 0xff, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 };
 
+static const struct opcode_info_t sync_cache_iarr[] = {
+	{0, 0x91, 0, F_LONG_DELAY | F_M_ACCESS, resp_sync_cache, NULL,
+	    {16,  0x6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	     0xff, 0xff, 0xff, 0xff, 0x3f, 0xc7} },	/* SYNC_CACHE (16) */
+};
+
 
 /* This array is accessed via SDEB_I_* values. Make sure all are mapped,
  * plus the terminating elements for logic that scans this table such as
@@ -536,8 +552,8 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
 	{ARRAY_SIZE(write_iarr), 0x8a, 0, F_D_OUT | FF_MEDIA_IO,
 	    resp_write_dt0, write_iarr,			/* WRITE(16) */
 		{16,  0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-		 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7} },		/* WRITE(16) */
-	{0, 0x1b, 0, 0, resp_start_stop, NULL,		/* START STOP UNIT */
+		 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7} },
+	{0, 0x1b, 0, F_LONG_DELAY, resp_start_stop, NULL,/* START STOP UNIT */
 	    {6,  0x1, 0, 0xf, 0xf7, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 	{ARRAY_SIZE(sa_in_16_iarr), 0x9e, 0x10, F_SA_LOW | F_D_IN,
 	    resp_readcap16, sa_in_16_iarr, /* SA_IN(16), READ CAPACITY(16) */
@@ -590,9 +606,10 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
 	    resp_write_same_10, write_same_iarr,	/* WRITE SAME(10) */
 		{10,  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0,
 		 0, 0, 0, 0, 0} },
-	{0, 0x35, 0, F_DELAY_OVERR | FF_MEDIA_IO, NULL, NULL, /* SYNC_CACHE */
+	{ARRAY_SIZE(sync_cache_iarr), 0x35, 0, F_LONG_DELAY | F_M_ACCESS,
+	    resp_sync_cache, sync_cache_iarr,
 	    {10,  0x7, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0,
-	     0, 0, 0, 0} },
+	     0, 0, 0, 0} },			/* SYNC_CACHE (10) */
 	{0, 0x89, 0, F_D_OUT | FF_MEDIA_IO, resp_comp_write, NULL,
 	    {16,  0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0,
 	     0, 0xff, 0x3f, 0xc7} },		/* COMPARE AND WRITE */
@@ -616,6 +633,8 @@ static unsigned int sdebug_guard = DEF_GUARD;
 static int sdebug_lowest_aligned = DEF_LOWEST_ALIGNED;
 static int sdebug_max_luns = DEF_MAX_LUNS;
 static int sdebug_max_queue = SDEBUG_CANQUEUE;	/* per submit queue */
+static unsigned int sdebug_medium_error_start = OPT_MEDIUM_ERR_ADDR;
+static int sdebug_medium_error_count = OPT_MEDIUM_ERR_NUM;
 static atomic_t retired_max_queue;	/* if > 0 then was prior max_queue */
 static int sdebug_ndelay = DEF_NDELAY;	/* if > 0 then unit is nanoseconds */
 static int sdebug_no_lun_0 = DEF_NO_LUN_0;
@@ -649,7 +668,6 @@ static bool sdebug_any_injecting_opt;
 static bool sdebug_verbose;
 static bool have_dif_prot;
 static bool sdebug_statistics = DEF_STATISTICS;
-static bool sdebug_mq_active;
 
 static unsigned int sdebug_store_sectors;
 static sector_t sdebug_capacity;	/* in sectors */
@@ -1155,8 +1173,8 @@ static int inquiry_vpd_84(unsigned char *arr)
 static int inquiry_vpd_85(unsigned char *arr)
 {
 	int num = 0;
-	const char * na1 = "https://www.kernel.org/config";
-	const char * na2 = "http://www.kernel.org/log";
+	const char *na1 = "https://www.kernel.org/config";
+	const char *na2 = "http://www.kernel.org/log";
 	int plen, olen;
 
 	arr[num++] = 0x1;	/* lu, storage config */
@@ -1372,7 +1390,7 @@ static int inquiry_vpd_b2(unsigned char *arr)
 static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 {
 	unsigned char pq_pdt;
-	unsigned char * arr;
+	unsigned char *arr;
 	unsigned char *cmd = scp->cmnd;
 	int alloc_len, n, ret;
 	bool have_wlun, is_disk;
@@ -1523,10 +1541,10 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
 				   0, 0, 0x0, 0x0};
 
-static int resp_requests(struct scsi_cmnd * scp,
-			 struct sdebug_dev_info * devip)
+static int resp_requests(struct scsi_cmnd *scp,
+			 struct sdebug_dev_info *devip)
 {
-	unsigned char * sbuff;
+	unsigned char *sbuff;
 	unsigned char *cmd = scp->cmnd;
 	unsigned char arr[SCSI_SENSE_BUFFERSIZE];
 	bool dsense;
@@ -1584,8 +1602,8 @@ static int resp_requests(struct scsi_cmnd * scp,
 	return fill_from_dev_buffer(scp, arr, len);
 }
 
-static int resp_start_stop(struct scsi_cmnd * scp,
-			   struct sdebug_dev_info * devip)
+static int resp_start_stop(struct scsi_cmnd *scp,
+			   struct sdebug_dev_info *devip)
 {
 	unsigned char *cmd = scp->cmnd;
 	int power_cond, stop;
@@ -1597,7 +1615,7 @@ static int resp_start_stop(struct scsi_cmnd * scp,
 	}
 	stop = !(cmd[4] & 1);
 	atomic_xchg(&devip->stopped, stop);
-	return 0;
+	return (cmd[1] & 0x1) ? SDEG_RES_IMMED_MASK : 0; /* check IMMED bit */
 }
 
 static sector_t get_sdebug_capacity(void)
@@ -1612,8 +1630,8 @@ static sector_t get_sdebug_capacity(void)
 }
 
 #define SDEBUG_READCAP_ARR_SZ 8
-static int resp_readcap(struct scsi_cmnd * scp,
-			struct sdebug_dev_info * devip)
+static int resp_readcap(struct scsi_cmnd *scp,
+			struct sdebug_dev_info *devip)
 {
 	unsigned char arr[SDEBUG_READCAP_ARR_SZ];
 	unsigned int capac;
@@ -1631,8 +1649,8 @@ static int resp_readcap(struct scsi_cmnd * scp,
 }
 
 #define SDEBUG_READCAP16_ARR_SZ 32
-static int resp_readcap16(struct scsi_cmnd * scp,
-			  struct sdebug_dev_info * devip)
+static int resp_readcap16(struct scsi_cmnd *scp,
+			  struct sdebug_dev_info *devip)
 {
 	unsigned char *cmd = scp->cmnd;
 	unsigned char arr[SDEBUG_READCAP16_ARR_SZ];
@@ -1670,11 +1688,11 @@ static int resp_readcap16(struct scsi_cmnd * scp,
 
 #define SDEBUG_MAX_TGTPGS_ARR_SZ 1412
 
-static int resp_report_tgtpgs(struct scsi_cmnd * scp,
-			      struct sdebug_dev_info * devip)
+static int resp_report_tgtpgs(struct scsi_cmnd *scp,
+			      struct sdebug_dev_info *devip)
 {
 	unsigned char *cmd = scp->cmnd;
-	unsigned char * arr;
+	unsigned char *arr;
 	int host_no = devip->sdbg_host->shost->host_no;
 	int n, ret, alen, rlen;
 	int port_group_a, port_group_b, port_a, port_b;
@@ -1926,7 +1944,7 @@ static int resp_rsup_tmfs(struct scsi_cmnd *scp,
 
 /* <<Following mode page info copied from ST318451LW>> */
 
-static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
+static int resp_err_recov_pg(unsigned char *p, int pcontrol, int target)
 {	/* Read-Write Error Recovery page for mode_sense */
 	unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
 					5, 0, 0xff, 0xff};
@@ -1937,7 +1955,7 @@ static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
 	return sizeof(err_recov_pg);
 }
 
-static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target)
+static int resp_disconnect_pg(unsigned char *p, int pcontrol, int target)
 { 	/* Disconnect-Reconnect page for mode_sense */
 	unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
 					 0, 0, 0, 0, 0, 0, 0, 0};
@@ -1948,7 +1966,7 @@ static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target)
 	return sizeof(disconnect_pg);
 }
 
-static int resp_format_pg(unsigned char * p, int pcontrol, int target)
+static int resp_format_pg(unsigned char *p, int pcontrol, int target)
 {       /* Format device page for mode_sense */
 	unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
 				     0, 0, 0, 0, 0, 0, 0, 0,
@@ -1968,7 +1986,7 @@ static unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
 				     0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0,
 				     0, 0, 0, 0};
 
-static int resp_caching_pg(unsigned char * p, int pcontrol, int target)
+static int resp_caching_pg(unsigned char *p, int pcontrol, int target)
 { 	/* Caching page for mode_sense */
 	unsigned char ch_caching_pg[] = {/* 0x8, 18, */ 0x4, 0, 0, 0, 0, 0,
 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -1988,7 +2006,7 @@ static int resp_caching_pg(unsigned char * p, int pcontrol, int target)
 static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
 				    0, 0, 0x2, 0x4b};
 
-static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target)
+static int resp_ctrl_m_pg(unsigned char *p, int pcontrol, int target)
 { 	/* Control mode page for mode_sense */
 	unsigned char ch_ctrl_m_pg[] = {/* 0xa, 10, */ 0x6, 0, 0, 0, 0, 0,
 					0, 0, 0, 0};
@@ -2012,7 +2030,7 @@ static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target)
 }
 
 
-static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target)
+static int resp_iec_m_pg(unsigned char *p, int pcontrol, int target)
 {	/* Informational Exceptions control mode page for mode_sense */
 	unsigned char ch_iec_m_pg[] = {/* 0x1c, 0xa, */ 0x4, 0xf, 0, 0, 0, 0,
 				       0, 0, 0x0, 0x0};
@@ -2027,7 +2045,7 @@ static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target)
 	return sizeof(iec_m_pg);
 }
 
-static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target)
+static int resp_sas_sf_m_pg(unsigned char *p, int pcontrol, int target)
 {	/* SAS SSP mode page - short format for mode_sense */
 	unsigned char sas_sf_m_pg[] = {0x19, 0x6,
 		0x6, 0x0, 0x7, 0xd0, 0x0, 0x0};
@@ -2039,7 +2057,7 @@ static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target)
 }
 
 
-static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target,
+static int resp_sas_pcd_m_spg(unsigned char *p, int pcontrol, int target,
 			      int target_dev_id)
 {	/* SAS phy control and discover mode page for mode_sense */
 	unsigned char sas_pcd_m_pg[] = {0x59, 0x1, 0, 0x64, 0, 0x6, 0, 2,
@@ -2072,7 +2090,7 @@ static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target,
 	return sizeof(sas_pcd_m_pg);
 }
 
-static int resp_sas_sha_m_spg(unsigned char * p, int pcontrol)
+static int resp_sas_sha_m_spg(unsigned char *p, int pcontrol)
 {	/* SAS SSP shared protocol specific port mode subpage */
 	unsigned char sas_sha_m_pg[] = {0x59, 0x2, 0, 0xc, 0, 0x6, 0x10, 0,
 		    0, 0, 0, 0, 0, 0, 0, 0,
@@ -2093,7 +2111,7 @@ static int resp_mode_sense(struct scsi_cmnd *scp,
 	unsigned char dev_spec;
 	int alloc_len, offset, len, target_dev_id;
 	int target = scp->device->id;
-	unsigned char * ap;
+	unsigned char *ap;
 	unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
 	unsigned char *cmd = scp->cmnd;
 	bool dbd, llbaa, msense_6, is_disk, bad_pcode;
@@ -2324,7 +2342,7 @@ static int resp_mode_select(struct scsi_cmnd *scp,
 	return 0;
 }
 
-static int resp_temp_l_pg(unsigned char * arr)
+static int resp_temp_l_pg(unsigned char *arr)
 {
 	unsigned char temp_l_pg[] = {0x0, 0x0, 0x3, 0x2, 0x0, 38,
 				     0x0, 0x1, 0x3, 0x2, 0x0, 65,
@@ -2334,7 +2352,7 @@ static int resp_temp_l_pg(unsigned char * arr)
 	return sizeof(temp_l_pg);
 }
 
-static int resp_ie_l_pg(unsigned char * arr)
+static int resp_ie_l_pg(unsigned char *arr)
 {
 	unsigned char ie_l_pg[] = {0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 38,
 		};
@@ -2712,8 +2730,8 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 	}
 
 	if (unlikely((SDEBUG_OPT_MEDIUM_ERR & sdebug_opts) &&
-		     (lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) &&
-		     ((lba + num) > OPT_MEDIUM_ERR_ADDR))) {
+		     (lba <= (sdebug_medium_error_start + sdebug_medium_error_count - 1)) &&
+		     ((lba + num) > sdebug_medium_error_start))) {
 		/* claim unrecoverable read error */
 		mk_sense_buffer(scp, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0);
 		/* set info field and valid bit for fixed descriptor */
@@ -3562,6 +3580,27 @@ static int resp_get_lba_status(struct scsi_cmnd *scp,
 	return fill_from_dev_buffer(scp, arr, SDEBUG_GET_LBA_STATUS_LEN);
 }
 
+static int resp_sync_cache(struct scsi_cmnd *scp,
+			   struct sdebug_dev_info *devip)
+{
+	u64 lba;
+	u32 num_blocks;
+	u8 *cmd = scp->cmnd;
+
+	if (cmd[0] == SYNCHRONIZE_CACHE) {	/* 10 byte cdb */
+		lba = get_unaligned_be32(cmd + 2);
+		num_blocks = get_unaligned_be16(cmd + 7);
+	} else {				/* SYNCHRONIZE_CACHE(16) */
+		lba = get_unaligned_be64(cmd + 2);
+		num_blocks = get_unaligned_be32(cmd + 10);
+	}
+	if (lba + num_blocks > sdebug_capacity) {
+		mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0);
+		return check_condition_result;
+	}
+	return (cmd[1] & 0x2) ? SDEG_RES_IMMED_MASK : 0; /* check IMMED bit */
+}
+
 #define RL_BUCKET_ELEMS 8
 
 /* Even though each pseudo target has a REPORT LUNS "well known logical unit"
@@ -3727,20 +3766,13 @@ static int resp_xdwriteread_10(struct scsi_cmnd *scp,
 
 static struct sdebug_queue *get_queue(struct scsi_cmnd *cmnd)
 {
-	struct sdebug_queue *sqp = sdebug_q_arr;
+	u32 tag = blk_mq_unique_tag(cmnd->request);
+	u16 hwq = blk_mq_unique_tag_to_hwq(tag);
 
-	if (sdebug_mq_active) {
-		u32 tag = blk_mq_unique_tag(cmnd->request);
-		u16 hwq = blk_mq_unique_tag_to_hwq(tag);
-
-		if (unlikely(hwq >= submit_queues)) {
-			pr_warn("Unexpected hwq=%d, apply modulo\n", hwq);
-			hwq %= submit_queues;
-		}
-		pr_debug("tag=%u, hwq=%d\n", tag, hwq);
-		return sqp + hwq;
-	} else
-		return sqp;
+	pr_debug("tag=%#x, hwq=%d\n", tag, hwq);
+	if (WARN_ON_ONCE(hwq >= submit_queues))
+		hwq = 0;
+	return sdebug_q_arr + hwq;
 }
 
 /* Queued (deferred) command completions converge here. */
@@ -3897,7 +3929,7 @@ static int scsi_debug_slave_alloc(struct scsi_device *sdp)
 	if (sdebug_verbose)
 		pr_info("slave_alloc <%u %u %u %llu>\n",
 		       sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
-	queue_flag_set_unlocked(QUEUE_FLAG_BIDI, sdp->request_queue);
+	blk_queue_flag_set(QUEUE_FLAG_BIDI, sdp->request_queue);
 	return 0;
 }
 
@@ -4066,7 +4098,7 @@ static int scsi_debug_abort(struct scsi_cmnd *SCpnt)
 	return SUCCESS;
 }
 
-static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
+static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt)
 {
 	++num_dev_resets;
 	if (SCpnt && SCpnt->device) {
@@ -4118,7 +4150,7 @@ static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt)
 	return SUCCESS;
 }
 
-static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt)
+static int scsi_debug_bus_reset(struct scsi_cmnd *SCpnt)
 {
 	struct sdebug_host_info *sdbg_host;
 	struct sdebug_dev_info *devip;
@@ -4151,9 +4183,9 @@ static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt)
 	return SUCCESS;
 }
 
-static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt)
+static int scsi_debug_host_reset(struct scsi_cmnd *SCpnt)
 {
-	struct sdebug_host_info * sdbg_host;
+	struct sdebug_host_info *sdbg_host;
 	struct sdebug_dev_info *devip;
 	int k = 0;
 
@@ -4179,7 +4211,7 @@ static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt)
 static void __init sdebug_build_parts(unsigned char *ramp,
 				      unsigned long store_size)
 {
-	struct partition * pp;
+	struct partition *pp;
 	int starts[SDEBUG_MAX_PARTS + 2];
 	int sectors_per_part, num_sectors, k;
 	int heads_by_sects, start_sec, end_sec;
@@ -4262,8 +4294,13 @@ static void clear_queue_stats(void)
 static void setup_inject(struct sdebug_queue *sqp,
 			 struct sdebug_queued_cmd *sqcp)
 {
-	if ((atomic_read(&sdebug_cmnd_count) % abs(sdebug_every_nth)) > 0)
+	if ((atomic_read(&sdebug_cmnd_count) % abs(sdebug_every_nth)) > 0) {
+		if (sdebug_every_nth > 0)
+			sqcp->inj_recovered = sqcp->inj_transport
+				= sqcp->inj_dif
+				= sqcp->inj_dix = sqcp->inj_short = 0;
 		return;
+	}
 	sqcp->inj_recovered = !!(SDEBUG_OPT_RECOVERED_ERR & sdebug_opts);
 	sqcp->inj_transport = !!(SDEBUG_OPT_TRANSPORT_ERR & sdebug_opts);
 	sqcp->inj_dif = !!(SDEBUG_OPT_DIF_ERR & sdebug_opts);
@@ -4278,7 +4315,10 @@ static void setup_inject(struct sdebug_queue *sqp,
  * SCSI_MLQUEUE_HOST_BUSY if temporarily out of resources.
  */
 static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
-			 int scsi_result, int delta_jiff, int ndelay)
+			 int scsi_result,
+			 int (*pfp)(struct scsi_cmnd *,
+				    struct sdebug_dev_info *),
+			 int delta_jiff, int ndelay)
 {
 	unsigned long iflags;
 	int k, num_in_q, qdepth, inject;
@@ -4294,9 +4334,6 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 	}
 	sdp = cmnd->device;
 
-	if (unlikely(sdebug_verbose && scsi_result))
-		sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
-			    __func__, scsi_result);
 	if (delta_jiff == 0)
 		goto respond_in_thread;
 
@@ -4351,7 +4388,6 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 	sqcp = &sqp->qc_arr[k];
 	sqcp->a_cmnd = cmnd;
 	cmnd->host_scribble = (unsigned char *)sqcp;
-	cmnd->result = scsi_result;
 	sd_dp = sqcp->sd_dp;
 	spin_unlock_irqrestore(&sqp->qc_lock, iflags);
 	if (unlikely(sdebug_every_nth && sdebug_any_injecting_opt))
@@ -4361,6 +4397,22 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 		if (sd_dp == NULL)
 			return SCSI_MLQUEUE_HOST_BUSY;
 	}
+
+	cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0;
+	if (cmnd->result & SDEG_RES_IMMED_MASK) {
+		/*
+		 * This is the F_DELAY_OVERR case. No delay.
+		 */
+		cmnd->result &= ~SDEG_RES_IMMED_MASK;
+		delta_jiff = ndelay = 0;
+	}
+	if (cmnd->result == 0 && scsi_result != 0)
+		cmnd->result = scsi_result;
+
+	if (unlikely(sdebug_verbose && cmnd->result))
+		sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
+			    __func__, cmnd->result);
+
 	if (delta_jiff > 0 || ndelay > 0) {
 		ktime_t kt;
 
@@ -4403,7 +4455,10 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 	return 0;
 
 respond_in_thread:	/* call back to mid-layer using invocation thread */
-	cmnd->result = scsi_result;
+	cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0;
+	cmnd->result &= ~SDEG_RES_IMMED_MASK;
+	if (cmnd->result == 0 && scsi_result != 0)
+		cmnd->result = scsi_result;
 	cmnd->scsi_done(cmnd);
 	return 0;
 }
@@ -4440,6 +4495,8 @@ module_param_named(lbprz, sdebug_lbprz, int, S_IRUGO);
 module_param_named(lowest_aligned, sdebug_lowest_aligned, int, S_IRUGO);
 module_param_named(max_luns, sdebug_max_luns, int, S_IRUGO | S_IWUSR);
 module_param_named(max_queue, sdebug_max_queue, int, S_IRUGO | S_IWUSR);
+module_param_named(medium_error_start, sdebug_medium_error_start, int, S_IRUGO | S_IWUSR);
+module_param_named(medium_error_count, sdebug_medium_error_count, int, S_IRUGO | S_IWUSR);
 module_param_named(ndelay, sdebug_ndelay, int, S_IRUGO | S_IWUSR);
 module_param_named(no_lun_0, sdebug_no_lun_0, int, S_IRUGO | S_IWUSR);
 module_param_named(no_uld, sdebug_no_uld, int, S_IRUGO);
@@ -4497,6 +4554,8 @@ MODULE_PARM_DESC(lbprz,
 MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)");
 MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)");
 MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to max(def))");
+MODULE_PARM_DESC(medium_error_start, "starting sector number to return MEDIUM error");
+MODULE_PARM_DESC(medium_error_count, "count of sectors to return follow on MEDIUM error");
 MODULE_PARM_DESC(ndelay, "response delay in nanoseconds (def=0 -> ignore)");
 MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)");
 MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))");
@@ -4526,7 +4585,7 @@ MODULE_PARM_DESC(write_same_length, "Maximum blocks per WRITE SAME cmd (def=0xff
 #define SDEBUG_INFO_LEN 256
 static char sdebug_info[SDEBUG_INFO_LEN];
 
-static const char * scsi_debug_info(struct Scsi_Host * shp)
+static const char *scsi_debug_info(struct Scsi_Host *shp)
 {
 	int k;
 
@@ -4587,9 +4646,8 @@ static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host)
 		   num_host_resets);
 	seq_printf(m, "dix_reads=%d, dix_writes=%d, dif_errors=%d\n",
 		   dix_reads, dix_writes, dif_errors);
-	seq_printf(m, "usec_in_jiffy=%lu, %s=%d, mq_active=%d\n",
-		   TICK_NSEC / 1000, "statistics", sdebug_statistics,
-		   sdebug_mq_active);
+	seq_printf(m, "usec_in_jiffy=%lu, statistics=%d\n", TICK_NSEC / 1000,
+		   sdebug_statistics);
 	seq_printf(m, "cmnd_count=%d, completions=%d, %s=%d, a_tsf=%d\n",
 		   atomic_read(&sdebug_cmnd_count),
 		   atomic_read(&sdebug_completions),
@@ -5450,7 +5508,7 @@ static void __exit scsi_debug_exit(void)
 device_initcall(scsi_debug_init);
 module_exit(scsi_debug_exit);
 
-static void sdebug_release_adapter(struct device * dev)
+static void sdebug_release_adapter(struct device *dev)
 {
 	struct sdebug_host_info *sdbg_host;
 
@@ -5588,6 +5646,7 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
 	struct sdebug_dev_info *devip;
 	u8 *cmd = scp->cmnd;
 	int (*r_pfp)(struct scsi_cmnd *, struct sdebug_dev_info *);
+	int (*pfp)(struct scsi_cmnd *, struct sdebug_dev_info *) = NULL;
 	int k, na;
 	int errsts = 0;
 	u32 flags;
@@ -5612,13 +5671,8 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
 				n += scnprintf(b + n, sb - n, "%02x ",
 					       (u32)cmd[k]);
 		}
-		if (sdebug_mq_active)
-			sdev_printk(KERN_INFO, sdp, "%s: tag=%u, cmd %s\n",
-				    my_name, blk_mq_unique_tag(scp->request),
-				    b);
-		else
-			sdev_printk(KERN_INFO, sdp, "%s: cmd %s\n", my_name,
-				    b);
+		sdev_printk(KERN_INFO, sdp, "%s: tag=%#x, cmd %s\n", my_name,
+			    blk_mq_unique_tag(scp->request), b);
 	}
 	if (fake_host_busy(scp))
 		return SCSI_MLQUEUE_HOST_BUSY;
@@ -5714,20 +5768,30 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
 			return 0;	/* ignore command: make trouble */
 	}
 	if (likely(oip->pfp))
-		errsts = oip->pfp(scp, devip);	/* calls a resp_* function */
-	else if (r_pfp)	/* if leaf function ptr NULL, try the root's */
-		errsts = r_pfp(scp, devip);
+		pfp = oip->pfp;	/* calls a resp_* function */
+	else
+		pfp = r_pfp;    /* if leaf function ptr NULL, try the root's */
 
 fini:
 	if (F_DELAY_OVERR & flags)
-		return schedule_resp(scp, devip, errsts, 0, 0);
-	else
-		return schedule_resp(scp, devip, errsts, sdebug_jdelay,
+		return schedule_resp(scp, devip, errsts, pfp, 0, 0);
+	else if ((sdebug_jdelay || sdebug_ndelay) && (flags & F_LONG_DELAY)) {
+		/*
+		 * If any delay is active, want F_LONG_DELAY to be at least 1
+		 * second and if sdebug_jdelay>0 want a long delay of that
+		 * many seconds.
+		 */
+		int jdelay = (sdebug_jdelay < 2) ? 1 : sdebug_jdelay;
+
+		jdelay = mult_frac(USER_HZ * jdelay, HZ, USER_HZ);
+		return schedule_resp(scp, devip, errsts, pfp, jdelay, 0);
+	} else
+		return schedule_resp(scp, devip, errsts, pfp, sdebug_jdelay,
 				     sdebug_ndelay);
 check_cond:
-	return schedule_resp(scp, devip, check_condition_result, 0, 0);
+	return schedule_resp(scp, devip, check_condition_result, NULL, 0, 0);
 err_out:
-	return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, 0, 0);
+	return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, NULL, 0, 0);
 }
 
 static struct scsi_host_template sdebug_driver_template = {
@@ -5757,7 +5821,7 @@ static struct scsi_host_template sdebug_driver_template = {
 	.track_queue_depth =	1,
 };
 
-static int sdebug_driver_probe(struct device * dev)
+static int sdebug_driver_probe(struct device *dev)
 {
 	int error = 0;
 	struct sdebug_host_info *sdbg_host;
@@ -5782,8 +5846,7 @@ static int sdebug_driver_probe(struct device * dev)
 	}
 	/* Decide whether to tell scsi subsystem that we want mq */
 	/* Following should give the same answer for each host */
-	sdebug_mq_active = shost_use_blk_mq(hpnt) && (submit_queues > 1);
-	if (sdebug_mq_active)
+	if (shost_use_blk_mq(hpnt))
 		hpnt->nr_hw_queues = submit_queues;
 
 	sdbg_host->shost = hpnt;
@@ -5855,7 +5918,7 @@ static int sdebug_driver_probe(struct device * dev)
 	return error;
 }
 
-static int sdebug_driver_remove(struct device * dev)
+static int sdebug_driver_remove(struct device *dev)
 {
 	struct sdebug_host_info *sdbg_host;
 	struct sdebug_dev_info *sdbg_devinfo, *tmp;
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index f3b1172..e5370d7 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -175,11 +175,6 @@ static struct {
 	{"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2},
 	{"HITACHI", "HUS1530", "*", BLIST_NO_DIF},
 	{"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES},
-	{"HITACHI", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HITACHI", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HITACHI", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HITACHI", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HITACHI", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN},	/* HP VA7400 */
 	{"HP", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, /* HP XP Arrays */
 	{"HP", "NetRAID-4M", NULL, BLIST_FORCELUN},
@@ -187,13 +182,7 @@ static struct {
 	{"HP", "C1557A", NULL, BLIST_FORCELUN},
 	{"HP", "C3323-300", "4269", BLIST_NOTQ},
 	{"HP", "C5713A", NULL, BLIST_NOREPORTLUN},
-	{"HP", "DF400", "*", BLIST_REPORTLUN2},
-	{"HP", "DF500", "*", BLIST_REPORTLUN2},
-	{"HP", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HP", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HP", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HP", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HP", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"HP", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2},
 	{"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN},
 	{"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"IBM", "2105", NULL, BLIST_RETRY_HWERROR},
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index ca53a5f..9460391 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -117,6 +117,12 @@ static int scsi_host_eh_past_deadline(struct Scsi_Host *shost)
 /**
  * scmd_eh_abort_handler - Handle command aborts
  * @work:	command to be aborted.
+ *
+ * Note: this function must be called only for a command that has timed out.
+ * Because the block layer marks a request as complete before it calls
+ * scsi_times_out(), a .scsi_done() call from the LLD for a command that has
+ * timed out do not have any effect. Hence it is safe to call
+ * scsi_finish_command() from this function.
  */
 void
 scmd_eh_abort_handler(struct work_struct *work)
@@ -1889,7 +1895,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
 	}
 	return FAILED;
 
-      maybe_retry:
+maybe_retry:
 
 	/* we requeue for retry because the error was retryable, and
 	 * the request was not marked fast fail.  Note that above,
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index c84f931..0dfec0d 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -191,7 +191,19 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy)
 	 */
 	cmd->result = 0;
 	if (q->mq_ops) {
-		scsi_mq_requeue_cmd(cmd);
+		/*
+		 * Before a SCSI command is dispatched,
+		 * get_device(&sdev->sdev_gendev) is called and the host,
+		 * target and device busy counters are increased. Since
+		 * requeuing a request causes these actions to be repeated and
+		 * since scsi_device_unbusy() has already been called,
+		 * put_device(&device->sdev_gendev) must still be called. Call
+		 * put_device() after blk_mq_requeue_request() to avoid that
+		 * removal of the SCSI device can start before requeueing has
+		 * happened.
+		 */
+		blk_mq_requeue_request(cmd->request, true);
+		put_device(&device->sdev_gendev);
 		return;
 	}
 	spin_lock_irqsave(q->queue_lock, flags);
@@ -858,6 +870,17 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 		/* for passthrough error may be set */
 		error = BLK_STS_OK;
 	}
+	/*
+	 * Another corner case: the SCSI status byte is non-zero but 'good'.
+	 * Example: PRE-FETCH command returns SAM_STAT_CONDITION_MET when
+	 * it is able to fit nominated LBs in its cache (and SAM_STAT_GOOD
+	 * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related
+	 * intermediate statuses (both obsolete in SAM-4) as good.
+	 */
+	if (status_byte(result) && scsi_status_is_good(result)) {
+		result = 0;
+		error = BLK_STS_OK;
+	}
 
 	/*
 	 * special case: failed zero length commands always need to
@@ -2144,8 +2167,6 @@ void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q)
 {
 	struct device *dev = shost->dma_dev;
 
-	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
-
 	/*
 	 * this limit is imposed by hardware restrictions
 	 */
@@ -2227,7 +2248,7 @@ struct request_queue *scsi_old_alloc_queue(struct scsi_device *sdev)
 	struct Scsi_Host *shost = sdev->host;
 	struct request_queue *q;
 
-	q = blk_alloc_queue_node(GFP_KERNEL, NUMA_NO_NODE);
+	q = blk_alloc_queue_node(GFP_KERNEL, NUMA_NO_NODE, NULL);
 	if (!q)
 		return NULL;
 	q->cmd_size = sizeof(struct scsi_cmnd) + shost->hostt->cmd_size;
@@ -2243,6 +2264,7 @@ struct request_queue *scsi_old_alloc_queue(struct scsi_device *sdev)
 	}
 
 	__scsi_init_queue(shost, q);
+	blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
 	blk_queue_prep_rq(q, scsi_prep_fn);
 	blk_queue_unprep_rq(q, scsi_unprep_fn);
 	blk_queue_softirq_done(q, scsi_softirq_done);
@@ -2274,6 +2296,7 @@ struct request_queue *scsi_mq_alloc_queue(struct scsi_device *sdev)
 
 	sdev->request_queue->queuedata = sdev;
 	__scsi_init_queue(sdev->host, sdev->request_queue);
+	blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, sdev->request_queue);
 	return sdev->request_queue;
 }
 
@@ -2611,7 +2634,7 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
 	/* try to eat the UNIT_ATTENTION if there are enough retries */
 	do {
 		result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sshdr,
-					  timeout, retries, NULL);
+					  timeout, 1, NULL);
 		if (sdev->removable && scsi_sense_valid(sshdr) &&
 		    sshdr->sense_key == UNIT_ATTENTION)
 			sdev->changed = 1;
diff --git a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c
deleted file mode 100644
index 4891758..0000000
--- a/drivers/scsi/scsi_module.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2003 Christoph Hellwig.
- *	Released under GPL v2.
- *
- * Support for old-style host templates.
- *
- * NOTE:  Do not use this for new drivers ever.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <scsi/scsi_host.h>
-
-
-static int __init init_this_scsi_driver(void)
-{
-	struct scsi_host_template *sht = &driver_template;
-	struct Scsi_Host *shost;
-	struct list_head *l;
-	int error;
-
-	if (!sht->release) {
-		printk(KERN_ERR
-		    "scsi HBA driver %s didn't set a release method.\n",
-		    sht->name);
-		return -EINVAL;
-	}
-
-	sht->module = THIS_MODULE;
-	INIT_LIST_HEAD(&sht->legacy_hosts);
-
-	sht->detect(sht);
-	if (list_empty(&sht->legacy_hosts))
-		return -ENODEV;
-
-	list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) {
-		error = scsi_add_host(shost, NULL);
-		if (error)
-			goto fail;
-		scsi_scan_host(shost);
-	}
-	return 0;
- fail:
-	l = &shost->sht_legacy_list;
-	while ((l = l->prev) != &sht->legacy_hosts)
-		scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list));
-	return error;
-}
-
-static void __exit exit_this_scsi_driver(void)
-{
-	struct scsi_host_template *sht = &driver_template;
-	struct Scsi_Host *shost, *s;
-
-	list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list)
-		scsi_remove_host(shost);
-	list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list)
-		sht->release(shost);
-
-	if (list_empty(&sht->legacy_hosts))
-		return;
-
-	printk(KERN_WARNING "%s did not call scsi_unregister\n", sht->name);
-	dump_stack();
-
-	list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list)
-		scsi_unregister(shost);
-}
-
-module_init(init_this_scsi_driver);
-module_exit(exit_this_scsi_driver);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 91b90f6..1e36c9a 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1292,8 +1292,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 	transport_add_device(&sdev->sdev_gendev);
 	sdev->is_visible = 1;
 
-	error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL);
-
+	error = bsg_scsi_register_queue(rq, &sdev->sdev_gendev);
 	if (error)
 		/* we're treating error on bsg register as non-fatal,
 		 * so pretend nothing went wrong */
@@ -1310,6 +1309,13 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 		}
 	}
 
+	if (sdev->host->hostt->sdev_groups) {
+		error = sysfs_create_groups(&sdev->sdev_gendev.kobj,
+				sdev->host->hostt->sdev_groups);
+		if (error)
+			return error;
+	}
+
 	scsi_autopm_put_device(sdev);
 	return error;
 }
@@ -1349,6 +1355,10 @@ void __scsi_remove_device(struct scsi_device *sdev)
 		if (res != 0)
 			return;
 
+		if (sdev->host->hostt->sdev_groups)
+			sysfs_remove_groups(&sdev->sdev_gendev.kobj,
+					sdev->host->hostt->sdev_groups);
+
 		bsg_unregister_queue(sdev->request_queue);
 		device_unregister(&sdev->sdev_dev);
 		transport_remove_device(dev);
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 736a1f4..08acbab 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -227,8 +227,7 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
 	 * by default assume old behaviour and bounce for any highmem page
 	 */
 	blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
-	queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
-	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
+	blk_queue_flag_set(QUEUE_FLAG_BIDI, q);
 	return 0;
 }
 
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 871ea58..2ca150b 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -822,11 +822,11 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer)
 	 * fails, the device won't let us write to the echo buffer
 	 * so just return failure */
 	
-	const char spi_test_unit_ready[] = {
+	static const char spi_test_unit_ready[] = {
 		TEST_UNIT_READY, 0, 0, 0, 0, 0
 	};
 
-	const char spi_read_buffer_descriptor[] = {
+	static const char spi_read_buffer_descriptor[] = {
 		READ_BUFFER, 0x0b, 0, 0, 0, 0, 0, 0, 4, 0
 	};
 
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 1fa84d6..a6201e6 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -714,7 +714,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
 	case SD_LBP_FULL:
 	case SD_LBP_DISABLE:
 		blk_queue_max_discard_sectors(q, 0);
-		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
+		blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
 		return;
 
 	case SD_LBP_UNMAP:
@@ -747,7 +747,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
 	}
 
 	blk_queue_max_discard_sectors(q, max_blocks * (logical_block_size >> 9));
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
 }
 
 static int sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
@@ -2955,8 +2955,8 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
 	rot = get_unaligned_be16(&buffer[4]);
 
 	if (rot == 1) {
-		queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
-		queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q);
+		blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
+		blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q);
 	}
 
 	if (sdkp->device->type == TYPE_ZBC) {
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index 89cf449..41df75e 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -515,7 +515,8 @@ static inline unsigned long *sd_zbc_alloc_zone_bitmap(struct scsi_disk *sdkp)
  * sd_zbc_get_seq_zones - Parse report zones reply to identify sequential zones
  * @sdkp: disk used
  * @buf: report reply buffer
- * @seq_zone_bitamp: bitmap of sequential zones to set
+ * @buflen: length of @buf
+ * @seq_zones_bitmap: bitmap of sequential zones to set
  *
  * Parse reported zone descriptors in @buf to identify sequential zones and
  * set the reported zone bit in @seq_zones_bitmap accordingly.
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index b2880c7..592b6db 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -40,11 +40,11 @@
 #define BUILD_TIMESTAMP
 #endif
 
-#define DRIVER_VERSION		"1.1.2-126"
+#define DRIVER_VERSION		"1.1.4-115"
 #define DRIVER_MAJOR		1
 #define DRIVER_MINOR		1
-#define DRIVER_RELEASE		2
-#define DRIVER_REVISION		126
+#define DRIVER_RELEASE		4
+#define DRIVER_REVISION		115
 
 #define DRIVER_NAME		"Microsemi PQI Driver (v" \
 				DRIVER_VERSION BUILD_TIMESTAMP ")"
@@ -3898,29 +3898,6 @@ static int pqi_validate_device_capability(struct pqi_ctrl_info *ctrl_info)
 	return 0;
 }
 
-static int pqi_delete_operational_queue(struct pqi_ctrl_info *ctrl_info,
-	bool inbound_queue, u16 queue_id)
-{
-	struct pqi_general_admin_request request;
-	struct pqi_general_admin_response response;
-
-	memset(&request, 0, sizeof(request));
-	request.header.iu_type = PQI_REQUEST_IU_GENERAL_ADMIN;
-	put_unaligned_le16(PQI_GENERAL_ADMIN_IU_LENGTH,
-		&request.header.iu_length);
-	if (inbound_queue)
-		request.function_code =
-			PQI_GENERAL_ADMIN_FUNCTION_DELETE_IQ;
-	else
-		request.function_code =
-			PQI_GENERAL_ADMIN_FUNCTION_DELETE_OQ;
-	put_unaligned_le16(queue_id,
-		&request.data.delete_operational_queue.queue_id);
-
-	return pqi_submit_admin_request_synchronous(ctrl_info, &request,
-		&response);
-}
-
 static int pqi_create_event_queue(struct pqi_ctrl_info *ctrl_info)
 {
 	int rc;
@@ -4038,7 +4015,7 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info,
 	if (rc) {
 		dev_err(&ctrl_info->pci_dev->dev,
 			"error creating inbound AIO queue\n");
-		goto delete_inbound_queue_raid;
+		return rc;
 	}
 
 	queue_group->iq_pi[AIO_PATH] = ctrl_info->iomem_base +
@@ -4066,7 +4043,7 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info,
 	if (rc) {
 		dev_err(&ctrl_info->pci_dev->dev,
 			"error changing queue property\n");
-		goto delete_inbound_queue_aio;
+		return rc;
 	}
 
 	/*
@@ -4096,7 +4073,7 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info,
 	if (rc) {
 		dev_err(&ctrl_info->pci_dev->dev,
 			"error creating outbound queue\n");
-		goto delete_inbound_queue_aio;
+		return rc;
 	}
 
 	queue_group->oq_ci = ctrl_info->iomem_base +
@@ -4105,16 +4082,6 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info,
 			&response.data.create_operational_oq.oq_ci_offset);
 
 	return 0;
-
-delete_inbound_queue_aio:
-	pqi_delete_operational_queue(ctrl_info, true,
-		queue_group->iq_id[AIO_PATH]);
-
-delete_inbound_queue_raid:
-	pqi_delete_operational_queue(ctrl_info, true,
-		queue_group->iq_id[RAID_PATH]);
-
-	return rc;
 }
 
 static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info)
@@ -5348,7 +5315,7 @@ static int pqi_map_queues(struct Scsi_Host *shost)
 {
 	struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost);
 
-	return blk_mq_pci_map_queues(&shost->tag_set, ctrl_info->pci_dev);
+	return blk_mq_pci_map_queues(&shost->tag_set, ctrl_info->pci_dev, 0);
 }
 
 static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info,
@@ -6797,6 +6764,14 @@ static __maybe_unused int pqi_resume(struct pci_dev *pci_dev)
 static const struct pci_device_id pqi_pci_id_table[] = {
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x105b, 0x1211)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x105b, 0x1321)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
 			       0x152d, 0x8a22)
 	},
 	{
@@ -6817,6 +6792,38 @@ static const struct pci_device_id pqi_pci_id_table[] = {
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x193d, 0x8460)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x193d, 0x8461)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x193d, 0xf460)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x193d, 0xf461)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x1bd4, 0x0045)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x1bd4, 0x0046)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x1bd4, 0x0047)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x1bd4, 0x0048)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
 			       PCI_VENDOR_ID_ADAPTEC2, 0x0110)
 	},
 	{
@@ -6917,6 +6924,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1282)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
 			       PCI_VENDOR_ID_ADAPTEC2, 0x1300)
 	},
 	{
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 9be34d3..0cf25d7 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -525,6 +525,8 @@ static int sr_block_open(struct block_device *bdev, fmode_t mode)
 	struct scsi_cd *cd;
 	int ret = -ENXIO;
 
+	check_disk_change(bdev);
+
 	mutex_lock(&sr_mutex);
 	cd = scsi_cd_get(bdev->bd_disk);
 	if (cd) {
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
index d50c5ed8..0b1421c 100644
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -210,7 +210,7 @@ static int esp_sun3x_probe(struct platform_device *dev)
 	esp = shost_priv(host);
 
 	esp->host = host;
-	esp->dev = dev;
+	esp->dev = &dev->dev;
 	esp->ops = &sun3x_esp_ops;
 
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
deleted file mode 100644
index 5bdcbe8..0000000
--- a/drivers/scsi/sym53c416.c
+++ /dev/null
@@ -1,844 +0,0 @@
-/*
- *  sym53c416.c
- *  Low-level SCSI driver for sym53c416 chip.
- *  Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com)
- * 
- *  Changes : 
- * 
- *  Marcelo Tosatti <marcelo@conectiva.com.br> : Added io_request_lock locking
- *  Alan Cox <alan@lxorguk.ukuu.org.uk> : Cleaned up code formatting
- *				 Fixed an irq locking bug
- *				 Added ISAPnP support
- *  Bjoern A. Zeeb <bzeeb@zabbadoz.net> : Initial irq locking updates
- *					  Added another card with ISAPnP support
- * 
- *  LILO command line usage: sym53c416=<PORTBASE>[,<IRQ>]
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2, or (at your option) any
- *  later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <linux/blkdev.h>
-#include <linux/isapnp.h>
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "sym53c416.h"
-
-#define VERSION_STRING        "Version 1.0.0-ac"
-
-#define TC_LOW       0x00     /* Transfer counter low        */
-#define TC_MID       0x01     /* Transfer counter mid        */
-#define SCSI_FIFO    0x02     /* SCSI FIFO register          */
-#define COMMAND_REG  0x03     /* Command Register            */
-#define STATUS_REG   0x04     /* Status Register (READ)      */
-#define DEST_BUS_ID  0x04     /* Destination Bus ID (WRITE)  */
-#define INT_REG      0x05     /* Interrupt Register (READ)   */
-#define TOM          0x05     /* Time out multiplier (WRITE) */
-#define STP          0x06     /* Synchronous Transfer period */
-#define SYNC_OFFSET  0x07     /* Synchronous Offset          */
-#define CONF_REG_1   0x08     /* Configuration register 1    */
-#define CONF_REG_2   0x0B     /* Configuration register 2    */
-#define CONF_REG_3   0x0C     /* Configuration register 3    */
-#define CONF_REG_4   0x0D     /* Configuration register 4    */
-#define TC_HIGH      0x0E     /* Transfer counter high       */
-#define PIO_FIFO_1   0x10     /* PIO FIFO register 1         */
-#define PIO_FIFO_2   0x11     /* PIO FIFO register 2         */
-#define PIO_FIFO_3   0x12     /* PIO FIFO register 3         */
-#define PIO_FIFO_4   0x13     /* PIO FIFO register 4         */
-#define PIO_FIFO_CNT 0x14     /* PIO FIFO count              */
-#define PIO_INT_REG  0x15     /* PIO interrupt register      */
-#define CONF_REG_5   0x16     /* Configuration register 5    */
-#define FEATURE_EN   0x1D     /* Feature Enable register     */
-
-/* Configuration register 1 entries: */
-/* Bits 2-0: SCSI ID of host adapter */
-#define SCM    0x80                     /* Slow Cable Mode              */
-#define SRID   0x40                     /* SCSI Reset Interrupt Disable */
-#define PTM    0x20                     /* Parity Test Mode             */
-#define EPC    0x10                     /* Enable Parity Checking       */
-#define CTME   0x08                     /* Special Test Mode            */
-
-/* Configuration register 2 entries: */
-#define FE     0x40                     /* Features Enable              */
-#define SCSI2  0x08                     /* SCSI 2 Enable                */
-#define TBPA   0x04                     /* Target Bad Parity Abort      */
-
-/* Configuration register 3 entries: */
-#define IDMRC  0x80                     /* ID Message Reserved Check    */
-#define QTE    0x40                     /* Queue Tag Enable             */
-#define CDB10  0x20                     /* Command Descriptor Block 10  */
-#define FSCSI  0x10                     /* FastSCSI                     */
-#define FCLK   0x08                     /* FastClock                    */
-
-/* Configuration register 4 entries: */
-#define RBS    0x08                     /* Register bank select         */
-#define EAN    0x04                     /* Enable Active Negotiation    */
-
-/* Configuration register 5 entries: */
-#define LPSR   0x80                     /* Lower Power SCSI Reset       */
-#define IE     0x20                     /* Interrupt Enable             */
-#define LPM    0x02                     /* Low Power Mode               */
-#define WSE0   0x01                     /* 0WS Enable                   */
-
-/* Interrupt register entries: */
-#define SRST   0x80                     /* SCSI Reset                   */
-#define ILCMD  0x40                     /* Illegal Command              */
-#define DIS    0x20                     /* Disconnect                   */
-#define BS     0x10                     /* Bus Service                  */
-#define FC     0x08                     /* Function Complete            */
-#define RESEL  0x04                     /* Reselected                   */
-#define SI     0x03                     /* Selection Interrupt          */
-
-/* Status Register Entries: */
-#define SCI    0x80                     /* SCSI Core Int                */
-#define GE     0x40                     /* Gross Error                  */
-#define PE     0x20                     /* Parity Error                 */
-#define TC     0x10                     /* Terminal Count               */
-#define VGC    0x08                     /* Valid Group Code             */
-#define PHBITS 0x07                     /* Phase bits                   */
-
-/* PIO Interrupt Register Entries: */
-#define SCI    0x80                     /* SCSI Core Int                */
-#define PFI    0x40                     /* PIO FIFO Interrupt           */
-#define FULL   0x20                     /* PIO FIFO Full                */
-#define EMPTY  0x10                     /* PIO FIFO Empty               */
-#define CE     0x08                     /* Collision Error              */
-#define OUE    0x04                     /* Overflow / Underflow error   */
-#define FIE    0x02                     /* Full Interrupt Enable        */
-#define EIE    0x01                     /* Empty Interrupt Enable       */
-
-/* SYM53C416 SCSI phases (lower 3 bits of SYM53C416_STATUS_REG) */
-#define PHASE_DATA_OUT    0x00
-#define PHASE_DATA_IN     0x01
-#define PHASE_COMMAND     0x02
-#define PHASE_STATUS      0x03
-#define PHASE_RESERVED_1  0x04
-#define PHASE_RESERVED_2  0x05
-#define PHASE_MESSAGE_OUT 0x06
-#define PHASE_MESSAGE_IN  0x07
-
-/* SYM53C416 core commands */
-#define NOOP                      0x00
-#define FLUSH_FIFO                0x01
-#define RESET_CHIP                0x02
-#define RESET_SCSI_BUS            0x03
-#define DISABLE_SEL_RESEL         0x45
-#define RESEL_SEQ                 0x40
-#define SEL_WITHOUT_ATN_SEQ       0x41
-#define SEL_WITH_ATN_SEQ          0x42
-#define SEL_WITH_ATN_AND_STOP_SEQ 0x43
-#define ENABLE_SEL_RESEL          0x44
-#define SEL_WITH_ATN3_SEQ         0x46
-#define RESEL3_SEQ                0x47
-#define SND_MSG                   0x20
-#define SND_STAT                  0x21
-#define SND_DATA                  0x22
-#define DISCONNECT_SEQ            0x23
-#define TERMINATE_SEQ             0x24
-#define TARGET_COMM_COMPLETE_SEQ  0x25
-#define DISCONN                   0x27
-#define RECV_MSG_SEQ              0x28
-#define RECV_CMD                  0x29
-#define RECV_DATA                 0x2A
-#define RECV_CMD_SEQ              0x2B
-#define TARGET_ABORT_PIO          0x04
-#define TRANSFER_INFORMATION      0x10
-#define INIT_COMM_COMPLETE_SEQ    0x11
-#define MSG_ACCEPTED              0x12
-#define TRANSFER_PAD              0x18
-#define SET_ATN                   0x1A
-#define RESET_ATN                 0x1B
-#define ILLEGAL                   0xFF
-
-#define PIO_MODE                  0x80
-
-#define IO_RANGE 0x20         /* 0x00 - 0x1F                   */
-#define ID       "sym53c416"	/* Attention: copied to the sym53c416.h */
-#define PIO_SIZE 128          /* Size of PIO fifo is 128 bytes */
-
-#define READ_TIMEOUT              150
-#define WRITE_TIMEOUT             150
-
-#ifdef MODULE
-
-#define sym53c416_base sym53c416
-#define sym53c416_base_1 sym53c416_1
-#define sym53c416_base_2 sym53c416_2
-#define sym53c416_base_3 sym53c416_3
-
-static unsigned int sym53c416_base[2];
-static unsigned int sym53c416_base_1[2];
-static unsigned int sym53c416_base_2[2];
-static unsigned int sym53c416_base_3[2];
-
-#endif
-
-#define MAXHOSTS 4
-
-#define SG_ADDRESS(buffer)     ((char *) sg_virt((buffer)))
-
-enum phases
-{
-	idle,
-	data_out,
-	data_in,
-	command_ph,
-	status_ph,
-	message_out,
-	message_in
-};
-
-typedef struct
-{
-	int base;
-	int irq;
-	int scsi_id;
-} host;
-
-static host hosts[MAXHOSTS] = {
-                       {0, 0, SYM53C416_SCSI_ID},
-                       {0, 0, SYM53C416_SCSI_ID},
-                       {0, 0, SYM53C416_SCSI_ID},
-                       {0, 0, SYM53C416_SCSI_ID}
-                       };
-
-static int host_index = 0;
-static char info[120];
-static Scsi_Cmnd *current_command = NULL;
-static int fastpio = 1;
-
-static int probeaddrs[] = {0x200, 0x220, 0x240, 0};
-
-static void sym53c416_set_transfer_counter(int base, unsigned int len)
-{
-	/* Program Transfer Counter */
-	outb(len & 0x0000FF, base + TC_LOW);
-	outb((len & 0x00FF00) >> 8, base + TC_MID);
-	outb((len & 0xFF0000) >> 16, base + TC_HIGH);
-}
-
-static DEFINE_SPINLOCK(sym53c416_lock);
-
-/* Returns the number of bytes read */
-static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len)
-{
-	unsigned int orig_len = len;
-	unsigned long flags = 0;
-	unsigned int bytes_left;
-	unsigned long i;
-	int timeout = READ_TIMEOUT;
-
-	/* Do transfer */
-	spin_lock_irqsave(&sym53c416_lock, flags);
-	while(len && timeout)
-	{
-		bytes_left = inb(base + PIO_FIFO_CNT); /* Number of bytes in the PIO FIFO */
-		if(fastpio && bytes_left > 3)
-		{
-			insl(base + PIO_FIFO_1, buffer, bytes_left >> 2);
-			buffer += bytes_left & 0xFC;
-			len -= bytes_left & 0xFC;
-		}
-		else if(bytes_left > 0)
-		{
-			len -= bytes_left;
-			for(; bytes_left > 0; bytes_left--)
-				*(buffer++) = inb(base + PIO_FIFO_1);
-		}
-		else
-		{
-			i = jiffies + timeout;
-			spin_unlock_irqrestore(&sym53c416_lock, flags);
-			while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & EMPTY) && timeout)
-				if(inb(base + PIO_INT_REG) & SCI)
-					timeout = 0;
-			spin_lock_irqsave(&sym53c416_lock, flags);
-			if(inb(base + PIO_INT_REG) & EMPTY)
-				timeout = 0;
-		}
-	}
-	spin_unlock_irqrestore(&sym53c416_lock, flags);
-	return orig_len - len;
-}
-
-/* Returns the number of bytes written */
-static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer, unsigned int len)
-{
-	unsigned int orig_len = len;
-	unsigned long flags = 0;
-	unsigned int bufferfree;
-	unsigned long i;
-	unsigned int timeout = WRITE_TIMEOUT;
-
-	/* Do transfer */
-	spin_lock_irqsave(&sym53c416_lock, flags);
-	while(len && timeout)
-	{
-		bufferfree = PIO_SIZE - inb(base + PIO_FIFO_CNT);
-		if(bufferfree > len)
-			bufferfree = len;
-		if(fastpio && bufferfree > 3)
-		{
-			outsl(base + PIO_FIFO_1, buffer, bufferfree >> 2);
-			buffer += bufferfree & 0xFC;
-			len -= bufferfree & 0xFC;
-		}
-		else if(bufferfree > 0)
-		{
-			len -= bufferfree;
-			for(; bufferfree > 0; bufferfree--)
-				outb(*(buffer++), base + PIO_FIFO_1);
-		}
-		else
-		{
-			i = jiffies + timeout;
-			spin_unlock_irqrestore(&sym53c416_lock, flags);
-			while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & FULL) && timeout)
-				;
-			spin_lock_irqsave(&sym53c416_lock, flags);
-			if(inb(base + PIO_INT_REG) & FULL)
-				timeout = 0;
-		}
-	}
-	spin_unlock_irqrestore(&sym53c416_lock, flags);
-	return orig_len - len;
-}
-
-static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id)
-{
-	struct Scsi_Host *dev = dev_id;
-	int base = dev->io_port;
-	int i;
-	unsigned long flags = 0;
-	unsigned char status_reg, pio_int_reg, int_reg;
-	struct scatterlist *sg;
-	unsigned int tot_trans = 0;
-
-	spin_lock_irqsave(dev->host_lock,flags);
-	status_reg = inb(base + STATUS_REG);
-	pio_int_reg = inb(base + PIO_INT_REG);
-	int_reg = inb(base + INT_REG);
-	spin_unlock_irqrestore(dev->host_lock, flags);
-
-	/* First, we handle error conditions */
-	if(int_reg & SCI)         /* SCSI Reset */
-	{
-		printk(KERN_DEBUG "sym53c416: Reset received\n");
-		current_command->SCp.phase = idle;
-		current_command->result = DID_RESET << 16;
-		spin_lock_irqsave(dev->host_lock, flags);
-		current_command->scsi_done(current_command);
-		spin_unlock_irqrestore(dev->host_lock, flags);
-		goto out;
-	}
-	if(int_reg & ILCMD)       /* Illegal Command */
-	{
-		printk(KERN_WARNING "sym53c416: Illegal Command: 0x%02x.\n", inb(base + COMMAND_REG));
-		current_command->SCp.phase = idle;
-		current_command->result = DID_ERROR << 16;
-		spin_lock_irqsave(dev->host_lock, flags);
-		current_command->scsi_done(current_command);
-		spin_unlock_irqrestore(dev->host_lock, flags);
-		goto out;
-	}
-	if(status_reg & GE)         /* Gross Error */
-	{
-		printk(KERN_WARNING "sym53c416: Controller reports gross error.\n");
-		current_command->SCp.phase = idle;
-		current_command->result = DID_ERROR << 16;
-		spin_lock_irqsave(dev->host_lock, flags);
-		current_command->scsi_done(current_command);
-		spin_unlock_irqrestore(dev->host_lock, flags);
-		goto out;
-	}
-	if(status_reg & PE)         /* Parity Error */
-	{
-		printk(KERN_WARNING "sym53c416:SCSI parity error.\n");
-		current_command->SCp.phase = idle;
-		current_command->result = DID_PARITY << 16;
-		spin_lock_irqsave(dev->host_lock, flags);
-		current_command->scsi_done(current_command);
-		spin_unlock_irqrestore(dev->host_lock, flags);
-		goto out;
-	}
-	if(pio_int_reg & (CE | OUE))
-	{
-		printk(KERN_WARNING "sym53c416: PIO interrupt error.\n");
-		current_command->SCp.phase = idle;
-		current_command->result = DID_ERROR << 16;
-		spin_lock_irqsave(dev->host_lock, flags);
-		current_command->scsi_done(current_command);
-		spin_unlock_irqrestore(dev->host_lock, flags);
-		goto out;
-	}
-	if(int_reg & DIS)           /* Disconnect */
-	{
-		if(current_command->SCp.phase != message_in)
-			current_command->result = DID_NO_CONNECT << 16;
-		else
-			current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16);
-		current_command->SCp.phase = idle;
-		spin_lock_irqsave(dev->host_lock, flags);
-		current_command->scsi_done(current_command);
-		spin_unlock_irqrestore(dev->host_lock, flags);
-		goto out;
-	}
-	/* Now we handle SCSI phases         */
-
-	switch(status_reg & PHBITS)       /* Filter SCSI phase out of status reg */
-	{
-		case PHASE_DATA_OUT:
-		{
-			if(int_reg & BS)
-			{
-				current_command->SCp.phase = data_out;
-				outb(FLUSH_FIFO, base + COMMAND_REG);
-				sym53c416_set_transfer_counter(base,
-							       scsi_bufflen(current_command));
-				outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
-
-				scsi_for_each_sg(current_command,
-						 sg, scsi_sg_count(current_command), i) {
-					tot_trans += sym53c416_write(base,
-								     SG_ADDRESS(sg),
-								     sg->length);
-				}
-				if(tot_trans < current_command->underflow)
-					printk(KERN_WARNING "sym53c416: Underflow, wrote %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow);
-			}
-			break;
-		}
-
-		case PHASE_DATA_IN:
-		{
-			if(int_reg & BS)
-			{
-				current_command->SCp.phase = data_in;
-				outb(FLUSH_FIFO, base + COMMAND_REG);
-				sym53c416_set_transfer_counter(base,
-							       scsi_bufflen(current_command));
-
-				outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
-
-				scsi_for_each_sg(current_command,
-						 sg, scsi_sg_count(current_command), i) {
-					tot_trans += sym53c416_read(base,
-								    SG_ADDRESS(sg),
-								    sg->length);
-				}
-				if(tot_trans < current_command->underflow)
-					printk(KERN_WARNING "sym53c416: Underflow, read %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow);
-			}
-			break;
-		}
-
-		case PHASE_COMMAND:
-		{
-			current_command->SCp.phase = command_ph;
-			printk(KERN_ERR "sym53c416: Unknown interrupt in command phase.\n");
-			break;
-		}
-
-		case PHASE_STATUS:
-		{
-			current_command->SCp.phase = status_ph;
-			outb(FLUSH_FIFO, base + COMMAND_REG);
-			outb(INIT_COMM_COMPLETE_SEQ, base + COMMAND_REG);
-			break;
-		}
-		
-		case PHASE_RESERVED_1:
-		case PHASE_RESERVED_2:
-		{
-			printk(KERN_ERR "sym53c416: Reserved phase occurred.\n");
-			break;
-		}
-
-		case PHASE_MESSAGE_OUT:
-		{
-			current_command->SCp.phase = message_out;
-			outb(SET_ATN, base + COMMAND_REG);
-			outb(MSG_ACCEPTED, base + COMMAND_REG);
-			break;
-		}
-
-		case PHASE_MESSAGE_IN:
-		{
-			current_command->SCp.phase = message_in;
-			current_command->SCp.Status = inb(base + SCSI_FIFO);
-			current_command->SCp.Message = inb(base + SCSI_FIFO);
-			if(current_command->SCp.Message == SAVE_POINTERS || current_command->SCp.Message == DISCONNECT)
-				outb(SET_ATN, base + COMMAND_REG);
-			outb(MSG_ACCEPTED, base + COMMAND_REG);
-			break;
-		}
-	}
-out:
-	return IRQ_HANDLED;
-}
-
-static void sym53c416_init(int base, int scsi_id)
-{
-	outb(RESET_CHIP, base + COMMAND_REG);
-	outb(NOOP, base + COMMAND_REG);
-	outb(0x99, base + TOM); /* Time out of 250 ms */
-	outb(0x05, base + STP);
-	outb(0x00, base + SYNC_OFFSET);
-	outb(EPC | scsi_id, base + CONF_REG_1);
-	outb(FE | SCSI2 | TBPA, base + CONF_REG_2);
-	outb(IDMRC | QTE | CDB10 | FSCSI | FCLK, base + CONF_REG_3);
-	outb(0x83 | EAN, base + CONF_REG_4);
-	outb(IE | WSE0, base + CONF_REG_5);
-	outb(0, base + FEATURE_EN);
-}
-
-static int sym53c416_probeirq(int base, int scsi_id)
-{
-	int irq, irqs;
-	unsigned long i;
-
-	/* Clear interrupt register */
-	inb(base + INT_REG);
-	/* Start probing for irq's */
-	irqs = probe_irq_on();
-	/* Reinit chip */
-	sym53c416_init(base, scsi_id);
-	/* Cause interrupt */
-	outb(NOOP, base + COMMAND_REG);
-	outb(ILLEGAL, base + COMMAND_REG);
-	outb(0x07, base + DEST_BUS_ID);
-	outb(0x00, base + DEST_BUS_ID);
-	/* Wait for interrupt to occur */
-	i = jiffies + 20;
-	while(time_before(jiffies, i) && !(inb(base + STATUS_REG) & SCI))
-		barrier();
-	if(time_before_eq(i, jiffies))	/* timed out */
-		return 0;
-	/* Get occurred irq */
-	irq = probe_irq_off(irqs);
-	sym53c416_init(base, scsi_id);
-	return irq;
-}
-
-/* Setup: sym53c416=base,irq */
-void sym53c416_setup(char *str, int *ints)
-{
-	int i;
-
-	if(host_index >= MAXHOSTS)
-	{
-		printk(KERN_WARNING "sym53c416: Too many hosts defined\n");
-		return;
-	}
-	if(ints[0] < 1 || ints[0] > 2)
-	{
-		printk(KERN_ERR "sym53c416: Wrong number of parameters:\n");
-		printk(KERN_ERR "sym53c416: usage: sym53c416=<base>[,<irq>]\n");
-		return;
-	}
-	for(i = 0; i < host_index && i >= 0; i++)
-	        if(hosts[i].base == ints[1])
-        		i = -2;
-	if(i >= 0)
-	{
-        	hosts[host_index].base = ints[1];
-        	hosts[host_index].irq = (ints[0] == 2)? ints[2] : 0;
-        	host_index++;
-	}
-}
-
-static int sym53c416_test(int base)
-{
-	outb(RESET_CHIP, base + COMMAND_REG);
-	outb(NOOP, base + COMMAND_REG);
-	if(inb(base + COMMAND_REG) != NOOP)
-		return 0;
-	if(!inb(base + TC_HIGH) || inb(base + TC_HIGH) == 0xFF)
-		return 0;
-	if((inb(base + PIO_INT_REG) & (FULL | EMPTY | CE | OUE | FIE | EIE)) != EMPTY)
-		return 0;
-	return 1;
-}
-
-
-static struct isapnp_device_id id_table[] = {
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('S','L','I'), ISAPNP_FUNCTION(0x4161), 0 },
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('S','L','I'), ISAPNP_FUNCTION(0x4163), 0 },
-	{	ISAPNP_DEVICE_SINGLE_END }
-};
-
-MODULE_DEVICE_TABLE(isapnp, id_table);
-
-static void sym53c416_probe(void)
-{
-	int *base = probeaddrs;
-	int ints[2];
-
-	ints[0] = 1;
-	for(; *base; base++) {
-		if (request_region(*base, IO_RANGE, ID)) {
-			if (sym53c416_test(*base)) {
-				ints[1] = *base;
-				sym53c416_setup(NULL, ints);
-			}
-			release_region(*base, IO_RANGE);
-		}
-	}
-}
-
-int __init sym53c416_detect(struct scsi_host_template *tpnt)
-{
-	unsigned long flags;
-	struct Scsi_Host * shpnt = NULL;
-	int i;
-	int count;
-	struct pnp_dev *idev = NULL;
-	
-#ifdef MODULE
-	int ints[3];
-
-	ints[0] = 2;
-	if(sym53c416_base[0])
-	{
-		ints[1] = sym53c416_base[0];
-		ints[2] = sym53c416_base[1];
-		sym53c416_setup(NULL, ints);
-	}
-	if(sym53c416_base_1[0])
-	{
-		ints[1] = sym53c416_base_1[0];
-		ints[2] = sym53c416_base_1[1];
-		sym53c416_setup(NULL, ints);
-	}
-	if(sym53c416_base_2[0])
-	{
-		ints[1] = sym53c416_base_2[0];
-		ints[2] = sym53c416_base_2[1];
-		sym53c416_setup(NULL, ints);
-	}
-	if(sym53c416_base_3[0])
-	{
-		ints[1] = sym53c416_base_3[0];
-		ints[2] = sym53c416_base_3[1];
-		sym53c416_setup(NULL, ints);
-	}
-#endif
-	printk(KERN_INFO "sym53c416.c: %s\n", VERSION_STRING);
-
-	for (i=0; id_table[i].vendor != 0; i++) {
-		while((idev=pnp_find_dev(NULL, id_table[i].vendor,
-					id_table[i].function, idev))!=NULL)
-		{
-			int i[3];
-
-			if(pnp_device_attach(idev)<0)
-			{
-				printk(KERN_WARNING "sym53c416: unable to attach PnP device.\n");
-				continue;
-			}
-			if(pnp_activate_dev(idev) < 0)
-			{
-				printk(KERN_WARNING "sym53c416: unable to activate PnP device.\n");
-				pnp_device_detach(idev);
-				continue;
-			
-			}
-
-			i[0] = 2;
-			i[1] = pnp_port_start(idev, 0);
- 			i[2] = pnp_irq(idev, 0);
-
-			printk(KERN_INFO "sym53c416: ISAPnP card found and configured at 0x%X, IRQ %d.\n",
-				i[1], i[2]);
- 			sym53c416_setup(NULL, i);
- 		}
-	}
-	sym53c416_probe();
-
-	/* Now we register and set up each host adapter found... */
-	for(count = 0, i = 0; i < host_index; i++) {
-		if (!request_region(hosts[i].base, IO_RANGE, ID))
-			continue;
-		if (!sym53c416_test(hosts[i].base)) {
-			printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base);
-			goto fail_release_region;
-		}
-
-		/* We don't have an irq yet, so we should probe for one */
-		if (!hosts[i].irq)
-			hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id);
-		if (!hosts[i].irq)
-			goto fail_release_region;
-	
-		shpnt = scsi_register(tpnt, 0);
-		if (!shpnt)
-			goto fail_release_region;
-		/* Request for specified IRQ */
-		if (request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
-			goto fail_free_host;
-
-		spin_lock_irqsave(&sym53c416_lock, flags);
-		shpnt->unique_id = hosts[i].base;
-		shpnt->io_port = hosts[i].base;
-		shpnt->n_io_port = IO_RANGE;
-		shpnt->irq = hosts[i].irq;
-		shpnt->this_id = hosts[i].scsi_id;
-		sym53c416_init(hosts[i].base, hosts[i].scsi_id);
-		count++;
-		spin_unlock_irqrestore(&sym53c416_lock, flags);
-		continue;
-
- fail_free_host:
-		scsi_unregister(shpnt);
- fail_release_region:
-		release_region(hosts[i].base, IO_RANGE);
-	}
-	return count;
-}
-
-const char *sym53c416_info(struct Scsi_Host *SChost)
-{
-	int i;
-	int base = SChost->io_port;
-	int irq = SChost->irq;
-	int scsi_id = 0;
-	int rev = inb(base + TC_HIGH);
-
-	for(i = 0; i < host_index; i++)
-		if(hosts[i].base == base)
-			scsi_id = hosts[i].scsi_id;
-	sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow");
-	return info;
-}
-
-static int sym53c416_queuecommand_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
-{
-	int base;
-	unsigned long flags = 0;
-	int i;
-
-	/* Store base register as we can have more than one controller in the system */
-	base = SCpnt->device->host->io_port;
-	current_command = SCpnt;                  /* set current command                */
-	current_command->scsi_done = done;        /* set ptr to done function           */
-	current_command->SCp.phase = command_ph;  /* currect phase is the command phase */
-	current_command->SCp.Status = 0;
-	current_command->SCp.Message = 0;
-
-	spin_lock_irqsave(&sym53c416_lock, flags);
-	outb(scmd_id(SCpnt), base + DEST_BUS_ID); /* Set scsi id target        */
-	outb(FLUSH_FIFO, base + COMMAND_REG);    /* Flush SCSI and PIO FIFO's */
-	/* Write SCSI command into the SCSI fifo */
-	for(i = 0; i < SCpnt->cmd_len; i++)
-		outb(SCpnt->cmnd[i], base + SCSI_FIFO);
-	/* Start selection sequence */
-	outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG);
-	/* Now an interrupt will be generated which we will catch in out interrupt routine */
-	spin_unlock_irqrestore(&sym53c416_lock, flags);
-	return 0;
-}
-
-DEF_SCSI_QCMD(sym53c416_queuecommand)
-
-static int sym53c416_host_reset(Scsi_Cmnd *SCpnt)
-{
-	int base;
-	int scsi_id = -1;	
-	int i;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sym53c416_lock, flags);
-
-	/* printk("sym53c416_reset\n"); */
-	base = SCpnt->device->host->io_port;
-	/* search scsi_id - fixme, we shouldn't need to iterate for this! */
-	for(i = 0; i < host_index && scsi_id == -1; i++)
-		if(hosts[i].base == base)
-			scsi_id = hosts[i].scsi_id;
-	outb(RESET_CHIP, base + COMMAND_REG);
-	outb(NOOP | PIO_MODE, base + COMMAND_REG);
-	outb(RESET_SCSI_BUS, base + COMMAND_REG);
-	sym53c416_init(base, scsi_id);
-
-	spin_unlock_irqrestore(&sym53c416_lock, flags);
-	return SUCCESS;
-}
-
-static int sym53c416_release(struct Scsi_Host *shost)
-{
-	if (shost->irq)
-		free_irq(shost->irq, shost);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
-	return 0;
-}
-
-static int sym53c416_bios_param(struct scsi_device *sdev,
-		struct block_device *dev,
-		sector_t capacity, int *ip)
-{
-	int size;
-
-	size = capacity;
-	ip[0] = 64;				/* heads                        */
-	ip[1] = 32;				/* sectors                      */
-	if((ip[2] = size >> 11) > 1024)		/* cylinders, test for big disk */
-	{
-		ip[0] = 255;			/* heads                        */
-		ip[1] = 63;			/* sectors                      */
-		ip[2] = size / (255 * 63);	/* cylinders                    */
-	}
-	return 0;
-}
-
-/* Loadable module support */
-#ifdef MODULE
-
-MODULE_AUTHOR("Lieven Willems");
-MODULE_LICENSE("GPL");
-
-module_param_array(sym53c416, uint, NULL, 0);
-module_param_array(sym53c416_1, uint, NULL, 0);
-module_param_array(sym53c416_2, uint, NULL, 0);
-module_param_array(sym53c416_3, uint, NULL, 0);
-
-#endif
-
-static struct scsi_host_template driver_template = {
-	.proc_name =		"sym53c416",
-	.name =			"Symbios Logic 53c416",
-	.detect =		sym53c416_detect,
-	.info =			sym53c416_info,	
-	.queuecommand =		sym53c416_queuecommand,
-	.eh_host_reset_handler =sym53c416_host_reset,
-	.release = 		sym53c416_release,
-	.bios_param =		sym53c416_bios_param,
-	.can_queue =		1,
-	.this_id =		SYM53C416_SCSI_ID,
-	.sg_tablesize =		32,
-	.unchecked_isa_dma =	1,
-	.use_clustering =	ENABLE_CLUSTERING,
-};
-#include "scsi_module.c"
diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h
deleted file mode 100644
index 387de5d..0000000
--- a/drivers/scsi/sym53c416.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  sym53c416.h
- * 
- *  Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.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, or (at your option) any
- *  later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- */
-
-#ifndef _SYM53C416_H
-#define _SYM53C416_H
-
-#include <linux/types.h>
-
-#define SYM53C416_SCSI_ID 7
-
-static int sym53c416_detect(struct scsi_host_template *);
-static const char *sym53c416_info(struct Scsi_Host *);
-static int sym53c416_release(struct Scsi_Host *);
-static int sym53c416_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
-static int sym53c416_host_reset(Scsi_Cmnd *);
-static int sym53c416_bios_param(struct scsi_device *, struct block_device *,
-		sector_t, int *);
-static void sym53c416_setup(char *str, int *ints);
-#endif
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 791a218..7320d5f 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -1393,7 +1393,7 @@ static struct Scsi_Host *sym_attach(struct scsi_host_template *tpnt, int unit,
 		scsi_host_put(shost);
 
 	return NULL;
- }
+}
 
 
 /*
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 9310c6c..918f579 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -3,6 +3,7 @@
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
-obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
+obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
+ufshcd-core-objs := ufshcd.o ufs-sysfs.o
 obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pci.c b/drivers/scsi/ufs/tc-dwc-g210-pci.c
index 325d5e1..2f41722 100644
--- a/drivers/scsi/ufs/tc-dwc-g210-pci.c
+++ b/drivers/scsi/ufs/tc-dwc-g210-pci.c
@@ -51,7 +51,7 @@ static int tc_dwc_g210_pci_runtime_idle(struct device *dev)
 	return ufshcd_runtime_idle(dev_get_drvdata(dev));
 }
 
-/**
+/*
  * struct ufs_hba_dwc_vops - UFS DWC specific variant operations
  */
 static struct ufs_hba_variant_ops tc_dwc_g210_pci_hba_vops = {
@@ -71,7 +71,7 @@ static void tc_dwc_g210_pci_shutdown(struct pci_dev *pdev)
 /**
  * tc_dwc_g210_pci_remove - de-allocate PCI/SCSI host and host memory space
  *		data structure memory
- * @pdev - pointer to PCI handle
+ * @pdev: pointer to PCI handle
  */
 static void tc_dwc_g210_pci_remove(struct pci_dev *pdev)
 {
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c b/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c
index 2d3f527..6dfe5a9 100644
--- a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c
+++ b/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c
@@ -20,7 +20,7 @@
 #include "ufshcd-dwc.h"
 #include "tc-dwc-g210.h"
 
-/**
+/*
  * UFS DWC specific variant operations
  */
 static struct ufs_hba_variant_ops tc_dwc_g210_20bit_pltfm_hba_vops = {
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
new file mode 100644
index 0000000..8d9332b
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -0,0 +1,817 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Western Digital Corporation
+
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/bitfield.h>
+#include <asm/unaligned.h>
+
+#include "ufs.h"
+#include "ufs-sysfs.h"
+
+static const char *ufschd_uic_link_state_to_string(
+			enum uic_link_state state)
+{
+	switch (state) {
+	case UIC_LINK_OFF_STATE:	return "OFF";
+	case UIC_LINK_ACTIVE_STATE:	return "ACTIVE";
+	case UIC_LINK_HIBERN8_STATE:	return "HIBERN8";
+	default:			return "UNKNOWN";
+	}
+}
+
+static const char *ufschd_ufs_dev_pwr_mode_to_string(
+			enum ufs_dev_pwr_mode state)
+{
+	switch (state) {
+	case UFS_ACTIVE_PWR_MODE:	return "ACTIVE";
+	case UFS_SLEEP_PWR_MODE:	return "SLEEP";
+	case UFS_POWERDOWN_PWR_MODE:	return "POWERDOWN";
+	default:			return "UNKNOWN";
+	}
+}
+
+static inline ssize_t ufs_sysfs_pm_lvl_store(struct device *dev,
+					     struct device_attribute *attr,
+					     const char *buf, size_t count,
+					     bool rpm)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+	unsigned long flags, value;
+
+	if (kstrtoul(buf, 0, &value))
+		return -EINVAL;
+
+	if (value >= UFS_PM_LVL_MAX)
+		return -EINVAL;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	if (rpm)
+		hba->rpm_lvl = value;
+	else
+		hba->spm_lvl = value;
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+	return count;
+}
+
+static ssize_t rpm_lvl_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", hba->rpm_lvl);
+}
+
+static ssize_t rpm_lvl_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, true);
+}
+
+static ssize_t rpm_target_dev_state_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", ufschd_ufs_dev_pwr_mode_to_string(
+			ufs_pm_lvl_states[hba->rpm_lvl].dev_state));
+}
+
+static ssize_t rpm_target_link_state_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", ufschd_uic_link_state_to_string(
+			ufs_pm_lvl_states[hba->rpm_lvl].link_state));
+}
+
+static ssize_t spm_lvl_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", hba->spm_lvl);
+}
+
+static ssize_t spm_lvl_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);
+}
+
+static ssize_t spm_target_dev_state_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", ufschd_ufs_dev_pwr_mode_to_string(
+				ufs_pm_lvl_states[hba->spm_lvl].dev_state));
+}
+
+static ssize_t spm_target_link_state_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", ufschd_uic_link_state_to_string(
+				ufs_pm_lvl_states[hba->spm_lvl].link_state));
+}
+
+static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit)
+{
+	unsigned long flags;
+
+	if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
+		return;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	if (hba->ahit == ahit)
+		goto out_unlock;
+	hba->ahit = ahit;
+	if (!pm_runtime_suspended(hba->dev))
+		ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER);
+out_unlock:
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+}
+
+/* Convert Auto-Hibernate Idle Timer register value to microseconds */
+static int ufshcd_ahit_to_us(u32 ahit)
+{
+	int timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, ahit);
+	int scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK, ahit);
+
+	for (; scale > 0; --scale)
+		timer *= UFSHCI_AHIBERN8_SCALE_FACTOR;
+
+	return timer;
+}
+
+/* Convert microseconds to Auto-Hibernate Idle Timer register value */
+static u32 ufshcd_us_to_ahit(unsigned int timer)
+{
+	unsigned int scale;
+
+	for (scale = 0; timer > UFSHCI_AHIBERN8_TIMER_MASK; ++scale)
+		timer /= UFSHCI_AHIBERN8_SCALE_FACTOR;
+
+	return FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, timer) |
+	       FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, scale);
+}
+
+static ssize_t auto_hibern8_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
+		return -EOPNOTSUPP;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ufshcd_ahit_to_us(hba->ahit));
+}
+
+static ssize_t auto_hibern8_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+	unsigned int timer;
+
+	if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
+		return -EOPNOTSUPP;
+
+	if (kstrtouint(buf, 0, &timer))
+		return -EINVAL;
+
+	if (timer > UFSHCI_AHIBERN8_MAX)
+		return -EINVAL;
+
+	ufshcd_auto_hibern8_update(hba, ufshcd_us_to_ahit(timer));
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(rpm_lvl);
+static DEVICE_ATTR_RO(rpm_target_dev_state);
+static DEVICE_ATTR_RO(rpm_target_link_state);
+static DEVICE_ATTR_RW(spm_lvl);
+static DEVICE_ATTR_RO(spm_target_dev_state);
+static DEVICE_ATTR_RO(spm_target_link_state);
+static DEVICE_ATTR_RW(auto_hibern8);
+
+static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
+	&dev_attr_rpm_lvl.attr,
+	&dev_attr_rpm_target_dev_state.attr,
+	&dev_attr_rpm_target_link_state.attr,
+	&dev_attr_spm_lvl.attr,
+	&dev_attr_spm_target_dev_state.attr,
+	&dev_attr_spm_target_link_state.attr,
+	&dev_attr_auto_hibern8.attr,
+	NULL
+};
+
+static const struct attribute_group ufs_sysfs_default_group = {
+	.attrs = ufs_sysfs_ufshcd_attrs,
+};
+
+static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
+				  enum desc_idn desc_id,
+				  u8 desc_index,
+				  u8 param_offset,
+				  u8 *sysfs_buf,
+				  u8 param_size)
+{
+	u8 desc_buf[8] = {0};
+	int ret;
+
+	if (param_size > 8)
+		return -EINVAL;
+
+	ret = ufshcd_read_desc_param(hba, desc_id, desc_index,
+				param_offset, desc_buf, param_size);
+	if (ret)
+		return -EINVAL;
+	switch (param_size) {
+	case 1:
+		ret = sprintf(sysfs_buf, "0x%02X\n", *desc_buf);
+		break;
+	case 2:
+		ret = sprintf(sysfs_buf, "0x%04X\n",
+			get_unaligned_be16(desc_buf));
+		break;
+	case 4:
+		ret = sprintf(sysfs_buf, "0x%08X\n",
+			get_unaligned_be32(desc_buf));
+		break;
+	case 8:
+		ret = sprintf(sysfs_buf, "0x%016llX\n",
+			get_unaligned_be64(desc_buf));
+		break;
+	}
+
+	return ret;
+}
+
+#define UFS_DESC_PARAM(_name, _puname, _duname, _size)			\
+static ssize_t _name##_show(struct device *dev,				\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname,	\
+		0, _duname##_DESC_PARAM##_puname, buf, _size);		\
+}									\
+static DEVICE_ATTR_RO(_name)
+
+#define UFS_DEVICE_DESC_PARAM(_name, _uname, _size)			\
+	UFS_DESC_PARAM(_name, _uname, DEVICE, _size)
+
+UFS_DEVICE_DESC_PARAM(device_type, _DEVICE_TYPE, 1);
+UFS_DEVICE_DESC_PARAM(device_class, _DEVICE_CLASS, 1);
+UFS_DEVICE_DESC_PARAM(device_sub_class, _DEVICE_SUB_CLASS, 1);
+UFS_DEVICE_DESC_PARAM(protocol, _PRTCL, 1);
+UFS_DEVICE_DESC_PARAM(number_of_luns, _NUM_LU, 1);
+UFS_DEVICE_DESC_PARAM(number_of_wluns, _NUM_WLU, 1);
+UFS_DEVICE_DESC_PARAM(boot_enable, _BOOT_ENBL, 1);
+UFS_DEVICE_DESC_PARAM(descriptor_access_enable, _DESC_ACCSS_ENBL, 1);
+UFS_DEVICE_DESC_PARAM(initial_power_mode, _INIT_PWR_MODE, 1);
+UFS_DEVICE_DESC_PARAM(high_priority_lun, _HIGH_PR_LUN, 1);
+UFS_DEVICE_DESC_PARAM(secure_removal_type, _SEC_RMV_TYPE, 1);
+UFS_DEVICE_DESC_PARAM(support_security_lun, _SEC_LU, 1);
+UFS_DEVICE_DESC_PARAM(bkops_termination_latency, _BKOP_TERM_LT, 1);
+UFS_DEVICE_DESC_PARAM(initial_active_icc_level, _ACTVE_ICC_LVL, 1);
+UFS_DEVICE_DESC_PARAM(specification_version, _SPEC_VER, 2);
+UFS_DEVICE_DESC_PARAM(manufacturing_date, _MANF_DATE, 2);
+UFS_DEVICE_DESC_PARAM(manufacturer_id, _MANF_ID, 2);
+UFS_DEVICE_DESC_PARAM(rtt_capability, _RTT_CAP, 1);
+UFS_DEVICE_DESC_PARAM(rtc_update, _FRQ_RTC, 2);
+UFS_DEVICE_DESC_PARAM(ufs_features, _UFS_FEAT, 1);
+UFS_DEVICE_DESC_PARAM(ffu_timeout, _FFU_TMT, 1);
+UFS_DEVICE_DESC_PARAM(queue_depth, _Q_DPTH, 1);
+UFS_DEVICE_DESC_PARAM(device_version, _DEV_VER, 2);
+UFS_DEVICE_DESC_PARAM(number_of_secure_wpa, _NUM_SEC_WPA, 1);
+UFS_DEVICE_DESC_PARAM(psa_max_data_size, _PSA_MAX_DATA, 4);
+UFS_DEVICE_DESC_PARAM(psa_state_timeout, _PSA_TMT, 1);
+
+static struct attribute *ufs_sysfs_device_descriptor[] = {
+	&dev_attr_device_type.attr,
+	&dev_attr_device_class.attr,
+	&dev_attr_device_sub_class.attr,
+	&dev_attr_protocol.attr,
+	&dev_attr_number_of_luns.attr,
+	&dev_attr_number_of_wluns.attr,
+	&dev_attr_boot_enable.attr,
+	&dev_attr_descriptor_access_enable.attr,
+	&dev_attr_initial_power_mode.attr,
+	&dev_attr_high_priority_lun.attr,
+	&dev_attr_secure_removal_type.attr,
+	&dev_attr_support_security_lun.attr,
+	&dev_attr_bkops_termination_latency.attr,
+	&dev_attr_initial_active_icc_level.attr,
+	&dev_attr_specification_version.attr,
+	&dev_attr_manufacturing_date.attr,
+	&dev_attr_manufacturer_id.attr,
+	&dev_attr_rtt_capability.attr,
+	&dev_attr_rtc_update.attr,
+	&dev_attr_ufs_features.attr,
+	&dev_attr_ffu_timeout.attr,
+	&dev_attr_queue_depth.attr,
+	&dev_attr_device_version.attr,
+	&dev_attr_number_of_secure_wpa.attr,
+	&dev_attr_psa_max_data_size.attr,
+	&dev_attr_psa_state_timeout.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_device_descriptor_group = {
+	.name = "device_descriptor",
+	.attrs = ufs_sysfs_device_descriptor,
+};
+
+#define UFS_INTERCONNECT_DESC_PARAM(_name, _uname, _size)		\
+	UFS_DESC_PARAM(_name, _uname, INTERCONNECT, _size)
+
+UFS_INTERCONNECT_DESC_PARAM(unipro_version, _UNIPRO_VER, 2);
+UFS_INTERCONNECT_DESC_PARAM(mphy_version, _MPHY_VER, 2);
+
+static struct attribute *ufs_sysfs_interconnect_descriptor[] = {
+	&dev_attr_unipro_version.attr,
+	&dev_attr_mphy_version.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_interconnect_descriptor_group = {
+	.name = "interconnect_descriptor",
+	.attrs = ufs_sysfs_interconnect_descriptor,
+};
+
+#define UFS_GEOMETRY_DESC_PARAM(_name, _uname, _size)			\
+	UFS_DESC_PARAM(_name, _uname, GEOMETRY, _size)
+
+UFS_GEOMETRY_DESC_PARAM(raw_device_capacity, _DEV_CAP, 8);
+UFS_GEOMETRY_DESC_PARAM(max_number_of_luns, _MAX_NUM_LUN, 1);
+UFS_GEOMETRY_DESC_PARAM(segment_size, _SEG_SIZE, 4);
+UFS_GEOMETRY_DESC_PARAM(allocation_unit_size, _ALLOC_UNIT_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(min_addressable_block_size, _MIN_BLK_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(optimal_read_block_size, _OPT_RD_BLK_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(optimal_write_block_size, _OPT_WR_BLK_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(max_in_buffer_size, _MAX_IN_BUF_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(max_out_buffer_size, _MAX_OUT_BUF_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(rpmb_rw_size, _RPMB_RW_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(dyn_capacity_resource_policy, _DYN_CAP_RSRC_PLC, 1);
+UFS_GEOMETRY_DESC_PARAM(data_ordering, _DATA_ORDER, 1);
+UFS_GEOMETRY_DESC_PARAM(max_number_of_contexts, _MAX_NUM_CTX, 1);
+UFS_GEOMETRY_DESC_PARAM(sys_data_tag_unit_size, _TAG_UNIT_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(sys_data_tag_resource_size, _TAG_RSRC_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(secure_removal_types, _SEC_RM_TYPES, 1);
+UFS_GEOMETRY_DESC_PARAM(memory_types, _MEM_TYPES, 2);
+UFS_GEOMETRY_DESC_PARAM(sys_code_memory_max_alloc_units,
+	_SCM_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(sys_code_memory_capacity_adjustment_factor,
+	_SCM_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(non_persist_memory_max_alloc_units,
+	_NPM_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(non_persist_memory_capacity_adjustment_factor,
+	_NPM_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(enh1_memory_max_alloc_units,
+	_ENM1_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(enh1_memory_capacity_adjustment_factor,
+	_ENM1_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(enh2_memory_max_alloc_units,
+	_ENM2_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(enh2_memory_capacity_adjustment_factor,
+	_ENM2_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(enh3_memory_max_alloc_units,
+	_ENM3_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(enh3_memory_capacity_adjustment_factor,
+	_ENM3_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(enh4_memory_max_alloc_units,
+	_ENM4_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(enh4_memory_capacity_adjustment_factor,
+	_ENM4_CAP_ADJ_FCTR, 2);
+
+static struct attribute *ufs_sysfs_geometry_descriptor[] = {
+	&dev_attr_raw_device_capacity.attr,
+	&dev_attr_max_number_of_luns.attr,
+	&dev_attr_segment_size.attr,
+	&dev_attr_allocation_unit_size.attr,
+	&dev_attr_min_addressable_block_size.attr,
+	&dev_attr_optimal_read_block_size.attr,
+	&dev_attr_optimal_write_block_size.attr,
+	&dev_attr_max_in_buffer_size.attr,
+	&dev_attr_max_out_buffer_size.attr,
+	&dev_attr_rpmb_rw_size.attr,
+	&dev_attr_dyn_capacity_resource_policy.attr,
+	&dev_attr_data_ordering.attr,
+	&dev_attr_max_number_of_contexts.attr,
+	&dev_attr_sys_data_tag_unit_size.attr,
+	&dev_attr_sys_data_tag_resource_size.attr,
+	&dev_attr_secure_removal_types.attr,
+	&dev_attr_memory_types.attr,
+	&dev_attr_sys_code_memory_max_alloc_units.attr,
+	&dev_attr_sys_code_memory_capacity_adjustment_factor.attr,
+	&dev_attr_non_persist_memory_max_alloc_units.attr,
+	&dev_attr_non_persist_memory_capacity_adjustment_factor.attr,
+	&dev_attr_enh1_memory_max_alloc_units.attr,
+	&dev_attr_enh1_memory_capacity_adjustment_factor.attr,
+	&dev_attr_enh2_memory_max_alloc_units.attr,
+	&dev_attr_enh2_memory_capacity_adjustment_factor.attr,
+	&dev_attr_enh3_memory_max_alloc_units.attr,
+	&dev_attr_enh3_memory_capacity_adjustment_factor.attr,
+	&dev_attr_enh4_memory_max_alloc_units.attr,
+	&dev_attr_enh4_memory_capacity_adjustment_factor.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_geometry_descriptor_group = {
+	.name = "geometry_descriptor",
+	.attrs = ufs_sysfs_geometry_descriptor,
+};
+
+#define UFS_HEALTH_DESC_PARAM(_name, _uname, _size)			\
+	UFS_DESC_PARAM(_name, _uname, HEALTH, _size)
+
+UFS_HEALTH_DESC_PARAM(eol_info, _EOL_INFO, 1);
+UFS_HEALTH_DESC_PARAM(life_time_estimation_a, _LIFE_TIME_EST_A, 1);
+UFS_HEALTH_DESC_PARAM(life_time_estimation_b, _LIFE_TIME_EST_B, 1);
+
+static struct attribute *ufs_sysfs_health_descriptor[] = {
+	&dev_attr_eol_info.attr,
+	&dev_attr_life_time_estimation_a.attr,
+	&dev_attr_life_time_estimation_b.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_health_descriptor_group = {
+	.name = "health_descriptor",
+	.attrs = ufs_sysfs_health_descriptor,
+};
+
+#define UFS_POWER_DESC_PARAM(_name, _uname, _index)			\
+static ssize_t _name##_index##_show(struct device *dev,			\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_POWER, 0,	\
+		PWR_DESC##_uname##_0 + _index * 2, buf, 2);		\
+}									\
+static DEVICE_ATTR_RO(_name##_index)
+
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 0);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 1);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 2);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 3);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 4);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 5);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 6);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 7);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 8);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 9);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 10);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 11);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 12);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 13);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 14);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 15);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 0);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 1);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 2);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 3);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 4);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 5);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 6);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 7);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 8);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 9);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 10);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 11);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 12);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 13);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 14);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 15);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 0);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 1);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 2);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 3);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 4);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 5);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 6);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 7);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 8);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 9);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 10);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 11);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 12);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 13);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 14);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 15);
+
+static struct attribute *ufs_sysfs_power_descriptor[] = {
+	&dev_attr_active_icc_levels_vcc0.attr,
+	&dev_attr_active_icc_levels_vcc1.attr,
+	&dev_attr_active_icc_levels_vcc2.attr,
+	&dev_attr_active_icc_levels_vcc3.attr,
+	&dev_attr_active_icc_levels_vcc4.attr,
+	&dev_attr_active_icc_levels_vcc5.attr,
+	&dev_attr_active_icc_levels_vcc6.attr,
+	&dev_attr_active_icc_levels_vcc7.attr,
+	&dev_attr_active_icc_levels_vcc8.attr,
+	&dev_attr_active_icc_levels_vcc9.attr,
+	&dev_attr_active_icc_levels_vcc10.attr,
+	&dev_attr_active_icc_levels_vcc11.attr,
+	&dev_attr_active_icc_levels_vcc12.attr,
+	&dev_attr_active_icc_levels_vcc13.attr,
+	&dev_attr_active_icc_levels_vcc14.attr,
+	&dev_attr_active_icc_levels_vcc15.attr,
+	&dev_attr_active_icc_levels_vccq0.attr,
+	&dev_attr_active_icc_levels_vccq1.attr,
+	&dev_attr_active_icc_levels_vccq2.attr,
+	&dev_attr_active_icc_levels_vccq3.attr,
+	&dev_attr_active_icc_levels_vccq4.attr,
+	&dev_attr_active_icc_levels_vccq5.attr,
+	&dev_attr_active_icc_levels_vccq6.attr,
+	&dev_attr_active_icc_levels_vccq7.attr,
+	&dev_attr_active_icc_levels_vccq8.attr,
+	&dev_attr_active_icc_levels_vccq9.attr,
+	&dev_attr_active_icc_levels_vccq10.attr,
+	&dev_attr_active_icc_levels_vccq11.attr,
+	&dev_attr_active_icc_levels_vccq12.attr,
+	&dev_attr_active_icc_levels_vccq13.attr,
+	&dev_attr_active_icc_levels_vccq14.attr,
+	&dev_attr_active_icc_levels_vccq15.attr,
+	&dev_attr_active_icc_levels_vccq20.attr,
+	&dev_attr_active_icc_levels_vccq21.attr,
+	&dev_attr_active_icc_levels_vccq22.attr,
+	&dev_attr_active_icc_levels_vccq23.attr,
+	&dev_attr_active_icc_levels_vccq24.attr,
+	&dev_attr_active_icc_levels_vccq25.attr,
+	&dev_attr_active_icc_levels_vccq26.attr,
+	&dev_attr_active_icc_levels_vccq27.attr,
+	&dev_attr_active_icc_levels_vccq28.attr,
+	&dev_attr_active_icc_levels_vccq29.attr,
+	&dev_attr_active_icc_levels_vccq210.attr,
+	&dev_attr_active_icc_levels_vccq211.attr,
+	&dev_attr_active_icc_levels_vccq212.attr,
+	&dev_attr_active_icc_levels_vccq213.attr,
+	&dev_attr_active_icc_levels_vccq214.attr,
+	&dev_attr_active_icc_levels_vccq215.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_power_descriptor_group = {
+	.name = "power_descriptor",
+	.attrs = ufs_sysfs_power_descriptor,
+};
+
+#define UFS_STRING_DESCRIPTOR(_name, _pname)				\
+static ssize_t _name##_show(struct device *dev,				\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	u8 index;							\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	int ret;							\
+	int desc_len = QUERY_DESC_MAX_SIZE;				\
+	u8 *desc_buf;							\
+	desc_buf = kzalloc(QUERY_DESC_MAX_SIZE, GFP_ATOMIC);		\
+	if (!desc_buf)							\
+		return -ENOMEM;						\
+	ret = ufshcd_query_descriptor_retry(hba,			\
+		UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_DEVICE,	\
+		0, 0, desc_buf, &desc_len);				\
+	if (ret) {							\
+		ret = -EINVAL;						\
+		goto out;						\
+	}								\
+	index = desc_buf[DEVICE_DESC_PARAM##_pname];			\
+	memset(desc_buf, 0, QUERY_DESC_MAX_SIZE);			\
+	if (ufshcd_read_string_desc(hba, index, desc_buf,		\
+		QUERY_DESC_MAX_SIZE, true)) {				\
+		ret = -EINVAL;						\
+		goto out;						\
+	}								\
+	ret = snprintf(buf, PAGE_SIZE, "%s\n",				\
+		desc_buf + QUERY_DESC_HDR_SIZE);			\
+out:									\
+	kfree(desc_buf);						\
+	return ret;							\
+}									\
+static DEVICE_ATTR_RO(_name)
+
+UFS_STRING_DESCRIPTOR(manufacturer_name, _MANF_NAME);
+UFS_STRING_DESCRIPTOR(product_name, _PRDCT_NAME);
+UFS_STRING_DESCRIPTOR(oem_id, _OEM_ID);
+UFS_STRING_DESCRIPTOR(serial_number, _SN);
+UFS_STRING_DESCRIPTOR(product_revision, _PRDCT_REV);
+
+static struct attribute *ufs_sysfs_string_descriptors[] = {
+	&dev_attr_manufacturer_name.attr,
+	&dev_attr_product_name.attr,
+	&dev_attr_oem_id.attr,
+	&dev_attr_serial_number.attr,
+	&dev_attr_product_revision.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_string_descriptors_group = {
+	.name = "string_descriptors",
+	.attrs = ufs_sysfs_string_descriptors,
+};
+
+#define UFS_FLAG(_name, _uname)						\
+static ssize_t _name##_show(struct device *dev,				\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	bool flag;							\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	if (ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG,		\
+		QUERY_FLAG_IDN##_uname, &flag))				\
+		return -EINVAL;						\
+	return sprintf(buf, "%s\n", flag ? "true" : "false");		\
+}									\
+static DEVICE_ATTR_RO(_name)
+
+UFS_FLAG(device_init, _FDEVICEINIT);
+UFS_FLAG(permanent_wpe, _PERMANENT_WPE);
+UFS_FLAG(power_on_wpe, _PWR_ON_WPE);
+UFS_FLAG(bkops_enable, _BKOPS_EN);
+UFS_FLAG(life_span_mode_enable, _LIFE_SPAN_MODE_ENABLE);
+UFS_FLAG(phy_resource_removal, _FPHYRESOURCEREMOVAL);
+UFS_FLAG(busy_rtc, _BUSY_RTC);
+UFS_FLAG(disable_fw_update, _PERMANENTLY_DISABLE_FW_UPDATE);
+
+static struct attribute *ufs_sysfs_device_flags[] = {
+	&dev_attr_device_init.attr,
+	&dev_attr_permanent_wpe.attr,
+	&dev_attr_power_on_wpe.attr,
+	&dev_attr_bkops_enable.attr,
+	&dev_attr_life_span_mode_enable.attr,
+	&dev_attr_phy_resource_removal.attr,
+	&dev_attr_busy_rtc.attr,
+	&dev_attr_disable_fw_update.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_flags_group = {
+	.name = "flags",
+	.attrs = ufs_sysfs_device_flags,
+};
+
+#define UFS_ATTRIBUTE(_name, _uname)					\
+static ssize_t _name##_show(struct device *dev,				\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	u32 value;							\
+	if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,		\
+		QUERY_ATTR_IDN##_uname, 0, 0, &value))			\
+		return -EINVAL;						\
+	return sprintf(buf, "0x%08X\n", value);				\
+}									\
+static DEVICE_ATTR_RO(_name)
+
+UFS_ATTRIBUTE(boot_lun_enabled, _BOOT_LU_EN);
+UFS_ATTRIBUTE(current_power_mode, _POWER_MODE);
+UFS_ATTRIBUTE(active_icc_level, _ACTIVE_ICC_LVL);
+UFS_ATTRIBUTE(ooo_data_enabled, _OOO_DATA_EN);
+UFS_ATTRIBUTE(bkops_status, _BKOPS_STATUS);
+UFS_ATTRIBUTE(purge_status, _PURGE_STATUS);
+UFS_ATTRIBUTE(max_data_in_size, _MAX_DATA_IN);
+UFS_ATTRIBUTE(max_data_out_size, _MAX_DATA_OUT);
+UFS_ATTRIBUTE(reference_clock_frequency, _REF_CLK_FREQ);
+UFS_ATTRIBUTE(configuration_descriptor_lock, _CONF_DESC_LOCK);
+UFS_ATTRIBUTE(max_number_of_rtt, _MAX_NUM_OF_RTT);
+UFS_ATTRIBUTE(exception_event_control, _EE_CONTROL);
+UFS_ATTRIBUTE(exception_event_status, _EE_STATUS);
+UFS_ATTRIBUTE(ffu_status, _FFU_STATUS);
+UFS_ATTRIBUTE(psa_state, _PSA_STATE);
+UFS_ATTRIBUTE(psa_data_size, _PSA_DATA_SIZE);
+
+static struct attribute *ufs_sysfs_attributes[] = {
+	&dev_attr_boot_lun_enabled.attr,
+	&dev_attr_current_power_mode.attr,
+	&dev_attr_active_icc_level.attr,
+	&dev_attr_ooo_data_enabled.attr,
+	&dev_attr_bkops_status.attr,
+	&dev_attr_purge_status.attr,
+	&dev_attr_max_data_in_size.attr,
+	&dev_attr_max_data_out_size.attr,
+	&dev_attr_reference_clock_frequency.attr,
+	&dev_attr_configuration_descriptor_lock.attr,
+	&dev_attr_max_number_of_rtt.attr,
+	&dev_attr_exception_event_control.attr,
+	&dev_attr_exception_event_status.attr,
+	&dev_attr_ffu_status.attr,
+	&dev_attr_psa_state.attr,
+	&dev_attr_psa_data_size.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_attributes_group = {
+	.name = "attributes",
+	.attrs = ufs_sysfs_attributes,
+};
+
+static const struct attribute_group *ufs_sysfs_groups[] = {
+	&ufs_sysfs_default_group,
+	&ufs_sysfs_device_descriptor_group,
+	&ufs_sysfs_interconnect_descriptor_group,
+	&ufs_sysfs_geometry_descriptor_group,
+	&ufs_sysfs_health_descriptor_group,
+	&ufs_sysfs_power_descriptor_group,
+	&ufs_sysfs_string_descriptors_group,
+	&ufs_sysfs_flags_group,
+	&ufs_sysfs_attributes_group,
+	NULL,
+};
+
+#define UFS_LUN_DESC_PARAM(_pname, _puname, _duname, _size)		\
+static ssize_t _pname##_show(struct device *dev,			\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	struct scsi_device *sdev = to_scsi_device(dev);			\
+	struct ufs_hba *hba = shost_priv(sdev->host);			\
+	u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun);			\
+	if (!ufs_is_valid_unit_desc_lun(lun))				\
+		return -EINVAL;						\
+	return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname,	\
+		lun, _duname##_DESC_PARAM##_puname, buf, _size);	\
+}									\
+static DEVICE_ATTR_RO(_pname)
+
+#define UFS_UNIT_DESC_PARAM(_name, _uname, _size)			\
+	UFS_LUN_DESC_PARAM(_name, _uname, UNIT, _size)
+
+UFS_UNIT_DESC_PARAM(boot_lun_id, _BOOT_LUN_ID, 1);
+UFS_UNIT_DESC_PARAM(lun_write_protect, _LU_WR_PROTECT, 1);
+UFS_UNIT_DESC_PARAM(lun_queue_depth, _LU_Q_DEPTH, 1);
+UFS_UNIT_DESC_PARAM(psa_sensitive, _PSA_SENSITIVE, 1);
+UFS_UNIT_DESC_PARAM(lun_memory_type, _MEM_TYPE, 1);
+UFS_UNIT_DESC_PARAM(data_reliability, _DATA_RELIABILITY, 1);
+UFS_UNIT_DESC_PARAM(logical_block_size, _LOGICAL_BLK_SIZE, 1);
+UFS_UNIT_DESC_PARAM(logical_block_count, _LOGICAL_BLK_COUNT, 8);
+UFS_UNIT_DESC_PARAM(erase_block_size, _ERASE_BLK_SIZE, 4);
+UFS_UNIT_DESC_PARAM(provisioning_type, _PROVISIONING_TYPE, 1);
+UFS_UNIT_DESC_PARAM(physical_memory_resourse_count, _PHY_MEM_RSRC_CNT, 8);
+UFS_UNIT_DESC_PARAM(context_capabilities, _CTX_CAPABILITIES, 2);
+UFS_UNIT_DESC_PARAM(large_unit_granularity, _LARGE_UNIT_SIZE_M1, 1);
+
+static struct attribute *ufs_sysfs_unit_descriptor[] = {
+	&dev_attr_boot_lun_id.attr,
+	&dev_attr_lun_write_protect.attr,
+	&dev_attr_lun_queue_depth.attr,
+	&dev_attr_psa_sensitive.attr,
+	&dev_attr_lun_memory_type.attr,
+	&dev_attr_data_reliability.attr,
+	&dev_attr_logical_block_size.attr,
+	&dev_attr_logical_block_count.attr,
+	&dev_attr_erase_block_size.attr,
+	&dev_attr_provisioning_type.attr,
+	&dev_attr_physical_memory_resourse_count.attr,
+	&dev_attr_context_capabilities.attr,
+	&dev_attr_large_unit_granularity.attr,
+	NULL,
+};
+
+const struct attribute_group ufs_sysfs_unit_descriptor_group = {
+	.name = "unit_descriptor",
+	.attrs = ufs_sysfs_unit_descriptor,
+};
+
+static ssize_t dyn_cap_needed_attribute_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	u32 value;
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct ufs_hba *hba = shost_priv(sdev->host);
+	u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun);
+
+	if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+		QUERY_ATTR_IDN_DYN_CAP_NEEDED, lun, 0, &value))
+		return -EINVAL;
+	return sprintf(buf, "0x%08X\n", value);
+}
+static DEVICE_ATTR_RO(dyn_cap_needed_attribute);
+
+static struct attribute *ufs_sysfs_lun_attributes[] = {
+	&dev_attr_dyn_cap_needed_attribute.attr,
+	NULL,
+};
+
+const struct attribute_group ufs_sysfs_lun_attributes_group = {
+	.attrs = ufs_sysfs_lun_attributes,
+};
+
+void ufs_sysfs_add_nodes(struct device *dev)
+{
+	int ret;
+
+	ret = sysfs_create_groups(&dev->kobj, ufs_sysfs_groups);
+	if (ret)
+		dev_err(dev,
+			"%s: sysfs groups creation failed (err = %d)\n",
+			__func__, ret);
+}
+
+void ufs_sysfs_remove_nodes(struct device *dev)
+{
+	sysfs_remove_groups(&dev->kobj, ufs_sysfs_groups);
+}
diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h
new file mode 100644
index 0000000..e5621e5
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-sysfs.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (C) 2018 Western Digital Corporation
+ */
+
+#ifndef __UFS_SYSFS_H__
+#define __UFS_SYSFS_H__
+
+#include <linux/sysfs.h>
+
+#include "ufshcd.h"
+
+void ufs_sysfs_add_nodes(struct device *dev);
+void ufs_sysfs_remove_nodes(struct device *dev);
+
+extern const struct attribute_group ufs_sysfs_unit_descriptor_group;
+extern const struct attribute_group ufs_sysfs_lun_attributes_group;
+#endif
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 54deeb7..14e5bf7 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -130,17 +130,44 @@ enum {
 
 /* Flag idn for Query Requests*/
 enum flag_idn {
-	QUERY_FLAG_IDN_FDEVICEINIT      = 0x01,
-	QUERY_FLAG_IDN_PWR_ON_WPE	= 0x03,
-	QUERY_FLAG_IDN_BKOPS_EN         = 0x04,
+	QUERY_FLAG_IDN_FDEVICEINIT			= 0x01,
+	QUERY_FLAG_IDN_PERMANENT_WPE			= 0x02,
+	QUERY_FLAG_IDN_PWR_ON_WPE			= 0x03,
+	QUERY_FLAG_IDN_BKOPS_EN				= 0x04,
+	QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE		= 0x05,
+	QUERY_FLAG_IDN_PURGE_ENABLE			= 0x06,
+	QUERY_FLAG_IDN_RESERVED2			= 0x07,
+	QUERY_FLAG_IDN_FPHYRESOURCEREMOVAL		= 0x08,
+	QUERY_FLAG_IDN_BUSY_RTC				= 0x09,
+	QUERY_FLAG_IDN_RESERVED3			= 0x0A,
+	QUERY_FLAG_IDN_PERMANENTLY_DISABLE_FW_UPDATE	= 0x0B,
 };
 
 /* Attribute idn for Query requests */
 enum attr_idn {
-	QUERY_ATTR_IDN_ACTIVE_ICC_LVL	= 0x03,
-	QUERY_ATTR_IDN_BKOPS_STATUS	= 0x05,
-	QUERY_ATTR_IDN_EE_CONTROL	= 0x0D,
-	QUERY_ATTR_IDN_EE_STATUS	= 0x0E,
+	QUERY_ATTR_IDN_BOOT_LU_EN		= 0x00,
+	QUERY_ATTR_IDN_RESERVED			= 0x01,
+	QUERY_ATTR_IDN_POWER_MODE		= 0x02,
+	QUERY_ATTR_IDN_ACTIVE_ICC_LVL		= 0x03,
+	QUERY_ATTR_IDN_OOO_DATA_EN		= 0x04,
+	QUERY_ATTR_IDN_BKOPS_STATUS		= 0x05,
+	QUERY_ATTR_IDN_PURGE_STATUS		= 0x06,
+	QUERY_ATTR_IDN_MAX_DATA_IN		= 0x07,
+	QUERY_ATTR_IDN_MAX_DATA_OUT		= 0x08,
+	QUERY_ATTR_IDN_DYN_CAP_NEEDED		= 0x09,
+	QUERY_ATTR_IDN_REF_CLK_FREQ		= 0x0A,
+	QUERY_ATTR_IDN_CONF_DESC_LOCK		= 0x0B,
+	QUERY_ATTR_IDN_MAX_NUM_OF_RTT		= 0x0C,
+	QUERY_ATTR_IDN_EE_CONTROL		= 0x0D,
+	QUERY_ATTR_IDN_EE_STATUS		= 0x0E,
+	QUERY_ATTR_IDN_SECONDS_PASSED		= 0x0F,
+	QUERY_ATTR_IDN_CNTX_CONF		= 0x10,
+	QUERY_ATTR_IDN_CORR_PRG_BLK_NUM		= 0x11,
+	QUERY_ATTR_IDN_RESERVED2		= 0x12,
+	QUERY_ATTR_IDN_RESERVED3		= 0x13,
+	QUERY_ATTR_IDN_FFU_STATUS		= 0x14,
+	QUERY_ATTR_IDN_PSA_STATE		= 0x15,
+	QUERY_ATTR_IDN_PSA_DATA_SIZE		= 0x16,
 };
 
 /* Descriptor idn for Query requests */
@@ -154,6 +181,7 @@ enum desc_idn {
 	QUERY_DESC_IDN_RFU_1		= 0x6,
 	QUERY_DESC_IDN_GEOMETRY		= 0x7,
 	QUERY_DESC_IDN_POWER		= 0x8,
+	QUERY_DESC_IDN_HEALTH           = 0x9,
 	QUERY_DESC_IDN_MAX,
 };
 
@@ -169,6 +197,7 @@ enum ufs_desc_def_size {
 	QUERY_DESC_INTERCONNECT_DEF_SIZE	= 0x06,
 	QUERY_DESC_GEOMETRY_DEF_SIZE		= 0x44,
 	QUERY_DESC_POWER_DEF_SIZE		= 0x62,
+	QUERY_DESC_HEALTH_DEF_SIZE		= 0x25,
 };
 
 /* Unit descriptor parameters offsets in bytes*/
@@ -180,6 +209,7 @@ enum unit_desc_param {
 	UNIT_DESC_PARAM_BOOT_LUN_ID		= 0x4,
 	UNIT_DESC_PARAM_LU_WR_PROTECT		= 0x5,
 	UNIT_DESC_PARAM_LU_Q_DEPTH		= 0x6,
+	UNIT_DESC_PARAM_PSA_SENSITIVE		= 0x7,
 	UNIT_DESC_PARAM_MEM_TYPE		= 0x8,
 	UNIT_DESC_PARAM_DATA_RELIABILITY	= 0x9,
 	UNIT_DESC_PARAM_LOGICAL_BLK_SIZE	= 0xA,
@@ -220,6 +250,67 @@ enum device_desc_param {
 	DEVICE_DESC_PARAM_UD_LEN		= 0x1B,
 	DEVICE_DESC_PARAM_RTT_CAP		= 0x1C,
 	DEVICE_DESC_PARAM_FRQ_RTC		= 0x1D,
+	DEVICE_DESC_PARAM_UFS_FEAT		= 0x1F,
+	DEVICE_DESC_PARAM_FFU_TMT		= 0x20,
+	DEVICE_DESC_PARAM_Q_DPTH		= 0x21,
+	DEVICE_DESC_PARAM_DEV_VER		= 0x22,
+	DEVICE_DESC_PARAM_NUM_SEC_WPA		= 0x24,
+	DEVICE_DESC_PARAM_PSA_MAX_DATA		= 0x25,
+	DEVICE_DESC_PARAM_PSA_TMT		= 0x29,
+	DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
+};
+
+/* Interconnect descriptor parameters offsets in bytes*/
+enum interconnect_desc_param {
+	INTERCONNECT_DESC_PARAM_LEN		= 0x0,
+	INTERCONNECT_DESC_PARAM_TYPE		= 0x1,
+	INTERCONNECT_DESC_PARAM_UNIPRO_VER	= 0x2,
+	INTERCONNECT_DESC_PARAM_MPHY_VER	= 0x4,
+};
+
+/* Geometry descriptor parameters offsets in bytes*/
+enum geometry_desc_param {
+	GEOMETRY_DESC_PARAM_LEN			= 0x0,
+	GEOMETRY_DESC_PARAM_TYPE		= 0x1,
+	GEOMETRY_DESC_PARAM_DEV_CAP		= 0x4,
+	GEOMETRY_DESC_PARAM_MAX_NUM_LUN		= 0xC,
+	GEOMETRY_DESC_PARAM_SEG_SIZE		= 0xD,
+	GEOMETRY_DESC_PARAM_ALLOC_UNIT_SIZE	= 0x11,
+	GEOMETRY_DESC_PARAM_MIN_BLK_SIZE	= 0x12,
+	GEOMETRY_DESC_PARAM_OPT_RD_BLK_SIZE	= 0x13,
+	GEOMETRY_DESC_PARAM_OPT_WR_BLK_SIZE	= 0x14,
+	GEOMETRY_DESC_PARAM_MAX_IN_BUF_SIZE	= 0x15,
+	GEOMETRY_DESC_PARAM_MAX_OUT_BUF_SIZE	= 0x16,
+	GEOMETRY_DESC_PARAM_RPMB_RW_SIZE	= 0x17,
+	GEOMETRY_DESC_PARAM_DYN_CAP_RSRC_PLC	= 0x18,
+	GEOMETRY_DESC_PARAM_DATA_ORDER		= 0x19,
+	GEOMETRY_DESC_PARAM_MAX_NUM_CTX		= 0x1A,
+	GEOMETRY_DESC_PARAM_TAG_UNIT_SIZE	= 0x1B,
+	GEOMETRY_DESC_PARAM_TAG_RSRC_SIZE	= 0x1C,
+	GEOMETRY_DESC_PARAM_SEC_RM_TYPES	= 0x1D,
+	GEOMETRY_DESC_PARAM_MEM_TYPES		= 0x1E,
+	GEOMETRY_DESC_PARAM_SCM_MAX_NUM_UNITS	= 0x20,
+	GEOMETRY_DESC_PARAM_SCM_CAP_ADJ_FCTR	= 0x24,
+	GEOMETRY_DESC_PARAM_NPM_MAX_NUM_UNITS	= 0x26,
+	GEOMETRY_DESC_PARAM_NPM_CAP_ADJ_FCTR	= 0x2A,
+	GEOMETRY_DESC_PARAM_ENM1_MAX_NUM_UNITS	= 0x2C,
+	GEOMETRY_DESC_PARAM_ENM1_CAP_ADJ_FCTR	= 0x30,
+	GEOMETRY_DESC_PARAM_ENM2_MAX_NUM_UNITS	= 0x32,
+	GEOMETRY_DESC_PARAM_ENM2_CAP_ADJ_FCTR	= 0x36,
+	GEOMETRY_DESC_PARAM_ENM3_MAX_NUM_UNITS	= 0x38,
+	GEOMETRY_DESC_PARAM_ENM3_CAP_ADJ_FCTR	= 0x3C,
+	GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS	= 0x3E,
+	GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR	= 0x42,
+	GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE	= 0x44,
+};
+
+/* Health descriptor parameters offsets in bytes*/
+enum health_desc_param {
+	HEALTH_DESC_PARAM_LEN			= 0x0,
+	HEALTH_DESC_PARAM_TYPE			= 0x1,
+	HEALTH_DESC_PARAM_EOL_INFO		= 0x2,
+	HEALTH_DESC_PARAM_LIFE_TIME_EST_A	= 0x3,
+	HEALTH_DESC_PARAM_LIFE_TIME_EST_B	= 0x4,
 };
 
 /*
@@ -529,4 +620,14 @@ struct ufs_dev_desc {
 	char model[MAX_MODEL_LEN + 1];
 };
 
+/**
+ * ufs_is_valid_unit_desc_lun - checks if the given LUN has a unit descriptor
+ * @lun: LU number to check
+ * @return: true if the lun has a matching unit descriptor, false otherwise
+ */
+static inline bool ufs_is_valid_unit_desc_lun(u8 lun)
+{
+	return lun == UFS_UPIU_RPMB_WLUN || (lun < UFS_UPIU_MAX_GENERAL_LUN);
+}
+
 #endif /* End of Header */
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c
index 925b0ec..ffe6f82 100644
--- a/drivers/scsi/ufs/ufshcd-pci.c
+++ b/drivers/scsi/ufs/ufshcd-pci.c
@@ -75,8 +75,7 @@ static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = {
 #ifdef CONFIG_PM_SLEEP
 /**
  * ufshcd_pci_suspend - suspend power management function
- * @pdev: pointer to PCI device handle
- * @state: power state
+ * @dev: pointer to PCI device handle
  *
  * Returns 0 if successful
  * Returns non-zero otherwise
@@ -88,7 +87,7 @@ static int ufshcd_pci_suspend(struct device *dev)
 
 /**
  * ufshcd_pci_resume - resume power management function
- * @pdev: pointer to PCI device handle
+ * @dev: pointer to PCI device handle
  *
  * Returns 0 if successful
  * Returns non-zero otherwise
@@ -126,7 +125,7 @@ static void ufshcd_pci_shutdown(struct pci_dev *pdev)
 /**
  * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space
  *		data structure memory
- * @pdev - pointer to PCI handle
+ * @pdev: pointer to PCI handle
  */
 static void ufshcd_pci_remove(struct pci_dev *pdev)
 {
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c7da2c1..c5b1bf1 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -41,9 +41,11 @@
 #include <linux/devfreq.h>
 #include <linux/nls.h>
 #include <linux/of.h>
+#include <linux/bitfield.h>
 #include "ufshcd.h"
 #include "ufs_quirks.h"
 #include "unipro.h"
+#include "ufs-sysfs.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ufs.h>
@@ -150,7 +152,7 @@ enum {
 #define ufshcd_is_ufs_dev_poweroff(h) \
 	((h)->curr_dev_pwr_mode == UFS_POWERDOWN_PWR_MODE)
 
-static struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
+struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
 	{UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE},
 	{UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE},
 	{UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE},
@@ -523,7 +525,7 @@ int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask,
 
 /**
  * ufshcd_get_intr_mask - Get the interrupt bit mask
- * @hba - Pointer to adapter instance
+ * @hba: Pointer to adapter instance
  *
  * Returns interrupt bit mask per version
  */
@@ -550,7 +552,7 @@ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba)
 
 /**
  * ufshcd_get_ufs_version - Get the UFS version supported by the HBA
- * @hba - Pointer to adapter instance
+ * @hba: Pointer to adapter instance
  *
  * Returns UFSHCI version supported by the controller
  */
@@ -577,7 +579,7 @@ static inline bool ufshcd_is_device_present(struct ufs_hba *hba)
 
 /**
  * ufshcd_get_tr_ocs - Get the UTRD Overall Command Status
- * @lrb: pointer to local command reference block
+ * @lrbp: pointer to local command reference block
  *
  * This function is used to get the OCS field from UTRD
  * Returns the OCS field in the UTRD
@@ -813,28 +815,6 @@ static inline bool ufshcd_is_hba_active(struct ufs_hba *hba)
 		? false : true;
 }
 
-static const char *ufschd_uic_link_state_to_string(
-			enum uic_link_state state)
-{
-	switch (state) {
-	case UIC_LINK_OFF_STATE:	return "OFF";
-	case UIC_LINK_ACTIVE_STATE:	return "ACTIVE";
-	case UIC_LINK_HIBERN8_STATE:	return "HIBERN8";
-	default:			return "UNKNOWN";
-	}
-}
-
-static const char *ufschd_ufs_dev_pwr_mode_to_string(
-			enum ufs_dev_pwr_mode state)
-{
-	switch (state) {
-	case UFS_ACTIVE_PWR_MODE:	return "ACTIVE";
-	case UFS_SLEEP_PWR_MODE:	return "SLEEP";
-	case UFS_POWERDOWN_PWR_MODE:	return "POWERDOWN";
-	default:			return "UNKNOWN";
-	}
-}
-
 u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba)
 {
 	/* HCI version 1.0 and 1.1 supports UniPro 1.41 */
@@ -1759,7 +1739,7 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
 
 /**
  * ufshcd_copy_sense_data - Copy sense data in case of check condition
- * @lrb - pointer to local reference block
+ * @lrbp: pointer to local reference block
  */
 static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp)
 {
@@ -1781,7 +1761,7 @@ static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp)
  * ufshcd_copy_query_response() - Copy the Query Response and the data
  * descriptor
  * @hba: per adapter instance
- * @lrb - pointer to local reference block
+ * @lrbp: pointer to local reference block
  */
 static
 int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
@@ -1882,7 +1862,7 @@ ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
 /**
  * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command
  * @hba: per adapter instance
- * @uic_command: UIC command
+ * @uic_cmd: UIC command
  *
  * Must be called with mutex held.
  * Returns 0 only if success.
@@ -1965,7 +1945,8 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
 
 /**
  * ufshcd_map_sg - Map scatter-gather list to prdt
- * @lrbp - pointer to local reference block
+ * @hba: per adapter instance
+ * @lrbp: pointer to local reference block
  *
  * Returns 0 in case of success, non-zero value in case of failure
  */
@@ -2101,8 +2082,8 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp,
 /**
  * ufshcd_prepare_utp_scsi_cmd_upiu() - fills the utp_transfer_req_desc,
  * for scsi commands
- * @lrbp - local reference block pointer
- * @upiu_flags - flags
+ * @lrbp: local reference block pointer
+ * @upiu_flags: flags
  */
 static
 void ufshcd_prepare_utp_scsi_cmd_upiu(struct ufshcd_lrb *lrbp, u32 upiu_flags)
@@ -2190,8 +2171,8 @@ static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp)
 /**
  * ufshcd_comp_devman_upiu - UFS Protocol Information Unit(UPIU)
  *			     for Device Management Purposes
- * @hba - per adapter instance
- * @lrb - pointer to local reference block
+ * @hba: per adapter instance
+ * @lrbp: pointer to local reference block
  */
 static int ufshcd_comp_devman_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 {
@@ -2218,8 +2199,8 @@ static int ufshcd_comp_devman_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 /**
  * ufshcd_comp_scsi_upiu - UFS Protocol Information Unit(UPIU)
  *			   for SCSI Purposes
- * @hba - per adapter instance
- * @lrb - pointer to local reference block
+ * @hba: per adapter instance
+ * @lrbp: pointer to local reference block
  */
 static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 {
@@ -2243,24 +2224,9 @@ static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 	return ret;
 }
 
-/*
- * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN
- * @scsi_lun: scsi LUN id
- *
- * Returns UPIU LUN id
- */
-static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun)
-{
-	if (scsi_is_wlun(scsi_lun))
-		return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID)
-			| UFS_UPIU_WLUN_ID;
-	else
-		return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID;
-}
-
 /**
  * ufshcd_upiu_wlun_to_scsi_wlun - maps UPIU W-LUN id to SCSI W-LUN ID
- * @scsi_lun: UPIU W-LUN id
+ * @upiu_wlun_id: UPIU W-LUN id
  *
  * Returns SCSI W-LUN id
  */
@@ -2271,8 +2237,8 @@ static inline u16 ufshcd_upiu_wlun_to_scsi_wlun(u8 upiu_wlun_id)
 
 /**
  * ufshcd_queuecommand - main entry point for SCSI requests
+ * @host: SCSI host pointer
  * @cmd: command from SCSI Midlayer
- * @done: call back function
  *
  * Returns 0 for success, non-zero in case of failure
  */
@@ -2513,7 +2479,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
 /**
  * ufshcd_get_dev_cmd_tag - Get device management command tag
  * @hba: per-adapter instance
- * @tag: pointer to variable with available slot value
+ * @tag_out: pointer to variable with available slot value
  *
  * Get a free slot and lock it until device management command
  * completes.
@@ -2550,9 +2516,9 @@ static inline void ufshcd_put_dev_cmd_tag(struct ufs_hba *hba, int tag)
 
 /**
  * ufshcd_exec_dev_cmd - API for sending device management requests
- * @hba - UFS hba
- * @cmd_type - specifies the type (NOP, Query...)
- * @timeout - time in seconds
+ * @hba: UFS hba
+ * @cmd_type: specifies the type (NOP, Query...)
+ * @timeout: time in seconds
  *
  * NOTE: Since there is only one available tag for device management commands,
  * it is expected you hold the hba->dev_cmd.lock mutex.
@@ -2649,10 +2615,10 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba,
 
 /**
  * ufshcd_query_flag() - API function for sending flag query requests
- * hba: per-adapter instance
- * query_opcode: flag query to perform
- * idn: flag idn to access
- * flag_res: the flag value after the query request completes
+ * @hba: per-adapter instance
+ * @opcode: flag query to perform
+ * @idn: flag idn to access
+ * @flag_res: the flag value after the query request completes
  *
  * Returns 0 for success, non-zero in case of failure
  */
@@ -2716,17 +2682,17 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
 
 /**
  * ufshcd_query_attr - API function for sending attribute requests
- * hba: per-adapter instance
- * opcode: attribute opcode
- * idn: attribute idn to access
- * index: index field
- * selector: selector field
- * attr_val: the attribute value after the query request completes
+ * @hba: per-adapter instance
+ * @opcode: attribute opcode
+ * @idn: attribute idn to access
+ * @index: index field
+ * @selector: selector field
+ * @attr_val: the attribute value after the query request completes
  *
  * Returns 0 for success, non-zero in case of failure
 */
-static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
-			enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
+int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
+		      enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
 {
 	struct ufs_query_req *request = NULL;
 	struct ufs_query_res *response = NULL;
@@ -2880,25 +2846,24 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba,
 }
 
 /**
- * ufshcd_query_descriptor_retry - API function for sending descriptor
- * requests
- * hba: per-adapter instance
- * opcode: attribute opcode
- * idn: attribute idn to access
- * index: index field
- * selector: selector field
- * desc_buf: the buffer that contains the descriptor
- * buf_len: length parameter passed to the device
+ * ufshcd_query_descriptor_retry - API function for sending descriptor requests
+ * @hba: per-adapter instance
+ * @opcode: attribute opcode
+ * @idn: attribute idn to access
+ * @index: index field
+ * @selector: selector field
+ * @desc_buf: the buffer that contains the descriptor
+ * @buf_len: length parameter passed to the device
  *
  * Returns 0 for success, non-zero in case of failure.
  * The buf_len parameter will contain, on return, the length parameter
  * received on the response.
  */
-static int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
-					 enum query_opcode opcode,
-					 enum desc_idn idn, u8 index,
-					 u8 selector,
-					 u8 *desc_buf, int *buf_len)
+int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
+				  enum query_opcode opcode,
+				  enum desc_idn idn, u8 index,
+				  u8 selector,
+				  u8 *desc_buf, int *buf_len)
 {
 	int err;
 	int retries;
@@ -2987,6 +2952,9 @@ int ufshcd_map_desc_id_to_length(struct ufs_hba *hba,
 	case QUERY_DESC_IDN_STRING:
 		*desc_len = QUERY_DESC_MAX_SIZE;
 		break;
+	case QUERY_DESC_IDN_HEALTH:
+		*desc_len = hba->desc_size.hlth_desc;
+		break;
 	case QUERY_DESC_IDN_RFU_0:
 	case QUERY_DESC_IDN_RFU_1:
 		*desc_len = 0;
@@ -3010,12 +2978,12 @@ EXPORT_SYMBOL(ufshcd_map_desc_id_to_length);
  *
  * Return 0 in case of success, non-zero otherwise
  */
-static int ufshcd_read_desc_param(struct ufs_hba *hba,
-				  enum desc_idn desc_id,
-				  int desc_index,
-				  u8 param_offset,
-				  u8 *param_read_buf,
-				  u8 param_size)
+int ufshcd_read_desc_param(struct ufs_hba *hba,
+			   enum desc_idn desc_id,
+			   int desc_index,
+			   u8 param_offset,
+			   u8 *param_read_buf,
+			   u8 param_size)
 {
 	int ret;
 	u8 *desc_buf;
@@ -3110,9 +3078,8 @@ static int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size)
  *
  * Return 0 in case of success, non-zero otherwise
  */
-#define ASCII_STD true
-static int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
-				   u8 *buf, u32 size, bool ascii)
+int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
+			    u8 *buf, u32 size, bool ascii)
 {
 	int err = 0;
 
@@ -3189,7 +3156,7 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba,
 	 * Unit descriptors are only available for general purpose LUs (LUN id
 	 * from 0 to 7) and RPMB Well known LU.
 	 */
-	if (lun != UFS_UPIU_RPMB_WLUN && (lun >= UFS_UPIU_MAX_GENERAL_LUN))
+	if (!ufs_is_valid_unit_desc_lun(lun))
 		return -EOPNOTSUPP;
 
 	return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_UNIT, lun,
@@ -3742,6 +3709,18 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
 	return ret;
 }
 
+static void ufshcd_auto_hibern8_enable(struct ufs_hba *hba)
+{
+	unsigned long flags;
+
+	if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) || !hba->ahit)
+		return;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER);
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+}
+
  /**
  * ufshcd_init_pwr_info - setting the POR (power on reset)
  * values in hba power info
@@ -3912,7 +3891,7 @@ static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
 
 /**
  * ufshcd_complete_dev_init() - checks device readiness
- * hba: per-adapter instance
+ * @hba: per-adapter instance
  *
  * Set fDeviceInit flag and poll until device toggles it.
  */
@@ -4453,7 +4432,7 @@ static int ufshcd_task_req_compl(struct ufs_hba *hba, u32 index, u8 *resp)
 
 /**
  * ufshcd_scsi_cmd_status - Update SCSI command result based on SCSI status
- * @lrb: pointer to local reference block of completed command
+ * @lrbp: pointer to local reference block of completed command
  * @scsi_status: SCSI command status
  *
  * Returns value base on SCSI command status
@@ -4488,7 +4467,7 @@ ufshcd_scsi_cmd_status(struct ufshcd_lrb *lrbp, int scsi_status)
 /**
  * ufshcd_transfer_rsp_status - Get overall status of the response
  * @hba: per adapter instance
- * @lrb: pointer to local reference block of completed command
+ * @lrbp: pointer to local reference block of completed command
  *
  * Returns result of the command to notify SCSI midlayer
  */
@@ -5796,7 +5775,7 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba)
 
 /**
  * ufshcd_eh_host_reset_handler - host reset handler registered to scsi layer
- * @cmd - SCSI command pointer
+ * @cmd: SCSI command pointer
  *
  * Returns SUCCESS/FAILED
  */
@@ -5981,11 +5960,11 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba)
  * will take effect only when its sent to "UFS device" well known logical unit
  * hence we require the scsi_device instance to represent this logical unit in
  * order for the UFS host driver to send the SSU command for power management.
-
+ *
  * We also require the scsi_device instance for "RPMB" (Replay Protected Memory
  * Block) LU so user space process can control this LU. User space may also
  * want to have access to BOOT LU.
-
+ *
  * This function adds scsi device instances for each of all well known LUs
  * (except "REPORT LUNS" LU).
  *
@@ -6054,7 +6033,7 @@ static int ufs_get_device_desc(struct ufs_hba *hba,
 	model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];
 
 	err = ufshcd_read_string_desc(hba, model_index, str_desc_buf,
-				QUERY_DESC_MAX_SIZE, ASCII_STD);
+				      QUERY_DESC_MAX_SIZE, true/*ASCII*/);
 	if (err) {
 		dev_err(hba->dev, "%s: Failed reading Product Name. err = %d\n",
 			__func__, err);
@@ -6300,6 +6279,10 @@ static void ufshcd_init_desc_sizes(struct ufs_hba *hba)
 		&hba->desc_size.geom_desc);
 	if (err)
 		hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE;
+	err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_HEALTH, 0,
+		&hba->desc_size.hlth_desc);
+	if (err)
+		hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE;
 }
 
 static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
@@ -6310,6 +6293,7 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
 	hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE;
 	hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE;
 	hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE;
+	hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE;
 }
 
 /**
@@ -6338,6 +6322,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
 	/* UniPro link is active now */
 	ufshcd_set_link_active(hba);
 
+	/* Enable Auto-Hibernate if configured */
+	ufshcd_auto_hibern8_enable(hba);
+
 	ret = ufshcd_verify_dev_init(hba);
 	if (ret)
 		goto out;
@@ -6496,6 +6483,12 @@ static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd)
 	return found ? BLK_EH_NOT_HANDLED : BLK_EH_RESET_TIMER;
 }
 
+static const struct attribute_group *ufshcd_driver_groups[] = {
+	&ufs_sysfs_unit_descriptor_group,
+	&ufs_sysfs_lun_attributes_group,
+	NULL,
+};
+
 static struct scsi_host_template ufshcd_driver_template = {
 	.module			= THIS_MODULE,
 	.name			= UFSHCD,
@@ -6515,6 +6508,7 @@ static struct scsi_host_template ufshcd_driver_template = {
 	.can_queue		= UFSHCD_CAN_QUEUE,
 	.max_host_blocked	= 1,
 	.track_queue_depth	= 1,
+	.sdev_groups		= ufshcd_driver_groups,
 };
 
 static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
@@ -7415,6 +7409,10 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 
 	/* Schedule clock gating in case of no access to UFS device yet */
 	ufshcd_release(hba);
+
+	/* Enable Auto-Hibernate if configured */
+	ufshcd_auto_hibern8_enable(hba);
+
 	goto out;
 
 set_old_link_state:
@@ -7436,7 +7434,6 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 /**
  * ufshcd_system_suspend - system suspend routine
  * @hba: per adapter instance
- * @pm_op: runtime PM or system PM
  *
  * Check the description of ufshcd_suspend() function for more details.
  *
@@ -7587,133 +7584,6 @@ int ufshcd_runtime_idle(struct ufs_hba *hba)
 }
 EXPORT_SYMBOL(ufshcd_runtime_idle);
 
-static inline ssize_t ufshcd_pm_lvl_store(struct device *dev,
-					   struct device_attribute *attr,
-					   const char *buf, size_t count,
-					   bool rpm)
-{
-	struct ufs_hba *hba = dev_get_drvdata(dev);
-	unsigned long flags, value;
-
-	if (kstrtoul(buf, 0, &value))
-		return -EINVAL;
-
-	if (value >= UFS_PM_LVL_MAX)
-		return -EINVAL;
-
-	spin_lock_irqsave(hba->host->host_lock, flags);
-	if (rpm)
-		hba->rpm_lvl = value;
-	else
-		hba->spm_lvl = value;
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
-	return count;
-}
-
-static ssize_t ufshcd_rpm_lvl_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct ufs_hba *hba = dev_get_drvdata(dev);
-	int curr_len;
-	u8 lvl;
-
-	curr_len = snprintf(buf, PAGE_SIZE,
-			    "\nCurrent Runtime PM level [%d] => dev_state [%s] link_state [%s]\n",
-			    hba->rpm_lvl,
-			    ufschd_ufs_dev_pwr_mode_to_string(
-				ufs_pm_lvl_states[hba->rpm_lvl].dev_state),
-			    ufschd_uic_link_state_to_string(
-				ufs_pm_lvl_states[hba->rpm_lvl].link_state));
-
-	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
-			     "\nAll available Runtime PM levels info:\n");
-	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
-		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
-				     "\tRuntime PM level [%d] => dev_state [%s] link_state [%s]\n",
-				    lvl,
-				    ufschd_ufs_dev_pwr_mode_to_string(
-					ufs_pm_lvl_states[lvl].dev_state),
-				    ufschd_uic_link_state_to_string(
-					ufs_pm_lvl_states[lvl].link_state));
-
-	return curr_len;
-}
-
-static ssize_t ufshcd_rpm_lvl_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	return ufshcd_pm_lvl_store(dev, attr, buf, count, true);
-}
-
-static void ufshcd_add_rpm_lvl_sysfs_nodes(struct ufs_hba *hba)
-{
-	hba->rpm_lvl_attr.show = ufshcd_rpm_lvl_show;
-	hba->rpm_lvl_attr.store = ufshcd_rpm_lvl_store;
-	sysfs_attr_init(&hba->rpm_lvl_attr.attr);
-	hba->rpm_lvl_attr.attr.name = "rpm_lvl";
-	hba->rpm_lvl_attr.attr.mode = 0644;
-	if (device_create_file(hba->dev, &hba->rpm_lvl_attr))
-		dev_err(hba->dev, "Failed to create sysfs for rpm_lvl\n");
-}
-
-static ssize_t ufshcd_spm_lvl_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct ufs_hba *hba = dev_get_drvdata(dev);
-	int curr_len;
-	u8 lvl;
-
-	curr_len = snprintf(buf, PAGE_SIZE,
-			    "\nCurrent System PM level [%d] => dev_state [%s] link_state [%s]\n",
-			    hba->spm_lvl,
-			    ufschd_ufs_dev_pwr_mode_to_string(
-				ufs_pm_lvl_states[hba->spm_lvl].dev_state),
-			    ufschd_uic_link_state_to_string(
-				ufs_pm_lvl_states[hba->spm_lvl].link_state));
-
-	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
-			     "\nAll available System PM levels info:\n");
-	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
-		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
-				     "\tSystem PM level [%d] => dev_state [%s] link_state [%s]\n",
-				    lvl,
-				    ufschd_ufs_dev_pwr_mode_to_string(
-					ufs_pm_lvl_states[lvl].dev_state),
-				    ufschd_uic_link_state_to_string(
-					ufs_pm_lvl_states[lvl].link_state));
-
-	return curr_len;
-}
-
-static ssize_t ufshcd_spm_lvl_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	return ufshcd_pm_lvl_store(dev, attr, buf, count, false);
-}
-
-static void ufshcd_add_spm_lvl_sysfs_nodes(struct ufs_hba *hba)
-{
-	hba->spm_lvl_attr.show = ufshcd_spm_lvl_show;
-	hba->spm_lvl_attr.store = ufshcd_spm_lvl_store;
-	sysfs_attr_init(&hba->spm_lvl_attr.attr);
-	hba->spm_lvl_attr.attr.name = "spm_lvl";
-	hba->spm_lvl_attr.attr.mode = 0644;
-	if (device_create_file(hba->dev, &hba->spm_lvl_attr))
-		dev_err(hba->dev, "Failed to create sysfs for spm_lvl\n");
-}
-
-static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba)
-{
-	ufshcd_add_rpm_lvl_sysfs_nodes(hba);
-	ufshcd_add_spm_lvl_sysfs_nodes(hba);
-}
-
-static inline void ufshcd_remove_sysfs_nodes(struct ufs_hba *hba)
-{
-	device_remove_file(hba->dev, &hba->rpm_lvl_attr);
-	device_remove_file(hba->dev, &hba->spm_lvl_attr);
-}
-
 /**
  * ufshcd_shutdown - shutdown routine
  * @hba: per adapter instance
@@ -7747,11 +7617,11 @@ EXPORT_SYMBOL(ufshcd_shutdown);
 /**
  * ufshcd_remove - de-allocate SCSI host and host memory space
  *		data structure memory
- * @hba - per adapter instance
+ * @hba: per adapter instance
  */
 void ufshcd_remove(struct ufs_hba *hba)
 {
-	ufshcd_remove_sysfs_nodes(hba);
+	ufs_sysfs_remove_nodes(hba->dev);
 	scsi_remove_host(hba->host);
 	/* disable interrupts */
 	ufshcd_disable_intr(hba, hba->intr_mask);
@@ -7986,6 +7856,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 						UFS_SLEEP_PWR_MODE,
 						UIC_LINK_HIBERN8_STATE);
 
+	/* Set the default auto-hiberate idle timer value to 150 ms */
+	if (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) {
+		hba->ahit = FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, 150) |
+			    FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, 3);
+	}
+
 	/* Hold auto suspend until async scan completes */
 	pm_runtime_get_sync(dev);
 
@@ -7998,7 +7874,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 	ufshcd_set_ufs_dev_active(hba);
 
 	async_schedule(ufshcd_async_scan, hba);
-	ufshcd_add_sysfs_nodes(hba);
+	ufs_sysfs_add_nodes(hba->dev);
 
 	return 0;
 
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 1332e54..8110dcd 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -229,6 +229,7 @@ struct ufs_desc_size {
 	int interc_desc;
 	int unit_desc;
 	int conf_desc;
+	int hlth_desc;
 };
 
 /**
@@ -530,6 +531,9 @@ struct ufs_hba {
 	struct device_attribute spm_lvl_attr;
 	int pm_op_in_progress;
 
+	/* Auto-Hibernate Idle Timer register value */
+	u32 ahit;
+
 	struct ufshcd_lrb *lrb;
 	unsigned long lrb_in_use;
 
@@ -841,8 +845,24 @@ static inline bool ufshcd_is_hs_mode(struct ufs_pa_layer_attr *pwr_info)
 }
 
 /* Expose Query-Request API */
+int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
+				  enum query_opcode opcode,
+				  enum desc_idn idn, u8 index,
+				  u8 selector,
+				  u8 *desc_buf, int *buf_len);
+int ufshcd_read_desc_param(struct ufs_hba *hba,
+			   enum desc_idn desc_id,
+			   int desc_index,
+			   u8 param_offset,
+			   u8 *param_read_buf,
+			   u8 param_size);
+int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
+		      enum attr_idn idn, u8 index, u8 selector, u32 *attr_val);
 int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
 	enum flag_idn idn, bool *flag_res);
+int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
+			    u8 *buf, u32 size, bool ascii);
+
 int ufshcd_hold(struct ufs_hba *hba, bool async);
 void ufshcd_release(struct ufs_hba *hba);
 
@@ -985,4 +1005,21 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
 		hba->vops->dbg_register_dump(hba);
 }
 
+extern struct ufs_pm_lvl_states ufs_pm_lvl_states[];
+
+/*
+ * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN
+ * @scsi_lun: scsi LUN id
+ *
+ * Returns UPIU LUN id
+ */
+static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun)
+{
+	if (scsi_is_wlun(scsi_lun))
+		return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID)
+			| UFS_UPIU_WLUN_ID;
+	else
+		return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID;
+}
+
 #endif /* End of Header */
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h
index 1a1b5d9..bb5d9c7 100644
--- a/drivers/scsi/ufs/ufshci.h
+++ b/drivers/scsi/ufs/ufshci.h
@@ -86,6 +86,7 @@ enum {
 enum {
 	MASK_TRANSFER_REQUESTS_SLOTS		= 0x0000001F,
 	MASK_TASK_MANAGEMENT_REQUEST_SLOTS	= 0x00070000,
+	MASK_AUTO_HIBERN8_SUPPORT		= 0x00800000,
 	MASK_64_ADDRESSING_SUPPORT		= 0x01000000,
 	MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT	= 0x02000000,
 	MASK_UIC_DME_TEST_MODE_SUPPORT		= 0x04000000,
@@ -119,6 +120,12 @@ enum {
 #define MANUFACTURE_ID_MASK	UFS_MASK(0xFFFF, 0)
 #define PRODUCT_ID_MASK		UFS_MASK(0xFFFF, 16)
 
+/* AHIT - Auto-Hibernate Idle Timer */
+#define UFSHCI_AHIBERN8_TIMER_MASK		GENMASK(9, 0)
+#define UFSHCI_AHIBERN8_SCALE_MASK		GENMASK(12, 10)
+#define UFSHCI_AHIBERN8_SCALE_FACTOR		10
+#define UFSHCI_AHIBERN8_MAX			(1023 * 100000)
+
 /*
  * IS - Interrupt Status - 20h
  */
diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
index 2bdeebc..6289965 100644
--- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
+++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
@@ -184,7 +184,8 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
 
 	rstc = devm_reset_control_array_get(&pdev->dev, false, false);
 	if (IS_ERR(rstc)) {
-		dev_err(&pdev->dev, "failed to get reset lines\n");
+		if (PTR_ERR(rstc) != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "failed to get reset lines\n");
 		return PTR_ERR(rstc);
 	}
 
@@ -224,7 +225,11 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
 
 static void meson_gx_pwrc_vpu_shutdown(struct platform_device *pdev)
 {
-	meson_gx_pwrc_vpu_power_off(&vpu_hdmi_pd.genpd);
+	bool powered_off;
+
+	powered_off = meson_gx_pwrc_vpu_get_power(&vpu_hdmi_pd);
+	if (!powered_off)
+		meson_gx_pwrc_vpu_power_off(&vpu_hdmi_pd.genpd);
 }
 
 static const struct of_device_id meson_gx_pwrc_vpu_match_table[] = {
diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c
index f2d8c3c..37ea0a1 100644
--- a/drivers/soc/amlogic/meson-gx-socinfo.c
+++ b/drivers/soc/amlogic/meson-gx-socinfo.c
@@ -33,6 +33,10 @@ static const struct meson_gx_soc_id {
 	{ "GXL", 0x21 },
 	{ "GXM", 0x22 },
 	{ "TXL", 0x23 },
+	{ "TXLX", 0x24 },
+	{ "AXG", 0x25 },
+	{ "GXLX", 0x26 },
+	{ "TXHD", 0x27 },
 };
 
 static const struct meson_gx_package_id {
@@ -41,12 +45,18 @@ static const struct meson_gx_package_id {
 	unsigned int pack_id;
 } soc_packages[] = {
 	{ "S905", 0x1f, 0 },
+	{ "S905H", 0x1f, 0x13 },
 	{ "S905M", 0x1f, 0x20 },
 	{ "S905D", 0x21, 0 },
 	{ "S905X", 0x21, 0x80 },
+	{ "S905W", 0x21, 0xa0 },
 	{ "S905L", 0x21, 0xc0 },
 	{ "S905M2", 0x21, 0xe0 },
 	{ "S912", 0x22, 0 },
+	{ "962X", 0x24, 0x10 },
+	{ "962E", 0x24, 0x20 },
+	{ "A113X", 0x25, 0x37 },
+	{ "A113D", 0x25, 0x22 },
 };
 
 static inline unsigned int socinfo_to_major(u32 socinfo)
@@ -97,7 +107,7 @@ static const char *socinfo_to_soc_id(u32 socinfo)
 	return "Unknown";
 }
 
-int __init meson_gx_socinfo_init(void)
+static int __init meson_gx_socinfo_init(void)
 {
 	struct soc_device_attribute *soc_dev_attr;
 	struct soc_device *soc_dev;
diff --git a/drivers/soc/amlogic/meson-mx-socinfo.c b/drivers/soc/amlogic/meson-mx-socinfo.c
index 7bfff5f..78f0f1a 100644
--- a/drivers/soc/amlogic/meson-mx-socinfo.c
+++ b/drivers/soc/amlogic/meson-mx-socinfo.c
@@ -104,7 +104,7 @@ static const struct of_device_id meson_mx_socinfo_analog_top_ids[] = {
 	{ /* sentinel */ }
 };
 
-int __init meson_mx_socinfo_init(void)
+static int __init meson_mx_socinfo_init(void)
 {
 	struct soc_device_attribute *soc_dev_attr;
 	struct soc_device *soc_dev;
diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
index 750f931..c4d35f3 100644
--- a/drivers/soc/imx/gpc.c
+++ b/drivers/soc/imx/gpc.c
@@ -254,6 +254,7 @@ static struct imx_pm_domain imx_gpc_domains[] = {
 	{
 		.base = {
 			.name = "ARM",
+			.flags = GENPD_FLAG_ALWAYS_ON,
 		},
 	}, {
 		.base = {
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 435ce5e..d762a46 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -24,6 +24,7 @@
 #include <dt-bindings/power/mt2712-power.h>
 #include <dt-bindings/power/mt6797-power.h>
 #include <dt-bindings/power/mt7622-power.h>
+#include <dt-bindings/power/mt7623a-power.h>
 #include <dt-bindings/power/mt8173-power.h>
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -518,7 +519,8 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
 		.name = "conn",
 		.sta_mask = PWR_STATUS_CONN,
 		.ctl_offs = SPM_CONN_PWR_CON,
-		.bus_prot_mask = 0x0104,
+		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
+				 MT2701_TOP_AXI_PROT_EN_CONN_S,
 		.clk_id = {CLK_NONE},
 		.active_wakeup = true,
 	},
@@ -528,7 +530,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
 		.ctl_offs = SPM_DIS_PWR_CON,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.clk_id = {CLK_MM},
-		.bus_prot_mask = 0x0002,
+		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0,
 		.active_wakeup = true,
 	},
 	[MT2701_POWER_DOMAIN_MFG] = {
@@ -664,12 +666,48 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
 		.name = "mfg",
 		.sta_mask = PWR_STATUS_MFG,
 		.ctl_offs = SPM_MFG_PWR_CON,
-		.sram_pdn_bits = GENMASK(11, 8),
-		.sram_pdn_ack_bits = GENMASK(19, 16),
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(16, 16),
 		.clk_id = {CLK_MFG},
 		.bus_prot_mask = BIT(14) | BIT(21) | BIT(23),
 		.active_wakeup = true,
 	},
+	[MT2712_POWER_DOMAIN_MFG_SC1] = {
+		.name = "mfg_sc1",
+		.sta_mask = BIT(22),
+		.ctl_offs = 0x02c0,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(16, 16),
+		.clk_id = {CLK_NONE},
+		.active_wakeup = true,
+	},
+	[MT2712_POWER_DOMAIN_MFG_SC2] = {
+		.name = "mfg_sc2",
+		.sta_mask = BIT(23),
+		.ctl_offs = 0x02c4,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(16, 16),
+		.clk_id = {CLK_NONE},
+		.active_wakeup = true,
+	},
+	[MT2712_POWER_DOMAIN_MFG_SC3] = {
+		.name = "mfg_sc3",
+		.sta_mask = BIT(30),
+		.ctl_offs = 0x01f8,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(16, 16),
+		.clk_id = {CLK_NONE},
+		.active_wakeup = true,
+	},
+};
+
+static const struct scp_subdomain scp_subdomain_mt2712[] = {
+	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VDEC},
+	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VENC},
+	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_ISP},
+	{MT2712_POWER_DOMAIN_MFG, MT2712_POWER_DOMAIN_MFG_SC1},
+	{MT2712_POWER_DOMAIN_MFG_SC1, MT2712_POWER_DOMAIN_MFG_SC2},
+	{MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3},
 };
 
 /*
@@ -794,6 +832,47 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = {
 };
 
 /*
+ * MT7623A power domain support
+ */
+
+static const struct scp_domain_data scp_domain_data_mt7623a[] = {
+	[MT7623A_POWER_DOMAIN_CONN] = {
+		.name = "conn",
+		.sta_mask = PWR_STATUS_CONN,
+		.ctl_offs = SPM_CONN_PWR_CON,
+		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
+				 MT2701_TOP_AXI_PROT_EN_CONN_S,
+		.clk_id = {CLK_NONE},
+		.active_wakeup = true,
+	},
+	[MT7623A_POWER_DOMAIN_ETH] = {
+		.name = "eth",
+		.sta_mask = PWR_STATUS_ETH,
+		.ctl_offs = SPM_ETH_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.clk_id = {CLK_ETHIF},
+		.active_wakeup = true,
+	},
+	[MT7623A_POWER_DOMAIN_HIF] = {
+		.name = "hif",
+		.sta_mask = PWR_STATUS_HIF,
+		.ctl_offs = SPM_HIF_PWR_CON,
+		.sram_pdn_bits = GENMASK(11, 8),
+		.sram_pdn_ack_bits = GENMASK(15, 12),
+		.clk_id = {CLK_ETHIF},
+		.active_wakeup = true,
+	},
+	[MT7623A_POWER_DOMAIN_IFR_MSC] = {
+		.name = "ifr_msc",
+		.sta_mask = PWR_STATUS_IFR_MSC,
+		.ctl_offs = SPM_IFR_MSC_PWR_CON,
+		.clk_id = {CLK_NONE},
+		.active_wakeup = true,
+	},
+};
+
+/*
  * MT8173 power domain support
  */
 
@@ -905,6 +984,8 @@ static const struct scp_soc_data mt2701_data = {
 static const struct scp_soc_data mt2712_data = {
 	.domains = scp_domain_data_mt2712,
 	.num_domains = ARRAY_SIZE(scp_domain_data_mt2712),
+	.subdomains = scp_subdomain_mt2712,
+	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712),
 	.regs = {
 		.pwr_sta_offs = SPM_PWR_STATUS,
 		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
@@ -934,6 +1015,16 @@ static const struct scp_soc_data mt7622_data = {
 	.bus_prot_reg_update = true,
 };
 
+static const struct scp_soc_data mt7623a_data = {
+	.domains = scp_domain_data_mt7623a,
+	.num_domains = ARRAY_SIZE(scp_domain_data_mt7623a),
+	.regs = {
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+	},
+	.bus_prot_reg_update = true,
+};
+
 static const struct scp_soc_data mt8173_data = {
 	.domains = scp_domain_data_mt8173,
 	.num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
@@ -964,6 +1055,9 @@ static const struct of_device_id of_scpsys_match_tbl[] = {
 		.compatible = "mediatek,mt7622-scpsys",
 		.data = &mt7622_data,
 	}, {
+		.compatible = "mediatek,mt7623a-scpsys",
+		.data = &mt7623a_data,
+	}, {
 		.compatible = "mediatek,mt8173-scpsys",
 		.data = &mt8173_data,
 	}, {
@@ -992,7 +1086,7 @@ static int scpsys_probe(struct platform_device *pdev)
 
 	pd_data = &scp->pd_data;
 
-	for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) {
+	for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) {
 		ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
 					     pd_data->domains[sd->subdomain]);
 		if (ret && IS_ENABLED(CONFIG_PM))
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index e050eb8..a993d19 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -47,6 +47,7 @@
 config QCOM_RMTFS_MEM
 	tristate "Qualcomm Remote Filesystem memory driver"
 	depends on ARCH_QCOM
+	select QCOM_SCM
 	help
 	  The Qualcomm remote filesystem memory driver is used for allocating
 	  and exposing regions of shared memory with remote processors for the
diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c
index 0a43b2e..c8999e3 100644
--- a/drivers/soc/qcom/rmtfs_mem.c
+++ b/drivers/soc/qcom/rmtfs_mem.c
@@ -37,6 +37,8 @@ struct qcom_rmtfs_mem {
 	phys_addr_t size;
 
 	unsigned int client_id;
+
+	unsigned int perms;
 };
 
 static ssize_t qcom_rmtfs_mem_show(struct device *dev,
@@ -151,9 +153,11 @@ static void qcom_rmtfs_mem_release_device(struct device *dev)
 static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
+	struct qcom_scm_vmperm perms[2];
 	struct reserved_mem *rmem;
 	struct qcom_rmtfs_mem *rmtfs_mem;
 	u32 client_id;
+	u32 vmid;
 	int ret;
 
 	rmem = of_reserved_mem_lookup(node);
@@ -204,10 +208,31 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
 
 	rmtfs_mem->dev.release = qcom_rmtfs_mem_release_device;
 
+	ret = of_property_read_u32(node, "qcom,vmid", &vmid);
+	if (ret < 0 && ret != -EINVAL) {
+		dev_err(&pdev->dev, "failed to parse qcom,vmid\n");
+		goto remove_cdev;
+	} else if (!ret) {
+		perms[0].vmid = QCOM_SCM_VMID_HLOS;
+		perms[0].perm = QCOM_SCM_PERM_RW;
+		perms[1].vmid = vmid;
+		perms[1].perm = QCOM_SCM_PERM_RW;
+
+		rmtfs_mem->perms = BIT(QCOM_SCM_VMID_HLOS);
+		ret = qcom_scm_assign_mem(rmtfs_mem->addr, rmtfs_mem->size,
+					  &rmtfs_mem->perms, perms, 2);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "assign memory failed\n");
+			goto remove_cdev;
+		}
+	}
+
 	dev_set_drvdata(&pdev->dev, rmtfs_mem);
 
 	return 0;
 
+remove_cdev:
+	cdev_device_del(&rmtfs_mem->cdev, &rmtfs_mem->dev);
 put_device:
 	put_device(&rmtfs_mem->dev);
 
@@ -217,6 +242,15 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
 static int qcom_rmtfs_mem_remove(struct platform_device *pdev)
 {
 	struct qcom_rmtfs_mem *rmtfs_mem = dev_get_drvdata(&pdev->dev);
+	struct qcom_scm_vmperm perm;
+
+	if (rmtfs_mem->perms) {
+		perm.vmid = QCOM_SCM_VMID_HLOS;
+		perm.perm = QCOM_SCM_PERM_RW;
+
+		qcom_scm_assign_mem(rmtfs_mem->addr, rmtfs_mem->size,
+				    &rmtfs_mem->perms, &perm, 1);
+	}
 
 	cdev_device_del(&rmtfs_mem->cdev, &rmtfs_mem->dev);
 	put_device(&rmtfs_mem->dev);
diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
index d008e5b..df3ccb3 100644
--- a/drivers/soc/qcom/wcnss_ctrl.c
+++ b/drivers/soc/qcom/wcnss_ctrl.c
@@ -249,7 +249,7 @@ static int wcnss_download_nv(struct wcnss_ctrl *wcnss, bool *expect_cbc)
 		/* Increment for next fragment */
 		req->seq++;
 
-		data += req->hdr.len;
+		data += NV_FRAGMENT_SIZE;
 		left -= NV_FRAGMENT_SIZE;
 	} while (left > 0);
 
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 09550b1..3bbe611 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -3,8 +3,8 @@
 	default y if ARCH_RENESAS
 	select SOC_BUS
 	select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \
-			   ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77970 || \
-			   ARCH_R8A77995
+			   ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \
+			   ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77995
 	select SYSC_R8A7743 if ARCH_R8A7743
 	select SYSC_R8A7745 if ARCH_R8A7745
 	select SYSC_R8A7779 if ARCH_R8A7779
@@ -14,7 +14,9 @@
 	select SYSC_R8A7794 if ARCH_R8A7794
 	select SYSC_R8A7795 if ARCH_R8A7795
 	select SYSC_R8A7796 if ARCH_R8A7796
+	select SYSC_R8A77965 if ARCH_R8A77965
 	select SYSC_R8A77970 if ARCH_R8A77970
+	select SYSC_R8A77980 if ARCH_R8A77980
 	select SYSC_R8A77995 if ARCH_R8A77995
 
 if SOC_RENESAS
@@ -56,10 +58,18 @@
 	bool "R-Car M3-W System Controller support" if COMPILE_TEST
 	select SYSC_RCAR
 
+config SYSC_R8A77965
+	bool "R-Car M3-N System Controller support" if COMPILE_TEST
+	select SYSC_RCAR
+
 config SYSC_R8A77970
 	bool "R-Car V3M System Controller support" if COMPILE_TEST
 	select SYSC_RCAR
 
+config SYSC_R8A77980
+	bool "R-Car V3H System Controller support" if COMPILE_TEST
+	select SYSC_RCAR
+
 config SYSC_R8A77995
 	bool "R-Car D3 System Controller support" if COMPILE_TEST
 	select SYSC_RCAR
diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
index 845d62a..ccb5ec5 100644
--- a/drivers/soc/renesas/Makefile
+++ b/drivers/soc/renesas/Makefile
@@ -12,7 +12,9 @@
 obj-$(CONFIG_SYSC_R8A7794)	+= r8a7794-sysc.o
 obj-$(CONFIG_SYSC_R8A7795)	+= r8a7795-sysc.o
 obj-$(CONFIG_SYSC_R8A7796)	+= r8a7796-sysc.o
+obj-$(CONFIG_SYSC_R8A77965)	+= r8a77965-sysc.o
 obj-$(CONFIG_SYSC_R8A77970)	+= r8a77970-sysc.o
+obj-$(CONFIG_SYSC_R8A77980)	+= r8a77980-sysc.o
 obj-$(CONFIG_SYSC_R8A77995)	+= r8a77995-sysc.o
 
 # Family
diff --git a/drivers/soc/renesas/r8a77965-sysc.c b/drivers/soc/renesas/r8a77965-sysc.c
new file mode 100644
index 0000000..d7f7928
--- /dev/null
+++ b/drivers/soc/renesas/r8a77965-sysc.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas R-Car M3-N System Controller
+ * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
+ *
+ * Based on Renesas R-Car M3-W System Controller
+ * Copyright (C) 2016 Glider bvba
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/power/r8a77965-sysc.h>
+
+#include "rcar-sysc.h"
+
+static const struct rcar_sysc_area r8a77965_areas[] __initconst = {
+	{ "always-on",	    0, 0, R8A77965_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+	{ "ca57-scu",	0x1c0, 0, R8A77965_PD_CA57_SCU,	R8A77965_PD_ALWAYS_ON,
+	  PD_SCU },
+	{ "ca57-cpu0",	 0x80, 0, R8A77965_PD_CA57_CPU0, R8A77965_PD_CA57_SCU,
+	  PD_CPU_NOCR },
+	{ "ca57-cpu1",	 0x80, 1, R8A77965_PD_CA57_CPU1, R8A77965_PD_CA57_SCU,
+	  PD_CPU_NOCR },
+	{ "cr7",	0x240, 0, R8A77965_PD_CR7,	R8A77965_PD_ALWAYS_ON },
+	{ "a3vc",	0x380, 0, R8A77965_PD_A3VC,	R8A77965_PD_ALWAYS_ON },
+	{ "a3vp",	0x340, 0, R8A77965_PD_A3VP,	R8A77965_PD_ALWAYS_ON },
+	{ "a2vc1",	0x3c0, 1, R8A77965_PD_A2VC1,	R8A77965_PD_A3VC },
+	{ "3dg-a",	0x100, 0, R8A77965_PD_3DG_A,	R8A77965_PD_ALWAYS_ON },
+	{ "3dg-b",	0x100, 1, R8A77965_PD_3DG_B,	R8A77965_PD_3DG_A },
+	{ "a3ir",	0x180, 0, R8A77965_PD_A3IR,	R8A77965_PD_ALWAYS_ON },
+};
+
+const struct rcar_sysc_info r8a77965_sysc_info __initconst = {
+	.areas = r8a77965_areas,
+	.num_areas = ARRAY_SIZE(r8a77965_areas),
+};
diff --git a/drivers/soc/renesas/r8a77970-sysc.c b/drivers/soc/renesas/r8a77970-sysc.c
index 8c61416..caf894f 100644
--- a/drivers/soc/renesas/r8a77970-sysc.c
+++ b/drivers/soc/renesas/r8a77970-sysc.c
@@ -25,12 +25,12 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = {
 	  PD_CPU_NOCR },
 	{ "cr7",	0x240, 0, R8A77970_PD_CR7,	R8A77970_PD_ALWAYS_ON },
 	{ "a3ir",	0x180, 0, R8A77970_PD_A3IR,	R8A77970_PD_ALWAYS_ON },
-	{ "a2ir0",	0x400, 0, R8A77970_PD_A2IR0,	R8A77970_PD_ALWAYS_ON },
-	{ "a2ir1",	0x400, 1, R8A77970_PD_A2IR1,	R8A77970_PD_A2IR0 },
-	{ "a2ir2",	0x400, 2, R8A77970_PD_A2IR2,	R8A77970_PD_A2IR0 },
-	{ "a2ir3",	0x400, 3, R8A77970_PD_A2IR3,	R8A77970_PD_A2IR0 },
-	{ "a2sc0",	0x400, 4, R8A77970_PD_A2SC0,	R8A77970_PD_ALWAYS_ON },
-	{ "a2sc1",	0x400, 5, R8A77970_PD_A2SC1,	R8A77970_PD_A2SC0 },
+	{ "a2ir0",	0x400, 0, R8A77970_PD_A2IR0,	R8A77970_PD_A3IR },
+	{ "a2ir1",	0x400, 1, R8A77970_PD_A2IR1,	R8A77970_PD_A3IR },
+	{ "a2ir2",	0x400, 2, R8A77970_PD_A2IR2,	R8A77970_PD_A3IR },
+	{ "a2ir3",	0x400, 3, R8A77970_PD_A2IR3,	R8A77970_PD_A3IR },
+	{ "a2sc0",	0x400, 4, R8A77970_PD_A2SC0,	R8A77970_PD_A3IR },
+	{ "a2sc1",	0x400, 5, R8A77970_PD_A2SC1,	R8A77970_PD_A3IR },
 };
 
 const struct rcar_sysc_info r8a77970_sysc_info __initconst = {
diff --git a/drivers/soc/renesas/r8a77980-sysc.c b/drivers/soc/renesas/r8a77980-sysc.c
new file mode 100644
index 0000000..9265fb5
--- /dev/null
+++ b/drivers/soc/renesas/r8a77980-sysc.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas R-Car V3H System Controller
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/power/r8a77980-sysc.h>
+
+#include "rcar-sysc.h"
+
+static const struct rcar_sysc_area r8a77980_areas[] __initconst = {
+	{ "always-on",	    0, 0, R8A77980_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+	{ "ca53-scu",	0x140, 0, R8A77980_PD_CA53_SCU,	R8A77980_PD_ALWAYS_ON,
+	  PD_SCU },
+	{ "ca53-cpu0",	0x200, 0, R8A77980_PD_CA53_CPU0, R8A77980_PD_CA53_SCU,
+	  PD_CPU_NOCR },
+	{ "ca53-cpu1",	0x200, 1, R8A77980_PD_CA53_CPU1, R8A77980_PD_CA53_SCU,
+	  PD_CPU_NOCR },
+	{ "ca53-cpu2",	0x200, 2, R8A77980_PD_CA53_CPU2, R8A77980_PD_CA53_SCU,
+	  PD_CPU_NOCR },
+	{ "ca53-cpu3",	0x200, 3, R8A77980_PD_CA53_CPU3, R8A77980_PD_CA53_SCU,
+	  PD_CPU_NOCR },
+	{ "cr7",	0x240, 0, R8A77980_PD_CR7,	R8A77980_PD_ALWAYS_ON },
+	{ "a3ir",	0x180, 0, R8A77980_PD_A3IR,	R8A77980_PD_ALWAYS_ON },
+	{ "a2ir0",	0x400, 0, R8A77980_PD_A2IR0,	R8A77980_PD_A3IR },
+	{ "a2ir1",	0x400, 1, R8A77980_PD_A2IR1,	R8A77980_PD_A3IR },
+	{ "a2ir2",	0x400, 2, R8A77980_PD_A2IR2,	R8A77980_PD_A3IR },
+	{ "a2ir3",	0x400, 3, R8A77980_PD_A2IR3,	R8A77980_PD_A3IR },
+	{ "a2ir4",	0x400, 4, R8A77980_PD_A2IR4,	R8A77980_PD_A3IR },
+	{ "a2ir5",	0x400, 5, R8A77980_PD_A2IR5,	R8A77980_PD_A3IR },
+	{ "a2sc0",	0x400, 6, R8A77980_PD_A2SC0,	R8A77980_PD_A3IR },
+	{ "a2sc1",	0x400, 7, R8A77980_PD_A2SC1,	R8A77980_PD_A3IR },
+	{ "a2sc2",	0x400, 8, R8A77980_PD_A2SC2,	R8A77980_PD_A3IR },
+	{ "a2sc3",	0x400, 9, R8A77980_PD_A2SC3,	R8A77980_PD_A3IR },
+	{ "a2sc4",	0x400, 10, R8A77980_PD_A2SC4,	R8A77980_PD_A3IR },
+	{ "a2pd0",	0x400, 11, R8A77980_PD_A2PD0,	R8A77980_PD_A3IR },
+	{ "a2pd1",	0x400, 12, R8A77980_PD_A2PD1,	R8A77980_PD_A3IR },
+	{ "a2cn",	0x400, 13, R8A77980_PD_A2CN,	R8A77980_PD_A3IR },
+	{ "a3vip",	0x2c0, 0, R8A77980_PD_A3VIP,	R8A77980_PD_ALWAYS_ON },
+	{ "a3vip1",	0x300, 0, R8A77980_PD_A3VIP1,	R8A77980_PD_A3VIP },
+	{ "a3vip2",	0x280, 0, R8A77980_PD_A3VIP2,	R8A77980_PD_A3VIP },
+};
+
+const struct rcar_sysc_info r8a77980_sysc_info __initconst = {
+	.areas = r8a77980_areas,
+	.num_areas = ARRAY_SIZE(r8a77980_areas),
+};
diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c
index 3316b02..8e9cb79 100644
--- a/drivers/soc/renesas/rcar-rst.c
+++ b/drivers/soc/renesas/rcar-rst.c
@@ -13,8 +13,18 @@
 #include <linux/of_address.h>
 #include <linux/soc/renesas/rcar-rst.h>
 
+#define WDTRSTCR_RESET		0xA55A0002
+#define WDTRSTCR		0x0054
+
+static int rcar_rst_enable_wdt_reset(void __iomem *base)
+{
+	iowrite32(WDTRSTCR_RESET, base + WDTRSTCR);
+	return 0;
+}
+
 struct rst_config {
-	unsigned int modemr;	/* Mode Monitoring Register Offset */
+	unsigned int modemr;		/* Mode Monitoring Register Offset */
+	int (*configure)(void *base);	/* Platform specific configuration */
 };
 
 static const struct rst_config rcar_rst_gen1 __initconst = {
@@ -23,6 +33,11 @@ static const struct rst_config rcar_rst_gen1 __initconst = {
 
 static const struct rst_config rcar_rst_gen2 __initconst = {
 	.modemr = 0x60,
+	.configure = rcar_rst_enable_wdt_reset,
+};
+
+static const struct rst_config rcar_rst_gen3 __initconst = {
+	.modemr = 0x60,
 };
 
 static const struct of_device_id rcar_rst_matches[] __initconst = {
@@ -38,11 +53,13 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
 	{ .compatible = "renesas,r8a7792-rst", .data = &rcar_rst_gen2 },
 	{ .compatible = "renesas,r8a7793-rst", .data = &rcar_rst_gen2 },
 	{ .compatible = "renesas,r8a7794-rst", .data = &rcar_rst_gen2 },
-	/* R-Car Gen3 is handled like R-Car Gen2 */
-	{ .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 },
-	{ .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 },
-	{ .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen2 },
-	{ .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen2 },
+	/* R-Car Gen3 */
+	{ .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen3 },
+	{ .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen3 },
+	{ .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen3 },
+	{ .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen3 },
+	{ .compatible = "renesas,r8a77980-rst", .data = &rcar_rst_gen3 },
+	{ .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen3 },
 	{ /* sentinel */ }
 };
 
@@ -71,6 +88,14 @@ static int __init rcar_rst_init(void)
 	rcar_rst_base = base;
 	cfg = match->data;
 	saved_mode = ioread32(base + cfg->modemr);
+	if (cfg->configure) {
+		error = cfg->configure(base);
+		if (error) {
+			pr_warn("%pOF: Cannot run SoC specific configuration\n",
+				np);
+			goto out_put;
+		}
+	}
 
 	pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode);
 
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index 52c25a5..faf20e7 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -254,7 +254,7 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
 	pm_genpd_init(genpd, gov, false);
 }
 
-static const struct of_device_id rcar_sysc_matches[] = {
+static const struct of_device_id rcar_sysc_matches[] __initconst = {
 #ifdef CONFIG_SYSC_R8A7743
 	{ .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info },
 #endif
@@ -284,9 +284,15 @@ static const struct of_device_id rcar_sysc_matches[] = {
 #ifdef CONFIG_SYSC_R8A7796
 	{ .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info },
 #endif
+#ifdef CONFIG_SYSC_R8A77965
+	{ .compatible = "renesas,r8a77965-sysc", .data = &r8a77965_sysc_info },
+#endif
 #ifdef CONFIG_SYSC_R8A77970
 	{ .compatible = "renesas,r8a77970-sysc", .data = &r8a77970_sysc_info },
 #endif
+#ifdef CONFIG_SYSC_R8A77980
+	{ .compatible = "renesas,r8a77980-sysc", .data = &r8a77980_sysc_info },
+#endif
 #ifdef CONFIG_SYSC_R8A77995
 	{ .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info },
 #endif
diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h
index 9d9daf9..dcdc9ec 100644
--- a/drivers/soc/renesas/rcar-sysc.h
+++ b/drivers/soc/renesas/rcar-sysc.h
@@ -58,7 +58,9 @@ extern const struct rcar_sysc_info r8a7792_sysc_info;
 extern const struct rcar_sysc_info r8a7794_sysc_info;
 extern const struct rcar_sysc_info r8a7795_sysc_info;
 extern const struct rcar_sysc_info r8a7796_sysc_info;
+extern const struct rcar_sysc_info r8a77965_sysc_info;
 extern const struct rcar_sysc_info r8a77970_sysc_info;
+extern const struct rcar_sysc_info r8a77980_sysc_info;
 extern const struct rcar_sysc_info r8a77995_sysc_info;
 
 
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
index 926b7fd..ea71c41 100644
--- a/drivers/soc/renesas/renesas-soc.c
+++ b/drivers/soc/renesas/renesas-soc.c
@@ -144,11 +144,21 @@ static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = {
 	.id	= 0x52,
 };
 
+static const struct renesas_soc soc_rcar_m3_n __initconst __maybe_unused = {
+	.family = &fam_rcar_gen3,
+	.id     = 0x55,
+};
+
 static const struct renesas_soc soc_rcar_v3m __initconst __maybe_unused = {
 	.family	= &fam_rcar_gen3,
 	.id	= 0x54,
 };
 
+static const struct renesas_soc soc_rcar_v3h __initconst __maybe_unused = {
+	.family	= &fam_rcar_gen3,
+	.id	= 0x56,
+};
+
 static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = {
 	.family	= &fam_rcar_gen3,
 	.id	= 0x58,
@@ -209,9 +219,15 @@ static const struct of_device_id renesas_socs[] __initconst = {
 #ifdef CONFIG_ARCH_R8A7796
 	{ .compatible = "renesas,r8a7796",	.data = &soc_rcar_m3_w },
 #endif
+#ifdef CONFIG_ARCH_R8A77965
+	{ .compatible = "renesas,r8a77965",	.data = &soc_rcar_m3_n },
+#endif
 #ifdef CONFIG_ARCH_R8A77970
 	{ .compatible = "renesas,r8a77970",	.data = &soc_rcar_v3m },
 #endif
+#ifdef CONFIG_ARCH_R8A77980
+	{ .compatible = "renesas,r8a77980",	.data = &soc_rcar_v3h },
+#endif
 #ifdef CONFIG_ARCH_R8A77995
 	{ .compatible = "renesas,r8a77995",	.data = &soc_rcar_d3 },
 #endif
diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c
index 15e71fd..96882ff 100644
--- a/drivers/soc/rockchip/grf.c
+++ b/drivers/soc/rockchip/grf.c
@@ -43,6 +43,28 @@ static const struct rockchip_grf_info rk3036_grf __initconst = {
 	.num_values = ARRAY_SIZE(rk3036_defaults),
 };
 
+#define RK3128_GRF_SOC_CON0		0x140
+
+static const struct rockchip_grf_value rk3128_defaults[] __initconst = {
+	{ "jtag switching", RK3128_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 8) },
+};
+
+static const struct rockchip_grf_info rk3128_grf __initconst = {
+	.values = rk3128_defaults,
+	.num_values = ARRAY_SIZE(rk3128_defaults),
+};
+
+#define RK3228_GRF_SOC_CON6		0x418
+
+static const struct rockchip_grf_value rk3228_defaults[] __initconst = {
+	{ "jtag switching", RK3228_GRF_SOC_CON6, HIWORD_UPDATE(0, 1, 8) },
+};
+
+static const struct rockchip_grf_info rk3228_grf __initconst = {
+	.values = rk3228_defaults,
+	.num_values = ARRAY_SIZE(rk3228_defaults),
+};
+
 #define RK3288_GRF_SOC_CON0		0x244
 
 static const struct rockchip_grf_value rk3288_defaults[] __initconst = {
@@ -92,6 +114,12 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
 		.compatible = "rockchip,rk3036-grf",
 		.data = (void *)&rk3036_grf,
 	}, {
+		.compatible = "rockchip,rk3128-grf",
+		.data = (void *)&rk3128_grf,
+	}, {
+		.compatible = "rockchip,rk3228-grf",
+		.data = (void *)&rk3228_grf,
+	}, {
 		.compatible = "rockchip,rk3288-grf",
 		.data = (void *)&rk3288_grf,
 	}, {
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index 5c34216..53efc38 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -67,7 +67,7 @@ struct rockchip_pm_domain {
 	struct regmap **qos_regmap;
 	u32 *qos_save_regs[MAX_QOS_REGS_NUM];
 	int num_clks;
-	struct clk *clks[];
+	struct clk_bulk_data *clks;
 };
 
 struct rockchip_pmu {
@@ -274,13 +274,18 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
 
 static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
 {
-	int i;
+	struct rockchip_pmu *pmu = pd->pmu;
+	int ret;
 
-	mutex_lock(&pd->pmu->mutex);
+	mutex_lock(&pmu->mutex);
 
 	if (rockchip_pmu_domain_is_on(pd) != power_on) {
-		for (i = 0; i < pd->num_clks; i++)
-			clk_enable(pd->clks[i]);
+		ret = clk_bulk_enable(pd->num_clks, pd->clks);
+		if (ret < 0) {
+			dev_err(pmu->dev, "failed to enable clocks\n");
+			mutex_unlock(&pmu->mutex);
+			return ret;
+		}
 
 		if (!power_on) {
 			rockchip_pmu_save_qos(pd);
@@ -298,11 +303,10 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
 			rockchip_pmu_restore_qos(pd);
 		}
 
-		for (i = pd->num_clks - 1; i >= 0; i--)
-			clk_disable(pd->clks[i]);
+		clk_bulk_disable(pd->num_clks, pd->clks);
 	}
 
-	mutex_unlock(&pd->pmu->mutex);
+	mutex_unlock(&pmu->mutex);
 	return 0;
 }
 
@@ -364,8 +368,6 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
 	const struct rockchip_domain_info *pd_info;
 	struct rockchip_pm_domain *pd;
 	struct device_node *qos_node;
-	struct clk *clk;
-	int clk_cnt;
 	int i, j;
 	u32 id;
 	int error;
@@ -391,41 +393,41 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
 		return -EINVAL;
 	}
 
-	clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
-	pd = devm_kzalloc(pmu->dev,
-			  sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]),
-			  GFP_KERNEL);
+	pd = devm_kzalloc(pmu->dev, sizeof(*pd), GFP_KERNEL);
 	if (!pd)
 		return -ENOMEM;
 
 	pd->info = pd_info;
 	pd->pmu = pmu;
 
-	for (i = 0; i < clk_cnt; i++) {
-		clk = of_clk_get(node, i);
-		if (IS_ERR(clk)) {
-			error = PTR_ERR(clk);
+	pd->num_clks = of_count_phandle_with_args(node, "clocks",
+						  "#clock-cells");
+	if (pd->num_clks > 0) {
+		pd->clks = devm_kcalloc(pmu->dev, pd->num_clks,
+					sizeof(*pd->clks), GFP_KERNEL);
+		if (!pd->clks)
+			return -ENOMEM;
+	} else {
+		dev_dbg(pmu->dev, "%s: doesn't have clocks: %d\n",
+			node->name, pd->num_clks);
+		pd->num_clks = 0;
+	}
+
+	for (i = 0; i < pd->num_clks; i++) {
+		pd->clks[i].clk = of_clk_get(node, i);
+		if (IS_ERR(pd->clks[i].clk)) {
+			error = PTR_ERR(pd->clks[i].clk);
 			dev_err(pmu->dev,
 				"%s: failed to get clk at index %d: %d\n",
 				node->name, i, error);
-			goto err_out;
+			return error;
 		}
-
-		error = clk_prepare(clk);
-		if (error) {
-			dev_err(pmu->dev,
-				"%s: failed to prepare clk %pC (index %d): %d\n",
-				node->name, clk, i, error);
-			clk_put(clk);
-			goto err_out;
-		}
-
-		pd->clks[pd->num_clks++] = clk;
-
-		dev_dbg(pmu->dev, "added clock '%pC' to domain '%s'\n",
-			clk, node->name);
 	}
 
+	error = clk_bulk_prepare(pd->num_clks, pd->clks);
+	if (error)
+		goto err_put_clocks;
+
 	pd->num_qos = of_count_phandle_with_args(node, "pm_qos",
 						 NULL);
 
@@ -435,7 +437,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
 					      GFP_KERNEL);
 		if (!pd->qos_regmap) {
 			error = -ENOMEM;
-			goto err_out;
+			goto err_unprepare_clocks;
 		}
 
 		for (j = 0; j < MAX_QOS_REGS_NUM; j++) {
@@ -445,7 +447,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
 							    GFP_KERNEL);
 			if (!pd->qos_save_regs[j]) {
 				error = -ENOMEM;
-				goto err_out;
+				goto err_unprepare_clocks;
 			}
 		}
 
@@ -453,13 +455,13 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
 			qos_node = of_parse_phandle(node, "pm_qos", j);
 			if (!qos_node) {
 				error = -ENODEV;
-				goto err_out;
+				goto err_unprepare_clocks;
 			}
 			pd->qos_regmap[j] = syscon_node_to_regmap(qos_node);
 			if (IS_ERR(pd->qos_regmap[j])) {
 				error = -ENODEV;
 				of_node_put(qos_node);
-				goto err_out;
+				goto err_unprepare_clocks;
 			}
 			of_node_put(qos_node);
 		}
@@ -470,7 +472,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
 		dev_err(pmu->dev,
 			"failed to power on domain '%s': %d\n",
 			node->name, error);
-		goto err_out;
+		goto err_unprepare_clocks;
 	}
 
 	pd->genpd.name = node->name;
@@ -486,17 +488,16 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
 	pmu->genpd_data.domains[id] = &pd->genpd;
 	return 0;
 
-err_out:
-	while (--i >= 0) {
-		clk_unprepare(pd->clks[i]);
-		clk_put(pd->clks[i]);
-	}
+err_unprepare_clocks:
+	clk_bulk_unprepare(pd->num_clks, pd->clks);
+err_put_clocks:
+	clk_bulk_put(pd->num_clks, pd->clks);
 	return error;
 }
 
 static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
 {
-	int i, ret;
+	int ret;
 
 	/*
 	 * We're in the error cleanup already, so we only complain,
@@ -507,10 +508,8 @@ static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
 		dev_err(pd->pmu->dev, "failed to remove domain '%s' : %d - state may be inconsistent\n",
 			pd->genpd.name, ret);
 
-	for (i = 0; i < pd->num_clks; i++) {
-		clk_unprepare(pd->clks[i]);
-		clk_put(pd->clks[i]);
-	}
+	clk_bulk_unprepare(pd->num_clks, pd->clks);
+	clk_bulk_put(pd->num_clks, pd->clks);
 
 	/* protect the zeroing of pm->num_clks */
 	mutex_lock(&pd->pmu->mutex);
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index f56adbd..d34ca20 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -85,10 +85,14 @@ static const struct of_device_id exynos_pmu_of_device_ids[] = {
 		.compatible = "samsung,exynos5250-pmu",
 		.data = exynos_pmu_data_arm_ptr(exynos5250_pmu_data),
 	}, {
+		.compatible = "samsung,exynos5410-pmu",
+	}, {
 		.compatible = "samsung,exynos5420-pmu",
 		.data = exynos_pmu_data_arm_ptr(exynos5420_pmu_data),
 	}, {
 		.compatible = "samsung,exynos5433-pmu",
+	}, {
+		.compatible = "samsung,exynos7-pmu",
 	},
 	{ /*sentinel*/ },
 };
@@ -126,6 +130,9 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, pmu_context);
 
+	if (devm_of_platform_populate(dev))
+		dev_err(dev, "Error populating children, reboot and poweroff might not work properly\n");
+
 	dev_dbg(dev, "Exynos PMU Driver probe done\n");
 	return 0;
 }
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 89ebe22..fe44816 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -104,6 +104,16 @@
 	  multi-format support, ISP for image capture processing and BPMP for
 	  power management.
 
+config ARCH_TEGRA_194_SOC
+	bool "NVIDIA Tegra194 SoC"
+	select MAILBOX
+	select TEGRA_BPMP
+	select TEGRA_HSP_MBOX
+	select TEGRA_IVC
+	select SOC_TEGRA_PMC
+	help
+	  Enable support for the NVIDIA Tegra194 SoC.
+
 endif
 endif
 
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index ce62a47..d9fcdb5 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -127,8 +127,7 @@ struct tegra_powergate {
 	unsigned int id;
 	struct clk **clks;
 	unsigned int num_clks;
-	struct reset_control **resets;
-	unsigned int num_resets;
+	struct reset_control *reset;
 };
 
 struct tegra_io_pad_soc {
@@ -153,6 +152,7 @@ struct tegra_pmc_soc {
 
 	bool has_tsense_reset;
 	bool has_gpu_clamps;
+	bool needs_mbist_war;
 
 	const struct tegra_io_pad_soc *io_pads;
 	unsigned int num_io_pads;
@@ -368,31 +368,8 @@ static int tegra_powergate_enable_clocks(struct tegra_powergate *pg)
 	return err;
 }
 
-static int tegra_powergate_reset_assert(struct tegra_powergate *pg)
+int __weak tegra210_clk_handle_mbist_war(unsigned int id)
 {
-	unsigned int i;
-	int err;
-
-	for (i = 0; i < pg->num_resets; i++) {
-		err = reset_control_assert(pg->resets[i]);
-		if (err)
-			return err;
-	}
-
-	return 0;
-}
-
-static int tegra_powergate_reset_deassert(struct tegra_powergate *pg)
-{
-	unsigned int i;
-	int err;
-
-	for (i = 0; i < pg->num_resets; i++) {
-		err = reset_control_deassert(pg->resets[i]);
-		if (err)
-			return err;
-	}
-
 	return 0;
 }
 
@@ -401,7 +378,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
 {
 	int err;
 
-	err = tegra_powergate_reset_assert(pg);
+	err = reset_control_assert(pg->reset);
 	if (err)
 		return err;
 
@@ -425,12 +402,17 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
 
 	usleep_range(10, 20);
 
-	err = tegra_powergate_reset_deassert(pg);
+	err = reset_control_deassert(pg->reset);
 	if (err)
 		goto powergate_off;
 
 	usleep_range(10, 20);
 
+	if (pg->pmc->soc->needs_mbist_war)
+		err = tegra210_clk_handle_mbist_war(pg->id);
+	if (err)
+		goto disable_clks;
+
 	if (disable_clocks)
 		tegra_powergate_disable_clocks(pg);
 
@@ -456,7 +438,7 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg)
 
 	usleep_range(10, 20);
 
-	err = tegra_powergate_reset_assert(pg);
+	err = reset_control_assert(pg->reset);
 	if (err)
 		goto disable_clks;
 
@@ -475,7 +457,7 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg)
 assert_resets:
 	tegra_powergate_enable_clocks(pg);
 	usleep_range(10, 20);
-	tegra_powergate_reset_deassert(pg);
+	reset_control_deassert(pg->reset);
 	usleep_range(10, 20);
 
 disable_clks:
@@ -586,8 +568,8 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
 	pg.id = id;
 	pg.clks = &clk;
 	pg.num_clks = 1;
-	pg.resets = &rst;
-	pg.num_resets = 1;
+	pg.reset = rst;
+	pg.pmc = pmc;
 
 	err = tegra_powergate_power_up(&pg, false);
 	if (err)
@@ -775,45 +757,22 @@ static int tegra_powergate_of_get_clks(struct tegra_powergate *pg,
 static int tegra_powergate_of_get_resets(struct tegra_powergate *pg,
 					 struct device_node *np, bool off)
 {
-	struct reset_control *rst;
-	unsigned int i, count;
 	int err;
 
-	count = of_count_phandle_with_args(np, "resets", "#reset-cells");
-	if (count == 0)
-		return -ENODEV;
-
-	pg->resets = kcalloc(count, sizeof(rst), GFP_KERNEL);
-	if (!pg->resets)
-		return -ENOMEM;
-
-	for (i = 0; i < count; i++) {
-		pg->resets[i] = of_reset_control_get_by_index(np, i);
-		if (IS_ERR(pg->resets[i])) {
-			err = PTR_ERR(pg->resets[i]);
-			goto error;
-		}
-
-		if (off)
-			err = reset_control_assert(pg->resets[i]);
-		else
-			err = reset_control_deassert(pg->resets[i]);
-
-		if (err) {
-			reset_control_put(pg->resets[i]);
-			goto error;
-		}
+	pg->reset = of_reset_control_array_get_exclusive(np);
+	if (IS_ERR(pg->reset)) {
+		err = PTR_ERR(pg->reset);
+		pr_err("failed to get device resets: %d\n", err);
+		return err;
 	}
 
-	pg->num_resets = count;
+	if (off)
+		err = reset_control_assert(pg->reset);
+	else
+		err = reset_control_deassert(pg->reset);
 
-	return 0;
-
-error:
-	while (i--)
-		reset_control_put(pg->resets[i]);
-
-	kfree(pg->resets);
+	if (err)
+		reset_control_put(pg->reset);
 
 	return err;
 }
@@ -905,10 +864,7 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
 	pm_genpd_remove(&pg->genpd);
 
 remove_resets:
-	while (pg->num_resets--)
-		reset_control_put(pg->resets[pg->num_resets]);
-
-	kfree(pg->resets);
+	reset_control_put(pg->reset);
 
 remove_clks:
 	while (pg->num_clks--)
@@ -1815,6 +1771,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
 	.cpu_powergates = tegra210_cpu_powergates,
 	.has_tsense_reset = true,
 	.has_gpu_clamps = true,
+	.needs_mbist_war = true,
 	.num_io_pads = ARRAY_SIZE(tegra210_io_pads),
 	.io_pads = tegra210_io_pads,
 	.regs = &tegra20_pmc_regs,
@@ -1920,6 +1877,7 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
 };
 
 static const struct of_device_id tegra_pmc_match[] = {
+	{ .compatible = "nvidia,tegra194-pmc", .data = &tegra186_pmc_soc },
 	{ .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc },
 	{ .compatible = "nvidia,tegra210-pmc", .data = &tegra210_pmc_soc },
 	{ .compatible = "nvidia,tegra132-pmc", .data = &tegra124_pmc_soc },
diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index 39e152a..92770d8 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -28,6 +28,15 @@
 
 	  If unsure, say N.
 
+config AMX3_PM
+	tristate "AMx3 Power Management"
+	depends on SOC_AM33XX || SOC_AM43XX
+	depends on WKUP_M3_IPC && TI_EMIF_SRAM && SRAM
+	help
+	  Enable power management on AM335x and AM437x. Required for suspend to mem
+	  and standby states on both AM335x and AM437x platforms and for deeper cpuidle
+	  c-states on AM335x.
+
 config WKUP_M3_IPC
 	tristate "TI AMx3 Wkup-M3 IPC Driver"
 	depends on WKUP_M3_RPROC
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
index 8e20528..a22edc0 100644
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
@@ -5,5 +5,6 @@
 obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS)	+= knav_qmss.o
 knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o
 obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA)	+= knav_dma.o
+obj-$(CONFIG_AMX3_PM)			+= pm33xx.o
 obj-$(CONFIG_WKUP_M3_IPC)		+= wkup_m3_ipc.o
 obj-$(CONFIG_TI_SCI_PM_DOMAINS)		+= ti_sci_pm_domains.o
diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c
new file mode 100644
index 0000000..652739c
--- /dev/null
+++ b/drivers/soc/ti/pm33xx.c
@@ -0,0 +1,349 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AM33XX Power Management Routines
+ *
+ * Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/
+ *	Vaibhav Bedia, Dave Gerlach
+ */
+
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/genalloc.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_data/pm33xx.h>
+#include <linux/platform_device.h>
+#include <linux/sizes.h>
+#include <linux/sram.h>
+#include <linux/suspend.h>
+#include <linux/ti-emif-sram.h>
+#include <linux/wkup_m3_ipc.h>
+
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/system_misc.h>
+
+#define AMX3_PM_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \
+					 (unsigned long)pm_sram->do_wfi)
+
+static int (*am33xx_do_wfi_sram)(unsigned long unused);
+static phys_addr_t am33xx_do_wfi_sram_phys;
+
+static struct gen_pool *sram_pool, *sram_pool_data;
+static unsigned long ocmcram_location, ocmcram_location_data;
+
+static struct am33xx_pm_platform_data *pm_ops;
+static struct am33xx_pm_sram_addr *pm_sram;
+
+static struct device *pm33xx_dev;
+static struct wkup_m3_ipc *m3_ipc;
+
+static u32 sram_suspend_address(unsigned long addr)
+{
+	return ((unsigned long)am33xx_do_wfi_sram +
+		AMX3_PM_SRAM_SYMBOL_OFFSET(addr));
+}
+
+#ifdef CONFIG_SUSPEND
+static int am33xx_pm_suspend(suspend_state_t suspend_state)
+{
+	int i, ret = 0;
+
+	ret = pm_ops->soc_suspend((unsigned long)suspend_state,
+				  am33xx_do_wfi_sram);
+
+	if (ret) {
+		dev_err(pm33xx_dev, "PM: Kernel suspend failure\n");
+	} else {
+		i = m3_ipc->ops->request_pm_status(m3_ipc);
+
+		switch (i) {
+		case 0:
+			dev_info(pm33xx_dev,
+				 "PM: Successfully put all powerdomains to target state\n");
+			break;
+		case 1:
+			dev_err(pm33xx_dev,
+				"PM: Could not transition all powerdomains to target state\n");
+			ret = -1;
+			break;
+		default:
+			dev_err(pm33xx_dev,
+				"PM: CM3 returned unknown result = %d\n", i);
+			ret = -1;
+		}
+	}
+
+	return ret;
+}
+
+static int am33xx_pm_enter(suspend_state_t suspend_state)
+{
+	int ret = 0;
+
+	switch (suspend_state) {
+	case PM_SUSPEND_MEM:
+	case PM_SUSPEND_STANDBY:
+		ret = am33xx_pm_suspend(suspend_state);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int am33xx_pm_begin(suspend_state_t state)
+{
+	int ret = -EINVAL;
+
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_DEEPSLEEP);
+		break;
+	case PM_SUSPEND_STANDBY:
+		ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_STANDBY);
+		break;
+	}
+
+	return ret;
+}
+
+static void am33xx_pm_end(void)
+{
+	m3_ipc->ops->finish_low_power(m3_ipc);
+}
+
+static int am33xx_pm_valid(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static const struct platform_suspend_ops am33xx_pm_ops = {
+	.begin		= am33xx_pm_begin,
+	.end		= am33xx_pm_end,
+	.enter		= am33xx_pm_enter,
+	.valid		= am33xx_pm_valid,
+};
+#endif /* CONFIG_SUSPEND */
+
+static void am33xx_pm_set_ipc_ops(void)
+{
+	u32 resume_address;
+	int temp;
+
+	temp = ti_emif_get_mem_type();
+	if (temp < 0) {
+		dev_err(pm33xx_dev, "PM: Cannot determine memory type, no PM available\n");
+		return;
+	}
+	m3_ipc->ops->set_mem_type(m3_ipc, temp);
+
+	/* Physical resume address to be used by ROM code */
+	resume_address = am33xx_do_wfi_sram_phys +
+			 *pm_sram->resume_offset + 0x4;
+
+	m3_ipc->ops->set_resume_address(m3_ipc, (void *)resume_address);
+}
+
+static void am33xx_pm_free_sram(void)
+{
+	gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);
+	gen_pool_free(sram_pool_data, ocmcram_location_data,
+		      sizeof(struct am33xx_pm_ro_sram_data));
+}
+
+/*
+ * Push the minimal suspend-resume code to SRAM
+ */
+static int am33xx_pm_alloc_sram(void)
+{
+	struct device_node *np;
+	int ret = 0;
+
+	np = of_find_compatible_node(NULL, NULL, "ti,omap3-mpu");
+	if (!np) {
+		np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
+		if (!np) {
+			dev_err(pm33xx_dev, "PM: %s: Unable to find device node for mpu\n",
+				__func__);
+			return -ENODEV;
+		}
+	}
+
+	sram_pool = of_gen_pool_get(np, "pm-sram", 0);
+	if (!sram_pool) {
+		dev_err(pm33xx_dev, "PM: %s: Unable to get sram pool for ocmcram\n",
+			__func__);
+		ret = -ENODEV;
+		goto mpu_put_node;
+	}
+
+	sram_pool_data = of_gen_pool_get(np, "pm-sram", 1);
+	if (!sram_pool_data) {
+		dev_err(pm33xx_dev, "PM: %s: Unable to get sram data pool for ocmcram\n",
+			__func__);
+		ret = -ENODEV;
+		goto mpu_put_node;
+	}
+
+	ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz);
+	if (!ocmcram_location) {
+		dev_err(pm33xx_dev, "PM: %s: Unable to allocate memory from ocmcram\n",
+			__func__);
+		ret = -ENOMEM;
+		goto mpu_put_node;
+	}
+
+	ocmcram_location_data = gen_pool_alloc(sram_pool_data,
+					       sizeof(struct emif_regs_amx3));
+	if (!ocmcram_location_data) {
+		dev_err(pm33xx_dev, "PM: Unable to allocate memory from ocmcram\n");
+		gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);
+		ret = -ENOMEM;
+	}
+
+mpu_put_node:
+	of_node_put(np);
+	return ret;
+}
+
+static int am33xx_push_sram_idle(void)
+{
+	struct am33xx_pm_ro_sram_data ro_sram_data;
+	int ret;
+	u32 table_addr, ro_data_addr;
+	void *copy_addr;
+
+	ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;
+	ro_sram_data.amx3_pm_sram_data_phys =
+		gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);
+
+	/* Save physical address to calculate resume offset during pm init */
+	am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,
+							ocmcram_location);
+
+	am33xx_do_wfi_sram = sram_exec_copy(sram_pool, (void *)ocmcram_location,
+					    pm_sram->do_wfi,
+					    *pm_sram->do_wfi_sz);
+	if (!am33xx_do_wfi_sram) {
+		dev_err(pm33xx_dev,
+			"PM: %s: am33xx_do_wfi copy to sram failed\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	table_addr =
+		sram_suspend_address((unsigned long)pm_sram->emif_sram_table);
+	ret = ti_emif_copy_pm_function_table(sram_pool, (void *)table_addr);
+	if (ret) {
+		dev_dbg(pm33xx_dev,
+			"PM: %s: EMIF function copy failed\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
+	ro_data_addr =
+		sram_suspend_address((unsigned long)pm_sram->ro_sram_data);
+	copy_addr = sram_exec_copy(sram_pool, (void *)ro_data_addr,
+				   &ro_sram_data,
+				   sizeof(ro_sram_data));
+	if (!copy_addr) {
+		dev_err(pm33xx_dev,
+			"PM: %s: ro_sram_data copy to sram failed\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int am33xx_pm_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	if (!of_machine_is_compatible("ti,am33xx") &&
+	    !of_machine_is_compatible("ti,am43"))
+		return -ENODEV;
+
+	pm_ops = dev->platform_data;
+	if (!pm_ops) {
+		dev_err(dev, "PM: Cannot get core PM ops!\n");
+		return -ENODEV;
+	}
+
+	pm_sram = pm_ops->get_sram_addrs();
+	if (!pm_sram) {
+		dev_err(dev, "PM: Cannot get PM asm function addresses!!\n");
+		return -ENODEV;
+	}
+
+	pm33xx_dev = dev;
+
+	ret = am33xx_pm_alloc_sram();
+	if (ret)
+		return ret;
+
+	ret = am33xx_push_sram_idle();
+	if (ret)
+		goto err_free_sram;
+
+	m3_ipc = wkup_m3_ipc_get();
+	if (!m3_ipc) {
+		dev_dbg(dev, "PM: Cannot get wkup_m3_ipc handle\n");
+		ret = -EPROBE_DEFER;
+		goto err_free_sram;
+	}
+
+	am33xx_pm_set_ipc_ops();
+
+#ifdef CONFIG_SUSPEND
+	suspend_set_ops(&am33xx_pm_ops);
+#endif /* CONFIG_SUSPEND */
+
+	ret = pm_ops->init();
+	if (ret) {
+		dev_err(dev, "Unable to call core pm init!\n");
+		ret = -ENODEV;
+		goto err_put_wkup_m3_ipc;
+	}
+
+	return 0;
+
+err_put_wkup_m3_ipc:
+	wkup_m3_ipc_put(m3_ipc);
+err_free_sram:
+	am33xx_pm_free_sram();
+	pm33xx_dev = NULL;
+	return ret;
+}
+
+static int am33xx_pm_remove(struct platform_device *pdev)
+{
+	suspend_set_ops(NULL);
+	wkup_m3_ipc_put(m3_ipc);
+	am33xx_pm_free_sram();
+	return 0;
+}
+
+static struct platform_driver am33xx_pm_driver = {
+	.driver = {
+		.name   = "pm33xx",
+	},
+	.probe = am33xx_pm_probe,
+	.remove = am33xx_pm_remove,
+};
+module_platform_driver(am33xx_pm_driver);
+
+MODULE_ALIAS("platform:pm33xx");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("am33xx power management driver");
diff --git a/drivers/staging/goldfish/goldfish_nand.c b/drivers/staging/goldfish/goldfish_nand.c
index 52cc136..f5e002e 100644
--- a/drivers/staging/goldfish/goldfish_nand.c
+++ b/drivers/staging/goldfish/goldfish_nand.c
@@ -119,9 +119,6 @@ static int goldfish_nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 		return -EIO;
 	}
 
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
 	return 0;
 
 invalid_arg:
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
index d20284b..4484784 100644
--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c
+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
@@ -921,8 +921,8 @@ static int spinand_probe(struct spi_device *spi_nand)
 	chip->waitfunc	= spinand_wait;
 	chip->options	|= NAND_CACHEPRG;
 	chip->select_chip = spinand_select_chip;
-	chip->onfi_set_features = nand_onfi_get_set_features_notsupp;
-	chip->onfi_get_features = nand_onfi_get_set_features_notsupp;
+	chip->set_features = nand_get_set_features_notsupp;
+	chip->get_features = nand_get_set_features_notsupp;
 
 	mtd = nand_to_mtd(chip);
 
diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h
index 4f6e3c1..8a8cd5d 100644
--- a/drivers/staging/rts5208/rtsx_chip.h
+++ b/drivers/staging/rts5208/rtsx_chip.h
@@ -339,13 +339,13 @@ struct sense_data_t {
 #define CHK_BIT(data, idx)	((data) & (1 << (idx)))
 
 /* SG descriptor */
-#define SG_INT			0x04
-#define SG_END			0x02
-#define SG_VALID		0x01
+#define RTSX_SG_INT		0x04
+#define RTSX_SG_END		0x02
+#define RTSX_SG_VALID		0x01
 
-#define SG_NO_OP		0x00
-#define SG_TRANS_DATA		(0x02 << 4)
-#define SG_LINK_DESC		(0x03 << 4)
+#define RTSX_SG_NO_OP		0x00
+#define RTSX_SG_TRANS_DATA	(0x02 << 4)
+#define RTSX_SG_LINK_DESC	(0x03 << 4)
 
 struct rtsx_chip;
 
diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c
index 8b57e17..716cce2 100644
--- a/drivers/staging/rts5208/rtsx_transport.c
+++ b/drivers/staging/rts5208/rtsx_transport.c
@@ -308,7 +308,7 @@ static inline void rtsx_add_sg_tbl(
 	do {
 		if (len > 0x80000) {
 			temp_len = 0x80000;
-			temp_opt = option & (~SG_END);
+			temp_opt = option & (~RTSX_SG_END);
 		} else {
 			temp_len = len;
 			temp_opt = option;
@@ -407,9 +407,9 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
 			*index = *index + 1;
 		}
 		if ((i == (sg_cnt - 1)) || !resid)
-			option = SG_VALID | SG_END | SG_TRANS_DATA;
+			option = RTSX_SG_VALID | RTSX_SG_END | RTSX_SG_TRANS_DATA;
 		else
-			option = SG_VALID | SG_TRANS_DATA;
+			option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA;
 
 		rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option);
 
@@ -555,9 +555,9 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
 				(unsigned int)addr, len);
 
 			if (j == (sg_cnt - 1))
-				option = SG_VALID | SG_END | SG_TRANS_DATA;
+				option = RTSX_SG_VALID | RTSX_SG_END | RTSX_SG_TRANS_DATA;
 			else
-				option = SG_VALID | SG_TRANS_DATA;
+				option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA;
 
 			rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option);
 
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 9eb10d3..8e22379 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/sched/signal.h>
 #include <asm/unaligned.h>
+#include <linux/inet.h>
 #include <net/ipv6.h>
 #include <scsi/scsi_proto.h>
 #include <scsi/iscsi_proto.h>
@@ -3291,30 +3292,6 @@ iscsit_send_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
 	return conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL, NULL, 0);
 }
 
-static bool iscsit_check_inaddr_any(struct iscsi_np *np)
-{
-	bool ret = false;
-
-	if (np->np_sockaddr.ss_family == AF_INET6) {
-		const struct sockaddr_in6 sin6 = {
-			.sin6_addr = IN6ADDR_ANY_INIT };
-		struct sockaddr_in6 *sock_in6 =
-			 (struct sockaddr_in6 *)&np->np_sockaddr;
-
-		if (!memcmp(sock_in6->sin6_addr.s6_addr,
-				sin6.sin6_addr.s6_addr, 16))
-			ret = true;
-	} else {
-		struct sockaddr_in * sock_in =
-			(struct sockaddr_in *)&np->np_sockaddr;
-
-		if (sock_in->sin_addr.s_addr == htonl(INADDR_ANY))
-			ret = true;
-	}
-
-	return ret;
-}
-
 #define SENDTARGETS_BUF_LIMIT 32768U
 
 static int
@@ -3393,7 +3370,6 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
 			list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
 						tpg_np_list) {
 				struct iscsi_np *np = tpg_np->tpg_np;
-				bool inaddr_any = iscsit_check_inaddr_any(np);
 				struct sockaddr_storage *sockaddr;
 
 				if (np->np_network_transport != network_transport)
@@ -3422,7 +3398,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
 					}
 				}
 
-				if (inaddr_any)
+				if (inet_addr_is_any((struct sockaddr *)&np->np_sockaddr))
 					sockaddr = &conn->local_sockaddr;
 				else
 					sockaddr = &np->np_sockaddr;
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 9cd4ffe..60d5b91 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -309,7 +309,7 @@ static int tcm_loop_target_reset(struct scsi_cmnd *sc)
 
 static int tcm_loop_slave_alloc(struct scsi_device *sd)
 {
-	set_bit(QUEUE_FLAG_BIDI, &sd->request_queue->queue_flags);
+	blk_queue_flag_set(QUEUE_FLAG_BIDI, sd->request_queue);
 	return 0;
 }
 
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index e9843c5..e5fd5ed 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -356,6 +356,27 @@ static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
 	return false;
 }
 
+static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_call_get_os_revision_result result;
+	} res = {
+		.result = {
+			.build_id = 0
+		}
+	};
+
+	invoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0,
+		  &res.smccc);
+
+	if (res.result.build_id)
+		pr_info("revision %lu.%lu (%08lx)", res.result.major,
+			res.result.minor, res.result.build_id);
+	else
+		pr_info("revision %lu.%lu", res.result.major, res.result.minor);
+}
+
 static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
 {
 	union {
@@ -547,6 +568,8 @@ static struct optee *optee_probe(struct device_node *np)
 		return ERR_PTR(-EINVAL);
 	}
 
+	optee_msg_get_os_revision(invoke_fn);
+
 	if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
 		pr_warn("api revision mismatch\n");
 		return ERR_PTR(-EINVAL);
diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h
index 7cd3272..bbf0cf0 100644
--- a/drivers/tee/optee/optee_smc.h
+++ b/drivers/tee/optee/optee_smc.h
@@ -112,12 +112,20 @@ struct optee_smc_calls_revision_result {
  * Trusted OS, not of the API.
  *
  * Returns revision in a0-1 in the same way as OPTEE_SMC_CALLS_REVISION
- * described above.
+ * described above. May optionally return a 32-bit build identifier in a2,
+ * with zero meaning unspecified.
  */
 #define OPTEE_SMC_FUNCID_GET_OS_REVISION OPTEE_MSG_FUNCID_GET_OS_REVISION
 #define OPTEE_SMC_CALL_GET_OS_REVISION \
 	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_REVISION)
 
+struct optee_smc_call_get_os_revision_result {
+	unsigned long major;
+	unsigned long minor;
+	unsigned long build_id;
+	unsigned long reserved1;
+};
+
 /*
  * Call with struct optee_msg_arg as argument
  *
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index 6c4b200..0124a91 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -693,7 +693,7 @@ struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
 {
 	struct tee_device *teedev;
 	void *ret;
-	int rc;
+	int rc, max_id;
 	int offs = 0;
 
 	if (!teedesc || !teedesc->name || !teedesc->ops ||
@@ -707,16 +707,20 @@ struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
 		goto err;
 	}
 
-	if (teedesc->flags & TEE_DESC_PRIVILEGED)
+	max_id = TEE_NUM_DEVICES / 2;
+
+	if (teedesc->flags & TEE_DESC_PRIVILEGED) {
 		offs = TEE_NUM_DEVICES / 2;
+		max_id = TEE_NUM_DEVICES;
+	}
 
 	spin_lock(&driver_lock);
-	teedev->id = find_next_zero_bit(dev_mask, TEE_NUM_DEVICES, offs);
-	if (teedev->id < TEE_NUM_DEVICES)
+	teedev->id = find_next_zero_bit(dev_mask, max_id, offs);
+	if (teedev->id < max_id)
 		set_bit(teedev->id, dev_mask);
 	spin_unlock(&driver_lock);
 
-	if (teedev->id >= TEE_NUM_DEVICES) {
+	if (teedev->id >= max_id) {
 		ret = ERR_PTR(-ENOMEM);
 		goto err;
 	}
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index de6847d..66a7f5a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -866,7 +866,8 @@
 
 config EBC_C384_WDT
 	tristate "WinSystems EBC-C384 Watchdog Timer"
-	depends on X86 && ISA_BUS_API
+	depends on X86
+	select ISA_BUS_API
 	select WATCHDOG_CORE
 	help
 	  Enables watchdog timer support for the watchdog timer on the
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index f1d9c6c..2bdd561 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -2,7 +2,6 @@
 #include <linux/ceph/ceph_debug.h>
 
 #include <linux/spinlock.h>
-#include <linux/fs_struct.h>
 #include <linux/namei.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 1effd7b..874607b 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -315,8 +315,7 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, unsigned int flags)
 			dio_warn_stale_pagecache(dio->iocb->ki_filp);
 	}
 
-	if (!(dio->flags & DIO_SKIP_DIO_COUNT))
-		inode_dio_end(dio->inode);
+	inode_dio_end(dio->inode);
 
 	if (flags & DIO_COMPLETE_ASYNC) {
 		/*
@@ -1252,8 +1251,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
 	 */
 	if (is_sync_kiocb(iocb))
 		dio->is_async = false;
-	else if (!(dio->flags & DIO_ASYNC_EXTEND) &&
-		 iov_iter_rw(iter) == WRITE && end > i_size_read(inode))
+	else if (iov_iter_rw(iter) == WRITE && end > i_size_read(inode))
 		dio->is_async = false;
 	else
 		dio->is_async = true;
@@ -1297,8 +1295,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
 	/*
 	 * Will be decremented at I/O completion time.
 	 */
-	if (!(dio->flags & DIO_SKIP_DIO_COUNT))
-		inode_dio_begin(inode);
+	inode_dio_begin(inode);
 
 	retval = 0;
 	sdio.blkbits = blkbits;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 7666c06..de16945 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -827,7 +827,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 	unsigned long logic_sb_block;
 	unsigned long offset = 0;
 	unsigned long def_mount_opts;
-	long ret = -EINVAL;
+	long ret = -ENOMEM;
 	int blocksize = BLOCK_SIZE;
 	int db_count;
 	int i, j;
@@ -835,7 +835,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 	int err;
 	struct ext2_mount_options opts;
 
-	err = -ENOMEM;
 	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
 	if (!sbi)
 		goto failed;
@@ -851,6 +850,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 	sbi->s_daxdev = dax_dev;
 
 	spin_lock_init(&sbi->s_lock);
+	ret = -EINVAL;
 
 	/*
 	 * See what the current blocksize for the device is, and
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 18aa2ef..1292050 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5024,12 +5024,12 @@ static int other_inode_match(struct inode * inode, unsigned long ino,
 
 	if ((inode->i_ino != ino) ||
 	    (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
-			       I_DIRTY_SYNC | I_DIRTY_DATASYNC)) ||
+			       I_DIRTY_INODE)) ||
 	    ((inode->i_state & I_DIRTY_TIME) == 0))
 		return 0;
 	spin_lock(&inode->i_lock);
 	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
-				I_DIRTY_SYNC | I_DIRTY_DATASYNC)) == 0) &&
+				I_DIRTY_INODE)) == 0) &&
 	    (inode->i_state & I_DIRTY_TIME)) {
 		struct ext4_inode_info	*ei = EXT4_I(inode);
 
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 512dca8..bf77946 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -68,6 +68,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
 		.old_blkaddr = index,
 		.new_blkaddr = index,
 		.encrypted_page = NULL,
+		.is_meta = is_meta,
 	};
 
 	if (unlikely(!is_meta))
@@ -162,6 +163,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
 		.op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD,
 		.encrypted_page = NULL,
 		.in_list = false,
+		.is_meta = (type != META_POR),
 	};
 	struct blk_plug plug;
 
@@ -569,13 +571,8 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
 	struct node_info ni;
 	int err = acquire_orphan_inode(sbi);
 
-	if (err) {
-		set_sbi_flag(sbi, SBI_NEED_FSCK);
-		f2fs_msg(sbi->sb, KERN_WARNING,
-				"%s: orphan failed (ino=%x), run fsck to fix.",
-				__func__, ino);
-		return err;
-	}
+	if (err)
+		goto err_out;
 
 	__add_ino_entry(sbi, ino, 0, ORPHAN_INO);
 
@@ -589,6 +586,11 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
 		return PTR_ERR(inode);
 	}
 
+	err = dquot_initialize(inode);
+	if (err)
+		goto err_out;
+
+	dquot_initialize(inode);
 	clear_nlink(inode);
 
 	/* truncate all the data during iput */
@@ -598,14 +600,18 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
 
 	/* ENOMEM was fully retried in f2fs_evict_inode. */
 	if (ni.blk_addr != NULL_ADDR) {
-		set_sbi_flag(sbi, SBI_NEED_FSCK);
-		f2fs_msg(sbi->sb, KERN_WARNING,
-			"%s: orphan failed (ino=%x) by kernel, retry mount.",
-				__func__, ino);
-		return -EIO;
+		err = -EIO;
+		goto err_out;
 	}
 	__remove_ino_entry(sbi, ino, ORPHAN_INO);
 	return 0;
+
+err_out:
+	set_sbi_flag(sbi, SBI_NEED_FSCK);
+	f2fs_msg(sbi->sb, KERN_WARNING,
+			"%s: orphan failed (ino=%x), run fsck to fix.",
+			__func__, ino);
+	return err;
 }
 
 int recover_orphan_inodes(struct f2fs_sb_info *sbi)
@@ -1136,6 +1142,8 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 
 	if (cpc->reason & CP_TRIMMED)
 		__set_ckpt_flags(ckpt, CP_TRIMMED_FLAG);
+	else
+		__clear_ckpt_flags(ckpt, CP_TRIMMED_FLAG);
 
 	if (cpc->reason & CP_UMOUNT)
 		__set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
@@ -1162,6 +1170,39 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 	spin_unlock_irqrestore(&sbi->cp_lock, flags);
 }
 
+static void commit_checkpoint(struct f2fs_sb_info *sbi,
+	void *src, block_t blk_addr)
+{
+	struct writeback_control wbc = {
+		.for_reclaim = 0,
+	};
+
+	/*
+	 * pagevec_lookup_tag and lock_page again will take
+	 * some extra time. Therefore, update_meta_pages and
+	 * sync_meta_pages are combined in this function.
+	 */
+	struct page *page = grab_meta_page(sbi, blk_addr);
+	int err;
+
+	memcpy(page_address(page), src, PAGE_SIZE);
+	set_page_dirty(page);
+
+	f2fs_wait_on_page_writeback(page, META, true);
+	f2fs_bug_on(sbi, PageWriteback(page));
+	if (unlikely(!clear_page_dirty_for_io(page)))
+		f2fs_bug_on(sbi, 1);
+
+	/* writeout cp pack 2 page */
+	err = __f2fs_write_meta_page(page, &wbc, FS_CP_META_IO);
+	f2fs_bug_on(sbi, err);
+
+	f2fs_put_page(page, 0);
+
+	/* submit checkpoint (with barrier if NOBARRIER is not set) */
+	f2fs_submit_merged_write(sbi, META_FLUSH);
+}
+
 static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 {
 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
@@ -1264,16 +1305,6 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 		}
 	}
 
-	/* need to wait for end_io results */
-	wait_on_all_pages_writeback(sbi);
-	if (unlikely(f2fs_cp_error(sbi)))
-		return -EIO;
-
-	/* flush all device cache */
-	err = f2fs_flush_device_cache(sbi);
-	if (err)
-		return err;
-
 	/* write out checkpoint buffer at block 0 */
 	update_meta_page(sbi, ckpt, start_blk++);
 
@@ -1301,26 +1332,26 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 		start_blk += NR_CURSEG_NODE_TYPE;
 	}
 
-	/* writeout checkpoint block */
-	update_meta_page(sbi, ckpt, start_blk);
+	/* update user_block_counts */
+	sbi->last_valid_block_count = sbi->total_valid_block_count;
+	percpu_counter_set(&sbi->alloc_valid_block_count, 0);
 
-	/* wait for previous submitted node/meta pages writeback */
+	/* Here, we have one bio having CP pack except cp pack 2 page */
+	sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
+
+	/* wait for previous submitted meta pages writeback */
 	wait_on_all_pages_writeback(sbi);
 
 	if (unlikely(f2fs_cp_error(sbi)))
 		return -EIO;
 
-	filemap_fdatawait_range(NODE_MAPPING(sbi), 0, LLONG_MAX);
-	filemap_fdatawait_range(META_MAPPING(sbi), 0, LLONG_MAX);
+	/* flush all device cache */
+	err = f2fs_flush_device_cache(sbi);
+	if (err)
+		return err;
 
-	/* update user_block_counts */
-	sbi->last_valid_block_count = sbi->total_valid_block_count;
-	percpu_counter_set(&sbi->alloc_valid_block_count, 0);
-
-	/* Here, we only have one bio having CP pack */
-	sync_meta_pages(sbi, META_FLUSH, LONG_MAX, FS_CP_META_IO);
-
-	/* wait for previous submitted meta pages writeback */
+	/* barrier and flush checkpoint cp pack 2 page if it can */
+	commit_checkpoint(sbi, ckpt, start_blk);
 	wait_on_all_pages_writeback(sbi);
 
 	release_ino_entry(sbi, false);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 7578ed1..db50686 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -175,15 +175,22 @@ static bool __same_bdev(struct f2fs_sb_info *sbi,
  */
 static struct bio *__bio_alloc(struct f2fs_sb_info *sbi, block_t blk_addr,
 				struct writeback_control *wbc,
-				int npages, bool is_read)
+				int npages, bool is_read,
+				enum page_type type, enum temp_type temp)
 {
 	struct bio *bio;
 
 	bio = f2fs_bio_alloc(sbi, npages, true);
 
 	f2fs_target_device(sbi, blk_addr, bio);
-	bio->bi_end_io = is_read ? f2fs_read_end_io : f2fs_write_end_io;
-	bio->bi_private = is_read ? NULL : sbi;
+	if (is_read) {
+		bio->bi_end_io = f2fs_read_end_io;
+		bio->bi_private = NULL;
+	} else {
+		bio->bi_end_io = f2fs_write_end_io;
+		bio->bi_private = sbi;
+		bio->bi_write_hint = io_type_to_rw_hint(sbi, type, temp);
+	}
 	if (wbc)
 		wbc_init_bio(wbc, bio);
 
@@ -196,13 +203,12 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi,
 	if (!is_read_io(bio_op(bio))) {
 		unsigned int start;
 
-		if (f2fs_sb_mounted_blkzoned(sbi->sb) &&
-			current->plug && (type == DATA || type == NODE))
-			blk_finish_plug(current->plug);
-
 		if (type != DATA && type != NODE)
 			goto submit_io;
 
+		if (f2fs_sb_has_blkzoned(sbi->sb) && current->plug)
+			blk_finish_plug(current->plug);
+
 		start = bio->bi_iter.bi_size >> F2FS_BLKSIZE_BITS;
 		start %= F2FS_IO_SIZE(sbi);
 
@@ -377,12 +383,13 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
 	struct page *page = fio->encrypted_page ?
 			fio->encrypted_page : fio->page;
 
+	verify_block_addr(fio, fio->new_blkaddr);
 	trace_f2fs_submit_page_bio(page, fio);
 	f2fs_trace_ios(fio, 0);
 
 	/* Allocate a new bio */
 	bio = __bio_alloc(fio->sbi, fio->new_blkaddr, fio->io_wbc,
-				1, is_read_io(fio->op));
+				1, is_read_io(fio->op), fio->type, fio->temp);
 
 	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
 		bio_put(bio);
@@ -422,8 +429,8 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
 	}
 
 	if (fio->old_blkaddr != NEW_ADDR)
-		verify_block_addr(sbi, fio->old_blkaddr);
-	verify_block_addr(sbi, fio->new_blkaddr);
+		verify_block_addr(fio, fio->old_blkaddr);
+	verify_block_addr(fio, fio->new_blkaddr);
 
 	bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page;
 
@@ -445,7 +452,8 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
 			goto out_fail;
 		}
 		io->bio = __bio_alloc(sbi, fio->new_blkaddr, fio->io_wbc,
-						BIO_MAX_PAGES, false);
+						BIO_MAX_PAGES, false,
+						fio->type, fio->temp);
 		io->fio = *fio;
 	}
 
@@ -832,13 +840,6 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
 	return 0;
 }
 
-static inline bool __force_buffered_io(struct inode *inode, int rw)
-{
-	return (f2fs_encrypted_file(inode) ||
-			(rw == WRITE && test_opt(F2FS_I_SB(inode), LFS)) ||
-			F2FS_I_SB(inode)->s_ndevs);
-}
-
 int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
 {
 	struct inode *inode = file_inode(iocb->ki_filp);
@@ -870,7 +871,7 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
 
 	if (direct_io) {
 		map.m_seg_type = rw_hint_to_seg_type(iocb->ki_hint);
-		flag = __force_buffered_io(inode, WRITE) ?
+		flag = f2fs_force_buffered_io(inode, WRITE) ?
 					F2FS_GET_BLOCK_PRE_AIO :
 					F2FS_GET_BLOCK_PRE_DIO;
 		goto map_blocks;
@@ -1114,6 +1115,31 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
 	return err;
 }
 
+bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len)
+{
+	struct f2fs_map_blocks map;
+	block_t last_lblk;
+	int err;
+
+	if (pos + len > i_size_read(inode))
+		return false;
+
+	map.m_lblk = F2FS_BYTES_TO_BLK(pos);
+	map.m_next_pgofs = NULL;
+	map.m_next_extent = NULL;
+	map.m_seg_type = NO_CHECK_TYPE;
+	last_lblk = F2FS_BLK_ALIGN(pos + len);
+
+	while (map.m_lblk < last_lblk) {
+		map.m_len = last_lblk - map.m_lblk;
+		err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT);
+		if (err || map.m_len == 0)
+			return false;
+		map.m_lblk += map.m_len;
+	}
+	return true;
+}
+
 static int __get_data_block(struct inode *inode, sector_t iblock,
 			struct buffer_head *bh, int create, int flag,
 			pgoff_t *next_pgofs, int seg_type)
@@ -2287,25 +2313,41 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct address_space *mapping = iocb->ki_filp->f_mapping;
 	struct inode *inode = mapping->host;
+	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	size_t count = iov_iter_count(iter);
 	loff_t offset = iocb->ki_pos;
 	int rw = iov_iter_rw(iter);
 	int err;
+	enum rw_hint hint = iocb->ki_hint;
+	int whint_mode = F2FS_OPTION(sbi).whint_mode;
 
 	err = check_direct_IO(inode, iter, offset);
 	if (err)
 		return err;
 
-	if (__force_buffered_io(inode, rw))
+	if (f2fs_force_buffered_io(inode, rw))
 		return 0;
 
 	trace_f2fs_direct_IO_enter(inode, offset, count, rw);
 
-	down_read(&F2FS_I(inode)->dio_rwsem[rw]);
+	if (rw == WRITE && whint_mode == WHINT_MODE_OFF)
+		iocb->ki_hint = WRITE_LIFE_NOT_SET;
+
+	if (!down_read_trylock(&F2FS_I(inode)->dio_rwsem[rw])) {
+		if (iocb->ki_flags & IOCB_NOWAIT) {
+			iocb->ki_hint = hint;
+			err = -EAGAIN;
+			goto out;
+		}
+		down_read(&F2FS_I(inode)->dio_rwsem[rw]);
+	}
+
 	err = blockdev_direct_IO(iocb, inode, iter, get_data_block_dio);
 	up_read(&F2FS_I(inode)->dio_rwsem[rw]);
 
 	if (rw == WRITE) {
+		if (whint_mode == WHINT_MODE_OFF)
+			iocb->ki_hint = hint;
 		if (err > 0) {
 			f2fs_update_iostat(F2FS_I_SB(inode), APP_DIRECT_IO,
 									err);
@@ -2315,6 +2357,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 		}
 	}
 
+out:
 	trace_f2fs_direct_IO_exit(inode, offset, count, rw, err);
 
 	return err;
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index f00b5ed..fe66127 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -94,14 +94,12 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page,
 	struct f2fs_dir_entry *de;
 	struct f2fs_dentry_ptr d;
 
-	dentry_blk = (struct f2fs_dentry_block *)kmap(dentry_page);
+	dentry_blk = (struct f2fs_dentry_block *)page_address(dentry_page);
 
 	make_dentry_ptr_block(NULL, &d, dentry_blk);
 	de = find_target_dentry(fname, namehash, max_slots, &d);
 	if (de)
 		*res_page = dentry_page;
-	else
-		kunmap(dentry_page);
 
 	return de;
 }
@@ -287,7 +285,6 @@ ino_t f2fs_inode_by_name(struct inode *dir, const struct qstr *qstr,
 	de = f2fs_find_entry(dir, qstr, page);
 	if (de) {
 		res = le32_to_cpu(de->ino);
-		f2fs_dentry_kunmap(dir, *page);
 		f2fs_put_page(*page, 0);
 	}
 
@@ -302,7 +299,6 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
 	f2fs_wait_on_page_writeback(page, type, true);
 	de->ino = cpu_to_le32(inode->i_ino);
 	set_de_type(de, inode->i_mode);
-	f2fs_dentry_kunmap(dir, page);
 	set_page_dirty(page);
 
 	dir->i_mtime = dir->i_ctime = current_time(dir);
@@ -350,13 +346,11 @@ static int make_empty_dir(struct inode *inode,
 	if (IS_ERR(dentry_page))
 		return PTR_ERR(dentry_page);
 
-	dentry_blk = kmap_atomic(dentry_page);
+	dentry_blk = page_address(dentry_page);
 
 	make_dentry_ptr_block(NULL, &d, dentry_blk);
 	do_make_empty_dir(inode, parent, &d);
 
-	kunmap_atomic(dentry_blk);
-
 	set_page_dirty(dentry_page);
 	f2fs_put_page(dentry_page, 1);
 	return 0;
@@ -367,6 +361,7 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
 			struct page *dpage)
 {
 	struct page *page;
+	int dummy_encrypt = DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(dir));
 	int err;
 
 	if (is_inode_flag_set(inode, FI_NEW_INODE)) {
@@ -393,7 +388,8 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
 		if (err)
 			goto put_error;
 
-		if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) {
+		if ((f2fs_encrypted_inode(dir) || dummy_encrypt) &&
+					f2fs_may_encrypt(inode)) {
 			err = fscrypt_inherit_context(dir, inode, page, false);
 			if (err)
 				goto put_error;
@@ -402,8 +398,6 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
 		page = get_node_page(F2FS_I_SB(dir), inode->i_ino);
 		if (IS_ERR(page))
 			return page;
-
-		set_cold_node(inode, page);
 	}
 
 	if (new_name) {
@@ -547,13 +541,12 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
 		if (IS_ERR(dentry_page))
 			return PTR_ERR(dentry_page);
 
-		dentry_blk = kmap(dentry_page);
+		dentry_blk = page_address(dentry_page);
 		bit_pos = room_for_filename(&dentry_blk->dentry_bitmap,
 						slots, NR_DENTRY_IN_BLOCK);
 		if (bit_pos < NR_DENTRY_IN_BLOCK)
 			goto add_dentry;
 
-		kunmap(dentry_page);
 		f2fs_put_page(dentry_page, 1);
 	}
 
@@ -588,7 +581,6 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
 	if (inode)
 		up_write(&F2FS_I(inode)->i_sem);
 
-	kunmap(dentry_page);
 	f2fs_put_page(dentry_page, 1);
 
 	return err;
@@ -642,7 +634,6 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name,
 		F2FS_I(dir)->task = NULL;
 	}
 	if (de) {
-		f2fs_dentry_kunmap(dir, page);
 		f2fs_put_page(page, 0);
 		err = -EEXIST;
 	} else if (IS_ERR(page)) {
@@ -713,7 +704,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
 
 	f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
 
-	add_ino_entry(F2FS_I_SB(dir), dir->i_ino, TRANS_DIR_INO);
+	if (F2FS_OPTION(F2FS_I_SB(dir)).fsync_mode == FSYNC_MODE_STRICT)
+		add_ino_entry(F2FS_I_SB(dir), dir->i_ino, TRANS_DIR_INO);
 
 	if (f2fs_has_inline_dentry(dir))
 		return f2fs_delete_inline_entry(dentry, page, dir, inode);
@@ -730,7 +722,6 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
 	bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
 			NR_DENTRY_IN_BLOCK,
 			0);
-	kunmap(page); /* kunmap - pair of f2fs_find_entry */
 	set_page_dirty(page);
 
 	dir->i_ctime = dir->i_mtime = current_time(dir);
@@ -775,7 +766,7 @@ bool f2fs_empty_dir(struct inode *dir)
 				return false;
 		}
 
-		dentry_blk = kmap_atomic(dentry_page);
+		dentry_blk = page_address(dentry_page);
 		if (bidx == 0)
 			bit_pos = 2;
 		else
@@ -783,7 +774,6 @@ bool f2fs_empty_dir(struct inode *dir)
 		bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
 						NR_DENTRY_IN_BLOCK,
 						bit_pos);
-		kunmap_atomic(dentry_blk);
 
 		f2fs_put_page(dentry_page, 1);
 
@@ -901,19 +891,17 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
 			}
 		}
 
-		dentry_blk = kmap(dentry_page);
+		dentry_blk = page_address(dentry_page);
 
 		make_dentry_ptr_block(inode, &d, dentry_blk);
 
 		err = f2fs_fill_dentries(ctx, &d,
 				n * NR_DENTRY_IN_BLOCK, &fstr);
 		if (err) {
-			kunmap(dentry_page);
 			f2fs_put_page(dentry_page, 1);
 			break;
 		}
 
-		kunmap(dentry_page);
 		f2fs_put_page(dentry_page, 1);
 	}
 out_free:
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index ff2352a..d5a861b 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -460,7 +460,7 @@ static struct extent_node *__insert_extent_tree(struct inode *inode,
 				struct rb_node *insert_parent)
 {
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-	struct rb_node **p = &et->root.rb_node;
+	struct rb_node **p;
 	struct rb_node *parent = NULL;
 	struct extent_node *en = NULL;
 
@@ -706,6 +706,9 @@ void f2fs_drop_extent_tree(struct inode *inode)
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	struct extent_tree *et = F2FS_I(inode)->extent_tree;
 
+	if (!f2fs_may_extent_tree(inode))
+		return;
+
 	set_inode_flag(inode, FI_NO_EXTENT);
 
 	write_lock(&et->lock);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 6300ac5..1df7f10 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -98,9 +98,10 @@ extern char *fault_name[FAULT_MAX];
 #define F2FS_MOUNT_INLINE_XATTR_SIZE	0x00800000
 #define F2FS_MOUNT_RESERVE_ROOT		0x01000000
 
-#define clear_opt(sbi, option)	((sbi)->mount_opt.opt &= ~F2FS_MOUNT_##option)
-#define set_opt(sbi, option)	((sbi)->mount_opt.opt |= F2FS_MOUNT_##option)
-#define test_opt(sbi, option)	((sbi)->mount_opt.opt & F2FS_MOUNT_##option)
+#define F2FS_OPTION(sbi)	((sbi)->mount_opt)
+#define clear_opt(sbi, option)	(F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
+#define set_opt(sbi, option)	(F2FS_OPTION(sbi).opt |= F2FS_MOUNT_##option)
+#define test_opt(sbi, option)	(F2FS_OPTION(sbi).opt & F2FS_MOUNT_##option)
 
 #define ver_after(a, b)	(typecheck(unsigned long long, a) &&		\
 		typecheck(unsigned long long, b) &&			\
@@ -113,7 +114,26 @@ typedef u32 block_t;	/*
 typedef u32 nid_t;
 
 struct f2fs_mount_info {
-	unsigned int	opt;
+	unsigned int opt;
+	int write_io_size_bits;		/* Write IO size bits */
+	block_t root_reserved_blocks;	/* root reserved blocks */
+	kuid_t s_resuid;		/* reserved blocks for uid */
+	kgid_t s_resgid;		/* reserved blocks for gid */
+	int active_logs;		/* # of active logs */
+	int inline_xattr_size;		/* inline xattr size */
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+	struct f2fs_fault_info fault_info;	/* For fault injection */
+#endif
+#ifdef CONFIG_QUOTA
+	/* Names of quota files with journalled quota */
+	char *s_qf_names[MAXQUOTAS];
+	int s_jquota_fmt;			/* Format of quota to use */
+#endif
+	/* For which write hints are passed down to block layer */
+	int whint_mode;
+	int alloc_mode;			/* segment allocation policy */
+	int fsync_mode;			/* fsync policy */
+	bool test_dummy_encryption;	/* test dummy encryption */
 };
 
 #define F2FS_FEATURE_ENCRYPT		0x0001
@@ -125,6 +145,8 @@ struct f2fs_mount_info {
 #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR	0x0040
 #define F2FS_FEATURE_QUOTA_INO		0x0080
 #define F2FS_FEATURE_INODE_CRTIME	0x0100
+#define F2FS_FEATURE_LOST_FOUND		0x0200
+#define F2FS_FEATURE_VERITY		0x0400	/* reserved */
 
 #define F2FS_HAS_FEATURE(sb, mask)					\
 	((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -450,7 +472,7 @@ static inline void make_dentry_ptr_block(struct inode *inode,
 	d->inode = inode;
 	d->max = NR_DENTRY_IN_BLOCK;
 	d->nr_bitmap = SIZE_OF_DENTRY_BITMAP;
-	d->bitmap = &t->dentry_bitmap;
+	d->bitmap = t->dentry_bitmap;
 	d->dentry = t->dentry;
 	d->filename = t->filename;
 }
@@ -576,6 +598,8 @@ enum {
 #define FADVISE_ENCRYPT_BIT	0x04
 #define FADVISE_ENC_NAME_BIT	0x08
 #define FADVISE_KEEP_SIZE_BIT	0x10
+#define FADVISE_HOT_BIT		0x20
+#define FADVISE_VERITY_BIT	0x40	/* reserved */
 
 #define file_is_cold(inode)	is_file(inode, FADVISE_COLD_BIT)
 #define file_wrong_pino(inode)	is_file(inode, FADVISE_LOST_PINO_BIT)
@@ -590,6 +614,9 @@ enum {
 #define file_set_enc_name(inode) set_file(inode, FADVISE_ENC_NAME_BIT)
 #define file_keep_isize(inode)	is_file(inode, FADVISE_KEEP_SIZE_BIT)
 #define file_set_keep_isize(inode) set_file(inode, FADVISE_KEEP_SIZE_BIT)
+#define file_is_hot(inode)	is_file(inode, FADVISE_HOT_BIT)
+#define file_set_hot(inode)	set_file(inode, FADVISE_HOT_BIT)
+#define file_clear_hot(inode)	clear_file(inode, FADVISE_HOT_BIT)
 
 #define DEF_DIR_LEVEL		0
 
@@ -637,6 +664,7 @@ struct f2fs_inode_info {
 	kprojid_t i_projid;		/* id for project quota */
 	int i_inline_xattr_size;	/* inline xattr size */
 	struct timespec i_crtime;	/* inode creation time */
+	struct timespec i_disk_time[4];	/* inode disk times */
 };
 
 static inline void get_extent_info(struct extent_info *ext,
@@ -743,7 +771,7 @@ struct f2fs_nm_info {
 	unsigned int nid_cnt[MAX_NID_STATE];	/* the number of free node id */
 	spinlock_t nid_list_lock;	/* protect nid lists ops */
 	struct mutex build_lock;	/* lock for build free nids */
-	unsigned char (*free_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE];
+	unsigned char **free_nid_bitmap;
 	unsigned char *nat_block_bitmap;
 	unsigned short *free_nid_count;	/* free nid count of NAT block */
 
@@ -976,6 +1004,7 @@ struct f2fs_io_info {
 	bool submitted;		/* indicate IO submission */
 	int need_lock;		/* indicate we need to lock cp_rwsem */
 	bool in_list;		/* indicate fio is in io_list */
+	bool is_meta;		/* indicate borrow meta inode mapping or not */
 	enum iostat_type io_type;	/* io type */
 	struct writeback_control *io_wbc; /* writeback control */
 };
@@ -1037,10 +1066,34 @@ enum {
 	MAX_TIME,
 };
 
+enum {
+	WHINT_MODE_OFF,		/* not pass down write hints */
+	WHINT_MODE_USER,	/* try to pass down hints given by users */
+	WHINT_MODE_FS,		/* pass down hints with F2FS policy */
+};
+
+enum {
+	ALLOC_MODE_DEFAULT,	/* stay default */
+	ALLOC_MODE_REUSE,	/* reuse segments as much as possible */
+};
+
+enum fsync_mode {
+	FSYNC_MODE_POSIX,	/* fsync follows posix semantics */
+	FSYNC_MODE_STRICT,	/* fsync behaves in line with ext4 */
+};
+
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#define DUMMY_ENCRYPTION_ENABLED(sbi) \
+			(unlikely(F2FS_OPTION(sbi).test_dummy_encryption))
+#else
+#define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
+#endif
+
 struct f2fs_sb_info {
 	struct super_block *sb;			/* pointer to VFS super block */
 	struct proc_dir_entry *s_proc;		/* proc entry */
 	struct f2fs_super_block *raw_super;	/* raw super block pointer */
+	struct rw_semaphore sb_lock;		/* lock for raw super block */
 	int valid_super_block;			/* valid super block no */
 	unsigned long s_flag;				/* flags for sbi */
 
@@ -1060,7 +1113,6 @@ struct f2fs_sb_info {
 	struct f2fs_bio_info *write_io[NR_PAGE_TYPE];	/* for write bios */
 	struct mutex wio_mutex[NR_PAGE_TYPE - 1][NR_TEMP_TYPE];
 						/* bio ordering for NODE/DATA */
-	int write_io_size_bits;			/* Write IO size bits */
 	mempool_t *write_io_dummy;		/* Dummy pages */
 
 	/* for checkpoint */
@@ -1110,9 +1162,7 @@ struct f2fs_sb_info {
 	unsigned int total_node_count;		/* total node block count */
 	unsigned int total_valid_node_count;	/* valid node block count */
 	loff_t max_file_blocks;			/* max block index of file */
-	int active_logs;			/* # of active logs */
 	int dir_level;				/* directory level */
-	int inline_xattr_size;			/* inline xattr size */
 	unsigned int trigger_ssr_threshold;	/* threshold to trigger ssr */
 	int readdir_ra;				/* readahead inode in readdir */
 
@@ -1122,9 +1172,6 @@ struct f2fs_sb_info {
 	block_t last_valid_block_count;		/* for recovery */
 	block_t reserved_blocks;		/* configurable reserved blocks */
 	block_t current_reserved_blocks;	/* current reserved blocks */
-	block_t root_reserved_blocks;		/* root reserved blocks */
-	kuid_t s_resuid;			/* reserved blocks for uid */
-	kgid_t s_resgid;			/* reserved blocks for gid */
 
 	unsigned int nquota_files;		/* # of quota sysfile */
 
@@ -1209,17 +1256,6 @@ struct f2fs_sb_info {
 
 	/* Precomputed FS UUID checksum for seeding other checksums */
 	__u32 s_chksum_seed;
-
-	/* For fault injection */
-#ifdef CONFIG_F2FS_FAULT_INJECTION
-	struct f2fs_fault_info fault_info;
-#endif
-
-#ifdef CONFIG_QUOTA
-	/* Names of quota files with journalled quota */
-	char *s_qf_names[MAXQUOTAS];
-	int s_jquota_fmt;			/* Format of quota to use */
-#endif
 };
 
 #ifdef CONFIG_F2FS_FAULT_INJECTION
@@ -1229,7 +1265,7 @@ struct f2fs_sb_info {
 		__func__, __builtin_return_address(0))
 static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type)
 {
-	struct f2fs_fault_info *ffi = &sbi->fault_info;
+	struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info;
 
 	if (!ffi->inject_rate)
 		return false;
@@ -1586,13 +1622,13 @@ static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
 		return false;
 	if (IS_NOQUOTA(inode))
 		return true;
+	if (uid_eq(F2FS_OPTION(sbi).s_resuid, current_fsuid()))
+		return true;
+	if (!gid_eq(F2FS_OPTION(sbi).s_resgid, GLOBAL_ROOT_GID) &&
+					in_group_p(F2FS_OPTION(sbi).s_resgid))
+		return true;
 	if (capable(CAP_SYS_RESOURCE))
 		return true;
-	if (uid_eq(sbi->s_resuid, current_fsuid()))
-		return true;
-	if (!gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) &&
-					in_group_p(sbi->s_resgid))
-		return true;
 	return false;
 }
 
@@ -1627,7 +1663,7 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
 					sbi->current_reserved_blocks;
 
 	if (!__allow_reserved_blocks(sbi, inode))
-		avail_user_block_count -= sbi->root_reserved_blocks;
+		avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
 
 	if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
 		diff = sbi->total_valid_block_count - avail_user_block_count;
@@ -1762,6 +1798,12 @@ static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
 	int offset;
 
+	if (is_set_ckpt_flags(sbi, CP_LARGE_NAT_BITMAP_FLAG)) {
+		offset = (flag == SIT_BITMAP) ?
+			le32_to_cpu(ckpt->nat_ver_bitmap_bytesize) : 0;
+		return &ckpt->sit_nat_version_bitmap + offset;
+	}
+
 	if (__cp_payload(sbi) > 0) {
 		if (flag == NAT_BITMAP)
 			return &ckpt->sit_nat_version_bitmap;
@@ -1828,7 +1870,7 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
 					sbi->current_reserved_blocks + 1;
 
 	if (!__allow_reserved_blocks(sbi, inode))
-		valid_block_count += sbi->root_reserved_blocks;
+		valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks;
 
 	if (unlikely(valid_block_count > sbi->user_block_count)) {
 		spin_unlock(&sbi->stat_lock);
@@ -2399,12 +2441,6 @@ static inline int f2fs_has_inline_dentry(struct inode *inode)
 	return is_inode_flag_set(inode, FI_INLINE_DENTRY);
 }
 
-static inline void f2fs_dentry_kunmap(struct inode *dir, struct page *page)
-{
-	if (!f2fs_has_inline_dentry(dir))
-		kunmap(page);
-}
-
 static inline int is_file(struct inode *inode, int type)
 {
 	return F2FS_I(inode)->i_advise & type;
@@ -2436,7 +2472,17 @@ static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
 	}
 	if (!is_inode_flag_set(inode, FI_AUTO_RECOVER) ||
 			file_keep_isize(inode) ||
-			i_size_read(inode) & PAGE_MASK)
+			i_size_read(inode) & ~PAGE_MASK)
+		return false;
+
+	if (!timespec_equal(F2FS_I(inode)->i_disk_time, &inode->i_atime))
+		return false;
+	if (!timespec_equal(F2FS_I(inode)->i_disk_time + 1, &inode->i_ctime))
+		return false;
+	if (!timespec_equal(F2FS_I(inode)->i_disk_time + 2, &inode->i_mtime))
+		return false;
+	if (!timespec_equal(F2FS_I(inode)->i_disk_time + 3,
+						&F2FS_I(inode)->i_crtime))
 		return false;
 
 	down_read(&F2FS_I(inode)->i_sem);
@@ -2446,9 +2492,9 @@ static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
 	return ret;
 }
 
-static inline int f2fs_readonly(struct super_block *sb)
+static inline bool f2fs_readonly(struct super_block *sb)
 {
-	return sb->s_flags & SB_RDONLY;
+	return sb_rdonly(sb);
 }
 
 static inline bool f2fs_cp_error(struct f2fs_sb_info *sbi)
@@ -2596,6 +2642,8 @@ void handle_failed_inode(struct inode *inode);
 /*
  * namei.c
  */
+int update_extension_list(struct f2fs_sb_info *sbi, const char *name,
+							bool hot, bool set);
 struct dentry *f2fs_get_parent(struct dentry *child);
 
 /*
@@ -2768,6 +2816,8 @@ void destroy_segment_manager(struct f2fs_sb_info *sbi);
 int __init create_segment_manager_caches(void);
 void destroy_segment_manager_caches(void);
 int rw_hint_to_seg_type(enum rw_hint hint);
+enum rw_hint io_type_to_rw_hint(struct f2fs_sb_info *sbi, enum page_type type,
+				enum temp_type temp);
 
 /*
  * checkpoint.c
@@ -2850,6 +2900,7 @@ int f2fs_release_page(struct page *page, gfp_t wait);
 int f2fs_migrate_page(struct address_space *mapping, struct page *newpage,
 			struct page *page, enum migrate_mode mode);
 #endif
+bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len);
 
 /*
  * gc.c
@@ -3172,45 +3223,21 @@ static inline bool f2fs_bio_encrypted(struct bio *bio)
 	return bio->bi_private != NULL;
 }
 
-static inline int f2fs_sb_has_crypto(struct super_block *sb)
-{
-	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_ENCRYPT);
+#define F2FS_FEATURE_FUNCS(name, flagname) \
+static inline int f2fs_sb_has_##name(struct super_block *sb) \
+{ \
+	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_##flagname); \
 }
 
-static inline int f2fs_sb_mounted_blkzoned(struct super_block *sb)
-{
-	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_BLKZONED);
-}
-
-static inline int f2fs_sb_has_extra_attr(struct super_block *sb)
-{
-	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_EXTRA_ATTR);
-}
-
-static inline int f2fs_sb_has_project_quota(struct super_block *sb)
-{
-	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_PRJQUOTA);
-}
-
-static inline int f2fs_sb_has_inode_chksum(struct super_block *sb)
-{
-	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_INODE_CHKSUM);
-}
-
-static inline int f2fs_sb_has_flexible_inline_xattr(struct super_block *sb)
-{
-	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_FLEXIBLE_INLINE_XATTR);
-}
-
-static inline int f2fs_sb_has_quota_ino(struct super_block *sb)
-{
-	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_QUOTA_INO);
-}
-
-static inline int f2fs_sb_has_inode_crtime(struct super_block *sb)
-{
-	return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_INODE_CRTIME);
-}
+F2FS_FEATURE_FUNCS(encrypt, ENCRYPT);
+F2FS_FEATURE_FUNCS(blkzoned, BLKZONED);
+F2FS_FEATURE_FUNCS(extra_attr, EXTRA_ATTR);
+F2FS_FEATURE_FUNCS(project_quota, PRJQUOTA);
+F2FS_FEATURE_FUNCS(inode_chksum, INODE_CHKSUM);
+F2FS_FEATURE_FUNCS(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);
+F2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO);
+F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME);
+F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND);
 
 #ifdef CONFIG_BLK_DEV_ZONED
 static inline int get_blkz_type(struct f2fs_sb_info *sbi,
@@ -3230,7 +3257,7 @@ static inline bool f2fs_discard_en(struct f2fs_sb_info *sbi)
 {
 	struct request_queue *q = bdev_get_queue(sbi->sb->s_bdev);
 
-	return blk_queue_discard(q) || f2fs_sb_mounted_blkzoned(sbi->sb);
+	return blk_queue_discard(q) || f2fs_sb_has_blkzoned(sbi->sb);
 }
 
 static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt)
@@ -3259,4 +3286,11 @@ static inline bool f2fs_may_encrypt(struct inode *inode)
 #endif
 }
 
+static inline bool f2fs_force_buffered_io(struct inode *inode, int rw)
+{
+	return (f2fs_encrypted_file(inode) ||
+			(rw == WRITE && test_opt(F2FS_I_SB(inode), LFS)) ||
+			F2FS_I_SB(inode)->s_ndevs);
+}
+
 #endif
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 672a542..6b94f19 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -163,9 +163,10 @@ static inline enum cp_reason_type need_do_checkpoint(struct inode *inode)
 		cp_reason = CP_NODE_NEED_CP;
 	else if (test_opt(sbi, FASTBOOT))
 		cp_reason = CP_FASTBOOT_MODE;
-	else if (sbi->active_logs == 2)
+	else if (F2FS_OPTION(sbi).active_logs == 2)
 		cp_reason = CP_SPEC_LOG_NUM;
-	else if (need_dentry_mark(sbi, inode->i_ino) &&
+	else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT &&
+		need_dentry_mark(sbi, inode->i_ino) &&
 		exist_written_data(sbi, F2FS_I(inode)->i_pino, TRANS_DIR_INO))
 		cp_reason = CP_RECOVER_DIR;
 
@@ -479,6 +480,9 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
 
 	if (err)
 		return err;
+
+	filp->f_mode |= FMODE_NOWAIT;
+
 	return dquot_file_open(inode, filp);
 }
 
@@ -569,7 +573,6 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
 int truncate_blocks(struct inode *inode, u64 from, bool lock)
 {
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-	unsigned int blocksize = inode->i_sb->s_blocksize;
 	struct dnode_of_data dn;
 	pgoff_t free_from;
 	int count = 0, err = 0;
@@ -578,7 +581,7 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock)
 
 	trace_f2fs_truncate_blocks_enter(inode, from);
 
-	free_from = (pgoff_t)F2FS_BYTES_TO_BLK(from + blocksize - 1);
+	free_from = (pgoff_t)F2FS_BLK_ALIGN(from);
 
 	if (free_from >= sbi->max_file_blocks)
 		goto free_partial;
@@ -1348,8 +1351,12 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
 	}
 
 out:
-	if (!(mode & FALLOC_FL_KEEP_SIZE) && i_size_read(inode) < new_size)
-		f2fs_i_size_write(inode, new_size);
+	if (new_size > i_size_read(inode)) {
+		if (mode & FALLOC_FL_KEEP_SIZE)
+			file_set_keep_isize(inode);
+		else
+			f2fs_i_size_write(inode, new_size);
+	}
 out_sem:
 	up_write(&F2FS_I(inode)->i_mmap_sem);
 
@@ -1711,6 +1718,8 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
 
 	inode_lock(inode);
 
+	down_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
+
 	if (f2fs_is_volatile_file(inode))
 		goto err_out;
 
@@ -1729,6 +1738,7 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
 		ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false);
 	}
 err_out:
+	up_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
 	inode_unlock(inode);
 	mnt_drop_write_file(filp);
 	return ret;
@@ -1938,7 +1948,7 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
 {
 	struct inode *inode = file_inode(filp);
 
-	if (!f2fs_sb_has_crypto(inode->i_sb))
+	if (!f2fs_sb_has_encrypt(inode->i_sb))
 		return -EOPNOTSUPP;
 
 	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
@@ -1948,7 +1958,7 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
 
 static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg)
 {
-	if (!f2fs_sb_has_crypto(file_inode(filp)->i_sb))
+	if (!f2fs_sb_has_encrypt(file_inode(filp)->i_sb))
 		return -EOPNOTSUPP;
 	return fscrypt_ioctl_get_policy(filp, (void __user *)arg);
 }
@@ -1959,16 +1969,18 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg)
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	int err;
 
-	if (!f2fs_sb_has_crypto(inode->i_sb))
+	if (!f2fs_sb_has_encrypt(inode->i_sb))
 		return -EOPNOTSUPP;
 
-	if (uuid_is_nonzero(sbi->raw_super->encrypt_pw_salt))
-		goto got_it;
-
 	err = mnt_want_write_file(filp);
 	if (err)
 		return err;
 
+	down_write(&sbi->sb_lock);
+
+	if (uuid_is_nonzero(sbi->raw_super->encrypt_pw_salt))
+		goto got_it;
+
 	/* update superblock with uuid */
 	generate_random_uuid(sbi->raw_super->encrypt_pw_salt);
 
@@ -1976,15 +1988,16 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg)
 	if (err) {
 		/* undo new data */
 		memset(sbi->raw_super->encrypt_pw_salt, 0, 16);
-		mnt_drop_write_file(filp);
-		return err;
+		goto out_err;
 	}
-	mnt_drop_write_file(filp);
 got_it:
 	if (copy_to_user((__u8 __user *)arg, sbi->raw_super->encrypt_pw_salt,
 									16))
-		return -EFAULT;
-	return 0;
+		err = -EFAULT;
+out_err:
+	up_write(&sbi->sb_lock);
+	mnt_drop_write_file(filp);
+	return err;
 }
 
 static int f2fs_ioc_gc(struct file *filp, unsigned long arg)
@@ -2045,8 +2058,10 @@ static int f2fs_ioc_gc_range(struct file *filp, unsigned long arg)
 		return ret;
 
 	end = range.start + range.len;
-	if (range.start < MAIN_BLKADDR(sbi) || end >= MAX_BLKADDR(sbi))
-		return -EINVAL;
+	if (range.start < MAIN_BLKADDR(sbi) || end >= MAX_BLKADDR(sbi)) {
+		ret = -EINVAL;
+		goto out;
+	}
 do_more:
 	if (!range.sync) {
 		if (!mutex_trylock(&sbi->gc_mutex)) {
@@ -2885,25 +2900,54 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
 		return -EIO;
 
-	inode_lock(inode);
+	if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT))
+		return -EINVAL;
+
+	if (!inode_trylock(inode)) {
+		if (iocb->ki_flags & IOCB_NOWAIT)
+			return -EAGAIN;
+		inode_lock(inode);
+	}
+
 	ret = generic_write_checks(iocb, from);
 	if (ret > 0) {
+		bool preallocated = false;
+		size_t target_size = 0;
 		int err;
 
 		if (iov_iter_fault_in_readable(from, iov_iter_count(from)))
 			set_inode_flag(inode, FI_NO_PREALLOC);
 
-		err = f2fs_preallocate_blocks(iocb, from);
-		if (err) {
-			clear_inode_flag(inode, FI_NO_PREALLOC);
-			inode_unlock(inode);
-			return err;
+		if ((iocb->ki_flags & IOCB_NOWAIT) &&
+			(iocb->ki_flags & IOCB_DIRECT)) {
+				if (!f2fs_overwrite_io(inode, iocb->ki_pos,
+						iov_iter_count(from)) ||
+					f2fs_has_inline_data(inode) ||
+					f2fs_force_buffered_io(inode, WRITE)) {
+						inode_unlock(inode);
+						return -EAGAIN;
+				}
+
+		} else {
+			preallocated = true;
+			target_size = iocb->ki_pos + iov_iter_count(from);
+
+			err = f2fs_preallocate_blocks(iocb, from);
+			if (err) {
+				clear_inode_flag(inode, FI_NO_PREALLOC);
+				inode_unlock(inode);
+				return err;
+			}
 		}
 		blk_start_plug(&plug);
 		ret = __generic_file_write_iter(iocb, from);
 		blk_finish_plug(&plug);
 		clear_inode_flag(inode, FI_NO_PREALLOC);
 
+		/* if we couldn't write data, we should deallocate blocks. */
+		if (preallocated && i_size_read(inode) < target_size)
+			f2fs_truncate(inode);
+
 		if (ret > 0)
 			f2fs_update_iostat(F2FS_I_SB(inode), APP_WRITE_IO, ret);
 	}
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index aa720cc..bfb7a4a 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -76,14 +76,15 @@ static int gc_thread_func(void *data)
 		 * invalidated soon after by user update or deletion.
 		 * So, I'd like to wait some time to collect dirty segments.
 		 */
-		if (!mutex_trylock(&sbi->gc_mutex))
-			goto next;
-
 		if (gc_th->gc_urgent) {
 			wait_ms = gc_th->urgent_sleep_time;
+			mutex_lock(&sbi->gc_mutex);
 			goto do_gc;
 		}
 
+		if (!mutex_trylock(&sbi->gc_mutex))
+			goto next;
+
 		if (!is_idle(sbi)) {
 			increase_sleep_time(gc_th, &wait_ms);
 			mutex_unlock(&sbi->gc_mutex);
@@ -161,12 +162,17 @@ static int select_gc_type(struct f2fs_gc_kthread *gc_th, int gc_type)
 {
 	int gc_mode = (gc_type == BG_GC) ? GC_CB : GC_GREEDY;
 
-	if (gc_th && gc_th->gc_idle) {
+	if (!gc_th)
+		return gc_mode;
+
+	if (gc_th->gc_idle) {
 		if (gc_th->gc_idle == 1)
 			gc_mode = GC_CB;
 		else if (gc_th->gc_idle == 2)
 			gc_mode = GC_GREEDY;
 	}
+	if (gc_th->gc_urgent)
+		gc_mode = GC_GREEDY;
 	return gc_mode;
 }
 
@@ -188,11 +194,14 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
 	}
 
 	/* we need to check every dirty segments in the FG_GC case */
-	if (gc_type != FG_GC && p->max_search > sbi->max_victim_search)
+	if (gc_type != FG_GC &&
+			(sbi->gc_thread && !sbi->gc_thread->gc_urgent) &&
+			p->max_search > sbi->max_victim_search)
 		p->max_search = sbi->max_victim_search;
 
-	/* let's select beginning hot/small space first */
-	if (type == CURSEG_HOT_DATA || IS_NODESEG(type))
+	/* let's select beginning hot/small space first in no_heap mode*/
+	if (test_opt(sbi, NOHEAP) &&
+		(type == CURSEG_HOT_DATA || IS_NODESEG(type)))
 		p->offset = 0;
 	else
 		p->offset = SIT_I(sbi)->last_victim[p->gc_mode];
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 90e38d8..3b77d64 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -369,7 +369,7 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
 	f2fs_wait_on_page_writeback(page, DATA, true);
 	zero_user_segment(page, MAX_INLINE_DATA(dir), PAGE_SIZE);
 
-	dentry_blk = kmap_atomic(page);
+	dentry_blk = page_address(page);
 
 	make_dentry_ptr_inline(dir, &src, inline_dentry);
 	make_dentry_ptr_block(dir, &dst, dentry_blk);
@@ -386,7 +386,6 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
 	memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max);
 	memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN);
 
-	kunmap_atomic(dentry_blk);
 	if (!PageUptodate(page))
 		SetPageUptodate(page);
 	set_page_dirty(page);
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 205add3..e0d9e8f 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -284,6 +284,10 @@ static int do_read_inode(struct inode *inode)
 		fi->i_crtime.tv_nsec = le32_to_cpu(ri->i_crtime_nsec);
 	}
 
+	F2FS_I(inode)->i_disk_time[0] = inode->i_atime;
+	F2FS_I(inode)->i_disk_time[1] = inode->i_ctime;
+	F2FS_I(inode)->i_disk_time[2] = inode->i_mtime;
+	F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime;
 	f2fs_put_page(node_page, 1);
 
 	stat_inc_inline_xattr(inode);
@@ -328,7 +332,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
 		inode->i_op = &f2fs_dir_inode_operations;
 		inode->i_fop = &f2fs_dir_operations;
 		inode->i_mapping->a_ops = &f2fs_dblock_aops;
-		mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO);
+		inode_nohighmem(inode);
 	} else if (S_ISLNK(inode->i_mode)) {
 		if (f2fs_encrypted_inode(inode))
 			inode->i_op = &f2fs_encrypted_symlink_inode_operations;
@@ -439,12 +443,15 @@ void update_inode(struct inode *inode, struct page *node_page)
 	}
 
 	__set_inode_rdev(inode, ri);
-	set_cold_node(inode, node_page);
 
 	/* deleted inode */
 	if (inode->i_nlink == 0)
 		clear_inline_node(node_page);
 
+	F2FS_I(inode)->i_disk_time[0] = inode->i_atime;
+	F2FS_I(inode)->i_disk_time[1] = inode->i_ctime;
+	F2FS_I(inode)->i_disk_time[2] = inode->i_mtime;
+	F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime;
 }
 
 void update_inode_page(struct inode *inode)
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index b68e7b0..d5098ef 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -78,7 +78,8 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
 	set_inode_flag(inode, FI_NEW_INODE);
 
 	/* If the directory encrypted, then we should encrypt the inode. */
-	if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode))
+	if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
+				f2fs_may_encrypt(inode))
 		f2fs_set_encrypted_inode(inode);
 
 	if (f2fs_sb_has_extra_attr(sbi->sb)) {
@@ -97,7 +98,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
 	if (f2fs_sb_has_flexible_inline_xattr(sbi->sb)) {
 		f2fs_bug_on(sbi, !f2fs_has_extra_attr(inode));
 		if (f2fs_has_inline_xattr(inode))
-			xattr_size = sbi->inline_xattr_size;
+			xattr_size = F2FS_OPTION(sbi).inline_xattr_size;
 		/* Otherwise, will be 0 */
 	} else if (f2fs_has_inline_xattr(inode) ||
 				f2fs_has_inline_dentry(inode)) {
@@ -142,7 +143,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
 	return ERR_PTR(err);
 }
 
-static int is_multimedia_file(const unsigned char *s, const char *sub)
+static int is_extension_exist(const unsigned char *s, const char *sub)
 {
 	size_t slen = strlen(s);
 	size_t sublen = strlen(sub);
@@ -168,19 +169,94 @@ static int is_multimedia_file(const unsigned char *s, const char *sub)
 /*
  * Set multimedia files as cold files for hot/cold data separation
  */
-static inline void set_cold_files(struct f2fs_sb_info *sbi, struct inode *inode,
+static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode *inode,
 		const unsigned char *name)
 {
-	int i;
-	__u8 (*extlist)[8] = sbi->raw_super->extension_list;
+	__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
+	int i, cold_count, hot_count;
 
-	int count = le32_to_cpu(sbi->raw_super->extension_count);
-	for (i = 0; i < count; i++) {
-		if (is_multimedia_file(name, extlist[i])) {
+	down_read(&sbi->sb_lock);
+
+	cold_count = le32_to_cpu(sbi->raw_super->extension_count);
+	hot_count = sbi->raw_super->hot_ext_count;
+
+	for (i = 0; i < cold_count + hot_count; i++) {
+		if (!is_extension_exist(name, extlist[i]))
+			continue;
+		if (i < cold_count)
 			file_set_cold(inode);
-			break;
-		}
+		else
+			file_set_hot(inode);
+		break;
 	}
+
+	up_read(&sbi->sb_lock);
+}
+
+int update_extension_list(struct f2fs_sb_info *sbi, const char *name,
+							bool hot, bool set)
+{
+	__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
+	int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
+	int hot_count = sbi->raw_super->hot_ext_count;
+	int total_count = cold_count + hot_count;
+	int start, count;
+	int i;
+
+	if (set) {
+		if (total_count == F2FS_MAX_EXTENSION)
+			return -EINVAL;
+	} else {
+		if (!hot && !cold_count)
+			return -EINVAL;
+		if (hot && !hot_count)
+			return -EINVAL;
+	}
+
+	if (hot) {
+		start = cold_count;
+		count = total_count;
+	} else {
+		start = 0;
+		count = cold_count;
+	}
+
+	for (i = start; i < count; i++) {
+		if (strcmp(name, extlist[i]))
+			continue;
+
+		if (set)
+			return -EINVAL;
+
+		memcpy(extlist[i], extlist[i + 1],
+				F2FS_EXTENSION_LEN * (total_count - i - 1));
+		memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN);
+		if (hot)
+			sbi->raw_super->hot_ext_count = hot_count - 1;
+		else
+			sbi->raw_super->extension_count =
+						cpu_to_le32(cold_count - 1);
+		return 0;
+	}
+
+	if (!set)
+		return -EINVAL;
+
+	if (hot) {
+		strncpy(extlist[count], name, strlen(name));
+		sbi->raw_super->hot_ext_count = hot_count + 1;
+	} else {
+		char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];
+
+		memcpy(buf, &extlist[cold_count],
+				F2FS_EXTENSION_LEN * hot_count);
+		memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN);
+		strncpy(extlist[cold_count], name, strlen(name));
+		memcpy(&extlist[cold_count + 1], buf,
+				F2FS_EXTENSION_LEN * hot_count);
+		sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1);
+	}
+	return 0;
 }
 
 static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
@@ -203,7 +279,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 		return PTR_ERR(inode);
 
 	if (!test_opt(sbi, DISABLE_EXT_IDENTIFY))
-		set_cold_files(sbi, inode, dentry->d_name.name);
+		set_file_temperature(sbi, inode, dentry->d_name.name);
 
 	inode->i_op = &f2fs_file_inode_operations;
 	inode->i_fop = &f2fs_file_operations;
@@ -317,7 +393,6 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino)
 
 	de = f2fs_find_entry(dir, &dot, &page);
 	if (de) {
-		f2fs_dentry_kunmap(dir, page);
 		f2fs_put_page(page, 0);
 	} else if (IS_ERR(page)) {
 		err = PTR_ERR(page);
@@ -329,14 +404,12 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino)
 	}
 
 	de = f2fs_find_entry(dir, &dotdot, &page);
-	if (de) {
-		f2fs_dentry_kunmap(dir, page);
+	if (de)
 		f2fs_put_page(page, 0);
-	} else if (IS_ERR(page)) {
+	else if (IS_ERR(page))
 		err = PTR_ERR(page);
-	} else {
+	else
 		err = __f2fs_add_link(dir, &dotdot, NULL, pino, S_IFDIR);
-	}
 out:
 	if (!err)
 		clear_inode_flag(dir, FI_INLINE_DOTS);
@@ -377,7 +450,6 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
 	}
 
 	ino = le32_to_cpu(de->ino);
-	f2fs_dentry_kunmap(dir, page);
 	f2fs_put_page(page, 0);
 
 	inode = f2fs_iget(dir->i_sb, ino);
@@ -452,7 +524,6 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
 	err = acquire_orphan_inode(sbi);
 	if (err) {
 		f2fs_unlock_op(sbi);
-		f2fs_dentry_kunmap(dir, page);
 		f2fs_put_page(page, 0);
 		goto fail;
 	}
@@ -579,7 +650,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	inode->i_op = &f2fs_dir_inode_operations;
 	inode->i_fop = &f2fs_dir_operations;
 	inode->i_mapping->a_ops = &f2fs_dblock_aops;
-	mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO);
+	inode_nohighmem(inode);
 
 	set_inode_flag(inode, FI_INC_LINK);
 	f2fs_lock_op(sbi);
@@ -717,10 +788,12 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
 
 static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
-	if (unlikely(f2fs_cp_error(F2FS_I_SB(dir))))
+	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+
+	if (unlikely(f2fs_cp_error(sbi)))
 		return -EIO;
 
-	if (f2fs_encrypted_inode(dir)) {
+	if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
 		int err = fscrypt_get_encryption_info(dir);
 		if (err)
 			return err;
@@ -893,16 +966,15 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	}
 
 	if (old_dir_entry) {
-		if (old_dir != new_dir && !whiteout) {
+		if (old_dir != new_dir && !whiteout)
 			f2fs_set_link(old_inode, old_dir_entry,
 						old_dir_page, new_dir);
-		} else {
-			f2fs_dentry_kunmap(old_inode, old_dir_page);
+		else
 			f2fs_put_page(old_dir_page, 0);
-		}
 		f2fs_i_links_write(old_dir, false);
 	}
-	add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
+	if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT)
+		add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
 
 	f2fs_unlock_op(sbi);
 
@@ -912,20 +984,15 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
 put_out_dir:
 	f2fs_unlock_op(sbi);
-	if (new_page) {
-		f2fs_dentry_kunmap(new_dir, new_page);
+	if (new_page)
 		f2fs_put_page(new_page, 0);
-	}
 out_whiteout:
 	if (whiteout)
 		iput(whiteout);
 out_dir:
-	if (old_dir_entry) {
-		f2fs_dentry_kunmap(old_inode, old_dir_page);
+	if (old_dir_entry)
 		f2fs_put_page(old_dir_page, 0);
-	}
 out_old:
-	f2fs_dentry_kunmap(old_dir, old_page);
 	f2fs_put_page(old_page, 0);
 out:
 	return err;
@@ -1057,8 +1124,10 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
 	}
 	f2fs_mark_inode_dirty_sync(new_dir, false);
 
-	add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);
-	add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
+	if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
+		add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);
+		add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
+	}
 
 	f2fs_unlock_op(sbi);
 
@@ -1067,19 +1136,15 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
 	return 0;
 out_new_dir:
 	if (new_dir_entry) {
-		f2fs_dentry_kunmap(new_inode, new_dir_page);
 		f2fs_put_page(new_dir_page, 0);
 	}
 out_old_dir:
 	if (old_dir_entry) {
-		f2fs_dentry_kunmap(old_inode, old_dir_page);
 		f2fs_put_page(old_dir_page, 0);
 	}
 out_new:
-	f2fs_dentry_kunmap(new_dir, new_page);
 	f2fs_put_page(new_page, 0);
 out_old:
-	f2fs_dentry_kunmap(old_dir, old_page);
 	f2fs_put_page(old_page, 0);
 out:
 	return err;
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 177c438..9a99243 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -193,8 +193,8 @@ static void __del_from_nat_cache(struct f2fs_nm_info *nm_i, struct nat_entry *e)
 	__free_nat_entry(e);
 }
 
-static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i,
-						struct nat_entry *ne)
+static struct nat_entry_set *__grab_nat_entry_set(struct f2fs_nm_info *nm_i,
+							struct nat_entry *ne)
 {
 	nid_t set = NAT_BLOCK_OFFSET(ne->ni.nid);
 	struct nat_entry_set *head;
@@ -209,15 +209,36 @@ static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i,
 		head->entry_cnt = 0;
 		f2fs_radix_tree_insert(&nm_i->nat_set_root, set, head);
 	}
+	return head;
+}
+
+static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i,
+						struct nat_entry *ne)
+{
+	struct nat_entry_set *head;
+	bool new_ne = nat_get_blkaddr(ne) == NEW_ADDR;
+
+	if (!new_ne)
+		head = __grab_nat_entry_set(nm_i, ne);
+
+	/*
+	 * update entry_cnt in below condition:
+	 * 1. update NEW_ADDR to valid block address;
+	 * 2. update old block address to new one;
+	 */
+	if (!new_ne && (get_nat_flag(ne, IS_PREALLOC) ||
+				!get_nat_flag(ne, IS_DIRTY)))
+		head->entry_cnt++;
+
+	set_nat_flag(ne, IS_PREALLOC, new_ne);
 
 	if (get_nat_flag(ne, IS_DIRTY))
 		goto refresh_list;
 
 	nm_i->dirty_nat_cnt++;
-	head->entry_cnt++;
 	set_nat_flag(ne, IS_DIRTY, true);
 refresh_list:
-	if (nat_get_blkaddr(ne) == NEW_ADDR)
+	if (new_ne)
 		list_del_init(&ne->list);
 	else
 		list_move_tail(&ne->list, &head->entry_list);
@@ -1076,7 +1097,7 @@ struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs)
 
 	f2fs_wait_on_page_writeback(page, NODE, true);
 	fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true);
-	set_cold_node(dn->inode, page);
+	set_cold_node(page, S_ISDIR(dn->inode->i_mode));
 	if (!PageUptodate(page))
 		SetPageUptodate(page);
 	if (set_page_dirty(page))
@@ -2291,6 +2312,7 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
 	if (!PageUptodate(ipage))
 		SetPageUptodate(ipage);
 	fill_node_footer(ipage, ino, ino, 0, true);
+	set_cold_node(page, false);
 
 	src = F2FS_INODE(page);
 	dst = F2FS_INODE(ipage);
@@ -2580,8 +2602,7 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi)
 	if (!enabled_nat_bits(sbi, NULL))
 		return 0;
 
-	nm_i->nat_bits_blocks = F2FS_BYTES_TO_BLK((nat_bits_bytes << 1) + 8 +
-						F2FS_BLKSIZE - 1);
+	nm_i->nat_bits_blocks = F2FS_BLK_ALIGN((nat_bits_bytes << 1) + 8);
 	nm_i->nat_bits = f2fs_kzalloc(sbi,
 			nm_i->nat_bits_blocks << F2FS_BLKSIZE_BITS, GFP_KERNEL);
 	if (!nm_i->nat_bits)
@@ -2707,12 +2728,20 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
 static int init_free_nid_cache(struct f2fs_sb_info *sbi)
 {
 	struct f2fs_nm_info *nm_i = NM_I(sbi);
+	int i;
 
-	nm_i->free_nid_bitmap = f2fs_kvzalloc(sbi, nm_i->nat_blocks *
-					NAT_ENTRY_BITMAP_SIZE, GFP_KERNEL);
+	nm_i->free_nid_bitmap = f2fs_kzalloc(sbi, nm_i->nat_blocks *
+				sizeof(unsigned char *), GFP_KERNEL);
 	if (!nm_i->free_nid_bitmap)
 		return -ENOMEM;
 
+	for (i = 0; i < nm_i->nat_blocks; i++) {
+		nm_i->free_nid_bitmap[i] = f2fs_kvzalloc(sbi,
+				NAT_ENTRY_BITMAP_SIZE_ALIGNED, GFP_KERNEL);
+		if (!nm_i->free_nid_bitmap)
+			return -ENOMEM;
+	}
+
 	nm_i->nat_block_bitmap = f2fs_kvzalloc(sbi, nm_i->nat_blocks / 8,
 								GFP_KERNEL);
 	if (!nm_i->nat_block_bitmap)
@@ -2803,7 +2832,13 @@ void destroy_node_manager(struct f2fs_sb_info *sbi)
 	up_write(&nm_i->nat_tree_lock);
 
 	kvfree(nm_i->nat_block_bitmap);
-	kvfree(nm_i->free_nid_bitmap);
+	if (nm_i->free_nid_bitmap) {
+		int i;
+
+		for (i = 0; i < nm_i->nat_blocks; i++)
+			kvfree(nm_i->free_nid_bitmap[i]);
+		kfree(nm_i->free_nid_bitmap);
+	}
 	kvfree(nm_i->free_nid_count);
 
 	kfree(nm_i->nat_bitmap);
diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
index 081ef0d..b95e49e 100644
--- a/fs/f2fs/node.h
+++ b/fs/f2fs/node.h
@@ -44,6 +44,7 @@ enum {
 	HAS_FSYNCED_INODE,	/* is the inode fsynced before? */
 	HAS_LAST_FSYNC,		/* has the latest node fsync mark? */
 	IS_DIRTY,		/* this nat entry is dirty? */
+	IS_PREALLOC,		/* nat entry is preallocated */
 };
 
 /*
@@ -422,12 +423,12 @@ static inline void clear_inline_node(struct page *page)
 	ClearPageChecked(page);
 }
 
-static inline void set_cold_node(struct inode *inode, struct page *page)
+static inline void set_cold_node(struct page *page, bool is_dir)
 {
 	struct f2fs_node *rn = F2FS_NODE(page);
 	unsigned int flag = le32_to_cpu(rn->footer.flag);
 
-	if (S_ISDIR(inode->i_mode))
+	if (is_dir)
 		flag &= ~(0x1 << COLD_BIT_SHIFT);
 	else
 		flag |= (0x1 << COLD_BIT_SHIFT);
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 337f336..1b23d3f 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -144,7 +144,7 @@ static int recover_dentry(struct inode *inode, struct page *ipage,
 retry:
 	de = __f2fs_find_entry(dir, &fname, &page);
 	if (de && inode->i_ino == le32_to_cpu(de->ino))
-		goto out_unmap_put;
+		goto out_put;
 
 	if (de) {
 		einode = f2fs_iget_retry(inode->i_sb, le32_to_cpu(de->ino));
@@ -153,19 +153,19 @@ static int recover_dentry(struct inode *inode, struct page *ipage,
 			err = PTR_ERR(einode);
 			if (err == -ENOENT)
 				err = -EEXIST;
-			goto out_unmap_put;
+			goto out_put;
 		}
 
 		err = dquot_initialize(einode);
 		if (err) {
 			iput(einode);
-			goto out_unmap_put;
+			goto out_put;
 		}
 
 		err = acquire_orphan_inode(F2FS_I_SB(inode));
 		if (err) {
 			iput(einode);
-			goto out_unmap_put;
+			goto out_put;
 		}
 		f2fs_delete_entry(de, page, dir, einode);
 		iput(einode);
@@ -180,8 +180,7 @@ static int recover_dentry(struct inode *inode, struct page *ipage,
 		goto retry;
 	goto out;
 
-out_unmap_put:
-	f2fs_dentry_kunmap(dir, page);
+out_put:
 	f2fs_put_page(page, 0);
 out:
 	if (file_enc_name(inode))
@@ -243,6 +242,9 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
 	struct curseg_info *curseg;
 	struct page *page = NULL;
 	block_t blkaddr;
+	unsigned int loop_cnt = 0;
+	unsigned int free_blocks = sbi->user_block_count -
+					valid_user_blocks(sbi);
 	int err = 0;
 
 	/* get node pages in the current segment */
@@ -295,6 +297,17 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
 		if (IS_INODE(page) && is_dent_dnode(page))
 			entry->last_dentry = blkaddr;
 next:
+		/* sanity check in order to detect looped node chain */
+		if (++loop_cnt >= free_blocks ||
+			blkaddr == next_blkaddr_of_node(page)) {
+			f2fs_msg(sbi->sb, KERN_NOTICE,
+				"%s: detect looped node chain, "
+				"blkaddr:%u, next:%u",
+				__func__, blkaddr, next_blkaddr_of_node(page));
+			err = -EINVAL;
+			break;
+		}
+
 		/* check next segment */
 		blkaddr = next_blkaddr_of_node(page);
 		f2fs_put_page(page, 1);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index b16a8e6..5854cc4 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1411,12 +1411,11 @@ static int issue_discard_thread(void *data)
 		if (kthread_should_stop())
 			return 0;
 
-		if (dcc->discard_wake) {
+		if (dcc->discard_wake)
 			dcc->discard_wake = 0;
-			if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
-				init_discard_policy(&dpolicy,
-							DPOLICY_FORCE, 1);
-		}
+
+		if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
+			init_discard_policy(&dpolicy, DPOLICY_FORCE, 1);
 
 		sb_start_intwrite(sbi->sb);
 
@@ -1485,7 +1484,7 @@ static int __issue_discard_async(struct f2fs_sb_info *sbi,
 		struct block_device *bdev, block_t blkstart, block_t blklen)
 {
 #ifdef CONFIG_BLK_DEV_ZONED
-	if (f2fs_sb_mounted_blkzoned(sbi->sb) &&
+	if (f2fs_sb_has_blkzoned(sbi->sb) &&
 				bdev_zoned_model(bdev) != BLK_ZONED_NONE)
 		return __f2fs_issue_discard_zone(sbi, bdev, blkstart, blklen);
 #endif
@@ -1683,7 +1682,7 @@ void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 					sbi->blocks_per_seg, cur_pos);
 			len = next_pos - cur_pos;
 
-			if (f2fs_sb_mounted_blkzoned(sbi->sb) ||
+			if (f2fs_sb_has_blkzoned(sbi->sb) ||
 			    (force && len < cpc->trim_minlen))
 				goto skip;
 
@@ -1727,7 +1726,7 @@ void init_discard_policy(struct discard_policy *dpolicy,
 	} else if (discard_type == DPOLICY_FORCE) {
 		dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
 		dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
-		dpolicy->io_aware = true;
+		dpolicy->io_aware = false;
 	} else if (discard_type == DPOLICY_FSTRIM) {
 		dpolicy->io_aware = false;
 	} else if (discard_type == DPOLICY_UMOUNT) {
@@ -1863,7 +1862,7 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
 			sbi->discard_blks--;
 
 		/* don't overwrite by SSR to keep node chain */
-		if (se->type == CURSEG_WARM_NODE) {
+		if (IS_NODESEG(se->type)) {
 			if (!f2fs_test_and_set_bit(offset, se->ckpt_valid_map))
 				se->ckpt_valid_blocks++;
 		}
@@ -2164,11 +2163,17 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
 	if (sbi->segs_per_sec != 1)
 		return CURSEG_I(sbi, type)->segno;
 
-	if (type == CURSEG_HOT_DATA || IS_NODESEG(type))
+	if (test_opt(sbi, NOHEAP) &&
+		(type == CURSEG_HOT_DATA || IS_NODESEG(type)))
 		return 0;
 
 	if (SIT_I(sbi)->last_victim[ALLOC_NEXT])
 		return SIT_I(sbi)->last_victim[ALLOC_NEXT];
+
+	/* find segments from 0 to reuse freed segments */
+	if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_REUSE)
+		return 0;
+
 	return CURSEG_I(sbi, type)->segno;
 }
 
@@ -2455,6 +2460,101 @@ int rw_hint_to_seg_type(enum rw_hint hint)
 	}
 }
 
+/* This returns write hints for each segment type. This hints will be
+ * passed down to block layer. There are mapping tables which depend on
+ * the mount option 'whint_mode'.
+ *
+ * 1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET.
+ *
+ * 2) whint_mode=user-based. F2FS tries to pass down hints given by users.
+ *
+ * User                  F2FS                     Block
+ * ----                  ----                     -----
+ *                       META                     WRITE_LIFE_NOT_SET
+ *                       HOT_NODE                 "
+ *                       WARM_NODE                "
+ *                       COLD_NODE                "
+ * ioctl(COLD)           COLD_DATA                WRITE_LIFE_EXTREME
+ * extension list        "                        "
+ *
+ * -- buffered io
+ * WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
+ * WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
+ * WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
+ * WRITE_LIFE_NONE       "                        "
+ * WRITE_LIFE_MEDIUM     "                        "
+ * WRITE_LIFE_LONG       "                        "
+ *
+ * -- direct io
+ * WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
+ * WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
+ * WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
+ * WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
+ * WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
+ * WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
+ *
+ * 3) whint_mode=fs-based. F2FS passes down hints with its policy.
+ *
+ * User                  F2FS                     Block
+ * ----                  ----                     -----
+ *                       META                     WRITE_LIFE_MEDIUM;
+ *                       HOT_NODE                 WRITE_LIFE_NOT_SET
+ *                       WARM_NODE                "
+ *                       COLD_NODE                WRITE_LIFE_NONE
+ * ioctl(COLD)           COLD_DATA                WRITE_LIFE_EXTREME
+ * extension list        "                        "
+ *
+ * -- buffered io
+ * WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
+ * WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
+ * WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_LONG
+ * WRITE_LIFE_NONE       "                        "
+ * WRITE_LIFE_MEDIUM     "                        "
+ * WRITE_LIFE_LONG       "                        "
+ *
+ * -- direct io
+ * WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
+ * WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
+ * WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
+ * WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
+ * WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
+ * WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
+ */
+
+enum rw_hint io_type_to_rw_hint(struct f2fs_sb_info *sbi,
+				enum page_type type, enum temp_type temp)
+{
+	if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_USER) {
+		if (type == DATA) {
+			if (temp == WARM)
+				return WRITE_LIFE_NOT_SET;
+			else if (temp == HOT)
+				return WRITE_LIFE_SHORT;
+			else if (temp == COLD)
+				return WRITE_LIFE_EXTREME;
+		} else {
+			return WRITE_LIFE_NOT_SET;
+		}
+	} else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS) {
+		if (type == DATA) {
+			if (temp == WARM)
+				return WRITE_LIFE_LONG;
+			else if (temp == HOT)
+				return WRITE_LIFE_SHORT;
+			else if (temp == COLD)
+				return WRITE_LIFE_EXTREME;
+		} else if (type == NODE) {
+			if (temp == WARM || temp == HOT)
+				return WRITE_LIFE_NOT_SET;
+			else if (temp == COLD)
+				return WRITE_LIFE_NONE;
+		} else if (type == META) {
+			return WRITE_LIFE_MEDIUM;
+		}
+	}
+	return WRITE_LIFE_NOT_SET;
+}
+
 static int __get_segment_type_2(struct f2fs_io_info *fio)
 {
 	if (fio->type == DATA)
@@ -2487,7 +2587,8 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
 
 		if (is_cold_data(fio->page) || file_is_cold(inode))
 			return CURSEG_COLD_DATA;
-		if (is_inode_flag_set(inode, FI_HOT_DATA))
+		if (file_is_hot(inode) ||
+				is_inode_flag_set(inode, FI_HOT_DATA))
 			return CURSEG_HOT_DATA;
 		return rw_hint_to_seg_type(inode->i_write_hint);
 	} else {
@@ -2502,7 +2603,7 @@ static int __get_segment_type(struct f2fs_io_info *fio)
 {
 	int type = 0;
 
-	switch (fio->sbi->active_logs) {
+	switch (F2FS_OPTION(fio->sbi).active_logs) {
 	case 2:
 		type = __get_segment_type_2(fio);
 		break;
@@ -2642,6 +2743,7 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
 	struct f2fs_io_info fio = {
 		.sbi = sbi,
 		.type = META,
+		.temp = HOT,
 		.op = REQ_OP_WRITE,
 		.op_flags = REQ_SYNC | REQ_META | REQ_PRIO,
 		.old_blkaddr = page->index,
@@ -2688,8 +2790,15 @@ void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio)
 int rewrite_data_page(struct f2fs_io_info *fio)
 {
 	int err;
+	struct f2fs_sb_info *sbi = fio->sbi;
 
 	fio->new_blkaddr = fio->old_blkaddr;
+	/* i/o temperature is needed for passing down write hints */
+	__get_segment_type(fio);
+
+	f2fs_bug_on(sbi, !IS_DATASEG(get_seg_entry(sbi,
+			GET_SEGNO(sbi, fio->new_blkaddr))->type));
+
 	stat_inc_inplace_blocks(fio->sbi);
 
 	err = f2fs_submit_page_bio(fio);
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index f11c4bc..3325d07 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -53,13 +53,19 @@
 	 ((secno) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno /		\
 	  (sbi)->segs_per_sec))	\
 
-#define MAIN_BLKADDR(sbi)	(SM_I(sbi)->main_blkaddr)
-#define SEG0_BLKADDR(sbi)	(SM_I(sbi)->seg0_blkaddr)
+#define MAIN_BLKADDR(sbi)						\
+	(SM_I(sbi) ? SM_I(sbi)->main_blkaddr : 				\
+		le32_to_cpu(F2FS_RAW_SUPER(sbi)->main_blkaddr))
+#define SEG0_BLKADDR(sbi)						\
+	(SM_I(sbi) ? SM_I(sbi)->seg0_blkaddr : 				\
+		le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment0_blkaddr))
 
 #define MAIN_SEGS(sbi)	(SM_I(sbi)->main_segments)
 #define MAIN_SECS(sbi)	((sbi)->total_sections)
 
-#define TOTAL_SEGS(sbi)	(SM_I(sbi)->segment_count)
+#define TOTAL_SEGS(sbi)							\
+	(SM_I(sbi) ? SM_I(sbi)->segment_count : 				\
+		le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count))
 #define TOTAL_BLKS(sbi)	(TOTAL_SEGS(sbi) << (sbi)->log_blocks_per_seg)
 
 #define MAX_BLKADDR(sbi)	(SEG0_BLKADDR(sbi) + TOTAL_BLKS(sbi))
@@ -596,6 +602,8 @@ static inline int utilization(struct f2fs_sb_info *sbi)
 #define DEF_MIN_FSYNC_BLOCKS	8
 #define DEF_MIN_HOT_BLOCKS	16
 
+#define SMALL_VOLUME_SEGMENTS	(16 * 512)	/* 16GB */
+
 enum {
 	F2FS_IPU_FORCE,
 	F2FS_IPU_SSR,
@@ -630,10 +638,17 @@ static inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
 	f2fs_bug_on(sbi, segno > TOTAL_SEGS(sbi) - 1);
 }
 
-static inline void verify_block_addr(struct f2fs_sb_info *sbi, block_t blk_addr)
+static inline void verify_block_addr(struct f2fs_io_info *fio, block_t blk_addr)
 {
-	BUG_ON(blk_addr < SEG0_BLKADDR(sbi)
-			|| blk_addr >= MAX_BLKADDR(sbi));
+	struct f2fs_sb_info *sbi = fio->sbi;
+
+	if (PAGE_TYPE_OF_BIO(fio->type) == META &&
+				(!is_read_io(fio->op) || fio->is_meta))
+		BUG_ON(blk_addr < SEG0_BLKADDR(sbi) ||
+				blk_addr >= MAIN_BLKADDR(sbi));
+	else
+		BUG_ON(blk_addr < MAIN_BLKADDR(sbi) ||
+				blk_addr >= MAX_BLKADDR(sbi));
 }
 
 /*
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8173ae6..42d564c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -60,7 +60,7 @@ char *fault_name[FAULT_MAX] = {
 static void f2fs_build_fault_attr(struct f2fs_sb_info *sbi,
 						unsigned int rate)
 {
-	struct f2fs_fault_info *ffi = &sbi->fault_info;
+	struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info;
 
 	if (rate) {
 		atomic_set(&ffi->inject_ops, 0);
@@ -129,6 +129,10 @@ enum {
 	Opt_jqfmt_vfsold,
 	Opt_jqfmt_vfsv0,
 	Opt_jqfmt_vfsv1,
+	Opt_whint,
+	Opt_alloc,
+	Opt_fsync,
+	Opt_test_dummy_encryption,
 	Opt_err,
 };
 
@@ -182,6 +186,10 @@ static match_table_t f2fs_tokens = {
 	{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
 	{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
 	{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
+	{Opt_whint, "whint_mode=%s"},
+	{Opt_alloc, "alloc_mode=%s"},
+	{Opt_fsync, "fsync_mode=%s"},
+	{Opt_test_dummy_encryption, "test_dummy_encryption"},
 	{Opt_err, NULL},
 };
 
@@ -202,21 +210,24 @@ static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
 	block_t limit = (sbi->user_block_count << 1) / 1000;
 
 	/* limit is 0.2% */
-	if (test_opt(sbi, RESERVE_ROOT) && sbi->root_reserved_blocks > limit) {
-		sbi->root_reserved_blocks = limit;
+	if (test_opt(sbi, RESERVE_ROOT) &&
+			F2FS_OPTION(sbi).root_reserved_blocks > limit) {
+		F2FS_OPTION(sbi).root_reserved_blocks = limit;
 		f2fs_msg(sbi->sb, KERN_INFO,
 			"Reduce reserved blocks for root = %u",
-				sbi->root_reserved_blocks);
+			F2FS_OPTION(sbi).root_reserved_blocks);
 	}
 	if (!test_opt(sbi, RESERVE_ROOT) &&
-		(!uid_eq(sbi->s_resuid,
+		(!uid_eq(F2FS_OPTION(sbi).s_resuid,
 				make_kuid(&init_user_ns, F2FS_DEF_RESUID)) ||
-		!gid_eq(sbi->s_resgid,
+		!gid_eq(F2FS_OPTION(sbi).s_resgid,
 				make_kgid(&init_user_ns, F2FS_DEF_RESGID))))
 		f2fs_msg(sbi->sb, KERN_INFO,
 			"Ignore s_resuid=%u, s_resgid=%u w/o reserve_root",
-				from_kuid_munged(&init_user_ns, sbi->s_resuid),
-				from_kgid_munged(&init_user_ns, sbi->s_resgid));
+				from_kuid_munged(&init_user_ns,
+					F2FS_OPTION(sbi).s_resuid),
+				from_kgid_munged(&init_user_ns,
+					F2FS_OPTION(sbi).s_resgid));
 }
 
 static void init_once(void *foo)
@@ -236,7 +247,7 @@ static int f2fs_set_qf_name(struct super_block *sb, int qtype,
 	char *qname;
 	int ret = -EINVAL;
 
-	if (sb_any_quota_loaded(sb) && !sbi->s_qf_names[qtype]) {
+	if (sb_any_quota_loaded(sb) && !F2FS_OPTION(sbi).s_qf_names[qtype]) {
 		f2fs_msg(sb, KERN_ERR,
 			"Cannot change journaled "
 			"quota options when quota turned on");
@@ -254,8 +265,8 @@ static int f2fs_set_qf_name(struct super_block *sb, int qtype,
 			"Not enough memory for storing quotafile name");
 		return -EINVAL;
 	}
-	if (sbi->s_qf_names[qtype]) {
-		if (strcmp(sbi->s_qf_names[qtype], qname) == 0)
+	if (F2FS_OPTION(sbi).s_qf_names[qtype]) {
+		if (strcmp(F2FS_OPTION(sbi).s_qf_names[qtype], qname) == 0)
 			ret = 0;
 		else
 			f2fs_msg(sb, KERN_ERR,
@@ -268,7 +279,7 @@ static int f2fs_set_qf_name(struct super_block *sb, int qtype,
 			"quotafile must be on filesystem root");
 		goto errout;
 	}
-	sbi->s_qf_names[qtype] = qname;
+	F2FS_OPTION(sbi).s_qf_names[qtype] = qname;
 	set_opt(sbi, QUOTA);
 	return 0;
 errout:
@@ -280,13 +291,13 @@ static int f2fs_clear_qf_name(struct super_block *sb, int qtype)
 {
 	struct f2fs_sb_info *sbi = F2FS_SB(sb);
 
-	if (sb_any_quota_loaded(sb) && sbi->s_qf_names[qtype]) {
+	if (sb_any_quota_loaded(sb) && F2FS_OPTION(sbi).s_qf_names[qtype]) {
 		f2fs_msg(sb, KERN_ERR, "Cannot change journaled quota options"
 			" when quota turned on");
 		return -EINVAL;
 	}
-	kfree(sbi->s_qf_names[qtype]);
-	sbi->s_qf_names[qtype] = NULL;
+	kfree(F2FS_OPTION(sbi).s_qf_names[qtype]);
+	F2FS_OPTION(sbi).s_qf_names[qtype] = NULL;
 	return 0;
 }
 
@@ -302,15 +313,19 @@ static int f2fs_check_quota_options(struct f2fs_sb_info *sbi)
 			 "Cannot enable project quota enforcement.");
 		return -1;
 	}
-	if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA] ||
-			sbi->s_qf_names[PRJQUOTA]) {
-		if (test_opt(sbi, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
+	if (F2FS_OPTION(sbi).s_qf_names[USRQUOTA] ||
+			F2FS_OPTION(sbi).s_qf_names[GRPQUOTA] ||
+			F2FS_OPTION(sbi).s_qf_names[PRJQUOTA]) {
+		if (test_opt(sbi, USRQUOTA) &&
+				F2FS_OPTION(sbi).s_qf_names[USRQUOTA])
 			clear_opt(sbi, USRQUOTA);
 
-		if (test_opt(sbi, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
+		if (test_opt(sbi, GRPQUOTA) &&
+				F2FS_OPTION(sbi).s_qf_names[GRPQUOTA])
 			clear_opt(sbi, GRPQUOTA);
 
-		if (test_opt(sbi, PRJQUOTA) && sbi->s_qf_names[PRJQUOTA])
+		if (test_opt(sbi, PRJQUOTA) &&
+				F2FS_OPTION(sbi).s_qf_names[PRJQUOTA])
 			clear_opt(sbi, PRJQUOTA);
 
 		if (test_opt(sbi, GRPQUOTA) || test_opt(sbi, USRQUOTA) ||
@@ -320,19 +335,19 @@ static int f2fs_check_quota_options(struct f2fs_sb_info *sbi)
 			return -1;
 		}
 
-		if (!sbi->s_jquota_fmt) {
+		if (!F2FS_OPTION(sbi).s_jquota_fmt) {
 			f2fs_msg(sbi->sb, KERN_ERR, "journaled quota format "
 					"not specified");
 			return -1;
 		}
 	}
 
-	if (f2fs_sb_has_quota_ino(sbi->sb) && sbi->s_jquota_fmt) {
+	if (f2fs_sb_has_quota_ino(sbi->sb) && F2FS_OPTION(sbi).s_jquota_fmt) {
 		f2fs_msg(sbi->sb, KERN_INFO,
 			"QUOTA feature is enabled, so ignore jquota_fmt");
-		sbi->s_jquota_fmt = 0;
+		F2FS_OPTION(sbi).s_jquota_fmt = 0;
 	}
-	if (f2fs_sb_has_quota_ino(sbi->sb) && sb_rdonly(sbi->sb)) {
+	if (f2fs_sb_has_quota_ino(sbi->sb) && f2fs_readonly(sbi->sb)) {
 		f2fs_msg(sbi->sb, KERN_INFO,
 			 "Filesystem with quota feature cannot be mounted RDWR "
 			 "without CONFIG_QUOTA");
@@ -403,14 +418,14 @@ static int parse_options(struct super_block *sb, char *options)
 			q = bdev_get_queue(sb->s_bdev);
 			if (blk_queue_discard(q)) {
 				set_opt(sbi, DISCARD);
-			} else if (!f2fs_sb_mounted_blkzoned(sb)) {
+			} else if (!f2fs_sb_has_blkzoned(sb)) {
 				f2fs_msg(sb, KERN_WARNING,
 					"mounting with \"discard\" option, but "
 					"the device does not support discard");
 			}
 			break;
 		case Opt_nodiscard:
-			if (f2fs_sb_mounted_blkzoned(sb)) {
+			if (f2fs_sb_has_blkzoned(sb)) {
 				f2fs_msg(sb, KERN_WARNING,
 					"discard is required for zoned block devices");
 				return -EINVAL;
@@ -440,7 +455,7 @@ static int parse_options(struct super_block *sb, char *options)
 			if (args->from && match_int(args, &arg))
 				return -EINVAL;
 			set_opt(sbi, INLINE_XATTR_SIZE);
-			sbi->inline_xattr_size = arg;
+			F2FS_OPTION(sbi).inline_xattr_size = arg;
 			break;
 #else
 		case Opt_user_xattr:
@@ -480,7 +495,7 @@ static int parse_options(struct super_block *sb, char *options)
 				return -EINVAL;
 			if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE)
 				return -EINVAL;
-			sbi->active_logs = arg;
+			F2FS_OPTION(sbi).active_logs = arg;
 			break;
 		case Opt_disable_ext_identify:
 			set_opt(sbi, DISABLE_EXT_IDENTIFY);
@@ -524,9 +539,9 @@ static int parse_options(struct super_block *sb, char *options)
 			if (test_opt(sbi, RESERVE_ROOT)) {
 				f2fs_msg(sb, KERN_INFO,
 					"Preserve previous reserve_root=%u",
-					sbi->root_reserved_blocks);
+					F2FS_OPTION(sbi).root_reserved_blocks);
 			} else {
-				sbi->root_reserved_blocks = arg;
+				F2FS_OPTION(sbi).root_reserved_blocks = arg;
 				set_opt(sbi, RESERVE_ROOT);
 			}
 			break;
@@ -539,7 +554,7 @@ static int parse_options(struct super_block *sb, char *options)
 					"Invalid uid value %d", arg);
 				return -EINVAL;
 			}
-			sbi->s_resuid = uid;
+			F2FS_OPTION(sbi).s_resuid = uid;
 			break;
 		case Opt_resgid:
 			if (args->from && match_int(args, &arg))
@@ -550,7 +565,7 @@ static int parse_options(struct super_block *sb, char *options)
 					"Invalid gid value %d", arg);
 				return -EINVAL;
 			}
-			sbi->s_resgid = gid;
+			F2FS_OPTION(sbi).s_resgid = gid;
 			break;
 		case Opt_mode:
 			name = match_strdup(&args[0]);
@@ -559,7 +574,7 @@ static int parse_options(struct super_block *sb, char *options)
 				return -ENOMEM;
 			if (strlen(name) == 8 &&
 					!strncmp(name, "adaptive", 8)) {
-				if (f2fs_sb_mounted_blkzoned(sb)) {
+				if (f2fs_sb_has_blkzoned(sb)) {
 					f2fs_msg(sb, KERN_WARNING,
 						 "adaptive mode is not allowed with "
 						 "zoned block device feature");
@@ -585,7 +600,7 @@ static int parse_options(struct super_block *sb, char *options)
 					1 << arg, BIO_MAX_PAGES);
 				return -EINVAL;
 			}
-			sbi->write_io_size_bits = arg;
+			F2FS_OPTION(sbi).write_io_size_bits = arg;
 			break;
 		case Opt_fault_injection:
 			if (args->from && match_int(args, &arg))
@@ -646,13 +661,13 @@ static int parse_options(struct super_block *sb, char *options)
 				return ret;
 			break;
 		case Opt_jqfmt_vfsold:
-			sbi->s_jquota_fmt = QFMT_VFS_OLD;
+			F2FS_OPTION(sbi).s_jquota_fmt = QFMT_VFS_OLD;
 			break;
 		case Opt_jqfmt_vfsv0:
-			sbi->s_jquota_fmt = QFMT_VFS_V0;
+			F2FS_OPTION(sbi).s_jquota_fmt = QFMT_VFS_V0;
 			break;
 		case Opt_jqfmt_vfsv1:
-			sbi->s_jquota_fmt = QFMT_VFS_V1;
+			F2FS_OPTION(sbi).s_jquota_fmt = QFMT_VFS_V1;
 			break;
 		case Opt_noquota:
 			clear_opt(sbi, QUOTA);
@@ -679,6 +694,73 @@ static int parse_options(struct super_block *sb, char *options)
 					"quota operations not supported");
 			break;
 #endif
+		case Opt_whint:
+			name = match_strdup(&args[0]);
+			if (!name)
+				return -ENOMEM;
+			if (strlen(name) == 10 &&
+					!strncmp(name, "user-based", 10)) {
+				F2FS_OPTION(sbi).whint_mode = WHINT_MODE_USER;
+			} else if (strlen(name) == 3 &&
+					!strncmp(name, "off", 3)) {
+				F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
+			} else if (strlen(name) == 8 &&
+					!strncmp(name, "fs-based", 8)) {
+				F2FS_OPTION(sbi).whint_mode = WHINT_MODE_FS;
+			} else {
+				kfree(name);
+				return -EINVAL;
+			}
+			kfree(name);
+			break;
+		case Opt_alloc:
+			name = match_strdup(&args[0]);
+			if (!name)
+				return -ENOMEM;
+
+			if (strlen(name) == 7 &&
+					!strncmp(name, "default", 7)) {
+				F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT;
+			} else if (strlen(name) == 5 &&
+					!strncmp(name, "reuse", 5)) {
+				F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_REUSE;
+			} else {
+				kfree(name);
+				return -EINVAL;
+			}
+			kfree(name);
+			break;
+		case Opt_fsync:
+			name = match_strdup(&args[0]);
+			if (!name)
+				return -ENOMEM;
+			if (strlen(name) == 5 &&
+					!strncmp(name, "posix", 5)) {
+				F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX;
+			} else if (strlen(name) == 6 &&
+					!strncmp(name, "strict", 6)) {
+				F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_STRICT;
+			} else {
+				kfree(name);
+				return -EINVAL;
+			}
+			kfree(name);
+			break;
+		case Opt_test_dummy_encryption:
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+			if (!f2fs_sb_has_encrypt(sb)) {
+				f2fs_msg(sb, KERN_ERR, "Encrypt feature is off");
+				return -EINVAL;
+			}
+
+			F2FS_OPTION(sbi).test_dummy_encryption = true;
+			f2fs_msg(sb, KERN_INFO,
+					"Test dummy encryption mode enabled");
+#else
+			f2fs_msg(sb, KERN_INFO,
+					"Test dummy encryption mount option ignored");
+#endif
+			break;
 		default:
 			f2fs_msg(sb, KERN_ERR,
 				"Unrecognized mount option \"%s\" or missing value",
@@ -699,14 +781,22 @@ static int parse_options(struct super_block *sb, char *options)
 	}
 
 	if (test_opt(sbi, INLINE_XATTR_SIZE)) {
+		if (!f2fs_sb_has_extra_attr(sb) ||
+			!f2fs_sb_has_flexible_inline_xattr(sb)) {
+			f2fs_msg(sb, KERN_ERR,
+					"extra_attr or flexible_inline_xattr "
+					"feature is off");
+			return -EINVAL;
+		}
 		if (!test_opt(sbi, INLINE_XATTR)) {
 			f2fs_msg(sb, KERN_ERR,
 					"inline_xattr_size option should be "
 					"set with inline_xattr option");
 			return -EINVAL;
 		}
-		if (!sbi->inline_xattr_size ||
-			sbi->inline_xattr_size >= DEF_ADDRS_PER_INODE -
+		if (!F2FS_OPTION(sbi).inline_xattr_size ||
+			F2FS_OPTION(sbi).inline_xattr_size >=
+					DEF_ADDRS_PER_INODE -
 					F2FS_TOTAL_EXTRA_ATTR_SIZE -
 					DEF_INLINE_RESERVED_SIZE -
 					DEF_MIN_INLINE_SIZE) {
@@ -715,6 +805,12 @@ static int parse_options(struct super_block *sb, char *options)
 			return -EINVAL;
 		}
 	}
+
+	/* Not pass down write hints if the number of active logs is lesser
+	 * than NR_CURSEG_TYPE.
+	 */
+	if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_TYPE)
+		F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
 	return 0;
 }
 
@@ -731,7 +827,6 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
 	/* Initialize f2fs-specific inode info */
 	atomic_set(&fi->dirty_pages, 0);
 	fi->i_current_depth = 1;
-	fi->i_advise = 0;
 	init_rwsem(&fi->i_sem);
 	INIT_LIST_HEAD(&fi->dirty_list);
 	INIT_LIST_HEAD(&fi->gdirty_list);
@@ -743,10 +838,6 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
 	init_rwsem(&fi->i_mmap_sem);
 	init_rwsem(&fi->i_xattr_sem);
 
-#ifdef CONFIG_QUOTA
-	memset(&fi->i_dquot, 0, sizeof(fi->i_dquot));
-	fi->i_reserved_quota = 0;
-#endif
 	/* Will be used by directory only */
 	fi->i_dir_level = F2FS_SB(sb)->dir_level;
 
@@ -956,7 +1047,7 @@ static void f2fs_put_super(struct super_block *sb)
 	mempool_destroy(sbi->write_io_dummy);
 #ifdef CONFIG_QUOTA
 	for (i = 0; i < MAXQUOTAS; i++)
-		kfree(sbi->s_qf_names[i]);
+		kfree(F2FS_OPTION(sbi).s_qf_names[i]);
 #endif
 	destroy_percpu_info(sbi);
 	for (i = 0; i < NR_PAGE_TYPE; i++)
@@ -1070,8 +1161,9 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	buf->f_blocks = total_count - start_count;
 	buf->f_bfree = user_block_count - valid_user_blocks(sbi) -
 						sbi->current_reserved_blocks;
-	if (buf->f_bfree > sbi->root_reserved_blocks)
-		buf->f_bavail = buf->f_bfree - sbi->root_reserved_blocks;
+	if (buf->f_bfree > F2FS_OPTION(sbi).root_reserved_blocks)
+		buf->f_bavail = buf->f_bfree -
+				F2FS_OPTION(sbi).root_reserved_blocks;
 	else
 		buf->f_bavail = 0;
 
@@ -1106,10 +1198,10 @@ static inline void f2fs_show_quota_options(struct seq_file *seq,
 #ifdef CONFIG_QUOTA
 	struct f2fs_sb_info *sbi = F2FS_SB(sb);
 
-	if (sbi->s_jquota_fmt) {
+	if (F2FS_OPTION(sbi).s_jquota_fmt) {
 		char *fmtname = "";
 
-		switch (sbi->s_jquota_fmt) {
+		switch (F2FS_OPTION(sbi).s_jquota_fmt) {
 		case QFMT_VFS_OLD:
 			fmtname = "vfsold";
 			break;
@@ -1123,14 +1215,17 @@ static inline void f2fs_show_quota_options(struct seq_file *seq,
 		seq_printf(seq, ",jqfmt=%s", fmtname);
 	}
 
-	if (sbi->s_qf_names[USRQUOTA])
-		seq_show_option(seq, "usrjquota", sbi->s_qf_names[USRQUOTA]);
+	if (F2FS_OPTION(sbi).s_qf_names[USRQUOTA])
+		seq_show_option(seq, "usrjquota",
+			F2FS_OPTION(sbi).s_qf_names[USRQUOTA]);
 
-	if (sbi->s_qf_names[GRPQUOTA])
-		seq_show_option(seq, "grpjquota", sbi->s_qf_names[GRPQUOTA]);
+	if (F2FS_OPTION(sbi).s_qf_names[GRPQUOTA])
+		seq_show_option(seq, "grpjquota",
+			F2FS_OPTION(sbi).s_qf_names[GRPQUOTA]);
 
-	if (sbi->s_qf_names[PRJQUOTA])
-		seq_show_option(seq, "prjjquota", sbi->s_qf_names[PRJQUOTA]);
+	if (F2FS_OPTION(sbi).s_qf_names[PRJQUOTA])
+		seq_show_option(seq, "prjjquota",
+			F2FS_OPTION(sbi).s_qf_names[PRJQUOTA]);
 #endif
 }
 
@@ -1165,7 +1260,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
 		seq_puts(seq, ",noinline_xattr");
 	if (test_opt(sbi, INLINE_XATTR_SIZE))
 		seq_printf(seq, ",inline_xattr_size=%u",
-					sbi->inline_xattr_size);
+					F2FS_OPTION(sbi).inline_xattr_size);
 #endif
 #ifdef CONFIG_F2FS_FS_POSIX_ACL
 	if (test_opt(sbi, POSIX_ACL))
@@ -1201,18 +1296,20 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
 		seq_puts(seq, "adaptive");
 	else if (test_opt(sbi, LFS))
 		seq_puts(seq, "lfs");
-	seq_printf(seq, ",active_logs=%u", sbi->active_logs);
+	seq_printf(seq, ",active_logs=%u", F2FS_OPTION(sbi).active_logs);
 	if (test_opt(sbi, RESERVE_ROOT))
 		seq_printf(seq, ",reserve_root=%u,resuid=%u,resgid=%u",
-				sbi->root_reserved_blocks,
-				from_kuid_munged(&init_user_ns, sbi->s_resuid),
-				from_kgid_munged(&init_user_ns, sbi->s_resgid));
+				F2FS_OPTION(sbi).root_reserved_blocks,
+				from_kuid_munged(&init_user_ns,
+					F2FS_OPTION(sbi).s_resuid),
+				from_kgid_munged(&init_user_ns,
+					F2FS_OPTION(sbi).s_resgid));
 	if (F2FS_IO_SIZE_BITS(sbi))
 		seq_printf(seq, ",io_size=%uKB", F2FS_IO_SIZE_KB(sbi));
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 	if (test_opt(sbi, FAULT_INJECTION))
 		seq_printf(seq, ",fault_injection=%u",
-				sbi->fault_info.inject_rate);
+				F2FS_OPTION(sbi).fault_info.inject_rate);
 #endif
 #ifdef CONFIG_QUOTA
 	if (test_opt(sbi, QUOTA))
@@ -1225,15 +1322,37 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
 		seq_puts(seq, ",prjquota");
 #endif
 	f2fs_show_quota_options(seq, sbi->sb);
+	if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_USER)
+		seq_printf(seq, ",whint_mode=%s", "user-based");
+	else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS)
+		seq_printf(seq, ",whint_mode=%s", "fs-based");
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+	if (F2FS_OPTION(sbi).test_dummy_encryption)
+		seq_puts(seq, ",test_dummy_encryption");
+#endif
 
+	if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_DEFAULT)
+		seq_printf(seq, ",alloc_mode=%s", "default");
+	else if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_REUSE)
+		seq_printf(seq, ",alloc_mode=%s", "reuse");
+
+	if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_POSIX)
+		seq_printf(seq, ",fsync_mode=%s", "posix");
+	else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT)
+		seq_printf(seq, ",fsync_mode=%s", "strict");
 	return 0;
 }
 
 static void default_options(struct f2fs_sb_info *sbi)
 {
 	/* init some FS parameters */
-	sbi->active_logs = NR_CURSEG_TYPE;
-	sbi->inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
+	F2FS_OPTION(sbi).active_logs = NR_CURSEG_TYPE;
+	F2FS_OPTION(sbi).inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
+	F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
+	F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT;
+	F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX;
+	F2FS_OPTION(sbi).test_dummy_encryption = false;
+	sbi->readdir_ra = 1;
 
 	set_opt(sbi, BG_GC);
 	set_opt(sbi, INLINE_XATTR);
@@ -1243,7 +1362,7 @@ static void default_options(struct f2fs_sb_info *sbi)
 	set_opt(sbi, NOHEAP);
 	sbi->sb->s_flags |= SB_LAZYTIME;
 	set_opt(sbi, FLUSH_MERGE);
-	if (f2fs_sb_mounted_blkzoned(sbi->sb)) {
+	if (f2fs_sb_has_blkzoned(sbi->sb)) {
 		set_opt_mode(sbi, F2FS_MOUNT_LFS);
 		set_opt(sbi, DISCARD);
 	} else {
@@ -1270,16 +1389,11 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 	struct f2fs_sb_info *sbi = F2FS_SB(sb);
 	struct f2fs_mount_info org_mount_opt;
 	unsigned long old_sb_flags;
-	int err, active_logs;
+	int err;
 	bool need_restart_gc = false;
 	bool need_stop_gc = false;
 	bool no_extent_cache = !test_opt(sbi, EXTENT_CACHE);
-#ifdef CONFIG_F2FS_FAULT_INJECTION
-	struct f2fs_fault_info ffi = sbi->fault_info;
-#endif
 #ifdef CONFIG_QUOTA
-	int s_jquota_fmt;
-	char *s_qf_names[MAXQUOTAS];
 	int i, j;
 #endif
 
@@ -1289,21 +1403,21 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 	 */
 	org_mount_opt = sbi->mount_opt;
 	old_sb_flags = sb->s_flags;
-	active_logs = sbi->active_logs;
 
 #ifdef CONFIG_QUOTA
-	s_jquota_fmt = sbi->s_jquota_fmt;
+	org_mount_opt.s_jquota_fmt = F2FS_OPTION(sbi).s_jquota_fmt;
 	for (i = 0; i < MAXQUOTAS; i++) {
-		if (sbi->s_qf_names[i]) {
-			s_qf_names[i] = kstrdup(sbi->s_qf_names[i],
-							 GFP_KERNEL);
-			if (!s_qf_names[i]) {
+		if (F2FS_OPTION(sbi).s_qf_names[i]) {
+			org_mount_opt.s_qf_names[i] =
+				kstrdup(F2FS_OPTION(sbi).s_qf_names[i],
+				GFP_KERNEL);
+			if (!org_mount_opt.s_qf_names[i]) {
 				for (j = 0; j < i; j++)
-					kfree(s_qf_names[j]);
+					kfree(org_mount_opt.s_qf_names[j]);
 				return -ENOMEM;
 			}
 		} else {
-			s_qf_names[i] = NULL;
+			org_mount_opt.s_qf_names[i] = NULL;
 		}
 	}
 #endif
@@ -1373,7 +1487,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 		need_stop_gc = true;
 	}
 
-	if (*flags & SB_RDONLY) {
+	if (*flags & SB_RDONLY ||
+		F2FS_OPTION(sbi).whint_mode != org_mount_opt.whint_mode) {
 		writeback_inodes_sb(sb, WB_REASON_SYNC);
 		sync_inodes_sb(sb);
 
@@ -1399,7 +1514,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 #ifdef CONFIG_QUOTA
 	/* Release old quota file names */
 	for (i = 0; i < MAXQUOTAS; i++)
-		kfree(s_qf_names[i]);
+		kfree(org_mount_opt.s_qf_names[i]);
 #endif
 	/* Update the POSIXACL Flag */
 	sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
@@ -1417,18 +1532,14 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 	}
 restore_opts:
 #ifdef CONFIG_QUOTA
-	sbi->s_jquota_fmt = s_jquota_fmt;
+	F2FS_OPTION(sbi).s_jquota_fmt = org_mount_opt.s_jquota_fmt;
 	for (i = 0; i < MAXQUOTAS; i++) {
-		kfree(sbi->s_qf_names[i]);
-		sbi->s_qf_names[i] = s_qf_names[i];
+		kfree(F2FS_OPTION(sbi).s_qf_names[i]);
+		F2FS_OPTION(sbi).s_qf_names[i] = org_mount_opt.s_qf_names[i];
 	}
 #endif
 	sbi->mount_opt = org_mount_opt;
-	sbi->active_logs = active_logs;
 	sb->s_flags = old_sb_flags;
-#ifdef CONFIG_F2FS_FAULT_INJECTION
-	sbi->fault_info = ffi;
-#endif
 	return err;
 }
 
@@ -1456,7 +1567,7 @@ static ssize_t f2fs_quota_read(struct super_block *sb, int type, char *data,
 	while (toread > 0) {
 		tocopy = min_t(unsigned long, sb->s_blocksize - offset, toread);
 repeat:
-		page = read_mapping_page(mapping, blkidx, NULL);
+		page = read_cache_page_gfp(mapping, blkidx, GFP_NOFS);
 		if (IS_ERR(page)) {
 			if (PTR_ERR(page) == -ENOMEM) {
 				congestion_wait(BLK_RW_ASYNC, HZ/50);
@@ -1550,8 +1661,8 @@ static qsize_t *f2fs_get_reserved_space(struct inode *inode)
 
 static int f2fs_quota_on_mount(struct f2fs_sb_info *sbi, int type)
 {
-	return dquot_quota_on_mount(sbi->sb, sbi->s_qf_names[type],
-						sbi->s_jquota_fmt, type);
+	return dquot_quota_on_mount(sbi->sb, F2FS_OPTION(sbi).s_qf_names[type],
+					F2FS_OPTION(sbi).s_jquota_fmt, type);
 }
 
 int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly)
@@ -1570,7 +1681,7 @@ int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly)
 	}
 
 	for (i = 0; i < MAXQUOTAS; i++) {
-		if (sbi->s_qf_names[i]) {
+		if (F2FS_OPTION(sbi).s_qf_names[i]) {
 			err = f2fs_quota_on_mount(sbi, i);
 			if (!err) {
 				enabled = 1;
@@ -1797,11 +1908,28 @@ static int f2fs_get_context(struct inode *inode, void *ctx, size_t len)
 static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
 							void *fs_data)
 {
+	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+
+	/*
+	 * Encrypting the root directory is not allowed because fsck
+	 * expects lost+found directory to exist and remain unencrypted
+	 * if LOST_FOUND feature is enabled.
+	 *
+	 */
+	if (f2fs_sb_has_lost_found(sbi->sb) &&
+			inode->i_ino == F2FS_ROOT_INO(sbi))
+		return -EPERM;
+
 	return f2fs_setxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
 				F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
 				ctx, len, fs_data, XATTR_CREATE);
 }
 
+static bool f2fs_dummy_context(struct inode *inode)
+{
+	return DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(inode));
+}
+
 static unsigned f2fs_max_namelen(struct inode *inode)
 {
 	return S_ISLNK(inode->i_mode) ?
@@ -1812,6 +1940,7 @@ static const struct fscrypt_operations f2fs_cryptops = {
 	.key_prefix	= "f2fs:",
 	.get_context	= f2fs_get_context,
 	.set_context	= f2fs_set_context,
+	.dummy_context	= f2fs_dummy_context,
 	.empty_dir	= f2fs_empty_dir,
 	.max_namelen	= f2fs_max_namelen,
 };
@@ -1894,7 +2023,6 @@ static int __f2fs_commit_super(struct buffer_head *bh,
 	lock_buffer(bh);
 	if (super)
 		memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super));
-	set_buffer_uptodate(bh);
 	set_buffer_dirty(bh);
 	unlock_buffer(bh);
 
@@ -2181,6 +2309,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
 
 	sbi->dirty_device = 0;
 	spin_lock_init(&sbi->dev_lock);
+
+	init_rwsem(&sbi->sb_lock);
 }
 
 static int init_percpu_info(struct f2fs_sb_info *sbi)
@@ -2206,7 +2336,7 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi)
 	unsigned int n = 0;
 	int err = -EIO;
 
-	if (!f2fs_sb_mounted_blkzoned(sbi->sb))
+	if (!f2fs_sb_has_blkzoned(sbi->sb))
 		return 0;
 
 	if (sbi->blocks_per_blkz && sbi->blocks_per_blkz !=
@@ -2334,7 +2464,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
 	}
 
 	/* write back-up superblock first */
-	bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0: 1);
+	bh = sb_bread(sbi->sb, sbi->valid_super_block ? 0 : 1);
 	if (!bh)
 		return -EIO;
 	err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi));
@@ -2345,7 +2475,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
 		return err;
 
 	/* write current valid superblock */
-	bh = sb_getblk(sbi->sb, sbi->valid_super_block);
+	bh = sb_bread(sbi->sb, sbi->valid_super_block);
 	if (!bh)
 		return -EIO;
 	err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi));
@@ -2413,7 +2543,7 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
 
 #ifdef CONFIG_BLK_DEV_ZONED
 		if (bdev_zoned_model(FDEV(i).bdev) == BLK_ZONED_HM &&
-				!f2fs_sb_mounted_blkzoned(sbi->sb)) {
+				!f2fs_sb_has_blkzoned(sbi->sb)) {
 			f2fs_msg(sbi->sb, KERN_ERR,
 				"Zoned block device feature not enabled\n");
 			return -EINVAL;
@@ -2447,6 +2577,18 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
 	return 0;
 }
 
+static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
+{
+	struct f2fs_sm_info *sm_i = SM_I(sbi);
+
+	/* adjust parameters according to the volume size */
+	if (sm_i->main_segments <= SMALL_VOLUME_SEGMENTS) {
+		F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_REUSE;
+		sm_i->dcc_info->discard_granularity = 1;
+		sm_i->ipu_policy = 1 << F2FS_IPU_FORCE;
+	}
+}
+
 static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct f2fs_sb_info *sbi;
@@ -2494,8 +2636,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_fs_info = sbi;
 	sbi->raw_super = raw_super;
 
-	sbi->s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID);
-	sbi->s_resgid = make_kgid(&init_user_ns, F2FS_DEF_RESGID);
+	F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID);
+	F2FS_OPTION(sbi).s_resgid = make_kgid(&init_user_ns, F2FS_DEF_RESGID);
 
 	/* precompute checksum seed for metadata */
 	if (f2fs_sb_has_inode_chksum(sb))
@@ -2508,7 +2650,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 	 * devices, but mandatory for host-managed zoned block devices.
 	 */
 #ifndef CONFIG_BLK_DEV_ZONED
-	if (f2fs_sb_mounted_blkzoned(sb)) {
+	if (f2fs_sb_has_blkzoned(sb)) {
 		f2fs_msg(sb, KERN_ERR,
 			 "Zoned block device support is not enabled\n");
 		err = -EOPNOTSUPP;
@@ -2724,7 +2866,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 	 * Turn on quotas which were not enabled for read-only mounts if
 	 * filesystem has quota feature, so that they are updated correctly.
 	 */
-	if (f2fs_sb_has_quota_ino(sb) && !sb_rdonly(sb)) {
+	if (f2fs_sb_has_quota_ino(sb) && !f2fs_readonly(sb)) {
 		err = f2fs_enable_quotas(sb);
 		if (err) {
 			f2fs_msg(sb, KERN_ERR,
@@ -2799,6 +2941,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 
 	f2fs_join_shrinker(sbi);
 
+	f2fs_tuning_parameters(sbi);
+
 	f2fs_msg(sbi->sb, KERN_NOTICE, "Mounted with checkpoint version = %llx",
 				cur_cp_version(F2FS_CKPT(sbi)));
 	f2fs_update_time(sbi, CP_TIME);
@@ -2807,7 +2951,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 
 free_meta:
 #ifdef CONFIG_QUOTA
-	if (f2fs_sb_has_quota_ino(sb) && !sb_rdonly(sb))
+	if (f2fs_sb_has_quota_ino(sb) && !f2fs_readonly(sb))
 		f2fs_quota_off_umount(sbi->sb);
 #endif
 	f2fs_sync_inode_meta(sbi);
@@ -2851,7 +2995,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 free_options:
 #ifdef CONFIG_QUOTA
 	for (i = 0; i < MAXQUOTAS; i++)
-		kfree(sbi->s_qf_names[i]);
+		kfree(F2FS_OPTION(sbi).s_qf_names[i]);
 #endif
 	kfree(options);
 free_sb_buf:
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index d978c7b..f33a56d 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -58,7 +58,7 @@ static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 	else if (struct_type == FAULT_INFO_RATE ||
 					struct_type == FAULT_INFO_TYPE)
-		return (unsigned char *)&sbi->fault_info;
+		return (unsigned char *)&F2FS_OPTION(sbi).fault_info;
 #endif
 	return NULL;
 }
@@ -92,10 +92,10 @@ static ssize_t features_show(struct f2fs_attr *a,
 	if (!sb->s_bdev->bd_part)
 		return snprintf(buf, PAGE_SIZE, "0\n");
 
-	if (f2fs_sb_has_crypto(sb))
+	if (f2fs_sb_has_encrypt(sb))
 		len += snprintf(buf, PAGE_SIZE - len, "%s",
 						"encryption");
-	if (f2fs_sb_mounted_blkzoned(sb))
+	if (f2fs_sb_has_blkzoned(sb))
 		len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
 				len ? ", " : "", "blkzoned");
 	if (f2fs_sb_has_extra_attr(sb))
@@ -116,6 +116,9 @@ static ssize_t features_show(struct f2fs_attr *a,
 	if (f2fs_sb_has_inode_crtime(sb))
 		len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
 				len ? ", " : "", "inode_crtime");
+	if (f2fs_sb_has_lost_found(sb))
+		len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
+				len ? ", " : "", "lost_found");
 	len += snprintf(buf + len, PAGE_SIZE - len, "\n");
 	return len;
 }
@@ -136,6 +139,27 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
 	if (!ptr)
 		return -EINVAL;
 
+	if (!strcmp(a->attr.name, "extension_list")) {
+		__u8 (*extlist)[F2FS_EXTENSION_LEN] =
+					sbi->raw_super->extension_list;
+		int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
+		int hot_count = sbi->raw_super->hot_ext_count;
+		int len = 0, i;
+
+		len += snprintf(buf + len, PAGE_SIZE - len,
+						"cold file extenstion:\n");
+		for (i = 0; i < cold_count; i++)
+			len += snprintf(buf + len, PAGE_SIZE - len, "%s\n",
+								extlist[i]);
+
+		len += snprintf(buf + len, PAGE_SIZE - len,
+						"hot file extenstion:\n");
+		for (i = cold_count; i < cold_count + hot_count; i++)
+			len += snprintf(buf + len, PAGE_SIZE - len, "%s\n",
+								extlist[i]);
+		return len;
+	}
+
 	ui = (unsigned int *)(ptr + a->offset);
 
 	return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
@@ -154,6 +178,41 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
 	if (!ptr)
 		return -EINVAL;
 
+	if (!strcmp(a->attr.name, "extension_list")) {
+		const char *name = strim((char *)buf);
+		bool set = true, hot;
+
+		if (!strncmp(name, "[h]", 3))
+			hot = true;
+		else if (!strncmp(name, "[c]", 3))
+			hot = false;
+		else
+			return -EINVAL;
+
+		name += 3;
+
+		if (*name == '!') {
+			name++;
+			set = false;
+		}
+
+		if (strlen(name) >= F2FS_EXTENSION_LEN)
+			return -EINVAL;
+
+		down_write(&sbi->sb_lock);
+
+		ret = update_extension_list(sbi, name, hot, set);
+		if (ret)
+			goto out;
+
+		ret = f2fs_commit_super(sbi, false);
+		if (ret)
+			update_extension_list(sbi, name, hot, !set);
+out:
+		up_write(&sbi->sb_lock);
+		return ret ? ret : count;
+	}
+
 	ui = (unsigned int *)(ptr + a->offset);
 
 	ret = kstrtoul(skip_spaces(buf), 0, &t);
@@ -166,7 +225,7 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
 	if (a->struct_type == RESERVED_BLOCKS) {
 		spin_lock(&sbi->stat_lock);
 		if (t > (unsigned long)(sbi->user_block_count -
-					sbi->root_reserved_blocks)) {
+				F2FS_OPTION(sbi).root_reserved_blocks)) {
 			spin_unlock(&sbi->stat_lock);
 			return -EINVAL;
 		}
@@ -236,6 +295,7 @@ enum feat_id {
 	FEAT_FLEXIBLE_INLINE_XATTR,
 	FEAT_QUOTA_INO,
 	FEAT_INODE_CRTIME,
+	FEAT_LOST_FOUND,
 };
 
 static ssize_t f2fs_feature_show(struct f2fs_attr *a,
@@ -251,6 +311,7 @@ static ssize_t f2fs_feature_show(struct f2fs_attr *a,
 	case FEAT_FLEXIBLE_INLINE_XATTR:
 	case FEAT_QUOTA_INO:
 	case FEAT_INODE_CRTIME:
+	case FEAT_LOST_FOUND:
 		return snprintf(buf, PAGE_SIZE, "supported\n");
 	}
 	return 0;
@@ -307,6 +368,7 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
 F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
@@ -329,6 +391,7 @@ F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
 F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR);
 F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
 F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
+F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -357,6 +420,7 @@ static struct attribute *f2fs_attrs[] = {
 	ATTR_LIST(iostat_enable),
 	ATTR_LIST(readdir_ra),
 	ATTR_LIST(gc_pin_file_thresh),
+	ATTR_LIST(extension_list),
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 	ATTR_LIST(inject_rate),
 	ATTR_LIST(inject_type),
@@ -383,6 +447,7 @@ static struct attribute *f2fs_feat_attrs[] = {
 	ATTR_LIST(flexible_inline_xattr),
 	ATTR_LIST(quota_ino),
 	ATTR_LIST(inode_crtime),
+	ATTR_LIST(lost_found),
 	NULL,
 };
 
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index d4d04fe..1280f91 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1343,7 +1343,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 
 	dirty = inode->i_state & I_DIRTY;
 	if (inode->i_state & I_DIRTY_TIME) {
-		if ((dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) ||
+		if ((dirty & I_DIRTY_INODE) ||
 		    wbc->sync_mode == WB_SYNC_ALL ||
 		    unlikely(inode->i_state & I_DIRTY_TIME_EXPIRED) ||
 		    unlikely(time_after(jiffies,
@@ -2112,7 +2112,6 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
  */
 void __mark_inode_dirty(struct inode *inode, int flags)
 {
-#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
 	struct super_block *sb = inode->i_sb;
 	int dirtytime;
 
@@ -2122,7 +2121,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
 	 * dirty the inode itself
 	 */
-	if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_TIME)) {
+	if (flags & (I_DIRTY_INODE | I_DIRTY_TIME)) {
 		trace_writeback_dirty_inode_start(inode, flags);
 
 		if (sb->s_op->dirty_inode)
@@ -2197,7 +2196,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 			if (dirtytime)
 				inode->dirtied_time_when = jiffies;
 
-			if (inode->i_state & (I_DIRTY_INODE | I_DIRTY_PAGES))
+			if (inode->i_state & I_DIRTY)
 				dirty_list = &wb->b_dirty;
 			else
 				dirty_list = &wb->b_dirty_time;
@@ -2221,8 +2220,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 	}
 out_unlock_inode:
 	spin_unlock(&inode->i_lock);
-
-#undef I_DIRTY_INODE
 }
 EXPORT_SYMBOL(__mark_inode_dirty);
 
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 620be05..cf5c7f3 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -800,7 +800,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
 	int need_endtrans = 0;
 	int ret;
 
-	if (!(flags & (I_DIRTY_DATASYNC|I_DIRTY_SYNC)))
+	if (!(flags & I_DIRTY_INODE))
 		return;
 	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
 		return;
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 05de209..f2bce1e 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -308,7 +308,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
 	}
 
 	ip->i_inode.i_ctime = current_time(&ip->i_inode);
-	__mark_inode_dirty(&ip->i_inode, I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+	__mark_inode_dirty(&ip->i_inode, I_DIRTY_DATASYNC);
 
 	gfs2_trans_end(sdp);
 
@@ -768,7 +768,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
 		goto out_end_trans;
 
 	ip->i_inode.i_ctime = current_time(&ip->i_inode);
-	__mark_inode_dirty(&ip->i_inode, I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+	__mark_inode_dirty(&ip->i_inode, I_DIRTY_DATASYNC);
 
 out_end_trans:
 	gfs2_trans_end(GFS2_SB(&ip->i_inode));
@@ -896,7 +896,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
 		ea_set_remove_stuffed(ip, es->es_el);
 
 	ip->i_inode.i_ctime = current_time(&ip->i_inode);
-	__mark_inode_dirty(&ip->i_inode, I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+	__mark_inode_dirty(&ip->i_inode, I_DIRTY_DATASYNC);
 
 	gfs2_trans_end(GFS2_SB(&ip->i_inode));
 	return error;
@@ -1114,7 +1114,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
 	}
 
 	ip->i_inode.i_ctime = current_time(&ip->i_inode);
-	__mark_inode_dirty(&ip->i_inode, I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+	__mark_inode_dirty(&ip->i_inode, I_DIRTY_DATASYNC);
 
 	gfs2_trans_end(GFS2_SB(&ip->i_inode));
 
diff --git a/fs/internal.h b/fs/internal.h
index 980d005..e08972d 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -125,7 +125,6 @@ int do_fchmodat(int dfd, const char __user *filename, umode_t mode);
 int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
 		int flag);
 
-extern int open_check_o_direct(struct file *f);
 extern int vfs_open(const struct path *, struct file *, const struct cred *);
 extern struct file *filp_clone_open(struct file *);
 
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 4a6cf28..83b8f06 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -21,14 +21,6 @@
 #include <linux/pagemap.h>
 #include "nodelist.h"
 
-struct erase_priv_struct {
-	struct jffs2_eraseblock *jeb;
-	struct jffs2_sb_info *c;
-};
-
-#ifndef __ECOS
-static void jffs2_erase_callback(struct erase_info *);
-#endif
 static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset);
 static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
 static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
@@ -51,7 +43,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
 	jffs2_dbg(1, "%s(): erase block %#08x (range %#08x-%#08x)\n",
 		  __func__,
 		  jeb->offset, jeb->offset, jeb->offset + c->sector_size);
-	instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
+	instr = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
 	if (!instr) {
 		pr_warn("kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
 		mutex_lock(&c->erase_free_sem);
@@ -67,18 +59,15 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
 
 	memset(instr, 0, sizeof(*instr));
 
-	instr->mtd = c->mtd;
 	instr->addr = jeb->offset;
 	instr->len = c->sector_size;
-	instr->callback = jffs2_erase_callback;
-	instr->priv = (unsigned long)(&instr[1]);
-
-	((struct erase_priv_struct *)instr->priv)->jeb = jeb;
-	((struct erase_priv_struct *)instr->priv)->c = c;
 
 	ret = mtd_erase(c->mtd, instr);
-	if (!ret)
+	if (!ret) {
+		jffs2_erase_succeeded(c, jeb);
+		kfree(instr);
 		return;
+	}
 
 	bad_offset = instr->fail_addr;
 	kfree(instr);
@@ -214,22 +203,6 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
 	wake_up(&c->erase_wait);
 }
 
-#ifndef __ECOS
-static void jffs2_erase_callback(struct erase_info *instr)
-{
-	struct erase_priv_struct *priv = (void *)instr->priv;
-
-	if(instr->state != MTD_ERASE_DONE) {
-		pr_warn("Erase at 0x%08llx finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n",
-			(unsigned long long)instr->addr, instr->state);
-		jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr);
-	} else {
-		jffs2_erase_succeeded(priv->c, priv->jeb);
-	}
-	kfree(instr);
-}
-#endif /* !__ECOS */
-
 /* Hmmm. Maybe we should accept the extra space it takes and make
    this a standard doubly-linked list? */
 static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 9c36d61..346ed16 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -57,8 +57,8 @@ static struct task_struct	*nlmsvc_task;
 static struct svc_rqst		*nlmsvc_rqst;
 unsigned long			nlmsvc_timeout;
 
-atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
-DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
+static atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
+static DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
 
 unsigned int lockd_net_id;
 
diff --git a/fs/locks.c b/fs/locks.c
index d6ff4be..62bbe8b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -559,7 +559,7 @@ static const struct lock_manager_operations lease_manager_ops = {
  * Initialize a lease, use the default lock manager operations
  */
 static int lease_init(struct file *filp, long type, struct file_lock *fl)
- {
+{
 	if (assign_type(fl, type) != 0)
 		return -EINVAL;
 
diff --git a/fs/namei.c b/fs/namei.c
index a094193..5661da1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -39,6 +39,7 @@
 #include <linux/bitops.h>
 #include <linux/init_task.h>
 #include <linux/uaccess.h>
+#include <linux/build_bug.h>
 
 #include "internal.h"
 #include "mount.h"
@@ -130,6 +131,7 @@ getname_flags(const char __user *filename, int flags, int *empty)
 	struct filename *result;
 	char *kname;
 	int len;
+	BUILD_BUG_ON(offsetof(struct filename, iname) % sizeof(long) != 0);
 
 	result = audit_reusename(filename);
 	if (result)
@@ -3374,9 +3376,7 @@ static int do_last(struct nameidata *nd,
 		goto out;
 	*opened |= FILE_OPENED;
 opened:
-	error = open_check_o_direct(file);
-	if (!error)
-		error = ima_file_check(file, op->acc_mode, *opened);
+	error = ima_file_check(file, op->acc_mode, *opened);
 	if (!error && will_truncate)
 		error = handle_truncate(file);
 out:
@@ -3456,9 +3456,6 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
 	error = finish_open(file, child, NULL, opened);
 	if (error)
 		goto out2;
-	error = open_check_o_direct(file);
-	if (error)
-		fput(file);
 out2:
 	mnt_drop_write(path.mnt);
 out:
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 65c9c41..b993ad2 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -52,7 +52,6 @@
 #include <linux/nfs.h>
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
-#include <linux/fs_struct.h>
 
 #include "nfs4_fs.h"
 #include "internal.h"
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 1d0ce3c..6259a4b 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -192,6 +192,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
 	struct nfsd3_writeres *resp = rqstp->rq_resp;
 	__be32	nfserr;
 	unsigned long cnt = argp->len;
+	unsigned int nvecs;
 
 	dprintk("nfsd: WRITE(3)    %s %d bytes at %Lu%s\n",
 				SVCFH_fmt(&argp->fh),
@@ -201,9 +202,12 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
 
 	fh_copy(&resp->fh, &argp->fh);
 	resp->committed = argp->stable;
+	nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
+	if (!nvecs)
+		RETURN_STATUS(nfserr_io);
 	nfserr = nfsd_write(rqstp, &resp->fh, argp->offset,
-				rqstp->rq_vec, argp->vlen,
-				&cnt, resp->committed);
+			    rqstp->rq_vec, nvecs, &cnt,
+			    resp->committed);
 	resp->count = cnt;
 	RETURN_STATUS(nfserr);
 }
@@ -279,6 +283,16 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp)
 	struct nfsd3_diropres *resp = rqstp->rq_resp;
 	__be32	nfserr;
 
+	if (argp->tlen == 0)
+		RETURN_STATUS(nfserr_inval);
+	if (argp->tlen > NFS3_MAXPATHLEN)
+		RETURN_STATUS(nfserr_nametoolong);
+
+	argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first,
+						argp->tlen);
+	if (IS_ERR(argp->tname))
+		RETURN_STATUS(nfserrno(PTR_ERR(argp->tname)));
+
 	dprintk("nfsd: SYMLINK(3)  %s %.*s -> %.*s\n",
 				SVCFH_fmt(&argp->ffh),
 				argp->flen, argp->fname,
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 1a70581..3192b54 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -391,7 +391,7 @@ int
 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_writeargs *args = rqstp->rq_argp;
-	unsigned int len, v, hdr, dlen;
+	unsigned int len, hdr, dlen;
 	u32 max_blocksize = svc_max_payload(rqstp);
 	struct kvec *head = rqstp->rq_arg.head;
 	struct kvec *tail = rqstp->rq_arg.tail;
@@ -433,17 +433,9 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 		args->count = max_blocksize;
 		len = args->len = max_blocksize;
 	}
-	rqstp->rq_vec[0].iov_base = (void*)p;
-	rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
-	v = 0;
-	while (len > rqstp->rq_vec[v].iov_len) {
-		len -= rqstp->rq_vec[v].iov_len;
-		v++;
-		rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
-		rqstp->rq_vec[v].iov_len = PAGE_SIZE;
-	}
-	rqstp->rq_vec[v].iov_len = len;
-	args->vlen = v + 1;
+
+	args->first.iov_base = (void *)p;
+	args->first.iov_len = head->iov_len - hdr;
 	return 1;
 }
 
@@ -489,51 +481,24 @@ int
 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_symlinkargs *args = rqstp->rq_argp;
-	unsigned int len, avail;
-	char *old, *new;
-	struct kvec *vec;
+	char *base = (char *)p;
+	size_t dlen;
 
 	if (!(p = decode_fh(p, &args->ffh)) ||
-	    !(p = decode_filename(p, &args->fname, &args->flen))
-		)
+	    !(p = decode_filename(p, &args->fname, &args->flen)))
 		return 0;
 	p = decode_sattr3(p, &args->attrs);
 
-	/* now decode the pathname, which might be larger than the first page.
-	 * As we have to check for nul's anyway, we copy it into a new page
-	 * This page appears in the rq_res.pages list, but as pages_len is always
-	 * 0, it won't get in the way
-	 */
-	len = ntohl(*p++);
-	if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
-		return 0;
-	args->tname = new = page_address(*(rqstp->rq_next_page++));
-	args->tlen = len;
-	/* first copy and check from the first page */
-	old = (char*)p;
-	vec = &rqstp->rq_arg.head[0];
-	if ((void *)old > vec->iov_base + vec->iov_len)
-		return 0;
-	avail = vec->iov_len - (old - (char*)vec->iov_base);
-	while (len && avail && *old) {
-		*new++ = *old++;
-		len--;
-		avail--;
-	}
-	/* now copy next page if there is one */
-	if (len && !avail && rqstp->rq_arg.page_len) {
-		avail = min_t(unsigned int, rqstp->rq_arg.page_len, PAGE_SIZE);
-		old = page_address(rqstp->rq_arg.pages[0]);
-	}
-	while (len && avail && *old) {
-		*new++ = *old++;
-		len--;
-		avail--;
-	}
-	*new = '\0';
-	if (len)
-		return 0;
+	args->tlen = ntohl(*p++);
 
+	args->first.iov_base = p;
+	args->first.iov_len = rqstp->rq_arg.head[0].iov_len;
+	args->first.iov_len -= (char *)p - base;
+
+	dlen = args->first.iov_len + rqstp->rq_arg.page_len +
+	       rqstp->rq_arg.tail[0].iov_len;
+	if (dlen < XDR_QUADLEN(args->tlen) << 2)
+		return 0;
 	return 1;
 }
 
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 49b0a9e..1f04d2a 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -223,8 +223,8 @@ static int nfs_cb_stat_to_errno(int status)
 	return -status;
 }
 
-static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
-			       int *status)
+static int decode_cb_op_status(struct xdr_stream *xdr,
+			       enum nfs_cb_opnum4 expected, int *status)
 {
 	__be32 *p;
 	u32 op;
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index 7d88836..228faf0 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -165,7 +165,7 @@ nfsd4_free_layout_stateid(struct nfs4_stid *stid)
 	struct nfs4_client *clp = ls->ls_stid.sc_client;
 	struct nfs4_file *fp = ls->ls_stid.sc_file;
 
-	trace_layoutstate_free(&ls->ls_stid.sc_stateid);
+	trace_nfsd_layoutstate_free(&ls->ls_stid.sc_stateid);
 
 	spin_lock(&clp->cl_lock);
 	list_del_init(&ls->ls_perclnt);
@@ -264,7 +264,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
 	list_add(&ls->ls_perfile, &fp->fi_lo_states);
 	spin_unlock(&fp->fi_lock);
 
-	trace_layoutstate_alloc(&ls->ls_stid.sc_stateid);
+	trace_nfsd_layoutstate_alloc(&ls->ls_stid.sc_stateid);
 	return ls;
 }
 
@@ -334,7 +334,7 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
 	if (list_empty(&ls->ls_layouts))
 		goto out_unlock;
 
-	trace_layout_recall(&ls->ls_stid.sc_stateid);
+	trace_nfsd_layout_recall(&ls->ls_stid.sc_stateid);
 
 	refcount_inc(&ls->ls_stid.sc_count);
 	nfsd4_run_cb(&ls->ls_recall);
@@ -507,7 +507,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
 						false, lrp->lr_layout_type,
 						&ls);
 	if (nfserr) {
-		trace_layout_return_lookup_fail(&lrp->lr_sid);
+		trace_nfsd_layout_return_lookup_fail(&lrp->lr_sid);
 		return nfserr;
 	}
 
@@ -523,7 +523,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
 			nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid);
 		lrp->lrs_present = 1;
 	} else {
-		trace_layoutstate_unhash(&ls->ls_stid.sc_stateid);
+		trace_nfsd_layoutstate_unhash(&ls->ls_stid.sc_stateid);
 		nfs4_unhash_stid(&ls->ls_stid);
 		lrp->lrs_present = 0;
 	}
@@ -694,7 +694,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
 		/*
 		 * Unknown error or non-responding client, we'll need to fence.
 		 */
-		trace_layout_recall_fail(&ls->ls_stid.sc_stateid);
+		trace_nfsd_layout_recall_fail(&ls->ls_stid.sc_stateid);
 
 		ops = nfsd4_layout_ops[ls->ls_layout_type];
 		if (ops->fence_client)
@@ -703,7 +703,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
 			nfsd4_cb_layout_fail(ls);
 		return -1;
 	case -NFS4ERR_NOMATCHING_LAYOUT:
-		trace_layout_recall_done(&ls->ls_stid.sc_stateid);
+		trace_nfsd_layout_recall_done(&ls->ls_stid.sc_stateid);
 		task->tk_status = 0;
 		return 1;
 	}
@@ -716,7 +716,7 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
 		container_of(cb, struct nfs4_layout_stateid, ls_recall);
 	LIST_HEAD(reaplist);
 
-	trace_layout_recall_release(&ls->ls_stid.sc_stateid);
+	trace_nfsd_layout_recall_release(&ls->ls_stid.sc_stateid);
 
 	nfsd4_return_all_layouts(ls, &reaplist);
 	nfsd4_free_layouts(&reaplist);
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index a0bed2b..5d99e88 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -32,6 +32,7 @@
  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+#include <linux/fs_struct.h>
 #include <linux/file.h>
 #include <linux/falloc.h>
 #include <linux/slab.h>
@@ -252,11 +253,13 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
 		 * Note: create modes (UNCHECKED,GUARDED...) are the same
 		 * in NFSv4 as in v3 except EXCLUSIVE4_1.
 		 */
+		current->fs->umask = open->op_umask;
 		status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
 					open->op_fname.len, &open->op_iattr,
 					*resfh, open->op_createmode,
 					(u32 *)open->op_verf.data,
 					&open->op_truncate, &open->op_created);
+		current->fs->umask = 0;
 
 		if (!status && open->op_label.len)
 			nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval);
@@ -603,6 +606,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	if (status)
 		return status;
 
+	current->fs->umask = create->cr_umask;
 	switch (create->cr_type) {
 	case NF4LNK:
 		status = nfsd_symlink(rqstp, &cstate->current_fh,
@@ -611,20 +615,22 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		break;
 
 	case NF4BLK:
+		status = nfserr_inval;
 		rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
 		if (MAJOR(rdev) != create->cr_specdata1 ||
 		    MINOR(rdev) != create->cr_specdata2)
-			return nfserr_inval;
+			goto out_umask;
 		status = nfsd_create(rqstp, &cstate->current_fh,
 				     create->cr_name, create->cr_namelen,
 				     &create->cr_iattr, S_IFBLK, rdev, &resfh);
 		break;
 
 	case NF4CHR:
+		status = nfserr_inval;
 		rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
 		if (MAJOR(rdev) != create->cr_specdata1 ||
 		    MINOR(rdev) != create->cr_specdata2)
-			return nfserr_inval;
+			goto out_umask;
 		status = nfsd_create(rqstp, &cstate->current_fh,
 				     create->cr_name, create->cr_namelen,
 				     &create->cr_iattr,S_IFCHR, rdev, &resfh);
@@ -668,6 +674,8 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	fh_dup2(&cstate->current_fh, &resfh);
 out:
 	fh_put(&resfh);
+out_umask:
+	current->fs->umask = 0;
 	return status;
 }
 
@@ -751,6 +759,9 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	if (read->rd_offset >= OFFSET_MAX)
 		return nfserr_inval;
 
+	trace_nfsd_read_start(rqstp, &cstate->current_fh,
+			      read->rd_offset, read->rd_length);
+
 	/*
 	 * If we do a zero copy read, then a client will see read data
 	 * that reflects the state of the file *after* performing the
@@ -783,6 +794,8 @@ nfsd4_read_release(union nfsd4_op_u *u)
 {
 	if (u->read.rd_filp)
 		fput(u->read.rd_filp);
+	trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
+			     u->read.rd_offset, u->read.rd_length);
 }
 
 static __be32
@@ -1001,6 +1014,9 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	if (write->wr_offset >= OFFSET_MAX)
 		return nfserr_inval;
 
+	cnt = write->wr_buflen;
+	trace_nfsd_write_start(rqstp, &cstate->current_fh,
+			       write->wr_offset, cnt);
 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
 						stateid, WR_STATE, &filp, NULL);
 	if (status) {
@@ -1008,7 +1024,6 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		return status;
 	}
 
-	cnt = write->wr_buflen;
 	write->wr_how_written = write->wr_stable_how;
 	gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));
 
@@ -1021,7 +1036,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	fput(filp);
 
 	write->wr_bytes_written = cnt;
-
+	trace_nfsd_write_done(rqstp, &cstate->current_fh,
+			      write->wr_offset, cnt);
 	return status;
 }
 
@@ -1106,7 +1122,6 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	else {
 		copy->cp_res.wr_bytes_written = bytes;
 		copy->cp_res.wr_stable_how = NFS_UNSTABLE;
-		copy->cp_consecutive = 1;
 		copy->cp_synchronous = 1;
 		gen_boot_verifier(&copy->cp_res.wr_verifier, SVC_NET(rqstp));
 		status = nfs_ok;
@@ -1412,7 +1427,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
 	nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid,
 						true, lgp->lg_layout_type, &ls);
 	if (nfserr) {
-		trace_layout_get_lookup_fail(&lgp->lg_sid);
+		trace_nfsd_layout_get_lookup_fail(&lgp->lg_sid);
 		goto out;
 	}
 
@@ -1481,7 +1496,7 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
 						false, lcp->lc_layout_type,
 						&ls);
 	if (nfserr) {
-		trace_layout_commit_lookup_fail(&lcp->lc_sid);
+		trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
 		/* fixup error code as per RFC5661 */
 		if (nfserr == nfserr_bad_stateid)
 			nfserr = nfserr_badlayout;
@@ -1714,12 +1729,10 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
 		goto encode_op;
 	}
 
+	trace_nfsd_compound(rqstp, args->opcnt);
 	while (!status && resp->opcnt < args->opcnt) {
 		op = &args->ops[resp->opcnt++];
 
-		dprintk("nfsv4 compound op #%d/%d: %d (%s)\n",
-			resp->opcnt, args->opcnt, op->opnum,
-			nfsd4_op_name(op->opnum));
 		/*
 		 * The XDR decode routines may have pre-set op->status;
 		 * for example, if there is a miscellaneous XDR error
@@ -1793,9 +1806,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
 			status = op->status;
 		}
 
-		dprintk("nfsv4 compound op %p opcnt %d #%d: %d: status %d\n",
-			args->ops, args->opcnt, resp->opcnt, op->opnum,
-			be32_to_cpu(status));
+		trace_nfsd_compound_status(args->opcnt, resp->opcnt, status,
+					   nfsd4_op_name(op->opnum));
 
 		nfsd4_cstate_clear_replay(cstate);
 		nfsd4_increment_op_stats(op->opnum);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 61b770e..fc74d6f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -98,6 +98,7 @@ enum nfsd4_st_mutex_lock_subclass {
  */
 static DECLARE_WAIT_QUEUE_HEAD(close_wq);
 
+static struct kmem_cache *client_slab;
 static struct kmem_cache *openowner_slab;
 static struct kmem_cache *lockowner_slab;
 static struct kmem_cache *file_slab;
@@ -806,7 +807,8 @@ static void block_delegations(struct knfsd_fh *fh)
 }
 
 static struct nfs4_delegation *
-alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh,
+alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp,
+		 struct svc_fh *current_fh,
 		 struct nfs4_clnt_odstate *odstate)
 {
 	struct nfs4_delegation *dp;
@@ -837,6 +839,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh,
 	dp->dl_retries = 1;
 	nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client,
 		      &nfsd4_cb_recall_ops, NFSPROC4_CLNT_CB_RECALL);
+	get_nfs4_file(fp);
+	dp->dl_stid.sc_file = fp;
 	return dp;
 out_dec:
 	atomic_long_dec(&num_delegations);
@@ -874,19 +878,35 @@ nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid)
 	spin_unlock(&stid->sc_lock);
 }
 
-static void nfs4_put_deleg_lease(struct nfs4_file *fp)
+static void put_deleg_file(struct nfs4_file *fp)
 {
 	struct file *filp = NULL;
 
 	spin_lock(&fp->fi_lock);
-	if (fp->fi_deleg_file && --fp->fi_delegees == 0)
+	if (--fp->fi_delegees == 0)
 		swap(filp, fp->fi_deleg_file);
 	spin_unlock(&fp->fi_lock);
 
-	if (filp) {
-		vfs_setlease(filp, F_UNLCK, NULL, (void **)&fp);
+	if (filp)
 		fput(filp);
-	}
+}
+
+static void nfs4_unlock_deleg_lease(struct nfs4_delegation *dp)
+{
+	struct nfs4_file *fp = dp->dl_stid.sc_file;
+	struct file *filp = fp->fi_deleg_file;
+
+	WARN_ON_ONCE(!fp->fi_delegees);
+
+	vfs_setlease(filp, F_UNLCK, NULL, (void **)&dp);
+	put_deleg_file(fp);
+}
+
+static void destroy_unhashed_deleg(struct nfs4_delegation *dp)
+{
+	put_clnt_odstate(dp->dl_clnt_odstate);
+	nfs4_unlock_deleg_lease(dp);
+	nfs4_put_stid(&dp->dl_stid);
 }
 
 void nfs4_unhash_stid(struct nfs4_stid *s)
@@ -895,20 +915,16 @@ void nfs4_unhash_stid(struct nfs4_stid *s)
 }
 
 /**
- * nfs4_get_existing_delegation - Discover if this delegation already exists
+ * nfs4_delegation_exists - Discover if this delegation already exists
  * @clp:     a pointer to the nfs4_client we're granting a delegation to
  * @fp:      a pointer to the nfs4_file we're granting a delegation on
  *
  * Return:
- *      On success: NULL if an existing delegation was not found.
- *
- *      On error: -EAGAIN if one was previously granted to this nfs4_client
- *                 for this nfs4_file.
- *
+ *      On success: true iff an existing delegation is found
  */
 
-static int
-nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp)
+static bool
+nfs4_delegation_exists(struct nfs4_client *clp, struct nfs4_file *fp)
 {
 	struct nfs4_delegation *searchdp = NULL;
 	struct nfs4_client *searchclp = NULL;
@@ -919,10 +935,10 @@ nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp)
 	list_for_each_entry(searchdp, &fp->fi_delegations, dl_perfile) {
 		searchclp = searchdp->dl_stid.sc_client;
 		if (clp == searchclp) {
-			return -EAGAIN;
+			return true;
 		}
 	}
-	return 0;
+	return false;
 }
 
 /**
@@ -941,16 +957,13 @@ nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp)
 static int
 hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
 {
-	int status;
 	struct nfs4_client *clp = dp->dl_stid.sc_client;
 
 	lockdep_assert_held(&state_lock);
 	lockdep_assert_held(&fp->fi_lock);
 
-	status = nfs4_get_existing_delegation(clp, fp);
-	if (status)
-		return status;
-	++fp->fi_delegees;
+	if (nfs4_delegation_exists(clp, fp))
+		return -EAGAIN;
 	refcount_inc(&dp->dl_stid.sc_count);
 	dp->dl_stid.sc_type = NFS4_DELEG_STID;
 	list_add(&dp->dl_perfile, &fp->fi_delegations);
@@ -986,11 +999,8 @@ static void destroy_delegation(struct nfs4_delegation *dp)
 	spin_lock(&state_lock);
 	unhashed = unhash_delegation_locked(dp);
 	spin_unlock(&state_lock);
-	if (unhashed) {
-		put_clnt_odstate(dp->dl_clnt_odstate);
-		nfs4_put_deleg_lease(dp->dl_stid.sc_file);
-		nfs4_put_stid(&dp->dl_stid);
-	}
+	if (unhashed)
+		destroy_unhashed_deleg(dp);
 }
 
 static void revoke_delegation(struct nfs4_delegation *dp)
@@ -999,17 +1009,14 @@ static void revoke_delegation(struct nfs4_delegation *dp)
 
 	WARN_ON(!list_empty(&dp->dl_recall_lru));
 
-	put_clnt_odstate(dp->dl_clnt_odstate);
-	nfs4_put_deleg_lease(dp->dl_stid.sc_file);
-
-	if (clp->cl_minorversion == 0)
-		nfs4_put_stid(&dp->dl_stid);
-	else {
+	if (clp->cl_minorversion) {
 		dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID;
+		refcount_inc(&dp->dl_stid.sc_count);
 		spin_lock(&clp->cl_lock);
 		list_add(&dp->dl_recall_lru, &clp->cl_revoked);
 		spin_unlock(&clp->cl_lock);
 	}
+	destroy_unhashed_deleg(dp);
 }
 
 /* 
@@ -1794,7 +1801,7 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
 	struct nfs4_client *clp;
 	int i;
 
-	clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL);
+	clp = kmem_cache_zalloc(client_slab, GFP_KERNEL);
 	if (clp == NULL)
 		return NULL;
 	clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL);
@@ -1825,7 +1832,7 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
 err_no_hashtbl:
 	kfree(clp->cl_name.data);
 err_no_name:
-	kfree(clp);
+	kmem_cache_free(client_slab, clp);
 	return NULL;
 }
 
@@ -1845,7 +1852,7 @@ free_client(struct nfs4_client *clp)
 	kfree(clp->cl_ownerstr_hashtbl);
 	kfree(clp->cl_name.data);
 	idr_destroy(&clp->cl_stateids);
-	kfree(clp);
+	kmem_cache_free(client_slab, clp);
 }
 
 /* must be called under the client_lock */
@@ -1911,9 +1918,7 @@ __destroy_client(struct nfs4_client *clp)
 	while (!list_empty(&reaplist)) {
 		dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
 		list_del_init(&dp->dl_recall_lru);
-		put_clnt_odstate(dp->dl_clnt_odstate);
-		nfs4_put_deleg_lease(dp->dl_stid.sc_file);
-		nfs4_put_stid(&dp->dl_stid);
+		destroy_unhashed_deleg(dp);
 	}
 	while (!list_empty(&clp->cl_revoked)) {
 		dp = list_entry(clp->cl_revoked.next, struct nfs4_delegation, dl_recall_lru);
@@ -2953,7 +2958,7 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
 static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
 {
 	if (!session)
-		return 0;
+		return false;
 	return !memcmp(sid, &session->se_sessionid, sizeof(*sid));
 }
 
@@ -3471,21 +3476,26 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval,
 void
 nfsd4_free_slabs(void)
 {
-	kmem_cache_destroy(odstate_slab);
+	kmem_cache_destroy(client_slab);
 	kmem_cache_destroy(openowner_slab);
 	kmem_cache_destroy(lockowner_slab);
 	kmem_cache_destroy(file_slab);
 	kmem_cache_destroy(stateid_slab);
 	kmem_cache_destroy(deleg_slab);
+	kmem_cache_destroy(odstate_slab);
 }
 
 int
 nfsd4_init_slabs(void)
 {
+	client_slab = kmem_cache_create("nfsd4_clients",
+			sizeof(struct nfs4_client), 0, 0, NULL);
+	if (client_slab == NULL)
+		goto out;
 	openowner_slab = kmem_cache_create("nfsd4_openowners",
 			sizeof(struct nfs4_openowner), 0, 0, NULL);
 	if (openowner_slab == NULL)
-		goto out;
+		goto out_free_client_slab;
 	lockowner_slab = kmem_cache_create("nfsd4_lockowners",
 			sizeof(struct nfs4_lockowner), 0, 0, NULL);
 	if (lockowner_slab == NULL)
@@ -3518,6 +3528,8 @@ nfsd4_init_slabs(void)
 	kmem_cache_destroy(lockowner_slab);
 out_free_openowner_slab:
 	kmem_cache_destroy(openowner_slab);
+out_free_client_slab:
+	kmem_cache_destroy(client_slab);
 out:
 	dprintk("nfsd4: out of memory while initializing nfsv4\n");
 	return -ENOMEM;
@@ -3945,17 +3957,9 @@ static bool
 nfsd_break_deleg_cb(struct file_lock *fl)
 {
 	bool ret = false;
-	struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
-	struct nfs4_delegation *dp;
+	struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
+	struct nfs4_file *fp = dp->dl_stid.sc_file;
 
-	if (!fp) {
-		WARN(1, "(%p)->fl_owner NULL\n", fl);
-		return ret;
-	}
-	if (fp->fi_had_conflict) {
-		WARN(1, "duplicate break on %p\n", fp);
-		return ret;
-	}
 	/*
 	 * We don't want the locks code to timeout the lease for us;
 	 * we'll remove it ourself if a delegation isn't returned
@@ -3965,15 +3969,7 @@ nfsd_break_deleg_cb(struct file_lock *fl)
 
 	spin_lock(&fp->fi_lock);
 	fp->fi_had_conflict = true;
-	/*
-	 * If there are no delegations on the list, then return true
-	 * so that the lease code will go ahead and delete it.
-	 */
-	if (list_empty(&fp->fi_delegations))
-		ret = true;
-	else
-		list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
-			nfsd_break_one_deleg(dp);
+	nfsd_break_one_deleg(dp);
 	spin_unlock(&fp->fi_lock);
 	return ret;
 }
@@ -4297,7 +4293,8 @@ static bool nfsd4_cb_channel_good(struct nfs4_client *clp)
 	return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN;
 }
 
-static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
+static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp,
+						int flag)
 {
 	struct file_lock *fl;
 
@@ -4308,124 +4305,88 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
 	fl->fl_flags = FL_DELEG;
 	fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
 	fl->fl_end = OFFSET_MAX;
-	fl->fl_owner = (fl_owner_t)fp;
+	fl->fl_owner = (fl_owner_t)dp;
 	fl->fl_pid = current->tgid;
+	fl->fl_file = dp->dl_stid.sc_file->fi_deleg_file;
 	return fl;
 }
 
-/**
- * nfs4_setlease - Obtain a delegation by requesting lease from vfs layer
- * @dp:   a pointer to the nfs4_delegation we're adding.
- *
- * Return:
- *      On success: Return code will be 0 on success.
- *
- *      On error: -EAGAIN if there was an existing delegation.
- *                 nonzero if there is an error in other cases.
- *
- */
-
-static int nfs4_setlease(struct nfs4_delegation *dp)
-{
-	struct nfs4_file *fp = dp->dl_stid.sc_file;
-	struct file_lock *fl;
-	struct file *filp;
-	int status = 0;
-
-	fl = nfs4_alloc_init_lease(fp, NFS4_OPEN_DELEGATE_READ);
-	if (!fl)
-		return -ENOMEM;
-	filp = find_readable_file(fp);
-	if (!filp) {
-		/* We should always have a readable file here */
-		WARN_ON_ONCE(1);
-		locks_free_lock(fl);
-		return -EBADF;
-	}
-	fl->fl_file = filp;
-	status = vfs_setlease(filp, fl->fl_type, &fl, NULL);
-	if (fl)
-		locks_free_lock(fl);
-	if (status)
-		goto out_fput;
-	spin_lock(&state_lock);
-	spin_lock(&fp->fi_lock);
-	/* Did the lease get broken before we took the lock? */
-	status = -EAGAIN;
-	if (fp->fi_had_conflict)
-		goto out_unlock;
-	/* Race breaker */
-	if (fp->fi_deleg_file) {
-		status = hash_delegation_locked(dp, fp);
-		goto out_unlock;
-	}
-	fp->fi_deleg_file = filp;
-	fp->fi_delegees = 0;
-	status = hash_delegation_locked(dp, fp);
-	spin_unlock(&fp->fi_lock);
-	spin_unlock(&state_lock);
-	if (status) {
-		/* Should never happen, this is a new fi_deleg_file  */
-		WARN_ON_ONCE(1);
-		goto out_fput;
-	}
-	return 0;
-out_unlock:
-	spin_unlock(&fp->fi_lock);
-	spin_unlock(&state_lock);
-out_fput:
-	fput(filp);
-	return status;
-}
-
 static struct nfs4_delegation *
 nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
 		    struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate)
 {
-	int status;
+	int status = 0;
 	struct nfs4_delegation *dp;
+	struct file *filp;
+	struct file_lock *fl;
 
+	/*
+	 * The fi_had_conflict and nfs_get_existing_delegation checks
+	 * here are just optimizations; we'll need to recheck them at
+	 * the end:
+	 */
 	if (fp->fi_had_conflict)
 		return ERR_PTR(-EAGAIN);
 
+	filp = find_readable_file(fp);
+	if (!filp) {
+		/* We should always have a readable file here */
+		WARN_ON_ONCE(1);
+		return ERR_PTR(-EBADF);
+	}
 	spin_lock(&state_lock);
 	spin_lock(&fp->fi_lock);
-	status = nfs4_get_existing_delegation(clp, fp);
+	if (nfs4_delegation_exists(clp, fp))
+		status = -EAGAIN;
+	else if (!fp->fi_deleg_file) {
+		fp->fi_deleg_file = filp;
+		/* increment early to prevent fi_deleg_file from being
+		 * cleared */
+		fp->fi_delegees = 1;
+		filp = NULL;
+	} else
+		fp->fi_delegees++;
+	spin_unlock(&fp->fi_lock);
+	spin_unlock(&state_lock);
+	if (filp)
+		fput(filp);
+	if (status)
+		return ERR_PTR(status);
+
+	status = -ENOMEM;
+	dp = alloc_init_deleg(clp, fp, fh, odstate);
+	if (!dp)
+		goto out_delegees;
+
+	fl = nfs4_alloc_init_lease(dp, NFS4_OPEN_DELEGATE_READ);
+	if (!fl)
+		goto out_stid;
+
+	status = vfs_setlease(fp->fi_deleg_file, fl->fl_type, &fl, NULL);
+	if (fl)
+		locks_free_lock(fl);
+	if (status)
+		goto out_clnt_odstate;
+
+	spin_lock(&state_lock);
+	spin_lock(&fp->fi_lock);
+	if (fp->fi_had_conflict)
+		status = -EAGAIN;
+	else
+		status = hash_delegation_locked(dp, fp);
 	spin_unlock(&fp->fi_lock);
 	spin_unlock(&state_lock);
 
 	if (status)
-		return ERR_PTR(status);
-
-	dp = alloc_init_deleg(clp, fh, odstate);
-	if (!dp)
-		return ERR_PTR(-ENOMEM);
-
-	get_nfs4_file(fp);
-	spin_lock(&state_lock);
-	spin_lock(&fp->fi_lock);
-	dp->dl_stid.sc_file = fp;
-	if (!fp->fi_deleg_file) {
-		spin_unlock(&fp->fi_lock);
-		spin_unlock(&state_lock);
-		status = nfs4_setlease(dp);
-		goto out;
-	}
-	if (fp->fi_had_conflict) {
-		status = -EAGAIN;
-		goto out_unlock;
-	}
-	status = hash_delegation_locked(dp, fp);
-out_unlock:
-	spin_unlock(&fp->fi_lock);
-	spin_unlock(&state_lock);
-out:
-	if (status) {
-		put_clnt_odstate(dp->dl_clnt_odstate);
-		nfs4_put_stid(&dp->dl_stid);
-		return ERR_PTR(status);
-	}
+		destroy_unhashed_deleg(dp);
 	return dp;
+out_clnt_odstate:
+	put_clnt_odstate(dp->dl_clnt_odstate);
+out_stid:
+	nfs4_put_stid(&dp->dl_stid);
+out_delegees:
+	put_deleg_file(fp);
+	return ERR_PTR(status);
 }
 
 static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
@@ -5521,15 +5482,26 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		goto out; 
 
 	stp->st_stid.sc_type = NFS4_CLOSED_STID;
+
+	/*
+	 * Technically we don't _really_ have to increment or copy it, since
+	 * it should just be gone after this operation and we clobber the
+	 * copied value below, but we continue to do so here just to ensure
+	 * that racing ops see that there was a state change.
+	 */
 	nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
 
 	nfsd4_close_open_stateid(stp);
 	mutex_unlock(&stp->st_mutex);
 
-	/* See RFC5661 sectionm 18.2.4 */
-	if (stp->st_stid.sc_client->cl_minorversion)
-		memcpy(&close->cl_stateid, &close_stateid,
-				sizeof(close->cl_stateid));
+	/* v4.1+ suggests that we send a special stateid in here, since the
+	 * clients should just ignore this anyway. Since this is not useful
+	 * for v4.0 clients either, we set it to the special close_stateid
+	 * universally.
+	 *
+	 * See RFC5661 section 18.2.4, and RFC7530 section 16.2.5
+	 */
+	memcpy(&close->cl_stateid, &close_stateid, sizeof(close->cl_stateid));
 
 	/* put reference from nfs4_preprocess_seqid_op */
 	nfs4_put_stid(&stp->st_stid);
@@ -7264,9 +7236,7 @@ nfs4_state_shutdown_net(struct net *net)
 	list_for_each_safe(pos, next, &reaplist) {
 		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
 		list_del_init(&dp->dl_recall_lru);
-		put_clnt_odstate(dp->dl_clnt_odstate);
-		nfs4_put_deleg_lease(dp->dl_stid.sc_file);
-		nfs4_put_stid(&dp->dl_stid);
+		destroy_unhashed_deleg(dp);
 	}
 
 	nfsd4_client_tracking_exit(net);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index e502fd1..1d048dd 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -33,7 +33,6 @@
  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <linux/fs_struct.h>
 #include <linux/file.h>
 #include <linux/slab.h>
 #include <linux/namei.h>
@@ -682,7 +681,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
 
 	status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
 				    &create->cr_acl, &create->cr_label,
-				    &current->fs->umask);
+				    &create->cr_umask);
 	if (status)
 		goto out;
 
@@ -927,7 +926,6 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 	case NFS4_OPEN_NOCREATE:
 		break;
 	case NFS4_OPEN_CREATE:
-		current->fs->umask = 0;
 		READ_BUF(4);
 		open->op_createmode = be32_to_cpup(p++);
 		switch (open->op_createmode) {
@@ -935,7 +933,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 		case NFS4_CREATE_GUARDED:
 			status = nfsd4_decode_fattr(argp, open->op_bmval,
 				&open->op_iattr, &open->op_acl, &open->op_label,
-				&current->fs->umask);
+				&open->op_umask);
 			if (status)
 				goto out;
 			break;
@@ -950,7 +948,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
 			status = nfsd4_decode_fattr(argp, open->op_bmval,
 				&open->op_iattr, &open->op_acl, &open->op_label,
-				&current->fs->umask);
+				&open->op_umask);
 			if (status)
 				goto out;
 			break;
@@ -1759,7 +1757,7 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 	p = xdr_decode_hyper(p, &copy->cp_src_pos);
 	p = xdr_decode_hyper(p, &copy->cp_dst_pos);
 	p = xdr_decode_hyper(p, &copy->cp_count);
-	copy->cp_consecutive = be32_to_cpup(p++);
+	p++; /* ca_consecutive: we always do consecutive copies */
 	copy->cp_synchronous = be32_to_cpup(p++);
 	tmp = be32_to_cpup(p); /* Source server list not supported */
 
@@ -3427,8 +3425,9 @@ static __be32 nfsd4_encode_splice_read(
 		return nfserr_resource;
 
 	len = maxcount;
-	nfserr = nfsd_splice_read(read->rd_rqstp, file,
-				  read->rd_offset, &maxcount);
+	nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
+				  file, read->rd_offset, &maxcount);
+	read->rd_length = maxcount;
 	if (nfserr) {
 		/*
 		 * nfsd_splice_actor may have already messed with the
@@ -3511,8 +3510,9 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
 	read->rd_vlen = v;
 
 	len = maxcount;
-	nfserr = nfsd_readv(file, read->rd_offset, resp->rqstp->rq_vec,
-			read->rd_vlen, &maxcount);
+	nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
+			    resp->rqstp->rq_vec, read->rd_vlen, &maxcount);
+	read->rd_length = maxcount;
 	if (nfserr)
 		return nfserr;
 	xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3));
@@ -4214,7 +4214,7 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
 		return nfserr;
 
 	p = xdr_reserve_space(&resp->xdr, 4 + 4);
-	*p++ = cpu_to_be32(copy->cp_consecutive);
+	*p++ = xdr_one; /* cr_consecutive */
 	*p++ = cpu_to_be32(copy->cp_synchronous);
 	return 0;
 }
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 8aa0118..a008e76 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -87,13 +87,23 @@ nfsd_mode_check(struct svc_rqst *rqstp, struct dentry *dentry,
 	return nfserr_inval;
 }
 
+static bool nfsd_originating_port_ok(struct svc_rqst *rqstp, int flags)
+{
+	if (flags & NFSEXP_INSECURE_PORT)
+		return true;
+	/* We don't require gss requests to use low ports: */
+	if (rqstp->rq_cred.cr_flavor >= RPC_AUTH_GSS)
+		return true;
+	return test_bit(RQ_SECURE, &rqstp->rq_flags);
+}
+
 static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
 					  struct svc_export *exp)
 {
 	int flags = nfsexp_flags(rqstp, exp);
 
 	/* Check if the request originated from a secure port. */
-	if (!test_bit(RQ_SECURE, &rqstp->rq_flags) && !(flags & NFSEXP_INSECURE_PORT)) {
+	if (!nfsd_originating_port_ok(rqstp, flags)) {
 		RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
 		dprintk("nfsd: request from insecure port %s!\n",
 		        svc_print_addr(rqstp, buf, sizeof(buf)));
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 43c0419..f107f9f 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -212,13 +212,18 @@ nfsd_proc_write(struct svc_rqst *rqstp)
 	struct nfsd_attrstat *resp = rqstp->rq_resp;
 	__be32	nfserr;
 	unsigned long cnt = argp->len;
+	unsigned int nvecs;
 
 	dprintk("nfsd: WRITE    %s %d bytes at %d\n",
 		SVCFH_fmt(&argp->fh),
 		argp->len, argp->offset);
 
-	nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh), argp->offset,
-				rqstp->rq_vec, argp->vlen, &cnt, NFS_DATA_SYNC);
+	nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
+	if (!nvecs)
+		return nfserr_io;
+	nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh),
+			    argp->offset, rqstp->rq_vec, nvecs,
+			    &cnt, NFS_DATA_SYNC);
 	return nfsd_return_attrs(nfserr, resp);
 }
 
@@ -444,17 +449,19 @@ nfsd_proc_symlink(struct svc_rqst *rqstp)
 	struct svc_fh	newfh;
 	__be32		nfserr;
 
+	if (argp->tlen > NFS_MAXPATHLEN)
+		return nfserr_nametoolong;
+
+	argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first,
+						argp->tlen);
+	if (IS_ERR(argp->tname))
+		return nfserrno(PTR_ERR(argp->tname));
+
 	dprintk("nfsd: SYMLINK  %s %.*s -> %.*s\n",
 		SVCFH_fmt(&argp->ffh), argp->flen, argp->fname,
 		argp->tlen, argp->tname);
 
 	fh_init(&newfh, NFS_FHSIZE);
-	/*
-	 * Crazy hack: the request fits in a page, and already-decoded
-	 * attributes follow argp->tname, so it's safe to just write a
-	 * null to ensure it's null-terminated:
-	 */
-	argp->tname[argp->tlen] = '\0';
 	nfserr = nfsd_symlink(rqstp, &argp->ffh, argp->fname, argp->flen,
 						 argp->tname, &newfh);
 
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 79b6064..a43e826 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -71,22 +71,6 @@ decode_filename(__be32 *p, char **namp, unsigned int *lenp)
 }
 
 static __be32 *
-decode_pathname(__be32 *p, char **namp, unsigned int *lenp)
-{
-	char		*name;
-	unsigned int	i;
-
-	if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS_MAXPATHLEN)) != NULL) {
-		for (i = 0, name = *namp; i < *lenp; i++, name++) {
-			if (*name == '\0')
-				return NULL;
-		}
-	}
-
-	return p;
-}
-
-static __be32 *
 decode_sattr(__be32 *p, struct iattr *iap)
 {
 	u32	tmp, tmp1;
@@ -287,7 +271,6 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 	struct nfsd_writeargs *args = rqstp->rq_argp;
 	unsigned int len, hdr, dlen;
 	struct kvec *head = rqstp->rq_arg.head;
-	int v;
 
 	p = decode_fh(p, &args->fh);
 	if (!p)
@@ -323,17 +306,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 	if (dlen < XDR_QUADLEN(len)*4)
 		return 0;
 
-	rqstp->rq_vec[0].iov_base = (void*)p;
-	rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
-	v = 0;
-	while (len > rqstp->rq_vec[v].iov_len) {
-		len -= rqstp->rq_vec[v].iov_len;
-		v++;
-		rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
-		rqstp->rq_vec[v].iov_len = PAGE_SIZE;
-	}
-	rqstp->rq_vec[v].iov_len = len;
-	args->vlen = v + 1;
+	args->first.iov_base = (void *)p;
+	args->first.iov_len = head->iov_len - hdr;
 	return 1;
 }
 
@@ -394,14 +368,39 @@ int
 nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd_symlinkargs *args = rqstp->rq_argp;
+	char *base = (char *)p;
+	size_t xdrlen;
 
 	if (   !(p = decode_fh(p, &args->ffh))
-	    || !(p = decode_filename(p, &args->fname, &args->flen))
-	    || !(p = decode_pathname(p, &args->tname, &args->tlen)))
+	    || !(p = decode_filename(p, &args->fname, &args->flen)))
 		return 0;
-	p = decode_sattr(p, &args->attrs);
 
-	return xdr_argsize_check(rqstp, p);
+	args->tlen = ntohl(*p++);
+	if (args->tlen == 0)
+		return 0;
+
+	args->first.iov_base = p;
+	args->first.iov_len = rqstp->rq_arg.head[0].iov_len;
+	args->first.iov_len -= (char *)p - base;
+
+	/* This request is never larger than a page. Therefore,
+	 * transport will deliver either:
+	 * 1. pathname in the pagelist -> sattr is in the tail.
+	 * 2. everything in the head buffer -> sattr is in the head.
+	 */
+	if (rqstp->rq_arg.page_len) {
+		if (args->tlen != rqstp->rq_arg.page_len)
+			return 0;
+		p = rqstp->rq_arg.tail[0].iov_base;
+	} else {
+		xdrlen = XDR_QUADLEN(args->tlen);
+		if (xdrlen > args->first.iov_len - (8 * sizeof(__be32)))
+			return 0;
+		p += xdrlen;
+	}
+	decode_sattr(p, &args->attrs);
+
+	return 1;
 }
 
 int
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 8b2f1d9..80933e4 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -11,39 +11,79 @@
 #include <linux/tracepoint.h>
 #include "nfsfh.h"
 
+TRACE_EVENT(nfsd_compound,
+	TP_PROTO(const struct svc_rqst *rqst,
+		 u32 args_opcnt),
+	TP_ARGS(rqst, args_opcnt),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, args_opcnt)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqst->rq_xid);
+		__entry->args_opcnt = args_opcnt;
+	),
+	TP_printk("xid=0x%08x opcnt=%u",
+		__entry->xid, __entry->args_opcnt)
+)
+
+TRACE_EVENT(nfsd_compound_status,
+	TP_PROTO(u32 args_opcnt,
+		 u32 resp_opcnt,
+		 __be32 status,
+		 const char *name),
+	TP_ARGS(args_opcnt, resp_opcnt, status, name),
+	TP_STRUCT__entry(
+		__field(u32, args_opcnt)
+		__field(u32, resp_opcnt)
+		__field(int, status)
+		__string(name, name)
+	),
+	TP_fast_assign(
+		__entry->args_opcnt = args_opcnt;
+		__entry->resp_opcnt = resp_opcnt;
+		__entry->status = be32_to_cpu(status);
+		__assign_str(name, name);
+	),
+	TP_printk("op=%u/%u %s status=%d",
+		__entry->resp_opcnt, __entry->args_opcnt,
+		__get_str(name), __entry->status)
+)
+
 DECLARE_EVENT_CLASS(nfsd_io_class,
 	TP_PROTO(struct svc_rqst *rqstp,
 		 struct svc_fh	*fhp,
 		 loff_t		offset,
-		 int		len),
+		 unsigned long	len),
 	TP_ARGS(rqstp, fhp, offset, len),
 	TP_STRUCT__entry(
-		__field(__be32, xid)
-		__field_struct(struct knfsd_fh, fh)
+		__field(u32, xid)
+		__field(u32, fh_hash)
 		__field(loff_t, offset)
-		__field(int, len)
+		__field(unsigned long, len)
 	),
 	TP_fast_assign(
-		__entry->xid = rqstp->rq_xid,
-		fh_copy_shallow(&__entry->fh, &fhp->fh_handle);
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->fh_hash = knfsd_fh_hash(&fhp->fh_handle);
 		__entry->offset = offset;
 		__entry->len = len;
 	),
-	TP_printk("xid=0x%x fh=0x%x offset=%lld len=%d",
-		  __be32_to_cpu(__entry->xid), knfsd_fh_hash(&__entry->fh),
+	TP_printk("xid=0x%08x fh_hash=0x%08x offset=%lld len=%lu",
+		  __entry->xid, __entry->fh_hash,
 		  __entry->offset, __entry->len)
 )
 
 #define DEFINE_NFSD_IO_EVENT(name)		\
-DEFINE_EVENT(nfsd_io_class, name,		\
+DEFINE_EVENT(nfsd_io_class, nfsd_##name,	\
 	TP_PROTO(struct svc_rqst *rqstp,	\
 		 struct svc_fh	*fhp,		\
 		 loff_t		offset,		\
-		 int		len),		\
+		 unsigned long	len),		\
 	TP_ARGS(rqstp, fhp, offset, len))
 
 DEFINE_NFSD_IO_EVENT(read_start);
-DEFINE_NFSD_IO_EVENT(read_opened);
+DEFINE_NFSD_IO_EVENT(read_splice);
+DEFINE_NFSD_IO_EVENT(read_vector);
 DEFINE_NFSD_IO_EVENT(read_io_done);
 DEFINE_NFSD_IO_EVENT(read_done);
 DEFINE_NFSD_IO_EVENT(write_start);
@@ -51,6 +91,40 @@ DEFINE_NFSD_IO_EVENT(write_opened);
 DEFINE_NFSD_IO_EVENT(write_io_done);
 DEFINE_NFSD_IO_EVENT(write_done);
 
+DECLARE_EVENT_CLASS(nfsd_err_class,
+	TP_PROTO(struct svc_rqst *rqstp,
+		 struct svc_fh	*fhp,
+		 loff_t		offset,
+		 int		status),
+	TP_ARGS(rqstp, fhp, offset, status),
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, fh_hash)
+		__field(loff_t, offset)
+		__field(int, status)
+	),
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqstp->rq_xid);
+		__entry->fh_hash = knfsd_fh_hash(&fhp->fh_handle);
+		__entry->offset = offset;
+		__entry->status = status;
+	),
+	TP_printk("xid=0x%08x fh_hash=0x%08x offset=%lld status=%d",
+		  __entry->xid, __entry->fh_hash,
+		  __entry->offset, __entry->status)
+)
+
+#define DEFINE_NFSD_ERR_EVENT(name)		\
+DEFINE_EVENT(nfsd_err_class, nfsd_##name,	\
+	TP_PROTO(struct svc_rqst *rqstp,	\
+		 struct svc_fh	*fhp,		\
+		 loff_t		offset,		\
+		 int		len),		\
+	TP_ARGS(rqstp, fhp, offset, len))
+
+DEFINE_NFSD_ERR_EVENT(read_err);
+DEFINE_NFSD_ERR_EVENT(write_err);
+
 #include "state.h"
 
 DECLARE_EVENT_CLASS(nfsd_stateid_class,
@@ -76,7 +150,7 @@ DECLARE_EVENT_CLASS(nfsd_stateid_class,
 )
 
 #define DEFINE_STATEID_EVENT(name) \
-DEFINE_EVENT(nfsd_stateid_class, name, \
+DEFINE_EVENT(nfsd_stateid_class, nfsd_##name, \
 	TP_PROTO(stateid_t *stp), \
 	TP_ARGS(stp))
 DEFINE_STATEID_EVENT(layoutstate_alloc);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index a3c9bfa..2410b09 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -881,20 +881,24 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
 	return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
 }
 
-static __be32
-nfsd_finish_read(struct file *file, unsigned long *count, int host_err)
+static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
+			       struct file *file, loff_t offset,
+			       unsigned long *count, int host_err)
 {
 	if (host_err >= 0) {
 		nfsdstats.io_read += host_err;
 		*count = host_err;
 		fsnotify_access(file);
+		trace_nfsd_read_io_done(rqstp, fhp, offset, *count);
 		return 0;
-	} else 
+	} else {
+		trace_nfsd_read_err(rqstp, fhp, offset, host_err);
 		return nfserrno(host_err);
+	}
 }
 
-__be32 nfsd_splice_read(struct svc_rqst *rqstp,
-		     struct file *file, loff_t offset, unsigned long *count)
+__be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
+			struct file *file, loff_t offset, unsigned long *count)
 {
 	struct splice_desc sd = {
 		.len		= 0,
@@ -904,21 +908,23 @@ __be32 nfsd_splice_read(struct svc_rqst *rqstp,
 	};
 	int host_err;
 
+	trace_nfsd_read_splice(rqstp, fhp, offset, *count);
 	rqstp->rq_next_page = rqstp->rq_respages + 1;
 	host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
-	return nfsd_finish_read(file, count, host_err);
+	return nfsd_finish_read(rqstp, fhp, file, offset, count, host_err);
 }
 
-__be32 nfsd_readv(struct file *file, loff_t offset, struct kvec *vec, int vlen,
-		unsigned long *count)
+__be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp,
+		  struct file *file, loff_t offset,
+		  struct kvec *vec, int vlen, unsigned long *count)
 {
 	struct iov_iter iter;
 	int host_err;
 
+	trace_nfsd_read_vector(rqstp, fhp, offset, *count);
 	iov_iter_kvec(&iter, READ | ITER_KVEC, vec, vlen, *count);
 	host_err = vfs_iter_read(file, &iter, &offset, 0);
-
-	return nfsd_finish_read(file, count, host_err);
+	return nfsd_finish_read(rqstp, fhp, file, offset, count, host_err);
 }
 
 /*
@@ -965,13 +971,15 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 {
 	struct svc_export	*exp;
 	struct iov_iter		iter;
-	__be32			err = 0;
+	__be32			nfserr;
 	int			host_err;
 	int			use_wgather;
 	loff_t			pos = offset;
 	unsigned int		pflags = current->flags;
 	rwf_t			flags = 0;
 
+	trace_nfsd_write_opened(rqstp, fhp, offset, *cnt);
+
 	if (test_bit(RQ_LOCAL, &rqstp->rq_flags))
 		/*
 		 * We want less throttling in balance_dirty_pages()
@@ -994,22 +1002,23 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 	host_err = vfs_iter_write(file, &iter, &pos, flags);
 	if (host_err < 0)
 		goto out_nfserr;
-	*cnt = host_err;
-	nfsdstats.io_write += host_err;
+	nfsdstats.io_write += *cnt;
 	fsnotify_modify(file);
 
 	if (stable && use_wgather)
 		host_err = wait_for_concurrent_writes(file);
 
 out_nfserr:
-	dprintk("nfsd: write complete host_err=%d\n", host_err);
-	if (host_err >= 0)
-		err = 0;
-	else
-		err = nfserrno(host_err);
+	if (host_err >= 0) {
+		trace_nfsd_write_io_done(rqstp, fhp, offset, *cnt);
+		nfserr = nfs_ok;
+	} else {
+		trace_nfsd_write_err(rqstp, fhp, offset, host_err);
+		nfserr = nfserrno(host_err);
+	}
 	if (test_bit(RQ_LOCAL, &rqstp->rq_flags))
 		current_restore_flags(pflags, PF_LESS_THROTTLE);
-	return err;
+	return nfserr;
 }
 
 /*
@@ -1024,27 +1033,23 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
 	struct raparms	*ra;
 	__be32 err;
 
-	trace_read_start(rqstp, fhp, offset, vlen);
+	trace_nfsd_read_start(rqstp, fhp, offset, *count);
 	err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
 	if (err)
 		return err;
 
 	ra = nfsd_init_raparms(file);
 
-	trace_read_opened(rqstp, fhp, offset, vlen);
-
 	if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &rqstp->rq_flags))
-		err = nfsd_splice_read(rqstp, file, offset, count);
+		err = nfsd_splice_read(rqstp, fhp, file, offset, count);
 	else
-		err = nfsd_readv(file, offset, vec, vlen, count);
-
-	trace_read_io_done(rqstp, fhp, offset, vlen);
+		err = nfsd_readv(rqstp, fhp, file, offset, vec, vlen, count);
 
 	if (ra)
 		nfsd_put_raparams(file, ra);
 	fput(file);
 
-	trace_read_done(rqstp, fhp, offset, vlen);
+	trace_nfsd_read_done(rqstp, fhp, offset, *count);
 
 	return err;
 }
@@ -1061,18 +1066,16 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
 	struct file *file = NULL;
 	__be32 err = 0;
 
-	trace_write_start(rqstp, fhp, offset, vlen);
+	trace_nfsd_write_start(rqstp, fhp, offset, *cnt);
 
 	err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file);
 	if (err)
 		goto out;
 
-	trace_write_opened(rqstp, fhp, offset, vlen);
 	err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, cnt, stable);
-	trace_write_io_done(rqstp, fhp, offset, vlen);
 	fput(file);
 out:
-	trace_write_done(rqstp, fhp, offset, vlen);
+	trace_nfsd_write_done(rqstp, fhp, offset, *cnt);
 	return err;
 }
 
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index be6d8e0..a7e1073 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -78,10 +78,13 @@ __be32		nfsd_commit(struct svc_rqst *, struct svc_fh *,
 __be32		nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
 				int, struct file **);
 struct raparms;
-__be32		nfsd_splice_read(struct svc_rqst *,
-				struct file *, loff_t, unsigned long *);
-__be32		nfsd_readv(struct file *, loff_t, struct kvec *, int,
-				unsigned long *);
+__be32		nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
+				struct file *file, loff_t offset,
+				unsigned long *count);
+__be32		nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp,
+				struct file *file, loff_t offset,
+				struct kvec *vec, int vlen,
+				unsigned long *count);
 __be32 		nfsd_read(struct svc_rqst *, struct svc_fh *,
 				loff_t, struct kvec *, int, unsigned long *);
 __be32 		nfsd_write(struct svc_rqst *, struct svc_fh *, loff_t,
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h
index 2f4f22e..ea7cca3 100644
--- a/fs/nfsd/xdr.h
+++ b/fs/nfsd/xdr.h
@@ -34,7 +34,7 @@ struct nfsd_writeargs {
 	svc_fh			fh;
 	__u32			offset;
 	int			len;
-	int			vlen;
+	struct kvec		first;
 };
 
 struct nfsd_createargs {
@@ -72,6 +72,7 @@ struct nfsd_symlinkargs {
 	char *			tname;
 	unsigned int		tlen;
 	struct iattr		attrs;
+	struct kvec		first;
 };
 
 struct nfsd_readdirargs {
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 056bf8a..2cb29e9 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -41,7 +41,7 @@ struct nfsd3_writeargs {
 	__u32			count;
 	int			stable;
 	__u32			len;
-	int			vlen;
+	struct kvec		first;
 };
 
 struct nfsd3_createargs {
@@ -90,6 +90,7 @@ struct nfsd3_symlinkargs {
 	char *			tname;
 	unsigned int		tlen;
 	struct iattr		attrs;
+	struct kvec		first;
 };
 
 struct nfsd3_readdirargs {
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index bc29511..17c453a 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -110,6 +110,7 @@ struct nfsd4_create {
 		struct {
 			u32 datalen;
 			char *data;
+			struct kvec first;
 		} link;   /* NF4LNK */
 		struct {
 			u32 specdata1;
@@ -118,12 +119,14 @@ struct nfsd4_create {
 	} u;
 	u32		cr_bmval[3];        /* request */
 	struct iattr	cr_iattr;           /* request */
+	int		cr_umask;           /* request */
 	struct nfsd4_change_info  cr_cinfo; /* response */
 	struct nfs4_acl *cr_acl;
 	struct xdr_netobj cr_label;
 };
 #define cr_datalen	u.link.datalen
 #define cr_data		u.link.data
+#define cr_first	u.link.first
 #define cr_specdata1	u.dev.specdata1
 #define cr_specdata2	u.dev.specdata2
 
@@ -228,6 +231,7 @@ struct nfsd4_open {
 	u32		op_why_no_deleg;    /* response - DELEG_NONE_EXT only */
 	u32		op_create;     	    /* request */
 	u32		op_createmode;      /* request */
+	int		op_umask;           /* request */
 	u32		op_bmval[3];        /* request */
 	struct iattr	op_iattr;           /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
 	nfs4_verifier	op_verf __attribute__((aligned(32)));
@@ -518,7 +522,6 @@ struct nfsd4_copy {
 	u64		cp_count;
 
 	/* both */
-	bool		cp_consecutive;
 	bool		cp_synchronous;
 
 	/* response */
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 6702a6a..d51e1bb 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -139,23 +139,32 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
 	return false;
 }
 
-struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask,
+struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
+						 struct inode *inode, u32 mask,
 						 const struct path *path)
 {
 	struct fanotify_event_info *event;
+	gfp_t gfp = GFP_KERNEL;
+
+	/*
+	 * For queues with unlimited length lost events are not expected and
+	 * can possibly have security implications. Avoid losing events when
+	 * memory is short.
+	 */
+	if (group->max_events == UINT_MAX)
+		gfp |= __GFP_NOFAIL;
 
 	if (fanotify_is_perm_event(mask)) {
 		struct fanotify_perm_event_info *pevent;
 
-		pevent = kmem_cache_alloc(fanotify_perm_event_cachep,
-					  GFP_KERNEL);
+		pevent = kmem_cache_alloc(fanotify_perm_event_cachep, gfp);
 		if (!pevent)
 			return NULL;
 		event = &pevent->fae;
 		pevent->response = 0;
 		goto init;
 	}
-	event = kmem_cache_alloc(fanotify_event_cachep, GFP_KERNEL);
+	event = kmem_cache_alloc(fanotify_event_cachep, gfp);
 	if (!event)
 		return NULL;
 init: __maybe_unused
@@ -210,10 +219,17 @@ static int fanotify_handle_event(struct fsnotify_group *group,
 			return 0;
 	}
 
-	event = fanotify_alloc_event(inode, mask, data);
+	event = fanotify_alloc_event(group, inode, mask, data);
 	ret = -ENOMEM;
-	if (unlikely(!event))
+	if (unlikely(!event)) {
+		/*
+		 * We don't queue overflow events for permission events as
+		 * there the access is denied and so no event is in fact lost.
+		 */
+		if (!fanotify_is_perm_event(mask))
+			fsnotify_queue_overflow(group);
 		goto finish;
+	}
 
 	fsn_event = &event->fse;
 	ret = fsnotify_add_event(group, fsn_event, fanotify_merge);
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h
index 256d9d1..8609ba0 100644
--- a/fs/notify/fanotify/fanotify.h
+++ b/fs/notify/fanotify/fanotify.h
@@ -52,5 +52,6 @@ static inline struct fanotify_event_info *FANOTIFY_E(struct fsnotify_event *fse)
 	return container_of(fse, struct fanotify_event_info, fse);
 }
 
-struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask,
+struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
+						 struct inode *inode, u32 mask,
 						 const struct path *path);
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index fa803a5..ec4d8c5 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -757,7 +757,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 	group->fanotify_data.user = user;
 	atomic_inc(&user->fanotify_listeners);
 
-	oevent = fanotify_alloc_event(NULL, FS_Q_OVERFLOW, NULL);
+	oevent = fanotify_alloc_event(group, NULL, FS_Q_OVERFLOW, NULL);
 	if (unlikely(!oevent)) {
 		fd = -ENOMEM;
 		goto out_destroy_group;
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 8b73332..40dedb3 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -99,8 +99,14 @@ int inotify_handle_event(struct fsnotify_group *group,
 			      fsn_mark);
 
 	event = kmalloc(alloc_len, GFP_KERNEL);
-	if (unlikely(!event))
+	if (unlikely(!event)) {
+		/*
+		 * Treat lost event due to ENOMEM the same way as queue
+		 * overflow to let userspace know event was lost.
+		 */
+		fsnotify_queue_overflow(group);
 		return -ENOMEM;
+	}
 
 	fsn_event = &event->fse;
 	fsnotify_init_event(fsn_event, inode, mask);
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 43c2365..ef32f36 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -307,6 +307,20 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
 		spin_unlock(&group->notification_lock);
 		ret = put_user(send_len, (int __user *) p);
 		break;
+#ifdef CONFIG_CHECKPOINT_RESTORE
+	case INOTIFY_IOC_SETNEXTWD:
+		ret = -EINVAL;
+		if (arg >= 1 && arg <= INT_MAX) {
+			struct inotify_group_private_data *data;
+
+			data = &group->inotify_data;
+			spin_lock(&data->idr_lock);
+			idr_set_cursor(&data->idr, (unsigned int)arg);
+			spin_unlock(&data->idr_lock);
+			ret = 0;
+		}
+		break;
+#endif /* CONFIG_CHECKPOINT_RESTORE */
 	}
 
 	return ret;
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index 66f85c6..3c3e367 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -111,7 +111,8 @@ int fsnotify_add_event(struct fsnotify_group *group,
 		return 2;
 	}
 
-	if (group->q_len >= group->max_events) {
+	if (event == group->overflow_event ||
+	    group->q_len >= group->max_events) {
 		ret = 2;
 		/* Queue overflow event only if it isn't already queued */
 		if (!list_empty(&group->overflow_event->list)) {
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 2831f49..32c523c 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -381,7 +381,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
  * vfs inode dirty.  This ensures that any changes to the mft record are
  * written out to disk.
  *
- * NOTE:  We only set I_DIRTY_SYNC and I_DIRTY_DATASYNC (and not I_DIRTY_PAGES)
+ * NOTE:  We only set I_DIRTY_DATASYNC (and not I_DIRTY_PAGES)
  * on the base vfs inode, because even though file data may have been modified,
  * it is dirty in the inode meta data rather than the data page cache of the
  * inode, and thus there are no data pages that need writing out.  Therefore, a
@@ -407,7 +407,7 @@ void __mark_mft_record_dirty(ntfs_inode *ni)
 	else
 		base_ni = ni->ext.base_ntfs_ino;
 	mutex_unlock(&ni->extent_lock);
-	__mark_inode_dirty(VFS_I(base_ni), I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+	__mark_inode_dirty(VFS_I(base_ni), I_DIRTY_DATASYNC);
 }
 
 static const char *ntfs_please_email = "Please email "
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index bc746e8..97a972e 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -3532,7 +3532,7 @@ static int ocfs2_downconvert_lock(struct ocfs2_super *osb,
 	 * On DLM_LKF_VALBLK, fsdlm behaves differently with o2cb. It always
 	 * expects DLM_LKF_VALBLK being set if the LKB has LVB, so that
 	 * we can recover correctly from node failure. Otherwise, we may get
-	 * invalid LVB in LKB, but without DLM_SBF_VALNOTVALID being set.
+	 * invalid LVB in LKB, but without DLM_SBF_VALNOTVALID being set.
 	 */
 	if (!ocfs2_is_o2cb_active() &&
 	    lockres->l_ops->flags & LOCK_TYPE_USES_LVB)
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c
index dae9eb7..d2fb97b 100644
--- a/fs/ocfs2/stack_user.c
+++ b/fs/ocfs2/stack_user.c
@@ -398,7 +398,7 @@ static int ocfs2_control_do_setnode_msg(struct file *file,
 
 static int ocfs2_control_do_setversion_msg(struct file *file,
 					   struct ocfs2_control_message_setv *msg)
- {
+{
 	long major, minor;
 	char *ptr = NULL;
 	struct ocfs2_control_private *p = file->private_data;
diff --git a/fs/open.c b/fs/open.c
index d0e955b..c5ee7cd 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -724,16 +724,6 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
 	return ksys_fchown(fd, user, group);
 }
 
-int open_check_o_direct(struct file *f)
-{
-	/* NB: we're sure to have correct a_ops only after f_op->open */
-	if (f->f_flags & O_DIRECT) {
-		if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)
-			return -EINVAL;
-	}
-	return 0;
-}
-
 static int do_dentry_open(struct file *f,
 			  struct inode *inode,
 			  int (*open)(struct inode *, struct file *),
@@ -755,7 +745,7 @@ static int do_dentry_open(struct file *f,
 	if (unlikely(f->f_flags & O_PATH)) {
 		f->f_mode = FMODE_PATH;
 		f->f_op = &empty_fops;
-		return 0;
+		goto done;
 	}
 
 	if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
@@ -808,7 +798,12 @@ static int do_dentry_open(struct file *f,
 	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
 
 	file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
-
+done:
+	/* NB: we're sure to have correct a_ops only after f_op->open */
+	error = -EINVAL;
+	if ((f->f_flags & O_DIRECT) &&
+	    (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO))
+	    	goto out_fput;
 	return 0;
 
 cleanup_all:
@@ -823,6 +818,9 @@ static int do_dentry_open(struct file *f,
 	f->f_path.dentry = NULL;
 	f->f_inode = NULL;
 	return error;
+out_fput:
+    	fput(f);
+	return error;
 }
 
 /**
@@ -920,20 +918,14 @@ struct file *dentry_open(const struct path *path, int flags,
 	BUG_ON(!path->mnt);
 
 	f = get_empty_filp();
-	if (!IS_ERR(f)) {
-		f->f_flags = flags;
-		error = vfs_open(path, f, cred);
-		if (!error) {
-			/* from now on we need fput() to dispose of f */
-			error = open_check_o_direct(f);
-			if (error) {
-				fput(f);
-				f = ERR_PTR(error);
-			}
-		} else { 
-			put_filp(f);
-			f = ERR_PTR(error);
-		}
+	if (IS_ERR(f))
+		return f;
+
+	f->f_flags = flags;
+	error = vfs_open(path, f, cred);
+	if (error) {
+		put_filp(f);
+		return ERR_PTR(error);
 	}
 	return f;
 }
diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c
index 480ea05..1058741 100644
--- a/fs/orangefs/acl.c
+++ b/fs/orangefs/acl.c
@@ -9,7 +9,6 @@
 #include "orangefs-kernel.h"
 #include "orangefs-bufmap.h"
 #include <linux/posix_acl_xattr.h>
-#include <linux/fs_struct.h>
 
 struct posix_acl *orangefs_get_acl(struct inode *inode, int type)
 {
diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c
index ea6256d..00fadaf 100644
--- a/fs/orangefs/orangefs-utils.c
+++ b/fs/orangefs/orangefs-utils.c
@@ -500,7 +500,7 @@ int orangefs_normalize_to_errno(__s32 error_code)
 	 * server.
 	 */
 	} else if (error_code > 0) {
-		gossip_err("orangefs: error status receieved.\n");
+		gossip_err("orangefs: error status received.\n");
 		gossip_err("orangefs: assuming error code is inverted.\n");
 		error_code = -error_code;
 	}
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h
index 48835a6..ae4811f 100644
--- a/fs/reiserfs/reiserfs.h
+++ b/fs/reiserfs/reiserfs.h
@@ -1916,7 +1916,7 @@ struct reiserfs_de_head {
 
 /* empty directory contains two entries "." and ".." and their headers */
 #define EMPTY_DIR_SIZE \
-(DEH_SIZE * 2 + ROUND_UP (strlen (".")) + ROUND_UP (strlen ("..")))
+(DEH_SIZE * 2 + ROUND_UP (sizeof(".") - 1) + ROUND_UP (sizeof("..") - 1))
 
 /* old format directories have this size when empty */
 #define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3)
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index cf348ba..1acb2ff 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1256,7 +1256,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
 		 * Inode length changed, so we have to make sure
 		 * @I_DIRTY_DATASYNC is set.
 		 */
-		 __mark_inode_dirty(inode, I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+		 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
 	else
 		mark_inode_dirty_sync(inode);
 	mutex_unlock(&ui->ui_mutex);
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 356c2bf..cd31e4f 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -257,12 +257,22 @@ const struct file_operations udf_file_operations = {
 static int udf_setattr(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = d_inode(dentry);
+	struct super_block *sb = inode->i_sb;
 	int error;
 
 	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
+	if ((attr->ia_valid & ATTR_UID) &&
+	    UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET) &&
+	    !uid_eq(attr->ia_uid, UDF_SB(sb)->s_uid))
+		return -EPERM;
+	if ((attr->ia_valid & ATTR_GID) &&
+	    UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET) &&
+	    !gid_eq(attr->ia_gid, UDF_SB(sb)->s_gid))
+		return -EPERM;
+
 	if ((attr->ia_valid & ATTR_SIZE) &&
 	    attr->ia_size != i_size_read(inode)) {
 		error = udf_setsize(inode, attr->ia_size);
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index b6e420c..b7a0d4b 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -104,6 +104,10 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode)
 	}
 
 	inode_init_owner(inode, dir, mode);
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET))
+		inode->i_uid = sbi->s_uid;
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET))
+		inode->i_gid = sbi->s_gid;
 
 	iinfo->i_location.logicalBlockNum = block;
 	iinfo->i_location.partitionReferenceNum =
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index c23744d..c80765d 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1275,6 +1275,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
 	unsigned int indirections = 0;
 	int bs = inode->i_sb->s_blocksize;
 	int ret = -EIO;
+	uint32_t uid, gid;
 
 reread:
 	if (iloc->partitionReferenceNum >= sbi->s_partitions) {
@@ -1400,17 +1401,19 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
 
 	ret = -EIO;
 	read_lock(&sbi->s_cred_lock);
-	i_uid_write(inode, le32_to_cpu(fe->uid));
-	if (!uid_valid(inode->i_uid) ||
-	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) ||
+	uid = le32_to_cpu(fe->uid);
+	if (uid == UDF_INVALID_ID ||
 	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET))
-		inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
+		inode->i_uid = sbi->s_uid;
+	else
+		i_uid_write(inode, uid);
 
-	i_gid_write(inode, le32_to_cpu(fe->gid));
-	if (!gid_valid(inode->i_gid) ||
-	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_IGNORE) ||
+	gid = le32_to_cpu(fe->gid);
+	if (gid == UDF_INVALID_ID ||
 	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET))
-		inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
+		inode->i_gid = sbi->s_gid;
+	else
+		i_gid_write(inode, gid);
 
 	if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
 			sbi->s_fmode != UDF_INVALID_MODE)
@@ -1655,12 +1658,12 @@ static int udf_update_inode(struct inode *inode, int do_sync)
 	}
 
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
-		fe->uid = cpu_to_le32(-1);
+		fe->uid = cpu_to_le32(UDF_INVALID_ID);
 	else
 		fe->uid = cpu_to_le32(i_uid_read(inode));
 
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
-		fe->gid = cpu_to_le32(-1);
+		fe->gid = cpu_to_le32(UDF_INVALID_ID);
 	else
 		fe->gid = cpu_to_le32(i_gid_read(inode));
 
diff --git a/fs/udf/super.c b/fs/udf/super.c
index f73239a..7949c33 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -64,14 +64,13 @@
 #include <linux/init.h>
 #include <linux/uaccess.h>
 
-#define VDS_POS_PRIMARY_VOL_DESC	0
-#define VDS_POS_UNALLOC_SPACE_DESC	1
-#define VDS_POS_LOGICAL_VOL_DESC	2
-#define VDS_POS_PARTITION_DESC		3
-#define VDS_POS_IMP_USE_VOL_DESC	4
-#define VDS_POS_VOL_DESC_PTR		5
-#define VDS_POS_TERMINATING_DESC	6
-#define VDS_POS_LENGTH			7
+enum {
+	VDS_POS_PRIMARY_VOL_DESC,
+	VDS_POS_UNALLOC_SPACE_DESC,
+	VDS_POS_LOGICAL_VOL_DESC,
+	VDS_POS_IMP_USE_VOL_DESC,
+	VDS_POS_LENGTH
+};
 
 #define VSD_FIRST_SECTOR_OFFSET		32768
 #define VSD_MAX_SECTOR_OFFSET		0x800000
@@ -223,10 +222,6 @@ struct udf_options {
 	unsigned int session;
 	unsigned int lastblock;
 	unsigned int anchor;
-	unsigned int volume;
-	unsigned short partition;
-	unsigned int fileset;
-	unsigned int rootdir;
 	unsigned int flags;
 	umode_t umask;
 	kgid_t gid;
@@ -349,12 +344,8 @@ static int udf_show_options(struct seq_file *seq, struct dentry *root)
 		seq_puts(seq, ",shortad");
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_FORGET))
 		seq_puts(seq, ",uid=forget");
-	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_IGNORE))
-		seq_puts(seq, ",uid=ignore");
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_FORGET))
 		seq_puts(seq, ",gid=forget");
-	if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_IGNORE))
-		seq_puts(seq, ",gid=ignore");
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET))
 		seq_printf(seq, ",uid=%u", from_kuid(&init_user_ns, sbi->s_uid));
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET))
@@ -371,10 +362,6 @@ static int udf_show_options(struct seq_file *seq, struct dentry *root)
 		seq_printf(seq, ",lastblock=%u", sbi->s_last_block);
 	if (sbi->s_anchor != 0)
 		seq_printf(seq, ",anchor=%u", sbi->s_anchor);
-	/*
-	 * volume, partition, fileset and rootdir seem to be ignored
-	 * currently
-	 */
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
 		seq_puts(seq, ",utf8");
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP) && sbi->s_nls_map)
@@ -487,14 +474,9 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
 	int option;
 
 	uopt->novrs = 0;
-	uopt->partition = 0xFFFF;
 	uopt->session = 0xFFFFFFFF;
 	uopt->lastblock = 0;
 	uopt->anchor = 0;
-	uopt->volume = 0xFFFFFFFF;
-	uopt->rootdir = 0xFFFFFFFF;
-	uopt->fileset = 0xFFFFFFFF;
-	uopt->nls_map = NULL;
 
 	if (!options)
 		return 1;
@@ -582,42 +564,30 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
 			uopt->anchor = option;
 			break;
 		case Opt_volume:
-			if (match_int(args, &option))
-				return 0;
-			uopt->volume = option;
-			break;
 		case Opt_partition:
-			if (match_int(args, &option))
-				return 0;
-			uopt->partition = option;
-			break;
 		case Opt_fileset:
-			if (match_int(args, &option))
-				return 0;
-			uopt->fileset = option;
-			break;
 		case Opt_rootdir:
-			if (match_int(args, &option))
-				return 0;
-			uopt->rootdir = option;
+			/* Ignored (never implemented properly) */
 			break;
 		case Opt_utf8:
 			uopt->flags |= (1 << UDF_FLAG_UTF8);
 			break;
 #ifdef CONFIG_UDF_NLS
 		case Opt_iocharset:
-			uopt->nls_map = load_nls(args[0].from);
-			uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
+			if (!remount) {
+				if (uopt->nls_map)
+					unload_nls(uopt->nls_map);
+				uopt->nls_map = load_nls(args[0].from);
+				uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
+			}
 			break;
 #endif
-		case Opt_uignore:
-			uopt->flags |= (1 << UDF_FLAG_UID_IGNORE);
-			break;
 		case Opt_uforget:
 			uopt->flags |= (1 << UDF_FLAG_UID_FORGET);
 			break;
+		case Opt_uignore:
 		case Opt_gignore:
-			uopt->flags |= (1 << UDF_FLAG_GID_IGNORE);
+			/* These options are superseeded by uid=<number> */
 			break;
 		case Opt_gforget:
 			uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
@@ -660,6 +630,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
 	uopt.umask = sbi->s_umask;
 	uopt.fmode = sbi->s_fmode;
 	uopt.dmode = sbi->s_dmode;
+	uopt.nls_map = NULL;
 
 	if (!udf_parse_options(options, &uopt, true))
 		return -EINVAL;
@@ -1592,6 +1563,60 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_
 	sbi->s_lvid_bh = NULL;
 }
 
+/*
+ * Step for reallocation of table of partition descriptor sequence numbers.
+ * Must be power of 2.
+ */
+#define PART_DESC_ALLOC_STEP 32
+
+struct desc_seq_scan_data {
+	struct udf_vds_record vds[VDS_POS_LENGTH];
+	unsigned int size_part_descs;
+	struct udf_vds_record *part_descs_loc;
+};
+
+static struct udf_vds_record *handle_partition_descriptor(
+				struct buffer_head *bh,
+				struct desc_seq_scan_data *data)
+{
+	struct partitionDesc *desc = (struct partitionDesc *)bh->b_data;
+	int partnum;
+
+	partnum = le16_to_cpu(desc->partitionNumber);
+	if (partnum >= data->size_part_descs) {
+		struct udf_vds_record *new_loc;
+		unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP);
+
+		new_loc = kzalloc(sizeof(*new_loc) * new_size, GFP_KERNEL);
+		if (!new_loc)
+			return ERR_PTR(-ENOMEM);
+		memcpy(new_loc, data->part_descs_loc,
+		       data->size_part_descs * sizeof(*new_loc));
+		kfree(data->part_descs_loc);
+		data->part_descs_loc = new_loc;
+		data->size_part_descs = new_size;
+	}
+	return &(data->part_descs_loc[partnum]);
+}
+
+
+static struct udf_vds_record *get_volume_descriptor_record(uint16_t ident,
+		struct buffer_head *bh, struct desc_seq_scan_data *data)
+{
+	switch (ident) {
+	case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
+		return &(data->vds[VDS_POS_PRIMARY_VOL_DESC]);
+	case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
+		return &(data->vds[VDS_POS_IMP_USE_VOL_DESC]);
+	case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
+		return &(data->vds[VDS_POS_LOGICAL_VOL_DESC]);
+	case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
+		return &(data->vds[VDS_POS_UNALLOC_SPACE_DESC]);
+	case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
+		return handle_partition_descriptor(bh, data);
+	}
+	return NULL;
+}
 
 /*
  * Process a main/reserve volume descriptor sequence.
@@ -1608,18 +1633,23 @@ static noinline int udf_process_sequence(
 		struct kernel_lb_addr *fileset)
 {
 	struct buffer_head *bh = NULL;
-	struct udf_vds_record vds[VDS_POS_LENGTH];
 	struct udf_vds_record *curr;
 	struct generic_desc *gd;
 	struct volDescPtr *vdp;
 	bool done = false;
 	uint32_t vdsn;
 	uint16_t ident;
-	long next_s = 0, next_e = 0;
 	int ret;
 	unsigned int indirections = 0;
+	struct desc_seq_scan_data data;
+	unsigned int i;
 
-	memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
+	memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
+	data.size_part_descs = PART_DESC_ALLOC_STEP;
+	data.part_descs_loc = kzalloc(sizeof(*data.part_descs_loc) *
+					data.size_part_descs, GFP_KERNEL);
+	if (!data.part_descs_loc)
+		return -ENOMEM;
 
 	/*
 	 * Read the main descriptor sequence and find which descriptors
@@ -1628,79 +1658,51 @@ static noinline int udf_process_sequence(
 	for (; (!done && block <= lastblock); block++) {
 
 		bh = udf_read_tagged(sb, block, block, &ident);
-		if (!bh) {
-			udf_err(sb,
-				"Block %llu of volume descriptor sequence is corrupted or we could not read it\n",
-				(unsigned long long)block);
-			return -EAGAIN;
-		}
+		if (!bh)
+			break;
 
 		/* Process each descriptor (ISO 13346 3/8.3-8.4) */
 		gd = (struct generic_desc *)bh->b_data;
 		vdsn = le32_to_cpu(gd->volDescSeqNum);
 		switch (ident) {
-		case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
-			curr = &vds[VDS_POS_PRIMARY_VOL_DESC];
-			if (vdsn >= curr->volDescSeqNum) {
-				curr->volDescSeqNum = vdsn;
-				curr->block = block;
-			}
-			break;
 		case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
-			curr = &vds[VDS_POS_VOL_DESC_PTR];
-			if (vdsn >= curr->volDescSeqNum) {
-				curr->volDescSeqNum = vdsn;
-				curr->block = block;
+			if (++indirections > UDF_MAX_TD_NESTING) {
+				udf_err(sb, "too many Volume Descriptor "
+					"Pointers (max %u supported)\n",
+					UDF_MAX_TD_NESTING);
+				brelse(bh);
+				return -EIO;
+			}
 
-				vdp = (struct volDescPtr *)bh->b_data;
-				next_s = le32_to_cpu(
-					vdp->nextVolDescSeqExt.extLocation);
-				next_e = le32_to_cpu(
-					vdp->nextVolDescSeqExt.extLength);
-				next_e = next_e >> sb->s_blocksize_bits;
-				next_e += next_s;
-			}
+			vdp = (struct volDescPtr *)bh->b_data;
+			block = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
+			lastblock = le32_to_cpu(
+				vdp->nextVolDescSeqExt.extLength) >>
+				sb->s_blocksize_bits;
+			lastblock += block - 1;
+			/* For loop is going to increment 'block' again */
+			block--;
 			break;
+		case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
 		case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
-			curr = &vds[VDS_POS_IMP_USE_VOL_DESC];
-			if (vdsn >= curr->volDescSeqNum) {
-				curr->volDescSeqNum = vdsn;
-				curr->block = block;
-			}
-			break;
-		case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
-			curr = &vds[VDS_POS_PARTITION_DESC];
-			if (!curr->block)
-				curr->block = block;
-			break;
 		case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
-			curr = &vds[VDS_POS_LOGICAL_VOL_DESC];
-			if (vdsn >= curr->volDescSeqNum) {
-				curr->volDescSeqNum = vdsn;
-				curr->block = block;
-			}
-			break;
 		case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
-			curr = &vds[VDS_POS_UNALLOC_SPACE_DESC];
+		case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
+			curr = get_volume_descriptor_record(ident, bh, &data);
+			if (IS_ERR(curr)) {
+				brelse(bh);
+				return PTR_ERR(curr);
+			}
+			/* Descriptor we don't care about? */
+			if (!curr)
+				break;
 			if (vdsn >= curr->volDescSeqNum) {
 				curr->volDescSeqNum = vdsn;
 				curr->block = block;
 			}
 			break;
 		case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
-			if (++indirections > UDF_MAX_TD_NESTING) {
-				udf_err(sb, "too many TDs (max %u supported)\n", UDF_MAX_TD_NESTING);
-				brelse(bh);
-				return -EIO;
-			}
-
-			vds[VDS_POS_TERMINATING_DESC].block = block;
-			if (next_e) {
-				block = next_s;
-				lastblock = next_e;
-				next_s = next_e = 0;
-			} else
-				done = true;
+			done = true;
 			break;
 		}
 		brelse(bh);
@@ -1709,31 +1711,27 @@ static noinline int udf_process_sequence(
 	 * Now read interesting descriptors again and process them
 	 * in a suitable order
 	 */
-	if (!vds[VDS_POS_PRIMARY_VOL_DESC].block) {
+	if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) {
 		udf_err(sb, "Primary Volume Descriptor not found!\n");
 		return -EAGAIN;
 	}
-	ret = udf_load_pvoldesc(sb, vds[VDS_POS_PRIMARY_VOL_DESC].block);
+	ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block);
 	if (ret < 0)
 		return ret;
 
-	if (vds[VDS_POS_LOGICAL_VOL_DESC].block) {
+	if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) {
 		ret = udf_load_logicalvol(sb,
-					  vds[VDS_POS_LOGICAL_VOL_DESC].block,
-					  fileset);
+				data.vds[VDS_POS_LOGICAL_VOL_DESC].block,
+				fileset);
 		if (ret < 0)
 			return ret;
 	}
 
-	if (vds[VDS_POS_PARTITION_DESC].block) {
-		/*
-		 * We rescan the whole descriptor sequence to find
-		 * partition descriptor blocks and process them.
-		 */
-		for (block = vds[VDS_POS_PARTITION_DESC].block;
-		     block < vds[VDS_POS_TERMINATING_DESC].block;
-		     block++) {
-			ret = udf_load_partdesc(sb, block);
+	/* Now handle prevailing Partition Descriptors */
+	for (i = 0; i < data.size_part_descs; i++) {
+		if (data.part_descs_loc[i].block) {
+			ret = udf_load_partdesc(sb,
+						data.part_descs_loc[i].block);
 			if (ret < 0)
 				return ret;
 		}
@@ -1760,13 +1758,13 @@ static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh,
 	main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
 	main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength);
 	main_e = main_e >> sb->s_blocksize_bits;
-	main_e += main_s;
+	main_e += main_s - 1;
 
 	/* Locate the reserve sequence */
 	reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
 	reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
 	reserve_e = reserve_e >> sb->s_blocksize_bits;
-	reserve_e += reserve_s;
+	reserve_e += reserve_s - 1;
 
 	/* Process the main & reserve sequences */
 	/* responsible for finding the PartitionDesc(s) */
@@ -1994,7 +1992,10 @@ static void udf_open_lvid(struct super_block *sb)
 	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
 	ktime_get_real_ts(&ts);
 	udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts);
-	lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
+	if (le32_to_cpu(lvid->integrityType) == LVID_INTEGRITY_TYPE_CLOSE)
+		lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
+	else
+		UDF_SET_FLAG(sb, UDF_FLAG_INCONSISTENT);
 
 	lvid->descTag.descCRC = cpu_to_le16(
 		crc_itu_t(0, (char *)lvid + sizeof(struct tag),
@@ -2034,7 +2035,8 @@ static void udf_close_lvid(struct super_block *sb)
 		lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev);
 	if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev))
 		lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev);
-	lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
+	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT))
+		lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
 
 	lvid->descTag.descCRC = cpu_to_le16(
 			crc_itu_t(0, (char *)lvid + sizeof(struct tag),
@@ -2091,11 +2093,13 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
 	bool lvid_open = false;
 
 	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
-	uopt.uid = INVALID_UID;
-	uopt.gid = INVALID_GID;
+	/* By default we'll use overflow[ug]id when UDF inode [ug]id == -1 */
+	uopt.uid = make_kuid(current_user_ns(), overflowuid);
+	uopt.gid = make_kgid(current_user_ns(), overflowgid);
 	uopt.umask = 0;
 	uopt.fmode = UDF_INVALID_MODE;
 	uopt.dmode = UDF_INVALID_MODE;
+	uopt.nls_map = NULL;
 
 	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
 	if (!sbi)
@@ -2276,8 +2280,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
 	iput(sbi->s_vat_inode);
 parse_options_failure:
 #ifdef CONFIG_UDF_NLS
-	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
-		unload_nls(sbi->s_nls_map);
+	if (uopt.nls_map)
+		unload_nls(uopt.nls_map);
 #endif
 	if (lvid_open)
 		udf_close_lvid(sb);
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 68c9f1d..9dd3e1b 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -23,14 +23,13 @@
 #define UDF_FLAG_NLS_MAP		9
 #define UDF_FLAG_UTF8			10
 #define UDF_FLAG_UID_FORGET     11    /* save -1 for uid to disk */
-#define UDF_FLAG_UID_IGNORE     12    /* use sb uid instead of on disk uid */
-#define UDF_FLAG_GID_FORGET     13
-#define UDF_FLAG_GID_IGNORE     14
-#define UDF_FLAG_UID_SET	15
-#define UDF_FLAG_GID_SET	16
-#define UDF_FLAG_SESSION_SET	17
-#define UDF_FLAG_LASTBLOCK_SET	18
-#define UDF_FLAG_BLOCKSIZE_SET	19
+#define UDF_FLAG_GID_FORGET     12
+#define UDF_FLAG_UID_SET	13
+#define UDF_FLAG_GID_SET	14
+#define UDF_FLAG_SESSION_SET	15
+#define UDF_FLAG_LASTBLOCK_SET	16
+#define UDF_FLAG_BLOCKSIZE_SET	17
+#define UDF_FLAG_INCONSISTENT	18
 
 #define UDF_PART_FLAG_UNALLOC_BITMAP	0x0001
 #define UDF_PART_FLAG_UNALLOC_TABLE	0x0002
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index f5e0fe7..68e8a64 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -48,6 +48,8 @@ extern __printf(3, 4) void _udf_warn(struct super_block *sb,
 #define UDF_EXTENT_LENGTH_MASK	0x3FFFFFFF
 #define UDF_EXTENT_FLAG_MASK	0xC0000000
 
+#define UDF_INVALID_ID ((uint32_t)-1)
+
 #define UDF_NAME_PAD		4
 #define UDF_NAME_LEN		254
 #define UDF_NAME_LEN_CS0	255
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 19eadc8..31f1f10 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -1390,7 +1390,7 @@ xfs_vm_bmap(
 
 	/*
 	 * The swap code (ab-)uses ->bmap to get a block mapping and then
-	 * bypasseѕ the file system for actual I/O.  We really can't allow
+	 * bypasses the file system for actual I/O.  We really can't allow
 	 * that on reflinks inodes, so we have to skip out here.  And yes,
 	 * 0 is the magic code for a bmap error.
 	 *
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index 761f318..eed698a 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -122,7 +122,7 @@ xfs_nfs_get_inode(
 	struct super_block	*sb,
 	u64			ino,
 	u32			generation)
- {
+{
  	xfs_mount_t		*mp = XFS_M(sb);
 	xfs_inode_t		*ip;
 	int			error;
diff --git a/include/acpi/nfit.h b/include/acpi/nfit.h
new file mode 100644
index 0000000..86ed07c1
--- /dev/null
+++ b/include/acpi/nfit.h
@@ -0,0 +1,18 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (C) 2018 Intel Corporation
+ */
+
+#ifndef __ACPI_NFIT_H
+#define __ACPI_NFIT_H
+
+#if IS_ENABLED(CONFIG_ACPI_NFIT)
+int nfit_get_smbios_id(u32 device_handle, u16 *flags);
+#else
+static inline int nfit_get_smbios_id(u32 device_handle, u16 *flags)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
+#endif /* __ACPI_NFIT_H */
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/include/clocksource/timer-ti-dm.h
similarity index 86%
rename from arch/arm/plat-omap/include/plat/dmtimer.h
rename to include/clocksource/timer-ti-dm.h
index dd79f30..7d9598d 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/include/clocksource/timer-ti-dm.h
@@ -1,6 +1,4 @@
 /*
- * arch/arm/plat-omap/include/plat/dmtimer.h
- *
  * OMAP Dual-Mode Timers
  *
  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
@@ -36,8 +34,8 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 
-#ifndef __ASM_ARCH_DMTIMER_H
-#define __ASM_ARCH_DMTIMER_H
+#ifndef __CLOCKSOURCE_DMTIMER_H
+#define __CLOCKSOURCE_DMTIMER_H
 
 /* clock sources */
 #define OMAP_TIMER_SRC_SYS_CLK			0x00
@@ -75,10 +73,6 @@
  */
 #define OMAP_TIMER_ERRATA_I103_I767			0x80000000
 
-struct omap_timer_capability_dev_attr {
-	u32 timer_capability;
-};
-
 struct timer_regs {
 	u32 tidr;
 	u32 tier;
@@ -125,37 +119,13 @@ struct omap_dm_timer {
 };
 
 int omap_dm_timer_reserve_systimer(int id);
-struct omap_dm_timer *omap_dm_timer_request(void);
-struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
-int omap_dm_timer_free(struct omap_dm_timer *timer);
-void omap_dm_timer_enable(struct omap_dm_timer *timer);
-void omap_dm_timer_disable(struct omap_dm_timer *timer);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
 
 u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
 
 int omap_dm_timer_trigger(struct omap_dm_timer *timer);
-int omap_dm_timer_start(struct omap_dm_timer *timer);
-int omap_dm_timer_stop(struct omap_dm_timer *timer);
-
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
-
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
-
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
 
 int omap_dm_timers_active(void);
 
@@ -276,6 +246,12 @@ int omap_dm_timers_active(void);
 #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG				\
 		(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
 
+/*
+ * The below are inlined to optimize code size for system timers. Other code
+ * should not need these at all, see
+ * include/linux/platform_data/pwm_omap_dmtimer.h
+ */
+#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2PLUS)
 static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
 						int posted)
 {
@@ -414,5 +390,5 @@ static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer,
 {
 	writel_relaxed(value, timer->irq_stat);
 }
-
-#endif /* __ASM_ARCH_DMTIMER_H */
+#endif /* CONFIG_ARCH_OMAP1 || CONFIG_ARCH_OMAP2PLUS */
+#endif /* __CLOCKSOURCE_DMTIMER_H */
diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h
index e2f99ae..b2325d3e2 100644
--- a/include/dt-bindings/clock/imx7d-clock.h
+++ b/include/dt-bindings/clock/imx7d-clock.h
@@ -452,5 +452,8 @@
 #define IMX7D_OCOTP_CLK			439
 #define IMX7D_NAND_RAWNAND_CLK		440
 #define IMX7D_NAND_USDHC_BUS_RAWNAND_CLK 441
-#define IMX7D_CLK_END			442
+#define IMX7D_SNVS_CLK			442
+#define IMX7D_CAAM_CLK			443
+#define IMX7D_KPP_ROOT_CLK		444
+#define IMX7D_CLK_END			445
 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
diff --git a/include/dt-bindings/clock/tegra194-clock.h b/include/dt-bindings/clock/tegra194-clock.h
new file mode 100644
index 0000000..a2ff663
--- /dev/null
+++ b/include/dt-bindings/clock/tegra194-clock.h
@@ -0,0 +1,321 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. */
+
+#ifndef __ABI_MACH_T194_CLOCK_H
+#define __ABI_MACH_T194_CLOCK_H
+
+#define TEGRA194_CLK_ACTMON			1
+#define TEGRA194_CLK_ADSP			2
+#define TEGRA194_CLK_ADSPNEON			3
+#define TEGRA194_CLK_AHUB			4
+#define TEGRA194_CLK_APB2APE			5
+#define TEGRA194_CLK_APE			6
+#define TEGRA194_CLK_AUD_MCLK			7
+#define TEGRA194_CLK_AXI_CBB			8
+#define TEGRA194_CLK_CAN1			9
+#define TEGRA194_CLK_CAN1_HOST			10
+#define TEGRA194_CLK_CAN2			11
+#define TEGRA194_CLK_CAN2_HOST			12
+#define TEGRA194_CLK_CEC			13
+#define TEGRA194_CLK_CLK_M			14
+#define TEGRA194_CLK_DMIC1			15
+#define TEGRA194_CLK_DMIC2			16
+#define TEGRA194_CLK_DMIC3			17
+#define TEGRA194_CLK_DMIC4			18
+#define TEGRA194_CLK_DPAUX			19
+#define TEGRA194_CLK_DPAUX1			20
+#define TEGRA194_CLK_ACLK			21
+#define TEGRA194_CLK_MSS_ENCRYPT		22
+#define TEGRA194_CLK_EQOS_RX_INPUT		23
+#define TEGRA194_CLK_IQC2			24
+#define TEGRA194_CLK_AON_APB			25
+#define TEGRA194_CLK_AON_NIC			26
+#define TEGRA194_CLK_AON_CPU_NIC		27
+#define TEGRA194_CLK_PLLA1			28
+#define TEGRA194_CLK_DSPK1			29
+#define TEGRA194_CLK_DSPK2			30
+#define TEGRA194_CLK_EMC			31
+#define TEGRA194_CLK_EQOS_AXI			32
+#define TEGRA194_CLK_EQOS_PTP_REF		33
+#define TEGRA194_CLK_EQOS_RX			34
+#define TEGRA194_CLK_EQOS_TX			35
+#define TEGRA194_CLK_EXTPERIPH1			36
+#define TEGRA194_CLK_EXTPERIPH2			37
+#define TEGRA194_CLK_EXTPERIPH3			38
+#define TEGRA194_CLK_EXTPERIPH4			39
+#define TEGRA194_CLK_FUSE			40
+#define TEGRA194_CLK_GPCCLK			41
+#define TEGRA194_CLK_GPU_PWR			42
+#define TEGRA194_CLK_HDA			43
+#define TEGRA194_CLK_HDA2CODEC_2X		44
+#define TEGRA194_CLK_HDA2HDMICODEC		45
+#define TEGRA194_CLK_HOST1X			46
+#define TEGRA194_CLK_HSIC_TRK			47
+#define TEGRA194_CLK_I2C1			48
+#define TEGRA194_CLK_I2C2			49
+#define TEGRA194_CLK_I2C3			50
+#define TEGRA194_CLK_I2C4			51
+#define TEGRA194_CLK_I2C6			52
+#define TEGRA194_CLK_I2C7			53
+#define TEGRA194_CLK_I2C8			54
+#define TEGRA194_CLK_I2C9			55
+#define TEGRA194_CLK_I2S1			56
+#define TEGRA194_CLK_I2S1_SYNC_INPUT		57
+#define TEGRA194_CLK_I2S2			58
+#define TEGRA194_CLK_I2S2_SYNC_INPUT		59
+#define TEGRA194_CLK_I2S3			60
+#define TEGRA194_CLK_I2S3_SYNC_INPUT		61
+#define TEGRA194_CLK_I2S4			62
+#define TEGRA194_CLK_I2S4_SYNC_INPUT		63
+#define TEGRA194_CLK_I2S5			64
+#define TEGRA194_CLK_I2S5_SYNC_INPUT		65
+#define TEGRA194_CLK_I2S6			66
+#define TEGRA194_CLK_I2S6_SYNC_INPUT		67
+#define TEGRA194_CLK_IQC1			68
+#define TEGRA194_CLK_ISP			69
+#define TEGRA194_CLK_KFUSE			70
+#define TEGRA194_CLK_MAUD			71
+#define TEGRA194_CLK_MIPI_CAL			72
+#define TEGRA194_CLK_MPHY_CORE_PLL_FIXED	73
+#define TEGRA194_CLK_MPHY_L0_RX_ANA		74
+#define TEGRA194_CLK_MPHY_L0_RX_LS_BIT		75
+#define TEGRA194_CLK_MPHY_L0_RX_SYMB		76
+#define TEGRA194_CLK_MPHY_L0_TX_LS_3XBIT	77
+#define TEGRA194_CLK_MPHY_L0_TX_SYMB		78
+#define TEGRA194_CLK_MPHY_L1_RX_ANA		79
+#define TEGRA194_CLK_MPHY_TX_1MHZ_REF		80
+#define TEGRA194_CLK_NVCSI			81
+#define TEGRA194_CLK_NVCSILP			82
+#define TEGRA194_CLK_NVDEC			83
+#define TEGRA194_CLK_NVDISPLAYHUB		84
+#define TEGRA194_CLK_NVDISPLAY_DISP		85
+#define TEGRA194_CLK_NVDISPLAY_P0		86
+#define TEGRA194_CLK_NVDISPLAY_P1		87
+#define TEGRA194_CLK_NVDISPLAY_P2		88
+#define TEGRA194_CLK_NVENC			89
+#define TEGRA194_CLK_NVJPG			90
+#define TEGRA194_CLK_OSC			91
+#define TEGRA194_CLK_AON_TOUCH			92
+#define TEGRA194_CLK_PLLA			93
+#define TEGRA194_CLK_PLLAON			94
+#define TEGRA194_CLK_PLLD			95
+#define TEGRA194_CLK_PLLD2			96
+#define TEGRA194_CLK_PLLD3			97
+#define TEGRA194_CLK_PLLDP			98
+#define TEGRA194_CLK_PLLD4			99
+#define TEGRA194_CLK_PLLE			100
+#define TEGRA194_CLK_PLLP			101
+#define TEGRA194_CLK_PLLP_OUT0			102
+#define TEGRA194_CLK_UTMIPLL			103
+#define TEGRA194_CLK_PLLA_OUT0			104
+#define TEGRA194_CLK_PWM1			105
+#define TEGRA194_CLK_PWM2			106
+#define TEGRA194_CLK_PWM3			107
+#define TEGRA194_CLK_PWM4			108
+#define TEGRA194_CLK_PWM5			109
+#define TEGRA194_CLK_PWM6			110
+#define TEGRA194_CLK_PWM7			111
+#define TEGRA194_CLK_PWM8			112
+#define TEGRA194_CLK_RCE_CPU_NIC		113
+#define TEGRA194_CLK_RCE_NIC			114
+#define TEGRA194_CLK_SATA			115
+#define TEGRA194_CLK_SATA_OOB			116
+#define TEGRA194_CLK_AON_I2C_SLOW		117
+#define TEGRA194_CLK_SCE_CPU_NIC		118
+#define TEGRA194_CLK_SCE_NIC			119
+#define TEGRA194_CLK_SDMMC1			120
+#define TEGRA194_CLK_UPHY_PLL3			121
+#define TEGRA194_CLK_SDMMC3			122
+#define TEGRA194_CLK_SDMMC4			123
+#define TEGRA194_CLK_SE				124
+#define TEGRA194_CLK_SOR0_OUT			125
+#define TEGRA194_CLK_SOR0_REF			126
+#define TEGRA194_CLK_SOR0_PAD_CLKOUT		127
+#define TEGRA194_CLK_SOR1_OUT			128
+#define TEGRA194_CLK_SOR1_REF			129
+#define TEGRA194_CLK_SOR1_PAD_CLKOUT		130
+#define TEGRA194_CLK_SOR_SAFE			131
+#define TEGRA194_CLK_IQC1_IN			132
+#define TEGRA194_CLK_IQC2_IN			133
+#define TEGRA194_CLK_DMIC5			134
+#define TEGRA194_CLK_SPI1			135
+#define TEGRA194_CLK_SPI2			136
+#define TEGRA194_CLK_SPI3			137
+#define TEGRA194_CLK_I2C_SLOW			138
+#define TEGRA194_CLK_SYNC_DMIC1			139
+#define TEGRA194_CLK_SYNC_DMIC2			140
+#define TEGRA194_CLK_SYNC_DMIC3			141
+#define TEGRA194_CLK_SYNC_DMIC4			142
+#define TEGRA194_CLK_SYNC_DSPK1			143
+#define TEGRA194_CLK_SYNC_DSPK2			144
+#define TEGRA194_CLK_SYNC_I2S1			145
+#define TEGRA194_CLK_SYNC_I2S2			146
+#define TEGRA194_CLK_SYNC_I2S3			147
+#define TEGRA194_CLK_SYNC_I2S4			148
+#define TEGRA194_CLK_SYNC_I2S5			149
+#define TEGRA194_CLK_SYNC_I2S6			150
+#define TEGRA194_CLK_MPHY_FORCE_LS_MODE		151
+#define TEGRA194_CLK_TACH			152
+#define TEGRA194_CLK_TSEC			153
+#define TEGRA194_CLK_TSECB			154
+#define TEGRA194_CLK_UARTA			155
+#define TEGRA194_CLK_UARTB			156
+#define TEGRA194_CLK_UARTC			157
+#define TEGRA194_CLK_UARTD			158
+#define TEGRA194_CLK_UARTE			159
+#define TEGRA194_CLK_UARTF			160
+#define TEGRA194_CLK_UARTG			161
+#define TEGRA194_CLK_UART_FST_MIPI_CAL		162
+#define TEGRA194_CLK_UFSDEV_REF			163
+#define TEGRA194_CLK_UFSHC			164
+#define TEGRA194_CLK_USB2_TRK			165
+#define TEGRA194_CLK_VI				166
+#define TEGRA194_CLK_VIC			167
+#define TEGRA194_CLK_PVA0_AXI			168
+#define TEGRA194_CLK_PVA0_VPS0			169
+#define TEGRA194_CLK_PVA0_VPS1			170
+#define TEGRA194_CLK_PVA1_AXI			171
+#define TEGRA194_CLK_PVA1_VPS0			172
+#define TEGRA194_CLK_PVA1_VPS1			173
+#define TEGRA194_CLK_DLA0_FALCON		174
+#define TEGRA194_CLK_DLA0_CORE			175
+#define TEGRA194_CLK_DLA1_FALCON		176
+#define TEGRA194_CLK_DLA1_CORE			177
+#define TEGRA194_CLK_SOR2_OUT			178
+#define TEGRA194_CLK_SOR2_REF			179
+#define TEGRA194_CLK_SOR2_PAD_CLKOUT		180
+#define TEGRA194_CLK_SOR3_OUT			181
+#define TEGRA194_CLK_SOR3_REF			182
+#define TEGRA194_CLK_SOR3_PAD_CLKOUT		183
+#define TEGRA194_CLK_NVDISPLAY_P3		184
+#define TEGRA194_CLK_DPAUX2			185
+#define TEGRA194_CLK_DPAUX3			186
+#define TEGRA194_CLK_NVDEC1			187
+#define TEGRA194_CLK_NVENC1			188
+#define TEGRA194_CLK_SE_FREE			189
+#define TEGRA194_CLK_UARTH			190
+#define TEGRA194_CLK_FUSE_SERIAL		191
+#define TEGRA194_CLK_QSPI0			192
+#define TEGRA194_CLK_QSPI1			193
+#define TEGRA194_CLK_QSPI0_PM			194
+#define TEGRA194_CLK_QSPI1_PM			195
+#define TEGRA194_CLK_VI_CONST			196
+#define TEGRA194_CLK_NAFLL_BPMP			197
+#define TEGRA194_CLK_NAFLL_SCE			198
+#define TEGRA194_CLK_NAFLL_NVDEC		199
+#define TEGRA194_CLK_NAFLL_NVJPG		200
+#define TEGRA194_CLK_NAFLL_TSEC			201
+#define TEGRA194_CLK_NAFLL_TSECB		202
+#define TEGRA194_CLK_NAFLL_VI			203
+#define TEGRA194_CLK_NAFLL_SE			204
+#define TEGRA194_CLK_NAFLL_NVENC		205
+#define TEGRA194_CLK_NAFLL_ISP			206
+#define TEGRA194_CLK_NAFLL_VIC			207
+#define TEGRA194_CLK_NAFLL_NVDISPLAYHUB		208
+#define TEGRA194_CLK_NAFLL_AXICBB		209
+#define TEGRA194_CLK_NAFLL_DLA			210
+#define TEGRA194_CLK_NAFLL_PVA_CORE		211
+#define TEGRA194_CLK_NAFLL_PVA_VPS		212
+#define TEGRA194_CLK_NAFLL_CVNAS		213
+#define TEGRA194_CLK_NAFLL_RCE			214
+#define TEGRA194_CLK_NAFLL_NVENC1		215
+#define TEGRA194_CLK_NAFLL_DLA_FALCON		216
+#define TEGRA194_CLK_NAFLL_NVDEC1		217
+#define TEGRA194_CLK_NAFLL_GPU			218
+#define TEGRA194_CLK_SDMMC_LEGACY_TM		219
+#define TEGRA194_CLK_PEX0_CORE_0		220
+#define TEGRA194_CLK_PEX0_CORE_1		221
+#define TEGRA194_CLK_PEX0_CORE_2		222
+#define TEGRA194_CLK_PEX0_CORE_3		223
+#define TEGRA194_CLK_PEX0_CORE_4		224
+#define TEGRA194_CLK_PEX1_CORE_5		225
+#define TEGRA194_CLK_PEX_REF1			226
+#define TEGRA194_CLK_PEX_REF2			227
+#define TEGRA194_CLK_CSI_A			229
+#define TEGRA194_CLK_CSI_B			230
+#define TEGRA194_CLK_CSI_C			231
+#define TEGRA194_CLK_CSI_D			232
+#define TEGRA194_CLK_CSI_E			233
+#define TEGRA194_CLK_CSI_F			234
+#define TEGRA194_CLK_CSI_G			235
+#define TEGRA194_CLK_CSI_H			236
+#define TEGRA194_CLK_PLLC4			237
+#define TEGRA194_CLK_PLLC4_OUT			238
+#define TEGRA194_CLK_PLLC4_OUT1			239
+#define TEGRA194_CLK_PLLC4_OUT2			240
+#define TEGRA194_CLK_PLLC4_MUXED		241
+#define TEGRA194_CLK_PLLC4_VCO_DIV2		242
+#define TEGRA194_CLK_CSI_A_PAD			244
+#define TEGRA194_CLK_CSI_B_PAD			245
+#define TEGRA194_CLK_CSI_C_PAD			246
+#define TEGRA194_CLK_CSI_D_PAD			247
+#define TEGRA194_CLK_CSI_E_PAD			248
+#define TEGRA194_CLK_CSI_F_PAD			249
+#define TEGRA194_CLK_CSI_G_PAD			250
+#define TEGRA194_CLK_CSI_H_PAD			251
+#define TEGRA194_CLK_PEX_SATA_USB_RX_BYP	254
+#define TEGRA194_CLK_PEX_USB_PAD_PLL0_MGMT	255
+#define TEGRA194_CLK_PEX_USB_PAD_PLL1_MGMT	256
+#define TEGRA194_CLK_PEX_USB_PAD_PLL2_MGMT	257
+#define TEGRA194_CLK_PEX_USB_PAD_PLL3_MGMT	258
+#define TEGRA194_CLK_XUSB_CORE_DEV		265
+#define TEGRA194_CLK_XUSB_CORE_MUX		266
+#define TEGRA194_CLK_XUSB_CORE_HOST		267
+#define TEGRA194_CLK_XUSB_CORE_SS		268
+#define TEGRA194_CLK_XUSB_FALCON		269
+#define TEGRA194_CLK_XUSB_FALCON_HOST		270
+#define TEGRA194_CLK_XUSB_FALCON_SS		271
+#define TEGRA194_CLK_XUSB_FS			272
+#define TEGRA194_CLK_XUSB_FS_HOST		273
+#define TEGRA194_CLK_XUSB_FS_DEV		274
+#define TEGRA194_CLK_XUSB_SS			275
+#define TEGRA194_CLK_XUSB_SS_DEV		276
+#define TEGRA194_CLK_XUSB_SS_SUPERSPEED		277
+#define TEGRA194_CLK_PLLDISPHUB			278
+#define TEGRA194_CLK_PLLDISPHUB_DIV		279
+#define TEGRA194_CLK_NAFLL_CLUSTER0		280
+#define TEGRA194_CLK_NAFLL_CLUSTER1		281
+#define TEGRA194_CLK_NAFLL_CLUSTER2		282
+#define TEGRA194_CLK_NAFLL_CLUSTER3		283
+#define TEGRA194_CLK_CAN1_CORE			284
+#define TEGRA194_CLK_CAN2_CORE			285
+#define TEGRA194_CLK_PLLA1_OUT1			286
+#define TEGRA194_CLK_PLLREFE_VCOOUT		288
+#define TEGRA194_CLK_CLK_32K			289
+#define TEGRA194_CLK_SPDIFIN_SYNC_INPUT		290
+#define TEGRA194_CLK_UTMIPLL_CLKOUT48		291
+#define TEGRA194_CLK_UTMIPLL_CLKOUT480		292
+#define TEGRA194_CLK_CVNAS			293
+#define TEGRA194_CLK_PLLNVCSI			294
+#define TEGRA194_CLK_PVA0_CPU_AXI		295
+#define TEGRA194_CLK_PVA1_CPU_AXI		296
+#define TEGRA194_CLK_PVA0_VPS			297
+#define TEGRA194_CLK_PVA1_VPS			298
+#define TEGRA194_CLK_DLA0_FALCON_MUX		299
+#define TEGRA194_CLK_DLA1_FALCON_MUX		300
+#define TEGRA194_CLK_DLA0_CORE_MUX		301
+#define TEGRA194_CLK_DLA1_CORE_MUX		302
+#define TEGRA194_CLK_UTMIPLL_HPS		304
+#define TEGRA194_CLK_I2C5			305
+#define TEGRA194_CLK_I2C10			306
+#define TEGRA194_CLK_BPMP_CPU_NIC		307
+#define TEGRA194_CLK_BPMP_APB			308
+#define TEGRA194_CLK_TSC			309
+#define TEGRA194_CLK_EMCSA			310
+#define TEGRA194_CLK_EMCSB			311
+#define TEGRA194_CLK_EMCSC			312
+#define TEGRA194_CLK_EMCSD			313
+#define TEGRA194_CLK_PLLC			314
+#define TEGRA194_CLK_PLLC2			315
+#define TEGRA194_CLK_PLLC3			316
+#define TEGRA194_CLK_TSC_REF			317
+#define TEGRA194_CLK_FUSE_BURN			318
+#define TEGRA194_CLK_PEX0_CORE_0M		319
+#define TEGRA194_CLK_PEX0_CORE_1M		320
+#define TEGRA194_CLK_PEX0_CORE_2M		321
+#define TEGRA194_CLK_PEX0_CORE_3M		322
+#define TEGRA194_CLK_PEX0_CORE_4M		323
+#define TEGRA194_CLK_PEX1_CORE_5M		324
+#define TEGRA194_CLK_PLLE_HPS			326
+
+#endif
diff --git a/include/dt-bindings/gpio/tegra194-gpio.h b/include/dt-bindings/gpio/tegra194-gpio.h
new file mode 100644
index 0000000..ede8602
--- /dev/null
+++ b/include/dt-bindings/gpio/tegra194-gpio.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. */
+
+/*
+ * This header provides constants for binding nvidia,tegra194-gpio*.
+ *
+ * The first cell in Tegra's GPIO specifier is the GPIO ID. The macros below
+ * provide names for this.
+ *
+ * The second cell contains standard flag values specified in gpio.h.
+ */
+
+#ifndef _DT_BINDINGS_GPIO_TEGRA194_GPIO_H
+#define _DT_BINDINGS_GPIO_TEGRA194_GPIO_H
+
+#include <dt-bindings/gpio/gpio.h>
+
+/* GPIOs implemented by main GPIO controller */
+#define TEGRA194_MAIN_GPIO_PORT_A 0
+#define TEGRA194_MAIN_GPIO_PORT_B 1
+#define TEGRA194_MAIN_GPIO_PORT_C 2
+#define TEGRA194_MAIN_GPIO_PORT_D 3
+#define TEGRA194_MAIN_GPIO_PORT_E 4
+#define TEGRA194_MAIN_GPIO_PORT_F 5
+#define TEGRA194_MAIN_GPIO_PORT_G 6
+#define TEGRA194_MAIN_GPIO_PORT_H 7
+#define TEGRA194_MAIN_GPIO_PORT_I 8
+#define TEGRA194_MAIN_GPIO_PORT_J 9
+#define TEGRA194_MAIN_GPIO_PORT_K 10
+#define TEGRA194_MAIN_GPIO_PORT_L 11
+#define TEGRA194_MAIN_GPIO_PORT_M 12
+#define TEGRA194_MAIN_GPIO_PORT_N 13
+#define TEGRA194_MAIN_GPIO_PORT_O 14
+#define TEGRA194_MAIN_GPIO_PORT_P 15
+#define TEGRA194_MAIN_GPIO_PORT_Q 16
+#define TEGRA194_MAIN_GPIO_PORT_R 17
+#define TEGRA194_MAIN_GPIO_PORT_S 18
+#define TEGRA194_MAIN_GPIO_PORT_T 19
+#define TEGRA194_MAIN_GPIO_PORT_U 20
+#define TEGRA194_MAIN_GPIO_PORT_V 21
+#define TEGRA194_MAIN_GPIO_PORT_W 22
+#define TEGRA194_MAIN_GPIO_PORT_X 23
+#define TEGRA194_MAIN_GPIO_PORT_Y 24
+#define TEGRA194_MAIN_GPIO_PORT_Z 25
+#define TEGRA194_MAIN_GPIO_PORT_FF 26
+#define TEGRA194_MAIN_GPIO_PORT_GG 27
+
+#define TEGRA194_MAIN_GPIO(port, offset) \
+	((TEGRA194_MAIN_GPIO_PORT_##port * 8) + offset)
+
+/* GPIOs implemented by AON GPIO controller */
+#define TEGRA194_AON_GPIO_PORT_AA 0
+#define TEGRA194_AON_GPIO_PORT_BB 1
+#define TEGRA194_AON_GPIO_PORT_CC 2
+#define TEGRA194_AON_GPIO_PORT_DD 3
+#define TEGRA194_AON_GPIO_PORT_EE 4
+
+#define TEGRA194_AON_GPIO(port, offset) \
+	((TEGRA194_AON_GPIO_PORT_##port * 8) + offset)
+
+#endif
diff --git a/include/dt-bindings/input/gpio-keys.h b/include/dt-bindings/input/gpio-keys.h
new file mode 100644
index 0000000..8962df7
--- /dev/null
+++ b/include/dt-bindings/input/gpio-keys.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides constants for gpio keys bindings.
+ */
+
+#ifndef _DT_BINDINGS_GPIO_KEYS_H
+#define _DT_BINDINGS_GPIO_KEYS_H
+
+#define EV_ACT_ANY		0x00	/* asserted or deasserted */
+#define EV_ACT_ASSERTED		0x01	/* asserted */
+#define EV_ACT_DEASSERTED	0x02	/* deasserted */
+
+#endif /* _DT_BINDINGS_GPIO_KEYS_H */
diff --git a/include/dt-bindings/mfd/stm32f7-rcc.h b/include/dt-bindings/mfd/stm32f7-rcc.h
index 8b7b719..a90f361 100644
--- a/include/dt-bindings/mfd/stm32f7-rcc.h
+++ b/include/dt-bindings/mfd/stm32f7-rcc.h
@@ -91,6 +91,7 @@
 #define STM32F7_RCC_APB2_TIM8		1
 #define STM32F7_RCC_APB2_USART1		4
 #define STM32F7_RCC_APB2_USART6		5
+#define STM32F7_RCC_APB2_SDMMC2		7
 #define STM32F7_RCC_APB2_ADC1		8
 #define STM32F7_RCC_APB2_ADC2		9
 #define STM32F7_RCC_APB2_ADC3		10
diff --git a/include/dt-bindings/power/mt2712-power.h b/include/dt-bindings/power/mt2712-power.h
index 92b46d7..2c14781 100644
--- a/include/dt-bindings/power/mt2712-power.h
+++ b/include/dt-bindings/power/mt2712-power.h
@@ -22,5 +22,8 @@
 #define MT2712_POWER_DOMAIN_USB		5
 #define MT2712_POWER_DOMAIN_USB2	6
 #define MT2712_POWER_DOMAIN_MFG		7
+#define MT2712_POWER_DOMAIN_MFG_SC1	8
+#define MT2712_POWER_DOMAIN_MFG_SC2	9
+#define MT2712_POWER_DOMAIN_MFG_SC3	10
 
 #endif /* _DT_BINDINGS_POWER_MT2712_POWER_H */
diff --git a/include/dt-bindings/power/mt7623a-power.h b/include/dt-bindings/power/mt7623a-power.h
new file mode 100644
index 0000000..2544822
--- /dev/null
+++ b/include/dt-bindings/power/mt7623a-power.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _DT_BINDINGS_POWER_MT7623A_POWER_H
+#define _DT_BINDINGS_POWER_MT7623A_POWER_H
+
+#define MT7623A_POWER_DOMAIN_CONN	0
+#define MT7623A_POWER_DOMAIN_ETH	1
+#define MT7623A_POWER_DOMAIN_HIF	2
+#define MT7623A_POWER_DOMAIN_IFR_MSC	3
+
+#endif /* _DT_BINDINGS_POWER_MT7623A_POWER_H */
diff --git a/include/dt-bindings/power/r8a77965-sysc.h b/include/dt-bindings/power/r8a77965-sysc.h
new file mode 100644
index 0000000..05a4b59
--- /dev/null
+++ b/include/dt-bindings/power/r8a77965-sysc.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
+ * Copyright (C) 2016 Glider bvba
+ */
+
+#ifndef __DT_BINDINGS_POWER_R8A77965_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A77965_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A77965_PD_CA57_CPU0		 0
+#define R8A77965_PD_CA57_CPU1		 1
+#define R8A77965_PD_A3VP		 9
+#define R8A77965_PD_CA57_SCU		12
+#define R8A77965_PD_CR7			13
+#define R8A77965_PD_A3VC		14
+#define R8A77965_PD_3DG_A		17
+#define R8A77965_PD_3DG_B		18
+#define R8A77965_PD_A3IR		24
+#define R8A77965_PD_A2VC1		26
+
+/* Always-on power area */
+#define R8A77965_PD_ALWAYS_ON		32
+
+#endif /* __DT_BINDINGS_POWER_R8A77965_SYSC_H__ */
diff --git a/include/dt-bindings/power/r8a77980-sysc.h b/include/dt-bindings/power/r8a77980-sysc.h
new file mode 100644
index 0000000..2c90c12
--- /dev/null
+++ b/include/dt-bindings/power/r8a77980-sysc.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A77980_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A77980_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A77980_PD_A2SC2		0
+#define R8A77980_PD_A2SC3		1
+#define R8A77980_PD_A2SC4		2
+#define R8A77980_PD_A2PD0		3
+#define R8A77980_PD_A2PD1		4
+#define R8A77980_PD_CA53_CPU0		5
+#define R8A77980_PD_CA53_CPU1		6
+#define R8A77980_PD_CA53_CPU2		7
+#define R8A77980_PD_CA53_CPU3		8
+#define R8A77980_PD_A2CN		10
+#define R8A77980_PD_A3VIP		11
+#define R8A77980_PD_A2IR5		12
+#define R8A77980_PD_CR7			13
+#define R8A77980_PD_A2IR4		15
+#define R8A77980_PD_CA53_SCU		21
+#define R8A77980_PD_A2IR0		23
+#define R8A77980_PD_A3IR		24
+#define R8A77980_PD_A3VIP1		25
+#define R8A77980_PD_A3VIP2		26
+#define R8A77980_PD_A2IR1		27
+#define R8A77980_PD_A2IR2		28
+#define R8A77980_PD_A2IR3		29
+#define R8A77980_PD_A2SC0		30
+#define R8A77980_PD_A2SC1		31
+
+/* Always-on power area */
+#define R8A77980_PD_ALWAYS_ON		32
+
+#endif /* __DT_BINDINGS_POWER_R8A77980_SYSC_H__ */
diff --git a/include/dt-bindings/power/tegra194-powergate.h b/include/dt-bindings/power/tegra194-powergate.h
new file mode 100644
index 0000000..8225374
--- /dev/null
+++ b/include/dt-bindings/power/tegra194-powergate.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. */
+
+#ifndef __ABI_MACH_T194_POWERGATE_T194_H_
+#define __ABI_MACH_T194_POWERGATE_T194_H_
+
+#define TEGRA194_POWER_DOMAIN_AUD	1
+#define TEGRA194_POWER_DOMAIN_DISP	2
+#define TEGRA194_POWER_DOMAIN_DISPB	3
+#define TEGRA194_POWER_DOMAIN_DISPC	4
+#define TEGRA194_POWER_DOMAIN_ISPA	5
+#define TEGRA194_POWER_DOMAIN_NVDECA	6
+#define TEGRA194_POWER_DOMAIN_NVJPG	7
+#define TEGRA194_POWER_DOMAIN_NVENCA	8
+#define TEGRA194_POWER_DOMAIN_NVENCB	9
+#define TEGRA194_POWER_DOMAIN_NVDECB	10
+#define TEGRA194_POWER_DOMAIN_SAX	11
+#define TEGRA194_POWER_DOMAIN_VE	12
+#define TEGRA194_POWER_DOMAIN_VIC	13
+#define TEGRA194_POWER_DOMAIN_XUSBA	14
+#define TEGRA194_POWER_DOMAIN_XUSBB	15
+#define TEGRA194_POWER_DOMAIN_XUSBC	16
+#define TEGRA194_POWER_DOMAIN_PCIEX8A	17
+#define TEGRA194_POWER_DOMAIN_PCIEX4A	18
+#define TEGRA194_POWER_DOMAIN_PCIEX1A	19
+#define TEGRA194_POWER_DOMAIN_PCIEX8B	21
+#define TEGRA194_POWER_DOMAIN_PVAA	22
+#define TEGRA194_POWER_DOMAIN_PVAB	23
+#define TEGRA194_POWER_DOMAIN_DLAA	24
+#define TEGRA194_POWER_DOMAIN_DLAB	25
+#define TEGRA194_POWER_DOMAIN_CV	26
+#define TEGRA194_POWER_DOMAIN_GPU	27
+#define TEGRA194_POWER_DOMAIN_MAX	27
+
+#endif
diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h
new file mode 100644
index 0000000..f0c3aae
--- /dev/null
+++ b/include/dt-bindings/reset/stm32mp1-resets.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP1_RESET_H_
+#define _DT_BINDINGS_STM32MP1_RESET_H_
+
+#define LTDC_R		3072
+#define DSI_R		3076
+#define DDRPERFM_R	3080
+#define USBPHY_R	3088
+#define SPI6_R		3136
+#define I2C4_R		3138
+#define I2C6_R		3139
+#define USART1_R	3140
+#define STGEN_R		3156
+#define GPIOZ_R		3200
+#define CRYP1_R		3204
+#define HASH1_R		3205
+#define RNG1_R		3206
+#define AXIM_R		3216
+#define GPU_R		3269
+#define ETHMAC_R	3274
+#define FMC_R		3276
+#define QSPI_R		3278
+#define SDMMC1_R	3280
+#define SDMMC2_R	3281
+#define CRC1_R		3284
+#define USBH_R		3288
+#define MDMA_R		3328
+#define MCU_R		8225
+#define TIM2_R		19456
+#define TIM3_R		19457
+#define TIM4_R		19458
+#define TIM5_R		19459
+#define TIM6_R		19460
+#define TIM7_R		19461
+#define TIM12_R		16462
+#define TIM13_R		16463
+#define TIM14_R		16464
+#define LPTIM1_R	19465
+#define SPI2_R		19467
+#define SPI3_R		19468
+#define USART2_R	19470
+#define USART3_R	19471
+#define UART4_R		19472
+#define UART5_R		19473
+#define UART7_R		19474
+#define UART8_R		19475
+#define I2C1_R		19477
+#define I2C2_R		19478
+#define I2C3_R		19479
+#define I2C5_R		19480
+#define SPDIF_R		19482
+#define CEC_R		19483
+#define DAC12_R		19485
+#define MDIO_R		19847
+#define TIM1_R		19520
+#define TIM8_R		19521
+#define TIM15_R		19522
+#define TIM16_R		19523
+#define TIM17_R		19524
+#define SPI1_R		19528
+#define SPI4_R		19529
+#define SPI5_R		19530
+#define USART6_R	19533
+#define SAI1_R		19536
+#define SAI2_R		19537
+#define SAI3_R		19538
+#define DFSDM_R		19540
+#define FDCAN_R		19544
+#define LPTIM2_R	19584
+#define LPTIM3_R	19585
+#define LPTIM4_R	19586
+#define LPTIM5_R	19587
+#define SAI4_R		19592
+#define SYSCFG_R	19595
+#define VREF_R		19597
+#define TMPSENS_R	19600
+#define PMBCTRL_R	19601
+#define DMA1_R		19648
+#define DMA2_R		19649
+#define DMAMUX_R	19650
+#define ADC12_R		19653
+#define USBO_R		19656
+#define SDMMC3_R	19664
+#define CAMITF_R	19712
+#define CRYP2_R		19716
+#define HASH2_R		19717
+#define RNG2_R		19718
+#define CRC2_R		19719
+#define HSEM_R		19723
+#define MBOX_R		19724
+#define GPIOA_R		19776
+#define GPIOB_R		19777
+#define GPIOC_R		19778
+#define GPIOD_R		19779
+#define GPIOE_R		19780
+#define GPIOF_R		19781
+#define GPIOG_R		19782
+#define GPIOH_R		19783
+#define GPIOI_R		19784
+#define GPIOJ_R		19785
+#define GPIOK_R		19786
+
+#endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */
diff --git a/include/dt-bindings/reset/tegra194-reset.h b/include/dt-bindings/reset/tegra194-reset.h
new file mode 100644
index 0000000..473afaa
--- /dev/null
+++ b/include/dt-bindings/reset/tegra194-reset.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. */
+
+#ifndef __ABI_MACH_T194_RESET_H
+#define __ABI_MACH_T194_RESET_H
+
+#define TEGRA194_RESET_ACTMON			1
+#define TEGRA194_RESET_ADSP_ALL			2
+#define TEGRA194_RESET_AFI			3
+#define TEGRA194_RESET_CAN1			4
+#define TEGRA194_RESET_CAN2			5
+#define TEGRA194_RESET_DLA0			6
+#define TEGRA194_RESET_DLA1			7
+#define TEGRA194_RESET_DPAUX			8
+#define TEGRA194_RESET_DPAUX1			9
+#define TEGRA194_RESET_DPAUX2			10
+#define TEGRA194_RESET_DPAUX3			11
+#define TEGRA194_RESET_EQOS			17
+#define TEGRA194_RESET_GPCDMA			18
+#define TEGRA194_RESET_GPU			19
+#define TEGRA194_RESET_HDA			20
+#define TEGRA194_RESET_HDA2CODEC_2X		21
+#define TEGRA194_RESET_HDA2HDMICODEC		22
+#define TEGRA194_RESET_HOST1X			23
+#define TEGRA194_RESET_I2C1			24
+#define TEGRA194_RESET_I2C10			25
+#define TEGRA194_RESET_RSVD_26			26
+#define TEGRA194_RESET_RSVD_27			27
+#define TEGRA194_RESET_RSVD_28			28
+#define TEGRA194_RESET_I2C2			29
+#define TEGRA194_RESET_I2C3			30
+#define TEGRA194_RESET_I2C4			31
+#define TEGRA194_RESET_I2C6			32
+#define TEGRA194_RESET_I2C7			33
+#define TEGRA194_RESET_I2C8			34
+#define TEGRA194_RESET_I2C9			35
+#define TEGRA194_RESET_ISP			36
+#define TEGRA194_RESET_MIPI_CAL			37
+#define TEGRA194_RESET_MPHY_CLK_CTL		38
+#define TEGRA194_RESET_MPHY_L0_RX		39
+#define TEGRA194_RESET_MPHY_L0_TX		40
+#define TEGRA194_RESET_MPHY_L1_RX		41
+#define TEGRA194_RESET_MPHY_L1_TX		42
+#define TEGRA194_RESET_NVCSI			43
+#define TEGRA194_RESET_NVDEC			44
+#define TEGRA194_RESET_NVDISPLAY0_HEAD0		45
+#define TEGRA194_RESET_NVDISPLAY0_HEAD1		46
+#define TEGRA194_RESET_NVDISPLAY0_HEAD2		47
+#define TEGRA194_RESET_NVDISPLAY0_HEAD3		48
+#define TEGRA194_RESET_NVDISPLAY0_MISC		49
+#define TEGRA194_RESET_NVDISPLAY0_WGRP0		50
+#define TEGRA194_RESET_NVDISPLAY0_WGRP1		51
+#define TEGRA194_RESET_NVDISPLAY0_WGRP2		52
+#define TEGRA194_RESET_NVDISPLAY0_WGRP3		53
+#define TEGRA194_RESET_NVDISPLAY0_WGRP4		54
+#define TEGRA194_RESET_NVDISPLAY0_WGRP5		55
+#define TEGRA194_RESET_RSVD_56			56
+#define TEGRA194_RESET_RSVD_57			57
+#define TEGRA194_RESET_RSVD_58			58
+#define TEGRA194_RESET_NVENC			59
+#define TEGRA194_RESET_NVENC1			60
+#define TEGRA194_RESET_NVJPG			61
+#define TEGRA194_RESET_PCIE			62
+#define TEGRA194_RESET_PCIEXCLK			63
+#define TEGRA194_RESET_RSVD_64			64
+#define TEGRA194_RESET_RSVD_65			65
+#define TEGRA194_RESET_PVA0_ALL			66
+#define TEGRA194_RESET_PVA1_ALL			67
+#define TEGRA194_RESET_PWM1			68
+#define TEGRA194_RESET_PWM2			69
+#define TEGRA194_RESET_PWM3			70
+#define TEGRA194_RESET_PWM4			71
+#define TEGRA194_RESET_PWM5			72
+#define TEGRA194_RESET_PWM6			73
+#define TEGRA194_RESET_PWM7			74
+#define TEGRA194_RESET_PWM8			75
+#define TEGRA194_RESET_QSPI0			76
+#define TEGRA194_RESET_QSPI1			77
+#define TEGRA194_RESET_SATA			78
+#define TEGRA194_RESET_SATACOLD			79
+#define TEGRA194_RESET_SCE_ALL			80
+#define TEGRA194_RESET_RCE_ALL			81
+#define TEGRA194_RESET_SDMMC1			82
+#define TEGRA194_RESET_RSVD_83			83
+#define TEGRA194_RESET_SDMMC3			84
+#define TEGRA194_RESET_SDMMC4			85
+#define TEGRA194_RESET_SE			86
+#define TEGRA194_RESET_SOR0			87
+#define TEGRA194_RESET_SOR1			88
+#define TEGRA194_RESET_SOR2			89
+#define TEGRA194_RESET_SOR3			90
+#define TEGRA194_RESET_SPI1			91
+#define TEGRA194_RESET_SPI2			92
+#define TEGRA194_RESET_SPI3			93
+#define TEGRA194_RESET_SPI4			94
+#define TEGRA194_RESET_TACH			95
+#define TEGRA194_RESET_RSVD_96			96
+#define TEGRA194_RESET_TSCTNVI			97
+#define TEGRA194_RESET_TSEC			98
+#define TEGRA194_RESET_TSECB			99
+#define TEGRA194_RESET_UARTA			100
+#define TEGRA194_RESET_UARTB			101
+#define TEGRA194_RESET_UARTC			102
+#define TEGRA194_RESET_UARTD			103
+#define TEGRA194_RESET_UARTE			104
+#define TEGRA194_RESET_UARTF			105
+#define TEGRA194_RESET_UARTG			106
+#define TEGRA194_RESET_UARTH			107
+#define TEGRA194_RESET_UFSHC			108
+#define TEGRA194_RESET_UFSHC_AXI_M		109
+#define TEGRA194_RESET_UFSHC_LP_SEQ		110
+#define TEGRA194_RESET_RSVD_111			111
+#define TEGRA194_RESET_VI			112
+#define TEGRA194_RESET_VIC			113
+#define TEGRA194_RESET_XUSB_PADCTL		114
+#define TEGRA194_RESET_NVDEC1			115
+#define TEGRA194_RESET_PEX0_CORE_0		116
+#define TEGRA194_RESET_PEX0_CORE_1		117
+#define TEGRA194_RESET_PEX0_CORE_2		118
+#define TEGRA194_RESET_PEX0_CORE_3		119
+#define TEGRA194_RESET_PEX0_CORE_4		120
+#define TEGRA194_RESET_PEX0_CORE_0_APB		121
+#define TEGRA194_RESET_PEX0_CORE_1_APB		122
+#define TEGRA194_RESET_PEX0_CORE_2_APB		123
+#define TEGRA194_RESET_PEX0_CORE_3_APB		124
+#define TEGRA194_RESET_PEX0_CORE_4_APB		125
+#define TEGRA194_RESET_PEX0_COMMON_APB		126
+#define TEGRA194_RESET_PEX1_CORE_5		129
+#define TEGRA194_RESET_PEX1_CORE_5_APB		130
+#define TEGRA194_RESET_CVNAS			131
+#define TEGRA194_RESET_CVNAS_FCM		132
+#define TEGRA194_RESET_DMIC5			144
+#define TEGRA194_RESET_APE			145
+#define TEGRA194_RESET_PEX_USB_UPHY		146
+#define TEGRA194_RESET_PEX_USB_UPHY_L0		147
+#define TEGRA194_RESET_PEX_USB_UPHY_L1		148
+#define TEGRA194_RESET_PEX_USB_UPHY_L2		149
+#define TEGRA194_RESET_PEX_USB_UPHY_L3		150
+#define TEGRA194_RESET_PEX_USB_UPHY_L4		151
+#define TEGRA194_RESET_PEX_USB_UPHY_L5		152
+#define TEGRA194_RESET_PEX_USB_UPHY_L6		153
+#define TEGRA194_RESET_PEX_USB_UPHY_L7		154
+#define TEGRA194_RESET_PEX_USB_UPHY_L8		155
+#define TEGRA194_RESET_PEX_USB_UPHY_L9		156
+#define TEGRA194_RESET_PEX_USB_UPHY_L10		157
+#define TEGRA194_RESET_PEX_USB_UPHY_L11		158
+#define TEGRA194_RESET_PEX_USB_UPHY_PLL0	159
+#define TEGRA194_RESET_PEX_USB_UPHY_PLL1	160
+#define TEGRA194_RESET_PEX_USB_UPHY_PLL2	161
+#define TEGRA194_RESET_PEX_USB_UPHY_PLL3	162
+
+#endif
diff --git a/include/dt-bindings/sound/rt5651.h b/include/dt-bindings/sound/rt5651.h
new file mode 100644
index 0000000..2f2dac9
--- /dev/null
+++ b/include/dt-bindings/sound/rt5651.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_RT5651_H
+#define __DT_RT5651_H
+
+#define RT5651_JD_NULL			0
+#define RT5651_JD1_1			1
+#define RT5651_JD1_2			2
+#define RT5651_JD2			3
+
+#define RT5651_OVCD_SF_0P5		0
+#define RT5651_OVCD_SF_0P75		1
+#define RT5651_OVCD_SF_1P0		2
+#define RT5651_OVCD_SF_1P5		3
+
+#endif /* __DT_RT5651_H */
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 69bea82..6c666fd 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -88,6 +88,7 @@ struct blkg_policy_data {
 	/* the blkg and policy id this per-policy data belongs to */
 	struct blkcg_gq			*blkg;
 	int				plid;
+	bool				offline;
 };
 
 /*
diff --git a/include/linux/blk-mq-pci.h b/include/linux/blk-mq-pci.h
index 6338551..9f4c17f 100644
--- a/include/linux/blk-mq-pci.h
+++ b/include/linux/blk-mq-pci.h
@@ -5,6 +5,7 @@
 struct blk_mq_tag_set;
 struct pci_dev;
 
-int blk_mq_pci_map_queues(struct blk_mq_tag_set *set, struct pci_dev *pdev);
+int blk_mq_pci_map_queues(struct blk_mq_tag_set *set, struct pci_dev *pdev,
+			  int offset);
 
 #endif /* _LINUX_BLK_MQ_PCI_H */
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index bf18b95..17b18b9 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -20,8 +20,13 @@ typedef void (bio_end_io_t) (struct bio *);
 
 /*
  * Block error status values.  See block/blk-core:blk_errors for the details.
+ * Alpha cannot write a byte atomically, so we need to use 32-bit value.
  */
+#if defined(CONFIG_ALPHA) && !defined(__alpha_bwx__)
+typedef u32 __bitwise blk_status_t;
+#else
 typedef u8 __bitwise blk_status_t;
+#endif
 #define	BLK_STS_OK 0
 #define BLK_STS_NOTSUPP		((__force blk_status_t)1)
 #define BLK_STS_TIMEOUT		((__force blk_status_t)2)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ed63f3b..9af3e0f 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -707,73 +707,10 @@ struct request_queue {
 				 (1 << QUEUE_FLAG_SAME_COMP)	|	\
 				 (1 << QUEUE_FLAG_POLL))
 
-/*
- * @q->queue_lock is set while a queue is being initialized. Since we know
- * that no other threads access the queue object before @q->queue_lock has
- * been set, it is safe to manipulate queue flags without holding the
- * queue_lock if @q->queue_lock == NULL. See also blk_alloc_queue_node() and
- * blk_init_allocated_queue().
- */
-static inline void queue_lockdep_assert_held(struct request_queue *q)
-{
-	if (q->queue_lock)
-		lockdep_assert_held(q->queue_lock);
-}
-
-static inline void queue_flag_set_unlocked(unsigned int flag,
-					   struct request_queue *q)
-{
-	__set_bit(flag, &q->queue_flags);
-}
-
-static inline int queue_flag_test_and_clear(unsigned int flag,
-					    struct request_queue *q)
-{
-	queue_lockdep_assert_held(q);
-
-	if (test_bit(flag, &q->queue_flags)) {
-		__clear_bit(flag, &q->queue_flags);
-		return 1;
-	}
-
-	return 0;
-}
-
-static inline int queue_flag_test_and_set(unsigned int flag,
-					  struct request_queue *q)
-{
-	queue_lockdep_assert_held(q);
-
-	if (!test_bit(flag, &q->queue_flags)) {
-		__set_bit(flag, &q->queue_flags);
-		return 0;
-	}
-
-	return 1;
-}
-
-static inline void queue_flag_set(unsigned int flag, struct request_queue *q)
-{
-	queue_lockdep_assert_held(q);
-	__set_bit(flag, &q->queue_flags);
-}
-
-static inline void queue_flag_clear_unlocked(unsigned int flag,
-					     struct request_queue *q)
-{
-	__clear_bit(flag, &q->queue_flags);
-}
-
-static inline int queue_in_flight(struct request_queue *q)
-{
-	return q->in_flight[0] + q->in_flight[1];
-}
-
-static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
-{
-	queue_lockdep_assert_held(q);
-	__clear_bit(flag, &q->queue_flags);
-}
+void blk_queue_flag_set(unsigned int flag, struct request_queue *q);
+void blk_queue_flag_clear(unsigned int flag, struct request_queue *q);
+bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q);
+bool blk_queue_flag_test_and_clear(unsigned int flag, struct request_queue *q);
 
 #define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
 #define blk_queue_stopped(q)	test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
@@ -804,6 +741,11 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
 extern int blk_set_preempt_only(struct request_queue *q);
 extern void blk_clear_preempt_only(struct request_queue *q);
 
+static inline int queue_in_flight(struct request_queue *q)
+{
+	return q->in_flight[0] + q->in_flight[1];
+}
+
 static inline bool blk_account_rq(struct request *rq)
 {
 	return (rq->rq_flags & RQF_STARTED) && !blk_rq_is_passthrough(rq);
@@ -1080,6 +1022,19 @@ static inline struct request_queue *bdev_get_queue(struct block_device *bdev)
 }
 
 /*
+ * The basic unit of block I/O is a sector. It is used in a number of contexts
+ * in Linux (blk, bio, genhd). The size of one sector is 512 = 2**9
+ * bytes. Variables of type sector_t represent an offset or size that is a
+ * multiple of 512 bytes. Hence these two constants.
+ */
+#ifndef SECTOR_SHIFT
+#define SECTOR_SHIFT 9
+#endif
+#ifndef SECTOR_SIZE
+#define SECTOR_SIZE (1 << SECTOR_SHIFT)
+#endif
+
+/*
  * blk_rq_pos()			: the current sector
  * blk_rq_bytes()		: bytes left in the entire request
  * blk_rq_cur_bytes()		: bytes left in the current segment
@@ -1106,12 +1061,12 @@ extern unsigned int blk_rq_err_bytes(const struct request *rq);
 
 static inline unsigned int blk_rq_sectors(const struct request *rq)
 {
-	return blk_rq_bytes(rq) >> 9;
+	return blk_rq_bytes(rq) >> SECTOR_SHIFT;
 }
 
 static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
 {
-	return blk_rq_cur_bytes(rq) >> 9;
+	return blk_rq_cur_bytes(rq) >> SECTOR_SHIFT;
 }
 
 static inline unsigned int blk_rq_zone_no(struct request *rq)
@@ -1141,7 +1096,8 @@ static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
 						     int op)
 {
 	if (unlikely(op == REQ_OP_DISCARD || op == REQ_OP_SECURE_ERASE))
-		return min(q->limits.max_discard_sectors, UINT_MAX >> 9);
+		return min(q->limits.max_discard_sectors,
+			   UINT_MAX >> SECTOR_SHIFT);
 
 	if (unlikely(op == REQ_OP_WRITE_SAME))
 		return q->limits.max_write_same_sectors;
@@ -1321,7 +1277,8 @@ extern long nr_blockdev_pages(void);
 
 bool __must_check blk_get_queue(struct request_queue *);
 struct request_queue *blk_alloc_queue(gfp_t);
-struct request_queue *blk_alloc_queue_node(gfp_t, int);
+struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id,
+					   spinlock_t *lock);
 extern void blk_put_queue(struct request_queue *);
 extern void blk_set_queue_dying(struct request_queue *);
 
@@ -1452,16 +1409,21 @@ extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
 static inline int sb_issue_discard(struct super_block *sb, sector_t block,
 		sector_t nr_blocks, gfp_t gfp_mask, unsigned long flags)
 {
-	return blkdev_issue_discard(sb->s_bdev, block << (sb->s_blocksize_bits - 9),
-				    nr_blocks << (sb->s_blocksize_bits - 9),
+	return blkdev_issue_discard(sb->s_bdev,
+				    block << (sb->s_blocksize_bits -
+					      SECTOR_SHIFT),
+				    nr_blocks << (sb->s_blocksize_bits -
+						  SECTOR_SHIFT),
 				    gfp_mask, flags);
 }
 static inline int sb_issue_zeroout(struct super_block *sb, sector_t block,
 		sector_t nr_blocks, gfp_t gfp_mask)
 {
 	return blkdev_issue_zeroout(sb->s_bdev,
-				    block << (sb->s_blocksize_bits - 9),
-				    nr_blocks << (sb->s_blocksize_bits - 9),
+				    block << (sb->s_blocksize_bits -
+					      SECTOR_SHIFT),
+				    nr_blocks << (sb->s_blocksize_bits -
+						  SECTOR_SHIFT),
 				    gfp_mask, 0);
 }
 
@@ -1568,7 +1530,8 @@ static inline int queue_alignment_offset(struct request_queue *q)
 static inline int queue_limit_alignment_offset(struct queue_limits *lim, sector_t sector)
 {
 	unsigned int granularity = max(lim->physical_block_size, lim->io_min);
-	unsigned int alignment = sector_div(sector, granularity >> 9) << 9;
+	unsigned int alignment = sector_div(sector, granularity >> SECTOR_SHIFT)
+		<< SECTOR_SHIFT;
 
 	return (granularity + lim->alignment_offset - alignment) % granularity;
 }
@@ -1602,8 +1565,8 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector
 		return 0;
 
 	/* Why are these in bytes, not sectors? */
-	alignment = lim->discard_alignment >> 9;
-	granularity = lim->discard_granularity >> 9;
+	alignment = lim->discard_alignment >> SECTOR_SHIFT;
+	granularity = lim->discard_granularity >> SECTOR_SHIFT;
 	if (!granularity)
 		return 0;
 
@@ -1614,7 +1577,7 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector
 	offset = (granularity + alignment - offset) % granularity;
 
 	/* Turn it back into bytes, gaah */
-	return offset << 9;
+	return offset << SECTOR_SHIFT;
 }
 
 static inline int bdev_discard_alignment(struct block_device *bdev)
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index b1be023..28a7ccc 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -38,12 +38,12 @@ struct bsg_buffer {
 };
 
 struct bsg_job {
-	struct scsi_request sreq;
 	struct device *dev;
-	struct request *req;
 
 	struct kref kref;
 
+	unsigned int timeout;
+
 	/* Transport/driver specific request/reply structs */
 	void *request;
 	void *reply;
@@ -63,6 +63,9 @@ struct bsg_job {
 	struct bsg_buffer request_payload;
 	struct bsg_buffer reply_payload;
 
+	int result;
+	unsigned int reply_payload_rcv_len;
+
 	void *dd_data;		/* Used for driver-specific storage */
 };
 
diff --git a/include/linux/bsg.h b/include/linux/bsg.h
index 2a202e4..0c7dd9c 100644
--- a/include/linux/bsg.h
+++ b/include/linux/bsg.h
@@ -1,34 +1,43 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef BSG_H
-#define BSG_H
+#ifndef _LINUX_BSG_H
+#define _LINUX_BSG_H
 
 #include <uapi/linux/bsg.h>
 
+struct request;
 
-#if defined(CONFIG_BLK_DEV_BSG)
+#ifdef CONFIG_BLK_DEV_BSG
+struct bsg_ops {
+	int	(*check_proto)(struct sg_io_v4 *hdr);
+	int	(*fill_hdr)(struct request *rq, struct sg_io_v4 *hdr,
+				fmode_t mode);
+	int	(*complete_rq)(struct request *rq, struct sg_io_v4 *hdr);
+	void	(*free_rq)(struct request *rq);
+};
+
 struct bsg_class_device {
 	struct device *class_dev;
 	struct device *parent;
 	int minor;
 	struct request_queue *queue;
 	struct kref ref;
+	const struct bsg_ops *ops;
 	void (*release)(struct device *);
 };
 
-extern int bsg_register_queue(struct request_queue *q,
-			      struct device *parent, const char *name,
-			      void (*release)(struct device *));
-extern void bsg_unregister_queue(struct request_queue *);
+int bsg_register_queue(struct request_queue *q, struct device *parent,
+		const char *name, const struct bsg_ops *ops,
+		void (*release)(struct device *));
+int bsg_scsi_register_queue(struct request_queue *q, struct device *parent);
+void bsg_unregister_queue(struct request_queue *q);
 #else
-static inline int bsg_register_queue(struct request_queue *q,
-				     struct device *parent, const char *name,
-				     void (*release)(struct device *))
+static inline int bsg_scsi_register_queue(struct request_queue *q,
+		struct device *parent)
 {
 	return 0;
 }
 static inline void bsg_unregister_queue(struct request_queue *q)
 {
 }
-#endif
-
-#endif
+#endif /* CONFIG_BLK_DEV_BSG */
+#endif /* _LINUX_BSG_H */
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index d18da83..7e3bcee 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -203,6 +203,7 @@ enum {
 	TI_CLKM_PRM,
 	TI_CLKM_SCRM,
 	TI_CLKM_CTRL,
+	TI_CLKM_CTRL_AUX,
 	TI_CLKM_PLLSS,
 	CLK_MAX_MEMMAPS
 };
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 9847c5a0..f188eab 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -226,6 +226,8 @@ typedef struct compat_siginfo {
 #ifdef __ARCH_SI_TRAPNO
 			int _trapno;	/* TRAP # which caused the signal */
 #endif
+#define __COMPAT_ADDR_BND_PKEY_PAD  (__alignof__(compat_uptr_t) < sizeof(short) ? \
+				     sizeof(short) : __alignof__(compat_uptr_t))
 			union {
 				/*
 				 * used when si_code=BUS_MCEERR_AR or
@@ -234,13 +236,13 @@ typedef struct compat_siginfo {
 				short int _addr_lsb;	/* Valid LSB of the reported address. */
 				/* used when si_code=SEGV_BNDERR */
 				struct {
-					compat_uptr_t _dummy_bnd;
+					char _dummy_bnd[__COMPAT_ADDR_BND_PKEY_PAD];
 					compat_uptr_t _lower;
 					compat_uptr_t _upper;
 				} _addr_bnd;
 				/* used when si_code=SEGV_PKUERR */
 				struct {
-					compat_uptr_t _dummy_pkey;
+					char _dummy_pkey[__COMPAT_ADDR_BND_PKEY_PAD];
 					u32 _pkey;
 				} _addr_pkey;
 			};
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index da83f64..31fef7c 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -87,10 +87,10 @@ typedef void (*dm_resume_fn) (struct dm_target *ti);
 typedef void (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
 			      unsigned status_flags, char *result, unsigned maxlen);
 
-typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);
+typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv,
+			      char *result, unsigned maxlen);
 
-typedef int (*dm_prepare_ioctl_fn) (struct dm_target *ti,
-			    struct block_device **bdev, fmode_t *mode);
+typedef int (*dm_prepare_ioctl_fn) (struct dm_target *ti, struct block_device **bdev);
 
 /*
  * These iteration functions are typically used to check (and combine)
@@ -267,6 +267,12 @@ struct dm_target {
 	unsigned num_discard_bios;
 
 	/*
+	 * The number of secure erase bios that will be submitted to the target.
+	 * The bio number can be accessed with dm_bio_get_target_bio_nr.
+	 */
+	unsigned num_secure_erase_bios;
+
+	/*
 	 * The number of WRITE SAME bios that will be submitted to the target.
 	 * The bio number can be accessed with dm_bio_get_target_bio_nr.
 	 */
@@ -542,8 +548,6 @@ do {									\
 #define DMEMIT(x...) sz += ((sz >= maxlen) ? \
 			  0 : scnprintf(result + sz, maxlen - sz, x))
 
-#define SECTOR_SHIFT 9
-
 /*
  * Definitions of return values from target end_io function.
  */
diff --git a/drivers/md/dm-bufio.h b/include/linux/dm-bufio.h
similarity index 98%
rename from drivers/md/dm-bufio.h
rename to include/linux/dm-bufio.h
index be732d3..3c8b7d2 100644
--- a/drivers/md/dm-bufio.h
+++ b/include/linux/dm-bufio.h
@@ -6,8 +6,8 @@
  * This file is released under the GPL.
  */
 
-#ifndef DM_BUFIO_H
-#define DM_BUFIO_H
+#ifndef _LINUX_DM_BUFIO_H
+#define _LINUX_DM_BUFIO_H
 
 #include <linux/blkdev.h>
 #include <linux/types.h>
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 12fedcb..f8ab1c0 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -212,14 +212,14 @@ static inline void set_dma_ops(struct device *dev,
 }
 #else
 /*
- * Define the dma api to allow compilation but not linking of
- * dma dependent code.  Code that depends on the dma-mapping
- * API needs to set 'depends on HAS_DMA' in its Kconfig
+ * Define the dma api to allow compilation of dma dependent code.
+ * Code that depends on the dma-mapping API needs to set 'depends on HAS_DMA'
+ * in its Kconfig, unless it already depends on <something> || COMPILE_TEST,
+ * where <something> guarantuees the availability of the dma-mapping API.
  */
-extern const struct dma_map_ops bad_dma_ops;
 static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-	return &bad_dma_ops;
+	return NULL;
 }
 #endif
 
@@ -772,10 +772,19 @@ static inline void dma_deconfigure(struct device *dev) {}
 /*
  * Managed DMA API
  */
+#ifdef CONFIG_HAS_DMA
 extern void *dmam_alloc_coherent(struct device *dev, size_t size,
 				 dma_addr_t *dma_handle, gfp_t gfp);
 extern void dmam_free_coherent(struct device *dev, size_t size, void *vaddr,
 			       dma_addr_t dma_handle);
+#else /* !CONFIG_HAS_DMA */
+static inline void *dmam_alloc_coherent(struct device *dev, size_t size,
+					dma_addr_t *dma_handle, gfp_t gfp)
+{ return NULL; }
+static inline void dmam_free_coherent(struct device *dev, size_t size,
+				      void *vaddr, dma_addr_t dma_handle) { }
+#endif /* !CONFIG_HAS_DMA */
+
 extern void *dmam_alloc_attrs(struct device *dev, size_t size,
 			      dma_addr_t *dma_handle, gfp_t gfp,
 			      unsigned long attrs);
diff --git a/include/linux/dmapool.h b/include/linux/dmapool.h
index 53ba737..f632ecf 100644
--- a/include/linux/dmapool.h
+++ b/include/linux/dmapool.h
@@ -16,6 +16,8 @@
 
 struct device;
 
+#ifdef CONFIG_HAS_DMA
+
 struct dma_pool *dma_pool_create(const char *name, struct device *dev, 
 			size_t size, size_t align, size_t allocation);
 
@@ -23,13 +25,6 @@ void dma_pool_destroy(struct dma_pool *pool);
 
 void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
 		     dma_addr_t *handle);
-
-static inline void *dma_pool_zalloc(struct dma_pool *pool, gfp_t mem_flags,
-				    dma_addr_t *handle)
-{
-	return dma_pool_alloc(pool, mem_flags | __GFP_ZERO, handle);
-}
-
 void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t addr);
 
 /*
@@ -39,5 +34,26 @@ struct dma_pool *dmam_pool_create(const char *name, struct device *dev,
 				  size_t size, size_t align, size_t allocation);
 void dmam_pool_destroy(struct dma_pool *pool);
 
+#else /* !CONFIG_HAS_DMA */
+static inline struct dma_pool *dma_pool_create(const char *name,
+	struct device *dev, size_t size, size_t align, size_t allocation)
+{ return NULL; }
+static inline void dma_pool_destroy(struct dma_pool *pool) { }
+static inline void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
+				   dma_addr_t *handle) { return NULL; }
+static inline void dma_pool_free(struct dma_pool *pool, void *vaddr,
+				 dma_addr_t addr) { }
+static inline struct dma_pool *dmam_pool_create(const char *name,
+	struct device *dev, size_t size, size_t align, size_t allocation)
+{ return NULL; }
+static inline void dmam_pool_destroy(struct dma_pool *pool) { }
+#endif /* !CONFIG_HAS_DMA */
+
+static inline void *dma_pool_zalloc(struct dma_pool *pool, gfp_t mem_flags,
+				    dma_addr_t *handle)
+{
+	return dma_pool_alloc(pool, mem_flags | __GFP_ZERO, handle);
+}
+
 #endif
 
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index 6a86d8d..c46fdb3 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -114,6 +114,7 @@ extern int dmi_walk(void (*decode)(const struct dmi_header *, void *),
 	void *private_data);
 extern bool dmi_match(enum dmi_field f, const char *str);
 extern void dmi_memdev_name(u16 handle, const char **bank, const char **device);
+extern u64 dmi_memdev_size(u16 handle);
 
 #else
 
@@ -144,6 +145,7 @@ static inline bool dmi_match(enum dmi_field f, const char *str)
 	{ return false; }
 static inline void dmi_memdev_name(u16 handle, const char **bank,
 		const char **device) { }
+static inline u64 dmi_memdev_size(u16 handle) { return ~0ul; }
 static inline const struct dmi_system_id *
 	dmi_first_match(const struct dmi_system_id *list) { return NULL; }
 
diff --git a/include/linux/edac.h b/include/linux/edac.h
index cd75c17..bffb978 100644
--- a/include/linux/edac.h
+++ b/include/linux/edac.h
@@ -186,6 +186,7 @@ static inline char *mc_event_error_type(const unsigned int err_type)
  * @MEM_RDDR4:		Registered DDR4 RAM
  *			This is a variant of the DDR4 memories.
  * @MEM_LRDDR4:		Load-Reduced DDR4 memory.
+ * @MEM_NVDIMM:		Non-volatile RAM
  */
 enum mem_type {
 	MEM_EMPTY = 0,
@@ -209,6 +210,7 @@ enum mem_type {
 	MEM_DDR4,
 	MEM_RDDR4,
 	MEM_LRDDR4,
+	MEM_NVDIMM,
 };
 
 #define MEM_FLAG_EMPTY		BIT(MEM_EMPTY)
@@ -231,6 +233,7 @@ enum mem_type {
 #define MEM_FLAG_DDR4           BIT(MEM_DDR4)
 #define MEM_FLAG_RDDR4          BIT(MEM_RDDR4)
 #define MEM_FLAG_LRDDR4         BIT(MEM_LRDDR4)
+#define MEM_FLAG_NVDIMM         BIT(MEM_NVDIMM)
 
 /**
  * enum edac-type - Error Detection and Correction capabilities and mode
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 58aecb6..aa5db8b 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -21,6 +21,7 @@
 #define F2FS_BLKSIZE			4096	/* support only 4KB block */
 #define F2FS_BLKSIZE_BITS		12	/* bits for F2FS_BLKSIZE */
 #define F2FS_MAX_EXTENSION		64	/* # of extension entries */
+#define F2FS_EXTENSION_LEN		8	/* max size of extension */
 #define F2FS_BLK_ALIGN(x)	(((x) + F2FS_BLKSIZE - 1) >> F2FS_BLKSIZE_BITS)
 
 #define NULL_ADDR		((block_t)0)	/* used as block_t addresses */
@@ -38,15 +39,14 @@
 
 #define F2FS_MAX_QUOTAS		3
 
-#define F2FS_IO_SIZE(sbi)	(1 << (sbi)->write_io_size_bits) /* Blocks */
-#define F2FS_IO_SIZE_KB(sbi)	(1 << ((sbi)->write_io_size_bits + 2)) /* KB */
-#define F2FS_IO_SIZE_BYTES(sbi)	(1 << ((sbi)->write_io_size_bits + 12)) /* B */
-#define F2FS_IO_SIZE_BITS(sbi)	((sbi)->write_io_size_bits) /* power of 2 */
+#define F2FS_IO_SIZE(sbi)	(1 << F2FS_OPTION(sbi).write_io_size_bits) /* Blocks */
+#define F2FS_IO_SIZE_KB(sbi)	(1 << (F2FS_OPTION(sbi).write_io_size_bits + 2)) /* KB */
+#define F2FS_IO_SIZE_BYTES(sbi)	(1 << (F2FS_OPTION(sbi).write_io_size_bits + 12)) /* B */
+#define F2FS_IO_SIZE_BITS(sbi)	(F2FS_OPTION(sbi).write_io_size_bits) /* power of 2 */
 #define F2FS_IO_SIZE_MASK(sbi)	(F2FS_IO_SIZE(sbi) - 1)
 
 /* This flag is used by node and meta inodes, and by recovery */
 #define GFP_F2FS_ZERO		(GFP_NOFS | __GFP_ZERO)
-#define GFP_F2FS_HIGH_ZERO	(GFP_NOFS | __GFP_ZERO | __GFP_HIGHMEM)
 
 /*
  * For further optimization on multi-head logs, on-disk layout supports maximum
@@ -102,7 +102,7 @@ struct f2fs_super_block {
 	__u8 uuid[16];			/* 128-bit uuid for volume */
 	__le16 volume_name[MAX_VOLUME_NAME];	/* volume name */
 	__le32 extension_count;		/* # of extensions below */
-	__u8 extension_list[F2FS_MAX_EXTENSION][8];	/* extension array */
+	__u8 extension_list[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];/* extension array */
 	__le32 cp_payload;
 	__u8 version[VERSION_LEN];	/* the kernel version */
 	__u8 init_version[VERSION_LEN];	/* the initial kernel version */
@@ -111,12 +111,14 @@ struct f2fs_super_block {
 	__u8 encrypt_pw_salt[16];	/* Salt used for string2key algorithm */
 	struct f2fs_device devs[MAX_DEVICES];	/* device list */
 	__le32 qf_ino[F2FS_MAX_QUOTAS];	/* quota inode numbers */
-	__u8 reserved[315];		/* valid reserved region */
+	__u8 hot_ext_count;		/* # of hot file extension */
+	__u8 reserved[314];		/* valid reserved region */
 } __packed;
 
 /*
  * For checkpoint
  */
+#define CP_LARGE_NAT_BITMAP_FLAG	0x00000400
 #define CP_NOCRC_RECOVERY_FLAG	0x00000200
 #define CP_TRIMMED_FLAG		0x00000100
 #define CP_NAT_BITS_FLAG	0x00000080
@@ -303,6 +305,10 @@ struct f2fs_node {
  */
 #define NAT_ENTRY_PER_BLOCK (PAGE_SIZE / sizeof(struct f2fs_nat_entry))
 #define NAT_ENTRY_BITMAP_SIZE	((NAT_ENTRY_PER_BLOCK + 7) / 8)
+#define NAT_ENTRY_BITMAP_SIZE_ALIGNED				\
+	((NAT_ENTRY_BITMAP_SIZE + BITS_PER_LONG - 1) /		\
+	BITS_PER_LONG * BITS_PER_LONG)
+
 
 struct f2fs_nat_entry {
 	__u8 version;		/* latest version of cached nat entry */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c6baf76..0d79805 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2015,7 +2015,8 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
 #define I_WB_SWITCH		(1 << 13)
 #define I_OVL_INUSE			(1 << 14)
 
-#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
+#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
+#define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
 #define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME)
 
 extern void __mark_inode_dirty(struct inode *, int);
@@ -2381,8 +2382,8 @@ struct audit_names;
 struct filename {
 	const char		*name;	/* pointer to actual string */
 	const __user char	*uptr;	/* original userland pointer */
-	struct audit_names	*aname;
 	int			refcnt;
+	struct audit_names	*aname;
 	const char		iname[];
 };
 
@@ -2977,12 +2978,6 @@ enum {
 
 	/* filesystem does not support filling holes */
 	DIO_SKIP_HOLES	= 0x02,
-
-	/* filesystem can handle aio writes beyond i_size */
-	DIO_ASYNC_EXTEND = 0x04,
-
-	/* inode/fs/bdev does not need truncate protection */
-	DIO_SKIP_DIO_COUNT = 0x08,
 };
 
 void dio_end_io(struct bio *bio);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 067d52e..9f1edb9 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -331,6 +331,12 @@ extern int fsnotify_add_event(struct fsnotify_group *group,
 			      struct fsnotify_event *event,
 			      int (*merge)(struct list_head *,
 					   struct fsnotify_event *));
+/* Queue overflow event to a notification group */
+static inline void fsnotify_queue_overflow(struct fsnotify_group *group)
+{
+	fsnotify_add_event(group, group->overflow_event, NULL);
+}
+
 /* true if the group notification queue is empty */
 extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
 /* return, but do not dequeue the first event on the notification queue */
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 1ba9a33..5382b51 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -288,6 +288,21 @@ struct gpio_chip {
 	struct gpio_irq_chip irq;
 #endif
 
+	/**
+	 * @need_valid_mask:
+	 *
+	 * If set core allocates @valid_mask with all bits set to one.
+	 */
+	bool need_valid_mask;
+
+	/**
+	 * @valid_mask:
+	 *
+	 * If not %NULL holds bitmask of GPIOs which are valid to be used
+	 * from the chip.
+	 */
+	unsigned long *valid_mask;
+
 #if defined(CONFIG_OF_GPIO)
 	/*
 	 * If CONFIG_OF is enabled, then all GPIO controllers described in the
@@ -384,6 +399,7 @@ bool gpiochip_line_is_open_source(struct gpio_chip *chip, unsigned int offset);
 
 /* Sleep persistence inquiry for drivers */
 bool gpiochip_line_is_persistent(struct gpio_chip *chip, unsigned int offset);
+bool gpiochip_line_is_valid(const struct gpio_chip *chip, unsigned int offset);
 
 /* get driver data */
 void *gpiochip_get_data(struct gpio_chip *chip);
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index d06bf77..7160df5 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -13,6 +13,7 @@ struct device;
  * @desc:		label that will be attached to button's gpio
  * @type:		input event type (%EV_KEY, %EV_SW, %EV_ABS)
  * @wakeup:		configure the button as a wake-up source
+ * @wakeup_event_action:	event action to trigger wakeup
  * @debounce_interval:	debounce ticks interval in msecs
  * @can_disable:	%true indicates that userspace is allowed to
  *			disable button via sysfs
@@ -26,6 +27,7 @@ struct gpio_keys_button {
 	const char *desc;
 	unsigned int type;
 	int wakeup;
+	int wakeup_event_action;
 	int debounce_interval;
 	bool can_disable;
 	int value;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 091a81c..8da3e1f 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -26,6 +26,7 @@
 #define __HID_H
 
 
+#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/list.h>
@@ -310,13 +311,13 @@ struct hid_item {
  * HID connect requests
  */
 
-#define HID_CONNECT_HIDINPUT		0x01
-#define HID_CONNECT_HIDINPUT_FORCE	0x02
-#define HID_CONNECT_HIDRAW		0x04
-#define HID_CONNECT_HIDDEV		0x08
-#define HID_CONNECT_HIDDEV_FORCE	0x10
-#define HID_CONNECT_FF			0x20
-#define HID_CONNECT_DRIVER		0x40
+#define HID_CONNECT_HIDINPUT		BIT(0)
+#define HID_CONNECT_HIDINPUT_FORCE	BIT(1)
+#define HID_CONNECT_HIDRAW		BIT(2)
+#define HID_CONNECT_HIDDEV		BIT(3)
+#define HID_CONNECT_HIDDEV_FORCE	BIT(4)
+#define HID_CONNECT_FF			BIT(5)
+#define HID_CONNECT_DRIVER		BIT(6)
 #define HID_CONNECT_DEFAULT	(HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \
 		HID_CONNECT_HIDDEV|HID_CONNECT_FF)
 
@@ -329,25 +330,25 @@ struct hid_item {
  */
 #define MAX_USBHID_BOOT_QUIRKS 4
 
-#define HID_QUIRK_INVERT			0x00000001
-#define HID_QUIRK_NOTOUCH			0x00000002
-#define HID_QUIRK_IGNORE			0x00000004
-#define HID_QUIRK_NOGET				0x00000008
-#define HID_QUIRK_HIDDEV_FORCE			0x00000010
-#define HID_QUIRK_BADPAD			0x00000020
-#define HID_QUIRK_MULTI_INPUT			0x00000040
-#define HID_QUIRK_HIDINPUT_FORCE		0x00000080
-#define HID_QUIRK_NO_EMPTY_INPUT		0x00000100
-/* 0x00000200 reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
-#define HID_QUIRK_ALWAYS_POLL			0x00000400
-#define HID_QUIRK_SKIP_OUTPUT_REPORTS		0x00010000
-#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID		0x00020000
-#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP	0x00040000
-#define HID_QUIRK_HAVE_SPECIAL_DRIVER		0x00080000
-#define HID_QUIRK_FULLSPEED_INTERVAL		0x10000000
-#define HID_QUIRK_NO_INIT_REPORTS		0x20000000
-#define HID_QUIRK_NO_IGNORE			0x40000000
-#define HID_QUIRK_NO_INPUT_SYNC			0x80000000
+#define HID_QUIRK_INVERT			BIT(0)
+#define HID_QUIRK_NOTOUCH			BIT(1)
+#define HID_QUIRK_IGNORE			BIT(2)
+#define HID_QUIRK_NOGET				BIT(3)
+#define HID_QUIRK_HIDDEV_FORCE			BIT(4)
+#define HID_QUIRK_BADPAD			BIT(5)
+#define HID_QUIRK_MULTI_INPUT			BIT(6)
+#define HID_QUIRK_HIDINPUT_FORCE		BIT(7)
+/* BIT(8) reserved for backward compatibility, was HID_QUIRK_NO_EMPTY_INPUT */
+/* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
+#define HID_QUIRK_ALWAYS_POLL			BIT(10)
+#define HID_QUIRK_SKIP_OUTPUT_REPORTS		BIT(16)
+#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID		BIT(17)
+#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP	BIT(18)
+#define HID_QUIRK_HAVE_SPECIAL_DRIVER		BIT(19)
+#define HID_QUIRK_FULLSPEED_INTERVAL		BIT(28)
+#define HID_QUIRK_NO_INIT_REPORTS		BIT(29)
+#define HID_QUIRK_NO_IGNORE			BIT(30)
+#define HID_QUIRK_NO_INPUT_SYNC			BIT(31)
 
 /*
  * HID device groups
@@ -494,13 +495,13 @@ struct hid_output_fifo {
 	char *raw_report;
 };
 
-#define HID_CLAIMED_INPUT	1
-#define HID_CLAIMED_HIDDEV	2
-#define HID_CLAIMED_HIDRAW	4
-#define HID_CLAIMED_DRIVER	8
+#define HID_CLAIMED_INPUT	BIT(0)
+#define HID_CLAIMED_HIDDEV	BIT(1)
+#define HID_CLAIMED_HIDRAW	BIT(2)
+#define HID_CLAIMED_DRIVER	BIT(3)
 
-#define HID_STAT_ADDED		1
-#define HID_STAT_PARSED		2
+#define HID_STAT_ADDED		BIT(0)
+#define HID_STAT_PARSED		BIT(1)
 
 struct hid_input {
 	struct list_head list;
@@ -686,8 +687,6 @@ struct hid_usage_id {
  * @input_mapped: invoked on input registering after mapping an usage
  * @input_configured: invoked just before the device is registered
  * @feature_mapping: invoked on feature registering
- * @bus_add_driver: invoked when a HID driver is about to be added
- * @bus_removed_driver: invoked when a HID driver has been removed
  * @suspend: invoked on suspend (NULL means nop)
  * @resume: invoked on resume if device was not reset (NULL means nop)
  * @reset_resume: invoked on resume if device was reset (NULL means nop)
@@ -742,8 +741,6 @@ struct hid_driver {
 	void (*feature_mapping)(struct hid_device *hdev,
 			struct hid_field *field,
 			struct hid_usage *usage);
-	void (*bus_add_driver)(struct hid_driver *driver);
-	void (*bus_removed_driver)(struct hid_driver *driver);
 #ifdef CONFIG_PM
 	int (*suspend)(struct hid_device *hdev, pm_message_t message);
 	int (*resume)(struct hid_device *hdev);
@@ -851,7 +848,7 @@ extern int hidinput_connect(struct hid_device *hid, unsigned int force);
 extern void hidinput_disconnect(struct hid_device *);
 
 int hid_set_field(struct hid_field *, unsigned, __s32);
-int hid_input_report(struct hid_device *, int type, u8 *, int, int);
+int hid_input_report(struct hid_device *, int type, u8 *, u32, int);
 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);
@@ -1102,13 +1099,13 @@ static inline void hid_hw_wait(struct hid_device *hdev)
  *
  * @report: the report we want to know the length
  */
-static inline int hid_report_len(struct hid_report *report)
+static inline u32 hid_report_len(struct hid_report *report)
 {
 	/* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
 	return ((report->size - 1) >> 3) + 1 + (report->id > 0);
 }
 
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 		int interrupt);
 
 /* HID quirks API */
diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h
index ceb7519..e5fd270 100644
--- a/include/linux/hwmon.h
+++ b/include/linux/hwmon.h
@@ -29,6 +29,7 @@ enum hwmon_sensor_types {
 	hwmon_humidity,
 	hwmon_fan,
 	hwmon_pwm,
+	hwmon_max,
 };
 
 enum hwmon_chip_attributes {
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 1d6f161..ca9d34f 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -160,7 +160,6 @@ struct ide_io_ports {
  */
 #define PARTN_BITS	6	/* number of minor dev bits for partitions */
 #define MAX_DRIVES	2	/* per interface; 2 assumed by lots of code */
-#define SECTOR_SIZE	512
 
 /*
  * Timeouts for various operations:
diff --git a/include/linux/inet.h b/include/linux/inet.h
index 636ebe8..97defc1 100644
--- a/include/linux/inet.h
+++ b/include/linux/inet.h
@@ -59,5 +59,6 @@ extern int in6_pton(const char *src, int srclen, u8 *dst, int delim, const char
 
 extern int inet_pton_with_scope(struct net *net, unsigned short af,
 		const char *src, const char *port, struct sockaddr_storage *addr);
+extern bool inet_addr_is_any(struct sockaddr *addr);
 
 #endif	/* _LINUX_INET_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 3cbf3cf..4ae1dfd 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -792,41 +792,58 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 #endif /* CONFIG_TRACING */
 
 /*
- * min()/max()/clamp() macros that also do
- * strict type-checking.. See the
- * "unnecessary" pointer comparison.
+ * min()/max()/clamp() macros must accomplish three things:
+ *
+ * - avoid multiple evaluations of the arguments (so side-effects like
+ *   "x++" happen only once) when non-constant.
+ * - perform strict type-checking (to generate warnings instead of
+ *   nasty runtime surprises). See the "unnecessary" pointer comparison
+ *   in __typecheck().
+ * - retain result as a constant expressions when called with only
+ *   constant expressions (to avoid tripping VLA warnings in stack
+ *   allocation usage).
  */
-#define __min(t1, t2, min1, min2, x, y) ({		\
-	t1 min1 = (x);					\
-	t2 min2 = (y);					\
-	(void) (&min1 == &min2);			\
-	min1 < min2 ? min1 : min2; })
+#define __typecheck(x, y) \
+		(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
+
+/*
+ * This returns a constant expression while determining if an argument is
+ * a constant expression, most importantly without evaluating the argument.
+ * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de>
+ */
+#define __is_constexpr(x) \
+	(sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
+
+#define __no_side_effects(x, y) \
+		(__is_constexpr(x) && __is_constexpr(y))
+
+#define __safe_cmp(x, y) \
+		(__typecheck(x, y) && __no_side_effects(x, y))
+
+#define __cmp(x, y, op)	((x) op (y) ? (x) : (y))
+
+#define __cmp_once(x, y, op) ({		\
+		typeof(x) __x = (x);	\
+		typeof(y) __y = (y);	\
+		__cmp(__x, __y, op); })
+
+#define __careful_cmp(x, y, op)				\
+		__builtin_choose_expr(__safe_cmp(x, y),	\
+				      __cmp(x, y, op), __cmp_once(x, y, op))
 
 /**
  * min - return minimum of two values of the same or compatible types
  * @x: first value
  * @y: second value
  */
-#define min(x, y)					\
-	__min(typeof(x), typeof(y),			\
-	      __UNIQUE_ID(min1_), __UNIQUE_ID(min2_),	\
-	      x, y)
-
-#define __max(t1, t2, max1, max2, x, y) ({		\
-	t1 max1 = (x);					\
-	t2 max2 = (y);					\
-	(void) (&max1 == &max2);			\
-	max1 > max2 ? max1 : max2; })
+#define min(x, y)	__careful_cmp(x, y, <)
 
 /**
  * max - return maximum of two values of the same or compatible types
  * @x: first value
  * @y: second value
  */
-#define max(x, y)					\
-	__max(typeof(x), typeof(y),			\
-	      __UNIQUE_ID(max1_), __UNIQUE_ID(max2_),	\
-	      x, y)
+#define max(x, y)	__careful_cmp(x, y, >)
 
 /**
  * min3 - return minimum of three values
@@ -878,10 +895,7 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
  * @x: first value
  * @y: second value
  */
-#define min_t(type, x, y)				\
-	__min(type, type,				\
-	      __UNIQUE_ID(min1_), __UNIQUE_ID(min2_),	\
-	      x, y)
+#define min_t(type, x, y)	__careful_cmp((type)(x), (type)(y), <)
 
 /**
  * max_t - return maximum of two values, using the specified type
@@ -889,10 +903,7 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
  * @x: first value
  * @y: second value
  */
-#define max_t(type, x, y)				\
-	__max(type, type,				\
-	      __UNIQUE_ID(min1_), __UNIQUE_ID(min2_),	\
-	      x, y)
+#define max_t(type, x, y)	__careful_cmp((type)(x), (type)(y), >)
 
 /**
  * clamp_t - return a value clamped to a given range using a given type
diff --git a/include/linux/libfdt_env.h b/include/linux/libfdt_env.h
index 1499728..c6ac1fe 100644
--- a/include/linux/libfdt_env.h
+++ b/include/linux/libfdt_env.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _LIBFDT_ENV_H
-#define _LIBFDT_ENV_H
+#ifndef LIBFDT_ENV_H
+#define LIBFDT_ENV_H
 
 #include <linux/string.h>
 
@@ -15,4 +15,4 @@ typedef __be64 fdt64_t;
 #define fdt64_to_cpu(x) be64_to_cpu(x)
 #define cpu_to_fdt64(x) cpu_to_be64(x)
 
-#endif /* _LIBFDT_ENV_H */
+#endif /* LIBFDT_ENV_H */
diff --git a/include/linux/libps2.h b/include/linux/libps2.h
index 4ad06e8..5f18fe0 100644
--- a/include/linux/libps2.h
+++ b/include/linux/libps2.h
@@ -10,7 +10,13 @@
  * the Free Software Foundation.
  */
 
+#include <linux/bitops.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/wait.h>
 
+#define PS2_CMD_SETSCALE11	0x00e6
+#define PS2_CMD_SETRES		0x10e8
 #define PS2_CMD_GETID		0x02f2
 #define PS2_CMD_RESET_BAT	0x02ff
 
@@ -20,11 +26,12 @@
 #define PS2_RET_NAK		0xfe
 #define PS2_RET_ERR		0xfc
 
-#define PS2_FLAG_ACK		1	/* Waiting for ACK/NAK */
-#define PS2_FLAG_CMD		2	/* Waiting for command to finish */
-#define PS2_FLAG_CMD1		4	/* Waiting for the first byte of command response */
-#define PS2_FLAG_WAITID		8	/* Command execiting is GET ID */
-#define PS2_FLAG_NAK		16	/* Last transmission was NAKed */
+#define PS2_FLAG_ACK		BIT(0)	/* Waiting for ACK/NAK */
+#define PS2_FLAG_CMD		BIT(1)	/* Waiting for a command to finish */
+#define PS2_FLAG_CMD1		BIT(2)	/* Waiting for the first byte of command response */
+#define PS2_FLAG_WAITID		BIT(3)	/* Command executing is GET ID */
+#define PS2_FLAG_NAK		BIT(4)	/* Last transmission was NAKed */
+#define PS2_FLAG_ACK_CMD	BIT(5)	/* Waiting to ACK the command (first) byte */
 
 struct ps2dev {
 	struct serio *serio;
@@ -36,21 +43,22 @@ struct ps2dev {
 	wait_queue_head_t wait;
 
 	unsigned long flags;
-	unsigned char cmdbuf[8];
-	unsigned char cmdcnt;
-	unsigned char nak;
+	u8 cmdbuf[8];
+	u8 cmdcnt;
+	u8 nak;
 };
 
 void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
-int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
-void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
+int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout);
+void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout);
 void ps2_begin_command(struct ps2dev *ps2dev);
 void ps2_end_command(struct ps2dev *ps2dev);
-int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
-int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
-int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
-int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
+int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command);
+int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command);
+int ps2_sliced_command(struct ps2dev *ps2dev, u8 command);
+bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data);
+bool ps2_handle_response(struct ps2dev *ps2dev, u8 data);
 void ps2_cmd_aborted(struct ps2dev *ps2dev);
-int ps2_is_keyboard_id(char id);
+bool ps2_is_keyboard_id(u8 id);
 
 #endif /* _LIBPS2_H */
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index 7f4b60a..6e0859b 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -16,26 +16,58 @@ enum {
 	NVM_IOTYPE_GC = 1,
 };
 
-#define NVM_BLK_BITS (16)
-#define NVM_PG_BITS  (16)
-#define NVM_SEC_BITS (8)
-#define NVM_PL_BITS  (8)
-#define NVM_LUN_BITS (8)
-#define NVM_CH_BITS  (7)
+/* common format */
+#define NVM_GEN_CH_BITS  (8)
+#define NVM_GEN_LUN_BITS (8)
+#define NVM_GEN_BLK_BITS (16)
+#define NVM_GEN_RESERVED (32)
+
+/* 1.2 format */
+#define NVM_12_PG_BITS  (16)
+#define NVM_12_PL_BITS  (4)
+#define NVM_12_SEC_BITS (4)
+#define NVM_12_RESERVED (8)
+
+/* 2.0 format */
+#define NVM_20_SEC_BITS (24)
+#define NVM_20_RESERVED (8)
+
+enum {
+	NVM_OCSSD_SPEC_12 = 12,
+	NVM_OCSSD_SPEC_20 = 20,
+};
 
 struct ppa_addr {
 	/* Generic structure for all addresses */
 	union {
+		/* generic device format */
 		struct {
-			u64 blk		: NVM_BLK_BITS;
-			u64 pg		: NVM_PG_BITS;
-			u64 sec		: NVM_SEC_BITS;
-			u64 pl		: NVM_PL_BITS;
-			u64 lun		: NVM_LUN_BITS;
-			u64 ch		: NVM_CH_BITS;
-			u64 reserved	: 1;
+			u64 ch		: NVM_GEN_CH_BITS;
+			u64 lun		: NVM_GEN_LUN_BITS;
+			u64 blk		: NVM_GEN_BLK_BITS;
+			u64 reserved	: NVM_GEN_RESERVED;
+		} a;
+
+		/* 1.2 device format */
+		struct {
+			u64 ch		: NVM_GEN_CH_BITS;
+			u64 lun		: NVM_GEN_LUN_BITS;
+			u64 blk		: NVM_GEN_BLK_BITS;
+			u64 pg		: NVM_12_PG_BITS;
+			u64 pl		: NVM_12_PL_BITS;
+			u64 sec		: NVM_12_SEC_BITS;
+			u64 reserved	: NVM_12_RESERVED;
 		} g;
 
+		/* 2.0 device format */
+		struct {
+			u64 grp		: NVM_GEN_CH_BITS;
+			u64 pu		: NVM_GEN_LUN_BITS;
+			u64 chk		: NVM_GEN_BLK_BITS;
+			u64 sec		: NVM_20_SEC_BITS;
+			u64 reserved	: NVM_20_RESERVED;
+		} m;
+
 		struct {
 			u64 line	: 63;
 			u64 is_cached	: 1;
@@ -49,10 +81,13 @@ struct nvm_rq;
 struct nvm_id;
 struct nvm_dev;
 struct nvm_tgt_dev;
+struct nvm_chk_meta;
 
-typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
+typedef int (nvm_id_fn)(struct nvm_dev *);
 typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, u8 *);
 typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
+typedef int (nvm_get_chk_meta_fn)(struct nvm_dev *, struct nvm_chk_meta *,
+								sector_t, int);
 typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
 typedef int (nvm_submit_io_sync_fn)(struct nvm_dev *, struct nvm_rq *);
 typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *);
@@ -66,6 +101,8 @@ struct nvm_dev_ops {
 	nvm_op_bb_tbl_fn	*get_bb_tbl;
 	nvm_op_set_bb_fn	*set_bb_tbl;
 
+	nvm_get_chk_meta_fn	*get_chk_meta;
+
 	nvm_submit_io_fn	*submit_io;
 	nvm_submit_io_sync_fn	*submit_io_sync;
 
@@ -73,8 +110,6 @@ struct nvm_dev_ops {
 	nvm_destroy_dma_pool_fn	*destroy_dma_pool;
 	nvm_dev_dma_alloc_fn	*dev_dma_alloc;
 	nvm_dev_dma_free_fn	*dev_dma_free;
-
-	unsigned int		max_phys_sect;
 };
 
 #ifdef CONFIG_NVM
@@ -154,60 +189,75 @@ struct nvm_id_lp_tbl {
 	struct nvm_id_lp_mlc mlc;
 };
 
-struct nvm_id_group {
-	u8	mtype;
-	u8	fmtype;
-	u8	num_ch;
-	u8	num_lun;
-	u16	num_chk;
-	u16	clba;
-	u16	csecs;
-	u16	sos;
-
-	u16	ws_min;
-	u16	ws_opt;
-	u16	ws_seq;
-	u16	ws_per_chk;
-
-	u32	trdt;
-	u32	trdm;
-	u32	tprt;
-	u32	tprm;
-	u32	tbet;
-	u32	tbem;
-	u32	mpos;
-	u32	mccap;
-	u16	cpar;
-
-	/* 1.2 compatibility */
-	u8	num_pln;
-	u16	num_pg;
-	u16	fpg_sz;
-};
-
-struct nvm_addr_format {
-	u8	ch_offset;
+struct nvm_addrf_12 {
 	u8	ch_len;
-	u8	lun_offset;
 	u8	lun_len;
-	u8	pln_offset;
-	u8	pln_len;
-	u8	blk_offset;
 	u8	blk_len;
-	u8	pg_offset;
 	u8	pg_len;
-	u8	sect_offset;
-	u8	sect_len;
+	u8	pln_len;
+	u8	sec_len;
+
+	u8	ch_offset;
+	u8	lun_offset;
+	u8	blk_offset;
+	u8	pg_offset;
+	u8	pln_offset;
+	u8	sec_offset;
+
+	u64	ch_mask;
+	u64	lun_mask;
+	u64	blk_mask;
+	u64	pg_mask;
+	u64	pln_mask;
+	u64	sec_mask;
 };
 
-struct nvm_id {
-	u8	ver_id;
-	u8	vmnt;
-	u32	cap;
-	u32	dom;
-	struct nvm_addr_format ppaf;
-	struct nvm_id_group grp;
-} __packed;
+struct nvm_addrf {
+	u8	ch_len;
+	u8	lun_len;
+	u8	chk_len;
+	u8	sec_len;
+	u8	rsv_len[2];
+
+	u8	ch_offset;
+	u8	lun_offset;
+	u8	chk_offset;
+	u8	sec_offset;
+	u8	rsv_off[2];
+
+	u64	ch_mask;
+	u64	lun_mask;
+	u64	chk_mask;
+	u64	sec_mask;
+	u64	rsv_mask[2];
+};
+
+enum {
+	/* Chunk states */
+	NVM_CHK_ST_FREE =	1 << 0,
+	NVM_CHK_ST_CLOSED =	1 << 1,
+	NVM_CHK_ST_OPEN =	1 << 2,
+	NVM_CHK_ST_OFFLINE =	1 << 3,
+
+	/* Chunk types */
+	NVM_CHK_TP_W_SEQ =	1 << 0,
+	NVM_CHK_TP_W_RAN =	1 << 1,
+	NVM_CHK_TP_SZ_SPEC =	1 << 4,
+};
+
+/*
+ * Note: The structure size is linked to nvme_nvm_chk_meta such that the same
+ * buffer can be used when converting from little endian to cpu addressing.
+ */
+struct nvm_chk_meta {
+	u8	state;
+	u8	type;
+	u8	wi;
+	u8	rsvd[5];
+	u64	slba;
+	u64	cnlb;
+	u64	wp;
+};
 
 struct nvm_target {
 	struct list_head list;
@@ -226,6 +276,8 @@ struct nvm_target {
 #define NVM_VERSION_MINOR 0
 #define NVM_VERSION_PATCH 0
 
+#define NVM_MAX_VLBA (64) /* max logical blocks in a vector command */
+
 struct nvm_rq;
 typedef void (nvm_end_io_fn)(struct nvm_rq *);
 
@@ -272,38 +324,69 @@ enum {
 	NVM_BLK_ST_BAD =	0x8,	/* Bad block */
 };
 
-
-/* Device generic information */
+/* Instance geometry */
 struct nvm_geo {
-	/* generic geometry */
-	int nr_chnls;
-	int all_luns; /* across channels */
-	int nr_luns; /* per channel */
-	int nr_chks; /* per lun */
+	/* device reported version */
+	u8	major_ver_id;
+	u8	minor_ver_id;
 
-	int sec_size;
-	int oob_size;
-	int mccap;
+	/* kernel short version */
+	u8	version;
 
-	int sec_per_chk;
-	int sec_per_lun;
+	/* instance specific geometry */
+	int num_ch;
+	int num_lun;		/* per channel */
 
-	int ws_min;
-	int ws_opt;
-	int ws_seq;
-	int ws_per_chk;
+	/* calculated values */
+	int all_luns;		/* across channels */
+	int all_chunks;		/* across channels */
 
-	int max_rq_size;
+	int op;			/* over-provision in instance */
 
-	int op;
+	sector_t total_secs;	/* across channels */
 
-	struct nvm_addr_format ppaf;
+	/* chunk geometry */
+	u32	num_chk;	/* chunks per lun */
+	u32	clba;		/* sectors per chunk */
+	u16	csecs;		/* sector size */
+	u16	sos;		/* out-of-band area size */
 
-	/* Legacy 1.2 specific geometry */
-	int plane_mode; /* drive device in single, double or quad mode */
-	int nr_planes;
-	int sec_per_pg; /* only sectors for a single page */
-	int sec_per_pl; /* all sectors across planes */
+	/* device write constrains */
+	u32	ws_min;		/* minimum write size */
+	u32	ws_opt;		/* optimal write size */
+	u32	mw_cunits;	/* distance required for successful read */
+	u32	maxoc;		/* maximum open chunks */
+	u32	maxocpu;	/* maximum open chunks per parallel unit */
+
+	/* device capabilities */
+	u32	mccap;
+
+	/* device timings */
+	u32	trdt;		/* Avg. Tread (ns) */
+	u32	trdm;		/* Max Tread (ns) */
+	u32	tprt;		/* Avg. Tprog (ns) */
+	u32	tprm;		/* Max Tprog (ns) */
+	u32	tbet;		/* Avg. Terase (ns) */
+	u32	tbem;		/* Max Terase (ns) */
+
+	/* generic address format */
+	struct nvm_addrf addrf;
+
+	/* 1.2 compatibility */
+	u8	vmnt;
+	u32	cap;
+	u32	dom;
+
+	u8	mtype;
+	u8	fmtype;
+
+	u16	cpar;
+	u32	mpos;
+
+	u8	num_pln;
+	u8	pln_mode;
+	u16	num_pg;
+	u16	fpg_sz;
 };
 
 /* sub-device structure */
@@ -314,9 +397,6 @@ struct nvm_tgt_dev {
 	/* Base ppas for target LUNs */
 	struct ppa_addr *luns;
 
-	sector_t total_secs;
-
-	struct nvm_id identity;
 	struct request_queue *q;
 
 	struct nvm_dev *parent;
@@ -331,13 +411,9 @@ struct nvm_dev {
 	/* Device information */
 	struct nvm_geo geo;
 
-	unsigned long total_secs;
-
 	unsigned long *lun_map;
 	void *dma_pool;
 
-	struct nvm_id identity;
-
 	/* Backend device */
 	struct request_queue *q;
 	char name[DISK_NAME_LEN];
@@ -353,44 +429,58 @@ struct nvm_dev {
 	struct list_head targets;
 };
 
-static inline struct ppa_addr generic_to_dev_addr(struct nvm_tgt_dev *tgt_dev,
+static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev,
 						  struct ppa_addr r)
 {
-	struct nvm_geo *geo = &tgt_dev->geo;
+	struct nvm_geo *geo = &dev->geo;
 	struct ppa_addr l;
 
-	l.ppa = ((u64)r.g.blk) << geo->ppaf.blk_offset;
-	l.ppa |= ((u64)r.g.pg) << geo->ppaf.pg_offset;
-	l.ppa |= ((u64)r.g.sec) << geo->ppaf.sect_offset;
-	l.ppa |= ((u64)r.g.pl) << geo->ppaf.pln_offset;
-	l.ppa |= ((u64)r.g.lun) << geo->ppaf.lun_offset;
-	l.ppa |= ((u64)r.g.ch) << geo->ppaf.ch_offset;
+	if (geo->version == NVM_OCSSD_SPEC_12) {
+		struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&geo->addrf;
+
+		l.ppa = ((u64)r.g.ch) << ppaf->ch_offset;
+		l.ppa |= ((u64)r.g.lun) << ppaf->lun_offset;
+		l.ppa |= ((u64)r.g.blk) << ppaf->blk_offset;
+		l.ppa |= ((u64)r.g.pg) << ppaf->pg_offset;
+		l.ppa |= ((u64)r.g.pl) << ppaf->pln_offset;
+		l.ppa |= ((u64)r.g.sec) << ppaf->sec_offset;
+	} else {
+		struct nvm_addrf *lbaf = &geo->addrf;
+
+		l.ppa = ((u64)r.m.grp) << lbaf->ch_offset;
+		l.ppa |= ((u64)r.m.pu) << lbaf->lun_offset;
+		l.ppa |= ((u64)r.m.chk) << lbaf->chk_offset;
+		l.ppa |= ((u64)r.m.sec) << lbaf->sec_offset;
+	}
 
 	return l;
 }
 
-static inline struct ppa_addr dev_to_generic_addr(struct nvm_tgt_dev *tgt_dev,
+static inline struct ppa_addr dev_to_generic_addr(struct nvm_dev *dev,
 						  struct ppa_addr r)
 {
-	struct nvm_geo *geo = &tgt_dev->geo;
+	struct nvm_geo *geo = &dev->geo;
 	struct ppa_addr l;
 
 	l.ppa = 0;
-	/*
-	 * (r.ppa << X offset) & X len bitmask. X eq. blk, pg, etc.
-	 */
-	l.g.blk = (r.ppa >> geo->ppaf.blk_offset) &
-					(((1 << geo->ppaf.blk_len) - 1));
-	l.g.pg |= (r.ppa >> geo->ppaf.pg_offset) &
-					(((1 << geo->ppaf.pg_len) - 1));
-	l.g.sec |= (r.ppa >> geo->ppaf.sect_offset) &
-					(((1 << geo->ppaf.sect_len) - 1));
-	l.g.pl |= (r.ppa >> geo->ppaf.pln_offset) &
-					(((1 << geo->ppaf.pln_len) - 1));
-	l.g.lun |= (r.ppa >> geo->ppaf.lun_offset) &
-					(((1 << geo->ppaf.lun_len) - 1));
-	l.g.ch |= (r.ppa >> geo->ppaf.ch_offset) &
-					(((1 << geo->ppaf.ch_len) - 1));
+
+	if (geo->version == NVM_OCSSD_SPEC_12) {
+		struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&geo->addrf;
+
+		l.g.ch = (r.ppa & ppaf->ch_mask) >> ppaf->ch_offset;
+		l.g.lun = (r.ppa & ppaf->lun_mask) >> ppaf->lun_offset;
+		l.g.blk = (r.ppa & ppaf->blk_mask) >> ppaf->blk_offset;
+		l.g.pg = (r.ppa & ppaf->pg_mask) >> ppaf->pg_offset;
+		l.g.pl = (r.ppa & ppaf->pln_mask) >> ppaf->pln_offset;
+		l.g.sec = (r.ppa & ppaf->sec_mask) >> ppaf->sec_offset;
+	} else {
+		struct nvm_addrf *lbaf = &geo->addrf;
+
+		l.m.grp = (r.ppa & lbaf->ch_mask) >> lbaf->ch_offset;
+		l.m.pu = (r.ppa & lbaf->lun_mask) >> lbaf->lun_offset;
+		l.m.chk = (r.ppa & lbaf->chk_mask) >> lbaf->chk_offset;
+		l.m.sec = (r.ppa & lbaf->sec_mask) >> lbaf->sec_offset;
+	}
 
 	return l;
 }
@@ -434,9 +524,13 @@ extern struct nvm_dev *nvm_alloc_dev(int);
 extern int nvm_register(struct nvm_dev *);
 extern void nvm_unregister(struct nvm_dev *);
 
+
+extern int nvm_get_chunk_meta(struct nvm_tgt_dev *tgt_dev,
+			      struct nvm_chk_meta *meta, struct ppa_addr ppa,
+			      int nchks);
+
 extern int nvm_set_tgt_bb_tbl(struct nvm_tgt_dev *, struct ppa_addr *,
 			      int, int);
-extern int nvm_max_phys_sects(struct nvm_tgt_dev *);
 extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *);
 extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *);
 extern void nvm_end_io(struct nvm_rq *);
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 3bf8f95..3102bd7 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -1,6 +1,4 @@
 /*
- *  linux/include/linux/mtd/bbm.h
- *
  *  NAND family Bad Block Management (BBM) header file
  *    - Bad Block Table (BBT) implementation
  *
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 205eded..a86c4fa 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -30,32 +30,19 @@
 
 #include <asm/div64.h>
 
-#define MTD_ERASE_PENDING	0x01
-#define MTD_ERASING		0x02
-#define MTD_ERASE_SUSPEND	0x04
-#define MTD_ERASE_DONE		0x08
-#define MTD_ERASE_FAILED	0x10
-
 #define MTD_FAIL_ADDR_UNKNOWN -1LL
 
+struct mtd_info;
+
 /*
  * If the erase fails, fail_addr might indicate exactly which block failed. If
  * fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level
  * or was not specific to any particular block.
  */
 struct erase_info {
-	struct mtd_info *mtd;
 	uint64_t addr;
 	uint64_t len;
 	uint64_t fail_addr;
-	u_long time;
-	u_long retries;
-	unsigned dev;
-	unsigned cell;
-	void (*callback) (struct erase_info *self);
-	u_long priv;
-	u_char state;
-	struct erase_info *next;
 };
 
 struct mtd_erase_region_info {
@@ -595,8 +582,6 @@ extern void register_mtd_user (struct mtd_notifier *new);
 extern int unregister_mtd_user (struct mtd_notifier *old);
 void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
 
-void mtd_erase_callback(struct erase_info *instr);
-
 static inline int mtd_is_bitflip(int err) {
 	return err == -EUCLEAN;
 }
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
new file mode 100644
index 0000000..792ea5c
--- /dev/null
+++ b/include/linux/mtd/nand.h
@@ -0,0 +1,731 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright 2017 - Free Electrons
+ *
+ *  Authors:
+ *	Boris Brezillon <boris.brezillon@free-electrons.com>
+ *	Peter Pan <peterpandong@micron.com>
+ */
+
+#ifndef __LINUX_MTD_NAND_H
+#define __LINUX_MTD_NAND_H
+
+#include <linux/mtd/mtd.h>
+
+/**
+ * struct nand_memory_organization - Memory organization structure
+ * @bits_per_cell: number of bits per NAND cell
+ * @pagesize: page size
+ * @oobsize: OOB area size
+ * @pages_per_eraseblock: number of pages per eraseblock
+ * @eraseblocks_per_lun: number of eraseblocks per LUN (Logical Unit Number)
+ * @planes_per_lun: number of planes per LUN
+ * @luns_per_target: number of LUN per target (target is a synonym for die)
+ * @ntargets: total number of targets exposed by the NAND device
+ */
+struct nand_memory_organization {
+	unsigned int bits_per_cell;
+	unsigned int pagesize;
+	unsigned int oobsize;
+	unsigned int pages_per_eraseblock;
+	unsigned int eraseblocks_per_lun;
+	unsigned int planes_per_lun;
+	unsigned int luns_per_target;
+	unsigned int ntargets;
+};
+
+#define NAND_MEMORG(bpc, ps, os, ppe, epl, ppl, lpt, nt)	\
+	{							\
+		.bits_per_cell = (bpc),				\
+		.pagesize = (ps),				\
+		.oobsize = (os),				\
+		.pages_per_eraseblock = (ppe),			\
+		.eraseblocks_per_lun = (epl),			\
+		.planes_per_lun = (ppl),			\
+		.luns_per_target = (lpt),			\
+		.ntargets = (nt),				\
+	}
+
+/**
+ * struct nand_row_converter - Information needed to convert an absolute offset
+ *			       into a row address
+ * @lun_addr_shift: position of the LUN identifier in the row address
+ * @eraseblock_addr_shift: position of the eraseblock identifier in the row
+ *			   address
+ */
+struct nand_row_converter {
+	unsigned int lun_addr_shift;
+	unsigned int eraseblock_addr_shift;
+};
+
+/**
+ * struct nand_pos - NAND position object
+ * @target: the NAND target/die
+ * @lun: the LUN identifier
+ * @plane: the plane within the LUN
+ * @eraseblock: the eraseblock within the LUN
+ * @page: the page within the LUN
+ *
+ * These information are usually used by specific sub-layers to select the
+ * appropriate target/die and generate a row address to pass to the device.
+ */
+struct nand_pos {
+	unsigned int target;
+	unsigned int lun;
+	unsigned int plane;
+	unsigned int eraseblock;
+	unsigned int page;
+};
+
+/**
+ * struct nand_page_io_req - NAND I/O request object
+ * @pos: the position this I/O request is targeting
+ * @dataoffs: the offset within the page
+ * @datalen: number of data bytes to read from/write to this page
+ * @databuf: buffer to store data in or get data from
+ * @ooboffs: the OOB offset within the page
+ * @ooblen: the number of OOB bytes to read from/write to this page
+ * @oobbuf: buffer to store OOB data in or get OOB data from
+ *
+ * This object is used to pass per-page I/O requests to NAND sub-layers. This
+ * way all useful information are already formatted in a useful way and
+ * specific NAND layers can focus on translating these information into
+ * specific commands/operations.
+ */
+struct nand_page_io_req {
+	struct nand_pos pos;
+	unsigned int dataoffs;
+	unsigned int datalen;
+	union {
+		const void *out;
+		void *in;
+	} databuf;
+	unsigned int ooboffs;
+	unsigned int ooblen;
+	union {
+		const void *out;
+		void *in;
+	} oobbuf;
+};
+
+/**
+ * struct nand_ecc_req - NAND ECC requirements
+ * @strength: ECC strength
+ * @step_size: ECC step/block size
+ */
+struct nand_ecc_req {
+	unsigned int strength;
+	unsigned int step_size;
+};
+
+#define NAND_ECCREQ(str, stp) { .strength = (str), .step_size = (stp) }
+
+/**
+ * struct nand_bbt - bad block table object
+ * @cache: in memory BBT cache
+ */
+struct nand_bbt {
+	unsigned long *cache;
+};
+
+struct nand_device;
+
+/**
+ * struct nand_ops - NAND operations
+ * @erase: erase a specific block. No need to check if the block is bad before
+ *	   erasing, this has been taken care of by the generic NAND layer
+ * @markbad: mark a specific block bad. No need to check if the block is
+ *	     already marked bad, this has been taken care of by the generic
+ *	     NAND layer. This method should just write the BBM (Bad Block
+ *	     Marker) so that future call to struct_nand_ops->isbad() return
+ *	     true
+ * @isbad: check whether a block is bad or not. This method should just read
+ *	   the BBM and return whether the block is bad or not based on what it
+ *	   reads
+ *
+ * These are all low level operations that should be implemented by specialized
+ * NAND layers (SPI NAND, raw NAND, ...).
+ */
+struct nand_ops {
+	int (*erase)(struct nand_device *nand, const struct nand_pos *pos);
+	int (*markbad)(struct nand_device *nand, const struct nand_pos *pos);
+	bool (*isbad)(struct nand_device *nand, const struct nand_pos *pos);
+};
+
+/**
+ * struct nand_device - NAND device
+ * @mtd: MTD instance attached to the NAND device
+ * @memorg: memory layout
+ * @eccreq: ECC requirements
+ * @rowconv: position to row address converter
+ * @bbt: bad block table info
+ * @ops: NAND operations attached to the NAND device
+ *
+ * Generic NAND object. Specialized NAND layers (raw NAND, SPI NAND, OneNAND)
+ * should declare their own NAND object embedding a nand_device struct (that's
+ * how inheritance is done).
+ * struct_nand_device->memorg and struct_nand_device->eccreq should be filled
+ * at device detection time to reflect the NAND device
+ * capabilities/requirements. Once this is done nanddev_init() can be called.
+ * It will take care of converting NAND information into MTD ones, which means
+ * the specialized NAND layers should never manually tweak
+ * struct_nand_device->mtd except for the ->_read/write() hooks.
+ */
+struct nand_device {
+	struct mtd_info mtd;
+	struct nand_memory_organization memorg;
+	struct nand_ecc_req eccreq;
+	struct nand_row_converter rowconv;
+	struct nand_bbt bbt;
+	const struct nand_ops *ops;
+};
+
+/**
+ * struct nand_io_iter - NAND I/O iterator
+ * @req: current I/O request
+ * @oobbytes_per_page: maximum number of OOB bytes per page
+ * @dataleft: remaining number of data bytes to read/write
+ * @oobleft: remaining number of OOB bytes to read/write
+ *
+ * Can be used by specialized NAND layers to iterate over all pages covered
+ * by an MTD I/O request, which should greatly simplifies the boiler-plate
+ * code needed to read/write data from/to a NAND device.
+ */
+struct nand_io_iter {
+	struct nand_page_io_req req;
+	unsigned int oobbytes_per_page;
+	unsigned int dataleft;
+	unsigned int oobleft;
+};
+
+/**
+ * mtd_to_nanddev() - Get the NAND device attached to the MTD instance
+ * @mtd: MTD instance
+ *
+ * Return: the NAND device embedding @mtd.
+ */
+static inline struct nand_device *mtd_to_nanddev(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct nand_device, mtd);
+}
+
+/**
+ * nanddev_to_mtd() - Get the MTD device attached to a NAND device
+ * @nand: NAND device
+ *
+ * Return: the MTD device embedded in @nand.
+ */
+static inline struct mtd_info *nanddev_to_mtd(struct nand_device *nand)
+{
+	return &nand->mtd;
+}
+
+/*
+ * nanddev_bits_per_cell() - Get the number of bits per cell
+ * @nand: NAND device
+ *
+ * Return: the number of bits per cell.
+ */
+static inline unsigned int nanddev_bits_per_cell(const struct nand_device *nand)
+{
+	return nand->memorg.bits_per_cell;
+}
+
+/**
+ * nanddev_page_size() - Get NAND page size
+ * @nand: NAND device
+ *
+ * Return: the page size.
+ */
+static inline size_t nanddev_page_size(const struct nand_device *nand)
+{
+	return nand->memorg.pagesize;
+}
+
+/**
+ * nanddev_per_page_oobsize() - Get NAND OOB size
+ * @nand: NAND device
+ *
+ * Return: the OOB size.
+ */
+static inline unsigned int
+nanddev_per_page_oobsize(const struct nand_device *nand)
+{
+	return nand->memorg.oobsize;
+}
+
+/**
+ * nanddev_pages_per_eraseblock() - Get the number of pages per eraseblock
+ * @nand: NAND device
+ *
+ * Return: the number of pages per eraseblock.
+ */
+static inline unsigned int
+nanddev_pages_per_eraseblock(const struct nand_device *nand)
+{
+	return nand->memorg.pages_per_eraseblock;
+}
+
+/**
+ * nanddev_per_page_oobsize() - Get NAND erase block size
+ * @nand: NAND device
+ *
+ * Return: the eraseblock size.
+ */
+static inline size_t nanddev_eraseblock_size(const struct nand_device *nand)
+{
+	return nand->memorg.pagesize * nand->memorg.pages_per_eraseblock;
+}
+
+/**
+ * nanddev_eraseblocks_per_lun() - Get the number of eraseblocks per LUN
+ * @nand: NAND device
+ *
+ * Return: the number of eraseblocks per LUN.
+ */
+static inline unsigned int
+nanddev_eraseblocks_per_lun(const struct nand_device *nand)
+{
+	return nand->memorg.eraseblocks_per_lun;
+}
+
+/**
+ * nanddev_target_size() - Get the total size provided by a single target/die
+ * @nand: NAND device
+ *
+ * Return: the total size exposed by a single target/die in bytes.
+ */
+static inline u64 nanddev_target_size(const struct nand_device *nand)
+{
+	return (u64)nand->memorg.luns_per_target *
+	       nand->memorg.eraseblocks_per_lun *
+	       nand->memorg.pages_per_eraseblock *
+	       nand->memorg.pagesize;
+}
+
+/**
+ * nanddev_ntarget() - Get the total of targets
+ * @nand: NAND device
+ *
+ * Return: the number of targets/dies exposed by @nand.
+ */
+static inline unsigned int nanddev_ntargets(const struct nand_device *nand)
+{
+	return nand->memorg.ntargets;
+}
+
+/**
+ * nanddev_neraseblocks() - Get the total number of erasablocks
+ * @nand: NAND device
+ *
+ * Return: the total number of eraseblocks exposed by @nand.
+ */
+static inline unsigned int nanddev_neraseblocks(const struct nand_device *nand)
+{
+	return (u64)nand->memorg.luns_per_target *
+	       nand->memorg.eraseblocks_per_lun *
+	       nand->memorg.pages_per_eraseblock;
+}
+
+/**
+ * nanddev_size() - Get NAND size
+ * @nand: NAND device
+ *
+ * Return: the total size (in bytes) exposed by @nand.
+ */
+static inline u64 nanddev_size(const struct nand_device *nand)
+{
+	return nanddev_target_size(nand) * nanddev_ntargets(nand);
+}
+
+/**
+ * nanddev_get_memorg() - Extract memory organization info from a NAND device
+ * @nand: NAND device
+ *
+ * This can be used by the upper layer to fill the memorg info before calling
+ * nanddev_init().
+ *
+ * Return: the memorg object embedded in the NAND device.
+ */
+static inline struct nand_memory_organization *
+nanddev_get_memorg(struct nand_device *nand)
+{
+	return &nand->memorg;
+}
+
+int nanddev_init(struct nand_device *nand, const struct nand_ops *ops,
+		 struct module *owner);
+void nanddev_cleanup(struct nand_device *nand);
+
+/**
+ * nanddev_register() - Register a NAND device
+ * @nand: NAND device
+ *
+ * Register a NAND device.
+ * This function is just a wrapper around mtd_device_register()
+ * registering the MTD device embedded in @nand.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+static inline int nanddev_register(struct nand_device *nand)
+{
+	return mtd_device_register(&nand->mtd, NULL, 0);
+}
+
+/**
+ * nanddev_unregister() - Unregister a NAND device
+ * @nand: NAND device
+ *
+ * Unregister a NAND device.
+ * This function is just a wrapper around mtd_device_unregister()
+ * unregistering the MTD device embedded in @nand.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+static inline int nanddev_unregister(struct nand_device *nand)
+{
+	return mtd_device_unregister(&nand->mtd);
+}
+
+/**
+ * nanddev_set_of_node() - Attach a DT node to a NAND device
+ * @nand: NAND device
+ * @np: DT node
+ *
+ * Attach a DT node to a NAND device.
+ */
+static inline void nanddev_set_of_node(struct nand_device *nand,
+				       struct device_node *np)
+{
+	mtd_set_of_node(&nand->mtd, np);
+}
+
+/**
+ * nanddev_get_of_node() - Retrieve the DT node attached to a NAND device
+ * @nand: NAND device
+ *
+ * Return: the DT node attached to @nand.
+ */
+static inline struct device_node *nanddev_get_of_node(struct nand_device *nand)
+{
+	return mtd_get_of_node(&nand->mtd);
+}
+
+/**
+ * nanddev_offs_to_pos() - Convert an absolute NAND offset into a NAND position
+ * @nand: NAND device
+ * @offs: absolute NAND offset (usually passed by the MTD layer)
+ * @pos: a NAND position object to fill in
+ *
+ * Converts @offs into a nand_pos representation.
+ *
+ * Return: the offset within the NAND page pointed by @pos.
+ */
+static inline unsigned int nanddev_offs_to_pos(struct nand_device *nand,
+					       loff_t offs,
+					       struct nand_pos *pos)
+{
+	unsigned int pageoffs;
+	u64 tmp = offs;
+
+	pageoffs = do_div(tmp, nand->memorg.pagesize);
+	pos->page = do_div(tmp, nand->memorg.pages_per_eraseblock);
+	pos->eraseblock = do_div(tmp, nand->memorg.eraseblocks_per_lun);
+	pos->plane = pos->eraseblock % nand->memorg.planes_per_lun;
+	pos->lun = do_div(tmp, nand->memorg.luns_per_target);
+	pos->target = tmp;
+
+	return pageoffs;
+}
+
+/**
+ * nanddev_pos_cmp() - Compare two NAND positions
+ * @a: First NAND position
+ * @b: Second NAND position
+ *
+ * Compares two NAND positions.
+ *
+ * Return: -1 if @a < @b, 0 if @a == @b and 1 if @a > @b.
+ */
+static inline int nanddev_pos_cmp(const struct nand_pos *a,
+				  const struct nand_pos *b)
+{
+	if (a->target != b->target)
+		return a->target < b->target ? -1 : 1;
+
+	if (a->lun != b->lun)
+		return a->lun < b->lun ? -1 : 1;
+
+	if (a->eraseblock != b->eraseblock)
+		return a->eraseblock < b->eraseblock ? -1 : 1;
+
+	if (a->page != b->page)
+		return a->page < b->page ? -1 : 1;
+
+	return 0;
+}
+
+/**
+ * nanddev_pos_to_offs() - Convert a NAND position into an absolute offset
+ * @nand: NAND device
+ * @pos: the NAND position to convert
+ *
+ * Converts @pos NAND position into an absolute offset.
+ *
+ * Return: the absolute offset. Note that @pos points to the beginning of a
+ *	   page, if one wants to point to a specific offset within this page
+ *	   the returned offset has to be adjusted manually.
+ */
+static inline loff_t nanddev_pos_to_offs(struct nand_device *nand,
+					 const struct nand_pos *pos)
+{
+	unsigned int npages;
+
+	npages = pos->page +
+		 ((pos->eraseblock +
+		   (pos->lun +
+		    (pos->target * nand->memorg.luns_per_target)) *
+		   nand->memorg.eraseblocks_per_lun) *
+		  nand->memorg.pages_per_eraseblock);
+
+	return (loff_t)npages * nand->memorg.pagesize;
+}
+
+/**
+ * nanddev_pos_to_row() - Extract a row address from a NAND position
+ * @nand: NAND device
+ * @pos: the position to convert
+ *
+ * Converts a NAND position into a row address that can then be passed to the
+ * device.
+ *
+ * Return: the row address extracted from @pos.
+ */
+static inline unsigned int nanddev_pos_to_row(struct nand_device *nand,
+					      const struct nand_pos *pos)
+{
+	return (pos->lun << nand->rowconv.lun_addr_shift) |
+	       (pos->eraseblock << nand->rowconv.eraseblock_addr_shift) |
+	       pos->page;
+}
+
+/**
+ * nanddev_pos_next_target() - Move a position to the next target/die
+ * @nand: NAND device
+ * @pos: the position to update
+ *
+ * Updates @pos to point to the start of the next target/die. Useful when you
+ * want to iterate over all targets/dies of a NAND device.
+ */
+static inline void nanddev_pos_next_target(struct nand_device *nand,
+					   struct nand_pos *pos)
+{
+	pos->page = 0;
+	pos->plane = 0;
+	pos->eraseblock = 0;
+	pos->lun = 0;
+	pos->target++;
+}
+
+/**
+ * nanddev_pos_next_lun() - Move a position to the next LUN
+ * @nand: NAND device
+ * @pos: the position to update
+ *
+ * Updates @pos to point to the start of the next LUN. Useful when you want to
+ * iterate over all LUNs of a NAND device.
+ */
+static inline void nanddev_pos_next_lun(struct nand_device *nand,
+					struct nand_pos *pos)
+{
+	if (pos->lun >= nand->memorg.luns_per_target - 1)
+		return nanddev_pos_next_target(nand, pos);
+
+	pos->lun++;
+	pos->page = 0;
+	pos->plane = 0;
+	pos->eraseblock = 0;
+}
+
+/**
+ * nanddev_pos_next_eraseblock() - Move a position to the next eraseblock
+ * @nand: NAND device
+ * @pos: the position to update
+ *
+ * Updates @pos to point to the start of the next eraseblock. Useful when you
+ * want to iterate over all eraseblocks of a NAND device.
+ */
+static inline void nanddev_pos_next_eraseblock(struct nand_device *nand,
+					       struct nand_pos *pos)
+{
+	if (pos->eraseblock >= nand->memorg.eraseblocks_per_lun - 1)
+		return nanddev_pos_next_lun(nand, pos);
+
+	pos->eraseblock++;
+	pos->page = 0;
+	pos->plane = pos->eraseblock % nand->memorg.planes_per_lun;
+}
+
+/**
+ * nanddev_pos_next_eraseblock() - Move a position to the next page
+ * @nand: NAND device
+ * @pos: the position to update
+ *
+ * Updates @pos to point to the start of the next page. Useful when you want to
+ * iterate over all pages of a NAND device.
+ */
+static inline void nanddev_pos_next_page(struct nand_device *nand,
+					 struct nand_pos *pos)
+{
+	if (pos->page >= nand->memorg.pages_per_eraseblock - 1)
+		return nanddev_pos_next_eraseblock(nand, pos);
+
+	pos->page++;
+}
+
+/**
+ * nand_io_iter_init - Initialize a NAND I/O iterator
+ * @nand: NAND device
+ * @offs: absolute offset
+ * @req: MTD request
+ * @iter: NAND I/O iterator
+ *
+ * Initializes a NAND iterator based on the information passed by the MTD
+ * layer.
+ */
+static inline void nanddev_io_iter_init(struct nand_device *nand,
+					loff_t offs, struct mtd_oob_ops *req,
+					struct nand_io_iter *iter)
+{
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+
+	iter->req.dataoffs = nanddev_offs_to_pos(nand, offs, &iter->req.pos);
+	iter->req.ooboffs = req->ooboffs;
+	iter->oobbytes_per_page = mtd_oobavail(mtd, req);
+	iter->dataleft = req->len;
+	iter->oobleft = req->ooblen;
+	iter->req.databuf.in = req->datbuf;
+	iter->req.datalen = min_t(unsigned int,
+				  nand->memorg.pagesize - iter->req.dataoffs,
+				  iter->dataleft);
+	iter->req.oobbuf.in = req->oobbuf;
+	iter->req.ooblen = min_t(unsigned int,
+				 iter->oobbytes_per_page - iter->req.ooboffs,
+				 iter->oobleft);
+}
+
+/**
+ * nand_io_iter_next_page - Move to the next page
+ * @nand: NAND device
+ * @iter: NAND I/O iterator
+ *
+ * Updates the @iter to point to the next page.
+ */
+static inline void nanddev_io_iter_next_page(struct nand_device *nand,
+					     struct nand_io_iter *iter)
+{
+	nanddev_pos_next_page(nand, &iter->req.pos);
+	iter->dataleft -= iter->req.datalen;
+	iter->req.databuf.in += iter->req.datalen;
+	iter->oobleft -= iter->req.ooblen;
+	iter->req.oobbuf.in += iter->req.ooblen;
+	iter->req.dataoffs = 0;
+	iter->req.ooboffs = 0;
+	iter->req.datalen = min_t(unsigned int, nand->memorg.pagesize,
+				  iter->dataleft);
+	iter->req.ooblen = min_t(unsigned int, iter->oobbytes_per_page,
+				 iter->oobleft);
+}
+
+/**
+ * nand_io_iter_end - Should end iteration or not
+ * @nand: NAND device
+ * @iter: NAND I/O iterator
+ *
+ * Check whether @iter has reached the end of the NAND portion it was asked to
+ * iterate on or not.
+ *
+ * Return: true if @iter has reached the end of the iteration request, false
+ *	   otherwise.
+ */
+static inline bool nanddev_io_iter_end(struct nand_device *nand,
+				       const struct nand_io_iter *iter)
+{
+	if (iter->dataleft || iter->oobleft)
+		return false;
+
+	return true;
+}
+
+/**
+ * nand_io_for_each_page - Iterate over all NAND pages contained in an MTD I/O
+ *			   request
+ * @nand: NAND device
+ * @start: start address to read/write from
+ * @req: MTD I/O request
+ * @iter: NAND I/O iterator
+ *
+ * Should be used for iterate over pages that are contained in an MTD request.
+ */
+#define nanddev_io_for_each_page(nand, start, req, iter)		\
+	for (nanddev_io_iter_init(nand, start, req, iter);		\
+	     !nanddev_io_iter_end(nand, iter);				\
+	     nanddev_io_iter_next_page(nand, iter))
+
+bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos);
+bool nanddev_isreserved(struct nand_device *nand, const struct nand_pos *pos);
+int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos);
+int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos);
+
+/* BBT related functions */
+enum nand_bbt_block_status {
+	NAND_BBT_BLOCK_STATUS_UNKNOWN,
+	NAND_BBT_BLOCK_GOOD,
+	NAND_BBT_BLOCK_WORN,
+	NAND_BBT_BLOCK_RESERVED,
+	NAND_BBT_BLOCK_FACTORY_BAD,
+	NAND_BBT_BLOCK_NUM_STATUS,
+};
+
+int nanddev_bbt_init(struct nand_device *nand);
+void nanddev_bbt_cleanup(struct nand_device *nand);
+int nanddev_bbt_update(struct nand_device *nand);
+int nanddev_bbt_get_block_status(const struct nand_device *nand,
+				 unsigned int entry);
+int nanddev_bbt_set_block_status(struct nand_device *nand, unsigned int entry,
+				 enum nand_bbt_block_status status);
+int nanddev_bbt_markbad(struct nand_device *nand, unsigned int block);
+
+/**
+ * nanddev_bbt_pos_to_entry() - Convert a NAND position into a BBT entry
+ * @nand: NAND device
+ * @pos: the NAND position we want to get BBT entry for
+ *
+ * Return the BBT entry used to store information about the eraseblock pointed
+ * by @pos.
+ *
+ * Return: the BBT entry storing information about eraseblock pointed by @pos.
+ */
+static inline unsigned int nanddev_bbt_pos_to_entry(struct nand_device *nand,
+						    const struct nand_pos *pos)
+{
+	return pos->eraseblock +
+	       ((pos->lun + (pos->target * nand->memorg.luns_per_target)) *
+		nand->memorg.eraseblocks_per_lun);
+}
+
+/**
+ * nanddev_bbt_is_initialized() - Check if the BBT has been initialized
+ * @nand: NAND device
+ *
+ * Return: true if the BBT has been initialized, false otherwise.
+ */
+static inline bool nanddev_bbt_is_initialized(struct nand_device *nand)
+{
+	return !!nand->bbt.cache;
+}
+
+/* MTD -> NAND helper functions. */
+int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo);
+
+#endif /* __LINUX_MTD_NAND_H */
diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h
index 4d8406c..8a2decf 100644
--- a/include/linux/mtd/nand_ecc.h
+++ b/include/linux/mtd/nand_ecc.h
@@ -1,6 +1,4 @@
 /*
- *  drivers/mtd/nand_ecc.h
- *
  *  Copyright (C) 2000-2010 Steven J. Hill <sjhill@realitydiluted.com>
  *			    David Woodhouse <dwmw2@infradead.org>
  *			    Thomas Gleixner <tglx@linutronix.de>
diff --git a/include/linux/mtd/ndfc.h b/include/linux/mtd/ndfc.h
index d0558a9..357e88b 100644
--- a/include/linux/mtd/ndfc.h
+++ b/include/linux/mtd/ndfc.h
@@ -1,6 +1,4 @@
 /*
- *  linux/include/linux/mtd/ndfc.h
- *
  *  Copyright (c) 2006 Thomas Gleixner <tglx@linutronix.de>
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index c4beb70..11cb0c5 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
 	struct list_head list;
 	struct module *owner;
 	const char *name;
+	const struct of_device_id *of_match_table;
 	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
 			struct mtd_part_parser_data *);
 	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 56c5570..5dad59b 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -21,6 +21,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/flashchip.h>
 #include <linux/mtd/bbm.h>
+#include <linux/types.h>
 
 struct mtd_info;
 struct nand_flash_dev;
@@ -235,7 +236,8 @@ struct nand_chip;
 #define ONFI_TIMING_MODE_5		(1 << 5)
 #define ONFI_TIMING_MODE_UNKNOWN	(1 << 6)
 
-/* ONFI feature address */
+/* ONFI feature number/address */
+#define ONFI_FEATURE_NUMBER		256
 #define ONFI_FEATURE_ADDR_TIMING_MODE	0x1
 
 /* Vendor-specific feature address (Micron) */
@@ -429,6 +431,47 @@ struct nand_jedec_params {
 	__le16 crc;
 } __packed;
 
+/**
+ * struct onfi_params - ONFI specific parameters that will be reused
+ * @version: ONFI version (BCD encoded), 0 if ONFI is not supported
+ * @tPROG: Page program time
+ * @tBERS: Block erase time
+ * @tR: Page read time
+ * @tCCS: Change column setup time
+ * @async_timing_mode: Supported asynchronous timing mode
+ * @vendor_revision: Vendor specific revision number
+ * @vendor: Vendor specific data
+ */
+struct onfi_params {
+	int version;
+	u16 tPROG;
+	u16 tBERS;
+	u16 tR;
+	u16 tCCS;
+	u16 async_timing_mode;
+	u16 vendor_revision;
+	u8 vendor[88];
+};
+
+/**
+ * struct nand_parameters - NAND generic parameters from the parameter page
+ * @model: Model name
+ * @supports_set_get_features: The NAND chip supports setting/getting features
+ * @set_feature_list: Bitmap of features that can be set
+ * @get_feature_list: Bitmap of features that can be get
+ * @onfi: ONFI specific parameters
+ */
+struct nand_parameters {
+	/* Generic parameters */
+	char model[100];
+	bool supports_set_get_features;
+	DECLARE_BITMAP(set_feature_list, ONFI_FEATURE_NUMBER);
+	DECLARE_BITMAP(get_feature_list, ONFI_FEATURE_NUMBER);
+
+	/* ONFI parameters */
+	struct onfi_params onfi;
+};
+
 /* The maximum expected count of bytes in the NAND ID sequence */
 #define NAND_MAX_ID_LEN 8
 
@@ -1157,21 +1200,15 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
  *			currently in data_buf.
  * @subpagesize:	[INTERN] holds the subpagesize
  * @id:			[INTERN] holds NAND ID
- * @onfi_version:	[INTERN] holds the chip ONFI version (BCD encoded),
- *			non 0 if ONFI supported.
- * @jedec_version:	[INTERN] holds the chip JEDEC version (BCD encoded),
- *			non 0 if JEDEC supported.
- * @onfi_params:	[INTERN] holds the ONFI page parameter when ONFI is
- *			supported, 0 otherwise.
- * @jedec_params:	[INTERN] holds the JEDEC parameter page when JEDEC is
- *			supported, 0 otherwise.
+ * @parameters:		[INTERN] holds generic parameters under an easily
+ *			readable form.
  * @max_bb_per_die:	[INTERN] the max number of bad blocks each die of a
  *			this nand device will encounter their life times.
  * @blocks_per_die:	[INTERN] The number of PEBs in a die
  * @data_interface:	[INTERN] NAND interface timing information
  * @read_retries:	[INTERN] the number of read retry modes supported
- * @onfi_set_features:	[REPLACEABLE] set the features for ONFI nand
- * @onfi_get_features:	[REPLACEABLE] get the features for ONFI nand
+ * @set_features:	[REPLACEABLE] set the NAND chip features
+ * @get_features:	[REPLACEABLE] get the NAND chip features
  * @setup_data_interface: [OPTIONAL] setup the data interface and timing. If
  *			  chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
  *			  means the configuration should not be applied but
@@ -1212,10 +1249,10 @@ struct nand_chip {
 		       bool check_only);
 	int (*erase)(struct mtd_info *mtd, int page);
 	int (*scan_bbt)(struct mtd_info *mtd);
-	int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
-			int feature_addr, uint8_t *subfeature_para);
-	int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
-			int feature_addr, uint8_t *subfeature_para);
+	int (*set_features)(struct mtd_info *mtd, struct nand_chip *chip,
+			    int feature_addr, uint8_t *subfeature_para);
+	int (*get_features)(struct mtd_info *mtd, struct nand_chip *chip,
+			    int feature_addr, uint8_t *subfeature_para);
 	int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
 	int (*setup_data_interface)(struct mtd_info *mtd, int chipnr,
 				    const struct nand_data_interface *conf);
@@ -1243,12 +1280,7 @@ struct nand_chip {
 	int badblockbits;
 
 	struct nand_id id;
-	int onfi_version;
-	int jedec_version;
-	union {
-		struct nand_onfi_params	onfi_params;
-		struct nand_jedec_params jedec_params;
-	};
+	struct nand_parameters parameters;
 	u16 max_bb_per_die;
 	u32 blocks_per_die;
 
@@ -1535,26 +1567,13 @@ struct platform_nand_data {
 	struct platform_nand_ctrl ctrl;
 };
 
-/* return the supported features. */
-static inline int onfi_feature(struct nand_chip *chip)
-{
-	return chip->onfi_version ? le16_to_cpu(chip->onfi_params.features) : 0;
-}
-
 /* return the supported asynchronous timing mode. */
 static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
 {
-	if (!chip->onfi_version)
+	if (!chip->parameters.onfi.version)
 		return ONFI_TIMING_MODE_UNKNOWN;
-	return le16_to_cpu(chip->onfi_params.async_timing_mode);
-}
 
-/* return the supported synchronous timing mode. */
-static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
-{
-	if (!chip->onfi_version)
-		return ONFI_TIMING_MODE_UNKNOWN;
-	return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
+	return chip->parameters.onfi.async_timing_mode;
 }
 
 int onfi_fill_data_interface(struct nand_chip *chip,
@@ -1591,13 +1610,6 @@ static inline int nand_opcode_8bits(unsigned int command)
 	return 0;
 }
 
-/* return the supported JEDEC features. */
-static inline int jedec_feature(struct nand_chip *chip)
-{
-	return chip->jedec_version ? le16_to_cpu(chip->jedec_params.features)
-		: 0;
-}
-
 /* get timing characteristics from ONFI timing mode. */
 const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
 
@@ -1629,10 +1641,12 @@ int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page);
 int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 			   int page);
 
+/* Wrapper to use in order for controllers/vendors to GET/SET FEATURES */
+int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param);
+int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param);
 /* Stub used by drivers that do not support GET/SET FEATURES operations */
-int nand_onfi_get_set_features_notsupp(struct mtd_info *mtd,
-				       struct nand_chip *chip, int addr,
-				       u8 *subfeature_param);
+int nand_get_set_features_notsupp(struct mtd_info *mtd, struct nand_chip *chip,
+				  int addr, u8 *subfeature_param);
 
 /* Default read_page_raw implementation */
 int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
diff --git a/include/linux/of.h b/include/linux/of.h
index ebf22dd..4d25e4f 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -363,6 +363,9 @@ extern struct device_node *of_parse_phandle(const struct device_node *np,
 extern int of_parse_phandle_with_args(const struct device_node *np,
 	const char *list_name, const char *cells_name, int index,
 	struct of_phandle_args *out_args);
+extern int of_parse_phandle_with_args_map(const struct device_node *np,
+	const char *list_name, const char *stem_name, int index,
+	struct of_phandle_args *out_args);
 extern int of_parse_phandle_with_fixed_args(const struct device_node *np,
 	const char *list_name, int cells_count, int index,
 	struct of_phandle_args *out_args);
@@ -815,6 +818,15 @@ static inline int of_parse_phandle_with_args(const struct device_node *np,
 	return -ENOSYS;
 }
 
+static inline int of_parse_phandle_with_args_map(const struct device_node *np,
+						 const char *list_name,
+						 const char *stem_name,
+						 int index,
+						 struct of_phandle_args *out_args)
+{
+	return -ENOSYS;
+}
+
 static inline int of_parse_phandle_with_fixed_args(const struct device_node *np,
 	const char *list_name, int cells_count, int index,
 	struct of_phandle_args *out_args)
diff --git a/include/linux/platform_data/asoc-ti-mcbsp.h b/include/linux/platform_data/asoc-ti-mcbsp.h
index e684543..e319d0a 100644
--- a/include/linux/platform_data/asoc-ti-mcbsp.h
+++ b/include/linux/platform_data/asoc-ti-mcbsp.h
@@ -25,10 +25,6 @@
 #include <linux/spinlock.h>
 #include <linux/clk.h>
 
-#define MCBSP_CONFIG_TYPE2	0x2
-#define MCBSP_CONFIG_TYPE3	0x3
-#define MCBSP_CONFIG_TYPE4	0x4
-
 /* Platform specific configuration */
 struct omap_mcbsp_ops {
 	void (*request)(unsigned int);
@@ -47,14 +43,6 @@ struct omap_mcbsp_platform_data {
 	int (*force_ick_on)(struct clk *clk, bool force_on);
 };
 
-/**
- * omap_mcbsp_dev_attr - OMAP McBSP device attributes for omap_hwmod
- * @sidetone: name of the sidetone device
- */
-struct omap_mcbsp_dev_attr {
-	const char *sidetone;
-};
-
 void omap3_mcbsp_init_pdata_callback(struct omap_mcbsp_platform_data *pdata);
 
 #endif
diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h
index a19b78d..757a0f9 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -20,12 +20,50 @@
 #ifndef __PLATFORM_DATA_DMTIMER_OMAP_H__
 #define __PLATFORM_DATA_DMTIMER_OMAP_H__
 
+struct omap_dm_timer_ops {
+	struct omap_dm_timer *(*request_by_node)(struct device_node *np);
+	struct omap_dm_timer *(*request_specific)(int timer_id);
+	struct omap_dm_timer *(*request)(void);
+
+	int	(*free)(struct omap_dm_timer *timer);
+
+	void	(*enable)(struct omap_dm_timer *timer);
+	void	(*disable)(struct omap_dm_timer *timer);
+
+	int	(*get_irq)(struct omap_dm_timer *timer);
+	int	(*set_int_enable)(struct omap_dm_timer *timer,
+				  unsigned int value);
+	int	(*set_int_disable)(struct omap_dm_timer *timer, u32 mask);
+
+	struct clk *(*get_fclk)(struct omap_dm_timer *timer);
+
+	int	(*start)(struct omap_dm_timer *timer);
+	int	(*stop)(struct omap_dm_timer *timer);
+	int	(*set_source)(struct omap_dm_timer *timer, int source);
+
+	int	(*set_load)(struct omap_dm_timer *timer, int autoreload,
+			    unsigned int value);
+	int	(*set_match)(struct omap_dm_timer *timer, int enable,
+			     unsigned int match);
+	int	(*set_pwm)(struct omap_dm_timer *timer, int def_on,
+			   int toggle, int trigger);
+	int	(*set_prescaler)(struct omap_dm_timer *timer, int prescaler);
+
+	unsigned int (*read_counter)(struct omap_dm_timer *timer);
+	int	(*write_counter)(struct omap_dm_timer *timer,
+				 unsigned int value);
+	unsigned int (*read_status)(struct omap_dm_timer *timer);
+	int	(*write_status)(struct omap_dm_timer *timer,
+				unsigned int value);
+};
+
 struct dmtimer_platform_data {
 	/* set_timer_src - Only used for OMAP1 devices */
 	int (*set_timer_src)(struct platform_device *pdev, int source);
 	u32 timer_capability;
 	u32 timer_errata;
 	int (*get_context_loss_count)(struct device *);
+	const struct omap_dm_timer_ops *timer_ops;
 };
 
 #endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */
diff --git a/include/linux/platform_data/gpio-htc-egpio.h b/include/linux/platform_data/gpio-htc-egpio.h
index b7baf1e..9a3e780 100644
--- a/include/linux/platform_data/gpio-htc-egpio.h
+++ b/include/linux/platform_data/gpio-htc-egpio.h
@@ -6,8 +6,6 @@
 #ifndef __HTC_EGPIO_H__
 #define __HTC_EGPIO_H__
 
-#include <linux/gpio.h>
-
 /* Descriptive values for all-in or all-out htc_egpio_chip descriptors. */
 #define HTC_EGPIO_OUTPUT (~0)
 #define HTC_EGPIO_INPUT  0
diff --git a/include/linux/platform_data/gpio-omap.h b/include/linux/platform_data/gpio-omap.h
index cb26181..8612855 100644
--- a/include/linux/platform_data/gpio-omap.h
+++ b/include/linux/platform_data/gpio-omap.h
@@ -157,11 +157,6 @@
 #define OMAP_MPUIO(nr)		(OMAP_MAX_GPIO_LINES + (nr))
 #define OMAP_GPIO_IS_MPUIO(nr)	((nr) >= OMAP_MAX_GPIO_LINES)
 
-struct omap_gpio_dev_attr {
-	int bank_width;		/* GPIO bank width */
-	bool dbck_flag;		/* dbck required or not - True for OMAP3&4 */
-};
-
 struct omap_gpio_reg_offs {
 	u16 revision;
 	u16 direction;
diff --git a/include/linux/platform_data/mtd-nand-pxa3xx.h b/include/linux/platform_data/mtd-nand-pxa3xx.h
index b42ad83..4fd0f59 100644
--- a/include/linux/platform_data/mtd-nand-pxa3xx.h
+++ b/include/linux/platform_data/mtd-nand-pxa3xx.h
@@ -6,41 +6,22 @@
 #include <linux/mtd/partitions.h>
 
 /*
- * Current pxa3xx_nand controller has two chip select which
- * both be workable.
- *
- * Notice should be taken that:
- * When you want to use this feature, you should not enable the
- * keep configuration feature, for two chip select could be
- * attached with different nand chip. The different page size
- * and timing requirement make the keep configuration impossible.
+ * Current pxa3xx_nand controller has two chip select which both be workable but
+ * historically all platforms remaining on platform data used only one. Switch
+ * to device tree if you need more.
  */
-
-/* The max num of chip select current support */
-#define NUM_CHIP_SELECT		(2)
 struct pxa3xx_nand_platform_data {
-
-	/* the data flash bus is shared between the Static Memory
-	 * Controller and the Data Flash Controller,  the arbiter
-	 * controls the ownership of the bus
-	 */
-	int	enable_arbiter;
-
-	/* allow platform code to keep OBM/bootloader defined NFC config */
-	int	keep_config;
-
-	/* indicate how many chip selects will be used */
-	int	num_cs;
-
-	/* use an flash-based bad block table */
-	bool	flash_bbt;
-
-	/* requested ECC strength and ECC step size */
+	/* Keep OBM/bootloader NFC timing configuration */
+	bool keep_config;
+	/* Use a flash-based bad block table */
+	bool flash_bbt;
+	/* Requested ECC strength and ECC step size */
 	int ecc_strength, ecc_step_size;
-
-	const struct mtd_partition		*parts[NUM_CHIP_SELECT];
-	unsigned int				nr_parts[NUM_CHIP_SELECT];
+	/* Partitions */
+	const struct mtd_partition *parts;
+	unsigned int nr_parts;
 };
 
 extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info);
+
 #endif /* __ASM_ARCH_PXA3XX_NAND_H */
diff --git a/include/linux/platform_data/phy-da8xx-usb.h b/include/linux/platform_data/phy-da8xx-usb.h
new file mode 100644
index 0000000..85c2b99
--- /dev/null
+++ b/include/linux/platform_data/phy-da8xx-usb.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * phy-da8xx-usb - TI DaVinci DA8xx USB PHY driver
+ *
+ * Copyright (C) 2018 David Lechner <david@lechnology.com>
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_PHY_DA8XX_USB_H__
+#define __LINUX_PLATFORM_DATA_PHY_DA8XX_USB_H__
+
+#include <linux/regmap.h>
+
+/**
+ * da8xx_usb_phy_platform_data
+ * @cfgchip: CFGCHIP syscon regmap
+ */
+struct da8xx_usb_phy_platform_data {
+	struct regmap *cfgchip;
+};
+
+#endif /* __LINUX_PLATFORM_DATA_PHY_DA8XX_USB_H__ */
diff --git a/include/linux/platform_data/pm33xx.h b/include/linux/platform_data/pm33xx.h
new file mode 100644
index 0000000..f9bed2a
--- /dev/null
+++ b/include/linux/platform_data/pm33xx.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TI pm33xx platform data
+ *
+ * Copyright (C) 2016-2018 Texas Instruments, Inc.
+ *	Dave Gerlach <d-gerlach@ti.com>
+ */
+
+#ifndef _LINUX_PLATFORM_DATA_PM33XX_H
+#define _LINUX_PLATFORM_DATA_PM33XX_H
+
+#include <linux/kbuild.h>
+#include <linux/types.h>
+
+#ifndef __ASSEMBLER__
+struct am33xx_pm_sram_addr {
+	void (*do_wfi)(void);
+	unsigned long *do_wfi_sz;
+	unsigned long *resume_offset;
+	unsigned long *emif_sram_table;
+	unsigned long *ro_sram_data;
+};
+
+struct am33xx_pm_platform_data {
+	int	(*init)(void);
+	int	(*soc_suspend)(unsigned int state, int (*fn)(unsigned long));
+	struct  am33xx_pm_sram_addr *(*get_sram_addrs)(void);
+};
+
+struct am33xx_pm_sram_data {
+	u32 wfi_flags;
+	u32 l2_aux_ctrl_val;
+	u32 l2_prefetch_ctrl_val;
+} __packed __aligned(8);
+
+struct am33xx_pm_ro_sram_data {
+	u32 amx3_pm_sram_data_virt;
+	u32 amx3_pm_sram_data_phys;
+} __packed __aligned(8);
+
+#endif /* __ASSEMBLER__ */
+#endif /* _LINUX_PLATFORM_DATA_PM33XX_H */
diff --git a/include/linux/platform_data/spi-omap2-mcspi.h b/include/linux/platform_data/spi-omap2-mcspi.h
index 13c83a2..0bf9fdd 100644
--- a/include/linux/platform_data/spi-omap2-mcspi.h
+++ b/include/linux/platform_data/spi-omap2-mcspi.h
@@ -2,10 +2,6 @@
 #ifndef _OMAP2_MCSPI_H
 #define _OMAP2_MCSPI_H
 
-#define OMAP2_MCSPI_REV 0
-#define OMAP3_MCSPI_REV 1
-#define OMAP4_MCSPI_REV 2
-
 #define OMAP4_MCSPI_REG_OFFSET 0x100
 
 #define MCSPI_PINDIR_D0_IN_D1_OUT	0
@@ -17,10 +13,6 @@ struct omap2_mcspi_platform_config {
 	unsigned int pin_dir:1;
 };
 
-struct omap2_mcspi_dev_attr {
-	unsigned short num_chipselect;
-};
-
 struct omap2_mcspi_device_config {
 	unsigned turbo_mode:1;
 
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h
index 1be3563..80ce28d 100644
--- a/include/linux/platform_data/ti-sysc.h
+++ b/include/linux/platform_data/ti-sysc.h
@@ -16,6 +16,10 @@ enum ti_sysc_module_type {
 	TI_SYSC_OMAP4_USB_HOST_FS,
 };
 
+struct ti_sysc_cookie {
+	void *data;
+};
+
 /**
  * struct sysc_regbits - TI OCP_SYSCONFIG register field offsets
  * @midle_shift: Offset of the midle bit
@@ -41,6 +45,7 @@ struct sysc_regbits {
 	s8 emufree_shift;
 };
 
+#define SYSC_QUIRK_LEGACY_IDLE		BIT(8)
 #define SYSC_QUIRK_RESET_STATUS		BIT(7)
 #define SYSC_QUIRK_NO_IDLE_ON_INIT	BIT(6)
 #define SYSC_QUIRK_NO_RESET_ON_INIT	BIT(5)
@@ -83,4 +88,49 @@ struct sysc_config {
 	u32 quirks;
 };
 
+enum sysc_registers {
+	SYSC_REVISION,
+	SYSC_SYSCONFIG,
+	SYSC_SYSSTATUS,
+	SYSC_MAX_REGS,
+};
+
+/**
+ * struct ti_sysc_module_data - ti-sysc to hwmod translation data for a module
+ * @name: legacy "ti,hwmods" module name
+ * @module_pa: physical address of the interconnect target module
+ * @module_size: size of the interconnect target module
+ * @offsets: array of register offsets as listed in enum sysc_registers
+ * @nr_offsets: number of registers
+ * @cap: interconnect target module capabilities
+ * @cfg: interconnect target module configuration
+ *
+ * This data is enough to allocate a new struct omap_hwmod_class_sysconfig
+ * based on device tree data parsed by ti-sysc driver.
+ */
+struct ti_sysc_module_data {
+	const char *name;
+	u64 module_pa;
+	u32 module_size;
+	int *offsets;
+	int nr_offsets;
+	const struct sysc_capabilities *cap;
+	struct sysc_config *cfg;
+};
+
+struct device;
+
+struct ti_sysc_platform_data {
+	struct of_dev_auxdata *auxdata;
+	int (*init_module)(struct device *dev,
+			   const struct ti_sysc_module_data *data,
+			   struct ti_sysc_cookie *cookie);
+	int (*enable_module)(struct device *dev,
+			     const struct ti_sysc_cookie *cookie);
+	int (*idle_module)(struct device *dev,
+			   const struct ti_sysc_cookie *cookie);
+	int (*shutdown_module)(struct device *dev,
+			       const struct ti_sysc_cookie *cookie);
+};
+
 #endif	/* __TI_SYSC_DATA_H__ */
diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h
index d8b187c3..7b81dad 100644
--- a/include/linux/power/smartreflex.h
+++ b/include/linux/power/smartreflex.h
@@ -143,6 +143,13 @@
 #define OMAP3430_SR_ERRWEIGHT		0x04
 #define OMAP3430_SR_ERRMAXLIMIT		0x02
 
+enum sr_instance {
+	OMAP_SR_MPU,			/* shared with iva on omap3 */
+	OMAP_SR_CORE,
+	OMAP_SR_IVA,
+	OMAP_SR_NR,
+};
+
 struct omap_sr {
 	char				*name;
 	struct list_head		node;
@@ -207,7 +214,6 @@ struct omap_smartreflex_dev_attr {
 	const char      *sensor_voltdm_name;
 };
 
-#ifdef CONFIG_POWER_AVS_OMAP
 /*
  * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
  * The smartreflex class driver should pass the class type.
@@ -290,6 +296,8 @@ struct omap_sr_data {
 	struct voltagedomain		*voltdm;
 };
 
+#ifdef CONFIG_POWER_AVS_OMAP
+
 /* Smartreflex module enable/disable interface */
 void omap_sr_enable(struct voltagedomain *voltdm);
 void omap_sr_disable(struct voltagedomain *voltdm);
diff --git a/include/linux/printk.h b/include/linux/printk.h
index e9b603e..6d7e800 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -201,6 +201,7 @@ void __init setup_log_buf(int early);
 __printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...);
 void dump_stack_print_info(const char *log_lvl);
 void show_regs_print_info(const char *log_lvl);
+extern asmlinkage void dump_stack(void) __cold;
 extern void printk_safe_init(void);
 extern void printk_safe_flush(void);
 extern void printk_safe_flush_on_panic(void);
@@ -264,6 +265,10 @@ static inline void show_regs_print_info(const char *log_lvl)
 {
 }
 
+static inline asmlinkage void dump_stack(void)
+{
+}
+
 static inline void printk_safe_init(void)
 {
 }
@@ -279,8 +284,6 @@ static inline void printk_safe_flush_on_panic(void)
 
 extern int kptr_restrict;
 
-extern asmlinkage void dump_stack(void) __cold;
-
 #ifndef pr_fmt
 #define pr_fmt(fmt) fmt
 #endif
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 5ac9de4..ca9772c 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -267,7 +267,6 @@ struct dqstats {
 	struct percpu_counter counter[_DQST_DQSTAT_LAST];
 };
 
-extern struct dqstats *dqstats_pcpu;
 extern struct dqstats dqstats;
 
 static inline void dqstats_inc(unsigned int type)
diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h
index 31e1ff6..ec86555 100644
--- a/include/linux/raid_class.h
+++ b/include/linux/raid_class.h
@@ -38,6 +38,7 @@ enum raid_level {
 	RAID_LEVEL_5,
 	RAID_LEVEL_50,
 	RAID_LEVEL_6,
+	RAID_LEVEL_JBOD,
 };
 
 struct raid_data {
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
index adb88f8..9326d67 100644
--- a/include/linux/reset-controller.h
+++ b/include/linux/reset-controller.h
@@ -27,12 +27,38 @@ struct device_node;
 struct of_phandle_args;
 
 /**
+ * struct reset_control_lookup - represents a single lookup entry
+ *
+ * @list: internal list of all reset lookup entries
+ * @provider: name of the reset controller device controlling this reset line
+ * @index: ID of the reset controller in the reset controller device
+ * @dev_id: name of the device associated with this reset line
+ * @con_id name of the reset line (can be NULL)
+ */
+struct reset_control_lookup {
+	struct list_head list;
+	const char *provider;
+	unsigned int index;
+	const char *dev_id;
+	const char *con_id;
+};
+
+#define RESET_LOOKUP(_provider, _index, _dev_id, _con_id)		\
+	{								\
+		.provider = _provider,					\
+		.index = _index,					\
+		.dev_id = _dev_id,					\
+		.con_id = _con_id,					\
+	}
+
+/**
  * struct reset_controller_dev - reset controller entity that might
  *                               provide multiple reset controls
  * @ops: a pointer to device specific struct reset_control_ops
  * @owner: kernel module of the reset controller driver
  * @list: internal list of reset controller devices
  * @reset_control_head: head of internal list of requested reset controls
+ * @dev: corresponding driver model device struct
  * @of_node: corresponding device tree node as phandle target
  * @of_reset_n_cells: number of cells in reset line specifiers
  * @of_xlate: translation function to translate from specifier as found in the
@@ -44,6 +70,7 @@ struct reset_controller_dev {
 	struct module *owner;
 	struct list_head list;
 	struct list_head reset_control_head;
+	struct device *dev;
 	struct device_node *of_node;
 	int of_reset_n_cells;
 	int (*of_xlate)(struct reset_controller_dev *rcdev,
@@ -58,4 +85,7 @@ struct device;
 int devm_reset_controller_register(struct device *dev,
 				   struct reset_controller_dev *rcdev);
 
+void reset_controller_add_lookup(struct reset_control_lookup *lookup,
+				 unsigned int num_entries);
+
 #endif
diff --git a/include/linux/rtsx_pci.h b/include/linux/rtsx_pci.h
index 478acf6..e964bbd 100644
--- a/include/linux/rtsx_pci.h
+++ b/include/linux/rtsx_pci.h
@@ -36,12 +36,12 @@
 #define   CHECK_REG_CMD			2
 
 #define RTSX_HDBAR			0x08
-#define   SG_INT			0x04
-#define   SG_END			0x02
-#define   SG_VALID			0x01
-#define   SG_NO_OP			0x00
-#define   SG_TRANS_DATA			(0x02 << 4)
-#define   SG_LINK_DESC			(0x03 << 4)
+#define   RTSX_SG_INT			0x04
+#define   RTSX_SG_END			0x02
+#define   RTSX_SG_VALID			0x01
+#define   RTSX_SG_NO_OP			0x00
+#define   RTSX_SG_TRANS_DATA		(0x02 << 4)
+#define   RTSX_SG_LINK_DESC		(0x03 << 4)
 #define RTSX_HDBCTLR			0x0C
 #define   SDMA_MODE			0x00
 #define   ADMA_MODE			(0x02 << 26)
diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
index 0dcc60e8..841585f 100644
--- a/include/linux/sbitmap.h
+++ b/include/linux/sbitmap.h
@@ -171,6 +171,8 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth);
  *               starting from the last allocated bit. This is less efficient
  *               than the default behavior (false).
  *
+ * This operation provides acquire barrier semantics if it succeeds.
+ *
  * Return: Non-negative allocated bit number if successful, -1 otherwise.
  */
 int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint, bool round_robin);
@@ -300,6 +302,12 @@ static inline void sbitmap_clear_bit(struct sbitmap *sb, unsigned int bitnr)
 	clear_bit(SB_NR_TO_BIT(sb, bitnr), __sbitmap_word(sb, bitnr));
 }
 
+static inline void sbitmap_clear_bit_unlock(struct sbitmap *sb,
+					    unsigned int bitnr)
+{
+	clear_bit_unlock(SB_NR_TO_BIT(sb, bitnr), __sbitmap_word(sb, bitnr));
+}
+
 static inline int sbitmap_test_bit(struct sbitmap *sb, unsigned int bitnr)
 {
 	return test_bit(SB_NR_TO_BIT(sb, bitnr), __sbitmap_word(sb, bitnr));
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index aa5d4eb..51f5202 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -65,16 +65,18 @@ struct sg_table {
  */
 
 #define SG_MAGIC	0x87654321
+#define SG_CHAIN	0x01UL
+#define SG_END		0x02UL
 
 /*
  * We overload the LSB of the page pointer to indicate whether it's
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)		((sg)->page_link & 0x01)
-#define sg_is_last(sg)		((sg)->page_link & 0x02)
+#define sg_is_chain(sg)		((sg)->page_link & SG_CHAIN)
+#define sg_is_last(sg)		((sg)->page_link & SG_END)
 #define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((sg)->page_link & ~0x03))
+	((struct scatterlist *) ((sg)->page_link & ~(SG_CHAIN | SG_END)))
 
 /**
  * sg_assign_page - Assign a given page to an SG entry
@@ -88,13 +90,13 @@ struct sg_table {
  **/
 static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
 {
-	unsigned long page_link = sg->page_link & 0x3;
+	unsigned long page_link = sg->page_link & (SG_CHAIN | SG_END);
 
 	/*
 	 * In order for the low bit stealing approach to work, pages
 	 * must be aligned at a 32-bit boundary as a minimum.
 	 */
-	BUG_ON((unsigned long) page & 0x03);
+	BUG_ON((unsigned long) page & (SG_CHAIN | SG_END));
 #ifdef CONFIG_DEBUG_SG
 	BUG_ON(sg->sg_magic != SG_MAGIC);
 	BUG_ON(sg_is_chain(sg));
@@ -130,7 +132,7 @@ static inline struct page *sg_page(struct scatterlist *sg)
 	BUG_ON(sg->sg_magic != SG_MAGIC);
 	BUG_ON(sg_is_chain(sg));
 #endif
-	return (struct page *)((sg)->page_link & ~0x3);
+	return (struct page *)((sg)->page_link & ~(SG_CHAIN | SG_END));
 }
 
 /**
@@ -178,7 +180,8 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 	 * Set lowest bit to indicate a link pointer, and make sure to clear
 	 * the termination bit if it happens to be set.
 	 */
-	prv[prv_nents - 1].page_link = ((unsigned long) sgl | 0x01) & ~0x02;
+	prv[prv_nents - 1].page_link = ((unsigned long) sgl | SG_CHAIN)
+					& ~SG_END;
 }
 
 /**
@@ -198,8 +201,8 @@ static inline void sg_mark_end(struct scatterlist *sg)
 	/*
 	 * Set termination bit, clear potential chain bit
 	 */
-	sg->page_link |= 0x02;
-	sg->page_link &= ~0x01;
+	sg->page_link |= SG_END;
+	sg->page_link &= ~SG_CHAIN;
 }
 
 /**
@@ -215,7 +218,7 @@ static inline void sg_unmark_end(struct scatterlist *sg)
 #ifdef CONFIG_DEBUG_SG
 	BUG_ON(sg->sg_magic != SG_MAGIC);
 #endif
-	sg->page_link &= ~0x02;
+	sg->page_link &= ~SG_END;
 }
 
 /**
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
new file mode 100644
index 0000000..b458c87
--- /dev/null
+++ b/include/linux/scmi_protocol.h
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SCMI Message Protocol driver header
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ */
+#include <linux/device.h>
+#include <linux/types.h>
+
+#define SCMI_MAX_STR_SIZE	16
+#define SCMI_MAX_NUM_RATES	16
+
+/**
+ * struct scmi_revision_info - version information structure
+ *
+ * @major_ver: Major ABI version. Change here implies risk of backward
+ *	compatibility break.
+ * @minor_ver: Minor ABI version. Change here implies new feature addition,
+ *	or compatible change in ABI.
+ * @num_protocols: Number of protocols that are implemented, excluding the
+ *	base protocol.
+ * @num_agents: Number of agents in the system.
+ * @impl_ver: A vendor-specific implementation version.
+ * @vendor_id: A vendor identifier(Null terminated ASCII string)
+ * @sub_vendor_id: A sub-vendor identifier(Null terminated ASCII string)
+ */
+struct scmi_revision_info {
+	u16 major_ver;
+	u16 minor_ver;
+	u8 num_protocols;
+	u8 num_agents;
+	u32 impl_ver;
+	char vendor_id[SCMI_MAX_STR_SIZE];
+	char sub_vendor_id[SCMI_MAX_STR_SIZE];
+};
+
+struct scmi_clock_info {
+	char name[SCMI_MAX_STR_SIZE];
+	bool rate_discrete;
+	union {
+		struct {
+			int num_rates;
+			u64 rates[SCMI_MAX_NUM_RATES];
+		} list;
+		struct {
+			u64 min_rate;
+			u64 max_rate;
+			u64 step_size;
+		} range;
+	};
+};
+
+struct scmi_handle;
+
+/**
+ * struct scmi_clk_ops - represents the various operations provided
+ *	by SCMI Clock Protocol
+ *
+ * @count_get: get the count of clocks provided by SCMI
+ * @info_get: get the information of the specified clock
+ * @rate_get: request the current clock rate of a clock
+ * @rate_set: set the clock rate of a clock
+ * @enable: enables the specified clock
+ * @disable: disables the specified clock
+ */
+struct scmi_clk_ops {
+	int (*count_get)(const struct scmi_handle *handle);
+
+	const struct scmi_clock_info *(*info_get)
+		(const struct scmi_handle *handle, u32 clk_id);
+	int (*rate_get)(const struct scmi_handle *handle, u32 clk_id,
+			u64 *rate);
+	int (*rate_set)(const struct scmi_handle *handle, u32 clk_id,
+			u32 config, u64 rate);
+	int (*enable)(const struct scmi_handle *handle, u32 clk_id);
+	int (*disable)(const struct scmi_handle *handle, u32 clk_id);
+};
+
+/**
+ * struct scmi_perf_ops - represents the various operations provided
+ *	by SCMI Performance Protocol
+ *
+ * @limits_set: sets limits on the performance level of a domain
+ * @limits_get: gets limits on the performance level of a domain
+ * @level_set: sets the performance level of a domain
+ * @level_get: gets the performance level of a domain
+ * @device_domain_id: gets the scmi domain id for a given device
+ * @get_transition_latency: gets the DVFS transition latency for a given device
+ * @add_opps_to_device: adds all the OPPs for a given device
+ * @freq_set: sets the frequency for a given device using sustained frequency
+ *	to sustained performance level mapping
+ * @freq_get: gets the frequency for a given device using sustained frequency
+ *	to sustained performance level mapping
+ */
+struct scmi_perf_ops {
+	int (*limits_set)(const struct scmi_handle *handle, u32 domain,
+			  u32 max_perf, u32 min_perf);
+	int (*limits_get)(const struct scmi_handle *handle, u32 domain,
+			  u32 *max_perf, u32 *min_perf);
+	int (*level_set)(const struct scmi_handle *handle, u32 domain,
+			 u32 level, bool poll);
+	int (*level_get)(const struct scmi_handle *handle, u32 domain,
+			 u32 *level, bool poll);
+	int (*device_domain_id)(struct device *dev);
+	int (*get_transition_latency)(const struct scmi_handle *handle,
+				      struct device *dev);
+	int (*add_opps_to_device)(const struct scmi_handle *handle,
+				  struct device *dev);
+	int (*freq_set)(const struct scmi_handle *handle, u32 domain,
+			unsigned long rate, bool poll);
+	int (*freq_get)(const struct scmi_handle *handle, u32 domain,
+			unsigned long *rate, bool poll);
+};
+
+/**
+ * struct scmi_power_ops - represents the various operations provided
+ *	by SCMI Power Protocol
+ *
+ * @num_domains_get: get the count of power domains provided by SCMI
+ * @name_get: gets the name of a power domain
+ * @state_set: sets the power state of a power domain
+ * @state_get: gets the power state of a power domain
+ */
+struct scmi_power_ops {
+	int (*num_domains_get)(const struct scmi_handle *handle);
+	char *(*name_get)(const struct scmi_handle *handle, u32 domain);
+#define SCMI_POWER_STATE_TYPE_SHIFT	30
+#define SCMI_POWER_STATE_ID_MASK	(BIT(28) - 1)
+#define SCMI_POWER_STATE_PARAM(type, id) \
+	((((type) & BIT(0)) << SCMI_POWER_STATE_TYPE_SHIFT) | \
+		((id) & SCMI_POWER_STATE_ID_MASK))
+#define SCMI_POWER_STATE_GENERIC_ON	SCMI_POWER_STATE_PARAM(0, 0)
+#define SCMI_POWER_STATE_GENERIC_OFF	SCMI_POWER_STATE_PARAM(1, 0)
+	int (*state_set)(const struct scmi_handle *handle, u32 domain,
+			 u32 state);
+	int (*state_get)(const struct scmi_handle *handle, u32 domain,
+			 u32 *state);
+};
+
+struct scmi_sensor_info {
+	u32 id;
+	u8 type;
+	char name[SCMI_MAX_STR_SIZE];
+};
+
+/*
+ * Partial list from Distributed Management Task Force (DMTF) specification:
+ * DSP0249 (Platform Level Data Model specification)
+ */
+enum scmi_sensor_class {
+	NONE = 0x0,
+	TEMPERATURE_C = 0x2,
+	VOLTAGE = 0x5,
+	CURRENT = 0x6,
+	POWER = 0x7,
+	ENERGY = 0x8,
+};
+
+/**
+ * struct scmi_sensor_ops - represents the various operations provided
+ *	by SCMI Sensor Protocol
+ *
+ * @count_get: get the count of sensors provided by SCMI
+ * @info_get: get the information of the specified sensor
+ * @configuration_set: control notifications on cross-over events for
+ *	the trip-points
+ * @trip_point_set: selects and configures a trip-point of interest
+ * @reading_get: gets the current value of the sensor
+ */
+struct scmi_sensor_ops {
+	int (*count_get)(const struct scmi_handle *handle);
+
+	const struct scmi_sensor_info *(*info_get)
+		(const struct scmi_handle *handle, u32 sensor_id);
+	int (*configuration_set)(const struct scmi_handle *handle,
+				 u32 sensor_id);
+	int (*trip_point_set)(const struct scmi_handle *handle, u32 sensor_id,
+			      u8 trip_id, u64 trip_value);
+	int (*reading_get)(const struct scmi_handle *handle, u32 sensor_id,
+			   bool async, u64 *value);
+};
+
+/**
+ * struct scmi_handle - Handle returned to ARM SCMI clients for usage.
+ *
+ * @dev: pointer to the SCMI device
+ * @version: pointer to the structure containing SCMI version information
+ * @power_ops: pointer to set of power protocol operations
+ * @perf_ops: pointer to set of performance protocol operations
+ * @clk_ops: pointer to set of clock protocol operations
+ * @sensor_ops: pointer to set of sensor protocol operations
+ */
+struct scmi_handle {
+	struct device *dev;
+	struct scmi_revision_info *version;
+	struct scmi_perf_ops *perf_ops;
+	struct scmi_clk_ops *clk_ops;
+	struct scmi_power_ops *power_ops;
+	struct scmi_sensor_ops *sensor_ops;
+	/* for protocol internal use */
+	void *perf_priv;
+	void *clk_priv;
+	void *power_priv;
+	void *sensor_priv;
+};
+
+enum scmi_std_protocol {
+	SCMI_PROTOCOL_BASE = 0x10,
+	SCMI_PROTOCOL_POWER = 0x11,
+	SCMI_PROTOCOL_SYSTEM = 0x12,
+	SCMI_PROTOCOL_PERF = 0x13,
+	SCMI_PROTOCOL_CLOCK = 0x14,
+	SCMI_PROTOCOL_SENSOR = 0x15,
+};
+
+struct scmi_device {
+	u32 id;
+	u8 protocol_id;
+	struct device dev;
+	struct scmi_handle *handle;
+};
+
+#define to_scmi_dev(d) container_of(d, struct scmi_device, dev)
+
+struct scmi_device *
+scmi_device_create(struct device_node *np, struct device *parent, int protocol);
+void scmi_device_destroy(struct scmi_device *scmi_dev);
+
+struct scmi_device_id {
+	u8 protocol_id;
+};
+
+struct scmi_driver {
+	const char *name;
+	int (*probe)(struct scmi_device *sdev);
+	void (*remove)(struct scmi_device *sdev);
+	const struct scmi_device_id *id_table;
+
+	struct device_driver driver;
+};
+
+#define to_scmi_driver(d) container_of(d, struct scmi_driver, driver)
+
+#ifdef CONFIG_ARM_SCMI_PROTOCOL
+int scmi_driver_register(struct scmi_driver *driver,
+			 struct module *owner, const char *mod_name);
+void scmi_driver_unregister(struct scmi_driver *driver);
+#else
+static inline int
+scmi_driver_register(struct scmi_driver *driver, struct module *owner,
+		     const char *mod_name)
+{
+	return -EINVAL;
+}
+
+static inline void scmi_driver_unregister(struct scmi_driver *driver) {}
+#endif /* CONFIG_ARM_SCMI_PROTOCOL */
+
+#define scmi_register(driver) \
+	scmi_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+#define scmi_unregister(driver) \
+	scmi_driver_unregister(driver)
+
+/**
+ * module_scmi_driver() - Helper macro for registering a scmi driver
+ * @__scmi_driver: scmi_driver structure
+ *
+ * Helper macro for scmi drivers to set up proper module init / exit
+ * functions.  Replaces module_init() and module_exit() and keeps people from
+ * printing pointless things to the kernel log when their driver is loaded.
+ */
+#define module_scmi_driver(__scmi_driver)	\
+	module_driver(__scmi_driver, scmi_register, scmi_unregister)
+
+typedef int (*scmi_prot_init_fn_t)(struct scmi_handle *);
+int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn);
+void scmi_protocol_unregister(int protocol_id);
diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h
index a7f004a..463ed28 100644
--- a/include/linux/serial_s3c.h
+++ b/include/linux/serial_s3c.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  Internal header file for Samsung S3C2410 serial ports (UART0-2)
  *
@@ -10,21 +11,7 @@
  *  Internal header file for MX1ADS serial ports (UART1 & 2)
  *
  *  Copyright (C) 2002 Shane Nay (shane@minirl.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_ARM_REGS_SERIAL_H
 #define __ASM_ARM_REGS_SERIAL_H
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
index b0a507d..fd25f01 100644
--- a/include/linux/soc/mediatek/infracfg.h
+++ b/include/linux/soc/mediatek/infracfg.h
@@ -21,6 +21,10 @@
 #define MT8173_TOP_AXI_PROT_EN_MFG_M1		BIT(22)
 #define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT	BIT(23)
 
+#define MT2701_TOP_AXI_PROT_EN_MM_M0		BIT(1)
+#define MT2701_TOP_AXI_PROT_EN_CONN_M		BIT(2)
+#define MT2701_TOP_AXI_PROT_EN_CONN_S		BIT(8)
+
 #define MT7622_TOP_AXI_PROT_EN_ETHSYS		(BIT(3) | BIT(17))
 #define MT7622_TOP_AXI_PROT_EN_HIF0		(BIT(24) | BIT(25))
 #define MT7622_TOP_AXI_PROT_EN_HIF1		(BIT(26) | BIT(27) | \
diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
index e57eb4b..fc0b445 100644
--- a/include/linux/soc/samsung/exynos-pmu.h
+++ b/include/linux/soc/samsung/exynos-pmu.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com
  *
  * Header for EXYNOS PMU Driver support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #ifndef __LINUX_SOC_EXYNOS_PMU_H
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index bebdde5..66dcb9e 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2010-2015 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com
  *
  * EXYNOS - Power management unit definition
  *
- * 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.
- *
- *
  * Notice:
  * This is not a list of all Exynos Power Management Unit SFRs.
  * There are too many of them, not mentioning subtle differences
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 786ae22..574368e 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -272,6 +272,7 @@ struct svc_rqst {
 #define	RQ_BUSY		(6)			/* request is busy */
 #define	RQ_DATA		(7)			/* request has data */
 	unsigned long		rq_flags;	/* flags field */
+	ktime_t			rq_qtime;	/* enqueue time */
 
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */
@@ -283,6 +284,7 @@ struct svc_rqst {
 	int			rq_reserved;	/* space on socket outq
 						 * reserved for this request
 						 */
+	ktime_t			rq_stime;	/* start time */
 
 	struct cache_req	rq_chandle;	/* handle passed to caches for 
 						 * request delaying 
@@ -493,6 +495,10 @@ void		   svc_wake_up(struct svc_serv *);
 void		   svc_reserve(struct svc_rqst *rqstp, int space);
 struct svc_pool *  svc_pool_for_cpu(struct svc_serv *serv, int cpu);
 char *		   svc_print_addr(struct svc_rqst *, char *, size_t);
+unsigned int	   svc_fill_write_vector(struct svc_rqst *rqstp,
+					 struct kvec *first, size_t total);
+char		  *svc_fill_symlink_pathname(struct svc_rqst *rqstp,
+					     struct kvec *first, size_t total);
 
 #define	RPC_MAX_ADDRBUFLEN	(63U)
 
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index 4b731b0..7337e12 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -132,9 +132,6 @@ struct svcxprt_rdma {
 #define RDMAXPRT_CONN_PENDING	3
 
 #define RPCRDMA_LISTEN_BACKLOG  10
-/* The default ORD value is based on two outstanding full-size writes with a
- * page size of 4k, or 32k * 2 ops / 4k = 16 outstanding RDMA_READ.  */
-#define RPCRDMA_ORD             (64/4)
 #define RPCRDMA_MAX_REQUESTS    32
 
 /* Typical ULP usage of BC requests is NFSv4.1 backchannel. Our
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 1caf7bc..c3d7206 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -25,7 +25,7 @@ struct svc_xprt_ops {
 	void		(*xpo_release_rqst)(struct svc_rqst *);
 	void		(*xpo_detach)(struct svc_xprt *);
 	void		(*xpo_free)(struct svc_xprt *);
-	int		(*xpo_secure_port)(struct svc_rqst *);
+	void		(*xpo_secure_port)(struct svc_rqst *rqstp);
 	void		(*xpo_kill_temp_xprt)(struct svc_xprt *);
 };
 
@@ -83,6 +83,7 @@ struct svc_xprt {
 	size_t			xpt_locallen;	/* length of address */
 	struct sockaddr_storage	xpt_remote;	/* remote peer's address */
 	size_t			xpt_remotelen;	/* length of address */
+	char			xpt_remotebuf[INET6_ADDRSTRLEN + 10];
 	struct rpc_wait_queue	xpt_bc_pending;	/* backchannel wait queue */
 	struct list_head	xpt_users;	/* callbacks on free */
 
@@ -152,7 +153,10 @@ static inline void svc_xprt_set_remote(struct svc_xprt *xprt,
 {
 	memcpy(&xprt->xpt_remote, sa, salen);
 	xprt->xpt_remotelen = salen;
+	snprintf(xprt->xpt_remotebuf, sizeof(xprt->xpt_remotebuf) - 1,
+		 "%pISpc", sa);
 }
+
 static inline unsigned short svc_addr_port(const struct sockaddr *sa)
 {
 	const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h
index 3119d0a..aaafecf 100644
--- a/include/linux/usb/audio-v2.h
+++ b/include/linux/usb/audio-v2.h
@@ -34,14 +34,14 @@
  *
  */
 
-static inline bool uac2_control_is_readable(u32 bmControls, u8 control)
+static inline bool uac_v2v3_control_is_readable(u32 bmControls, u8 control)
 {
-	return (bmControls >> (control * 2)) & 0x1;
+	return (bmControls >> ((control - 1) * 2)) & 0x1;
 }
 
-static inline bool uac2_control_is_writeable(u32 bmControls, u8 control)
+static inline bool uac_v2v3_control_is_writeable(u32 bmControls, u8 control)
 {
-	return (bmControls >> (control * 2)) & 0x2;
+	return (bmControls >> ((control - 1) * 2)) & 0x2;
 }
 
 /* 4.7.2 Class-Specific AC Interface Descriptor */
diff --git a/include/linux/usb/audio-v3.h b/include/linux/usb/audio-v3.h
new file mode 100644
index 0000000..a8959aa
--- /dev/null
+++ b/include/linux/usb/audio-v3.h
@@ -0,0 +1,395 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2017 Ruslan Bilovol <ruslan.bilovol@gmail.com>
+ *
+ * This file holds USB constants and structures defined
+ * by the USB DEVICE CLASS DEFINITION FOR AUDIO DEVICES Release 3.0.
+ */
+
+#ifndef __LINUX_USB_AUDIO_V3_H
+#define __LINUX_USB_AUDIO_V3_H
+
+#include <linux/types.h>
+
+/*
+ * v1.0, v2.0 and v3.0 of this standard have many things in common. For the rest
+ * of the definitions, please refer to audio.h and audio-v2.h
+ */
+
+/* All High Capability descriptors have these 2 fields at the beginning */
+struct uac3_hc_descriptor_header {
+	__le16 wLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__le16 wDescriptorID;
+} __attribute__ ((packed));
+
+/* 4.3.1 CLUSTER DESCRIPTOR HEADER */
+struct uac3_cluster_header_descriptor {
+	__le16 wLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__le16 wDescriptorID;
+	__u8 bNrChannels;
+} __attribute__ ((packed));
+
+/* 4.3.2.1 SEGMENTS */
+struct uac3_cluster_segment_descriptor {
+	__le16 wLength;
+	__u8 bSegmentType;
+	/* __u8[0]; segment-specific data */
+} __attribute__ ((packed));
+
+/* 4.3.2.1.1 END SEGMENT */
+struct uac3_cluster_end_segment_descriptor {
+	__le16 wLength;
+	__u8 bSegmentType;		/* Constant END_SEGMENT */
+} __attribute__ ((packed));
+
+/* 4.3.2.1.3.1 INFORMATION SEGMENT */
+struct uac3_cluster_information_segment_descriptor {
+	__le16 wLength;
+	__u8 bSegmentType;
+	__u8 bChPurpose;
+	__u8 bChRelationship;
+	__u8 bChGroupID;
+} __attribute__ ((packed));
+
+/* 4.5.2 CLASS-SPECIFIC AC INTERFACE DESCRIPTOR */
+struct uac3_ac_header_descriptor {
+	__u8 bLength;			/* 10 */
+	__u8 bDescriptorType;		/* CS_INTERFACE descriptor type */
+	__u8 bDescriptorSubtype;	/* HEADER descriptor subtype */
+	__u8 bCategory;
+
+	/* includes Clock Source, Unit, Terminal, and Power Domain desc. */
+	__le16 wTotalLength;
+
+	__le32 bmControls;
+} __attribute__ ((packed));
+
+/* 4.5.2.1 INPUT TERMINAL DESCRIPTOR */
+struct uac3_input_terminal_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__u8 bTerminalID;
+	__le16 wTerminalType;
+	__u8 bAssocTerminal;
+	__u8 bCSourceID;
+	__le32 bmControls;
+	__le16 wClusterDescrID;
+	__le16 wExTerminalDescrID;
+	__le16 wConnectorsDescrID;
+	__le16 wTerminalDescrStr;
+} __attribute__((packed));
+
+/* 4.5.2.2 OUTPUT TERMINAL DESCRIPTOR */
+struct uac3_output_terminal_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__u8 bTerminalID;
+	__le16 wTerminalType;
+	__u8 bAssocTerminal;
+	__u8 bSourceID;
+	__u8 bCSourceID;
+	__le32 bmControls;
+	__le16 wExTerminalDescrID;
+	__le16 wConnectorsDescrID;
+	__le16 wTerminalDescrStr;
+} __attribute__((packed));
+
+/* 4.5.2.7 FEATURE UNIT DESCRIPTOR */
+struct uac3_feature_unit_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__u8 bUnitID;
+	__u8 bSourceID;
+	/* bmaControls is actually u32,
+	 * but u8 is needed for the hybrid parser */
+	__u8 bmaControls[0]; /* variable length */
+	/* wFeatureDescrStr omitted */
+} __attribute__((packed));
+
+#define UAC3_DT_FEATURE_UNIT_SIZE(ch)		(7 + ((ch) + 1) * 4)
+
+/* As above, but more useful for defining your own descriptors */
+#define DECLARE_UAC3_FEATURE_UNIT_DESCRIPTOR(ch)		\
+struct uac3_feature_unit_descriptor_##ch {			\
+	__u8 bLength;						\
+	__u8 bDescriptorType;					\
+	__u8 bDescriptorSubtype;				\
+	__u8 bUnitID;						\
+	__u8 bSourceID;						\
+	__le32 bmaControls[ch + 1];				\
+	__le16 wFeatureDescrStr;				\
+} __attribute__ ((packed))
+
+/* 4.5.2.12 CLOCK SOURCE DESCRIPTOR */
+struct uac3_clock_source_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__u8 bClockID;
+	__u8 bmAttributes;
+	__le32 bmControls;
+	__u8 bReferenceTerminal;
+	__le16 wClockSourceStr;
+} __attribute__((packed));
+
+/* bmAttribute fields */
+#define UAC3_CLOCK_SOURCE_TYPE_EXT	0x0
+#define UAC3_CLOCK_SOURCE_TYPE_INT	0x1
+#define UAC3_CLOCK_SOURCE_ASYNC		(0 << 2)
+#define UAC3_CLOCK_SOURCE_SYNCED_TO_SOF	(1 << 1)
+
+/* 4.5.2.13 CLOCK SELECTOR DESCRIPTOR */
+struct uac3_clock_selector_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__u8 bClockID;
+	__u8 bNrInPins;
+	__u8 baCSourceID[];
+	/* bmControls and wCSelectorDescrStr omitted */
+} __attribute__((packed));
+
+/* 4.5.2.14 CLOCK MULTIPLIER DESCRIPTOR */
+struct uac3_clock_multiplier_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__u8 bClockID;
+	__u8 bCSourceID;
+	__le32 bmControls;
+	__le16 wCMultiplierDescrStr;
+} __attribute__((packed));
+
+/* 4.5.2.15 POWER DOMAIN DESCRIPTOR */
+struct uac3_power_domain_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__u8 bPowerDomainID;
+	__le16 waRecoveryTime1;
+	__le16 waRecoveryTime2;
+	__u8 bNrEntities;
+	__u8 baEntityID[];
+	/* wPDomainDescrStr omitted */
+} __attribute__((packed));
+
+/* As above, but more useful for defining your own descriptors */
+#define DECLARE_UAC3_POWER_DOMAIN_DESCRIPTOR(n)			\
+struct uac3_power_domain_descriptor_##n {			\
+	__u8 bLength;						\
+	__u8 bDescriptorType;					\
+	__u8 bDescriptorSubtype;				\
+	__u8 bPowerDomainID;					\
+	__le16 waRecoveryTime1;					\
+	__le16 waRecoveryTime2;					\
+	__u8 bNrEntities;					\
+	__u8 baEntityID[n];					\
+	__le16 wPDomainDescrStr;					\
+} __attribute__ ((packed))
+
+/* 4.7.2 CLASS-SPECIFIC AS INTERFACE DESCRIPTOR */
+struct uac3_as_header_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__u8 bTerminalLink;
+	__le32 bmControls;
+	__le16 wClusterDescrID;
+	__le64 bmFormats;
+	__u8 bSubslotSize;
+	__u8 bBitResolution;
+	__le16 bmAuxProtocols;
+	__u8 bControlSize;
+} __attribute__((packed));
+
+#define UAC3_FORMAT_TYPE_I_RAW_DATA	(1 << 6)
+
+/* 4.8.1.2 CLASS-SPECIFIC AS ISOCHRONOUS AUDIO DATA ENDPOINT DESCRIPTOR */
+struct uac3_iso_endpoint_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDescriptorSubtype;
+	__le32 bmControls;
+	__u8 bLockDelayUnits;
+	__le16 wLockDelay;
+} __attribute__((packed));
+
+/* 6.1 INTERRUPT DATA MESSAGE */
+struct uac3_interrupt_data_msg {
+	__u8 bInfo;
+	__u8 bSourceType;
+	__le16 wValue;
+	__le16 wIndex;
+} __attribute__((packed));
+
+/* A.2 AUDIO AUDIO FUNCTION SUBCLASS CODES */
+#define UAC3_FUNCTION_SUBCLASS_UNDEFINED	0x00
+#define UAC3_FUNCTION_SUBCLASS_FULL_ADC_3_0	0x01
+/* BADD profiles */
+#define UAC3_FUNCTION_SUBCLASS_GENERIC_IO	0x20
+#define UAC3_FUNCTION_SUBCLASS_HEADPHONE	0x21
+#define UAC3_FUNCTION_SUBCLASS_SPEAKER		0x22
+#define UAC3_FUNCTION_SUBCLASS_MICROPHONE	0x23
+#define UAC3_FUNCTION_SUBCLASS_HEADSET		0x24
+#define UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER	0x25
+#define UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE	0x26
+
+/* A.7 AUDIO FUNCTION CATEGORY CODES */
+#define UAC3_FUNCTION_SUBCLASS_UNDEFINED	0x00
+#define UAC3_FUNCTION_DESKTOP_SPEAKER		0x01
+#define UAC3_FUNCTION_HOME_THEATER		0x02
+#define UAC3_FUNCTION_MICROPHONE		0x03
+#define UAC3_FUNCTION_HEADSET			0x04
+#define UAC3_FUNCTION_TELEPHONE			0x05
+#define UAC3_FUNCTION_CONVERTER			0x06
+#define UAC3_FUNCTION_SOUND_RECORDER		0x07
+#define UAC3_FUNCTION_IO_BOX			0x08
+#define UAC3_FUNCTION_MUSICAL_INSTRUMENT	0x09
+#define UAC3_FUNCTION_PRO_AUDIO			0x0a
+#define UAC3_FUNCTION_AUDIO_VIDEO		0x0b
+#define UAC3_FUNCTION_CONTROL_PANEL		0x0c
+#define UAC3_FUNCTION_HEADPHONE			0x0d
+#define UAC3_FUNCTION_GENERIC_SPEAKER		0x0e
+#define UAC3_FUNCTION_HEADSET_ADAPTER		0x0f
+#define UAC3_FUNCTION_SPEAKERPHONE		0x10
+#define UAC3_FUNCTION_OTHER			0xff
+
+/* A.8 AUDIO CLASS-SPECIFIC DESCRIPTOR TYPES */
+#define UAC3_CS_UNDEFINED		0x20
+#define UAC3_CS_DEVICE			0x21
+#define UAC3_CS_CONFIGURATION		0x22
+#define UAC3_CS_STRING			0x23
+#define UAC3_CS_INTERFACE		0x24
+#define UAC3_CS_ENDPOINT		0x25
+#define UAC3_CS_CLUSTER			0x26
+
+/* A.10 CLUSTER DESCRIPTOR SEGMENT TYPES */
+#define UAC3_SEGMENT_UNDEFINED		0x00
+#define UAC3_CLUSTER_DESCRIPTION	0x01
+#define UAC3_CLUSTER_VENDOR_DEFINED	0x1F
+#define UAC3_CHANNEL_INFORMATION	0x20
+#define UAC3_CHANNEL_AMBISONIC		0x21
+#define UAC3_CHANNEL_DESCRIPTION	0x22
+#define UAC3_CHANNEL_VENDOR_DEFINED	0xFE
+#define UAC3_END_SEGMENT		0xFF
+
+/* A.11 CHANNEL PURPOSE DEFINITIONS */
+#define UAC3_PURPOSE_UNDEFINED		0x00
+#define UAC3_PURPOSE_GENERIC_AUDIO	0x01
+#define UAC3_PURPOSE_VOICE		0x02
+#define UAC3_PURPOSE_SPEECH		0x03
+#define UAC3_PURPOSE_AMBIENT		0x04
+#define UAC3_PURPOSE_REFERENCE		0x05
+#define UAC3_PURPOSE_ULTRASONIC		0x06
+#define UAC3_PURPOSE_VIBROKINETIC	0x07
+#define UAC3_PURPOSE_NON_AUDIO		0xFF
+
+/* A.12 CHANNEL RELATIONSHIP DEFINITIONS */
+#define UAC3_CH_RELATIONSHIP_UNDEFINED	0x00
+#define UAC3_CH_MONO			0x01
+#define UAC3_CH_LEFT			0x02
+#define UAC3_CH_RIGHT			0x03
+#define UAC3_CH_ARRAY			0x04
+#define UAC3_CH_PATTERN_X		0x20
+#define UAC3_CH_PATTERN_Y		0x21
+#define UAC3_CH_PATTERN_A		0x22
+#define UAC3_CH_PATTERN_B		0x23
+#define UAC3_CH_PATTERN_M		0x24
+#define UAC3_CH_PATTERN_S		0x25
+#define UAC3_CH_FRONT_LEFT		0x80
+#define UAC3_CH_FRONT_RIGHT		0x81
+#define UAC3_CH_FRONT_CENTER		0x82
+#define UAC3_CH_FRONT_LEFT_OF_CENTER	0x83
+#define UAC3_CH_FRONT_RIGHT_OF_CENTER	0x84
+#define UAC3_CH_FRONT_WIDE_LEFT		0x85
+#define UAC3_CH_FRONT_WIDE_RIGHT	0x86
+#define UAC3_CH_SIDE_LEFT		0x87
+#define UAC3_CH_SIDE_RIGHT		0x88
+#define UAC3_CH_SURROUND_ARRAY_LEFT	0x89
+#define UAC3_CH_SURROUND_ARRAY_RIGHT	0x8A
+#define UAC3_CH_BACK_LEFT		0x8B
+#define UAC3_CH_BACK_RIGHT		0x8C
+#define UAC3_CH_BACK_CENTER		0x8D
+#define UAC3_CH_BACK_LEFT_OF_CENTER	0x8E
+#define UAC3_CH_BACK_RIGHT_OF_CENTER	0x8F
+#define UAC3_CH_BACK_WIDE_LEFT		0x90
+#define UAC3_CH_BACK_WIDE_RIGHT		0x91
+#define UAC3_CH_TOP_CENTER		0x92
+#define UAC3_CH_TOP_FRONT_LEFT		0x93
+#define UAC3_CH_TOP_FRONT_RIGHT		0x94
+#define UAC3_CH_TOP_FRONT_CENTER	0x95
+#define UAC3_CH_TOP_FRONT_LOC		0x96
+#define UAC3_CH_TOP_FRONT_ROC		0x97
+#define UAC3_CH_TOP_FRONT_WIDE_LEFT	0x98
+#define UAC3_CH_TOP_FRONT_WIDE_RIGHT	0x99
+#define UAC3_CH_TOP_SIDE_LEFT		0x9A
+#define UAC3_CH_TOP_SIDE_RIGHT		0x9B
+#define UAC3_CH_TOP_SURR_ARRAY_LEFT	0x9C
+#define UAC3_CH_TOP_SURR_ARRAY_RIGHT	0x9D
+#define UAC3_CH_TOP_BACK_LEFT		0x9E
+#define UAC3_CH_TOP_BACK_RIGHT		0x9F
+#define UAC3_CH_TOP_BACK_CENTER		0xA0
+#define UAC3_CH_TOP_BACK_LOC		0xA1
+#define UAC3_CH_TOP_BACK_ROC		0xA2
+#define UAC3_CH_TOP_BACK_WIDE_LEFT	0xA3
+#define UAC3_CH_TOP_BACK_WIDE_RIGHT	0xA4
+#define UAC3_CH_BOTTOM_CENTER		0xA5
+#define UAC3_CH_BOTTOM_FRONT_LEFT	0xA6
+#define UAC3_CH_BOTTOM_FRONT_RIGHT	0xA7
+#define UAC3_CH_BOTTOM_FRONT_CENTER	0xA8
+#define UAC3_CH_BOTTOM_FRONT_LOC	0xA9
+#define UAC3_CH_BOTTOM_FRONT_ROC	0xAA
+#define UAC3_CH_BOTTOM_FRONT_WIDE_LEFT	0xAB
+#define UAC3_CH_BOTTOM_FRONT_WIDE_RIGHT	0xAC
+#define UAC3_CH_BOTTOM_SIDE_LEFT	0xAD
+#define UAC3_CH_BOTTOM_SIDE_RIGHT	0xAE
+#define UAC3_CH_BOTTOM_SURR_ARRAY_LEFT	0xAF
+#define UAC3_CH_BOTTOM_SURR_ARRAY_RIGHT	0xB0
+#define UAC3_CH_BOTTOM_BACK_LEFT	0xB1
+#define UAC3_CH_BOTTOM_BACK_RIGHT	0xB2
+#define UAC3_CH_BOTTOM_BACK_CENTER	0xB3
+#define UAC3_CH_BOTTOM_BACK_LOC		0xB4
+#define UAC3_CH_BOTTOM_BACK_ROC		0xB5
+#define UAC3_CH_BOTTOM_BACK_WIDE_LEFT	0xB6
+#define UAC3_CH_BOTTOM_BACK_WIDE_RIGHT	0xB7
+#define UAC3_CH_LOW_FREQUENCY_EFFECTS	0xB8
+#define UAC3_CH_LFE_LEFT		0xB9
+#define UAC3_CH_LFE_RIGHT		0xBA
+#define UAC3_CH_HEADPHONE_LEFT		0xBB
+#define UAC3_CH_HEADPHONE_RIGHT		0xBC
+
+/* A.15 AUDIO CLASS-SPECIFIC AC INTERFACE DESCRIPTOR SUBTYPES */
+/* see audio.h for the rest, which is identical to v1 */
+#define UAC3_EXTENDED_TERMINAL		0x04
+#define UAC3_MIXER_UNIT			0x05
+#define UAC3_SELECTOR_UNIT		0x06
+#define UAC3_FEATURE_UNIT		0x07
+#define UAC3_EFFECT_UNIT		0x08
+#define UAC3_PROCESSING_UNIT		0x09
+#define UAC3_EXTENSION_UNIT		0x0a
+#define UAC3_CLOCK_SOURCE		0x0b
+#define UAC3_CLOCK_SELECTOR		0x0c
+#define UAC3_CLOCK_MULTIPLIER		0x0d
+#define UAC3_SAMPLE_RATE_CONVERTER	0x0e
+#define UAC3_CONNECTORS			0x0f
+#define UAC3_POWER_DOMAIN		0x10
+
+/* A.22 AUDIO CLASS-SPECIFIC REQUEST CODES */
+/* see audio-v2.h for the rest, which is identical to v2 */
+#define UAC3_CS_REQ_INTEN			0x04
+#define UAC3_CS_REQ_STRING			0x05
+#define UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR	0x06
+
+/* A.23.1 AUDIOCONTROL INTERFACE CONTROL SELECTORS */
+#define UAC3_AC_CONTROL_UNDEFINED		0x00
+#define UAC3_AC_ACTIVE_INTERFACE_CONTROL	0x01
+#define UAC3_AC_POWER_DOMAIN_CONTROL		0x02
+
+#endif /* __LINUX_USB_AUDIO_V3_H */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e342423..847f423 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -806,6 +806,7 @@ int usb_otg_descriptor_init(struct usb_gadget *gadget,
 
 /* utility to simplify map/unmap of usb_requests to/from DMA */
 
+#ifdef	CONFIG_HAS_DMA
 extern int usb_gadget_map_request_by_dev(struct device *dev,
 		struct usb_request *req, int is_in);
 extern int usb_gadget_map_request(struct usb_gadget *gadget,
@@ -815,6 +816,17 @@ extern void usb_gadget_unmap_request_by_dev(struct device *dev,
 		struct usb_request *req, int is_in);
 extern void usb_gadget_unmap_request(struct usb_gadget *gadget,
 		struct usb_request *req, int is_in);
+#else /* !CONFIG_HAS_DMA */
+static inline int usb_gadget_map_request_by_dev(struct device *dev,
+		struct usb_request *req, int is_in) { return -ENOSYS; }
+static inline int usb_gadget_map_request(struct usb_gadget *gadget,
+		struct usb_request *req, int is_in) { return -ENOSYS; }
+
+static inline void usb_gadget_unmap_request_by_dev(struct device *dev,
+		struct usb_request *req, int is_in) { }
+static inline void usb_gadget_unmap_request(struct usb_gadget *gadget,
+		struct usb_request *req, int is_in) { }
+#endif /* !CONFIG_HAS_DMA */
 
 /*-------------------------------------------------------------------------*/
 
diff --git a/include/media/i2c/saa6588.h b/include/media/i2c/saa6588.h
index b5ec1aa..a0825f5 100644
--- a/include/media/i2c/saa6588.h
+++ b/include/media/i2c/saa6588.h
@@ -32,6 +32,7 @@ struct saa6588_command {
 	unsigned char __user *buffer;
 	struct file   *instance;
 	poll_table    *event_list;
+	__poll_t      poll_mask;
 };
 
 /* These ioctls are internal to the kernel */
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index 7252820..d2ea586 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -364,7 +364,7 @@ struct iw_handler_def {
  * defined in struct iw_priv_args.
  *
  * For standard IOCTLs, things are quite different and we need to
- * use the stuctures below. Actually, this struct is also more
+ * use the structures below. Actually, this struct is also more
  * efficient, but that's another story...
  */
 
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index cb85edd..eb7853c 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -47,6 +47,8 @@ static inline int scsi_status_is_good(int status)
 	 */
 	status &= 0xfe;
 	return ((status == SAM_STAT_GOOD) ||
+		(status == SAM_STAT_CONDITION_MET) ||
+		/* Next two "intermediate" statuses are obsolete in SAM-4 */
 		(status == SAM_STAT_INTERMEDIATE) ||
 		(status == SAM_STAT_INTERMEDIATE_CONDITION_MET) ||
 		/* FIXME: this is obsolete in SAM-3 */
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 2280b23..aaf1e97 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -174,8 +174,13 @@ extern void scsi_kunmap_atomic_sg(void *virt);
 
 extern int scsi_init_io(struct scsi_cmnd *cmd);
 
+#ifdef CONFIG_SCSI_DMA
 extern int scsi_dma_map(struct scsi_cmnd *cmd);
 extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
+#else /* !CONFIG_SCSI_DMA */
+static inline int scsi_dma_map(struct scsi_cmnd *cmd) { return -ENOSYS; }
+static inline void scsi_dma_unmap(struct scsi_cmnd *cmd) { }
+#endif /* !CONFIG_SCSI_DMA */
 
 static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
 {
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 9c1e4ba..12f454c 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -52,21 +52,6 @@ struct scsi_host_template {
 	const char *name;
 
 	/*
-	 * Used to initialize old-style drivers.  For new-style drivers
-	 * just perform all work in your module initialization function.
-	 *
-	 * Status:  OBSOLETE
-	 */
-	int (* detect)(struct scsi_host_template *);
-
-	/*
-	 * Used as unload callback for hosts with old-style drivers.
-	 *
-	 * Status: OBSOLETE
-	 */
-	int (* release)(struct Scsi_Host *);
-
-	/*
 	 * The info function will return whatever useful information the
 	 * developer sees fit.  If not provided, then the name field will
 	 * be used instead.
@@ -480,13 +465,10 @@ struct scsi_host_template {
 	struct device_attribute **sdev_attrs;
 
 	/*
-	 * List of hosts per template.
-	 *
-	 * This is only for use by scsi_module.c for legacy templates.
-	 * For these access to it is synchronized implicitly by
-	 * module_init/module_exit.
+	 * Pointer to the SCSI device attribute groups for this host,
+	 * NULL terminated.
 	 */
-	struct list_head legacy_hosts;
+	const struct attribute_group **sdev_groups;
 
 	/*
 	 * Vendor Identifier associated with the host
@@ -709,15 +691,6 @@ struct Scsi_Host {
 	struct device		shost_gendev, shost_dev;
 
 	/*
-	 * List of hosts per template.
-	 *
-	 * This is only for use by scsi_module.c for legacy templates.
-	 * For these access to it is synchronized implicitly by
-	 * module_init/module_exit.
-	 */
-	struct list_head sht_legacy_list;
-
-	/*
 	 * Points to the transport data (if any) which is allocated
 	 * separately
 	 */
@@ -917,9 +890,6 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost)
 	return shost->prot_guard_type;
 }
 
-/* legacy interfaces */
-extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int);
-extern void scsi_unregister(struct Scsi_Host *);
 extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state);
 
 #endif /* _SCSI_SCSI_HOST_H */
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index cb979ad..50df5b2 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -63,6 +63,7 @@ enum rpi_firmware_property_tag {
 	RPI_FIRMWARE_GET_MIN_VOLTAGE =                        0x00030008,
 	RPI_FIRMWARE_GET_TURBO =                              0x00030009,
 	RPI_FIRMWARE_GET_MAX_TEMPERATURE =                    0x0003000a,
+	RPI_FIRMWARE_GET_STC =                                0x0003000b,
 	RPI_FIRMWARE_ALLOCATE_MEMORY =                        0x0003000c,
 	RPI_FIRMWARE_LOCK_MEMORY =                            0x0003000d,
 	RPI_FIRMWARE_UNLOCK_MEMORY =                          0x0003000e,
@@ -72,12 +73,22 @@ enum rpi_firmware_property_tag {
 	RPI_FIRMWARE_SET_ENABLE_QPU =                         0x00030012,
 	RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE =       0x00030014,
 	RPI_FIRMWARE_GET_EDID_BLOCK =                         0x00030020,
+	RPI_FIRMWARE_GET_CUSTOMER_OTP =                       0x00030021,
 	RPI_FIRMWARE_GET_DOMAIN_STATE =                       0x00030030,
 	RPI_FIRMWARE_SET_CLOCK_STATE =                        0x00038001,
 	RPI_FIRMWARE_SET_CLOCK_RATE =                         0x00038002,
 	RPI_FIRMWARE_SET_VOLTAGE =                            0x00038003,
 	RPI_FIRMWARE_SET_TURBO =                              0x00038009,
+	RPI_FIRMWARE_SET_CUSTOMER_OTP =                       0x00038021,
 	RPI_FIRMWARE_SET_DOMAIN_STATE =                       0x00038030,
+	RPI_FIRMWARE_GET_GPIO_STATE =                         0x00030041,
+	RPI_FIRMWARE_SET_GPIO_STATE =                         0x00038041,
+	RPI_FIRMWARE_SET_SDHOST_CLOCK =                       0x00038042,
+	RPI_FIRMWARE_GET_GPIO_CONFIG =                        0x00030043,
+	RPI_FIRMWARE_SET_GPIO_CONFIG =                        0x00038043,
+	RPI_FIRMWARE_GET_PERIPH_REG =                         0x00030045,
+	RPI_FIRMWARE_SET_PERIPH_REG =                         0x00038045,
+
 
 	/* Dispmanx TAGS */
 	RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE =                   0x00040001,
@@ -91,6 +102,8 @@ enum rpi_firmware_property_tag {
 	RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET =         0x00040009,
 	RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN =               0x0004000a,
 	RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE =                0x0004000b,
+	RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF =               0x0004000f,
+	RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF =            0x00040010,
 	RPI_FIRMWARE_FRAMEBUFFER_RELEASE =                    0x00048001,
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT =  0x00044004,
@@ -100,6 +113,7 @@ enum rpi_firmware_property_tag {
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET =        0x00044009,
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN =              0x0004400a,
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE =               0x0004400b,
+	RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC =                 0x0004400e,
 	RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT =  0x00048003,
 	RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT =   0x00048004,
 	RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH =                  0x00048005,
@@ -108,6 +122,10 @@ enum rpi_firmware_property_tag {
 	RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET =         0x00048009,
 	RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN =               0x0004800a,
 	RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE =                0x0004800b,
+	RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF =               0x0004801f,
+	RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF =            0x00048020,
+	RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC =                  0x0004800e,
+	RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT =              0x0004800f,
 
 	RPI_FIRMWARE_VCHIQ_INIT =                             0x00048010,
 
diff --git a/include/soc/tegra/bpmp.h b/include/soc/tegra/bpmp.h
index aeae446..e69e4c4 100644
--- a/include/soc/tegra/bpmp.h
+++ b/include/soc/tegra/bpmp.h
@@ -75,8 +75,8 @@ struct tegra_bpmp {
 		struct mbox_chan *channel;
 	} mbox;
 
-	struct tegra_bpmp_channel *channels;
-	unsigned int num_channels;
+	spinlock_t atomic_tx_lock;
+	struct tegra_bpmp_channel *tx_channel, *rx_channel, *threaded_channels;
 
 	struct {
 		unsigned long *allocated;
diff --git a/include/sound/da7219.h b/include/sound/da7219.h
index 409ef139..1bfcb16 100644
--- a/include/sound/da7219.h
+++ b/include/sound/da7219.h
@@ -36,6 +36,8 @@ struct da7219_aad_pdata;
 struct da7219_pdata {
 	bool wakeup_source;
 
+	const char *dai_clks_name;
+
 	/* Mic */
 	enum da7219_micbias_voltage micbias_lvl;
 	enum da7219_mic_amp_in_sel mic_amp_in_sel;
diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index 67be244..e3481ee 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -118,6 +118,8 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
  *   PCM substream. Will be called from the PCM drivers hwparams callback.
  * @compat_request_channel: Callback to request a DMA channel for platforms
  *   which do not use devicetree.
+ * @process: Callback used to apply processing on samples transferred from/to
+ *   user space.
  * @compat_filter_fn: Will be used as the filter function when requesting a
  *  channel for platforms which do not use devicetree. The filter parameter
  *  will be the DAI's DMA data.
@@ -140,6 +142,9 @@ struct snd_dmaengine_pcm_config {
 	struct dma_chan *(*compat_request_channel)(
 			struct snd_soc_pcm_runtime *rtd,
 			struct snd_pcm_substream *substream);
+	int (*process)(struct snd_pcm_substream *substream,
+		       int channel, unsigned long hwoff,
+		       void *buf, unsigned long bytes);
 	dma_filter_fn compat_filter_fn;
 	struct device *dma_dev;
 	const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
@@ -161,4 +166,6 @@ int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params,
 	struct dma_slave_config *slave_config);
 
+#define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
+
 #endif
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 4f42aff..5ebcc51 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1710,6 +1710,7 @@ struct snd_emu10k1 {
 	unsigned int ecard_ctrl;		/* ecard control bits */
 	unsigned int address_mode;		/* address mode */
 	unsigned long dma_mask;			/* PCI DMA mask */
+	bool iommu_workaround;			/* IOMMU workaround needed */
 	unsigned int delay_pcm_irq;		/* in samples */
 	int max_cache_pages;			/* max memory size / PAGE_SIZE */
 	struct snd_dma_buffer silent_page;	/* silent page */
@@ -1718,7 +1719,6 @@ struct snd_emu10k1 {
 	struct snd_dma_buffer p16v_buffer;
 
 	struct snd_util_memhdr *memhdr;		/* page allocation list */
-	struct snd_emu10k1_memblk *reserved_page;	/* reserved page */
 
 	struct list_head mapped_link_head;
 	struct list_head mapped_order_link_head;
@@ -1878,6 +1878,8 @@ void snd_p16v_resume(struct snd_emu10k1 *emu);
 /* memory allocation */
 struct snd_util_memblk *snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream);
 int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk);
+int snd_emu10k1_alloc_pages_maybe_wider(struct snd_emu10k1 *emu, size_t size,
+					struct snd_dma_buffer *dmab);
 struct snd_util_memblk *snd_emu10k1_synth_alloc(struct snd_emu10k1 *emu, unsigned int size);
 int snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *blk);
 int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, int size);
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 5b2ed12..06536e0 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -146,6 +146,8 @@ int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
 			int flags, unsigned int verb, unsigned int parm);
 bool snd_hdac_check_power_state(struct hdac_device *hdac,
 		hda_nid_t nid, unsigned int target_state);
+unsigned int snd_hdac_sync_power_state(struct hdac_device *hdac,
+		      hda_nid_t nid, unsigned int target_state);
 /**
  * snd_hdac_read_parm - read a codec parameter
  * @codec: the codec object
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index 760c969..12bbf8c 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -57,6 +57,7 @@ struct snd_pcm_oss_runtime {
 	char *buffer;				/* vmallocated period */
 	size_t buffer_used;			/* used length from period buffer */
 	struct mutex params_lock;
+	atomic_t rw_ref;		/* concurrent read/write accesses */
 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
 	struct snd_pcm_plugin *plugin_first;
 	struct snd_pcm_plugin *plugin_last;
diff --git a/include/sound/rt5651.h b/include/sound/rt5651.h
deleted file mode 100644
index 18b79a7..0000000
--- a/include/sound/rt5651.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * linux/sound/rt286.h -- Platform data for RT286
- *
- * Copyright 2013 Realtek Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __LINUX_SND_RT5651_H
-#define __LINUX_SND_RT5651_H
-
-enum rt5651_jd_src {
-	RT5651_JD_NULL,
-	RT5651_JD1_1,
-	RT5651_JD1_2,
-	RT5651_JD2,
-};
-
-struct rt5651_platform_data {
-	/* IN2 can optionally be differential */
-	bool in2_diff;
-
-	bool dmic_en;
-	enum rt5651_jd_src jd_src;
-};
-
-#endif
diff --git a/include/sound/rt5659.h b/include/sound/rt5659.h
index 656c4d5..9012e2b 100644
--- a/include/sound/rt5659.h
+++ b/include/sound/rt5659.h
@@ -30,6 +30,7 @@ enum rt5659_dmic2_data_pin {
 enum rt5659_jd_src {
 	RT5659_JD_NULL,
 	RT5659_JD3,
+	RT5659_JD_HDA_HEADER,
 };
 
 struct rt5659_platform_data {
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 344b96c..a6ce2de 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -269,6 +269,13 @@ struct device;
 	.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
 	.on_val = wflags}
+#define SND_SOC_DAPM_PINCTRL(wname, active, sleep) \
+{	.id = snd_soc_dapm_pinctrl, .name = wname, \
+	.priv = (&(struct snd_soc_dapm_pinctrl_priv) \
+		{ .active_state = active, .sleep_state = sleep,}), \
+	.reg = SND_SOC_NOPM, .event = dapm_pinctrl_event, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
+
 
 
 /* dapm kcontrol types */
@@ -374,6 +381,8 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event);
 int dapm_clock_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event);
+int dapm_pinctrl_event(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol, int event);
 
 /* dapm controls */
 int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
@@ -500,6 +509,7 @@ enum snd_soc_dapm_type {
 	snd_soc_dapm_pre,			/* machine specific pre widget - exec first */
 	snd_soc_dapm_post,			/* machine specific post widget - exec last */
 	snd_soc_dapm_supply,		/* power/clock supply */
+	snd_soc_dapm_pinctrl,		/* pinctrl */
 	snd_soc_dapm_regulator_supply,	/* external regulator */
 	snd_soc_dapm_clock_supply,	/* external clock */
 	snd_soc_dapm_aif_in,		/* audio interface input */
@@ -581,6 +591,7 @@ struct snd_soc_dapm_widget {
 
 	void *priv;				/* widget specific data */
 	struct regulator *regulator;		/* attached regulator */
+	struct pinctrl *pinctrl;		/* attached pinctrl */
 	const struct snd_soc_pcm_stream *params; /* params for dai links */
 	unsigned int num_params; /* number of params for dai links */
 	unsigned int params_select; /* currently selected param for dai link */
@@ -683,6 +694,11 @@ struct snd_soc_dapm_stats {
 	int neighbour_checks;
 };
 
+struct snd_soc_dapm_pinctrl_priv {
+	const char *active_state;
+	const char *sleep_state;
+};
+
 /**
  * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
  * @dapm: The DAPM context to initialize
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 747fd58..ad266d7 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -586,10 +586,17 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
 				unsigned int mask, unsigned int value);
 
 #ifdef CONFIG_SND_SOC_AC97_BUS
-struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec);
-struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+#define snd_soc_alloc_ac97_codec(codec) \
+	snd_soc_alloc_ac97_component(&codec->component)
+#define snd_soc_new_ac97_codec(codec, id, id_mask) \
+	snd_soc_new_ac97_component(&codec->component, id, id_mask)
+#define snd_soc_free_ac97_codec(ac97) \
+	snd_soc_free_ac97_component(ac97)
+
+struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component);
+struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
 	unsigned int id, unsigned int id_mask);
-void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
+void snd_soc_free_ac97_component(struct snd_ac97 *ac97);
 
 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
 int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
@@ -1807,6 +1814,7 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
 int snd_soc_of_get_dai_link_codecs(struct device *dev,
 				   struct device_node *of_node,
 				   struct snd_soc_dai_link *dai_link);
+void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link);
 
 int snd_soc_add_dai_link(struct snd_soc_card *card,
 				struct snd_soc_dai_link *dai_link);
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 970c91a..922cb89 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -485,31 +485,55 @@ TRACE_EVENT(xs_tcp_data_recv,
 		{ (1UL << RQ_BUSY),		"RQ_BUSY"})
 
 TRACE_EVENT(svc_recv,
-	TP_PROTO(struct svc_rqst *rqst, int status),
+	TP_PROTO(struct svc_rqst *rqst, int len),
 
-	TP_ARGS(rqst, status),
+	TP_ARGS(rqst, len),
 
 	TP_STRUCT__entry(
 		__field(u32, xid)
-		__field(int, status)
+		__field(int, len)
 		__field(unsigned long, flags)
-		__dynamic_array(unsigned char, addr, rqst->rq_addrlen)
+		__string(addr, rqst->rq_xprt->xpt_remotebuf)
 	),
 
 	TP_fast_assign(
-		__entry->xid = status > 0 ? be32_to_cpu(rqst->rq_xid) : 0;
-		__entry->status = status;
+		__entry->xid = be32_to_cpu(rqst->rq_xid);
+		__entry->len = len;
 		__entry->flags = rqst->rq_flags;
-		memcpy(__get_dynamic_array(addr),
-			&rqst->rq_addr, rqst->rq_addrlen);
+		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
 	),
 
-	TP_printk("addr=%pIScp xid=0x%08x status=%d flags=%s",
-			(struct sockaddr *)__get_dynamic_array(addr),
-			__entry->xid, __entry->status,
+	TP_printk("addr=%s xid=0x%08x len=%d flags=%s",
+			__get_str(addr), __entry->xid, __entry->len,
 			show_rqstp_flags(__entry->flags))
 );
 
+TRACE_EVENT(svc_process,
+	TP_PROTO(const struct svc_rqst *rqst, const char *name),
+
+	TP_ARGS(rqst, name),
+
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(u32, vers)
+		__field(u32, proc)
+		__string(service, name)
+		__string(addr, rqst->rq_xprt->xpt_remotebuf)
+	),
+
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqst->rq_xid);
+		__entry->vers = rqst->rq_vers;
+		__entry->proc = rqst->rq_proc;
+		__assign_str(service, name);
+		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
+	),
+
+	TP_printk("addr=%s xid=0x%08x service=%s vers=%u proc=%u",
+			__get_str(addr), __entry->xid,
+			__get_str(service), __entry->vers, __entry->proc)
+);
+
 DECLARE_EVENT_CLASS(svc_rqst_event,
 
 	TP_PROTO(struct svc_rqst *rqst),
@@ -519,20 +543,18 @@ DECLARE_EVENT_CLASS(svc_rqst_event,
 	TP_STRUCT__entry(
 		__field(u32, xid)
 		__field(unsigned long, flags)
-		__dynamic_array(unsigned char, addr, rqst->rq_addrlen)
+		__string(addr, rqst->rq_xprt->xpt_remotebuf)
 	),
 
 	TP_fast_assign(
 		__entry->xid = be32_to_cpu(rqst->rq_xid);
 		__entry->flags = rqst->rq_flags;
-		memcpy(__get_dynamic_array(addr),
-			&rqst->rq_addr, rqst->rq_addrlen);
+		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
 	),
 
-	TP_printk("addr=%pIScp rq_xid=0x%08x flags=%s",
-		(struct sockaddr *)__get_dynamic_array(addr),
-		__entry->xid,
-		show_rqstp_flags(__entry->flags))
+	TP_printk("addr=%s xid=0x%08x flags=%s",
+			__get_str(addr), __entry->xid,
+			show_rqstp_flags(__entry->flags))
 );
 
 DEFINE_EVENT(svc_rqst_event, svc_defer,
@@ -553,27 +575,21 @@ DECLARE_EVENT_CLASS(svc_rqst_status,
 		__field(u32, xid)
 		__field(int, status)
 		__field(unsigned long, flags)
-		__dynamic_array(unsigned char, addr, rqst->rq_addrlen)
+		__string(addr, rqst->rq_xprt->xpt_remotebuf)
 	),
 
 	TP_fast_assign(
 		__entry->xid = be32_to_cpu(rqst->rq_xid);
 		__entry->status = status;
 		__entry->flags = rqst->rq_flags;
-		memcpy(__get_dynamic_array(addr),
-			&rqst->rq_addr, rqst->rq_addrlen);
+		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
 	),
 
-	TP_printk("addr=%pIScp rq_xid=0x%08x status=%d flags=%s",
-		(struct sockaddr *)__get_dynamic_array(addr),
-		__entry->xid,
-		__entry->status, show_rqstp_flags(__entry->flags))
+	TP_printk("addr=%s xid=0x%08x status=%d flags=%s",
+		  __get_str(addr), __entry->xid,
+		  __entry->status, show_rqstp_flags(__entry->flags))
 );
 
-DEFINE_EVENT(svc_rqst_status, svc_process,
-	TP_PROTO(struct svc_rqst *rqst, int status),
-	TP_ARGS(rqst, status));
-
 DEFINE_EVENT(svc_rqst_status, svc_send,
 	TP_PROTO(struct svc_rqst *rqst, int status),
 	TP_ARGS(rqst, status));
@@ -591,7 +607,9 @@ DEFINE_EVENT(svc_rqst_status, svc_send,
 		{ (1UL << XPT_OLD),		"XPT_OLD"},		\
 		{ (1UL << XPT_LISTENER),	"XPT_LISTENER"},	\
 		{ (1UL << XPT_CACHE_AUTH),	"XPT_CACHE_AUTH"},	\
-		{ (1UL << XPT_LOCAL),		"XPT_LOCAL"})
+		{ (1UL << XPT_LOCAL),		"XPT_LOCAL"},		\
+		{ (1UL << XPT_KILL_TEMP),	"XPT_KILL_TEMP"},	\
+		{ (1UL << XPT_CONG_CTRL),	"XPT_CONG_CTRL"})
 
 TRACE_EVENT(svc_xprt_do_enqueue,
 	TP_PROTO(struct svc_xprt *xprt, struct svc_rqst *rqst),
@@ -602,26 +620,19 @@ TRACE_EVENT(svc_xprt_do_enqueue,
 		__field(struct svc_xprt *, xprt)
 		__field(int, pid)
 		__field(unsigned long, flags)
-		__dynamic_array(unsigned char, addr, xprt != NULL ?
-			xprt->xpt_remotelen : 0)
+		__string(addr, xprt->xpt_remotebuf)
 	),
 
 	TP_fast_assign(
 		__entry->xprt = xprt;
 		__entry->pid = rqst? rqst->rq_task->pid : 0;
-		if (xprt) {
-			memcpy(__get_dynamic_array(addr),
-				&xprt->xpt_remote,
-				xprt->xpt_remotelen);
-			__entry->flags = xprt->xpt_flags;
-		} else
-			__entry->flags = 0;
+		__entry->flags = xprt->xpt_flags;
+		__assign_str(addr, xprt->xpt_remotebuf);
 	),
 
-	TP_printk("xprt=0x%p addr=%pIScp pid=%d flags=%s", __entry->xprt,
-		__get_dynamic_array_len(addr) != 0 ?
-			(struct sockaddr *)__get_dynamic_array(addr) : NULL,
-		__entry->pid, show_svc_xprt_flags(__entry->flags))
+	TP_printk("xprt=%p addr=%s pid=%d flags=%s",
+			__entry->xprt, __get_str(addr),
+			__entry->pid, show_svc_xprt_flags(__entry->flags))
 );
 
 DECLARE_EVENT_CLASS(svc_xprt_event,
@@ -632,35 +643,50 @@ DECLARE_EVENT_CLASS(svc_xprt_event,
 	TP_STRUCT__entry(
 		__field(struct svc_xprt *, xprt)
 		__field(unsigned long, flags)
-		__dynamic_array(unsigned char, addr, xprt != NULL ?
-			xprt->xpt_remotelen : 0)
+		__string(addr, xprt->xpt_remotebuf)
 	),
 
 	TP_fast_assign(
 		__entry->xprt = xprt;
-		if (xprt) {
-			memcpy(__get_dynamic_array(addr),
-					&xprt->xpt_remote,
-					xprt->xpt_remotelen);
-			__entry->flags = xprt->xpt_flags;
-		} else
-			__entry->flags = 0;
+		__entry->flags = xprt->xpt_flags;
+		__assign_str(addr, xprt->xpt_remotebuf);
 	),
 
-	TP_printk("xprt=0x%p addr=%pIScp flags=%s", __entry->xprt,
-		__get_dynamic_array_len(addr) != 0 ?
-			(struct sockaddr *)__get_dynamic_array(addr) : NULL,
-		show_svc_xprt_flags(__entry->flags))
+	TP_printk("xprt=%p addr=%s flags=%s",
+			__entry->xprt, __get_str(addr),
+			show_svc_xprt_flags(__entry->flags))
 );
 
-DEFINE_EVENT(svc_xprt_event, svc_xprt_dequeue,
-	TP_PROTO(struct svc_xprt *xprt),
-	TP_ARGS(xprt));
-
 DEFINE_EVENT(svc_xprt_event, svc_xprt_no_write_space,
 	TP_PROTO(struct svc_xprt *xprt),
 	TP_ARGS(xprt));
 
+TRACE_EVENT(svc_xprt_dequeue,
+	TP_PROTO(struct svc_rqst *rqst),
+
+	TP_ARGS(rqst),
+
+	TP_STRUCT__entry(
+		__field(struct svc_xprt *, xprt)
+		__field(unsigned long, flags)
+		__field(unsigned long, wakeup)
+		__string(addr, rqst->rq_xprt->xpt_remotebuf)
+	),
+
+	TP_fast_assign(
+		__entry->xprt = rqst->rq_xprt;
+		__entry->flags = rqst->rq_xprt->xpt_flags;
+		__entry->wakeup = ktime_to_us(ktime_sub(ktime_get(),
+							rqst->rq_qtime));
+		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
+	),
+
+	TP_printk("xprt=%p addr=%s flags=%s wakeup-us=%lu",
+			__entry->xprt, __get_str(addr),
+			show_svc_xprt_flags(__entry->flags),
+			__entry->wakeup)
+);
+
 TRACE_EVENT(svc_wake_up,
 	TP_PROTO(int pid),
 
@@ -686,28 +712,42 @@ TRACE_EVENT(svc_handle_xprt,
 		__field(struct svc_xprt *, xprt)
 		__field(int, len)
 		__field(unsigned long, flags)
-		__dynamic_array(unsigned char, addr, xprt != NULL ?
-			xprt->xpt_remotelen : 0)
+		__string(addr, xprt->xpt_remotebuf)
 	),
 
 	TP_fast_assign(
 		__entry->xprt = xprt;
 		__entry->len = len;
-		if (xprt) {
-			memcpy(__get_dynamic_array(addr),
-					&xprt->xpt_remote,
-					xprt->xpt_remotelen);
-			__entry->flags = xprt->xpt_flags;
-		} else
-			__entry->flags = 0;
+		__entry->flags = xprt->xpt_flags;
+		__assign_str(addr, xprt->xpt_remotebuf);
 	),
 
-	TP_printk("xprt=0x%p addr=%pIScp len=%d flags=%s", __entry->xprt,
-		__get_dynamic_array_len(addr) != 0 ?
-			(struct sockaddr *)__get_dynamic_array(addr) : NULL,
+	TP_printk("xprt=%p addr=%s len=%d flags=%s",
+		__entry->xprt, __get_str(addr),
 		__entry->len, show_svc_xprt_flags(__entry->flags))
 );
 
+TRACE_EVENT(svc_stats_latency,
+	TP_PROTO(const struct svc_rqst *rqst),
+
+	TP_ARGS(rqst),
+
+	TP_STRUCT__entry(
+		__field(u32, xid)
+		__field(unsigned long, execute)
+		__string(addr, rqst->rq_xprt->xpt_remotebuf)
+	),
+
+	TP_fast_assign(
+		__entry->xid = be32_to_cpu(rqst->rq_xid);
+		__entry->execute = ktime_to_us(ktime_sub(ktime_get(),
+							 rqst->rq_stime));
+		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
+	),
+
+	TP_printk("addr=%s xid=0x%08x execute-us=%lu",
+		__get_str(addr), __entry->xid, __entry->execute)
+);
 
 DECLARE_EVENT_CLASS(svc_deferred_event,
 	TP_PROTO(struct svc_deferred_req *dr),
@@ -716,18 +756,16 @@ DECLARE_EVENT_CLASS(svc_deferred_event,
 
 	TP_STRUCT__entry(
 		__field(u32, xid)
-		__dynamic_array(unsigned char, addr, dr->addrlen)
+		__string(addr, dr->xprt->xpt_remotebuf)
 	),
 
 	TP_fast_assign(
 		__entry->xid = be32_to_cpu(*(__be32 *)(dr->args +
 						       (dr->xprt_hlen>>2)));
-		memcpy(__get_dynamic_array(addr), &dr->addr, dr->addrlen);
+		__assign_str(addr, dr->xprt->xpt_remotebuf);
 	),
 
-	TP_printk("addr=%pIScp xid=0x%08x",
-		(struct sockaddr *)__get_dynamic_array(addr),
-		__entry->xid)
+	TP_printk("addr=%s xid=0x%08x", __get_str(addr), __entry->xid)
 );
 
 DEFINE_EVENT(svc_deferred_event, svc_drop_deferred,
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index 6088bca..544208f 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -94,6 +94,9 @@ typedef struct siginfo {
 			unsigned int _flags;	/* see ia64 si_flags */
 			unsigned long _isr;	/* isr */
 #endif
+
+#define __ADDR_BND_PKEY_PAD  (__alignof__(void *) < sizeof(short) ? \
+			      sizeof(short) : __alignof__(void *))
 			union {
 				/*
 				 * used when si_code=BUS_MCEERR_AR or
@@ -102,13 +105,13 @@ typedef struct siginfo {
 				short _addr_lsb; /* LSB of the reported address */
 				/* used when si_code=SEGV_BNDERR */
 				struct {
-					void *_dummy_bnd;
+					char _dummy_bnd[__ADDR_BND_PKEY_PAD];
 					void __user *_lower;
 					void __user *_upper;
 				} _addr_bnd;
 				/* used when si_code=SEGV_PKUERR */
 				struct {
-					void *_dummy_pkey;
+					char _dummy_pkey[__ADDR_BND_PKEY_PAD];
 					__u32 _pkey;
 				} _addr_pkey;
 			};
diff --git a/include/uapi/linux/blktrace_api.h b/include/uapi/linux/blktrace_api.h
index 3c50e07..690621b 100644
--- a/include/uapi/linux/blktrace_api.h
+++ b/include/uapi/linux/blktrace_api.h
@@ -101,7 +101,7 @@ enum blktrace_notify {
 struct blk_io_trace {
 	__u32 magic;		/* MAGIC << 8 | version */
 	__u32 sequence;		/* event number */
-	__u64 time;		/* in microseconds */
+	__u64 time;		/* in nanoseconds */
 	__u64 sector;		/* disk offset */
 	__u32 bytes;		/* transfer length */
 	__u32 action;		/* what happened */
diff --git a/include/uapi/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h
index 14c44ec..d1e4951 100644
--- a/include/uapi/linux/dm-ioctl.h
+++ b/include/uapi/linux/dm-ioctl.h
@@ -270,9 +270,9 @@ enum {
 #define DM_DEV_SET_GEOMETRY	_IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR	4
-#define DM_VERSION_MINOR	37
+#define DM_VERSION_MINOR	39
 #define DM_VERSION_PATCHLEVEL	0
-#define DM_VERSION_EXTRA	"-ioctl (2017-09-20)"
+#define DM_VERSION_EXTRA	"-ioctl (2018-04-03)"
 
 /* Status bits */
 #define DM_READONLY_FLAG	(1 << 0) /* In/Out */
diff --git a/include/uapi/linux/inotify.h b/include/uapi/linux/inotify.h
index 5474461..4800bf2 100644
--- a/include/uapi/linux/inotify.h
+++ b/include/uapi/linux/inotify.h
@@ -71,5 +71,13 @@ struct inotify_event {
 #define IN_CLOEXEC O_CLOEXEC
 #define IN_NONBLOCK O_NONBLOCK
 
+/*
+ * ioctl numbers: inotify uses 'I' prefix for all ioctls,
+ * except historical FIONREAD, which is based on 'T'.
+ *
+ * INOTIFY_IOC_SETNEXTWD: set desired number of next created
+ * watch descriptor.
+ */
+#define INOTIFY_IOC_SETNEXTWD	_IOW('I', 0, __s32)
 
 #endif /* _UAPI_LINUX_INOTIFY_H */
diff --git a/include/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h
index a45d075..fde7537 100644
--- a/include/uapi/linux/msdos_fs.h
+++ b/include/uapi/linux/msdos_fs.h
@@ -10,7 +10,9 @@
  * The MS-DOS filesystem constants/structures
  */
 
+#ifndef SECTOR_SIZE
 #define SECTOR_SIZE	512		/* sector size (bytes) */
+#endif
 #define SECTOR_BITS	9		/* log2(SECTOR_SIZE) */
 #define MSDOS_DPB	(MSDOS_DPS)	/* dir entries per block */
 #define MSDOS_DPB_BITS	4		/* log2(MSDOS_DPB) */
diff --git a/include/uapi/linux/usb/audio.h b/include/uapi/linux/usb/audio.h
index da3315e..3a78e71 100644
--- a/include/uapi/linux/usb/audio.h
+++ b/include/uapi/linux/usb/audio.h
@@ -27,6 +27,7 @@
 /* bInterfaceProtocol values to denote the version of the standard used */
 #define UAC_VERSION_1			0x00
 #define UAC_VERSION_2			0x20
+#define UAC_VERSION_3			0x30
 
 /* A.2 Audio Interface Subclass Codes */
 #define USB_SUBCLASS_AUDIOCONTROL	0x01
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index 07d6158..ed0a120 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -242,6 +242,7 @@ typedef int __bitwise snd_pcm_format_t;
 #define	SNDRV_PCM_FORMAT_DSD_U16_BE	((__force snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */
 #define	SNDRV_PCM_FORMAT_DSD_U32_BE	((__force snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */
 #define	SNDRV_PCM_FORMAT_LAST		SNDRV_PCM_FORMAT_DSD_U32_BE
+#define	SNDRV_PCM_FORMAT_FIRST		SNDRV_PCM_FORMAT_S8
 
 #ifdef SNDRV_LITTLE_ENDIAN
 #define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_LE
diff --git a/init/Kconfig b/init/Kconfig
index 2852692..9d167a5 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1437,7 +1437,7 @@
 	  See tools/perf/design.txt for details
 
 config PC104
-	bool "PC/104 support"
+	bool "PC/104 support" if EXPERT
 	help
 	  Expose PC/104 form factor device drivers and options available for
 	  selection and configuration. Enable this option if your target
diff --git a/kernel/audit.c b/kernel/audit.c
index 227db99..d97e8f0 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -443,15 +443,15 @@ static int audit_set_failure(u32 state)
  * Drop any references inside the auditd connection tracking struct and free
  * the memory.
  */
- static void auditd_conn_free(struct rcu_head *rcu)
- {
+static void auditd_conn_free(struct rcu_head *rcu)
+{
 	struct auditd_connection *ac;
 
 	ac = container_of(rcu, struct auditd_connection, rcu);
 	put_pid(ac->pid);
 	put_net(ac->net);
 	kfree(ac);
- }
+}
 
 /**
  * auditd_set - Set/Reset the auditd connection state
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index 0975b02..a569711 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -19,7 +19,6 @@
 #include <linux/syscalls.h>
 #include <linux/sysctl.h>
 #include <linux/types.h>
-#include <linux/fs_struct.h>
 
 #ifdef CONFIG_PROC_FS
 static int execdomains_proc_show(struct seq_file *m, void *v)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index f274fbe..704e551 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -42,7 +42,6 @@
 #include <linux/rculist.h>
 #include <linux/poll.h>
 #include <linux/irq_work.h>
-#include <linux/utsname.h>
 #include <linux/ctype.h>
 #include <linux/uio.h>
 #include <linux/sched/clock.h>
@@ -2162,7 +2161,7 @@ void suspend_console(void)
 {
 	if (!console_suspend_enabled)
 		return;
-	printk("Suspending console(s) (use no_console_suspend to debug)\n");
+	pr_info("Suspending console(s) (use no_console_suspend to debug)\n");
 	console_lock();
 	console_suspended = 1;
 	up_console_sem();
@@ -3257,60 +3256,4 @@ void kmsg_dump_rewind(struct kmsg_dumper *dumper)
 }
 EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
 
-static char dump_stack_arch_desc_str[128];
-
-/**
- * dump_stack_set_arch_desc - set arch-specific str to show with task dumps
- * @fmt: printf-style format string
- * @...: arguments for the format string
- *
- * The configured string will be printed right after utsname during task
- * dumps.  Usually used to add arch-specific system identifiers.  If an
- * arch wants to make use of such an ID string, it should initialize this
- * as soon as possible during boot.
- */
-void __init dump_stack_set_arch_desc(const char *fmt, ...)
-{
-	va_list args;
-
-	va_start(args, fmt);
-	vsnprintf(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str),
-		  fmt, args);
-	va_end(args);
-}
-
-/**
- * dump_stack_print_info - print generic debug info for dump_stack()
- * @log_lvl: log level
- *
- * Arch-specific dump_stack() implementations can use this function to
- * print out the same debug information as the generic dump_stack().
- */
-void dump_stack_print_info(const char *log_lvl)
-{
-	printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s\n",
-	       log_lvl, raw_smp_processor_id(), current->pid, current->comm,
-	       print_tainted(), init_utsname()->release,
-	       (int)strcspn(init_utsname()->version, " "),
-	       init_utsname()->version);
-
-	if (dump_stack_arch_desc_str[0] != '\0')
-		printk("%sHardware name: %s\n",
-		       log_lvl, dump_stack_arch_desc_str);
-
-	print_worker_info(log_lvl, current);
-}
-
-/**
- * show_regs_print_info - print generic debug info for show_regs()
- * @log_lvl: log level
- *
- * show_regs() implementations can use this function to print out generic
- * debug information.
- */
-void show_regs_print_info(const char *log_lvl)
-{
-	dump_stack_print_info(log_lvl);
-}
-
 #endif
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 300f4ea..5071931 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2380,7 +2380,7 @@ EXPORT_SYMBOL_GPL(trace_event_buffer_commit);
  *   trace_buffer_unlock_commit_regs()
  *   trace_event_buffer_commit()
  *   trace_event_raw_event_xxx()
-*/
+ */
 # define STACK_SKIP 3
 
 void trace_buffer_unlock_commit_regs(struct trace_array *tr,
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index ad1d616..50f44b7 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -196,7 +196,7 @@ struct notifier_block module_trace_bprintk_format_nb = {
 };
 
 int __trace_bprintk(unsigned long ip, const char *fmt, ...)
- {
+{
 	int ret;
 	va_list ap;
 
@@ -214,7 +214,7 @@ int __trace_bprintk(unsigned long ip, const char *fmt, ...)
 EXPORT_SYMBOL_GPL(__trace_bprintk);
 
 int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap)
- {
+{
 	if (unlikely(!fmt))
 		return 0;
 
diff --git a/lib/Makefile b/lib/Makefile
index a90d4fc..0bd50d71f 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -18,7 +18,7 @@
 KCOV_INSTRUMENT_dynamic_debug.o := n
 
 lib-y := ctype.o string.o vsprintf.o cmdline.o \
-	 rbtree.o radix-tree.o dump_stack.o timerqueue.o\
+	 rbtree.o radix-tree.o timerqueue.o\
 	 idr.o int_sqrt.o extable.o \
 	 sha1.o chacha20.o irq_regs.o argv_split.o \
 	 flex_proportions.o ratelimit.o show_mem.o \
@@ -26,6 +26,7 @@
 	 earlycpio.o seq_buf.o siphash.o \
 	 nmi_backtrace.o nodemask.o win_minmax.o
 
+lib-$(CONFIG_PRINTK) += dump_stack.o
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
 lib-$(CONFIG_DMA_DIRECT_OPS) += dma-direct.o
diff --git a/lib/dump_stack.c b/lib/dump_stack.c
index c5edbed..5cff72f 100644
--- a/lib/dump_stack.c
+++ b/lib/dump_stack.c
@@ -10,6 +10,66 @@
 #include <linux/sched/debug.h>
 #include <linux/smp.h>
 #include <linux/atomic.h>
+#include <linux/kexec.h>
+#include <linux/utsname.h>
+
+static char dump_stack_arch_desc_str[128];
+
+/**
+ * dump_stack_set_arch_desc - set arch-specific str to show with task dumps
+ * @fmt: printf-style format string
+ * @...: arguments for the format string
+ *
+ * The configured string will be printed right after utsname during task
+ * dumps.  Usually used to add arch-specific system identifiers.  If an
+ * arch wants to make use of such an ID string, it should initialize this
+ * as soon as possible during boot.
+ */
+void __init dump_stack_set_arch_desc(const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	vsnprintf(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str),
+		  fmt, args);
+	va_end(args);
+}
+
+/**
+ * dump_stack_print_info - print generic debug info for dump_stack()
+ * @log_lvl: log level
+ *
+ * Arch-specific dump_stack() implementations can use this function to
+ * print out the same debug information as the generic dump_stack().
+ */
+void dump_stack_print_info(const char *log_lvl)
+{
+	printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s\n",
+	       log_lvl, raw_smp_processor_id(), current->pid, current->comm,
+	       kexec_crash_loaded() ? "Kdump: loaded " : "",
+	       print_tainted(),
+	       init_utsname()->release,
+	       (int)strcspn(init_utsname()->version, " "),
+	       init_utsname()->version);
+
+	if (dump_stack_arch_desc_str[0] != '\0')
+		printk("%sHardware name: %s\n",
+		       log_lvl, dump_stack_arch_desc_str);
+
+	print_worker_info(log_lvl, current);
+}
+
+/**
+ * show_regs_print_info - print generic debug info for show_regs()
+ * @log_lvl: log level
+ *
+ * show_regs() implementations can use this function to print out generic
+ * debug information.
+ */
+void show_regs_print_info(const char *log_lvl)
+{
+	dump_stack_print_info(log_lvl);
+}
 
 static void __dump_stack(void)
 {
diff --git a/lib/kfifo.c b/lib/kfifo.c
index 90ba1eb..b0f757b 100644
--- a/lib/kfifo.c
+++ b/lib/kfifo.c
@@ -39,7 +39,7 @@ int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
 		size_t esize, gfp_t gfp_mask)
 {
 	/*
-	 * round down to the next power of 2, since our 'let the indices
+	 * round up to the next power of 2, since our 'let the indices
 	 * wrap' technique works only in this case.
 	 */
 	size = roundup_pow_of_two(size);
diff --git a/lib/raid6/sse2.c b/lib/raid6/sse2.c
index 1d2276b..8191e1d 100644
--- a/lib/raid6/sse2.c
+++ b/lib/raid6/sse2.c
@@ -91,7 +91,7 @@ static void raid6_sse21_gen_syndrome(int disks, size_t bytes, void **ptrs)
 
 static void raid6_sse21_xor_syndrome(int disks, int start, int stop,
 				     size_t bytes, void **ptrs)
- {
+{
 	u8 **dptr = (u8 **)ptrs;
 	u8 *p, *q;
 	int d, z, z0;
@@ -200,9 +200,9 @@ static void raid6_sse22_gen_syndrome(int disks, size_t bytes, void **ptrs)
 	kernel_fpu_end();
 }
 
- static void raid6_sse22_xor_syndrome(int disks, int start, int stop,
+static void raid6_sse22_xor_syndrome(int disks, int start, int stop,
 				     size_t bytes, void **ptrs)
- {
+{
 	u8 **dptr = (u8 **)ptrs;
 	u8 *p, *q;
 	int d, z, z0;
@@ -265,7 +265,7 @@ static void raid6_sse22_gen_syndrome(int disks, size_t bytes, void **ptrs)
 
 	asm volatile("sfence" : : : "memory");
 	kernel_fpu_end();
- }
+}
 
 const struct raid6_calls raid6_sse2x2 = {
 	raid6_sse22_gen_syndrome,
@@ -366,9 +366,9 @@ static void raid6_sse24_gen_syndrome(int disks, size_t bytes, void **ptrs)
 	kernel_fpu_end();
 }
 
- static void raid6_sse24_xor_syndrome(int disks, int start, int stop,
+static void raid6_sse24_xor_syndrome(int disks, int start, int stop,
 				     size_t bytes, void **ptrs)
- {
+{
 	u8 **dptr = (u8 **)ptrs;
 	u8 *p, *q;
 	int d, z, z0;
@@ -471,7 +471,7 @@ static void raid6_sse24_gen_syndrome(int disks, size_t bytes, void **ptrs)
 	}
 	asm volatile("sfence" : : : "memory");
 	kernel_fpu_end();
- }
+}
 
 
 const struct raid6_calls raid6_sse2x4 = {
diff --git a/lib/sbitmap.c b/lib/sbitmap.c
index 42b5ca0..e6a9c06 100644
--- a/lib/sbitmap.c
+++ b/lib/sbitmap.c
@@ -100,7 +100,7 @@ static int __sbitmap_get_word(unsigned long *word, unsigned long depth,
 			return -1;
 		}
 
-		if (!test_and_set_bit(nr, word))
+		if (!test_and_set_bit_lock(nr, word))
 			break;
 
 		hint = nr + 1;
@@ -434,9 +434,9 @@ static void sbq_wake_up(struct sbitmap_queue *sbq)
 	/*
 	 * Pairs with the memory barrier in set_current_state() to ensure the
 	 * proper ordering of clear_bit()/waitqueue_active() in the waker and
-	 * test_and_set_bit()/prepare_to_wait()/finish_wait() in the waiter. See
-	 * the comment on waitqueue_active(). This is __after_atomic because we
-	 * just did clear_bit() in the caller.
+	 * test_and_set_bit_lock()/prepare_to_wait()/finish_wait() in the
+	 * waiter. See the comment on waitqueue_active(). This is __after_atomic
+	 * because we just did clear_bit_unlock() in the caller.
 	 */
 	smp_mb__after_atomic();
 
@@ -469,7 +469,7 @@ static void sbq_wake_up(struct sbitmap_queue *sbq)
 void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr,
 			 unsigned int cpu)
 {
-	sbitmap_clear_bit(&sbq->sb, nr);
+	sbitmap_clear_bit_unlock(&sbq->sb, nr);
 	sbq_wake_up(sbq);
 	if (likely(!sbq->round_robin && nr < sbq->sb.depth))
 		*per_cpu_ptr(sbq->alloc_hint, cpu) = nr;
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index fac66ab..08b9aab 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -734,7 +734,6 @@ static void cgwb_bdi_unregister(struct backing_dev_info *bdi)
  */
 void wb_memcg_offline(struct mem_cgroup *memcg)
 {
-	LIST_HEAD(to_destroy);
 	struct list_head *memcg_cgwb_list = mem_cgroup_cgwb_list(memcg);
 	struct bdi_writeback *wb, *next;
 
@@ -753,7 +752,6 @@ void wb_memcg_offline(struct mem_cgroup *memcg)
  */
 void wb_blkcg_offline(struct blkcg *blkcg)
 {
-	LIST_HEAD(to_destroy);
 	struct bdi_writeback *wb, *next;
 
 	spin_lock_irq(&cgwb_lock);
diff --git a/net/core/utils.c b/net/core/utils.c
index 93066bd..d47863b 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -403,6 +403,29 @@ int inet_pton_with_scope(struct net *net, __kernel_sa_family_t af,
 }
 EXPORT_SYMBOL(inet_pton_with_scope);
 
+bool inet_addr_is_any(struct sockaddr *addr)
+{
+	if (addr->sa_family == AF_INET6) {
+		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr;
+		const struct sockaddr_in6 in6_any =
+			{ .sin6_addr = IN6ADDR_ANY_INIT };
+
+		if (!memcmp(in6->sin6_addr.s6_addr,
+			    in6_any.sin6_addr.s6_addr, 16))
+			return true;
+	} else if (addr->sa_family == AF_INET) {
+		struct sockaddr_in *in = (struct sockaddr_in *)addr;
+
+		if (in->sin_addr.s_addr == htonl(INADDR_ANY))
+			return true;
+	} else {
+		pr_warn("unexpected address family %u\n", addr->sa_family);
+	}
+
+	return false;
+}
+EXPORT_SYMBOL(inet_addr_is_any);
+
 void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
 			      __be32 from, __be32 to, bool pseudohdr)
 {
diff --git a/net/socket.c b/net/socket.c
index 54dcb43..f10f1d9 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1536,7 +1536,7 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog)
  *
  *	1003.1g adds the ability to recvmsg() to query connection pending
  *	status to recvmsg. We need to add that support in a way thats
- *	clean when we restucture accept also.
+ *	clean when we restructure accept also.
  */
 
 int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 12649c9..8654494 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -237,9 +237,6 @@ make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
 
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
 
-	err = crypto_ahash_init(req);
-	if (err)
-		goto out;
 	err = crypto_ahash_setkey(hmac_md5, cksumkey, kctx->gk5e->keylength);
 	if (err)
 		goto out;
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index 1d74d65..94a2b3f 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -177,6 +177,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
 	u64 seq_send;
 	u8 *cksumkey;
 	unsigned int cksum_usage;
+	__be64 seq_send_be64;
 
 	dprintk("RPC:       %s\n", __func__);
 
@@ -187,7 +188,9 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
 	spin_lock(&krb5_seq_lock);
 	seq_send = ctx->seq_send64++;
 	spin_unlock(&krb5_seq_lock);
-	*((__be64 *)(krb5_hdr + 8)) = cpu_to_be64(seq_send);
+
+	seq_send_be64 = cpu_to_be64(seq_send);
+	memcpy(krb5_hdr + 8, (char *) &seq_send_be64, 8);
 
 	if (ctx->initiate) {
 		cksumkey = ctx->initiator_sign;
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index dcf9515..b601a73 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -155,10 +155,12 @@ gss_verify_mic_v2(struct krb5_ctx *ctx,
 	u8 flags;
 	int i;
 	unsigned int cksum_usage;
+	__be16 be16_ptr;
 
 	dprintk("RPC:       %s\n", __func__);
 
-	if (be16_to_cpu(*((__be16 *)ptr)) != KG2_TOK_MIC)
+	memcpy(&be16_ptr, (char *) ptr, 2);
+	if (be16_to_cpu(be16_ptr) != KG2_TOK_MIC)
 		return GSS_S_DEFECTIVE_TOKEN;
 
 	flags = ptr[2];
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index c536cc2..cdda474 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -1450,8 +1450,8 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
 			   struct cache_detail *cd)
 {
 	char tbuf[20];
-	char *bp, *ep;
-	time_t then, now;
+	char *ep;
+	time_t now;
 
 	if (*ppos || count > sizeof(tbuf)-1)
 		return -EINVAL;
@@ -1461,24 +1461,24 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
 	simple_strtoul(tbuf, &ep, 0);
 	if (*ep && *ep != '\n')
 		return -EINVAL;
-
-	bp = tbuf;
-	then = get_expiry(&bp);
-	now = seconds_since_boot();
-	cd->nextcheck = now;
-	/* Can only set flush_time to 1 second beyond "now", or
-	 * possibly 1 second beyond flushtime.  This is because
-	 * flush_time never goes backwards so it mustn't get too far
-	 * ahead of time.
+	/* Note that while we check that 'buf' holds a valid number,
+	 * we always ignore the value and just flush everything.
+	 * Making use of the number leads to races.
 	 */
-	if (then >= now) {
-		/* Want to flush everything, so behave like cache_purge() */
-		if (cd->flush_time >= now)
-			now = cd->flush_time + 1;
-		then = now;
-	}
 
-	cd->flush_time = then;
+	now = seconds_since_boot();
+	/* Always flush everything, so behave like cache_purge()
+	 * Do this by advancing flush_time to the current time,
+	 * or by one second if it has already reached the current time.
+	 * Newly added cache entries will always have ->last_refresh greater
+	 * that ->flush_time, so they don't get flushed prematurely.
+	 */
+
+	if (cd->flush_time >= now)
+		now = cd->flush_time + 1;
+
+	cd->flush_time = now;
+	cd->nextcheck = now;
 	cache_flush();
 
 	*ppos += count;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 387cc4a..30a4226 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1255,6 +1255,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
 
 	/* Syntactic check complete */
 	serv->sv_stats->rpccnt++;
+	trace_svc_process(rqstp, progp->pg_name);
 
 	/* Build the reply header. */
 	statp = resv->iov_base +resv->iov_len;
@@ -1431,14 +1432,10 @@ svc_process(struct svc_rqst *rqstp)
 	}
 
 	/* Returns 1 for send, 0 for drop */
-	if (likely(svc_process_common(rqstp, argv, resv))) {
-		int ret = svc_send(rqstp);
+	if (likely(svc_process_common(rqstp, argv, resv)))
+		return svc_send(rqstp);
 
-		trace_svc_process(rqstp, ret);
-		return ret;
-	}
 out_drop:
-	trace_svc_process(rqstp, 0);
 	svc_drop(rqstp);
 	return 0;
 }
@@ -1536,3 +1533,112 @@ u32 svc_max_payload(const struct svc_rqst *rqstp)
 	return max;
 }
 EXPORT_SYMBOL_GPL(svc_max_payload);
+
+/**
+ * svc_fill_write_vector - Construct data argument for VFS write call
+ * @rqstp: svc_rqst to operate on
+ * @first: buffer containing first section of write payload
+ * @total: total number of bytes of write payload
+ *
+ * Returns the number of elements populated in the data argument array.
+ */
+unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct kvec *first,
+				   size_t total)
+{
+	struct kvec *vec = rqstp->rq_vec;
+	struct page **pages;
+	unsigned int i;
+
+	/* Some types of transport can present the write payload
+	 * entirely in rq_arg.pages. In this case, @first is empty.
+	 */
+	i = 0;
+	if (first->iov_len) {
+		vec[i].iov_base = first->iov_base;
+		vec[i].iov_len = min_t(size_t, total, first->iov_len);
+		total -= vec[i].iov_len;
+		++i;
+	}
+
+	WARN_ON_ONCE(rqstp->rq_arg.page_base != 0);
+	pages = rqstp->rq_arg.pages;
+	while (total) {
+		vec[i].iov_base = page_address(*pages);
+		vec[i].iov_len = min_t(size_t, total, PAGE_SIZE);
+		total -= vec[i].iov_len;
+		++i;
+
+		++pages;
+	}
+
+	WARN_ON_ONCE(i > ARRAY_SIZE(rqstp->rq_vec));
+	return i;
+}
+EXPORT_SYMBOL_GPL(svc_fill_write_vector);
+
+/**
+ * svc_fill_symlink_pathname - Construct pathname argument for VFS symlink call
+ * @rqstp: svc_rqst to operate on
+ * @first: buffer containing first section of pathname
+ * @total: total length of the pathname argument
+ *
+ * Returns pointer to a NUL-terminated string, or an ERR_PTR. The buffer is
+ * released automatically when @rqstp is recycled.
+ */
+char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, struct kvec *first,
+				size_t total)
+{
+	struct xdr_buf *arg = &rqstp->rq_arg;
+	struct page **pages;
+	char *result;
+
+	/* VFS API demands a NUL-terminated pathname. This function
+	 * uses a page from @rqstp as the pathname buffer, to enable
+	 * direct placement. Thus the total buffer size is PAGE_SIZE.
+	 * Space in this buffer for NUL-termination requires that we
+	 * cap the size of the returned symlink pathname just a
+	 * little early.
+	 */
+	if (total > PAGE_SIZE - 1)
+		return ERR_PTR(-ENAMETOOLONG);
+
+	/* Some types of transport can present the pathname entirely
+	 * in rq_arg.pages. If not, then copy the pathname into one
+	 * page.
+	 */
+	pages = arg->pages;
+	WARN_ON_ONCE(arg->page_base != 0);
+	if (first->iov_base == 0) {
+		result = page_address(*pages);
+		result[total] = '\0';
+	} else {
+		size_t len, remaining;
+		char *dst;
+
+		result = page_address(*(rqstp->rq_next_page++));
+		dst = result;
+		remaining = total;
+
+		len = min_t(size_t, total, first->iov_len);
+		memcpy(dst, first->iov_base, len);
+		dst += len;
+		remaining -= len;
+
+		/* No more than one page left */
+		if (remaining) {
+			len = min_t(size_t, remaining, PAGE_SIZE);
+			memcpy(dst, page_address(*pages), len);
+			dst += len;
+		}
+
+		*dst = '\0';
+	}
+
+	/* Sanity check: we don't allow the pathname argument to
+	 * contain a NUL byte.
+	 */
+	if (strlen(result) != total)
+		return ERR_PTR(-EINVAL);
+	return result;
+}
+EXPORT_SYMBOL_GPL(svc_fill_symlink_pathname);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index f9307bd..5185efb 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -173,6 +173,7 @@ void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
 	set_bit(XPT_BUSY, &xprt->xpt_flags);
 	rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending");
 	xprt->xpt_net = get_net(net);
+	strcpy(xprt->xpt_remotebuf, "uninitialized");
 }
 EXPORT_SYMBOL_GPL(svc_xprt_init);
 
@@ -382,25 +383,21 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt)
 	int cpu;
 
 	if (!svc_xprt_has_something_to_do(xprt))
-		goto out;
+		return;
 
 	/* Mark transport as busy. It will remain in this state until
 	 * the provider calls svc_xprt_received. We update XPT_BUSY
 	 * atomically because it also guards against trying to enqueue
 	 * the transport twice.
 	 */
-	if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) {
-		/* Don't enqueue transport while already enqueued */
-		dprintk("svc: transport %p busy, not enqueued\n", xprt);
-		goto out;
-	}
+	if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags))
+		return;
 
 	cpu = get_cpu();
 	pool = svc_pool_for_cpu(xprt->xpt_server, cpu);
 
 	atomic_long_inc(&pool->sp_stats.packets);
 
-	dprintk("svc: transport %p put into queue\n", xprt);
 	spin_lock_bh(&pool->sp_lock);
 	list_add_tail(&xprt->xpt_ready, &pool->sp_sockets);
 	pool->sp_stats.sockets_queued++;
@@ -412,6 +409,7 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt)
 		if (test_and_set_bit(RQ_BUSY, &rqstp->rq_flags))
 			continue;
 		atomic_long_inc(&pool->sp_stats.threads_woken);
+		rqstp->rq_qtime = ktime_get();
 		wake_up_process(rqstp->rq_task);
 		goto out_unlock;
 	}
@@ -420,7 +418,6 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt)
 out_unlock:
 	rcu_read_unlock();
 	put_cpu();
-out:
 	trace_svc_xprt_do_enqueue(xprt, rqstp);
 }
 EXPORT_SYMBOL_GPL(svc_xprt_do_enqueue);
@@ -454,13 +451,9 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
 					struct svc_xprt, xpt_ready);
 		list_del_init(&xprt->xpt_ready);
 		svc_xprt_get(xprt);
-
-		dprintk("svc: transport %p dequeued, inuse=%d\n",
-			xprt, kref_read(&xprt->xpt_ref));
 	}
 	spin_unlock_bh(&pool->sp_lock);
 out:
-	trace_svc_xprt_dequeue(xprt);
 	return xprt;
 }
 
@@ -492,7 +485,7 @@ static void svc_xprt_release(struct svc_rqst *rqstp)
 {
 	struct svc_xprt	*xprt = rqstp->rq_xprt;
 
-	rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
+	xprt->xpt_ops->xpo_release_rqst(rqstp);
 
 	kfree(rqstp->rq_deferred);
 	rqstp->rq_deferred = NULL;
@@ -538,7 +531,6 @@ void svc_wake_up(struct svc_serv *serv)
 		if (test_bit(RQ_BUSY, &rqstp->rq_flags))
 			continue;
 		rcu_read_unlock();
-		dprintk("svc: daemon %p woken up.\n", rqstp);
 		wake_up_process(rqstp->rq_task);
 		trace_svc_wake_up(rqstp->rq_task->pid);
 		return;
@@ -734,6 +726,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
 		rqstp->rq_chandle.thread_wait = 5*HZ;
 	else
 		rqstp->rq_chandle.thread_wait = 1*HZ;
+	trace_svc_xprt_dequeue(rqstp);
 	return rqstp->rq_xprt;
 }
 
@@ -789,7 +782,7 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
 			len = svc_deferred_recv(rqstp);
 		else
 			len = xprt->xpt_ops->xpo_recvfrom(rqstp);
-		dprintk("svc: got len=%d\n", len);
+		rqstp->rq_stime = ktime_get();
 		rqstp->rq_reserved = serv->sv_max_mesg;
 		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
 	}
@@ -844,10 +837,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
 
 	clear_bit(XPT_OLD, &xprt->xpt_flags);
 
-	if (xprt->xpt_ops->xpo_secure_port(rqstp))
-		set_bit(RQ_SECURE, &rqstp->rq_flags);
-	else
-		clear_bit(RQ_SECURE, &rqstp->rq_flags);
+	xprt->xpt_ops->xpo_secure_port(rqstp);
 	rqstp->rq_chandle.defer = svc_defer;
 	rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]);
 
@@ -859,7 +849,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
 	rqstp->rq_res.len = 0;
 	svc_xprt_release(rqstp);
 out:
-	trace_svc_recv(rqstp, err);
 	return err;
 }
 EXPORT_SYMBOL_GPL(svc_recv);
@@ -889,7 +878,7 @@ int svc_send(struct svc_rqst *rqstp)
 		goto out;
 
 	/* release the receive skb before sending the reply */
-	rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
+	xprt->xpt_ops->xpo_release_rqst(rqstp);
 
 	/* calculate over-all length */
 	xb = &rqstp->rq_res;
@@ -899,6 +888,7 @@ int svc_send(struct svc_rqst *rqstp)
 
 	/* Grab mutex to serialize outgoing data. */
 	mutex_lock(&xprt->xpt_mutex);
+	trace_svc_stats_latency(rqstp);
 	if (test_bit(XPT_DEAD, &xprt->xpt_flags)
 			|| test_bit(XPT_CLOSE, &xprt->xpt_flags))
 		len = -ENOTCONN;
@@ -906,12 +896,12 @@ int svc_send(struct svc_rqst *rqstp)
 		len = xprt->xpt_ops->xpo_sendto(rqstp);
 	mutex_unlock(&xprt->xpt_mutex);
 	rpc_wake_up(&xprt->xpt_bc_pending);
+	trace_svc_send(rqstp, len);
 	svc_xprt_release(rqstp);
 
 	if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN)
 		len = 0;
 out:
-	trace_svc_send(rqstp, len);
 	return len;
 }
 
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 08cd951..5445145 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -391,9 +391,12 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,
 	release_sock(sock->sk);
 }
 
-static int svc_sock_secure_port(struct svc_rqst *rqstp)
+static void svc_sock_secure_port(struct svc_rqst *rqstp)
 {
-	return svc_port_is_privileged(svc_addr(rqstp));
+	if (svc_port_is_privileged(svc_addr(rqstp)))
+		set_bit(RQ_SECURE, &rqstp->rq_flags);
+	else
+		clear_bit(RQ_SECURE, &rqstp->rq_flags);
 }
 
 /*
@@ -1309,6 +1312,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
 	set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags);
 	if (sk->sk_state == TCP_LISTEN) {
 		dprintk("setting up TCP socket for listening\n");
+		strcpy(svsk->sk_xprt.xpt_remotebuf, "listener");
 		set_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags);
 		sk->sk_data_ready = svc_tcp_listen_data_ready;
 		set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
index a4a8f69..dd8a431 100644
--- a/net/sunrpc/xprtrdma/svc_rdma.c
+++ b/net/sunrpc/xprtrdma/svc_rdma.c
@@ -51,9 +51,9 @@
 #define RPCDBG_FACILITY	RPCDBG_SVCXPRT
 
 /* RPC/RDMA parameters */
-unsigned int svcrdma_ord = RPCRDMA_ORD;
+unsigned int svcrdma_ord = 16;	/* historical default */
 static unsigned int min_ord = 1;
-static unsigned int max_ord = 4096;
+static unsigned int max_ord = 255;
 unsigned int svcrdma_max_requests = RPCRDMA_MAX_REQUESTS;
 unsigned int svcrdma_max_bc_requests = RPCRDMA_MAX_BC_REQUESTS;
 static unsigned int min_max_requests = 4;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 19e9c6b..3d45015 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -110,15 +110,16 @@
  * the RDMA_RECV completion. The SGL should contain full pages up until the
  * last one.
  */
-static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
-			       struct svc_rdma_op_ctxt *ctxt,
-			       u32 byte_count)
+static void svc_rdma_build_arg_xdr(struct svc_rqst *rqstp,
+				   struct svc_rdma_op_ctxt *ctxt)
 {
 	struct page *page;
-	u32 bc;
 	int sge_no;
+	u32 len;
 
-	/* Swap the page in the SGE with the page in argpages */
+	/* The reply path assumes the Call's transport header resides
+	 * in rqstp->rq_pages[0].
+	 */
 	page = ctxt->pages[0];
 	put_page(rqstp->rq_pages[0]);
 	rqstp->rq_pages[0] = page;
@@ -126,35 +127,35 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
 	/* Set up the XDR head */
 	rqstp->rq_arg.head[0].iov_base = page_address(page);
 	rqstp->rq_arg.head[0].iov_len =
-		min_t(size_t, byte_count, ctxt->sge[0].length);
-	rqstp->rq_arg.len = byte_count;
-	rqstp->rq_arg.buflen = byte_count;
+		min_t(size_t, ctxt->byte_len, ctxt->sge[0].length);
+	rqstp->rq_arg.len = ctxt->byte_len;
+	rqstp->rq_arg.buflen = ctxt->byte_len;
 
 	/* Compute bytes past head in the SGL */
-	bc = byte_count - rqstp->rq_arg.head[0].iov_len;
+	len = ctxt->byte_len - rqstp->rq_arg.head[0].iov_len;
 
 	/* If data remains, store it in the pagelist */
-	rqstp->rq_arg.page_len = bc;
+	rqstp->rq_arg.page_len = len;
 	rqstp->rq_arg.page_base = 0;
 
 	sge_no = 1;
-	while (bc && sge_no < ctxt->count) {
+	while (len && sge_no < ctxt->count) {
 		page = ctxt->pages[sge_no];
 		put_page(rqstp->rq_pages[sge_no]);
 		rqstp->rq_pages[sge_no] = page;
-		bc -= min_t(u32, bc, ctxt->sge[sge_no].length);
+		len -= min_t(u32, len, ctxt->sge[sge_no].length);
 		sge_no++;
 	}
 	rqstp->rq_respages = &rqstp->rq_pages[sge_no];
 	rqstp->rq_next_page = rqstp->rq_respages + 1;
 
 	/* If not all pages were used from the SGL, free the remaining ones */
-	bc = sge_no;
+	len = sge_no;
 	while (sge_no < ctxt->count) {
 		page = ctxt->pages[sge_no++];
 		put_page(page);
 	}
-	ctxt->count = bc;
+	ctxt->count = len;
 
 	/* Set up tail */
 	rqstp->rq_arg.tail[0].iov_base = NULL;
@@ -534,10 +535,8 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
 		ctxt, rdma_xprt, rqstp);
 	atomic_inc(&rdma_stat_recv);
 
-	/* Build up the XDR from the receive buffers. */
-	rdma_build_arg_xdr(rqstp, ctxt, ctxt->byte_len);
+	svc_rdma_build_arg_xdr(rqstp, ctxt);
 
-	/* Decode the RDMA header. */
 	p = (__be32 *)rqstp->rq_arg.head[0].iov_base;
 	ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg);
 	if (ret < 0)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 9ad12a2..96cc8f6 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -69,7 +69,7 @@ static void svc_rdma_release_rqst(struct svc_rqst *);
 static void svc_rdma_detach(struct svc_xprt *xprt);
 static void svc_rdma_free(struct svc_xprt *xprt);
 static int svc_rdma_has_wspace(struct svc_xprt *xprt);
-static int svc_rdma_secure_port(struct svc_rqst *);
+static void svc_rdma_secure_port(struct svc_rqst *);
 static void svc_rdma_kill_temp_xprt(struct svc_xprt *);
 
 static const struct svc_xprt_ops svc_rdma_ops = {
@@ -330,9 +330,9 @@ static void svc_rdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc)
 
 flushed:
 	if (wc->status != IB_WC_WR_FLUSH_ERR)
-		pr_warn("svcrdma: receive: %s (%u/0x%x)\n",
-			ib_wc_status_msg(wc->status),
-			wc->status, wc->vendor_err);
+		pr_err("svcrdma: Recv: %s (%u/0x%x)\n",
+		       ib_wc_status_msg(wc->status),
+		       wc->status, wc->vendor_err);
 	set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
 	svc_rdma_put_context(ctxt, 1);
 
@@ -401,8 +401,10 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
 	 */
 	set_bit(XPT_CONG_CTRL, &cma_xprt->sc_xprt.xpt_flags);
 
-	if (listener)
+	if (listener) {
+		strcpy(cma_xprt->sc_xprt.xpt_remotebuf, "listener");
 		set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags);
+	}
 
 	return cma_xprt;
 }
@@ -762,13 +764,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
 	if (!svc_rdma_prealloc_ctxts(newxprt))
 		goto errout;
 
-	/*
-	 * Limit ORD based on client limit, local device limit, and
-	 * configured svcrdma limit.
-	 */
-	newxprt->sc_ord = min_t(size_t, dev->attrs.max_qp_rd_atom, newxprt->sc_ord);
-	newxprt->sc_ord = min_t(size_t,	svcrdma_ord, newxprt->sc_ord);
-
 	newxprt->sc_pd = ib_alloc_pd(dev, 0);
 	if (IS_ERR(newxprt->sc_pd)) {
 		dprintk("svcrdma: error creating PD for connect request\n");
@@ -843,15 +838,18 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
 	set_bit(RDMAXPRT_CONN_PENDING, &newxprt->sc_flags);
 	memset(&conn_param, 0, sizeof conn_param);
 	conn_param.responder_resources = 0;
-	conn_param.initiator_depth = newxprt->sc_ord;
+	conn_param.initiator_depth = min_t(int, newxprt->sc_ord,
+					   dev->attrs.max_qp_init_rd_atom);
+	if (!conn_param.initiator_depth) {
+		dprintk("svcrdma: invalid ORD setting\n");
+		ret = -EINVAL;
+		goto errout;
+	}
 	conn_param.private_data = &pmsg;
 	conn_param.private_data_len = sizeof(pmsg);
 	ret = rdma_accept(newxprt->sc_cm_id, &conn_param);
-	if (ret) {
-		dprintk("svcrdma: failed to accept new connection, ret=%d\n",
-		       ret);
+	if (ret)
 		goto errout;
-	}
 
 	dprintk("svcrdma: new connection %p accepted:\n", newxprt);
 	sap = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr;
@@ -862,7 +860,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
 	dprintk("    sq_depth        : %d\n", newxprt->sc_sq_depth);
 	dprintk("    rdma_rw_ctxs    : %d\n", ctxts);
 	dprintk("    max_requests    : %d\n", newxprt->sc_max_requests);
-	dprintk("    ord             : %d\n", newxprt->sc_ord);
+	dprintk("    ord             : %d\n", conn_param.initiator_depth);
 
 	return &newxprt->sc_xprt;
 
@@ -992,9 +990,9 @@ static int svc_rdma_has_wspace(struct svc_xprt *xprt)
 	return 1;
 }
 
-static int svc_rdma_secure_port(struct svc_rqst *rqstp)
+static void svc_rdma_secure_port(struct svc_rqst *rqstp)
 {
-	return 1;
+	set_bit(RQ_SECURE, &rqstp->rq_flags);
 }
 
 static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index e3215b7..45b9aa3 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -210,7 +210,7 @@
 	$(call if_changed,bison)
 
 quiet_cmd_bison_h = YACC    $@
-      cmd_bison_h = bison -o/dev/null --defines=$@ -t -l -p $(YACC_PREFIX) $<
+      cmd_bison_h = bison -o/dev/null --defines=$@ -t -l $<
 
 ifdef REGENERATE_PARSERS
 .PRECIOUS: $(src)/%.tab.h_shipped
@@ -269,10 +269,9 @@
 # Disable noisy checks by default
 ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),)
 DTC_FLAGS += -Wno-unit_address_vs_reg \
-	-Wno-simple_bus_reg \
 	-Wno-unit_address_format \
-	-Wno-pci_bridge \
-	-Wno-pci_device_bus_num \
+	-Wno-avoid_unnecessary_addr_size \
+	-Wno-alias_paths \
 	-Wno-pci_device_reg
 endif
 
@@ -309,7 +308,7 @@
 		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
 	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
 
-$(obj)/%.dtb: $(src)/%.dts FORCE
+$(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
 	$(call if_changed_dep,dtc)
 
 dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 0dc922b..a88b8c9 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -28,5 +28,7 @@
 # dependencies on generated files need to be listed explicitly
 $(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h
 
-# generated files need to be cleaned explicitly
-clean-files	:= dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h
+# generated files need to include *.cmd and be cleaned explicitly
+generated-files	:= dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h
+targets		:= $(generated-files)
+clean-files	:= $(generated-files)
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index e661384..c07ba4d 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -53,26 +53,28 @@ struct check {
 	struct check **prereq;
 };
 
-#define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...)	       \
-	static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \
-	static struct check _nm = { \
-		.name = #_nm, \
-		.fn = (_fn), \
-		.data = (_d), \
-		.warn = (_w), \
-		.error = (_e), \
+#define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...)	       \
+	static struct check *nm_##_prereqs[] = { __VA_ARGS__ }; \
+	static struct check nm_ = { \
+		.name = #nm_, \
+		.fn = (fn_), \
+		.data = (d_), \
+		.warn = (w_), \
+		.error = (e_), \
 		.status = UNCHECKED, \
-		.num_prereqs = ARRAY_SIZE(_nm##_prereqs), \
-		.prereq = _nm##_prereqs, \
+		.num_prereqs = ARRAY_SIZE(nm_##_prereqs), \
+		.prereq = nm_##_prereqs, \
 	};
-#define WARNING(_nm, _fn, _d, ...) \
-	CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__)
-#define ERROR(_nm, _fn, _d, ...) \
-	CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__)
-#define CHECK(_nm, _fn, _d, ...) \
-	CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__)
+#define WARNING(nm_, fn_, d_, ...) \
+	CHECK_ENTRY(nm_, fn_, d_, true, false, __VA_ARGS__)
+#define ERROR(nm_, fn_, d_, ...) \
+	CHECK_ENTRY(nm_, fn_, d_, false, true, __VA_ARGS__)
+#define CHECK(nm_, fn_, d_, ...) \
+	CHECK_ENTRY(nm_, fn_, d_, false, false, __VA_ARGS__)
 
-static inline void  PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti,
+static inline void  PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti,
+					   struct node *node,
+					   struct property *prop,
 					   const char *fmt, ...)
 {
 	va_list ap;
@@ -83,19 +85,33 @@ static inline void  PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti,
 		fprintf(stderr, "%s: %s (%s): ",
 			strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
 			(c->error) ? "ERROR" : "Warning", c->name);
+		if (node) {
+			fprintf(stderr, "%s", node->fullpath);
+			if (prop)
+				fprintf(stderr, ":%s", prop->name);
+			fputs(": ", stderr);
+		}
 		vfprintf(stderr, fmt, ap);
 		fprintf(stderr, "\n");
 	}
 	va_end(ap);
 }
 
-#define FAIL(c, dti, ...)						\
+#define FAIL(c, dti, node, ...)						\
 	do {								\
 		TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__);	\
 		(c)->status = FAILED;					\
-		check_msg((c), dti, __VA_ARGS__);			\
+		check_msg((c), dti, node, NULL, __VA_ARGS__);		\
 	} while (0)
 
+#define FAIL_PROP(c, dti, node, prop, ...)				\
+	do {								\
+		TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__);	\
+		(c)->status = FAILED;					\
+		check_msg((c), dti, node, prop, __VA_ARGS__);		\
+	} while (0)
+
+
 static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node)
 {
 	struct node *child;
@@ -126,7 +142,7 @@ static bool run_check(struct check *c, struct dt_info *dti)
 		error = error || run_check(prq, dti);
 		if (prq->status != PASSED) {
 			c->status = PREREQ;
-			check_msg(c, dti, "Failed prerequisite '%s'",
+			check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'",
 				  c->prereq[i]->name);
 		}
 	}
@@ -156,7 +172,7 @@ static bool run_check(struct check *c, struct dt_info *dti)
 static inline void check_always_fail(struct check *c, struct dt_info *dti,
 				     struct node *node)
 {
-	FAIL(c, dti, "always_fail check");
+	FAIL(c, dti, node, "always_fail check");
 }
 CHECK(always_fail, check_always_fail, NULL);
 
@@ -171,14 +187,42 @@ static void check_is_string(struct check *c, struct dt_info *dti,
 		return; /* Not present, assumed ok */
 
 	if (!data_is_one_string(prop->val))
-		FAIL(c, dti, "\"%s\" property in %s is not a string",
-		     propname, node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "property is not a string");
 }
 #define WARNING_IF_NOT_STRING(nm, propname) \
 	WARNING(nm, check_is_string, (propname))
 #define ERROR_IF_NOT_STRING(nm, propname) \
 	ERROR(nm, check_is_string, (propname))
 
+static void check_is_string_list(struct check *c, struct dt_info *dti,
+				 struct node *node)
+{
+	int rem, l;
+	struct property *prop;
+	char *propname = c->data;
+	char *str;
+
+	prop = get_property(node, propname);
+	if (!prop)
+		return; /* Not present, assumed ok */
+
+	str = prop->val.val;
+	rem = prop->val.len;
+	while (rem > 0) {
+		l = strnlen(str, rem);
+		if (l == rem) {
+			FAIL_PROP(c, dti, node, prop, "property is not a string list");
+			break;
+		}
+		rem -= l + 1;
+		str += l + 1;
+	}
+}
+#define WARNING_IF_NOT_STRING_LIST(nm, propname) \
+	WARNING(nm, check_is_string_list, (propname))
+#define ERROR_IF_NOT_STRING_LIST(nm, propname) \
+	ERROR(nm, check_is_string_list, (propname))
+
 static void check_is_cell(struct check *c, struct dt_info *dti,
 			  struct node *node)
 {
@@ -190,8 +234,7 @@ static void check_is_cell(struct check *c, struct dt_info *dti,
 		return; /* Not present, assumed ok */
 
 	if (prop->val.len != sizeof(cell_t))
-		FAIL(c, dti, "\"%s\" property in %s is not a single cell",
-		     propname, node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "property is not a single cell");
 }
 #define WARNING_IF_NOT_CELL(nm, propname) \
 	WARNING(nm, check_is_cell, (propname))
@@ -212,8 +255,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti,
 		     child2;
 		     child2 = child2->next_sibling)
 			if (streq(child->name, child2->name))
-				FAIL(c, dti, "Duplicate node name %s",
-				     child->fullpath);
+				FAIL(c, dti, node, "Duplicate node name");
 }
 ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
 
@@ -227,8 +269,7 @@ static void check_duplicate_property_names(struct check *c, struct dt_info *dti,
 			if (prop2->deleted)
 				continue;
 			if (streq(prop->name, prop2->name))
-				FAIL(c, dti, "Duplicate property name %s in %s",
-				     prop->name, node->fullpath);
+				FAIL_PROP(c, dti, node, prop, "Duplicate property name");
 		}
 	}
 }
@@ -246,8 +287,8 @@ static void check_node_name_chars(struct check *c, struct dt_info *dti,
 	int n = strspn(node->name, c->data);
 
 	if (n < strlen(node->name))
-		FAIL(c, dti, "Bad character '%c' in node %s",
-		     node->name[n], node->fullpath);
+		FAIL(c, dti, node, "Bad character '%c' in node name",
+		     node->name[n]);
 }
 ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
 
@@ -257,8 +298,8 @@ static void check_node_name_chars_strict(struct check *c, struct dt_info *dti,
 	int n = strspn(node->name, c->data);
 
 	if (n < node->basenamelen)
-		FAIL(c, dti, "Character '%c' not recommended in node %s",
-		     node->name[n], node->fullpath);
+		FAIL(c, dti, node, "Character '%c' not recommended in node name",
+		     node->name[n]);
 }
 CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT);
 
@@ -266,8 +307,7 @@ static void check_node_name_format(struct check *c, struct dt_info *dti,
 				   struct node *node)
 {
 	if (strchr(get_unitname(node), '@'))
-		FAIL(c, dti, "Node %s has multiple '@' characters in name",
-		     node->fullpath);
+		FAIL(c, dti, node, "multiple '@' characters in node name");
 }
 ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
 
@@ -285,12 +325,10 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
 
 	if (prop) {
 		if (!unitname[0])
-			FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name",
-			    node->fullpath);
+			FAIL(c, dti, node, "node has a reg or ranges property, but no unit name");
 	} else {
 		if (unitname[0])
-			FAIL(c, dti, "Node %s has a unit name, but no reg property",
-			    node->fullpath);
+			FAIL(c, dti, node, "node has a unit name, but no reg property");
 	}
 }
 WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
@@ -304,8 +342,8 @@ static void check_property_name_chars(struct check *c, struct dt_info *dti,
 		int n = strspn(prop->name, c->data);
 
 		if (n < strlen(prop->name))
-			FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s",
-			     prop->name[n], prop->name, node->fullpath);
+			FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name",
+				  prop->name[n]);
 	}
 }
 ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
@@ -336,8 +374,8 @@ static void check_property_name_chars_strict(struct check *c,
 			n = strspn(name, c->data);
 		}
 		if (n < strlen(name))
-			FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s",
-			     name[n], prop->name, node->fullpath);
+			FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name",
+				  name[n]);
 	}
 }
 CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT);
@@ -370,7 +408,7 @@ static void check_duplicate_label(struct check *c, struct dt_info *dti,
 		return;
 
 	if ((othernode != node) || (otherprop != prop) || (othermark != mark))
-		FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT
+		FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT
 		     " and " DESCLABEL_FMT,
 		     label, DESCLABEL_ARGS(node, prop, mark),
 		     DESCLABEL_ARGS(othernode, otherprop, othermark));
@@ -410,8 +448,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
 		return 0;
 
 	if (prop->val.len != sizeof(cell_t)) {
-		FAIL(c, dti, "%s has bad length (%d) %s property",
-		     node->fullpath, prop->val.len, prop->name);
+		FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property",
+			  prop->val.len, prop->name);
 		return 0;
 	}
 
@@ -422,8 +460,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
 			/* "Set this node's phandle equal to some
 			 * other node's phandle".  That's nonsensical
 			 * by construction. */ {
-			FAIL(c, dti, "%s in %s is a reference to another node",
-			     prop->name, node->fullpath);
+			FAIL(c, dti, node, "%s is a reference to another node",
+			     prop->name);
 		}
 		/* But setting this node's phandle equal to its own
 		 * phandle is allowed - that means allocate a unique
@@ -436,8 +474,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
 	phandle = propval_cell(prop);
 
 	if ((phandle == 0) || (phandle == -1)) {
-		FAIL(c, dti, "%s has bad value (0x%x) in %s property",
-		     node->fullpath, phandle, prop->name);
+		FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property",
+		     phandle, prop->name);
 		return 0;
 	}
 
@@ -463,16 +501,16 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti,
 		return;
 
 	if (linux_phandle && phandle && (phandle != linux_phandle))
-		FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'"
-		     " properties", node->fullpath);
+		FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'"
+		     " properties");
 
 	if (linux_phandle && !phandle)
 		phandle = linux_phandle;
 
 	other = get_node_by_phandle(root, phandle);
 	if (other && (other != node)) {
-		FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)",
-		     node->fullpath, phandle, other->fullpath);
+		FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)",
+		     phandle, other->fullpath);
 		return;
 	}
 
@@ -496,8 +534,8 @@ static void check_name_properties(struct check *c, struct dt_info *dti,
 
 	if ((prop->val.len != node->basenamelen+1)
 	    || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
-		FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead"
-		     " of base node name)", node->fullpath, prop->val.val);
+		FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead"
+		     " of base node name)", prop->val.val);
 	} else {
 		/* The name property is correct, and therefore redundant.
 		 * Delete it */
@@ -531,7 +569,7 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
 			refnode = get_node_by_ref(dt, m->ref);
 			if (! refnode) {
 				if (!(dti->dtsflags & DTSF_PLUGIN))
-					FAIL(c, dti, "Reference to non-existent node or "
+					FAIL(c, dti, node, "Reference to non-existent node or "
 							"label \"%s\"\n", m->ref);
 				else /* mark the entry as unresolved */
 					*((fdt32_t *)(prop->val.val + m->offset)) =
@@ -563,7 +601,7 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,
 
 			refnode = get_node_by_ref(dt, m->ref);
 			if (!refnode) {
-				FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n",
+				FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n",
 				     m->ref);
 				continue;
 			}
@@ -586,6 +624,45 @@ WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells");
 WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
 WARNING_IF_NOT_STRING(model_is_string, "model");
 WARNING_IF_NOT_STRING(status_is_string, "status");
+WARNING_IF_NOT_STRING(label_is_string, "label");
+
+WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible");
+
+static void check_names_is_string_list(struct check *c, struct dt_info *dti,
+				       struct node *node)
+{
+	struct property *prop;
+
+	for_each_property(node, prop) {
+		const char *s = strrchr(prop->name, '-');
+		if (!s || !streq(s, "-names"))
+			continue;
+
+		c->data = prop->name;
+		check_is_string_list(c, dti, node);
+	}
+}
+WARNING(names_is_string_list, check_names_is_string_list, NULL);
+
+static void check_alias_paths(struct check *c, struct dt_info *dti,
+				    struct node *node)
+{
+	struct property *prop;
+
+	if (!streq(node->name, "aliases"))
+		return;
+
+	for_each_property(node, prop) {
+		if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) {
+			FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)",
+				  prop->val.val);
+			continue;
+		}
+		if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name))
+			FAIL(c, dti, node, "aliases property name must include only lowercase and '-'");
+	}
+}
+WARNING(alias_paths, check_alias_paths, NULL);
 
 static void fixup_addr_size_cells(struct check *c, struct dt_info *dti,
 				  struct node *node)
@@ -622,21 +699,21 @@ static void check_reg_format(struct check *c, struct dt_info *dti,
 		return; /* No "reg", that's fine */
 
 	if (!node->parent) {
-		FAIL(c, dti, "Root node has a \"reg\" property");
+		FAIL(c, dti, node, "Root node has a \"reg\" property");
 		return;
 	}
 
 	if (prop->val.len == 0)
-		FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "property is empty");
 
 	addr_cells = node_addr_cells(node->parent);
 	size_cells = node_size_cells(node->parent);
 	entrylen = (addr_cells + size_cells) * sizeof(cell_t);
 
 	if (!entrylen || (prop->val.len % entrylen) != 0)
-		FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) "
-		     "(#address-cells == %d, #size-cells == %d)",
-		     node->fullpath, prop->val.len, addr_cells, size_cells);
+		FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) "
+			  "(#address-cells == %d, #size-cells == %d)",
+			  prop->val.len, addr_cells, size_cells);
 }
 WARNING(reg_format, check_reg_format, NULL, &addr_size_cells);
 
@@ -651,7 +728,7 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,
 		return;
 
 	if (!node->parent) {
-		FAIL(c, dti, "Root node has a \"ranges\" property");
+		FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property");
 		return;
 	}
 
@@ -663,20 +740,20 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,
 
 	if (prop->val.len == 0) {
 		if (p_addr_cells != c_addr_cells)
-			FAIL(c, dti, "%s has empty \"ranges\" property but its "
-			     "#address-cells (%d) differs from %s (%d)",
-			     node->fullpath, c_addr_cells, node->parent->fullpath,
-			     p_addr_cells);
+			FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "
+				  "#address-cells (%d) differs from %s (%d)",
+				  c_addr_cells, node->parent->fullpath,
+				  p_addr_cells);
 		if (p_size_cells != c_size_cells)
-			FAIL(c, dti, "%s has empty \"ranges\" property but its "
-			     "#size-cells (%d) differs from %s (%d)",
-			     node->fullpath, c_size_cells, node->parent->fullpath,
-			     p_size_cells);
+			FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "
+				  "#size-cells (%d) differs from %s (%d)",
+				  c_size_cells, node->parent->fullpath,
+				  p_size_cells);
 	} else if ((prop->val.len % entrylen) != 0) {
-		FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) "
-		     "(parent #address-cells == %d, child #address-cells == %d, "
-		     "#size-cells == %d)", node->fullpath, prop->val.len,
-		     p_addr_cells, c_addr_cells, c_size_cells);
+		FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) "
+			  "(parent #address-cells == %d, child #address-cells == %d, "
+			  "#size-cells == %d)", prop->val.len,
+			  p_addr_cells, c_addr_cells, c_size_cells);
 	}
 }
 WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
@@ -696,41 +773,33 @@ static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *
 
 	node->bus = &pci_bus;
 
-	if (!strneq(node->name, "pci", node->basenamelen) &&
-	    !strneq(node->name, "pcie", node->basenamelen))
-		FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"",
-			     node->fullpath);
+	if (!strprefixeq(node->name, node->basenamelen, "pci") &&
+	    !strprefixeq(node->name, node->basenamelen, "pcie"))
+		FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\"");
 
 	prop = get_property(node, "ranges");
 	if (!prop)
-		FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)",
-			     node->fullpath);
+		FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)");
 
 	if (node_addr_cells(node) != 3)
-		FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge",
-			     node->fullpath);
+		FAIL(c, dti, node, "incorrect #address-cells for PCI bridge");
 	if (node_size_cells(node) != 2)
-		FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge",
-			     node->fullpath);
+		FAIL(c, dti, node, "incorrect #size-cells for PCI bridge");
 
 	prop = get_property(node, "bus-range");
 	if (!prop) {
-		FAIL(c, dti, "Node %s missing bus-range for PCI bridge",
-			     node->fullpath);
+		FAIL(c, dti, node, "missing bus-range for PCI bridge");
 		return;
 	}
 	if (prop->val.len != (sizeof(cell_t) * 2)) {
-		FAIL(c, dti, "Node %s bus-range must be 2 cells",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "value must be 2 cells");
 		return;
 	}
 	cells = (cell_t *)prop->val.val;
 	if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1]))
-		FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell");
 	if (fdt32_to_cpu(cells[1]) > 0xff)
-		FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256");
 }
 WARNING(pci_bridge, check_pci_bridge, NULL,
 	&device_type_is_string, &addr_size_cells);
@@ -760,8 +829,8 @@ static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struc
 		max_bus = fdt32_to_cpu(cells[0]);
 	}
 	if ((bus_num < min_bus) || (bus_num > max_bus))
-		FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)",
-		     node->fullpath, bus_num, min_bus, max_bus);
+		FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)",
+			  bus_num, min_bus, max_bus);
 }
 WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge);
 
@@ -778,25 +847,22 @@ static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct no
 
 	prop = get_property(node, "reg");
 	if (!prop) {
-		FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath);
+		FAIL(c, dti, node, "missing PCI reg property");
 		return;
 	}
 
 	cells = (cell_t *)prop->val.val;
 	if (cells[1] || cells[2])
-		FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0");
 
 	reg = fdt32_to_cpu(cells[0]);
 	dev = (reg & 0xf800) >> 11;
 	func = (reg & 0x700) >> 8;
 
 	if (reg & 0xff000000)
-		FAIL(c, dti, "Node %s PCI reg address is not configuration space",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space");
 	if (reg & 0x000000ff)
-		FAIL(c, dti, "Node %s PCI reg config space address register number must be 0",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0");
 
 	if (func == 0) {
 		snprintf(unit_addr, sizeof(unit_addr), "%x", dev);
@@ -808,8 +874,8 @@ static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct no
 	if (streq(unitname, unit_addr))
 		return;
 
-	FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"",
-	     node->fullpath, unit_addr);
+	FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"",
+	     unit_addr);
 }
 WARNING(pci_device_reg, check_pci_device_reg, NULL, &reg_format, &pci_bridge);
 
@@ -828,7 +894,7 @@ static bool node_is_compatible(struct node *node, const char *compat)
 
 	for (str = prop->val.val, end = str + prop->val.len; str < end;
 	     str += strnlen(str, end - str) + 1) {
-		if (strneq(str, compat, end - str))
+		if (strprefixeq(str, end - str, compat))
 			return true;
 	}
 	return false;
@@ -865,7 +931,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
 
 	if (!cells) {
 		if (node->parent->parent && !(node->bus == &simple_bus))
-			FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath);
+			FAIL(c, dti, node, "missing or empty reg/ranges property");
 		return;
 	}
 
@@ -875,8 +941,8 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
 
 	snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
 	if (!streq(unitname, unit_addr))
-		FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
-		     node->fullpath, unit_addr);
+		FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"",
+		     unit_addr);
 }
 WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge);
 
@@ -892,14 +958,12 @@ static void check_unit_address_format(struct check *c, struct dt_info *dti,
 		return;
 
 	if (!strncmp(unitname, "0x", 2)) {
-		FAIL(c, dti, "Node %s unit name should not have leading \"0x\"",
-		    node->fullpath);
+		FAIL(c, dti, node, "unit name should not have leading \"0x\"");
 		/* skip over 0x for next test */
 		unitname += 2;
 	}
 	if (unitname[0] == '0' && isxdigit(unitname[1]))
-		FAIL(c, dti, "Node %s unit name should not have leading 0s",
-		    node->fullpath);
+		FAIL(c, dti, node, "unit name should not have leading 0s");
 }
 WARNING(unit_address_format, check_unit_address_format, NULL,
 	&node_name_format, &pci_bridge, &simple_bus_bridge);
@@ -922,16 +986,38 @@ static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti,
 		return;
 
 	if (node->parent->addr_cells == -1)
-		FAIL(c, dti, "Relying on default #address-cells value for %s",
-		     node->fullpath);
+		FAIL(c, dti, node, "Relying on default #address-cells value");
 
 	if (node->parent->size_cells == -1)
-		FAIL(c, dti, "Relying on default #size-cells value for %s",
-		     node->fullpath);
+		FAIL(c, dti, node, "Relying on default #size-cells value");
 }
 WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
 	&addr_size_cells);
 
+static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti,
+					      struct node *node)
+{
+	struct property *prop;
+	struct node *child;
+	bool has_reg = false;
+
+	if (!node->parent || node->addr_cells < 0 || node->size_cells < 0)
+		return;
+
+	if (get_property(node, "ranges") || !node->children)
+		return;
+
+	for_each_child(node, child) {
+		prop = get_property(child, "reg");
+		if (prop)
+			has_reg = true;
+	}
+
+	if (!has_reg)
+		FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property");
+}
+WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
+
 static void check_obsolete_chosen_interrupt_controller(struct check *c,
 						       struct dt_info *dti,
 						       struct node *node)
@@ -950,12 +1036,61 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
 
 	prop = get_property(chosen, "interrupt-controller");
 	if (prop)
-		FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" "
-		     "property");
+		FAIL_PROP(c, dti, node, prop,
+			  "/chosen has obsolete \"interrupt-controller\" property");
 }
 WARNING(obsolete_chosen_interrupt_controller,
 	check_obsolete_chosen_interrupt_controller, NULL);
 
+static void check_chosen_node_is_root(struct check *c, struct dt_info *dti,
+				      struct node *node)
+{
+	if (!streq(node->name, "chosen"))
+		return;
+
+	if (node->parent != dti->dt)
+		FAIL(c, dti, node, "chosen node must be at root node");
+}
+WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL);
+
+static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti,
+				       struct node *node)
+{
+	struct property *prop;
+
+	if (!streq(node->name, "chosen"))
+		return;
+
+	prop = get_property(node, "bootargs");
+	if (!prop)
+		return;
+
+	c->data = prop->name;
+	check_is_string(c, dti, node);
+}
+WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL);
+
+static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti,
+					  struct node *node)
+{
+	struct property *prop;
+
+	if (!streq(node->name, "chosen"))
+		return;
+
+	prop = get_property(node, "stdout-path");
+	if (!prop) {
+		prop = get_property(node, "linux,stdout-path");
+		if (!prop)
+			return;
+		FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead");
+	}
+
+	c->data = prop->name;
+	check_is_string(c, dti, node);
+}
+WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL);
+
 struct provider {
 	const char *prop_name;
 	const char *cell_name;
@@ -972,8 +1107,9 @@ static void check_property_phandle_args(struct check *c,
 	int cell, cellsize = 0;
 
 	if (prop->val.len % sizeof(cell_t)) {
-		FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
-		     prop->name, prop->val.len, sizeof(cell_t), node->fullpath);
+		FAIL_PROP(c, dti, node, prop,
+			  "property size (%d) is invalid, expected multiple of %zu",
+			  prop->val.len, sizeof(cell_t));
 		return;
 	}
 
@@ -1004,14 +1140,16 @@ static void check_property_phandle_args(struct check *c,
 					break;
 			}
 			if (!m)
-				FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s",
-				     prop->name, cell, node->fullpath);
+				FAIL_PROP(c, dti, node, prop,
+					  "cell %d is not a phandle reference",
+					  cell);
 		}
 
 		provider_node = get_node_by_phandle(root, phandle);
 		if (!provider_node) {
-			FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)",
-			     node->fullpath, prop->name, cell);
+			FAIL_PROP(c, dti, node, prop,
+				  "Could not get phandle node for (cell %d)",
+				  cell);
 			break;
 		}
 
@@ -1021,16 +1159,17 @@ static void check_property_phandle_args(struct check *c,
 		} else if (provider->optional) {
 			cellsize = 0;
 		} else {
-			FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])",
+			FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])",
 			     provider->cell_name,
 			     provider_node->fullpath,
-			     node->fullpath, prop->name, cell);
+			     prop->name, cell);
 			break;
 		}
 
 		if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
-			FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s",
-			     prop->name, prop->val.len, cellsize, node->fullpath);
+			FAIL_PROP(c, dti, node, prop,
+				  "property size (%d) too small for cell size %d",
+				  prop->val.len, cellsize);
 		}
 	}
 }
@@ -1066,7 +1205,7 @@ WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
 WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
 WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
 WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
-WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells");
 WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
 
 static bool prop_is_gpio(struct property *prop)
@@ -1132,8 +1271,8 @@ static void check_deprecated_gpio_property(struct check *c,
 		if (!streq(str, "gpio"))
 			continue;
 
-		FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s",
-		     node->fullpath, prop->name);
+		FAIL_PROP(c, dti, node, prop,
+			  "'[*-]gpio' is deprecated, use '[*-]gpios' instead");
 	}
 
 }
@@ -1167,9 +1306,8 @@ static void check_interrupts_property(struct check *c,
 		return;
 
 	if (irq_prop->val.len % sizeof(cell_t))
-		FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
-		     irq_prop->name, irq_prop->val.len, sizeof(cell_t),
-		     node->fullpath);
+		FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu",
+		     irq_prop->val.len, sizeof(cell_t));
 
 	while (parent && !prop) {
 		if (parent != node && node_is_interrupt_provider(parent)) {
@@ -1187,14 +1325,12 @@ static void check_interrupts_property(struct check *c,
 
 			irq_node = get_node_by_phandle(root, phandle);
 			if (!irq_node) {
-				FAIL(c, dti, "Bad interrupt-parent phandle for %s",
-				     node->fullpath);
+				FAIL_PROP(c, dti, parent, prop, "Bad phandle");
 				return;
 			}
 			if (!node_is_interrupt_provider(irq_node))
-				FAIL(c, dti,
-				     "Missing interrupt-controller or interrupt-map property in %s",
-				     irq_node->fullpath);
+				FAIL(c, dti, irq_node,
+				     "Missing interrupt-controller or interrupt-map property");
 
 			break;
 		}
@@ -1203,23 +1339,21 @@ static void check_interrupts_property(struct check *c,
 	}
 
 	if (!irq_node) {
-		FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath);
+		FAIL(c, dti, node, "Missing interrupt-parent");
 		return;
 	}
 
 	prop = get_property(irq_node, "#interrupt-cells");
 	if (!prop) {
-		FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s",
-		     irq_node->fullpath);
+		FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent");
 		return;
 	}
 
 	irq_cells = propval_cell(prop);
 	if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
-		FAIL(c, dti,
-		     "interrupts size is (%d), expected multiple of %d in %s",
-		     irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)),
-		     node->fullpath);
+		FAIL_PROP(c, dti, node, prop,
+			  "size is (%d), expected multiple of %d",
+			  irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)));
 	}
 }
 WARNING(interrupts_property, check_interrupts_property, &phandle_references);
@@ -1236,6 +1370,9 @@ static struct check *check_table[] = {
 
 	&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
 	&device_type_is_string, &model_is_string, &status_is_string,
+	&label_is_string,
+
+	&compatible_is_string_list, &names_is_string_list,
 
 	&property_name_chars_strict,
 	&node_name_chars_strict,
@@ -1253,7 +1390,9 @@ static struct check *check_table[] = {
 	&simple_bus_reg,
 
 	&avoid_default_addr_size,
+	&avoid_unnecessary_addr_size,
 	&obsolete_chosen_interrupt_controller,
+	&chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
 
 	&clocks_property,
 	&cooling_device_property,
@@ -1269,13 +1408,15 @@ static struct check *check_table[] = {
 	&power_domains_property,
 	&pwms_property,
 	&resets_property,
-	&sound_dais_property,
+	&sound_dai_property,
 	&thermal_sensors_property,
 
 	&deprecated_gpio_property,
 	&gpios_property,
 	&interrupts_property,
 
+	&alias_paths,
+
 	&always_fail,
 };
 
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
deleted file mode 100644
index 011bb96..0000000
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ /dev/null
@@ -1,2259 +0,0 @@
-#line 2 "dtc-lexer.lex.c"
-
-#line 4 "dtc-lexer.lex.c"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 1
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-/* TODO: this is always defined, so inline it */
-#define yyconst const
-
-#if defined(__GNUC__) && __GNUC__ >= 3
-#define yynoreturn __attribute__((__noreturn__))
-#else
-#define yynoreturn
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin  )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-extern int yyleng;
-
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-    #define YY_LESS_LINENO(n)
-    #define YY_LINENO_REWIND_TO(ptr)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		*yy_cp = (yy_hold_char); \
-		YY_RESTORE_YY_MORE_OFFSET \
-		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
-		} \
-	while ( 0 )
-
-#define unput(c) yyunput( c, (yytext_ptr)  )
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-	{
-	FILE *yy_input_file;
-
-	char *yy_ch_buf;		/* input buffer */
-	char *yy_buf_pos;		/* current position in input buffer */
-
-	/* Size of input buffer in bytes, not including room for EOB
-	 * characters.
-	 */
-	int yy_buf_size;
-
-	/* Number of characters read into yy_ch_buf, not including EOB
-	 * characters.
-	 */
-	int yy_n_chars;
-
-	/* Whether we "own" the buffer - i.e., we know we created it,
-	 * and can realloc() it to grow it, and should free() it to
-	 * delete it.
-	 */
-	int yy_is_our_buffer;
-
-	/* Whether this is an "interactive" input source; if so, and
-	 * if we're using stdio for input, then we want to use getc()
-	 * instead of fread(), to make sure we stop fetching input after
-	 * each newline.
-	 */
-	int yy_is_interactive;
-
-	/* Whether we're considered to be at the beginning of a line.
-	 * If so, '^' rules will be active on the next match, otherwise
-	 * not.
-	 */
-	int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-
-	/* Whether to try to fill the input buffer when we reach the
-	 * end of it.
-	 */
-	int yy_fill_buffer;
-
-	int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-	/* When an EOF's been seen but there's still some text to process
-	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-	 * shouldn't try reading from the input source any more.  We might
-	 * still have a bunch of tokens to match, though, because of
-	 * possible backing-up.
-	 *
-	 * When we actually see the EOF, we change the status to "new"
-	 * (via yyrestart()), so that the user can continue scanning by
-	 * just pointing yyin at a new input file.
-	 */
-#define YY_BUFFER_EOF_PENDING 2
-
-	};
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = NULL;
-static int yy_init = 0;		/* whether we need to initialize */
-static int yy_start = 0;	/* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin.  A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
-
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
-
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
-
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
-	}
-
-#define yy_set_bol(at_bol) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
-	}
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define yywrap() (/*CONSTCOND*/1)
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-FILE *yyin = NULL, *yyout = NULL;
-
-typedef int yy_state_type;
-
-extern int yylineno;
-
-int yylineno = 1;
-
-extern char *yytext;
-#ifdef yytext_ptr
-#undef yytext_ptr
-#endif
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yynoreturn yy_fatal_error (yyconst char* msg  );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
-	(yytext_ptr) = yy_bp; \
-	yyleng = (int) (yy_cp - yy_bp); \
-	(yy_hold_char) = *yy_cp; \
-	*yy_cp = '\0'; \
-	(yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 31
-#define YY_END_OF_BUFFER 32
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-	{
-	flex_int32_t yy_verify;
-	flex_int32_t yy_nxt;
-	};
-static yyconst flex_int16_t yy_accept[166] =
-    {   0,
-        0,    0,    0,    0,    0,    0,    0,    0,   32,   30,
-       19,   19,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   30,   16,   17,   17,   30,
-       17,   11,   11,   19,   27,    0,    3,    0,   28,   13,
-        0,    0,   12,    0,    0,    0,    0,    0,    0,    0,
-        0,   22,   24,   26,   25,   23,    0,   10,   29,    0,
-        0,    0,   15,   15,   17,   17,   17,   11,   11,   11,
-        0,   13,    0,   12,    0,    0,    0,   21,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,   17,   11,   11,
-       11,    0,   14,   20,    0,    0,    0,    0,    0,    0,
-
-        0,    0,    0,    0,   17,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,   17,    7,    0,    0,    0,
-        0,    0,    0,    0,    2,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    4,   18,    0,    0,    5,    2,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    1,    0,    0,    0,    0,    6,    9,    0,
-        0,    0,    0,    8,    0
-    } ;
-
-static yyconst YY_CHAR yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        4,    4,    4,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    5,    6,    7,    1,    1,    8,    9,    1,
-        1,   10,   11,   11,   12,   11,   13,   14,   15,   16,
-       16,   16,   16,   16,   16,   16,   16,   17,    1,   18,
-       19,   20,   11,   11,   21,   21,   21,   21,   21,   21,
-       22,   22,   22,   22,   22,   23,   22,   22,   22,   22,
-       22,   22,   22,   22,   24,   22,   22,   25,   22,   22,
-        1,   26,   27,    1,   22,    1,   21,   28,   29,   30,
-
-       31,   21,   32,   22,   33,   22,   22,   34,   35,   36,
-       37,   38,   22,   39,   40,   41,   42,   43,   22,   25,
-       44,   22,   45,   46,   47,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
-    } ;
-
-static yyconst YY_CHAR yy_meta[48] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    2,    3,    1,    2,
-        2,    2,    4,    5,    5,    5,    6,    1,    1,    1,
-        7,    8,    8,    8,    8,    1,    1,    7,    7,    7,
-        7,    8,    8,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    8,    8,    3,    1,    4
-    } ;
-
-static yyconst flex_uint16_t yy_base[180] =
-    {   0,
-        0,  393,   35,  392,   66,  391,   38,  107,  397,  401,
-       55,  113,  377,  112,  111,  111,  114,   42,  376,  106,
-      377,  347,  126,  120,    0,  147,  401,    0,  124,    0,
-      137,  158,  170,  163,  401,  153,  401,  389,  401,    0,
-      378,  120,  401,  131,  380,  386,  355,  139,  351,  355,
-      351,  401,  401,  401,  401,  401,  367,  401,  401,  185,
-      350,  346,  401,  364,    0,  185,  347,  189,  356,  355,
-        0,    0,  330,  180,  366,  141,  372,  361,  332,  338,
-      331,  341,  334,  326,  205,  331,  337,  329,  401,  341,
-      167,  316,  401,  349,  348,  320,  328,  346,  180,  318,
-
-      324,  209,  324,  320,  322,  342,  338,  309,  306,  315,
-      305,  315,  312,  192,  342,  341,  401,  293,  306,  282,
-      268,  252,  255,  203,  285,  282,  272,  268,  252,  233,
-      232,  239,  208,  107,  401,  401,  238,  211,  401,  211,
-      212,  208,  228,  203,  215,  207,  233,  222,  212,  211,
-      203,  227,  401,  237,  225,  204,  185,  401,  401,  149,
-      128,   88,   42,  401,  401,  253,  259,  267,  271,  275,
-      281,  288,  292,  300,  308,  312,  318,  326,  334
-    } ;
-
-static yyconst flex_int16_t yy_def[180] =
-    {   0,
-      165,    1,    1,    3,  165,    5,    1,    1,  165,  165,
-      165,  165,  165,  166,  167,  168,  165,  165,  165,  165,
-      169,  165,  165,  165,  170,  169,  165,  171,  172,  171,
-      171,  165,  165,  165,  165,  166,  165,  166,  165,  173,
-      165,  168,  165,  168,  174,  175,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  169,  165,  165,  165,
-      165,  165,  165,  169,  171,  172,  171,  165,  165,  165,
-      176,  173,  177,  168,  174,  174,  175,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  171,  165,  165,
-      176,  177,  165,  165,  165,  165,  165,  165,  165,  165,
-
-      165,  165,  165,  165,  171,  165,  165,  165,  165,  165,
-      165,  165,  165,  178,  165,  171,  165,  165,  165,  165,
-      165,  165,  165,  178,  165,  178,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  179,  165,  165,
-      165,  179,  165,  179,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,    0,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165
-    } ;
-
-static yyconst flex_uint16_t yy_nxt[449] =
-    {   0,
-       10,   11,   12,   11,   13,   14,   10,   15,   16,   10,
-       10,   10,   17,   10,   10,   10,   10,   18,   19,   20,
-       21,   21,   21,   21,   21,   10,   10,   21,   21,   21,
-       21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
-       21,   21,   21,   21,   10,   22,   10,   24,   25,   25,
-       25,   32,   33,   33,  164,   26,   34,   34,   34,   52,
-       53,   27,   26,   26,   26,   26,   10,   11,   12,   11,
-       13,   14,   28,   15,   16,   28,   28,   28,   24,   28,
-       28,   28,   10,   18,   19,   20,   29,   29,   29,   29,
-       29,   30,   10,   29,   29,   29,   29,   29,   29,   29,
-
-       29,   29,   29,   29,   29,   29,   29,   29,   29,   29,
-       10,   22,   10,   23,   34,   34,   34,   37,   39,   43,
-       32,   33,   33,   45,   55,   56,   46,   60,   43,   45,
-       65,  163,   46,   65,   65,   65,   44,   38,   60,   74,
-       58,   47,  141,   48,  142,   44,   49,   47,   50,   48,
-       76,   51,   62,   94,   50,   41,   44,   51,   37,   61,
-       64,   64,   64,   58,   34,   34,   34,   64,  162,   80,
-       67,   68,   68,   68,   64,   64,   64,   64,   38,   81,
-       69,   70,   71,   68,   68,   68,   60,  161,   43,   69,
-       70,   65,   69,   70,   65,   65,   65,  125,   85,   85,
-
-       85,   58,   68,   68,   68,   44,  102,  110,  125,  133,
-      102,   69,   70,  111,  114,  160,  159,  126,   85,   85,
-       85,  140,  140,  140,  140,  140,  140,  153,  126,  147,
-      147,  147,  153,  148,  147,  147,  147,  158,  148,  165,
-      157,  156,  155,  151,  150,  149,  146,  154,  145,  144,
-      143,  139,  154,   36,   36,   36,   36,   36,   36,   36,
-       36,   40,  138,  137,  136,   40,   40,   42,   42,   42,
-       42,   42,   42,   42,   42,   57,   57,   57,   57,   63,
-      135,   63,   65,  134,  165,   65,  133,   65,   65,   66,
-      132,  131,   66,   66,   66,   66,   72,  130,   72,   72,
-
-       75,   75,   75,   75,   75,   75,   75,   75,   77,   77,
-       77,   77,   77,   77,   77,   77,   91,  129,   91,   92,
-      128,   92,   92,  127,   92,   92,  124,  124,  124,  124,
-      124,  124,  124,  124,  152,  152,  152,  152,  152,  152,
-      152,  152,   60,   60,  123,  122,  121,  120,  119,  118,
-      117,   45,  116,  111,  115,  113,  112,  109,  108,  107,
-       46,  106,   93,   89,  105,  104,  103,  101,  100,   99,
-       98,   97,   96,   95,   78,   76,   93,   90,   89,   88,
-       58,   87,   86,   58,   84,   83,   82,   79,   78,   76,
-       73,  165,   59,   58,   54,   35,  165,   31,   23,   23,
-
-        9,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165
-    } ;
-
-static yyconst flex_int16_t yy_chk[449] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    3,    3,    3,
-        3,    7,    7,    7,  163,    3,   11,   11,   11,   18,
-       18,    3,    3,    3,    3,    3,    5,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    8,   12,   12,   12,   14,   15,   16,
-        8,    8,    8,   17,   20,   20,   17,   23,   42,   24,
-       29,  162,   24,   29,   29,   29,   16,   14,   31,   44,
-       29,   17,  134,   17,  134,   42,   17,   24,   17,   24,
-       76,   17,   24,   76,   24,   15,   44,   24,   36,   23,
-       26,   26,   26,   26,   34,   34,   34,   26,  161,   48,
-       31,   32,   32,   32,   26,   26,   26,   26,   36,   48,
-       32,   32,   32,   33,   33,   33,   60,  160,   74,   91,
-       91,   66,   33,   33,   66,   66,   66,  114,   60,   60,
-
-       60,   66,   68,   68,   68,   74,   85,   99,  124,  133,
-      102,   68,   68,   99,  102,  157,  156,  114,   85,   85,
-       85,  133,  133,  133,  140,  140,  140,  148,  124,  143,
-      143,  143,  152,  143,  147,  147,  147,  155,  147,  154,
-      151,  150,  149,  146,  145,  144,  142,  148,  141,  138,
-      137,  132,  152,  166,  166,  166,  166,  166,  166,  166,
-      166,  167,  131,  130,  129,  167,  167,  168,  168,  168,
-      168,  168,  168,  168,  168,  169,  169,  169,  169,  170,
-      128,  170,  171,  127,  126,  171,  125,  171,  171,  172,
-      123,  122,  172,  172,  172,  172,  173,  121,  173,  173,
-
-      174,  174,  174,  174,  174,  174,  174,  174,  175,  175,
-      175,  175,  175,  175,  175,  175,  176,  120,  176,  177,
-      119,  177,  177,  118,  177,  177,  178,  178,  178,  178,
-      178,  178,  178,  178,  179,  179,  179,  179,  179,  179,
-      179,  179,  116,  115,  113,  112,  111,  110,  109,  108,
-      107,  106,  105,  104,  103,  101,  100,   98,   97,   96,
-       95,   94,   92,   90,   88,   87,   86,   84,   83,   82,
-       81,   80,   79,   78,   77,   75,   73,   70,   69,   67,
-       64,   62,   61,   57,   51,   50,   49,   47,   46,   45,
-       41,   38,   22,   21,   19,   13,    9,    6,    4,    2,
-
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165
-    } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "dtc-lexer.l"
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute 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 YY_NO_INPUT 1
-
-
-
-#line 37 "dtc-lexer.l"
-#include "dtc.h"
-#include "srcpos.h"
-#include "dtc-parser.tab.h"
-
-YYLTYPE yylloc;
-extern bool treesource_error;
-
-/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
-#define	YY_USER_ACTION \
-	{ \
-		srcpos_update(&yylloc, yytext, yyleng); \
-	}
-
-/*#define LEXDEBUG	1*/
-
-#ifdef LEXDEBUG
-#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
-#else
-#define DPRINT(fmt, ...)	do { } while (0)
-#endif
-
-static int dts_version = 1;
-
-#define BEGIN_DEFAULT()		DPRINT("<V1>\n"); \
-				BEGIN(V1); \
-
-static void push_input_file(const char *filename);
-static bool pop_input_file(void);
-static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
-
-#line 661 "dtc-lexer.lex.c"
-
-#define INITIAL 0
-#define BYTESTRING 1
-#define PROPNODENAME 2
-#define V1 3
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int yylex_destroy (void );
-
-int yyget_debug (void );
-
-void yyset_debug (int debug_flag  );
-
-YY_EXTRA_TYPE yyget_extra (void );
-
-void yyset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *yyget_in (void );
-
-void yyset_in  (FILE * _in_str  );
-
-FILE *yyget_out (void );
-
-void yyset_out  (FILE * _out_str  );
-
-			int yyget_leng (void );
-
-char *yyget_text (void );
-
-int yyget_lineno (void );
-
-void yyset_lineno (int _line_number  );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap (void );
-#else
-extern int yywrap (void );
-#endif
-#endif
-
-#ifndef YY_NO_UNPUT
-    
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-		{ \
-		int c = '*'; \
-		size_t n; \
-		for ( n = 0; n < max_size && \
-			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
-			buf[n] = (char) c; \
-		if ( c == '\n' ) \
-			buf[n++] = (char) c; \
-		if ( c == EOF && ferror( yyin ) ) \
-			YY_FATAL_ERROR( "input in flex scanner failed" ); \
-		result = n; \
-		} \
-	else \
-		{ \
-		errno=0; \
-		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-			{ \
-			if( errno != EINTR) \
-				{ \
-				YY_FATAL_ERROR( "input in flex scanner failed" ); \
-				break; \
-				} \
-			errno=0; \
-			clearerr(yyin); \
-			} \
-		}\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK /*LINTED*/break;
-#endif
-
-#define YY_RULE_SETUP \
-	if ( yyleng > 0 ) \
-		YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
-				(yytext[yyleng - 1] == '\n'); \
-	YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
-	yy_state_type yy_current_state;
-	char *yy_cp, *yy_bp;
-	int yy_act;
-    
-	if ( !(yy_init) )
-		{
-		(yy_init) = 1;
-
-#ifdef YY_USER_INIT
-		YY_USER_INIT;
-#endif
-
-		if ( ! (yy_start) )
-			(yy_start) = 1;	/* first start state */
-
-		if ( ! yyin )
-			yyin = stdin;
-
-		if ( ! yyout )
-			yyout = stdout;
-
-		if ( ! YY_CURRENT_BUFFER ) {
-			yyensure_buffer_stack ();
-			YY_CURRENT_BUFFER_LVALUE =
-				yy_create_buffer(yyin,YY_BUF_SIZE );
-		}
-
-		yy_load_buffer_state( );
-		}
-
-	{
-#line 69 "dtc-lexer.l"
-
-#line 885 "dtc-lexer.lex.c"
-
-	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
-		{
-		yy_cp = (yy_c_buf_p);
-
-		/* Support of yytext. */
-		*yy_cp = (yy_hold_char);
-
-		/* yy_bp points to the position in yy_ch_buf of the start of
-		 * the current run.
-		 */
-		yy_bp = yy_cp;
-
-		yy_current_state = (yy_start);
-		yy_current_state += YY_AT_BOL();
-yy_match:
-		do
-			{
-			YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
-			if ( yy_accept[yy_current_state] )
-				{
-				(yy_last_accepting_state) = yy_current_state;
-				(yy_last_accepting_cpos) = yy_cp;
-				}
-			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-				{
-				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 166 )
-					yy_c = yy_meta[(unsigned int) yy_c];
-				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
-			++yy_cp;
-			}
-		while ( yy_current_state != 165 );
-		yy_cp = (yy_last_accepting_cpos);
-		yy_current_state = (yy_last_accepting_state);
-
-yy_find_action:
-		yy_act = yy_accept[yy_current_state];
-
-		YY_DO_BEFORE_ACTION;
-
-do_action:	/* This label is used only to access EOF actions. */
-
-		switch ( yy_act )
-	{ /* beginning of action switch */
-			case 0: /* must back up */
-			/* undo the effects of YY_DO_BEFORE_ACTION */
-			*yy_cp = (yy_hold_char);
-			yy_cp = (yy_last_accepting_cpos);
-			yy_current_state = (yy_last_accepting_state);
-			goto yy_find_action;
-
-case 1:
-/* rule 1 can match eol */
-YY_RULE_SETUP
-#line 70 "dtc-lexer.l"
-{
-			char *name = strchr(yytext, '\"') + 1;
-			yytext[yyleng-1] = '\0';
-			push_input_file(name);
-		}
-	YY_BREAK
-case 2:
-/* rule 2 can match eol */
-YY_RULE_SETUP
-#line 76 "dtc-lexer.l"
-{
-			char *line, *fnstart, *fnend;
-			struct data fn;
-			/* skip text before line # */
-			line = yytext;
-			while (!isdigit((unsigned char)*line))
-				line++;
-
-			/* regexp ensures that first and list "
-			 * in the whole yytext are those at
-			 * beginning and end of the filename string */
-			fnstart = memchr(yytext, '"', yyleng);
-			for (fnend = yytext + yyleng - 1;
-			     *fnend != '"'; fnend--)
-				;
-			assert(fnstart && fnend && (fnend > fnstart));
-
-			fn = data_copy_escape_string(fnstart + 1,
-						     fnend - fnstart - 1);
-
-			/* Don't allow nuls in filenames */
-			if (memchr(fn.val, '\0', fn.len - 1))
-				lexical_error("nul in line number directive");
-
-			/* -1 since #line is the number of the next line */
-			srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
-			data_free(fn);
-		}
-	YY_BREAK
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(BYTESTRING):
-case YY_STATE_EOF(PROPNODENAME):
-case YY_STATE_EOF(V1):
-#line 105 "dtc-lexer.l"
-{
-			if (!pop_input_file()) {
-				yyterminate();
-			}
-		}
-	YY_BREAK
-case 3:
-/* rule 3 can match eol */
-YY_RULE_SETUP
-#line 111 "dtc-lexer.l"
-{
-			DPRINT("String: %s\n", yytext);
-			yylval.data = data_copy_escape_string(yytext+1,
-					yyleng-2);
-			return DT_STRING;
-		}
-	YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 118 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /dts-v1/\n");
-			dts_version = 1;
-			BEGIN_DEFAULT();
-			return DT_V1;
-		}
-	YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 125 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /plugin/\n");
-			return DT_PLUGIN;
-		}
-	YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 130 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /memreserve/\n");
-			BEGIN_DEFAULT();
-			return DT_MEMRESERVE;
-		}
-	YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 136 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /bits/\n");
-			BEGIN_DEFAULT();
-			return DT_BITS;
-		}
-	YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 142 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /delete-property/\n");
-			DPRINT("<PROPNODENAME>\n");
-			BEGIN(PROPNODENAME);
-			return DT_DEL_PROP;
-		}
-	YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 149 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /delete-node/\n");
-			DPRINT("<PROPNODENAME>\n");
-			BEGIN(PROPNODENAME);
-			return DT_DEL_NODE;
-		}
-	YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 156 "dtc-lexer.l"
-{
-			DPRINT("Label: %s\n", yytext);
-			yylval.labelref = xstrdup(yytext);
-			yylval.labelref[yyleng-1] = '\0';
-			return DT_LABEL;
-		}
-	YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 163 "dtc-lexer.l"
-{
-			char *e;
-			DPRINT("Integer Literal: '%s'\n", yytext);
-
-			errno = 0;
-			yylval.integer = strtoull(yytext, &e, 0);
-
-			if (*e && e[strspn(e, "UL")]) {
-				lexical_error("Bad integer literal '%s'",
-					      yytext);
-			}
-
-			if (errno == ERANGE)
-				lexical_error("Integer literal '%s' out of range",
-					      yytext);
-			else
-				/* ERANGE is the only strtoull error triggerable
-				 *  by strings matching the pattern */
-				assert(errno == 0);
-			return DT_LITERAL;
-		}
-	YY_BREAK
-case 12:
-/* rule 12 can match eol */
-YY_RULE_SETUP
-#line 185 "dtc-lexer.l"
-{
-			struct data d;
-			DPRINT("Character literal: %s\n", yytext);
-
-			d = data_copy_escape_string(yytext+1, yyleng-2);
-			if (d.len == 1) {
-				lexical_error("Empty character literal");
-				yylval.integer = 0;
-			} else {
-				yylval.integer = (unsigned char)d.val[0];
-
-				if (d.len > 2)
-					lexical_error("Character literal has %d"
-						      " characters instead of 1",
-						      d.len - 1);
-			}
-
-			data_free(d);
-			return DT_CHAR_LITERAL;
-		}
-	YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 206 "dtc-lexer.l"
-{	/* label reference */
-			DPRINT("Ref: %s\n", yytext+1);
-			yylval.labelref = xstrdup(yytext+1);
-			return DT_REF;
-		}
-	YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 212 "dtc-lexer.l"
-{	/* new-style path reference */
-			yytext[yyleng-1] = '\0';
-			DPRINT("Ref: %s\n", yytext+2);
-			yylval.labelref = xstrdup(yytext+2);
-			return DT_REF;
-		}
-	YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 219 "dtc-lexer.l"
-{
-			yylval.byte = strtol(yytext, NULL, 16);
-			DPRINT("Byte: %02x\n", (int)yylval.byte);
-			return DT_BYTE;
-		}
-	YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 225 "dtc-lexer.l"
-{
-			DPRINT("/BYTESTRING\n");
-			BEGIN_DEFAULT();
-			return ']';
-		}
-	YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 231 "dtc-lexer.l"
-{
-			DPRINT("PropNodeName: %s\n", yytext);
-			yylval.propnodename = xstrdup((yytext[0] == '\\') ?
-							yytext + 1 : yytext);
-			BEGIN_DEFAULT();
-			return DT_PROPNODENAME;
-		}
-	YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 239 "dtc-lexer.l"
-{
-			DPRINT("Binary Include\n");
-			return DT_INCBIN;
-		}
-	YY_BREAK
-case 19:
-/* rule 19 can match eol */
-YY_RULE_SETUP
-#line 244 "dtc-lexer.l"
-/* eat whitespace */
-	YY_BREAK
-case 20:
-/* rule 20 can match eol */
-YY_RULE_SETUP
-#line 245 "dtc-lexer.l"
-/* eat C-style comments */
-	YY_BREAK
-case 21:
-/* rule 21 can match eol */
-YY_RULE_SETUP
-#line 246 "dtc-lexer.l"
-/* eat C++-style comments */
-	YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 248 "dtc-lexer.l"
-{ return DT_LSHIFT; };
-	YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 249 "dtc-lexer.l"
-{ return DT_RSHIFT; };
-	YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 250 "dtc-lexer.l"
-{ return DT_LE; };
-	YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 251 "dtc-lexer.l"
-{ return DT_GE; };
-	YY_BREAK
-case 26:
-YY_RULE_SETUP
-#line 252 "dtc-lexer.l"
-{ return DT_EQ; };
-	YY_BREAK
-case 27:
-YY_RULE_SETUP
-#line 253 "dtc-lexer.l"
-{ return DT_NE; };
-	YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 254 "dtc-lexer.l"
-{ return DT_AND; };
-	YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 255 "dtc-lexer.l"
-{ return DT_OR; };
-	YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 257 "dtc-lexer.l"
-{
-			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
-				(unsigned)yytext[0]);
-			if (yytext[0] == '[') {
-				DPRINT("<BYTESTRING>\n");
-				BEGIN(BYTESTRING);
-			}
-			if ((yytext[0] == '{')
-			    || (yytext[0] == ';')) {
-				DPRINT("<PROPNODENAME>\n");
-				BEGIN(PROPNODENAME);
-			}
-			return yytext[0];
-		}
-	YY_BREAK
-case 31:
-YY_RULE_SETUP
-#line 272 "dtc-lexer.l"
-ECHO;
-	YY_BREAK
-#line 1257 "dtc-lexer.lex.c"
-
-	case YY_END_OF_BUFFER:
-		{
-		/* Amount of text matched not including the EOB char. */
-		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
-		/* Undo the effects of YY_DO_BEFORE_ACTION. */
-		*yy_cp = (yy_hold_char);
-		YY_RESTORE_YY_MORE_OFFSET
-
-		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-			{
-			/* We're scanning a new file or input source.  It's
-			 * possible that this happened because the user
-			 * just pointed yyin at a new source and called
-			 * yylex().  If so, then we have to assure
-			 * consistency between YY_CURRENT_BUFFER and our
-			 * globals.  Here is the right place to do so, because
-			 * this is the first action (other than possibly a
-			 * back-up) that will match for the new input source.
-			 */
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-			}
-
-		/* Note that here we test for yy_c_buf_p "<=" to the position
-		 * of the first EOB in the buffer, since yy_c_buf_p will
-		 * already have been incremented past the NUL character
-		 * (since all states make transitions on EOB to the
-		 * end-of-buffer state).  Contrast this with the test
-		 * in input().
-		 */
-		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			{ /* This was really a NUL. */
-			yy_state_type yy_next_state;
-
-			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
-			yy_current_state = yy_get_previous_state(  );
-
-			/* Okay, we're now positioned to make the NUL
-			 * transition.  We couldn't have
-			 * yy_get_previous_state() go ahead and do it
-			 * for us because it doesn't know how to deal
-			 * with the possibility of jamming (and we don't
-			 * want to build jamming into it because then it
-			 * will run more slowly).
-			 */
-
-			yy_next_state = yy_try_NUL_trans( yy_current_state );
-
-			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
-			if ( yy_next_state )
-				{
-				/* Consume the NUL. */
-				yy_cp = ++(yy_c_buf_p);
-				yy_current_state = yy_next_state;
-				goto yy_match;
-				}
-
-			else
-				{
-				yy_cp = (yy_last_accepting_cpos);
-				yy_current_state = (yy_last_accepting_state);
-				goto yy_find_action;
-				}
-			}
-
-		else switch ( yy_get_next_buffer(  ) )
-			{
-			case EOB_ACT_END_OF_FILE:
-				{
-				(yy_did_buffer_switch_on_eof) = 0;
-
-				if ( yywrap( ) )
-					{
-					/* Note: because we've taken care in
-					 * yy_get_next_buffer() to have set up
-					 * yytext, we can now set up
-					 * yy_c_buf_p so that if some total
-					 * hoser (like flex itself) wants to
-					 * call the scanner after we return the
-					 * YY_NULL, it'll still work - another
-					 * YY_NULL will get returned.
-					 */
-					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
-					yy_act = YY_STATE_EOF(YY_START);
-					goto do_action;
-					}
-
-				else
-					{
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-					}
-				break;
-				}
-
-			case EOB_ACT_CONTINUE_SCAN:
-				(yy_c_buf_p) =
-					(yytext_ptr) + yy_amount_of_matched_text;
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_match;
-
-			case EOB_ACT_LAST_MATCH:
-				(yy_c_buf_p) =
-				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_find_action;
-			}
-		break;
-		}
-
-	default:
-		YY_FATAL_ERROR(
-			"fatal flex scanner internal error--no action found" );
-	} /* end of action switch */
-		} /* end of scanning one token */
-	} /* end of user's declarations */
-} /* end of yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *	EOB_ACT_LAST_MATCH -
- *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *	EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
-    	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-	char *source = (yytext_ptr);
-	int number_to_move, i;
-	int ret_val;
-
-	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
-		YY_FATAL_ERROR(
-		"fatal flex scanner internal error--end of buffer missed" );
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
-		{ /* Don't try to fill the buffer, so this is an EOF. */
-		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
-			{
-			/* We matched a single character, the EOB, so
-			 * treat this as a final EOF.
-			 */
-			return EOB_ACT_END_OF_FILE;
-			}
-
-		else
-			{
-			/* We matched some text prior to the EOB, first
-			 * process it.
-			 */
-			return EOB_ACT_LAST_MATCH;
-			}
-		}
-
-	/* Try to read more data. */
-
-	/* First move last chars to start of buffer. */
-	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
-
-	for ( i = 0; i < number_to_move; ++i )
-		*(dest++) = *(source++);
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-		/* don't do the read, it's not guaranteed to return an EOF,
-		 * just force an EOF
-		 */
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
-	else
-		{
-			int num_to_read =
-			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
-		while ( num_to_read <= 0 )
-			{ /* Not enough room in the buffer - grow it. */
-
-			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
-
-			int yy_c_buf_p_offset =
-				(int) ((yy_c_buf_p) - b->yy_ch_buf);
-
-			if ( b->yy_is_our_buffer )
-				{
-				int new_size = b->yy_buf_size * 2;
-
-				if ( new_size <= 0 )
-					b->yy_buf_size += b->yy_buf_size / 8;
-				else
-					b->yy_buf_size *= 2;
-
-				b->yy_ch_buf = (char *)
-					/* Include room in for 2 EOB chars. */
-					yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
-				}
-			else
-				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = NULL;
-
-			if ( ! b->yy_ch_buf )
-				YY_FATAL_ERROR(
-				"fatal error - scanner input buffer overflow" );
-
-			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-						number_to_move - 1;
-
-			}
-
-		if ( num_to_read > YY_READ_BUF_SIZE )
-			num_to_read = YY_READ_BUF_SIZE;
-
-		/* Read in more data. */
-		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), num_to_read );
-
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	if ( (yy_n_chars) == 0 )
-		{
-		if ( number_to_move == YY_MORE_ADJ )
-			{
-			ret_val = EOB_ACT_END_OF_FILE;
-			yyrestart(yyin  );
-			}
-
-		else
-			{
-			ret_val = EOB_ACT_LAST_MATCH;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
-				YY_BUFFER_EOF_PENDING;
-			}
-		}
-
-	else
-		ret_val = EOB_ACT_CONTINUE_SCAN;
-
-	if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
-		/* Extend the array by 50%, plus the number we really need. */
-		int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
-		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
-	}
-
-	(yy_n_chars) += number_to_move;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
-	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
-	return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-    static yy_state_type yy_get_previous_state (void)
-{
-	yy_state_type yy_current_state;
-	char *yy_cp;
-    
-	yy_current_state = (yy_start);
-	yy_current_state += YY_AT_BOL();
-
-	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
-		{
-		YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
-		if ( yy_accept[yy_current_state] )
-			{
-			(yy_last_accepting_state) = yy_current_state;
-			(yy_last_accepting_cpos) = yy_cp;
-			}
-		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-			{
-			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 166 )
-				yy_c = yy_meta[(unsigned int) yy_c];
-			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
-		}
-
-	return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *	next_state = yy_try_NUL_trans( current_state );
- */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
-	int yy_is_jam;
-    	char *yy_cp = (yy_c_buf_p);
-
-	YY_CHAR yy_c = 1;
-	if ( yy_accept[yy_current_state] )
-		{
-		(yy_last_accepting_state) = yy_current_state;
-		(yy_last_accepting_cpos) = yy_cp;
-		}
-	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-		{
-		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 166 )
-			yy_c = yy_meta[(unsigned int) yy_c];
-		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
-	yy_is_jam = (yy_current_state == 165);
-
-		return yy_is_jam ? 0 : yy_current_state;
-}
-
-#ifndef YY_NO_UNPUT
-
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
-
-{
-	int c;
-    
-	*(yy_c_buf_p) = (yy_hold_char);
-
-	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
-		{
-		/* yy_c_buf_p now points to the character we want to return.
-		 * If this occurs *before* the EOB characters, then it's a
-		 * valid NUL; if not, then we've hit the end of the buffer.
-		 */
-		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			/* This was really a NUL. */
-			*(yy_c_buf_p) = '\0';
-
-		else
-			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
-			++(yy_c_buf_p);
-
-			switch ( yy_get_next_buffer(  ) )
-				{
-				case EOB_ACT_LAST_MATCH:
-					/* This happens because yy_g_n_b()
-					 * sees that we've accumulated a
-					 * token and flags that we need to
-					 * try matching the token before
-					 * proceeding.  But for input(),
-					 * there's no matching to consider.
-					 * So convert the EOB_ACT_LAST_MATCH
-					 * to EOB_ACT_END_OF_FILE.
-					 */
-
-					/* Reset buffer status. */
-					yyrestart(yyin );
-
-					/*FALLTHROUGH*/
-
-				case EOB_ACT_END_OF_FILE:
-					{
-					if ( yywrap( ) )
-						return 0;
-
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-#ifdef __cplusplus
-					return yyinput();
-#else
-					return input();
-#endif
-					}
-
-				case EOB_ACT_CONTINUE_SCAN:
-					(yy_c_buf_p) = (yytext_ptr) + offset;
-					break;
-				}
-			}
-		}
-
-	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve yytext */
-	(yy_hold_char) = *++(yy_c_buf_p);
-
-	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
-
-	return c;
-}
-#endif	/* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file )
-{
-    
-	if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack ();
-		YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE );
-	}
-
-	yy_init_buffer(YY_CURRENT_BUFFER,input_file );
-	yy_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-	/* TODO. We should be able to replace this entire function body
-	 * with
-	 *		yypop_buffer_state();
-	 *		yypush_buffer_state(new_buffer);
-     */
-	yyensure_buffer_stack ();
-	if ( YY_CURRENT_BUFFER == new_buffer )
-		return;
-
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	yy_load_buffer_state( );
-
-	/* We don't actually know whether we did this switch during
-	 * EOF (yywrap()) processing, but the only time this flag
-	 * is looked at is after yywrap() is called, so it's safe
-	 * to go ahead and always set it.
-	 */
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void yy_load_buffer_state  (void)
-{
-    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-	(yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
-{
-	YY_BUFFER_STATE b;
-    
-	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-	b->yy_buf_size = (yy_size_t)size;
-
-	/* yy_ch_buf has to be 2 characters longer than the size given because
-	 * we need to put in 2 end-of-buffer characters.
-	 */
-	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
-	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-	b->yy_is_our_buffer = 1;
-
-	yy_init_buffer(b,file );
-
-	return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * 
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
-	if ( ! b )
-		return;
-
-	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
-	if ( b->yy_is_our_buffer )
-		yyfree((void *) b->yy_ch_buf  );
-
-	yyfree((void *) b  );
-}
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
-
-{
-	int oerrno = errno;
-    
-	yy_flush_buffer(b );
-
-	b->yy_input_file = file;
-	b->yy_fill_buffer = 1;
-
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = 0;
-    
-	errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b )
-{
-    	if ( ! b )
-		return;
-
-	b->yy_n_chars = 0;
-
-	/* We always need two end-of-buffer characters.  The first causes
-	 * a transition to the end-of-buffer state.  The second causes
-	 * a jam in that state.
-	 */
-	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-	b->yy_buf_pos = &b->yy_ch_buf[0];
-
-	b->yy_at_bol = 1;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	if ( b == YY_CURRENT_BUFFER )
-		yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-    	if (new_buffer == NULL)
-		return;
-
-	yyensure_buffer_stack();
-
-	/* This block is copied from yy_switch_to_buffer. */
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	/* Only push if top exists. Otherwise, replace top. */
-	if (YY_CURRENT_BUFFER)
-		(yy_buffer_stack_top)++;
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-	/* copied from yy_switch_to_buffer. */
-	yy_load_buffer_state( );
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void yypop_buffer_state (void)
-{
-    	if (!YY_CURRENT_BUFFER)
-		return;
-
-	yy_delete_buffer(YY_CURRENT_BUFFER );
-	YY_CURRENT_BUFFER_LVALUE = NULL;
-	if ((yy_buffer_stack_top) > 0)
-		--(yy_buffer_stack_top);
-
-	if (YY_CURRENT_BUFFER) {
-		yy_load_buffer_state( );
-		(yy_did_buffer_switch_on_eof) = 1;
-	}
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
-	int num_to_alloc;
-    
-	if (!(yy_buffer_stack)) {
-
-		/* First allocation is just for 2 elements, since we don't know if this
-		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
-		 * immediate realloc on the next call.
-         */
-      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
-		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
-								(num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
-		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
-		(yy_buffer_stack_max) = num_to_alloc;
-		(yy_buffer_stack_top) = 0;
-		return;
-	}
-
-	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
-		/* Increase the buffer to prepare for a possible push. */
-		yy_size_t grow_size = 8 /* arbitrary grow size */;
-
-		num_to_alloc = (yy_buffer_stack_max) + grow_size;
-		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
-								((yy_buffer_stack),
-								num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
-		/* zero only the new slots.*/
-		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-		(yy_buffer_stack_max) = num_to_alloc;
-	}
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
-{
-	YY_BUFFER_STATE b;
-    
-	if ( size < 2 ||
-	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
-	     base[size-1] != YY_END_OF_BUFFER_CHAR )
-		/* They forgot to leave room for the EOB's. */
-		return NULL;
-
-	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
-	b->yy_buf_pos = b->yy_ch_buf = base;
-	b->yy_is_our_buffer = 0;
-	b->yy_input_file = NULL;
-	b->yy_n_chars = b->yy_buf_size;
-	b->yy_is_interactive = 0;
-	b->yy_at_bol = 1;
-	b->yy_fill_buffer = 0;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	yy_switch_to_buffer(b  );
-
-	return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
-{
-    
-	return yy_scan_bytes(yystr,(int) strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
-{
-	YY_BUFFER_STATE b;
-	char *buf;
-	yy_size_t n;
-	int i;
-    
-	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = (yy_size_t) (_yybytes_len + 2);
-	buf = (char *) yyalloc(n  );
-	if ( ! buf )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
-	for ( i = 0; i < _yybytes_len; ++i )
-		buf[i] = yybytes[i];
-
-	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
-	b = yy_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
-
-	return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yynoreturn yy_fatal_error (yyconst char* msg )
-{
-			(void) fprintf( stderr, "%s\n", msg );
-	exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		yytext[yyleng] = (yy_hold_char); \
-		(yy_c_buf_p) = yytext + yyless_macro_arg; \
-		(yy_hold_char) = *(yy_c_buf_p); \
-		*(yy_c_buf_p) = '\0'; \
-		yyleng = yyless_macro_arg; \
-		} \
-	while ( 0 )
-
-/* Accessor  methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- * 
- */
-int yyget_lineno  (void)
-{
-    
-    return yylineno;
-}
-
-/** Get the input stream.
- * 
- */
-FILE *yyget_in  (void)
-{
-        return yyin;
-}
-
-/** Get the output stream.
- * 
- */
-FILE *yyget_out  (void)
-{
-        return yyout;
-}
-
-/** Get the length of the current token.
- * 
- */
-int yyget_leng  (void)
-{
-        return yyleng;
-}
-
-/** Get the current token.
- * 
- */
-
-char *yyget_text  (void)
-{
-        return yytext;
-}
-
-/** Set the current line number.
- * @param _line_number line number
- * 
- */
-void yyset_lineno (int  _line_number )
-{
-    
-    yylineno = _line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param _in_str A readable stream.
- * 
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  _in_str )
-{
-        yyin = _in_str ;
-}
-
-void yyset_out (FILE *  _out_str )
-{
-        yyout = _out_str ;
-}
-
-int yyget_debug  (void)
-{
-        return yy_flex_debug;
-}
-
-void yyset_debug (int  _bdebug )
-{
-        yy_flex_debug = _bdebug ;
-}
-
-static int yy_init_globals (void)
-{
-        /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from yylex_destroy(), so don't allocate here.
-     */
-
-    (yy_buffer_stack) = NULL;
-    (yy_buffer_stack_top) = 0;
-    (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = NULL;
-    (yy_init) = 0;
-    (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    yyin = stdin;
-    yyout = stdout;
-#else
-    yyin = NULL;
-    yyout = NULL;
-#endif
-
-    /* For future reference: Set errno on error, since we are called by
-     * yylex_init()
-     */
-    return 0;
-}
-
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-	while(YY_CURRENT_BUFFER){
-		yy_delete_buffer(YY_CURRENT_BUFFER  );
-		YY_CURRENT_BUFFER_LVALUE = NULL;
-		yypop_buffer_state();
-	}
-
-	/* Destroy the stack itself. */
-	yyfree((yy_buffer_stack) );
-	(yy_buffer_stack) = NULL;
-
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * yylex() is called, initialization will occur. */
-    yy_init_globals( );
-
-    return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
-		
-	int i;
-	for ( i = 0; i < n; ++i )
-		s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
-	int n;
-	for ( n = 0; s[n]; ++n )
-		;
-
-	return n;
-}
-#endif
-
-void *yyalloc (yy_size_t  size )
-{
-			return malloc(size);
-}
-
-void *yyrealloc  (void * ptr, yy_size_t  size )
-{
-		
-	/* The cast to (char *) in the following accommodates both
-	 * implementations that use char* generic pointers, and those
-	 * that use void* generic pointers.  It works with the latter
-	 * because both ANSI C and C++ allow castless assignment from
-	 * any pointer type to void*, and deal with argument conversions
-	 * as though doing an assignment.
-	 */
-	return realloc(ptr, size);
-}
-
-void yyfree (void * ptr )
-{
-			free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 272 "dtc-lexer.l"
-
-
-
-static void push_input_file(const char *filename)
-{
-	assert(filename);
-
-	srcfile_push(filename);
-
-	yyin = current_srcfile->f;
-
-	yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
-}
-
-
-static bool pop_input_file(void)
-{
-	if (srcfile_pop() == 0)
-		return false;
-
-	yypop_buffer_state();
-	yyin = current_srcfile->f;
-
-	return true;
-}
-
-static void lexical_error(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	srcpos_verror(&yylloc, "Lexical error", fmt, ap);
-	va_end(ap);
-
-	treesource_error = true;
-}
-
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
deleted file mode 100644
index aea514f..0000000
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ /dev/null
@@ -1,2321 +0,0 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
-
-/* Bison implementation for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, 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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
-   simplifying the original so-called "semantic" parser.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-/* Identify Bison output.  */
-#define YYBISON 1
-
-/* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
-
-/* Skeleton name.  */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers.  */
-#define YYPURE 0
-
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
-
-
-
-/* Copy the first part of user declarations.  */
-#line 20 "dtc-parser.y" /* yacc.c:339  */
-
-#include <stdio.h>
-#include <inttypes.h>
-
-#include "dtc.h"
-#include "srcpos.h"
-
-extern int yylex(void);
-extern void yyerror(char const *s);
-#define ERROR(loc, ...) \
-	do { \
-		srcpos_error((loc), "Error", __VA_ARGS__); \
-		treesource_error = true; \
-	} while (0)
-
-extern struct dt_info *parser_output;
-extern bool treesource_error;
-
-#line 85 "dtc-parser.tab.c" /* yacc.c:339  */
-
-# ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
-#  else
-#   define YY_NULLPTR 0
-#  endif
-# endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* In a future release of Bison, this section will be replaced
-   by #include "dtc-parser.tab.h".  */
-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-/* Token type.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-  enum yytokentype
-  {
-    DT_V1 = 258,
-    DT_PLUGIN = 259,
-    DT_MEMRESERVE = 260,
-    DT_LSHIFT = 261,
-    DT_RSHIFT = 262,
-    DT_LE = 263,
-    DT_GE = 264,
-    DT_EQ = 265,
-    DT_NE = 266,
-    DT_AND = 267,
-    DT_OR = 268,
-    DT_BITS = 269,
-    DT_DEL_PROP = 270,
-    DT_DEL_NODE = 271,
-    DT_PROPNODENAME = 272,
-    DT_LITERAL = 273,
-    DT_CHAR_LITERAL = 274,
-    DT_BYTE = 275,
-    DT_STRING = 276,
-    DT_LABEL = 277,
-    DT_REF = 278,
-    DT_INCBIN = 279
-  };
-#endif
-
-/* Value type.  */
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
-union YYSTYPE
-{
-#line 39 "dtc-parser.y" /* yacc.c:355  */
-
-	char *propnodename;
-	char *labelref;
-	uint8_t byte;
-	struct data data;
-
-	struct {
-		struct data	data;
-		int		bits;
-	} array;
-
-	struct property *prop;
-	struct property *proplist;
-	struct node *node;
-	struct node *nodelist;
-	struct reserve_info *re;
-	uint64_t integer;
-	unsigned int flags;
-
-#line 170 "dtc-parser.tab.c" /* yacc.c:355  */
-};
-
-typedef union YYSTYPE YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-/* Location type.  */
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE YYLTYPE;
-struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-};
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-extern YYSTYPE yylval;
-extern YYLTYPE yylloc;
-int yyparse (void);
-
-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED  */
-
-/* Copy the second part of user declarations.  */
-
-#line 201 "dtc-parser.tab.c" /* yacc.c:358  */
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#else
-typedef signed char yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-#  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# else
-#  define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
-#  if ENABLE_NLS
-#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
-#  endif
-# endif
-# ifndef YY_
-#  define YY_(Msgid) Msgid
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE
-# if (defined __GNUC__                                               \
-      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
-     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
-#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
-# else
-#  define YY_ATTRIBUTE(Spec) /* empty */
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE_PURE
-# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
-#endif
-
-#ifndef YY_ATTRIBUTE_UNUSED
-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
-#endif
-
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E.  */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(E) ((void) (E))
-#else
-# define YYUSE(E) /* empty */
-#endif
-
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
-/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
-    _Pragma ("GCC diagnostic push") \
-    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
-    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
-    _Pragma ("GCC diagnostic pop")
-#else
-# define YY_INITIAL_VALUE(Value) Value
-#endif
-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END
-#endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
-#endif
-
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
-
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   elif defined __BUILTIN_VA_ARG_INCR
-#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-#   elif defined _AIX
-#    define YYSTACK_ALLOC __alloca
-#   elif defined _MSC_VER
-#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-#    define alloca _alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
-#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's 'empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-    /* The OS might guarantee only one guard page at the bottom of the stack,
-       and a page size can be as small as 4096 bytes.  So we cannot safely
-       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
-       to allow for a few compiler-allocated temporary stack slots.  */
-#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-#  endif
-# else
-#  define YYSTACK_ALLOC YYMALLOC
-#  define YYSTACK_FREE YYFREE
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-#  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
-       && ! ((defined YYMALLOC || defined malloc) \
-             && (defined YYFREE || defined free)))
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
-#   endif
-#  endif
-#  ifndef YYMALLOC
-#   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-#  ifndef YYFREE
-#   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
-     && (! defined __cplusplus \
-         || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
-             && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-  YYLTYPE yyls_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
-      + 2 * YYSTACK_GAP_MAXIMUM)
-
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
-    do                                                                  \
-      {                                                                 \
-        YYSIZE_T yynewbytes;                                            \
-        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-        Stack = &yyptr->Stack_alloc;                                    \
-        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-        yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                 \
-    while (0)
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(Dst, Src, Count) \
-      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
-#  else
-#   define YYCOPY(Dst, Src, Count)              \
-      do                                        \
-        {                                       \
-          YYSIZE_T yyi;                         \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (Dst)[yyi] = (Src)[yyi];            \
-        }                                       \
-      while (0)
-#  endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
-/* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  6
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   138
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  48
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  30
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  85
-/* YYNSTATES -- Number of states.  */
-#define YYNSTATES  149
-
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   279
-
-#define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
-static const yytype_uint8 yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    47,     2,     2,     2,    45,    41,     2,
-      33,    35,    44,    42,    34,    43,     2,    26,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    38,    25,
-      36,    29,    30,    37,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    31,     2,    32,    40,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    27,    39,    28,    46,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23,    24
-};
-
-#if YYDEBUG
-  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,   109,   109,   117,   121,   128,   129,   139,   142,   149,
-     153,   161,   165,   170,   181,   200,   213,   220,   228,   231,
-     238,   242,   246,   250,   258,   262,   266,   270,   274,   290,
-     300,   308,   311,   315,   322,   338,   343,   362,   376,   383,
-     384,   385,   392,   396,   397,   401,   402,   406,   407,   411,
-     412,   416,   417,   421,   422,   426,   427,   428,   432,   433,
-     434,   435,   436,   440,   441,   442,   446,   447,   448,   452,
-     453,   462,   471,   475,   476,   477,   478,   483,   486,   490,
-     498,   501,   505,   513,   517,   521
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || 0
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE",
-  "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND",
-  "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME",
-  "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL",
-  "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['",
-  "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'",
-  "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile",
-  "header", "headers", "memreserves", "memreserve", "devicetree",
-  "nodedef", "proplist", "propdef", "propdata", "propdataprefix",
-  "arrayprefix", "integer_prim", "integer_expr", "integer_trinary",
-  "integer_or", "integer_and", "integer_bitor", "integer_bitxor",
-  "integer_bitand", "integer_eq", "integer_rela", "integer_shift",
-  "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes",
-  "subnode", YY_NULLPTR
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
-   (internal) symbol number NUM (which must be that of a token).  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,   279,    59,    47,   123,   125,    61,
-      62,    91,    93,    40,    44,    41,    60,    63,    58,   124,
-      94,    38,    43,    45,    42,    37,   126,    33
-};
-# endif
-
-#define YYPACT_NINF -44
-
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-44)))
-
-#define YYTABLE_NINF -1
-
-#define yytable_value_is_error(Yytable_value) \
-  0
-
-  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-     STATE-NUM.  */
-static const yytype_int8 yypact[] =
-{
-      14,    27,    61,    14,     8,    18,   -44,   -44,    37,     8,
-      40,     8,    64,   -44,   -44,   -12,    37,   -44,    50,    52,
-     -44,   -44,   -12,   -12,   -12,   -44,    51,   -44,    -4,    78,
-      53,    54,    55,    17,     2,    30,    38,    -3,   -44,    66,
-     -44,   -44,    70,    72,    50,    50,   -44,   -44,   -44,   -44,
-     -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,
-     -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -44,
-       3,    73,    50,   -44,   -44,    78,    59,    53,    54,    55,
-      17,     2,     2,    30,    30,    30,    30,    38,    38,    -3,
-      -3,   -44,   -44,   -44,    82,    83,    44,     3,   -44,    74,
-       3,   -44,   -44,   -12,    76,    79,   -44,   -44,   -44,   -44,
-     -44,    80,   -44,   -44,   -44,   -44,   -44,   -10,    36,   -44,
-     -44,   -44,   -44,    85,   -44,   -44,   -44,    75,   -44,   -44,
-      21,    71,    88,    -6,   -44,   -44,   -44,   -44,   -44,    11,
-     -44,   -44,   -44,    37,   -44,    77,    37,    81,   -44
-};
-
-  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
-     Performed when YYTABLE does not specify something else to do.  Zero
-     means the default is an error.  */
-static const yytype_uint8 yydefact[] =
-{
-       0,     0,     0,     5,     7,     3,     1,     6,     0,     0,
-      16,     7,     0,    39,    40,     0,     0,    10,     0,     2,
-       8,     4,     0,     0,     0,    73,     0,    42,    43,    45,
-      47,    49,    51,    53,    55,    58,    65,    68,    72,     0,
-      18,    11,     0,     0,     0,     0,    74,    75,    76,    41,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     9,
-      80,     0,     0,    14,    12,    46,     0,    48,    50,    52,
-      54,    56,    57,    61,    62,    60,    59,    63,    64,    66,
-      67,    70,    69,    71,     0,     0,     0,     0,    19,     0,
-      80,    15,    13,     0,     0,     0,    21,    31,    83,    23,
-      85,     0,    82,    81,    44,    22,    84,     0,     0,    17,
-      30,    20,    32,     0,    24,    33,    27,     0,    77,    35,
-       0,     0,     0,     0,    38,    37,    25,    36,    34,     0,
-      78,    79,    26,     0,    29,     0,     0,     0,    28
-};
-
-  /* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
-{
-     -44,   -44,   -44,   103,    99,   104,   -44,   -43,   -44,   -21,
-     -44,   -44,   -44,    -8,    63,     9,   -44,    65,    67,    68,
-      69,    62,    26,     4,    22,    23,   -19,   -44,    20,    28
-};
-
-  /* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int16 yydefgoto[] =
-{
-      -1,     2,     3,     4,    10,    11,    19,    41,    70,    98,
-     117,   118,   130,    25,    26,    27,    28,    29,    30,    31,
-      32,    33,    34,    35,    36,    37,    38,   133,    99,   100
-};
-
-  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
-     positive, shift that token.  If negative, reduce the rule whose
-     number is the opposite.  If YYTABLE_NINF, syntax error.  */
-static const yytype_uint8 yytable[] =
-{
-      16,    73,    74,    46,    47,    48,    13,    14,    39,    50,
-      58,    59,   120,     8,   140,   121,   141,     1,    94,    95,
-      96,    15,    12,    66,   122,    97,   142,    56,    57,   102,
-       9,    22,    60,    51,    23,    24,    62,    63,    61,    13,
-      14,    67,    68,   134,   135,   143,   144,    91,    92,    93,
-     123,   136,     5,   108,    15,    13,    14,   124,   125,   126,
-     127,     6,    83,    84,    85,    86,    18,   128,    42,   106,
-      15,    40,   129,   107,    43,    44,   109,    40,    45,   112,
-      64,    65,    81,    82,    87,    88,    49,    89,    90,    21,
-      52,    69,    53,    71,    54,    72,    55,   103,   101,   104,
-     105,   115,   111,   131,   116,   119,     7,   138,   132,   139,
-      20,   146,   114,    17,    76,    75,   148,    80,     0,    77,
-     113,    78,   137,    79,     0,   110,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   145,     0,     0,   147
-};
-
-static const yytype_int16 yycheck[] =
-{
-       8,    44,    45,    22,    23,    24,    18,    19,    16,    13,
-       8,     9,    22,     5,    20,    25,    22,     3,    15,    16,
-      17,    33,     4,    26,    34,    22,    32,    10,    11,    72,
-      22,    43,    30,    37,    46,    47,     6,     7,    36,    18,
-      19,    44,    45,    22,    23,    34,    35,    66,    67,    68,
-      14,    30,    25,    96,    33,    18,    19,    21,    22,    23,
-      24,     0,    58,    59,    60,    61,    26,    31,    16,    25,
-      33,    27,    36,    29,    22,    23,    97,    27,    26,   100,
-      42,    43,    56,    57,    62,    63,    35,    64,    65,    25,
-      12,    25,    39,    23,    40,    23,    41,    38,    25,    17,
-      17,    25,    28,    18,    25,    25,     3,    36,    33,    21,
-      11,    34,   103,     9,    51,    50,    35,    55,    -1,    52,
-     100,    53,   130,    54,    -1,    97,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,   143,    -1,    -1,   146
-};
-
-  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-     symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,     3,    49,    50,    51,    25,     0,    51,     5,    22,
-      52,    53,     4,    18,    19,    33,    61,    53,    26,    54,
-      52,    25,    43,    46,    47,    61,    62,    63,    64,    65,
-      66,    67,    68,    69,    70,    71,    72,    73,    74,    61,
-      27,    55,    16,    22,    23,    26,    74,    74,    74,    35,
-      13,    37,    12,    39,    40,    41,    10,    11,     8,     9,
-      30,    36,     6,     7,    42,    43,    26,    44,    45,    25,
-      56,    23,    23,    55,    55,    65,    62,    66,    67,    68,
-      69,    70,    70,    71,    71,    71,    71,    72,    72,    73,
-      73,    74,    74,    74,    15,    16,    17,    22,    57,    76,
-      77,    25,    55,    38,    17,    17,    25,    29,    55,    57,
-      77,    28,    57,    76,    63,    25,    25,    58,    59,    25,
-      22,    25,    34,    14,    21,    22,    23,    24,    31,    36,
-      60,    18,    33,    75,    22,    23,    30,    61,    36,    21,
-      20,    22,    32,    34,    35,    61,    34,    61,    35
-};
-
-  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    48,    49,    50,    50,    51,    51,    52,    52,    53,
-      53,    54,    54,    54,    54,    54,    54,    55,    56,    56,
-      57,    57,    57,    57,    58,    58,    58,    58,    58,    58,
-      58,    59,    59,    59,    60,    60,    60,    60,    60,    61,
-      61,    61,    62,    63,    63,    64,    64,    65,    65,    66,
-      66,    67,    67,    68,    68,    69,    69,    69,    70,    70,
-      70,    70,    70,    71,    71,    71,    72,    72,    72,    73,
-      73,    73,    73,    74,    74,    74,    74,    75,    75,    75,
-      76,    76,    76,    77,    77,    77
-};
-
-  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     3,     2,     4,     1,     2,     0,     2,     4,
-       2,     2,     3,     4,     3,     4,     0,     5,     0,     2,
-       4,     2,     3,     2,     2,     3,     4,     2,     9,     5,
-       2,     0,     2,     2,     3,     1,     2,     2,     2,     1,
-       1,     3,     1,     1,     5,     1,     3,     1,     3,     1,
-       3,     1,     3,     1,     3,     1,     3,     3,     1,     3,
-       3,     3,     3,     3,     3,     1,     3,     3,     1,     3,
-       3,     3,     1,     1,     2,     2,     2,     0,     2,     2,
-       0,     2,     2,     2,     3,     2
-};
-
-
-#define yyerrok         (yyerrstatus = 0)
-#define yyclearin       (yychar = YYEMPTY)
-#define YYEMPTY         (-2)
-#define YYEOF           0
-
-#define YYACCEPT        goto yyacceptlab
-#define YYABORT         goto yyabortlab
-#define YYERROR         goto yyerrorlab
-
-
-#define YYRECOVERING()  (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
-
-/* Error token number */
-#define YYTERROR        1
-#define YYERRCODE       256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-   If N is 0, then set CURRENT to the empty location which ends
-   the previous symbol: RHS[0] (always defined).  */
-
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)                                \
-    do                                                                  \
-      if (N)                                                            \
-        {                                                               \
-          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
-          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
-          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
-          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
-        }                                                               \
-      else                                                              \
-        {                                                               \
-          (Current).first_line   = (Current).last_line   =              \
-            YYRHSLOC (Rhs, 0).last_line;                                \
-          (Current).first_column = (Current).last_column =              \
-            YYRHSLOC (Rhs, 0).last_column;                              \
-        }                                                               \
-    while (0)
-#endif
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                        \
-do {                                            \
-  if (yydebug)                                  \
-    YYFPRINTF Args;                             \
-} while (0)
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
-
-#ifndef YY_LOCATION_PRINT
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-
-/* Print *YYLOCP on YYO.  Private, do not rely on its existence. */
-
-YY_ATTRIBUTE_UNUSED
-static unsigned
-yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
-{
-  unsigned res = 0;
-  int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
-  if (0 <= yylocp->first_line)
-    {
-      res += YYFPRINTF (yyo, "%d", yylocp->first_line);
-      if (0 <= yylocp->first_column)
-        res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
-    }
-  if (0 <= yylocp->last_line)
-    {
-      if (yylocp->first_line < yylocp->last_line)
-        {
-          res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
-          if (0 <= end_col)
-            res += YYFPRINTF (yyo, ".%d", end_col);
-        }
-      else if (0 <= end_col && yylocp->first_column < end_col)
-        res += YYFPRINTF (yyo, "-%d", end_col);
-    }
-  return res;
- }
-
-#  define YY_LOCATION_PRINT(File, Loc)          \
-  yy_location_print_ (File, &(Loc))
-
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
-do {                                                                      \
-  if (yydebug)                                                            \
-    {                                                                     \
-      YYFPRINTF (stderr, "%s ", Title);                                   \
-      yy_symbol_print (stderr,                                            \
-                  Type, Value, Location); \
-      YYFPRINTF (stderr, "\n");                                           \
-    }                                                                     \
-} while (0)
-
-
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
-
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
-{
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
-  YYUSE (yylocationp);
-  if (!yyvaluep)
-    return;
-# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
-  YYUSE (yytype);
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
-{
-  YYFPRINTF (yyoutput, "%s %s (",
-             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
-
-  YY_LOCATION_PRINT (yyoutput, *yylocationp);
-  YYFPRINTF (yyoutput, ": ");
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
-  YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included).                                                   |
-`------------------------------------------------------------------*/
-
-static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-{
-  YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
-  YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top)                            \
-do {                                                            \
-  if (yydebug)                                                  \
-    yy_stack_print ((Bottom), (Top));                           \
-} while (0)
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced.  |
-`------------------------------------------------*/
-
-static void
-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
-{
-  unsigned long int yylno = yyrline[yyrule];
-  int yynrhs = yyr2[yyrule];
-  int yyi;
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-             yyrule - 1, yylno);
-  /* The symbols being reduced.  */
-  for (yyi = 0; yyi < yynrhs; yyi++)
-    {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr,
-                       yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
-                       , &(yylsp[(yyi + 1) - (yynrhs)])                       );
-      YYFPRINTF (stderr, "\n");
-    }
-}
-
-# define YY_REDUCE_PRINT(Rule)          \
-do {                                    \
-  if (yydebug)                          \
-    yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \
-} while (0)
-
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
-
-   Do not make this value too large; the results are undefined if
-   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-#  if defined __GLIBC__ && defined _STRING_H
-#   define yystrlen strlen
-#  else
-/* Return the length of YYSTR.  */
-static YYSIZE_T
-yystrlen (const char *yystr)
-{
-  YYSIZE_T yylen;
-  for (yylen = 0; yystr[yylen]; yylen++)
-    continue;
-  return yylen;
-}
-#  endif
-# endif
-
-# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-{
-  char *yyd = yydest;
-  const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
-
-  return yyd - 1;
-}
-#  endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-   quotes and backslashes, so that it's suitable for yyerror.  The
-   heuristic is that double-quoting is unnecessary unless the string
-   contains an apostrophe, a comma, or backslash (other than
-   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
-   null, do not copy; instead, return the length of what the result
-   would have been.  */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
-  if (*yystr == '"')
-    {
-      YYSIZE_T yyn = 0;
-      char const *yyp = yystr;
-
-      for (;;)
-        switch (*++yyp)
-          {
-          case '\'':
-          case ',':
-            goto do_not_strip_quotes;
-
-          case '\\':
-            if (*++yyp != '\\')
-              goto do_not_strip_quotes;
-            /* Fall through.  */
-          default:
-            if (yyres)
-              yyres[yyn] = *yyp;
-            yyn++;
-            break;
-
-          case '"':
-            if (yyres)
-              yyres[yyn] = '\0';
-            return yyn;
-          }
-    do_not_strip_quotes: ;
-    }
-
-  if (! yyres)
-    return yystrlen (yystr);
-
-  return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store.  */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
-{
-  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = YY_NULLPTR;
-  /* Arguments of yyformat. */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
-  int yycount = 0;
-
-  /* There are many possibilities here to consider:
-     - If this state is a consistent state with a default action, then
-       the only way this function was invoked is if the default action
-       is an error action.  In that case, don't check for expected
-       tokens because there are none.
-     - The only way there can be no lookahead present (in yychar) is if
-       this state is a consistent state with a default action.  Thus,
-       detecting the absence of a lookahead is sufficient to determine
-       that there is no unexpected or expected token to report.  In that
-       case, just report a simple "syntax error".
-     - Don't assume there isn't a lookahead just because this state is a
-       consistent state with a default action.  There might have been a
-       previous inconsistent state, consistent state with a non-default
-       action, or user semantic action that manipulated yychar.
-     - Of course, the expected token list depends on states to have
-       correct lookahead information, and it depends on the parser not
-       to perform extra reductions after fetching a lookahead from the
-       scanner and before detecting a syntax error.  Thus, state merging
-       (from LALR or IELR) and default reductions corrupt the expected
-       token list.  However, the list is correct for canonical LR with
-       one exception: it will still contain any token that will not be
-       accepted due to an error action in a later state.
-  */
-  if (yytoken != YYEMPTY)
-    {
-      int yyn = yypact[*yyssp];
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                    return 2;
-                  yysize = yysize1;
-                }
-              }
-        }
-    }
-
-  switch (yycount)
-    {
-# define YYCASE_(N, S)                      \
-      case N:                               \
-        yyformat = S;                       \
-      break
-      YYCASE_(0, YY_("syntax error"));
-      YYCASE_(1, YY_("syntax error, unexpected %s"));
-      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
-      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
-      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
-    }
-
-  {
-    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-      return 2;
-    yysize = yysize1;
-  }
-
-  if (*yymsg_alloc < yysize)
-    {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
-    }
-
-  /* Avoid sprintf, as that infringes on the user's name space.
-     Don't have undefined behavior even if the translation
-     produced a string with the wrong number of "%s"s.  */
-  {
-    char *yyp = *yymsg;
-    int yyi = 0;
-    while ((*yyp = *yyformat) != '\0')
-      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
-          yyformat += 2;
-        }
-      else
-        {
-          yyp++;
-          yyformat++;
-        }
-  }
-  return 0;
-}
-#endif /* YYERROR_VERBOSE */
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol.  |
-`-----------------------------------------------*/
-
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
-{
-  YYUSE (yyvaluep);
-  YYUSE (yylocationp);
-  if (!yymsg)
-    yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  YYUSE (yytype);
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-}
-
-
-
-
-/* The lookahead symbol.  */
-int yychar;
-
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval;
-/* Location data for the lookahead symbol.  */
-YYLTYPE yylloc
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-  = { 1, 1, 1, 1 }
-# endif
-;
-/* Number of syntax errors so far.  */
-int yynerrs;
-
-
-/*----------.
-| yyparse.  |
-`----------*/
-
-int
-yyparse (void)
-{
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
-
-    /* The stacks and their tools:
-       'yyss': related to states.
-       'yyvs': related to semantic values.
-       'yyls': related to locations.
-
-       Refer to the stacks through separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
-
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
-
-    /* The location stack.  */
-    YYLTYPE yylsa[YYINITDEPTH];
-    YYLTYPE *yyls;
-    YYLTYPE *yylsp;
-
-    /* The locations where the error started and ended.  */
-    YYLTYPE yyerror_range[3];
-
-    YYSIZE_T yystacksize;
-
-  int yyn;
-  int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken = 0;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-  YYLTYPE yyloc;
-
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
-  /* The number of symbols on the RHS of the reduced rule.
-     Keep to zero when no symbol should be popped.  */
-  int yylen = 0;
-
-  yyssp = yyss = yyssa;
-  yyvsp = yyvs = yyvsa;
-  yylsp = yyls = yylsa;
-  yystacksize = YYINITDEPTH;
-
-  YYDPRINTF ((stderr, "Starting parse\n"));
-
-  yystate = 0;
-  yyerrstatus = 0;
-  yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
-  yylsp[0] = yylloc;
-  goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
- yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed.  So pushing a state here evens the stacks.  */
-  yyssp++;
-
- yysetstate:
-  *yyssp = yystate;
-
-  if (yyss + yystacksize - 1 <= yyssp)
-    {
-      /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
-      {
-        /* Give user a chance to reallocate the stack.  Use copies of
-           these so that the &'s don't force the real ones into
-           memory.  */
-        YYSTYPE *yyvs1 = yyvs;
-        yytype_int16 *yyss1 = yyss;
-        YYLTYPE *yyls1 = yyls;
-
-        /* Each stack pointer address is followed by the size of the
-           data in use in that stack, in bytes.  This used to be a
-           conditional around just the two extra args, but that might
-           be undefined if yyoverflow is a macro.  */
-        yyoverflow (YY_("memory exhausted"),
-                    &yyss1, yysize * sizeof (*yyssp),
-                    &yyvs1, yysize * sizeof (*yyvsp),
-                    &yyls1, yysize * sizeof (*yylsp),
-                    &yystacksize);
-
-        yyls = yyls1;
-        yyss = yyss1;
-        yyvs = yyvs1;
-      }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
-      /* Extend the stack our own way.  */
-      if (YYMAXDEPTH <= yystacksize)
-        goto yyexhaustedlab;
-      yystacksize *= 2;
-      if (YYMAXDEPTH < yystacksize)
-        yystacksize = YYMAXDEPTH;
-
-      {
-        yytype_int16 *yyss1 = yyss;
-        union yyalloc *yyptr =
-          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-        if (! yyptr)
-          goto yyexhaustedlab;
-        YYSTACK_RELOCATE (yyss_alloc, yyss);
-        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-        YYSTACK_RELOCATE (yyls_alloc, yyls);
-#  undef YYSTACK_RELOCATE
-        if (yyss1 != yyssa)
-          YYSTACK_FREE (yyss1);
-      }
-# endif
-#endif /* no yyoverflow */
-
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-      yylsp = yyls + yysize - 1;
-
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
-
-      if (yyss + yystacksize - 1 <= yyssp)
-        YYABORT;
-    }
-
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
-  goto yybackup;
-
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
-
-  /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
-
-  /* First try to decide what to do without reference to lookahead token.  */
-  yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
-    goto yydefault;
-
-  /* Not known => get a lookahead token if don't already have one.  */
-
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
-  if (yychar == YYEMPTY)
-    {
-      YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = yylex ();
-    }
-
-  if (yychar <= YYEOF)
-    {
-      yychar = yytoken = YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
-    }
-  else
-    {
-      yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
-    }
-
-  /* If the proper action on seeing token YYTOKEN is to reduce or to
-     detect an error, take that action.  */
-  yyn += yytoken;
-  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-    goto yydefault;
-  yyn = yytable[yyn];
-  if (yyn <= 0)
-    {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
-      yyn = -yyn;
-      goto yyreduce;
-    }
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
-
-  /* Shift the lookahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
-
-  yystate = yyn;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-  *++yylsp = yylloc;
-  goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
-yydefault:
-  yyn = yydefact[yystate];
-  if (yyn == 0)
-    goto yyerrlab;
-  goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction.  |
-`-----------------------------*/
-yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
-  yylen = yyr2[yyn];
-
-  /* If YYLEN is nonzero, implement the default value of the action:
-     '$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to garbage.
-     This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-  /* Default location.  */
-  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
-  YY_REDUCE_PRINT (yyn);
-  switch (yyn)
-    {
-        case 2:
-#line 110 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node),
-			                              guess_boot_cpuid((yyvsp[0].node)));
-		}
-#line 1478 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 3:
-#line 118 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.flags) = DTSF_V1;
-		}
-#line 1486 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 4:
-#line 122 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.flags) = DTSF_V1 | DTSF_PLUGIN;
-		}
-#line 1494 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 6:
-#line 130 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			if ((yyvsp[0].flags) != (yyvsp[-1].flags))
-				ERROR(&(yylsp[0]), "Header flags don't match earlier ones");
-			(yyval.flags) = (yyvsp[-1].flags);
-		}
-#line 1504 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 7:
-#line 139 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.re) = NULL;
-		}
-#line 1512 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 8:
-#line 143 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
-		}
-#line 1520 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 9:
-#line 150 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
-		}
-#line 1528 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 10:
-#line 154 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
-			(yyval.re) = (yyvsp[0].re);
-		}
-#line 1537 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 11:
-#line 162 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = name_node((yyvsp[0].node), "");
-		}
-#line 1545 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 12:
-#line 166 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
-		}
-#line 1553 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 13:
-#line 171 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
-
-			if (target) {
-				add_label(&target->labels, (yyvsp[-2].labelref));
-				merge_nodes(target, (yyvsp[0].node));
-			} else
-				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
-			(yyval.node) = (yyvsp[-3].node);
-		}
-#line 1568 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 14:
-#line 182 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
-
-			if (target) {
-				merge_nodes(target, (yyvsp[0].node));
-			} else {
-				/*
-				 * We rely on the rule being always:
-				 *   versioninfo plugindecl memreserves devicetree
-				 * so $-1 is what we want (plugindecl)
-				 */
-				if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN)
-					add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref));
-				else
-					ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
-			}
-			(yyval.node) = (yyvsp[-2].node);
-		}
-#line 1591 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 15:
-#line 201 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
-
-			if (target)
-				delete_node(target);
-			else
-				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
-
-
-			(yyval.node) = (yyvsp[-3].node);
-		}
-#line 1607 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 16:
-#line 213 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			/* build empty node */
-			(yyval.node) = name_node(build_node(NULL, NULL), "");
-		}
-#line 1616 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 17:
-#line 221 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
-		}
-#line 1624 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 18:
-#line 228 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.proplist) = NULL;
-		}
-#line 1632 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 19:
-#line 232 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
-		}
-#line 1640 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 20:
-#line 239 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
-		}
-#line 1648 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 21:
-#line 243 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
-		}
-#line 1656 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 22:
-#line 247 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
-		}
-#line 1664 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 23:
-#line 251 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
-			(yyval.prop) = (yyvsp[0].prop);
-		}
-#line 1673 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 24:
-#line 259 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
-		}
-#line 1681 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 25:
-#line 263 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
-		}
-#line 1689 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 26:
-#line 267 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
-		}
-#line 1697 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 27:
-#line 271 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
-		}
-#line 1705 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 28:
-#line 275 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
-			struct data d;
-
-			if ((yyvsp[-3].integer) != 0)
-				if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0)
-					die("Couldn't seek to offset %llu in \"%s\": %s",
-					    (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val,
-					    strerror(errno));
-
-			d = data_copy_file(f, (yyvsp[-1].integer));
-
-			(yyval.data) = data_merge((yyvsp[-8].data), d);
-			fclose(f);
-		}
-#line 1725 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 29:
-#line 291 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
-			struct data d = empty_data;
-
-			d = data_copy_file(f, -1);
-
-			(yyval.data) = data_merge((yyvsp[-4].data), d);
-			fclose(f);
-		}
-#line 1739 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 30:
-#line 301 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
-		}
-#line 1747 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 31:
-#line 308 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = empty_data;
-		}
-#line 1755 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 32:
-#line 312 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = (yyvsp[-1].data);
-		}
-#line 1763 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 33:
-#line 316 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
-		}
-#line 1771 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 34:
-#line 323 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			unsigned long long bits;
-
-			bits = (yyvsp[-1].integer);
-
-			if ((bits !=  8) && (bits != 16) &&
-			    (bits != 32) && (bits != 64)) {
-				ERROR(&(yylsp[-1]), "Array elements must be"
-				      " 8, 16, 32 or 64-bits");
-				bits = 32;
-			}
-
-			(yyval.array).data = empty_data;
-			(yyval.array).bits = bits;
-		}
-#line 1791 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 35:
-#line 339 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.array).data = empty_data;
-			(yyval.array).bits = 32;
-		}
-#line 1800 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 36:
-#line 344 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			if ((yyvsp[-1].array).bits < 64) {
-				uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
-				/*
-				 * Bits above mask must either be all zero
-				 * (positive within range of mask) or all one
-				 * (negative and sign-extended). The second
-				 * condition is true if when we set all bits
-				 * within the mask to one (i.e. | in the
-				 * mask), all bits are one.
-				 */
-				if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL))
-					ERROR(&(yylsp[0]), "Value out of range for"
-					      " %d-bit array element", (yyvsp[-1].array).bits);
-			}
-
-			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
-		}
-#line 1823 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 37:
-#line 363 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
-
-			if ((yyvsp[-1].array).bits == 32)
-				(yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data,
-							  REF_PHANDLE,
-							  (yyvsp[0].labelref));
-			else
-				ERROR(&(yylsp[0]), "References are only allowed in "
-					    "arrays with 32-bit elements.");
-
-			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
-		}
-#line 1841 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 38:
-#line 377 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
-		}
-#line 1849 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 41:
-#line 386 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.integer) = (yyvsp[-1].integer);
-		}
-#line 1857 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 44:
-#line 397 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
-#line 1863 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 46:
-#line 402 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
-#line 1869 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 48:
-#line 407 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
-#line 1875 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 50:
-#line 412 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
-#line 1881 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 52:
-#line 417 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
-#line 1887 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 54:
-#line 422 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
-#line 1893 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 56:
-#line 427 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
-#line 1899 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 57:
-#line 428 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
-#line 1905 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 59:
-#line 433 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
-#line 1911 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 60:
-#line 434 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
-#line 1917 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 61:
-#line 435 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
-#line 1923 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 62:
-#line 436 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
-#line 1929 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 63:
-#line 440 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
-#line 1935 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 64:
-#line 441 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
-#line 1941 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 66:
-#line 446 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
-#line 1947 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 67:
-#line 447 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
-#line 1953 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 69:
-#line 452 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
-#line 1959 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 70:
-#line 454 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			if ((yyvsp[0].integer) != 0) {
-				(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
-			} else {
-				ERROR(&(yyloc), "Division by zero");
-				(yyval.integer) = 0;
-			}
-		}
-#line 1972 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 71:
-#line 463 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			if ((yyvsp[0].integer) != 0) {
-				(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
-			} else {
-				ERROR(&(yyloc), "Division by zero");
-				(yyval.integer) = 0;
-			}
-		}
-#line 1985 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 74:
-#line 476 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = -(yyvsp[0].integer); }
-#line 1991 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 75:
-#line 477 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = ~(yyvsp[0].integer); }
-#line 1997 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 76:
-#line 478 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = !(yyvsp[0].integer); }
-#line 2003 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 77:
-#line 483 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = empty_data;
-		}
-#line 2011 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 78:
-#line 487 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
-		}
-#line 2019 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 79:
-#line 491 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
-		}
-#line 2027 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 80:
-#line 498 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.nodelist) = NULL;
-		}
-#line 2035 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 81:
-#line 502 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
-		}
-#line 2043 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 82:
-#line 506 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			ERROR(&(yylsp[0]), "Properties must precede subnodes");
-			YYERROR;
-		}
-#line 2052 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 83:
-#line 514 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
-		}
-#line 2060 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 84:
-#line 518 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
-		}
-#line 2068 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 85:
-#line 522 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
-			(yyval.node) = (yyvsp[0].node);
-		}
-#line 2077 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-
-#line 2081 "dtc-parser.tab.c" /* yacc.c:1646  */
-      default: break;
-    }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
-  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-
-  *++yyvsp = yyval;
-  *++yylsp = yyloc;
-
-  /* Now 'shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
-
-  goto yynewstate;
-
-
-/*--------------------------------------.
-| yyerrlab -- here on detecting error.  |
-`--------------------------------------*/
-yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
-    {
-      ++yynerrs;
-#if ! YYERROR_VERBOSE
-      yyerror (YY_("syntax error"));
-#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
-                                        yyssp, yytoken)
-      {
-        char const *yymsgp = YY_("syntax error");
-        int yysyntax_error_status;
-        yysyntax_error_status = YYSYNTAX_ERROR;
-        if (yysyntax_error_status == 0)
-          yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
-          {
-            if (yymsg != yymsgbuf)
-              YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
-            if (!yymsg)
-              {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
-              }
-            else
-              {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
-              }
-          }
-        yyerror (yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
-      }
-# undef YYSYNTAX_ERROR
-#endif
-    }
-
-  yyerror_range[1] = yylloc;
-
-  if (yyerrstatus == 3)
-    {
-      /* If just tried and failed to reuse lookahead token after an
-         error, discard it.  */
-
-      if (yychar <= YYEOF)
-        {
-          /* Return failure if at end of input.  */
-          if (yychar == YYEOF)
-            YYABORT;
-        }
-      else
-        {
-          yydestruct ("Error: discarding",
-                      yytoken, &yylval, &yylloc);
-          yychar = YYEMPTY;
-        }
-    }
-
-  /* Else will try to reuse lookahead token after shifting the error
-     token.  */
-  goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR.  |
-`---------------------------------------------------*/
-yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
-
-  yyerror_range[1] = yylsp[1-yylen];
-  /* Do not reclaim the symbols of the rule whose action triggered
-     this YYERROR.  */
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-  yystate = *yyssp;
-  goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR.  |
-`-------------------------------------------------------------*/
-yyerrlab1:
-  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
-
-  for (;;)
-    {
-      yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
-        {
-          yyn += YYTERROR;
-          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-            {
-              yyn = yytable[yyn];
-              if (0 < yyn)
-                break;
-            }
-        }
-
-      /* Pop the current state because it cannot handle the error token.  */
-      if (yyssp == yyss)
-        YYABORT;
-
-      yyerror_range[1] = *yylsp;
-      yydestruct ("Error: popping",
-                  yystos[yystate], yyvsp, yylsp);
-      YYPOPSTACK (1);
-      yystate = *yyssp;
-      YY_STACK_PRINT (yyss, yyssp);
-    }
-
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-
-  yyerror_range[2] = yylloc;
-  /* Using YYLLOC is tempting, but would change the location of
-     the lookahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
-  *++yylsp = yyloc;
-
-  /* Shift the error token.  */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
-  yystate = yyn;
-  goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yyresult = 1;
-  goto yyreturn;
-
-#if !defined yyoverflow || YYERROR_VERBOSE
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here.  |
-`-------------------------------------------------*/
-yyexhaustedlab:
-  yyerror (YY_("memory exhausted"));
-  yyresult = 2;
-  /* Fall through.  */
-#endif
-
-yyreturn:
-  if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval, &yylloc);
-    }
-  /* Do not reclaim the symbols of the rule whose action triggered
-     this YYABORT or YYACCEPT.  */
-  YYPOPSTACK (yylen);
-  YY_STACK_PRINT (yyss, yyssp);
-  while (yyssp != yyss)
-    {
-      yydestruct ("Cleanup: popping",
-                  yystos[*yyssp], yyvsp, yylsp);
-      YYPOPSTACK (1);
-    }
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
-  if (yymsg != yymsgbuf)
-    YYSTACK_FREE (yymsg);
-#endif
-  return yyresult;
-}
-#line 528 "dtc-parser.y" /* yacc.c:1906  */
-
-
-void yyerror(char const *s)
-{
-	ERROR(&yylloc, "%s", s);
-}
diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
deleted file mode 100644
index 6aa512c..0000000
--- a/scripts/dtc/dtc-parser.tab.h_shipped
+++ /dev/null
@@ -1,125 +0,0 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
-
-/* Bison interface for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, 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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-/* Token type.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-  enum yytokentype
-  {
-    DT_V1 = 258,
-    DT_PLUGIN = 259,
-    DT_MEMRESERVE = 260,
-    DT_LSHIFT = 261,
-    DT_RSHIFT = 262,
-    DT_LE = 263,
-    DT_GE = 264,
-    DT_EQ = 265,
-    DT_NE = 266,
-    DT_AND = 267,
-    DT_OR = 268,
-    DT_BITS = 269,
-    DT_DEL_PROP = 270,
-    DT_DEL_NODE = 271,
-    DT_PROPNODENAME = 272,
-    DT_LITERAL = 273,
-    DT_CHAR_LITERAL = 274,
-    DT_BYTE = 275,
-    DT_STRING = 276,
-    DT_LABEL = 277,
-    DT_REF = 278,
-    DT_INCBIN = 279
-  };
-#endif
-
-/* Value type.  */
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
-union YYSTYPE
-{
-#line 39 "dtc-parser.y" /* yacc.c:1909  */
-
-	char *propnodename;
-	char *labelref;
-	uint8_t byte;
-	struct data data;
-
-	struct {
-		struct data	data;
-		int		bits;
-	} array;
-
-	struct property *prop;
-	struct property *proplist;
-	struct node *node;
-	struct node *nodelist;
-	struct reserve_info *re;
-	uint64_t integer;
-	unsigned int flags;
-
-#line 99 "dtc-parser.tab.h" /* yacc.c:1909  */
-};
-
-typedef union YYSTYPE YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-/* Location type.  */
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE YYLTYPE;
-struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-};
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-extern YYSTYPE yylval;
-extern YYLTYPE yylloc;
-int yyparse (void);
-
-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED  */
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index affc81a..44af170 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -166,7 +166,17 @@
 		{
 			$$ = merge_nodes($1, $3);
 		}
-
+	| DT_REF nodedef
+		{
+			/*
+			 * We rely on the rule being always:
+			 *   versioninfo plugindecl memreserves devicetree
+			 * so $-1 is what we want (plugindecl)
+			 */
+			if (!($<flags>-1 & DTSF_PLUGIN))
+				ERROR(&@2, "Label or path %s not found", $1);
+			$$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1);
+		}
 	| devicetree DT_LABEL DT_REF nodedef
 		{
 			struct node *target = get_node_by_ref($1, $3);
@@ -209,11 +219,6 @@
 
 			$$ = $1;
 		}
-	| /* empty */
-		{
-			/* build empty node */
-			$$ = name_node(build_node(NULL, NULL), "");
-		}
 	;
 
 nodedef:
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 5ed873c..c36994e 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -59,8 +59,6 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
 }
 
 /* Usage related data. */
-#define FDT_VERSION(version)	_FDT_VERSION(version)
-#define _FDT_VERSION(version)	#version
 static const char usage_synopsis[] = "dtc [options] <input file>";
 static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv";
 static struct option const usage_long_opts[] = {
@@ -98,7 +96,7 @@ static const char * const usage_opts_help[] = {
 	 "\t\tdts - device tree source text\n"
 	 "\t\tdtb - device tree blob\n"
 	 "\t\tasm - assembler source",
-	"\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
+	"\n\tBlob version to produce, defaults to "stringify(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
 	"\n\tOutput dependency file",
 	"\n\tMake space for <number> reserve map entries (for dtb and asm output)",
 	"\n\tMake the blob at least <bytes> long (extra space)",
@@ -319,13 +317,14 @@ int main(int argc, char *argv[])
 		dti->boot_cpuid_phys = cmdline_boot_cpuid;
 
 	fill_fullpaths(dti->dt, "");
-	process_checks(force, dti);
 
 	/* on a plugin, generate by default */
 	if (dti->dtsflags & DTSF_PLUGIN) {
 		generate_fixups = 1;
 	}
 
+	process_checks(force, dti);
+
 	if (auto_label_aliases)
 		generate_label_tree(dti, "aliases", false);
 
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 35cf926..3b18a42 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -1,5 +1,5 @@
-#ifndef _DTC_H
-#define _DTC_H
+#ifndef DTC_H
+#define DTC_H
 
 /*
  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
@@ -67,7 +67,8 @@ typedef uint32_t cell_t;
 
 
 #define streq(a, b)	(strcmp((a), (b)) == 0)
-#define strneq(a, b, n)	(strncmp((a), (b), (n)) == 0)
+#define strstarts(s, prefix)	(strncmp((s), (prefix), strlen(prefix)) == 0)
+#define strprefixeq(a, n, b)	(strlen(b) == (n) && (memcmp(a, b, n) == 0))
 
 #define ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
 
@@ -203,7 +204,7 @@ struct node *build_node_delete(void);
 struct node *name_node(struct node *node, char *name);
 struct node *chain_node(struct node *first, struct node *list);
 struct node *merge_nodes(struct node *old_node, struct node *new_node);
-void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
+struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
 
 void add_property(struct node *node, struct property *prop);
 void delete_property_by_name(struct node *node, char *name);
@@ -289,4 +290,4 @@ struct dt_info *dt_from_source(const char *f);
 
 struct dt_info *dt_from_fs(const char *dirname);
 
-#endif /* _DTC_H */
+#endif /* DTC_H */
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index fcf7154..8d268fb 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -731,7 +731,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath)
 
 	plen = strlen(ppath);
 
-	if (!strneq(ppath, cpath, plen))
+	if (!strstarts(cpath, ppath))
 		die("Path \"%s\" is not valid as a child of \"%s\"\n",
 		    cpath, ppath);
 
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 22286a1..7855a17 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -88,7 +88,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
 		    || ((offset + len) > fdt_size_dt_struct(fdt)))
 			return NULL;
 
-	return _fdt_offset_ptr(fdt, offset);
+	return fdt_offset_ptr_(fdt, offset);
 }
 
 uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
@@ -123,6 +123,9 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
 		/* skip-name offset, length and value */
 		offset += sizeof(struct fdt_property) - FDT_TAGSIZE
 			+ fdt32_to_cpu(*lenp);
+		if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
+		    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
+			offset += 4;
 		break;
 
 	case FDT_END:
@@ -141,7 +144,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
 	return tag;
 }
 
-int _fdt_check_node_offset(const void *fdt, int offset)
+int fdt_check_node_offset_(const void *fdt, int offset)
 {
 	if ((offset < 0) || (offset % FDT_TAGSIZE)
 	    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
@@ -150,7 +153,7 @@ int _fdt_check_node_offset(const void *fdt, int offset)
 	return offset;
 }
 
-int _fdt_check_prop_offset(const void *fdt, int offset)
+int fdt_check_prop_offset_(const void *fdt, int offset)
 {
 	if ((offset < 0) || (offset % FDT_TAGSIZE)
 	    || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
@@ -165,7 +168,7 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
 	uint32_t tag;
 
 	if (offset >= 0)
-		if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
+		if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0)
 			return nextoffset;
 
 	do {
@@ -227,7 +230,7 @@ int fdt_next_subnode(const void *fdt, int offset)
 	return offset;
 }
 
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
+const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)
 {
 	int len = strlen(s) + 1;
 	const char *last = strtab + tabsize - len;
diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h
index 526aedb..74961f9 100644
--- a/scripts/dtc/libfdt/fdt.h
+++ b/scripts/dtc/libfdt/fdt.h
@@ -1,5 +1,5 @@
-#ifndef _FDT_H
-#define _FDT_H
+#ifndef FDT_H
+#define FDT_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -108,4 +108,4 @@ struct fdt_property {
 #define FDT_V16_SIZE	FDT_V3_SIZE
 #define FDT_V17_SIZE	(FDT_V16_SIZE + sizeof(fdt32_t))
 
-#endif /* _FDT_H */
+#endif /* FDT_H */
diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
index bd81241..bf75388 100644
--- a/scripts/dtc/libfdt/fdt_overlay.c
+++ b/scripts/dtc/libfdt/fdt_overlay.c
@@ -1,3 +1,54 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2016 Free Electrons
+ * Copyright (C) 2016 NextThing Co.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ *  a) This library is free software; you can redistribute 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 library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 #include "libfdt_env.h"
 
 #include <fdt.h>
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index 08de2cc..dfb3236 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -55,12 +55,13 @@
 
 #include "libfdt_internal.h"
 
-static int _fdt_nodename_eq(const void *fdt, int offset,
+static int fdt_nodename_eq_(const void *fdt, int offset,
 			    const char *s, int len)
 {
-	const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
+	int olen;
+	const char *p = fdt_get_name(fdt, offset, &olen);
 
-	if (!p)
+	if (!p || olen < len)
 		/* short match */
 		return 0;
 
@@ -80,7 +81,7 @@ const char *fdt_string(const void *fdt, int stroffset)
 	return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
 }
 
-static int _fdt_string_eq(const void *fdt, int stroffset,
+static int fdt_string_eq_(const void *fdt, int stroffset,
 			  const char *s, int len)
 {
 	const char *p = fdt_string(fdt, stroffset);
@@ -117,8 +118,8 @@ uint32_t fdt_get_max_phandle(const void *fdt)
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 {
 	FDT_CHECK_HEADER(fdt);
-	*address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
-	*size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
+	*address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address);
+	*size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size);
 	return 0;
 }
 
@@ -126,12 +127,12 @@ int fdt_num_mem_rsv(const void *fdt)
 {
 	int i = 0;
 
-	while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
+	while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0)
 		i++;
 	return i;
 }
 
-static int _nextprop(const void *fdt, int offset)
+static int nextprop_(const void *fdt, int offset)
 {
 	uint32_t tag;
 	int nextoffset;
@@ -166,7 +167,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,
 	     (offset >= 0) && (depth >= 0);
 	     offset = fdt_next_node(fdt, offset, &depth))
 		if ((depth == 1)
-		    && _fdt_nodename_eq(fdt, offset, name, namelen))
+		    && fdt_nodename_eq_(fdt, offset, name, namelen))
 			return offset;
 
 	if (depth < 0)
@@ -232,17 +233,35 @@ int fdt_path_offset(const void *fdt, const char *path)
 
 const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
 {
-	const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
+	const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset);
+	const char *nameptr;
 	int err;
 
 	if (((err = fdt_check_header(fdt)) != 0)
-	    || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
+	    || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))
 			goto fail;
 
-	if (len)
-		*len = strlen(nh->name);
+	nameptr = nh->name;
 
-	return nh->name;
+	if (fdt_version(fdt) < 0x10) {
+		/*
+		 * For old FDT versions, match the naming conventions of V16:
+		 * give only the leaf name (after all /). The actual tree
+		 * contents are loosely checked.
+		 */
+		const char *leaf;
+		leaf = strrchr(nameptr, '/');
+		if (leaf == NULL) {
+			err = -FDT_ERR_BADSTRUCTURE;
+			goto fail;
+		}
+		nameptr = leaf+1;
+	}
+
+	if (len)
+		*len = strlen(nameptr);
+
+	return nameptr;
 
  fail:
 	if (len)
@@ -254,34 +273,34 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset)
 {
 	int offset;
 
-	if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+	if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
 		return offset;
 
-	return _nextprop(fdt, offset);
+	return nextprop_(fdt, offset);
 }
 
 int fdt_next_property_offset(const void *fdt, int offset)
 {
-	if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
+	if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0)
 		return offset;
 
-	return _nextprop(fdt, offset);
+	return nextprop_(fdt, offset);
 }
 
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
-						      int offset,
-						      int *lenp)
+static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
+						              int offset,
+						              int *lenp)
 {
 	int err;
 	const struct fdt_property *prop;
 
-	if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
+	if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {
 		if (lenp)
 			*lenp = err;
 		return NULL;
 	}
 
-	prop = _fdt_offset_ptr(fdt, offset);
+	prop = fdt_offset_ptr_(fdt, offset);
 
 	if (lenp)
 		*lenp = fdt32_to_cpu(prop->len);
@@ -289,23 +308,44 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
 	return prop;
 }
 
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
-						    int offset,
-						    const char *name,
-						    int namelen, int *lenp)
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+						      int offset,
+						      int *lenp)
+{
+	/* Prior to version 16, properties may need realignment
+	 * and this API does not work. fdt_getprop_*() will, however. */
+
+	if (fdt_version(fdt) < 0x10) {
+		if (lenp)
+			*lenp = -FDT_ERR_BADVERSION;
+		return NULL;
+	}
+
+	return fdt_get_property_by_offset_(fdt, offset, lenp);
+}
+
+static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
+						            int offset,
+						            const char *name,
+						            int namelen,
+							    int *lenp,
+							    int *poffset)
 {
 	for (offset = fdt_first_property_offset(fdt, offset);
 	     (offset >= 0);
 	     (offset = fdt_next_property_offset(fdt, offset))) {
 		const struct fdt_property *prop;
 
-		if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
+		if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {
 			offset = -FDT_ERR_INTERNAL;
 			break;
 		}
-		if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
-				   name, namelen))
+		if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff),
+				   name, namelen)) {
+			if (poffset)
+				*poffset = offset;
 			return prop;
+		}
 	}
 
 	if (lenp)
@@ -313,6 +353,25 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
 	return NULL;
 }
 
+
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+						    int offset,
+						    const char *name,
+						    int namelen, int *lenp)
+{
+	/* Prior to version 16, properties may need realignment
+	 * and this API does not work. fdt_getprop_*() will, however. */
+	if (fdt_version(fdt) < 0x10) {
+		if (lenp)
+			*lenp = -FDT_ERR_BADVERSION;
+		return NULL;
+	}
+
+	return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp,
+					 NULL);
+}
+
+
 const struct fdt_property *fdt_get_property(const void *fdt,
 					    int nodeoffset,
 					    const char *name, int *lenp)
@@ -324,12 +383,18 @@ const struct fdt_property *fdt_get_property(const void *fdt,
 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
 				const char *name, int namelen, int *lenp)
 {
+	int poffset;
 	const struct fdt_property *prop;
 
-	prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
+	prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp,
+					 &poffset);
 	if (!prop)
 		return NULL;
 
+	/* Handle realignment */
+	if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&
+	    fdt32_to_cpu(prop->len) >= 8)
+		return prop->data + 4;
 	return prop->data;
 }
 
@@ -338,11 +403,16 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
 {
 	const struct fdt_property *prop;
 
-	prop = fdt_get_property_by_offset(fdt, offset, lenp);
+	prop = fdt_get_property_by_offset_(fdt, offset, lenp);
 	if (!prop)
 		return NULL;
 	if (namep)
 		*namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+
+	/* Handle realignment */
+	if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&
+	    fdt32_to_cpu(prop->len) >= 8)
+		return prop->data + 4;
 	return prop->data;
 }
 
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 5c3a2bb..9b82905 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -55,8 +55,8 @@
 
 #include "libfdt_internal.h"
 
-static int _fdt_blocks_misordered(const void *fdt,
-			      int mem_rsv_size, int struct_size)
+static int fdt_blocks_misordered_(const void *fdt,
+				  int mem_rsv_size, int struct_size)
 {
 	return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
 		|| (fdt_off_dt_struct(fdt) <
@@ -67,13 +67,13 @@ static int _fdt_blocks_misordered(const void *fdt,
 		    (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
 }
 
-static int _fdt_rw_check_header(void *fdt)
+static int fdt_rw_check_header_(void *fdt)
 {
 	FDT_CHECK_HEADER(fdt);
 
 	if (fdt_version(fdt) < 17)
 		return -FDT_ERR_BADVERSION;
-	if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
+	if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
 				   fdt_size_dt_struct(fdt)))
 		return -FDT_ERR_BADLAYOUT;
 	if (fdt_version(fdt) > 17)
@@ -84,20 +84,20 @@ static int _fdt_rw_check_header(void *fdt)
 
 #define FDT_RW_CHECK_HEADER(fdt) \
 	{ \
-		int __err; \
-		if ((__err = _fdt_rw_check_header(fdt)) != 0) \
-			return __err; \
+		int err_; \
+		if ((err_ = fdt_rw_check_header_(fdt)) != 0) \
+			return err_; \
 	}
 
-static inline int _fdt_data_size(void *fdt)
+static inline int fdt_data_size_(void *fdt)
 {
 	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 }
 
-static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
+static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
 {
 	char *p = splicepoint;
-	char *end = (char *)fdt + _fdt_data_size(fdt);
+	char *end = (char *)fdt + fdt_data_size_(fdt);
 
 	if (((p + oldlen) < p) || ((p + oldlen) > end))
 		return -FDT_ERR_BADOFFSET;
@@ -109,12 +109,12 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
 	return 0;
 }
 
-static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
+static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p,
 			       int oldn, int newn)
 {
 	int delta = (newn - oldn) * sizeof(*p);
 	int err;
-	err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
+	err = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
 	if (err)
 		return err;
 	fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
@@ -122,13 +122,13 @@ static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
 	return 0;
 }
 
-static int _fdt_splice_struct(void *fdt, void *p,
+static int fdt_splice_struct_(void *fdt, void *p,
 			      int oldlen, int newlen)
 {
 	int delta = newlen - oldlen;
 	int err;
 
-	if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
+	if ((err = fdt_splice_(fdt, p, oldlen, newlen)))
 		return err;
 
 	fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
@@ -136,20 +136,20 @@ static int _fdt_splice_struct(void *fdt, void *p,
 	return 0;
 }
 
-static int _fdt_splice_string(void *fdt, int newlen)
+static int fdt_splice_string_(void *fdt, int newlen)
 {
 	void *p = (char *)fdt
 		+ fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 	int err;
 
-	if ((err = _fdt_splice(fdt, p, 0, newlen)))
+	if ((err = fdt_splice_(fdt, p, 0, newlen)))
 		return err;
 
 	fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
 	return 0;
 }
 
-static int _fdt_find_add_string(void *fdt, const char *s)
+static int fdt_find_add_string_(void *fdt, const char *s)
 {
 	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
 	const char *p;
@@ -157,13 +157,13 @@ static int _fdt_find_add_string(void *fdt, const char *s)
 	int len = strlen(s) + 1;
 	int err;
 
-	p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
+	p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
 	if (p)
 		/* found it */
 		return (p - strtab);
 
 	new = strtab + fdt_size_dt_strings(fdt);
-	err = _fdt_splice_string(fdt, len);
+	err = fdt_splice_string_(fdt, len);
 	if (err)
 		return err;
 
@@ -178,8 +178,8 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
 
 	FDT_RW_CHECK_HEADER(fdt);
 
-	re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
-	err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
+	re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));
+	err = fdt_splice_mem_rsv_(fdt, re, 0, 1);
 	if (err)
 		return err;
 
@@ -190,17 +190,17 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
 
 int fdt_del_mem_rsv(void *fdt, int n)
 {
-	struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
+	struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);
 
 	FDT_RW_CHECK_HEADER(fdt);
 
 	if (n >= fdt_num_mem_rsv(fdt))
 		return -FDT_ERR_NOTFOUND;
 
-	return _fdt_splice_mem_rsv(fdt, re, 1, 0);
+	return fdt_splice_mem_rsv_(fdt, re, 1, 0);
 }
 
-static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
+static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,
 				int len, struct fdt_property **prop)
 {
 	int oldlen;
@@ -210,7 +210,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
 	if (!*prop)
 		return oldlen;
 
-	if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
+	if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
 				      FDT_TAGALIGN(len))))
 		return err;
 
@@ -218,7 +218,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
 	return 0;
 }
 
-static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
+static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
 			     int len, struct fdt_property **prop)
 {
 	int proplen;
@@ -226,17 +226,17 @@ static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
 	int namestroff;
 	int err;
 
-	if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+	if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
 		return nextoffset;
 
-	namestroff = _fdt_find_add_string(fdt, name);
+	namestroff = fdt_find_add_string_(fdt, name);
 	if (namestroff < 0)
 		return namestroff;
 
-	*prop = _fdt_offset_ptr_w(fdt, nextoffset);
+	*prop = fdt_offset_ptr_w_(fdt, nextoffset);
 	proplen = sizeof(**prop) + FDT_TAGALIGN(len);
 
-	err = _fdt_splice_struct(fdt, *prop, 0, proplen);
+	err = fdt_splice_struct_(fdt, *prop, 0, proplen);
 	if (err)
 		return err;
 
@@ -260,7 +260,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
 
 	newlen = strlen(name);
 
-	err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
+	err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1),
 				 FDT_TAGALIGN(newlen+1));
 	if (err)
 		return err;
@@ -277,9 +277,9 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
 
 	FDT_RW_CHECK_HEADER(fdt);
 
-	err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
+	err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
 	if (err == -FDT_ERR_NOTFOUND)
-		err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+		err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
 	if (err)
 		return err;
 
@@ -313,7 +313,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
 	prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
 	if (prop) {
 		newlen = len + oldlen;
-		err = _fdt_splice_struct(fdt, prop->data,
+		err = fdt_splice_struct_(fdt, prop->data,
 					 FDT_TAGALIGN(oldlen),
 					 FDT_TAGALIGN(newlen));
 		if (err)
@@ -321,7 +321,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
 		prop->len = cpu_to_fdt32(newlen);
 		memcpy(prop->data + oldlen, val, len);
 	} else {
-		err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+		err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
 		if (err)
 			return err;
 		memcpy(prop->data, val, len);
@@ -341,7 +341,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
 		return len;
 
 	proplen = sizeof(*prop) + FDT_TAGALIGN(len);
-	return _fdt_splice_struct(fdt, prop, proplen, 0);
+	return fdt_splice_struct_(fdt, prop, proplen, 0);
 }
 
 int fdt_add_subnode_namelen(void *fdt, int parentoffset,
@@ -369,10 +369,10 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
 		tag = fdt_next_tag(fdt, offset, &nextoffset);
 	} while ((tag == FDT_PROP) || (tag == FDT_NOP));
 
-	nh = _fdt_offset_ptr_w(fdt, offset);
+	nh = fdt_offset_ptr_w_(fdt, offset);
 	nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
 
-	err = _fdt_splice_struct(fdt, nh, 0, nodelen);
+	err = fdt_splice_struct_(fdt, nh, 0, nodelen);
 	if (err)
 		return err;
 
@@ -396,15 +396,15 @@ int fdt_del_node(void *fdt, int nodeoffset)
 
 	FDT_RW_CHECK_HEADER(fdt);
 
-	endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+	endoffset = fdt_node_end_offset_(fdt, nodeoffset);
 	if (endoffset < 0)
 		return endoffset;
 
-	return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
+	return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset),
 				  endoffset - nodeoffset, 0);
 }
 
-static void _fdt_packblocks(const char *old, char *new,
+static void fdt_packblocks_(const char *old, char *new,
 			    int mem_rsv_size, int struct_size)
 {
 	int mem_rsv_off, struct_off, strings_off;
@@ -450,7 +450,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
 			return struct_size;
 	}
 
-	if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
+	if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
 		/* no further work necessary */
 		err = fdt_move(fdt, buf, bufsize);
 		if (err)
@@ -478,7 +478,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
 			return -FDT_ERR_NOSPACE;
 	}
 
-	_fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
+	fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);
 	memmove(buf, tmp, newsize);
 
 	fdt_set_magic(buf, FDT_MAGIC);
@@ -498,8 +498,8 @@ int fdt_pack(void *fdt)
 
 	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
 		* sizeof(struct fdt_reserve_entry);
-	_fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
-	fdt_set_totalsize(fdt, _fdt_data_size(fdt));
+	fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
+	fdt_set_totalsize(fdt, fdt_data_size_(fdt));
 
 	return 0;
 }
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 2bd15e7..6d33cc2 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -55,7 +55,7 @@
 
 #include "libfdt_internal.h"
 
-static int _fdt_sw_check_header(void *fdt)
+static int fdt_sw_check_header_(void *fdt)
 {
 	if (fdt_magic(fdt) != FDT_SW_MAGIC)
 		return -FDT_ERR_BADMAGIC;
@@ -66,11 +66,11 @@ static int _fdt_sw_check_header(void *fdt)
 #define FDT_SW_CHECK_HEADER(fdt) \
 	{ \
 		int err; \
-		if ((err = _fdt_sw_check_header(fdt)) != 0) \
+		if ((err = fdt_sw_check_header_(fdt)) != 0) \
 			return err; \
 	}
 
-static void *_fdt_grab_space(void *fdt, size_t len)
+static void *fdt_grab_space_(void *fdt, size_t len)
 {
 	int offset = fdt_size_dt_struct(fdt);
 	int spaceleft;
@@ -82,7 +82,7 @@ static void *_fdt_grab_space(void *fdt, size_t len)
 		return NULL;
 
 	fdt_set_size_dt_struct(fdt, offset + len);
-	return _fdt_offset_ptr_w(fdt, offset);
+	return fdt_offset_ptr_w_(fdt, offset);
 }
 
 int fdt_create(void *buf, int bufsize)
@@ -174,7 +174,7 @@ int fdt_begin_node(void *fdt, const char *name)
 
 	FDT_SW_CHECK_HEADER(fdt);
 
-	nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
+	nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
 	if (! nh)
 		return -FDT_ERR_NOSPACE;
 
@@ -189,7 +189,7 @@ int fdt_end_node(void *fdt)
 
 	FDT_SW_CHECK_HEADER(fdt);
 
-	en = _fdt_grab_space(fdt, FDT_TAGSIZE);
+	en = fdt_grab_space_(fdt, FDT_TAGSIZE);
 	if (! en)
 		return -FDT_ERR_NOSPACE;
 
@@ -197,7 +197,7 @@ int fdt_end_node(void *fdt)
 	return 0;
 }
 
-static int _fdt_find_add_string(void *fdt, const char *s)
+static int fdt_find_add_string_(void *fdt, const char *s)
 {
 	char *strtab = (char *)fdt + fdt_totalsize(fdt);
 	const char *p;
@@ -205,7 +205,7 @@ static int _fdt_find_add_string(void *fdt, const char *s)
 	int len = strlen(s) + 1;
 	int struct_top, offset;
 
-	p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
+	p = fdt_find_string_(strtab - strtabsize, strtabsize, s);
 	if (p)
 		return p - strtab;
 
@@ -227,11 +227,11 @@ int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
 
 	FDT_SW_CHECK_HEADER(fdt);
 
-	nameoff = _fdt_find_add_string(fdt, name);
+	nameoff = fdt_find_add_string_(fdt, name);
 	if (nameoff == 0)
 		return -FDT_ERR_NOSPACE;
 
-	prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
+	prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
 	if (! prop)
 		return -FDT_ERR_NOSPACE;
 
@@ -265,7 +265,7 @@ int fdt_finish(void *fdt)
 	FDT_SW_CHECK_HEADER(fdt);
 
 	/* Add terminator */
-	end = _fdt_grab_space(fdt, sizeof(*end));
+	end = fdt_grab_space_(fdt, sizeof(*end));
 	if (! end)
 		return -FDT_ERR_NOSPACE;
 	*end = cpu_to_fdt32(FDT_END);
@@ -281,7 +281,7 @@ int fdt_finish(void *fdt)
 	while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
 		if (tag == FDT_PROP) {
 			struct fdt_property *prop =
-				_fdt_offset_ptr_w(fdt, offset);
+				fdt_offset_ptr_w_(fdt, offset);
 			int nameoff;
 
 			nameoff = fdt32_to_cpu(prop->nameoff);
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
index 5e85919..534c1cb 100644
--- a/scripts/dtc/libfdt/fdt_wip.c
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -93,7 +93,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
 						   val, len);
 }
 
-static void _fdt_nop_region(void *start, int len)
+static void fdt_nop_region_(void *start, int len)
 {
 	fdt32_t *p;
 
@@ -110,12 +110,12 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
 	if (!prop)
 		return len;
 
-	_fdt_nop_region(prop, len + sizeof(*prop));
+	fdt_nop_region_(prop, len + sizeof(*prop));
 
 	return 0;
 }
 
-int _fdt_node_end_offset(void *fdt, int offset)
+int fdt_node_end_offset_(void *fdt, int offset)
 {
 	int depth = 0;
 
@@ -129,11 +129,11 @@ int fdt_nop_node(void *fdt, int nodeoffset)
 {
 	int endoffset;
 
-	endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+	endoffset = fdt_node_end_offset_(fdt, nodeoffset);
 	if (endoffset < 0)
 		return endoffset;
 
-	_fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
+	fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
 			endoffset - nodeoffset);
 	return 0;
 }
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index 7f83023..1e27780 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -1,5 +1,5 @@
-#ifndef _LIBFDT_H
-#define _LIBFDT_H
+#ifndef LIBFDT_H
+#define LIBFDT_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -54,7 +54,7 @@
 #include "libfdt_env.h"
 #include "fdt.h"
 
-#define FDT_FIRST_SUPPORTED_VERSION	0x10
+#define FDT_FIRST_SUPPORTED_VERSION	0x02
 #define FDT_LAST_SUPPORTED_VERSION	0x11
 
 /* Error codes: informative error codes */
@@ -225,23 +225,23 @@ int fdt_next_subnode(const void *fdt, int offset);
 #define fdt_size_dt_strings(fdt)	(fdt_get_header(fdt, size_dt_strings))
 #define fdt_size_dt_struct(fdt)		(fdt_get_header(fdt, size_dt_struct))
 
-#define __fdt_set_hdr(name) \
+#define fdt_set_hdr_(name) \
 	static inline void fdt_set_##name(void *fdt, uint32_t val) \
 	{ \
 		struct fdt_header *fdth = (struct fdt_header *)fdt; \
 		fdth->name = cpu_to_fdt32(val); \
 	}
-__fdt_set_hdr(magic);
-__fdt_set_hdr(totalsize);
-__fdt_set_hdr(off_dt_struct);
-__fdt_set_hdr(off_dt_strings);
-__fdt_set_hdr(off_mem_rsvmap);
-__fdt_set_hdr(version);
-__fdt_set_hdr(last_comp_version);
-__fdt_set_hdr(boot_cpuid_phys);
-__fdt_set_hdr(size_dt_strings);
-__fdt_set_hdr(size_dt_struct);
-#undef __fdt_set_hdr
+fdt_set_hdr_(magic);
+fdt_set_hdr_(totalsize);
+fdt_set_hdr_(off_dt_struct);
+fdt_set_hdr_(off_dt_strings);
+fdt_set_hdr_(off_mem_rsvmap);
+fdt_set_hdr_(version);
+fdt_set_hdr_(last_comp_version);
+fdt_set_hdr_(boot_cpuid_phys);
+fdt_set_hdr_(size_dt_strings);
+fdt_set_hdr_(size_dt_struct);
+#undef fdt_set_hdr_
 
 /**
  * fdt_check_header - sanity check a device tree or possible device tree
@@ -527,6 +527,9 @@ int fdt_next_property_offset(const void *fdt, int offset);
  * offset.  If lenp is non-NULL, the length of the property value is
  * also returned, in the integer pointed to by lenp.
  *
+ * Note that this code only works on device tree versions >= 16. fdt_getprop()
+ * works on all versions.
+ *
  * returns:
  *	pointer to the structure representing the property
  *		if lenp is non-NULL, *lenp contains the length of the property
@@ -1449,7 +1452,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
 		const void *val, int len);
 
 /**
- * fdt_setprop _placeholder - allocate space for a property
+ * fdt_setprop_placeholder - allocate space for a property
  * @fdt: pointer to the device tree blob
  * @nodeoffset: offset of the node whose property to change
  * @name: name of the property to change
@@ -1896,4 +1899,4 @@ int fdt_overlay_apply(void *fdt, void *fdto);
 
 const char *fdt_strerror(int errval);
 
-#endif /* _LIBFDT_H */
+#endif /* LIBFDT_H */
diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h
index 952056c..bd24746 100644
--- a/scripts/dtc/libfdt/libfdt_env.h
+++ b/scripts/dtc/libfdt/libfdt_env.h
@@ -1,5 +1,5 @@
-#ifndef _LIBFDT_ENV_H
-#define _LIBFDT_ENV_H
+#ifndef LIBFDT_ENV_H
+#define LIBFDT_ENV_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -109,4 +109,31 @@ static inline fdt64_t cpu_to_fdt64(uint64_t x)
 #undef CPU_TO_FDT16
 #undef EXTRACT_BYTE
 
-#endif /* _LIBFDT_ENV_H */
+#ifdef __APPLE__
+#include <AvailabilityMacros.h>
+
+/* strnlen() is not available on Mac OS < 10.7 */
+# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \
+                                         MAC_OS_X_VERSION_10_7)
+
+#define strnlen fdt_strnlen
+
+/*
+ * fdt_strnlen: returns the length of a string or max_count - which ever is
+ * smallest.
+ * Input 1 string: the string whose size is to be determined
+ * Input 2 max_count: the maximum value returned by this function
+ * Output: length of the string or max_count (the smallest of the two)
+ */
+static inline size_t fdt_strnlen(const char *string, size_t max_count)
+{
+    const char *p = memchr(string, 0, max_count);
+    return p ? p - string : max_count;
+}
+
+#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED <
+          MAC_OS_X_VERSION_10_7) */
+
+#endif /* __APPLE__ */
+
+#endif /* LIBFDT_ENV_H */
diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h
index 02cfa6f..7681e19 100644
--- a/scripts/dtc/libfdt/libfdt_internal.h
+++ b/scripts/dtc/libfdt/libfdt_internal.h
@@ -1,5 +1,5 @@
-#ifndef _LIBFDT_INTERNAL_H
-#define _LIBFDT_INTERNAL_H
+#ifndef LIBFDT_INTERNAL_H
+#define LIBFDT_INTERNAL_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -57,27 +57,27 @@
 
 #define FDT_CHECK_HEADER(fdt) \
 	{ \
-		int __err; \
-		if ((__err = fdt_check_header(fdt)) != 0) \
-			return __err; \
+		int err_; \
+		if ((err_ = fdt_check_header(fdt)) != 0) \
+			return err_; \
 	}
 
-int _fdt_check_node_offset(const void *fdt, int offset);
-int _fdt_check_prop_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
+int fdt_check_node_offset_(const void *fdt, int offset);
+int fdt_check_prop_offset_(const void *fdt, int offset);
+const char *fdt_find_string_(const char *strtab, int tabsize, const char *s);
+int fdt_node_end_offset_(void *fdt, int nodeoffset);
 
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
+static inline const void *fdt_offset_ptr_(const void *fdt, int offset)
 {
 	return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
 }
 
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
+static inline void *fdt_offset_ptr_w_(void *fdt, int offset)
 {
-	return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
+	return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset);
 }
 
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
+static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n)
 {
 	const struct fdt_reserve_entry *rsv_table =
 		(const struct fdt_reserve_entry *)
@@ -85,11 +85,11 @@ static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int
 
 	return rsv_table + n;
 }
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
+static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)
 {
-	return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
+	return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n);
 }
 
 #define FDT_SW_MAGIC		(~FDT_MAGIC)
 
-#endif /* _LIBFDT_INTERNAL_H */
+#endif /* LIBFDT_INTERNAL_H */
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 6846ad2f..57b7db2 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -216,7 +216,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
 	return old_node;
 }
 
-void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
+struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
 {
 	static unsigned int next_orphan_fragment = 0;
 	struct node *node;
@@ -236,6 +236,7 @@ void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
 	name_node(node, name);
 
 	add_child(dt, node);
+	return dt;
 }
 
 struct node *chain_node(struct node *first, struct node *list)
@@ -507,7 +508,7 @@ struct node *get_node_by_path(struct node *tree, const char *path)
 
 	for_each_child(tree, child) {
 		if (p && (strlen(child->name) == p-path) &&
-				strneq(path, child->name, p-path))
+		    strprefixeq(path, p - path, child->name))
 			return get_node_by_path(child, p+1);
 		else if (!p && streq(path, child->name))
 			return child;
@@ -540,7 +541,10 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
 {
 	struct node *child, *node;
 
-	assert((phandle != 0) && (phandle != -1));
+	if ((phandle == 0) || (phandle == -1)) {
+		assert(generate_fixups);
+		return NULL;
+	}
 
 	if (tree->phandle == phandle) {
 		if (tree->deleted)
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index 9d38459..cb6ed0e 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -209,8 +209,6 @@ struct srcpos srcpos_empty = {
 	.file = NULL,
 };
 
-#define TAB_SIZE      8
-
 void srcpos_update(struct srcpos *pos, const char *text, int len)
 {
 	int i;
@@ -224,9 +222,6 @@ void srcpos_update(struct srcpos *pos, const char *text, int len)
 		if (text[i] == '\n') {
 			current_srcfile->lineno++;
 			current_srcfile->colno = 1;
-		} else if (text[i] == '\t') {
-			current_srcfile->colno =
-				ALIGN(current_srcfile->colno, TAB_SIZE);
 		} else {
 			current_srcfile->colno++;
 		}
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index 7caca82..9ded12a 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -17,8 +17,8 @@
  *                                                                   USA
  */
 
-#ifndef _SRCPOS_H_
-#define _SRCPOS_H_
+#ifndef SRCPOS_H
+#define SRCPOS_H
 
 #include <stdio.h>
 #include <stdbool.h>
@@ -114,4 +114,4 @@ extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix,
 
 extern void srcpos_set_line(char *f, int l);
 
-#endif /* _SRCPOS_H_ */
+#endif /* SRCPOS_H */
diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh
index fe8926b..1a009fd 100755
--- a/scripts/dtc/update-dtc-source.sh
+++ b/scripts/dtc/update-dtc-source.sh
@@ -4,7 +4,7 @@
 #
 # This script assumes that the dtc and the linux git trees are in the
 # same directory. After building dtc in the dtc directory, it copies the
-# source files and generated source files into the scripts/dtc directory
+# source files and generated source file(s) into the scripts/dtc directory
 # in the kernel and creates a git commit updating them to the new
 # version.
 #
@@ -34,7 +34,6 @@
 DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \
 		srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \
 		dtc-lexer.l dtc-parser.y"
-DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h"
 LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \
 		fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \
 		fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
@@ -59,10 +58,6 @@
 	cp ${DTC_UPSTREAM_PATH}/${f} ${f}
 	git add ${f}
 done
-for f in $DTC_GENERATED; do
-	cp ${DTC_UPSTREAM_PATH}/$f ${f}_shipped
-	git add ${f}_shipped
-done
 for f in $LIBFDT_SOURCE; do
        cp ${DTC_UPSTREAM_PATH}/libfdt/${f} libfdt/${f}
        git add libfdt/${f}
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
index ad5f411..66fba8e 100644
--- a/scripts/dtc/util.h
+++ b/scripts/dtc/util.h
@@ -1,5 +1,5 @@
-#ifndef _UTIL_H
-#define _UTIL_H
+#ifndef UTIL_H
+#define UTIL_H
 
 #include <stdarg.h>
 #include <stdbool.h>
@@ -35,6 +35,9 @@
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
+#define stringify(s)	stringify_(s)
+#define stringify_(s)	#s
+
 static inline void NORETURN PRINTF(1, 2) die(const char *str, ...)
 {
 	va_list ap;
@@ -260,4 +263,4 @@ void NORETURN util_usage(const char *errmsg, const char *synopsis,
 	case 'V': util_version(); \
 	case '?': usage("unknown option");
 
-#endif /* _UTIL_H */
+#endif /* UTIL_H */
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 6a4e847..ad87849 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.5-gc1e55a55"
+#define DTC_VERSION "DTC 1.4.6-gaadd0b65"
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
index dbe6efd..5fa1912 100644
--- a/security/loadpin/loadpin.c
+++ b/security/loadpin/loadpin.c
@@ -19,7 +19,6 @@
 
 #include <linux/module.h>
 #include <linux/fs.h>
-#include <linux/fs_struct.h>
 #include <linux/lsm_hooks.h>
 #include <linux/mount.h>
 #include <linux/path.h>
diff --git a/sound/core/control.c b/sound/core/control.c
index 8a77620..69734b0 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -105,7 +105,7 @@ static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl)
 {
 	unsigned long flags;
 	struct snd_kctl_event *cread;
-	
+
 	spin_lock_irqsave(&ctl->read_lock, flags);
 	while (!list_empty(&ctl->events)) {
 		cread = snd_kctl_event(ctl->events.next);
@@ -159,7 +159,7 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
 	unsigned long flags;
 	struct snd_ctl_file *ctl;
 	struct snd_kctl_event *ev;
-	
+
 	if (snd_BUG_ON(!card || !id))
 		return;
 	if (card->shutdown)
@@ -213,7 +213,7 @@ static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count,
 {
 	unsigned int size;
 	unsigned int idx;
-	
+
 	if (count == 0 || count > MAX_CONTROL_COUNT)
 		return -EINVAL;
 
@@ -238,7 +238,7 @@ static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count,
  * @ncontrol: the initialization record
  * @private_data: the private data to set
  *
- * Allocates a new struct snd_kcontrol instance and initialize from the given 
+ * Allocates a new struct snd_kcontrol instance and initialize from the given
  * template.  When the access field of ncontrol is 0, it's assumed as
  * READWRITE access. When the count field is 0, it's assumes as one.
  *
@@ -251,7 +251,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
 	unsigned int count;
 	unsigned int access;
 	int err;
-	
+
 	if (snd_BUG_ON(!ncontrol || !ncontrol->info))
 		return NULL;
 
@@ -753,7 +753,7 @@ static int snd_ctl_elem_list(struct snd_card *card,
 	struct snd_ctl_elem_id id;
 	unsigned int offset, space, jidx;
 	int err = 0;
-	
+
 	if (copy_from_user(&list, _list, sizeof(list)))
 		return -EFAULT;
 	offset = list.offset;
@@ -827,7 +827,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
 	struct snd_kcontrol_volatile *vd;
 	unsigned int index_offset;
 	int result;
-	
+
 	down_read(&card->controls_rwsem);
 	kctl = snd_ctl_find_id(card, &info->id);
 	if (kctl == NULL) {
@@ -992,7 +992,7 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file,
 	struct snd_kcontrol *kctl;
 	struct snd_kcontrol_volatile *vd;
 	int result;
-	
+
 	if (copy_from_user(&id, _id, sizeof(id)))
 		return -EFAULT;
 	down_write(&card->controls_rwsem);
@@ -1020,7 +1020,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
 	struct snd_kcontrol *kctl;
 	struct snd_kcontrol_volatile *vd;
 	int result;
-	
+
 	if (copy_from_user(&id, _id, sizeof(id)))
 		return -EFAULT;
 	down_write(&card->controls_rwsem);
diff --git a/sound/core/init.c b/sound/core/init.c
index 4fa5dd9..79b4df1c 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -670,7 +670,7 @@ card_id_show_attr(struct device *dev,
 		  struct device_attribute *attr, char *buf)
 {
 	struct snd_card *card = container_of(dev, struct snd_card, card_dev);
-	return snprintf(buf, PAGE_SIZE, "%s\n", card->id);
+	return scnprintf(buf, PAGE_SIZE, "%s\n", card->id);
 }
 
 static ssize_t
@@ -710,7 +710,7 @@ card_number_show_attr(struct device *dev,
 		     struct device_attribute *attr, char *buf)
 {
 	struct snd_card *card = container_of(dev, struct snd_card, card_dev);
-	return snprintf(buf, PAGE_SIZE, "%i\n", card->number);
+	return scnprintf(buf, PAGE_SIZE, "%i\n", card->number);
 }
 
 static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 4414050..481ab0e 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -823,8 +823,25 @@ static int choose_rate(struct snd_pcm_substream *substream,
 	return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
 }
 
-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
-				     bool trylock)
+/* parameter locking: returns immediately if tried during streaming */
+static int lock_params(struct snd_pcm_runtime *runtime)
+{
+	if (mutex_lock_interruptible(&runtime->oss.params_lock))
+		return -ERESTARTSYS;
+	if (atomic_read(&runtime->oss.rw_ref)) {
+		mutex_unlock(&runtime->oss.params_lock);
+		return -EBUSY;
+	}
+	return 0;
+}
+
+static void unlock_params(struct snd_pcm_runtime *runtime)
+{
+	mutex_unlock(&runtime->oss.params_lock);
+}
+
+/* call with params_lock held */
+static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_hw_params *params, *sparams;
@@ -838,11 +855,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
 	const struct snd_mask *sformat_mask;
 	struct snd_mask mask;
 
-	if (trylock) {
-		if (!(mutex_trylock(&runtime->oss.params_lock)))
-			return -EAGAIN;
-	} else if (mutex_lock_interruptible(&runtime->oss.params_lock))
-		return -ERESTARTSYS;
+	if (!runtime->oss.params)
+		return 0;
 	sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL);
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
 	sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
@@ -1068,6 +1082,23 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
 	kfree(sw_params);
 	kfree(params);
 	kfree(sparams);
+	return err;
+}
+
+/* this one takes the lock by itself */
+static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
+				     bool trylock)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int err;
+
+	if (trylock) {
+		if (!(mutex_trylock(&runtime->oss.params_lock)))
+			return -EAGAIN;
+	} else if (mutex_lock_interruptible(&runtime->oss.params_lock))
+		return -ERESTARTSYS;
+
+	err = snd_pcm_oss_change_params_locked(substream);
 	mutex_unlock(&runtime->oss.params_lock);
 	return err;
 }
@@ -1096,11 +1127,14 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil
 	return 0;
 }
 
+/* call with params_lock held */
 static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
 {
 	int err;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
+	if (!runtime->oss.prepare)
+		return 0;
 	err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
 	if (err < 0) {
 		pcm_dbg(substream->pcm,
@@ -1120,8 +1154,6 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime;
 	int err;
 
-	if (substream == NULL)
-		return 0;
 	runtime = substream->runtime;
 	if (runtime->oss.params) {
 		err = snd_pcm_oss_change_params(substream, false);
@@ -1129,6 +1161,29 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
 			return err;
 	}
 	if (runtime->oss.prepare) {
+		if (mutex_lock_interruptible(&runtime->oss.params_lock))
+			return -ERESTARTSYS;
+		err = snd_pcm_oss_prepare(substream);
+		mutex_unlock(&runtime->oss.params_lock);
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+/* call with params_lock held */
+static int snd_pcm_oss_make_ready_locked(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime;
+	int err;
+
+	runtime = substream->runtime;
+	if (runtime->oss.params) {
+		err = snd_pcm_oss_change_params_locked(substream);
+		if (err < 0)
+			return err;
+	}
+	if (runtime->oss.prepare) {
 		err = snd_pcm_oss_prepare(substream);
 		if (err < 0)
 			return err;
@@ -1332,13 +1387,15 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
 	if (atomic_read(&substream->mmap_count))
 		return -ENXIO;
 
-	if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
-		return tmp;
+	atomic_inc(&runtime->oss.rw_ref);
 	while (bytes > 0) {
 		if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
 			tmp = -ERESTARTSYS;
 			break;
 		}
+		tmp = snd_pcm_oss_make_ready_locked(substream);
+		if (tmp < 0)
+			goto err;
 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
 			tmp = bytes;
 			if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
@@ -1394,6 +1451,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
 		}
 		tmp = 0;
 	}
+	atomic_dec(&runtime->oss.rw_ref);
 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 }
 
@@ -1439,13 +1497,15 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
 	if (atomic_read(&substream->mmap_count))
 		return -ENXIO;
 
-	if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
-		return tmp;
+	atomic_inc(&runtime->oss.rw_ref);
 	while (bytes > 0) {
 		if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
 			tmp = -ERESTARTSYS;
 			break;
 		}
+		tmp = snd_pcm_oss_make_ready_locked(substream);
+		if (tmp < 0)
+			goto err;
 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
 			if (runtime->oss.buffer_used == 0) {
 				tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1486,6 +1546,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
 		}
 		tmp = 0;
 	}
+	atomic_dec(&runtime->oss.rw_ref);
 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 }
 
@@ -1501,10 +1562,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
 			continue;
 		runtime = substream->runtime;
 		snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
+		mutex_lock(&runtime->oss.params_lock);
 		runtime->oss.prepare = 1;
 		runtime->oss.buffer_used = 0;
 		runtime->oss.prev_hw_ptr_period = 0;
 		runtime->oss.period_ptr = 0;
+		mutex_unlock(&runtime->oss.params_lock);
 	}
 	return 0;
 }
@@ -1590,9 +1653,13 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
 			goto __direct;
 		if ((err = snd_pcm_oss_make_ready(substream)) < 0)
 			return err;
+		atomic_inc(&runtime->oss.rw_ref);
+		if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+			atomic_dec(&runtime->oss.rw_ref);
+			return -ERESTARTSYS;
+		}
 		format = snd_pcm_oss_format_from(runtime->oss.format);
 		width = snd_pcm_format_physical_width(format);
-		mutex_lock(&runtime->oss.params_lock);
 		if (runtime->oss.buffer_used > 0) {
 #ifdef OSS_DEBUG
 			pcm_dbg(substream->pcm, "sync: buffer_used\n");
@@ -1602,10 +1669,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
 						   runtime->oss.buffer + runtime->oss.buffer_used,
 						   size);
 			err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes);
-			if (err < 0) {
-				mutex_unlock(&runtime->oss.params_lock);
-				return err;
-			}
+			if (err < 0)
+				goto unlock;
 		} else if (runtime->oss.period_ptr > 0) {
 #ifdef OSS_DEBUG
 			pcm_dbg(substream->pcm, "sync: period_ptr\n");
@@ -1615,10 +1680,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
 						   runtime->oss.buffer,
 						   size * 8 / width);
 			err = snd_pcm_oss_sync1(substream, size);
-			if (err < 0) {
-				mutex_unlock(&runtime->oss.params_lock);
-				return err;
-			}
+			if (err < 0)
+				goto unlock;
 		}
 		/*
 		 * The ALSA's period might be a bit large than OSS one.
@@ -1632,7 +1695,11 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
 			else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
 				snd_pcm_lib_writev(substream, NULL, size);
 		}
+unlock:
 		mutex_unlock(&runtime->oss.params_lock);
+		atomic_dec(&runtime->oss.rw_ref);
+		if (err < 0)
+			return err;
 		/*
 		 * finish sync: drain the buffer
 		 */
@@ -1643,7 +1710,9 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
 		substream->f_flags = saved_f_flags;
 		if (err < 0)
 			return err;
+		mutex_lock(&runtime->oss.params_lock);
 		runtime->oss.prepare = 1;
+		mutex_unlock(&runtime->oss.params_lock);
 	}
 
 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
@@ -1654,8 +1723,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
 		err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
 		if (err < 0)
 			return err;
+		mutex_lock(&runtime->oss.params_lock);
 		runtime->oss.buffer_used = 0;
 		runtime->oss.prepare = 1;
+		mutex_unlock(&runtime->oss.params_lock);
 	}
 	return 0;
 }
@@ -1667,6 +1738,8 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate)
 	for (idx = 1; idx >= 0; --idx) {
 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
 		struct snd_pcm_runtime *runtime;
+		int err;
+
 		if (substream == NULL)
 			continue;
 		runtime = substream->runtime;
@@ -1674,10 +1747,14 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate)
 			rate = 1000;
 		else if (rate > 192000)
 			rate = 192000;
+		err = lock_params(runtime);
+		if (err < 0)
+			return err;
 		if (runtime->oss.rate != rate) {
 			runtime->oss.params = 1;
 			runtime->oss.rate = rate;
 		}
+		unlock_params(runtime);
 	}
 	return snd_pcm_oss_get_rate(pcm_oss_file);
 }
@@ -1702,13 +1779,19 @@ static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsig
 	for (idx = 1; idx >= 0; --idx) {
 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
 		struct snd_pcm_runtime *runtime;
+		int err;
+
 		if (substream == NULL)
 			continue;
 		runtime = substream->runtime;
+		err = lock_params(runtime);
+		if (err < 0)
+			return err;
 		if (runtime->oss.channels != channels) {
 			runtime->oss.params = 1;
 			runtime->oss.channels = channels;
 		}
+		unlock_params(runtime);
 	}
 	return snd_pcm_oss_get_channels(pcm_oss_file);
 }
@@ -1781,6 +1864,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
 static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)
 {
 	int formats, idx;
+	int err;
 	
 	if (format != AFMT_QUERY) {
 		formats = snd_pcm_oss_get_formats(pcm_oss_file);
@@ -1794,10 +1878,14 @@ static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int for
 			if (substream == NULL)
 				continue;
 			runtime = substream->runtime;
+			err = lock_params(runtime);
+			if (err < 0)
+				return err;
 			if (runtime->oss.format != format) {
 				runtime->oss.params = 1;
 				runtime->oss.format = format;
 			}
+			unlock_params(runtime);
 		}
 	}
 	return snd_pcm_oss_get_format(pcm_oss_file);
@@ -1817,8 +1905,6 @@ static int snd_pcm_oss_set_subdivide1(struct snd_pcm_substream *substream, int s
 {
 	struct snd_pcm_runtime *runtime;
 
-	if (substream == NULL)
-		return 0;
 	runtime = substream->runtime;
 	if (subdivide == 0) {
 		subdivide = runtime->oss.subdivision;
@@ -1842,9 +1928,17 @@ static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int
 
 	for (idx = 1; idx >= 0; --idx) {
 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_runtime *runtime;
+
 		if (substream == NULL)
 			continue;
-		if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0)
+		runtime = substream->runtime;
+		err = lock_params(runtime);
+		if (err < 0)
+			return err;
+		err = snd_pcm_oss_set_subdivide1(substream, subdivide);
+		unlock_params(runtime);
+		if (err < 0)
 			return err;
 	}
 	return err;
@@ -1854,8 +1948,6 @@ static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsign
 {
 	struct snd_pcm_runtime *runtime;
 
-	if (substream == NULL)
-		return 0;
 	runtime = substream->runtime;
 	if (runtime->oss.subdivision || runtime->oss.fragshift)
 		return -EINVAL;
@@ -1875,9 +1967,17 @@ static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsig
 
 	for (idx = 1; idx >= 0; --idx) {
 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_runtime *runtime;
+
 		if (substream == NULL)
 			continue;
-		if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0)
+		runtime = substream->runtime;
+		err = lock_params(runtime);
+		if (err < 0)
+			return err;
+		err = snd_pcm_oss_set_fragment1(substream, val);
+		unlock_params(runtime);
+		if (err < 0)
 			return err;
 	}
 	return err;
@@ -1961,6 +2061,9 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
 	}
       	if (psubstream) {
       		runtime = psubstream->runtime;
+		cmd = 0;
+		if (mutex_lock_interruptible(&runtime->oss.params_lock))
+			return -ERESTARTSYS;
 		if (trigger & PCM_ENABLE_OUTPUT) {
 			if (runtime->oss.trigger)
 				goto _skip1;
@@ -1978,13 +2081,19 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
 			cmd = SNDRV_PCM_IOCTL_DROP;
 			runtime->oss.prepare = 1;
 		}
-		err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
-		if (err < 0)
-			return err;
-	}
  _skip1:
+		mutex_unlock(&runtime->oss.params_lock);
+		if (cmd) {
+			err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
+			if (err < 0)
+				return err;
+		}
+	}
 	if (csubstream) {
       		runtime = csubstream->runtime;
+		cmd = 0;
+		if (mutex_lock_interruptible(&runtime->oss.params_lock))
+			return -ERESTARTSYS;
 		if (trigger & PCM_ENABLE_INPUT) {
 			if (runtime->oss.trigger)
 				goto _skip2;
@@ -1999,11 +2108,14 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
 			cmd = SNDRV_PCM_IOCTL_DROP;
 			runtime->oss.prepare = 1;
 		}
-		err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
-		if (err < 0)
-			return err;
-	}
  _skip2:
+		mutex_unlock(&runtime->oss.params_lock);
+		if (cmd) {
+			err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
+			if (err < 0)
+				return err;
+		}
+	}
 	return 0;
 }
 
@@ -2255,6 +2367,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
 	runtime->oss.maxfrags = 0;
 	runtime->oss.subdivision = 0;
 	substream->pcm_release = snd_pcm_oss_release_substream;
+	atomic_set(&runtime->oss.rw_ref, 0);
 }
 
 static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 09ee8c6..66ac89a 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -28,6 +28,7 @@
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/pcm.h>
+#include <sound/timer.h>
 #include <sound/control.h>
 #include <sound/info.h>
 
@@ -1054,8 +1055,13 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
 	snd_free_pages((void*)runtime->control,
 		       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
 	kfree(runtime->hw_constraints.rules);
-	kfree(runtime);
+	/* Avoid concurrent access to runtime via PCM timer interface */
+	if (substream->timer)
+		spin_lock_irq(&substream->timer->lock);
 	substream->runtime = NULL;
+	if (substream->timer)
+		spin_unlock_irq(&substream->timer->lock);
+	kfree(runtime);
 	put_pid(substream->pid);
 	substream->pid = NULL;
 	substream->pstr->substream_opened--;
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a83152e..f4a1950 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1129,16 +1129,12 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
 	if (constrs->rules_num >= constrs->rules_all) {
 		struct snd_pcm_hw_rule *new;
 		unsigned int new_rules = constrs->rules_all + 16;
-		new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
+		new = krealloc(constrs->rules, new_rules * sizeof(*c),
+			       GFP_KERNEL);
 		if (!new) {
 			va_end(args);
 			return -ENOMEM;
 		}
-		if (constrs->rules) {
-			memcpy(new, constrs->rules,
-			       constrs->rules_num * sizeof(*c));
-			kfree(constrs->rules);
-		}
 		constrs->rules = new;
 		constrs->rules_all = new_rules;
 	}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index d18b398..b845548 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -323,7 +323,7 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_constraints *constrs =
 					&substream->runtime->hw_constraints;
 	unsigned int k;
-	unsigned int rstamps[constrs->rules_num];
+	unsigned int *rstamps;
 	unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1];
 	unsigned int stamp;
 	struct snd_pcm_hw_rule *r;
@@ -331,7 +331,7 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream,
 	struct snd_mask old_mask;
 	struct snd_interval old_interval;
 	bool again;
-	int changed;
+	int changed, err = 0;
 
 	/*
 	 * Each application of rule has own sequence number.
@@ -339,8 +339,9 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream,
 	 * Each member of 'rstamps' array represents the sequence number of
 	 * recent application of corresponding rule.
 	 */
-	for (k = 0; k < constrs->rules_num; k++)
-		rstamps[k] = 0;
+	rstamps = kcalloc(constrs->rules_num, sizeof(unsigned int), GFP_KERNEL);
+	if (!rstamps)
+		return -ENOMEM;
 
 	/*
 	 * Each member of 'vstamps' array represents the sequence number of
@@ -398,8 +399,10 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream,
 		}
 
 		changed = r->func(params, r);
-		if (changed < 0)
-			return changed;
+		if (changed < 0) {
+			err = changed;
+			goto out;
+		}
 
 		/*
 		 * When the parameter is changed, notify it to the caller
@@ -430,7 +433,9 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream,
 	if (again)
 		goto retry;
 
-	return 0;
+ out:
+	kfree(rstamps);
+	return err;
 }
 
 static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 8632301..9e96186 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -63,15 +63,18 @@ static int slave_update(struct link_slave *slave)
 	struct snd_ctl_elem_value *uctl;
 	int err, ch;
 
-	uctl = kmalloc(sizeof(*uctl), GFP_KERNEL);
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (!uctl)
 		return -ENOMEM;
 	uctl->id = slave->slave.id;
 	err = slave->slave.get(&slave->slave, uctl);
+	if (err < 0)
+		goto error;
 	for (ch = 0; ch < slave->info.count; ch++)
 		slave->vals[ch] = uctl->value.integer.value[ch];
+ error:
 	kfree(uctl);
-	return 0;
+	return err < 0 ? err : 0;
 }
 
 /* get the slave ctl info and save the initial values */
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 1063a43..58e349f 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -296,6 +296,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
 		cable->pause |= stream;
 		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_RELEASE:
 	case SNDRV_PCM_TRIGGER_RESUME:
@@ -304,6 +306,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
 		cable->pause &= ~stream;
 		loopback_timer_start(dpcm);
 		spin_unlock(&cable->lock);
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			loopback_active_notify(dpcm);
 		break;
 	default:
 		return -EINVAL;
@@ -892,9 +896,11 @@ static int loopback_active_get(struct snd_kcontrol *kcontrol,
 			[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
 	unsigned int val = 0;
 
-	if (cable != NULL)
-		val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
-									1 : 0;
+	if (cable != NULL) {
+		unsigned int running = cable->running ^ cable->pause;
+
+		val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0;
+	}
 	ucontrol->value.integer.value[0] = val;
 	return 0;
 }
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index 06f845e..7ba100b 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -3,6 +3,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -1064,3 +1065,37 @@ bool snd_hdac_check_power_state(struct hdac_device *hdac,
 	return (state == target_state);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_check_power_state);
+/**
+ * snd_hdac_sync_power_state - wait until actual power state matches
+ * with the target state
+ *
+ * @hdac: the HDAC device
+ * @nid: NID to send the command
+ * @target_state: target state to check for
+ *
+ * Return power state or PS_ERROR if codec rejects GET verb.
+ */
+unsigned int snd_hdac_sync_power_state(struct hdac_device *codec,
+			hda_nid_t nid, unsigned int power_state)
+{
+	unsigned long end_time = jiffies + msecs_to_jiffies(500);
+	unsigned int state, actual_state, count;
+
+	for (count = 0; count < 500; count++) {
+		state = snd_hdac_codec_read(codec, nid, 0,
+				AC_VERB_GET_POWER_STATE, 0);
+		if (state & AC_PWRST_ERROR) {
+			msleep(20);
+			break;
+		}
+		actual_state = (state >> 4) & 0x0f;
+		if (actual_state == power_state)
+			break;
+		if (time_after_eq(jiffies, end_time))
+			break;
+		/* wait until the codec reachs to the target state */
+		msleep(1);
+	}
+	return state;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_sync_power_state);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index d68f99e..0935a5c 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -736,8 +736,7 @@ static int pcm_prepare(struct snd_pcm_substream *substream)
 static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct echoaudio *chip = snd_pcm_substream_chip(substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct audiopipe *pipe = runtime->private_data;
+	struct audiopipe *pipe;
 	int i, err;
 	u32 channelmask = 0;
 	struct snd_pcm_substream *s;
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index ccf4415..18267de 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/iommu.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
@@ -1272,12 +1273,6 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
 	release_firmware(emu->dock_fw);
 	if (emu->irq >= 0)
 		free_irq(emu->irq, emu);
-	/* remove reserved page */
-	if (emu->reserved_page) {
-		snd_emu10k1_synth_free(emu,
-			(struct snd_util_memblk *)emu->reserved_page);
-		emu->reserved_page = NULL;
-	}
 	snd_util_memhdr_free(emu->memhdr);
 	if (emu->silent_page.area)
 		snd_dma_free_pages(&emu->silent_page);
@@ -1764,6 +1759,38 @@ static struct snd_emu_chip_details emu_chip_details[] = {
 	{ } /* terminator */
 };
 
+/*
+ * The chip (at least the Audigy 2 CA0102 chip, but most likely others, too)
+ * has a problem that from time to time it likes to do few DMA reads a bit
+ * beyond its normal allocation and gets very confused if these reads get
+ * blocked by a IOMMU.
+ *
+ * This behaviour has been observed for the first (reserved) page
+ * (for which it happens multiple times at every playback), often for various
+ * synth pages and sometimes for PCM playback buffers and the page table
+ * memory itself.
+ *
+ * As a workaround let's widen these DMA allocations by an extra page if we
+ * detect that the device is behind a non-passthrough IOMMU.
+ */
+static void snd_emu10k1_detect_iommu(struct snd_emu10k1 *emu)
+{
+	struct iommu_domain *domain;
+
+	emu->iommu_workaround = false;
+
+	if (!iommu_present(emu->card->dev->bus))
+		return;
+
+	domain = iommu_get_domain_for_dev(emu->card->dev);
+	if (domain && domain->type == IOMMU_DOMAIN_IDENTITY)
+		return;
+
+	dev_notice(emu->card->dev,
+		   "non-passthrough IOMMU detected, widening DMA allocations");
+	emu->iommu_workaround = true;
+}
+
 int snd_emu10k1_create(struct snd_card *card,
 		       struct pci_dev *pci,
 		       unsigned short extin_mask,
@@ -1776,6 +1803,7 @@ int snd_emu10k1_create(struct snd_card *card,
 	struct snd_emu10k1 *emu;
 	int idx, err;
 	int is_audigy;
+	size_t page_table_size;
 	unsigned int silent_page;
 	const struct snd_emu_chip_details *c;
 	static struct snd_device_ops ops = {
@@ -1873,12 +1901,13 @@ int snd_emu10k1_create(struct snd_card *card,
 
 	is_audigy = emu->audigy = c->emu10k2_chip;
 
+	snd_emu10k1_detect_iommu(emu);
+
 	/* set addressing mode */
 	emu->address_mode = is_audigy ? 0 : 1;
 	/* set the DMA transfer mask */
 	emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK;
-	if (dma_set_mask(&pci->dev, emu->dma_mask) < 0 ||
-	    dma_set_coherent_mask(&pci->dev, emu->dma_mask) < 0) {
+	if (dma_set_mask_and_coherent(&pci->dev, emu->dma_mask) < 0) {
 		dev_err(card->dev,
 			"architecture does not support PCI busmaster DMA with mask 0x%lx\n",
 			emu->dma_mask);
@@ -1900,11 +1929,17 @@ int snd_emu10k1_create(struct snd_card *card,
 	emu->port = pci_resource_start(pci, 0);
 
 	emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
-	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-				(emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) {
+
+	page_table_size = sizeof(u32) * (emu->address_mode ? MAXPAGES1 :
+					 MAXPAGES0);
+	if (snd_emu10k1_alloc_pages_maybe_wider(emu, page_table_size,
+						&emu->ptb_pages) < 0) {
 		err = -ENOMEM;
 		goto error;
 	}
+	dev_dbg(card->dev, "page table address range is %.8lx:%.8lx\n",
+		(unsigned long)emu->ptb_pages.addr,
+		(unsigned long)(emu->ptb_pages.addr + emu->ptb_pages.bytes));
 
 	emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *));
 	emu->page_addr_table = vmalloc(emu->max_cache_pages *
@@ -1914,11 +1949,16 @@ int snd_emu10k1_create(struct snd_card *card,
 		goto error;
 	}
 
-	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-				EMUPAGESIZE, &emu->silent_page) < 0) {
+	if (snd_emu10k1_alloc_pages_maybe_wider(emu, EMUPAGESIZE,
+						&emu->silent_page) < 0) {
 		err = -ENOMEM;
 		goto error;
 	}
+	dev_dbg(card->dev, "silent page range is %.8lx:%.8lx\n",
+		(unsigned long)emu->silent_page.addr,
+		(unsigned long)(emu->silent_page.addr +
+				emu->silent_page.bytes));
+
 	emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
 	if (emu->memhdr == NULL) {
 		err = -ENOMEM;
@@ -1993,13 +2033,8 @@ int snd_emu10k1_create(struct snd_card *card,
 		SPCS_GENERATIONSTATUS | 0x00001200 |
 		0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
 
-	emu->reserved_page = (struct snd_emu10k1_memblk *)
-		snd_emu10k1_synth_alloc(emu, 4096);
-	if (emu->reserved_page)
-		emu->reserved_page->map_locked = 1;
-
 	/* Clear silent pages and set up pointers */
-	memset(emu->silent_page.area, 0, PAGE_SIZE);
+	memset(emu->silent_page.area, 0, emu->silent_page.bytes);
 	silent_page = emu->silent_page.addr << emu->address_mode;
 	for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++)
 		((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 2683b97..cefe613 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -411,12 +411,20 @@ static int snd_emu10k1_playback_hw_params(struct snd_pcm_substream *substream,
 	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_emu10k1_pcm *epcm = runtime->private_data;
+	size_t alloc_size;
 	int err;
 
 	if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0)
 		return err;
-	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
+
+	alloc_size = params_buffer_bytes(hw_params);
+	if (emu->iommu_workaround)
+		alloc_size += EMUPAGESIZE;
+	err = snd_pcm_lib_malloc_pages(substream, alloc_size);
+	if (err < 0)
 		return err;
+	if (emu->iommu_workaround && runtime->dma_bytes >= EMUPAGESIZE)
+		runtime->dma_bytes -= EMUPAGESIZE;
 	if (err > 0) {	/* change */
 		int mapped;
 		if (epcm->memblk != NULL)
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 4f1f69b..5865f3b 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -34,7 +34,10 @@
  * aligned pages in others
  */
 #define __set_ptb_entry(emu,page,addr) \
-	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page)))
+	(((__le32 *)(emu)->ptb_pages.area)[page] = \
+	 cpu_to_le32(((addr) << (emu->address_mode)) | (page)))
+#define __get_ptb_entry(emu, page) \
+	(le32_to_cpu(((__le32 *)(emu)->ptb_pages.area)[page]))
 
 #define UNIT_PAGES		(PAGE_SIZE / EMUPAGESIZE)
 #define MAX_ALIGN_PAGES0		(MAXPAGES0 / UNIT_PAGES)
@@ -44,8 +47,7 @@
 /* get offset address from aligned page */
 #define aligned_page_offset(page)	((page) << PAGE_SHIFT)
 
-#if PAGE_SIZE == 4096
-/* page size == EMUPAGESIZE */
+#if PAGE_SIZE == EMUPAGESIZE && !IS_ENABLED(CONFIG_DYNAMIC_DEBUG)
 /* fill PTB entrie(s) corresponding to page with addr */
 #define set_ptb_entry(emu,page,addr)	__set_ptb_entry(emu,page,addr)
 /* fill PTB entrie(s) corresponding to page with silence pointer */
@@ -58,6 +60,8 @@ static inline void set_ptb_entry(struct snd_emu10k1 *emu, int page, dma_addr_t a
 	page *= UNIT_PAGES;
 	for (i = 0; i < UNIT_PAGES; i++, page++) {
 		__set_ptb_entry(emu, page, addr);
+		dev_dbg(emu->card->dev, "mapped page %d to entry %.8x\n", page,
+			(unsigned int)__get_ptb_entry(emu, page));
 		addr += EMUPAGESIZE;
 	}
 }
@@ -65,9 +69,12 @@ static inline void set_silent_ptb(struct snd_emu10k1 *emu, int page)
 {
 	int i;
 	page *= UNIT_PAGES;
-	for (i = 0; i < UNIT_PAGES; i++, page++)
+	for (i = 0; i < UNIT_PAGES; i++, page++) {
 		/* do not increment ptr */
 		__set_ptb_entry(emu, page, emu->silent_page.addr);
+		dev_dbg(emu->card->dev, "mapped silent page %d to entry %.8x\n",
+			page, (unsigned int)__get_ptb_entry(emu, page));
+	}
 }
 #endif /* PAGE_SIZE */
 
@@ -102,7 +109,7 @@ static void emu10k1_memblk_init(struct snd_emu10k1_memblk *blk)
  */
 static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct list_head **nextp)
 {
-	int page = 0, found_page = -ENOMEM;
+	int page = 1, found_page = -ENOMEM;
 	int max_size = npages;
 	int size;
 	struct list_head *candidate = &emu->mapped_link_head;
@@ -147,6 +154,10 @@ static int map_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 	page = search_empty_map_area(emu, blk->pages, &next);
 	if (page < 0) /* not found */
 		return page;
+	if (page == 0) {
+		dev_err(emu->card->dev, "trying to map zero (reserved) page\n");
+		return -EINVAL;
+	}
 	/* insert this block in the proper position of mapped list */
 	list_add_tail(&blk->mapped_link, next);
 	/* append this as a newest block in order list */
@@ -177,7 +188,7 @@ static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 		q = get_emu10k1_memblk(p, mapped_link);
 		start_page = q->mapped_page + q->pages;
 	} else
-		start_page = 0;
+		start_page = 1;
 	if ((p = blk->mapped_link.next) != &emu->mapped_link_head) {
 		q = get_emu10k1_memblk(p, mapped_link);
 		end_page = q->mapped_page;
@@ -366,6 +377,33 @@ int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk)
 	return snd_emu10k1_synth_free(emu, blk);
 }
 
+/*
+ * allocate DMA pages, widening the allocation if necessary
+ *
+ * See the comment above snd_emu10k1_detect_iommu() in emu10k1_main.c why
+ * this might be needed.
+ *
+ * If you modify this function check whether __synth_free_pages() also needs
+ * changes.
+ */
+int snd_emu10k1_alloc_pages_maybe_wider(struct snd_emu10k1 *emu, size_t size,
+					struct snd_dma_buffer *dmab)
+{
+	if (emu->iommu_workaround) {
+		size_t npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+		size_t size_real = npages * PAGE_SIZE;
+
+		/*
+		 * The device has been observed to accesses up to 256 extra
+		 * bytes, but use 1k to be safe.
+		 */
+		if (size_real < size + 1024)
+			size += PAGE_SIZE;
+	}
+
+	return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+				   snd_dma_pci_data(emu->pci), size, dmab);
+}
 
 /*
  * memory allocation using multiple pages (for synth)
@@ -450,10 +488,27 @@ static void get_single_page_range(struct snd_util_memhdr *hdr,
 static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page,
 			       int last_page)
 {
+	struct snd_dma_buffer dmab;
 	int page;
 
+	dmab.dev.type = SNDRV_DMA_TYPE_DEV;
+	dmab.dev.dev = snd_dma_pci_data(emu->pci);
+
 	for (page = first_page; page <= last_page; page++) {
-		free_page((unsigned long)emu->page_ptr_table[page]);
+		if (emu->page_ptr_table[page] == NULL)
+			continue;
+		dmab.area = emu->page_ptr_table[page];
+		dmab.addr = emu->page_addr_table[page];
+
+		/*
+		 * please keep me in sync with logic in
+		 * snd_emu10k1_alloc_pages_maybe_wider()
+		 */
+		dmab.bytes = PAGE_SIZE;
+		if (emu->iommu_workaround)
+			dmab.bytes *= 2;
+
+		snd_dma_free_pages(&dmab);
 		emu->page_addr_table[page] = 0;
 		emu->page_ptr_table[page] = NULL;
 	}
@@ -465,30 +520,30 @@ static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page,
 static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 {
 	int page, first_page, last_page;
+	struct snd_dma_buffer dmab;
 
 	emu10k1_memblk_init(blk);
 	get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
 	/* allocate kernel pages */
 	for (page = first_page; page <= last_page; page++) {
-		/* first try to allocate from <4GB zone */
-		struct page *p = alloc_page(GFP_KERNEL | GFP_DMA32 |
-					    __GFP_NOWARN);
-		if (!p || (page_to_pfn(p) & ~(emu->dma_mask >> PAGE_SHIFT))) {
-			if (p)
-				__free_page(p);
-			/* try to allocate from <16MB zone */
-			p = alloc_page(GFP_ATOMIC | GFP_DMA |
-				       __GFP_NORETRY | /* no OOM-killer */
-				       __GFP_NOWARN);
+		if (snd_emu10k1_alloc_pages_maybe_wider(emu, PAGE_SIZE,
+							&dmab) < 0)
+			goto __fail;
+		if (!is_valid_page(emu, dmab.addr)) {
+			snd_dma_free_pages(&dmab);
+			goto __fail;
 		}
-		if (!p) {
-			__synth_free_pages(emu, first_page, page - 1);
-			return -ENOMEM;
-		}
-		emu->page_addr_table[page] = page_to_phys(p);
-		emu->page_ptr_table[page] = page_address(p);
+		emu->page_addr_table[page] = dmab.addr;
+		emu->page_ptr_table[page] = dmab.area;
 	}
 	return 0;
+
+__fail:
+	/* release allocated pages */
+	last_page = page - 1;
+	__synth_free_pages(emu, first_page, last_page);
+
+	return -ENOMEM;
 }
 
 /*
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index c397e7d..066b5b5 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -1,22 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Digital Beep Input Interface for HD-audio codec
  *
- * Author: Matt Ranostay <mranostay@gmail.com>
+ * Author: Matt Ranostay <matt.ranostay@konsulko.com>
  * Copyright (c) 2008 Embedded Alley Solutions Inc
- *
- *  This driver is free software; you can redistribute 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 driver 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/input.h>
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index 1052ad3..d1a6a9c 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -1,22 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Digital Beep Input Interface for HD-audio codec
  *
- * Author: Matt Ranostay <mranostay@gmail.com>
+ * Author: Matt Ranostay <matt.ranostay@konsulko.com>
  * Copyright (c) 2008 Embedded Alley Solutions Inc
- *
- *  This driver is free software; you can redistribute 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 driver 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 __SOUND_HDA_BEEP_H
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e018ecb..5bc3a74 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2702,32 +2702,6 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
 }
 EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all);
 
-/*
- * wait until the state is reached, returns the current state
- */
-static unsigned int hda_sync_power_state(struct hda_codec *codec,
-					 hda_nid_t fg,
-					 unsigned int power_state)
-{
-	unsigned long end_time = jiffies + msecs_to_jiffies(500);
-	unsigned int state, actual_state;
-
-	for (;;) {
-		state = snd_hda_codec_read(codec, fg, 0,
-					   AC_VERB_GET_POWER_STATE, 0);
-		if (state & AC_PWRST_ERROR)
-			break;
-		actual_state = (state >> 4) & 0x0f;
-		if (actual_state == power_state)
-			break;
-		if (time_after_eq(jiffies, end_time))
-			break;
-		/* wait until the codec reachs to the target state */
-		msleep(1);
-	}
-	return state;
-}
-
 /**
  * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD
  * @codec: the HDA codec
@@ -2790,7 +2764,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
 						   state);
 			snd_hda_codec_set_power_to_all(codec, fg, power_state);
 		}
-		state = hda_sync_power_state(codec, fg, power_state);
+		state = snd_hda_sync_power_state(codec, fg, power_state);
 		if (!(state & AC_PWRST_ERROR))
 			break;
 	}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index e2f649f..7720e31 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2447,6 +2447,9 @@ static const struct pci_device_id azx_ids[] = {
 	/* Cannonlake */
 	{ PCI_DEVICE(0x8086, 0x9dc8),
 	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+	/* Icelake */
+	{ PCI_DEVICE(0x8086, 0x34c8),
+	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
 	/* Broxton-P(Apollolake) */
 	{ PCI_DEVICE(0x8086, 0x5a98),
 	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 5b5c324..321e78b 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -622,7 +622,11 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
 {
 	return snd_hdac_check_power_state(&codec->core, nid, target_state);
 }
-
+static inline bool snd_hda_sync_power_state(struct hda_codec *codec,
+			   hda_nid_t nid, unsigned int target_state)
+{
+	return snd_hdac_sync_power_state(&codec->core, nid, target_state);
+}
 unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
 					     hda_nid_t nid,
 					     unsigned int power_state);
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 0dbaccf..21806ba 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/tlv.h>
 
@@ -425,10 +426,9 @@ DECLARE_TLV_DB_SCALE(juli_master_db_scale, -6350, 50, 1);
 static struct snd_kcontrol *ctl_find(struct snd_card *card,
 				     const char *name)
 {
-	struct snd_ctl_elem_id sid;
-	memset(&sid, 0, sizeof(sid));
-	/* FIXME: strcpy is bad. */
-	strcpy(sid.name, name);
+	struct snd_ctl_elem_id sid = {0};
+
+	strlcpy(sid.name, name, sizeof(sid.name));
 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_find_id(card, &sid);
 }
diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c
index d145b5e..5bc8362 100644
--- a/sound/pci/ice1712/quartet.c
+++ b/sound/pci/ice1712/quartet.c
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/tlv.h>
 #include <sound/info.h>
@@ -785,10 +786,9 @@ DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1);
 static struct snd_kcontrol *ctl_find(struct snd_card *card,
 				     const char *name)
 {
-	struct snd_ctl_elem_id sid;
-	memset(&sid, 0, sizeof(sid));
-	/* FIXME: strcpy is bad. */
-	strcpy(sid.name, name);
+	struct snd_ctl_elem_id sid = {0};
+
+	strlcpy(sid.name, name, sizeof(sid.name));
 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_find_id(card, &sid);
 }
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 84c3582..41af6b9 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -45,7 +45,6 @@
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/bcm/Kconfig"
-source "sound/soc/blackfin/Kconfig"
 source "sound/soc/cirrus/Kconfig"
 source "sound/soc/davinci/Kconfig"
 source "sound/soc/dwc/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 74cd185..8d92492 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -29,7 +29,6 @@
 obj-$(CONFIG_SND_SOC)	+= atmel/
 obj-$(CONFIG_SND_SOC)	+= au1x/
 obj-$(CONFIG_SND_SOC)	+= bcm/
-obj-$(CONFIG_SND_SOC)	+= blackfin/
 obj-$(CONFIG_SND_SOC)	+= cirrus/
 obj-$(CONFIG_SND_SOC)	+= davinci/
 obj-$(CONFIG_SND_SOC)	+= dwc/
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
index d583840..6cbf9cf 100644
--- a/sound/soc/amd/Kconfig
+++ b/sound/soc/amd/Kconfig
@@ -3,6 +3,15 @@
 	help
 	 This option enables ACP DMA support on AMD platform.
 
+config SND_SOC_AMD_CZ_DA7219MX98357_MACH
+	tristate "AMD CZ support for DA7219 and MAX9835"
+	select SND_SOC_DA7219
+	select SND_SOC_MAX98357A
+	select SND_SOC_ADAU7002
+	depends on SND_SOC_AMD_ACP && I2C
+	help
+	 This option enables machine driver for DA7219 and MAX9835.
+
 config SND_SOC_AMD_CZ_RT5645_MACH
 	tristate "AMD CZ support for RT5645"
 	select SND_SOC_RT5645
diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile
index f07fd2e..79b0622 100644
--- a/sound/soc/amd/Makefile
+++ b/sound/soc/amd/Makefile
@@ -1,5 +1,7 @@
 acp_audio_dma-objs := acp-pcm-dma.o
+snd-soc-acp-da7219mx98357-mach-objs := acp-da7219-max98357a.o
 snd-soc-acp-rt5645-mach-objs := acp-rt5645.o
 
 obj-$(CONFIG_SND_SOC_AMD_ACP) += acp_audio_dma.o
+obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mach.o
 obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c
new file mode 100644
index 0000000..b205c78
--- /dev/null
+++ b/sound/soc/amd/acp-da7219-max98357a.c
@@ -0,0 +1,276 @@
+/*
+ * Machine driver for AMD ACP Audio engine using DA7219 & MAX98357 codec
+ *
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+
+#include "../codecs/da7219.h"
+#include "../codecs/da7219-aad.h"
+
+#define CZ_PLAT_CLK 24000000
+#define MCLK_RATE 24576000
+#define DUAL_CHANNEL		2
+
+static struct snd_soc_jack cz_jack;
+struct clk *da7219_dai_clk;
+
+static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
+{
+	int ret;
+	struct snd_soc_card *card = rtd->card;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_component *component = codec_dai->component;
+
+	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+	ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK,
+				     CZ_PLAT_CLK, SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL,
+				  CZ_PLAT_CLK, MCLK_RATE);
+	if (ret < 0) {
+		dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
+		return ret;
+	}
+
+	da7219_dai_clk = clk_get(component->dev, "da7219-dai-clks");
+
+	ret = snd_soc_card_jack_new(card, "Headset Jack",
+				SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
+				SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+				SND_JACK_BTN_2 | SND_JACK_BTN_3,
+				&cz_jack, NULL, 0);
+	if (ret) {
+		dev_err(card->dev, "HP jack creation failed %d\n", ret);
+		return ret;
+	}
+
+	da7219_aad_jack_det(component, &cz_jack);
+
+	return 0;
+}
+
+static int cz_da7219_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
+{
+	int ret = 0;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+	ret = clk_prepare_enable(da7219_dai_clk);
+	if (ret < 0) {
+		dev_err(rtd->dev, "can't enable master clock %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int cz_da7219_hw_free(struct snd_pcm_substream *substream)
+{
+	clk_disable_unprepare(da7219_dai_clk);
+
+	return 0;
+}
+
+static const unsigned int channels[] = {
+	DUAL_CHANNEL,
+};
+
+static const unsigned int rates[] = {
+	48000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_rates = {
+	.count = ARRAY_SIZE(rates),
+	.list  = rates,
+	.mask = 0,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+	.count = ARRAY_SIZE(channels),
+	.list = channels,
+	.mask = 0,
+};
+
+static int cz_fe_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	/*
+	 * On this platform for PCM device we support stereo
+	 */
+
+	runtime->hw.channels_max = DUAL_CHANNEL;
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+				   &constraints_channels);
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+				   &constraints_rates);
+
+	return 0;
+}
+
+static struct snd_soc_ops cz_da7219_cap_ops = {
+	.hw_params = cz_da7219_hw_params,
+	.hw_free = cz_da7219_hw_free,
+	.startup = cz_fe_startup,
+};
+
+static struct snd_soc_ops cz_max_play_ops = {
+	.hw_params = cz_da7219_hw_params,
+	.hw_free = cz_da7219_hw_free,
+};
+
+static struct snd_soc_ops cz_dmic_cap_ops = {
+	.hw_params = cz_da7219_hw_params,
+	.hw_free = cz_da7219_hw_free,
+};
+
+static struct snd_soc_dai_link cz_dai_7219_98357[] = {
+	{
+		.name = "amd-da7219-play-cap",
+		.stream_name = "Playback and Capture",
+		.platform_name = "acp_audio_dma.0.auto",
+		.cpu_dai_name = "designware-i2s.3.auto",
+		.codec_dai_name = "da7219-hifi",
+		.codec_name = "i2c-DLGS7219:00",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+		.init = cz_da7219_init,
+		.dpcm_playback = 1,
+		.dpcm_capture = 1,
+		.ops = &cz_da7219_cap_ops,
+	},
+	{
+		.name = "amd-max98357-play",
+		.stream_name = "HiFi Playback",
+		.platform_name = "acp_audio_dma.0.auto",
+		.cpu_dai_name = "designware-i2s.1.auto",
+		.codec_dai_name = "HiFi",
+		.codec_name = "MX98357A:00",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+		.dpcm_playback = 1,
+		.ops = &cz_max_play_ops,
+	},
+	{
+		.name = "dmic",
+		.stream_name = "DMIC Capture",
+		.platform_name = "acp_audio_dma.0.auto",
+		.cpu_dai_name = "designware-i2s.2.auto",
+		.codec_dai_name = "adau7002-hifi",
+		.codec_name = "ADAU7002:00",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+		.dpcm_capture = 1,
+		.ops = &cz_dmic_cap_ops,
+	},
+};
+
+static const struct snd_soc_dapm_widget cz_widgets[] = {
+	SND_SOC_DAPM_HP("Headphones", NULL),
+	SND_SOC_DAPM_SPK("Speakers", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+	SND_SOC_DAPM_MIC("Int Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route cz_audio_route[] = {
+	{"Headphones", NULL, "HPL"},
+	{"Headphones", NULL, "HPR"},
+	{"MIC", NULL, "Headset Mic"},
+	{"Speakers", NULL, "Speaker"},
+	{"PDM_DAT", NULL, "Int Mic"},
+};
+
+static const struct snd_kcontrol_new cz_mc_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Headphones"),
+	SOC_DAPM_PIN_SWITCH("Speakers"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
+	SOC_DAPM_PIN_SWITCH("Int Mic"),
+};
+
+static struct snd_soc_card cz_card = {
+	.name = "acpd7219m98357",
+	.owner = THIS_MODULE,
+	.dai_link = cz_dai_7219_98357,
+	.num_links = ARRAY_SIZE(cz_dai_7219_98357),
+	.dapm_widgets = cz_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(cz_widgets),
+	.dapm_routes = cz_audio_route,
+	.num_dapm_routes = ARRAY_SIZE(cz_audio_route),
+	.controls = cz_mc_controls,
+	.num_controls = ARRAY_SIZE(cz_mc_controls),
+};
+
+static int cz_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct snd_soc_card *card;
+
+	card = &cz_card;
+	cz_card.dev = &pdev->dev;
+	platform_set_drvdata(pdev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, &cz_card);
+	if (ret) {
+		dev_err(&pdev->dev,
+				"devm_snd_soc_register_card(%s) failed: %d\n",
+				cz_card.name, ret);
+		return ret;
+	}
+	return 0;
+}
+
+static const struct acpi_device_id cz_audio_acpi_match[] = {
+	{ "AMD7219", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);
+
+static struct platform_driver cz_pcm_driver = {
+	.driver = {
+		.name = "cz-da7219-max98357a",
+		.acpi_match_table = ACPI_PTR(cz_audio_acpi_match),
+		.pm = &snd_soc_pm_ops,
+	},
+	.probe = cz_probe,
+};
+
+module_platform_driver(cz_pcm_driver);
+
+MODULE_AUTHOR("akshu.agrawal@amd.com");
+MODULE_DESCRIPTION("DA7219 & MAX98357A audio support");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index 9fb356d..540088d 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -23,6 +23,8 @@
 #include <drm/amd_asic_type.h>
 #include "acp.h"
 
+#define DRV_NAME "acp_audio_dma"
+
 #define PLAYBACK_MIN_NUM_PERIODS    2
 #define PLAYBACK_MAX_NUM_PERIODS    2
 #define PLAYBACK_MAX_PERIOD_SIZE    16384
@@ -182,19 +184,18 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
  * system memory <-> ACP SRAM
  */
 static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
-					u32 size, int direction,
-					u32 pte_offset, u32 asic_type)
+					u32 size, int direction, u32 pte_offset,
+					u16 ch, u32 sram_bank,
+					u16 dma_dscr_idx, u32 asic_type)
 {
 	u16 i;
-	u16 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
 	acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
 
 	for (i = 0; i < NUM_DSCRS_PER_CHANNEL; i++) {
 		dmadscr[i].xfer_val = 0;
 		if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
-			dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12 + i;
-			dmadscr[i].dest = ACP_SHARED_RAM_BANK_1_ADDRESS
-					+ (i * (size/2));
+			dma_dscr_idx = dma_dscr_idx + i;
+			dmadscr[i].dest = sram_bank + (i * (size/2));
 			dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS
 				+ (pte_offset * SZ_4K) + (i * (size/2));
 			switch (asic_type) {
@@ -209,25 +210,19 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
 				(size / 2);
 			}
 		} else {
-			dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14 + i;
+			dma_dscr_idx = dma_dscr_idx + i;
+			dmadscr[i].src = sram_bank + (i * (size/2));
+			dmadscr[i].dest =
+			ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
+			(pte_offset * SZ_4K) + (i * (size/2));
 			switch (asic_type) {
 			case CHIP_STONEY:
-				dmadscr[i].src = ACP_SHARED_RAM_BANK_3_ADDRESS +
-				(i * (size/2));
-				dmadscr[i].dest =
-				ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
-				(pte_offset * SZ_4K) + (i * (size/2));
 				dmadscr[i].xfer_val |=
 				BIT(22) |
 				(ACP_DMA_ATTRIBUTES_SHARED_MEM_TO_DAGB_GARLIC << 16) |
 				(size / 2);
 				break;
 			default:
-				dmadscr[i].src = ACP_SHARED_RAM_BANK_5_ADDRESS +
-				(i * (size/2));
-				dmadscr[i].dest =
-				ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
-				(pte_offset * SZ_4K) + (i * (size/2));
 				dmadscr[i].xfer_val |=
 				BIT(22) |
 				(ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION << 16) |
@@ -237,72 +232,49 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
 		config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
 						&dmadscr[i]);
 	}
-	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
-		config_acp_dma_channel(acp_mmio, SYSRAM_TO_ACP_CH_NUM,
-					PLAYBACK_START_DMA_DESCR_CH12,
-					NUM_DSCRS_PER_CHANNEL,
-					ACP_DMA_PRIORITY_LEVEL_NORMAL);
-	else
-		config_acp_dma_channel(acp_mmio, ACP_TO_SYSRAM_CH_NUM,
-					CAPTURE_START_DMA_DESCR_CH14,
-					NUM_DSCRS_PER_CHANNEL,
-					ACP_DMA_PRIORITY_LEVEL_NORMAL);
+	config_acp_dma_channel(acp_mmio, ch,
+				dma_dscr_idx - 1,
+				NUM_DSCRS_PER_CHANNEL,
+				ACP_DMA_PRIORITY_LEVEL_NORMAL);
 }
 
 /* Initialize the DMA descriptor information for transfer between
  * ACP SRAM <-> I2S
  */
-static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio,
-					u32 size, int direction,
-					u32 asic_type)
+static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
+						int direction, u32 sram_bank,
+						u16 destination, u16 ch,
+						u16 dma_dscr_idx, u32 asic_type)
 {
 
 	u16 i;
-	u16 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13;
 	acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
 
 	for (i = 0; i < NUM_DSCRS_PER_CHANNEL; i++) {
 		dmadscr[i].xfer_val = 0;
 		if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
-			dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13 + i;
-			dmadscr[i].src = ACP_SHARED_RAM_BANK_1_ADDRESS +
-					 (i * (size/2));
+			dma_dscr_idx = dma_dscr_idx + i;
+			dmadscr[i].src = sram_bank  + (i * (size/2));
 			/* dmadscr[i].dest is unused by hardware. */
 			dmadscr[i].dest = 0;
-			dmadscr[i].xfer_val |= BIT(22) | (TO_ACP_I2S_1 << 16) |
+			dmadscr[i].xfer_val |= BIT(22) | (destination << 16) |
 						(size / 2);
 		} else {
-			dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15 + i;
+			dma_dscr_idx = dma_dscr_idx + i;
 			/* dmadscr[i].src is unused by hardware. */
 			dmadscr[i].src = 0;
-			switch (asic_type) {
-			case CHIP_STONEY:
-				dmadscr[i].dest =
-					 ACP_SHARED_RAM_BANK_3_ADDRESS +
-					(i * (size / 2));
-				break;
-			default:
-				dmadscr[i].dest =
-					 ACP_SHARED_RAM_BANK_5_ADDRESS +
-					(i * (size / 2));
-			}
+			dmadscr[i].dest =
+				 sram_bank + (i * (size / 2));
 			dmadscr[i].xfer_val |= BIT(22) |
-					(FROM_ACP_I2S_1 << 16) | (size / 2);
+				(destination << 16) | (size / 2);
 		}
 		config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
 						&dmadscr[i]);
 	}
 	/* Configure the DMA channel with the above descriptore */
-	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
-		config_acp_dma_channel(acp_mmio, ACP_TO_I2S_DMA_CH_NUM,
-					PLAYBACK_START_DMA_DESCR_CH13,
-					NUM_DSCRS_PER_CHANNEL,
-					ACP_DMA_PRIORITY_LEVEL_NORMAL);
-	else
-		config_acp_dma_channel(acp_mmio, I2S_TO_ACP_DMA_CH_NUM,
-					CAPTURE_START_DMA_DESCR_CH15,
-					NUM_DSCRS_PER_CHANNEL,
-					ACP_DMA_PRIORITY_LEVEL_NORMAL);
+	config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1,
+				NUM_DSCRS_PER_CHANNEL,
+				ACP_DMA_PRIORITY_LEVEL_NORMAL);
 }
 
 /* Create page table entries in ACP SRAM for the allocated memory */
@@ -344,23 +316,51 @@ static void config_acp_dma(void __iomem *acp_mmio,
 			struct audio_substream_data *audio_config,
 			u32 asic_type)
 {
-	u32 pte_offset;
+	u32 pte_offset, sram_bank;
+	u16 ch1, ch2, destination, dma_dscr_idx;
 
-	if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
+	if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) {
 		pte_offset = ACP_PLAYBACK_PTE_OFFSET;
-	else
+		ch1 = SYSRAM_TO_ACP_CH_NUM;
+		ch2 = ACP_TO_I2S_DMA_CH_NUM;
+		sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS;
+		destination = TO_ACP_I2S_1;
+
+	} else {
 		pte_offset = ACP_CAPTURE_PTE_OFFSET;
+		ch1 = SYSRAM_TO_ACP_CH_NUM;
+		ch2 = ACP_TO_I2S_DMA_CH_NUM;
+		switch (asic_type) {
+		case CHIP_STONEY:
+			sram_bank = ACP_SHARED_RAM_BANK_3_ADDRESS;
+			break;
+		default:
+			sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS;
+		}
+		destination = FROM_ACP_I2S_1;
+	}
 
 	acp_pte_config(acp_mmio, audio_config->pg, audio_config->num_of_pages,
 			pte_offset);
+	if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
+		dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
+	else
+		dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14;
 
 	/* Configure System memory <-> ACP SRAM DMA descriptors */
 	set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size,
-				audio_config->direction, pte_offset, asic_type);
+				       audio_config->direction, pte_offset,
+					ch1, sram_bank, dma_dscr_idx, asic_type);
 
+	if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
+		dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13;
+	else
+		dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15;
 	/* Configure ACP SRAM <-> I2S DMA descriptors */
 	set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size,
-				audio_config->direction, asic_type);
+					audio_config->direction, sram_bank,
+					destination, ch2, dma_dscr_idx,
+					asic_type);
 }
 
 /* Start a given DMA channel transfer */
@@ -655,7 +655,7 @@ static irqreturn_t dma_irq_handler(int irq, void *arg)
 				       1, 0);
 		acp_dma_start(acp_mmio, SYSRAM_TO_ACP_CH_NUM, false);
 
-		snd_pcm_period_elapsed(irq_data->play_stream);
+		snd_pcm_period_elapsed(irq_data->play_i2ssp_stream);
 
 		acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) << 16,
 				acp_mmio, mmACP_EXTERNAL_INTR_STAT);
@@ -678,7 +678,7 @@ static irqreturn_t dma_irq_handler(int irq, void *arg)
 
 	if ((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) != 0) {
 		valid_irq = true;
-		snd_pcm_period_elapsed(irq_data->capture_stream);
+		snd_pcm_period_elapsed(irq_data->capture_i2ssp_stream);
 		acp_reg_write((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) << 16,
 				acp_mmio, mmACP_EXTERNAL_INTR_STAT);
 	}
@@ -695,8 +695,8 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
 	int ret = 0;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *prtd = substream->private_data;
-	struct audio_drv_data *intr_data = dev_get_drvdata(prtd->platform->dev);
-
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+	struct audio_drv_data *intr_data = dev_get_drvdata(component->dev);
 	struct audio_substream_data *adata =
 		kzalloc(sizeof(struct audio_substream_data), GFP_KERNEL);
 	if (adata == NULL)
@@ -723,7 +723,7 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
 	ret = snd_pcm_hw_constraint_integer(runtime,
 					    SNDRV_PCM_HW_PARAM_PERIODS);
 	if (ret < 0) {
-		dev_err(prtd->platform->dev, "set integer constraint failed\n");
+		dev_err(component->dev, "set integer constraint failed\n");
 		kfree(adata);
 		return ret;
 	}
@@ -736,11 +736,11 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
 	 * This enablement is not required for another stream, if current
 	 * stream is not closed
 	*/
-	if (!intr_data->play_stream && !intr_data->capture_stream)
+	if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream)
 		acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		intr_data->play_stream = substream;
+		intr_data->play_i2ssp_stream = substream;
 		/* For Stoney, Memory gating is disabled,i.e SRAM Banks
 		 * won't be turned off. The default state for SRAM banks is ON.
 		 * Setting SRAM bank state code skipped for STONEY platform.
@@ -751,7 +751,7 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
 							bank, true);
 		}
 	} else {
-		intr_data->capture_stream = substream;
+		intr_data->capture_i2ssp_stream = substream;
 		if (intr_data->asic_type != CHIP_STONEY) {
 			for (bank = 5; bank <= 8; bank++)
 				acp_set_sram_bank_state(intr_data->acp_mmio,
@@ -772,7 +772,8 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_runtime *runtime;
 	struct audio_substream_data *rtd;
 	struct snd_soc_pcm_runtime *prtd = substream->private_data;
-	struct audio_drv_data *adata = dev_get_drvdata(prtd->platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+	struct audio_drv_data *adata = dev_get_drvdata(component->dev);
 
 	runtime = substream->runtime;
 	rtd = runtime->private_data;
@@ -859,11 +860,11 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream)
 	bytescount = acp_get_byte_count(rtd->acp_mmio, substream->stream);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		if (bytescount > rtd->renderbytescount)
-			bytescount = bytescount - rtd->renderbytescount;
+		if (bytescount > rtd->i2ssp_renderbytescount)
+			bytescount = bytescount - rtd->i2ssp_renderbytescount;
 	} else {
-		if (bytescount > rtd->capturebytescount)
-			bytescount = bytescount - rtd->capturebytescount;
+		if (bytescount > rtd->i2ssp_capturebytescount)
+			bytescount = bytescount - rtd->i2ssp_capturebytescount;
 	}
 	pos = do_div(bytescount, buffersize);
 	return bytes_to_frames(runtime, pos);
@@ -909,6 +910,7 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *prtd = substream->private_data;
 	struct audio_substream_data *rtd = runtime->private_data;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
 
 	if (!rtd)
 		return -EINVAL;
@@ -919,14 +921,14 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
 		bytescount = acp_get_byte_count(rtd->acp_mmio,
 						substream->stream);
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			if (rtd->renderbytescount == 0)
-				rtd->renderbytescount = bytescount;
+			if (rtd->i2ssp_renderbytescount == 0)
+				rtd->i2ssp_renderbytescount = bytescount;
 			acp_dma_start(rtd->acp_mmio,
 						SYSRAM_TO_ACP_CH_NUM, false);
 			while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) &
 						BIT(SYSRAM_TO_ACP_CH_NUM)) {
 				if (!loops--) {
-					dev_err(prtd->platform->dev,
+					dev_err(component->dev,
 						"acp dma start timeout\n");
 					return -ETIMEDOUT;
 				}
@@ -937,8 +939,8 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
 					ACP_TO_I2S_DMA_CH_NUM, true);
 
 		} else {
-			if (rtd->capturebytescount == 0)
-				rtd->capturebytescount = bytescount;
+			if (rtd->i2ssp_capturebytescount == 0)
+				rtd->i2ssp_capturebytescount = bytescount;
 			acp_dma_start(rtd->acp_mmio,
 					    I2S_TO_ACP_DMA_CH_NUM, true);
 		}
@@ -954,12 +956,16 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
 		 */
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 			ret = acp_dma_stop(rtd->acp_mmio,
+						SYSRAM_TO_ACP_CH_NUM);
+			ret = acp_dma_stop(rtd->acp_mmio,
 					ACP_TO_I2S_DMA_CH_NUM);
-			rtd->renderbytescount = 0;
+			rtd->i2ssp_renderbytescount = 0;
 		} else {
 			ret = acp_dma_stop(rtd->acp_mmio,
 					I2S_TO_ACP_DMA_CH_NUM);
-			rtd->capturebytescount = 0;
+			ret = acp_dma_stop(rtd->acp_mmio,
+						ACP_TO_SYSRAM_CH_NUM);
+			rtd->i2ssp_capturebytescount = 0;
 		}
 		break;
 	default:
@@ -972,7 +978,8 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
 static int acp_dma_new(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
-	struct audio_drv_data *adata = dev_get_drvdata(rtd->platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct audio_drv_data *adata = dev_get_drvdata(component->dev);
 
 	switch (adata->asic_type) {
 	case CHIP_STONEY:
@@ -989,7 +996,7 @@ static int acp_dma_new(struct snd_soc_pcm_runtime *rtd)
 		break;
 	}
 	if (ret < 0)
-		dev_err(rtd->platform->dev,
+		dev_err(component->dev,
 				"buffer preallocation failer error:%d\n", ret);
 	return ret;
 }
@@ -1000,12 +1007,13 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct audio_substream_data *rtd = runtime->private_data;
 	struct snd_soc_pcm_runtime *prtd = substream->private_data;
-	struct audio_drv_data *adata = dev_get_drvdata(prtd->platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+	struct audio_drv_data *adata = dev_get_drvdata(component->dev);
 
 	kfree(rtd);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		adata->play_stream = NULL;
+		adata->play_i2ssp_stream = NULL;
 		/* For Stoney, Memory gating is disabled,i.e SRAM Banks
 		 * won't be turned off. The default state for SRAM banks is ON.
 		 * Setting SRAM bank state code skipped for STONEY platform.
@@ -1017,7 +1025,7 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
 				false);
 		}
 	} else  {
-		adata->capture_stream = NULL;
+		adata->capture_i2ssp_stream = NULL;
 		if (adata->asic_type != CHIP_STONEY) {
 			for (bank = 5; bank <= 8; bank++)
 				acp_set_sram_bank_state(adata->acp_mmio, bank,
@@ -1028,7 +1036,7 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
 	/* Disable ACP irq, when the current stream is being closed and
 	 * another stream is also not active.
 	*/
-	if (!adata->play_stream && !adata->capture_stream)
+	if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream)
 		acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
 
 	return 0;
@@ -1046,7 +1054,8 @@ static const struct snd_pcm_ops acp_dma_ops = {
 	.prepare = acp_dma_prepare,
 };
 
-static struct snd_soc_platform_driver acp_asoc_platform = {
+static struct snd_soc_component_driver acp_asoc_platform = {
+	.name = DRV_NAME,
 	.ops = &acp_dma_ops,
 	.pcm_new = acp_dma_new,
 };
@@ -1078,8 +1087,9 @@ static int acp_audio_probe(struct platform_device *pdev)
 	 * and device doesn't generate any interrupts.
 	 */
 
-	audio_drv_data->play_stream = NULL;
-	audio_drv_data->capture_stream = NULL;
+	audio_drv_data->play_i2ssp_stream = NULL;
+	audio_drv_data->capture_i2ssp_stream = NULL;
+
 	audio_drv_data->asic_type =  *pdata;
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -1104,7 +1114,8 @@ static int acp_audio_probe(struct platform_device *pdev)
 		return status;
 	}
 
-	status = snd_soc_register_platform(&pdev->dev, &acp_asoc_platform);
+	status = devm_snd_soc_register_component(&pdev->dev,
+						&acp_asoc_platform, NULL, 0);
 	if (status != 0) {
 		dev_err(&pdev->dev, "Fail to register ALSA platform device\n");
 		return status;
@@ -1125,7 +1136,6 @@ static int acp_audio_remove(struct platform_device *pdev)
 	status = acp_deinit(adata->acp_mmio);
 	if (status)
 		dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status);
-	snd_soc_unregister_platform(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
@@ -1143,7 +1153,7 @@ static int acp_pcm_resume(struct device *dev)
 		return status;
 	}
 
-	if (adata->play_stream && adata->play_stream->runtime) {
+	if (adata->play_i2ssp_stream && adata->play_i2ssp_stream->runtime) {
 		/* For Stoney, Memory gating is disabled,i.e SRAM Banks
 		 * won't be turned off. The default state for SRAM banks is ON.
 		 * Setting SRAM bank state code skipped for STONEY platform.
@@ -1154,17 +1164,17 @@ static int acp_pcm_resume(struct device *dev)
 						true);
 		}
 		config_acp_dma(adata->acp_mmio,
-			adata->play_stream->runtime->private_data,
+			adata->play_i2ssp_stream->runtime->private_data,
 			adata->asic_type);
 	}
-	if (adata->capture_stream && adata->capture_stream->runtime) {
+	if (adata->capture_i2ssp_stream && adata->capture_i2ssp_stream->runtime) {
 		if (adata->asic_type != CHIP_STONEY) {
 			for (bank = 5; bank <= 8; bank++)
 				acp_set_sram_bank_state(adata->acp_mmio, bank,
 						true);
 		}
 		config_acp_dma(adata->acp_mmio,
-			adata->capture_stream->runtime->private_data,
+			adata->capture_i2ssp_stream->runtime->private_data,
 			adata->asic_type);
 	}
 	acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
diff --git a/sound/soc/amd/acp-rt5645.c b/sound/soc/amd/acp-rt5645.c
index 941aed6..b79b922 100644
--- a/sound/soc/amd/acp-rt5645.c
+++ b/sound/soc/amd/acp-rt5645.c
@@ -71,9 +71,9 @@ static int cz_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
 	struct snd_soc_card *card;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *codec;
 
-	codec = rtd->codec;
+	codec = rtd->codec_dai->component;
 	card = rtd->card;
 
 	ret = snd_soc_card_jack_new(card, "Headset Jack",
diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h
index 9293f17..ba01510 100644
--- a/sound/soc/amd/acp.h
+++ b/sound/soc/amd/acp.h
@@ -86,14 +86,14 @@ struct audio_substream_data {
 	u16 num_of_pages;
 	u16 direction;
 	uint64_t size;
-	u64 renderbytescount;
-	u64 capturebytescount;
+	u64 i2ssp_renderbytescount;
+	u64 i2ssp_capturebytescount;
 	void __iomem *acp_mmio;
 };
 
 struct audio_drv_data {
-	struct snd_pcm_substream *play_stream;
-	struct snd_pcm_substream *capture_stream;
+	struct snd_pcm_substream *play_i2ssp_stream;
+	struct snd_pcm_substream *capture_i2ssp_stream;
 	void __iomem *acp_mmio;
 	u32 asic_type;
 };
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index ebabed6..3d70061 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -32,6 +32,7 @@ struct atmel_classd {
 	struct regmap *regmap;
 	struct clk *pclk;
 	struct clk *gclk;
+	struct device *dev;
 	int irq;
 	const struct atmel_classd_pdata *pdata;
 };
@@ -165,7 +166,7 @@ atmel_classd_platform_configure_dma(struct snd_pcm_substream *substream,
 	struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
 
 	if (params_physical_width(params) != 16) {
-		dev_err(rtd->platform->dev,
+		dev_err(dd->dev,
 			"only supports 16-bit audio data\n");
 		return -EINVAL;
 	}
@@ -247,9 +248,9 @@ static const char * const pwm_type[] = {
 	"Single ended", "Differential"
 };
 
-static int atmel_classd_codec_probe(struct snd_soc_codec *codec)
+static int atmel_classd_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
 	struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
 	const struct atmel_classd_pdata *pdata = dd->pdata;
 	u32 mask, val;
@@ -283,16 +284,16 @@ static int atmel_classd_codec_probe(struct snd_soc_codec *codec)
 		default:
 			val |= (CLASSD_MR_NOVR_VAL_10NS
 				<< CLASSD_MR_NOVR_VAL_SHIFT);
-			dev_warn(codec->dev,
+			dev_warn(component->dev,
 				"non-overlapping value %d is invalid, the default value 10 is specified\n",
 				pdata->non_overlap_time);
 			break;
 		}
 	}
 
-	snd_soc_update_bits(codec, CLASSD_MR, mask, val);
+	snd_soc_component_update_bits(component, CLASSD_MR, mask, val);
 
-	dev_info(codec->dev,
+	dev_info(component->dev,
 		"PWM modulation type is %s, non-overlapping is %s\n",
 		pwm_type[pdata->pwm_type],
 		pdata->non_overlap_enable?"enabled":"disabled");
@@ -300,21 +301,23 @@ static int atmel_classd_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int atmel_classd_codec_resume(struct snd_soc_codec *codec)
+static int atmel_classd_component_resume(struct snd_soc_component *component)
 {
-	struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
 	struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
 
 	return regcache_sync(dd->regmap);
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_classd = {
-	.probe		= atmel_classd_codec_probe,
-	.resume		= atmel_classd_codec_resume,
-	.component_driver = {
-		.controls		= atmel_classd_snd_controls,
-		.num_controls		= ARRAY_SIZE(atmel_classd_snd_controls),
-	},
+static struct snd_soc_component_driver soc_component_dev_classd = {
+	.probe			= atmel_classd_component_probe,
+	.resume			= atmel_classd_component_resume,
+	.controls		= atmel_classd_snd_controls,
+	.num_controls		= ARRAY_SIZE(atmel_classd_snd_controls),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /* codec dai component */
@@ -330,7 +333,7 @@ static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream,
 static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
 	int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u32 mask, val;
 
 	mask = CLASSD_MR_LMUTE_MASK | CLASSD_MR_RMUTE_MASK;
@@ -340,7 +343,7 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
 	else
 		val = 0;
 
-	snd_soc_update_bits(codec, CLASSD_MR, mask, val);
+	snd_soc_component_update_bits(component, CLASSD_MR, mask, val);
 
 	return 0;
 }
@@ -379,7 +382,7 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int fs;
 	int i, best, best_val, cur_val, ret;
 	u32 mask, val;
@@ -397,7 +400,7 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 
-	dev_dbg(codec->dev,
+	dev_dbg(component->dev,
 		"Selected SAMPLE_RATE of %dHz, GCLK_RATE of %ldHz\n",
 		sample_rates[best].rate, sample_rates[best].gclk_rate);
 
@@ -411,7 +414,7 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
 	val = (sample_rates[best].dsp_clk << CLASSD_INTPMR_DSP_CLK_FREQ_SHIFT)
 	| (sample_rates[best].sample_rate << CLASSD_INTPMR_FRAME_SHIFT);
 
-	snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val);
+	snd_soc_component_update_bits(component, CLASSD_INTPMR, mask, val);
 
 	return clk_prepare_enable(dd->gclk);
 }
@@ -429,9 +432,9 @@ atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream,
 static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream,
 					struct snd_soc_dai *codec_dai)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
-	snd_soc_update_bits(codec, CLASSD_MR,
+	snd_soc_component_update_bits(component, CLASSD_MR,
 				CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK,
 				(CLASSD_MR_LEN_DIS << CLASSD_MR_LEN_SHIFT)
 				|(CLASSD_MR_REN_DIS << CLASSD_MR_REN_SHIFT));
@@ -442,7 +445,7 @@ static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream,
 static int atmel_classd_codec_dai_trigger(struct snd_pcm_substream *substream,
 					int cmd, struct snd_soc_dai *codec_dai)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u32 mask, val;
 
 	mask = CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK;
@@ -463,7 +466,7 @@ static int atmel_classd_codec_dai_trigger(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, CLASSD_MR, mask, val);
+	snd_soc_component_update_bits(component, CLASSD_MR, mask, val);
 
 	return 0;
 }
@@ -580,13 +583,11 @@ static int atmel_classd_probe(struct platform_device *pdev)
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	io_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(io_base)) {
-		ret =  PTR_ERR(io_base);
-		dev_err(dev, "failed to remap register memory: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(io_base))
+		return PTR_ERR(io_base);
 
 	dd->phy_base = res->start;
+	dd->dev = dev;
 
 	dd->regmap = devm_regmap_init_mmio(dev, io_base,
 					&atmel_classd_regmap_config);
@@ -612,10 +613,10 @@ static int atmel_classd_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(dev, &soc_codec_dev_classd,
+	ret = devm_snd_soc_register_component(dev, &soc_component_dev_classd,
 					&atmel_classd_codec_dai, 1);
 	if (ret) {
-		dev_err(dev, "could not register codec: %d\n", ret);
+		dev_err(dev, "could not register component: %d\n", ret);
 		return ret;
 	}
 
@@ -643,13 +644,11 @@ static int atmel_classd_probe(struct platform_device *pdev)
 	return 0;
 
 unregister_codec:
-	snd_soc_unregister_codec(dev);
 	return ret;
 }
 
 static int atmel_classd_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
 
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
index 91b7069..99ca23d 100644
--- a/sound/soc/atmel/atmel-pcm-pdc.c
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
@@ -393,7 +393,7 @@ static const struct snd_pcm_ops atmel_pcm_ops = {
 	.mmap		= atmel_pcm_mmap,
 };
 
-static struct snd_soc_platform_driver atmel_soc_platform = {
+static struct snd_soc_component_driver atmel_soc_platform = {
 	.ops		= &atmel_pcm_ops,
 	.pcm_new	= atmel_pcm_new,
 	.pcm_free	= atmel_pcm_free,
@@ -401,13 +401,13 @@ static struct snd_soc_platform_driver atmel_soc_platform = {
 
 int atmel_pcm_pdc_platform_register(struct device *dev)
 {
-	return snd_soc_register_platform(dev, &atmel_soc_platform);
+	return devm_snd_soc_register_component(dev, &atmel_soc_platform,
+					       NULL, 0);
 }
 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);
 
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c
index 8e3d34b..915c2b0 100644
--- a/sound/soc/atmel/atmel-pdmic.c
+++ b/sound/soc/atmel/atmel-pdmic.c
@@ -32,6 +32,7 @@ struct atmel_pdmic {
 	struct regmap *regmap;
 	struct clk *pclk;
 	struct clk *gclk;
+	struct device *dev;
 	int irq;
 	struct snd_pcm_substream *substream;
 	const struct atmel_pdmic_pdata *pdata;
@@ -206,7 +207,7 @@ atmel_pdmic_platform_configure_dma(struct snd_pcm_substream *substream,
 	ret = snd_hwparams_to_dma_slave_config(substream, params,
 					       slave_config);
 	if (ret) {
-		dev_err(rtd->platform->dev,
+		dev_err(dd->dev,
 			"hw params to dma slave configure failed\n");
 		return ret;
 	}
@@ -288,14 +289,14 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
 static int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int dgain_val, scale_val;
 	int i;
 
-	dgain_val = (snd_soc_read(codec, PDMIC_DSPR1) & PDMIC_DSPR1_DGAIN_MASK)
+	dgain_val = (snd_soc_component_read32(component, PDMIC_DSPR1) & PDMIC_DSPR1_DGAIN_MASK)
 		    >> PDMIC_DSPR1_DGAIN_SHIFT;
 
-	scale_val = (snd_soc_read(codec, PDMIC_DSPR0) & PDMIC_DSPR0_SCALE_MASK)
+	scale_val = (snd_soc_component_read32(component, PDMIC_DSPR0) & PDMIC_DSPR0_SCALE_MASK)
 		    >> PDMIC_DSPR0_SCALE_SHIFT;
 
 	for (i = 0; i < ARRAY_SIZE(mic_gain_table); i++) {
@@ -312,7 +313,7 @@ static int pdmic_put_mic_volsw(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int max = mc->max;
 	unsigned int val;
 	int ret;
@@ -322,12 +323,12 @@ static int pdmic_put_mic_volsw(struct snd_kcontrol *kcontrol,
 	if (val > max)
 		return -EINVAL;
 
-	ret = snd_soc_update_bits(codec, PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_MASK,
+	ret = snd_soc_component_update_bits(component, PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_MASK,
 			 mic_gain_table[val].dgain << PDMIC_DSPR1_DGAIN_SHIFT);
 	if (ret < 0)
 		return ret;
 
-	ret = snd_soc_update_bits(codec, PDMIC_DSPR0, PDMIC_DSPR0_SCALE_MASK,
+	ret = snd_soc_component_update_bits(component, PDMIC_DSPR0, PDMIC_DSPR0_SCALE_MASK,
 			 mic_gain_table[val].scale << PDMIC_DSPR0_SCALE_SHIFT);
 	if (ret < 0)
 		return ret;
@@ -346,23 +347,25 @@ SOC_SINGLE("High Pass Filter Switch", PDMIC_DSPR0,
 SOC_SINGLE("SINCC Filter Switch", PDMIC_DSPR0, PDMIC_DSPR0_SINBYP_SHIFT, 1, 1),
 };
 
-static int atmel_pdmic_codec_probe(struct snd_soc_codec *codec)
+static int atmel_pdmic_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
 	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
 
-	snd_soc_update_bits(codec, PDMIC_DSPR1, PDMIC_DSPR1_OFFSET_MASK,
+	snd_soc_component_update_bits(component, PDMIC_DSPR1, PDMIC_DSPR1_OFFSET_MASK,
 		     (u32)(dd->pdata->mic_offset << PDMIC_DSPR1_OFFSET_SHIFT));
 
 	return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_pdmic = {
-	.probe		= atmel_pdmic_codec_probe,
-	.component_driver = {
-		.controls		= atmel_pdmic_snd_controls,
-		.num_controls		= ARRAY_SIZE(atmel_pdmic_snd_controls),
-	},
+static struct snd_soc_component_driver soc_component_dev_pdmic = {
+	.probe			= atmel_pdmic_component_probe,
+	.controls		= atmel_pdmic_snd_controls,
+	.num_controls		= ARRAY_SIZE(atmel_pdmic_snd_controls),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /* codec dai component */
@@ -375,7 +378,7 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int rate_min = substream->runtime->hw.rate_min;
 	unsigned int rate_max = substream->runtime->hw.rate_max;
 	int fs = params_rate(params);
@@ -385,13 +388,13 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
 	u32 mr_val, dspr0_val, pclk_prescal, gclk_prescal;
 
 	if (params_channels(params) != 1) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"only supports one channel\n");
 		return -EINVAL;
 	}
 
 	if ((fs < rate_min) || (fs > rate_max)) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"sample rate is %dHz, min rate is %dHz, max rate is %dHz\n",
 			fs, rate_min, rate_max);
 
@@ -436,10 +439,10 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
 		mr_val |= PDMIC_MR_CLKS_PCK << PDMIC_MR_CLKS_SHIFT;
 	}
 
-	snd_soc_update_bits(codec, PDMIC_MR,
+	snd_soc_component_update_bits(component, PDMIC_MR,
 		PDMIC_MR_PRESCAL_MASK | PDMIC_MR_CLKS_MASK, mr_val);
 
-	snd_soc_update_bits(codec, PDMIC_DSPR0,
+	snd_soc_component_update_bits(component, PDMIC_DSPR0,
 		PDMIC_DSPR0_OSR_MASK | PDMIC_DSPR0_SIZE_MASK, dspr0_val);
 
 	return 0;
@@ -448,9 +451,9 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
 static int atmel_pdmic_codec_dai_prepare(struct snd_pcm_substream *substream,
 					struct snd_soc_dai *codec_dai)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
-	snd_soc_update_bits(codec, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
+	snd_soc_component_update_bits(component, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
 			    PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT);
 
 	return 0;
@@ -459,7 +462,7 @@ static int atmel_pdmic_codec_dai_prepare(struct snd_pcm_substream *substream,
 static int atmel_pdmic_codec_dai_trigger(struct snd_pcm_substream *substream,
 					int cmd, struct snd_soc_dai *codec_dai)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u32 val;
 
 	switch (cmd) {
@@ -477,7 +480,7 @@ static int atmel_pdmic_codec_dai_trigger(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, PDMIC_CR, PDMIC_CR_ENPDM_MASK, val);
+	snd_soc_component_update_bits(component, PDMIC_CR, PDMIC_CR_ENPDM_MASK, val);
 
 	return 0;
 }
@@ -596,6 +599,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	dd->pdata = pdata;
+	dd->dev = dev;
 
 	dd->irq = platform_get_irq(pdev, 0);
 	if (dd->irq < 0) {
@@ -629,11 +633,8 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	io_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(io_base)) {
-		ret = PTR_ERR(io_base);
-		dev_err(dev, "failed to remap register memory: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(io_base))
+		return PTR_ERR(io_base);
 
 	dd->phy_base = res->start;
 
@@ -679,10 +680,10 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
 	/* register codec and codec dai */
 	atmel_pdmic_codec_dai.capture.rate_min = rate_min;
 	atmel_pdmic_codec_dai.capture.rate_max = rate_max;
-	ret = snd_soc_register_codec(dev, &soc_codec_dev_pdmic,
+	ret = devm_snd_soc_register_component(dev, &soc_component_dev_pdmic,
 				     &atmel_pdmic_codec_dai, 1);
 	if (ret) {
-		dev_err(dev, "could not register codec: %d\n", ret);
+		dev_err(dev, "could not register component: %d\n", ret);
 		return ret;
 	}
 
@@ -710,13 +711,11 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
 	return 0;
 
 unregister_codec:
-	snd_soc_unregister_codec(dev);
 	return ret;
 }
 
 static int atmel_pdmic_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
 
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 6a035ca..fb65065 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -32,6 +32,8 @@
 
 /*#define PCM_DEBUG*/
 
+#define DRV_NAME "dbdma2"
+
 #define MSG(x...)	printk(KERN_INFO "au1xpsc_pcm: " x)
 #ifdef PCM_DEBUG
 #define DBG		MSG
@@ -187,8 +189,8 @@ static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd,
 static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream *ss)
 {
 	struct snd_soc_pcm_runtime *rtd = ss->private_data;
-	struct au1xpsc_audio_dmadata *pcd =
-				snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct au1xpsc_audio_dmadata *pcd = snd_soc_component_get_drvdata(component);
 	return &pcd[ss->stream];
 }
 
@@ -327,7 +329,8 @@ static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd)
 }
 
 /* au1xpsc audio platform */
-static struct snd_soc_platform_driver au1xpsc_soc_platform = {
+static struct snd_soc_component_driver au1xpsc_soc_component = {
+	.name		= DRV_NAME,
 	.ops		= &au1xpsc_pcm_ops,
 	.pcm_new	= au1xpsc_pcm_new,
 };
@@ -344,8 +347,8 @@ static int au1xpsc_pcm_drvprobe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, dmadata);
 
-	return devm_snd_soc_register_platform(&pdev->dev,
-					      &au1xpsc_soc_platform);
+	return devm_snd_soc_register_component(&pdev->dev,
+					&au1xpsc_soc_component, NULL, 0);
 }
 
 static struct platform_driver au1xpsc_pcm_driver = {
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c
index 19457e2..efff1e2 100644
--- a/sound/soc/au1x/dma.c
+++ b/sound/soc/au1x/dma.c
@@ -21,6 +21,8 @@
 
 #include "psc.h"
 
+#define DRV_NAME "au1x_dma"
+
 struct pcm_period {
 	u32 start;
 	u32 relative_end;	/* relative to start of buffer */
@@ -174,7 +176,8 @@ static const struct snd_pcm_hardware alchemy_pcm_hardware = {
 static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss)
 {
 	struct snd_soc_pcm_runtime *rtd = ss->private_data;
-	return snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	return snd_soc_component_get_drvdata(component);
 }
 
 static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss)
@@ -297,7 +300,8 @@ static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	return 0;
 }
 
-static struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
+static struct snd_soc_component_driver alchemy_pcm_soc_component = {
+	.name		= DRV_NAME,
 	.ops		= &alchemy_pcm_ops,
 	.pcm_new	= alchemy_pcm_new,
 };
@@ -312,8 +316,8 @@ static int alchemy_pcm_drvprobe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, ctx);
 
-	return devm_snd_soc_register_platform(&pdev->dev,
-					      &alchemy_pcm_soc_platform);
+	return devm_snd_soc_register_component(&pdev->dev,
+					&alchemy_pcm_soc_component, NULL, 0);
 }
 
 static struct platform_driver alchemy_pcmdma_driver = {
diff --git a/sound/soc/bcm/cygnus-pcm.c b/sound/soc/bcm/cygnus-pcm.c
index d616e096..123ecf5 100644
--- a/sound/soc/bcm/cygnus-pcm.c
+++ b/sound/soc/bcm/cygnus-pcm.c
@@ -820,7 +820,7 @@ static int cygnus_dma_new(struct snd_soc_pcm_runtime *rtd)
 	return 0;
 }
 
-static struct snd_soc_platform_driver cygnus_soc_platform = {
+static struct snd_soc_component_driver cygnus_soc_platform = {
 	.ops		= &cygnus_pcm_ops,
 	.pcm_new	= cygnus_dma_new,
 	.pcm_free	= cygnus_dma_free_dma_buffers,
@@ -840,7 +840,8 @@ int cygnus_soc_platform_register(struct device *dev,
 		return rc;
 	}
 
-	rc = snd_soc_register_platform(dev, &cygnus_soc_platform);
+	rc = devm_snd_soc_register_component(dev, &cygnus_soc_platform,
+					     NULL, 0);
 	if (rc) {
 		dev_err(dev, "%s failed\n", __func__);
 		return rc;
@@ -851,8 +852,6 @@ int cygnus_soc_platform_register(struct device *dev,
 
 int cygnus_soc_platform_unregister(struct device *dev)
 {
-	snd_soc_unregister_platform(dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c
index abafadc..b733f14 100644
--- a/sound/soc/bcm/cygnus-ssp.c
+++ b/sound/soc/bcm/cygnus-ssp.c
@@ -1281,7 +1281,7 @@ static int cygnus_ssp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *child_node;
-	struct resource *res = pdev->resource;
+	struct resource *res;
 	struct cygnus_audio *cygaud;
 	int err = -EINVAL;
 	int node_count;
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
deleted file mode 100644
index 6410aa2..0000000
--- a/sound/soc/blackfin/Kconfig
+++ /dev/null
@@ -1,205 +0,0 @@
-config SND_BF5XX_I2S
-	tristate "SoC I2S Audio for the ADI Blackfin chip"
-	depends on BLACKFIN
-	select SND_BF5XX_SOC_SPORT if !BF60x
-	select SND_BF6XX_SOC_SPORT if BF60x
-	help
-	  Say Y or M if you want to add support for codecs attached to
-	  the Blackfin SPORT (synchronous serial ports) interface in I2S
-	  mode (supports single stereo In/Out).
-	  You will also need to select the audio interfaces to support below.
-
-config SND_BF5XX_SOC_SSM2602
-	tristate "SoC SSM2602 Audio Codec Add-On Card support"
-	depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
-	select SND_BF5XX_SOC_I2S if !BF60x
-	select SND_BF6XX_SOC_I2S if BF60x
-	select SND_SOC_SSM2602_SPI if SPI_MASTER
-	select SND_SOC_SSM2602_I2C if I2C
-	help
-	  Say Y if you want to add support for the Analog Devices
-	  SSM2602 Audio Codec Add-On Card.
-
-config SND_SOC_BFIN_EVAL_ADAU1701
-	tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards"
-	depends on SND_BF5XX_I2S && I2C
-	select SND_BF5XX_SOC_I2S
-	select SND_SOC_ADAU1701
-	help
-	  Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ
-	  board connected to one of the Blackfin evaluation boards like the
-	  BF5XX-STAMP or BF5XX-EZKIT.
-
-config SND_SOC_BFIN_EVAL_ADAU1373
-	tristate "Support for the EVAL-ADAU1373 board on Blackfin eval boards"
-	depends on SND_BF5XX_I2S && I2C
-	select SND_BF5XX_SOC_I2S
-	select SND_SOC_ADAU1373
-	help
-	  Say Y if you want to add support for the Analog Devices EVAL-ADAU1373
-	  board connected to one of the Blackfin evaluation boards like the
-	  BF5XX-STAMP or BF5XX-EZKIT.
-
-	  Note: This driver assumes that first ADAU1373 DAI is connected to the
-	  first SPORT port on the BF5XX board.
-
-config SND_SOC_BFIN_EVAL_ADAU1X61
-	tristate "Support for the EVAL-ADAU1X61 board on Blackfin eval boards"
-	depends on SND_BF5XX_I2S && I2C
-	select SND_BF5XX_SOC_I2S
-	select SND_SOC_ADAU1761_I2C
-	help
-	  Say Y if you want to add support for the Analog Devices EVAL-ADAU1X61
-	  board connected to one of the Blackfin evaluation boards like the
-	  BF5XX-STAMP or BF5XX-EZKIT.
-
-	  Note: This driver assumes that the ADAU1X61 is connected to the
-	  first SPORT port on the BF5XX board.
-
-config SND_SOC_BFIN_EVAL_ADAU1X81
-	tristate "Support for the EVAL-ADAU1X81 boards on Blackfin eval boards"
-	depends on SND_BF5XX_I2S && I2C
-	select SND_BF5XX_SOC_I2S
-	select SND_SOC_ADAU1781_I2C
-	help
-	  Say Y if you want to add support for the Analog Devices EVAL-ADAU1X81
-	  board connected to one of the Blackfin evaluation boards like the
-	  BF5XX-STAMP or BF5XX-EZKIT.
-
-	  Note: This driver assumes that the ADAU1X81 is connected to the
-	  first SPORT port on the BF5XX board.
-
-config SND_SOC_BFIN_EVAL_ADAV80X
-	tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
-	depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
-	select SND_BF5XX_SOC_I2S
-	select SND_SOC_ADAV801 if SPI_MASTER
-	select SND_SOC_ADAV803 if I2C
-	help
-	  Say Y if you want to add support for the Analog Devices EVAL-ADAV801 or
-	  EVAL-ADAV803 board connected to one of the Blackfin evaluation boards
-	  like the BF5XX-STAMP or BF5XX-EZKIT.
-
-	  Note: This driver assumes that the ADAV80X digital record and playback
-	  interfaces are connected to the first SPORT port on the BF5XX board.
-
-config SND_BF5XX_SOC_AD1836
-	tristate "SoC AD1836 Audio support for BF5xx"
-	depends on SND_BF5XX_I2S && SPI_MASTER
-	select SND_BF5XX_SOC_I2S
-	select SND_SOC_AD1836
-	help
-	  Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD193X
-	tristate "SoC AD193X Audio support for Blackfin"
-	depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
-	select SND_BF5XX_SOC_I2S
-	select SND_SOC_AD193X_I2C if I2C
-	select SND_SOC_AD193X_SPI if SPI_MASTER
-	help
-	  Say Y if you want to add support for AD193X codec on Blackfin.
-	  This driver supports AD1936, AD1937, AD1938 and AD1939.
-
-config SND_BF5XX_SOC_AD73311
-	tristate "SoC AD73311 Audio support for Blackfin"
-	depends on SND_BF5XX_I2S
-	select SND_BF5XX_SOC_I2S
-	select SND_SOC_AD73311
-	help
-	  Say Y if you want to add support for AD73311 codec on Blackfin.
-
-config SND_BFIN_AD73311_SE
-	int "PF pin for AD73311L Chip Select"
-	depends on SND_BF5XX_SOC_AD73311
-	default 4
-	help
-	  Enter the GPIO used to control AD73311's SE pin. Acceptable
-	  values are 0 to 7
-
-config SND_BF5XX_AC97
-	tristate "SoC AC97 Audio for the ADI BF5xx chip"
-	depends on BLACKFIN
-	select AC97_BUS
-	select SND_SOC_AC97_BUS
-	select SND_BF5XX_SOC_SPORT
-	select SND_BF5XX_SOC_AC97
-	help
-	  Say Y or M if you want to add support for codecs attached to
-	  the Blackfin SPORT (synchronous serial ports) interface in slot 16
-	  mode (pseudo AC97 interface).
-	  You will also need to select the audio interfaces to support below.
-
-	  Note:
-	  AC97 codecs which do not implement the slot-16 mode will not function
-	  properly with this driver. This driver is known to work with the
-	  Analog Devices line of AC97 codecs.
-
-config SND_BF5XX_MMAP_SUPPORT
-	bool "Enable MMAP Support"
-	depends on SND_BF5XX_AC97
-	default y
-	help
-	  Say y if you want AC97 driver to support mmap mode.
-	  We introduce an intermediate buffer to simulate mmap.
-
-config SND_BF5XX_MULTICHAN_SUPPORT
-	bool "Enable Multichannel Support"
-	depends on SND_BF5XX_AC97
-	default n
-	help
-	  Say y if you want AC97 driver to support up to 5.1 channel audio.
-	  this mode will consume much more memory for DMA.
-
-config SND_BF5XX_HAVE_COLD_RESET
-	bool "BOARD has COLD Reset GPIO"
-	depends on SND_BF5XX_AC97
-	default y if BFIN548_EZKIT
-	default n if !BFIN548_EZKIT
-
-config SND_BF5XX_RESET_GPIO_NUM
-	int "Set a GPIO for cold reset"
-	depends on SND_BF5XX_HAVE_COLD_RESET
-	range 0 159
-	default 19 if BFIN548_EZKIT
-	default 5 if BFIN537_STAMP
-	default 0
-	help
-	  Set the correct GPIO for RESET the sound chip.
-
-config SND_BF5XX_SOC_AD1980
-	tristate "SoC AD1980/1 Audio support for BF5xx (Obsolete)"
-	depends on SND_BF5XX_AC97
-	select SND_BF5XX_SOC_AC97
-	select SND_SOC_AD1980
-	help
-	  Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-	  Warning:
-	  Because Analog Devices Inc. discontinued the ad1980 sound chip since
-	  Sep. 2009, this ad1980 driver is not maintained, tested and supported
-	  by ADI now.
-
-config SND_BF5XX_SOC_SPORT
-	tristate
-
-config SND_BF6XX_SOC_SPORT
-	tristate
-
-config SND_BF5XX_SOC_I2S
-	tristate
-
-config SND_BF6XX_SOC_I2S
-	tristate
-
-config SND_BF5XX_SOC_AC97
-	tristate
-
-config SND_BF5XX_SPORT_NUM
-	int "Set a SPORT for Sound chip"
-	depends on (SND_BF5XX_SOC_SPORT || SND_BF6XX_SOC_SPORT)
-	range 0 3 if BF54x
-	range 0 1 if !BF54x
-	default 0
-	help
-	  Set the correct SPORT for sound chip.
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
deleted file mode 100644
index ebeb6a9..0000000
--- a/sound/soc/blackfin/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Blackfin Platform Support
-snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
-snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
-snd-soc-bf5xx-sport-objs := bf5xx-sport.o
-snd-soc-bf6xx-sport-objs := bf6xx-sport.o
-snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
-snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
-snd-soc-bf6xx-i2s-objs := bf6xx-i2s.o
-
-obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
-obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
-obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
-obj-$(CONFIG_SND_BF6XX_SOC_SPORT) += snd-soc-bf6xx-sport.o
-obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
-obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
-obj-$(CONFIG_SND_BF6XX_SOC_I2S) += snd-soc-bf6xx-i2s.o
-
-# Blackfin Machine Support
-snd-ad1836-objs := bf5xx-ad1836.o
-snd-ad1980-objs := bf5xx-ad1980.o
-snd-ssm2602-objs := bf5xx-ssm2602.o
-snd-ad73311-objs := bf5xx-ad73311.o
-snd-ad193x-objs := bf5xx-ad193x.o
-snd-soc-bfin-eval-adau1373-objs := bfin-eval-adau1373.o
-snd-soc-bfin-eval-adau1x61-objs := bfin-eval-adau1x61.o
-snd-soc-bfin-eval-adau1x81-objs := bfin-eval-adau1x81.o
-snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o
-snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o
-
-obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
-obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1373) += snd-soc-bfin-eval-adau1373.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) += snd-soc-bfin-eval-adau1x61.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X81) += snd-soc-bfin-eval-adau1x81.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
deleted file mode 100644
index 8c1d198..0000000
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ac97-pcm.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  DMA Driver for AC97 sound chip
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-
-#include "bf5xx-ac97.h"
-#include "bf5xx-sport.h"
-
-static unsigned int ac97_chan_mask[] = {
-	SP_FL, /* Mono */
-	SP_STEREO, /* Stereo */
-	SP_2DOT1, /* 2.1*/
-	SP_QUAD,/*Quadraquic*/
-	SP_FL | SP_FR | SP_FC | SP_SL | SP_SR,/*5 channels */
-	SP_5DOT1, /* 5.1 */
-};
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
-	 snd_pcm_uframes_t count)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sport_device *sport = runtime->private_data;
-	unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		bf5xx_pcm_to_ac97((struct ac97_frame *)sport->tx_dma_buf +
-		sport->tx_pos, (__u16 *)runtime->dma_area + sport->tx_pos *
-		runtime->channels, count, chan_mask);
-		sport->tx_pos += runtime->period_size;
-		if (sport->tx_pos >= runtime->buffer_size)
-			sport->tx_pos %= runtime->buffer_size;
-		sport->tx_delay_pos = sport->tx_pos;
-	} else {
-		bf5xx_ac97_to_pcm((struct ac97_frame *)sport->rx_dma_buf +
-		sport->rx_pos, (__u16 *)runtime->dma_area + sport->rx_pos *
-		runtime->channels, count);
-		sport->rx_pos += runtime->period_size;
-		if (sport->rx_pos >= runtime->buffer_size)
-			sport->rx_pos %= runtime->buffer_size;
-	}
-}
-#endif
-
-static void bf5xx_dma_irq(void *data)
-{
-	struct snd_pcm_substream *pcm = data;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-	struct snd_pcm_runtime *runtime = pcm->runtime;
-	struct sport_device *sport = runtime->private_data;
-	bf5xx_mmap_copy(pcm, runtime->period_size);
-	if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		if (sport->once == 0) {
-			snd_pcm_period_elapsed(pcm);
-			bf5xx_mmap_copy(pcm, runtime->period_size);
-			sport->once = 1;
-		}
-	}
-#endif
-	snd_pcm_period_elapsed(pcm);
-}
-
-/* The memory size for pure pcm data is 128*1024 = 0x20000 bytes.
- * The total rx/tx buffer is for ac97 frame to hold all pcm data
- * is  0x20000 * sizeof(struct ac97_frame) / 4.
- */
-static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
-	.info			= SNDRV_PCM_INFO_INTERLEAVED |
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-				   SNDRV_PCM_INFO_MMAP |
-				   SNDRV_PCM_INFO_MMAP_VALID |
-#endif
-				   SNDRV_PCM_INFO_BLOCK_TRANSFER,
-
-	.period_bytes_min	= 32,
-	.period_bytes_max	= 0x10000,
-	.periods_min		= 1,
-	.periods_max		= PAGE_SIZE/32,
-	.buffer_bytes_max	= 0x20000, /* 128 kbytes */
-	.fifo_size		= 16,
-};
-
-static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	size_t size = bf5xx_pcm_hardware.buffer_bytes_max
-			* sizeof(struct ac97_frame) / 4;
-
-	snd_pcm_lib_malloc_pages(substream, size);
-
-	return 0;
-}
-
-static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sport_device *sport = runtime->private_data;
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		sport->once = 0;
-		if (runtime->dma_area)
-			memset(runtime->dma_area, 0, runtime->buffer_size);
-		memset(sport->tx_dma_buf, 0, runtime->buffer_size *
-			sizeof(struct ac97_frame));
-	} else
-		memset(sport->rx_dma_buf, 0, runtime->buffer_size *
-			sizeof(struct ac97_frame));
-#endif
-	snd_pcm_lib_free_pages(substream);
-	return 0;
-}
-
-static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sport_device *sport = runtime->private_data;
-
-	/* An intermediate buffer is introduced for implementing mmap for
-	 * SPORT working in TMD mode(include AC97).
-	 */
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
-		sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
-			runtime->period_size * sizeof(struct ac97_frame));
-	} else {
-		sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
-		sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods,
-			runtime->period_size * sizeof(struct ac97_frame));
-	}
-#else
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
-		sport_config_tx_dma(sport, runtime->dma_area, runtime->periods,
-			runtime->period_size * sizeof(struct ac97_frame));
-	} else {
-		sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
-		sport_config_rx_dma(sport, runtime->dma_area, runtime->periods,
-			runtime->period_size * sizeof(struct ac97_frame));
-	}
-#endif
-	return 0;
-}
-
-static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sport_device *sport = runtime->private_data;
-	int ret = 0;
-
-	pr_debug("%s enter\n", __func__);
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-			bf5xx_mmap_copy(substream, runtime->period_size);
-			sport->tx_delay_pos = 0;
-#endif
-			sport_tx_start(sport);
-		} else
-			sport_rx_start(sport);
-		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-	case SNDRV_PCM_TRIGGER_SUSPEND:
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-			sport->tx_pos = 0;
-#endif
-			sport_tx_stop(sport);
-		} else {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-			sport->rx_pos = 0;
-#endif
-			sport_rx_stop(sport);
-		}
-		break;
-	default:
-		ret = -EINVAL;
-	}
-	return ret;
-}
-
-static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sport_device *sport = runtime->private_data;
-	unsigned int curr;
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		curr = sport->tx_delay_pos;
-	else
-		curr = sport->rx_pos;
-#else
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		curr = sport_curr_offset_tx(sport) / sizeof(struct ac97_frame);
-	else
-		curr = sport_curr_offset_rx(sport) / sizeof(struct ac97_frame);
-
-#endif
-	return curr;
-}
-
-static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	int ret;
-
-	pr_debug("%s enter\n", __func__);
-	snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
-
-	ret = snd_pcm_hw_constraint_integer(runtime,
-					    SNDRV_PCM_HW_PARAM_PERIODS);
-	if (ret < 0)
-		goto out;
-
-	if (sport_handle != NULL)
-		runtime->private_data = sport_handle;
-	else {
-		pr_err("sport_handle is NULL\n");
-		return -1;
-	}
-	return 0;
-
- out:
-	return ret;
-}
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
-	struct vm_area_struct *vma)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	size_t size = vma->vm_end - vma->vm_start;
-	vma->vm_start = (unsigned long)runtime->dma_area;
-	vma->vm_end = vma->vm_start + size;
-	vma->vm_flags |=  VM_SHARED;
-	return 0 ;
-}
-#else
-static	int bf5xx_pcm_copy(struct snd_pcm_substream *substream,
-			   int channel, unsigned long pos,
-			   void *buf, unsigned long count)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
-	struct ac97_frame *dst;
-
-	pr_debug("%s copy pos:0x%lx count:0x%lx\n",
-			substream->stream ? "Capture" : "Playback", pos, count);
-	dst = (struct ac97_frame *)runtime->dma_area +
-		bytes_to_frames(runtime, pos);
-	count = bytes_to_frames(runtime, count);
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		bf5xx_pcm_to_ac97(dst, buf, count, chan_mask);
-	else
-		bf5xx_ac97_to_pcm(dst, buf, count);
-	return 0;
-}
-
-static	int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream,
-				int channel, unsigned long pos,
-				void __user *buf, unsigned long count)
-{
-	return bf5xx_pcm_copy(substream, channel, pos, (void *)buf, count);
-}
-#endif
-
-static const struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
-	.open		= bf5xx_pcm_open,
-	.ioctl		= snd_pcm_lib_ioctl,
-	.hw_params	= bf5xx_pcm_hw_params,
-	.hw_free	= bf5xx_pcm_hw_free,
-	.prepare	= bf5xx_pcm_prepare,
-	.trigger	= bf5xx_pcm_trigger,
-	.pointer	= bf5xx_pcm_pointer,
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-	.mmap		= bf5xx_pcm_mmap,
-#else
-	.copy_user	= bf5xx_pcm_copy_user,
-	.copy_kernel	= bf5xx_pcm_copy,
-#endif
-};
-
-static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
-	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-	struct snd_pcm_substream *substream = pcm->streams[stream].substream;
-	struct snd_dma_buffer *buf = &substream->dma_buffer;
-	size_t size = bf5xx_pcm_hardware.buffer_bytes_max
-			* sizeof(struct ac97_frame) / 4;
-
-	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);
-	if (!buf->area) {
-		pr_err("Failed to allocate dma memory\n");
-		pr_err("Please increase uncached DMA memory region\n");
-		return -ENOMEM;
-	}
-	buf->bytes = size;
-
-	pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
-			buf->area, buf->bytes);
-
-	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-		sport_handle->tx_buf = buf->area;
-	else
-		sport_handle->rx_buf = buf->area;
-
-/*
- * Need to allocate local buffer when enable
- * MMAP for SPORT working in TMD mode (include AC97).
- */
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		if (!sport_handle->tx_dma_buf) {
-			sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
-				size, &sport_handle->tx_dma_phy, GFP_KERNEL);
-			if (!sport_handle->tx_dma_buf) {
-				pr_err("Failed to allocate memory for tx dma buf - Please increase uncached DMA memory region\n");
-				return -ENOMEM;
-			} else
-				memset(sport_handle->tx_dma_buf, 0, size);
-		} else
-			memset(sport_handle->tx_dma_buf, 0, size);
-	} else {
-		if (!sport_handle->rx_dma_buf) {
-			sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \
-				size, &sport_handle->rx_dma_phy, GFP_KERNEL);
-			if (!sport_handle->rx_dma_buf) {
-				pr_err("Failed to allocate memory for rx dma buf - Please increase uncached DMA memory region\n");
-				return -ENOMEM;
-			} else
-				memset(sport_handle->rx_dma_buf, 0, size);
-		} else
-			memset(sport_handle->rx_dma_buf, 0, size);
-	}
-#endif
-	return 0;
-}
-
-static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
-	struct snd_pcm_substream *substream;
-	struct snd_dma_buffer *buf;
-	int stream;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-	size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
-		sizeof(struct ac97_frame) / 4;
-#endif
-	for (stream = 0; stream < 2; stream++) {
-		substream = pcm->streams[stream].substream;
-		if (!substream)
-			continue;
-
-		buf = &substream->dma_buffer;
-		if (!buf->area)
-			continue;
-		dma_free_coherent(NULL, buf->bytes, buf->area, 0);
-		buf->area = NULL;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		if (sport_handle->tx_dma_buf)
-			dma_free_coherent(NULL, size, \
-				sport_handle->tx_dma_buf, 0);
-		sport_handle->tx_dma_buf = NULL;
-	} else {
-
-		if (sport_handle->rx_dma_buf)
-			dma_free_coherent(NULL, size, \
-				sport_handle->rx_dma_buf, 0);
-		sport_handle->rx_dma_buf = NULL;
-	}
-#endif
-	}
-}
-
-static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_card *card = rtd->card->snd_card;
-	struct snd_pcm *pcm = rtd->pcm;
-	int ret;
-
-	pr_debug("%s enter\n", __func__);
-	ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-
-	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
-		ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
-			SNDRV_PCM_STREAM_PLAYBACK);
-		if (ret)
-			goto out;
-	}
-
-	if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
-		ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
-			SNDRV_PCM_STREAM_CAPTURE);
-		if (ret)
-			goto out;
-	}
- out:
-	return ret;
-}
-
-static struct snd_soc_platform_driver bf5xx_ac97_soc_platform = {
-	.ops			= &bf5xx_pcm_ac97_ops,
-	.pcm_new	= bf5xx_pcm_ac97_new,
-	.pcm_free	= bf5xx_pcm_free_dma_buffers,
-};
-
-static int bf5xx_soc_platform_probe(struct platform_device *pdev)
-{
-	return devm_snd_soc_register_platform(&pdev->dev,
-					      &bf5xx_ac97_soc_platform);
-}
-
-static struct platform_driver bf5xx_pcm_driver = {
-	.driver = {
-			.name = "bfin-ac97-pcm-audio",
-	},
-
-	.probe = bf5xx_soc_platform_probe,
-};
-
-module_platform_driver(bf5xx_pcm_driver);
-
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
deleted file mode 100644
index a040cfe..0000000
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * bf5xx-ac97.c -- AC97 support for the ADI blackfin chip.
- *
- * Author:	Roy Huang
- * Created:	11th. June 2007
- * Copyright:	Analog Device 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.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <asm/irq.h>
-#include <asm/portmux.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-
-#include "bf5xx-sport.h"
-#include "bf5xx-ac97.h"
-
-/* Anomaly notes:
- *  05000250 -	AD1980 is running in TDM mode and RFS/TFS are generated by SPORT
- *		contrtoller. But, RFSDIV and TFSDIV are always set to 16*16-1,
- *		while the max AC97 data size is 13*16. The DIV is always larger
- *		than data size. AD73311 and ad2602 are not running in TDM mode.
- *		AD1836 and AD73322 depend on external RFS/TFS only. So, this
- *		anomaly does not affect blackfin sound drivers.
-*/
-
-static struct sport_device *ac97_sport_handle;
-
-void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
-		size_t count, unsigned int chan_mask)
-{
-	while (count--) {
-		dst->ac97_tag = TAG_VALID;
-		if (chan_mask & SP_FL) {
-			dst->ac97_pcm_r = *src++;
-			dst->ac97_tag |= TAG_PCM_RIGHT;
-		}
-		if (chan_mask & SP_FR) {
-			dst->ac97_pcm_l = *src++;
-			dst->ac97_tag |= TAG_PCM_LEFT;
-
-		}
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-		if (chan_mask & SP_SR) {
-			dst->ac97_sl = *src++;
-			dst->ac97_tag |= TAG_PCM_SL;
-		}
-		if (chan_mask & SP_SL) {
-			dst->ac97_sr = *src++;
-			dst->ac97_tag |= TAG_PCM_SR;
-		}
-		if (chan_mask & SP_LFE) {
-			dst->ac97_lfe = *src++;
-			dst->ac97_tag |= TAG_PCM_LFE;
-		}
-		if (chan_mask & SP_FC) {
-			dst->ac97_center = *src++;
-			dst->ac97_tag |= TAG_PCM_CENTER;
-		}
-#endif
-		dst++;
-	}
-}
-EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
-
-void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst,
-		size_t count)
-{
-	while (count--) {
-		*(dst++) = src->ac97_pcm_l;
-		*(dst++) = src->ac97_pcm_r;
-		src++;
-	}
-}
-EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
-
-static unsigned int sport_tx_curr_frag(struct sport_device *sport)
-{
-	return sport->tx_curr_frag = sport_curr_offset_tx(sport) /
-			sport->tx_fragsize;
-}
-
-static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
-{
-	struct sport_device *sport = ac97_sport_handle;
-	int *cmd_count = sport->private_data;
-	int nextfrag = sport_tx_curr_frag(sport);
-	struct ac97_frame *nextwrite;
-
-	sport_incfrag(sport, &nextfrag, 1);
-
-	nextwrite = (struct ac97_frame *)(sport->tx_buf +
-			nextfrag * sport->tx_fragsize);
-	pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
-		sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
-	nextwrite[cmd_count[nextfrag]].ac97_tag |= TAG_CMD;
-	nextwrite[cmd_count[nextfrag]].ac97_addr = addr;
-	nextwrite[cmd_count[nextfrag]].ac97_data = data;
-	++cmd_count[nextfrag];
-	pr_debug("ac97_sport: Inserting %02x/%04x into fragment %d\n",
-			addr >> 8, data, nextfrag);
-}
-
-static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
-	unsigned short reg)
-{
-	struct sport_device *sport_handle = ac97_sport_handle;
-	struct ac97_frame out_frame[2], in_frame[2];
-
-	pr_debug("%s enter 0x%x\n", __func__, reg);
-
-	/* When dma descriptor is enabled, the register should not be read */
-	if (sport_handle->tx_run || sport_handle->rx_run) {
-		pr_err("Could you send a mail to cliff.cai@analog.com "
-				"to report this?\n");
-		return -EFAULT;
-	}
-
-	memset(&out_frame, 0, 2 * sizeof(struct ac97_frame));
-	memset(&in_frame, 0, 2 * sizeof(struct ac97_frame));
-	out_frame[0].ac97_tag = TAG_VALID | TAG_CMD;
-	out_frame[0].ac97_addr = ((reg << 8) | 0x8000);
-	sport_send_and_recv(sport_handle, (unsigned char *)&out_frame,
-			(unsigned char *)&in_frame,
-			2 * sizeof(struct ac97_frame));
-	return in_frame[1].ac97_data;
-}
-
-void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
-	unsigned short val)
-{
-	struct sport_device *sport_handle = ac97_sport_handle;
-
-	pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);
-
-	if (sport_handle->tx_run) {
-		enqueue_cmd(ac97, (reg << 8), val); /* write */
-		enqueue_cmd(ac97, (reg << 8) | 0x8000, 0); /* read back */
-	} else {
-		struct ac97_frame frame;
-		memset(&frame, 0, sizeof(struct ac97_frame));
-		frame.ac97_tag = TAG_VALID | TAG_CMD;
-		frame.ac97_addr = (reg << 8);
-		frame.ac97_data = val;
-		sport_send_and_recv(sport_handle, (unsigned char *)&frame, \
-				NULL, sizeof(struct ac97_frame));
-	}
-}
-
-static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
-{
-	struct sport_device *sport_handle = ac97_sport_handle;
-	u16 gpio = P_IDENT(sport_handle->pin_req[3]);
-
-	pr_debug("%s enter\n", __func__);
-
-	peripheral_free_list(sport_handle->pin_req);
-	gpio_request(gpio, "bf5xx-ac97");
-	gpio_direction_output(gpio, 1);
-	udelay(2);
-	gpio_set_value(gpio, 0);
-	udelay(1);
-	gpio_free(gpio);
-	peripheral_request_list(sport_handle->pin_req, "soc-audio");
-}
-
-static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
-{
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
-	pr_debug("%s enter\n", __func__);
-
-	/* It is specified for bf548-ezkit */
-	gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 0);
-	/* Keep reset pin low for 1 ms */
-	mdelay(1);
-	gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
-	/* Wait for bit clock recover */
-	mdelay(1);
-#else
-	pr_info("%s: Not implemented\n", __func__);
-#endif
-}
-
-static struct snd_ac97_bus_ops bf5xx_ac97_ops = {
-	.read	= bf5xx_ac97_read,
-	.write	= bf5xx_ac97_write,
-	.warm_reset	= bf5xx_ac97_warm_reset,
-	.reset	= bf5xx_ac97_cold_reset,
-};
-
-#ifdef CONFIG_PM
-static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
-{
-	struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
-	pr_debug("%s : sport %d\n", __func__, dai->id);
-	if (!dai->active)
-		return 0;
-	if (dai->capture_active)
-		sport_rx_stop(sport);
-	if (dai->playback_active)
-		sport_tx_stop(sport);
-	return 0;
-}
-
-static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
-{
-	int ret;
-	struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
-	pr_debug("%s : sport %d\n", __func__, dai->id);
-	if (!dai->active)
-		return 0;
-
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-	ret = sport_set_multichannel(sport, 16, 0x3FF, 0x3FF, 1);
-#else
-	ret = sport_set_multichannel(sport, 16, 0x1F, 0x1F, 1);
-#endif
-	if (ret) {
-		pr_err("SPORT is busy!\n");
-		return -EBUSY;
-	}
-
-	ret = sport_config_rx(sport, IRFS, 0xF, 0, (16*16-1));
-	if (ret) {
-		pr_err("SPORT is busy!\n");
-		return -EBUSY;
-	}
-
-	ret = sport_config_tx(sport, ITFS, 0xF, 0, (16*16-1));
-	if (ret) {
-		pr_err("SPORT is busy!\n");
-		return -EBUSY;
-	}
-
-	return 0;
-}
-
-#else
-#define bf5xx_ac97_suspend	NULL
-#define bf5xx_ac97_resume	NULL
-#endif
-
-static struct snd_soc_dai_driver bfin_ac97_dai = {
-	.bus_control = true,
-	.suspend = bf5xx_ac97_suspend,
-	.resume = bf5xx_ac97_resume,
-	.playback = {
-		.stream_name = "AC97 Playback",
-		.channels_min = 2,
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-		.channels_max = 6,
-#else
-		.channels_max = 2,
-#endif
-		.rates = SNDRV_PCM_RATE_48000,
-		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
-	.capture = {
-		.stream_name = "AC97 Capture",
-		.channels_min = 2,
-		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_48000,
-		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
-};
-
-static const struct snd_soc_component_driver bfin_ac97_component = {
-	.name		= "bfin-ac97",
-};
-
-static int asoc_bfin_ac97_probe(struct platform_device *pdev)
-{
-	struct sport_device *sport_handle;
-	int ret;
-
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
-	/* Request PB3 as reset pin */
-	ret = devm_gpio_request_one(&pdev->dev,
-				    CONFIG_SND_BF5XX_RESET_GPIO_NUM,
-				    GPIOF_OUT_INIT_HIGH, "SND_AD198x RESET");
-	if (ret) {
-		dev_err(&pdev->dev,
-			"Failed to request GPIO_%d for reset: %d\n",
-			CONFIG_SND_BF5XX_RESET_GPIO_NUM, ret);
-		return ret;
-	}
-#endif
-
-	sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
-		PAGE_SIZE);
-	if (!sport_handle) {
-		ret = -ENODEV;
-		goto sport_err;
-	}
-
-	/*SPORT works in TDM mode to simulate AC97 transfers*/
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-	ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 0x3FF, 1);
-#else
-	ret = sport_set_multichannel(sport_handle, 16, 0x1F, 0x1F, 1);
-#endif
-	if (ret) {
-		pr_err("SPORT is busy!\n");
-		ret = -EBUSY;
-		goto sport_config_err;
-	}
-
-	ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
-	if (ret) {
-		pr_err("SPORT is busy!\n");
-		ret = -EBUSY;
-		goto sport_config_err;
-	}
-
-	ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
-	if (ret) {
-		pr_err("SPORT is busy!\n");
-		ret = -EBUSY;
-		goto sport_config_err;
-	}
-
-	ret = snd_soc_set_ac97_ops(&bf5xx_ac97_ops);
-	if (ret != 0) {
-		dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
-		goto sport_config_err;
-	}
-
-	ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,
-					 &bfin_ac97_dai, 1);
-	if (ret) {
-		pr_err("Failed to register DAI: %d\n", ret);
-		goto sport_config_err;
-	}
-
-	ac97_sport_handle = sport_handle;
-
-	return 0;
-
-sport_config_err:
-	sport_done(sport_handle);
-sport_err:
-	snd_soc_set_ac97_ops(NULL);
-
-	return ret;
-}
-
-static int asoc_bfin_ac97_remove(struct platform_device *pdev)
-{
-	struct sport_device *sport_handle = platform_get_drvdata(pdev);
-
-	snd_soc_unregister_component(&pdev->dev);
-	sport_done(sport_handle);
-	snd_soc_set_ac97_ops(NULL);
-
-	return 0;
-}
-
-static struct platform_driver asoc_bfin_ac97_driver = {
-	.driver = {
-			.name = "bfin-ac97",
-	},
-
-	.probe = asoc_bfin_ac97_probe,
-	.remove = asoc_bfin_ac97_remove,
-};
-
-module_platform_driver(asoc_bfin_ac97_driver);
-
-MODULE_AUTHOR("Roy Huang");
-MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
deleted file mode 100644
index a680fdc..0000000
--- a/sound/soc/blackfin/bf5xx-ac97.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * sound/soc/blackfin/bf5xx-ac97.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _BF5XX_AC97_H
-#define _BF5XX_AC97_H
-
-/* Frame format in memory, only support stereo currently */
-struct ac97_frame {
-	u16 ac97_tag;		/* slot 0 */
-	u16 ac97_addr;		/* slot 1 */
-	u16 ac97_data;		/* slot 2 */
-	u16 ac97_pcm_l;		/*slot 3:front left*/
-	u16 ac97_pcm_r;		/*slot 4:front left*/
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-	u16 ac97_mdm_l1;
-	u16 ac97_center;	/*slot 6:center*/
-	u16 ac97_sl;		/*slot 7:surround left*/
-	u16 ac97_sr;		/*slot 8:surround right*/
-	u16 ac97_lfe;		/*slot 9:lfe*/
-#endif
-} __attribute__ ((packed));
-
-/* Speaker location */
-#define SP_FL		0x0001
-#define SP_FR		0x0010
-#define SP_FC		0x0002
-#define SP_LFE		0x0020
-#define SP_SL		0x0004
-#define SP_SR		0x0040
-
-#define SP_STEREO	(SP_FL | SP_FR)
-#define SP_2DOT1	(SP_FL | SP_FR | SP_LFE)
-#define SP_QUAD		(SP_FL | SP_FR | SP_SL | SP_SR)
-#define SP_5DOT1	(SP_FL | SP_FR | SP_FC | SP_LFE | SP_SL | SP_SR)
-
-#define TAG_VALID		0x8000
-#define TAG_CMD			0x6000
-#define TAG_PCM_LEFT		0x1000
-#define TAG_PCM_RIGHT		0x0800
-#define TAG_PCM_MDM_L1		0x0400
-#define TAG_PCM_CENTER		0x0200
-#define TAG_PCM_SL		0x0100
-#define TAG_PCM_SR		0x0080
-#define TAG_PCM_LFE		0x0040
-
-void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
-		size_t count, unsigned int chan_mask);
-
-void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst, \
-		size_t count);
-
-#endif
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
deleted file mode 100644
index 864df26..0000000
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ad1836.c
- * Author:       Barry Song <Barry.Song@analog.com>
- *
- * Created:      Aug 4 2009
- * Description:  Board driver for ad1836 sound chip
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad1836.h"
-
-static struct snd_soc_card bf5xx_ad1836;
-
-static int bf5xx_ad1836_init(struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
-	int ret = 0;
-
-	/* set cpu DAI channel mapping */
-	ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
-		channel_map, ARRAY_SIZE(channel_map), channel_map);
-	if (ret < 0)
-		return ret;
-
-	ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xFF, 0xFF, 8, 32);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
-				SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ad1836_dai = {
-	.name = "ad1836",
-	.stream_name = "AD1836",
-	.codec_dai_name = "ad1836-hifi",
-	.platform_name = "bfin-i2s-pcm-audio",
-	.dai_fmt = BF5XX_AD1836_DAIFMT,
-	.init = bf5xx_ad1836_init,
-};
-
-static struct snd_soc_card bf5xx_ad1836 = {
-	.name = "bfin-ad1836",
-	.owner = THIS_MODULE,
-	.dai_link = &bf5xx_ad1836_dai,
-	.num_links = 1,
-};
-
-static int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
-{
-	struct snd_soc_card *card = &bf5xx_ad1836;
-	const char **link_name;
-	int ret;
-
-	link_name = pdev->dev.platform_data;
-	if (!link_name) {
-		dev_err(&pdev->dev, "No platform data supplied\n");
-		return -EINVAL;
-	}
-	bf5xx_ad1836_dai.cpu_dai_name = link_name[0];
-	bf5xx_ad1836_dai.codec_name = link_name[1];
-
-	card->dev = &pdev->dev;
-	platform_set_drvdata(pdev, card);
-
-	ret = devm_snd_soc_register_card(&pdev->dev, card);
-	if (ret)
-		dev_err(&pdev->dev, "Failed to register card\n");
-	return ret;
-}
-
-static struct platform_driver bf5xx_ad1836_driver = {
-	.driver = {
-		.name = "bfin-snd-ad1836",
-		.pm = &snd_soc_pm_ops,
-	},
-	.probe = bf5xx_ad1836_driver_probe,
-};
-module_platform_driver(bf5xx_ad1836_driver);
-
-/* Module information */
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("ALSA SoC AD1836 board driver");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
deleted file mode 100644
index 603ad1f..0000000
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ad193x.c
- * Author:       Barry Song <Barry.Song@analog.com>
- *
- * Created:      Thur June 4 2009
- * Description:  Board driver for ad193x sound chip
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad193x.h"
-
-static struct snd_soc_card bf5xx_ad193x;
-
-static int bf5xx_ad193x_link_init(struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-
-	/* set the codec system clock for DAC and ADC */
-	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 24576000, SND_SOC_CLOCK_IN);
-	if (ret < 0)
-		return ret;
-
-	/* set codec DAI slots, 8 channels, all channels are enabled */
-	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
-	if (ret < 0)
-		return ret;
-
-	ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xFF, 0xFF, 8, 32);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
-				SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
-	{
-		.name = "ad193x",
-		.stream_name = "AD193X",
-		.cpu_dai_name = "bfin-i2s.0",
-		.codec_dai_name ="ad193x-hifi",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.codec_name = "spi0.5",
-		.dai_fmt = BF5XX_AD193X_DAIFMT,
-		.init = bf5xx_ad193x_link_init,
-	},
-	{
-		.name = "ad193x",
-		.stream_name = "AD193X",
-		.cpu_dai_name = "bfin-i2s.1",
-		.codec_dai_name ="ad193x-hifi",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.codec_name = "spi0.5",
-		.dai_fmt = BF5XX_AD193X_DAIFMT,
-		.init = bf5xx_ad193x_link_init,
-	},
-};
-
-static struct snd_soc_card bf5xx_ad193x = {
-	.name = "bfin-ad193x",
-	.owner = THIS_MODULE,
-	.dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-	.num_links = 1,
-};
-
-static struct platform_device *bfxx_ad193x_snd_device;
-
-static int __init bf5xx_ad193x_init(void)
-{
-	int ret;
-
-	bfxx_ad193x_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!bfxx_ad193x_snd_device)
-		return -ENOMEM;
-
-	platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x);
-	ret = platform_device_add(bfxx_ad193x_snd_device);
-
-	if (ret)
-		platform_device_put(bfxx_ad193x_snd_device);
-
-	return ret;
-}
-
-static void __exit bf5xx_ad193x_exit(void)
-{
-	platform_device_unregister(bfxx_ad193x_snd_device);
-}
-
-module_init(bf5xx_ad193x_init);
-module_exit(bf5xx_ad193x_exit);
-
-/* Module information */
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("ALSA SoC AD193X board driver");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
deleted file mode 100644
index 0fa81a5..0000000
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ad1980.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  Board driver for AD1980/1 audio codec
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-/*
- * WARNING:
- *
- * Because Analog Devices Inc. discontinued the ad1980 sound chip since
- * Sep. 2009, this ad1980 driver is not maintained, tested and supported
- * by ADI now.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <asm/dma.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <linux/gpio.h>
-#include <asm/portmux.h>
-
-#include "bf5xx-ac97.h"
-
-static struct snd_soc_card bf5xx_board;
-
-static struct snd_soc_dai_link bf5xx_board_dai[] = {
-	{
-		.name = "AC97",
-		.stream_name = "AC97 HiFi",
-		.cpu_dai_name = "bfin-ac97.0",
-		.codec_dai_name = "ad1980-hifi",
-		.platform_name = "bfin-ac97-pcm-audio",
-		.codec_name = "ad1980",
-	},
-	{
-		.name = "AC97",
-		.stream_name = "AC97 HiFi",
-		.cpu_dai_name = "bfin-ac97.1",
-		.codec_dai_name = "ad1980-hifi",
-		.platform_name = "bfin-ac97-pcm-audio",
-		.codec_name = "ad1980",
-	},
-};
-
-static struct snd_soc_card bf5xx_board = {
-	.name = "bfin-ad1980",
-	.owner = THIS_MODULE,
-	.dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-	.num_links = 1,
-};
-
-static struct platform_device *bf5xx_board_snd_device;
-
-static int __init bf5xx_board_init(void)
-{
-	int ret;
-
-	bf5xx_board_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!bf5xx_board_snd_device)
-		return -ENOMEM;
-
-	platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board);
-	ret = platform_device_add(bf5xx_board_snd_device);
-
-	if (ret)
-		platform_device_put(bf5xx_board_snd_device);
-
-	return ret;
-}
-
-static void __exit bf5xx_board_exit(void)
-{
-	platform_device_unregister(bf5xx_board_snd_device);
-}
-
-module_init(bf5xx_board_init);
-module_exit(bf5xx_board_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC AD1980/1 BF5xx board (Obsolete)");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
deleted file mode 100644
index 786bbdd..0000000
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ad73311.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Thur Sep 25 2008
- * Description:  Board driver for ad73311 sound chip
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad73311.h"
-#include "bf5xx-sport.h"
-
-#if CONFIG_SND_BF5XX_SPORT_NUM == 0
-#define bfin_write_SPORT_TCR1	bfin_write_SPORT0_TCR1
-#define bfin_read_SPORT_TCR1	bfin_read_SPORT0_TCR1
-#define bfin_write_SPORT_TCR2	bfin_write_SPORT0_TCR2
-#define bfin_write_SPORT_TX16	bfin_write_SPORT0_TX16
-#define bfin_read_SPORT_STAT	bfin_read_SPORT0_STAT
-#else
-#define bfin_write_SPORT_TCR1	bfin_write_SPORT1_TCR1
-#define bfin_read_SPORT_TCR1	bfin_read_SPORT1_TCR1
-#define bfin_write_SPORT_TCR2	bfin_write_SPORT1_TCR2
-#define bfin_write_SPORT_TX16	bfin_write_SPORT1_TX16
-#define bfin_read_SPORT_STAT	bfin_read_SPORT1_STAT
-#endif
-
-#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
-
-static struct snd_soc_card bf5xx_ad73311;
-
-static int snd_ad73311_startup(void)
-{
-	pr_debug("%s enter\n", __func__);
-
-	/* Pull up SE pin on AD73311L */
-	gpio_set_value(GPIO_SE, 1);
-	return 0;
-}
-
-static int snd_ad73311_configure(void)
-{
-	unsigned short ctrl_regs[6];
-	unsigned short status = 0;
-	int count = 0;
-
-	/* DMCLK = MCLK = 16.384 MHz
-	 * SCLK = DMCLK/8 = 2.048 MHz
-	 * Sample Rate = DMCLK/2048  = 8 KHz
-	 */
-	ctrl_regs[0] = AD_CONTROL | AD_WRITE | CTRL_REG_B | REGB_MCDIV(0) | \
-			REGB_SCDIV(0) | REGB_DIRATE(0);
-	ctrl_regs[1] = AD_CONTROL | AD_WRITE | CTRL_REG_C | REGC_PUDEV | \
-			REGC_PUADC | REGC_PUDAC | REGC_PUREF | REGC_REFUSE ;
-	ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(2) | \
-			REGD_IGS(2);
-	ctrl_regs[3] = AD_CONTROL | AD_WRITE | CTRL_REG_E | REGE_DA(0x1f);
-	ctrl_regs[4] = AD_CONTROL | AD_WRITE | CTRL_REG_F | REGF_SEEN ;
-	ctrl_regs[5] = AD_CONTROL | AD_WRITE | CTRL_REG_A | REGA_MODE_DATA;
-
-	local_irq_disable();
-	snd_ad73311_startup();
-	udelay(1);
-
-	bfin_write_SPORT_TCR1(TFSR);
-	bfin_write_SPORT_TCR2(0xF);
-	SSYNC();
-
-	/* SPORT Tx Register is a 8 x 16 FIFO, all the data can be put to
-	 * FIFO before enable SPORT to transfer the data
-	 */
-	for (count = 0; count < 6; count++)
-		bfin_write_SPORT_TX16(ctrl_regs[count]);
-	SSYNC();
-	bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() | TSPEN);
-	SSYNC();
-
-	/* When TUVF is set, the data is already send out */
-	while (!(status & TUVF) && ++count < 10000) {
-		udelay(1);
-		status = bfin_read_SPORT_STAT();
-		SSYNC();
-	}
-	bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() & ~TSPEN);
-	SSYNC();
-	local_irq_enable();
-
-	if (count >= 10000) {
-		printk(KERN_ERR "ad73311: failed to configure codec\n");
-		return -1;
-	}
-	return 0;
-}
-
-static int bf5xx_probe(struct snd_soc_card *card)
-{
-	int err;
-	if (gpio_request(GPIO_SE, "AD73311_SE")) {
-		printk(KERN_ERR "%s: Failed ro request GPIO_%d\n", __func__, GPIO_SE);
-		return -EBUSY;
-	}
-
-	gpio_direction_output(GPIO_SE, 0);
-
-	err = snd_ad73311_configure();
-	if (err < 0)
-		return -EFAULT;
-
-	return 0;
-}
-
-#define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
-				SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
-	{
-		.name = "ad73311",
-		.stream_name = "AD73311",
-		.cpu_dai_name = "bfin-i2s.0",
-		.codec_dai_name = "ad73311-hifi",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.codec_name = "ad73311",
-		.dai_fmt = BF5XX_AD7311_DAI_FMT,
-	},
-	{
-		.name = "ad73311",
-		.stream_name = "AD73311",
-		.cpu_dai_name = "bfin-i2s.1",
-		.codec_dai_name = "ad73311-hifi",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.codec_name = "ad73311",
-		.dai_fmt = BF5XX_AD7311_DAI_FMT,
-	},
-};
-
-static struct snd_soc_card bf5xx_ad73311 = {
-	.name = "bfin-ad73311",
-	.owner = THIS_MODULE,
-	.probe = bf5xx_probe,
-	.dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-	.num_links = 1,
-};
-
-static struct platform_device *bf5xx_ad73311_snd_device;
-
-static int __init bf5xx_ad73311_init(void)
-{
-	int ret;
-
-	pr_debug("%s enter\n", __func__);
-	bf5xx_ad73311_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!bf5xx_ad73311_snd_device)
-		return -ENOMEM;
-
-	platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311);
-	ret = platform_device_add(bf5xx_ad73311_snd_device);
-
-	if (ret)
-		platform_device_put(bf5xx_ad73311_snd_device);
-
-	return ret;
-}
-
-static void __exit bf5xx_ad73311_exit(void)
-{
-	pr_debug("%s enter\n", __func__);
-	platform_device_unregister(bf5xx_ad73311_snd_device);
-}
-
-module_init(bf5xx_ad73311_init);
-module_exit(bf5xx_ad73311_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC AD73311 Blackfin");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
deleted file mode 100644
index 51cae76..0000000
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-i2s-pcm.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  DMA driver for i2s codec
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-
-#include "bf5xx-sport.h"
-#include "bf5xx-i2s-pcm.h"
-
-static void bf5xx_dma_irq(void *data)
-{
-	struct snd_pcm_substream *pcm = data;
-	snd_pcm_period_elapsed(pcm);
-}
-
-static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
-	.info			= SNDRV_PCM_INFO_INTERLEAVED |
-				   SNDRV_PCM_INFO_MMAP_VALID |
-				   SNDRV_PCM_INFO_BLOCK_TRANSFER,
-	.period_bytes_min	= 32,
-	.period_bytes_max	= 0x10000,
-	.periods_min		= 1,
-	.periods_max		= PAGE_SIZE/32,
-	.buffer_bytes_max	= 0x20000, /* 128 kbytes */
-	.fifo_size		= 16,
-};
-
-static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	unsigned int buffer_size = params_buffer_bytes(params);
-	struct bf5xx_i2s_pcm_data *dma_data;
-
-	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-	if (dma_data->tdm_mode)
-		buffer_size = buffer_size / params_channels(params) * 8;
-
-	return snd_pcm_lib_malloc_pages(substream, buffer_size);
-}
-
-static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-	snd_pcm_lib_free_pages(substream);
-
-	return 0;
-}
-
-static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sport_device *sport = runtime->private_data;
-	int period_bytes = frames_to_bytes(runtime, runtime->period_size);
-	struct bf5xx_i2s_pcm_data *dma_data;
-
-	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-	if (dma_data->tdm_mode)
-		period_bytes = period_bytes / runtime->channels * 8;
-
-	pr_debug("%s enter\n", __func__);
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
-		sport_config_tx_dma(sport, runtime->dma_area,
-			runtime->periods, period_bytes);
-	} else {
-		sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
-		sport_config_rx_dma(sport, runtime->dma_area,
-			runtime->periods, period_bytes);
-	}
-
-	return 0;
-}
-
-static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sport_device *sport = runtime->private_data;
-	int ret = 0;
-
-	pr_debug("%s enter\n", __func__);
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			sport_tx_start(sport);
-		else
-			sport_rx_start(sport);
-		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-	case SNDRV_PCM_TRIGGER_SUSPEND:
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			sport_tx_stop(sport);
-		else
-			sport_rx_stop(sport);
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	return ret;
-}
-
-static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sport_device *sport = runtime->private_data;
-	unsigned int diff;
-	snd_pcm_uframes_t frames;
-	struct bf5xx_i2s_pcm_data *dma_data;
-
-	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-	pr_debug("%s enter\n", __func__);
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		diff = sport_curr_offset_tx(sport);
-	} else {
-		diff = sport_curr_offset_rx(sport);
-	}
-
-	/*
-	 * TX at least can report one frame beyond the end of the
-	 * buffer if we hit the wraparound case - clamp to within the
-	 * buffer as the ALSA APIs require.
-	 */
-	if (diff == snd_pcm_lib_buffer_bytes(substream))
-		diff = 0;
-
-	frames = bytes_to_frames(substream->runtime, diff);
-	if (dma_data->tdm_mode)
-		frames = frames * runtime->channels / 8;
-
-	return frames;
-}
-
-static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct snd_dma_buffer *buf = &substream->dma_buffer;
-	struct bf5xx_i2s_pcm_data *dma_data;
-	int ret;
-
-	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-	pr_debug("%s enter\n", __func__);
-
-	snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
-	if (dma_data->tdm_mode)
-		runtime->hw.buffer_bytes_max /= 4;
-	else
-		runtime->hw.info |= SNDRV_PCM_INFO_MMAP;
-
-	ret = snd_pcm_hw_constraint_integer(runtime,
-			SNDRV_PCM_HW_PARAM_PERIODS);
-	if (ret < 0)
-		goto out;
-
-	if (sport_handle != NULL) {
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			sport_handle->tx_buf = buf->area;
-		else
-			sport_handle->rx_buf = buf->area;
-
-		runtime->private_data = sport_handle;
-	} else {
-		pr_err("sport_handle is NULL\n");
-		return -1;
-	}
-	return 0;
-
- out:
-	return ret;
-}
-
-static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
-	struct vm_area_struct *vma)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	size_t size = vma->vm_end - vma->vm_start;
-	vma->vm_start = (unsigned long)runtime->dma_area;
-	vma->vm_end = vma->vm_start + size;
-	vma->vm_flags |=  VM_SHARED;
-
-	return 0 ;
-}
-
-static int bf5xx_pcm_copy(struct snd_pcm_substream *substream,
-			  int channel, unsigned long pos,
-			  void *buf, unsigned long count)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	unsigned int sample_size = runtime->sample_bits / 8;
-	struct bf5xx_i2s_pcm_data *dma_data;
-	unsigned int i;
-	void *src, *dst;
-
-	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-	if (dma_data->tdm_mode) {
-		pos = bytes_to_frames(runtime, pos);
-		count = bytes_to_frames(runtime, count);
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			src = buf;
-			dst = runtime->dma_area;
-			dst += pos * sample_size * 8;
-
-			while (count--) {
-				for (i = 0; i < runtime->channels; i++) {
-					memcpy(dst + dma_data->map[i] *
-						sample_size, src, sample_size);
-					src += sample_size;
-				}
-				dst += 8 * sample_size;
-			}
-		} else {
-			src = runtime->dma_area;
-			src += pos * sample_size * 8;
-			dst = buf;
-
-			while (count--) {
-				for (i = 0; i < runtime->channels; i++) {
-					memcpy(dst, src + dma_data->map[i] *
-						sample_size, sample_size);
-					dst += sample_size;
-				}
-				src += 8 * sample_size;
-			}
-		}
-	} else {
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			src = buf;
-			dst = runtime->dma_area;
-			dst += pos;
-		} else {
-			src = runtime->dma_area;
-			src += pos;
-			dst = buf;
-		}
-
-		memcpy(dst, src, count);
-	}
-
-	return 0;
-}
-
-static int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream,
-			       int channel, unsigned long pos,
-			       void __user *buf, unsigned long count)
-{
-	return bf5xx_pcm_copy(substream, channel, pos, (void *)buf, count);
-}
-
-static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
-			     int channel, unsigned long pos,
-			     unsigned long count)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	unsigned int sample_size = runtime->sample_bits / 8;
-	void *buf = runtime->dma_area;
-	struct bf5xx_i2s_pcm_data *dma_data;
-	unsigned int offset, samples;
-
-	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-	if (dma_data->tdm_mode) {
-		offset = bytes_to_frames(runtime, pos) * 8 * sample_size;
-		samples = bytes_to_frames(runtime, count) * 8;
-	} else {
-		offset = pos;
-		samples = bytes_to_samples(runtime, count);
-	}
-
-	snd_pcm_format_set_silence(runtime->format, buf + offset, samples);
-
-	return 0;
-}
-
-static const struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
-	.open		= bf5xx_pcm_open,
-	.ioctl		= snd_pcm_lib_ioctl,
-	.hw_params	= bf5xx_pcm_hw_params,
-	.hw_free	= bf5xx_pcm_hw_free,
-	.prepare	= bf5xx_pcm_prepare,
-	.trigger	= bf5xx_pcm_trigger,
-	.pointer	= bf5xx_pcm_pointer,
-	.mmap		= bf5xx_pcm_mmap,
-	.copy_user	= bf5xx_pcm_copy_user,
-	.copy_kernel	= bf5xx_pcm_copy,
-	.fill_silence	= bf5xx_pcm_silence,
-};
-
-static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_card *card = rtd->card->snd_card;
-	size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
-	int ret;
-
-	pr_debug("%s enter\n", __func__);
-	ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-
-	return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
-				SNDRV_DMA_TYPE_DEV, card->dev, size, size);
-}
-
-static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = {
-	.ops		= &bf5xx_pcm_i2s_ops,
-	.pcm_new	= bf5xx_pcm_i2s_new,
-};
-
-static int bfin_i2s_soc_platform_probe(struct platform_device *pdev)
-{
-	return devm_snd_soc_register_platform(&pdev->dev,
-					      &bf5xx_i2s_soc_platform);
-}
-
-static struct platform_driver bfin_i2s_pcm_driver = {
-	.driver = {
-		.name = "bfin-i2s-pcm-audio",
-	},
-
-	.probe = bfin_i2s_soc_platform_probe,
-};
-
-module_platform_driver(bfin_i2s_pcm_driver);
-
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.h b/sound/soc/blackfin/bf5xx-i2s-pcm.h
deleted file mode 100644
index 1f04352..0000000
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * 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 _BF5XX_TDM_PCM_H
-#define _BF5XX_TDM_PCM_H
-
-#define BFIN_TDM_DAI_MAX_SLOTS 8
-
-struct bf5xx_i2s_pcm_data {
-	unsigned int map[BFIN_TDM_DAI_MAX_SLOTS];
-	bool tdm_mode;
-};
-
-#endif
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
deleted file mode 100644
index b69aeef..0000000
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-i2s.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  Blackfin I2S CPU DAI driver
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <asm/irq.h>
-#include <asm/portmux.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-
-#include "bf5xx-sport.h"
-#include "bf5xx-i2s-pcm.h"
-
-struct bf5xx_i2s_port {
-	u16 tcr1;
-	u16 rcr1;
-	u16 tcr2;
-	u16 rcr2;
-	int configured;
-
-	unsigned int slots;
-	unsigned int tx_mask;
-	unsigned int rx_mask;
-
-	struct bf5xx_i2s_pcm_data tx_dma_data;
-	struct bf5xx_i2s_pcm_data rx_dma_data;
-};
-
-static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-		unsigned int fmt)
-{
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-	struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-	int ret = 0;
-
-	/* interface format:support I2S,slave mode */
-	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-	case SND_SOC_DAIFMT_I2S:
-		bf5xx_i2s->tcr1 |= TFSR | TCKFE;
-		bf5xx_i2s->rcr1 |= RFSR | RCKFE;
-		bf5xx_i2s->tcr2 |= TSFSE;
-		bf5xx_i2s->rcr2 |= RSFSE;
-		break;
-	case SND_SOC_DAIFMT_DSP_A:
-		bf5xx_i2s->tcr1 |= TFSR;
-		bf5xx_i2s->rcr1 |= RFSR;
-		break;
-	case SND_SOC_DAIFMT_LEFT_J:
-		ret = -EINVAL;
-		break;
-	default:
-		dev_err(cpu_dai->dev, "%s: Unknown DAI format type\n",
-			__func__);
-		ret = -EINVAL;
-		break;
-	}
-
-	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-	case SND_SOC_DAIFMT_CBM_CFM:
-		break;
-	case SND_SOC_DAIFMT_CBS_CFS:
-	case SND_SOC_DAIFMT_CBM_CFS:
-	case SND_SOC_DAIFMT_CBS_CFM:
-		ret = -EINVAL;
-		break;
-	default:
-		dev_err(cpu_dai->dev, "%s: Unknown DAI master type\n",
-			__func__);
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
-				struct snd_pcm_hw_params *params,
-				struct snd_soc_dai *dai)
-{
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-	struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-	int ret = 0;
-
-	bf5xx_i2s->tcr2 &= ~0x1f;
-	bf5xx_i2s->rcr2 &= ~0x1f;
-	switch (params_format(params)) {
-	case SNDRV_PCM_FORMAT_S8:
-		bf5xx_i2s->tcr2 |= 7;
-		bf5xx_i2s->rcr2 |= 7;
-		sport_handle->wdsize = 1;
-		break;
-	case SNDRV_PCM_FORMAT_S16_LE:
-		bf5xx_i2s->tcr2 |= 15;
-		bf5xx_i2s->rcr2 |= 15;
-		sport_handle->wdsize = 2;
-		break;
-	case SNDRV_PCM_FORMAT_S24_LE:
-		bf5xx_i2s->tcr2 |= 23;
-		bf5xx_i2s->rcr2 |= 23;
-		sport_handle->wdsize = 3;
-		break;
-	case SNDRV_PCM_FORMAT_S32_LE:
-		bf5xx_i2s->tcr2 |= 31;
-		bf5xx_i2s->rcr2 |= 31;
-		sport_handle->wdsize = 4;
-		break;
-	}
-
-	if (!bf5xx_i2s->configured) {
-		/*
-		 * TX and RX are not independent,they are enabled at the
-		 * same time, even if only one side is running. So, we
-		 * need to configure both of them at the time when the first
-		 * stream is opened.
-		 *
-		 * CPU DAI:slave mode.
-		 */
-		bf5xx_i2s->configured = 1;
-		ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
-				      bf5xx_i2s->rcr2, 0, 0);
-		if (ret) {
-			dev_err(dai->dev, "SPORT is busy!\n");
-			return -EBUSY;
-		}
-
-		ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
-				      bf5xx_i2s->tcr2, 0, 0);
-		if (ret) {
-			dev_err(dai->dev, "SPORT is busy!\n");
-			return -EBUSY;
-		}
-	}
-
-	return 0;
-}
-
-static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
-			       struct snd_soc_dai *dai)
-{
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-	struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-
-	dev_dbg(dai->dev, "%s enter\n", __func__);
-	/* No active stream, SPORT is allowed to be configured again. */
-	if (!dai->active)
-		bf5xx_i2s->configured = 0;
-}
-
-static int bf5xx_i2s_set_channel_map(struct snd_soc_dai *dai,
-		unsigned int tx_num, unsigned int *tx_slot,
-		unsigned int rx_num, unsigned int *rx_slot)
-{
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-	struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-	unsigned int tx_mapped = 0, rx_mapped = 0;
-	unsigned int slot;
-	int i;
-
-	if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) ||
-			(rx_num > BFIN_TDM_DAI_MAX_SLOTS))
-		return -EINVAL;
-
-	for (i = 0; i < tx_num; i++) {
-		slot = tx_slot[i];
-		if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
-				(!(tx_mapped & (1 << slot)))) {
-			bf5xx_i2s->tx_dma_data.map[i] = slot;
-			tx_mapped |= 1 << slot;
-		} else
-			return -EINVAL;
-	}
-	for (i = 0; i < rx_num; i++) {
-		slot = rx_slot[i];
-		if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
-				(!(rx_mapped & (1 << slot)))) {
-			bf5xx_i2s->rx_dma_data.map[i] = slot;
-			rx_mapped |= 1 << slot;
-		} else
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int bf5xx_i2s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
-	unsigned int rx_mask, int slots, int width)
-{
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-	struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-
-	if (slots % 8 != 0 || slots > 8)
-		return -EINVAL;
-
-	if (width != 32)
-		return -EINVAL;
-
-	bf5xx_i2s->slots = slots;
-	bf5xx_i2s->tx_mask = tx_mask;
-	bf5xx_i2s->rx_mask = rx_mask;
-
-	bf5xx_i2s->tx_dma_data.tdm_mode = slots != 0;
-	bf5xx_i2s->rx_dma_data.tdm_mode = slots != 0;
-
-	return sport_set_multichannel(sport_handle, slots, tx_mask, rx_mask, 0);
-}
-
-#ifdef CONFIG_PM
-static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
-{
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-
-	dev_dbg(dai->dev, "%s : sport %d\n", __func__, dai->id);
-
-	if (dai->capture_active)
-		sport_rx_stop(sport_handle);
-	if (dai->playback_active)
-		sport_tx_stop(sport_handle);
-	return 0;
-}
-
-static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
-{
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-	struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-	int ret;
-
-	dev_dbg(dai->dev, "%s : sport %d\n", __func__, dai->id);
-
-	ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
-				      bf5xx_i2s->rcr2, 0, 0);
-	if (ret) {
-		dev_err(dai->dev, "SPORT is busy!\n");
-		return -EBUSY;
-	}
-
-	ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
-				      bf5xx_i2s->tcr2, 0, 0);
-	if (ret) {
-		dev_err(dai->dev, "SPORT is busy!\n");
-		return -EBUSY;
-	}
-
-	return sport_set_multichannel(sport_handle, bf5xx_i2s->slots,
-			bf5xx_i2s->tx_mask, bf5xx_i2s->rx_mask, 0);
-}
-
-#else
-#define bf5xx_i2s_suspend	NULL
-#define bf5xx_i2s_resume	NULL
-#endif
-
-static int bf5xx_i2s_dai_probe(struct snd_soc_dai *dai)
-{
-	struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-	struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-	unsigned int i;
-
-	for (i = 0; i < BFIN_TDM_DAI_MAX_SLOTS; i++) {
-		bf5xx_i2s->tx_dma_data.map[i] = i;
-		bf5xx_i2s->rx_dma_data.map[i] = i;
-	}
-
-	dai->playback_dma_data = &bf5xx_i2s->tx_dma_data;
-	dai->capture_dma_data = &bf5xx_i2s->rx_dma_data;
-
-	return 0;
-}
-
-#define BF5XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
-		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
-		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
-		SNDRV_PCM_RATE_96000)
-
-#define BF5XX_I2S_FORMATS \
-	(SNDRV_PCM_FMTBIT_S8 | \
-	 SNDRV_PCM_FMTBIT_S16_LE | \
-	 SNDRV_PCM_FMTBIT_S24_LE | \
-	 SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
-	.shutdown	 = bf5xx_i2s_shutdown,
-	.hw_params	 = bf5xx_i2s_hw_params,
-	.set_fmt	 = bf5xx_i2s_set_dai_fmt,
-	.set_tdm_slot	 = bf5xx_i2s_set_tdm_slot,
-	.set_channel_map = bf5xx_i2s_set_channel_map,
-};
-
-static struct snd_soc_dai_driver bf5xx_i2s_dai = {
-	.probe = bf5xx_i2s_dai_probe,
-	.suspend = bf5xx_i2s_suspend,
-	.resume = bf5xx_i2s_resume,
-	.playback = {
-		.channels_min = 2,
-		.channels_max = 8,
-		.rates = BF5XX_I2S_RATES,
-		.formats = BF5XX_I2S_FORMATS,},
-	.capture = {
-		.channels_min = 2,
-		.channels_max = 8,
-		.rates = BF5XX_I2S_RATES,
-		.formats = BF5XX_I2S_FORMATS,},
-	.ops = &bf5xx_i2s_dai_ops,
-};
-
-static const struct snd_soc_component_driver bf5xx_i2s_component = {
-	.name		= "bf5xx-i2s",
-};
-
-static int bf5xx_i2s_probe(struct platform_device *pdev)
-{
-	struct sport_device *sport_handle;
-	int ret;
-
-	/* configure SPORT for I2S */
-	sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
-		sizeof(struct bf5xx_i2s_port));
-	if (!sport_handle)
-		return -ENODEV;
-
-	/* register with the ASoC layers */
-	ret = snd_soc_register_component(&pdev->dev, &bf5xx_i2s_component,
-					 &bf5xx_i2s_dai, 1);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
-		sport_done(sport_handle);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int bf5xx_i2s_remove(struct platform_device *pdev)
-{
-	struct sport_device *sport_handle = platform_get_drvdata(pdev);
-
-	dev_dbg(&pdev->dev, "%s enter\n", __func__);
-
-	snd_soc_unregister_component(&pdev->dev);
-	sport_done(sport_handle);
-
-	return 0;
-}
-
-static struct platform_driver bfin_i2s_driver = {
-	.probe  = bf5xx_i2s_probe,
-	.remove = bf5xx_i2s_remove,
-	.driver = {
-		.name = "bfin-i2s",
-	},
-};
-
-module_platform_driver(bfin_i2s_driver);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
deleted file mode 100644
index 9dfa124..0000000
--- a/sound/soc/blackfin/bf5xx-sport.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * File:         bf5xx_sport.c
- * Based on:
- * Author:       Roy Huang <roy.huang@analog.com>
- *
- * Created:      Tue Sep 21 10:52:42 CEST 2004
- * Description:
- *               Blackfin SPORT Driver
- *
- *               Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/bug.h>
-#include <linux/module.h>
-#include <asm/portmux.h>
-#include <asm/dma.h>
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-
-#include "bf5xx-sport.h"
-/* delay between frame sync pulse and first data bit in multichannel mode */
-#define FRAME_DELAY (1<<12)
-
-/* note: multichannel is in units of 8 channels,
- * tdm_count is # channels NOT / 8 ! */
-int sport_set_multichannel(struct sport_device *sport,
-		int tdm_count, u32 tx_mask, u32 rx_mask, int packed)
-{
-	pr_debug("%s tdm_count=%d tx_mask:0x%08x rx_mask:0x%08x packed=%d\n",
-			__func__, tdm_count, tx_mask, rx_mask, packed);
-
-	if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
-		return -EBUSY;
-
-	if (tdm_count & 0x7)
-		return -EINVAL;
-
-	if (tdm_count > 32)
-		return -EINVAL; /* Only support less than 32 channels now */
-
-	if (tdm_count) {
-		sport->regs->mcmc1 = ((tdm_count>>3)-1) << 12;
-		sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
-				(packed ? (MCDTXPE|MCDRXPE) : 0);
-
-		sport->regs->mtcs0 = tx_mask;
-		sport->regs->mrcs0 = rx_mask;
-		sport->regs->mtcs1 = 0;
-		sport->regs->mrcs1 = 0;
-		sport->regs->mtcs2 = 0;
-		sport->regs->mrcs2 = 0;
-		sport->regs->mtcs3 = 0;
-		sport->regs->mrcs3 = 0;
-	} else {
-		sport->regs->mcmc1 = 0;
-		sport->regs->mcmc2 = 0;
-
-		sport->regs->mtcs0 = 0;
-		sport->regs->mrcs0 = 0;
-	}
-
-	sport->regs->mtcs1 = 0; sport->regs->mtcs2 = 0; sport->regs->mtcs3 = 0;
-	sport->regs->mrcs1 = 0; sport->regs->mrcs2 = 0; sport->regs->mrcs3 = 0;
-
-	SSYNC();
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_set_multichannel);
-
-int sport_config_rx(struct sport_device *sport, unsigned int rcr1,
-		unsigned int rcr2, unsigned int clkdiv, unsigned int fsdiv)
-{
-	if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
-		return -EBUSY;
-
-	sport->regs->rcr1 = rcr1;
-	sport->regs->rcr2 = rcr2;
-	sport->regs->rclkdiv = clkdiv;
-	sport->regs->rfsdiv = fsdiv;
-
-	SSYNC();
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_config_rx);
-
-int sport_config_tx(struct sport_device *sport, unsigned int tcr1,
-		unsigned int tcr2, unsigned int clkdiv, unsigned int fsdiv)
-{
-	if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
-		return -EBUSY;
-
-	sport->regs->tcr1 = tcr1;
-	sport->regs->tcr2 = tcr2;
-	sport->regs->tclkdiv = clkdiv;
-	sport->regs->tfsdiv = fsdiv;
-
-	SSYNC();
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_config_tx);
-
-static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
-		size_t fragsize, unsigned int cfg,
-		unsigned int x_count, unsigned int ycount, size_t wdsize)
-{
-
-	int i;
-
-	for (i = 0; i < fragcount; ++i) {
-		desc[i].next_desc_addr  = &(desc[i + 1]);
-		desc[i].start_addr = (unsigned long)buf + i*fragsize;
-		desc[i].cfg = cfg;
-		desc[i].x_count = x_count;
-		desc[i].x_modify = wdsize;
-		desc[i].y_count = ycount;
-		desc[i].y_modify = wdsize;
-	}
-
-	/* make circular */
-	desc[fragcount-1].next_desc_addr = desc;
-
-	pr_debug("setup desc: desc0=%p, next0=%p, desc1=%p,"
-		"next1=%p\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n",
-		desc, desc[0].next_desc_addr,
-		desc+1, desc[1].next_desc_addr,
-		desc[0].x_count, desc[0].y_count,
-		desc[0].start_addr, desc[0].cfg);
-}
-
-static int sport_start(struct sport_device *sport)
-{
-	enable_dma(sport->dma_rx_chan);
-	enable_dma(sport->dma_tx_chan);
-	sport->regs->rcr1 |= RSPEN;
-	sport->regs->tcr1 |= TSPEN;
-	SSYNC();
-
-	return 0;
-}
-
-static int sport_stop(struct sport_device *sport)
-{
-	sport->regs->tcr1 &= ~TSPEN;
-	sport->regs->rcr1 &= ~RSPEN;
-	SSYNC();
-
-	disable_dma(sport->dma_rx_chan);
-	disable_dma(sport->dma_tx_chan);
-	return 0;
-}
-
-static inline int sport_hook_rx_dummy(struct sport_device *sport)
-{
-	struct dmasg *desc, temp_desc;
-	unsigned long flags;
-
-	if (WARN_ON(!sport->dummy_rx_desc) ||
-	    WARN_ON(sport->curr_rx_desc == sport->dummy_rx_desc))
-		return -EINVAL;
-
-	/* Maybe the dummy buffer descriptor ring is damaged */
-	sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc + 1;
-
-	local_irq_save(flags);
-	desc = get_dma_next_desc_ptr(sport->dma_rx_chan);
-	/* Copy the descriptor which will be damaged to backup */
-	temp_desc = *desc;
-	desc->x_count = sport->dummy_count / 2;
-	desc->y_count = 0;
-	desc->next_desc_addr = sport->dummy_rx_desc;
-	local_irq_restore(flags);
-	/* Waiting for dummy buffer descriptor is already hooked*/
-	while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
-			sizeof(struct dmasg)) != sport->dummy_rx_desc)
-		continue;
-	sport->curr_rx_desc = sport->dummy_rx_desc;
-	/* Restore the damaged descriptor */
-	*desc = temp_desc;
-
-	return 0;
-}
-
-static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
-{
-	if (dummy) {
-		sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc;
-		sport->curr_rx_desc = sport->dummy_rx_desc;
-	} else
-		sport->curr_rx_desc = sport->dma_rx_desc;
-
-	set_dma_next_desc_addr(sport->dma_rx_chan, sport->curr_rx_desc);
-	set_dma_x_count(sport->dma_rx_chan, 0);
-	set_dma_x_modify(sport->dma_rx_chan, 0);
-	set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \
-				WDSIZE_32 | WNR));
-	set_dma_curr_addr(sport->dma_rx_chan, sport->curr_rx_desc->start_addr);
-	SSYNC();
-
-	return 0;
-}
-
-static inline int sport_tx_dma_start(struct sport_device *sport, int dummy)
-{
-	if (dummy) {
-		sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc;
-		sport->curr_tx_desc = sport->dummy_tx_desc;
-	} else
-		sport->curr_tx_desc = sport->dma_tx_desc;
-
-	set_dma_next_desc_addr(sport->dma_tx_chan, sport->curr_tx_desc);
-	set_dma_x_count(sport->dma_tx_chan, 0);
-	set_dma_x_modify(sport->dma_tx_chan, 0);
-	set_dma_config(sport->dma_tx_chan,
-			(DMAFLOW_LARGE | NDSIZE_9 | WDSIZE_32));
-	set_dma_curr_addr(sport->dma_tx_chan, sport->curr_tx_desc->start_addr);
-	SSYNC();
-
-	return 0;
-}
-
-int sport_rx_start(struct sport_device *sport)
-{
-	unsigned long flags;
-	pr_debug("%s enter\n", __func__);
-	if (sport->rx_run)
-		return -EBUSY;
-	if (sport->tx_run) {
-		/* tx is running, rx is not running */
-		if (WARN_ON(!sport->dma_rx_desc) ||
-		    WARN_ON(sport->curr_rx_desc != sport->dummy_rx_desc))
-			return -EINVAL;
-		local_irq_save(flags);
-		while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
-			sizeof(struct dmasg)) != sport->dummy_rx_desc)
-			continue;
-		sport->dummy_rx_desc->next_desc_addr = sport->dma_rx_desc;
-		local_irq_restore(flags);
-		sport->curr_rx_desc = sport->dma_rx_desc;
-	} else {
-		sport_tx_dma_start(sport, 1);
-		sport_rx_dma_start(sport, 0);
-		sport_start(sport);
-	}
-
-	sport->rx_run = 1;
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_rx_start);
-
-int sport_rx_stop(struct sport_device *sport)
-{
-	pr_debug("%s enter\n", __func__);
-
-	if (!sport->rx_run)
-		return 0;
-	if (sport->tx_run) {
-		/* TX dma is still running, hook the dummy buffer */
-		sport_hook_rx_dummy(sport);
-	} else {
-		/* Both rx and tx dma will be stopped */
-		sport_stop(sport);
-		sport->curr_rx_desc = NULL;
-		sport->curr_tx_desc = NULL;
-	}
-
-	sport->rx_run = 0;
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_rx_stop);
-
-static inline int sport_hook_tx_dummy(struct sport_device *sport)
-{
-	struct dmasg *desc, temp_desc;
-	unsigned long flags;
-
-	if (WARN_ON(!sport->dummy_tx_desc) ||
-	    WARN_ON(sport->curr_tx_desc == sport->dummy_tx_desc))
-		return -EINVAL;
-
-	sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc + 1;
-
-	/* Shorten the time on last normal descriptor */
-	local_irq_save(flags);
-	desc = get_dma_next_desc_ptr(sport->dma_tx_chan);
-	/* Store the descriptor which will be damaged */
-	temp_desc = *desc;
-	desc->x_count = sport->dummy_count / 2;
-	desc->y_count = 0;
-	desc->next_desc_addr = sport->dummy_tx_desc;
-	local_irq_restore(flags);
-	/* Waiting for dummy buffer descriptor is already hooked*/
-	while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
-			sizeof(struct dmasg)) != sport->dummy_tx_desc)
-		continue;
-	sport->curr_tx_desc = sport->dummy_tx_desc;
-	/* Restore the damaged descriptor */
-	*desc = temp_desc;
-
-	return 0;
-}
-
-int sport_tx_start(struct sport_device *sport)
-{
-	unsigned long flags;
-	pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
-			sport->tx_run, sport->rx_run);
-	if (sport->tx_run)
-		return -EBUSY;
-	if (sport->rx_run) {
-		if (WARN_ON(!sport->dma_tx_desc) ||
-		    WARN_ON(sport->curr_tx_desc != sport->dummy_tx_desc))
-			return -EINVAL;
-		/* Hook the normal buffer descriptor */
-		local_irq_save(flags);
-		while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) -
-			sizeof(struct dmasg)) != sport->dummy_tx_desc)
-			continue;
-		sport->dummy_tx_desc->next_desc_addr = sport->dma_tx_desc;
-		local_irq_restore(flags);
-		sport->curr_tx_desc = sport->dma_tx_desc;
-	} else {
-
-		sport_tx_dma_start(sport, 0);
-		/* Let rx dma run the dummy buffer */
-		sport_rx_dma_start(sport, 1);
-		sport_start(sport);
-	}
-	sport->tx_run = 1;
-	return 0;
-}
-EXPORT_SYMBOL(sport_tx_start);
-
-int sport_tx_stop(struct sport_device *sport)
-{
-	if (!sport->tx_run)
-		return 0;
-	if (sport->rx_run) {
-		/* RX is still running, hook the dummy buffer */
-		sport_hook_tx_dummy(sport);
-	} else {
-		/* Both rx and tx dma stopped */
-		sport_stop(sport);
-		sport->curr_rx_desc = NULL;
-		sport->curr_tx_desc = NULL;
-	}
-
-	sport->tx_run = 0;
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_tx_stop);
-
-static inline int compute_wdsize(size_t wdsize)
-{
-	switch (wdsize) {
-	case 1:
-		return WDSIZE_8;
-	case 2:
-		return WDSIZE_16;
-	case 4:
-	default:
-		return WDSIZE_32;
-	}
-}
-
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
-		int fragcount, size_t fragsize)
-{
-	unsigned int x_count;
-	unsigned int y_count;
-	unsigned int cfg;
-	dma_addr_t addr;
-
-	pr_debug("%s buf:%p, frag:%d, fragsize:0x%lx\n", __func__, \
-			buf, fragcount, fragsize);
-
-	x_count = fragsize / sport->wdsize;
-	y_count = 0;
-
-	/* for fragments larger than 64k words we use 2d dma,
-	 * denote fragecount as two numbers' mutliply and both of them
-	 * are less than 64k.*/
-	if (x_count >= 0x10000) {
-		int i, count = x_count;
-
-		for (i = 16; i > 0; i--) {
-			x_count = 1 << i;
-			if ((count & (x_count - 1)) == 0) {
-				y_count = count >> i;
-				if (y_count < 0x10000)
-					break;
-			}
-		}
-		if (i == 0)
-			return -EINVAL;
-	}
-	pr_debug("%s(x_count:0x%x, y_count:0x%x)\n", __func__,
-			x_count, y_count);
-
-	if (sport->dma_rx_desc)
-		dma_free_coherent(NULL, sport->rx_desc_bytes,
-					sport->dma_rx_desc, 0);
-
-	/* Allocate a new descritor ring as current one. */
-	sport->dma_rx_desc = dma_alloc_coherent(NULL, \
-			fragcount * sizeof(struct dmasg), &addr, 0);
-	sport->rx_desc_bytes = fragcount * sizeof(struct dmasg);
-
-	if (!sport->dma_rx_desc) {
-		pr_err("Failed to allocate memory for rx desc\n");
-		return -ENOMEM;
-	}
-
-	sport->rx_buf = buf;
-	sport->rx_fragsize = fragsize;
-	sport->rx_frags = fragcount;
-
-	cfg     = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | WNR | \
-		  (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
-
-	if (y_count != 0)
-		cfg |= DMA2D;
-
-	setup_desc(sport->dma_rx_desc, buf, fragcount, fragsize,
-			cfg|DMAEN, x_count, y_count, sport->wdsize);
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_config_rx_dma);
-
-int sport_config_tx_dma(struct sport_device *sport, void *buf, \
-		int fragcount, size_t fragsize)
-{
-	unsigned int x_count;
-	unsigned int y_count;
-	unsigned int cfg;
-	dma_addr_t addr;
-
-	pr_debug("%s buf:%p, fragcount:%d, fragsize:0x%lx\n",
-			__func__, buf, fragcount, fragsize);
-
-	x_count = fragsize/sport->wdsize;
-	y_count = 0;
-
-	/* for fragments larger than 64k words we use 2d dma,
-	 * denote fragecount as two numbers' mutliply and both of them
-	 * are less than 64k.*/
-	if (x_count >= 0x10000) {
-		int i, count = x_count;
-
-		for (i = 16; i > 0; i--) {
-			x_count = 1 << i;
-			if ((count & (x_count - 1)) == 0) {
-				y_count = count >> i;
-				if (y_count < 0x10000)
-					break;
-			}
-		}
-		if (i == 0)
-			return -EINVAL;
-	}
-	pr_debug("%s x_count:0x%x, y_count:0x%x\n", __func__,
-			x_count, y_count);
-
-
-	if (sport->dma_tx_desc) {
-		dma_free_coherent(NULL, sport->tx_desc_bytes, \
-				sport->dma_tx_desc, 0);
-	}
-
-	sport->dma_tx_desc = dma_alloc_coherent(NULL, \
-			fragcount * sizeof(struct dmasg), &addr, 0);
-	sport->tx_desc_bytes = fragcount * sizeof(struct dmasg);
-	if (!sport->dma_tx_desc) {
-		pr_err("Failed to allocate memory for tx desc\n");
-		return -ENOMEM;
-	}
-
-	sport->tx_buf = buf;
-	sport->tx_fragsize = fragsize;
-	sport->tx_frags = fragcount;
-	cfg     = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | \
-		  (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
-
-	if (y_count != 0)
-		cfg |= DMA2D;
-
-	setup_desc(sport->dma_tx_desc, buf, fragcount, fragsize,
-			cfg|DMAEN, x_count, y_count, sport->wdsize);
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_config_tx_dma);
-
-/* setup dummy dma descriptor ring, which don't generate interrupts,
- * the x_modify is set to 0 */
-static int sport_config_rx_dummy(struct sport_device *sport)
-{
-	struct dmasg *desc;
-	unsigned config;
-
-	pr_debug("%s entered\n", __func__);
-	if (L1_DATA_A_LENGTH)
-		desc = l1_data_sram_zalloc(2 * sizeof(*desc));
-	else {
-		dma_addr_t addr;
-		desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
-		memset(desc, 0, 2 * sizeof(*desc));
-	}
-	if (desc == NULL) {
-		pr_err("Failed to allocate memory for dummy rx desc\n");
-		return -ENOMEM;
-	}
-	sport->dummy_rx_desc = desc;
-	desc->start_addr = (unsigned long)sport->dummy_buf;
-	config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize)
-		 | WNR | DMAEN;
-	desc->cfg = config;
-	desc->x_count = sport->dummy_count/sport->wdsize;
-	desc->x_modify = sport->wdsize;
-	desc->y_count = 0;
-	desc->y_modify = 0;
-	memcpy(desc+1, desc, sizeof(*desc));
-	desc->next_desc_addr = desc + 1;
-	desc[1].next_desc_addr = desc;
-	return 0;
-}
-
-static int sport_config_tx_dummy(struct sport_device *sport)
-{
-	struct dmasg *desc;
-	unsigned int config;
-
-	pr_debug("%s entered\n", __func__);
-
-	if (L1_DATA_A_LENGTH)
-		desc = l1_data_sram_zalloc(2 * sizeof(*desc));
-	else {
-		dma_addr_t addr;
-		desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
-		memset(desc, 0, 2 * sizeof(*desc));
-	}
-	if (!desc) {
-		pr_err("Failed to allocate memory for dummy tx desc\n");
-		return -ENOMEM;
-	}
-	sport->dummy_tx_desc = desc;
-	desc->start_addr = (unsigned long)sport->dummy_buf + \
-		sport->dummy_count;
-	config = DMAFLOW_LARGE | NDSIZE_9 |
-		 compute_wdsize(sport->wdsize) | DMAEN;
-	desc->cfg = config;
-	desc->x_count = sport->dummy_count/sport->wdsize;
-	desc->x_modify = sport->wdsize;
-	desc->y_count = 0;
-	desc->y_modify = 0;
-	memcpy(desc+1, desc, sizeof(*desc));
-	desc->next_desc_addr = desc + 1;
-	desc[1].next_desc_addr = desc;
-	return 0;
-}
-
-unsigned long sport_curr_offset_rx(struct sport_device *sport)
-{
-	unsigned long curr = get_dma_curr_addr(sport->dma_rx_chan);
-
-	return (unsigned char *)curr - sport->rx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_rx);
-
-unsigned long sport_curr_offset_tx(struct sport_device *sport)
-{
-	unsigned long curr = get_dma_curr_addr(sport->dma_tx_chan);
-
-	return (unsigned char *)curr - sport->tx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_tx);
-
-void sport_incfrag(struct sport_device *sport, int *frag, int tx)
-{
-	++(*frag);
-	if (tx == 1 && *frag == sport->tx_frags)
-		*frag = 0;
-
-	if (tx == 0 && *frag == sport->rx_frags)
-		*frag = 0;
-}
-EXPORT_SYMBOL(sport_incfrag);
-
-void sport_decfrag(struct sport_device *sport, int *frag, int tx)
-{
-	--(*frag);
-	if (tx == 1 && *frag == 0)
-		*frag = sport->tx_frags;
-
-	if (tx == 0 && *frag == 0)
-		*frag = sport->rx_frags;
-}
-EXPORT_SYMBOL(sport_decfrag);
-
-static int sport_check_status(struct sport_device *sport,
-		unsigned int *sport_stat,
-		unsigned int *rx_stat,
-		unsigned int *tx_stat)
-{
-	int status = 0;
-
-	if (sport_stat) {
-		SSYNC();
-		status = sport->regs->stat;
-		if (status & (TOVF|TUVF|ROVF|RUVF))
-			sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
-		SSYNC();
-		*sport_stat = status;
-	}
-
-	if (rx_stat) {
-		SSYNC();
-		status = get_dma_curr_irqstat(sport->dma_rx_chan);
-		if (status & (DMA_DONE|DMA_ERR))
-			clear_dma_irqstat(sport->dma_rx_chan);
-		SSYNC();
-		*rx_stat = status;
-	}
-
-	if (tx_stat) {
-		SSYNC();
-		status = get_dma_curr_irqstat(sport->dma_tx_chan);
-		if (status & (DMA_DONE|DMA_ERR))
-			clear_dma_irqstat(sport->dma_tx_chan);
-		SSYNC();
-		*tx_stat = status;
-	}
-
-	return 0;
-}
-
-int  sport_dump_stat(struct sport_device *sport, char *buf, size_t len)
-{
-	int ret;
-
-	ret = snprintf(buf, len,
-			"sts: 0x%04x\n"
-			"rx dma %d sts: 0x%04x tx dma %d sts: 0x%04x\n",
-			sport->regs->stat,
-			sport->dma_rx_chan,
-			get_dma_curr_irqstat(sport->dma_rx_chan),
-			sport->dma_tx_chan,
-			get_dma_curr_irqstat(sport->dma_tx_chan));
-	buf += ret;
-	len -= ret;
-
-	ret += snprintf(buf, len,
-			"curr_rx_desc:0x%p, curr_tx_desc:0x%p\n"
-			"dma_rx_desc:0x%p, dma_tx_desc:0x%p\n"
-			"dummy_rx_desc:0x%p, dummy_tx_desc:0x%p\n",
-			sport->curr_rx_desc, sport->curr_tx_desc,
-			sport->dma_rx_desc, sport->dma_tx_desc,
-			sport->dummy_rx_desc, sport->dummy_tx_desc);
-
-	return ret;
-}
-
-static irqreturn_t rx_handler(int irq, void *dev_id)
-{
-	unsigned int rx_stat;
-	struct sport_device *sport = dev_id;
-
-	pr_debug("%s enter\n", __func__);
-	sport_check_status(sport, NULL, &rx_stat, NULL);
-	if (!(rx_stat & DMA_DONE))
-		pr_err("rx dma is already stopped\n");
-
-	if (sport->rx_callback) {
-		sport->rx_callback(sport->rx_data);
-		return IRQ_HANDLED;
-	}
-
-	return IRQ_NONE;
-}
-
-static irqreturn_t tx_handler(int irq, void *dev_id)
-{
-	unsigned int tx_stat;
-	struct sport_device *sport = dev_id;
-	pr_debug("%s enter\n", __func__);
-	sport_check_status(sport, NULL, NULL, &tx_stat);
-	if (!(tx_stat & DMA_DONE)) {
-		pr_err("tx dma is already stopped\n");
-		return IRQ_HANDLED;
-	}
-	if (sport->tx_callback) {
-		sport->tx_callback(sport->tx_data);
-		return IRQ_HANDLED;
-	}
-
-	return IRQ_NONE;
-}
-
-static irqreturn_t err_handler(int irq, void *dev_id)
-{
-	unsigned int status = 0;
-	struct sport_device *sport = dev_id;
-
-	pr_debug("%s\n", __func__);
-	if (sport_check_status(sport, &status, NULL, NULL)) {
-		pr_err("error checking status ??");
-		return IRQ_NONE;
-	}
-
-	if (status & (TOVF|TUVF|ROVF|RUVF)) {
-		pr_info("sport status error:%s%s%s%s\n",
-				status & TOVF ? " TOVF" : "",
-				status & TUVF ? " TUVF" : "",
-				status & ROVF ? " ROVF" : "",
-				status & RUVF ? " RUVF" : "");
-		if (status & TOVF || status & TUVF) {
-			disable_dma(sport->dma_tx_chan);
-			if (sport->tx_run)
-				sport_tx_dma_start(sport, 0);
-			else
-				sport_tx_dma_start(sport, 1);
-			enable_dma(sport->dma_tx_chan);
-		} else {
-			disable_dma(sport->dma_rx_chan);
-			if (sport->rx_run)
-				sport_rx_dma_start(sport, 0);
-			else
-				sport_rx_dma_start(sport, 1);
-			enable_dma(sport->dma_rx_chan);
-		}
-	}
-	status = sport->regs->stat;
-	if (status & (TOVF|TUVF|ROVF|RUVF))
-		sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
-	SSYNC();
-
-	if (sport->err_callback)
-		sport->err_callback(sport->err_data);
-
-	return IRQ_HANDLED;
-}
-
-int sport_set_rx_callback(struct sport_device *sport,
-		       void (*rx_callback)(void *), void *rx_data)
-{
-	if (WARN_ON(!rx_callback))
-		return -EINVAL;
-	sport->rx_callback = rx_callback;
-	sport->rx_data = rx_data;
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_set_rx_callback);
-
-int sport_set_tx_callback(struct sport_device *sport,
-		void (*tx_callback)(void *), void *tx_data)
-{
-	if (WARN_ON(!tx_callback))
-		return -EINVAL;
-	sport->tx_callback = tx_callback;
-	sport->tx_data = tx_data;
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_set_tx_callback);
-
-int sport_set_err_callback(struct sport_device *sport,
-		void (*err_callback)(void *), void *err_data)
-{
-	if (WARN_ON(!err_callback))
-		return -EINVAL;
-	sport->err_callback = err_callback;
-	sport->err_data = err_data;
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_set_err_callback);
-
-static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param)
-{
-	/* Extract settings from platform data */
-	struct device *dev = &pdev->dev;
-	struct bfin_snd_platform_data *pdata = dev->platform_data;
-	struct resource *res;
-
-	param->num = pdev->id;
-
-	if (!pdata) {
-		dev_err(dev, "no platform_data\n");
-		return -ENODEV;
-	}
-	param->pin_req = pdata->pin_req;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(dev, "no MEM resource\n");
-		return -ENODEV;
-	}
-	param->regs = (struct sport_register *)res->start;
-
-	/* first RX, then TX */
-	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-	if (!res) {
-		dev_err(dev, "no rx DMA resource\n");
-		return -ENODEV;
-	}
-	param->dma_rx_chan = res->start;
-
-	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-	if (!res) {
-		dev_err(dev, "no tx DMA resource\n");
-		return -ENODEV;
-	}
-	param->dma_tx_chan = res->start;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(dev, "no irq resource\n");
-		return -ENODEV;
-	}
-	param->err_irq = res->start;
-
-	return 0;
-}
-
-struct sport_device *sport_init(struct platform_device *pdev,
-	unsigned int wdsize, unsigned int dummy_count, size_t priv_size)
-{
-	struct device *dev = &pdev->dev;
-	struct sport_param param;
-	struct sport_device *sport;
-	int ret;
-
-	dev_dbg(dev, "%s enter\n", __func__);
-
-	param.wdsize = wdsize;
-	param.dummy_count = dummy_count;
-	if (WARN_ON(param.wdsize == 0 || param.dummy_count == 0))
-		return NULL;
-
-	ret = sport_config_pdev(pdev, &param);
-	if (ret)
-		return NULL;
-
-	if (peripheral_request_list(param.pin_req, "soc-audio")) {
-		dev_err(dev, "requesting Peripherals failed\n");
-		return NULL;
-	}
-
-	sport = kzalloc(sizeof(*sport), GFP_KERNEL);
-	if (!sport) {
-		dev_err(dev, "failed to allocate for sport device\n");
-		goto __init_err0;
-	}
-
-	sport->num = param.num;
-	sport->dma_rx_chan = param.dma_rx_chan;
-	sport->dma_tx_chan = param.dma_tx_chan;
-	sport->err_irq = param.err_irq;
-	sport->regs = param.regs;
-	sport->pin_req = param.pin_req;
-
-	if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
-		dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan);
-		goto __init_err1;
-	}
-	if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
-		dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan);
-		goto __init_err2;
-	}
-
-	if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
-		dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan);
-		goto __init_err2;
-	}
-
-	if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
-		dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan);
-		goto __init_err3;
-	}
-
-	if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
-			sport) < 0) {
-		dev_err(dev, "failed to request err irq %d\n", sport->err_irq);
-		goto __init_err3;
-	}
-
-	dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n",
-			sport->dma_rx_chan, sport->dma_tx_chan,
-			sport->err_irq, sport->regs);
-
-	sport->wdsize = param.wdsize;
-	sport->dummy_count = param.dummy_count;
-
-	sport->private_data = kzalloc(priv_size, GFP_KERNEL);
-	if (!sport->private_data) {
-		dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size);
-		goto __init_err4;
-	}
-
-	if (L1_DATA_A_LENGTH)
-		sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2);
-	else
-		sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL);
-	if (sport->dummy_buf == NULL) {
-		dev_err(dev, "failed to allocate dummy buffer\n");
-		goto __error1;
-	}
-
-	ret = sport_config_rx_dummy(sport);
-	if (ret) {
-		dev_err(dev, "failed to config rx dummy ring\n");
-		goto __error2;
-	}
-	ret = sport_config_tx_dummy(sport);
-	if (ret) {
-		dev_err(dev, "failed to config tx dummy ring\n");
-		goto __error3;
-	}
-
-	platform_set_drvdata(pdev, sport);
-
-	return sport;
-__error3:
-	if (L1_DATA_A_LENGTH)
-		l1_data_sram_free(sport->dummy_rx_desc);
-	else
-		dma_free_coherent(NULL, 2*sizeof(struct dmasg),
-				sport->dummy_rx_desc, 0);
-__error2:
-	if (L1_DATA_A_LENGTH)
-		l1_data_sram_free(sport->dummy_buf);
-	else
-		kfree(sport->dummy_buf);
-__error1:
-	kfree(sport->private_data);
-__init_err4:
-	free_irq(sport->err_irq, sport);
-__init_err3:
-	free_dma(sport->dma_tx_chan);
-__init_err2:
-	free_dma(sport->dma_rx_chan);
-__init_err1:
-	kfree(sport);
-__init_err0:
-	peripheral_free_list(param.pin_req);
-	return NULL;
-}
-EXPORT_SYMBOL(sport_init);
-
-void sport_done(struct sport_device *sport)
-{
-	if (sport == NULL)
-		return;
-
-	sport_stop(sport);
-	if (sport->dma_rx_desc)
-		dma_free_coherent(NULL, sport->rx_desc_bytes,
-			sport->dma_rx_desc, 0);
-	if (sport->dma_tx_desc)
-		dma_free_coherent(NULL, sport->tx_desc_bytes,
-			sport->dma_tx_desc, 0);
-
-#if L1_DATA_A_LENGTH != 0
-	l1_data_sram_free(sport->dummy_rx_desc);
-	l1_data_sram_free(sport->dummy_tx_desc);
-	l1_data_sram_free(sport->dummy_buf);
-#else
-	dma_free_coherent(NULL, 2*sizeof(struct dmasg),
-		sport->dummy_rx_desc, 0);
-	dma_free_coherent(NULL, 2*sizeof(struct dmasg),
-		sport->dummy_tx_desc, 0);
-	kfree(sport->dummy_buf);
-#endif
-	free_dma(sport->dma_rx_chan);
-	free_dma(sport->dma_tx_chan);
-	free_irq(sport->err_irq, sport);
-
-	kfree(sport->private_data);
-	peripheral_free_list(sport->pin_req);
-	kfree(sport);
-}
-EXPORT_SYMBOL(sport_done);
-
-/*
-* It is only used to send several bytes when dma is not enabled
- * sport controller is configured but not enabled.
- * Multichannel cannot works with pio mode */
-/* Used by ac97 to write and read codec register */
-int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
-		u8 *in_data, int len)
-{
-	unsigned short dma_config;
-	unsigned short status;
-	unsigned long flags;
-	unsigned long wait = 0;
-
-	pr_debug("%s enter, out_data:%p, in_data:%p len:%d\n", \
-			__func__, out_data, in_data, len);
-	pr_debug("tcr1:0x%04x, tcr2:0x%04x, tclkdiv:0x%04x, tfsdiv:0x%04x\n"
-			"mcmc1:0x%04x, mcmc2:0x%04x\n",
-			sport->regs->tcr1, sport->regs->tcr2,
-			sport->regs->tclkdiv, sport->regs->tfsdiv,
-			sport->regs->mcmc1, sport->regs->mcmc2);
-	flush_dcache_range((unsigned)out_data, (unsigned)(out_data + len));
-
-	/* Enable tx dma */
-	dma_config = (RESTART | WDSIZE_16 | DI_EN);
-	set_dma_start_addr(sport->dma_tx_chan, (unsigned long)out_data);
-	set_dma_x_count(sport->dma_tx_chan, len/2);
-	set_dma_x_modify(sport->dma_tx_chan, 2);
-	set_dma_config(sport->dma_tx_chan, dma_config);
-	enable_dma(sport->dma_tx_chan);
-
-	if (in_data != NULL) {
-		invalidate_dcache_range((unsigned)in_data, \
-				(unsigned)(in_data + len));
-		/* Enable rx dma */
-		dma_config = (RESTART | WDSIZE_16 | WNR | DI_EN);
-		set_dma_start_addr(sport->dma_rx_chan, (unsigned long)in_data);
-		set_dma_x_count(sport->dma_rx_chan, len/2);
-		set_dma_x_modify(sport->dma_rx_chan, 2);
-		set_dma_config(sport->dma_rx_chan, dma_config);
-		enable_dma(sport->dma_rx_chan);
-	}
-
-	local_irq_save(flags);
-	sport->regs->tcr1 |= TSPEN;
-	sport->regs->rcr1 |= RSPEN;
-	SSYNC();
-
-	status = get_dma_curr_irqstat(sport->dma_tx_chan);
-	while (status & DMA_RUN) {
-		udelay(1);
-		status = get_dma_curr_irqstat(sport->dma_tx_chan);
-		pr_debug("DMA status:0x%04x\n", status);
-		if (wait++ > 100)
-			goto __over;
-	}
-	status = sport->regs->stat;
-	wait = 0;
-
-	while (!(status & TXHRE)) {
-		pr_debug("sport status:0x%04x\n", status);
-		udelay(1);
-		status = *(unsigned short *)&sport->regs->stat;
-		if (wait++ > 1000)
-			goto __over;
-	}
-	/* Wait for the last byte sent out */
-	udelay(20);
-	pr_debug("sport status:0x%04x\n", status);
-
-__over:
-	sport->regs->tcr1 &= ~TSPEN;
-	sport->regs->rcr1 &= ~RSPEN;
-	SSYNC();
-	disable_dma(sport->dma_tx_chan);
-	/* Clear the status */
-	clear_dma_irqstat(sport->dma_tx_chan);
-	if (in_data != NULL) {
-		disable_dma(sport->dma_rx_chan);
-		clear_dma_irqstat(sport->dma_rx_chan);
-	}
-	SSYNC();
-	local_irq_restore(flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(sport_send_and_recv);
-
-MODULE_AUTHOR("Roy Huang");
-MODULE_DESCRIPTION("SPORT driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
deleted file mode 100644
index 9fc2192..0000000
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * File:         bf5xx_sport.h
- * Based on:
- * Author:       Roy Huang <roy.huang@analog.com>
- *
- * Created:
- * Description:
- *
- *               Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#ifndef __BF5XX_SPORT_H__
-#define __BF5XX_SPORT_H__
-
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <asm/dma.h>
-#include <asm/bfin_sport.h>
-
-#define DESC_ELEMENT_COUNT 9
-
-struct sport_device {
-	int num;
-	int dma_rx_chan;
-	int dma_tx_chan;
-	int err_irq;
-	const unsigned short *pin_req;
-	struct sport_register *regs;
-
-	unsigned char *rx_buf;
-	unsigned char *tx_buf;
-	unsigned int rx_fragsize;
-	unsigned int tx_fragsize;
-	unsigned int rx_frags;
-	unsigned int tx_frags;
-	unsigned int wdsize;
-
-	/* for dummy dma transfer */
-	void *dummy_buf;
-	unsigned int dummy_count;
-
-	/* DMA descriptor ring head of current audio stream*/
-	struct dmasg *dma_rx_desc;
-	struct dmasg *dma_tx_desc;
-	unsigned int rx_desc_bytes;
-	unsigned int tx_desc_bytes;
-
-	unsigned int rx_run:1; /* rx is running */
-	unsigned int tx_run:1; /* tx is running */
-
-	struct dmasg *dummy_rx_desc;
-	struct dmasg *dummy_tx_desc;
-
-	struct dmasg *curr_rx_desc;
-	struct dmasg *curr_tx_desc;
-
-	int rx_curr_frag;
-	int tx_curr_frag;
-
-	unsigned int rcr1;
-	unsigned int rcr2;
-	int rx_tdm_count;
-
-	unsigned int tcr1;
-	unsigned int tcr2;
-	int tx_tdm_count;
-
-	void (*rx_callback)(void *data);
-	void *rx_data;
-	void (*tx_callback)(void *data);
-	void *tx_data;
-	void (*err_callback)(void *data);
-	void *err_data;
-	unsigned char *tx_dma_buf;
-	unsigned char *rx_dma_buf;
-#ifdef CONFIG_SND_BF5XX_MMAP_SUPPORT
-	dma_addr_t tx_dma_phy;
-	dma_addr_t rx_dma_phy;
-	int tx_pos;/*pcm sample count*/
-	int rx_pos;
-	unsigned int tx_buffer_size;
-	unsigned int rx_buffer_size;
-	int tx_delay_pos;
-	int once;
-#endif
-	void *private_data;
-};
-
-struct sport_param {
-	int num;
-	int dma_rx_chan;
-	int dma_tx_chan;
-	int err_irq;
-	const unsigned short *pin_req;
-	struct sport_register *regs;
-	unsigned int wdsize;
-	unsigned int dummy_count;
-	void *private_data;
-};
-
-struct sport_device *sport_init(struct platform_device *pdev,
-	unsigned int wdsize, unsigned int dummy_count, size_t priv_size);
-
-void sport_done(struct sport_device *sport);
-
-/* first use these ...*/
-
-/* note: multichannel is in units of 8 channels, tdm_count is number of channels
- *  NOT / 8 ! all channels are enabled by default */
-int sport_set_multichannel(struct sport_device *sport, int tdm_count,
-		u32 tx_mask, u32 rx_mask, int packed);
-
-int sport_config_rx(struct sport_device *sport,
-		unsigned int rcr1, unsigned int rcr2,
-		unsigned int clkdiv, unsigned int fsdiv);
-
-int sport_config_tx(struct sport_device *sport,
-		unsigned int tcr1, unsigned int tcr2,
-		unsigned int clkdiv, unsigned int fsdiv);
-
-/* ... then these: */
-
-/* buffer size (in bytes) == fragcount * fragsize_bytes */
-
-/* this is not a very general api, it sets the dma to 2d autobuffer mode */
-
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
-		int fragcount, size_t fragsize_bytes);
-
-int sport_config_tx_dma(struct sport_device *sport, void *buf,
-		int fragcount, size_t fragsize_bytes);
-
-int sport_tx_start(struct sport_device *sport);
-int sport_tx_stop(struct sport_device *sport);
-int sport_rx_start(struct sport_device *sport);
-int sport_rx_stop(struct sport_device *sport);
-
-/* for use in interrupt handler */
-unsigned long sport_curr_offset_rx(struct sport_device *sport);
-unsigned long sport_curr_offset_tx(struct sport_device *sport);
-
-void sport_incfrag(struct sport_device *sport, int *frag, int tx);
-void sport_decfrag(struct sport_device *sport, int *frag, int tx);
-
-int sport_set_rx_callback(struct sport_device *sport,
-		       void (*rx_callback)(void *), void *rx_data);
-int sport_set_tx_callback(struct sport_device *sport,
-		       void (*tx_callback)(void *), void *tx_data);
-int sport_set_err_callback(struct sport_device *sport,
-		       void (*err_callback)(void *), void *err_data);
-
-int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
-		u8 *in_data, int len);
-#endif /* BF53X_SPORT_H */
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
deleted file mode 100644
index 9c19ccc..0000000
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ssm2602.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  board driver for SSM2602 sound chip
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-#include <linux/gpio.h>
-#include "../codecs/ssm2602.h"
-#include "bf5xx-sport.h"
-
-static struct snd_soc_card bf5xx_ssm2602;
-
-static int bf5xx_ssm2602_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
-	/*
-	 * If you are using a crystal source which frequency is not 12MHz
-	 * then modify the below case statement with frequency of the crystal.
-	 *
-	 * If you are using the SPORT to generate clocking then this is
-	 * where to do it.
-	 */
-	return snd_soc_dai_set_sysclk(rtd->codec_dai, SSM2602_SYSCLK, 12000000,
-		SND_SOC_CLOCK_IN);
-}
-
-/* CODEC is master for BCLK and LRC in this configuration. */
-#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \
-				SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
-	{
-		.name = "ssm2602",
-		.stream_name = "SSM2602",
-		.cpu_dai_name = "bfin-i2s.0",
-		.codec_dai_name = "ssm2602-hifi",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.codec_name = "ssm2602.0-001b",
-		.init = bf5xx_ssm2602_dai_init,
-		.dai_fmt = BF5XX_SSM2602_DAIFMT,
-	},
-	{
-		.name = "ssm2602",
-		.stream_name = "SSM2602",
-		.cpu_dai_name = "bfin-i2s.1",
-		.codec_dai_name = "ssm2602-hifi",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.codec_name = "ssm2602.0-001b",
-		.init = bf5xx_ssm2602_dai_init,
-		.dai_fmt = BF5XX_SSM2602_DAIFMT,
-	},
-};
-
-static struct snd_soc_card bf5xx_ssm2602 = {
-	.name = "bfin-ssm2602",
-	.owner = THIS_MODULE,
-	.dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-	.num_links = 1,
-};
-
-static struct platform_device *bf5xx_ssm2602_snd_device;
-
-static int __init bf5xx_ssm2602_init(void)
-{
-	int ret;
-
-	pr_debug("%s enter\n", __func__);
-	bf5xx_ssm2602_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!bf5xx_ssm2602_snd_device)
-		return -ENOMEM;
-
-	platform_set_drvdata(bf5xx_ssm2602_snd_device, &bf5xx_ssm2602);
-	ret = platform_device_add(bf5xx_ssm2602_snd_device);
-
-	if (ret)
-		platform_device_put(bf5xx_ssm2602_snd_device);
-
-	return ret;
-}
-
-static void __exit bf5xx_ssm2602_exit(void)
-{
-	pr_debug("%s enter\n", __func__);
-	platform_device_unregister(bf5xx_ssm2602_snd_device);
-}
-
-module_init(bf5xx_ssm2602_init);
-module_exit(bf5xx_ssm2602_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC SSM2602 BF527-EZKIT");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c
deleted file mode 100644
index 819cff1..0000000
--- a/sound/soc/blackfin/bf6xx-i2s.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * bf6xx-i2s.c - Analog Devices BF6XX i2s interface driver
- *
- * Copyright (c) 2012 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dai.h>
-
-#include "bf6xx-sport.h"
-
-struct sport_params param;
-
-static int bfin_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-		unsigned int fmt)
-{
-	struct sport_device *sport = snd_soc_dai_get_drvdata(cpu_dai);
-	struct device *dev = &sport->pdev->dev;
-	int ret = 0;
-
-	param.spctl &= ~(SPORT_CTL_OPMODE | SPORT_CTL_CKRE | SPORT_CTL_FSR
-			| SPORT_CTL_LFS | SPORT_CTL_LAFS);
-	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-	case SND_SOC_DAIFMT_I2S:
-		param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_CKRE
-			| SPORT_CTL_LFS;
-		break;
-	case SND_SOC_DAIFMT_DSP_A:
-		param.spctl |= SPORT_CTL_FSR;
-		break;
-	case SND_SOC_DAIFMT_LEFT_J:
-		param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_LFS
-			| SPORT_CTL_LAFS;
-		break;
-	default:
-		dev_err(dev, "%s: Unknown DAI format type\n", __func__);
-		ret = -EINVAL;
-		break;
-	}
-
-	param.spctl &= ~(SPORT_CTL_ICLK | SPORT_CTL_IFS);
-	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-	case SND_SOC_DAIFMT_CBM_CFM:
-		break;
-	case SND_SOC_DAIFMT_CBS_CFS:
-	case SND_SOC_DAIFMT_CBM_CFS:
-	case SND_SOC_DAIFMT_CBS_CFM:
-		ret = -EINVAL;
-		break;
-	default:
-		dev_err(dev, "%s: Unknown DAI master type\n", __func__);
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int bfin_i2s_hw_params(struct snd_pcm_substream *substream,
-				struct snd_pcm_hw_params *params,
-				struct snd_soc_dai *dai)
-{
-	struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-	struct device *dev = &sport->pdev->dev;
-	int ret = 0;
-
-	param.spctl &= ~SPORT_CTL_SLEN;
-	switch (params_format(params)) {
-	case SNDRV_PCM_FORMAT_S8:
-		param.spctl |= 0x70;
-		sport->wdsize = 1;
-		break;
-	case SNDRV_PCM_FORMAT_S16_LE:
-		param.spctl |= 0xf0;
-		sport->wdsize = 2;
-		break;
-	case SNDRV_PCM_FORMAT_S24_LE:
-		param.spctl |= 0x170;
-		sport->wdsize = 3;
-		break;
-	case SNDRV_PCM_FORMAT_S32_LE:
-		param.spctl |= 0x1f0;
-		sport->wdsize = 4;
-		break;
-	}
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		ret = sport_set_tx_params(sport, &param);
-		if (ret) {
-			dev_err(dev, "SPORT tx is busy!\n");
-			return ret;
-		}
-	} else {
-		ret = sport_set_rx_params(sport, &param);
-		if (ret) {
-			dev_err(dev, "SPORT rx is busy!\n");
-			return ret;
-		}
-	}
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int bfin_i2s_suspend(struct snd_soc_dai *dai)
-{
-	struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
-	if (dai->capture_active)
-		sport_rx_stop(sport);
-	if (dai->playback_active)
-		sport_tx_stop(sport);
-	return 0;
-}
-
-static int bfin_i2s_resume(struct snd_soc_dai *dai)
-{
-	struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-	struct device *dev = &sport->pdev->dev;
-	int ret;
-
-	ret = sport_set_tx_params(sport, &param);
-	if (ret) {
-		dev_err(dev, "SPORT tx is busy!\n");
-		return ret;
-	}
-	ret = sport_set_rx_params(sport, &param);
-	if (ret) {
-		dev_err(dev, "SPORT rx is busy!\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-#else
-#define bfin_i2s_suspend NULL
-#define bfin_i2s_resume NULL
-#endif
-
-#define BFIN_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
-		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
-		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
-		SNDRV_PCM_RATE_96000)
-
-#define BFIN_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
-		SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops bfin_i2s_dai_ops = {
-	.hw_params	= bfin_i2s_hw_params,
-	.set_fmt	= bfin_i2s_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver bfin_i2s_dai = {
-	.suspend = bfin_i2s_suspend,
-	.resume = bfin_i2s_resume,
-	.playback = {
-		.channels_min = 1,
-		.channels_max = 2,
-		.rates = BFIN_I2S_RATES,
-		.formats = BFIN_I2S_FORMATS,
-	},
-	.capture = {
-		.channels_min = 1,
-		.channels_max = 2,
-		.rates = BFIN_I2S_RATES,
-		.formats = BFIN_I2S_FORMATS,
-	},
-	.ops = &bfin_i2s_dai_ops,
-};
-
-static const struct snd_soc_component_driver bfin_i2s_component = {
-	.name		= "bfin-i2s",
-};
-
-static int bfin_i2s_probe(struct platform_device *pdev)
-{
-	struct sport_device *sport;
-	struct device *dev = &pdev->dev;
-	int ret;
-
-	sport = sport_create(pdev);
-	if (!sport)
-		return -ENODEV;
-
-	/* register with the ASoC layers */
-	ret = snd_soc_register_component(dev, &bfin_i2s_component,
-					 &bfin_i2s_dai, 1);
-	if (ret) {
-		dev_err(dev, "Failed to register DAI: %d\n", ret);
-		sport_delete(sport);
-		return ret;
-	}
-	platform_set_drvdata(pdev, sport);
-
-	return 0;
-}
-
-static int bfin_i2s_remove(struct platform_device *pdev)
-{
-	struct sport_device *sport = platform_get_drvdata(pdev);
-
-	snd_soc_unregister_component(&pdev->dev);
-	sport_delete(sport);
-
-	return 0;
-}
-
-static struct platform_driver bfin_i2s_driver = {
-	.probe  = bfin_i2s_probe,
-	.remove = bfin_i2s_remove,
-	.driver = {
-		.name = "bfin-i2s",
-	},
-};
-
-module_platform_driver(bfin_i2s_driver);
-
-MODULE_DESCRIPTION("Analog Devices BF6XX i2s interface driver");
-MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c
deleted file mode 100644
index d2caadf..0000000
--- a/sound/soc/blackfin/bf6xx-sport.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * bf6xx_sport.c Analog Devices BF6XX SPORT driver
- *
- * Copyright (c) 2012 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <asm/blackfin.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "bf6xx-sport.h"
-
-int sport_set_tx_params(struct sport_device *sport,
-			struct sport_params *params)
-{
-	if (sport->tx_regs->spctl & SPORT_CTL_SPENPRI)
-		return -EBUSY;
-	sport->tx_regs->spctl = params->spctl | SPORT_CTL_SPTRAN;
-	sport->tx_regs->div = params->div;
-	SSYNC();
-	return 0;
-}
-EXPORT_SYMBOL(sport_set_tx_params);
-
-int sport_set_rx_params(struct sport_device *sport,
-			struct sport_params *params)
-{
-	if (sport->rx_regs->spctl & SPORT_CTL_SPENPRI)
-		return -EBUSY;
-	sport->rx_regs->spctl = params->spctl & ~SPORT_CTL_SPTRAN;
-	sport->rx_regs->div = params->div;
-	SSYNC();
-	return 0;
-}
-EXPORT_SYMBOL(sport_set_rx_params);
-
-static int compute_wdsize(size_t wdsize)
-{
-	switch (wdsize) {
-	case 1:
-		return WDSIZE_8 | PSIZE_8;
-	case 2:
-		return WDSIZE_16 | PSIZE_16;
-	default:
-		return WDSIZE_32 | PSIZE_32;
-	}
-}
-
-void sport_tx_start(struct sport_device *sport)
-{
-	set_dma_next_desc_addr(sport->tx_dma_chan, sport->tx_desc);
-	set_dma_config(sport->tx_dma_chan, DMAFLOW_LIST | DI_EN
-			| compute_wdsize(sport->wdsize) | NDSIZE_6);
-	enable_dma(sport->tx_dma_chan);
-	sport->tx_regs->spctl |= SPORT_CTL_SPENPRI;
-	SSYNC();
-}
-EXPORT_SYMBOL(sport_tx_start);
-
-void sport_rx_start(struct sport_device *sport)
-{
-	set_dma_next_desc_addr(sport->rx_dma_chan, sport->rx_desc);
-	set_dma_config(sport->rx_dma_chan, DMAFLOW_LIST | DI_EN | WNR
-			| compute_wdsize(sport->wdsize) | NDSIZE_6);
-	enable_dma(sport->rx_dma_chan);
-	sport->rx_regs->spctl |= SPORT_CTL_SPENPRI;
-	SSYNC();
-}
-EXPORT_SYMBOL(sport_rx_start);
-
-void sport_tx_stop(struct sport_device *sport)
-{
-	sport->tx_regs->spctl &= ~SPORT_CTL_SPENPRI;
-	SSYNC();
-	disable_dma(sport->tx_dma_chan);
-}
-EXPORT_SYMBOL(sport_tx_stop);
-
-void sport_rx_stop(struct sport_device *sport)
-{
-	sport->rx_regs->spctl &= ~SPORT_CTL_SPENPRI;
-	SSYNC();
-	disable_dma(sport->rx_dma_chan);
-}
-EXPORT_SYMBOL(sport_rx_stop);
-
-void sport_set_tx_callback(struct sport_device *sport,
-		void (*tx_callback)(void *), void *tx_data)
-{
-	sport->tx_callback = tx_callback;
-	sport->tx_data = tx_data;
-}
-EXPORT_SYMBOL(sport_set_tx_callback);
-
-void sport_set_rx_callback(struct sport_device *sport,
-		void (*rx_callback)(void *), void *rx_data)
-{
-	sport->rx_callback = rx_callback;
-	sport->rx_data = rx_data;
-}
-EXPORT_SYMBOL(sport_set_rx_callback);
-
-static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
-		size_t fragsize, unsigned int cfg,
-		unsigned int count, size_t wdsize)
-{
-
-	int i;
-
-	for (i = 0; i < fragcount; ++i) {
-		desc[i].next_desc_addr  = &(desc[i + 1]);
-		desc[i].start_addr = (unsigned long)buf + i * fragsize;
-		desc[i].cfg = cfg;
-		desc[i].x_count = count;
-		desc[i].x_modify = wdsize;
-		desc[i].y_count = 0;
-		desc[i].y_modify = 0;
-	}
-
-	/* make circular */
-	desc[fragcount - 1].next_desc_addr = desc;
-}
-
-int sport_config_tx_dma(struct sport_device *sport, void *buf,
-		int fragcount, size_t fragsize)
-{
-	unsigned int count;
-	unsigned int cfg;
-	dma_addr_t addr;
-
-	count = fragsize / sport->wdsize;
-
-	if (sport->tx_desc)
-		dma_free_coherent(NULL, sport->tx_desc_size,
-				sport->tx_desc, 0);
-
-	sport->tx_desc = dma_alloc_coherent(NULL,
-			fragcount * sizeof(struct dmasg), &addr, 0);
-	sport->tx_desc_size = fragcount * sizeof(struct dmasg);
-	if (!sport->tx_desc)
-		return -ENOMEM;
-
-	sport->tx_buf = buf;
-	sport->tx_fragsize = fragsize;
-	sport->tx_frags = fragcount;
-	cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6;
-
-	setup_desc(sport->tx_desc, buf, fragcount, fragsize,
-		   cfg | DMAEN, count, sport->wdsize);
-	return 0;
-}
-EXPORT_SYMBOL(sport_config_tx_dma);
-
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
-		int fragcount, size_t fragsize)
-{
-	unsigned int count;
-	unsigned int cfg;
-	dma_addr_t addr;
-
-	count = fragsize / sport->wdsize;
-
-	if (sport->rx_desc)
-		dma_free_coherent(NULL, sport->rx_desc_size,
-				sport->rx_desc, 0);
-
-	sport->rx_desc = dma_alloc_coherent(NULL,
-			fragcount * sizeof(struct dmasg), &addr, 0);
-	sport->rx_desc_size = fragcount * sizeof(struct dmasg);
-	if (!sport->rx_desc)
-		return -ENOMEM;
-
-	sport->rx_buf = buf;
-	sport->rx_fragsize = fragsize;
-	sport->rx_frags = fragcount;
-	cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize)
-		| WNR | NDSIZE_6;
-
-	setup_desc(sport->rx_desc, buf, fragcount, fragsize,
-		   cfg | DMAEN, count, sport->wdsize);
-	return 0;
-}
-EXPORT_SYMBOL(sport_config_rx_dma);
-
-unsigned long sport_curr_offset_tx(struct sport_device *sport)
-{
-	unsigned long curr = get_dma_curr_addr(sport->tx_dma_chan);
-
-	return (unsigned char *)curr - sport->tx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_tx);
-
-unsigned long sport_curr_offset_rx(struct sport_device *sport)
-{
-	unsigned long curr = get_dma_curr_addr(sport->rx_dma_chan);
-
-	return (unsigned char *)curr - sport->rx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_rx);
-
-static irqreturn_t sport_tx_irq(int irq, void *dev_id)
-{
-	struct sport_device *sport = dev_id;
-	static unsigned long status;
-
-	status = get_dma_curr_irqstat(sport->tx_dma_chan);
-	if (status & (DMA_DONE | DMA_ERR)) {
-		clear_dma_irqstat(sport->tx_dma_chan);
-		SSYNC();
-	}
-	if (sport->tx_callback)
-		sport->tx_callback(sport->tx_data);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t sport_rx_irq(int irq, void *dev_id)
-{
-	struct sport_device *sport = dev_id;
-	unsigned long status;
-
-	status = get_dma_curr_irqstat(sport->rx_dma_chan);
-	if (status & (DMA_DONE | DMA_ERR)) {
-		clear_dma_irqstat(sport->rx_dma_chan);
-		SSYNC();
-	}
-	if (sport->rx_callback)
-		sport->rx_callback(sport->rx_data);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t sport_err_irq(int irq, void *dev_id)
-{
-	struct sport_device *sport = dev_id;
-	struct device *dev = &sport->pdev->dev;
-
-	if (sport->tx_regs->spctl & SPORT_CTL_DERRPRI)
-		dev_err(dev, "sport error: TUVF\n");
-	if (sport->rx_regs->spctl & SPORT_CTL_DERRPRI)
-		dev_err(dev, "sport error: ROVF\n");
-
-	return IRQ_HANDLED;
-}
-
-static int sport_get_resource(struct sport_device *sport)
-{
-	struct platform_device *pdev = sport->pdev;
-	struct device *dev = &pdev->dev;
-	struct bfin_snd_platform_data *pdata = dev->platform_data;
-	struct resource *res;
-
-	if (!pdata) {
-		dev_err(dev, "No platform data\n");
-		return -ENODEV;
-	}
-	sport->pin_req = pdata->pin_req;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(dev, "No tx MEM resource\n");
-		return -ENODEV;
-	}
-	sport->tx_regs = (struct sport_register *)res->start;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!res) {
-		dev_err(dev, "No rx MEM resource\n");
-		return -ENODEV;
-	}
-	sport->rx_regs = (struct sport_register *)res->start;
-
-	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-	if (!res) {
-		dev_err(dev, "No tx DMA resource\n");
-		return -ENODEV;
-	}
-	sport->tx_dma_chan = res->start;
-
-	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-	if (!res) {
-		dev_err(dev, "No rx DMA resource\n");
-		return -ENODEV;
-	}
-	sport->rx_dma_chan = res->start;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(dev, "No tx error irq resource\n");
-		return -ENODEV;
-	}
-	sport->tx_err_irq = res->start;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
-	if (!res) {
-		dev_err(dev, "No rx error irq resource\n");
-		return -ENODEV;
-	}
-	sport->rx_err_irq = res->start;
-
-	return 0;
-}
-
-static int sport_request_resource(struct sport_device *sport)
-{
-	struct device *dev = &sport->pdev->dev;
-	int ret;
-
-	ret = peripheral_request_list(sport->pin_req, "soc-audio");
-	if (ret) {
-		dev_err(dev, "Unable to request sport pin\n");
-		return ret;
-	}
-
-	ret = request_dma(sport->tx_dma_chan, "SPORT TX Data");
-	if (ret) {
-		dev_err(dev, "Unable to allocate DMA channel for sport tx\n");
-		goto err_tx_dma;
-	}
-	set_dma_callback(sport->tx_dma_chan, sport_tx_irq, sport);
-
-	ret = request_dma(sport->rx_dma_chan, "SPORT RX Data");
-	if (ret) {
-		dev_err(dev, "Unable to allocate DMA channel for sport rx\n");
-		goto err_rx_dma;
-	}
-	set_dma_callback(sport->rx_dma_chan, sport_rx_irq, sport);
-
-	ret = request_irq(sport->tx_err_irq, sport_err_irq,
-			0, "SPORT TX ERROR", sport);
-	if (ret) {
-		dev_err(dev, "Unable to allocate tx error IRQ for sport\n");
-		goto err_tx_irq;
-	}
-
-	ret = request_irq(sport->rx_err_irq, sport_err_irq,
-			0, "SPORT RX ERROR", sport);
-	if (ret) {
-		dev_err(dev, "Unable to allocate rx error IRQ for sport\n");
-		goto err_rx_irq;
-	}
-
-	return 0;
-err_rx_irq:
-	free_irq(sport->tx_err_irq, sport);
-err_tx_irq:
-	free_dma(sport->rx_dma_chan);
-err_rx_dma:
-	free_dma(sport->tx_dma_chan);
-err_tx_dma:
-	peripheral_free_list(sport->pin_req);
-	return ret;
-}
-
-static void sport_free_resource(struct sport_device *sport)
-{
-	free_irq(sport->rx_err_irq, sport);
-	free_irq(sport->tx_err_irq, sport);
-	free_dma(sport->rx_dma_chan);
-	free_dma(sport->tx_dma_chan);
-	peripheral_free_list(sport->pin_req);
-}
-
-struct sport_device *sport_create(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct sport_device *sport;
-	int ret;
-
-	sport = kzalloc(sizeof(*sport), GFP_KERNEL);
-	if (!sport)
-		return NULL;
-
-	sport->pdev = pdev;
-
-	ret = sport_get_resource(sport);
-	if (ret)
-		goto free_data;
-
-	ret = sport_request_resource(sport);
-	if (ret)
-		goto free_data;
-
-	dev_dbg(dev, "SPORT create success\n");
-	return sport;
-free_data:
-	kfree(sport);
-	return NULL;
-}
-EXPORT_SYMBOL(sport_create);
-
-void sport_delete(struct sport_device *sport)
-{
-	if (sport->tx_desc)
-		dma_free_coherent(NULL, sport->tx_desc_size,
-				sport->tx_desc, 0);
-	if (sport->rx_desc)
-		dma_free_coherent(NULL, sport->rx_desc_size,
-				sport->rx_desc, 0);
-	sport_free_resource(sport);
-	kfree(sport);
-}
-EXPORT_SYMBOL(sport_delete);
-
-MODULE_DESCRIPTION("Analog Devices BF6XX SPORT driver");
-MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/blackfin/bf6xx-sport.h b/sound/soc/blackfin/bf6xx-sport.h
deleted file mode 100644
index 307d193..0000000
--- a/sound/soc/blackfin/bf6xx-sport.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * bf6xx_sport - Analog Devices BF6XX SPORT driver
- *
- * Copyright (c) 2012 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _BF6XX_SPORT_H_
-#define _BF6XX_SPORT_H_
-
-#include <linux/platform_device.h>
-#include <asm/bfin_sport3.h>
-
-struct sport_device {
-	struct platform_device *pdev;
-	const unsigned short *pin_req;
-	struct sport_register *tx_regs;
-	struct sport_register *rx_regs;
-	int tx_dma_chan;
-	int rx_dma_chan;
-	int tx_err_irq;
-	int rx_err_irq;
-
-	void (*tx_callback)(void *data);
-	void *tx_data;
-	void (*rx_callback)(void *data);
-	void *rx_data;
-
-	struct dmasg *tx_desc;
-	struct dmasg *rx_desc;
-	unsigned int tx_desc_size;
-	unsigned int rx_desc_size;
-	unsigned char *tx_buf;
-	unsigned char *rx_buf;
-	unsigned int tx_fragsize;
-	unsigned int rx_fragsize;
-	unsigned int tx_frags;
-	unsigned int rx_frags;
-	unsigned int wdsize;
-};
-
-struct sport_params {
-	u32 spctl;
-	u32 div;
-};
-
-struct sport_device *sport_create(struct platform_device *pdev);
-void sport_delete(struct sport_device *sport);
-int sport_set_tx_params(struct sport_device *sport,
-		struct sport_params *params);
-int sport_set_rx_params(struct sport_device *sport,
-		struct sport_params *params);
-void sport_tx_start(struct sport_device *sport);
-void sport_rx_start(struct sport_device *sport);
-void sport_tx_stop(struct sport_device *sport);
-void sport_rx_stop(struct sport_device *sport);
-void sport_set_tx_callback(struct sport_device *sport,
-	void (*tx_callback)(void *), void *tx_data);
-void sport_set_rx_callback(struct sport_device *sport,
-	void (*rx_callback)(void *), void *rx_data);
-int sport_config_tx_dma(struct sport_device *sport, void *buf,
-	int fragcount, size_t fragsize);
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
-	int fragcount, size_t fragsize);
-unsigned long sport_curr_offset_tx(struct sport_device *sport);
-unsigned long sport_curr_offset_rx(struct sport_device *sport);
-
-
-
-#endif
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
deleted file mode 100644
index 64b88fd..0000000
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1373 on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau1373.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1373_dapm_widgets[] = {
-	SND_SOC_DAPM_LINE("Line In1", NULL),
-	SND_SOC_DAPM_LINE("Line In2", NULL),
-	SND_SOC_DAPM_LINE("Line In3", NULL),
-	SND_SOC_DAPM_LINE("Line In4", NULL),
-
-	SND_SOC_DAPM_LINE("Line Out1", NULL),
-	SND_SOC_DAPM_LINE("Line Out2", NULL),
-	SND_SOC_DAPM_LINE("Stereo Out", NULL),
-	SND_SOC_DAPM_HP("Headphone", NULL),
-	SND_SOC_DAPM_HP("Earpiece", NULL),
-	SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1373_dapm_routes[] = {
-	{ "AIN1L", NULL, "Line In1" },
-	{ "AIN1R", NULL, "Line In1" },
-	{ "AIN2L", NULL, "Line In2" },
-	{ "AIN2R", NULL, "Line In2" },
-	{ "AIN3L", NULL, "Line In3" },
-	{ "AIN3R", NULL, "Line In3" },
-	{ "AIN4L", NULL, "Line In4" },
-	{ "AIN4R", NULL, "Line In4" },
-
-	/* MICBIAS can be connected via a jumper to the line-in jack, since w
-	   don't know which one is going to be used, just power both. */
-	{ "Line In1", NULL, "MICBIAS1" },
-	{ "Line In2", NULL, "MICBIAS1" },
-	{ "Line In3", NULL, "MICBIAS1" },
-	{ "Line In4", NULL, "MICBIAS1" },
-	{ "Line In1", NULL, "MICBIAS2" },
-	{ "Line In2", NULL, "MICBIAS2" },
-	{ "Line In3", NULL, "MICBIAS2" },
-	{ "Line In4", NULL, "MICBIAS2" },
-
-	{ "Line Out1", NULL, "LOUT1L" },
-	{ "Line Out1", NULL, "LOUT1R" },
-	{ "Line Out2", NULL, "LOUT2L" },
-	{ "Line Out2", NULL, "LOUT2R" },
-	{ "Headphone", NULL, "HPL" },
-	{ "Headphone", NULL, "HPR" },
-	{ "Earpiece", NULL, "EP" },
-	{ "Speaker", NULL, "SPKL" },
-	{ "Stereo Out", NULL, "SPKR" },
-};
-
-static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-	int pll_rate;
-
-	switch (params_rate(params)) {
-	case 48000:
-	case 8000:
-	case 12000:
-	case 16000:
-	case 24000:
-	case 32000:
-		pll_rate = 48000 * 1024;
-		break;
-	case 44100:
-	case 7350:
-	case 11025:
-	case 14700:
-	case 22050:
-	case 29400:
-		pll_rate = 44100 * 1024;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
-			ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
-			SND_SOC_CLOCK_IN);
-
-	return ret;
-}
-
-static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	unsigned int pll_rate = 48000 * 1024;
-	int ret;
-
-	ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
-			ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
-			SND_SOC_CLOCK_IN);
-
-	return ret;
-}
-static const struct snd_soc_ops bfin_eval_adau1373_ops = {
-	.hw_params = bfin_eval_adau1373_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
-	.name = "adau1373",
-	.stream_name = "adau1373",
-	.cpu_dai_name = "bfin-i2s.0",
-	.codec_dai_name = "adau1373-aif1",
-	.platform_name = "bfin-i2s-pcm-audio",
-	.codec_name = "adau1373.0-001a",
-	.ops = &bfin_eval_adau1373_ops,
-	.init = bfin_eval_adau1373_codec_init,
-	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-			SND_SOC_DAIFMT_CBM_CFM,
-};
-
-static struct snd_soc_card bfin_eval_adau1373 = {
-	.name = "bfin-eval-adau1373",
-	.owner = THIS_MODULE,
-	.dai_link = &bfin_eval_adau1373_dai,
-	.num_links = 1,
-
-	.dapm_widgets		= bfin_eval_adau1373_dapm_widgets,
-	.num_dapm_widgets	= ARRAY_SIZE(bfin_eval_adau1373_dapm_widgets),
-	.dapm_routes		= bfin_eval_adau1373_dapm_routes,
-	.num_dapm_routes	= ARRAY_SIZE(bfin_eval_adau1373_dapm_routes),
-};
-
-static int bfin_eval_adau1373_probe(struct platform_device *pdev)
-{
-	struct snd_soc_card *card = &bfin_eval_adau1373;
-
-	card->dev = &pdev->dev;
-
-	return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1373);
-}
-
-static struct platform_driver bfin_eval_adau1373_driver = {
-	.driver = {
-		.name = "bfin-eval-adau1373",
-		.pm = &snd_soc_pm_ops,
-	},
-	.probe = bfin_eval_adau1373_probe,
-};
-
-module_platform_driver(bfin_eval_adau1373_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1373");
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
deleted file mode 100644
index 5c67f72..0000000
--- a/sound/soc/blackfin/bfin-eval-adau1701.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1701MINIZ on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau1701.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1701_dapm_widgets[] = {
-	SND_SOC_DAPM_SPK("Speaker", NULL),
-	SND_SOC_DAPM_LINE("Line Out", NULL),
-	SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1701_dapm_routes[] = {
-	{ "Speaker", NULL, "OUT0" },
-	{ "Speaker", NULL, "OUT1" },
-	{ "Line Out", NULL, "OUT2" },
-	{ "Line Out", NULL, "OUT3" },
-
-	{ "IN0", NULL, "Line In" },
-	{ "IN1", NULL, "Line In" },
-};
-
-static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-
-	ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000,
-			SND_SOC_CLOCK_IN);
-
-	return ret;
-}
-
-static struct snd_soc_ops bfin_eval_adau1701_ops = {
-	.hw_params = bfin_eval_adau1701_hw_params,
-};
-
-#define BFIN_EVAL_ADAU1701_DAI_FMT (SND_SOC_DAIFMT_I2S | \
-				SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
-	{
-		.name = "adau1701",
-		.stream_name = "adau1701",
-		.cpu_dai_name = "bfin-i2s.0",
-		.codec_dai_name = "adau1701",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.codec_name = "adau1701.0-0034",
-		.ops = &bfin_eval_adau1701_ops,
-		.dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
-	},
-	{
-		.name = "adau1701",
-		.stream_name = "adau1701",
-		.cpu_dai_name = "bfin-i2s.1",
-		.codec_dai_name = "adau1701",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.codec_name = "adau1701.0-0034",
-		.ops = &bfin_eval_adau1701_ops,
-		.dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
-	},
-};
-
-static struct snd_soc_card bfin_eval_adau1701 = {
-	.name = "bfin-eval-adau1701",
-	.owner = THIS_MODULE,
-	.dai_link = &bfin_eval_adau1701_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-	.num_links = 1,
-
-	.dapm_widgets		= bfin_eval_adau1701_dapm_widgets,
-	.num_dapm_widgets	= ARRAY_SIZE(bfin_eval_adau1701_dapm_widgets),
-	.dapm_routes		= bfin_eval_adau1701_dapm_routes,
-	.num_dapm_routes	= ARRAY_SIZE(bfin_eval_adau1701_dapm_routes),
-};
-
-static int bfin_eval_adau1701_probe(struct platform_device *pdev)
-{
-	struct snd_soc_card *card = &bfin_eval_adau1701;
-
-	card->dev = &pdev->dev;
-
-	return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1701);
-}
-
-static struct platform_driver bfin_eval_adau1701_driver = {
-	.driver = {
-		.name = "bfin-eval-adau1701",
-		.pm = &snd_soc_pm_ops,
-	},
-	.probe = bfin_eval_adau1701_probe,
-};
-
-module_platform_driver(bfin_eval_adau1701_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin ADAU1701 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1701");
diff --git a/sound/soc/blackfin/bfin-eval-adau1x61.c b/sound/soc/blackfin/bfin-eval-adau1x61.c
deleted file mode 100644
index fddfe00c..0000000
--- a/sound/soc/blackfin/bfin-eval-adau1x61.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1x61MINIZ on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011-2014 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau17x1.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1x61_dapm_widgets[] = {
-	SND_SOC_DAPM_LINE("In 1", NULL),
-	SND_SOC_DAPM_LINE("In 2", NULL),
-	SND_SOC_DAPM_LINE("In 3-4", NULL),
-
-	SND_SOC_DAPM_LINE("Diff Out L", NULL),
-	SND_SOC_DAPM_LINE("Diff Out R", NULL),
-	SND_SOC_DAPM_LINE("Stereo Out", NULL),
-	SND_SOC_DAPM_HP("Capless HP Out", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1x61_dapm_routes[] = {
-	{ "LAUX", NULL, "In 3-4" },
-	{ "RAUX", NULL, "In 3-4" },
-	{ "LINP", NULL, "In 1" },
-	{ "LINN", NULL, "In 1"},
-	{ "RINP", NULL, "In 2" },
-	{ "RINN", NULL, "In 2" },
-
-	{ "In 1", NULL, "MICBIAS" },
-	{ "In 2", NULL, "MICBIAS" },
-
-	{ "Capless HP Out", NULL, "LHP" },
-	{ "Capless HP Out", NULL, "RHP" },
-	{ "Diff Out L", NULL, "LOUT" },
-	{ "Diff Out R", NULL, "ROUT" },
-	{ "Stereo Out", NULL, "LOUT" },
-	{ "Stereo Out", NULL, "ROUT" },
-};
-
-static int bfin_eval_adau1x61_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int pll_rate;
-	int ret;
-
-	switch (params_rate(params)) {
-	case 48000:
-	case 8000:
-	case 12000:
-	case 16000:
-	case 24000:
-	case 32000:
-	case 96000:
-		pll_rate = 48000 * 1024;
-		break;
-	case 44100:
-	case 7350:
-	case 11025:
-	case 14700:
-	case 22050:
-	case 29400:
-	case 88200:
-		pll_rate = 44100 * 1024;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	ret = snd_soc_dai_set_pll(codec_dai, ADAU17X1_PLL,
-			ADAU17X1_PLL_SRC_MCLK, 12288000, pll_rate);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_dai_set_sysclk(codec_dai, ADAU17X1_CLK_SRC_PLL, pll_rate,
-			SND_SOC_CLOCK_IN);
-
-	return ret;
-}
-
-static const struct snd_soc_ops bfin_eval_adau1x61_ops = {
-	.hw_params = bfin_eval_adau1x61_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adau1x61_dai = {
-	.name = "adau1x61",
-	.stream_name = "adau1x61",
-	.cpu_dai_name = "bfin-i2s.0",
-	.codec_dai_name = "adau-hifi",
-	.platform_name = "bfin-i2s-pcm-audio",
-	.codec_name = "adau1761.0-0038",
-	.ops = &bfin_eval_adau1x61_ops,
-	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-		SND_SOC_DAIFMT_CBM_CFM,
-};
-
-static struct snd_soc_card bfin_eval_adau1x61 = {
-	.name = "bfin-eval-adau1x61",
-	.owner = THIS_MODULE,
-	.driver_name = "eval-adau1x61",
-	.dai_link = &bfin_eval_adau1x61_dai,
-	.num_links = 1,
-
-	.dapm_widgets = bfin_eval_adau1x61_dapm_widgets,
-	.num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1x61_dapm_widgets),
-	.dapm_routes = bfin_eval_adau1x61_dapm_routes,
-	.num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1x61_dapm_routes),
-	.fully_routed = true,
-};
-
-static int bfin_eval_adau1x61_probe(struct platform_device *pdev)
-{
-	bfin_eval_adau1x61.dev = &pdev->dev;
-
-	return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1x61);
-}
-
-static struct platform_driver bfin_eval_adau1x61_driver = {
-	.driver = {
-		.name = "bfin-eval-adau1x61",
-		.pm = &snd_soc_pm_ops,
-	},
-	.probe = bfin_eval_adau1x61_probe,
-};
-module_platform_driver(bfin_eval_adau1x61_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adau1x61 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1x61");
diff --git a/sound/soc/blackfin/bfin-eval-adau1x81.c b/sound/soc/blackfin/bfin-eval-adau1x81.c
deleted file mode 100644
index 3e01cbe..0000000
--- a/sound/soc/blackfin/bfin-eval-adau1x81.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1x81 on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011-2014 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau17x1.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1x81_dapm_widgets[] = {
-	SND_SOC_DAPM_LINE("Stereo In", NULL),
-	SND_SOC_DAPM_LINE("Beep", NULL),
-
-	SND_SOC_DAPM_SPK("Speaker", NULL),
-	SND_SOC_DAPM_HP("Headphone", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1x81_dapm_routes[] = {
-	{ "BEEP", NULL, "Beep" },
-	{ "LMIC", NULL, "Stereo In" },
-	{ "LMIC", NULL, "Stereo In" },
-
-	{ "Headphone", NULL, "AOUTL" },
-	{ "Headphone", NULL, "AOUTR" },
-	{ "Speaker", NULL, "SP" },
-};
-
-static int bfin_eval_adau1x81_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int pll_rate;
-	int ret;
-
-	switch (params_rate(params)) {
-	case 48000:
-	case 8000:
-	case 12000:
-	case 16000:
-	case 24000:
-	case 32000:
-	case 96000:
-		pll_rate = 48000 * 1024;
-		break;
-	case 44100:
-	case 7350:
-	case 11025:
-	case 14700:
-	case 22050:
-	case 29400:
-	case 88200:
-		pll_rate = 44100 * 1024;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	ret = snd_soc_dai_set_pll(codec_dai, ADAU17X1_PLL,
-			ADAU17X1_PLL_SRC_MCLK, 12288000, pll_rate);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_dai_set_sysclk(codec_dai, ADAU17X1_CLK_SRC_PLL, pll_rate,
-			SND_SOC_CLOCK_IN);
-
-	return ret;
-}
-
-static const struct snd_soc_ops bfin_eval_adau1x81_ops = {
-	.hw_params = bfin_eval_adau1x81_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adau1x81_dai = {
-	.name = "adau1x81",
-	.stream_name = "adau1x81",
-	.cpu_dai_name = "bfin-i2s.0",
-	.codec_dai_name = "adau-hifi",
-	.platform_name = "bfin-i2s-pcm-audio",
-	.codec_name = "adau1781.0-0038",
-	.ops = &bfin_eval_adau1x81_ops,
-	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-		SND_SOC_DAIFMT_CBM_CFM,
-};
-
-static struct snd_soc_card bfin_eval_adau1x81 = {
-	.name = "bfin-eval-adau1x81",
-	.driver_name = "eval-adau1x81",
-	.dai_link = &bfin_eval_adau1x81_dai,
-	.num_links = 1,
-
-	.dapm_widgets = bfin_eval_adau1x81_dapm_widgets,
-	.num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1x81_dapm_widgets),
-	.dapm_routes = bfin_eval_adau1x81_dapm_routes,
-	.num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1x81_dapm_routes),
-	.fully_routed = true,
-};
-
-static int bfin_eval_adau1x81_probe(struct platform_device *pdev)
-{
-	bfin_eval_adau1x81.dev = &pdev->dev;
-
-	return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1x81);
-}
-
-static struct platform_driver bfin_eval_adau1x81_driver = {
-	.driver = {
-		.name = "bfin-eval-adau1x81",
-		.pm = &snd_soc_pm_ops,
-	},
-	.probe = bfin_eval_adau1x81_probe,
-};
-module_platform_driver(bfin_eval_adau1x81_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adau1x81 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1x81");
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
deleted file mode 100644
index 99e5eca..0000000
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Machine driver for EVAL-ADAV801 and EVAL-ADAV803 on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include "../codecs/adav80x.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adav80x_dapm_widgets[] = {
-	SND_SOC_DAPM_LINE("Line Out", NULL),
-	SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adav80x_dapm_routes[] = {
-	{ "Line Out", NULL, "VOUTL" },
-	{ "Line Out", NULL, "VOUTR" },
-
-	{ "VINL", NULL, "Line In" },
-	{ "VINR", NULL, "Line In" },
-};
-
-static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-
-	ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL,
-			27000000, params_rate(params) * 256);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_PLL1,
-			params_rate(params) * 256, SND_SOC_CLOCK_IN);
-
-	return ret;
-}
-
-static int bfin_eval_adav80x_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
-	snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK1, 0,
-	    SND_SOC_CLOCK_OUT);
-	snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK2, 0,
-	    SND_SOC_CLOCK_OUT);
-	snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK3, 0,
-	    SND_SOC_CLOCK_OUT);
-
-	snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_XTAL, 2700000, 0);
-
-	return 0;
-}
-
-static const struct snd_soc_ops bfin_eval_adav80x_ops = {
-	.hw_params = bfin_eval_adav80x_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
-	{
-		.name = "adav80x",
-		.stream_name = "ADAV80x HiFi",
-		.cpu_dai_name = "bfin-i2s.0",
-		.codec_dai_name = "adav80x-hifi",
-		.platform_name = "bfin-i2s-pcm-audio",
-		.init = bfin_eval_adav80x_codec_init,
-		.ops = &bfin_eval_adav80x_ops,
-		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-				SND_SOC_DAIFMT_CBM_CFM,
-	},
-};
-
-static struct snd_soc_card bfin_eval_adav80x = {
-	.name = "bfin-eval-adav80x",
-	.owner = THIS_MODULE,
-	.dai_link = bfin_eval_adav80x_dais,
-	.num_links = ARRAY_SIZE(bfin_eval_adav80x_dais),
-
-	.dapm_widgets		= bfin_eval_adav80x_dapm_widgets,
-	.num_dapm_widgets	= ARRAY_SIZE(bfin_eval_adav80x_dapm_widgets),
-	.dapm_routes		= bfin_eval_adav80x_dapm_routes,
-	.num_dapm_routes	= ARRAY_SIZE(bfin_eval_adav80x_dapm_routes),
-};
-
-enum bfin_eval_adav80x_type {
-	BFIN_EVAL_ADAV801,
-	BFIN_EVAL_ADAV803,
-};
-
-static int bfin_eval_adav80x_probe(struct platform_device *pdev)
-{
-	struct snd_soc_card *card = &bfin_eval_adav80x;
-	const char *codec_name;
-
-	switch (platform_get_device_id(pdev)->driver_data) {
-	case BFIN_EVAL_ADAV801:
-		codec_name = "spi0.1";
-		break;
-	case BFIN_EVAL_ADAV803:
-		codec_name = "adav803.0-0034";
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	bfin_eval_adav80x_dais[0].codec_name = codec_name;
-
-	card->dev = &pdev->dev;
-
-	return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adav80x);
-}
-
-static const struct platform_device_id bfin_eval_adav80x_ids[] = {
-	{ "bfin-eval-adav801", BFIN_EVAL_ADAV801 },
-	{ "bfin-eval-adav803", BFIN_EVAL_ADAV803 },
-	{ },
-};
-MODULE_DEVICE_TABLE(platform, bfin_eval_adav80x_ids);
-
-static struct platform_driver bfin_eval_adav80x_driver = {
-	.driver = {
-		.name = "bfin-eval-adav80x",
-		.pm = &snd_soc_pm_ops,
-	},
-	.probe = bfin_eval_adav80x_probe,
-	.id_table = bfin_eval_adav80x_ids,
-};
-
-module_platform_driver(bfin_eval_adav80x_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adav80x driver");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index be8ea72..3c3ef42 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -139,7 +139,7 @@ struct pm860x_priv {
 	unsigned int		pcmclk;
 	unsigned int		dir;
 	unsigned int		filter;
-	struct snd_soc_codec	*codec;
+	struct snd_soc_component *component;
 	struct i2c_client	*i2c;
 	struct regmap		*regmap;
 	struct pm860x_chip	*chip;
@@ -272,15 +272,15 @@ static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg = mc->reg;
 	unsigned int reg2 = mc->rreg;
 	int val[2], val2[2], i;
 
-	val[0] = snd_soc_read(codec, reg) & 0x3f;
-	val[1] = (snd_soc_read(codec, PM860X_SIDETONE_SHIFT) >> 4) & 0xf;
-	val2[0] = snd_soc_read(codec, reg2) & 0x3f;
-	val2[1] = (snd_soc_read(codec, PM860X_SIDETONE_SHIFT)) & 0xf;
+	val[0] = snd_soc_component_read32(component, reg) & 0x3f;
+	val[1] = (snd_soc_component_read32(component, PM860X_SIDETONE_SHIFT) >> 4) & 0xf;
+	val2[0] = snd_soc_component_read32(component, reg2) & 0x3f;
+	val2[1] = (snd_soc_component_read32(component, PM860X_SIDETONE_SHIFT)) & 0xf;
 
 	for (i = 0; i < ARRAY_SIZE(st_table); i++) {
 		if ((st_table[i].m == val[0]) && (st_table[i].n == val[1]))
@@ -296,7 +296,7 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg = mc->reg;
 	unsigned int reg2 = mc->rreg;
 	int err;
@@ -308,18 +308,18 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol,
 	if (val >= ARRAY_SIZE(st_table) || val2 >= ARRAY_SIZE(st_table))
 		return -EINVAL;
 
-	err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m);
+	err = snd_soc_component_update_bits(component, reg, 0x3f, st_table[val].m);
 	if (err < 0)
 		return err;
-	err = snd_soc_update_bits(codec, PM860X_SIDETONE_SHIFT, 0xf0,
+	err = snd_soc_component_update_bits(component, PM860X_SIDETONE_SHIFT, 0xf0,
 				  st_table[val].n << 4);
 	if (err < 0)
 		return err;
 
-	err = snd_soc_update_bits(codec, reg2, 0x3f, st_table[val2].m);
+	err = snd_soc_component_update_bits(component, reg2, 0x3f, st_table[val2].m);
 	if (err < 0)
 		return err;
-	err = snd_soc_update_bits(codec, PM860X_SIDETONE_SHIFT, 0x0f,
+	err = snd_soc_component_update_bits(component, PM860X_SIDETONE_SHIFT, 0x0f,
 				  st_table[val2].n);
 	return err;
 }
@@ -329,15 +329,15 @@ static int snd_soc_get_volsw_2r_out(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg = mc->reg;
 	unsigned int reg2 = mc->rreg;
 	unsigned int shift = mc->shift;
 	int max = mc->max, val, val2;
 	unsigned int mask = (1 << fls(max)) - 1;
 
-	val = snd_soc_read(codec, reg) >> shift;
-	val2 = snd_soc_read(codec, reg2) >> shift;
+	val = snd_soc_component_read32(component, reg) >> shift;
+	val2 = snd_soc_component_read32(component, reg2) >> shift;
 	ucontrol->value.integer.value[0] = (max - val) & mask;
 	ucontrol->value.integer.value[1] = (max - val2) & mask;
 
@@ -349,7 +349,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg = mc->reg;
 	unsigned int reg2 = mc->rreg;
 	unsigned int shift = mc->shift;
@@ -365,11 +365,11 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
 	val = val << shift;
 	val2 = val2 << shift;
 
-	err = snd_soc_update_bits(codec, reg, val_mask, val);
+	err = snd_soc_component_update_bits(component, reg, val_mask, val);
 	if (err < 0)
 		return err;
 
-	err = snd_soc_update_bits(codec, reg2, val_mask, val2);
+	err = snd_soc_component_update_bits(component, reg2, val_mask, val2);
 	return err;
 }
 
@@ -382,7 +382,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
 static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	/*
 	 * In order to avoid current on the load, mute power-on and power-off
@@ -390,8 +390,8 @@ static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
 	 * Unmute by DAC_MUTE. It should be unmuted when DAPM sequence is
 	 * finished.
 	 */
-	snd_soc_update_bits(codec, PM860X_DAC_OFFSET, DAC_MUTE, 0);
-	snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
+	snd_soc_component_update_bits(component, PM860X_DAC_OFFSET, DAC_MUTE, 0);
+	snd_soc_component_update_bits(component, PM860X_EAR_CTRL_2,
 			    RSYNC_CHANGE, RSYNC_CHANGE);
 	return 0;
 }
@@ -399,7 +399,7 @@ static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
 static int pm860x_dac_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int dac = 0;
 	int data;
 
@@ -412,28 +412,28 @@ static int pm860x_dac_event(struct snd_soc_dapm_widget *w,
 		if (dac) {
 			/* Auto mute in power-on sequence. */
 			dac |= MODULATOR;
-			snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
+			snd_soc_component_update_bits(component, PM860X_DAC_OFFSET,
 					    DAC_MUTE, DAC_MUTE);
-			snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
+			snd_soc_component_update_bits(component, PM860X_EAR_CTRL_2,
 					    RSYNC_CHANGE, RSYNC_CHANGE);
 			/* update dac */
-			snd_soc_update_bits(codec, PM860X_DAC_EN_2,
+			snd_soc_component_update_bits(component, PM860X_DAC_EN_2,
 					    dac, dac);
 		}
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
 		if (dac) {
 			/* Auto mute in power-off sequence. */
-			snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
+			snd_soc_component_update_bits(component, PM860X_DAC_OFFSET,
 					    DAC_MUTE, DAC_MUTE);
-			snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
+			snd_soc_component_update_bits(component, PM860X_EAR_CTRL_2,
 					    RSYNC_CHANGE, RSYNC_CHANGE);
 			/* update dac */
-			data = snd_soc_read(codec, PM860X_DAC_EN_2);
+			data = snd_soc_component_read32(component, PM860X_DAC_EN_2);
 			data &= ~dac;
 			if (!(data & (DAC_LEFT | DAC_RIGHT)))
 				data &= ~MODULATOR;
-			snd_soc_write(codec, PM860X_DAC_EN_2, data);
+			snd_soc_component_write(component, PM860X_DAC_EN_2, data);
 		}
 		break;
 	}
@@ -922,13 +922,13 @@ static const struct snd_soc_dapm_route pm860x_dapm_routes[] = {
  */
 static int pm860x_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int data = 0, mask = MUTE_LEFT | MUTE_RIGHT;
 
 	if (mute)
 		data = mask;
-	snd_soc_update_bits(codec, PM860X_DAC_OFFSET, mask, data);
-	snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
+	snd_soc_component_update_bits(component, PM860X_DAC_OFFSET, mask, data);
+	snd_soc_component_update_bits(component, PM860X_EAR_CTRL_2,
 			    RSYNC_CHANGE, RSYNC_CHANGE);
 	return 0;
 }
@@ -937,7 +937,7 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned char inf = 0, mask = 0;
 
 	/* bit size */
@@ -952,7 +952,7 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 	mask |= PCM_INF2_18WL;
-	snd_soc_update_bits(codec, PM860X_PCM_IFACE_2, mask, inf);
+	snd_soc_component_update_bits(component, PM860X_PCM_IFACE_2, mask, inf);
 
 	/* sample rate */
 	switch (params_rate(params)) {
@@ -971,7 +971,7 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, PM860X_PCM_RATE, 0x0f, inf);
+	snd_soc_component_update_bits(component, PM860X_PCM_RATE, 0x0f, inf);
 
 	return 0;
 }
@@ -979,8 +979,8 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
 static int pm860x_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
 				  unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 	unsigned char inf = 0, mask = 0;
 	int ret = -EINVAL;
 
@@ -1012,15 +1012,15 @@ static int pm860x_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	mask |= PCM_MODE_MASK;
 	if (ret)
 		return ret;
-	snd_soc_update_bits(codec, PM860X_PCM_IFACE_2, mask, inf);
+	snd_soc_component_update_bits(component, PM860X_PCM_IFACE_2, mask, inf);
 	return 0;
 }
 
 static int pm860x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 
 	if (dir == PM860X_CLK_DIR_OUT)
 		pm860x->dir = PM860X_CLK_DIR_OUT;
@@ -1034,7 +1034,7 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned char inf;
 
 	/* bit size */
@@ -1048,7 +1048,7 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, PM860X_I2S_IFACE_2, PCM_INF2_18WL, inf);
+	snd_soc_component_update_bits(component, PM860X_I2S_IFACE_2, PCM_INF2_18WL, inf);
 
 	/* sample rate */
 	switch (params_rate(params)) {
@@ -1076,7 +1076,7 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, PM860X_I2S_IFACE_4, 0xf, inf);
+	snd_soc_component_update_bits(component, PM860X_I2S_IFACE_4, 0xf, inf);
 
 	return 0;
 }
@@ -1084,8 +1084,8 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
 static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
 				  unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 	unsigned char inf = 0, mask = 0;
 
 	mask |= PCM_INF2_BCLK | PCM_INF2_FS | PCM_INF2_MASTER;
@@ -1116,14 +1116,14 @@ static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 	mask |= PCM_MODE_MASK;
-	snd_soc_update_bits(codec, PM860X_I2S_IFACE_2, mask, inf);
+	snd_soc_component_update_bits(component, PM860X_I2S_IFACE_2, mask, inf);
 	return 0;
 }
 
-static int pm860x_set_bias_level(struct snd_soc_codec *codec,
+static int pm860x_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+	struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 	int data;
 
 	switch (level) {
@@ -1134,7 +1134,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Enable Audio PLL & Audio section */
 			data = AUDIO_PLL | AUDIO_SECTION_ON;
 			pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
@@ -1216,7 +1216,7 @@ static struct snd_soc_dai_driver pm860x_dai[] = {
 	},
 };
 
-static irqreturn_t pm860x_codec_handler(int irq, void *data)
+static irqreturn_t pm860x_component_handler(int irq, void *data)
 {
 	struct pm860x_priv *pm860x = data;
 	int status, shrt, report = 0, mic_report = 0;
@@ -1230,7 +1230,7 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data)
 #ifndef CONFIG_SND_SOC_88PM860X_MODULE
 	if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 |
 		      SHORT_LO1 | SHORT_LO2))
-		trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev));
+		trace_snd_soc_jack_irq(dev_name(pm860x->component->dev));
 #endif
 
 	if ((pm860x->det.hp_det & SND_JACK_HEADPHONE)
@@ -1256,17 +1256,17 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data)
 		snd_soc_jack_report(pm860x->det.mic_jack, SND_JACK_MICROPHONE,
 				    SND_JACK_MICROPHONE);
 
-	dev_dbg(pm860x->codec->dev, "headphone report:0x%x, mask:%x\n",
+	dev_dbg(pm860x->component->dev, "headphone report:0x%x, mask:%x\n",
 		report, mask);
-	dev_dbg(pm860x->codec->dev, "microphone report:0x%x\n", mic_report);
+	dev_dbg(pm860x->component->dev, "microphone report:0x%x\n", mic_report);
 	return IRQ_HANDLED;
 }
 
-int pm860x_hs_jack_detect(struct snd_soc_codec *codec,
+int pm860x_hs_jack_detect(struct snd_soc_component *component,
 			  struct snd_soc_jack *jack,
 			  int det, int hook, int hs_shrt, int lo_shrt)
 {
-	struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+	struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 	int data;
 
 	pm860x->det.hp_jack = jack;
@@ -1290,15 +1290,15 @@ int pm860x_hs_jack_detect(struct snd_soc_codec *codec,
 	}
 
 	/* sync status */
-	pm860x_codec_handler(0, pm860x);
+	pm860x_component_handler(0, pm860x);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pm860x_hs_jack_detect);
 
-int pm860x_mic_jack_detect(struct snd_soc_codec *codec,
+int pm860x_mic_jack_detect(struct snd_soc_component *component,
 			   struct snd_soc_jack *jack, int det)
 {
-	struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+	struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 
 	pm860x->det.mic_jack = jack;
 	pm860x->det.mic_det = det;
@@ -1308,25 +1308,25 @@ int pm860x_mic_jack_detect(struct snd_soc_codec *codec,
 				MICDET_MASK, MICDET_MASK);
 
 	/* sync status */
-	pm860x_codec_handler(0, pm860x);
+	pm860x_component_handler(0, pm860x);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
 
-static int pm860x_probe(struct snd_soc_codec *codec)
+static int pm860x_probe(struct snd_soc_component *component)
 {
-	struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+	struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 	int i, ret;
 
-	pm860x->codec = codec;
-	snd_soc_codec_init_regmap(codec,  pm860x->regmap);
+	pm860x->component = component;
+	snd_soc_component_init_regmap(component,  pm860x->regmap);
 
 	for (i = 0; i < 4; i++) {
 		ret = request_threaded_irq(pm860x->irq[i], NULL,
-					   pm860x_codec_handler, IRQF_ONESHOT,
+					   pm860x_component_handler, IRQF_ONESHOT,
 					   pm860x->name[i], pm860x);
 		if (ret < 0) {
-			dev_err(codec->dev, "Failed to request IRQ!\n");
+			dev_err(component->dev, "Failed to request IRQ!\n");
 			goto out;
 		}
 	}
@@ -1339,29 +1339,29 @@ static int pm860x_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int pm860x_remove(struct snd_soc_codec *codec)
+static void pm860x_remove(struct snd_soc_component *component)
 {
-	struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+	struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 3; i >= 0; i--)
 		free_irq(pm860x->irq[i], pm860x);
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_pm860x = {
-	.probe		= pm860x_probe,
-	.remove		= pm860x_remove,
-	.set_bias_level	= pm860x_set_bias_level,
-
-	.component_driver = {
-		.controls		= pm860x_snd_controls,
-		.num_controls		= ARRAY_SIZE(pm860x_snd_controls),
-		.dapm_widgets		= pm860x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(pm860x_dapm_widgets),
-		.dapm_routes		= pm860x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(pm860x_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_pm860x = {
+	.probe			= pm860x_probe,
+	.remove			= pm860x_remove,
+	.set_bias_level		= pm860x_set_bias_level,
+	.controls		= pm860x_snd_controls,
+	.num_controls		= ARRAY_SIZE(pm860x_snd_controls),
+	.dapm_widgets		= pm860x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pm860x_dapm_widgets),
+	.dapm_routes		= pm860x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pm860x_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int pm860x_codec_probe(struct platform_device *pdev)
@@ -1393,10 +1393,11 @@ static int pm860x_codec_probe(struct platform_device *pdev)
 		strncpy(pm860x->name[i], res->name, MAX_NAME_LEN);
 	}
 
-	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pm860x,
+	ret = devm_snd_soc_register_component(&pdev->dev,
+				     &soc_component_dev_pm860x,
 				     pm860x_dai, ARRAY_SIZE(pm860x_dai));
 	if (ret) {
-		dev_err(&pdev->dev, "Failed to register codec\n");
+		dev_err(&pdev->dev, "Failed to register component\n");
 		return -EINVAL;
 	}
 	return ret;
@@ -1404,7 +1405,6 @@ static int pm860x_codec_probe(struct platform_device *pdev)
 
 static int pm860x_codec_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/88pm860x-codec.h b/sound/soc/codecs/88pm860x-codec.h
index f7282f4..33aa9ff 100644
--- a/sound/soc/codecs/88pm860x-codec.h
+++ b/sound/soc/codecs/88pm860x-codec.h
@@ -88,9 +88,9 @@
 #define PM860X_SHORT_LINEOUT		(1 << 4)
 #define PM860X_DET_MASK			0x1F
 
-extern int pm860x_hs_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
+extern int pm860x_hs_jack_detect(struct snd_soc_component *, struct snd_soc_jack *,
 				 int, int, int, int);
-extern int pm860x_mic_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
+extern int pm860x_mic_jack_detect(struct snd_soc_component *, struct snd_soc_jack *,
 				  int);
 
 #endif	/* __88PM860X_H */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 2b331f7..9548f63 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -35,6 +35,7 @@
 	select SND_SOC_ADAU7002
 	select SND_SOC_ADS117X
 	select SND_SOC_AK4104 if SPI_MASTER
+	select SND_SOC_AK4458 if I2C
 	select SND_SOC_AK4535 if I2C
 	select SND_SOC_AK4554
 	select SND_SOC_AK4613 if I2C
@@ -42,9 +43,11 @@
 	select SND_SOC_AK4642 if I2C
 	select SND_SOC_AK4671 if I2C
 	select SND_SOC_AK5386
+	select SND_SOC_AK5558 if I2C
 	select SND_SOC_ALC5623 if I2C
 	select SND_SOC_ALC5632 if I2C
 	select SND_SOC_BT_SCO
+	select SND_SOC_BD28623
 	select SND_SOC_CQ0093VC
 	select SND_SOC_CS35L32 if I2C
 	select SND_SOC_CS35L33 if I2C
@@ -98,6 +101,7 @@
 	select SND_SOC_MAX98373 if I2C
 	select SND_SOC_MAX9850 if I2C
 	select SND_SOC_MAX9860 if I2C
+	select SND_SOC_MAX9759
 	select SND_SOC_MAX9768 if I2C
 	select SND_SOC_MAX9877 if I2C
 	select SND_SOC_MC13783 if MFD_MC13XXX
@@ -108,6 +112,7 @@
 	select SND_SOC_NAU8825 if I2C
 	select SND_SOC_HDMI_CODEC
 	select SND_SOC_PCM1681 if I2C
+	select SND_SOC_PCM1789_I2C if I2C
 	select SND_SOC_PCM179X_I2C if I2C
 	select SND_SOC_PCM179X_SPI if SPI_MASTER
 	select SND_SOC_PCM186X_I2C if I2C
@@ -151,6 +156,7 @@
 	select SND_SOC_TAS571X if I2C
 	select SND_SOC_TAS5720 if I2C
 	select SND_SOC_TAS6424 if I2C
+	select SND_SOC_TDA7419 if I2C
 	select SND_SOC_TFA9879 if I2C
 	select SND_SOC_TLV320AIC23_I2C if I2C
 	select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
@@ -375,6 +381,11 @@
 	tristate "AKM AK4104 CODEC"
 	depends on SPI_MASTER
 
+config SND_SOC_AK4458
+	tristate "AKM AK4458 CODEC"
+	depends on I2C
+	select REGMAP_I2C
+
 config SND_SOC_AK4535
 	tristate
 
@@ -398,6 +409,11 @@
 config SND_SOC_AK5386
 	tristate "AKM AK5638 CODEC"
 
+config SND_SOC_AK5558
+	tristate "AKM AK5558 CODEC"
+	depends on I2C
+	select REGMAP_I2C
+
 config SND_SOC_ALC5623
        tristate "Realtek ALC5623 CODEC"
 	depends on I2C
@@ -405,9 +421,20 @@
 config SND_SOC_ALC5632
 	tristate
 
+config SND_SOC_BD28623
+	tristate "ROHM BD28623 CODEC"
+	help
+	  Enable support for ROHM BD28623MUV Class D speaker amplifier.
+	  This codec does not have any control buses such as I2C, it
+	  detect format of I2S automatically.
+
 config SND_SOC_BT_SCO
 	tristate "Dummy BT SCO codec driver"
 
+config SND_SOC_CPCAP
+	tristate "Motorola CPCAP codec"
+	depends on MFD_CPCAP
+
 config SND_SOC_CQ0093VC
 	tristate
 
@@ -615,7 +642,8 @@
 	depends on I2C
 
 config SND_SOC_MAX9867
-	tristate
+	tristate "Maxim MAX9867 CODEC"
+	depends on I2C
 
 config SND_SOC_MAX98925
        tristate
@@ -650,6 +678,17 @@
 	tristate "Texas Instruments PCM1681 CODEC"
 	depends on I2C
 
+config SND_SOC_PCM1789
+	tristate
+
+config SND_SOC_PCM1789_I2C
+	tristate "Texas Instruments PCM1789 CODEC (I2C)"
+	depends on I2C
+	select SND_SOC_PCM1789
+	help
+	  Enable support for Texas Instruments PCM1789 CODEC.
+	  Select this if your PCM1789 is connected via an I2C bus.
+
 config SND_SOC_PCM179X
 	tristate
 
@@ -910,6 +949,11 @@
 	  Enable support for Texas Instruments TAS6424 high-efficiency
 	  digital input quad-channel Class-D audio power amplifiers.
 
+config SND_SOC_TDA7419
+	tristate "ST TDA7419 audio processor"
+	depends on I2C
+	select REGMAP_I2C
+
 config SND_SOC_TFA9879
 	tristate "NXP Semiconductors TFA9879 amplifier"
 	depends on I2C
@@ -1187,6 +1231,10 @@
 config SND_SOC_LM4857
 	tristate
 
+config SND_SOC_MAX9759
+	tristate "Maxim MAX9759 speaker Amplifier"
+	select GPIOLIB
+
 config SND_SOC_MAX9768
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index da15713..e849d14 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -27,6 +27,7 @@
 snd-soc-adav803-objs := adav803.o
 snd-soc-ads117x-objs := ads117x.o
 snd-soc-ak4104-objs := ak4104.o
+snd-soc-ak4458-objs := ak4458.o
 snd-soc-ak4535-objs := ak4535.o
 snd-soc-ak4554-objs := ak4554.o
 snd-soc-ak4613-objs := ak4613.o
@@ -34,8 +35,11 @@
 snd-soc-ak4642-objs := ak4642.o
 snd-soc-ak4671-objs := ak4671.o
 snd-soc-ak5386-objs := ak5386.o
+snd-soc-ak5558-objs := ak5558.o
 snd-soc-arizona-objs := arizona.o
+snd-soc-bd28623-objs := bd28623.o
 snd-soc-bt-sco-objs := bt-sco.o
+snd-soc-cpcap-objs := cpcap.o
 snd-soc-cq93vc-objs := cq93vc.o
 snd-soc-cs35l32-objs := cs35l32.o
 snd-soc-cs35l33-objs := cs35l33.o
@@ -80,6 +84,7 @@
 snd-soc-l3-objs := l3.o
 snd-soc-lm4857-objs := lm4857.o
 snd-soc-lm49453-objs := lm49453.o
+snd-soc-max9759-objs := max9759.o
 snd-soc-max9768-objs := max9768.o
 snd-soc-max98088-objs := max98088.o
 snd-soc-max98090-objs := max98090.o
@@ -103,6 +108,8 @@
 snd-soc-nau8825-objs := nau8825.o
 snd-soc-hdmi-codec-objs := hdmi-codec.o
 snd-soc-pcm1681-objs := pcm1681.o
+snd-soc-pcm1789-codec-objs := pcm1789.o
+snd-soc-pcm1789-i2c-objs := pcm1789-i2c.o
 snd-soc-pcm179x-codec-objs := pcm179x.o
 snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o
 snd-soc-pcm179x-spi-objs := pcm179x-spi.o
@@ -160,6 +167,7 @@
 snd-soc-tas571x-objs := tas571x.o
 snd-soc-tas5720-objs := tas5720.o
 snd-soc-tas6424-objs := tas6424.o
+snd-soc-tda7419-objs := tda7419.o
 snd-soc-tfa9879-objs := tfa9879.o
 snd-soc-tlv320aic23-objs := tlv320aic23.o
 snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
@@ -270,6 +278,7 @@
 obj-$(CONFIG_SND_SOC_ADAV803)  += snd-soc-adav803.o
 obj-$(CONFIG_SND_SOC_ADS117X)	+= snd-soc-ads117x.o
 obj-$(CONFIG_SND_SOC_AK4104)	+= snd-soc-ak4104.o
+obj-$(CONFIG_SND_SOC_AK4458)	+= snd-soc-ak4458.o
 obj-$(CONFIG_SND_SOC_AK4535)	+= snd-soc-ak4535.o
 obj-$(CONFIG_SND_SOC_AK4554)	+= snd-soc-ak4554.o
 obj-$(CONFIG_SND_SOC_AK4613)	+= snd-soc-ak4613.o
@@ -277,11 +286,14 @@
 obj-$(CONFIG_SND_SOC_AK4642)	+= snd-soc-ak4642.o
 obj-$(CONFIG_SND_SOC_AK4671)	+= snd-soc-ak4671.o
 obj-$(CONFIG_SND_SOC_AK5386)	+= snd-soc-ak5386.o
+obj-$(CONFIG_SND_SOC_AK5558)	+= snd-soc-ak5558.o
 obj-$(CONFIG_SND_SOC_ALC5623)    += snd-soc-alc5623.o
 obj-$(CONFIG_SND_SOC_ALC5632)	+= snd-soc-alc5632.o
 obj-$(CONFIG_SND_SOC_ARIZONA)	+= snd-soc-arizona.o
+obj-$(CONFIG_SND_SOC_BD28623)	+= snd-soc-bd28623.o
 obj-$(CONFIG_SND_SOC_BT_SCO)	+= snd-soc-bt-sco.o
 obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
+obj-$(CONFIG_SND_SOC_CPCAP)	+= snd-soc-cpcap.o
 obj-$(CONFIG_SND_SOC_CS35L32)	+= snd-soc-cs35l32.o
 obj-$(CONFIG_SND_SOC_CS35L33)	+= snd-soc-cs35l33.o
 obj-$(CONFIG_SND_SOC_CS35L34)	+= snd-soc-cs35l34.o
@@ -325,6 +337,7 @@
 obj-$(CONFIG_SND_SOC_L3)	+= snd-soc-l3.o
 obj-$(CONFIG_SND_SOC_LM4857)	+= snd-soc-lm4857.o
 obj-$(CONFIG_SND_SOC_LM49453)   += snd-soc-lm49453.o
+obj-$(CONFIG_SND_SOC_MAX9759)	+= snd-soc-max9759.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
@@ -349,6 +362,8 @@
 obj-$(CONFIG_SND_SOC_HDMI_CODEC)	+= snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM1681)	+= snd-soc-pcm1681.o
 obj-$(CONFIG_SND_SOC_PCM179X)	+= snd-soc-pcm179x-codec.o
+obj-$(CONFIG_SND_SOC_PCM1789_I2C)	+= snd-soc-pcm1789-i2c.o
+obj-$(CONFIG_SND_SOC_PCM1789)	+= snd-soc-pcm1789-codec.o
 obj-$(CONFIG_SND_SOC_PCM179X_I2C)	+= snd-soc-pcm179x-i2c.o
 obj-$(CONFIG_SND_SOC_PCM179X_SPI)	+= snd-soc-pcm179x-spi.o
 obj-$(CONFIG_SND_SOC_PCM186X)	+= snd-soc-pcm186x.o
@@ -387,7 +402,6 @@
 obj-$(CONFIG_SND_SOC_SIGMADSP_I2C)	+= snd-soc-sigmadsp-i2c.o
 obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP)	+= snd-soc-sigmadsp-regmap.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_SIRF_AUDIO_CODEC) += sirf-audio-codec.o
 obj-$(CONFIG_SND_SOC_SSM2518)	+= snd-soc-ssm2518.o
@@ -405,6 +419,7 @@
 obj-$(CONFIG_SND_SOC_TAS571X)	+= snd-soc-tas571x.o
 obj-$(CONFIG_SND_SOC_TAS5720)	+= snd-soc-tas5720.o
 obj-$(CONFIG_SND_SOC_TAS6424)	+= snd-soc-tas6424.o
+obj-$(CONFIG_SND_SOC_TDA7419)	+= snd-soc-tda7419.o
 obj-$(CONFIG_SND_SOC_TFA9879)	+= snd-soc-tfa9879.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23)	+= snd-soc-tlv320aic23.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C)	+= snd-soc-tlv320aic23-i2c.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 006627b..03bbbcd 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -1037,86 +1037,86 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = {
 };
 
 /* ANC FIR-coefficients configuration sequence */
-static void anc_fir(struct snd_soc_codec *codec,
+static void anc_fir(struct snd_soc_component *component,
 		unsigned int bnk, unsigned int par, unsigned int val)
 {
 	if (par == 0 && bnk == 0)
-		snd_soc_update_bits(codec, AB8500_ANCCONF1,
+		snd_soc_component_update_bits(component, AB8500_ANCCONF1,
 			BIT(AB8500_ANCCONF1_ANCFIRUPDATE),
 			BIT(AB8500_ANCCONF1_ANCFIRUPDATE));
 
-	snd_soc_write(codec, AB8500_ANCCONF5, val >> 8 & 0xff);
-	snd_soc_write(codec, AB8500_ANCCONF6, val &  0xff);
+	snd_soc_component_write(component, AB8500_ANCCONF5, val >> 8 & 0xff);
+	snd_soc_component_write(component, AB8500_ANCCONF6, val &  0xff);
 
 	if (par == AB8500_ANC_FIR_COEFFS - 1 && bnk == 1)
-		snd_soc_update_bits(codec, AB8500_ANCCONF1,
+		snd_soc_component_update_bits(component, AB8500_ANCCONF1,
 			BIT(AB8500_ANCCONF1_ANCFIRUPDATE), 0);
 }
 
 /* ANC IIR-coefficients configuration sequence */
-static void anc_iir(struct snd_soc_codec *codec, unsigned int bnk,
+static void anc_iir(struct snd_soc_component *component, unsigned int bnk,
 		unsigned int par, unsigned int val)
 {
 	if (par == 0) {
 		if (bnk == 0) {
-			snd_soc_update_bits(codec, AB8500_ANCCONF1,
+			snd_soc_component_update_bits(component, AB8500_ANCCONF1,
 					BIT(AB8500_ANCCONF1_ANCIIRINIT),
 					BIT(AB8500_ANCCONF1_ANCIIRINIT));
 			usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
-			snd_soc_update_bits(codec, AB8500_ANCCONF1,
+			snd_soc_component_update_bits(component, AB8500_ANCCONF1,
 					BIT(AB8500_ANCCONF1_ANCIIRINIT), 0);
 			usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
 		} else {
-			snd_soc_update_bits(codec, AB8500_ANCCONF1,
+			snd_soc_component_update_bits(component, AB8500_ANCCONF1,
 					BIT(AB8500_ANCCONF1_ANCIIRUPDATE),
 					BIT(AB8500_ANCCONF1_ANCIIRUPDATE));
 		}
 	} else if (par > 3) {
-		snd_soc_write(codec, AB8500_ANCCONF7, 0);
-		snd_soc_write(codec, AB8500_ANCCONF8, val >> 16 & 0xff);
+		snd_soc_component_write(component, AB8500_ANCCONF7, 0);
+		snd_soc_component_write(component, AB8500_ANCCONF8, val >> 16 & 0xff);
 	}
 
-	snd_soc_write(codec, AB8500_ANCCONF7, val >> 8 & 0xff);
-	snd_soc_write(codec, AB8500_ANCCONF8, val & 0xff);
+	snd_soc_component_write(component, AB8500_ANCCONF7, val >> 8 & 0xff);
+	snd_soc_component_write(component, AB8500_ANCCONF8, val & 0xff);
 
 	if (par == AB8500_ANC_IIR_COEFFS - 1 && bnk == 1)
-		snd_soc_update_bits(codec, AB8500_ANCCONF1,
+		snd_soc_component_update_bits(component, AB8500_ANCCONF1,
 			BIT(AB8500_ANCCONF1_ANCIIRUPDATE), 0);
 }
 
 /* ANC IIR-/FIR-coefficients configuration sequence */
-static void anc_configure(struct snd_soc_codec *codec,
+static void anc_configure(struct snd_soc_component *component,
 			bool apply_fir, bool apply_iir)
 {
-	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
+	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
 	unsigned int bnk, par, val;
 
-	dev_dbg(codec->dev, "%s: Enter.\n", __func__);
+	dev_dbg(component->dev, "%s: Enter.\n", __func__);
 
 	if (apply_fir)
-		snd_soc_update_bits(codec, AB8500_ANCCONF1,
+		snd_soc_component_update_bits(component, AB8500_ANCCONF1,
 			BIT(AB8500_ANCCONF1_ENANC), 0);
 
-	snd_soc_update_bits(codec, AB8500_ANCCONF1,
+	snd_soc_component_update_bits(component, AB8500_ANCCONF1,
 		BIT(AB8500_ANCCONF1_ENANC), BIT(AB8500_ANCCONF1_ENANC));
 
 	if (apply_fir)
 		for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
 			for (par = 0; par < AB8500_ANC_FIR_COEFFS; par++) {
-				val = snd_soc_read(codec,
+				val = snd_soc_component_read32(component,
 						drvdata->anc_fir_values[par]);
-				anc_fir(codec, bnk, par, val);
+				anc_fir(component, bnk, par, val);
 			}
 
 	if (apply_iir)
 		for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
 			for (par = 0; par < AB8500_ANC_IIR_COEFFS; par++) {
-				val = snd_soc_read(codec,
+				val = snd_soc_component_read32(component,
 						drvdata->anc_iir_values[par]);
-				anc_iir(codec, bnk, par, val);
+				anc_iir(component, bnk, par, val);
 			}
 
-	dev_dbg(codec->dev, "%s: Exit.\n", __func__);
+	dev_dbg(component->dev, "%s: Exit.\n", __func__);
 }
 
 /*
@@ -1126,8 +1126,8 @@ static void anc_configure(struct snd_soc_codec *codec,
 static int sid_status_control_get(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
 
 	mutex_lock(&drvdata->ctrl_lock);
 	ucontrol->value.enumerated.item[0] = drvdata->sid_status;
@@ -1140,15 +1140,15 @@ static int sid_status_control_get(struct snd_kcontrol *kcontrol,
 static int sid_status_control_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
 	unsigned int param, sidconf, val;
 	int status = 1;
 
-	dev_dbg(codec->dev, "%s: Enter\n", __func__);
+	dev_dbg(component->dev, "%s: Enter\n", __func__);
 
 	if (ucontrol->value.enumerated.item[0] != SID_APPLY_FIR) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"%s: ERROR: This control supports '%s' only!\n",
 			__func__, enum_sid_state[SID_APPLY_FIR]);
 		return -EIO;
@@ -1156,10 +1156,10 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
 
 	mutex_lock(&drvdata->ctrl_lock);
 
-	sidconf = snd_soc_read(codec, AB8500_SIDFIRCONF);
+	sidconf = snd_soc_component_read32(component, AB8500_SIDFIRCONF);
 	if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) {
 		if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) {
-			dev_err(codec->dev, "%s: Sidetone busy while off!\n",
+			dev_err(component->dev, "%s: Sidetone busy while off!\n",
 				__func__);
 			status = -EPERM;
 		} else {
@@ -1168,18 +1168,18 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
 		goto out;
 	}
 
-	snd_soc_write(codec, AB8500_SIDFIRADR, 0);
+	snd_soc_component_write(component, AB8500_SIDFIRADR, 0);
 
 	for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) {
-		val = snd_soc_read(codec, drvdata->sid_fir_values[param]);
-		snd_soc_write(codec, AB8500_SIDFIRCOEF1, val >> 8 & 0xff);
-		snd_soc_write(codec, AB8500_SIDFIRCOEF2, val & 0xff);
+		val = snd_soc_component_read32(component, drvdata->sid_fir_values[param]);
+		snd_soc_component_write(component, AB8500_SIDFIRCOEF1, val >> 8 & 0xff);
+		snd_soc_component_write(component, AB8500_SIDFIRCOEF2, val & 0xff);
 	}
 
-	snd_soc_update_bits(codec, AB8500_SIDFIRADR,
+	snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
 		BIT(AB8500_SIDFIRADR_FIRSIDSET),
 		BIT(AB8500_SIDFIRADR_FIRSIDSET));
-	snd_soc_update_bits(codec, AB8500_SIDFIRADR,
+	snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
 		BIT(AB8500_SIDFIRADR_FIRSIDSET), 0);
 
 	drvdata->sid_status = SID_FIR_CONFIGURED;
@@ -1187,7 +1187,7 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
 out:
 	mutex_unlock(&drvdata->ctrl_lock);
 
-	dev_dbg(codec->dev, "%s: Exit\n", __func__);
+	dev_dbg(component->dev, "%s: Exit\n", __func__);
 
 	return status;
 }
@@ -1195,8 +1195,8 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
 static int anc_status_control_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
 
 	mutex_lock(&drvdata->ctrl_lock);
 	ucontrol->value.enumerated.item[0] = drvdata->anc_status;
@@ -1208,10 +1208,10 @@ static int anc_status_control_get(struct snd_kcontrol *kcontrol,
 static int anc_status_control_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
-	struct device *dev = codec->dev;
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
+	struct device *dev = component->dev;
 	bool apply_fir, apply_iir;
 	unsigned int req;
 	int status;
@@ -1244,7 +1244,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
 	}
 	snd_soc_dapm_sync(dapm);
 
-	anc_configure(codec, apply_fir, apply_iir);
+	anc_configure(component, apply_fir, apply_iir);
 
 	if (apply_fir) {
 		if (drvdata->anc_status == ANC_IIR_CONFIGURED)
@@ -1291,8 +1291,8 @@ static int filter_control_info(struct snd_kcontrol *kcontrol,
 static int filter_control_get(struct snd_kcontrol *kcontrol,
 			struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct ab8500_codec_drvdata *drvdata = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ab8500_codec_drvdata *drvdata = snd_soc_component_get_drvdata(component);
 	struct filter_control *fc =
 			(struct filter_control *)kcontrol->private_value;
 	unsigned int i;
@@ -1308,8 +1308,8 @@ static int filter_control_get(struct snd_kcontrol *kcontrol,
 static int filter_control_put(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct ab8500_codec_drvdata *drvdata = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ab8500_codec_drvdata *drvdata = snd_soc_component_get_drvdata(component);
 	struct filter_control *fc =
 			(struct filter_control *)kcontrol->private_value;
 	unsigned int i;
@@ -1926,11 +1926,11 @@ enum ab8500_filter {
  * Extended interface for codec-driver
  */
 
-static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec)
+static int ab8500_audio_init_audioblock(struct snd_soc_component *component)
 {
 	int status;
 
-	dev_dbg(codec->dev, "%s: Enter.\n", __func__);
+	dev_dbg(component->dev, "%s: Enter.\n", __func__);
 
 	/* Reset audio-registers and disable 32kHz-clock output 2 */
 	status = ab8500_sysctrl_write(AB8500_STW4500CTRL3,
@@ -1943,26 +1943,26 @@ static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
+static int ab8500_audio_setup_mics(struct snd_soc_component *component,
 			struct amic_settings *amics)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	u8 value8;
 	unsigned int value;
 	int status;
 	const struct snd_soc_dapm_route *route;
 
-	dev_dbg(codec->dev, "%s: Enter.\n", __func__);
+	dev_dbg(component->dev, "%s: Enter.\n", __func__);
 
 	/* Set DMic-clocks to outputs */
-	status = abx500_get_register_interruptible(codec->dev, AB8500_MISC,
+	status = abx500_get_register_interruptible(component->dev, AB8500_MISC,
 						AB8500_GPIO_DIR4_REG,
 						&value8);
 	if (status < 0)
 		return status;
 	value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT |
 		GPIO31_DIR_OUTPUT;
-	status = abx500_set_register_interruptible(codec->dev,
+	status = abx500_set_register_interruptible(component->dev,
 						AB8500_MISC,
 						AB8500_GPIO_DIR4_REG,
 						value);
@@ -1970,41 +1970,41 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
 		return status;
 
 	/* Attach regulators to AMic DAPM-paths */
-	dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__,
+	dev_dbg(component->dev, "%s: Mic 1a regulator: %s\n", __func__,
 		amic_micbias_str(amics->mic1a_micbias));
 	route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias];
 	status = snd_soc_dapm_add_routes(dapm, route, 1);
-	dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__,
+	dev_dbg(component->dev, "%s: Mic 1b regulator: %s\n", __func__,
 		amic_micbias_str(amics->mic1b_micbias));
 	route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias];
 	status |= snd_soc_dapm_add_routes(dapm, route, 1);
-	dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__,
+	dev_dbg(component->dev, "%s: Mic 2 regulator: %s\n", __func__,
 		amic_micbias_str(amics->mic2_micbias));
 	route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias];
 	status |= snd_soc_dapm_add_routes(dapm, route, 1);
 	if (status < 0) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"%s: Failed to add AMic-regulator DAPM-routes (%d).\n",
 			__func__, status);
 		return status;
 	}
 
 	/* Set AMic-configuration */
-	dev_dbg(codec->dev, "%s: Mic 1 mic-type: %s\n", __func__,
+	dev_dbg(component->dev, "%s: Mic 1 mic-type: %s\n", __func__,
 		amic_type_str(amics->mic1_type));
-	snd_soc_update_bits(codec, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX,
+	snd_soc_component_update_bits(component, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX,
 			amics->mic1_type == AMIC_TYPE_DIFFERENTIAL ?
 				0 : AB8500_ANAGAINX_ENSEMICX);
-	dev_dbg(codec->dev, "%s: Mic 2 mic-type: %s\n", __func__,
+	dev_dbg(component->dev, "%s: Mic 2 mic-type: %s\n", __func__,
 		amic_type_str(amics->mic2_type));
-	snd_soc_update_bits(codec, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX,
+	snd_soc_component_update_bits(component, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX,
 			amics->mic2_type == AMIC_TYPE_DIFFERENTIAL ?
 				0 : AB8500_ANAGAINX_ENSEMICX);
 
 	return 0;
 }
 
-static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
+static int ab8500_audio_set_ear_cmv(struct snd_soc_component *component,
 				enum ear_cm_voltage ear_cmv)
 {
 	char *cmv_str;
@@ -2023,14 +2023,14 @@ static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
 		cmv_str = "1.58V";
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"%s: Unknown earpiece CM-voltage (%d)!\n",
 			__func__, (int)ear_cmv);
 		return -EINVAL;
 	}
-	dev_dbg(codec->dev, "%s: Earpiece CM-voltage: %s\n", __func__,
+	dev_dbg(component->dev, "%s: Earpiece CM-voltage: %s\n", __func__,
 		cmv_str);
-	snd_soc_update_bits(codec, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM,
+	snd_soc_component_update_bits(component, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM,
 			ear_cmv);
 
 	return 0;
@@ -2040,7 +2040,7 @@ static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
 				unsigned int delay)
 {
 	unsigned int mask, val;
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	mask = BIT(AB8500_DIGIFCONF2_IF0DEL);
 	val = 0;
@@ -2052,21 +2052,21 @@ static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
 		val |= BIT(AB8500_DIGIFCONF2_IF0DEL);
 		break;
 	default:
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: Unsupported bit-delay (0x%x)!\n",
 			__func__, delay);
 		return -EINVAL;
 	}
 
-	dev_dbg(dai->codec->dev, "%s: IF0 Bit-delay: %d bits.\n",
+	dev_dbg(dai->component->dev, "%s: IF0 Bit-delay: %d bits.\n",
 		__func__, delay);
-	snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
+	snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
 
 	return 0;
 }
 
 /* Gates clocking according format mask */
-static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec,
+static int ab8500_codec_set_dai_clock_gate(struct snd_soc_component *component,
 					unsigned int fmt)
 {
 	unsigned int mask;
@@ -2079,22 +2079,22 @@ static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec,
 
 	switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
 	case SND_SOC_DAIFMT_CONT: /* continuous clock */
-		dev_dbg(codec->dev, "%s: IF0 Clock is continuous.\n",
+		dev_dbg(component->dev, "%s: IF0 Clock is continuous.\n",
 			__func__);
 		val |= BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
 		break;
 	case SND_SOC_DAIFMT_GATED: /* clock is gated */
-		dev_dbg(codec->dev, "%s: IF0 Clock is gated.\n",
+		dev_dbg(component->dev, "%s: IF0 Clock is gated.\n",
 			__func__);
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"%s: ERROR: Unsupported clock mask (0x%x)!\n",
 			__func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
+	snd_soc_component_update_bits(component, AB8500_DIGIFCONF1, mask, val);
 
 	return 0;
 }
@@ -2103,10 +2103,10 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
 	unsigned int mask;
 	unsigned int val;
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int status;
 
-	dev_dbg(codec->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt);
+	dev_dbg(component->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt);
 
 	mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) |
 			BIT(AB8500_DIGIFCONF3_IF1CLKTOIF0CLK) |
@@ -2116,32 +2116,32 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: IF0 Master-mode: AB8500 master.\n", __func__);
 		val |= BIT(AB8500_DIGIFCONF3_IF0MASTER);
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: IF0 Master-mode: AB8500 slave.\n", __func__);
 		break;
 	case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */
 	case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: The device is either a master or a slave.\n",
 			__func__);
 	default:
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: Unsupporter master mask 0x%x\n",
 			__func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val);
+	snd_soc_component_update_bits(component, AB8500_DIGIFCONF3, mask, val);
 
 	/* Set clock gating */
-	status = ab8500_codec_set_dai_clock_gate(codec, fmt);
+	status = ab8500_codec_set_dai_clock_gate(component, fmt);
 	if (status) {
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: Failed to set clock gate (%d).\n",
 			__func__, status);
 		return status;
@@ -2157,27 +2157,27 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S: /* I2S mode */
-		dev_dbg(dai->codec->dev, "%s: IF0 Protocol: I2S\n", __func__);
+		dev_dbg(dai->component->dev, "%s: IF0 Protocol: I2S\n", __func__);
 		val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1);
 		ab8500_audio_set_bit_delay(dai, 0);
 		break;
 
 	case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: IF0 Protocol: DSP A (TDM)\n", __func__);
 		val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
 		ab8500_audio_set_bit_delay(dai, 1);
 		break;
 
 	case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: IF0 Protocol: DSP B (TDM)\n", __func__);
 		val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
 		ab8500_audio_set_bit_delay(dai, 0);
 		break;
 
 	default:
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: Unsupported format (0x%x)!\n",
 			__func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 		return -EINVAL;
@@ -2185,37 +2185,37 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 	case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: IF0: Normal bit clock, normal frame\n",
 			__func__);
 		break;
 	case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: IF0: Normal bit clock, inverted frame\n",
 			__func__);
 		val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
 		break;
 	case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: IF0: Inverted bit clock, normal frame\n",
 			__func__);
 		val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
 		break;
 	case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: IF0: Inverted bit clock, inverted frame\n",
 			__func__);
 		val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
 		val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
 		break;
 	default:
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: Unsupported INV mask 0x%x\n",
 			__func__, fmt & SND_SOC_DAIFMT_INV_MASK);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
+	snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
 
 	return 0;
 }
@@ -2224,7 +2224,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
 		unsigned int tx_mask, unsigned int rx_mask,
 		int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val, mask, slot, slots_active;
 
 	mask = BIT(AB8500_DIGIFCONF2_IF0WL0) |
@@ -2245,17 +2245,17 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
 			BIT(AB8500_DIGIFCONF2_IF0WL0);
 		break;
 	default:
-		dev_err(dai->codec->dev, "%s: Unsupported slot-width 0x%x\n",
+		dev_err(dai->component->dev, "%s: Unsupported slot-width 0x%x\n",
 			__func__, slot_width);
 		return -EINVAL;
 	}
 
-	dev_dbg(dai->codec->dev, "%s: IF0 slot-width: %d bits.\n",
+	dev_dbg(dai->component->dev, "%s: IF0 slot-width: %d bits.\n",
 		__func__, slot_width);
-	snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
+	snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
 
 	/* Setup TDM clocking according to slot count */
-	dev_dbg(dai->codec->dev, "%s: Slots, total: %d\n", __func__, slots);
+	dev_dbg(dai->component->dev, "%s: Slots, total: %d\n", __func__, slots);
 	mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
 			BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
 	switch (slots) {
@@ -2273,12 +2273,12 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
 			BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
 		break;
 	default:
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: Unsupported number of slots (%d)!\n",
 			__func__, slots);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
+	snd_soc_component_update_bits(component, AB8500_DIGIFCONF1, mask, val);
 
 	/* Setup TDM DA according to active tx slots */
 
@@ -2289,7 +2289,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
 	tx_mask = tx_mask << AB8500_DA_DATA0_OFFSET;
 	slots_active = hweight32(tx_mask);
 
-	dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__,
+	dev_dbg(dai->component->dev, "%s: Slots, active, TX: %d\n", __func__,
 		slots_active);
 
 	switch (slots_active) {
@@ -2297,26 +2297,26 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
 		break;
 	case 1:
 		slot = ffs(tx_mask);
-		snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
-		snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
-		snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
-		snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
+		snd_soc_component_update_bits(component, AB8500_DASLOTCONF1, mask, slot);
+		snd_soc_component_update_bits(component, AB8500_DASLOTCONF3, mask, slot);
+		snd_soc_component_update_bits(component, AB8500_DASLOTCONF2, mask, slot);
+		snd_soc_component_update_bits(component, AB8500_DASLOTCONF4, mask, slot);
 		break;
 	case 2:
 		slot = ffs(tx_mask);
-		snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
-		snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
+		snd_soc_component_update_bits(component, AB8500_DASLOTCONF1, mask, slot);
+		snd_soc_component_update_bits(component, AB8500_DASLOTCONF3, mask, slot);
 		slot = fls(tx_mask);
-		snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
-		snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
+		snd_soc_component_update_bits(component, AB8500_DASLOTCONF2, mask, slot);
+		snd_soc_component_update_bits(component, AB8500_DASLOTCONF4, mask, slot);
 		break;
 	case 8:
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: In 8-channel mode DA-from-slot mapping is set manually.",
 			__func__);
 		break;
 	default:
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: Unsupported number of active TX-slots (%d)!\n",
 			__func__, slots_active);
 		return -EINVAL;
@@ -2330,7 +2330,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
 	rx_mask = rx_mask << AB8500_AD_DATA0_OFFSET;
 	slots_active = hweight32(rx_mask);
 
-	dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__,
+	dev_dbg(dai->component->dev, "%s: Slots, active, RX: %d\n", __func__,
 		slots_active);
 
 	switch (slots_active) {
@@ -2338,29 +2338,29 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
 		break;
 	case 1:
 		slot = ffs(rx_mask);
-		snd_soc_update_bits(codec, AB8500_ADSLOTSEL(slot),
+		snd_soc_component_update_bits(component, AB8500_ADSLOTSEL(slot),
 				AB8500_MASK_SLOT(slot),
 				AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
 		break;
 	case 2:
 		slot = ffs(rx_mask);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 				AB8500_ADSLOTSEL(slot),
 				AB8500_MASK_SLOT(slot),
 				AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
 		slot = fls(rx_mask);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 				AB8500_ADSLOTSEL(slot),
 				AB8500_MASK_SLOT(slot),
 				AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT2, slot));
 		break;
 	case 8:
-		dev_dbg(dai->codec->dev,
+		dev_dbg(dai->component->dev,
 			"%s: In 8-channel mode AD-to-slot mapping is set manually.",
 			__func__);
 		break;
 	default:
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: Unsupported number of active RX-slots (%d)!\n",
 			__func__, slots_active);
 		return -EINVAL;
@@ -2458,10 +2458,10 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
 	}
 }
 
-static int ab8500_codec_probe(struct snd_soc_codec *codec)
+static int ab8500_codec_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct device *dev = codec->dev;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct device *dev = component->dev;
 	struct device_node *np = dev->of_node;
 	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
 	struct ab8500_codec_platform_data codec_pdata;
@@ -2472,19 +2472,19 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
 
 	ab8500_codec_of_probe(dev, np, &codec_pdata);
 
-	status = ab8500_audio_setup_mics(codec, &codec_pdata.amics);
+	status = ab8500_audio_setup_mics(component, &codec_pdata.amics);
 	if (status < 0) {
 		pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
 		return status;
 	}
-	status = ab8500_audio_set_ear_cmv(codec, codec_pdata.ear_cmv);
+	status = ab8500_audio_set_ear_cmv(component, codec_pdata.ear_cmv);
 	if (status < 0) {
 		pr_err("%s: Failed to set earpiece CM-voltage (%d)!\n",
 			__func__, status);
 		return status;
 	}
 
-	status = ab8500_audio_init_audioblock(codec);
+	status = ab8500_audio_init_audioblock(component);
 	if (status < 0) {
 		dev_err(dev, "%s: failed to init audio-block (%d)!\n",
 			__func__, status);
@@ -2492,13 +2492,13 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
 	}
 
 	/* Override HW-defaults */
-	snd_soc_write(codec, AB8500_ANACONF5,
+	snd_soc_component_write(component, AB8500_ANACONF5,
 		      BIT(AB8500_ANACONF5_HSAUTOEN));
-	snd_soc_write(codec, AB8500_SHORTCIRCONF,
+	snd_soc_component_write(component, AB8500_SHORTCIRCONF,
 		      BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
 
 	/* Add filter controls */
-	status = snd_soc_add_codec_controls(codec, ab8500_filter_controls,
+	status = snd_soc_add_component_controls(component, ab8500_filter_controls,
 				ARRAY_SIZE(ab8500_filter_controls));
 	if (status < 0) {
 		dev_err(dev,
@@ -2523,16 +2523,18 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
 	return status;
 }
 
-static const struct snd_soc_codec_driver ab8500_codec_driver = {
-	.probe =		ab8500_codec_probe,
-	.component_driver = {
-		.controls =		ab8500_ctrls,
-		.num_controls =		ARRAY_SIZE(ab8500_ctrls),
-		.dapm_widgets =		ab8500_dapm_widgets,
-		.num_dapm_widgets =	ARRAY_SIZE(ab8500_dapm_widgets),
-		.dapm_routes =		ab8500_dapm_routes,
-		.num_dapm_routes =	ARRAY_SIZE(ab8500_dapm_routes),
-	},
+static const struct snd_soc_component_driver ab8500_component_driver = {
+	.probe			= ab8500_codec_probe,
+	.controls		= ab8500_ctrls,
+	.num_controls		= ARRAY_SIZE(ab8500_ctrls),
+	.dapm_widgets		= ab8500_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ab8500_dapm_widgets),
+	.dapm_routes		= ab8500_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ab8500_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ab8500_codec_driver_probe(struct platform_device *pdev)
@@ -2561,7 +2563,8 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
 	}
 
 	dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__);
-	status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver,
+	status = devm_snd_soc_register_component(&pdev->dev,
+				&ab8500_component_driver,
 				ab8500_codec_dai,
 				ARRAY_SIZE(ab8500_codec_dai));
 	if (status < 0)
@@ -2572,21 +2575,11 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
 	return status;
 }
 
-static int ab8500_codec_driver_remove(struct platform_device *pdev)
-{
-	dev_dbg(&pdev->dev, "%s Enter.\n", __func__);
-
-	snd_soc_unregister_codec(&pdev->dev);
-
-	return 0;
-}
-
 static struct platform_driver ab8500_codec_platform_driver = {
 	.driver	= {
 		.name	= "ab8500-codec",
 	},
 	.probe		= ab8500_codec_driver_probe,
-	.remove		= ab8500_codec_driver_remove,
 };
 module_platform_driver(ab8500_codec_platform_driver);
 
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 440b4ce..02b4d01 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -36,8 +36,8 @@ static const struct snd_soc_dapm_route ac97_routes[] = {
 static int ac97_prepare(struct snd_pcm_substream *substream,
 			struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
 	int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
 		  AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
@@ -65,7 +65,7 @@ static struct snd_soc_dai_driver ac97_dai = {
 	.ops = &ac97_dai_ops,
 };
 
-static int ac97_soc_probe(struct snd_soc_codec *codec)
+static int ac97_soc_probe(struct snd_soc_component *component)
 {
 	struct snd_ac97 *ac97;
 	struct snd_ac97_bus *ac97_bus;
@@ -73,7 +73,7 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
 	int ret;
 
 	/* add codec as bus device for standard ac97 */
-	ret = snd_ac97_bus(codec->component.card->snd_card, 0, soc_ac97_ops,
+	ret = snd_ac97_bus(component->card->snd_card, 0, soc_ac97_ops,
 			   NULL, &ac97_bus);
 	if (ret < 0)
 		return ret;
@@ -83,25 +83,25 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
 	if (ret < 0)
 		return ret;
 
-	snd_soc_codec_set_drvdata(codec, ac97);
+	snd_soc_component_set_drvdata(component, ac97);
 
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int ac97_soc_suspend(struct snd_soc_codec *codec)
+static int ac97_soc_suspend(struct snd_soc_component *component)
 {
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
 	snd_ac97_suspend(ac97);
 
 	return 0;
 }
 
-static int ac97_soc_resume(struct snd_soc_codec *codec)
+static int ac97_soc_resume(struct snd_soc_component *component)
 {
 
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
 	snd_ac97_resume(ac97);
 
@@ -112,28 +112,28 @@ static int ac97_soc_resume(struct snd_soc_codec *codec)
 #define ac97_soc_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_ac97 = {
-	.probe = 	ac97_soc_probe,
-	.suspend =	ac97_soc_suspend,
-	.resume =	ac97_soc_resume,
-
-	.component_driver = {
-		.dapm_widgets		= ac97_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ac97_widgets),
-		.dapm_routes		= ac97_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ac97_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ac97 = {
+	.probe			= ac97_soc_probe,
+	.suspend		= ac97_soc_suspend,
+	.resume			= ac97_soc_resume,
+	.dapm_widgets		= ac97_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ac97_widgets),
+	.dapm_routes		= ac97_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ac97_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ac97_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_ac97, &ac97_dai, 1);
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_ac97, &ac97_dai, 1);
 }
 
 static int ac97_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index d0361ca..ada663b 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -164,7 +164,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params,
 		struct snd_soc_dai *dai)
 {
-	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(dai->codec);
+	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(dai->component);
 	int word_len = 0;
 
 	/* bit size */
@@ -228,17 +228,17 @@ static struct snd_soc_dai_driver ad183x_dais[] = {
 };
 
 #ifdef CONFIG_PM
-static int ad1836_suspend(struct snd_soc_codec *codec)
+static int ad1836_suspend(struct snd_soc_component *component)
 {
-	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
 	/* reset clock control mode */
 	return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
 		AD1836_ADC_SERFMT_MASK, 0);
 }
 
-static int ad1836_resume(struct snd_soc_codec *codec)
+static int ad1836_resume(struct snd_soc_component *component)
 {
-	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
 	/* restore clock control mode */
 	return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
 		AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
@@ -248,10 +248,10 @@ static int ad1836_resume(struct snd_soc_codec *codec)
 #define ad1836_resume  NULL
 #endif
 
-static int ad1836_probe(struct snd_soc_codec *codec)
+static int ad1836_probe(struct snd_soc_component *component)
 {
-	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int num_dacs, num_adcs;
 	int ret = 0;
 	int i;
@@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 	if (ad1836->type == AD1836) {
 		/* left/right diff:PGA/MUX */
 		regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x3A);
-		ret = snd_soc_add_codec_controls(codec, ad1836_controls,
+		ret = snd_soc_add_component_controls(component, ad1836_controls,
 				ARRAY_SIZE(ad1836_controls));
 		if (ret)
 			return ret;
@@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 		regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x00);
 	}
 
-	ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
+	ret = snd_soc_add_component_controls(component, ad183x_dac_controls, num_dacs * 2);
 	if (ret)
 		return ret;
 
-	ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs);
+	ret = snd_soc_add_component_controls(component, ad183x_adc_controls, num_adcs);
 	if (ret)
 		return ret;
 
@@ -313,28 +313,29 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 }
 
 /* power down chip */
-static int ad1836_remove(struct snd_soc_codec *codec)
+static void ad1836_remove(struct snd_soc_component *component)
 {
-	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
 	/* reset clock control mode */
-	return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
+	regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
 		AD1836_ADC_SERFMT_MASK, 0);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
-	.probe = ad1836_probe,
-	.remove = ad1836_remove,
-	.suspend = ad1836_suspend,
-	.resume = ad1836_resume,
-
-	.component_driver = {
-		.controls		= ad183x_controls,
-		.num_controls		= ARRAY_SIZE(ad183x_controls),
-		.dapm_widgets		= ad183x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ad183x_dapm_widgets),
-		.dapm_routes		= ad183x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ad183x_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ad1836 = {
+	.probe			= ad1836_probe,
+	.remove			= ad1836_remove,
+	.suspend		= ad1836_suspend,
+	.resume			= ad1836_resume,
+	.controls		= ad183x_controls,
+	.num_controls		= ARRAY_SIZE(ad183x_controls),
+	.dapm_widgets		= ad183x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ad183x_dapm_widgets),
+	.dapm_routes		= ad183x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ad183x_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct reg_default ad1836_reg_defaults[] = {
@@ -382,17 +383,11 @@ static int ad1836_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, ad1836);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_ad1836, &ad183x_dais[ad1836->type], 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_ad1836, &ad183x_dais[ad1836->type], 1);
 	return ret;
 }
 
-static int ad1836_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static const struct spi_device_id ad1836_ids[] = {
 	{ "ad1835", AD1835 },
 	{ "ad1836", AD1836 },
@@ -408,7 +403,6 @@ static struct spi_driver ad1836_spi_driver = {
 		.name	= "ad1836",
 	},
 	.probe		= ad1836_spi_probe,
-	.remove		= ad1836_spi_remove,
 	.id_table	= ad1836_ids,
 };
 
diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c
index 1713136..b9551334 100644
--- a/sound/soc/codecs/ad193x-i2c.c
+++ b/sound/soc/codecs/ad193x-i2c.c
@@ -35,18 +35,11 @@ static int ad193x_i2c_probe(struct i2c_client *client,
 			    (enum ad193x_type)id->driver_data);
 }
 
-static int ad193x_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static struct i2c_driver ad193x_i2c_driver = {
 	.driver = {
 		.name = "ad193x",
 	},
 	.probe    = ad193x_i2c_probe,
-	.remove   = ad193x_i2c_remove,
 	.id_table = ad193x_id,
 };
 module_i2c_driver(ad193x_i2c_driver);
diff --git a/sound/soc/codecs/ad193x-spi.c b/sound/soc/codecs/ad193x-spi.c
index 23c2857..3c1394a 100644
--- a/sound/soc/codecs/ad193x-spi.c
+++ b/sound/soc/codecs/ad193x-spi.c
@@ -29,12 +29,6 @@ static int ad193x_spi_probe(struct spi_device *spi)
 			    (enum ad193x_type)id->driver_data);
 }
 
-static int ad193x_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static const struct spi_device_id ad193x_spi_id[] = {
 	{ "ad193x", AD193X },
 	{ "ad1933", AD1933 },
@@ -51,7 +45,6 @@ static struct spi_driver ad193x_spi_driver = {
 		.name	= "ad193x",
 	},
 	.probe		= ad193x_spi_probe,
-	.remove		= ad193x_spi_remove,
 	.id_table	= ad193x_spi_id,
 };
 module_spi_driver(ad193x_spi_driver);
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index d10988e..4b60ebe 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -130,7 +130,7 @@ static inline bool ad193x_has_adc(const struct ad193x_priv *ad193x)
 
 static int ad193x_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
+	struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
 
 	if (mute)
 		regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
@@ -146,7 +146,7 @@ static int ad193x_mute(struct snd_soc_dai *dai, int mute)
 static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			       unsigned int rx_mask, int slots, int width)
 {
-	struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
+	struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
 	unsigned int channels;
 
 	switch (slots) {
@@ -179,7 +179,7 @@ static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec_dai->codec);
+	struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(codec_dai->component);
 	unsigned int adc_serfmt = 0;
 	unsigned int adc_fmt = 0;
 	unsigned int dac_fmt = 0;
@@ -257,8 +257,8 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
 	switch (freq) {
 	case 12288000:
 	case 18432000:
@@ -275,8 +275,8 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 {
 	int word_len = 0, master_rate = 0;
-	struct snd_soc_codec *codec = dai->codec;
-	struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
 
 	/* bit size */
 	switch (params_width(params)) {
@@ -351,10 +351,10 @@ static struct snd_soc_dai_driver ad193x_dai = {
 	.ops = &ad193x_dai_ops,
 };
 
-static int ad193x_codec_probe(struct snd_soc_codec *codec)
+static int ad193x_component_probe(struct snd_soc_component *component)
 {
-	struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int num, ret;
 
 	/* default setting for ad193x */
@@ -382,7 +382,7 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
 	if (ad193x_has_adc(ad193x)) {
 		/* add adc controls */
 		num = ARRAY_SIZE(ad193x_adc_snd_controls);
-		ret = snd_soc_add_codec_controls(codec,
+		ret = snd_soc_add_component_controls(component,
 						 ad193x_adc_snd_controls,
 						 num);
 		if (ret)
@@ -408,16 +408,18 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ad193x = {
-	.probe = ad193x_codec_probe,
-	.component_driver = {
-		.controls		= ad193x_snd_controls,
-		.num_controls		= ARRAY_SIZE(ad193x_snd_controls),
-		.dapm_widgets		= ad193x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ad193x_dapm_widgets),
-		.dapm_routes		= audio_paths,
-		.num_dapm_routes	= ARRAY_SIZE(audio_paths),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ad193x = {
+	.probe			= ad193x_component_probe,
+	.controls		= ad193x_snd_controls,
+	.num_controls		= ARRAY_SIZE(ad193x_snd_controls),
+	.dapm_widgets		= ad193x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ad193x_dapm_widgets),
+	.dapm_routes		= audio_paths,
+	.num_dapm_routes	= ARRAY_SIZE(audio_paths),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 const struct regmap_config ad193x_regmap_config = {
@@ -442,7 +444,7 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
 
 	dev_set_drvdata(dev, ad193x);
 
-	return snd_soc_register_codec(dev, &soc_codec_dev_ad193x,
+	return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
 		&ad193x_dai, 1);
 }
 EXPORT_SYMBOL_GPL(ad193x_probe);
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index ce89bfb..16dab3f 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -205,9 +205,9 @@ static struct snd_soc_dai_driver ad1980_dai = {
 #define AD1980_VENDOR_ID 0x41445300
 #define AD1980_VENDOR_MASK 0xffffff00
 
-static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
+static int ad1980_reset(struct snd_soc_component *component, int try_warm)
 {
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 	unsigned int retry_cnt = 0;
 	int ret;
 
@@ -223,16 +223,16 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
 		 * case the first nibble of data is eaten by the addr. (Tag is
 		 * always 16 bit)
 		 */
-		snd_soc_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
+		snd_soc_component_write(component, AC97_AD_SERIAL_CFG, 0x9900);
 
 	} while (retry_cnt++ < 10);
 
-	dev_err(codec->dev, "Failed to reset: AC97 link error\n");
+	dev_err(component->dev, "Failed to reset: AC97 link error\n");
 
 	return -EIO;
 }
 
-static int ad1980_soc_probe(struct snd_soc_codec *codec)
+static int ad1980_soc_probe(struct snd_soc_component *component)
 {
 	struct snd_ac97 *ac97;
 	struct regmap *regmap;
@@ -240,10 +240,10 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
 	u16 vendor_id2;
 	u16 ext_status;
 
-	ac97 = snd_soc_new_ac97_codec(codec, 0, 0);
+	ac97 = snd_soc_new_ac97_component(component, 0, 0);
 	if (IS_ERR(ac97)) {
 		ret = PTR_ERR(ac97);
-		dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
+		dev_err(component->dev, "Failed to register AC97 component: %d\n", ret);
 		return ret;
 	}
 
@@ -253,72 +253,66 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
 		goto err_free_ac97;
 	}
 
-	snd_soc_codec_init_regmap(codec, regmap);
-	snd_soc_codec_set_drvdata(codec, ac97);
+	snd_soc_component_init_regmap(component, regmap);
+	snd_soc_component_set_drvdata(component, ac97);
 
-	ret = ad1980_reset(codec, 0);
+	ret = ad1980_reset(component, 0);
 	if (ret < 0)
 		goto reset_err;
 
-	vendor_id2 = snd_soc_read(codec, AC97_VENDOR_ID2);
+	vendor_id2 = snd_soc_component_read32(component, AC97_VENDOR_ID2);
 	if (vendor_id2 == 0x5374) {
-		dev_warn(codec->dev,
+		dev_warn(component->dev,
 			"Found AD1981 - only 2/2 IN/OUT Channels supported\n");
 	}
 
 	/* unmute captures and playbacks volume */
-	snd_soc_write(codec, AC97_MASTER, 0x0000);
-	snd_soc_write(codec, AC97_PCM, 0x0000);
-	snd_soc_write(codec, AC97_REC_GAIN, 0x0000);
-	snd_soc_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
-	snd_soc_write(codec, AC97_SURROUND_MASTER, 0x0000);
+	snd_soc_component_write(component, AC97_MASTER, 0x0000);
+	snd_soc_component_write(component, AC97_PCM, 0x0000);
+	snd_soc_component_write(component, AC97_REC_GAIN, 0x0000);
+	snd_soc_component_write(component, AC97_CENTER_LFE_MASTER, 0x0000);
+	snd_soc_component_write(component, AC97_SURROUND_MASTER, 0x0000);
 
 	/*power on LFE/CENTER/Surround DACs*/
-	ext_status = snd_soc_read(codec, AC97_EXTENDED_STATUS);
-	snd_soc_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
+	ext_status = snd_soc_component_read32(component, AC97_EXTENDED_STATUS);
+	snd_soc_component_write(component, AC97_EXTENDED_STATUS, ext_status&~0x3800);
 
 	return 0;
 
 reset_err:
-	snd_soc_codec_exit_regmap(codec);
+	snd_soc_component_exit_regmap(component);
 err_free_ac97:
-	snd_soc_free_ac97_codec(ac97);
+	snd_soc_free_ac97_component(ac97);
 	return ret;
 }
 
-static int ad1980_soc_remove(struct snd_soc_codec *codec)
+static void ad1980_soc_remove(struct snd_soc_component *component)
 {
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
-	snd_soc_codec_exit_regmap(codec);
-	snd_soc_free_ac97_codec(ac97);
-	return 0;
+	snd_soc_component_exit_regmap(component);
+	snd_soc_free_ac97_component(ac97);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
-	.probe = 	ad1980_soc_probe,
-	.remove = 	ad1980_soc_remove,
-
-	.component_driver = {
-		.controls		= ad1980_snd_ac97_controls,
-		.num_controls		= ARRAY_SIZE(ad1980_snd_ac97_controls),
-		.dapm_widgets		= ad1980_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ad1980_dapm_widgets),
-		.dapm_routes		= ad1980_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ad1980_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ad1980 = {
+	.probe			= ad1980_soc_probe,
+	.remove			= ad1980_soc_remove,
+	.controls		= ad1980_snd_ac97_controls,
+	.num_controls		= ARRAY_SIZE(ad1980_snd_ac97_controls),
+	.dapm_widgets		= ad1980_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ad1980_dapm_widgets),
+	.dapm_routes		= ad1980_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ad1980_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ad1980_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_ad1980, &ad1980_dai, 1);
-}
-
-static int ad1980_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_ad1980, &ad1980_dai, 1);
 }
 
 static struct platform_driver ad1980_codec_driver = {
@@ -327,7 +321,6 @@ static struct platform_driver ad1980_codec_driver = {
 	},
 
 	.probe = ad1980_probe,
-	.remove = ad1980_remove,
 };
 
 module_platform_driver(ad1980_codec_driver);
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index d8d86a0..03ee571 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -54,25 +54,21 @@ static struct snd_soc_dai_driver ad73311_dai = {
 		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ad73311 = {
-	.component_driver = {
-		.dapm_widgets		= ad73311_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ad73311_dapm_widgets),
-		.dapm_routes		= ad73311_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ad73311_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ad73311 = {
+	.dapm_widgets		= ad73311_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ad73311_dapm_widgets),
+	.dapm_routes		= ad73311_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ad73311_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ad73311_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_ad73311, &ad73311_dai, 1);
-}
-
-static int ad73311_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_ad73311, &ad73311_dai, 1);
 }
 
 static struct platform_driver ad73311_codec_driver = {
@@ -81,7 +77,6 @@ static struct platform_driver ad73311_codec_driver = {
 	},
 
 	.probe = ad73311_probe,
-	.remove = ad73311_remove,
 };
 
 module_platform_driver(ad73311_codec_driver);
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index a865945..f22ff9f 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -549,8 +549,8 @@ static const struct snd_kcontrol_new adau1373_drc_controls[] = {
 static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 	unsigned int pll_id = w->name[3] - '1';
 	unsigned int val;
 
@@ -821,8 +821,8 @@ static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = {
 static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
 	struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 	unsigned int dai;
 	const char *clk;
 
@@ -842,8 +842,8 @@ static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
 static int adau1373_check_src(struct snd_soc_dapm_widget *source,
 	struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 	unsigned int dai;
 
 	dai = sink->name[3] - '1';
@@ -1031,8 +1031,8 @@ static const struct snd_soc_dapm_route adau1373_dapm_routes[] = {
 static int adau1373_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 	struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
 	unsigned int div;
 	unsigned int freq;
@@ -1098,8 +1098,8 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream,
 
 static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 	struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
 	unsigned int ctrl;
 
@@ -1158,7 +1158,7 @@ static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
 	int clk_id, unsigned int freq, int dir)
 {
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(dai->component);
 	struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
 
 	switch (clk_id) {
@@ -1250,10 +1250,10 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = {
 	},
 };
 
-static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
+static int adau1373_set_pll(struct snd_soc_component *component, int pll_id,
 	int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 	unsigned int dpll_div = 0;
 	uint8_t pll_regs[5];
 	int ret;
@@ -1348,10 +1348,10 @@ static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
 	return false;
 }
 
-static int adau1373_probe(struct snd_soc_codec *codec)
+static int adau1373_probe(struct snd_soc_component *component)
 {
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
-	struct adau1373_platform_data *pdata = codec->dev->platform_data;
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
+	struct adau1373_platform_data *pdata = component->dev->platform_data;
 	bool lineout_differential = false;
 	unsigned int val;
 	int i;
@@ -1369,7 +1369,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
 				pdata->drc_setting[i]);
 		}
 
-		snd_soc_add_codec_controls(codec, adau1373_drc_controls,
+		snd_soc_add_component_controls(component, adau1373_drc_controls,
 			pdata->num_drc);
 
 		val = 0;
@@ -1394,7 +1394,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
 	}
 
 	if (!lineout_differential) {
-		snd_soc_add_codec_controls(codec, adau1373_lineout2_controls,
+		snd_soc_add_component_controls(component, adau1373_lineout2_controls,
 			ARRAY_SIZE(adau1373_lineout2_controls));
 	}
 
@@ -1404,10 +1404,10 @@ static int adau1373_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int adau1373_set_bias_level(struct snd_soc_codec *codec,
+static int adau1373_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -1426,9 +1426,9 @@ static int adau1373_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int adau1373_resume(struct snd_soc_codec *codec)
+static int adau1373_resume(struct snd_soc_component *component)
 {
-	struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+	struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 
 	regcache_sync(adau1373->regmap);
 
@@ -1458,22 +1458,20 @@ static const struct regmap_config adau1373_regmap_config = {
 	.num_reg_defaults = ARRAY_SIZE(adau1373_reg_defaults),
 };
 
-static const struct snd_soc_codec_driver adau1373_codec_driver = {
-	.probe =	adau1373_probe,
-	.resume =	adau1373_resume,
-	.set_bias_level = adau1373_set_bias_level,
-	.idle_bias_off = true,
-
-	.set_pll = adau1373_set_pll,
-
-	.component_driver = {
-		.controls		= adau1373_controls,
-		.num_controls		= ARRAY_SIZE(adau1373_controls),
-		.dapm_widgets		= adau1373_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(adau1373_dapm_widgets),
-		.dapm_routes		= adau1373_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(adau1373_dapm_routes),
-	},
+static const struct snd_soc_component_driver adau1373_component_driver = {
+	.probe			= adau1373_probe,
+	.resume			= adau1373_resume,
+	.set_bias_level		= adau1373_set_bias_level,
+	.set_pll		= adau1373_set_pll,
+	.controls		= adau1373_controls,
+	.num_controls		= ARRAY_SIZE(adau1373_controls),
+	.dapm_widgets		= adau1373_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(adau1373_dapm_widgets),
+	.dapm_routes		= adau1373_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(adau1373_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int adau1373_i2c_probe(struct i2c_client *client,
@@ -1495,17 +1493,12 @@ static int adau1373_i2c_probe(struct i2c_client *client,
 
 	dev_set_drvdata(&client->dev, adau1373);
 
-	ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,
+	ret = devm_snd_soc_register_component(&client->dev,
+			&adau1373_component_driver,
 			adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
 	return ret;
 }
 
-static int adau1373_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id adau1373_i2c_id[] = {
 	{ "adau1373", 0 },
 	{ }
@@ -1517,7 +1510,6 @@ static struct i2c_driver adau1373_i2c_driver = {
 		.name = "adau1373",
 	},
 	.probe = adau1373_i2c_probe,
-	.remove = adau1373_i2c_remove,
 	.id_table = adau1373_i2c_id,
 };
 
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 805afac..b5a6174 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -298,10 +298,10 @@ static const struct sigmadsp_ops adau1701_sigmadsp_ops = {
 	.safeload = adau1701_safeload,
 };
 
-static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv,
+static int adau1701_reset(struct snd_soc_component *component, unsigned int clkdiv,
 	unsigned int rate)
 {
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	sigmadsp_reset(adau1701->sigmadsp);
@@ -348,7 +348,7 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv,
 	if (clkdiv != ADAU1707_CLKDIV_UNSET) {
 		ret = sigmadsp_setup(adau1701->sigmadsp, rate);
 		if (ret) {
-			dev_warn(codec->dev, "Failed to load firmware\n");
+			dev_warn(component->dev, "Failed to load firmware\n");
 			return ret;
 		}
 	}
@@ -362,10 +362,10 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv,
 	return 0;
 }
 
-static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
+static int adau1701_set_capture_pcm_format(struct snd_soc_component *component,
 					   struct snd_pcm_hw_params *params)
 {
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 	unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
 	unsigned int val;
 
@@ -403,10 +403,10 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
+static int adau1701_set_playback_pcm_format(struct snd_soc_component *component,
 					    struct snd_pcm_hw_params *params)
 {
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
@@ -435,8 +435,8 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
 static int adau1701_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 	unsigned int clkdiv = adau1701->sysclk / params_rate(params);
 	unsigned int val;
 	int ret;
@@ -447,7 +447,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
 	 * firmware upload.
 	 */
 	if (clkdiv != adau1701->pll_clkdiv) {
-		ret = adau1701_reset(codec, clkdiv, params_rate(params));
+		ret = adau1701_reset(component, clkdiv, params_rate(params));
 		if (ret < 0)
 			return ret;
 	}
@@ -470,16 +470,16 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
 		ADAU1701_DSPCTRL_SR_MASK, val);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		return adau1701_set_playback_pcm_format(codec, params);
+		return adau1701_set_playback_pcm_format(component, params);
 	else
-		return adau1701_set_capture_pcm_format(codec, params);
+		return adau1701_set_capture_pcm_format(component, params);
 }
 
 static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 	unsigned int serictl = 0x00, seroctl = 0x00;
 	bool invert_lrclk;
 
@@ -548,11 +548,11 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-static int adau1701_set_bias_level(struct snd_soc_codec *codec,
+static int adau1701_set_bias_level(struct snd_soc_component *component,
 		enum snd_soc_bias_level level)
 {
 	unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD;
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -576,9 +576,9 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
 
 static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int mask = ADAU1701_DSPCTRL_DAM;
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (mute)
@@ -591,11 +591,11 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
 	return 0;
 }
 
-static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int adau1701_set_sysclk(struct snd_soc_component *component, int clk_id,
 	int source, unsigned int freq, int dir)
 {
 	unsigned int val;
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case ADAU1701_CLK_SRC_OSC:
@@ -618,7 +618,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 static int adau1701_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(dai->component);
 
 	return sigmadsp_restrict_params(adau1701->sigmadsp, substream);
 }
@@ -664,20 +664,20 @@ static const struct of_device_id adau1701_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
 #endif
 
-static int adau1701_probe(struct snd_soc_codec *codec)
+static int adau1701_probe(struct snd_soc_component *component)
 {
 	int i, ret;
 	unsigned int val;
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
-	ret = sigmadsp_attach(adau1701->sigmadsp, &codec->component);
+	ret = sigmadsp_attach(adau1701->sigmadsp, component);
 	if (ret)
 		return ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
 				    adau1701->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+		dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
 		return ret;
 	}
 
@@ -690,7 +690,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 	adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
 
 	/* initalize with pre-configured pll mode settings */
-	ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0);
+	ret = adau1701_reset(component, adau1701->pll_clkdiv, 0);
 	if (ret < 0)
 		goto exit_regulators_disable;
 
@@ -715,22 +715,20 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int adau1701_remove(struct snd_soc_codec *codec)
+static void adau1701_remove(struct snd_soc_component *component)
 {
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
 	if (gpio_is_valid(adau1701->gpio_nreset))
 		gpio_set_value_cansleep(adau1701->gpio_nreset, 0);
 
 	regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int adau1701_suspend(struct snd_soc_codec *codec)
+static int adau1701_suspend(struct snd_soc_component *component)
 {
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
 	regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies),
 			       adau1701->supplies);
@@ -738,42 +736,41 @@ static int adau1701_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int adau1701_resume(struct snd_soc_codec *codec)
+static int adau1701_resume(struct snd_soc_component *component)
 {
-	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+	struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 	int ret;
 
         ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
 				    adau1701->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+		dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
 		return ret;
 	}
 
-	return adau1701_reset(codec, adau1701->pll_clkdiv, 0);
+	return adau1701_reset(component, adau1701->pll_clkdiv, 0);
 }
 #else
 #define adau1701_resume 	NULL
 #define adau1701_suspend 	NULL
 #endif /* CONFIG_PM */
 
-static const struct snd_soc_codec_driver adau1701_codec_drv = {
+static const struct snd_soc_component_driver adau1701_component_drv = {
 	.probe			= adau1701_probe,
 	.remove			= adau1701_remove,
 	.resume			= adau1701_resume,
 	.suspend		= adau1701_suspend,
 	.set_bias_level		= adau1701_set_bias_level,
-	.idle_bias_off		= true,
-
-	.component_driver = {
-		.controls		= adau1701_controls,
-		.num_controls		= ARRAY_SIZE(adau1701_controls),
-		.dapm_widgets		= adau1701_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(adau1701_dapm_widgets),
-		.dapm_routes		= adau1701_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(adau1701_dapm_routes),
-	},
+	.controls		= adau1701_controls,
+	.num_controls		= ARRAY_SIZE(adau1701_controls),
+	.dapm_widgets		= adau1701_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(adau1701_dapm_widgets),
+	.dapm_routes		= adau1701_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(adau1701_dapm_routes),
 	.set_sysclk		= adau1701_set_sysclk,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config adau1701_regmap = {
@@ -889,7 +886,8 @@ static int adau1701_i2c_probe(struct i2c_client *client,
 		goto exit_regulators_disable;
 	}
 
-	ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
+	ret = devm_snd_soc_register_component(&client->dev,
+			&adau1701_component_drv,
 			&adau1701_dai, 1);
 
 exit_regulators_disable:
@@ -898,12 +896,6 @@ static int adau1701_i2c_probe(struct i2c_client *client,
 	return ret;
 }
 
-static int adau1701_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id adau1701_i2c_id[] = {
 	{ "adau1401", 0 },
 	{ "adau1401a", 0 },
@@ -919,7 +911,6 @@ static struct i2c_driver adau1701_i2c_driver = {
 		.of_match_table	= of_match_ptr(adau1701_dt_ids),
 	},
 	.probe		= adau1701_i2c_probe,
-	.remove		= adau1701_i2c_remove,
 	.id_table	= adau1701_i2c_id,
 };
 
diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c
index 3bc3cc5..be136e9 100644
--- a/sound/soc/codecs/adau1761.c
+++ b/sound/soc/codecs/adau1761.c
@@ -255,8 +255,8 @@ static const struct snd_kcontrol_new adau1761_input_mux_control =
 static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 
 	/* After any power changes have been made the dejitter circuit
 	 * has to be reinitialized. */
@@ -445,10 +445,10 @@ static const struct snd_soc_dapm_route adau1761_dapm_routes[] = {
 	{ "Digital Clock 1", NULL, "SYSCLK" },
 };
 
-static int adau1761_set_bias_level(struct snd_soc_codec *codec,
+static int adau1761_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -460,7 +460,7 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec,
 		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
 			ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
 			ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			regcache_sync(adau->regmap);
 		break;
 	case SND_SOC_BIAS_OFF:
@@ -474,9 +474,9 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec,
 }
 
 static enum adau1761_output_mode adau1761_get_lineout_mode(
-	struct snd_soc_codec *codec)
+	struct snd_soc_component *component)
 {
-	struct adau1761_platform_data *pdata = codec->dev->platform_data;
+	struct adau1761_platform_data *pdata = component->dev->platform_data;
 
 	if (pdata)
 		return pdata->lineout_mode;
@@ -484,11 +484,11 @@ static enum adau1761_output_mode adau1761_get_lineout_mode(
 	return ADAU1761_OUTPUT_MODE_LINE;
 }
 
-static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
+static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adau1761_platform_data *pdata = codec->dev->platform_data;
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adau1761_platform_data *pdata = component->dev->platform_data;
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	enum adau1761_digmic_jackdet_pin_mode mode;
 	unsigned int val = 0;
 	int ret;
@@ -513,7 +513,7 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
 		if (pdata->jackdetect_active_low)
 			val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW;
 
-		ret = snd_soc_add_codec_controls(codec,
+		ret = snd_soc_add_component_controls(component,
 			adau1761_jack_detect_controls,
 			ARRAY_SIZE(adau1761_jack_detect_controls));
 		if (ret)
@@ -546,11 +546,11 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
+static int adau1761_setup_headphone_mode(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
-	struct adau1761_platform_data *pdata = codec->dev->platform_data;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
+	struct adau1761_platform_data *pdata = component->dev->platform_data;
 	enum adau1761_output_mode mode;
 	int ret;
 
@@ -588,7 +588,7 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
 			adau1761_capless_dapm_routes,
 			ARRAY_SIZE(adau1761_capless_dapm_routes));
 	} else {
-		ret = snd_soc_add_codec_controls(codec, adau1761_mono_controls,
+		ret = snd_soc_add_component_controls(component, adau1761_mono_controls,
 			ARRAY_SIZE(adau1761_mono_controls));
 		if (ret)
 			return ret;
@@ -640,14 +640,14 @@ static bool adau1761_readable_register(struct device *dev, unsigned int reg)
 	return adau17x1_readable_register(dev, reg);
 }
 
-static int adau1761_codec_probe(struct snd_soc_codec *codec)
+static int adau1761_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adau1761_platform_data *pdata = codec->dev->platform_data;
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adau1761_platform_data *pdata = component->dev->platform_data;
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	ret = adau17x1_add_widgets(codec);
+	ret = adau17x1_add_widgets(component);
 	if (ret < 0)
 		return ret;
 
@@ -658,20 +658,20 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
 		regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
 			ADAU1761_DIFF_INPUT_VOL_LDEN,
 			ADAU1761_DIFF_INPUT_VOL_LDEN);
-		ret = snd_soc_add_codec_controls(codec,
+		ret = snd_soc_add_component_controls(component,
 			adau1761_differential_mode_controls,
 			ARRAY_SIZE(adau1761_differential_mode_controls));
 		if (ret)
 			return ret;
 	} else {
-		ret = snd_soc_add_codec_controls(codec,
+		ret = snd_soc_add_component_controls(component,
 			adau1761_single_mode_controls,
 			ARRAY_SIZE(adau1761_single_mode_controls));
 		if (ret)
 			return ret;
 	}
 
-	switch (adau1761_get_lineout_mode(codec)) {
+	switch (adau1761_get_lineout_mode(component)) {
 	case ADAU1761_OUTPUT_MODE_LINE:
 		break;
 	case ADAU1761_OUTPUT_MODE_HEADPHONE:
@@ -686,11 +686,11 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
 		return -EINVAL;
 	}
 
-	ret = adau1761_setup_headphone_mode(codec);
+	ret = adau1761_setup_headphone_mode(component);
 	if (ret)
 		return ret;
 
-	ret = adau1761_setup_digmic_jackdetect(codec);
+	ret = adau1761_setup_digmic_jackdetect(component);
 	if (ret)
 		return ret;
 
@@ -706,27 +706,28 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
 			return ret;
 	}
 
-	ret = adau17x1_add_routes(codec);
+	ret = adau17x1_add_routes(component);
 	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver adau1761_codec_driver = {
-	.probe = adau1761_codec_probe,
-	.resume	= adau17x1_resume,
-	.set_bias_level	= adau1761_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= adau1761_controls,
-		.num_controls		= ARRAY_SIZE(adau1761_controls),
-		.dapm_widgets		= adau1x61_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(adau1x61_dapm_widgets),
-		.dapm_routes		= adau1x61_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(adau1x61_dapm_routes),
-	},
+static const struct snd_soc_component_driver adau1761_component_driver = {
+	.probe			= adau1761_component_probe,
+	.resume			= adau17x1_resume,
+	.set_bias_level		= adau1761_set_bias_level,
+	.controls		= adau1761_controls,
+	.num_controls		= ARRAY_SIZE(adau1761_controls),
+	.dapm_widgets		= adau1x61_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(adau1x61_dapm_widgets),
+	.dapm_routes		= adau1x61_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(adau1x61_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
@@ -793,7 +794,8 @@ int adau1761_probe(struct device *dev, struct regmap *regmap,
 	 * reaches standby and the core clock is enabled */
 	regcache_cache_only(regmap, true);
 
-	return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);
+	return devm_snd_soc_register_component(dev, &adau1761_component_driver,
+					       dai_drv, 1);
 }
 EXPORT_SYMBOL_GPL(adau1761_probe);
 
diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c
index 546071c..6a66557 100644
--- a/sound/soc/codecs/adau1781.c
+++ b/sound/soc/codecs/adau1781.c
@@ -174,8 +174,8 @@ static const struct snd_kcontrol_new adau1781_mono_mixer_controls[] = {
 static int adau1781_dejitter_fixup(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 
 	/* After any power changes have been made the dejitter circuit
 	 * has to be reinitialized. */
@@ -314,10 +314,10 @@ static const struct snd_soc_dapm_route adau1781_dmic_dapm_routes[] = {
 	{ "Right Decimator", NULL, "DMIC Select" },
 };
 
-static int adau1781_set_bias_level(struct snd_soc_codec *codec,
+static int adau1781_set_bias_level(struct snd_soc_component *component,
 		enum snd_soc_bias_level level)
 {
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -380,14 +380,14 @@ static int adau1781_set_input_mode(struct adau *adau, unsigned int reg,
 		ADAU1781_INPUT_DIFFERNTIAL, val);
 }
 
-static int adau1781_codec_probe(struct snd_soc_codec *codec)
+static int adau1781_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adau1781_platform_data *pdata = dev_get_platdata(component->dev);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	ret = adau17x1_add_widgets(codec);
+	ret = adau17x1_add_widgets(component);
 	if (ret)
 		return ret;
 
@@ -419,27 +419,28 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec)
 			return ret;
 	}
 
-	ret = adau17x1_add_routes(codec);
+	ret = adau17x1_add_routes(component);
 	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver adau1781_codec_driver = {
-	.probe = adau1781_codec_probe,
-	.resume = adau17x1_resume,
-	.set_bias_level = adau1781_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= adau1781_controls,
-		.num_controls		= ARRAY_SIZE(adau1781_controls),
-		.dapm_widgets		= adau1781_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(adau1781_dapm_widgets),
-		.dapm_routes		= adau1781_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(adau1781_dapm_routes),
-	},
+static const struct snd_soc_component_driver adau1781_component_driver = {
+	.probe			= adau1781_component_probe,
+	.resume			= adau17x1_resume,
+	.set_bias_level		= adau1781_set_bias_level,
+	.controls		= adau1781_controls,
+	.num_controls		= ARRAY_SIZE(adau1781_controls),
+	.dapm_widgets		= adau1781_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(adau1781_dapm_widgets),
+	.dapm_routes		= adau1781_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(adau1781_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
@@ -498,7 +499,7 @@ int adau1781_probe(struct device *dev, struct regmap *regmap,
 	if (ret)
 		return ret;
 
-	return snd_soc_register_codec(dev, &adau1781_codec_driver,
+	return devm_snd_soc_register_component(dev, &adau1781_component_driver,
 		&adau1781_dai_driver, 1);
 }
 EXPORT_SYMBOL_GPL(adau1781_probe);
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c
index 6758f78..80c2a06 100644
--- a/sound/soc/codecs/adau17x1.c
+++ b/sound/soc/codecs/adau17x1.c
@@ -63,8 +63,8 @@ static const struct snd_kcontrol_new adau17x1_controls[] = {
 static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 
 	if (SND_SOC_DAPM_EVENT_ON(event)) {
 		adau->pll_regs[5] = 1;
@@ -93,8 +93,8 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
 static int adau17x1_adc_fixup(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 
 	/*
 	 * If we are capturing, toggle the ADOSR bit in Converter Control 0 to
@@ -177,11 +177,11 @@ static const struct snd_soc_dapm_route adau17x1_dapm_pll_route = {
 static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-	struct snd_soc_dapm_update update = { 0 };
+	struct snd_soc_dapm_update update = {};
 	unsigned int stream = e->shift_l;
 	unsigned int val, change;
 	int reg;
@@ -205,7 +205,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
 	else
 		reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;
 
-	change = snd_soc_test_bits(codec, reg, 0xff, val);
+	change = snd_soc_component_test_bits(component, reg, 0xff, val);
 	if (change) {
 		update.kcontrol = kcontrol;
 		update.mask = 0xff;
@@ -222,8 +222,8 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
 static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int stream = e->shift_l;
 	unsigned int reg, val;
@@ -328,8 +328,8 @@ EXPORT_SYMBOL_GPL(adau17x1_has_dsp);
 static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
 	int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	if (freq_in < 8000000 || freq_in > 27000000)
@@ -353,8 +353,8 @@ static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
 static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec);
-	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(dai->component);
+	struct adau *adau = snd_soc_component_get_drvdata(dai->component);
 	bool is_pll;
 	bool was_pll;
 
@@ -438,8 +438,8 @@ static int adau17x1_auto_pll(struct snd_soc_dai *dai,
 static int adau17x1_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	unsigned int val, div, dsp_div;
 	unsigned int freq;
 	int ret;
@@ -531,7 +531,7 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream,
 static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai,
 		unsigned int fmt)
 {
-	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau *adau = snd_soc_component_get_drvdata(dai->component);
 	unsigned int ctrl0, ctrl1;
 	int lrclk_pol;
 
@@ -603,7 +603,7 @@ static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai,
 static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai,
 	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau *adau = snd_soc_component_get_drvdata(dai->component);
 	unsigned int ser_ctrl0, ser_ctrl1;
 	unsigned int conv_ctrl0, conv_ctrl1;
 
@@ -728,7 +728,7 @@ static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai,
 static int adau17x1_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
-	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau *adau = snd_soc_component_get_drvdata(dai->component);
 
 	if (adau->sigmadsp)
 		return sigmadsp_restrict_params(adau->sigmadsp, substream);
@@ -746,10 +746,10 @@ const struct snd_soc_dai_ops adau17x1_dai_ops = {
 };
 EXPORT_SYMBOL_GPL(adau17x1_dai_ops);
 
-int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
+int adau17x1_set_micbias_voltage(struct snd_soc_component *component,
 	enum adau17x1_micbias_voltage micbias)
 {
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 
 	switch (micbias) {
 	case ADAU17X1_MICBIAS_0_90_AVDD:
@@ -858,13 +858,13 @@ int adau17x1_setup_firmware(struct adau *adau, unsigned int rate)
 }
 EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
 
-int adau17x1_add_widgets(struct snd_soc_codec *codec)
+int adau17x1_add_widgets(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	ret = snd_soc_add_codec_controls(codec, adau17x1_controls,
+	ret = snd_soc_add_component_controls(component, adau17x1_controls,
 		ARRAY_SIZE(adau17x1_controls));
 	if (ret)
 		return ret;
@@ -882,9 +882,9 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec)
 		if (!adau->sigmadsp)
 			return 0;
 
-		ret = sigmadsp_attach(adau->sigmadsp, &codec->component);
+		ret = sigmadsp_attach(adau->sigmadsp, component);
 		if (ret) {
-			dev_err(codec->dev, "Failed to attach firmware: %d\n",
+			dev_err(component->dev, "Failed to attach firmware: %d\n",
 				ret);
 			return ret;
 		}
@@ -894,10 +894,10 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(adau17x1_add_widgets);
 
-int adau17x1_add_routes(struct snd_soc_codec *codec)
+int adau17x1_add_routes(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = snd_soc_dapm_add_routes(dapm, adau17x1_dapm_routes,
@@ -920,12 +920,12 @@ int adau17x1_add_routes(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(adau17x1_add_routes);
 
-int adau17x1_resume(struct snd_soc_codec *codec)
+int adau17x1_resume(struct snd_soc_component *component)
 {
-	struct adau *adau = snd_soc_codec_get_drvdata(codec);
+	struct adau *adau = snd_soc_component_get_drvdata(component);
 
 	if (adau->switch_mode)
-		adau->switch_mode(codec->dev);
+		adau->switch_mode(component->dev);
 
 	regcache_sync(adau->regmap);
 
@@ -998,7 +998,6 @@ void adau17x1_remove(struct device *dev)
 {
 	struct adau *adau = dev_get_drvdata(dev);
 
-	snd_soc_unregister_codec(dev);
 	if (adau->mclk)
 		clk_disable_unprepare(adau->mclk);
 }
diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h
index eaf8f93..a7b1cb7 100644
--- a/sound/soc/codecs/adau17x1.h
+++ b/sound/soc/codecs/adau17x1.h
@@ -53,18 +53,18 @@ struct adau {
 	struct sigmadsp *sigmadsp;
 };
 
-int adau17x1_add_widgets(struct snd_soc_codec *codec);
-int adau17x1_add_routes(struct snd_soc_codec *codec);
+int adau17x1_add_widgets(struct snd_soc_component *component);
+int adau17x1_add_routes(struct snd_soc_component *component);
 int adau17x1_probe(struct device *dev, struct regmap *regmap,
 	enum adau17x1_type type, void (*switch_mode)(struct device *dev),
 	const char *firmware_name);
 void adau17x1_remove(struct device *dev);
-int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
+int adau17x1_set_micbias_voltage(struct snd_soc_component *component,
 	enum adau17x1_micbias_voltage micbias);
 bool adau17x1_readable_register(struct device *dev, unsigned int reg);
 bool adau17x1_volatile_register(struct device *dev, unsigned int reg);
 bool adau17x1_precious_register(struct device *dev, unsigned int reg);
-int adau17x1_resume(struct snd_soc_codec *codec);
+int adau17x1_resume(struct snd_soc_component *component);
 
 extern const struct snd_soc_dai_ops adau17x1_dai_ops;
 
diff --git a/sound/soc/codecs/adau1977-i2c.c b/sound/soc/codecs/adau1977-i2c.c
index 21e7394..e7fe1ee 100644
--- a/sound/soc/codecs/adau1977-i2c.c
+++ b/sound/soc/codecs/adau1977-i2c.c
@@ -29,12 +29,6 @@ static int adau1977_i2c_probe(struct i2c_client *client,
 		id->driver_data, NULL);
 }
 
-static int adau1977_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id adau1977_i2c_ids[] = {
 	{ "adau1977", ADAU1977 },
 	{ "adau1978", ADAU1978 },
@@ -48,7 +42,6 @@ static struct i2c_driver adau1977_i2c_driver = {
 		.name = "adau1977",
 	},
 	.probe = adau1977_i2c_probe,
-	.remove = adau1977_i2c_remove,
 	.id_table = adau1977_i2c_ids,
 };
 module_i2c_driver(adau1977_i2c_driver);
diff --git a/sound/soc/codecs/adau1977-spi.c b/sound/soc/codecs/adau1977-spi.c
index 0b46d88b..84ffbde 100644
--- a/sound/soc/codecs/adau1977-spi.c
+++ b/sound/soc/codecs/adau1977-spi.c
@@ -46,12 +46,6 @@ static int adau1977_spi_probe(struct spi_device *spi)
 		id->driver_data, adau1977_spi_switch_mode);
 }
 
-static int adau1977_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static const struct spi_device_id adau1977_spi_ids[] = {
 	{ "adau1977", ADAU1977 },
 	{ "adau1978", ADAU1978 },
@@ -65,7 +59,6 @@ static struct spi_driver adau1977_spi_driver = {
 		.name = "adau1977",
 	},
 	.probe = adau1977_spi_probe,
-	.remove = adau1977_spi_remove,
 	.id_table = adau1977_spi_ids,
 };
 module_spi_driver(adau1977_spi_driver);
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c
index e384f21..116af6a 100644
--- a/sound/soc/codecs/adau1977.c
+++ b/sound/soc/codecs/adau1977.c
@@ -294,8 +294,8 @@ static int adau1977_lookup_mcs(struct adau1977 *adau1977, unsigned int rate,
 static int adau1977_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
 	unsigned int rate = params_rate(params);
 	unsigned int slot_width;
 	unsigned int ctrl0, ctrl0_mask;
@@ -471,10 +471,10 @@ static int adau1977_power_enable(struct adau1977 *adau1977)
 	return ret;
 }
 
-static int adau1977_set_bias_level(struct snd_soc_codec *codec,
+static int adau1977_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	switch (level) {
@@ -483,7 +483,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			ret = adau1977_power_enable(adau1977);
 		break;
 	case SND_SOC_BIAS_OFF:
@@ -497,7 +497,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec,
 static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	unsigned int rx_mask, int slots, int width)
 {
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 	unsigned int ctrl0, ctrl1, drv;
 	unsigned int slot[4];
 	unsigned int i;
@@ -603,7 +603,7 @@ static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 
 static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream)
 {
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 	unsigned int val;
 
 	if (mute)
@@ -617,7 +617,7 @@ static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream)
 
 static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 	unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0;
 	bool invert_lrclk;
 	int ret;
@@ -704,7 +704,7 @@ static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int adau1977_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 	u64 formats = 0;
 
 	if (adau1977->slot_width == 16)
@@ -729,7 +729,7 @@ static int adau1977_startup(struct snd_pcm_substream *substream,
 
 static int adau1977_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
 	unsigned int val;
 
 	if (tristate)
@@ -790,10 +790,10 @@ static bool adau1977_check_sysclk(unsigned int mclk, unsigned int base_freq)
 	return true;
 }
 
-static int adau1977_set_sysclk(struct snd_soc_codec *codec,
+static int adau1977_set_sysclk(struct snd_soc_component *component,
 	int clk_id, int source, unsigned int freq, int dir)
 {
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
 	unsigned int mask = 0;
 	unsigned int clk_src;
 	unsigned int ret;
@@ -844,10 +844,10 @@ static int adau1977_set_sysclk(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int adau1977_codec_probe(struct snd_soc_codec *codec)
+static int adau1977_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (adau1977->type) {
@@ -865,20 +865,19 @@ static int adau1977_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver adau1977_codec_driver = {
-	.probe = adau1977_codec_probe,
-	.set_bias_level = adau1977_set_bias_level,
-	.set_sysclk = adau1977_set_sysclk,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= adau1977_snd_controls,
-		.num_controls		= ARRAY_SIZE(adau1977_snd_controls),
-		.dapm_widgets		= adau1977_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(adau1977_dapm_widgets),
-		.dapm_routes		= adau1977_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(adau1977_dapm_routes),
-	},
+static const struct snd_soc_component_driver adau1977_component_driver = {
+	.probe			= adau1977_component_probe,
+	.set_bias_level		= adau1977_set_bias_level,
+	.set_sysclk		= adau1977_set_sysclk,
+	.controls		= adau1977_snd_controls,
+	.num_controls		= ARRAY_SIZE(adau1977_snd_controls),
+	.dapm_widgets		= adau1977_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(adau1977_dapm_widgets),
+	.dapm_routes		= adau1977_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(adau1977_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int adau1977_setup_micbias(struct adau1977 *adau1977)
@@ -968,7 +967,7 @@ int adau1977_probe(struct device *dev, struct regmap *regmap,
 	if (ret)
 		return ret;
 
-	return snd_soc_register_codec(dev, &adau1977_codec_driver,
+	return devm_snd_soc_register_component(dev, &adau1977_component_driver,
 			&adau1977_dai, 1);
 
 err_poweroff:
diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c
index 6384c54..fdff868 100644
--- a/sound/soc/codecs/adau7002.c
+++ b/sound/soc/codecs/adau7002.c
@@ -7,6 +7,7 @@
  * Licensed under the GPL-2.
  */
 
+#include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -38,24 +39,26 @@ static struct snd_soc_dai_driver adau7002_dai = {
 	},
 };
 
-static const struct snd_soc_codec_driver adau7002_codec_driver = {
-	.component_driver = {
-		.dapm_widgets		= adau7002_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(adau7002_widgets),
-		.dapm_routes		= adau7002_routes,
-		.num_dapm_routes	= ARRAY_SIZE(adau7002_routes),
-	},
+static const struct snd_soc_component_driver adau7002_component_driver = {
+	.dapm_widgets		= adau7002_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(adau7002_widgets),
+	.dapm_routes		= adau7002_routes,
+	.num_dapm_routes	= ARRAY_SIZE(adau7002_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int adau7002_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &adau7002_codec_driver,
+	return devm_snd_soc_register_component(&pdev->dev,
+			&adau7002_component_driver,
 			&adau7002_dai, 1);
 }
 
 static int adau7002_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
 
@@ -67,10 +70,19 @@ static const struct of_device_id adau7002_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, adau7002_dt_ids);
 #endif
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id adau7002_acpi_match[] = {
+	{ "ADAU7002", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(acpi, adau7002_acpi_match);
+#endif
+
 static struct platform_driver adau7002_driver = {
 	.driver = {
 		.name = "adau7002",
 		.of_match_table	= of_match_ptr(adau7002_dt_ids),
+		.acpi_match_table = ACPI_PTR(adau7002_acpi_match),
 	},
 	.probe = adau7002_probe,
 	.remove = adau7002_remove,
diff --git a/sound/soc/codecs/adav801.c b/sound/soc/codecs/adav801.c
index 055f122..d82f79d 100644
--- a/sound/soc/codecs/adav801.c
+++ b/sound/soc/codecs/adav801.c
@@ -30,18 +30,11 @@ static int adav80x_spi_probe(struct spi_device *spi)
 	return adav80x_bus_probe(&spi->dev, devm_regmap_init_spi(spi, &config));
 }
 
-static int adav80x_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver adav80x_spi_driver = {
 	.driver = {
 		.name	= "adav801",
 	},
 	.probe		= adav80x_spi_probe,
-	.remove		= adav80x_spi_remove,
 	.id_table	= adav80x_spi_id,
 };
 module_spi_driver(adav80x_spi_driver);
diff --git a/sound/soc/codecs/adav803.c b/sound/soc/codecs/adav803.c
index 52881fa..deb14bc 100644
--- a/sound/soc/codecs/adav803.c
+++ b/sound/soc/codecs/adav803.c
@@ -27,18 +27,11 @@ static int adav803_probe(struct i2c_client *client,
 		devm_regmap_init_i2c(client, &adav80x_regmap_config));
 }
 
-static int adav803_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static struct i2c_driver adav803_driver = {
 	.driver = {
 		.name = "adav803",
 	},
 	.probe = adav803_probe,
-	.remove = adav803_remove,
 	.id_table = adav803_id,
 };
 module_i2c_driver(adav803_driver);
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index da7ca81..db21ecb 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -212,8 +212,8 @@ static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = {
 static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	const char *clk;
 
 	switch (adav80x->clk_src) {
@@ -236,8 +236,8 @@ static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,
 static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
 	return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL;
 }
@@ -281,9 +281,9 @@ static const struct snd_soc_dapm_route adav80x_dapm_routes[] = {
 	{ "AIFAUXIN", NULL, "SYSCLK" },
 };
 
-static int adav80x_set_deemph(struct snd_soc_codec *codec)
+static int adav80x_set_deemph(struct snd_soc_component *component)
 {
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (adav80x->deemph) {
@@ -315,8 +315,8 @@ static int adav80x_set_deemph(struct snd_soc_codec *codec)
 static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
@@ -324,14 +324,14 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
 
 	adav80x->deemph = deemph;
 
-	return adav80x_set_deemph(codec);
+	return adav80x_set_deemph(component);
 }
 
 static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = adav80x->deemph;
 	return 0;
@@ -365,8 +365,8 @@ static unsigned int adav80x_port_ctrl_regs[2][2] = {
 
 static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int capture = 0x00;
 	unsigned int playback = 0x00;
 
@@ -415,10 +415,10 @@ static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	return 0;
 }
 
-static int adav80x_set_adc_clock(struct snd_soc_codec *codec,
+static int adav80x_set_adc_clock(struct snd_soc_component *component,
 		unsigned int sample_rate)
 {
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (sample_rate <= 48000)
@@ -432,10 +432,10 @@ static int adav80x_set_adc_clock(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
+static int adav80x_set_dac_clock(struct snd_soc_component *component,
 		unsigned int sample_rate)
 {
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (sample_rate <= 48000)
@@ -450,10 +450,10 @@ static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
+static int adav80x_set_capture_pcm_format(struct snd_soc_component *component,
 		struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
 {
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	switch (params_width(params)) {
@@ -479,10 +479,10 @@ static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
+static int adav80x_set_playback_pcm_format(struct snd_soc_component *component,
 		struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
 {
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)
@@ -514,32 +514,32 @@ static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
 static int adav80x_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int rate = params_rate(params);
 
 	if (rate * 256 != adav80x->sysclk)
 		return -EINVAL;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		adav80x_set_playback_pcm_format(codec, dai, params);
-		adav80x_set_dac_clock(codec, rate);
+		adav80x_set_playback_pcm_format(component, dai, params);
+		adav80x_set_dac_clock(component, rate);
 	} else {
-		adav80x_set_capture_pcm_format(codec, dai, params);
-		adav80x_set_adc_clock(codec, rate);
+		adav80x_set_capture_pcm_format(component, dai, params);
+		adav80x_set_adc_clock(component, rate);
 	}
 	adav80x->rate = rate;
-	adav80x_set_deemph(codec);
+	adav80x_set_deemph(component);
 
 	return 0;
 }
 
-static int adav80x_set_sysclk(struct snd_soc_codec *codec,
+static int adav80x_set_sysclk(struct snd_soc_component *component,
 			      int clk_id, int source,
 			      unsigned int freq, int dir)
 {
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	if (dir == SND_SOC_CLOCK_IN) {
 		switch (clk_id) {
@@ -619,11 +619,11 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
+static int adav80x_set_pll(struct snd_soc_component *component, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int pll_ctrl1 = 0;
 	unsigned int pll_ctrl2 = 0;
 	unsigned int pll_src;
@@ -694,10 +694,10 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
 	return 0;
 }
 
-static int adav80x_set_bias_level(struct snd_soc_codec *codec,
+static int adav80x_set_bias_level(struct snd_soc_component *component,
 		enum snd_soc_bias_level level)
 {
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 	unsigned int mask = ADAV80X_DAC_CTRL1_PD;
 
 	switch (level) {
@@ -722,10 +722,10 @@ static int adav80x_set_bias_level(struct snd_soc_codec *codec,
 static int adav80x_dai_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
-	if (!snd_soc_codec_is_active(codec) || !adav80x->rate)
+	if (!snd_soc_component_is_active(component) || !adav80x->rate)
 		return 0;
 
 	return snd_pcm_hw_constraint_single(substream->runtime,
@@ -735,10 +735,10 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
 static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
-	if (!snd_soc_codec_is_active(codec))
+	if (!snd_soc_component_is_active(component))
 		adav80x->rate = 0;
 }
 
@@ -799,10 +799,10 @@ static struct snd_soc_dai_driver adav80x_dais[] = {
 	},
 };
 
-static int adav80x_probe(struct snd_soc_codec *codec)
+static int adav80x_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
 	/* Force PLLs on for SYSCLK output */
 	snd_soc_dapm_force_enable_pin(dapm, "PLL1");
@@ -816,32 +816,32 @@ static int adav80x_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int adav80x_resume(struct snd_soc_codec *codec)
+static int adav80x_resume(struct snd_soc_component *component)
 {
-	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+	struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
 	regcache_sync(adav80x->regmap);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver adav80x_codec_driver = {
-	.probe = adav80x_probe,
-	.resume = adav80x_resume,
-	.set_bias_level = adav80x_set_bias_level,
-	.suspend_bias_off = true,
-
-	.set_pll = adav80x_set_pll,
-	.set_sysclk = adav80x_set_sysclk,
-
-	.component_driver = {
-		.controls		= adav80x_controls,
-		.num_controls		= ARRAY_SIZE(adav80x_controls),
-		.dapm_widgets		= adav80x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(adav80x_dapm_widgets),
-		.dapm_routes		= adav80x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(adav80x_dapm_routes),
-	},
+static const struct snd_soc_component_driver adav80x_component_driver = {
+	.probe			= adav80x_probe,
+	.resume			= adav80x_resume,
+	.set_bias_level		= adav80x_set_bias_level,
+	.set_pll		= adav80x_set_pll,
+	.set_sysclk		= adav80x_set_sysclk,
+	.controls		= adav80x_controls,
+	.num_controls		= ARRAY_SIZE(adav80x_controls),
+	.dapm_widgets		= adav80x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(adav80x_dapm_widgets),
+	.dapm_routes		= adav80x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(adav80x_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
@@ -858,7 +858,7 @@ int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
 	dev_set_drvdata(dev, adav80x);
 	adav80x->regmap = regmap;
 
-	return snd_soc_register_codec(dev, &adav80x_codec_driver,
+	return devm_snd_soc_register_component(dev, &adav80x_component_driver,
 		adav80x_dais, ARRAY_SIZE(adav80x_dais));
 }
 EXPORT_SYMBOL_GPL(adav80x_bus_probe);
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index b7f0057..bcd45ff 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -58,25 +58,21 @@ static struct snd_soc_dai_driver ads117x_dai = {
 		.formats = ADS117X_FORMATS,},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ads117x = {
-	.component_driver = {
-		.dapm_widgets		= ads117x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ads117x_dapm_widgets),
-		.dapm_routes		= ads117x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ads117x_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ads117x = {
+	.dapm_widgets		= ads117x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ads117x_dapm_widgets),
+	.dapm_routes		= ads117x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ads117x_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ads117x_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_ads117x, &ads117x_dai, 1);
-}
-
-static int ads117x_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_ads117x, &ads117x_dai, 1);
 }
 
 #if defined(CONFIG_OF)
@@ -95,7 +91,6 @@ static struct platform_driver ads117x_codec_driver = {
 	},
 
 	.probe = ads117x_probe,
-	.remove = ads117x_remove,
 };
 
 module_platform_driver(ads117x_codec_driver);
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index dbb1841..32bc545 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -65,8 +65,8 @@ static const struct snd_soc_dapm_route ak4104_dapm_routes[] = {
 static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);
 	int val = 0;
 	int ret;
 
@@ -81,7 +81,7 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		val |= AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1;
 		break;
 	default:
-		dev_err(codec->dev, "invalid dai format\n");
+		dev_err(component->dev, "invalid dai format\n");
 		return -EINVAL;
 	}
 
@@ -102,8 +102,8 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);
 	int ret, val = 0;
 
 	/* set the IEC958 bits: consumer mode, no copyright bit */
@@ -141,7 +141,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
 		val |= IEC958_AES3_CON_FS_192000;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported sampling rate\n");
+		dev_err(component->dev, "unsupported sampling rate\n");
 		return -EINVAL;
 	}
 
@@ -174,14 +174,14 @@ static struct snd_soc_dai_driver ak4104_dai = {
 	.ops = &ak4101_dai_ops,
 };
 
-static int ak4104_probe(struct snd_soc_codec *codec)
+static int ak4104_probe(struct snd_soc_component *component)
 {
-	struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
+	struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_enable(ak4104->regulator);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unable to enable regulator: %d\n", ret);
+		dev_err(component->dev, "Unable to enable regulator: %d\n", ret);
 		return ret;
 	}
 
@@ -205,30 +205,28 @@ static int ak4104_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int ak4104_remove(struct snd_soc_codec *codec)
+static void ak4104_remove(struct snd_soc_component *component)
 {
-	struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
+	struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);
 
 	regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
 			   AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
 	regulator_disable(ak4104->regulator);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int ak4104_soc_suspend(struct snd_soc_codec *codec)
+static int ak4104_soc_suspend(struct snd_soc_component *component)
 {
-	struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct ak4104_private *priv = snd_soc_component_get_drvdata(component);
 
 	regulator_disable(priv->regulator);
 
 	return 0;
 }
 
-static int ak4104_soc_resume(struct snd_soc_codec *codec)
+static int ak4104_soc_resume(struct snd_soc_component *component)
 {
-	struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct ak4104_private *priv = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_enable(priv->regulator);
@@ -242,18 +240,19 @@ static int ak4104_soc_resume(struct snd_soc_codec *codec)
 #define ak4104_soc_resume	NULL
 #endif /* CONFIG_PM */
 
-static const struct snd_soc_codec_driver soc_codec_device_ak4104 = {
-	.probe = ak4104_probe,
-	.remove = ak4104_remove,
-	.suspend = ak4104_soc_suspend,
-	.resume = ak4104_soc_resume,
-
-	.component_driver = {
-		.dapm_widgets		= ak4104_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ak4104_dapm_widgets),
-		.dapm_routes		= ak4104_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ak4104_dapm_routes),
-	}
+static const struct snd_soc_component_driver soc_component_device_ak4104 = {
+	.probe			= ak4104_probe,
+	.remove			= ak4104_remove,
+	.suspend		= ak4104_soc_suspend,
+	.resume			= ak4104_soc_resume,
+	.dapm_widgets		= ak4104_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak4104_dapm_widgets),
+	.dapm_routes		= ak4104_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ak4104_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config ak4104_regmap = {
@@ -323,17 +322,11 @@ static int ak4104_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, ak4104);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_device_ak4104, &ak4104_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_device_ak4104, &ak4104_dai, 1);
 	return ret;
 }
 
-static int ak4104_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static const struct of_device_id ak4104_of_match[] = {
 	{ .compatible = "asahi-kasei,ak4104", },
 	{ }
@@ -353,7 +346,6 @@ static struct spi_driver ak4104_spi_driver = {
 	},
 	.id_table = ak4104_id_table,
 	.probe  = ak4104_spi_probe,
-	.remove = ak4104_spi_remove,
 };
 
 module_spi_driver(ak4104_spi_driver);
diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
new file mode 100644
index 0000000..31ec0ba
--- /dev/null
+++ b/sound/soc/codecs/ak4458.c
@@ -0,0 +1,657 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Audio driver for AK4458 DAC
+//
+// Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+// Copyright 2018 NXP
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <sound/initval.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#include "ak4458.h"
+
+/* AK4458 Codec Private Data */
+struct ak4458_priv {
+	struct device *dev;
+	struct regmap *regmap;
+	struct gpio_desc *reset_gpiod;
+	struct gpio_desc *mute_gpiod;
+	int digfil;	/* SSLOW, SD, SLOW bits */
+	int fs;		/* sampling rate */
+	int fmt;
+	int slots;
+	int slot_width;
+};
+
+static const struct reg_default ak4458_reg_defaults[] = {
+	{ 0x00, 0x0C },	/*	0x00	AK4458_00_CONTROL1	*/
+	{ 0x01, 0x22 },	/*	0x01	AK4458_01_CONTROL2	*/
+	{ 0x02, 0x00 },	/*	0x02	AK4458_02_CONTROL3	*/
+	{ 0x03, 0xFF },	/*	0x03	AK4458_03_LCHATT	*/
+	{ 0x04, 0xFF },	/*	0x04	AK4458_04_RCHATT	*/
+	{ 0x05, 0x00 },	/*	0x05	AK4458_05_CONTROL4	*/
+	{ 0x06, 0x00 },	/*	0x06	AK4458_06_DSD1		*/
+	{ 0x07, 0x03 },	/*	0x07	AK4458_07_CONTROL5	*/
+	{ 0x08, 0x00 },	/*	0x08	AK4458_08_SOUND_CONTROL	*/
+	{ 0x09, 0x00 },	/*	0x09	AK4458_09_DSD2		*/
+	{ 0x0A, 0x0D },	/*	0x0A	AK4458_0A_CONTROL6	*/
+	{ 0x0B, 0x0C },	/*	0x0B	AK4458_0B_CONTROL7	*/
+	{ 0x0C, 0x00 },	/*	0x0C	AK4458_0C_CONTROL8	*/
+	{ 0x0D, 0x00 },	/*	0x0D	AK4458_0D_CONTROL9	*/
+	{ 0x0E, 0x50 },	/*	0x0E	AK4458_0E_CONTROL10	*/
+	{ 0x0F, 0xFF },	/*	0x0F	AK4458_0F_L2CHATT	*/
+	{ 0x10, 0xFF },	/*	0x10	AK4458_10_R2CHATT	*/
+	{ 0x11, 0xFF },	/*	0x11	AK4458_11_L3CHATT	*/
+	{ 0x12, 0xFF },	/*	0x12	AK4458_12_R3CHATT	*/
+	{ 0x13, 0xFF },	/*	0x13	AK4458_13_L4CHATT	*/
+	{ 0x14, 0xFF },	/*	0x14	AK4458_14_R4CHATT	*/
+};
+
+/*
+ * Volume control:
+ * from -127 to 0 dB in 0.5 dB steps (mute instead of -127.5 dB)
+ */
+static DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+
+/*
+ * DEM1 bit DEM0 bit Mode
+ * 0 0 44.1kHz
+ * 0 1 OFF (default)
+ * 1 0 48kHz
+ * 1 1 32kHz
+ */
+static const char * const ak4458_dem_select_texts[] = {
+	"44.1kHz", "OFF", "48kHz", "32kHz"
+};
+
+/*
+ * SSLOW, SD, SLOW bits Digital Filter Setting
+ * 0, 0, 0 : Sharp Roll-Off Filter
+ * 0, 0, 1 : Slow Roll-Off Filter
+ * 0, 1, 0 : Short delay Sharp Roll-Off Filter
+ * 0, 1, 1 : Short delay Slow Roll-Off Filter
+ * 1, *, * : Super Slow Roll-Off Filter
+ */
+static const char * const ak4458_digfil_select_texts[] = {
+	"Sharp Roll-Off Filter",
+	"Slow Roll-Off Filter",
+	"Short delay Sharp Roll-Off Filter",
+	"Short delay Slow Roll-Off Filter",
+	"Super Slow Roll-Off Filter"
+};
+
+/*
+ * DZFB: Inverting Enable of DZF
+ * 0: DZF goes H at Zero Detection
+ * 1: DZF goes L at Zero Detection
+ */
+static const char * const ak4458_dzfb_select_texts[] = {"H", "L"};
+
+/*
+ * SC1-0 bits: Sound Mode Setting
+ * 0 0 : Sound Mode 0
+ * 0 1 : Sound Mode 1
+ * 1 0 : Sound Mode 2
+ * 1 1 : Reserved
+ */
+static const char * const ak4458_sc_select_texts[] = {
+	"Sound Mode 0", "Sound Mode 1", "Sound Mode 2"
+};
+
+/* FIR2-0 bits: FIR Filter Mode Setting */
+static const char * const ak4458_fir_select_texts[] = {
+	"Mode 0", "Mode 1", "Mode 2", "Mode 3",
+	"Mode 4", "Mode 5", "Mode 6", "Mode 7",
+};
+
+/* ATS1-0 bits Attenuation Speed */
+static const char * const ak4458_ats_select_texts[] = {
+	"4080/fs", "2040/fs", "510/fs", "255/fs",
+};
+
+/* DIF2 bit Audio Interface Format Setting(BICK fs) */
+static const char * const ak4458_dif_select_texts[] = {"32fs,48fs", "64fs",};
+
+static const struct soc_enum ak4458_dac1_dem_enum =
+	SOC_ENUM_SINGLE(AK4458_01_CONTROL2, 1,
+			ARRAY_SIZE(ak4458_dem_select_texts),
+			ak4458_dem_select_texts);
+static const struct soc_enum ak4458_dac2_dem_enum =
+	SOC_ENUM_SINGLE(AK4458_0A_CONTROL6, 0,
+			ARRAY_SIZE(ak4458_dem_select_texts),
+			ak4458_dem_select_texts);
+static const struct soc_enum ak4458_dac3_dem_enum =
+	SOC_ENUM_SINGLE(AK4458_0E_CONTROL10, 4,
+			ARRAY_SIZE(ak4458_dem_select_texts),
+			ak4458_dem_select_texts);
+static const struct soc_enum ak4458_dac4_dem_enum =
+	SOC_ENUM_SINGLE(AK4458_0E_CONTROL10, 6,
+			ARRAY_SIZE(ak4458_dem_select_texts),
+			ak4458_dem_select_texts);
+static const struct soc_enum ak4458_digfil_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4458_digfil_select_texts),
+			    ak4458_digfil_select_texts);
+static const struct soc_enum ak4458_dzfb_enum =
+	SOC_ENUM_SINGLE(AK4458_02_CONTROL3, 2,
+			ARRAY_SIZE(ak4458_dzfb_select_texts),
+			ak4458_dzfb_select_texts);
+static const struct soc_enum ak4458_sm_enum =
+	SOC_ENUM_SINGLE(AK4458_08_SOUND_CONTROL, 0,
+			ARRAY_SIZE(ak4458_sc_select_texts),
+			ak4458_sc_select_texts);
+static const struct soc_enum ak4458_fir_enum =
+	SOC_ENUM_SINGLE(AK4458_0C_CONTROL8, 0,
+			ARRAY_SIZE(ak4458_fir_select_texts),
+			ak4458_fir_select_texts);
+static const struct soc_enum ak4458_ats_enum =
+	SOC_ENUM_SINGLE(AK4458_0B_CONTROL7, 6,
+			ARRAY_SIZE(ak4458_ats_select_texts),
+			ak4458_ats_select_texts);
+static const struct soc_enum ak4458_dif_enum =
+	SOC_ENUM_SINGLE(AK4458_00_CONTROL1, 3,
+			ARRAY_SIZE(ak4458_dif_select_texts),
+			ak4458_dif_select_texts);
+
+static int get_digfil(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.enumerated.item[0] = ak4458->digfil;
+
+	return 0;
+}
+
+static int set_digfil(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+	int num;
+
+	num = ucontrol->value.enumerated.item[0];
+	if (num > 4)
+		return -EINVAL;
+
+	ak4458->digfil = num;
+
+	/* write SD bit */
+	snd_soc_component_update_bits(component, AK4458_01_CONTROL2,
+			    AK4458_SD_MASK,
+			    ((ak4458->digfil & 0x02) << 4));
+
+	/* write SLOW bit */
+	snd_soc_component_update_bits(component, AK4458_02_CONTROL3,
+			    AK4458_SLOW_MASK,
+			    (ak4458->digfil & 0x01));
+
+	/* write SSLOW bit */
+	snd_soc_component_update_bits(component, AK4458_05_CONTROL4,
+			    AK4458_SSLOW_MASK,
+			    ((ak4458->digfil & 0x04) >> 2));
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new ak4458_snd_controls[] = {
+	SOC_DOUBLE_R_TLV("DAC1 Playback Volume", AK4458_03_LCHATT,
+			 AK4458_04_RCHATT, 0, 0xFF, 0, dac_tlv),
+	SOC_DOUBLE_R_TLV("DAC2 Playback Volume", AK4458_0F_L2CHATT,
+			 AK4458_10_R2CHATT, 0, 0xFF, 0, dac_tlv),
+	SOC_DOUBLE_R_TLV("DAC3 Playback Volume", AK4458_11_L3CHATT,
+			 AK4458_12_R3CHATT, 0, 0xFF, 0, dac_tlv),
+	SOC_DOUBLE_R_TLV("DAC4 Playback Volume", AK4458_13_L4CHATT,
+			 AK4458_14_R4CHATT, 0, 0xFF, 0, dac_tlv),
+	SOC_ENUM("AK4458 De-emphasis Response DAC1", ak4458_dac1_dem_enum),
+	SOC_ENUM("AK4458 De-emphasis Response DAC2", ak4458_dac2_dem_enum),
+	SOC_ENUM("AK4458 De-emphasis Response DAC3", ak4458_dac3_dem_enum),
+	SOC_ENUM("AK4458 De-emphasis Response DAC4", ak4458_dac4_dem_enum),
+	SOC_ENUM_EXT("AK4458 Digital Filter Setting", ak4458_digfil_enum,
+		     get_digfil, set_digfil),
+	SOC_ENUM("AK4458 Inverting Enable of DZFB", ak4458_dzfb_enum),
+	SOC_ENUM("AK4458 Sound Mode", ak4458_sm_enum),
+	SOC_ENUM("AK4458 FIR Filter Mode Setting", ak4458_fir_enum),
+	SOC_ENUM("AK4458 Attenuation transition Time Setting",
+		 ak4458_ats_enum),
+	SOC_ENUM("AK4458 BICK fs Setting", ak4458_dif_enum),
+};
+
+/* ak4458 dapm widgets */
+static const struct snd_soc_dapm_widget ak4458_dapm_widgets[] = {
+	SND_SOC_DAPM_DAC("AK4458 DAC1", NULL, AK4458_0A_CONTROL6, 2, 0),/*pw*/
+	SND_SOC_DAPM_AIF_IN("AK4458 SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_OUTPUT("AK4458 AOUTA"),
+
+	SND_SOC_DAPM_DAC("AK4458 DAC2", NULL, AK4458_0A_CONTROL6, 3, 0),/*pw*/
+	SND_SOC_DAPM_OUTPUT("AK4458 AOUTB"),
+
+	SND_SOC_DAPM_DAC("AK4458 DAC3", NULL, AK4458_0B_CONTROL7, 2, 0),/*pw*/
+	SND_SOC_DAPM_OUTPUT("AK4458 AOUTC"),
+
+	SND_SOC_DAPM_DAC("AK4458 DAC4", NULL, AK4458_0B_CONTROL7, 3, 0),/*pw*/
+	SND_SOC_DAPM_OUTPUT("AK4458 AOUTD"),
+};
+
+static const struct snd_soc_dapm_route ak4458_intercon[] = {
+	{"AK4458 DAC1",		NULL,	"AK4458 SDTI"},
+	{"AK4458 AOUTA",	NULL,	"AK4458 DAC1"},
+
+	{"AK4458 DAC2",		NULL,	"AK4458 SDTI"},
+	{"AK4458 AOUTB",	NULL,	"AK4458 DAC2"},
+
+	{"AK4458 DAC3",		NULL,	"AK4458 SDTI"},
+	{"AK4458 AOUTC",	NULL,	"AK4458 DAC3"},
+
+	{"AK4458 DAC4",		NULL,	"AK4458 SDTI"},
+	{"AK4458 AOUTD",	NULL,	"AK4458 DAC4"},
+};
+
+static int ak4458_rstn_control(struct snd_soc_component *component, int bit)
+{
+	int ret;
+
+	if (bit)
+		ret = snd_soc_component_update_bits(component,
+					  AK4458_00_CONTROL1,
+					  AK4458_RSTN_MASK,
+					  0x1);
+	else
+		ret = snd_soc_component_update_bits(component,
+					  AK4458_00_CONTROL1,
+					  AK4458_RSTN_MASK,
+					  0x0);
+	return ret;
+}
+
+static int ak4458_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct snd_soc_component *component = dai->component;
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+	int pcm_width = max(params_physical_width(params), ak4458->slot_width);
+	int nfs1;
+	u8 format;
+
+	nfs1 = params_rate(params);
+	ak4458->fs = nfs1;
+
+	/* Master Clock Frequency Auto Setting Mode Enable */
+	snd_soc_component_update_bits(component, AK4458_00_CONTROL1, 0x80, 0x80);
+
+	switch (pcm_width) {
+	case 16:
+		if (ak4458->fmt == SND_SOC_DAIFMT_I2S)
+			format = AK4458_DIF_24BIT_I2S;
+		else
+			format = AK4458_DIF_16BIT_LSB;
+		break;
+	case 32:
+		switch (ak4458->fmt) {
+		case SND_SOC_DAIFMT_I2S:
+			format = AK4458_DIF_32BIT_I2S;
+			break;
+		case SND_SOC_DAIFMT_LEFT_J:
+			format = AK4458_DIF_32BIT_MSB;
+			break;
+		case SND_SOC_DAIFMT_RIGHT_J:
+			format = AK4458_DIF_32BIT_LSB;
+			break;
+		case SND_SOC_DAIFMT_DSP_B:
+			format = AK4458_DIF_32BIT_MSB;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
+			    AK4458_DIF_MASK, format);
+
+	ak4458_rstn_control(component, 0);
+	ak4458_rstn_control(component, 1);
+
+	return 0;
+}
+
+static int ak4458_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct snd_soc_component *component = dai->component;
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS: /* Slave Mode */
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM: /* Master Mode is not supported */
+	case SND_SOC_DAIFMT_CBS_CFM:
+	case SND_SOC_DAIFMT_CBM_CFS:
+	default:
+		dev_err(component->dev, "Master mode unsupported\n");
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+	case SND_SOC_DAIFMT_LEFT_J:
+	case SND_SOC_DAIFMT_RIGHT_J:
+	case SND_SOC_DAIFMT_DSP_B:
+		ak4458->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+		break;
+	default:
+		dev_err(component->dev, "Audio format 0x%02X unsupported\n",
+			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+		return -EINVAL;
+	}
+
+	ak4458_rstn_control(component, 0);
+	ak4458_rstn_control(component, 1);
+
+	return 0;
+}
+
+static const int att_speed[] = { 4080, 2040, 510, 255 };
+
+static int ak4458_set_dai_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_component *component = dai->component;
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+	int nfs, ndt, ret, reg;
+	int ats;
+
+	nfs = ak4458->fs;
+
+	reg = snd_soc_component_read32(component, AK4458_0B_CONTROL7);
+	ats = (reg & AK4458_ATS_MASK) >> AK4458_ATS_SHIFT;
+
+	ndt = att_speed[ats] / (nfs / 1000);
+
+	if (mute) {
+		ret = snd_soc_component_update_bits(component, AK4458_01_CONTROL2,  0x01, 1);
+		mdelay(ndt);
+		if (ak4458->mute_gpiod)
+			gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
+	} else {
+		if (ak4458->mute_gpiod)
+			gpiod_set_value_cansleep(ak4458->mute_gpiod, 0);
+		ret = snd_soc_component_update_bits(component, AK4458_01_CONTROL2, 0x01, 0);
+		mdelay(ndt);
+	}
+
+	return 0;
+}
+
+static int ak4458_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots, int slot_width)
+{
+	struct snd_soc_component *component = dai->component;
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+	int mode;
+
+	ak4458->slots = slots;
+	ak4458->slot_width = slot_width;
+
+	switch (slots * slot_width) {
+	case 128:
+		mode = AK4458_MODE_TDM128;
+		break;
+	case 256:
+		mode = AK4458_MODE_TDM256;
+		break;
+	case 512:
+		mode = AK4458_MODE_TDM512;
+		break;
+	default:
+		mode = AK4458_MODE_NORMAL;
+		break;
+	}
+
+	snd_soc_component_update_bits(component, AK4458_0A_CONTROL6,
+			    AK4458_MODE_MASK,
+			    mode);
+
+	return 0;
+}
+
+#define AK4458_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE |\
+			 SNDRV_PCM_FMTBIT_S24_LE |\
+			 SNDRV_PCM_FMTBIT_S32_LE)
+
+static const unsigned int ak4458_rates[] = {
+	8000, 11025,  16000, 22050,
+	32000, 44100, 48000, 88200,
+	96000, 176400, 192000, 352800,
+	384000, 705600, 768000, 1411200,
+	2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list ak4458_rate_constraints = {
+	.count = ARRAY_SIZE(ak4458_rates),
+	.list = ak4458_rates,
+};
+
+static int ak4458_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &ak4458_rate_constraints);
+
+	return ret;
+}
+
+static struct snd_soc_dai_ops ak4458_dai_ops = {
+	.startup        = ak4458_startup,
+	.hw_params	= ak4458_hw_params,
+	.set_fmt	= ak4458_set_dai_fmt,
+	.digital_mute	= ak4458_set_dai_mute,
+	.set_tdm_slot	= ak4458_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver ak4458_dai = {
+	.name = "ak4458-aif",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 8,
+		.rates = SNDRV_PCM_RATE_KNOT,
+		.formats = AK4458_FORMATS,
+	},
+	.ops = &ak4458_dai_ops,
+};
+
+static void ak4458_power_off(struct ak4458_priv *ak4458)
+{
+	if (ak4458->reset_gpiod) {
+		gpiod_set_value_cansleep(ak4458->reset_gpiod, 0);
+		usleep_range(1000, 2000);
+	}
+}
+
+static void ak4458_power_on(struct ak4458_priv *ak4458)
+{
+	if (ak4458->reset_gpiod) {
+		gpiod_set_value_cansleep(ak4458->reset_gpiod, 1);
+		usleep_range(1000, 2000);
+	}
+}
+
+static void ak4458_init(struct snd_soc_component *component)
+{
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+	/* External Mute ON */
+	if (ak4458->mute_gpiod)
+		gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
+
+	ak4458_power_on(ak4458);
+
+	snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
+			    0x80, 0x80);   /* ACKS bit = 1; 10000000 */
+
+	ak4458_rstn_control(component, 1);
+}
+
+static int ak4458_probe(struct snd_soc_component *component)
+{
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+	ak4458_init(component);
+
+	ak4458->fs = 48000;
+
+	return 0;
+}
+
+static void ak4458_remove(struct snd_soc_component *component)
+{
+	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+	ak4458_power_off(ak4458);
+}
+
+#ifdef CONFIG_PM
+static int __maybe_unused ak4458_runtime_suspend(struct device *dev)
+{
+	struct ak4458_priv *ak4458 = dev_get_drvdata(dev);
+
+	regcache_cache_only(ak4458->regmap, true);
+
+	ak4458_power_off(ak4458);
+
+	if (ak4458->mute_gpiod)
+		gpiod_set_value_cansleep(ak4458->mute_gpiod, 0);
+
+	return 0;
+}
+
+static int __maybe_unused ak4458_runtime_resume(struct device *dev)
+{
+	struct ak4458_priv *ak4458 = dev_get_drvdata(dev);
+
+	if (ak4458->mute_gpiod)
+		gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
+
+	ak4458_power_off(ak4458);
+	ak4458_power_on(ak4458);
+
+	regcache_cache_only(ak4458->regmap, false);
+	regcache_mark_dirty(ak4458->regmap);
+
+	return regcache_sync(ak4458->regmap);
+}
+#endif /* CONFIG_PM */
+
+struct snd_soc_component_driver soc_codec_dev_ak4458 = {
+	.probe			= ak4458_probe,
+	.remove			= ak4458_remove,
+	.controls		= ak4458_snd_controls,
+	.num_controls		= ARRAY_SIZE(ak4458_snd_controls),
+	.dapm_widgets		= ak4458_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak4458_dapm_widgets),
+	.dapm_routes		= ak4458_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(ak4458_intercon),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
+
+static const struct regmap_config ak4458_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = AK4458_14_R4CHATT,
+	.reg_defaults = ak4458_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(ak4458_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static const struct dev_pm_ops ak4458_pm = {
+	SET_RUNTIME_PM_OPS(ak4458_runtime_suspend, ak4458_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
+static int ak4458_i2c_probe(struct i2c_client *i2c)
+{
+	struct ak4458_priv *ak4458;
+	int ret;
+
+	ak4458 = devm_kzalloc(&i2c->dev, sizeof(*ak4458), GFP_KERNEL);
+	if (!ak4458)
+		return -ENOMEM;
+
+	ak4458->regmap = devm_regmap_init_i2c(i2c, &ak4458_regmap);
+	if (IS_ERR(ak4458->regmap))
+		return PTR_ERR(ak4458->regmap);
+
+	i2c_set_clientdata(i2c, ak4458);
+	ak4458->dev = &i2c->dev;
+
+	ak4458->reset_gpiod = devm_gpiod_get_optional(ak4458->dev, "reset",
+						      GPIOD_OUT_LOW);
+	if (IS_ERR(ak4458->reset_gpiod))
+		return PTR_ERR(ak4458->reset_gpiod);
+
+	ak4458->mute_gpiod = devm_gpiod_get_optional(ak4458->dev, "mute",
+						     GPIOD_OUT_LOW);
+	if (IS_ERR(ak4458->mute_gpiod))
+		return PTR_ERR(ak4458->mute_gpiod);
+
+	ret = devm_snd_soc_register_component(ak4458->dev, &soc_codec_dev_ak4458,
+				     &ak4458_dai, 1);
+	if (ret < 0) {
+		dev_err(ak4458->dev, "Failed to register CODEC: %d\n", ret);
+		return ret;
+	}
+
+	pm_runtime_enable(&i2c->dev);
+
+	return 0;
+}
+
+static int ak4458_i2c_remove(struct i2c_client *i2c)
+{
+	pm_runtime_disable(&i2c->dev);
+
+	return 0;
+}
+
+static const struct of_device_id ak4458_of_match[] = {
+	{ .compatible = "asahi-kasei,ak4458", },
+	{ },
+};
+
+static struct i2c_driver ak4458_i2c_driver = {
+	.driver = {
+		.name = "ak4458",
+		.pm = &ak4458_pm,
+		.of_match_table = ak4458_of_match,
+		},
+	.probe_new = ak4458_i2c_probe,
+	.remove = ak4458_i2c_remove,
+};
+
+module_i2c_driver(ak4458_i2c_driver);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_DESCRIPTION("ASoC AK4458 DAC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ak4458.h b/sound/soc/codecs/ak4458.h
new file mode 100644
index 0000000..f906215
--- /dev/null
+++ b/sound/soc/codecs/ak4458.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Audio driver for AK4458
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright 2018 NXP
+ */
+
+#ifndef _AK4458_H
+#define _AK4458_H
+
+#include <linux/regmap.h>
+
+/* Settings */
+
+#define AK4458_00_CONTROL1			0x00
+#define AK4458_01_CONTROL2			0x01
+#define AK4458_02_CONTROL3			0x02
+#define AK4458_03_LCHATT			0x03
+#define AK4458_04_RCHATT			0x04
+#define AK4458_05_CONTROL4			0x05
+#define AK4458_06_DSD1				0x06
+#define AK4458_07_CONTROL5			0x07
+#define AK4458_08_SOUND_CONTROL			0x08
+#define AK4458_09_DSD2				0x09
+#define AK4458_0A_CONTROL6			0x0A
+#define AK4458_0B_CONTROL7			0x0B
+#define AK4458_0C_CONTROL8			0x0C
+#define AK4458_0D_CONTROL9			0x0D
+#define AK4458_0E_CONTROL10			0x0E
+#define AK4458_0F_L2CHATT			0x0F
+#define AK4458_10_R2CHATT			0x10
+#define AK4458_11_L3CHATT			0x11
+#define AK4458_12_R3CHATT			0x12
+#define AK4458_13_L4CHATT			0x13
+#define AK4458_14_R4CHATT			0x14
+
+/* Bitfield Definitions */
+
+/* AK4458_00_CONTROL1 (0x00) Fields
+ * Addr Register Name  D7     D6    D5    D4    D3    D2    D1    D0
+ * 00H  Control 1      ACKS   0     0     0     DIF2  DIF1  DIF0  RSTN
+ */
+
+/* Digital Filter (SD, SLOW, SSLOW) */
+#define AK4458_SD_MASK		GENMASK(5, 5)
+#define AK4458_SLOW_MASK	GENMASK(0, 0)
+#define AK4458_SSLOW_MASK	GENMASK(0, 0)
+
+/* DIF2	1 0
+ *  x	1 0 MSB justified  Figure 3 (default)
+ *  x	1 1 I2S Compliment  Figure 4
+ */
+#define AK4458_DIF_SHIFT	1
+#define AK4458_DIF_MASK		GENMASK(3, 1)
+
+#define AK4458_DIF_16BIT_LSB	(0 << 1)
+#define AK4458_DIF_24BIT_I2S	(3 << 1)
+#define AK4458_DIF_32BIT_LSB	(5 << 1)
+#define AK4458_DIF_32BIT_MSB	(6 << 1)
+#define AK4458_DIF_32BIT_I2S	(7 << 1)
+
+/* AK4458_00_CONTROL1 (0x00) D0 bit */
+#define AK4458_RSTN_MASK	GENMASK(0, 0)
+#define AK4458_RSTN		(0x1 << 0)
+
+/* AK4458_0A_CONTROL6 Mode bits */
+#define AK4458_MODE_SHIFT	6
+#define AK4458_MODE_MASK	GENMASK(7, 6)
+#define AK4458_MODE_NORMAL	(0 << AK4458_MODE_SHIFT)
+#define AK4458_MODE_TDM128	(1 << AK4458_MODE_SHIFT)
+#define AK4458_MODE_TDM256	(2 << AK4458_MODE_SHIFT)
+#define AK4458_MODE_TDM512	(3 << AK4458_MODE_SHIFT)
+
+/* DAC Digital attenuator transition time setting
+ * Table 19
+ * Mode	ATS1	ATS2	ATT speed
+ * 0	0	0	4080/fs
+ * 1	0	1	2040/fs
+ * 2	1	0	510/fs
+ * 3	1	1	255/fs
+ * */
+#define AK4458_ATS_SHIFT	6
+#define AK4458_ATS_MASK		GENMASK(7, 6)
+
+#endif /* _AK4458_H */
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index e3c157d..31f6099 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -251,8 +251,8 @@ static const struct snd_soc_dapm_route ak4535_audio_map[] = {
 static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct ak4535_priv *ak4535 = snd_soc_component_get_drvdata(component);
 
 	ak4535->sysclk = freq;
 	return 0;
@@ -262,9 +262,9 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
-	u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5);
+	struct snd_soc_component *component = dai->component;
+	struct ak4535_priv *ak4535 = snd_soc_component_get_drvdata(component);
+	u8 mode2 = snd_soc_component_read32(component, AK4535_MODE2) & ~(0x3 << 5);
 	int rate = params_rate(params), fs = 256;
 
 	if (rate)
@@ -283,14 +283,14 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* set rate */
-	snd_soc_write(codec, AK4535_MODE2, mode2);
+	snd_soc_component_write(component, AK4535_MODE2, mode2);
 	return 0;
 }
 
 static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u8 mode1 = 0;
 
 	/* interface format */
@@ -308,37 +308,37 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	/* use 32 fs for BCLK to save power */
 	mode1 |= 0x4;
 
-	snd_soc_write(codec, AK4535_MODE1, mode1);
+	snd_soc_component_write(component, AK4535_MODE1, mode1);
 	return 0;
 }
 
 static int ak4535_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, AK4535_DAC);
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, AK4535_DAC);
 	if (!mute)
-		snd_soc_write(codec, AK4535_DAC, mute_reg & ~0x20);
+		snd_soc_component_write(component, AK4535_DAC, mute_reg & ~0x20);
 	else
-		snd_soc_write(codec, AK4535_DAC, mute_reg | 0x20);
+		snd_soc_component_write(component, AK4535_DAC, mute_reg | 0x20);
 	return 0;
 }
 
-static int ak4535_set_bias_level(struct snd_soc_codec *codec,
+static int ak4535_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0);
+		snd_soc_component_update_bits(component, AK4535_DAC, 0x20, 0);
 		break;
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0x20);
+		snd_soc_component_update_bits(component, AK4535_DAC, 0x20, 0x20);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0x80);
-		snd_soc_update_bits(codec, AK4535_PM2, 0x80, 0);
+		snd_soc_component_update_bits(component, AK4535_PM1, 0x80, 0x80);
+		snd_soc_component_update_bits(component, AK4535_PM2, 0x80, 0);
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0);
+		snd_soc_component_update_bits(component, AK4535_PM1, 0x80, 0);
 		break;
 	}
 	return 0;
@@ -372,9 +372,9 @@ static struct snd_soc_dai_driver ak4535_dai = {
 	.ops = &ak4535_dai_ops,
 };
 
-static int ak4535_resume(struct snd_soc_codec *codec)
+static int ak4535_resume(struct snd_soc_component *component)
 {
-	snd_soc_cache_sync(codec);
+	snd_soc_component_cache_sync(component);
 	return 0;
 }
 
@@ -390,19 +390,20 @@ static const struct regmap_config ak4535_regmap = {
 	.num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
-	.resume =	ak4535_resume,
-	.set_bias_level = ak4535_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= ak4535_snd_controls,
-		.num_controls		= ARRAY_SIZE(ak4535_snd_controls),
-		.dapm_widgets		= ak4535_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ak4535_dapm_widgets),
-		.dapm_routes		= ak4535_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(ak4535_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ak4535 = {
+	.resume			= ak4535_resume,
+	.set_bias_level		= ak4535_set_bias_level,
+	.controls		= ak4535_snd_controls,
+	.num_controls		= ARRAY_SIZE(ak4535_snd_controls),
+	.dapm_widgets		= ak4535_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak4535_dapm_widgets),
+	.dapm_routes		= ak4535_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(ak4535_audio_map),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ak4535_i2c_probe(struct i2c_client *i2c,
@@ -425,18 +426,12 @@ static int ak4535_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, ak4535);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_ak4535, &ak4535_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_ak4535, &ak4535_dai, 1);
 
 	return ret;
 }
 
-static int ak4535_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id ak4535_i2c_id[] = {
 	{ "ak4535", 0 },
 	{ }
@@ -448,7 +443,6 @@ static struct i2c_driver ak4535_i2c_driver = {
 		.name = "ak4535",
 	},
 	.probe =    ak4535_i2c_probe,
-	.remove =   ak4535_i2c_remove,
 	.id_table = ak4535_i2c_id,
 };
 
diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c
index 0bb4fe5..b7ee1340 100644
--- a/sound/soc/codecs/ak4554.c
+++ b/sound/soc/codecs/ak4554.c
@@ -64,28 +64,24 @@ static struct snd_soc_dai_driver ak4554_dai = {
 	.symmetric_rates = 1,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4554 = {
-	.component_driver = {
-		.dapm_widgets		= ak4554_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ak4554_dapm_widgets),
-		.dapm_routes		= ak4554_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ak4554_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ak4554 = {
+	.dapm_widgets		= ak4554_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak4554_dapm_widgets),
+	.dapm_routes		= ak4554_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ak4554_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ak4554_soc_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-				      &soc_codec_dev_ak4554,
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &soc_component_dev_ak4554,
 				      &ak4554_dai, 1);
 }
 
-static int ak4554_soc_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 static const struct of_device_id ak4554_of_match[] = {
 	{ .compatible = "asahi-kasei,ak4554" },
 	{},
@@ -98,7 +94,6 @@ static struct platform_driver ak4554_driver = {
 		.of_match_table = ak4554_of_match,
 	},
 	.probe	= ak4554_soc_probe,
-	.remove	= ak4554_soc_remove,
 };
 module_platform_driver(ak4554_driver);
 
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index 3d1cf47..8523ff9 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -243,9 +243,9 @@ static const struct snd_soc_dapm_route ak4613_intercon[] = {
 static void ak4613_dai_shutdown(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
-	struct device *dev = codec->dev;
+	struct snd_soc_component *component = dai->component;
+	struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
+	struct device *dev = component->dev;
 
 	mutex_lock(&priv->lock);
 	priv->cnt--;
@@ -305,8 +305,8 @@ static void ak4613_hw_constraints(struct ak4613_priv *priv,
 static int ak4613_dai_startup(struct snd_pcm_substream *substream,
 			      struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 
 	priv->cnt++;
 
@@ -318,8 +318,8 @@ static int ak4613_dai_startup(struct snd_pcm_substream *substream,
 static int ak4613_dai_set_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 
 	priv->sysclk = freq;
 
@@ -328,8 +328,8 @@ static int ak4613_dai_set_sysclk(struct snd_soc_dai *codec_dai,
 
 static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 
 	fmt &= SND_SOC_DAIFMT_FORMAT_MASK;
 
@@ -366,10 +366,10 @@ static int ak4613_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;
-	struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 	const struct ak4613_interface *iface;
-	struct device *dev = codec->dev;
+	struct device *dev = component->dev;
 	unsigned int width = params_width(params);
 	unsigned int fmt = priv->fmt;
 	unsigned int rate;
@@ -434,11 +434,11 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
 
 	fmt_ctrl = AUDIO_IFACE_TO_VAL(iface);
 
-	snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl);
-	snd_soc_update_bits(codec, CTRL2, DFS_MASK, ctrl2);
+	snd_soc_component_update_bits(component, CTRL1, FMT_MASK, fmt_ctrl);
+	snd_soc_component_update_bits(component, CTRL2, DFS_MASK, ctrl2);
 
-	snd_soc_update_bits(codec, ICTRL, ICTRL_MASK, priv->ic);
-	snd_soc_update_bits(codec, OCTRL, OCTRL_MASK, priv->oc);
+	snd_soc_component_update_bits(component, ICTRL, ICTRL_MASK, priv->ic);
+	snd_soc_component_update_bits(component, OCTRL, OCTRL_MASK, priv->oc);
 
 hw_params_end:
 	if (ret < 0)
@@ -447,7 +447,7 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
 	return ret;
 }
 
-static int ak4613_set_bias_level(struct snd_soc_codec *codec,
+static int ak4613_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	u8 mgmt1 = 0;
@@ -467,7 +467,7 @@ static int ak4613_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	}
 
-	snd_soc_write(codec, PW_MGMT1, mgmt1);
+	snd_soc_component_write(component, PW_MGMT1, mgmt1);
 
 	return 0;
 }
@@ -504,8 +504,8 @@ static void ak4613_dummy_write(struct work_struct *work)
 static int ak4613_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 			      struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 
 	/*
 	 * FIXME
@@ -537,7 +537,7 @@ static int ak4613_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
 		return  0;
 
-	priv->component = &codec->component;
+	priv->component = component;
 	schedule_work(&priv->dummy_write_work);
 
 	return 0;
@@ -582,35 +582,36 @@ static struct snd_soc_dai_driver ak4613_dai = {
 	.symmetric_rates = 1,
 };
 
-static int ak4613_suspend(struct snd_soc_codec *codec)
+static int ak4613_suspend(struct snd_soc_component *component)
 {
-	struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+	struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 
 	regcache_cache_only(regmap, true);
 	regcache_mark_dirty(regmap);
 	return 0;
 }
 
-static int ak4613_resume(struct snd_soc_codec *codec)
+static int ak4613_resume(struct snd_soc_component *component)
 {
-	struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+	struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 
 	regcache_cache_only(regmap, false);
 	return regcache_sync(regmap);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
+static const struct snd_soc_component_driver soc_component_dev_ak4613 = {
 	.suspend		= ak4613_suspend,
 	.resume			= ak4613_resume,
 	.set_bias_level		= ak4613_set_bias_level,
-	.component_driver = {
-		.controls		= ak4613_snd_controls,
-		.num_controls		= ARRAY_SIZE(ak4613_snd_controls),
-		.dapm_widgets		= ak4613_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ak4613_dapm_widgets),
-		.dapm_routes		= ak4613_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(ak4613_intercon),
-	},
+	.controls		= ak4613_snd_controls,
+	.num_controls		= ARRAY_SIZE(ak4613_snd_controls),
+	.dapm_widgets		= ak4613_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak4613_dapm_widgets),
+	.dapm_routes		= ak4613_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(ak4613_intercon),
+	.idle_bias_on		= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static void ak4613_parse_of(struct ak4613_priv *priv,
@@ -677,13 +678,12 @@ static int ak4613_i2c_probe(struct i2c_client *i2c,
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return snd_soc_register_codec(dev, &soc_codec_dev_ak4613,
+	return devm_snd_soc_register_component(dev, &soc_component_dev_ak4613,
 				      &ak4613_dai, 1);
 }
 
 static int ak4613_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index 60142ff..05869be 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -70,9 +70,9 @@ static const struct reg_default ak4641_reg_defaults[] = {
 
 static const int deemph_settings[] = {44100, 0, 48000, 32000};
 
-static int ak4641_set_deemph(struct snd_soc_codec *codec)
+static int ak4641_set_deemph(struct snd_soc_component *component)
 {
-	struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+	struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
 	int i, best = 0;
 
 	for (i = 0 ; i < ARRAY_SIZE(deemph_settings); i++) {
@@ -86,16 +86,16 @@ static int ak4641_set_deemph(struct snd_soc_codec *codec)
 			best = i;
 	}
 
-	dev_dbg(codec->dev, "Set deemphasis %d\n", best);
+	dev_dbg(component->dev, "Set deemphasis %d\n", best);
 
-	return snd_soc_update_bits(codec, AK4641_DAC, 0x3, best);
+	return snd_soc_component_update_bits(component, AK4641_DAC, 0x3, best);
 }
 
 static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
 	int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
@@ -103,14 +103,14 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
 
 	ak4641->deemph = deemph;
 
-	return ak4641_set_deemph(codec);
+	return ak4641_set_deemph(component);
 }
 
 static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = ak4641->deemph;
 	return 0;
@@ -307,8 +307,8 @@ static const struct snd_soc_dapm_route ak4641_audio_map[] = {
 static int ak4641_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
 
 	ak4641->sysclk = freq;
 	return 0;
@@ -318,8 +318,8 @@ static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
 	int rate = params_rate(params), fs = 256;
 	u8 mode2;
 
@@ -340,16 +340,16 @@ static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
 		mode2 = (0x0 << 5);
 		break;
 	default:
-		dev_err(codec->dev, "Error: unsupported fs=%d\n", fs);
+		dev_err(component->dev, "Error: unsupported fs=%d\n", fs);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, AK4641_MODE2, (0x3 << 5), mode2);
+	snd_soc_component_update_bits(component, AK4641_MODE2, (0x3 << 5), mode2);
 
 	/* Update de-emphasis filter for the new rate */
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		ak4641->playback_fs = rate;
-		ak4641_set_deemph(codec);
+		ak4641_set_deemph(component);
 	}
 
 	return 0;
@@ -358,7 +358,7 @@ static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
 static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
 				  unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u8 btif;
 	int ret;
 
@@ -380,7 +380,7 @@ static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	ret = snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif);
+	ret = snd_soc_component_update_bits(component, AK4641_BTIF, (0x3 << 5), btif);
 	if (ret < 0)
 		return ret;
 
@@ -390,7 +390,7 @@ static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u8 mode1 = 0;
 
 	/* interface format */
@@ -405,34 +405,34 @@ static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	return snd_soc_write(codec, AK4641_MODE1, mode1);
+	return snd_soc_component_write(component, AK4641_MODE1, mode1);
 }
 
 static int ak4641_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	return snd_soc_update_bits(codec, AK4641_DAC, 0x20, mute ? 0x20 : 0);
+	return snd_soc_component_update_bits(component, AK4641_DAC, 0x20, mute ? 0x20 : 0);
 }
 
-static int ak4641_set_bias_level(struct snd_soc_codec *codec,
+static int ak4641_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
-	struct ak4641_platform_data *pdata = codec->dev->platform_data;
+	struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
+	struct ak4641_platform_data *pdata = component->dev->platform_data;
 	int ret;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		/* unmute */
-		snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0);
+		snd_soc_component_update_bits(component, AK4641_DAC, 0x20, 0);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		/* mute */
-		snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
+		snd_soc_component_update_bits(component, AK4641_DAC, 0x20, 0x20);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			if (pdata && gpio_is_valid(pdata->gpio_power))
 				gpio_set_value(pdata->gpio_power, 1);
 			mdelay(1);
@@ -442,16 +442,16 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
 
 			ret = regcache_sync(ak4641->regmap);
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to sync cache: %d\n", ret);
 				return ret;
 			}
 		}
-		snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0x80);
-		snd_soc_update_bits(codec, AK4641_PM2, 0x80, 0);
+		snd_soc_component_update_bits(component, AK4641_PM1, 0x80, 0x80);
+		snd_soc_component_update_bits(component, AK4641_PM2, 0x80, 0);
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0);
+		snd_soc_component_update_bits(component, AK4641_PM1, 0x80, 0);
 		if (pdata && gpio_is_valid(pdata->gpio_npdn))
 			gpio_set_value(pdata->gpio_npdn, 0);
 		if (pdata && gpio_is_valid(pdata->gpio_power))
@@ -524,17 +524,19 @@ static struct snd_soc_dai_driver ak4641_dai[] = {
 },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
-	.component_driver = {
-		.controls		= ak4641_snd_controls,
-		.num_controls		= ARRAY_SIZE(ak4641_snd_controls),
-		.dapm_widgets		= ak4641_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ak4641_dapm_widgets),
-		.dapm_routes		= ak4641_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(ak4641_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ak4641 = {
+	.controls		= ak4641_snd_controls,
+	.num_controls		= ARRAY_SIZE(ak4641_snd_controls),
+	.dapm_widgets		= ak4641_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak4641_dapm_widgets),
+	.dapm_routes		= ak4641_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(ak4641_audio_map),
 	.set_bias_level		= ak4641_set_bias_level,
-	.suspend_bias_off	= true,
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config ak4641_regmap = {
@@ -583,7 +585,8 @@ static int ak4641_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, ak4641);
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				&soc_component_dev_ak4641,
 				ak4641_dai, ARRAY_SIZE(ak4641_dai));
 	if (ret != 0)
 		goto err_gpio2;
@@ -608,8 +611,6 @@ static int ak4641_i2c_remove(struct i2c_client *i2c)
 {
 	struct ak4641_platform_data *pdata = i2c->dev.platform_data;
 
-	snd_soc_unregister_codec(&i2c->dev);
-
 	if (pdata) {
 		if (gpio_is_valid(pdata->gpio_power)) {
 			gpio_set_value(pdata->gpio_power, 0);
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 29530c5..6050559 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -178,19 +178,19 @@ static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
 static int ak4642_lout_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMD:
 	case SND_SOC_DAPM_PRE_PMU:
 		/* Power save mode ON */
-		snd_soc_update_bits(codec, SG_SL2, LOPS, LOPS);
+		snd_soc_component_update_bits(component, SG_SL2, LOPS, LOPS);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
 	case SND_SOC_DAPM_POST_PMD:
 		/* Power save mode OFF */
 		msleep(300);
-		snd_soc_update_bits(codec, SG_SL2, LOPS, 0);
+		snd_soc_component_update_bits(component, SG_SL2, LOPS, 0);
 		break;
 	}
 
@@ -282,7 +282,7 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
 			      struct snd_soc_dai *dai)
 {
 	int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (is_play) {
 		/*
@@ -295,8 +295,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
 		 * This operation came from example code of
 		 * "ASAHI KASEI AK4642" (japanese) manual p97.
 		 */
-		snd_soc_write(codec, L_IVC, 0x91); /* volume */
-		snd_soc_write(codec, R_IVC, 0x91); /* volume */
+		snd_soc_component_write(component, L_IVC, 0x91); /* volume */
+		snd_soc_component_write(component, R_IVC, 0x91); /* volume */
 	} else {
 		/*
 		 * start stereo input
@@ -311,11 +311,11 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
 		 * This operation came from example code of
 		 * "ASAHI KASEI AK4642" (japanese) manual p94.
 		 */
-		snd_soc_update_bits(codec, SG_SL1, PMMP | MGAIN0, PMMP | MGAIN0);
-		snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
-		snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
-		snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL);
-		snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
+		snd_soc_component_update_bits(component, SG_SL1, PMMP | MGAIN0, PMMP | MGAIN0);
+		snd_soc_component_write(component, TIMER, ZTM(0x3) | WTM(0x3));
+		snd_soc_component_write(component, ALC_CTL1, ALC | LMTH0);
+		snd_soc_component_update_bits(component, PW_MGMT1, PMADL, PMADL);
+		snd_soc_component_update_bits(component, PW_MGMT3, PMADR, PMADR);
 	}
 
 	return 0;
@@ -325,22 +325,22 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
 	int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (is_play) {
 	} else {
 		/* stop stereo input */
-		snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
-		snd_soc_update_bits(codec, PW_MGMT3, PMADR, 0);
-		snd_soc_update_bits(codec, ALC_CTL1, ALC, 0);
+		snd_soc_component_update_bits(component, PW_MGMT1, PMADL, 0);
+		snd_soc_component_update_bits(component, PW_MGMT3, PMADR, 0);
+		snd_soc_component_update_bits(component, ALC_CTL1, ALC, 0);
 	}
 }
 
 static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
 	int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct ak4642_priv *priv = snd_soc_component_get_drvdata(component);
 	u8 pll;
 	int extended_freq = 0;
 
@@ -382,14 +382,14 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
 	if (extended_freq && !priv->drvdata->extended_frequencies)
 		return -EINVAL;
 
-	snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll);
+	snd_soc_component_update_bits(component, MD_CTL1, PLL_MASK, pll);
 
 	return 0;
 }
 
 static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 data;
 	u8 bcko;
 
@@ -407,8 +407,8 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
-	snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
+	snd_soc_component_update_bits(component, PW_MGMT2, MS | MCKO | PMPLL, data);
+	snd_soc_component_update_bits(component, MD_CTL1, BCKO_MASK, bcko);
 
 	/* format type */
 	data = 0;
@@ -425,12 +425,12 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
+	snd_soc_component_update_bits(component, MD_CTL1, DIF_MASK, data);
 
 	return 0;
 }
 
-static int ak4642_set_mcko(struct snd_soc_codec *codec,
+static int ak4642_set_mcko(struct snd_soc_component *component,
 			   u32 frequency)
 {
 	static const u32 fs_list[] = {
@@ -458,7 +458,7 @@ static int ak4642_set_mcko(struct snd_soc_codec *codec,
 	for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) {
 		for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) {
 			if (frequency == ps_list[ps] * fs_list[fs]) {
-				snd_soc_write(codec, MD_CTL2,
+				snd_soc_component_write(component, MD_CTL2,
 					      PSs(ps) | FSs(fs));
 				return 0;
 			}
@@ -472,25 +472,25 @@ static int ak4642_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;
-	struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak4642_priv *priv = snd_soc_component_get_drvdata(component);
 	u32 rate = clk_get_rate(priv->mcko);
 
 	if (!rate)
 		rate = params_rate(params) * 256;
 
-	return ak4642_set_mcko(codec, rate);
+	return ak4642_set_mcko(component, rate);
 }
 
-static int ak4642_set_bias_level(struct snd_soc_codec *codec,
+static int ak4642_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, PW_MGMT1, 0x00);
+		snd_soc_component_write(component, PW_MGMT1, 0x00);
 		break;
 	default:
-		snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
+		snd_soc_component_update_bits(component, PW_MGMT1, PMVCM, PMVCM);
 		break;
 	}
 
@@ -523,46 +523,47 @@ static struct snd_soc_dai_driver ak4642_dai = {
 	.symmetric_rates = 1,
 };
 
-static int ak4642_suspend(struct snd_soc_codec *codec)
+static int ak4642_suspend(struct snd_soc_component *component)
 {
-	struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+	struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 
 	regcache_cache_only(regmap, true);
 	regcache_mark_dirty(regmap);
 	return 0;
 }
 
-static int ak4642_resume(struct snd_soc_codec *codec)
+static int ak4642_resume(struct snd_soc_component *component)
 {
-	struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+	struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 
 	regcache_cache_only(regmap, false);
 	regcache_sync(regmap);
 	return 0;
 }
-static int ak4642_probe(struct snd_soc_codec *codec)
+static int ak4642_probe(struct snd_soc_component *component)
 {
-	struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct ak4642_priv *priv = snd_soc_component_get_drvdata(component);
 
 	if (priv->mcko)
-		ak4642_set_mcko(codec, clk_get_rate(priv->mcko));
+		ak4642_set_mcko(component, clk_get_rate(priv->mcko));
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+static const struct snd_soc_component_driver soc_component_dev_ak4642 = {
 	.probe			= ak4642_probe,
 	.suspend		= ak4642_suspend,
 	.resume			= ak4642_resume,
 	.set_bias_level		= ak4642_set_bias_level,
-	.component_driver = {
-		.controls		= ak4642_snd_controls,
-		.num_controls		= ARRAY_SIZE(ak4642_snd_controls),
-		.dapm_widgets		= ak4642_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ak4642_dapm_widgets),
-		.dapm_routes		= ak4642_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(ak4642_intercon),
-	},
+	.controls		= ak4642_snd_controls,
+	.num_controls		= ARRAY_SIZE(ak4642_snd_controls),
+	.dapm_widgets		= ak4642_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak4642_dapm_widgets),
+	.dapm_routes		= ak4642_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(ak4642_intercon),
+	.idle_bias_on		= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config ak4642_regmap = {
@@ -675,14 +676,8 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return snd_soc_register_codec(dev,
-				      &soc_codec_dev_ak4642, &ak4642_dai, 1);
-}
-
-static int ak4642_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
+	return devm_snd_soc_register_component(dev,
+				&soc_component_dev_ak4642, &ak4642_dai, 1);
 }
 
 static const struct of_device_id ak4642_of_match[] = {
@@ -707,7 +702,6 @@ static struct i2c_driver ak4642_i2c_driver = {
 		.of_match_table = ak4642_of_match,
 	},
 	.probe		= ak4642_i2c_probe,
-	.remove		= ak4642_i2c_remove,
 	.id_table	= ak4642_i2c_id,
 };
 
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index dcfdff5..7133fd6 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -163,15 +163,15 @@ static const struct snd_kcontrol_new ak4671_snd_controls[] = {
 static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
+		snd_soc_component_update_bits(component, AK4671_LOUT2_POWER_MANAGERMENT,
 				    AK4671_MUTEN, AK4671_MUTEN);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
+		snd_soc_component_update_bits(component, AK4671_LOUT2_POWER_MANAGERMENT,
 				    AK4671_MUTEN, 0);
 		break;
 	}
@@ -427,10 +427,10 @@ static int ak4671_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params,
 		struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 fs;
 
-	fs = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
+	fs = snd_soc_component_read32(component, AK4671_PLL_MODE_SELECT0);
 	fs &= ~AK4671_FS;
 
 	switch (params_rate(params)) {
@@ -465,7 +465,7 @@ static int ak4671_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, fs);
+	snd_soc_component_write(component, AK4671_PLL_MODE_SELECT0, fs);
 
 	return 0;
 }
@@ -473,10 +473,10 @@ static int ak4671_hw_params(struct snd_pcm_substream *substream,
 static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 		unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 pll;
 
-	pll = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
+	pll = snd_soc_component_read32(component, AK4671_PLL_MODE_SELECT0);
 	pll &= ~AK4671_PLL;
 
 	switch (freq) {
@@ -511,19 +511,19 @@ static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, pll);
+	snd_soc_component_write(component, AK4671_PLL_MODE_SELECT0, pll);
 
 	return 0;
 }
 
 static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 mode;
 	u8 format;
 
 	/* set master/slave audio interface */
-	mode = snd_soc_read(codec, AK4671_PLL_MODE_SELECT1);
+	mode = snd_soc_component_read32(component, AK4671_PLL_MODE_SELECT1);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -537,7 +537,7 @@ static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	}
 
 	/* interface format */
-	format = snd_soc_read(codec, AK4671_FORMAT_SELECT);
+	format = snd_soc_component_read32(component, AK4671_FORMAT_SELECT);
 	format &= ~AK4671_DIF;
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -557,24 +557,24 @@ static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	}
 
 	/* set mode and format */
-	snd_soc_write(codec, AK4671_PLL_MODE_SELECT1, mode);
-	snd_soc_write(codec, AK4671_FORMAT_SELECT, format);
+	snd_soc_component_write(component, AK4671_PLL_MODE_SELECT1, mode);
+	snd_soc_component_write(component, AK4671_FORMAT_SELECT, format);
 
 	return 0;
 }
 
-static int ak4671_set_bias_level(struct snd_soc_codec *codec,
+static int ak4671_set_bias_level(struct snd_soc_component *component,
 		enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_update_bits(codec, AK4671_AD_DA_POWER_MANAGEMENT,
+		snd_soc_component_update_bits(component, AK4671_AD_DA_POWER_MANAGEMENT,
 				    AK4671_PMVCM, AK4671_PMVCM);
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
+		snd_soc_component_write(component, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
 		break;
 	}
 	return 0;
@@ -610,16 +610,18 @@ static struct snd_soc_dai_driver ak4671_dai = {
 	.ops = &ak4671_dai_ops,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
-	.set_bias_level = ak4671_set_bias_level,
-	.component_driver = {
-		.controls		= ak4671_snd_controls,
-		.num_controls		= ARRAY_SIZE(ak4671_snd_controls),
-		.dapm_widgets		= ak4671_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ak4671_dapm_widgets),
-		.dapm_routes		= ak4671_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(ak4671_intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ak4671 = {
+	.set_bias_level		= ak4671_set_bias_level,
+	.controls		= ak4671_snd_controls,
+	.num_controls		= ARRAY_SIZE(ak4671_snd_controls),
+	.dapm_widgets		= ak4671_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak4671_dapm_widgets),
+	.dapm_routes		= ak4671_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(ak4671_intercon),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config ak4671_regmap = {
@@ -645,17 +647,11 @@ static int ak4671_i2c_probe(struct i2c_client *client,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&client->dev,
-			&soc_codec_dev_ak4671, &ak4671_dai, 1);
+	ret = devm_snd_soc_register_component(&client->dev,
+			&soc_component_dev_ak4671, &ak4671_dai, 1);
 	return ret;
 }
 
-static int ak4671_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id ak4671_i2c_id[] = {
 	{ "ak4671", 0 },
 	{ }
@@ -667,7 +663,6 @@ static struct i2c_driver ak4671_i2c_driver = {
 		.name = "ak4671-codec",
 	},
 	.probe = ak4671_i2c_probe,
-	.remove = ak4671_i2c_remove,
 	.id_table = ak4671_i2c_id,
 };
 
diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c
index d0e16c0..d212960 100644
--- a/sound/soc/codecs/ak5386.c
+++ b/sound/soc/codecs/ak5386.c
@@ -38,30 +38,29 @@ static const struct snd_soc_dapm_route ak5386_dapm_routes[] = {
 	{ "Capture", NULL, "AINR" },
 };
 
-static int ak5386_soc_probe(struct snd_soc_codec *codec)
+static int ak5386_soc_probe(struct snd_soc_component *component)
 {
-	struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
 	return regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 }
 
-static int ak5386_soc_remove(struct snd_soc_codec *codec)
+static void ak5386_soc_remove(struct snd_soc_component *component)
 {
-	struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
 	regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int ak5386_soc_suspend(struct snd_soc_codec *codec)
+static int ak5386_soc_suspend(struct snd_soc_component *component)
 {
-	struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
 	regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
 	return 0;
 }
 
-static int ak5386_soc_resume(struct snd_soc_codec *codec)
+static int ak5386_soc_resume(struct snd_soc_component *component)
 {
-	struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
 	return regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 }
 #else
@@ -69,28 +68,30 @@ static int ak5386_soc_resume(struct snd_soc_codec *codec)
 #define ak5386_soc_resume	NULL
 #endif /* CONFIG_PM */
 
-static const struct snd_soc_codec_driver soc_codec_ak5386 = {
-	.probe = ak5386_soc_probe,
-	.remove = ak5386_soc_remove,
-	.suspend = ak5386_soc_suspend,
-	.resume = ak5386_soc_resume,
-	.component_driver = {
-		.dapm_widgets		= ak5386_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ak5386_dapm_widgets),
-		.dapm_routes		= ak5386_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ak5386_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_ak5386 = {
+	.probe			= ak5386_soc_probe,
+	.remove			= ak5386_soc_remove,
+	.suspend		= ak5386_soc_suspend,
+	.resume			= ak5386_soc_resume,
+	.dapm_widgets		= ak5386_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak5386_dapm_widgets),
+	.dapm_routes		= ak5386_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ak5386_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	format &= SND_SOC_DAIFMT_FORMAT_MASK;
 	if (format != SND_SOC_DAIFMT_LEFT_J &&
 	    format != SND_SOC_DAIFMT_I2S) {
-		dev_err(codec->dev, "Invalid DAI format\n");
+		dev_err(component->dev, "Invalid DAI format\n");
 		return -EINVAL;
 	}
 
@@ -101,8 +102,8 @@ static int ak5386_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
 
 	/*
 	 * From the datasheet:
@@ -123,8 +124,8 @@ static int ak5386_hw_params(struct snd_pcm_substream *substream,
 static int ak5386_hw_free(struct snd_pcm_substream *substream,
 			  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
 
 	if (gpio_is_valid(priv->reset_gpio))
 		gpio_set_value(priv->reset_gpio, 0);
@@ -192,19 +193,12 @@ static int ak5386_probe(struct platform_device *pdev)
 					  "AK5386 Reset"))
 			priv->reset_gpio = -EINVAL;
 
-	return snd_soc_register_codec(dev, &soc_codec_ak5386,
+	return devm_snd_soc_register_component(dev, &soc_component_ak5386,
 				      &ak5386_dai, 1);
 }
 
-static int ak5386_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 static struct platform_driver ak5386_driver = {
 	.probe		= ak5386_probe,
-	.remove		= ak5386_remove,
 	.driver		= {
 		.name	= "ak5386",
 		.of_match_table = of_match_ptr(ak5386_dt_ids),
diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c
new file mode 100644
index 0000000..f4ed5cc
--- /dev/null
+++ b/sound/soc/codecs/ak5558.c
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Audio driver for AK5558 ADC
+//
+// Copyright (C) 2015 Asahi Kasei Microdevices Corporation
+// Copyright 2018 NXP
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#include "ak5558.h"
+
+/* AK5558 Codec Private Data */
+struct ak5558_priv {
+	struct snd_soc_component component;
+	struct regmap *regmap;
+	struct i2c_client *i2c;
+	struct gpio_desc *reset_gpiod; /* Reset & Power down GPIO */
+	int slots;
+	int slot_width;
+};
+
+/* ak5558 register cache & default register settings */
+static const struct reg_default ak5558_reg[] = {
+	{ 0x0, 0xFF },	/*	0x00	AK5558_00_POWER_MANAGEMENT1	*/
+	{ 0x1, 0x01 },	/*	0x01	AK5558_01_POWER_MANAGEMENT2	*/
+	{ 0x2, 0x01 },	/*	0x02	AK5558_02_CONTROL1		*/
+	{ 0x3, 0x00 },	/*	0x03	AK5558_03_CONTROL2		*/
+	{ 0x4, 0x00 },	/*	0x04	AK5558_04_CONTROL3		*/
+	{ 0x5, 0x00 }	/*	0x05	AK5558_05_DSD			*/
+};
+
+static const char * const mono_texts[] = {
+	"8 Slot", "2 Slot", "4 Slot", "1 Slot",
+};
+
+static const struct soc_enum ak5558_mono_enum[] = {
+	SOC_ENUM_SINGLE(AK5558_01_POWER_MANAGEMENT2, 1,
+			ARRAY_SIZE(mono_texts), mono_texts),
+};
+
+static const char * const digfil_texts[] = {
+	"Sharp Roll-Off", "Show Roll-Off",
+	"Short Delay Sharp Roll-Off", "Short Delay Show Roll-Off",
+};
+
+static const struct soc_enum ak5558_adcset_enum[] = {
+	SOC_ENUM_SINGLE(AK5558_04_CONTROL3, 0,
+			ARRAY_SIZE(digfil_texts), digfil_texts),
+};
+
+static const struct snd_kcontrol_new ak5558_snd_controls[] = {
+	SOC_ENUM("AK5558 Monaural Mode", ak5558_mono_enum[0]),
+	SOC_ENUM("AK5558 Digital Filter", ak5558_adcset_enum[0]),
+};
+
+static const struct snd_soc_dapm_widget ak5558_dapm_widgets[] = {
+	/* Analog Input */
+	SND_SOC_DAPM_INPUT("AIN1"),
+	SND_SOC_DAPM_INPUT("AIN2"),
+	SND_SOC_DAPM_INPUT("AIN3"),
+	SND_SOC_DAPM_INPUT("AIN4"),
+	SND_SOC_DAPM_INPUT("AIN5"),
+	SND_SOC_DAPM_INPUT("AIN6"),
+	SND_SOC_DAPM_INPUT("AIN7"),
+	SND_SOC_DAPM_INPUT("AIN8"),
+
+	SND_SOC_DAPM_ADC("ADC Ch1", NULL, AK5558_00_POWER_MANAGEMENT1, 0, 0),
+	SND_SOC_DAPM_ADC("ADC Ch2", NULL, AK5558_00_POWER_MANAGEMENT1, 1, 0),
+	SND_SOC_DAPM_ADC("ADC Ch3", NULL, AK5558_00_POWER_MANAGEMENT1, 2, 0),
+	SND_SOC_DAPM_ADC("ADC Ch4", NULL, AK5558_00_POWER_MANAGEMENT1, 3, 0),
+	SND_SOC_DAPM_ADC("ADC Ch5", NULL, AK5558_00_POWER_MANAGEMENT1, 4, 0),
+	SND_SOC_DAPM_ADC("ADC Ch6", NULL, AK5558_00_POWER_MANAGEMENT1, 5, 0),
+	SND_SOC_DAPM_ADC("ADC Ch7", NULL, AK5558_00_POWER_MANAGEMENT1, 6, 0),
+	SND_SOC_DAPM_ADC("ADC Ch8", NULL, AK5558_00_POWER_MANAGEMENT1, 7, 0),
+
+	SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
+};
+
+static const struct snd_soc_dapm_route ak5558_intercon[] = {
+	{"ADC Ch1", NULL, "AIN1"},
+	{"SDTO", NULL, "ADC Ch1"},
+
+	{"ADC Ch2", NULL, "AIN2"},
+	{"SDTO", NULL, "ADC Ch2"},
+
+	{"ADC Ch3", NULL, "AIN3"},
+	{"SDTO", NULL, "ADC Ch3"},
+
+	{"ADC Ch4", NULL, "AIN4"},
+	{"SDTO", NULL, "ADC Ch4"},
+
+	{"ADC Ch5", NULL, "AIN5"},
+	{"SDTO", NULL, "ADC Ch5"},
+
+	{"ADC Ch6", NULL, "AIN6"},
+	{"SDTO", NULL, "ADC Ch6"},
+
+	{"ADC Ch7", NULL, "AIN7"},
+	{"SDTO", NULL, "ADC Ch7"},
+
+	{"ADC Ch8", NULL, "AIN8"},
+	{"SDTO", NULL, "ADC Ch8"},
+};
+
+static int ak5558_set_mcki(struct snd_soc_component *component)
+{
+	return snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_CKS,
+				   AK5558_CKS_AUTO);
+}
+
+static int ak5558_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct snd_soc_component *component = dai->component;
+	struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
+	u8 bits;
+	int pcm_width = max(params_physical_width(params), ak5558->slot_width);
+
+	/* set master/slave audio interface */
+	bits = snd_soc_component_read32(component, AK5558_02_CONTROL1);
+	bits &= ~AK5558_BITS;
+
+	switch (pcm_width) {
+	case 16:
+		bits |= AK5558_DIF_24BIT_MODE;
+		break;
+	case 32:
+		bits |= AK5558_DIF_32BIT_MODE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_BITS, bits);
+
+	return 0;
+}
+
+static int ak5558_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct snd_soc_component *component = dai->component;
+	u8 format;
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		break;
+	case SND_SOC_DAIFMT_CBS_CFM:
+	case SND_SOC_DAIFMT_CBM_CFS:
+	default:
+		dev_err(dai->dev, "Clock mode unsupported");
+		return -EINVAL;
+	}
+
+	/* set master/slave audio interface */
+	format = snd_soc_component_read32(component, AK5558_02_CONTROL1);
+	format &= ~AK5558_DIF;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		format |= AK5558_DIF_I2S_MODE;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		format |= AK5558_DIF_MSB_MODE;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		format |= AK5558_DIF_MSB_MODE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_DIF, format);
+
+	return 0;
+}
+
+static int ak5558_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots,
+			       int slot_width)
+{
+	struct snd_soc_component *component = dai->component;
+	struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
+	int tdm_mode;
+
+	ak5558->slots = slots;
+	ak5558->slot_width = slot_width;
+
+	switch (slots * slot_width) {
+	case 128:
+		tdm_mode = AK5558_MODE_TDM128;
+		break;
+	case 256:
+		tdm_mode = AK5558_MODE_TDM256;
+		break;
+	case 512:
+		tdm_mode = AK5558_MODE_TDM512;
+		break;
+	default:
+		tdm_mode = AK5558_MODE_NORMAL;
+		break;
+	}
+
+	snd_soc_component_update_bits(component, AK5558_03_CONTROL2, AK5558_MODE_BITS,
+			    tdm_mode);
+	return 0;
+}
+
+#define AK5558_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE |\
+			 SNDRV_PCM_FMTBIT_S24_LE |\
+			 SNDRV_PCM_FMTBIT_S32_LE)
+
+static const unsigned int ak5558_rates[] = {
+	8000, 11025,  16000, 22050,
+	32000, 44100, 48000, 88200,
+	96000, 176400, 192000, 352800,
+	384000, 705600, 768000, 1411200,
+	2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list ak5558_rate_constraints = {
+	.count = ARRAY_SIZE(ak5558_rates),
+	.list = ak5558_rates,
+};
+
+static int ak5558_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	return snd_pcm_hw_constraint_list(substream->runtime, 0,
+					  SNDRV_PCM_HW_PARAM_RATE,
+					  &ak5558_rate_constraints);
+}
+
+static struct snd_soc_dai_ops ak5558_dai_ops = {
+	.startup        = ak5558_startup,
+	.hw_params	= ak5558_hw_params,
+
+	.set_fmt	= ak5558_set_dai_fmt,
+	.set_tdm_slot   = ak5558_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver ak5558_dai = {
+	.name = "ak5558-aif",
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 8,
+		.rates = SNDRV_PCM_RATE_KNOT,
+		.formats = AK5558_FORMATS,
+	},
+	.ops = &ak5558_dai_ops,
+};
+
+static void ak5558_power_off(struct ak5558_priv *ak5558)
+{
+	if (!ak5558->reset_gpiod)
+		return;
+
+	gpiod_set_value_cansleep(ak5558->reset_gpiod, 0);
+	usleep_range(1000, 2000);
+}
+
+static void ak5558_power_on(struct ak5558_priv *ak5558)
+{
+	if (!ak5558->reset_gpiod)
+		return;
+
+	gpiod_set_value_cansleep(ak5558->reset_gpiod, 1);
+	usleep_range(1000, 2000);
+}
+
+static int ak5558_probe(struct snd_soc_component *component)
+{
+	struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
+
+	ak5558_power_on(ak5558);
+	return ak5558_set_mcki(component);
+}
+
+static void ak5558_remove(struct snd_soc_component *component)
+{
+	struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
+
+	ak5558_power_off(ak5558);
+}
+
+static int __maybe_unused ak5558_runtime_suspend(struct device *dev)
+{
+	struct ak5558_priv *ak5558 = dev_get_drvdata(dev);
+
+	regcache_cache_only(ak5558->regmap, true);
+	ak5558_power_off(ak5558);
+
+	return 0;
+}
+
+static int __maybe_unused ak5558_runtime_resume(struct device *dev)
+{
+	struct ak5558_priv *ak5558 = dev_get_drvdata(dev);
+
+	ak5558_power_off(ak5558);
+	ak5558_power_on(ak5558);
+
+	regcache_cache_only(ak5558->regmap, false);
+	regcache_mark_dirty(ak5558->regmap);
+
+	return regcache_sync(ak5558->regmap);
+}
+
+const struct dev_pm_ops ak5558_pm = {
+	SET_RUNTIME_PM_OPS(ak5558_runtime_suspend, ak5558_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
+struct snd_soc_component_driver soc_codec_dev_ak5558 = {
+	.probe			= ak5558_probe,
+	.remove			= ak5558_remove,
+	.controls		= ak5558_snd_controls,
+	.num_controls		= ARRAY_SIZE(ak5558_snd_controls),
+	.dapm_widgets		= ak5558_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ak5558_dapm_widgets),
+	.dapm_routes		= ak5558_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(ak5558_intercon),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
+
+static const struct regmap_config ak5558_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = AK5558_05_DSD,
+	.reg_defaults = ak5558_reg,
+	.num_reg_defaults = ARRAY_SIZE(ak5558_reg),
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static int ak5558_i2c_probe(struct i2c_client *i2c)
+{
+	struct ak5558_priv *ak5558;
+	int ret = 0;
+
+	ak5558 = devm_kzalloc(&i2c->dev, sizeof(*ak5558), GFP_KERNEL);
+	if (!ak5558)
+		return -ENOMEM;
+
+	ak5558->regmap = devm_regmap_init_i2c(i2c, &ak5558_regmap);
+	if (IS_ERR(ak5558->regmap))
+		return PTR_ERR(ak5558->regmap);
+
+	i2c_set_clientdata(i2c, ak5558);
+	ak5558->i2c = i2c;
+
+	ak5558->reset_gpiod = devm_gpiod_get_optional(&i2c->dev, "reset",
+						      GPIOD_OUT_LOW);
+	if (IS_ERR(ak5558->reset_gpiod))
+		return PTR_ERR(ak5558->reset_gpiod);
+
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_codec_dev_ak5558,
+				     &ak5558_dai, 1);
+	if (ret)
+		return ret;
+
+	pm_runtime_enable(&i2c->dev);
+
+	return 0;
+}
+
+static int ak5558_i2c_remove(struct i2c_client *i2c)
+{
+	pm_runtime_disable(&i2c->dev);
+
+	return 0;
+}
+
+static const struct of_device_id ak5558_i2c_dt_ids[] = {
+	{ .compatible = "asahi-kasei,ak5558"},
+	{ }
+};
+
+static struct i2c_driver ak5558_i2c_driver = {
+	.driver = {
+		.name = "ak5558",
+		.of_match_table = of_match_ptr(ak5558_i2c_dt_ids),
+		.pm = &ak5558_pm,
+	},
+	.probe_new = ak5558_i2c_probe,
+	.remove = ak5558_i2c_remove,
+};
+
+module_i2c_driver(ak5558_i2c_driver);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_DESCRIPTION("ASoC AK5558 ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ak5558.h b/sound/soc/codecs/ak5558.h
new file mode 100644
index 0000000..6105908
--- /dev/null
+++ b/sound/soc/codecs/ak5558.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Audio driver header for AK5558
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright 2018 NXP
+ */
+
+#ifndef _AK5558_H
+#define _AK5558_H
+
+#define AK5558_00_POWER_MANAGEMENT1    0x00
+#define AK5558_01_POWER_MANAGEMENT2    0x01
+#define AK5558_02_CONTROL1             0x02
+#define AK5558_03_CONTROL2             0x03
+#define AK5558_04_CONTROL3             0x04
+#define AK5558_05_DSD                  0x05
+
+/* AK5558_02_CONTROL1 fields */
+#define AK5558_DIF			GENMASK(1, 1)
+#define AK5558_DIF_MSB_MODE		(0 << 1)
+#define AK5558_DIF_I2S_MODE		(1 << 1)
+
+#define AK5558_BITS			GENMASK(2, 2)
+#define AK5558_DIF_24BIT_MODE		(0 << 2)
+#define AK5558_DIF_32BIT_MODE		(1 << 2)
+
+#define AK5558_CKS			GENMASK(6, 3)
+#define AK5558_CKS_128FS_192KHZ		(0 << 3)
+#define AK5558_CKS_192FS_192KHZ		(1 << 3)
+#define AK5558_CKS_256FS_48KHZ		(2 << 3)
+#define AK5558_CKS_256FS_96KHZ		(3 << 3)
+#define AK5558_CKS_384FS_96KHZ		(4 << 3)
+#define AK5558_CKS_384FS_48KHZ		(5 << 3)
+#define AK5558_CKS_512FS_48KHZ		(6 << 3)
+#define AK5558_CKS_768FS_48KHZ		(7 << 3)
+#define AK5558_CKS_64FS_384KHZ		(8 << 3)
+#define AK5558_CKS_32FS_768KHZ		(9 << 3)
+#define AK5558_CKS_96FS_384KHZ		(10 << 3)
+#define AK5558_CKS_48FS_768KHZ		(11 << 3)
+#define AK5558_CKS_64FS_768KHZ		(12 << 3)
+#define AK5558_CKS_1024FS_16KHZ		(13 << 3)
+#define AK5558_CKS_AUTO			(15 << 3)
+
+/* AK5558_03_CONTROL2 fields */
+#define AK5558_MODE_BITS	GENMASK(6, 5)
+#define AK5558_MODE_NORMAL	(0 << 5)
+#define AK5558_MODE_TDM128	(1 << 5)
+#define AK5558_MODE_TDM256	(2 << 5)
+#define AK5558_MODE_TDM512	(3 << 5)
+
+#endif
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index 1db965a..981a329 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -47,28 +47,28 @@ struct alc5623_priv {
 	unsigned int jack_det_ctrl;
 };
 
-static inline int alc5623_reset(struct snd_soc_codec *codec)
+static inline int alc5623_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, ALC5623_RESET, 0);
+	return snd_soc_component_write(component, ALC5623_RESET, 0);
 }
 
 static int amp_mixer_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	/* to power-on/off class-d amp generators/speaker */
 	/* need to write to 'index-46h' register :        */
 	/* so write index num (here 0x46) to reg 0x6a     */
 	/* and then 0xffff/0 to reg 0x6c                  */
-	snd_soc_write(codec, ALC5623_HID_CTRL_INDEX, 0x46);
+	snd_soc_component_write(component, ALC5623_HID_CTRL_INDEX, 0x46);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_write(codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
+		snd_soc_component_write(component, ALC5623_HID_CTRL_DATA, 0xFFFF);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_write(codec, ALC5623_HID_CTRL_DATA, 0);
+		snd_soc_component_write(component, ALC5623_HID_CTRL_DATA, 0);
 		break;
 	}
 
@@ -526,7 +526,7 @@ static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
 	int i;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int gbl_clk = 0, pll_div = 0;
 	u16 reg;
 
@@ -534,12 +534,12 @@ static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		return -ENODEV;
 
 	/* Disable PLL power */
-	snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
+	snd_soc_component_update_bits(component, ALC5623_PWR_MANAG_ADD2,
 				ALC5623_PWR_ADD2_PLL,
 				0);
 
 	/* pll is not used in slave mode */
-	reg = snd_soc_read(codec, ALC5623_DAI_CONTROL);
+	reg = snd_soc_component_read32(component, ALC5623_DAI_CONTROL);
 	if (reg & ALC5623_DAI_SDP_SLAVE_MODE)
 		return 0;
 
@@ -575,13 +575,13 @@ static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	if (!pll_div)
 		return -EINVAL;
 
-	snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
-	snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div);
-	snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
+	snd_soc_component_write(component, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
+	snd_soc_component_write(component, ALC5623_PLL_CTRL, pll_div);
+	snd_soc_component_update_bits(component, ALC5623_PWR_MANAG_ADD2,
 				ALC5623_PWR_ADD2_PLL,
 				ALC5623_PWR_ADD2_PLL);
 	gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL;
-	snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
+	snd_soc_component_write(component, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
 
 	return 0;
 }
@@ -604,9 +604,9 @@ static const struct _coeff_div coeff_div[] = {
 	{384*1, 0x0c6b},
 };
 
-static int get_coeff(struct snd_soc_codec *codec, int rate)
+static int get_coeff(struct snd_soc_component *component, int rate)
 {
-	struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+	struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
@@ -622,8 +622,8 @@ static int get_coeff(struct snd_soc_codec *codec, int rate)
 static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case  8192000:
@@ -643,7 +643,7 @@ static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
 
 	/* set master/slave audio interface */
@@ -695,18 +695,18 @@ static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
+	return snd_soc_component_write(component, ALC5623_DAI_CONTROL, iface);
 }
 
 static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 	int coeff, rate;
 	u16 iface;
 
-	iface = snd_soc_read(codec, ALC5623_DAI_CONTROL);
+	iface = snd_soc_component_read32(component, ALC5623_DAI_CONTROL);
 	iface &= ~ALC5623_DAI_I2S_DL_MASK;
 
 	/* bit size */
@@ -728,30 +728,30 @@ static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* set iface & srate */
-	snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
+	snd_soc_component_write(component, ALC5623_DAI_CONTROL, iface);
 	rate = params_rate(params);
-	coeff = get_coeff(codec, rate);
+	coeff = get_coeff(component, rate);
 	if (coeff < 0)
 		return -EINVAL;
 
 	coeff = coeff_div[coeff].regvalue;
-	dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
+	dev_dbg(component->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
 		__func__, alc5623->sysclk, rate, coeff);
-	snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
+	snd_soc_component_write(component, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
 
 	return 0;
 }
 
 static int alc5623_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT;
-	u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute;
+	u16 mute_reg = snd_soc_component_read32(component, ALC5623_MISC_CTRL) & ~hp_mute;
 
 	if (mute)
 		mute_reg |= hp_mute;
 
-	return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg);
+	return snd_soc_component_write(component, ALC5623_MISC_CTRL, mute_reg);
 }
 
 #define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \
@@ -769,60 +769,60 @@ static int alc5623_mute(struct snd_soc_dai *dai, int mute)
 	(ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \
 	| ALC5623_PWR_ADD1_HP_OUT_AMP)
 
-static void enable_power_depop(struct snd_soc_codec *codec)
+static void enable_power_depop(struct snd_soc_component *component)
 {
-	struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+	struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 
-	snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1,
+	snd_soc_component_update_bits(component, ALC5623_PWR_MANAG_ADD1,
 				ALC5623_PWR_ADD1_SOFTGEN_EN,
 				ALC5623_PWR_ADD1_SOFTGEN_EN);
 
-	snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
+	snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
 
-	snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
+	snd_soc_component_update_bits(component, ALC5623_MISC_CTRL,
 				ALC5623_MISC_HP_DEPOP_MODE2_EN,
 				ALC5623_MISC_HP_DEPOP_MODE2_EN);
 
 	msleep(500);
 
-	snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
+	snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
 
 	/* avoid writing '1' into 5622 reserved bits */
 	if (alc5623->id == 0x22)
-		snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
+		snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD1,
 			ALC5623_ADD1_POWER_EN_5622);
 	else
-		snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
+		snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD1,
 			ALC5623_ADD1_POWER_EN);
 
 	/* disable HP Depop2 */
-	snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
+	snd_soc_component_update_bits(component, ALC5623_MISC_CTRL,
 				ALC5623_MISC_HP_DEPOP_MODE2_EN,
 				0);
 
 }
 
-static int alc5623_set_bias_level(struct snd_soc_codec *codec,
+static int alc5623_set_bias_level(struct snd_soc_component *component,
 				      enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		enable_power_depop(codec);
+		enable_power_depop(component);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* everything off except vref/vmid, */
-		snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2,
+		snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD2,
 				ALC5623_PWR_ADD2_VREF);
-		snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3,
+		snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD3,
 				ALC5623_PWR_ADD3_MAIN_BIAS);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* everything off, dac mute, inactive */
-		snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0);
-		snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0);
-		snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
+		snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD2, 0);
+		snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD3, 0);
+		snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD1, 0);
 		break;
 	}
 	return 0;
@@ -862,25 +862,25 @@ static struct snd_soc_dai_driver alc5623_dai = {
 	.ops = &alc5623_dai_ops,
 };
 
-static int alc5623_suspend(struct snd_soc_codec *codec)
+static int alc5623_suspend(struct snd_soc_component *component)
 {
-	struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+	struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(alc5623->regmap, true);
 
 	return 0;
 }
 
-static int alc5623_resume(struct snd_soc_codec *codec)
+static int alc5623_resume(struct snd_soc_component *component)
 {
-	struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+	struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	/* Sync reg_cache with the hardware */
 	regcache_cache_only(alc5623->regmap, false);
 	ret = regcache_sync(alc5623->regmap);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to sync register cache: %d\n",
+		dev_err(component->dev, "Failed to sync register cache: %d\n",
 			ret);
 		regcache_cache_only(alc5623->regmap, true);
 		return ret;
@@ -889,41 +889,41 @@ static int alc5623_resume(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int alc5623_probe(struct snd_soc_codec *codec)
+static int alc5623_probe(struct snd_soc_component *component)
 {
-	struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-	alc5623_reset(codec);
+	alc5623_reset(component);
 
 	if (alc5623->add_ctrl) {
-		snd_soc_write(codec, ALC5623_ADD_CTRL_REG,
+		snd_soc_component_write(component, ALC5623_ADD_CTRL_REG,
 				alc5623->add_ctrl);
 	}
 
 	if (alc5623->jack_det_ctrl) {
-		snd_soc_write(codec, ALC5623_JACK_DET_CTRL,
+		snd_soc_component_write(component, ALC5623_JACK_DET_CTRL,
 				alc5623->jack_det_ctrl);
 	}
 
 	switch (alc5623->id) {
 	case 0x21:
-		snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls,
+		snd_soc_add_component_controls(component, alc5621_vol_snd_controls,
 			ARRAY_SIZE(alc5621_vol_snd_controls));
 		break;
 	case 0x22:
-		snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls,
+		snd_soc_add_component_controls(component, alc5622_vol_snd_controls,
 			ARRAY_SIZE(alc5622_vol_snd_controls));
 		break;
 	case 0x23:
-		snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls,
+		snd_soc_add_component_controls(component, alc5623_vol_snd_controls,
 			ARRAY_SIZE(alc5623_vol_snd_controls));
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	snd_soc_add_codec_controls(codec, alc5623_snd_controls,
+	snd_soc_add_component_controls(component, alc5623_snd_controls,
 			ARRAY_SIZE(alc5623_snd_controls));
 
 	snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
@@ -951,12 +951,16 @@ static int alc5623_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_device_alc5623 = {
-	.probe = alc5623_probe,
-	.suspend = alc5623_suspend,
-	.resume = alc5623_resume,
-	.set_bias_level = alc5623_set_bias_level,
-	.suspend_bias_off = true,
+static const struct snd_soc_component_driver soc_component_device_alc5623 = {
+	.probe			= alc5623_probe,
+	.suspend		= alc5623_suspend,
+	.resume			= alc5623_resume,
+	.set_bias_level		= alc5623_set_bias_level,
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config alc5623_regmap = {
@@ -1052,20 +1056,14 @@ static int alc5623_i2c_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, alc5623);
 
-	ret =  snd_soc_register_codec(&client->dev,
-		&soc_codec_device_alc5623, &alc5623_dai, 1);
+	ret =  devm_snd_soc_register_component(&client->dev,
+		&soc_component_device_alc5623, &alc5623_dai, 1);
 	if (ret != 0)
 		dev_err(&client->dev, "Failed to register codec: %d\n", ret);
 
 	return ret;
 }
 
-static int alc5623_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id alc5623_i2c_table[] = {
 	{"alc5621", 0x21},
 	{"alc5622", 0x22},
@@ -1087,7 +1085,6 @@ static struct i2c_driver alc5623_i2c_driver = {
 		.of_match_table = of_match_ptr(alc5623_of_match),
 	},
 	.probe = alc5623_i2c_probe,
-	.remove =  alc5623_i2c_remove,
 	.id_table = alc5623_i2c_table,
 };
 
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index adb80d8..08034a6 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -116,20 +116,20 @@ static inline int alc5632_reset(struct regmap *map)
 static int amp_mixer_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	/* to power-on/off class-d amp generators/speaker */
 	/* need to write to 'index-46h' register :        */
 	/* so write index num (here 0x46) to reg 0x6a     */
 	/* and then 0xffff/0 to reg 0x6c                  */
-	snd_soc_write(codec, ALC5632_HID_CTRL_INDEX, 0x46);
+	snd_soc_component_write(component, ALC5632_HID_CTRL_INDEX, 0x46);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_write(codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
+		snd_soc_component_write(component, ALC5632_HID_CTRL_DATA, 0xFFFF);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_write(codec, ALC5632_HID_CTRL_DATA, 0);
+		snd_soc_component_write(component, ALC5632_HID_CTRL_DATA, 0);
 		break;
 	}
 
@@ -681,7 +681,7 @@ static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
 	int i;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int gbl_clk = 0, pll_div = 0;
 	u16 reg;
 
@@ -689,15 +689,15 @@ static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		return -EINVAL;
 
 	/* Disable PLL power */
-	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+	snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
 				ALC5632_PWR_ADD2_PLL1,
 				0);
-	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+	snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
 				ALC5632_PWR_ADD2_PLL2,
 				0);
 
 	/* pll is not used in slave mode */
-	reg = snd_soc_read(codec, ALC5632_DAI_CONTROL);
+	reg = snd_soc_component_read32(component, ALC5632_DAI_CONTROL);
 	if (reg & ALC5632_DAI_SDP_SLAVE_MODE)
 		return 0;
 
@@ -745,19 +745,19 @@ static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		return -EINVAL;
 
 	/* choose MCLK/BCLK/VBCLK */
-	snd_soc_write(codec, ALC5632_GPCR2, gbl_clk);
+	snd_soc_component_write(component, ALC5632_GPCR2, gbl_clk);
 	/* choose PLL1 clock rate */
-	snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div);
+	snd_soc_component_write(component, ALC5632_PLL1_CTRL, pll_div);
 	/* enable PLL1 */
-	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+	snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
 				ALC5632_PWR_ADD2_PLL1,
 				ALC5632_PWR_ADD2_PLL1);
 	/* enable PLL2 */
-	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+	snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
 				ALC5632_PWR_ADD2_PLL2,
 				ALC5632_PWR_ADD2_PLL2);
 	/* use PLL1 as main SYSCLK */
-	snd_soc_update_bits(codec, ALC5632_GPCR1,
+	snd_soc_component_update_bits(component, ALC5632_GPCR1,
 			ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,
 			ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);
 
@@ -775,9 +775,9 @@ static const struct _coeff_div coeff_div[] = {
 	{512*1, 0x3075},
 };
 
-static int get_coeff(struct snd_soc_codec *codec, int rate)
+static int get_coeff(struct snd_soc_component *component, int rate)
 {
-	struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+	struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
@@ -793,8 +793,8 @@ static int get_coeff(struct snd_soc_codec *codec, int rate)
 static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case  4096000:
@@ -815,7 +815,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
 
 	/* set master/slave audio interface */
@@ -864,17 +864,17 @@ static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	return snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
+	return snd_soc_component_write(component, ALC5632_DAI_CONTROL, iface);
 }
 
 static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int coeff, rate;
 	u16 iface;
 
-	iface = snd_soc_read(codec, ALC5632_DAI_CONTROL);
+	iface = snd_soc_component_read32(component, ALC5632_DAI_CONTROL);
 	iface &= ~ALC5632_DAI_I2S_DL_MASK;
 
 	/* bit size */
@@ -893,29 +893,29 @@ static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* set iface & srate */
-	snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
+	snd_soc_component_write(component, ALC5632_DAI_CONTROL, iface);
 	rate = params_rate(params);
-	coeff = get_coeff(codec, rate);
+	coeff = get_coeff(component, rate);
 	if (coeff < 0)
 		return -EINVAL;
 
 	coeff = coeff_div[coeff].regvalue;
-	snd_soc_write(codec, ALC5632_DAC_CLK_CTRL1, coeff);
+	snd_soc_component_write(component, ALC5632_DAC_CLK_CTRL1, coeff);
 
 	return 0;
 }
 
 static int alc5632_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L
 						|ALC5632_MISC_HP_DEPOP_MUTE_R;
-	u16 mute_reg = snd_soc_read(codec, ALC5632_MISC_CTRL) & ~hp_mute;
+	u16 mute_reg = snd_soc_component_read32(component, ALC5632_MISC_CTRL) & ~hp_mute;
 
 	if (mute)
 		mute_reg |= hp_mute;
 
-	return snd_soc_write(codec, ALC5632_MISC_CTRL, mute_reg);
+	return snd_soc_component_write(component, ALC5632_MISC_CTRL, mute_reg);
 }
 
 #define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)
@@ -929,73 +929,73 @@ static int alc5632_mute(struct snd_soc_dai *dai, int mute)
 		| ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \
 		| ALC5632_PWR_ADD1_MAIN_BIAS)
 
-static void enable_power_depop(struct snd_soc_codec *codec)
+static void enable_power_depop(struct snd_soc_component *component)
 {
-	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+	snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,
 				ALC5632_PWR_ADD1_SOFTGEN_EN,
 				ALC5632_PWR_ADD1_SOFTGEN_EN);
 
-	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
+	snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD3,
 				ALC5632_ADD3_POWER_EN,
 				ALC5632_ADD3_POWER_EN);
 
-	snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
+	snd_soc_component_update_bits(component, ALC5632_MISC_CTRL,
 				ALC5632_MISC_HP_DEPOP_MODE2_EN,
 				ALC5632_MISC_HP_DEPOP_MODE2_EN);
 
 	/* "normal" mode: 0 @ 26 */
 	/* set all PR0-7 mixers to 0 */
-	snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
+	snd_soc_component_update_bits(component, ALC5632_PWR_DOWN_CTRL_STATUS,
 				ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
 				0);
 
 	msleep(500);
 
-	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+	snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
 				ALC5632_ADD2_POWER_EN,
 				ALC5632_ADD2_POWER_EN);
 
-	snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+	snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,
 				ALC5632_ADD1_POWER_EN,
 				ALC5632_ADD1_POWER_EN);
 
 	/* disable HP Depop2 */
-	snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
+	snd_soc_component_update_bits(component, ALC5632_MISC_CTRL,
 				ALC5632_MISC_HP_DEPOP_MODE2_EN,
 				0);
 
 }
 
-static int alc5632_set_bias_level(struct snd_soc_codec *codec,
+static int alc5632_set_bias_level(struct snd_soc_component *component,
 				      enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		enable_power_depop(codec);
+		enable_power_depop(component);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* everything off except vref/vmid, */
-		snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+		snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,
 				ALC5632_PWR_MANAG_ADD1_MASK,
 				ALC5632_PWR_ADD1_MAIN_BIAS);
-		snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+		snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
 				ALC5632_PWR_MANAG_ADD2_MASK,
 				ALC5632_PWR_ADD2_VREF);
 		/* "normal" mode: 0 @ 26 */
-		snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
+		snd_soc_component_update_bits(component, ALC5632_PWR_DOWN_CTRL_STATUS,
 				ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
 				0xffff ^ (ALC5632_PWR_VREF_PR3
 				| ALC5632_PWR_VREF_PR2));
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* everything off, dac mute, inactive */
-		snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+		snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
 				ALC5632_PWR_MANAG_ADD2_MASK, 0);
-		snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
+		snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD3,
 				ALC5632_PWR_MANAG_ADD3_MASK, 0);
-		snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+		snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,
 				ALC5632_PWR_MANAG_ADD1_MASK, 0);
 		break;
 	}
@@ -1038,9 +1038,9 @@ static struct snd_soc_dai_driver alc5632_dai = {
 };
 
 #ifdef CONFIG_PM
-static int alc5632_resume(struct snd_soc_codec *codec)
+static int alc5632_resume(struct snd_soc_component *component)
 {
-	struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+	struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);
 
 	regcache_sync(alc5632->regmap);
 
@@ -1050,13 +1050,13 @@ static int alc5632_resume(struct snd_soc_codec *codec)
 #define	alc5632_resume	NULL
 #endif
 
-static int alc5632_probe(struct snd_soc_codec *codec)
+static int alc5632_probe(struct snd_soc_component *component)
 {
-	struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+	struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);
 
 	switch (alc5632->id) {
 	case 0x5c:
-		snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls,
+		snd_soc_add_component_controls(component, alc5632_vol_snd_controls,
 			ARRAY_SIZE(alc5632_vol_snd_controls));
 		break;
 	default:
@@ -1066,20 +1066,21 @@ static int alc5632_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_device_alc5632 = {
-	.probe = alc5632_probe,
-	.resume = alc5632_resume,
-	.set_bias_level = alc5632_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= alc5632_snd_controls,
-		.num_controls		= ARRAY_SIZE(alc5632_snd_controls),
-		.dapm_widgets		= alc5632_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(alc5632_dapm_widgets),
-		.dapm_routes		= alc5632_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(alc5632_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_device_alc5632 = {
+	.probe			= alc5632_probe,
+	.resume			= alc5632_resume,
+	.set_bias_level		= alc5632_set_bias_level,
+	.controls		= alc5632_snd_controls,
+	.num_controls		= ARRAY_SIZE(alc5632_snd_controls),
+	.dapm_widgets		= alc5632_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(alc5632_dapm_widgets),
+	.dapm_routes		= alc5632_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(alc5632_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config alc5632_regmap = {
@@ -1151,23 +1152,17 @@ static int alc5632_i2c_probe(struct i2c_client *client,
 		return -EINVAL;
 	}
 
-	ret = snd_soc_register_codec(&client->dev,
-		&soc_codec_device_alc5632, &alc5632_dai, 1);
+	ret = devm_snd_soc_register_component(&client->dev,
+		&soc_component_device_alc5632, &alc5632_dai, 1);
 
 	if (ret < 0) {
-		dev_err(&client->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&client->dev, "Failed to register component: %d\n", ret);
 		return ret;
 	}
 
 	return ret;
 }
 
-static int alc5632_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id alc5632_i2c_table[] = {
 	{"alc5632", 0x5c},
 	{}
@@ -1187,7 +1182,6 @@ static struct i2c_driver alc5632_i2c_driver = {
 		.of_match_table = of_match_ptr(alc5632_of_match),
 	},
 	.probe = alc5632_i2c_probe,
-	.remove =  alc5632_i2c_remove,
 	.id_table = alc5632_i2c_table,
 };
 
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index b3375e1..5727ea0 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -84,13 +84,14 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol,
 			  int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	int val;
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
+		val = snd_soc_component_read32(component,
+					       ARIZONA_INTERRUPT_RAW_STATUS_3);
 		if (val & ARIZONA_SPK_OVERHEAT_STS) {
 			dev_crit(arizona->dev,
 				 "Speaker not enabled due to temperature\n");
@@ -169,10 +170,10 @@ static const struct snd_soc_dapm_widget arizona_spkr =
 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
 
-int arizona_init_spk(struct snd_soc_codec *codec)
+int arizona_init_spk(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int ret;
 
@@ -238,10 +239,10 @@ static const struct snd_soc_dapm_route arizona_mono_routes[] = {
 	{ "OUT6R", NULL, "OUT6L" },
 };
 
-int arizona_init_mono(struct snd_soc_codec *codec)
+int arizona_init_mono(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int i;
 
@@ -255,11 +256,9 @@ int arizona_init_mono(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(arizona_init_mono);
 
-int arizona_init_gpio(struct snd_soc_codec *codec)
+int arizona_init_gpio(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int i;
 
@@ -643,7 +642,6 @@ const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
 };
 EXPORT_SYMBOL_GPL(arizona_rate_val);
 
-
 const struct soc_enum arizona_isrc_fsh[] = {
 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
 			      ARIZONA_ISRC1_FSH_SHIFT, 0xf,
@@ -882,9 +880,9 @@ const struct snd_kcontrol_new arizona_voice_trigger_switch[] = {
 };
 EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch);
 
-static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
+static void arizona_in_set_vu(struct snd_soc_component *component, int ena)
 {
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 	int i;
 
@@ -894,15 +892,15 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
 		val = 0;
 
 	for (i = 0; i < priv->num_inputs; i++)
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 				    ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
 				    ARIZONA_IN_VU, val);
 }
 
-bool arizona_input_analog(struct snd_soc_codec *codec, int shift)
+bool arizona_input_analog(struct snd_soc_component *component, int shift)
 {
 	unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
-	unsigned int val = snd_soc_read(codec, reg);
+	unsigned int val = snd_soc_component_read32(component, reg);
 
 	return !(val & ARIZONA_IN1_MODE_MASK);
 }
@@ -911,8 +909,8 @@ EXPORT_SYMBOL_GPL(arizona_input_analog);
 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
 		  int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	unsigned int reg;
 
 	if (w->shift % 2)
@@ -925,25 +923,26 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
 		priv->in_pending++;
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0);
+		snd_soc_component_update_bits(component, reg,
+					      ARIZONA_IN1L_MUTE, 0);
 
 		/* If this is the last input pending then allow VU */
 		priv->in_pending--;
 		if (priv->in_pending == 0) {
 			msleep(1);
-			arizona_in_set_vu(codec, 1);
+			arizona_in_set_vu(component, 1);
 		}
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 				    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
 				    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		/* Disable volume updates if no inputs are enabled */
-		reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
+		reg = snd_soc_component_read32(component, ARIZONA_INPUT_ENABLES);
 		if (reg == 0)
-			arizona_in_set_vu(codec, 0);
+			arizona_in_set_vu(component, 0);
 		break;
 	default:
 		break;
@@ -957,8 +956,8 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol,
 		   int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 
 	switch (event) {
@@ -1001,7 +1000,7 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
 		case ARIZONA_OUT4R_ENA_SHIFT:
 			priv->out_up_pending--;
 			if (!priv->out_up_pending && priv->out_up_delay) {
-				dev_dbg(codec->dev, "Power up delay: %d\n",
+				dev_dbg(component->dev, "Power up delay: %d\n",
 					priv->out_up_delay);
 				msleep(priv->out_up_delay);
 				priv->out_up_delay = 0;
@@ -1054,7 +1053,7 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
 		case ARIZONA_OUT4R_ENA_SHIFT:
 			priv->out_down_pending--;
 			if (!priv->out_down_pending && priv->out_down_delay) {
-				dev_dbg(codec->dev, "Power down delay: %d\n",
+				dev_dbg(component->dev, "Power down delay: %d\n",
 					priv->out_down_delay);
 				msleep(priv->out_down_delay);
 				priv->out_down_delay = 0;
@@ -1072,12 +1071,11 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(arizona_out_ev);
 
-int arizona_hp_ev(struct snd_soc_dapm_widget *w,
-		   struct snd_kcontrol *kcontrol,
-		   int event)
+int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
+		  int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	unsigned int mask = 1 << w->shift;
 	unsigned int val;
@@ -1111,15 +1109,15 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(arizona_hp_ev);
 
-static int arizona_dvfs_enable(struct snd_soc_codec *codec)
+static int arizona_dvfs_enable(struct snd_soc_component *component)
 {
-	const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int ret;
 
 	ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
 	if (ret) {
-		dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
+		dev_err(component->dev, "Failed to boost DCVDD: %d\n", ret);
 		return ret;
 	}
 
@@ -1128,7 +1126,7 @@ static int arizona_dvfs_enable(struct snd_soc_codec *codec)
 				 ARIZONA_SUBSYS_MAX_FREQ,
 				 ARIZONA_SUBSYS_MAX_FREQ);
 	if (ret) {
-		dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
+		dev_err(component->dev, "Failed to enable subsys max: %d\n", ret);
 		regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
 		return ret;
 	}
@@ -1136,9 +1134,9 @@ static int arizona_dvfs_enable(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int arizona_dvfs_disable(struct snd_soc_codec *codec)
+static int arizona_dvfs_disable(struct snd_soc_component *component)
 {
-	const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int ret;
 
@@ -1146,28 +1144,28 @@ static int arizona_dvfs_disable(struct snd_soc_codec *codec)
 				 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
 				 ARIZONA_SUBSYS_MAX_FREQ, 0);
 	if (ret) {
-		dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
+		dev_err(component->dev, "Failed to disable subsys max: %d\n", ret);
 		return ret;
 	}
 
 	ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
 	if (ret) {
-		dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
+		dev_err(component->dev, "Failed to unboost DCVDD: %d\n", ret);
 		return ret;
 	}
 
 	return 0;
 }
 
-int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
+int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags)
 {
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	mutex_lock(&priv->dvfs_lock);
 
 	if (!priv->dvfs_cached && !priv->dvfs_reqs) {
-		ret = arizona_dvfs_enable(codec);
+		ret = arizona_dvfs_enable(component);
 		if (ret)
 			goto err;
 	}
@@ -1179,9 +1177,9 @@ int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
 }
 EXPORT_SYMBOL_GPL(arizona_dvfs_up);
 
-int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
+int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
 {
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	unsigned int old_reqs;
 	int ret = 0;
 
@@ -1191,7 +1189,7 @@ int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
 	priv->dvfs_reqs &= ~flags;
 
 	if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
-		ret = arizona_dvfs_disable(codec);
+		ret = arizona_dvfs_disable(component);
 
 	mutex_unlock(&priv->dvfs_lock);
 	return ret;
@@ -1201,8 +1199,8 @@ EXPORT_SYMBOL_GPL(arizona_dvfs_down);
 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	mutex_lock(&priv->dvfs_lock);
@@ -1210,7 +1208,7 @@ int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		if (priv->dvfs_reqs)
-			ret = arizona_dvfs_enable(codec);
+			ret = arizona_dvfs_enable(component);
 
 		priv->dvfs_cached = false;
 		break;
@@ -1222,7 +1220,7 @@ int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
 		priv->dvfs_cached = true;
 
 		if (priv->dvfs_reqs)
-			ret = arizona_dvfs_disable(codec);
+			ret = arizona_dvfs_disable(component);
 		break;
 	default:
 		break;
@@ -1243,7 +1241,7 @@ int arizona_anc_ev(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol,
 		   int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int val;
 
 	switch (event) {
@@ -1257,7 +1255,7 @@ int arizona_anc_ev(struct snd_soc_dapm_widget *w,
 		return 0;
 	}
 
-	snd_soc_write(codec, ARIZONA_CLOCK_CONTROL, val);
+	snd_soc_component_write(component, ARIZONA_CLOCK_CONTROL, val);
 
 	return 0;
 }
@@ -1277,10 +1275,10 @@ static unsigned int arizona_opclk_ref_44k1_rates[] = {
 	45158400,
 };
 
-static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
-			     unsigned int freq)
+static int arizona_set_opclk(struct snd_soc_component *component,
+			     unsigned int clk, unsigned int freq)
 {
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	unsigned int reg;
 	unsigned int *rates;
 	int ref, div, refclk;
@@ -1304,13 +1302,13 @@ static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
 		rates = arizona_opclk_ref_48k_rates;
 
 	for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
-		     rates[ref] <= refclk; ref++) {
+	     rates[ref] <= refclk; ref++) {
 		div = 1;
 		while (rates[ref] / div >= freq && div < 32) {
 			if (rates[ref] / div == freq) {
-				dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
+				dev_dbg(component->dev, "Configured %dHz OPCLK\n",
 					freq);
-				snd_soc_update_bits(codec, reg,
+				snd_soc_component_update_bits(component, reg,
 						    ARIZONA_OPCLK_DIV_MASK |
 						    ARIZONA_OPCLK_SEL_MASK,
 						    (div <<
@@ -1322,22 +1320,22 @@ static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
 		}
 	}
 
-	dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
+	dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
 	return -EINVAL;
 }
 
 int arizona_clk_ev(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	unsigned int val;
 	int clk_idx;
 	int ret;
 
 	ret = regmap_read(arizona->regmap, w->reg, &val);
 	if (ret) {
-		dev_err(codec->dev, "Failed to check clock source: %d\n", ret);
+		dev_err(component->dev, "Failed to check clock source: %d\n", ret);
 		return ret;
 	}
 
@@ -1366,10 +1364,10 @@ int arizona_clk_ev(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(arizona_clk_ev);
 
-int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+int arizona_set_sysclk(struct snd_soc_component *component, int clk_id,
 		       int source, unsigned int freq, int dir)
 {
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	char *name;
 	unsigned int reg;
@@ -1391,7 +1389,7 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 		break;
 	case ARIZONA_CLK_OPCLK:
 	case ARIZONA_CLK_ASYNC_OPCLK:
-		return arizona_set_opclk(codec, clk_id, freq);
+		return arizona_set_opclk(component, clk_id, freq);
 	default:
 		return -EINVAL;
 	}
@@ -1445,8 +1443,8 @@ EXPORT_SYMBOL_GPL(arizona_set_sysclk);
 
 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int lrclk, bclk, mode, base;
 
@@ -1620,8 +1618,8 @@ static const struct snd_pcm_hw_constraint_list arizona_constraint = {
 static int arizona_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 	unsigned int base_rate;
 
@@ -1651,10 +1649,10 @@ static int arizona_startup(struct snd_pcm_substream *substream,
 					  &dai_priv->constraint);
 }
 
-static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
+static void arizona_wm5102_set_dac_comp(struct snd_soc_component *component,
 					unsigned int rate)
 {
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	struct reg_sequence dac_comp[] = {
 		{ 0x80, 0x3 },
@@ -1680,8 +1678,8 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 				  struct snd_pcm_hw_params *params,
 				  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 	int base = dai->driver->base;
 	int i, sr_val, ret;
@@ -1704,9 +1702,9 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 	case WM5102:
 	case WM8997:
 		if (arizona_sr_vals[sr_val] >= 88200)
-			ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
+			ret = arizona_dvfs_up(component, ARIZONA_DVFS_SR1_RQ);
 		else
-			ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
+			ret = arizona_dvfs_down(component, ARIZONA_DVFS_SR1_RQ);
 
 		if (ret) {
 			arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
@@ -1721,26 +1719,31 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 	case ARIZONA_CLK_SYSCLK:
 		switch (priv->arizona->type) {
 		case WM5102:
-			arizona_wm5102_set_dac_comp(codec,
+			arizona_wm5102_set_dac_comp(component,
 						    params_rate(params));
 			break;
 		default:
 			break;
 		}
 
-		snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
-				    ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
+		snd_soc_component_update_bits(component, ARIZONA_SAMPLE_RATE_1,
+					      ARIZONA_SAMPLE_RATE_1_MASK,
+					      sr_val);
 		if (base)
-			snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
-					    ARIZONA_AIF1_RATE_MASK, 0);
+			snd_soc_component_update_bits(component,
+					base + ARIZONA_AIF_RATE_CTRL,
+					ARIZONA_AIF1_RATE_MASK, 0);
 		break;
 	case ARIZONA_CLK_ASYNCCLK:
-		snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
-				    ARIZONA_ASYNC_SAMPLE_RATE_1_MASK, sr_val);
+		snd_soc_component_update_bits(component,
+					      ARIZONA_ASYNC_SAMPLE_RATE_1,
+					      ARIZONA_ASYNC_SAMPLE_RATE_1_MASK,
+					      sr_val);
 		if (base)
-			snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
-					    ARIZONA_AIF1_RATE_MASK,
-					    8 << ARIZONA_AIF1_RATE_SHIFT);
+			snd_soc_component_update_bits(component,
+					base + ARIZONA_AIF_RATE_CTRL,
+					ARIZONA_AIF1_RATE_MASK,
+					8 << ARIZONA_AIF1_RATE_SHIFT);
 		break;
 	default:
 		arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
@@ -1750,20 +1753,20 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
+static bool arizona_aif_cfg_changed(struct snd_soc_component *component,
 				    int base, int bclk, int lrclk, int frame)
 {
 	int val;
 
-	val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
+	val = snd_soc_component_read32(component, base + ARIZONA_AIF_BCLK_CTRL);
 	if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
 		return true;
 
-	val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
+	val = snd_soc_component_read32(component, base + ARIZONA_AIF_TX_BCLK_RATE);
 	if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
 		return true;
 
-	val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1);
+	val = snd_soc_component_read32(component, base + ARIZONA_AIF_FRAME_CTRL_1);
 	if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
 			     ARIZONA_AIF1TX_SLOT_LEN_MASK)))
 		return true;
@@ -1775,8 +1778,8 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int base = dai->driver->base;
 	const int *rates;
@@ -1813,7 +1816,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* Force multiple of 2 channels for I2S mode */
-	val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
+	val = snd_soc_component_read32(component, base + ARIZONA_AIF_FORMAT);
 	val &= ARIZONA_AIF1_FMT_MASK;
 	if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
 		arizona_aif_dbg(dai, "Forcing stereo mode\n");
@@ -1841,19 +1844,20 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
 
 	frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
 
-	reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
+	reconfig = arizona_aif_cfg_changed(component, base, bclk, lrclk, frame);
 
 	if (reconfig) {
 		/* Save AIF TX/RX state */
-		aif_tx_state = snd_soc_read(codec,
+		aif_tx_state = snd_soc_component_read32(component,
 					    base + ARIZONA_AIF_TX_ENABLES);
-		aif_rx_state = snd_soc_read(codec,
+		aif_rx_state = snd_soc_component_read32(component,
 					    base + ARIZONA_AIF_RX_ENABLES);
 		/* Disable AIF TX/RX before reconfiguring it */
 		regmap_update_bits_async(arizona->regmap,
-				    base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0);
+					 base + ARIZONA_AIF_TX_ENABLES,
+					 0xff, 0x0);
 		regmap_update_bits(arizona->regmap,
-				    base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
+				   base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
 	}
 
 	ret = arizona_hw_params_rate(substream, params, dai);
@@ -1908,9 +1912,9 @@ static const char *arizona_dai_clk_str(int clk_id)
 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
 				  int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 	struct snd_soc_dapm_route routes[2];
 
@@ -1926,12 +1930,12 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
 		return 0;
 
 	if (dai->active) {
-		dev_err(codec->dev, "Can't change clock on active DAI %d\n",
+		dev_err(component->dev, "Can't change clock on active DAI %d\n",
 			dai->id);
 		return -EBUSY;
 	}
 
-	dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
+	dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id + 1,
 		arizona_dai_clk_str(clk_id));
 
 	memset(&routes, 0, sizeof(routes));
@@ -1953,7 +1957,7 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
 
 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int base = dai->driver->base;
 	unsigned int reg;
 
@@ -1962,16 +1966,17 @@ static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
 	else
 		reg = 0;
 
-	return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
-				   ARIZONA_AIF1_TRI, reg);
+	return snd_soc_component_update_bits(component,
+					     base + ARIZONA_AIF_RATE_CTRL,
+					     ARIZONA_AIF1_TRI, reg);
 }
 
 static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
 					 unsigned int base,
 					 int channels, unsigned int mask)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int slot, i;
 
@@ -1992,8 +1997,8 @@ static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
 static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 				unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	int base = dai->driver->base;
 	int rx_max_chan = dai->driver->playback.channels_max;
@@ -2321,7 +2326,6 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 	arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
 
 	return 0;
-
 }
 
 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
@@ -2567,9 +2571,8 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 	fll->ref_src = source;
 	fll->ref_freq = Fref;
 
-	if (fll->fout && Fref > 0) {
+	if (fll->fout && Fref > 0)
 		ret = arizona_enable_fll(fll);
-	}
 
 	return ret;
 }
@@ -2645,7 +2648,7 @@ EXPORT_SYMBOL_GPL(arizona_init_fll);
 /**
  * arizona_set_output_mode - Set the mode of the specified output
  *
- * @codec: Device to configure
+ * @component: Device to configure
  * @output: Output number
  * @diff: True to set the output to differential mode
  *
@@ -2658,7 +2661,8 @@ EXPORT_SYMBOL_GPL(arizona_init_fll);
  * Most systems have a single static configuration and should use
  * platform data instead.
  */
-int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
+int arizona_set_output_mode(struct snd_soc_component *component, int output,
+			    bool diff)
 {
 	unsigned int reg, val;
 
@@ -2672,7 +2676,8 @@ int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
 	else
 		val = 0;
 
-	return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
+	return snd_soc_component_update_bits(component, reg,
+					     ARIZONA_OUT1_MONO, val);
 }
 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
 
@@ -2721,8 +2726,8 @@ static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
 			 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	struct soc_bytes *params = (void *)kcontrol->private_value;
 	unsigned int val;
 	__be16 *data;
@@ -2765,8 +2770,8 @@ EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
 			   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	__be16 *data = (__be16 *)ucontrol->value.bytes.data;
 	s16 val = be16_to_cpu(*data);
 
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index dfdf6d8..e3ccee5 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -273,7 +273,7 @@ int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
 
 int arizona_clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
 		   int event);
-int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, int source,
+int arizona_set_sysclk(struct snd_soc_component *component, int clk_id, int source,
 		       unsigned int freq, int dir);
 
 extern const struct snd_soc_dai_ops arizona_dai_ops;
@@ -297,8 +297,8 @@ struct arizona_fll {
 	char clock_ok_name[ARIZONA_FLL_NAME_LEN];
 };
 
-int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags);
-int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags);
+int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags);
+int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags);
 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event);
 void arizona_init_dvfs(struct arizona_priv *priv);
@@ -310,9 +310,9 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 int arizona_set_fll(struct arizona_fll *fll, int source,
 		    unsigned int Fref, unsigned int Fout);
 
-int arizona_init_spk(struct snd_soc_codec *codec);
-int arizona_init_gpio(struct snd_soc_codec *codec);
-int arizona_init_mono(struct snd_soc_codec *codec);
+int arizona_init_spk(struct snd_soc_component *component);
+int arizona_init_gpio(struct snd_soc_component *component);
+int arizona_init_mono(struct snd_soc_component *component);
 
 int arizona_init_common(struct arizona *arizona);
 int arizona_init_vol_limit(struct arizona *arizona);
@@ -322,20 +322,20 @@ int arizona_free_spk_irqs(struct arizona *arizona);
 
 int arizona_init_dai(struct arizona_priv *priv, int dai);
 
-int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
+int arizona_set_output_mode(struct snd_soc_component *component, int output,
 			    bool diff);
 
-bool arizona_input_analog(struct snd_soc_codec *codec, int shift);
+bool arizona_input_analog(struct snd_soc_component *component, int shift);
 
 const char *arizona_sample_rate_val_to_name(unsigned int rate_val);
 
-static inline int arizona_register_notifier(struct snd_soc_codec *codec,
+static inline int arizona_register_notifier(struct snd_soc_component *component,
 					    struct notifier_block *nb,
 					    int (*notify)
 					    (struct notifier_block *nb,
 					    unsigned long action, void *data))
 {
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 
 	nb->notifier_call = notify;
@@ -343,10 +343,10 @@ static inline int arizona_register_notifier(struct snd_soc_codec *codec,
 	return blocking_notifier_chain_register(&arizona->notifier, nb);
 }
 
-static inline int arizona_unregister_notifier(struct snd_soc_codec *codec,
+static inline int arizona_unregister_notifier(struct snd_soc_component *component,
 					      struct notifier_block *nb)
 {
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 
 	return blocking_notifier_chain_unregister(&arizona->notifier, nb);
diff --git a/sound/soc/codecs/bd28623.c b/sound/soc/codecs/bd28623.c
new file mode 100644
index 0000000..31904ef
--- /dev/null
+++ b/sound/soc/codecs/bd28623.c
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// ROHM BD28623MUV class D speaker amplifier codec driver.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#define BD28623_NUM_SUPPLIES    3
+
+static const char *const bd28623_supply_names[BD28623_NUM_SUPPLIES] = {
+	"VCCA",
+	"VCCP1",
+	"VCCP2",
+};
+
+struct bd28623_priv {
+	struct device *dev;
+	struct regulator_bulk_data supplies[BD28623_NUM_SUPPLIES];
+	struct gpio_desc *reset_gpio;
+	struct gpio_desc *mute_gpio;
+
+	int switch_spk;
+};
+
+static const struct snd_soc_dapm_widget bd28623_widgets[] = {
+	SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_OUTPUT("OUT1P"),
+	SND_SOC_DAPM_OUTPUT("OUT1N"),
+	SND_SOC_DAPM_OUTPUT("OUT2P"),
+	SND_SOC_DAPM_OUTPUT("OUT2N"),
+};
+
+static const struct snd_soc_dapm_route bd28623_routes[] = {
+	{ "OUT1P", NULL, "DAC" },
+	{ "OUT1N", NULL, "DAC" },
+	{ "OUT2P", NULL, "DAC" },
+	{ "OUT2N", NULL, "DAC" },
+};
+
+static int bd28623_power_on(struct bd28623_priv *bd)
+{
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(bd->supplies), bd->supplies);
+	if (ret) {
+		dev_err(bd->dev, "Failed to enable supplies: %d\n", ret);
+		return ret;
+	}
+
+	gpiod_set_value_cansleep(bd->reset_gpio, 0);
+	usleep_range(300000, 400000);
+
+	return 0;
+}
+
+static void bd28623_power_off(struct bd28623_priv *bd)
+{
+	gpiod_set_value_cansleep(bd->reset_gpio, 1);
+
+	regulator_bulk_disable(ARRAY_SIZE(bd->supplies), bd->supplies);
+}
+
+static int bd28623_get_switch_spk(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+		snd_soc_kcontrol_component(kcontrol);
+	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.integer.value[0] = bd->switch_spk;
+
+	return 0;
+}
+
+static int bd28623_set_switch_spk(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+		snd_soc_kcontrol_component(kcontrol);
+	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+
+	if (bd->switch_spk == ucontrol->value.integer.value[0])
+		return 0;
+
+	bd->switch_spk = ucontrol->value.integer.value[0];
+
+	gpiod_set_value_cansleep(bd->mute_gpio, bd->switch_spk ? 0 : 1);
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new bd28623_controls[] = {
+	SOC_SINGLE_BOOL_EXT("Speaker Switch", 0,
+			    bd28623_get_switch_spk, bd28623_set_switch_spk),
+};
+
+static int bd28623_codec_probe(struct snd_soc_component *component)
+{
+	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+	int ret;
+
+	bd->switch_spk = 1;
+
+	ret = bd28623_power_on(bd);
+	if (ret)
+		return ret;
+
+	gpiod_set_value_cansleep(bd->mute_gpio, bd->switch_spk ? 0 : 1);
+
+	return 0;
+}
+
+static void bd28623_codec_remove(struct snd_soc_component *component)
+{
+	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+
+	bd28623_power_off(bd);
+}
+
+static int bd28623_codec_suspend(struct snd_soc_component *component)
+{
+	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+
+	bd28623_power_off(bd);
+
+	return 0;
+}
+
+static int bd28623_codec_resume(struct snd_soc_component *component)
+{
+	struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+	int ret;
+
+	ret = bd28623_power_on(bd);
+	if (ret)
+		return ret;
+
+	gpiod_set_value_cansleep(bd->mute_gpio, bd->switch_spk ? 0 : 1);
+
+	return 0;
+}
+
+static const struct snd_soc_component_driver soc_codec_bd = {
+	.probe			= bd28623_codec_probe,
+	.remove			= bd28623_codec_remove,
+	.suspend		= bd28623_codec_suspend,
+	.resume			= bd28623_codec_resume,
+	.dapm_widgets		= bd28623_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(bd28623_widgets),
+	.dapm_routes		= bd28623_routes,
+	.num_dapm_routes	= ARRAY_SIZE(bd28623_routes),
+	.controls		= bd28623_controls,
+	.num_controls		= ARRAY_SIZE(bd28623_controls),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
+
+static struct snd_soc_dai_driver soc_dai_bd = {
+	.name     = "bd28623-speaker",
+	.playback = {
+		.stream_name  = "Playback",
+		.formats      = SNDRV_PCM_FMTBIT_S32_LE |
+				SNDRV_PCM_FMTBIT_S24_LE |
+				SNDRV_PCM_FMTBIT_S16_LE,
+		.rates        = SNDRV_PCM_RATE_48000 |
+				SNDRV_PCM_RATE_44100 |
+				SNDRV_PCM_RATE_32000,
+		.channels_min = 2,
+		.channels_max = 2,
+	},
+};
+
+static int bd28623_probe(struct platform_device *pdev)
+{
+	struct bd28623_priv *bd;
+	struct device *dev = &pdev->dev;
+	int i, ret;
+
+	bd = devm_kzalloc(&pdev->dev, sizeof(struct bd28623_priv), GFP_KERNEL);
+	if (!bd)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(bd->supplies); i++)
+		bd->supplies[i].supply = bd28623_supply_names[i];
+
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(bd->supplies),
+				      bd->supplies);
+	if (ret) {
+		dev_err(dev, "Failed to get supplies: %d\n", ret);
+		return ret;
+	}
+
+	bd->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+						 GPIOD_OUT_HIGH);
+	if (IS_ERR(bd->reset_gpio)) {
+		dev_err(dev, "Failed to request reset_gpio: %ld\n",
+			PTR_ERR(bd->reset_gpio));
+		return PTR_ERR(bd->reset_gpio);
+	}
+
+	bd->mute_gpio = devm_gpiod_get_optional(dev, "mute",
+						GPIOD_OUT_HIGH);
+	if (IS_ERR(bd->mute_gpio)) {
+		dev_err(dev, "Failed to request mute_gpio: %ld\n",
+			PTR_ERR(bd->mute_gpio));
+		return PTR_ERR(bd->mute_gpio);
+	}
+
+	platform_set_drvdata(pdev, bd);
+	bd->dev = dev;
+
+	return devm_snd_soc_register_component(dev, &soc_codec_bd,
+					       &soc_dai_bd, 1);
+}
+
+static const struct of_device_id bd28623_of_match[] = {
+	{ .compatible = "rohm,bd28623", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, bd28623_of_match);
+
+static struct platform_driver bd28623_codec_driver = {
+	.driver = {
+		.name = "bd28623",
+		.of_match_table = of_match_ptr(bd28623_of_match),
+	},
+	.probe  = bd28623_probe,
+};
+module_platform_driver(bd28623_codec_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("ROHM BD28623 speaker amplifier driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index 806191a..8422042 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -62,25 +62,26 @@ static struct snd_soc_dai_driver bt_sco_dai[] = {
 	}
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
-	.component_driver = {
-		.dapm_widgets		= bt_sco_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(bt_sco_widgets),
-		.dapm_routes		= bt_sco_routes,
-		.num_dapm_routes	= ARRAY_SIZE(bt_sco_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_bt_sco = {
+	.dapm_widgets		= bt_sco_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(bt_sco_widgets),
+	.dapm_routes		= bt_sco_routes,
+	.num_dapm_routes	= ARRAY_SIZE(bt_sco_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int bt_sco_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_bt_sco,
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &soc_component_dev_bt_sco,
 				      bt_sco_dai, ARRAY_SIZE(bt_sco_dai));
 }
 
 static int bt_sco_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c
new file mode 100644
index 0000000..d7f05b3
--- /dev/null
+++ b/sound/soc/codecs/cpcap.c
@@ -0,0 +1,1562 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ALSA SoC CPCAP codec driver
+ *
+ * Copyright (C) 2017 - 2018 Sebastian Reichel <sre@kernel.org>
+ *
+ * Very loosely based on original driver from Motorola:
+ * Copyright (C) 2007 - 2009 Motorola, Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/motorola-cpcap.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+/* Register 513 CPCAP_REG_CC     --- CODEC */
+#define CPCAP_BIT_CDC_CLK2                15
+#define CPCAP_BIT_CDC_CLK1                14
+#define CPCAP_BIT_CDC_CLK0                13
+#define CPCAP_BIT_CDC_SR3                 12
+#define CPCAP_BIT_CDC_SR2                 11
+#define CPCAP_BIT_CDC_SR1                 10
+#define CPCAP_BIT_CDC_SR0                 9
+#define CPCAP_BIT_CDC_CLOCK_TREE_RESET    8
+#define CPCAP_BIT_MIC2_CDC_EN             7
+#define CPCAP_BIT_CDC_EN_RX               6
+#define CPCAP_BIT_DF_RESET                5
+#define CPCAP_BIT_MIC1_CDC_EN             4
+#define CPCAP_BIT_AUDOHPF_1		  3
+#define CPCAP_BIT_AUDOHPF_0		  2
+#define CPCAP_BIT_AUDIHPF_1		  1
+#define CPCAP_BIT_AUDIHPF_0		  0
+
+/* Register 514 CPCAP_REG_CDI    --- CODEC Digital Audio Interface */
+#define CPCAP_BIT_CDC_PLL_SEL             15
+#define CPCAP_BIT_CLK_IN_SEL              13
+#define CPCAP_BIT_DIG_AUD_IN              12
+#define CPCAP_BIT_CDC_CLK_EN              11
+#define CPCAP_BIT_CDC_DIG_AUD_FS1         10
+#define CPCAP_BIT_CDC_DIG_AUD_FS0         9
+#define CPCAP_BIT_MIC2_TIMESLOT2          8
+#define CPCAP_BIT_MIC2_TIMESLOT1          7
+#define CPCAP_BIT_MIC2_TIMESLOT0          6
+#define CPCAP_BIT_MIC1_RX_TIMESLOT2       5
+#define CPCAP_BIT_MIC1_RX_TIMESLOT1       4
+#define CPCAP_BIT_MIC1_RX_TIMESLOT0       3
+#define CPCAP_BIT_FS_INV                  2
+#define CPCAP_BIT_CLK_INV                 1
+#define CPCAP_BIT_SMB_CDC                 0
+
+/* Register 515 CPCAP_REG_SDAC   --- Stereo DAC */
+#define CPCAP_BIT_FSYNC_CLK_IN_COMMON     11
+#define CPCAP_BIT_SLAVE_PLL_CLK_INPUT     10
+#define CPCAP_BIT_ST_CLOCK_TREE_RESET     9
+#define CPCAP_BIT_DF_RESET_ST_DAC         8
+#define CPCAP_BIT_ST_SR3                  7
+#define CPCAP_BIT_ST_SR2                  6
+#define CPCAP_BIT_ST_SR1                  5
+#define CPCAP_BIT_ST_SR0                  4
+#define CPCAP_BIT_ST_DAC_CLK2             3
+#define CPCAP_BIT_ST_DAC_CLK1             2
+#define CPCAP_BIT_ST_DAC_CLK0             1
+#define CPCAP_BIT_ST_DAC_EN               0
+
+/* Register 516 CPCAP_REG_SDACDI --- Stereo DAC Digital Audio Interface */
+#define CPCAP_BIT_ST_L_TIMESLOT2          13
+#define CPCAP_BIT_ST_L_TIMESLOT1          12
+#define CPCAP_BIT_ST_L_TIMESLOT0          11
+#define CPCAP_BIT_ST_R_TIMESLOT2          10
+#define CPCAP_BIT_ST_R_TIMESLOT1          9
+#define CPCAP_BIT_ST_R_TIMESLOT0          8
+#define CPCAP_BIT_ST_DAC_CLK_IN_SEL       7
+#define CPCAP_BIT_ST_FS_INV               6
+#define CPCAP_BIT_ST_CLK_INV              5
+#define CPCAP_BIT_ST_DIG_AUD_FS1          4
+#define CPCAP_BIT_ST_DIG_AUD_FS0          3
+#define CPCAP_BIT_DIG_AUD_IN_ST_DAC       2
+#define CPCAP_BIT_ST_CLK_EN               1
+#define CPCAP_BIT_SMB_ST_DAC              0
+
+/* Register 517 CPCAP_REG_TXI    --- TX Interface */
+#define CPCAP_BIT_PTT_TH		15
+#define CPCAP_BIT_PTT_CMP_EN		14
+#define CPCAP_BIT_HS_ID_TX		13
+#define CPCAP_BIT_MB_ON2		12
+#define CPCAP_BIT_MB_ON1L		11
+#define CPCAP_BIT_MB_ON1R		10
+#define CPCAP_BIT_RX_L_ENCODE		9
+#define CPCAP_BIT_RX_R_ENCODE		8
+#define CPCAP_BIT_MIC2_MUX		7
+#define CPCAP_BIT_MIC2_PGA_EN		6
+#define CPCAP_BIT_CDET_DIS		5
+#define CPCAP_BIT_EMU_MIC_MUX		4
+#define CPCAP_BIT_HS_MIC_MUX		3
+#define CPCAP_BIT_MIC1_MUX		2
+#define CPCAP_BIT_MIC1_PGA_EN		1
+#define CPCAP_BIT_DLM			0
+
+/* Register 518 CPCAP_REG_TXMP   --- Mic Gain */
+#define CPCAP_BIT_MB_BIAS_R1              11
+#define CPCAP_BIT_MB_BIAS_R0              10
+#define CPCAP_BIT_MIC2_GAIN_4             9
+#define CPCAP_BIT_MIC2_GAIN_3             8
+#define CPCAP_BIT_MIC2_GAIN_2             7
+#define CPCAP_BIT_MIC2_GAIN_1             6
+#define CPCAP_BIT_MIC2_GAIN_0             5
+#define CPCAP_BIT_MIC1_GAIN_4             4
+#define CPCAP_BIT_MIC1_GAIN_3             3
+#define CPCAP_BIT_MIC1_GAIN_2             2
+#define CPCAP_BIT_MIC1_GAIN_1             1
+#define CPCAP_BIT_MIC1_GAIN_0             0
+
+/* Register 519 CPCAP_REG_RXOA   --- RX Output Amplifier */
+#define CPCAP_BIT_UNUSED_519_15		15
+#define CPCAP_BIT_UNUSED_519_14		14
+#define CPCAP_BIT_UNUSED_519_13		13
+#define CPCAP_BIT_STDAC_LOW_PWR_DISABLE	12
+#define CPCAP_BIT_HS_LOW_PWR		11
+#define CPCAP_BIT_HS_ID_RX		10
+#define CPCAP_BIT_ST_HS_CP_EN		9
+#define CPCAP_BIT_EMU_SPKR_R_EN		8
+#define CPCAP_BIT_EMU_SPKR_L_EN		7
+#define CPCAP_BIT_HS_L_EN		6
+#define CPCAP_BIT_HS_R_EN		5
+#define CPCAP_BIT_A4_LINEOUT_L_EN	4
+#define CPCAP_BIT_A4_LINEOUT_R_EN	3
+#define CPCAP_BIT_A2_LDSP_L_EN		2
+#define CPCAP_BIT_A2_LDSP_R_EN		1
+#define CPCAP_BIT_A1_EAR_EN		0
+
+/* Register 520 CPCAP_REG_RXVC   --- RX Volume Control */
+#define CPCAP_BIT_VOL_EXT3                15
+#define CPCAP_BIT_VOL_EXT2                14
+#define CPCAP_BIT_VOL_EXT1                13
+#define CPCAP_BIT_VOL_EXT0                12
+#define CPCAP_BIT_VOL_DAC3                11
+#define CPCAP_BIT_VOL_DAC2                10
+#define CPCAP_BIT_VOL_DAC1                9
+#define CPCAP_BIT_VOL_DAC0                8
+#define CPCAP_BIT_VOL_DAC_LSB_1dB1        7
+#define CPCAP_BIT_VOL_DAC_LSB_1dB0        6
+#define CPCAP_BIT_VOL_CDC3                5
+#define CPCAP_BIT_VOL_CDC2                4
+#define CPCAP_BIT_VOL_CDC1                3
+#define CPCAP_BIT_VOL_CDC0                2
+#define CPCAP_BIT_VOL_CDC_LSB_1dB1        1
+#define CPCAP_BIT_VOL_CDC_LSB_1dB0        0
+
+/* Register 521 CPCAP_REG_RXCOA  --- Codec to Output Amp Switches */
+#define CPCAP_BIT_PGA_CDC_EN              10
+#define CPCAP_BIT_CDC_SW                  9
+#define CPCAP_BIT_PGA_OUTR_USBDP_CDC_SW   8
+#define CPCAP_BIT_PGA_OUTL_USBDN_CDC_SW   7
+#define CPCAP_BIT_ALEFT_HS_CDC_SW         6
+#define CPCAP_BIT_ARIGHT_HS_CDC_SW        5
+#define CPCAP_BIT_A4_LINEOUT_L_CDC_SW     4
+#define CPCAP_BIT_A4_LINEOUT_R_CDC_SW     3
+#define CPCAP_BIT_A2_LDSP_L_CDC_SW        2
+#define CPCAP_BIT_A2_LDSP_R_CDC_SW        1
+#define CPCAP_BIT_A1_EAR_CDC_SW           0
+
+/* Register 522 CPCAP_REG_RXSDOA --- RX Stereo DAC to Output Amp Switches */
+#define CPCAP_BIT_PGA_DAC_EN              12
+#define CPCAP_BIT_ST_DAC_SW               11
+#define CPCAP_BIT_MONO_DAC1               10
+#define CPCAP_BIT_MONO_DAC0               9
+#define CPCAP_BIT_PGA_OUTR_USBDP_DAC_SW   8
+#define CPCAP_BIT_PGA_OUTL_USBDN_DAC_SW   7
+#define CPCAP_BIT_ALEFT_HS_DAC_SW         6
+#define CPCAP_BIT_ARIGHT_HS_DAC_SW        5
+#define CPCAP_BIT_A4_LINEOUT_L_DAC_SW     4
+#define CPCAP_BIT_A4_LINEOUT_R_DAC_SW     3
+#define CPCAP_BIT_A2_LDSP_L_DAC_SW        2
+#define CPCAP_BIT_A2_LDSP_R_DAC_SW        1
+#define CPCAP_BIT_A1_EAR_DAC_SW           0
+
+/* Register 523 CPCAP_REG_RXEPOA --- RX External PGA to Output Amp Switches */
+#define CPCAP_BIT_PGA_EXT_L_EN            14
+#define CPCAP_BIT_PGA_EXT_R_EN            13
+#define CPCAP_BIT_PGA_IN_L_SW             12
+#define CPCAP_BIT_PGA_IN_R_SW             11
+#define CPCAP_BIT_MONO_EXT1               10
+#define CPCAP_BIT_MONO_EXT0               9
+#define CPCAP_BIT_PGA_OUTR_USBDP_EXT_SW   8
+#define CPCAP_BIT_PGA_OUTL_USBDN_EXT_SW   7
+#define CPCAP_BIT_ALEFT_HS_EXT_SW         6
+#define CPCAP_BIT_ARIGHT_HS_EXT_SW        5
+#define CPCAP_BIT_A4_LINEOUT_L_EXT_SW     4
+#define CPCAP_BIT_A4_LINEOUT_R_EXT_SW     3
+#define CPCAP_BIT_A2_LDSP_L_EXT_SW        2
+#define CPCAP_BIT_A2_LDSP_R_EXT_SW        1
+#define CPCAP_BIT_A1_EAR_EXT_SW           0
+
+/* Register 525 CPCAP_REG_A2LA --- SPK Amplifier and Clock Config for Headset */
+#define CPCAP_BIT_NCP_CLK_SYNC            7
+#define CPCAP_BIT_A2_CLK_SYNC             6
+#define CPCAP_BIT_A2_FREE_RUN             5
+#define CPCAP_BIT_A2_CLK2                 4
+#define CPCAP_BIT_A2_CLK1                 3
+#define CPCAP_BIT_A2_CLK0                 2
+#define CPCAP_BIT_A2_CLK_IN               1
+#define CPCAP_BIT_A2_CONFIG               0
+
+#define SLEEP_ACTIVATE_POWER 2
+#define CLOCK_TREE_RESET_TIME 1
+
+/* constants for ST delay workaround */
+#define STM_STDAC_ACTIVATE_RAMP_TIME   1
+#define STM_STDAC_EN_TEST_PRE          0x090C
+#define STM_STDAC_EN_TEST_POST         0x0000
+#define STM_STDAC_EN_ST_TEST1_PRE      0x2400
+#define STM_STDAC_EN_ST_TEST1_POST     0x0400
+
+struct cpcap_reg_info {
+	u16 reg;
+	u16 mask;
+	u16 val;
+};
+
+static const struct cpcap_reg_info cpcap_default_regs[] = {
+	{ CPCAP_REG_CC, 0xFFFF, 0x0000 },
+	{ CPCAP_REG_CC, 0xFFFF, 0x0000 },
+	{ CPCAP_REG_CDI, 0xBFFF, 0x0000 },
+	{ CPCAP_REG_SDAC, 0x0FFF, 0x0000 },
+	{ CPCAP_REG_SDACDI, 0x3FFF, 0x0000 },
+	{ CPCAP_REG_TXI, 0x0FDF, 0x0000 },
+	{ CPCAP_REG_TXMP, 0x0FFF, 0x0400 },
+	{ CPCAP_REG_RXOA, 0x01FF, 0x0000 },
+	{ CPCAP_REG_RXVC, 0xFF3C, 0x0000 },
+	{ CPCAP_REG_RXCOA, 0x07FF, 0x0000 },
+	{ CPCAP_REG_RXSDOA, 0x1FFF, 0x0000 },
+	{ CPCAP_REG_RXEPOA, 0x7FFF, 0x0000 },
+	{ CPCAP_REG_A2LA, BIT(CPCAP_BIT_A2_FREE_RUN),
+	  BIT(CPCAP_BIT_A2_FREE_RUN) },
+};
+
+enum cpcap_dai {
+	CPCAP_DAI_HIFI,
+	CPCAP_DAI_VOICE,
+};
+
+struct cpcap_audio {
+	struct snd_soc_component *component;
+	struct regmap *regmap;
+
+	u16 vendor;
+
+	int codec_clk_id;
+	int codec_freq;
+	int codec_format;
+};
+
+static int cpcap_st_workaround(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	int err = 0;
+
+	/* Only CPCAP from ST requires workaround */
+	if (cpcap->vendor != CPCAP_VENDOR_ST)
+		return 0;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
+				   STM_STDAC_EN_TEST_PRE);
+		if (err)
+			return err;
+		err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
+				   STM_STDAC_EN_ST_TEST1_PRE);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		msleep(STM_STDAC_ACTIVATE_RAMP_TIME);
+
+		err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
+				   STM_STDAC_EN_ST_TEST1_POST);
+		if (err)
+			return err;
+		err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
+				   STM_STDAC_EN_TEST_POST);
+		break;
+	default:
+		break;
+	}
+
+	return err;
+}
+
+/* Capture Gain Control: 0dB to 31dB in 1dB steps */
+static const DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0);
+
+/* Playback Gain Control: -33dB to 12dB in 3dB steps */
+static const DECLARE_TLV_DB_SCALE(vol_tlv, -3300, 300, 0);
+
+static const struct snd_kcontrol_new cpcap_snd_controls[] = {
+	/* Playback Gain */
+	SOC_SINGLE_TLV("HiFi Playback Volume",
+		CPCAP_REG_RXVC, CPCAP_BIT_VOL_DAC0, 0xF, 0, vol_tlv),
+	SOC_SINGLE_TLV("Voice Playback Volume",
+		CPCAP_REG_RXVC, CPCAP_BIT_VOL_CDC0, 0xF, 0, vol_tlv),
+	SOC_SINGLE_TLV("Ext Playback Volume",
+		CPCAP_REG_RXVC, CPCAP_BIT_VOL_EXT0, 0xF, 0, vol_tlv),
+
+	/* Capture Gain */
+	SOC_SINGLE_TLV("Mic1 Capture Volume",
+		CPCAP_REG_TXMP, CPCAP_BIT_MIC1_GAIN_0, 0x1F, 0, mic_gain_tlv),
+	SOC_SINGLE_TLV("Mic2 Capture Volume",
+		CPCAP_REG_TXMP, CPCAP_BIT_MIC2_GAIN_0, 0x1F, 0, mic_gain_tlv),
+
+	/* Phase Invert */
+	SOC_SINGLE("Hifi Left Phase Invert Switch",
+		CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC0, 1, 0),
+	SOC_SINGLE("Ext Left Phase Invert Switch",
+		CPCAP_REG_RXEPOA, CPCAP_BIT_MONO_EXT0, 1, 0),
+};
+
+static const char * const cpcap_out_mux_texts[] = {
+	"Off", "Voice", "HiFi", "Ext"
+};
+
+static const char * const cpcap_in_right_mux_texts[] = {
+	"Off", "Mic 1", "Headset Mic", "EMU Mic", "Ext Right"
+};
+
+static const char * const cpcap_in_left_mux_texts[] = {
+	"Off", "Mic 2", "Ext Left"
+};
+
+/*
+ * input muxes use unusual register layout, so that we need to use custom
+ * getter/setter methods
+ */
+static SOC_ENUM_SINGLE_EXT_DECL(cpcap_input_left_mux_enum,
+				cpcap_in_left_mux_texts);
+static SOC_ENUM_SINGLE_EXT_DECL(cpcap_input_right_mux_enum,
+				cpcap_in_right_mux_texts);
+
+/*
+ * mux uses same bit in CPCAP_REG_RXCOA, CPCAP_REG_RXSDOA & CPCAP_REG_RXEPOA;
+ * even though the register layout makes it look like a mixer, this is a mux.
+ * Enabling multiple inputs will result in no audio being forwarded.
+ */
+static SOC_ENUM_SINGLE_DECL(cpcap_earpiece_mux_enum, 0, 0, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_spkr_r_mux_enum, 0, 1, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_spkr_l_mux_enum, 0, 2, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_line_r_mux_enum, 0, 3, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_line_l_mux_enum, 0, 4, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_hs_r_mux_enum, 0, 5, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_hs_l_mux_enum, 0, 6, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_emu_l_mux_enum, 0, 7, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_emu_r_mux_enum, 0, 8, cpcap_out_mux_texts);
+
+static int cpcap_output_mux_get_enum(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int shift = e->shift_l;
+	int reg_voice, reg_hifi, reg_ext, status;
+	int err;
+
+	err = regmap_read(cpcap->regmap, CPCAP_REG_RXCOA, &reg_voice);
+	if (err)
+		return err;
+	err = regmap_read(cpcap->regmap, CPCAP_REG_RXSDOA, &reg_hifi);
+	if (err)
+		return err;
+	err = regmap_read(cpcap->regmap, CPCAP_REG_RXEPOA, &reg_ext);
+	if (err)
+		return err;
+
+	reg_voice = (reg_voice >> shift) & 1;
+	reg_hifi = (reg_hifi >> shift) & 1;
+	reg_ext = (reg_ext >> shift) & 1;
+	status = reg_ext << 2 | reg_hifi << 1 | reg_voice;
+
+	switch (status) {
+	case 0x04:
+		ucontrol->value.enumerated.item[0] = 3;
+		break;
+	case 0x02:
+		ucontrol->value.enumerated.item[0] = 2;
+		break;
+	case 0x01:
+		ucontrol->value.enumerated.item[0] = 1;
+		break;
+	default:
+		ucontrol->value.enumerated.item[0] = 0;
+		break;
+	}
+
+	return 0;
+}
+
+static int cpcap_output_mux_put_enum(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm =
+		snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int muxval = ucontrol->value.enumerated.item[0];
+	unsigned int mask = BIT(e->shift_l);
+	u16 reg_voice = 0x00, reg_hifi = 0x00, reg_ext = 0x00;
+	int err;
+
+	switch (muxval) {
+	case 1:
+		reg_voice = mask;
+		break;
+	case 2:
+		reg_hifi = mask;
+		break;
+	case 3:
+		reg_ext = mask;
+		break;
+	default:
+		break;
+	}
+
+	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA,
+				 mask, reg_voice);
+	if (err)
+		return err;
+	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA,
+				 mask, reg_hifi);
+	if (err)
+		return err;
+	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXEPOA,
+				 mask, reg_ext);
+	if (err)
+		return err;
+
+	snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
+
+	return 0;
+}
+
+static int cpcap_input_right_mux_get_enum(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	int regval, mask;
+	int err;
+
+	err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval);
+	if (err)
+		return err;
+
+	mask = 0;
+	mask |= BIT(CPCAP_BIT_MIC1_MUX);
+	mask |= BIT(CPCAP_BIT_HS_MIC_MUX);
+	mask |= BIT(CPCAP_BIT_EMU_MIC_MUX);
+	mask |= BIT(CPCAP_BIT_RX_R_ENCODE);
+
+	switch (regval & mask) {
+	case BIT(CPCAP_BIT_RX_R_ENCODE):
+		ucontrol->value.enumerated.item[0] = 4;
+		break;
+	case BIT(CPCAP_BIT_EMU_MIC_MUX):
+		ucontrol->value.enumerated.item[0] = 3;
+		break;
+	case BIT(CPCAP_BIT_HS_MIC_MUX):
+		ucontrol->value.enumerated.item[0] = 2;
+		break;
+	case BIT(CPCAP_BIT_MIC1_MUX):
+		ucontrol->value.enumerated.item[0] = 1;
+		break;
+	default:
+		ucontrol->value.enumerated.item[0] = 0;
+		break;
+	}
+
+	return 0;
+}
+
+static int cpcap_input_right_mux_put_enum(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm =
+		snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int muxval = ucontrol->value.enumerated.item[0];
+	int regval = 0, mask;
+	int err;
+
+	mask = 0;
+	mask |= BIT(CPCAP_BIT_MIC1_MUX);
+	mask |= BIT(CPCAP_BIT_HS_MIC_MUX);
+	mask |= BIT(CPCAP_BIT_EMU_MIC_MUX);
+	mask |= BIT(CPCAP_BIT_RX_R_ENCODE);
+
+	switch (muxval) {
+	case 1:
+		regval = BIT(CPCAP_BIT_MIC1_MUX);
+		break;
+	case 2:
+		regval = BIT(CPCAP_BIT_HS_MIC_MUX);
+		break;
+	case 3:
+		regval = BIT(CPCAP_BIT_EMU_MIC_MUX);
+		break;
+	case 4:
+		regval = BIT(CPCAP_BIT_RX_R_ENCODE);
+		break;
+	default:
+		break;
+	}
+
+	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
+				 mask, regval);
+	if (err)
+		return err;
+
+	snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
+
+	return 0;
+}
+
+static int cpcap_input_left_mux_get_enum(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	int regval, mask;
+	int err;
+
+	err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval);
+	if (err)
+		return err;
+
+	mask = 0;
+	mask |= BIT(CPCAP_BIT_MIC2_MUX);
+	mask |= BIT(CPCAP_BIT_RX_L_ENCODE);
+
+	switch (regval & mask) {
+	case BIT(CPCAP_BIT_RX_L_ENCODE):
+		ucontrol->value.enumerated.item[0] = 2;
+		break;
+	case BIT(CPCAP_BIT_MIC2_MUX):
+		ucontrol->value.enumerated.item[0] = 1;
+		break;
+	default:
+		ucontrol->value.enumerated.item[0] = 0;
+		break;
+	}
+
+	return 0;
+}
+
+static int cpcap_input_left_mux_put_enum(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm =
+		snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int muxval = ucontrol->value.enumerated.item[0];
+	int regval = 0, mask;
+	int err;
+
+	mask = 0;
+	mask |= BIT(CPCAP_BIT_MIC2_MUX);
+	mask |= BIT(CPCAP_BIT_RX_L_ENCODE);
+
+	switch (muxval) {
+	case 1:
+		regval = BIT(CPCAP_BIT_MIC2_MUX);
+		break;
+	case 2:
+		regval = BIT(CPCAP_BIT_RX_L_ENCODE);
+		break;
+	default:
+		break;
+	}
+
+	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
+				 mask, regval);
+	if (err)
+		return err;
+
+	snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new cpcap_input_left_mux =
+	SOC_DAPM_ENUM_EXT("Input Left", cpcap_input_left_mux_enum,
+			  cpcap_input_left_mux_get_enum,
+			  cpcap_input_left_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_input_right_mux =
+	SOC_DAPM_ENUM_EXT("Input Right", cpcap_input_right_mux_enum,
+			  cpcap_input_right_mux_get_enum,
+			  cpcap_input_right_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_emu_left_mux =
+	SOC_DAPM_ENUM_EXT("EMU Left", cpcap_emu_l_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_emu_right_mux =
+	SOC_DAPM_ENUM_EXT("EMU Right", cpcap_emu_r_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_hs_left_mux =
+	SOC_DAPM_ENUM_EXT("Headset Left", cpcap_hs_l_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_hs_right_mux =
+	SOC_DAPM_ENUM_EXT("Headset Right", cpcap_hs_r_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_line_left_mux =
+	SOC_DAPM_ENUM_EXT("Line Left", cpcap_line_l_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_line_right_mux =
+	SOC_DAPM_ENUM_EXT("Line Right", cpcap_line_r_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_speaker_left_mux =
+	SOC_DAPM_ENUM_EXT("Speaker Left", cpcap_spkr_l_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_speaker_right_mux =
+	SOC_DAPM_ENUM_EXT("Speaker Right", cpcap_spkr_r_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_earpiece_mux =
+	SOC_DAPM_ENUM_EXT("Earpiece", cpcap_earpiece_mux_enum,
+			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+
+static const struct snd_kcontrol_new cpcap_hifi_mono_mixer_controls[] = {
+	SOC_DAPM_SINGLE("HiFi Mono Playback Switch",
+		CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC1, 1, 0),
+};
+static const struct snd_kcontrol_new cpcap_ext_mono_mixer_controls[] = {
+	SOC_DAPM_SINGLE("Ext Mono Playback Switch",
+		CPCAP_REG_RXEPOA, CPCAP_BIT_MONO_EXT0, 1, 0),
+};
+
+static const struct snd_kcontrol_new cpcap_extr_mute_control =
+	SOC_DAPM_SINGLE("Switch",
+		CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_IN_R_SW, 1, 0);
+static const struct snd_kcontrol_new cpcap_extl_mute_control =
+	SOC_DAPM_SINGLE("Switch",
+		CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_IN_L_SW, 1, 0);
+
+static const struct snd_kcontrol_new cpcap_voice_loopback =
+	SOC_DAPM_SINGLE("Switch",
+		CPCAP_REG_TXI, CPCAP_BIT_DLM, 1, 0);
+
+static const struct snd_soc_dapm_widget cpcap_dapm_widgets[] = {
+	/* DAIs */
+	SND_SOC_DAPM_AIF_IN("HiFi RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("Voice RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("Voice TX", NULL, 0, SND_SOC_NOPM, 0, 0),
+
+	/* Power Supply */
+	SND_SOC_DAPM_REGULATOR_SUPPLY("VAUDIO", SLEEP_ACTIVATE_POWER, 0),
+
+	/* Highpass Filters */
+	SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Highpass Filter RX",
+		CPCAP_REG_CC, CPCAP_BIT_AUDIHPF_0, 0x3, 0x3, 0x0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Highpass Filter TX",
+		CPCAP_REG_CC, CPCAP_BIT_AUDOHPF_0, 0x3, 0x3, 0x0),
+
+	/* Clocks */
+	SND_SOC_DAPM_SUPPLY("HiFi DAI Clock",
+		CPCAP_REG_SDACDI, CPCAP_BIT_ST_CLK_EN, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("Voice DAI Clock",
+		CPCAP_REG_CDI, CPCAP_BIT_CDC_CLK_EN, 0, NULL, 0),
+
+	/* Microphone Bias */
+	SND_SOC_DAPM_SUPPLY("MIC1R Bias",
+		CPCAP_REG_TXI, CPCAP_BIT_MB_ON1R, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MIC1L Bias",
+		CPCAP_REG_TXI, CPCAP_BIT_MB_ON1L, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MIC2 Bias",
+		CPCAP_REG_TXI, CPCAP_BIT_MB_ON2, 0, NULL, 0),
+
+	/* Inputs */
+	SND_SOC_DAPM_INPUT("MICR"),
+	SND_SOC_DAPM_INPUT("HSMIC"),
+	SND_SOC_DAPM_INPUT("EMUMIC"),
+	SND_SOC_DAPM_INPUT("MICL"),
+	SND_SOC_DAPM_INPUT("EXTR"),
+	SND_SOC_DAPM_INPUT("EXTL"),
+
+	/* Capture Route */
+	SND_SOC_DAPM_MUX("Right Capture Route",
+		SND_SOC_NOPM, 0, 0, &cpcap_input_right_mux),
+	SND_SOC_DAPM_MUX("Left Capture Route",
+		SND_SOC_NOPM, 0, 0, &cpcap_input_left_mux),
+
+	/* Capture PGAs */
+	SND_SOC_DAPM_PGA("Microphone 1 PGA",
+		CPCAP_REG_TXI, CPCAP_BIT_MIC1_PGA_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Microphone 2 PGA",
+		CPCAP_REG_TXI, CPCAP_BIT_MIC2_PGA_EN, 0, NULL, 0),
+
+	/* ADC */
+	SND_SOC_DAPM_ADC("ADC Right", NULL,
+		CPCAP_REG_CC, CPCAP_BIT_MIC1_CDC_EN, 0),
+	SND_SOC_DAPM_ADC("ADC Left", NULL,
+		CPCAP_REG_CC, CPCAP_BIT_MIC2_CDC_EN, 0),
+
+	/* DAC */
+	SND_SOC_DAPM_DAC_E("DAC HiFi", NULL,
+		CPCAP_REG_SDAC, CPCAP_BIT_ST_DAC_EN, 0,
+		cpcap_st_workaround,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_DAC_E("DAC Voice", NULL,
+		CPCAP_REG_CC, CPCAP_BIT_CDC_EN_RX, 0,
+		cpcap_st_workaround,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+
+	/* Playback PGA */
+	SND_SOC_DAPM_PGA("HiFi PGA",
+		CPCAP_REG_RXSDOA, CPCAP_BIT_PGA_DAC_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Voice PGA",
+		CPCAP_REG_RXCOA, CPCAP_BIT_PGA_CDC_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA_E("Ext Right PGA",
+		CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_EXT_R_EN, 0,
+		NULL, 0,
+		cpcap_st_workaround,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+	SND_SOC_DAPM_PGA_E("Ext Left PGA",
+		CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_EXT_L_EN, 0,
+		NULL, 0,
+		cpcap_st_workaround,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+
+	/* Playback Switch */
+	SND_SOC_DAPM_SWITCH("Ext Right Enable", SND_SOC_NOPM, 0, 0,
+		&cpcap_extr_mute_control),
+	SND_SOC_DAPM_SWITCH("Ext Left Enable", SND_SOC_NOPM, 0, 0,
+		&cpcap_extl_mute_control),
+
+	/* Loopback Switch */
+	SND_SOC_DAPM_SWITCH("Voice Loopback", SND_SOC_NOPM, 0, 0,
+		&cpcap_voice_loopback),
+
+	/* Mono Mixer */
+	SOC_MIXER_ARRAY("HiFi Mono Left Mixer", SND_SOC_NOPM, 0, 0,
+		cpcap_hifi_mono_mixer_controls),
+	SOC_MIXER_ARRAY("HiFi Mono Right Mixer", SND_SOC_NOPM, 0, 0,
+		cpcap_hifi_mono_mixer_controls),
+	SOC_MIXER_ARRAY("Ext Mono Left Mixer", SND_SOC_NOPM, 0, 0,
+		cpcap_ext_mono_mixer_controls),
+	SOC_MIXER_ARRAY("Ext Mono Right Mixer", SND_SOC_NOPM, 0, 0,
+		cpcap_ext_mono_mixer_controls),
+
+	/* Output Routes */
+	SND_SOC_DAPM_MUX("Earpiece Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_earpiece_mux),
+	SND_SOC_DAPM_MUX("Speaker Right Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_speaker_right_mux),
+	SND_SOC_DAPM_MUX("Speaker Left Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_speaker_left_mux),
+	SND_SOC_DAPM_MUX("Lineout Right Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_line_right_mux),
+	SND_SOC_DAPM_MUX("Lineout Left Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_line_left_mux),
+	SND_SOC_DAPM_MUX("Headset Right Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_hs_right_mux),
+	SND_SOC_DAPM_MUX("Headset Left Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_hs_left_mux),
+	SND_SOC_DAPM_MUX("EMU Right Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_emu_right_mux),
+	SND_SOC_DAPM_MUX("EMU Left Playback Route", SND_SOC_NOPM, 0, 0,
+		&cpcap_emu_left_mux),
+
+	/* Output Amplifier */
+	SND_SOC_DAPM_PGA("Earpiece PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_A1_EAR_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Speaker Right PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_A2_LDSP_R_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Speaker Left PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_A2_LDSP_L_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Lineout Right PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_A4_LINEOUT_R_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Lineout Left PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_A4_LINEOUT_L_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Headset Right PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_HS_R_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Headset Left PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_HS_L_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("EMU Right PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_R_EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("EMU Left PGA",
+		CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_L_EN, 0, NULL, 0),
+
+	/* Headet Charge Pump */
+	SND_SOC_DAPM_SUPPLY("Headset Charge Pump",
+		CPCAP_REG_RXOA, CPCAP_BIT_ST_HS_CP_EN, 0, NULL, 0),
+
+	/* Outputs */
+	SND_SOC_DAPM_OUTPUT("EP"),
+	SND_SOC_DAPM_OUTPUT("SPKR"),
+	SND_SOC_DAPM_OUTPUT("SPKL"),
+	SND_SOC_DAPM_OUTPUT("LINER"),
+	SND_SOC_DAPM_OUTPUT("LINEL"),
+	SND_SOC_DAPM_OUTPUT("HSR"),
+	SND_SOC_DAPM_OUTPUT("HSL"),
+	SND_SOC_DAPM_OUTPUT("EMUR"),
+	SND_SOC_DAPM_OUTPUT("EMUL"),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+	/* Power Supply */
+	{"HiFi PGA", NULL, "VAUDIO"},
+	{"Voice PGA", NULL, "VAUDIO"},
+	{"Ext Right PGA", NULL, "VAUDIO"},
+	{"Ext Left PGA", NULL, "VAUDIO"},
+	{"Microphone 1 PGA", NULL, "VAUDIO"},
+	{"Microphone 2 PGA", NULL, "VAUDIO"},
+
+	/* Stream -> AIF */
+	{"HiFi RX", NULL, "HiFi Playback"},
+	{"Voice RX", NULL, "Voice Playback"},
+	{"Voice Capture", NULL, "Voice TX"},
+
+	/* AIF clocks */
+	{"HiFi RX", NULL, "HiFi DAI Clock"},
+	{"Voice RX", NULL, "Voice DAI Clock"},
+	{"Voice TX", NULL, "Voice DAI Clock"},
+
+	/* Digital Loopback */
+	{"Voice Loopback", "Switch", "Voice TX"},
+	{"Voice RX", NULL, "Voice Loopback"},
+
+	/* Highpass Filters */
+	{"Highpass Filter RX", NULL, "Voice RX"},
+	{"Voice TX", NULL, "Highpass Filter TX"},
+
+	/* AIF -> DAC mapping */
+	{"DAC HiFi", NULL, "HiFi RX"},
+	{"DAC Voice", NULL, "Highpass Filter RX"},
+
+	/* DAC -> PGA */
+	{"HiFi PGA", NULL, "DAC HiFi"},
+	{"Voice PGA", NULL, "DAC Voice"},
+
+	/* Ext Input -> PGA */
+	{"Ext Right PGA", NULL, "EXTR"},
+	{"Ext Left PGA", NULL, "EXTL"},
+
+	/* Ext PGA -> Ext Playback Switch */
+	{"Ext Right Enable", "Switch", "Ext Right PGA"},
+	{"Ext Left Enable", "Switch", "Ext Left PGA"},
+
+	/* HiFi PGA -> Mono Mixer */
+	{"HiFi Mono Left Mixer", NULL, "HiFi PGA"},
+	{"HiFi Mono Left Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
+	{"HiFi Mono Right Mixer", NULL, "HiFi PGA"},
+	{"HiFi Mono Right Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
+
+	/* Ext Playback Switch -> Ext Mono Mixer */
+	{"Ext Mono Right Mixer", NULL, "Ext Right Enable"},
+	{"Ext Mono Right Mixer", "Ext Mono Playback Switch", "Ext Left Enable"},
+	{"Ext Mono Left Mixer", NULL, "Ext Left Enable"},
+	{"Ext Mono Left Mixer", "Ext Mono Playback Switch", "Ext Right Enable"},
+
+	/* HiFi Mono Mixer -> Output Route */
+	{"Earpiece Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+	{"Speaker Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+	{"Speaker Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
+	{"Lineout Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+	{"Lineout Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
+	{"Headset Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+	{"Headset Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
+	{"EMU Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+	{"EMU Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
+
+	/* Voice PGA -> Output Route */
+	{"Earpiece Playback Route", "Voice", "Voice PGA"},
+	{"Speaker Right Playback Route", "Voice", "Voice PGA"},
+	{"Speaker Left Playback Route", "Voice", "Voice PGA"},
+	{"Lineout Right Playback Route", "Voice", "Voice PGA"},
+	{"Lineout Left Playback Route", "Voice", "Voice PGA"},
+	{"Headset Right Playback Route", "Voice", "Voice PGA"},
+	{"Headset Left Playback Route", "Voice", "Voice PGA"},
+	{"EMU Right Playback Route", "Voice", "Voice PGA"},
+	{"EMU Left Playback Route", "Voice", "Voice PGA"},
+
+	/* Ext Mono Mixer -> Output Route */
+	{"Earpiece Playback Route", "Ext", "Ext Mono Right Mixer"},
+	{"Speaker Right Playback Route", "Ext", "Ext Mono Right Mixer"},
+	{"Speaker Left Playback Route", "Ext", "Ext Mono Left Mixer"},
+	{"Lineout Right Playback Route", "Ext", "Ext Mono Right Mixer"},
+	{"Lineout Left Playback Route", "Ext", "Ext Mono Left Mixer"},
+	{"Headset Right Playback Route", "Ext", "Ext Mono Right Mixer"},
+	{"Headset Left Playback Route", "Ext", "Ext Mono Left Mixer"},
+	{"EMU Right Playback Route", "Ext", "Ext Mono Right Mixer"},
+	{"EMU Left Playback Route", "Ext", "Ext Mono Left Mixer"},
+
+	/* Output Route -> Output Amplifier */
+	{"Earpiece PGA", NULL, "Earpiece Playback Route"},
+	{"Speaker Right PGA", NULL, "Speaker Right Playback Route"},
+	{"Speaker Left PGA", NULL, "Speaker Left Playback Route"},
+	{"Lineout Right PGA", NULL, "Lineout Right Playback Route"},
+	{"Lineout Left PGA", NULL, "Lineout Left Playback Route"},
+	{"Headset Right PGA", NULL, "Headset Right Playback Route"},
+	{"Headset Left PGA", NULL, "Headset Left Playback Route"},
+	{"EMU Right PGA", NULL, "EMU Right Playback Route"},
+	{"EMU Left PGA", NULL, "EMU Left Playback Route"},
+
+	/* Output Amplifier -> Output */
+	{"EP", NULL, "Earpiece PGA"},
+	{"SPKR", NULL, "Speaker Right PGA"},
+	{"SPKL", NULL, "Speaker Left PGA"},
+	{"LINER", NULL, "Lineout Right PGA"},
+	{"LINEL", NULL, "Lineout Left PGA"},
+	{"HSR", NULL, "Headset Right PGA"},
+	{"HSL", NULL, "Headset Left PGA"},
+	{"EMUR", NULL, "EMU Right PGA"},
+	{"EMUL", NULL, "EMU Left PGA"},
+
+	/* Headset Charge Pump -> Headset */
+	{"HSR", NULL, "Headset Charge Pump"},
+	{"HSL", NULL, "Headset Charge Pump"},
+
+	/* Mic -> Mic Route */
+	{"Right Capture Route", "Mic 1", "MICR"},
+	{"Right Capture Route", "Headset Mic", "HSMIC"},
+	{"Right Capture Route", "EMU Mic", "EMUMIC"},
+	{"Right Capture Route", "Ext Right", "EXTR"},
+	{"Left Capture Route", "Mic 2", "MICL"},
+	{"Left Capture Route", "Ext Left", "EXTL"},
+
+	/* Input Route -> Microphone PGA */
+	{"Microphone 1 PGA", NULL, "Right Capture Route"},
+	{"Microphone 2 PGA", NULL, "Left Capture Route"},
+
+	/* Microphone PGA -> ADC */
+	{"ADC Right", NULL, "Microphone 1 PGA"},
+	{"ADC Left", NULL, "Microphone 2 PGA"},
+
+	/* ADC -> Stream */
+	{"Highpass Filter TX", NULL, "ADC Right"},
+	{"Highpass Filter TX", NULL, "ADC Left"},
+
+	/* Mic Bias */
+	{"MICL", NULL, "MIC1L Bias"},
+	{"MICR", NULL, "MIC1R Bias"},
+};
+
+static int cpcap_set_sysclk(struct cpcap_audio *cpcap, enum cpcap_dai dai,
+			    int clk_id, int freq)
+{
+	u16 clkfreqreg, clkfreqshift;
+	u16 clkfreqmask, clkfreqval;
+	u16 clkidreg, clkidshift;
+	u16 mask, val;
+	int err;
+
+	switch (dai) {
+	case CPCAP_DAI_HIFI:
+		clkfreqreg = CPCAP_REG_SDAC;
+		clkfreqshift = CPCAP_BIT_ST_DAC_CLK0;
+		clkidreg = CPCAP_REG_SDACDI;
+		clkidshift = CPCAP_BIT_ST_DAC_CLK_IN_SEL;
+		break;
+	case CPCAP_DAI_VOICE:
+		clkfreqreg = CPCAP_REG_CC;
+		clkfreqshift = CPCAP_BIT_CDC_CLK0;
+		clkidreg = CPCAP_REG_CDI;
+		clkidshift = CPCAP_BIT_CLK_IN_SEL;
+		break;
+	default:
+		dev_err(cpcap->component->dev, "invalid DAI: %d", dai);
+		return -EINVAL;
+	}
+
+	/* setup clk id */
+	if (clk_id < 0 || clk_id > 1) {
+		dev_err(cpcap->component->dev, "invalid clk id %d", clk_id);
+		return -EINVAL;
+	}
+	err = regmap_update_bits(cpcap->regmap, clkidreg, BIT(clkidshift),
+				 clk_id ? BIT(clkidshift) : 0);
+	if (err)
+		return err;
+
+	/* enable PLL for Voice DAI */
+	if (dai == CPCAP_DAI_VOICE) {
+		mask = BIT(CPCAP_BIT_CDC_PLL_SEL);
+		val = BIT(CPCAP_BIT_CDC_PLL_SEL);
+		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
+					 mask, val);
+		if (err)
+			return err;
+	}
+
+	/* setup frequency */
+	clkfreqmask = 0x7 << clkfreqshift;
+	switch (freq) {
+	case 15360000:
+		clkfreqval = 0x01 << clkfreqshift;
+		break;
+	case 16800000:
+		clkfreqval = 0x02 << clkfreqshift;
+		break;
+	case 19200000:
+		clkfreqval = 0x03 << clkfreqshift;
+		break;
+	case 26000000:
+		clkfreqval = 0x04 << clkfreqshift;
+		break;
+	case 33600000:
+		clkfreqval = 0x05 << clkfreqshift;
+		break;
+	case 38400000:
+		clkfreqval = 0x06 << clkfreqshift;
+		break;
+	default:
+		dev_err(cpcap->component->dev, "unsupported freq %u", freq);
+		return -EINVAL;
+	}
+
+	err = regmap_update_bits(cpcap->regmap, clkfreqreg,
+				 clkfreqmask, clkfreqval);
+	if (err)
+		return err;
+
+	if (dai == CPCAP_DAI_VOICE) {
+		cpcap->codec_clk_id = clk_id;
+		cpcap->codec_freq = freq;
+	}
+
+	return 0;
+}
+
+static int cpcap_set_samprate(struct cpcap_audio *cpcap, enum cpcap_dai dai,
+			      int samplerate)
+{
+	struct snd_soc_component *component = cpcap->component;
+	u16 sampreg, sampmask, sampshift, sampval, sampreset;
+	int err, sampreadval;
+
+	switch (dai) {
+	case CPCAP_DAI_HIFI:
+		sampreg = CPCAP_REG_SDAC;
+		sampshift = CPCAP_BIT_ST_SR0;
+		sampreset = BIT(CPCAP_BIT_DF_RESET_ST_DAC) |
+			    BIT(CPCAP_BIT_ST_CLOCK_TREE_RESET);
+		break;
+	case CPCAP_DAI_VOICE:
+		sampreg = CPCAP_REG_CC;
+		sampshift = CPCAP_BIT_CDC_SR0;
+		sampreset = BIT(CPCAP_BIT_DF_RESET) |
+			    BIT(CPCAP_BIT_CDC_CLOCK_TREE_RESET);
+		break;
+	default:
+		dev_err(component->dev, "invalid DAI: %d", dai);
+		return -EINVAL;
+	}
+
+	sampmask = 0xF << sampshift | sampreset;
+	switch (samplerate) {
+	case 48000:
+		sampval = 0x8 << sampshift;
+		break;
+	case 44100:
+		sampval = 0x7 << sampshift;
+		break;
+	case 32000:
+		sampval = 0x6 << sampshift;
+		break;
+	case 24000:
+		sampval = 0x5 << sampshift;
+		break;
+	case 22050:
+		sampval = 0x4 << sampshift;
+		break;
+	case 16000:
+		sampval = 0x3 << sampshift;
+		break;
+	case 12000:
+		sampval = 0x2 << sampshift;
+		break;
+	case 11025:
+		sampval = 0x1 << sampshift;
+		break;
+	case 8000:
+		sampval = 0x0 << sampshift;
+		break;
+	default:
+		dev_err(component->dev, "unsupported samplerate %d", samplerate);
+		return -EINVAL;
+	}
+	err = regmap_update_bits(cpcap->regmap, sampreg,
+				 sampmask, sampval | sampreset);
+	if (err)
+		return err;
+
+	/* Wait for clock tree reset to complete */
+	mdelay(CLOCK_TREE_RESET_TIME);
+
+	err = regmap_read(cpcap->regmap, sampreg, &sampreadval);
+	if (err)
+		return err;
+
+	if (sampreadval & sampreset) {
+		dev_err(component->dev, "reset self-clear failed: %04x",
+			sampreadval);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int cpcap_hifi_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params,
+				struct snd_soc_dai *dai)
+{
+	struct snd_soc_component *component = dai->component;
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	int rate = params_rate(params);
+
+	dev_dbg(component->dev, "HiFi setup HW params: rate=%d", rate);
+	return cpcap_set_samprate(cpcap, CPCAP_DAI_HIFI, rate);
+}
+
+static int cpcap_hifi_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
+				     unsigned int freq, int dir)
+{
+	struct snd_soc_component *component = codec_dai->component;
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	struct device *dev = component->dev;
+
+	dev_dbg(dev, "HiFi setup sysclk: clk_id=%u, freq=%u", clk_id, freq);
+	return cpcap_set_sysclk(cpcap, CPCAP_DAI_HIFI, clk_id, freq);
+}
+
+static int cpcap_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
+				  unsigned int fmt)
+{
+	struct snd_soc_component *component = codec_dai->component;
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	struct device *dev = component->dev;
+	static const u16 reg = CPCAP_REG_SDACDI;
+	static const u16 mask =
+		BIT(CPCAP_BIT_SMB_ST_DAC) |
+		BIT(CPCAP_BIT_ST_CLK_INV) |
+		BIT(CPCAP_BIT_ST_FS_INV) |
+		BIT(CPCAP_BIT_ST_DIG_AUD_FS0) |
+		BIT(CPCAP_BIT_ST_DIG_AUD_FS1) |
+		BIT(CPCAP_BIT_ST_L_TIMESLOT0) |
+		BIT(CPCAP_BIT_ST_L_TIMESLOT1) |
+		BIT(CPCAP_BIT_ST_L_TIMESLOT2) |
+		BIT(CPCAP_BIT_ST_R_TIMESLOT0) |
+		BIT(CPCAP_BIT_ST_R_TIMESLOT1) |
+		BIT(CPCAP_BIT_ST_R_TIMESLOT2);
+	u16 val = 0x0000;
+
+	dev_dbg(dev, "HiFi setup dai format (%08x)", fmt);
+
+	/*
+	 * "HiFi Playback" should always be configured as
+	 * SND_SOC_DAIFMT_CBM_CFM - codec clk & frm master
+	 * SND_SOC_DAIFMT_I2S - I2S mode
+	 */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		val &= ~BIT(CPCAP_BIT_SMB_ST_DAC);
+		break;
+	default:
+		dev_err(dev, "HiFi dai fmt failed: CPCAP should be master");
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_IB_IF:
+		val |= BIT(CPCAP_BIT_ST_FS_INV);
+		val |= BIT(CPCAP_BIT_ST_CLK_INV);
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		val &= ~BIT(CPCAP_BIT_ST_FS_INV);
+		val |= BIT(CPCAP_BIT_ST_CLK_INV);
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		val |= BIT(CPCAP_BIT_ST_FS_INV);
+		val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
+		break;
+	case SND_SOC_DAIFMT_NB_NF:
+		val &= ~BIT(CPCAP_BIT_ST_FS_INV);
+		val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
+		break;
+	default:
+		dev_err(dev, "HiFi dai fmt failed: unsupported clock invert mode");
+		return -EINVAL;
+	}
+
+	if (val & BIT(CPCAP_BIT_ST_CLK_INV))
+		val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
+	else
+		val |= BIT(CPCAP_BIT_ST_CLK_INV);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS0);
+		val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS1);
+		break;
+	default:
+		/* 01 - 4 slots network mode */
+		val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS0);
+		val &= ~BIT(CPCAP_BIT_ST_DIG_AUD_FS1);
+		/* L on slot 1 */
+		val |= BIT(CPCAP_BIT_ST_L_TIMESLOT0);
+		break;
+	}
+
+	dev_dbg(dev, "HiFi dai format: val=%04x", val);
+	return regmap_update_bits(cpcap->regmap, reg, mask, val);
+}
+
+static int cpcap_hifi_set_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_component *component = dai->component;
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	static const u16 reg = CPCAP_REG_RXSDOA;
+	static const u16 mask = BIT(CPCAP_BIT_ST_DAC_SW);
+	u16 val;
+
+	if (mute)
+		val = 0;
+	else
+		val = BIT(CPCAP_BIT_ST_DAC_SW);
+
+	dev_dbg(component->dev, "HiFi mute: %d", mute);
+	return regmap_update_bits(cpcap->regmap, reg, mask, val);
+}
+
+static const struct snd_soc_dai_ops cpcap_dai_hifi_ops = {
+	.hw_params	= cpcap_hifi_hw_params,
+	.set_sysclk	= cpcap_hifi_set_dai_sysclk,
+	.set_fmt	= cpcap_hifi_set_dai_fmt,
+	.digital_mute	= cpcap_hifi_set_mute,
+};
+
+static int cpcap_voice_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *dev = component->dev;
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	static const u16 reg_cdi = CPCAP_REG_CDI;
+	int rate = params_rate(params);
+	int channels = params_channels(params);
+	int direction = substream->stream;
+	u16 val, mask;
+	int err;
+
+	dev_dbg(dev, "Voice setup HW params: rate=%d, direction=%d, chan=%d",
+		rate, direction, channels);
+
+	err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, rate);
+	if (err)
+		return err;
+
+	if (direction == SNDRV_PCM_STREAM_CAPTURE) {
+		mask = 0x0000;
+		mask |= CPCAP_BIT_MIC1_RX_TIMESLOT0;
+		mask |= CPCAP_BIT_MIC1_RX_TIMESLOT1;
+		mask |= CPCAP_BIT_MIC1_RX_TIMESLOT2;
+		mask |= CPCAP_BIT_MIC2_TIMESLOT0;
+		mask |= CPCAP_BIT_MIC2_TIMESLOT1;
+		mask |= CPCAP_BIT_MIC2_TIMESLOT2;
+		val = 0x0000;
+		if (channels >= 2)
+			val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
+		err = regmap_update_bits(cpcap->regmap, reg_cdi, mask, val);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int cpcap_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
+				      unsigned int freq, int dir)
+{
+	struct snd_soc_component *component = codec_dai->component;
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+
+	dev_dbg(component->dev, "Voice setup sysclk: clk_id=%u, freq=%u",
+		clk_id, freq);
+	return cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, clk_id, freq);
+}
+
+static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
+				   unsigned int fmt)
+{
+	struct snd_soc_component *component = codec_dai->component;
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	static const u16 mask = BIT(CPCAP_BIT_SMB_CDC) |
+				BIT(CPCAP_BIT_CLK_INV) |
+				BIT(CPCAP_BIT_FS_INV) |
+				BIT(CPCAP_BIT_CDC_DIG_AUD_FS0) |
+				BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
+	u16 val = 0x0000;
+	int err;
+
+	dev_dbg(component->dev, "Voice setup dai format (%08x)", fmt);
+
+	/*
+	 * "Voice Playback" and "Voice Capture" should always be
+	 * configured as SND_SOC_DAIFMT_CBM_CFM - codec clk & frm
+	 * master
+	 */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		val &= ~BIT(CPCAP_BIT_SMB_CDC);
+		break;
+	default:
+		dev_err(component->dev, "Voice dai fmt failed: CPCAP should be the master");
+		val &= ~BIT(CPCAP_BIT_SMB_CDC);
+		break;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_IB_IF:
+		val |= BIT(CPCAP_BIT_CLK_INV);
+		val |= BIT(CPCAP_BIT_FS_INV);
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		val |= BIT(CPCAP_BIT_CLK_INV);
+		val &= ~BIT(CPCAP_BIT_FS_INV);
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		val &= ~BIT(CPCAP_BIT_CLK_INV);
+		val |= BIT(CPCAP_BIT_FS_INV);
+		break;
+	case SND_SOC_DAIFMT_NB_NF:
+		val &= ~BIT(CPCAP_BIT_CLK_INV);
+		val &= ~BIT(CPCAP_BIT_FS_INV);
+		break;
+	default:
+		dev_err(component->dev, "Voice dai fmt failed: unsupported clock invert mode");
+		break;
+	}
+
+	if (val & BIT(CPCAP_BIT_CLK_INV))
+		val &= ~BIT(CPCAP_BIT_CLK_INV);
+	else
+		val |= BIT(CPCAP_BIT_CLK_INV);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		/* 11 - true I2S mode */
+		val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS0);
+		val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
+		break;
+	default:
+		/* 4 timeslots network mode */
+		val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS0);
+		val &= ~BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
+		break;
+	}
+
+	dev_dbg(component->dev, "Voice dai format: val=%04x", val);
+	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, mask, val);
+	if (err)
+		return err;
+
+	cpcap->codec_format = val;
+	return 0;
+}
+
+static int cpcap_voice_set_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_component *component = dai->component;
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	static const u16 reg = CPCAP_REG_RXCOA;
+	static const u16 mask = BIT(CPCAP_BIT_CDC_SW);
+	u16 val;
+
+	if (mute)
+		val = 0;
+	else
+		val = BIT(CPCAP_BIT_CDC_SW);
+
+	dev_dbg(component->dev, "Voice mute: %d", mute);
+	return regmap_update_bits(cpcap->regmap, reg, mask, val);
+};
+
+static const struct snd_soc_dai_ops cpcap_dai_voice_ops = {
+	.hw_params	= cpcap_voice_hw_params,
+	.set_sysclk	= cpcap_voice_set_dai_sysclk,
+	.set_fmt	= cpcap_voice_set_dai_fmt,
+	.digital_mute	= cpcap_voice_set_mute,
+};
+
+static struct snd_soc_dai_driver cpcap_dai[] = {
+{
+	.id = 0,
+	.name = "cpcap-hifi",
+	.playback = {
+		.stream_name = "HiFi Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE,
+	},
+	.ops = &cpcap_dai_hifi_ops,
+},
+{
+	.id = 1,
+	.name = "cpcap-voice",
+	.playback = {
+		.stream_name = "Voice Playback",
+		.channels_min = 1,
+		.channels_max = 1,
+		.rates = SNDRV_PCM_RATE_8000_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.capture = {
+		.stream_name = "Voice Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.ops = &cpcap_dai_voice_ops,
+},
+};
+
+static int cpcap_dai_mux(struct cpcap_audio *cpcap, bool swap_dai_configuration)
+{
+	u16 hifi_val, voice_val;
+	u16 hifi_mask = BIT(CPCAP_BIT_DIG_AUD_IN_ST_DAC);
+	u16 voice_mask = BIT(CPCAP_BIT_DIG_AUD_IN);
+	int err;
+
+
+
+	if (!swap_dai_configuration) {
+		/* Codec on DAI0, HiFi on DAI1 */
+		voice_val = 0;
+		hifi_val = hifi_mask;
+	} else {
+		/* Codec on DAI1, HiFi on DAI0 */
+		voice_val = voice_mask;
+		hifi_val = 0;
+	}
+
+	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
+				 voice_mask, voice_val);
+	if (err)
+		return err;
+
+	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_SDACDI,
+				 hifi_mask, hifi_val);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int cpcap_audio_reset(struct snd_soc_component *component,
+			     bool swap_dai_configuration)
+{
+	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+	int i, err = 0;
+
+	dev_dbg(component->dev, "init audio codec");
+
+	for (i = 0; i < ARRAY_SIZE(cpcap_default_regs); i++) {
+		err = regmap_update_bits(cpcap->regmap,
+					 cpcap_default_regs[i].reg,
+					 cpcap_default_regs[i].mask,
+					 cpcap_default_regs[i].val);
+		if (err)
+			return err;
+	}
+
+	/* setup default settings */
+	err = cpcap_dai_mux(cpcap, swap_dai_configuration);
+	if (err)
+		return err;
+
+	err = cpcap_set_sysclk(cpcap, CPCAP_DAI_HIFI, 0, 26000000);
+	if (err)
+		return err;
+	err = cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, 0, 26000000);
+	if (err)
+		return err;
+
+	err = cpcap_set_samprate(cpcap, CPCAP_DAI_HIFI, 48000);
+	if (err)
+		return err;
+
+	err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, 48000);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int cpcap_soc_probe(struct snd_soc_component *component)
+{
+	struct cpcap_audio *cpcap;
+	int err;
+
+	cpcap = devm_kzalloc(component->dev, sizeof(*cpcap), GFP_KERNEL);
+	if (!cpcap)
+		return -ENOMEM;
+	snd_soc_component_set_drvdata(component, cpcap);
+	cpcap->component = component;
+
+	cpcap->regmap = dev_get_regmap(component->dev->parent, NULL);
+	if (!cpcap->regmap)
+		return -ENODEV;
+	snd_soc_component_init_regmap(component, cpcap->regmap);
+
+	err = cpcap_get_vendor(component->dev, cpcap->regmap, &cpcap->vendor);
+	if (err)
+		return err;
+
+	return cpcap_audio_reset(component, false);
+}
+
+static struct snd_soc_component_driver soc_codec_dev_cpcap = {
+	.probe			= cpcap_soc_probe,
+	.controls		= cpcap_snd_controls,
+	.num_controls		= ARRAY_SIZE(cpcap_snd_controls),
+	.dapm_widgets		= cpcap_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cpcap_dapm_widgets),
+	.dapm_routes		= intercon,
+	.num_dapm_routes	= ARRAY_SIZE(intercon),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
+
+static int cpcap_codec_probe(struct platform_device *pdev)
+{
+	struct device_node *codec_node =
+		of_get_child_by_name(pdev->dev.parent->of_node, "audio-codec");
+
+	pdev->dev.of_node = codec_node;
+
+	return devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_cpcap,
+				      cpcap_dai, ARRAY_SIZE(cpcap_dai));
+}
+
+static struct platform_driver cpcap_codec_driver = {
+	.probe		= cpcap_codec_probe,
+	.driver		= {
+		.name	= "cpcap-codec",
+	},
+};
+module_platform_driver(cpcap_codec_driver);
+
+MODULE_ALIAS("platform:cpcap-codec");
+MODULE_DESCRIPTION("ASoC CPCAP codec driver");
+MODULE_AUTHOR("Sebastian Reichel");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 3bf9365..3301861 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -45,7 +45,7 @@ static const struct snd_kcontrol_new cq93vc_snd_controls[] = {
 
 static int cq93vc_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 reg;
 
 	if (mute)
@@ -53,7 +53,7 @@ static int cq93vc_mute(struct snd_soc_dai *dai, int mute)
 	else
 		reg = 0;
 
-	snd_soc_update_bits(codec, DAVINCI_VC_REG09, DAVINCI_VC_REG09_MUTE,
+	snd_soc_component_update_bits(component, DAVINCI_VC_REG09, DAVINCI_VC_REG09_MUTE,
 			    reg);
 
 	return 0;
@@ -72,23 +72,23 @@ static int cq93vc_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	return -EINVAL;
 }
 
-static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
+static int cq93vc_set_bias_level(struct snd_soc_component *component,
 				enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		snd_soc_write(codec, DAVINCI_VC_REG12,
+		snd_soc_component_write(component, DAVINCI_VC_REG12,
 			     DAVINCI_VC_REG12_POWER_ALL_ON);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_write(codec, DAVINCI_VC_REG12,
+		snd_soc_component_write(component, DAVINCI_VC_REG12,
 			     DAVINCI_VC_REG12_POWER_ALL_OFF);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* force all power off */
-		snd_soc_write(codec, DAVINCI_VC_REG12,
+		snd_soc_component_write(component, DAVINCI_VC_REG12,
 			     DAVINCI_VC_REG12_POWER_ALL_OFF);
 		break;
 	}
@@ -130,24 +130,25 @@ static int cq93vc_probe(struct snd_soc_component *component)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
-	.set_bias_level = cq93vc_set_bias_level,
-	.component_driver = {
-		.probe = cq93vc_probe,
-		.controls = cq93vc_snd_controls,
-		.num_controls = ARRAY_SIZE(cq93vc_snd_controls),
-	},
+static const struct snd_soc_component_driver soc_component_dev_cq93vc = {
+	.set_bias_level		= cq93vc_set_bias_level,
+	.probe			= cq93vc_probe,
+	.controls		= cq93vc_snd_controls,
+	.num_controls		= ARRAY_SIZE(cq93vc_snd_controls),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int cq93vc_platform_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_cq93vc, &cq93vc_dai, 1);
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_cq93vc, &cq93vc_dai, 1);
 }
 
 static int cq93vc_platform_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c
index bc3a72e..4297058 100644
--- a/sound/soc/codecs/cs35l32.c
+++ b/sound/soc/codecs/cs35l32.c
@@ -43,7 +43,7 @@ static const char *const cs35l32_supply_names[CS35L32_NUM_SUPPLIES] = {
 
 struct  cs35l32_private {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct regulator_bulk_data supplies[CS35L32_NUM_SUPPLIES];
 	struct cs35l32_platform_data pdata;
 	struct gpio_desc *reset_gpio;
@@ -154,16 +154,16 @@ static const struct snd_soc_dapm_route cs35l32_audio_map[] = {
 
 static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
-		snd_soc_update_bits(codec, CS35L32_ADSP_CTL,
+		snd_soc_component_update_bits(component, CS35L32_ADSP_CTL,
 				    CS35L32_ADSP_MASTER_MASK,
 				CS35L32_ADSP_MASTER_MASK);
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
-		snd_soc_update_bits(codec, CS35L32_ADSP_CTL,
+		snd_soc_component_update_bits(component, CS35L32_ADSP_CTL,
 				    CS35L32_ADSP_MASTER_MASK, 0);
 		break;
 	default:
@@ -175,9 +175,9 @@ static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int cs35l32_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	return snd_soc_update_bits(codec, CS35L32_PWRCTL2,
+	return snd_soc_component_update_bits(component, CS35L32_PWRCTL2,
 					CS35L32_SDOUT_3ST, tristate << 3);
 }
 
@@ -202,7 +202,7 @@ static struct snd_soc_dai_driver cs35l32_dai[] = {
 	}
 };
 
-static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec,
+static int cs35l32_component_set_sysclk(struct snd_soc_component *component,
 			      int clk_id, int source, unsigned int freq, int dir)
 {
 	unsigned int val;
@@ -224,21 +224,22 @@ static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec,
 		return -EINVAL;
 	}
 
-	return snd_soc_update_bits(codec, CS35L32_CLK_CTL,
+	return snd_soc_component_update_bits(component, CS35L32_CLK_CTL,
 			CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = {
-	.set_sysclk = cs35l32_codec_set_sysclk,
-
-	.component_driver = {
-		.controls		= cs35l32_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs35l32_snd_controls),
-		.dapm_widgets		= cs35l32_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs35l32_dapm_widgets),
-		.dapm_routes		= cs35l32_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(cs35l32_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_cs35l32 = {
+	.set_sysclk		= cs35l32_component_set_sysclk,
+	.controls		= cs35l32_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs35l32_snd_controls),
+	.dapm_widgets		= cs35l32_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs35l32_dapm_widgets),
+	.dapm_routes		= cs35l32_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs35l32_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /* Current and threshold powerup sequence Pg37 in datasheet */
@@ -483,8 +484,8 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
 	/* Clear MCLK Error Bit since we don't have the clock yet */
 	ret = regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, &reg);
 
-	ret =  snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_dev_cs35l32, cs35l32_dai,
+	ret = devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_dev_cs35l32, cs35l32_dai,
 			ARRAY_SIZE(cs35l32_dai));
 	if (ret < 0)
 		goto err_disable;
@@ -501,8 +502,6 @@ static int cs35l32_i2c_remove(struct i2c_client *i2c_client)
 {
 	struct cs35l32_private *cs35l32 = i2c_get_clientdata(i2c_client);
 
-	snd_soc_unregister_codec(&i2c_client->dev);
-
 	/* Hold down reset */
 	gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
 
diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c
index 854cf8f..668cd37 100644
--- a/sound/soc/codecs/cs35l33.c
+++ b/sound/soc/codecs/cs35l33.c
@@ -42,7 +42,7 @@
 #define CS35L33_BOOT_DELAY	50
 
 struct cs35l33_private {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct cs35l33_pdata pdata;
 	struct regmap *regmap;
 	struct gpio_desc *reset_gpio;
@@ -201,8 +201,8 @@ static const struct snd_kcontrol_new cs35l33_snd_controls[] = {
 static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -211,15 +211,15 @@ static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
 			priv->amp_cal = true;
 			regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
 				    CS35L33_AMP_CAL, 0);
-			dev_dbg(codec->dev, "Amp calibration done\n");
+			dev_dbg(component->dev, "Amp calibration done\n");
 		}
-		dev_dbg(codec->dev, "Amp turned on\n");
+		dev_dbg(component->dev, "Amp turned on\n");
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		dev_dbg(codec->dev, "Amp turned off\n");
+		dev_dbg(component->dev, "Amp turned off\n");
 		break;
 	default:
-		dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid event = 0x%x\n", event);
 		break;
 	}
 
@@ -229,8 +229,8 @@ static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
 static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	switch (event) {
@@ -240,14 +240,14 @@ static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
 		val = priv->is_tdm_mode ? 0 : CS35L33_PDN_TDM;
 		regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
 				    CS35L33_PDN_TDM, val);
-		dev_dbg(codec->dev, "BST turned on\n");
+		dev_dbg(component->dev, "BST turned on\n");
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-		dev_dbg(codec->dev, "SDIN turned on\n");
+		dev_dbg(component->dev, "SDIN turned on\n");
 		if (!priv->amp_cal) {
 			regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
 				    CS35L33_AMP_CAL, CS35L33_AMP_CAL);
-			dev_dbg(codec->dev, "Amp calibration started\n");
+			dev_dbg(component->dev, "Amp calibration started\n");
 			usleep_range(10000, 11000);
 		}
 		break;
@@ -257,10 +257,10 @@ static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
 		usleep_range(4000, 4100);
 		regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
 				    CS35L33_PDN_BST, CS35L33_PDN_BST);
-		dev_dbg(codec->dev, "BST and SDIN turned off\n");
+		dev_dbg(component->dev, "BST and SDIN turned off\n");
 		break;
 	default:
-		dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid event = 0x%x\n", event);
 
 	}
 
@@ -270,8 +270,8 @@ static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
 static int cs35l33_sdout_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 	unsigned int mask = CS35L33_SDOUT_3ST_I2S | CS35L33_PDN_TDM;
 	unsigned int mask2 = CS35L33_SDOUT_3ST_TDM;
 	unsigned int val, val2;
@@ -289,15 +289,15 @@ static int cs35l33_sdout_event(struct snd_soc_dapm_widget *w,
 			/* set sdout_3st_tdm */
 			val2 = CS35L33_SDOUT_3ST_TDM;
 		}
-		dev_dbg(codec->dev, "SDOUT turned on\n");
+		dev_dbg(component->dev, "SDOUT turned on\n");
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
 		val = CS35L33_SDOUT_3ST_I2S | CS35L33_PDN_TDM;
 		val2 = CS35L33_SDOUT_3ST_TDM;
-		dev_dbg(codec->dev, "SDOUT turned off\n");
+		dev_dbg(component->dev, "SDOUT turned off\n");
 		break;
 	default:
-		dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid event = 0x%x\n", event);
 		return 0;
 	}
 
@@ -360,11 +360,11 @@ static const struct snd_soc_dapm_route cs35l33_vp_vbst_mon_route[] = {
 	{"VBSTMON", NULL, "MON"},
 };
 
-static int cs35l33_set_bias_level(struct snd_soc_codec *codec,
+static int cs35l33_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
 	unsigned int val;
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -441,19 +441,19 @@ static int cs35l33_get_mclk_coeff(int mclk, int srate)
 
 static int cs35l33_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
 		regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL,
 			CS35L33_MS_MASK, CS35L33_MS_MASK);
-		dev_dbg(codec->dev, "Audio port in master mode\n");
+		dev_dbg(component->dev, "Audio port in master mode\n");
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
 		regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL,
 			CS35L33_MS_MASK, 0);
-		dev_dbg(codec->dev, "Audio port in slave mode\n");
+		dev_dbg(component->dev, "Audio port in slave mode\n");
 		break;
 	default:
 		return -EINVAL;
@@ -466,11 +466,11 @@ static int cs35l33_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		 * closely, it is dsp-a with fsync shifted left by half bclk
 		 */
 		priv->is_tdm_mode = true;
-		dev_dbg(codec->dev, "Audio port in TDM mode\n");
+		dev_dbg(component->dev, "Audio port in TDM mode\n");
 		break;
 	case SND_SOC_DAIFMT_I2S:
 		priv->is_tdm_mode = false;
-		dev_dbg(codec->dev, "Audio port in I2S mode\n");
+		dev_dbg(component->dev, "Audio port in I2S mode\n");
 		break;
 	default:
 		return -EINVAL;
@@ -483,8 +483,8 @@ static int cs35l33_pcm_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 	int sample_size = params_width(params);
 	int coeff = cs35l33_get_mclk_coeff(priv->mclk_int, params_rate(params));
 
@@ -505,7 +505,7 @@ static int cs35l33_pcm_hw_params(struct snd_pcm_substream *substream,
 			sample_size << CS35L33_AUDIN_RX_DEPTH_SHIFT);
 	}
 
-	dev_dbg(codec->dev, "sample rate=%d, bits per sample=%d\n",
+	dev_dbg(component->dev, "sample rate=%d, bits per sample=%d\n",
 		params_rate(params), params_width(params));
 
 	return 0;
@@ -532,8 +532,8 @@ static int cs35l33_pcm_startup(struct snd_pcm_substream *substream,
 
 static int cs35l33_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
 	if (tristate) {
 		regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
@@ -553,9 +553,9 @@ static int cs35l33_set_tristate(struct snd_soc_dai *dai, int tristate)
 static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 				unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 	unsigned int reg, bit_pos, i;
 	int slot, slot_num;
 
@@ -567,7 +567,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	if (slot >= 0) {
 		regmap_update_bits(priv->regmap, CS35L33_RX_AUD,
 			CS35L33_X_LOC, slot);
-		dev_dbg(codec->dev, "Audio starts from slots %d", slot);
+		dev_dbg(component->dev, "Audio starts from slots %d", slot);
 	}
 
 	/*
@@ -593,7 +593,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 		if (slot_num == 0) {
 			regmap_update_bits(priv->regmap, CS35L33_TX_VMON,
 				CS35L33_X_STATE | CS35L33_X_LOC, slot);
-			dev_dbg(codec->dev, "VMON enabled in slots %d-%d",
+			dev_dbg(component->dev, "VMON enabled in slots %d-%d",
 				slot, slot + 1);
 		}
 
@@ -601,7 +601,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 		if (slot_num == 3) {
 			regmap_update_bits(priv->regmap, CS35L33_TX_IMON,
 				CS35L33_X_STATE | CS35L33_X_LOC, slot);
-			dev_dbg(codec->dev, "IMON enabled in slots %d-%d",
+			dev_dbg(component->dev, "IMON enabled in slots %d-%d",
 				slot, slot + 1);
 		}
 
@@ -611,7 +611,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 				CS35L33_X_STATE | CS35L33_X_LOC, slot);
 			snd_soc_dapm_add_routes(dapm,
 				&cs35l33_vp_vbst_mon_route[0], 2);
-			dev_dbg(codec->dev, "VPMON enabled in slots %d", slot);
+			dev_dbg(component->dev, "VPMON enabled in slots %d", slot);
 		}
 
 		/* configure VBSTMON_TX_LOC */
@@ -620,7 +620,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 				CS35L33_X_STATE | CS35L33_X_LOC, slot);
 			snd_soc_dapm_add_routes(dapm,
 				&cs35l33_vp_vbst_mon_route[2], 2);
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"VBSTMON enabled in slots %d", slot);
 		}
 
@@ -638,10 +638,10 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	return 0;
 }
 
-static int cs35l33_codec_set_sysclk(struct snd_soc_codec *codec,
+static int cs35l33_component_set_sysclk(struct snd_soc_component *component,
 		int clk_id, int source, unsigned int freq, int dir)
 {
-	struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
+	struct cs35l33_private *cs35l33 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case CS35L33_MCLK_5644:
@@ -663,7 +663,7 @@ static int cs35l33_codec_set_sysclk(struct snd_soc_codec *codec,
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "external mclk freq=%d, internal mclk freq=%d\n",
+	dev_dbg(component->dev, "external mclk freq=%d, internal mclk freq=%d\n",
 		freq, cs35l33->mclk_int);
 
 	return 0;
@@ -698,12 +698,12 @@ static struct snd_soc_dai_driver cs35l33_dai = {
 		.symmetric_rates = 1,
 };
 
-static int cs35l33_set_hg_data(struct snd_soc_codec *codec,
+static int cs35l33_set_hg_data(struct snd_soc_component *component,
 			       struct cs35l33_pdata *pdata)
 {
 	struct cs35l33_hg *hg_config = &pdata->hg_config;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
 	if (hg_config->enable_hg_algo) {
 		regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL,
@@ -747,20 +747,20 @@ static int cs35l33_set_hg_data(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int cs35l33_set_bst_ipk(struct snd_soc_codec *codec, unsigned int bst)
+static int cs35l33_set_bst_ipk(struct snd_soc_component *component, unsigned int bst)
 {
-	struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
+	struct cs35l33_private *cs35l33 = snd_soc_component_get_drvdata(component);
 	int ret = 0, steps = 0;
 
 	/* Boost current in uA */
 	if (bst > 3600000 || bst < 1850000) {
-		dev_err(codec->dev, "Invalid boost current %d\n", bst);
+		dev_err(component->dev, "Invalid boost current %d\n", bst);
 		ret = -EINVAL;
 		goto err;
 	}
 
 	if (bst % 15625) {
-		dev_err(codec->dev, "Current not a multiple of 15625uA (%d)\n",
+		dev_err(component->dev, "Current not a multiple of 15625uA (%d)\n",
 			bst);
 		ret = -EINVAL;
 		goto err;
@@ -778,12 +778,12 @@ static int cs35l33_set_bst_ipk(struct snd_soc_codec *codec, unsigned int bst)
 	return ret;
 }
 
-static int cs35l33_probe(struct snd_soc_codec *codec)
+static int cs35l33_probe(struct snd_soc_component *component)
 {
-	struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
+	struct cs35l33_private *cs35l33 = snd_soc_component_get_drvdata(component);
 
-	cs35l33->codec = codec;
-	pm_runtime_get_sync(codec->dev);
+	cs35l33->component = component;
+	pm_runtime_get_sync(component->dev);
 
 	regmap_update_bits(cs35l33->regmap, CS35L33_PROTECT_CTL,
 		CS35L33_ALIVE_WD_DIS, 0x8);
@@ -799,24 +799,24 @@ static int cs35l33_probe(struct snd_soc_codec *codec)
 		cs35l33->pdata.amp_drv_sel << CS35L33_AMP_DRV_SEL_SHIFT);
 
 	if (cs35l33->pdata.boost_ipk)
-		cs35l33_set_bst_ipk(codec, cs35l33->pdata.boost_ipk);
+		cs35l33_set_bst_ipk(component, cs35l33->pdata.boost_ipk);
 
 	if (cs35l33->enable_soft_ramp) {
-		snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+		snd_soc_component_update_bits(component, CS35L33_DAC_CTL,
 			CS35L33_DIGSFT, CS35L33_DIGSFT);
-		snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+		snd_soc_component_update_bits(component, CS35L33_DAC_CTL,
 			CS35L33_DSR_RATE, cs35l33->pdata.ramp_rate);
 	} else {
-		snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+		snd_soc_component_update_bits(component, CS35L33_DAC_CTL,
 			CS35L33_DIGSFT, 0);
 	}
 
 	/* update IMON scaling rate if different from default of 0x8 */
 	if (cs35l33->pdata.imon_adc_scale != 0x8)
-		snd_soc_update_bits(codec, CS35L33_ADC_CTL,
+		snd_soc_component_update_bits(component, CS35L33_ADC_CTL,
 			CS35L33_IMON_SCALE, cs35l33->pdata.imon_adc_scale);
 
-	cs35l33_set_hg_data(codec, &(cs35l33->pdata));
+	cs35l33_set_hg_data(component, &(cs35l33->pdata));
 
 	/*
 	 * unmask important interrupts that causes the chip to enter
@@ -826,26 +826,24 @@ static int cs35l33_probe(struct snd_soc_codec *codec)
 		CS35L33_M_OTE | CS35L33_M_OTW | CS35L33_M_AMP_SHORT |
 		CS35L33_M_CAL_ERR, 0);
 
-	pm_runtime_put_sync(codec->dev);
+	pm_runtime_put_sync(component->dev);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs35l33 = {
-	.probe = cs35l33_probe,
-
-	.set_bias_level = cs35l33_set_bias_level,
-	.set_sysclk = cs35l33_codec_set_sysclk,
-
-	.component_driver = {
-		.controls		= cs35l33_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs35l33_snd_controls),
-		.dapm_widgets		= cs35l33_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs35l33_dapm_widgets),
-		.dapm_routes		= cs35l33_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(cs35l33_audio_map),
-	},
-	.idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_cs35l33 = {
+	.probe			= cs35l33_probe,
+	.set_bias_level		= cs35l33_set_bias_level,
+	.set_sysclk		= cs35l33_component_set_sysclk,
+	.controls		= cs35l33_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs35l33_snd_controls),
+	.dapm_widgets		= cs35l33_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs35l33_dapm_widgets),
+	.dapm_routes		= cs35l33_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs35l33_audio_map),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config cs35l33_regmap = {
@@ -967,7 +965,7 @@ static int cs35l33_get_hg_data(const struct device_node *np,
 static irqreturn_t cs35l33_irq_thread(int irq, void *data)
 {
 	struct cs35l33_private *cs35l33 = data;
-	struct snd_soc_codec *codec = cs35l33->codec;
+	struct snd_soc_component *component = cs35l33->component;
 	unsigned int sticky_val1, sticky_val2, current_val, mask1, mask2;
 
 	regmap_read(cs35l33->regmap, CS35L33_INT_STATUS_2,
@@ -989,9 +987,9 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
 	/* handle the interrupts */
 
 	if (sticky_val1 & CS35L33_AMP_SHORT) {
-		dev_crit(codec->dev, "Amp short error\n");
+		dev_crit(component->dev, "Amp short error\n");
 		if (!(current_val & CS35L33_AMP_SHORT)) {
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Amp short error release\n");
 			regmap_update_bits(cs35l33->regmap,
 				CS35L33_AMP_CTL,
@@ -1007,13 +1005,13 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
 	}
 
 	if (sticky_val1 & CS35L33_CAL_ERR) {
-		dev_err(codec->dev, "Cal error\n");
+		dev_err(component->dev, "Cal error\n");
 
 		/* redo the calibration in next power up */
 		cs35l33->amp_cal = false;
 
 		if (!(current_val & CS35L33_CAL_ERR)) {
-			dev_dbg(codec->dev, "Cal error release\n");
+			dev_dbg(component->dev, "Cal error release\n");
 			regmap_update_bits(cs35l33->regmap,
 				CS35L33_AMP_CTL, CS35L33_CAL_ERR_RLS,
 				0);
@@ -1027,9 +1025,9 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
 	}
 
 	if (sticky_val1 & CS35L33_OTE) {
-		dev_crit(codec->dev, "Over temperature error\n");
+		dev_crit(component->dev, "Over temperature error\n");
 		if (!(current_val & CS35L33_OTE)) {
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Over temperature error release\n");
 			regmap_update_bits(cs35l33->regmap,
 				CS35L33_AMP_CTL, CS35L33_OTE_RLS, 0);
@@ -1042,9 +1040,9 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
 	}
 
 	if (sticky_val1 & CS35L33_OTW) {
-		dev_err(codec->dev, "Over temperature warning\n");
+		dev_err(component->dev, "Over temperature warning\n");
 		if (!(current_val & CS35L33_OTW)) {
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Over temperature warning release\n");
 			regmap_update_bits(cs35l33->regmap,
 				CS35L33_AMP_CTL, CS35L33_OTW_RLS, 0);
@@ -1056,21 +1054,21 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
 		}
 	}
 	if (CS35L33_ALIVE_ERR & sticky_val1)
-		dev_err(codec->dev, "ERROR: ADSPCLK Interrupt\n");
+		dev_err(component->dev, "ERROR: ADSPCLK Interrupt\n");
 
 	if (CS35L33_MCLK_ERR & sticky_val1)
-		dev_err(codec->dev, "ERROR: MCLK Interrupt\n");
+		dev_err(component->dev, "ERROR: MCLK Interrupt\n");
 
 	if (CS35L33_VMON_OVFL & sticky_val2)
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"ERROR: VMON Overflow Interrupt\n");
 
 	if (CS35L33_IMON_OVFL & sticky_val2)
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"ERROR: IMON Overflow Interrupt\n");
 
 	if (CS35L33_VPMON_OVFL & sticky_val2)
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"ERROR: VPMON Overflow Interrupt\n");
 
 	return IRQ_HANDLED;
@@ -1236,10 +1234,10 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client,
 	pm_runtime_set_active(&i2c_client->dev);
 	pm_runtime_enable(&i2c_client->dev);
 
-	ret =  snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_dev_cs35l33, &cs35l33_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_dev_cs35l33, &cs35l33_dai, 1);
 	if (ret < 0) {
-		dev_err(&i2c_client->dev, "%s: Register codec failed\n",
+		dev_err(&i2c_client->dev, "%s: Register component failed\n",
 			__func__);
 		goto err_enable;
 	}
@@ -1257,8 +1255,6 @@ static int cs35l33_i2c_remove(struct i2c_client *client)
 {
 	struct cs35l33_private *cs35l33 = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
-
 	gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
 
 	pm_runtime_disable(&client->dev);
diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c
index 0600d52..5063c05 100644
--- a/sound/soc/codecs/cs35l34.c
+++ b/sound/soc/codecs/cs35l34.c
@@ -43,7 +43,7 @@
 #define CS35L34_START_DELAY 50
 
 struct  cs35l34_private {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct cs35l34_platform_data pdata;
 	struct regmap *regmap;
 	struct regulator_bulk_data core_supplies[2];
@@ -237,8 +237,8 @@ static bool cs35l34_precious_register(struct device *dev, unsigned int reg)
 static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (event) {
@@ -250,7 +250,7 @@ static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,
 		ret = regmap_update_bits(priv->regmap, CS35L34_PWRCTL1,
 						CS35L34_PDN_ALL, 0);
 		if (ret < 0) {
-			dev_err(codec->dev, "Cannot set Power bits %d\n", ret);
+			dev_err(component->dev, "Cannot set Power bits %d\n", ret);
 			return ret;
 		}
 		usleep_range(5000, 5100);
@@ -272,8 +272,8 @@ static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,
 static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 				unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 	unsigned int reg, bit_pos;
 	int slot, slot_num;
 
@@ -284,7 +284,7 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	/* scan rx_mask for aud slot */
 	slot = ffs(rx_mask) - 1;
 	if (slot >= 0)
-		snd_soc_update_bits(codec, CS35L34_TDM_RX_CTL_1_AUDIN,
+		snd_soc_component_update_bits(component, CS35L34_TDM_RX_CTL_1_AUDIN,
 					CS35L34_X_LOC, slot);
 
 	/* scan tx_mask: vmon(2 slots); imon (2 slots); vpmon (1 slot)
@@ -294,10 +294,10 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	slot_num = 0;
 
 	/* disable vpmon/vbstmon: enable later if set in tx_mask */
-	snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_3_VPMON,
+	snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_3_VPMON,
 				CS35L34_X_STATE | CS35L34_X_LOC,
 				CS35L34_X_STATE | CS35L34_X_LOC);
-	snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_4_VBSTMON,
+	snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_4_VBSTMON,
 				CS35L34_X_STATE | CS35L34_X_LOC,
 				CS35L34_X_STATE | CS35L34_X_LOC);
 
@@ -305,22 +305,22 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	while (slot >= 0) {
 		/* configure VMON_TX_LOC */
 		if (slot_num == 0)
-			snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_1_VMON,
+			snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_1_VMON,
 					CS35L34_X_STATE | CS35L34_X_LOC, slot);
 
 		/* configure IMON_TX_LOC */
 		if (slot_num == 4) {
-			snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_2_IMON,
+			snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_2_IMON,
 					CS35L34_X_STATE | CS35L34_X_LOC, slot);
 		}
 		/* configure VPMON_TX_LOC */
 		if (slot_num == 3) {
-			snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_3_VPMON,
+			snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_3_VPMON,
 					CS35L34_X_STATE | CS35L34_X_LOC, slot);
 		}
 		/* configure VBSTMON_TX_LOC */
 		if (slot_num == 7) {
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 				CS35L34_TDM_TX_CTL_4_VBSTMON,
 				CS35L34_X_STATE | CS35L34_X_LOC, slot);
 		}
@@ -328,7 +328,7 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 		/* Enable the relevant tx slot */
 		reg = CS35L34_TDM_TX_SLOT_EN_4 - (slot/8);
 		bit_pos = slot - ((slot / 8) * (8));
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 			1 << bit_pos, 1 << bit_pos);
 
 		tx_mask &= ~(1 << slot);
@@ -342,8 +342,8 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int cs35l34_main_amp_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -382,8 +382,8 @@ static const struct snd_kcontrol_new cs35l34_snd_controls[] = {
 static int cs35l34_mclk_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 	int ret, i;
 	unsigned int reg;
 
@@ -524,8 +524,8 @@ static int cs35l34_get_mclk_coeff(int mclk, int srate)
 
 static int cs35l34_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -546,15 +546,15 @@ static int cs35l34_pcm_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 	int srate = params_rate(params);
 	int ret;
 
 	int coeff = cs35l34_get_mclk_coeff(priv->mclk_int, srate);
 
 	if (coeff < 0) {
-		dev_err(codec->dev, "ERROR: Invalid mclk %d and/or srate %d\n",
+		dev_err(component->dev, "ERROR: Invalid mclk %d and/or srate %d\n",
 			priv->mclk_int, srate);
 		return coeff;
 	}
@@ -562,7 +562,7 @@ static int cs35l34_pcm_hw_params(struct snd_pcm_substream *substream,
 	ret = regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL,
 		CS35L34_ADSP_RATE, cs35l34_mclk_coeffs[coeff].adsp_rate);
 	if (ret != 0)
-		dev_err(codec->dev, "Failed to set clock state %d\n", ret);
+		dev_err(component->dev, "Failed to set clock state %d\n", ret);
 
 	return ret;
 }
@@ -590,13 +590,13 @@ static int cs35l34_pcm_startup(struct snd_pcm_substream *substream,
 static int cs35l34_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
 
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (tristate)
-		snd_soc_update_bits(codec, CS35L34_PWRCTL3,
+		snd_soc_component_update_bits(component, CS35L34_PWRCTL3,
 					CS35L34_PDN_SDOUT, CS35L34_PDN_SDOUT);
 	else
-		snd_soc_update_bits(codec, CS35L34_PWRCTL3,
+		snd_soc_component_update_bits(component, CS35L34_PWRCTL3,
 					CS35L34_PDN_SDOUT, 0);
 	return 0;
 }
@@ -604,8 +604,8 @@ static int cs35l34_set_tristate(struct snd_soc_dai *dai, int tristate)
 static int cs35l34_dai_set_sysclk(struct snd_soc_dai *dai,
 				int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l34_private *cs35l34 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l34_private *cs35l34 = snd_soc_component_get_drvdata(component);
 	unsigned int value;
 
 	switch (freq) {
@@ -634,7 +634,7 @@ static int cs35l34_dai_set_sysclk(struct snd_soc_dai *dai,
 		cs35l34->mclk_int = freq / 2;
 	break;
 	default:
-		dev_err(codec->dev, "ERROR: Invalid Frequency %d\n", freq);
+		dev_err(component->dev, "ERROR: Invalid Frequency %d\n", freq);
 		cs35l34->mclk_int = 0;
 		return -EINVAL;
 	}
@@ -676,7 +676,7 @@ static struct snd_soc_dai_driver cs35l34_dai = {
 static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34,
 	unsigned int inductor)
 {
-	struct snd_soc_codec *codec = cs35l34->codec;
+	struct snd_soc_component *component = cs35l34->component;
 
 	switch (inductor) {
 	case 1000: /* 1 uH */
@@ -708,19 +708,19 @@ static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34,
 		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 3);
 		break;
 	default:
-		dev_err(codec->dev, "%s Invalid Inductor Value %d uH\n",
+		dev_err(component->dev, "%s Invalid Inductor Value %d uH\n",
 			__func__, inductor);
 		return -EINVAL;
 	}
 	return 0;
 }
 
-static int cs35l34_probe(struct snd_soc_codec *codec)
+static int cs35l34_probe(struct snd_soc_component *component)
 {
 	int ret = 0;
-	struct cs35l34_private *cs35l34 = snd_soc_codec_get_drvdata(codec);
+	struct cs35l34_private *cs35l34 = snd_soc_component_get_drvdata(component);
 
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
 	/* Set over temperature warning attenuation to 6 dB */
 	regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,
@@ -773,23 +773,24 @@ static int cs35l34_probe(struct snd_soc_codec *codec)
 		regmap_update_bits(cs35l34->regmap, CS35L34_ADSP_TDM_CTL,
 			1, 1);
 
-	pm_runtime_put_sync(codec->dev);
+	pm_runtime_put_sync(component->dev);
 
 	return ret;
 }
 
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs35l34 = {
-	.probe = cs35l34_probe,
-
-	.component_driver = {
-		.dapm_widgets = cs35l34_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(cs35l34_dapm_widgets),
-		.dapm_routes = cs35l34_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(cs35l34_audio_map),
-		.controls = cs35l34_snd_controls,
-		.num_controls = ARRAY_SIZE(cs35l34_snd_controls),
-	},
+static const struct snd_soc_component_driver soc_component_dev_cs35l34 = {
+	.probe			= cs35l34_probe,
+	.dapm_widgets		= cs35l34_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs35l34_dapm_widgets),
+	.dapm_routes		= cs35l34_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs35l34_audio_map),
+	.controls		= cs35l34_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs35l34_snd_controls),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static struct regmap_config cs35l34_regmap = {
@@ -864,7 +865,7 @@ static int cs35l34_handle_of_data(struct i2c_client *i2c_client,
 static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 {
 	struct cs35l34_private *cs35l34 = data;
-	struct snd_soc_codec *codec = cs35l34->codec;
+	struct snd_soc_component *component = cs35l34->component;
 	unsigned int sticky1, sticky2, sticky3, sticky4;
 	unsigned int mask1, mask2, mask3, mask4, current1;
 
@@ -887,11 +888,11 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 	regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_1, &current1);
 
 	if (sticky1 & CS35L34_CAL_ERR) {
-		dev_err(codec->dev, "Cal error\n");
+		dev_err(component->dev, "Cal error\n");
 
 		/* error is no longer asserted; safe to reset */
 		if (!(current1 & CS35L34_CAL_ERR)) {
-			dev_dbg(codec->dev, "Cal error release\n");
+			dev_dbg(component->dev, "Cal error release\n");
 			regmap_update_bits(cs35l34->regmap,
 					CS35L34_PROT_RELEASE_CTL,
 					CS35L34_CAL_ERR_RLS, 0);
@@ -907,14 +908,14 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 	}
 
 	if (sticky1 & CS35L34_ALIVE_ERR)
-		dev_err(codec->dev, "Alive error\n");
+		dev_err(component->dev, "Alive error\n");
 
 	if (sticky1 & CS35L34_AMP_SHORT) {
-		dev_crit(codec->dev, "Amp short error\n");
+		dev_crit(component->dev, "Amp short error\n");
 
 		/* error is no longer asserted; safe to reset */
 		if (!(current1 & CS35L34_AMP_SHORT)) {
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Amp short error release\n");
 			regmap_update_bits(cs35l34->regmap,
 					CS35L34_PROT_RELEASE_CTL,
@@ -930,11 +931,11 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 	}
 
 	if (sticky1 & CS35L34_OTW) {
-		dev_crit(codec->dev, "Over temperature warning\n");
+		dev_crit(component->dev, "Over temperature warning\n");
 
 		/* error is no longer asserted; safe to reset */
 		if (!(current1 & CS35L34_OTW)) {
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Over temperature warning release\n");
 			regmap_update_bits(cs35l34->regmap,
 					CS35L34_PROT_RELEASE_CTL,
@@ -950,11 +951,11 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 	}
 
 	if (sticky1 & CS35L34_OTE) {
-		dev_crit(codec->dev, "Over temperature error\n");
+		dev_crit(component->dev, "Over temperature error\n");
 
 		/* error is no longer asserted; safe to reset */
 		if (!(current1 & CS35L34_OTE)) {
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Over temperature error release\n");
 			regmap_update_bits(cs35l34->regmap,
 					CS35L34_PROT_RELEASE_CTL,
@@ -970,7 +971,7 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 	}
 
 	if (sticky3 & CS35L34_BST_HIGH) {
-		dev_crit(codec->dev, "VBST too high error; powering off!\n");
+		dev_crit(component->dev, "VBST too high error; powering off!\n");
 		regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL2,
 				CS35L34_PDN_AMP, CS35L34_PDN_AMP);
 		regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL1,
@@ -978,7 +979,7 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 	}
 
 	if (sticky3 & CS35L34_LBST_SHORT) {
-		dev_crit(codec->dev, "LBST short error; powering off!\n");
+		dev_crit(component->dev, "LBST short error; powering off!\n");
 		regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL2,
 				CS35L34_PDN_AMP, CS35L34_PDN_AMP);
 		regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL1,
@@ -1108,11 +1109,11 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client,
 	pm_runtime_set_active(&i2c_client->dev);
 	pm_runtime_enable(&i2c_client->dev);
 
-	ret =  snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_dev_cs35l34, &cs35l34_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_dev_cs35l34, &cs35l34_dai, 1);
 	if (ret < 0) {
 		dev_err(&i2c_client->dev,
-			"%s: Register codec failed\n", __func__);
+			"%s: Register component failed\n", __func__);
 		goto err_regulator;
 	}
 
@@ -1129,8 +1130,6 @@ static int cs35l34_i2c_remove(struct i2c_client *client)
 {
 	struct cs35l34_private *cs35l34 = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
-
 	gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);
 
 	pm_runtime_disable(&client->dev);
diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c
index 129978d..a4a2cb1 100644
--- a/sound/soc/codecs/cs35l35.c
+++ b/sound/soc/codecs/cs35l35.c
@@ -194,8 +194,8 @@ static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)
 static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	switch (event) {
@@ -231,7 +231,7 @@ static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
 				   1 << CS35L35_AMP_DIGSFT_SHIFT);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid event = 0x%x\n", event);
 		ret = -EINVAL;
 	}
 	return ret;
@@ -240,8 +240,8 @@ static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
 static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 	unsigned int reg[4];
 	int i;
 
@@ -301,7 +301,7 @@ static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,
 
 		break;
 	default:
-		dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid event = 0x%x\n", event);
 	}
 	return 0;
 }
@@ -369,8 +369,8 @@ static const struct snd_soc_dapm_route cs35l35_audio_map[] = {
 
 static int cs35l35_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -470,8 +470,8 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 	struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
 	int srate = params_rate(params);
 	int ret = 0;
@@ -482,7 +482,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 	int clk_ctl = cs35l35_get_clk_config(cs35l35->sysclk, srate);
 
 	if (clk_ctl < 0) {
-		dev_err(codec->dev, "Invalid CLK:Rate %d:%d\n",
+		dev_err(component->dev, "Invalid CLK:Rate %d:%d\n",
 			cs35l35->sysclk, srate);
 		return -EINVAL;
 	}
@@ -490,7 +490,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 	ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL2,
 			  CS35L35_CLK_CTL2_MASK, clk_ctl);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to set port config %d\n", ret);
+		dev_err(component->dev, "Failed to set port config %d\n", ret);
 		return ret;
 	}
 
@@ -509,7 +509,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 					CS35L35_CH_WKFET_DEL_MASK,
 					0 << CS35L35_CH_WKFET_DEL_SHIFT);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to set fet config %d\n",
+			dev_err(component->dev, "Failed to set fet config %d\n",
 				ret);
 			return ret;
 		}
@@ -531,7 +531,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 			audin_format = CS35L35_SDIN_DEPTH_24;
 			break;
 		default:
-			dev_err(codec->dev, "Unsupported Width %d\n",
+			dev_err(component->dev, "Unsupported Width %d\n",
 				params_width(params));
 			return -EINVAL;
 		}
@@ -554,7 +554,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 		 * to configure the CLOCK_CTL3 register correctly
 		 */
 		if ((cs35l35->sclk / srate) % 4) {
-			dev_err(codec->dev, "Unsupported sclk/fs ratio %d:%d\n",
+			dev_err(component->dev, "Unsupported sclk/fs ratio %d:%d\n",
 					cs35l35->sclk, srate);
 			return -EINVAL;
 		}
@@ -568,7 +568,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 			case CS35L35_SP_SCLKS_64FS:
 				break;
 			default:
-				dev_err(codec->dev, "ratio not supported\n");
+				dev_err(component->dev, "ratio not supported\n");
 				return -EINVAL;
 			}
 		} else {
@@ -578,7 +578,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 			case CS35L35_SP_SCLKS_64FS:
 				break;
 			default:
-				dev_err(codec->dev, "ratio not supported\n");
+				dev_err(component->dev, "ratio not supported\n");
 				return -EINVAL;
 			}
 		}
@@ -587,7 +587,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 					CS35L35_SP_SCLKS_MASK, sp_sclks <<
 					CS35L35_SP_SCLKS_SHIFT);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to set fsclk %d\n", ret);
+			dev_err(component->dev, "Failed to set fsclk %d\n", ret);
 			return ret;
 		}
 	}
@@ -607,8 +607,8 @@ static const struct snd_pcm_hw_constraint_list cs35l35_constraints = {
 static int cs35l35_pcm_startup(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 
 	if (!substream->runtime)
 		return 0;
@@ -635,8 +635,8 @@ static const struct snd_pcm_hw_constraint_list cs35l35_pdm_constraints = {
 static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 
 	if (!substream->runtime)
 		return 0;
@@ -655,8 +655,8 @@ static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,
 static int cs35l35_dai_set_sysclk(struct snd_soc_dai *dai,
 				int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 
 	/* Need the SCLK Frequency regardless of sysclk source for I2S */
 	cs35l35->sclk = freq;
@@ -712,11 +712,11 @@ static struct snd_soc_dai_driver cs35l35_dai[] = {
 	},
 };
 
-static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
+static int cs35l35_component_set_sysclk(struct snd_soc_component *component,
 				int clk_id, int source, unsigned int freq,
 				int dir)
 {
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 	int clksrc;
 	int ret = 0;
 
@@ -731,7 +731,7 @@ static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
 		clksrc = CS35L35_CLK_SOURCE_PDM;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid CLK Source\n");
+		dev_err(component->dev, "Invalid CLK Source\n");
 		return -EINVAL;
 	}
 
@@ -749,7 +749,7 @@ static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
 		cs35l35->sysclk = freq;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid CLK Frequency Input : %d\n", freq);
+		dev_err(component->dev, "Invalid CLK Frequency Input : %d\n", freq);
 		return -EINVAL;
 	}
 
@@ -757,7 +757,7 @@ static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
 				CS35L35_CLK_SOURCE_MASK,
 				clksrc << CS35L35_CLK_SOURCE_SHIFT);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to set sysclk %d\n", ret);
+		dev_err(component->dev, "Failed to set sysclk %d\n", ret);
 		return ret;
 	}
 
@@ -834,9 +834,9 @@ static int cs35l35_boost_inductor(struct cs35l35_private *cs35l35,
 	return 0;
 }
 
-static int cs35l35_codec_probe(struct snd_soc_codec *codec)
+static int cs35l35_component_probe(struct snd_soc_component *component)
 {
-	struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+	struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 	struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
 	struct monitor_cfg *monitor_config = &cs35l35->pdata.mon_cfg;
 	int ret;
@@ -880,7 +880,7 @@ static int cs35l35_codec_probe(struct snd_soc_codec *codec)
 			regmap_update_bits(cs35l35->regmap, CS35L35_CLASS_H_CTL,
 					CS35L35_CH_STEREO_MASK,
 					1 << CS35L35_CH_STEREO_SHIFT);
-		ret = snd_soc_add_codec_controls(codec, cs35l35_adv_controls,
+		ret = snd_soc_add_component_controls(component, cs35l35_adv_controls,
 					ARRAY_SIZE(cs35l35_adv_controls));
 		if (ret)
 			return ret;
@@ -1079,20 +1079,19 @@ static int cs35l35_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs35l35 = {
-	.probe = cs35l35_codec_probe,
-	.set_sysclk = cs35l35_codec_set_sysclk,
-	.component_driver = {
-		.dapm_widgets = cs35l35_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(cs35l35_dapm_widgets),
-
-		.dapm_routes = cs35l35_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(cs35l35_audio_map),
-
-		.controls = cs35l35_aud_controls,
-		.num_controls = ARRAY_SIZE(cs35l35_aud_controls),
-	},
-
+static const struct snd_soc_component_driver soc_component_dev_cs35l35 = {
+	.probe			= cs35l35_component_probe,
+	.set_sysclk		= cs35l35_component_set_sysclk,
+	.dapm_widgets		= cs35l35_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs35l35_dapm_widgets),
+	.dapm_routes		= cs35l35_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs35l35_audio_map),
+	.controls		= cs35l35_aud_controls,
+	.num_controls		= ARRAY_SIZE(cs35l35_aud_controls),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static struct regmap_config cs35l35_regmap = {
@@ -1617,10 +1616,10 @@ static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
 	regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
 		CS35L35_AMP_MUTE_MASK, 1 << CS35L35_AMP_MUTE_SHIFT);
 
-	ret =  snd_soc_register_codec(dev, &soc_codec_dev_cs35l35, cs35l35_dai,
-				      ARRAY_SIZE(cs35l35_dai));
+	ret = devm_snd_soc_register_component(dev, &soc_component_dev_cs35l35,
+					cs35l35_dai, ARRAY_SIZE(cs35l35_dai));
 	if (ret < 0) {
-		dev_err(dev, "Failed to register codec: %d\n", ret);
+		dev_err(dev, "Failed to register component: %d\n", ret);
 		goto err;
 	}
 
@@ -1634,12 +1633,6 @@ static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
 	return ret;
 }
 
-static int cs35l35_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct of_device_id cs35l35_of_match[] = {
 	{.compatible = "cirrus,cs35l35"},
 	{},
@@ -1660,7 +1653,6 @@ static struct i2c_driver cs35l35_i2c_driver = {
 	},
 	.id_table = cs35l35_id,
 	.probe = cs35l35_i2c_probe,
-	.remove = cs35l35_i2c_remove,
 };
 
 module_i2c_driver(cs35l35_i2c_driver);
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c
index fd966bb..275677d 100644
--- a/sound/soc/codecs/cs4265.c
+++ b/sound/soc/codecs/cs4265.c
@@ -322,12 +322,12 @@ static int cs4265_get_clk_index(int mclk, int rate)
 static int cs4265_set_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 			unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs4265_private *cs4265 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	if (clk_id != 0) {
-		dev_err(codec->dev, "Invalid clk_id %d\n", clk_id);
+		dev_err(component->dev, "Invalid clk_id %d\n", clk_id);
 		return -EINVAL;
 	}
 	for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
@@ -337,24 +337,24 @@ static int cs4265_set_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 		}
 	}
 	cs4265->sysclk = 0;
-	dev_err(codec->dev, "Invalid freq parameter %d\n", freq);
+	dev_err(component->dev, "Invalid freq parameter %d\n", freq);
 	return -EINVAL;
 }
 
 static int cs4265_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs4265_private *cs4265 = snd_soc_component_get_drvdata(component);
 	u8 iface = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
-		snd_soc_update_bits(codec, CS4265_ADC_CTL,
+		snd_soc_component_update_bits(component, CS4265_ADC_CTL,
 				CS4265_ADC_MASTER,
 				CS4265_ADC_MASTER);
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
-		snd_soc_update_bits(codec, CS4265_ADC_CTL,
+		snd_soc_component_update_bits(component, CS4265_ADC_CTL,
 				CS4265_ADC_MASTER,
 				0);
 		break;
@@ -383,20 +383,20 @@ static int cs4265_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int cs4265_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (mute) {
-		snd_soc_update_bits(codec, CS4265_DAC_CTL,
+		snd_soc_component_update_bits(component, CS4265_DAC_CTL,
 			CS4265_DAC_CTL_MUTE,
 			CS4265_DAC_CTL_MUTE);
-		snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+		snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
 			CS4265_SPDIF_CTL2_MUTE,
 			CS4265_SPDIF_CTL2_MUTE);
 	} else {
-		snd_soc_update_bits(codec, CS4265_DAC_CTL,
+		snd_soc_component_update_bits(component, CS4265_DAC_CTL,
 			CS4265_DAC_CTL_MUTE,
 			0);
-		snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+		snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
 			CS4265_SPDIF_CTL2_MUTE,
 			0);
 	}
@@ -407,8 +407,8 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
 				     struct snd_pcm_hw_params *params,
 				     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs4265_private *cs4265 = snd_soc_component_get_drvdata(component);
 	int index;
 
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
@@ -418,45 +418,45 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
 
 	index = cs4265_get_clk_index(cs4265->sysclk, params_rate(params));
 	if (index >= 0) {
-		snd_soc_update_bits(codec, CS4265_ADC_CTL,
+		snd_soc_component_update_bits(component, CS4265_ADC_CTL,
 			CS4265_ADC_FM, clk_map_table[index].fm_mode << 6);
-		snd_soc_update_bits(codec, CS4265_MCLK_FREQ,
+		snd_soc_component_update_bits(component, CS4265_MCLK_FREQ,
 			CS4265_MCLK_FREQ_MASK,
 			clk_map_table[index].mclkdiv << 4);
 
 	} else {
-		dev_err(codec->dev, "can't get correct mclk\n");
+		dev_err(component->dev, "can't get correct mclk\n");
 		return -EINVAL;
 	}
 
 	switch (cs4265->format & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		snd_soc_update_bits(codec, CS4265_DAC_CTL,
+		snd_soc_component_update_bits(component, CS4265_DAC_CTL,
 			CS4265_DAC_CTL_DIF, (1 << 4));
-		snd_soc_update_bits(codec, CS4265_ADC_CTL,
+		snd_soc_component_update_bits(component, CS4265_ADC_CTL,
 			CS4265_ADC_DIF, (1 << 4));
-		snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+		snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
 			CS4265_SPDIF_CTL2_DIF, (1 << 6));
 		break;
 	case SND_SOC_DAIFMT_RIGHT_J:
 		if (params_width(params) == 16) {
-			snd_soc_update_bits(codec, CS4265_DAC_CTL,
+			snd_soc_component_update_bits(component, CS4265_DAC_CTL,
 				CS4265_DAC_CTL_DIF, (2 << 4));
-			snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+			snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
 				CS4265_SPDIF_CTL2_DIF, (2 << 6));
 		} else {
-			snd_soc_update_bits(codec, CS4265_DAC_CTL,
+			snd_soc_component_update_bits(component, CS4265_DAC_CTL,
 				CS4265_DAC_CTL_DIF, (3 << 4));
-			snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+			snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
 				CS4265_SPDIF_CTL2_DIF, (3 << 6));
 		}
 		break;
 	case SND_SOC_DAIFMT_LEFT_J:
-		snd_soc_update_bits(codec, CS4265_DAC_CTL,
+		snd_soc_component_update_bits(component, CS4265_DAC_CTL,
 			CS4265_DAC_CTL_DIF, 0);
-		snd_soc_update_bits(codec, CS4265_ADC_CTL,
+		snd_soc_component_update_bits(component, CS4265_ADC_CTL,
 			CS4265_ADC_DIF, 0);
-		snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+		snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
 			CS4265_SPDIF_CTL2_DIF, 0);
 
 		break;
@@ -466,23 +466,23 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static int cs4265_set_bias_level(struct snd_soc_codec *codec,
+static int cs4265_set_bias_level(struct snd_soc_component *component,
 					enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, CS4265_PWRCTL,
+		snd_soc_component_update_bits(component, CS4265_PWRCTL,
 			CS4265_PWRCTL_PDN, 0);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_update_bits(codec, CS4265_PWRCTL,
+		snd_soc_component_update_bits(component, CS4265_PWRCTL,
 			CS4265_PWRCTL_PDN,
 			CS4265_PWRCTL_PDN);
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, CS4265_PWRCTL,
+		snd_soc_component_update_bits(component, CS4265_PWRCTL,
 			CS4265_PWRCTL_PDN,
 			CS4265_PWRCTL_PDN);
 		break;
@@ -544,17 +544,18 @@ static struct snd_soc_dai_driver cs4265_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_cs4265 = {
-	.set_bias_level = cs4265_set_bias_level,
-
-	.component_driver = {
-		.controls		= cs4265_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs4265_snd_controls),
-		.dapm_widgets		= cs4265_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs4265_dapm_widgets),
-		.dapm_routes		= cs4265_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(cs4265_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_cs4265 = {
+	.set_bias_level		= cs4265_set_bias_level,
+	.controls		= cs4265_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs4265_snd_controls),
+	.dapm_widgets		= cs4265_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs4265_dapm_widgets),
+	.dapm_routes		= cs4265_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs4265_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config cs4265_regmap = {
@@ -616,18 +617,12 @@ static int cs4265_i2c_probe(struct i2c_client *i2c_client,
 
 	regmap_write(cs4265->regmap, CS4265_PWRCTL, 0x0F);
 
-	ret =  snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_cs4265, cs4265_dai,
+	ret = devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_cs4265, cs4265_dai,
 			ARRAY_SIZE(cs4265_dai));
 	return ret;
 }
 
-static int cs4265_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct of_device_id cs4265_of_match[] = {
 	{ .compatible = "cirrus,cs4265", },
 	{ }
@@ -647,7 +642,6 @@ static struct i2c_driver cs4265_i2c_driver = {
 	},
 	.id_table = cs4265_id,
 	.probe =    cs4265_i2c_probe,
-	.remove =   cs4265_i2c_remove,
 };
 
 module_i2c_driver(cs4265_i2c_driver);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 84f8674..2a7a416 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -254,8 +254,8 @@ static bool cs4270_reg_is_volatile(struct device *dev, unsigned int reg)
 static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 
 	cs4270->mclk = freq;
 	return 0;
@@ -277,8 +277,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 
 	/* set DAI format */
 	switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -287,7 +287,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
 		break;
 	default:
-		dev_err(codec->dev, "invalid dai format\n");
+		dev_err(component->dev, "invalid dai format\n");
 		return -EINVAL;
 	}
 
@@ -301,7 +301,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		break;
 	default:
 		/* all other modes are unsupported by the hardware */
-		dev_err(codec->dev, "Unknown master/slave configuration\n");
+		dev_err(component->dev, "Unknown master/slave configuration\n");
 		return -EINVAL;
 	}
 
@@ -326,8 +326,8 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 	int ret;
 	unsigned int i;
 	unsigned int rate;
@@ -346,13 +346,13 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
 
 	if (i == NUM_MCLK_RATIOS) {
 		/* We did not find a matching ratio */
-		dev_err(codec->dev, "could not find matching ratio\n");
+		dev_err(component->dev, "could not find matching ratio\n");
 		return -EINVAL;
 	}
 
 	/* Set the sample rate */
 
-	reg = snd_soc_read(codec, CS4270_MODE);
+	reg = snd_soc_component_read32(component, CS4270_MODE);
 	reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
 	reg |= cs4270_mode_ratios[i].mclk;
 
@@ -361,15 +361,15 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
 	else
 		reg |= cs4270_mode_ratios[i].speed_mode;
 
-	ret = snd_soc_write(codec, CS4270_MODE, reg);
+	ret = snd_soc_component_write(component, CS4270_MODE, reg);
 	if (ret < 0) {
-		dev_err(codec->dev, "i2c write failed\n");
+		dev_err(component->dev, "i2c write failed\n");
 		return ret;
 	}
 
 	/* Set the DAI format */
 
-	reg = snd_soc_read(codec, CS4270_FORMAT);
+	reg = snd_soc_component_read32(component, CS4270_FORMAT);
 	reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
 
 	switch (cs4270->mode) {
@@ -380,13 +380,13 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
 		reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
 		break;
 	default:
-		dev_err(codec->dev, "unknown dai format\n");
+		dev_err(component->dev, "unknown dai format\n");
 		return -EINVAL;
 	}
 
-	ret = snd_soc_write(codec, CS4270_FORMAT, reg);
+	ret = snd_soc_component_write(component, CS4270_FORMAT, reg);
 	if (ret < 0) {
-		dev_err(codec->dev, "i2c write failed\n");
+		dev_err(component->dev, "i2c write failed\n");
 		return ret;
 	}
 
@@ -405,11 +405,11 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
  */
 static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 	int reg6;
 
-	reg6 = snd_soc_read(codec, CS4270_MUTE);
+	reg6 = snd_soc_component_read32(component, CS4270_MUTE);
 
 	if (mute)
 		reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
@@ -418,7 +418,7 @@ static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
 		reg6 |= cs4270->manual_mute;
 	}
 
-	return snd_soc_write(codec, CS4270_MUTE, reg6);
+	return snd_soc_component_write(component, CS4270_MUTE, reg6);
 }
 
 /**
@@ -438,8 +438,8 @@ static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
 static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 	int left = !ucontrol->value.integer.value[0];
 	int right = !ucontrol->value.integer.value[1];
 
@@ -501,9 +501,9 @@ static struct snd_soc_dai_driver cs4270_dai = {
  * This function is called when ASoC has all the pieces it needs to
  * instantiate a sound driver.
  */
-static int cs4270_probe(struct snd_soc_codec *codec)
+static int cs4270_probe(struct snd_soc_component *component)
 {
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	/* Disable auto-mute.  This feature appears to be buggy.  In some
@@ -511,9 +511,9 @@ static int cs4270_probe(struct snd_soc_codec *codec)
 	 * this feature disabled by default.  An application (e.g. alsactl) can
 	 * re-enabled it by using the controls.
 	 */
-	ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
+	ret = snd_soc_component_update_bits(component, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "i2c write failed\n");
+		dev_err(component->dev, "i2c write failed\n");
 		return ret;
 	}
 
@@ -522,10 +522,10 @@ static int cs4270_probe(struct snd_soc_codec *codec)
 	 * playback has started.  An application (e.g. alsactl) can
 	 * re-enabled it by using the controls.
 	 */
-	ret = snd_soc_update_bits(codec, CS4270_TRANS,
+	ret = snd_soc_component_update_bits(component, CS4270_TRANS,
 		CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "i2c write failed\n");
+		dev_err(component->dev, "i2c write failed\n");
 		return ret;
 	}
 
@@ -541,13 +541,11 @@ static int cs4270_probe(struct snd_soc_codec *codec)
  *
  * This function is the counterpart to cs4270_probe().
  */
-static int cs4270_remove(struct snd_soc_codec *codec)
+static void cs4270_remove(struct snd_soc_component *component)
 {
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 
 	regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
-
-	return 0;
 };
 
 #ifdef CONFIG_PM
@@ -561,16 +559,16 @@ static int cs4270_remove(struct snd_soc_codec *codec)
  * and all registers are written back to the hardware when resuming.
  */
 
-static int cs4270_soc_suspend(struct snd_soc_codec *codec)
+static int cs4270_soc_suspend(struct snd_soc_component *component)
 {
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 	int reg, ret;
 
-	reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
+	reg = snd_soc_component_read32(component, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
 	if (reg < 0)
 		return reg;
 
-	ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
+	ret = snd_soc_component_write(component, CS4270_PWRCTL, reg);
 	if (ret < 0)
 		return ret;
 
@@ -580,9 +578,9 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int cs4270_soc_resume(struct snd_soc_codec *codec)
+static int cs4270_soc_resume(struct snd_soc_component *component)
 {
-	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 	int reg, ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
@@ -598,10 +596,10 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
 	regcache_sync(cs4270->regmap);
 
 	/* ... then disable the power-down bits */
-	reg = snd_soc_read(codec, CS4270_PWRCTL);
+	reg = snd_soc_component_read32(component, CS4270_PWRCTL);
 	reg &= ~CS4270_PWRCTL_PDN_ALL;
 
-	return snd_soc_write(codec, CS4270_PWRCTL, reg);
+	return snd_soc_component_write(component, CS4270_PWRCTL, reg);
 }
 #else
 #define cs4270_soc_suspend	NULL
@@ -611,20 +609,21 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
 /*
  * ASoC codec driver structure
  */
-static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
-	.probe =		cs4270_probe,
-	.remove =		cs4270_remove,
-	.suspend =		cs4270_soc_suspend,
-	.resume =		cs4270_soc_resume,
-
-	.component_driver = {
-		.controls =		cs4270_snd_controls,
-		.num_controls =		ARRAY_SIZE(cs4270_snd_controls),
-		.dapm_widgets =		cs4270_dapm_widgets,
-		.num_dapm_widgets =	ARRAY_SIZE(cs4270_dapm_widgets),
-		.dapm_routes =		cs4270_dapm_routes,
-		.num_dapm_routes =	ARRAY_SIZE(cs4270_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_device_cs4270 = {
+	.probe			= cs4270_probe,
+	.remove			= cs4270_remove,
+	.suspend		= cs4270_soc_suspend,
+	.resume			= cs4270_soc_resume,
+	.controls		= cs4270_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs4270_snd_controls),
+	.dapm_widgets		= cs4270_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs4270_dapm_widgets),
+	.dapm_routes		= cs4270_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(cs4270_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /*
@@ -718,23 +717,11 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 
 	i2c_set_clientdata(i2c_client, cs4270);
 
-	ret = snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_device_cs4270, &cs4270_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_device_cs4270, &cs4270_dai, 1);
 	return ret;
 }
 
-/**
- * cs4270_i2c_remove - remove an I2C device
- * @i2c_client: the I2C client object
- *
- * This function is the counterpart to cs4270_i2c_probe().
- */
-static int cs4270_i2c_remove(struct i2c_client *i2c_client)
-{
-	snd_soc_unregister_codec(&i2c_client->dev);
-	return 0;
-}
-
 /*
  * cs4270_id - I2C device IDs supported by this driver
  */
@@ -757,7 +744,6 @@ static struct i2c_driver cs4270_i2c_driver = {
 	},
 	.id_table = cs4270_id,
 	.probe = cs4270_i2c_probe,
-	.remove = cs4270_i2c_remove,
 };
 
 module_i2c_driver(cs4270_i2c_driver);
diff --git a/sound/soc/codecs/cs4271-i2c.c b/sound/soc/codecs/cs4271-i2c.c
index dcb3223..ff73730 100644
--- a/sound/soc/codecs/cs4271-i2c.c
+++ b/sound/soc/codecs/cs4271-i2c.c
@@ -33,12 +33,6 @@ static int cs4271_i2c_probe(struct i2c_client *client,
 			    devm_regmap_init_i2c(client, &config));
 }
 
-static int cs4271_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id cs4271_i2c_id[] = {
 	{ "cs4271", 0 },
 	{ }
@@ -51,7 +45,6 @@ static struct i2c_driver cs4271_i2c_driver = {
 		.of_match_table = of_match_ptr(cs4271_dt_ids),
 	},
 	.probe = cs4271_i2c_probe,
-	.remove = cs4271_i2c_remove,
 	.id_table = cs4271_i2c_id,
 };
 module_i2c_driver(cs4271_i2c_driver);
diff --git a/sound/soc/codecs/cs4271-spi.c b/sound/soc/codecs/cs4271-spi.c
index 1ff5f52..217f6dc 100644
--- a/sound/soc/codecs/cs4271-spi.c
+++ b/sound/soc/codecs/cs4271-spi.c
@@ -33,19 +33,12 @@ static int cs4271_spi_probe(struct spi_device *spi)
 	return cs4271_probe(&spi->dev, devm_regmap_init_spi(spi, &config));
 }
 
-static int cs4271_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver cs4271_spi_driver = {
 	.driver = {
 		.name	= "cs4271",
 		.of_match_table = of_match_ptr(cs4271_dt_ids),
 	},
 	.probe		= cs4271_spi_probe,
-	.remove		= cs4271_spi_remove,
 };
 module_spi_driver(cs4271_spi_driver);
 
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 49a8062..849fdb2 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -206,8 +206,8 @@ static const struct snd_soc_dapm_route cs4271_dapm_routes[] = {
 static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
 	cs4271->mclk = freq;
 	return 0;
@@ -216,8 +216,8 @@ static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0;
 	int ret;
 
@@ -230,7 +230,7 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		val |= CS4271_MODE1_MASTER;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI format\n");
+		dev_err(component->dev, "Invalid DAI format\n");
 		return -EINVAL;
 	}
 
@@ -250,7 +250,7 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			return ret;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI format\n");
+		dev_err(component->dev, "Invalid DAI format\n");
 		return -EINVAL;
 	}
 
@@ -263,9 +263,9 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int cs4271_deemph[] = {0, 44100, 48000, 32000};
 
-static int cs4271_set_deemph(struct snd_soc_codec *codec)
+static int cs4271_set_deemph(struct snd_soc_component *component)
 {
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 	int i, ret;
 	int val = CS4271_DACCTL_DEM_DIS;
 
@@ -289,8 +289,8 @@ static int cs4271_set_deemph(struct snd_soc_codec *codec)
 static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = cs4271->deemph;
 	return 0;
@@ -299,11 +299,11 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
 static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
 	cs4271->deemph = ucontrol->value.integer.value[0];
-	return cs4271_set_deemph(codec);
+	return cs4271_set_deemph(component);
 }
 
 struct cs4271_clk_cfg {
@@ -349,8 +349,8 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 	int i, ret;
 	unsigned int ratio, val;
 
@@ -399,7 +399,7 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
 			break;
 
 	if (i == CS4171_NR_RATIOS) {
-		dev_err(codec->dev, "Invalid sample rate\n");
+		dev_err(component->dev, "Invalid sample rate\n");
 		return -EINVAL;
 	}
 
@@ -410,13 +410,13 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
 	if (ret < 0)
 		return ret;
 
-	return cs4271_set_deemph(codec);
+	return cs4271_set_deemph(component);
 }
 
 static int cs4271_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 	int ret;
 	int val_a = 0;
 	int val_b = 0;
@@ -493,9 +493,9 @@ static struct snd_soc_dai_driver cs4271_dai = {
 	.symmetric_rates = 1,
 };
 
-static int cs4271_reset(struct snd_soc_codec *codec)
+static int cs4271_reset(struct snd_soc_component *component)
 {
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
 	if (gpio_is_valid(cs4271->gpio_nreset)) {
 		gpio_direction_output(cs4271->gpio_nreset, 0);
@@ -508,10 +508,10 @@ static int cs4271_reset(struct snd_soc_codec *codec)
 }
 
 #ifdef CONFIG_PM
-static int cs4271_soc_suspend(struct snd_soc_codec *codec)
+static int cs4271_soc_suspend(struct snd_soc_component *component)
 {
 	int ret;
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
 	/* Set power-down bit */
 	ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
@@ -525,20 +525,20 @@ static int cs4271_soc_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int cs4271_soc_resume(struct snd_soc_codec *codec)
+static int cs4271_soc_resume(struct snd_soc_component *component)
 {
 	int ret;
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(cs4271->supplies),
 				    cs4271->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+		dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
 		return ret;
 	}
 
 	/* Do a proper reset after power up */
-	cs4271_reset(codec);
+	cs4271_reset(component);
 
 	/* Restore codec state */
 	ret = regcache_sync(cs4271->regmap);
@@ -567,20 +567,20 @@ MODULE_DEVICE_TABLE(of, cs4271_dt_ids);
 EXPORT_SYMBOL_GPL(cs4271_dt_ids);
 #endif
 
-static int cs4271_codec_probe(struct snd_soc_codec *codec)
+static int cs4271_component_probe(struct snd_soc_component *component)
 {
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
-	struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
+	struct cs4271_platform_data *cs4271plat = component->dev->platform_data;
 	int ret;
 	bool amutec_eq_bmutec = false;
 
 #ifdef CONFIG_OF
-	if (of_match_device(cs4271_dt_ids, codec->dev)) {
-		if (of_get_property(codec->dev->of_node,
+	if (of_match_device(cs4271_dt_ids, component->dev)) {
+		if (of_get_property(component->dev->of_node,
 				     "cirrus,amutec-eq-bmutec", NULL))
 			amutec_eq_bmutec = true;
 
-		if (of_get_property(codec->dev->of_node,
+		if (of_get_property(component->dev->of_node,
 				     "cirrus,enable-soft-reset", NULL))
 			cs4271->enable_soft_reset = true;
 	}
@@ -589,7 +589,7 @@ static int cs4271_codec_probe(struct snd_soc_codec *codec)
 	ret = regulator_bulk_enable(ARRAY_SIZE(cs4271->supplies),
 				    cs4271->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+		dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
 		return ret;
 	}
 
@@ -599,7 +599,7 @@ static int cs4271_codec_probe(struct snd_soc_codec *codec)
 	}
 
 	/* Reset codec */
-	cs4271_reset(codec);
+	cs4271_reset(component);
 
 	ret = regcache_sync(cs4271->regmap);
 	if (ret < 0)
@@ -625,9 +625,9 @@ static int cs4271_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int cs4271_codec_remove(struct snd_soc_codec *codec)
+static void cs4271_component_remove(struct snd_soc_component *component)
 {
-	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+	struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
 	if (gpio_is_valid(cs4271->gpio_nreset))
 		/* Set codec to the reset state */
@@ -635,24 +635,23 @@ static int cs4271_codec_remove(struct snd_soc_codec *codec)
 
 	regcache_mark_dirty(cs4271->regmap);
 	regulator_bulk_disable(ARRAY_SIZE(cs4271->supplies), cs4271->supplies);
-
-	return 0;
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
-	.probe			= cs4271_codec_probe,
-	.remove			= cs4271_codec_remove,
+static const struct snd_soc_component_driver soc_component_dev_cs4271 = {
+	.probe			= cs4271_component_probe,
+	.remove			= cs4271_component_remove,
 	.suspend		= cs4271_soc_suspend,
 	.resume			= cs4271_soc_resume,
-
-	.component_driver = {
-		.controls		= cs4271_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs4271_snd_controls),
-		.dapm_widgets		= cs4271_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs4271_dapm_widgets),
-		.dapm_routes		= cs4271_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(cs4271_dapm_routes),
-	},
+	.controls		= cs4271_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs4271_snd_controls),
+	.dapm_widgets		= cs4271_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs4271_dapm_widgets),
+	.dapm_routes		= cs4271_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(cs4271_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int cs4271_common_probe(struct device *dev,
@@ -721,8 +720,8 @@ int cs4271_probe(struct device *dev, struct regmap *regmap)
 	dev_set_drvdata(dev, cs4271);
 	cs4271->regmap = regmap;
 
-	return snd_soc_register_codec(dev, &soc_codec_dev_cs4271, &cs4271_dai,
-				      1);
+	return devm_snd_soc_register_component(dev, &soc_component_dev_cs4271,
+					       &cs4271_dai, 1);
 }
 EXPORT_SYMBOL_GPL(cs4271_probe);
 
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index a2324a0..651329b 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -468,33 +468,33 @@ static const struct snd_kcontrol_new cs42l42_snd_controls[] = {
 static int cs42l42_hpdrv_evt(struct snd_soc_dapm_widget *w,
 				struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	if (event & SND_SOC_DAPM_POST_PMU) {
 		/* Enable the channels */
-		snd_soc_update_bits(codec, CS42L42_ASP_RX_DAI0_EN,
+		snd_soc_component_update_bits(component, CS42L42_ASP_RX_DAI0_EN,
 				CS42L42_ASP_RX0_CH_EN_MASK,
 				(CS42L42_ASP_RX0_CH1_EN |
 				CS42L42_ASP_RX0_CH2_EN) <<
 				CS42L42_ASP_RX0_CH_EN_SHIFT);
 
 		/* Power up */
-		snd_soc_update_bits(codec, CS42L42_PWR_CTL1,
+		snd_soc_component_update_bits(component, CS42L42_PWR_CTL1,
 			CS42L42_ASP_DAI_PDN_MASK | CS42L42_MIXER_PDN_MASK |
 				CS42L42_HP_PDN_MASK, 0);
 	} else if (event & SND_SOC_DAPM_PRE_PMD) {
 		/* Disable the channels */
-		snd_soc_update_bits(codec, CS42L42_ASP_RX_DAI0_EN,
+		snd_soc_component_update_bits(component, CS42L42_ASP_RX_DAI0_EN,
 				CS42L42_ASP_RX0_CH_EN_MASK, 0);
 
 		/* Power down */
-		snd_soc_update_bits(codec, CS42L42_PWR_CTL1,
+		snd_soc_component_update_bits(component, CS42L42_PWR_CTL1,
 			CS42L42_ASP_DAI_PDN_MASK | CS42L42_MIXER_PDN_MASK |
 				CS42L42_HP_PDN_MASK,
 			CS42L42_ASP_DAI_PDN_MASK | CS42L42_MIXER_PDN_MASK |
 				CS42L42_HP_PDN_MASK);
 	} else {
-		dev_err(codec->dev, "Invalid event 0x%x\n", event);
+		dev_err(component->dev, "Invalid event 0x%x\n", event);
 	}
 	return 0;
 }
@@ -515,10 +515,10 @@ static const struct snd_soc_dapm_route cs42l42_audio_map[] = {
 	{"HP", NULL, "HPDRV"}
 };
 
-static int cs42l42_set_bias_level(struct snd_soc_codec *codec,
+static int cs42l42_set_bias_level(struct snd_soc_component *component,
 					enum snd_soc_bias_level level)
 {
-	struct cs42l42_private *cs42l42 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -527,14 +527,14 @@ static int cs42l42_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_cache_only(cs42l42->regmap, false);
 			regcache_sync(cs42l42->regmap);
 			ret = regulator_bulk_enable(
 						ARRAY_SIZE(cs42l42->supplies),
 						cs42l42->supplies);
 			if (ret != 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable regulators: %d\n",
 					ret);
 				return ret;
@@ -552,30 +552,28 @@ static int cs42l42_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int cs42l42_codec_probe(struct snd_soc_codec *codec)
+static int cs42l42_component_probe(struct snd_soc_component *component)
 {
 	struct cs42l42_private *cs42l42 =
-		(struct cs42l42_private *)snd_soc_codec_get_drvdata(codec);
+		(struct cs42l42_private *)snd_soc_component_get_drvdata(component);
 
-	cs42l42->codec = codec;
+	cs42l42->component = component;
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs42l42 = {
-	.probe = cs42l42_codec_probe,
-	.set_bias_level = cs42l42_set_bias_level,
-	.ignore_pmdown_time = true,
-
-	.component_driver = {
-		.dapm_widgets = cs42l42_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets),
-		.dapm_routes = cs42l42_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(cs42l42_audio_map),
-
-		.controls = cs42l42_snd_controls,
-		.num_controls = ARRAY_SIZE(cs42l42_snd_controls),
-	},
+static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
+	.probe			= cs42l42_component_probe,
+	.set_bias_level		= cs42l42_set_bias_level,
+	.dapm_widgets		= cs42l42_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs42l42_dapm_widgets),
+	.dapm_routes		= cs42l42_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs42l42_audio_map),
+	.controls		= cs42l42_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs42l42_snd_controls),
+	.idle_bias_on		= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 struct cs42l42_pll_params {
@@ -613,16 +611,16 @@ static const struct cs42l42_pll_params pll_ratio_table[] = {
 	{ 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0 }
 };
 
-static int cs42l42_pll_config(struct snd_soc_codec *codec)
+static int cs42l42_pll_config(struct snd_soc_component *component)
 {
-	struct cs42l42_private *cs42l42 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
 	int i;
 	u32 fsync;
 
 	for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
 		if (pll_ratio_table[i].sclk == cs42l42->sclk) {
 			/* Configure the internal sample rate */
-			snd_soc_update_bits(codec, CS42L42_MCLK_CTL,
+			snd_soc_component_update_bits(component, CS42L42_MCLK_CTL,
 					CS42L42_INTERNAL_FS_MASK,
 					((pll_ratio_table[i].mclk_int !=
 					12000000) &&
@@ -632,7 +630,7 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
 			/* Set the MCLK src (PLL or SCLK) and the divide
 			 * ratio
 			 */
-			snd_soc_update_bits(codec, CS42L42_MCLK_SRC_SEL,
+			snd_soc_component_update_bits(component, CS42L42_MCLK_SRC_SEL,
 					CS42L42_MCLK_SRC_SEL_MASK |
 					CS42L42_MCLKDIV_MASK,
 					(pll_ratio_table[i].mclk_src_sel
@@ -643,62 +641,62 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
 			fsync = cs42l42->sclk / cs42l42->srate;
 			if (((fsync * cs42l42->srate) != cs42l42->sclk)
 				|| ((fsync % 2) != 0)) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Unsupported sclk %d/sample rate %d\n",
 					cs42l42->sclk,
 					cs42l42->srate);
 				return -EINVAL;
 			}
 			/* Set the LRCLK period */
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					CS42L42_FSYNC_P_LOWER,
 					CS42L42_FSYNC_PERIOD_MASK,
 					CS42L42_FRAC0_VAL(fsync - 1) <<
 					CS42L42_FSYNC_PERIOD_SHIFT);
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					CS42L42_FSYNC_P_UPPER,
 					CS42L42_FSYNC_PERIOD_MASK,
 					CS42L42_FRAC1_VAL(fsync - 1) <<
 					CS42L42_FSYNC_PERIOD_SHIFT);
 			/* Set the LRCLK to 50% duty cycle */
 			fsync = fsync / 2;
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					CS42L42_FSYNC_PW_LOWER,
 					CS42L42_FSYNC_PULSE_WIDTH_MASK,
 					CS42L42_FRAC0_VAL(fsync - 1) <<
 					CS42L42_FSYNC_PULSE_WIDTH_SHIFT);
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					CS42L42_FSYNC_PW_UPPER,
 					CS42L42_FSYNC_PULSE_WIDTH_MASK,
 					CS42L42_FRAC1_VAL(fsync - 1) <<
 					CS42L42_FSYNC_PULSE_WIDTH_SHIFT);
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					CS42L42_ASP_FRM_CFG,
 					CS42L42_ASP_5050_MASK,
 					CS42L42_ASP_5050_MASK);
 			/* Set the frame delay to 1.0 SCLK clocks */
-			snd_soc_update_bits(codec, CS42L42_ASP_FRM_CFG,
+			snd_soc_component_update_bits(component, CS42L42_ASP_FRM_CFG,
 					CS42L42_ASP_FSD_MASK,
 					CS42L42_ASP_FSD_1_0 <<
 					CS42L42_ASP_FSD_SHIFT);
 			/* Set the sample rates (96k or lower) */
-			snd_soc_update_bits(codec, CS42L42_FS_RATE_EN,
+			snd_soc_component_update_bits(component, CS42L42_FS_RATE_EN,
 					CS42L42_FS_EN_MASK,
 					(CS42L42_FS_EN_IASRC_96K |
 					CS42L42_FS_EN_OASRC_96K) <<
 					CS42L42_FS_EN_SHIFT);
 			/* Set the input/output internal MCLK clock ~12 MHz */
-			snd_soc_update_bits(codec, CS42L42_IN_ASRC_CLK,
+			snd_soc_component_update_bits(component, CS42L42_IN_ASRC_CLK,
 					CS42L42_CLK_IASRC_SEL_MASK,
 					CS42L42_CLK_IASRC_SEL_12 <<
 					CS42L42_CLK_IASRC_SEL_SHIFT);
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					CS42L42_OUT_ASRC_CLK,
 					CS42L42_CLK_OASRC_SEL_MASK,
 					CS42L42_CLK_OASRC_SEL_12 <<
 					CS42L42_CLK_OASRC_SEL_SHIFT);
 			/* channel 1 on low LRCLK, 32 bit */
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					CS42L42_ASP_RX_DAI0_CH1_AP_RES,
 					CS42L42_ASP_RX_CH_AP_MASK |
 					CS42L42_ASP_RX_CH_RES_MASK,
@@ -707,7 +705,7 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
 					(CS42L42_ASP_RX_CH_RES_32 <<
 					CS42L42_ASP_RX_CH_RES_SHIFT));
 			/* Channel 2 on high LRCLK, 32 bit */
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					CS42L42_ASP_RX_DAI0_CH2_AP_RES,
 					CS42L42_ASP_RX_CH_AP_MASK |
 					CS42L42_ASP_RX_CH_RES_MASK,
@@ -717,50 +715,50 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
 					CS42L42_ASP_RX_CH_RES_SHIFT));
 			if (pll_ratio_table[i].mclk_src_sel == 0) {
 				/* Pass the clock straight through */
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_CTL1,
 					CS42L42_PLL_START_MASK,	0);
 			} else {
 				/* Configure PLL per table 4-5 */
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_DIV_CFG1,
 					CS42L42_SCLK_PREDIV_MASK,
 					pll_ratio_table[i].sclk_prediv
 					<< CS42L42_SCLK_PREDIV_SHIFT);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_DIV_INT,
 					CS42L42_PLL_DIV_INT_MASK,
 					pll_ratio_table[i].pll_div_int
 					<< CS42L42_PLL_DIV_INT_SHIFT);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_DIV_FRAC0,
 					CS42L42_PLL_DIV_FRAC_MASK,
 					CS42L42_FRAC0_VAL(
 					pll_ratio_table[i].pll_div_frac)
 					<< CS42L42_PLL_DIV_FRAC_SHIFT);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_DIV_FRAC1,
 					CS42L42_PLL_DIV_FRAC_MASK,
 					CS42L42_FRAC1_VAL(
 					pll_ratio_table[i].pll_div_frac)
 					<< CS42L42_PLL_DIV_FRAC_SHIFT);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_DIV_FRAC2,
 					CS42L42_PLL_DIV_FRAC_MASK,
 					CS42L42_FRAC2_VAL(
 					pll_ratio_table[i].pll_div_frac)
 					<< CS42L42_PLL_DIV_FRAC_SHIFT);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_CTL4,
 					CS42L42_PLL_MODE_MASK,
 					pll_ratio_table[i].pll_mode
 					<< CS42L42_PLL_MODE_SHIFT);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_CTL3,
 					CS42L42_PLL_DIVOUT_MASK,
 					pll_ratio_table[i].pll_divout
 					<< CS42L42_PLL_DIVOUT_SHIFT);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					CS42L42_PLL_CAL_RATIO,
 					CS42L42_PLL_CAL_RATIO_MASK,
 					pll_ratio_table[i].pll_cal_ratio
@@ -775,7 +773,7 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
 
 static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u32 asp_cfg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -820,7 +818,7 @@ static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		break;
 	}
 
-	snd_soc_update_bits(codec, CS42L42_ASP_CLK_CFG,
+	snd_soc_component_update_bits(component, CS42L42_ASP_CLK_CFG,
 				CS42L42_ASP_MODE_MASK |
 				CS42L42_ASP_SCPOL_IN_DAC_MASK |
 				CS42L42_ASP_LCPOL_IN_MASK, asp_cfg_val);
@@ -832,14 +830,14 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42l42_private *cs42l42 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
 	int retval;
 
 	cs42l42->srate = params_rate(params);
 	cs42l42->swidth = params_width(params);
 
-	retval = cs42l42_pll_config(codec);
+	retval = cs42l42_pll_config(component);
 
 	return retval;
 }
@@ -847,8 +845,8 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
 static int cs42l42_set_sysclk(struct snd_soc_dai *dai,
 				int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42l42_private *cs42l42 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
 
 	cs42l42->sclk = freq;
 
@@ -857,7 +855,7 @@ static int cs42l42_set_sysclk(struct snd_soc_dai *dai,
 
 static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int regval;
 	u8 fullScaleVol;
 
@@ -865,25 +863,25 @@ static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute)
 		/* Mark SCLK as not present to turn on the internal
 		 * oscillator.
 		 */
-		snd_soc_update_bits(codec, CS42L42_OSC_SWITCH,
+		snd_soc_component_update_bits(component, CS42L42_OSC_SWITCH,
 						CS42L42_SCLK_PRESENT_MASK, 0);
 
-		snd_soc_update_bits(codec, CS42L42_PLL_CTL1,
+		snd_soc_component_update_bits(component, CS42L42_PLL_CTL1,
 				CS42L42_PLL_START_MASK,
 				0 << CS42L42_PLL_START_SHIFT);
 
 		/* Mute the headphone */
-		snd_soc_update_bits(codec, CS42L42_HP_CTL,
+		snd_soc_component_update_bits(component, CS42L42_HP_CTL,
 				CS42L42_HP_ANA_AMUTE_MASK |
 				CS42L42_HP_ANA_BMUTE_MASK,
 				CS42L42_HP_ANA_AMUTE_MASK |
 				CS42L42_HP_ANA_BMUTE_MASK);
 	} else {
-		snd_soc_update_bits(codec, CS42L42_PLL_CTL1,
+		snd_soc_component_update_bits(component, CS42L42_PLL_CTL1,
 				CS42L42_PLL_START_MASK,
 				1 << CS42L42_PLL_START_SHIFT);
 		/* Read the headphone load */
-		regval = snd_soc_read(codec, CS42L42_LOAD_DET_RCSTAT);
+		regval = snd_soc_component_read32(component, CS42L42_LOAD_DET_RCSTAT);
 		if (((regval & CS42L42_RLA_STAT_MASK) >>
 			CS42L42_RLA_STAT_SHIFT) == CS42L42_RLA_STAT_15_OHM) {
 			fullScaleVol = CS42L42_HP_FULL_SCALE_VOL_MASK;
@@ -892,13 +890,13 @@ static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute)
 		}
 
 		/* Un-mute the headphone, set the full scale volume flag */
-		snd_soc_update_bits(codec, CS42L42_HP_CTL,
+		snd_soc_component_update_bits(component, CS42L42_HP_CTL,
 				CS42L42_HP_ANA_AMUTE_MASK |
 				CS42L42_HP_ANA_BMUTE_MASK |
 				CS42L42_HP_FULL_SCALE_VOL_MASK, fullScaleVol);
 
 		/* Mark SCLK as present, turn off internal oscillator */
-		snd_soc_update_bits(codec, CS42L42_OSC_SWITCH,
+		snd_soc_component_update_bits(component, CS42L42_OSC_SWITCH,
 				CS42L42_SCLK_PRESENT_MASK,
 				CS42L42_SCLK_PRESENT_MASK);
 	}
@@ -1262,16 +1260,16 @@ static void cs42l42_handle_button_press(struct cs42l42_private *cs42l42)
 
 	switch (bias_level) {
 	case 1: /* Function C button press */
-		dev_dbg(cs42l42->codec->dev, "Function C button press\n");
+		dev_dbg(cs42l42->component->dev, "Function C button press\n");
 		break;
 	case 2: /* Function B button press */
-		dev_dbg(cs42l42->codec->dev, "Function B button press\n");
+		dev_dbg(cs42l42->component->dev, "Function B button press\n");
 		break;
 	case 3: /* Function D button press */
-		dev_dbg(cs42l42->codec->dev, "Function D button press\n");
+		dev_dbg(cs42l42->component->dev, "Function D button press\n");
 		break;
 	case 4: /* Function A button press */
-		dev_dbg(cs42l42->codec->dev, "Function A button press\n");
+		dev_dbg(cs42l42->component->dev, "Function A button press\n");
 		break;
 	}
 
@@ -1340,7 +1338,7 @@ static const struct cs42l42_irq_params irq_params_table[] = {
 static irqreturn_t cs42l42_irq_thread(int irq, void *data)
 {
 	struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data;
-	struct snd_soc_codec *codec = cs42l42->codec;
+	struct snd_soc_component *component = cs42l42->component;
 	unsigned int stickies[12];
 	unsigned int masks[12];
 	unsigned int current_plug_status;
@@ -1372,7 +1370,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
 	if ((~masks[5]) & irq_params_table[5].mask) {
 		if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
 			cs42l42_process_hs_type_detect(cs42l42);
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Auto detect done (%d)\n",
 				cs42l42->hs_type);
 		}
@@ -1392,7 +1390,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
 			if (cs42l42->plug_state != CS42L42_TS_UNPLUG) {
 				cs42l42->plug_state = CS42L42_TS_UNPLUG;
 				cs42l42_cancel_hs_type_detect(cs42l42);
-				dev_dbg(codec->dev,
+				dev_dbg(component->dev,
 					"Unplug event\n");
 			}
 			break;
@@ -1410,7 +1408,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
 
 			if (current_button_status &
 				CS42L42_M_DETECT_TF_MASK) {
-				dev_dbg(codec->dev,
+				dev_dbg(component->dev,
 					"Button released\n");
 			} else if (current_button_status &
 				CS42L42_M_DETECT_FT_MASK) {
@@ -1879,8 +1877,8 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client,
 	cs42l42_set_interrupt_masks(cs42l42);
 
 	/* Register codec for machine driver */
-	ret =  snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_dev_cs42l42, &cs42l42_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_dev_cs42l42, &cs42l42_dai, 1);
 	if (ret < 0)
 		goto err_disable;
 	return 0;
@@ -1895,8 +1893,6 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client)
 {
 	struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client);
 
-	snd_soc_unregister_codec(&i2c_client->dev);
-
 	/* Hold down reset */
 	gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
 
diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h
index d87a0a5..09b0a93 100644
--- a/sound/soc/codecs/cs42l42.h
+++ b/sound/soc/codecs/cs42l42.h
@@ -754,7 +754,7 @@ static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = {
 
 struct  cs42l42_private {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct regulator_bulk_data supplies[CS42L42_NUM_SUPPLIES];
 	struct gpio_desc *reset_gpio;
 	struct completion pdn_done;
diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c
index 9bad478..4b5731a 100644
--- a/sound/soc/codecs/cs42l51-i2c.c
+++ b/sound/soc/codecs/cs42l51-i2c.c
@@ -35,20 +35,12 @@ static int cs42l51_i2c_probe(struct i2c_client *i2c,
 	return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config));
 }
 
-static int cs42l51_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-
-	return 0;
-}
-
 static struct i2c_driver cs42l51_i2c_driver = {
 	.driver = {
 		.name = "cs42l51",
 		.of_match_table = cs42l51_of_match,
 	},
 	.probe = cs42l51_i2c_probe,
-	.remove = cs42l51_i2c_remove,
 	.id_table = cs42l51_i2c_id,
 };
 
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index f8072f1..5080d7a3 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -54,8 +54,8 @@ struct cs42l51_private {
 static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
 			struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	unsigned long value = snd_soc_component_read32(component, CS42L51_PCM_MIXER)&3;
 
 	switch (value) {
 	default:
@@ -82,7 +82,7 @@ static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
 static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
 			struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned char val;
 
 	switch (ucontrol->value.enumerated.item[0]) {
@@ -98,7 +98,7 @@ static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
 		break;
 	}
 
-	snd_soc_write(codec, CS42L51_PCM_MIXER, val);
+	snd_soc_component_write(component, CS42L51_PCM_MIXER, val);
 
 	return 1;
 }
@@ -153,17 +153,17 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
 static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, CS42L51_POWER_CTL1,
+		snd_soc_component_update_bits(component, CS42L51_POWER_CTL1,
 				    CS42L51_POWER_CTL1_PDN,
 				    CS42L51_POWER_CTL1_PDN);
 		break;
 	default:
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, CS42L51_POWER_CTL1,
+		snd_soc_component_update_bits(component, CS42L51_POWER_CTL1,
 				    CS42L51_POWER_CTL1_PDN, 0);
 		break;
 	}
@@ -263,8 +263,8 @@ static const struct snd_soc_dapm_route cs42l51_routes[] = {
 static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
 
 	switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
@@ -273,7 +273,7 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
 		break;
 	default:
-		dev_err(codec->dev, "invalid DAI format\n");
+		dev_err(component->dev, "invalid DAI format\n");
 		return -EINVAL;
 	}
 
@@ -285,7 +285,7 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		cs42l51->func = MODE_SLAVE_AUTO;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown master/slave configuration\n");
+		dev_err(component->dev, "Unknown master/slave configuration\n");
 		return -EINVAL;
 	}
 
@@ -326,8 +326,8 @@ static struct cs42l51_ratios slave_auto_ratios[] = {
 static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
 
 	cs42l51->mclk = freq;
 	return 0;
@@ -337,8 +337,8 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params,
 		struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
 	int ret;
 	unsigned int i;
 	unsigned int rate;
@@ -370,12 +370,12 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
 
 	if (i == nr_ratios) {
 		/* We did not find a matching ratio */
-		dev_err(codec->dev, "could not find matching ratio\n");
+		dev_err(component->dev, "could not find matching ratio\n");
 		return -EINVAL;
 	}
 
-	intf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL);
-	power_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL);
+	intf_ctl = snd_soc_component_read32(component, CS42L51_INTF_CTL);
+	power_ctl = snd_soc_component_read32(component, CS42L51_MIC_POWER_CTL);
 
 	intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
 			| CS42L51_INTF_CTL_DAC_FORMAT(7));
@@ -418,24 +418,24 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
 			fmt = CS42L51_DAC_DIF_RJ24;
 			break;
 		default:
-			dev_err(codec->dev, "unknown format\n");
+			dev_err(component->dev, "unknown format\n");
 			return -EINVAL;
 		}
 		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);
 		break;
 	default:
-		dev_err(codec->dev, "unknown format\n");
+		dev_err(component->dev, "unknown format\n");
 		return -EINVAL;
 	}
 
 	if (ratios[i].mclk)
 		power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;
 
-	ret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl);
+	ret = snd_soc_component_write(component, CS42L51_INTF_CTL, intf_ctl);
 	if (ret < 0)
 		return ret;
 
-	ret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl);
+	ret = snd_soc_component_write(component, CS42L51_MIC_POWER_CTL, power_ctl);
 	if (ret < 0)
 		return ret;
 
@@ -444,18 +444,18 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
 
 static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int reg;
 	int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
 
-	reg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL);
+	reg = snd_soc_component_read32(component, CS42L51_DAC_OUT_CTL);
 
 	if (mute)
 		reg |= mask;
 	else
 		reg &= ~mask;
 
-	return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
+	return snd_soc_component_write(component, CS42L51_DAC_OUT_CTL, reg);
 }
 
 static const struct snd_soc_dai_ops cs42l51_dai_ops = {
@@ -484,7 +484,7 @@ static struct snd_soc_dai_driver cs42l51_dai = {
 	.ops = &cs42l51_dai_ops,
 };
 
-static int cs42l51_codec_probe(struct snd_soc_codec *codec)
+static int cs42l51_component_probe(struct snd_soc_component *component)
 {
 	int ret, reg;
 
@@ -497,24 +497,25 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec)
 	 */
 	reg = CS42L51_DAC_CTL_DATA_SEL(1)
 		| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
-	ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
+	ret = snd_soc_component_write(component, CS42L51_DAC_CTL, reg);
 	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
-	.probe = cs42l51_codec_probe,
-
-	.component_driver = {
-		.controls		= cs42l51_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs42l51_snd_controls),
-		.dapm_widgets		= cs42l51_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs42l51_dapm_widgets),
-		.dapm_routes		= cs42l51_routes,
-		.num_dapm_routes	= ARRAY_SIZE(cs42l51_routes),
-	},
+static const struct snd_soc_component_driver soc_component_device_cs42l51 = {
+	.probe			= cs42l51_component_probe,
+	.controls		= cs42l51_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs42l51_snd_controls),
+	.dapm_widgets		= cs42l51_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs42l51_dapm_widgets),
+	.dapm_routes		= cs42l51_routes,
+	.num_dapm_routes	= ARRAY_SIZE(cs42l51_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 const struct regmap_config cs42l51_regmap = {
@@ -555,8 +556,8 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
 	dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n",
 		 val & CS42L51_CHIP_REV_MASK);
 
-	ret =  snd_soc_register_codec(dev,
-			&soc_codec_device_cs42l51, &cs42l51_dai, 1);
+	ret = devm_snd_soc_register_component(dev,
+			&soc_component_device_cs42l51, &cs42l51_dai, 1);
 error:
 	return ret;
 }
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 9731e5d..3d83c1b 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -42,7 +42,7 @@ struct sp_config {
 
 struct  cs42l52_private {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct device *dev;
 	struct sp_config config;
 	struct cs42l52_platform_data pdata;
@@ -473,17 +473,17 @@ static const struct snd_kcontrol_new cs42l52_micb_controls[] = {
 	SOC_ENUM("MICB Select", micb_enum),
 };
 
-static int cs42l52_add_mic_controls(struct snd_soc_codec *codec)
+static int cs42l52_add_mic_controls(struct snd_soc_component *component)
 {
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 	struct cs42l52_platform_data *pdata = &cs42l52->pdata;
 
 	if (!pdata->mica_diff_cfg)
-		snd_soc_add_codec_controls(codec, cs42l52_mica_controls,
+		snd_soc_add_component_controls(component, cs42l52_mica_controls,
 				     ARRAY_SIZE(cs42l52_mica_controls));
 
 	if (!pdata->micb_diff_cfg)
-		snd_soc_add_codec_controls(codec, cs42l52_micb_controls,
+		snd_soc_add_component_controls(component, cs42l52_micb_controls,
 				     ARRAY_SIZE(cs42l52_micb_controls));
 
 	return 0;
@@ -716,13 +716,13 @@ static int cs42l52_get_clk(int mclk, int rate)
 static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai,
 			int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
 	if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) {
 		cs42l52->sysclk = freq;
 	} else {
-		dev_err(codec->dev, "Invalid freq parameter\n");
+		dev_err(component->dev, "Invalid freq parameter\n");
 		return -EINVAL;
 	}
 	return 0;
@@ -730,8 +730,8 @@ static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai,
 
 static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 	u8 iface = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -783,21 +783,21 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 	cs42l52->config.format = iface;
-	snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format);
+	snd_soc_component_write(component, CS42L52_IFACE_CTL1, cs42l52->config.format);
 
 	return 0;
 }
 
 static int cs42l52_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (mute)
-		snd_soc_update_bits(codec, CS42L52_PB_CTL1,
+		snd_soc_component_update_bits(component, CS42L52_PB_CTL1,
 				    CS42L52_PB_CTL1_MUTE_MASK,
 				CS42L52_PB_CTL1_MUTE);
 	else
-		snd_soc_update_bits(codec, CS42L52_PB_CTL1,
+		snd_soc_component_update_bits(component, CS42L52_PB_CTL1,
 				    CS42L52_PB_CTL1_MUTE_MASK,
 				CS42L52_PB_CTL1_UNMUTE);
 
@@ -808,8 +808,8 @@ static int cs42l52_pcm_hw_params(struct snd_pcm_substream *substream,
 				     struct snd_pcm_hw_params *params,
 				     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 	u32 clk = 0;
 	int index;
 
@@ -823,36 +823,36 @@ static int cs42l52_pcm_hw_params(struct snd_pcm_substream *substream,
 		(clk_map_table[index].ratio << CLK_RATIO_SHIFT) |
 		clk_map_table[index].mclkdiv2;
 
-		snd_soc_write(codec, CS42L52_CLK_CTL, clk);
+		snd_soc_component_write(component, CS42L52_CLK_CTL, clk);
 	} else {
-		dev_err(codec->dev, "can't get correct mclk\n");
+		dev_err(component->dev, "can't get correct mclk\n");
 		return -EINVAL;
 	}
 
 	return 0;
 }
 
-static int cs42l52_set_bias_level(struct snd_soc_codec *codec,
+static int cs42l52_set_bias_level(struct snd_soc_component *component,
 					enum snd_soc_bias_level level)
 {
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, CS42L52_PWRCTL1,
+		snd_soc_component_update_bits(component, CS42L52_PWRCTL1,
 				    CS42L52_PWRCTL1_PDN_CODEC, 0);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_cache_only(cs42l52->regmap, false);
 			regcache_sync(cs42l52->regmap);
 		}
-		snd_soc_write(codec, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
+		snd_soc_component_write(component, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
+		snd_soc_component_write(component, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
 		regcache_cache_only(cs42l52->regmap, true);
 		break;
 	}
@@ -902,8 +902,8 @@ static void cs42l52_beep_work(struct work_struct *work)
 {
 	struct cs42l52_private *cs42l52 =
 		container_of(work, struct cs42l52_private, beep_work);
-	struct snd_soc_codec *codec = cs42l52->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = cs42l52->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int i;
 	int val = 0;
 	int best = 0;
@@ -915,18 +915,18 @@ static void cs42l52_beep_work(struct work_struct *work)
 				best = i;
 		}
 
-		dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
+		dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
 			beep_rates[best], cs42l52->beep_rate);
 
 		val = (best << CS42L52_BEEP_RATE_SHIFT);
 
 		snd_soc_dapm_enable_pin(dapm, "Beep");
 	} else {
-		dev_dbg(codec->dev, "Disabling beep\n");
+		dev_dbg(component->dev, "Disabling beep\n");
 		snd_soc_dapm_disable_pin(dapm, "Beep");
 	}
 
-	snd_soc_update_bits(codec, CS42L52_BEEP_FREQ,
+	snd_soc_component_update_bits(component, CS42L52_BEEP_FREQ,
 			    CS42L52_BEEP_RATE_MASK, val);
 
 	snd_soc_dapm_sync(dapm);
@@ -938,10 +938,10 @@ static void cs42l52_beep_work(struct work_struct *work)
 static int cs42l52_beep_event(struct input_dev *dev, unsigned int type,
 			     unsigned int code, int hz)
 {
-	struct snd_soc_codec *codec = input_get_drvdata(dev);
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = input_get_drvdata(dev);
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
+	dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
 
 	switch (code) {
 	case SND_BELL:
@@ -978,14 +978,14 @@ static ssize_t cs42l52_beep_set(struct device *dev,
 
 static DEVICE_ATTR(beep, 0200, NULL, cs42l52_beep_set);
 
-static void cs42l52_init_beep(struct snd_soc_codec *codec)
+static void cs42l52_init_beep(struct snd_soc_component *component)
 {
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	cs42l52->beep = devm_input_allocate_device(codec->dev);
+	cs42l52->beep = devm_input_allocate_device(component->dev);
 	if (!cs42l52->beep) {
-		dev_err(codec->dev, "Failed to allocate beep device\n");
+		dev_err(component->dev, "Failed to allocate beep device\n");
 		return;
 	}
 
@@ -993,49 +993,49 @@ static void cs42l52_init_beep(struct snd_soc_codec *codec)
 	cs42l52->beep_rate = 0;
 
 	cs42l52->beep->name = "CS42L52 Beep Generator";
-	cs42l52->beep->phys = dev_name(codec->dev);
+	cs42l52->beep->phys = dev_name(component->dev);
 	cs42l52->beep->id.bustype = BUS_I2C;
 
 	cs42l52->beep->evbit[0] = BIT_MASK(EV_SND);
 	cs42l52->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	cs42l52->beep->event = cs42l52_beep_event;
-	cs42l52->beep->dev.parent = codec->dev;
-	input_set_drvdata(cs42l52->beep, codec);
+	cs42l52->beep->dev.parent = component->dev;
+	input_set_drvdata(cs42l52->beep, component);
 
 	ret = input_register_device(cs42l52->beep);
 	if (ret != 0) {
 		cs42l52->beep = NULL;
-		dev_err(codec->dev, "Failed to register beep device\n");
+		dev_err(component->dev, "Failed to register beep device\n");
 	}
 
-	ret = device_create_file(codec->dev, &dev_attr_beep);
+	ret = device_create_file(component->dev, &dev_attr_beep);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to create keyclick file: %d\n",
+		dev_err(component->dev, "Failed to create keyclick file: %d\n",
 			ret);
 	}
 }
 
-static void cs42l52_free_beep(struct snd_soc_codec *codec)
+static void cs42l52_free_beep(struct snd_soc_component *component)
 {
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
-	device_remove_file(codec->dev, &dev_attr_beep);
+	device_remove_file(component->dev, &dev_attr_beep);
 	cancel_work_sync(&cs42l52->beep_work);
 	cs42l52->beep = NULL;
 
-	snd_soc_update_bits(codec, CS42L52_BEEP_TONE_CTL,
+	snd_soc_component_update_bits(component, CS42L52_BEEP_TONE_CTL,
 			    CS42L52_BEEP_EN_MASK, 0);
 }
 
-static int cs42l52_probe(struct snd_soc_codec *codec)
+static int cs42l52_probe(struct snd_soc_component *component)
 {
-	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(cs42l52->regmap, true);
 
-	cs42l52_add_mic_controls(codec);
+	cs42l52_add_mic_controls(component);
 
-	cs42l52_init_beep(codec);
+	cs42l52_init_beep(component);
 
 	cs42l52->sysclk = CS42L52_DEFAULT_CLK;
 	cs42l52->config.format = CS42L52_DEFAULT_FORMAT;
@@ -1043,27 +1043,26 @@ static int cs42l52_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int cs42l52_remove(struct snd_soc_codec *codec)
+static void cs42l52_remove(struct snd_soc_component *component)
 {
-	cs42l52_free_beep(codec);
-
-	return 0;
+	cs42l52_free_beep(component);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
-	.probe = cs42l52_probe,
-	.remove = cs42l52_remove,
-	.set_bias_level = cs42l52_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= cs42l52_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs42l52_snd_controls),
-		.dapm_widgets		= cs42l52_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs42l52_dapm_widgets),
-		.dapm_routes		= cs42l52_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(cs42l52_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_cs42l52 = {
+	.probe			= cs42l52_probe,
+	.remove			= cs42l52_remove,
+	.set_bias_level		= cs42l52_set_bias_level,
+	.controls		= cs42l52_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs42l52_snd_controls),
+	.dapm_widgets		= cs42l52_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs42l52_dapm_widgets),
+	.dapm_routes		= cs42l52_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs42l52_audio_map),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /* Current and threshold powerup sequence Pg37 */
@@ -1202,19 +1201,13 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
 				   CS42L52_IFACE_CTL2_BIAS_LVL,
 				cs42l52->pdata.micbias_lvl);
 
-	ret =  snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_dev_cs42l52, &cs42l52_dai, 1);
+	ret =  devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_dev_cs42l52, &cs42l52_dai, 1);
 	if (ret < 0)
 		return ret;
 	return 0;
 }
 
-static int cs42l52_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct of_device_id cs42l52_of_match[] = {
 	{ .compatible = "cirrus,cs42l52", },
 	{},
@@ -1235,7 +1228,6 @@ static struct i2c_driver cs42l52_i2c_driver = {
 	},
 	.id_table = cs42l52_id,
 	.probe =    cs42l52_i2c_probe,
-	.remove =   cs42l52_i2c_remove,
 };
 
 module_i2c_driver(cs42l52_i2c_driver);
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c
index fd7b8d3..a5c8736 100644
--- a/sound/soc/codecs/cs42l56.c
+++ b/sound/soc/codecs/cs42l56.c
@@ -45,7 +45,7 @@ static const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = {
 
 struct  cs42l56_private {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct device *dev;
 	struct cs42l56_platform_data pdata;
 	struct regulator_bulk_data supplies[CS42L56_NUM_SUPPLIES];
@@ -726,8 +726,8 @@ static int cs42l56_get_mclk_ratio(int mclk, int rate)
 static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
 			int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case CS42L56_MCLK_5P6448MHZ:
@@ -753,10 +753,10 @@ static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
 	}
 	cs42l56->mclk = freq;
 
-	snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+	snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 			    CS42L56_MCLK_PREDIV_MASK,
 				cs42l56->mclk_prediv);
-	snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+	snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 			    CS42L56_MCLK_DIV2_MASK,
 				cs42l56->mclk_div2);
 
@@ -765,8 +765,8 @@ static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
 
 static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -803,22 +803,22 @@ static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+	snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 			    CS42L56_MS_MODE_MASK, cs42l56->iface);
-	snd_soc_update_bits(codec, CS42L56_SERIAL_FMT,
+	snd_soc_component_update_bits(component, CS42L56_SERIAL_FMT,
 			    CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt);
-	snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+	snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 			    CS42L56_SCLK_INV_MASK, cs42l56->iface_inv);
 	return 0;
 }
 
 static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (mute) {
 		/* Hit the DSP Mixer first */
-		snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL,
+		snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
 				    CS42L56_ADCAMIX_MUTE_MASK |
 				    CS42L56_ADCBMIX_MUTE_MASK |
 				    CS42L56_PCMAMIX_MUTE_MASK |
@@ -827,21 +827,21 @@ static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
 				    CS42L56_MSTA_MUTE_MASK,
 				    CS42L56_MUTE_ALL);
 		/* Mute ADC's */
-		snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL,
+		snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
 				    CS42L56_ADCA_MUTE_MASK |
 				    CS42L56_ADCB_MUTE_MASK,
 				    CS42L56_MUTE_ALL);
 		/* HP And LO */
-		snd_soc_update_bits(codec, CS42L56_HPA_VOLUME,
+		snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
 				    CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
-		snd_soc_update_bits(codec, CS42L56_HPB_VOLUME,
+		snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
 				    CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
-		snd_soc_update_bits(codec, CS42L56_LOA_VOLUME,
+		snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
 				    CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
-		snd_soc_update_bits(codec, CS42L56_LOB_VOLUME,
+		snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
 				    CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
 	} else {
-		snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL,
+		snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
 				    CS42L56_ADCAMIX_MUTE_MASK |
 				    CS42L56_ADCBMIX_MUTE_MASK |
 				    CS42L56_PCMAMIX_MUTE_MASK |
@@ -850,18 +850,18 @@ static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
 				    CS42L56_MSTA_MUTE_MASK,
 				    CS42L56_UNMUTE);
 
-		snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL,
+		snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
 				    CS42L56_ADCA_MUTE_MASK |
 				    CS42L56_ADCB_MUTE_MASK,
 				    CS42L56_UNMUTE);
 
-		snd_soc_update_bits(codec, CS42L56_HPA_VOLUME,
+		snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
 				    CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
-		snd_soc_update_bits(codec, CS42L56_HPB_VOLUME,
+		snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
 				    CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
-		snd_soc_update_bits(codec, CS42L56_LOA_VOLUME,
+		snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
 				    CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
-		snd_soc_update_bits(codec, CS42L56_LOB_VOLUME,
+		snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
 				    CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
 	}
 	return 0;
@@ -871,39 +871,39 @@ static int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream,
 				     struct snd_pcm_hw_params *params,
 				     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 	int ratio;
 
 	ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params));
 	if (ratio >= 0) {
-		snd_soc_update_bits(codec, CS42L56_CLKCTL_2,
+		snd_soc_component_update_bits(component, CS42L56_CLKCTL_2,
 				    CS42L56_CLK_RATIO_MASK, ratio);
 	} else {
-		dev_err(codec->dev, "unsupported mclk/sclk/lrclk ratio\n");
+		dev_err(component->dev, "unsupported mclk/sclk/lrclk ratio\n");
 		return -EINVAL;
 	}
 
 	return 0;
 }
 
-static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
+static int cs42l56_set_bias_level(struct snd_soc_component *component,
 					enum snd_soc_bias_level level)
 {
-	struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+		snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 				    CS42L56_MCLK_DIS_MASK, 0);
-		snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
+		snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
 				    CS42L56_PDN_ALL_MASK, 0);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_cache_only(cs42l56->regmap, false);
 			regcache_sync(cs42l56->regmap);
 			ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
@@ -915,13 +915,13 @@ static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
 				return ret;
 			}
 		}
-		snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
+		snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
 				    CS42L56_PDN_ALL_MASK, 1);
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
+		snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
 				    CS42L56_PDN_ALL_MASK, 1);
-		snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+		snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 				    CS42L56_MCLK_DIS_MASK, 1);
 		regcache_cache_only(cs42l56->regmap, true);
 		regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
@@ -974,8 +974,8 @@ static void cs42l56_beep_work(struct work_struct *work)
 {
 	struct cs42l56_private *cs42l56 =
 		container_of(work, struct cs42l56_private, beep_work);
-	struct snd_soc_codec *codec = cs42l56->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = cs42l56->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int i;
 	int val = 0;
 	int best = 0;
@@ -987,18 +987,18 @@ static void cs42l56_beep_work(struct work_struct *work)
 				best = i;
 		}
 
-		dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
+		dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
 			beep_freq[best], cs42l56->beep_rate);
 
 		val = (best << CS42L56_BEEP_RATE_SHIFT);
 
 		snd_soc_dapm_enable_pin(dapm, "Beep");
 	} else {
-		dev_dbg(codec->dev, "Disabling beep\n");
+		dev_dbg(component->dev, "Disabling beep\n");
 		snd_soc_dapm_disable_pin(dapm, "Beep");
 	}
 
-	snd_soc_update_bits(codec, CS42L56_BEEP_FREQ_ONTIME,
+	snd_soc_component_update_bits(component, CS42L56_BEEP_FREQ_ONTIME,
 			    CS42L56_BEEP_FREQ_MASK, val);
 
 	snd_soc_dapm_sync(dapm);
@@ -1010,10 +1010,10 @@ static void cs42l56_beep_work(struct work_struct *work)
 static int cs42l56_beep_event(struct input_dev *dev, unsigned int type,
 			     unsigned int code, int hz)
 {
-	struct snd_soc_codec *codec = input_get_drvdata(dev);
-	struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = input_get_drvdata(dev);
+	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
+	dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
 
 	switch (code) {
 	case SND_BELL:
@@ -1050,14 +1050,14 @@ static ssize_t cs42l56_beep_set(struct device *dev,
 
 static DEVICE_ATTR(beep, 0200, NULL, cs42l56_beep_set);
 
-static void cs42l56_init_beep(struct snd_soc_codec *codec)
+static void cs42l56_init_beep(struct snd_soc_component *component)
 {
-	struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	cs42l56->beep = devm_input_allocate_device(codec->dev);
+	cs42l56->beep = devm_input_allocate_device(component->dev);
 	if (!cs42l56->beep) {
-		dev_err(codec->dev, "Failed to allocate beep device\n");
+		dev_err(component->dev, "Failed to allocate beep device\n");
 		return;
 	}
 
@@ -1065,68 +1065,67 @@ static void cs42l56_init_beep(struct snd_soc_codec *codec)
 	cs42l56->beep_rate = 0;
 
 	cs42l56->beep->name = "CS42L56 Beep Generator";
-	cs42l56->beep->phys = dev_name(codec->dev);
+	cs42l56->beep->phys = dev_name(component->dev);
 	cs42l56->beep->id.bustype = BUS_I2C;
 
 	cs42l56->beep->evbit[0] = BIT_MASK(EV_SND);
 	cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	cs42l56->beep->event = cs42l56_beep_event;
-	cs42l56->beep->dev.parent = codec->dev;
-	input_set_drvdata(cs42l56->beep, codec);
+	cs42l56->beep->dev.parent = component->dev;
+	input_set_drvdata(cs42l56->beep, component);
 
 	ret = input_register_device(cs42l56->beep);
 	if (ret != 0) {
 		cs42l56->beep = NULL;
-		dev_err(codec->dev, "Failed to register beep device\n");
+		dev_err(component->dev, "Failed to register beep device\n");
 	}
 
-	ret = device_create_file(codec->dev, &dev_attr_beep);
+	ret = device_create_file(component->dev, &dev_attr_beep);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to create keyclick file: %d\n",
+		dev_err(component->dev, "Failed to create keyclick file: %d\n",
 			ret);
 	}
 }
 
-static void cs42l56_free_beep(struct snd_soc_codec *codec)
+static void cs42l56_free_beep(struct snd_soc_component *component)
 {
-	struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 
-	device_remove_file(codec->dev, &dev_attr_beep);
+	device_remove_file(component->dev, &dev_attr_beep);
 	cancel_work_sync(&cs42l56->beep_work);
 	cs42l56->beep = NULL;
 
-	snd_soc_update_bits(codec, CS42L56_BEEP_TONE_CFG,
+	snd_soc_component_update_bits(component, CS42L56_BEEP_TONE_CFG,
 			    CS42L56_BEEP_EN_MASK, 0);
 }
 
-static int cs42l56_probe(struct snd_soc_codec *codec)
+static int cs42l56_probe(struct snd_soc_component *component)
 {
-	cs42l56_init_beep(codec);
+	cs42l56_init_beep(component);
 
 	return 0;
 }
 
-static int cs42l56_remove(struct snd_soc_codec *codec)
+static void cs42l56_remove(struct snd_soc_component *component)
 {
-	cs42l56_free_beep(codec);
-
-	return 0;
+	cs42l56_free_beep(component);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
-	.probe = cs42l56_probe,
-	.remove = cs42l56_remove,
-	.set_bias_level = cs42l56_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= cs42l56_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs42l56_snd_controls),
-		.dapm_widgets		= cs42l56_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs42l56_dapm_widgets),
-		.dapm_routes		= cs42l56_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(cs42l56_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_cs42l56 = {
+	.probe			= cs42l56_probe,
+	.remove			= cs42l56_remove,
+	.set_bias_level		= cs42l56_set_bias_level,
+	.controls		= cs42l56_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs42l56_snd_controls),
+	.dapm_widgets		= cs42l56_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs42l56_dapm_widgets),
+	.dapm_routes		= cs42l56_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs42l56_audio_map),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config cs42l56_regmap = {
@@ -1315,8 +1314,8 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client,
 				   CS42L56_ADAPT_PWR_MASK,
 				cs42l56->pdata.adaptive_pwr);
 
-	ret =  snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_dev_cs42l56, &cs42l56_dai, 1);
+	ret =  devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_dev_cs42l56, &cs42l56_dai, 1);
 	if (ret < 0)
 		return ret;
 
@@ -1332,7 +1331,6 @@ static int cs42l56_i2c_remove(struct i2c_client *client)
 {
 	struct cs42l56_private *cs42l56 = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
 	regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
 			       cs42l56->supplies);
 	return 0;
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index aebaa97..36b57ee 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -490,8 +490,8 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
 static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMD:
 		/* 150 ms delay between setting PDN and MCLKDIS */
@@ -506,8 +506,8 @@ static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
 static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMD:
 		/* 50 ms delay between setting PDN and MCLKDIS */
@@ -524,8 +524,8 @@ static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w,
 static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMD:
 		/* 30 ms delay between setting PDN and MCLKDIS */
@@ -884,8 +884,8 @@ static int cs42l73_get_mclk_coeff(int mclk, int srate)
 
 static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 
 	int mclkx_coeff;
 	u32 mclk = 0;
@@ -899,14 +899,14 @@ static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
 	mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx /
 		cs42l73_mclkx_coeffs[mclkx_coeff].ratio;
 
-	dev_dbg(codec->dev, "MCLK%u %u  <-> internal MCLK %u\n",
+	dev_dbg(component->dev, "MCLK%u %u  <-> internal MCLK %u\n",
 		 priv->mclksel + 1, cs42l73_mclkx_coeffs[mclkx_coeff].mclkx,
 		 mclk);
 
 	dmmcc = (priv->mclksel << 4) |
 		(cs42l73_mclkx_coeffs[mclkx_coeff].mclkdiv << 1);
 
-	snd_soc_write(codec, CS42L73_DMMCC, dmmcc);
+	snd_soc_component_write(component, CS42L73_DMMCC, dmmcc);
 
 	priv->sysclk = mclkx_coeff;
 	priv->mclk = mclk;
@@ -917,8 +917,8 @@ static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
 static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
 			      int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case CS42L73_CLKID_MCLK1:
@@ -930,7 +930,7 @@ static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
 	}
 
 	if ((cs42l73_set_mclk(dai, freq)) < 0) {
-		dev_err(codec->dev, "Unable to set MCLK for dai %s\n",
+		dev_err(component->dev, "Unable to set MCLK for dai %s\n",
 			dai->name);
 		return -EINVAL;
 	}
@@ -942,14 +942,14 @@ static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
 
 static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 	u8 id = codec_dai->id;
 	unsigned int inv, format;
 	u8 spc, mmcc;
 
-	spc = snd_soc_read(codec, CS42L73_SPC(id));
-	mmcc = snd_soc_read(codec, CS42L73_MMCC(id));
+	spc = snd_soc_component_read32(component, CS42L73_SPC(id));
+	mmcc = snd_soc_component_read32(component, CS42L73_MMCC(id));
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -974,12 +974,12 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	case SND_SOC_DAIFMT_DSP_A:
 	case SND_SOC_DAIFMT_DSP_B:
 		if (mmcc & CS42L73_MS_MASTER) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"PCM format in slave mode only\n");
 			return -EINVAL;
 		}
 		if (id == CS42L73_ASP) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"PCM format is not supported on ASP port\n");
 			return -EINVAL;
 		}
@@ -1029,7 +1029,7 @@ static unsigned int cs42l73_get_xspfs_coeff(u32 rate)
 	return 0;		/* 0 = Don't know */
 }
 
-static void cs42l73_update_asrc(struct snd_soc_codec *codec, int id, int srate)
+static void cs42l73_update_asrc(struct snd_soc_component *component, int id, int srate)
 {
 	u8 spfs = 0;
 
@@ -1038,13 +1038,13 @@ static void cs42l73_update_asrc(struct snd_soc_codec *codec, int id, int srate)
 
 	switch (id) {
 	case CS42L73_XSP:
-		snd_soc_update_bits(codec, CS42L73_VXSPFS, 0x0f, spfs);
+		snd_soc_component_update_bits(component, CS42L73_VXSPFS, 0x0f, spfs);
 	break;
 	case CS42L73_ASP:
-		snd_soc_update_bits(codec, CS42L73_ASPC, 0x3c, spfs << 2);
+		snd_soc_component_update_bits(component, CS42L73_ASPC, 0x3c, spfs << 2);
 	break;
 	case CS42L73_VSP:
-		snd_soc_update_bits(codec, CS42L73_VXSPFS, 0xf0, spfs << 4);
+		snd_soc_component_update_bits(component, CS42L73_VXSPFS, 0xf0, spfs << 4);
 	break;
 	default:
 	break;
@@ -1055,8 +1055,8 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 	int id = dai->id;
 	int mclk_coeff;
 	int srate = params_rate(params);
@@ -1070,7 +1070,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
 		if (mclk_coeff < 0)
 			return -EINVAL;
 
-		dev_dbg(codec->dev,
+		dev_dbg(component->dev,
 			 "DAI[%d]: MCLK %u, srate %u, MMCC[5:0] = %x\n",
 			 id, priv->mclk, srate,
 			 cs42l73_mclk_coeffs[mclk_coeff].mmcc);
@@ -1091,38 +1091,38 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
 	/* Update ASRCs */
 	priv->config[id].srate = srate;
 
-	snd_soc_write(codec, CS42L73_SPC(id), priv->config[id].spc);
-	snd_soc_write(codec, CS42L73_MMCC(id), priv->config[id].mmcc);
+	snd_soc_component_write(component, CS42L73_SPC(id), priv->config[id].spc);
+	snd_soc_component_write(component, CS42L73_MMCC(id), priv->config[id].mmcc);
 
-	cs42l73_update_asrc(codec, id, srate);
+	cs42l73_update_asrc(component, id, srate);
 
 	return 0;
 }
 
-static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
+static int cs42l73_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l73_private *cs42l73 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 0);
-		snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 0);
+		snd_soc_component_update_bits(component, CS42L73_DMMCC, CS42L73_MCLKDIS, 0);
+		snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 0);
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_cache_only(cs42l73->regmap, false);
 			regcache_sync(cs42l73->regmap);
 		}
-		snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1);
+		snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 1);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1);
+		snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 1);
 		if (cs42l73->shutdwn_delay > 0) {
 			mdelay(cs42l73->shutdwn_delay);
 			cs42l73->shutdwn_delay = 0;
@@ -1131,7 +1131,7 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
 				     * down.
 				     */
 		}
-		snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1);
+		snd_soc_component_update_bits(component, CS42L73_DMMCC, CS42L73_MCLKDIS, 1);
 		break;
 	}
 	return 0;
@@ -1139,10 +1139,10 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
 
 static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int id = dai->id;
 
-	return snd_soc_update_bits(codec, CS42L73_SPC(id), CS42L73_SP_3ST,
+	return snd_soc_component_update_bits(component, CS42L73_SPC(id), CS42L73_SP_3ST,
 				   tristate << 7);
 }
 
@@ -1235,13 +1235,13 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
 	 }
 };
 
-static int cs42l73_probe(struct snd_soc_codec *codec)
+static int cs42l73_probe(struct snd_soc_component *component)
 {
-	struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
+	struct cs42l73_private *cs42l73 = snd_soc_component_get_drvdata(component);
 
 	/* Set Charge Pump Frequency */
 	if (cs42l73->pdata.chgfreq)
-		snd_soc_update_bits(codec, CS42L73_CPFCHC,
+		snd_soc_component_update_bits(component, CS42L73_CPFCHC,
 				    CS42L73_CHARGEPUMP_MASK,
 					cs42l73->pdata.chgfreq << 4);
 
@@ -1252,19 +1252,20 @@ static int cs42l73_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
-	.probe = cs42l73_probe,
-	.set_bias_level = cs42l73_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= cs42l73_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs42l73_snd_controls),
-		.dapm_widgets		= cs42l73_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs42l73_dapm_widgets),
-		.dapm_routes		= cs42l73_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(cs42l73_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_cs42l73 = {
+	.probe			= cs42l73_probe,
+	.set_bias_level		= cs42l73_set_bias_level,
+	.controls		= cs42l73_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs42l73_snd_controls),
+	.dapm_widgets		= cs42l73_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs42l73_dapm_widgets),
+	.dapm_routes		= cs42l73_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cs42l73_audio_map),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config cs42l73_regmap = {
@@ -1361,20 +1362,14 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client,
 	dev_info(&i2c_client->dev,
 		 "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF);
 
-	ret =  snd_soc_register_codec(&i2c_client->dev,
-			&soc_codec_dev_cs42l73, cs42l73_dai,
+	ret = devm_snd_soc_register_component(&i2c_client->dev,
+			&soc_component_dev_cs42l73, cs42l73_dai,
 			ARRAY_SIZE(cs42l73_dai));
 	if (ret < 0)
 		return ret;
 	return 0;
 }
 
-static int cs42l73_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct of_device_id cs42l73_of_match[] = {
 	{ .compatible = "cirrus,cs42l73", },
 	{},
@@ -1395,7 +1390,6 @@ static struct i2c_driver cs42l73_i2c_driver = {
 		   },
 	.id_table = cs42l73_id,
 	.probe = cs42l73_i2c_probe,
-	.remove = cs42l73_i2c_remove,
 
 };
 
diff --git a/sound/soc/codecs/cs42xx8-i2c.c b/sound/soc/codecs/cs42xx8-i2c.c
index 800c1d5..0214e3a 100644
--- a/sound/soc/codecs/cs42xx8-i2c.c
+++ b/sound/soc/codecs/cs42xx8-i2c.c
@@ -33,7 +33,6 @@ static int cs42xx8_i2c_probe(struct i2c_client *i2c,
 
 static int cs42xx8_i2c_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&i2c->dev);
 	pm_runtime_disable(&i2c->dev);
 
 	return 0;
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
index c1785bd..ebb9e0c 100644
--- a/sound/soc/codecs/cs42xx8.c
+++ b/sound/soc/codecs/cs42xx8.c
@@ -194,8 +194,8 @@ static const struct cs42xx8_ratios cs42xx8_ratios[] = {
 static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				  int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
 
 	cs42xx8->sysclk = freq;
 
@@ -205,8 +205,8 @@ static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			       unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
 	u32 val;
 
 	/* Set DAI format */
@@ -224,7 +224,7 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		val = CS42XX8_INTF_DAC_DIF_TDM | CS42XX8_INTF_ADC_DIF_TDM;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported dai format\n");
+		dev_err(component->dev, "unsupported dai format\n");
 		return -EINVAL;
 	}
 
@@ -241,7 +241,7 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		cs42xx8->slave_mode = false;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported master/slave mode\n");
+		dev_err(component->dev, "unsupported master/slave mode\n");
 		return -EINVAL;
 	}
 
@@ -252,8 +252,8 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 	u32 ratio = cs42xx8->sysclk / params_rate(params);
 	u32 i, fm, val, mask;
@@ -267,7 +267,7 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (i == ARRAY_SIZE(cs42xx8_ratios)) {
-		dev_err(codec->dev, "unsupported sysclk ratio\n");
+		dev_err(component->dev, "unsupported sysclk ratio\n");
 		return -EINVAL;
 	}
 
@@ -285,8 +285,8 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
 
 static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
 	u8 dac_unmute = cs42xx8->tx_channels ?
 		        ~((0x1 << cs42xx8->tx_channels) - 1) : 0;
 
@@ -382,14 +382,14 @@ const struct regmap_config cs42xx8_regmap_config = {
 };
 EXPORT_SYMBOL_GPL(cs42xx8_regmap_config);
 
-static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
+static int cs42xx8_component_probe(struct snd_soc_component *component)
 {
-	struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	switch (cs42xx8->drvdata->num_adcs) {
 	case 3:
-		snd_soc_add_codec_controls(codec, cs42xx8_adc3_snd_controls,
+		snd_soc_add_component_controls(component, cs42xx8_adc3_snd_controls,
 					ARRAY_SIZE(cs42xx8_adc3_snd_controls));
 		snd_soc_dapm_new_controls(dapm, cs42xx8_adc3_dapm_widgets,
 					ARRAY_SIZE(cs42xx8_adc3_dapm_widgets));
@@ -406,18 +406,17 @@ static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver cs42xx8_driver = {
-	.probe = cs42xx8_codec_probe,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= cs42xx8_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs42xx8_snd_controls),
-		.dapm_widgets		= cs42xx8_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs42xx8_dapm_widgets),
-		.dapm_routes		= cs42xx8_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(cs42xx8_dapm_routes),
-	},
+static const struct snd_soc_component_driver cs42xx8_driver = {
+	.probe			= cs42xx8_component_probe,
+	.controls		= cs42xx8_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs42xx8_snd_controls),
+	.dapm_widgets		= cs42xx8_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs42xx8_dapm_widgets),
+	.dapm_routes		= cs42xx8_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(cs42xx8_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 const struct cs42xx8_driver_data cs42448_data = {
@@ -520,9 +519,9 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap)
 	/* Each adc supports stereo input */
 	cs42xx8_dai.capture.channels_max = cs42xx8->drvdata->num_adcs * 2;
 
-	ret = snd_soc_register_codec(dev, &cs42xx8_driver, &cs42xx8_dai, 1);
+	ret = devm_snd_soc_register_component(dev, &cs42xx8_driver, &cs42xx8_dai, 1);
 	if (ret) {
-		dev_err(dev, "failed to register codec:%d\n", ret);
+		dev_err(dev, "failed to register component:%d\n", ret);
 		goto err_enable;
 	}
 
diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c
index 5ba0edc..feca0a6 100644
--- a/sound/soc/codecs/cs43130.c
+++ b/sound/soc/codecs/cs43130.c
@@ -236,12 +236,12 @@ static const struct cs43130_pll_params *cs43130_get_pll_table(
 	return NULL;
 }
 
-static int cs43130_pll_config(struct snd_soc_codec *codec)
+static int cs43130_pll_config(struct snd_soc_component *component)
 {
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 	const struct cs43130_pll_params *pll_entry;
 
-	dev_dbg(codec->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n",
+	dev_dbg(component->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n",
 		cs43130->mclk, cs43130->mclk_int);
 
 	pll_entry = cs43130_get_pll_table(cs43130->mclk, cs43130->mclk_int);
@@ -286,11 +286,11 @@ static int cs43130_pll_config(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+static int cs43130_set_pll(struct snd_soc_component *component, int pll_id, int source,
 			   unsigned int freq_in, unsigned int freq_out)
 {
 	int ret = 0;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	switch (freq_in) {
 	case 9600000:
@@ -306,7 +306,7 @@ static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
 		cs43130->mclk = freq_in;
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"unsupported pll input reference clock:%d\n", freq_in);
 		return -EINVAL;
 	}
@@ -319,21 +319,21 @@ static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
 		cs43130->mclk_int = freq_out;
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"unsupported pll output ref clock: %u\n", freq_out);
 		return -EINVAL;
 	}
 
-	ret = cs43130_pll_config(codec);
-	dev_dbg(codec->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass);
+	ret = cs43130_pll_config(component);
+	dev_dbg(component->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass);
 	return ret;
 }
 
-static int cs43130_change_clksrc(struct snd_soc_codec *codec,
+static int cs43130_change_clksrc(struct snd_soc_component *component,
 				 enum cs43130_mclk_src_sel src)
 {
 	int ret;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 	int mclk_int_decoded;
 
 	if (src == cs43130->mclk_int_src) {
@@ -349,7 +349,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
 		mclk_int_decoded = CS43130_MCLK_24P5;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int);
+		dev_err(component->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int);
 		return -EINVAL;
 	}
 
@@ -373,7 +373,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
 					   CS43130_XTAL_RDY_INT_MASK,
 					   1 << CS43130_XTAL_RDY_INT_SHIFT);
 			if (ret == 0) {
-				dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n");
+				dev_err(component->dev, "Timeout waiting for XTAL_READY interrupt\n");
 				return -ETIMEDOUT;
 			}
 		}
@@ -409,7 +409,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
 					   CS43130_XTAL_RDY_INT_MASK,
 					   1 << CS43130_XTAL_RDY_INT_SHIFT);
 			if (ret == 0) {
-				dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n");
+				dev_err(component->dev, "Timeout waiting for XTAL_READY interrupt\n");
 				return -ETIMEDOUT;
 			}
 		}
@@ -425,7 +425,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
 				   CS43130_PLL_RDY_INT_MASK,
 				   1 << CS43130_PLL_RDY_INT_SHIFT);
 		if (ret == 0) {
-			dev_err(codec->dev, "Timeout waiting for PLL_READY interrupt\n");
+			dev_err(component->dev, "Timeout waiting for PLL_READY interrupt\n");
 			return -ETIMEDOUT;
 		}
 
@@ -456,7 +456,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
 				   1 << CS43130_PDN_PLL_SHIFT);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid MCLK source value\n");
+		dev_err(component->dev, "Invalid MCLK source value\n");
 		return -EINVAL;
 	}
 
@@ -774,8 +774,8 @@ static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 	unsigned int required_clk;
 	u8 dsd_speed;
 
@@ -787,11 +787,11 @@ static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
 		else
 			required_clk = CS43130_MCLK_24M;
 
-		cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk);
+		cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);
 		if (cs43130->pll_bypass)
-			cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+			cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
 		else
-			cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+			cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
 	}
 
 	cs43130->clk_req++;
@@ -807,7 +807,7 @@ static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
 		dsd_speed = 1;
 		break;
 	default:
-		dev_err(codec->dev, "Rate(%u) not supported\n",
+		dev_err(component->dev, "Rate(%u) not supported\n",
 			params_rate(params));
 		return -EINVAL;
 	}
@@ -833,8 +833,8 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 	const struct cs43130_rate_map *rate_map;
 	unsigned int sclk = cs43130->dais[dai->id].sclk;
 	unsigned int bitwidth_sclk;
@@ -850,11 +850,11 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
 		else
 			required_clk = CS43130_MCLK_24M;
 
-		cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk);
+		cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);
 		if (cs43130->pll_bypass)
-			cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+			cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
 		else
-			cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+			cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
 	}
 
 	cs43130->clk_req++;
@@ -878,7 +878,7 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
 			dsd_speed = 1;
 			break;
 		default:
-			dev_err(codec->dev, "Rate(%u) not supported\n",
+			dev_err(component->dev, "Rate(%u) not supported\n",
 				params_rate(params));
 			return -EINVAL;
 		}
@@ -895,7 +895,7 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
 		regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI (%d)\n", dai->id);
+		dev_err(component->dev, "Invalid DAI (%d)\n", dai->id);
 		return -EINVAL;
 	}
 
@@ -919,21 +919,21 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
 
 	if (!sclk) {
 		/* at this point, SCLK must be set */
-		dev_err(codec->dev, "SCLK freq is not set\n");
+		dev_err(component->dev, "SCLK freq is not set\n");
 		return -EINVAL;
 	}
 
 	bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params);
 	if (bitwidth_sclk < bitwidth_dai) {
-		dev_err(codec->dev, "Format not supported: SCLK freq is too low\n");
+		dev_err(component->dev, "Format not supported: SCLK freq is too low\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev,
+	dev_dbg(component->dev,
 		"sclk = %u, fs = %d, bitwidth_dai = %u\n",
 		sclk, params_rate(params), bitwidth_dai);
 
-	dev_dbg(codec->dev,
+	dev_dbg(component->dev,
 		"bitwidth_sclk = %u, num_ch = %u\n",
 		bitwidth_sclk, params_channels(params));
 
@@ -946,14 +946,14 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
 static int cs43130_hw_free(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	mutex_lock(&cs43130->clk_mutex);
 	cs43130->clk_req--;
 	if (!cs43130->clk_req) {
 		/* no DAI is currently using clk */
-		cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO);
+		cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);
 		cs43130_pcm_dsd_mix(false, cs43130->regmap);
 	}
 	mutex_unlock(&cs43130->clk_mutex);
@@ -1023,8 +1023,8 @@ static int cs43130_pcm_ch_put(struct snd_kcontrol *kcontrol,
 {
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int *item = ucontrol->value.enumerated.item;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (item[0] >= e->items)
@@ -1144,8 +1144,8 @@ static const struct reg_sequence unmute_seq[] = {
 static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -1192,7 +1192,7 @@ static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
 		}
 		break;
 	default:
-		dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid event = 0x%x\n", event);
 		return -EINVAL;
 	}
 	return 0;
@@ -1201,8 +1201,8 @@ static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
 static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -1249,7 +1249,7 @@ static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
 		}
 		break;
 	default:
-		dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid event = 0x%x\n", event);
 		return -EINVAL;
 	}
 	return 0;
@@ -1270,8 +1270,8 @@ static const struct reg_sequence dac_postpmd_seq[] = {
 static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -1325,7 +1325,7 @@ static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
 		}
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAC event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid DAC event = 0x%x\n", event);
 		return -EINVAL;
 	}
 	return 0;
@@ -1350,8 +1350,8 @@ static const struct reg_sequence hpin_postpmu_seq[] = {
 static int cs43130_hpin_event(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMD:
@@ -1363,7 +1363,7 @@ static int cs43130_hpin_event(struct snd_soc_dapm_widget *w,
 				       ARRAY_SIZE(hpin_postpmu_seq));
 		break;
 	default:
-		dev_err(codec->dev, "Invalid HPIN event = 0x%x\n", event);
+		dev_err(component->dev, "Invalid HPIN event = 0x%x\n", event);
 		return -EINVAL;
 	}
 	return 0;
@@ -1471,8 +1471,8 @@ static int cs43130_dop_startup(struct snd_pcm_substream *substream,
 
 static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
@@ -1482,7 +1482,7 @@ static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported mode\n");
+		dev_err(component->dev, "unsupported mode\n");
 		return -EINVAL;
 	}
 
@@ -1500,12 +1500,12 @@ static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_B;
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"unsupported audio format\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "dai_id = %d,  dai_mode = %u, dai_format = %u\n",
+	dev_dbg(component->dev, "dai_id = %d,  dai_mode = %u, dai_format = %u\n",
 		codec_dai->id,
 		cs43130->dais[codec_dai->id].dai_mode,
 		cs43130->dais[codec_dai->id].dai_format);
@@ -1515,8 +1515,8 @@ static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
@@ -1526,11 +1526,11 @@ static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported DAI format.\n");
+		dev_err(component->dev, "Unsupported DAI format.\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "dai_mode = 0x%x\n",
+	dev_dbg(component->dev, "dai_mode = 0x%x\n",
 		cs43130->dais[codec_dai->id].dai_mode);
 
 	return 0;
@@ -1539,11 +1539,11 @@ static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai,
 				  int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
 	cs43130->dais[codec_dai->id].sclk = freq;
-	dev_dbg(codec->dev, "dai_id = %d,  sclk = %u\n", codec_dai->id,
+	dev_dbg(component->dev, "dai_id = %d,  sclk = %u\n", codec_dai->id,
 		cs43130->dais[codec_dai->id].sclk);
 
 	return 0;
@@ -1627,13 +1627,13 @@ static struct snd_soc_dai_driver cs43130_dai[] = {
 
 };
 
-static int cs43130_codec_set_sysclk(struct snd_soc_codec *codec,
+static int cs43130_component_set_sysclk(struct snd_soc_component *component,
 				    int clk_id, int source, unsigned int freq,
 				    int dir)
 {
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",
+	dev_dbg(component->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",
 		clk_id, source, freq, dir);
 
 	switch (freq) {
@@ -1642,14 +1642,14 @@ static int cs43130_codec_set_sysclk(struct snd_soc_codec *codec,
 		cs43130->mclk = freq;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", freq);
+		dev_err(component->dev, "Invalid MCLK INT freq: %u\n", freq);
 		return -EINVAL;
 	}
 
 	if (source == CS43130_MCLK_SRC_EXT) {
 		cs43130->pll_bypass = true;
 	} else {
-		dev_err(codec->dev, "Invalid MCLK source\n");
+		dev_err(component->dev, "Invalid MCLK source\n");
 		return -EINVAL;
 	}
 
@@ -1929,7 +1929,7 @@ static int cs43130_update_hpload(unsigned int msk, int ac_idx,
 	unsigned int reg;
 	u32 addr;
 	u16 impedance;
-	struct snd_soc_codec *codec = cs43130->codec;
+	struct snd_soc_component *component = cs43130->component;
 
 	switch (msk) {
 	case CS43130_HPLOAD_DC_INT:
@@ -1959,7 +1959,7 @@ static int cs43130_update_hpload(unsigned int msk, int ac_idx,
 		else
 			cs43130->hpload_dc[HP_RIGHT] = impedance;
 
-		dev_dbg(codec->dev, "HP DC impedance (Ch %u): %u\n", !left_ch,
+		dev_dbg(component->dev, "HP DC impedance (Ch %u): %u\n", !left_ch,
 			impedance);
 	} else {
 		if (left_ch)
@@ -1967,7 +1967,7 @@ static int cs43130_update_hpload(unsigned int msk, int ac_idx,
 		else
 			cs43130->hpload_ac[ac_idx][HP_RIGHT] = impedance;
 
-		dev_dbg(codec->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n",
+		dev_dbg(component->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n",
 			cs43130->ac_freq[ac_idx], !left_ch, impedance);
 	}
 
@@ -1981,7 +1981,7 @@ static int cs43130_hpload_proc(struct cs43130_private *cs43130,
 	int ret;
 	unsigned int msk;
 	u16 ac_reg_val;
-	struct snd_soc_codec *codec = cs43130->codec;
+	struct snd_soc_component *component = cs43130->component;
 
 	reinit_completion(&cs43130->hpload_evt);
 
@@ -2004,17 +2004,17 @@ static int cs43130_hpload_proc(struct cs43130_private *cs43130,
 					  msecs_to_jiffies(1000));
 	regmap_read(cs43130->regmap, CS43130_INT_MASK_4, &msk);
 	if (!ret) {
-		dev_err(codec->dev, "Timeout waiting for HPLOAD interrupt\n");
+		dev_err(component->dev, "Timeout waiting for HPLOAD interrupt\n");
 		return -1;
 	}
 
-	dev_dbg(codec->dev, "HP load stat: %x, INT_MASK_4: %x\n",
+	dev_dbg(component->dev, "HP load stat: %x, INT_MASK_4: %x\n",
 		cs43130->hpload_stat, msk);
 	if ((cs43130->hpload_stat & (CS43130_HPLOAD_NO_DC_INT |
 				     CS43130_HPLOAD_UNPLUG_INT |
 				     CS43130_HPLOAD_OOR_INT)) ||
 	    !(cs43130->hpload_stat & rslt_msk)) {
-		dev_dbg(codec->dev, "HP load measure failed\n");
+		dev_dbg(component->dev, "HP load measure failed\n");
 		return -1;
 	}
 
@@ -2056,11 +2056,11 @@ static void cs43130_imp_meas(struct work_struct *wk)
 	unsigned int reg, seq_size;
 	int i, ret, ac_idx;
 	struct cs43130_private *cs43130;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct reg_sequences *hpload_seq;
 
 	cs43130 = container_of(wk, struct cs43130_private, work);
-	codec = cs43130->codec;
+	component = cs43130->component;
 
 	if (!cs43130->mclk)
 		return;
@@ -2070,11 +2070,11 @@ static void cs43130_imp_meas(struct work_struct *wk)
 	mutex_lock(&cs43130->clk_mutex);
 	if (!cs43130->clk_req) {
 		/* clk not in use */
-		cs43130_set_pll(codec, 0, 0, cs43130->mclk, CS43130_MCLK_22M);
+		cs43130_set_pll(component, 0, 0, cs43130->mclk, CS43130_MCLK_22M);
 		if (cs43130->pll_bypass)
-			cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+			cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
 		else
-			cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+			cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
 	}
 
 	cs43130->clk_req++;
@@ -2125,9 +2125,9 @@ static void cs43130_imp_meas(struct work_struct *wk)
 		snd_soc_jack_report(&cs43130->jack, CS43130_JACK_HEADPHONE,
 				    CS43130_JACK_MASK);
 
-	dev_dbg(codec->dev, "Set HP output control. DC threshold\n");
+	dev_dbg(component->dev, "Set HP output control. DC threshold\n");
 	for (i = 0; i < CS43130_DC_THRESHOLD; i++)
-		dev_dbg(codec->dev, "DC threshold[%d]: %u.\n", i,
+		dev_dbg(component->dev, "DC threshold[%d]: %u.\n", i,
 			cs43130->dc_threshold[i]);
 
 	cs43130_set_hv(cs43130->regmap, cs43130->hpload_dc[HP_LEFT],
@@ -2154,14 +2154,14 @@ static void cs43130_imp_meas(struct work_struct *wk)
 	cs43130->clk_req--;
 	/* clk not in use */
 	if (!cs43130->clk_req)
-		cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO);
+		cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);
 	mutex_unlock(&cs43130->clk_mutex);
 }
 
 static irqreturn_t cs43130_irq_thread(int irq, void *data)
 {
 	struct cs43130_private *cs43130 = (struct cs43130_private *)data;
-	struct snd_soc_codec *codec = cs43130->codec;
+	struct snd_soc_component *component = cs43130->component;
 	unsigned int stickies[CS43130_NUM_INT];
 	unsigned int irq_occurrence = 0;
 	unsigned int masks[CS43130_NUM_INT];
@@ -2179,7 +2179,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 		for (j = 0; j < 8; j++)
 			irq_occurrence += (stickies[i] >> j) & 1;
 	}
-	dev_dbg(codec->dev, "number of interrupts occurred (%u)\n",
+	dev_dbg(component->dev, "number of interrupts occurred (%u)\n",
 		irq_occurrence);
 
 	if (!irq_occurrence)
@@ -2197,7 +2197,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
 	if (stickies[3] & CS43130_HPLOAD_NO_DC_INT) {
 		cs43130->hpload_stat = stickies[3];
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"DC load has not completed before AC load (%x)\n",
 			cs43130->hpload_stat);
 		complete(&cs43130->hpload_evt);
@@ -2206,7 +2206,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
 	if (stickies[3] & CS43130_HPLOAD_UNPLUG_INT) {
 		cs43130->hpload_stat = stickies[3];
-		dev_err(codec->dev, "HP unplugged during measurement (%x)\n",
+		dev_err(component->dev, "HP unplugged during measurement (%x)\n",
 			cs43130->hpload_stat);
 		complete(&cs43130->hpload_evt);
 		return IRQ_HANDLED;
@@ -2214,7 +2214,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
 	if (stickies[3] & CS43130_HPLOAD_OOR_INT) {
 		cs43130->hpload_stat = stickies[3];
-		dev_err(codec->dev, "HP load out of range (%x)\n",
+		dev_err(component->dev, "HP load out of range (%x)\n",
 			cs43130->hpload_stat);
 		complete(&cs43130->hpload_evt);
 		return IRQ_HANDLED;
@@ -2222,7 +2222,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
 	if (stickies[3] & CS43130_HPLOAD_AC_INT) {
 		cs43130->hpload_stat = stickies[3];
-		dev_dbg(codec->dev, "HP AC load measurement done (%x)\n",
+		dev_dbg(component->dev, "HP AC load measurement done (%x)\n",
 			cs43130->hpload_stat);
 		complete(&cs43130->hpload_evt);
 		return IRQ_HANDLED;
@@ -2230,7 +2230,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
 	if (stickies[3] & CS43130_HPLOAD_DC_INT) {
 		cs43130->hpload_stat = stickies[3];
-		dev_dbg(codec->dev, "HP DC load measurement done (%x)\n",
+		dev_dbg(component->dev, "HP DC load measurement done (%x)\n",
 			cs43130->hpload_stat);
 		complete(&cs43130->hpload_evt);
 		return IRQ_HANDLED;
@@ -2238,7 +2238,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
 	if (stickies[3] & CS43130_HPLOAD_ON_INT) {
 		cs43130->hpload_stat = stickies[3];
-		dev_dbg(codec->dev, "HP load state machine on done (%x)\n",
+		dev_dbg(component->dev, "HP load state machine on done (%x)\n",
 			cs43130->hpload_stat);
 		complete(&cs43130->hpload_evt);
 		return IRQ_HANDLED;
@@ -2246,19 +2246,19 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
 	if (stickies[3] & CS43130_HPLOAD_OFF_INT) {
 		cs43130->hpload_stat = stickies[3];
-		dev_dbg(codec->dev, "HP load state machine off done (%x)\n",
+		dev_dbg(component->dev, "HP load state machine off done (%x)\n",
 			cs43130->hpload_stat);
 		complete(&cs43130->hpload_evt);
 		return IRQ_HANDLED;
 	}
 
 	if (stickies[0] & CS43130_XTAL_ERR_INT) {
-		dev_err(codec->dev, "Crystal err: clock is not running\n");
+		dev_err(component->dev, "Crystal err: clock is not running\n");
 		return IRQ_HANDLED;
 	}
 
 	if (stickies[0] & CS43130_HP_UNPLUG_INT) {
-		dev_dbg(codec->dev, "HP unplugged\n");
+		dev_dbg(component->dev, "HP unplugged\n");
 		cs43130->hpload_done = false;
 		snd_soc_jack_report(&cs43130->jack, 0, CS43130_JACK_MASK);
 		return IRQ_HANDLED;
@@ -2267,7 +2267,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 	if (stickies[0] & CS43130_HP_PLUG_INT) {
 		if (cs43130->dc_meas && !cs43130->hpload_done &&
 		    !work_busy(&cs43130->work)) {
-			dev_dbg(codec->dev, "HP load queue work\n");
+			dev_dbg(component->dev, "HP load queue work\n");
 			queue_work(cs43130->wq, &cs43130->work);
 		}
 
@@ -2279,14 +2279,14 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 	return IRQ_NONE;
 }
 
-static int cs43130_probe(struct snd_soc_codec *codec)
+static int cs43130_probe(struct snd_soc_component *component)
 {
 	int ret;
-	struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_card *card = codec->component.card;
+	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_card *card = component->card;
 	unsigned int reg;
 
-	cs43130->codec = codec;
+	cs43130->component = component;
 
 	if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) {
 		regmap_update_bits(cs43130->regmap, CS43130_CRYSTAL_SET,
@@ -2299,25 +2299,25 @@ static int cs43130_probe(struct snd_soc_codec *codec)
 	ret = snd_soc_card_jack_new(card, "Headphone", CS43130_JACK_MASK,
 				    &cs43130->jack, NULL, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Cannot create jack\n");
+		dev_err(component->dev, "Cannot create jack\n");
 		return ret;
 	}
 
 	cs43130->hpload_done = false;
 	if (cs43130->dc_meas) {
-		ret = device_create_file(codec->dev, &dev_attr_hpload_dc_l);
+		ret = device_create_file(component->dev, &dev_attr_hpload_dc_l);
 		if (ret < 0)
 			return ret;
 
-		ret = device_create_file(codec->dev, &dev_attr_hpload_dc_r);
+		ret = device_create_file(component->dev, &dev_attr_hpload_dc_r);
 		if (ret < 0)
 			return ret;
 
-		ret = device_create_file(codec->dev, &dev_attr_hpload_ac_l);
+		ret = device_create_file(component->dev, &dev_attr_hpload_ac_l);
 		if (ret < 0)
 			return ret;
 
-		ret = device_create_file(codec->dev, &dev_attr_hpload_ac_r);
+		ret = device_create_file(component->dev, &dev_attr_hpload_ac_r);
 		if (ret < 0)
 			return ret;
 
@@ -2338,14 +2338,16 @@ static int cs43130_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_cs43130 = {
+static struct snd_soc_component_driver soc_component_dev_cs43130 = {
 	.probe			= cs43130_probe,
-	.component_driver = {
-		.controls		= cs43130_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs43130_snd_controls),
-	},
-	.set_sysclk		= cs43130_codec_set_sysclk,
+	.controls		= cs43130_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs43130_snd_controls),
+	.set_sysclk		= cs43130_component_set_sysclk,
 	.set_pll		= cs43130_set_pll,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config cs43130_regmap = {
@@ -2536,33 +2538,34 @@ static int cs43130_i2c_probe(struct i2c_client *client,
 		memcpy(all_hp_routes + ARRAY_SIZE(digital_hp_routes),
 		       analog_hp_routes, sizeof(analog_hp_routes));
 
-		soc_codec_dev_cs43130.component_driver.dapm_widgets =
+		soc_component_dev_cs43130.dapm_widgets =
 			all_hp_widgets;
-		soc_codec_dev_cs43130.component_driver.num_dapm_widgets =
+		soc_component_dev_cs43130.num_dapm_widgets =
 			ARRAY_SIZE(all_hp_widgets);
-		soc_codec_dev_cs43130.component_driver.dapm_routes =
+		soc_component_dev_cs43130.dapm_routes =
 			all_hp_routes;
-		soc_codec_dev_cs43130.component_driver.num_dapm_routes =
+		soc_component_dev_cs43130.num_dapm_routes =
 			ARRAY_SIZE(all_hp_routes);
 		break;
 	case CS43198_CHIP_ID:
 	case CS4399_CHIP_ID:
-		soc_codec_dev_cs43130.component_driver.dapm_widgets =
+		soc_component_dev_cs43130.dapm_widgets =
 			digital_hp_widgets;
-		soc_codec_dev_cs43130.component_driver.num_dapm_widgets =
+		soc_component_dev_cs43130.num_dapm_widgets =
 			ARRAY_SIZE(digital_hp_widgets);
-		soc_codec_dev_cs43130.component_driver.dapm_routes =
+		soc_component_dev_cs43130.dapm_routes =
 			digital_hp_routes;
-		soc_codec_dev_cs43130.component_driver.num_dapm_routes =
+		soc_component_dev_cs43130.num_dapm_routes =
 			ARRAY_SIZE(digital_hp_routes);
 		break;
 	}
 
-	ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_cs43130,
+	ret = devm_snd_soc_register_component(&client->dev,
+				     &soc_component_dev_cs43130,
 				     cs43130_dai, ARRAY_SIZE(cs43130_dai));
 	if (ret < 0) {
 		dev_err(&client->dev,
-			"snd_soc_register_codec failed with ret = %d\n", ret);
+			"snd_soc_register_component failed with ret = %d\n", ret);
 		goto err;
 	}
 
@@ -2604,8 +2607,6 @@ static int cs43130_i2c_remove(struct i2c_client *client)
 	pm_runtime_disable(&client->dev);
 	regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
 
-	snd_soc_unregister_codec(&client->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h
index 7812584..c3c6eef 100644
--- a/sound/soc/codecs/cs43130.h
+++ b/sound/soc/codecs/cs43130.h
@@ -508,7 +508,7 @@ struct cs43130_dai {
 };
 
 struct	cs43130_private {
-	struct snd_soc_codec		*codec;
+	struct snd_soc_component	*component;
 	struct regmap			*regmap;
 	struct regulator_bulk_data	supplies[CS43130_NUM_SUPPLIES];
 	struct gpio_desc		*reset_gpio;
diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c
index 0a749c7..bee0e34 100644
--- a/sound/soc/codecs/cs4349.c
+++ b/sound/soc/codecs/cs4349.c
@@ -74,8 +74,8 @@ static bool cs4349_writeable_register(struct device *dev, unsigned int reg)
 static int cs4349_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct cs4349_private *cs4349 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct cs4349_private *cs4349 = snd_soc_component_get_drvdata(component);
 	unsigned int fmt;
 
 	fmt = format & SND_SOC_DAIFMT_FORMAT_MASK;
@@ -97,8 +97,8 @@ static int cs4349_pcm_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct cs4349_private *cs4349 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct cs4349_private *cs4349 = snd_soc_component_get_drvdata(component);
 	int fmt, ret;
 
 	cs4349->rate = params_rate(params);
@@ -126,7 +126,7 @@ static int cs4349_pcm_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	ret = snd_soc_update_bits(codec, CS4349_MODE, DIF_MASK,
+	ret = snd_soc_component_update_bits(component, CS4349_MODE, DIF_MASK,
 				  MODE_FORMAT(fmt));
 	if (ret < 0)
 		return ret;
@@ -136,14 +136,14 @@ static int cs4349_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int cs4349_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int reg;
 
 	reg = 0;
 	if (mute)
 		reg = MUTE_AB_MASK;
 
-	return snd_soc_update_bits(codec, CS4349_MUTE, MUTE_AB_MASK, reg);
+	return snd_soc_component_update_bits(component, CS4349_MUTE, MUTE_AB_MASK, reg);
 }
 
 static DECLARE_TLV_DB_SCALE(dig_tlv, -12750, 50, 0);
@@ -255,15 +255,17 @@ static struct snd_soc_dai_driver cs4349_dai = {
 	.symmetric_rates = 1,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs4349 = {
-	.component_driver = {
-		.controls		= cs4349_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs4349_snd_controls),
-		.dapm_widgets		= cs4349_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs4349_dapm_widgets),
-		.dapm_routes		= cs4349_routes,
-		.num_dapm_routes	= ARRAY_SIZE(cs4349_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_cs4349 = {
+	.controls		= cs4349_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs4349_snd_controls),
+	.dapm_widgets		= cs4349_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs4349_dapm_widgets),
+	.dapm_routes		= cs4349_routes,
+	.num_dapm_routes	= ARRAY_SIZE(cs4349_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config cs4349_regmap = {
@@ -305,7 +307,8 @@ static int cs4349_i2c_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, cs4349);
 
-	return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4349,
+	return devm_snd_soc_register_component(&client->dev,
+		&soc_component_dev_cs4349,
 		&cs4349_dai, 1);
 }
 
@@ -313,8 +316,6 @@ static int cs4349_i2c_remove(struct i2c_client *client)
 {
 	struct cs4349_private *cs4349 = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
-
 	/* Hold down reset */
 	gpiod_set_value_cansleep(cs4349->reset_gpio, 0);
 
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index be27506..196e9c3 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -33,6 +33,8 @@
 #include "wm_adsp.h"
 #include "cs47l24.h"
 
+#define DRV_NAME "cs47l24-codec"
+
 struct cs47l24_priv {
 	struct arizona_priv core;
 	struct arizona_fll fll[2];
@@ -60,14 +62,14 @@ static const struct wm_adsp_region *cs47l24_dsp_regions[] = {
 static int cs47l24_adsp_power_ev(struct snd_soc_dapm_widget *w,
 				 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	unsigned int v;
 	int ret;
 
 	ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to read SYSCLK state: %d\n", ret);
+		dev_err(component->dev, "Failed to read SYSCLK state: %d\n", ret);
 		return ret;
 	}
 
@@ -194,14 +196,13 @@ SOC_SINGLE("HPOUT1 SC Protect Switch", ARIZONA_HP1_SHORT_CIRCUIT_CTRL,
 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
 	     ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
 SOC_SINGLE("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
-	     ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
+	   ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
 
 SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
 		 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
 		 0xbf, 0, digital_tlv),
 SOC_SINGLE_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
-		 ARIZONA_OUT4L_VOL_SHIFT,
-		 0xbf, 0, digital_tlv),
+	       ARIZONA_OUT4L_VOL_SHIFT, 0xbf, 0, digital_tlv),
 
 SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
 SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
@@ -492,8 +493,7 @@ SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3,
 		 ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-		       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-		       &cs47l24_aec_loopback_mux),
+		 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &cs47l24_aec_loopback_mux),
 
 SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
 		     ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
@@ -929,10 +929,10 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
 	{ "DSP3 Voice Trigger", "Switch", "DSP3" },
 };
 
-static int cs47l24_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-			  unsigned int Fref, unsigned int Fout)
+static int cs47l24_set_fll(struct snd_soc_component *component, int fll_id,
+			   int source, unsigned int Fref, unsigned int Fout)
 {
-	struct cs47l24_priv *cs47l24 = snd_soc_codec_get_drvdata(codec);
+	struct cs47l24_priv *cs47l24 = snd_soc_component_get_drvdata(component);
 
 	switch (fll_id) {
 	case CS47L24_FLL1:
@@ -1069,7 +1069,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = {
 static int cs47l24_open(struct snd_compr_stream *stream)
 {
 	struct snd_soc_pcm_runtime *rtd = stream->private_data;
-	struct cs47l24_priv *priv = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->core.arizona;
 	int n_adsp;
 
@@ -1115,34 +1116,34 @@ static irqreturn_t cs47l24_adsp2_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static int cs47l24_codec_probe(struct snd_soc_codec *codec)
+static int cs47l24_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-	struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->core.arizona;
 	int ret;
 
 	arizona->dapm = dapm;
-	snd_soc_codec_init_regmap(codec, arizona->regmap);
+	snd_soc_component_init_regmap(component, arizona->regmap);
 
-	ret = arizona_init_spk(codec);
+	ret = arizona_init_spk(component);
 	if (ret < 0)
 		return ret;
 
-	arizona_init_gpio(codec);
-	arizona_init_mono(codec);
+	arizona_init_gpio(component);
+	arizona_init_mono(component);
 
-	ret = wm_adsp2_codec_probe(&priv->core.adsp[1], codec);
+	ret = wm_adsp2_component_probe(&priv->core.adsp[1], component);
 	if (ret)
 		goto err_adsp2_codec_probe;
 
-	ret = wm_adsp2_codec_probe(&priv->core.adsp[2], codec);
+	ret = wm_adsp2_component_probe(&priv->core.adsp[2], component);
 	if (ret)
 		goto err_adsp2_codec_probe;
 
-	ret = snd_soc_add_codec_controls(codec,
-					 &arizona_adsp2_rate_controls[1], 2);
+	ret = snd_soc_add_component_controls(component,
+					     &arizona_adsp2_rate_controls[1],
+					     2);
 	if (ret)
 		goto err_adsp2_codec_probe;
 
@@ -1151,22 +1152,20 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 
 err_adsp2_codec_probe:
-	wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
-	wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
+	wm_adsp2_component_remove(&priv->core.adsp[1], component);
+	wm_adsp2_component_remove(&priv->core.adsp[2], component);
 
 	return ret;
 }
 
-static int cs47l24_codec_remove(struct snd_soc_codec *codec)
+static void cs47l24_component_remove(struct snd_soc_component *component)
 {
-	struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
 
-	wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
-	wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
+	wm_adsp2_component_remove(&priv->core.adsp[1], component);
+	wm_adsp2_component_remove(&priv->core.adsp[2], component);
 
 	priv->core.arizona->dapm = NULL;
-
-	return 0;
 }
 
 #define CS47L24_DIG_VU 0x0200
@@ -1177,37 +1176,32 @@ static unsigned int cs47l24_digital_vu[] = {
 	ARIZONA_DAC_DIGITAL_VOLUME_4L,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
-	.probe = cs47l24_codec_probe,
-	.remove = cs47l24_codec_remove,
-
-	.idle_bias_off = true,
-
-	.set_sysclk = arizona_set_sysclk,
-	.set_pll = cs47l24_set_fll,
-
-	.component_driver = {
-		.controls		= cs47l24_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs47l24_snd_controls),
-		.dapm_widgets		= cs47l24_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs47l24_dapm_widgets),
-		.dapm_routes		= cs47l24_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(cs47l24_dapm_routes),
-	},
+static struct snd_compr_ops cs47l24_compr_ops = {
+	.open		= cs47l24_open,
+	.free		= wm_adsp_compr_free,
+	.set_params	= wm_adsp_compr_set_params,
+	.get_caps	= wm_adsp_compr_get_caps,
+	.trigger	= wm_adsp_compr_trigger,
+	.pointer	= wm_adsp_compr_pointer,
+	.copy		= wm_adsp_compr_copy,
 };
 
-static const struct snd_compr_ops cs47l24_compr_ops = {
-	.open = cs47l24_open,
-	.free = wm_adsp_compr_free,
-	.set_params = wm_adsp_compr_set_params,
-	.get_caps = wm_adsp_compr_get_caps,
-	.trigger = wm_adsp_compr_trigger,
-	.pointer = wm_adsp_compr_pointer,
-	.copy = wm_adsp_compr_copy,
-};
-
-static const struct snd_soc_platform_driver cs47l24_compr_platform = {
-	.compr_ops = &cs47l24_compr_ops,
+static const struct snd_soc_component_driver soc_component_dev_cs47l24 = {
+	.probe			= cs47l24_component_probe,
+	.remove			= cs47l24_component_remove,
+	.set_sysclk		= arizona_set_sysclk,
+	.set_pll		= cs47l24_set_fll,
+	.name			= DRV_NAME,
+	.compr_ops		= &cs47l24_compr_ops,
+	.controls		= cs47l24_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs47l24_snd_controls),
+	.dapm_widgets		= cs47l24_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs47l24_dapm_widgets),
+	.dapm_routes		= cs47l24_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(cs47l24_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int cs47l24_probe(struct platform_device *pdev)
@@ -1219,7 +1213,7 @@ static int cs47l24_probe(struct platform_device *pdev)
 	BUILD_BUG_ON(ARRAY_SIZE(cs47l24_dai) > ARIZONA_MAX_DAI);
 
 	cs47l24 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l24_priv),
-			      GFP_KERNEL);
+			       GFP_KERNEL);
 	if (!cs47l24)
 		return -ENOMEM;
 
@@ -1298,23 +1292,17 @@ static int cs47l24_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_dsp_irq;
 
-	ret = snd_soc_register_platform(&pdev->dev, &cs47l24_compr_platform);
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &soc_component_dev_cs47l24,
+					      cs47l24_dai,
+					      ARRAY_SIZE(cs47l24_dai));
 	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+		dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
 		goto err_spk_irqs;
 	}
 
-	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24,
-				      cs47l24_dai, ARRAY_SIZE(cs47l24_dai));
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
-		goto err_platform;
-	}
-
 	return ret;
 
-err_platform:
-	snd_soc_unregister_platform(&pdev->dev);
 err_spk_irqs:
 	arizona_free_spk_irqs(arizona);
 err_dsp_irq:
@@ -1328,8 +1316,6 @@ static int cs47l24_remove(struct platform_device *pdev)
 	struct cs47l24_priv *cs47l24 = platform_get_drvdata(pdev);
 	struct arizona *arizona = cs47l24->core.arizona;
 
-	snd_soc_unregister_platform(&pdev->dev);
-	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 	wm_adsp2_remove(&cs47l24->core.adsp[1]);
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
index c7edf2d..8995ea4 100644
--- a/sound/soc/codecs/cs53l30.c
+++ b/sound/soc/codecs/cs53l30.c
@@ -549,7 +549,7 @@ static int cs53l30_get_mclk_coeff(int mclk_rate, int srate)
 static int cs53l30_set_sysclk(struct snd_soc_dai *dai,
 			      int clk_id, unsigned int freq, int dir)
 {
-	struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
 	int mclkx_coeff;
 	u32 mclk_rate;
 
@@ -572,7 +572,7 @@ static int cs53l30_set_sysclk(struct snd_soc_dai *dai,
 
 static int cs53l30_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
 	u8 aspcfg = 0, aspctl1 = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -626,7 +626,7 @@ static int cs53l30_pcm_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
 	int srate = params_rate(params);
 	int mclk_coeff;
 
@@ -650,11 +650,11 @@ static int cs53l30_pcm_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static int cs53l30_set_bias_level(struct snd_soc_codec *codec,
+static int cs53l30_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct cs53l30_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct cs53l30_private *priv = snd_soc_component_get_drvdata(component);
 	unsigned int reg;
 	int i, inter_max_check, ret;
 
@@ -670,7 +670,7 @@ static int cs53l30_set_bias_level(struct snd_soc_codec *codec,
 		if (dapm->bias_level == SND_SOC_BIAS_OFF) {
 			ret = clk_prepare_enable(priv->mclk);
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"failed to enable MCLK: %d\n", ret);
 				return ret;
 			}
@@ -736,7 +736,7 @@ static int cs53l30_set_bias_level(struct snd_soc_codec *codec,
 
 static int cs53l30_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
 	u8 val = tristate ? CS53L30_ASP_3ST : 0;
 
 	return regmap_update_bits(priv->regmap, CS53L30_ASP_CTL1,
@@ -770,7 +770,7 @@ static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai,
 				    unsigned int tx_mask, unsigned int rx_mask,
 				    int slots, int slot_width)
 {
-	struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
 	unsigned int loc[CS53L30_TDM_SLOT_MAX] = {48, 48, 48, 48};
 	unsigned int slot_next, slot_step;
 	u64 tx_enable = 0;
@@ -840,7 +840,7 @@ static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai,
 
 static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-	struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
 
 	gpiod_set_value_cansleep(priv->mute_gpio, mute);
 
@@ -876,10 +876,10 @@ static struct snd_soc_dai_driver cs53l30_dai = {
 	.symmetric_rates = 1,
 };
 
-static int cs53l30_codec_probe(struct snd_soc_codec *codec)
+static int cs53l30_component_probe(struct snd_soc_component *component)
 {
-	struct cs53l30_private *priv = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct cs53l30_private *priv = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	if (priv->use_sdout2)
 		snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout2,
@@ -891,19 +891,18 @@ static int cs53l30_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver cs53l30_driver = {
-	.probe = cs53l30_codec_probe,
-	.set_bias_level = cs53l30_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= cs53l30_snd_controls,
-		.num_controls		= ARRAY_SIZE(cs53l30_snd_controls),
-		.dapm_widgets		= cs53l30_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cs53l30_dapm_widgets),
-		.dapm_routes		= cs53l30_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(cs53l30_dapm_routes),
-	},
+static const struct snd_soc_component_driver cs53l30_driver = {
+	.probe			= cs53l30_component_probe,
+	.set_bias_level		= cs53l30_set_bias_level,
+	.controls		= cs53l30_snd_controls,
+	.num_controls		= ARRAY_SIZE(cs53l30_snd_controls),
+	.dapm_widgets		= cs53l30_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cs53l30_dapm_widgets),
+	.dapm_routes		= cs53l30_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(cs53l30_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static struct regmap_config cs53l30_regmap = {
@@ -1033,9 +1032,9 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
 
 	dev_info(dev, "Cirrus Logic CS53L30, Revision: %02X\n", reg & 0xFF);
 
-	ret = snd_soc_register_codec(dev, &cs53l30_driver, &cs53l30_dai, 1);
+	ret = devm_snd_soc_register_component(dev, &cs53l30_driver, &cs53l30_dai, 1);
 	if (ret) {
-		dev_err(dev, "failed to register codec: %d\n", ret);
+		dev_err(dev, "failed to register component: %d\n", ret);
 		goto error;
 	}
 
@@ -1051,8 +1050,6 @@ static int cs53l30_i2c_remove(struct i2c_client *client)
 {
 	struct cs53l30_private *cs53l30 = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
-
 	/* Hold down reset */
 	gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
 
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 95bb10b..07dd33b0 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -89,10 +89,10 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
 	{"ADC", NULL, "Input Mixer"},
 };
 
-static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
+static unsigned int cx20442_read_reg_cache(struct snd_soc_component *component,
 					   unsigned int reg)
 {
-	struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+	struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component);
 
 	if (reg >= 1)
 		return -EINVAL;
@@ -153,10 +153,10 @@ static int cx20442_pm_to_v253_vsp(u8 value)
 	return (value & (1 << CX20442_AGC)) ? -EINVAL : 0;
 }
 
-static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
+static int cx20442_write(struct snd_soc_component *component, unsigned int reg,
 							unsigned int value)
 {
-	struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+	struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component);
 	int vls, vsp, old, len;
 	char buf[18];
 
@@ -193,7 +193,7 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
 	if (unlikely(len > (ARRAY_SIZE(buf) - 1)))
 		return -ENOMEM;
 
-	dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
+	dev_dbg(component->dev, "%s: %s\n", __func__, buf);
 	if (cx20442->tty->ops->write(cx20442->tty, buf, len) != len)
 		return -EIO;
 
@@ -240,19 +240,19 @@ static int v253_open(struct tty_struct *tty)
 /* Line discipline .close() */
 static void v253_close(struct tty_struct *tty)
 {
-	struct snd_soc_codec *codec = tty->disc_data;
+	struct snd_soc_component *component = tty->disc_data;
 	struct cx20442_priv *cx20442;
 
 	tty->disc_data = NULL;
 
-	if (!codec)
+	if (!component)
 		return;
 
-	cx20442 = snd_soc_codec_get_drvdata(codec);
+	cx20442 = snd_soc_component_get_drvdata(component);
 
 	/* Prevent the codec driver from further accessing the modem */
 	cx20442->tty = NULL;
-	codec->component.card->pop_time = 0;
+	component->card->pop_time = 0;
 }
 
 /* Line discipline .hangup() */
@@ -266,20 +266,20 @@ static int v253_hangup(struct tty_struct *tty)
 static void v253_receive(struct tty_struct *tty,
 				const unsigned char *cp, char *fp, int count)
 {
-	struct snd_soc_codec *codec = tty->disc_data;
+	struct snd_soc_component *component = tty->disc_data;
 	struct cx20442_priv *cx20442;
 
-	if (!codec)
+	if (!component)
 		return;
 
-	cx20442 = snd_soc_codec_get_drvdata(codec);
+	cx20442 = snd_soc_component_get_drvdata(component);
 
 	if (!cx20442->tty) {
 		/* First modem response, complete setup procedure */
 
 		/* Set up codec driver access to modem controls */
 		cx20442->tty = tty;
-		codec->component.card->pop_time = 1;
+		component->card->pop_time = 1;
 	}
 }
 
@@ -323,15 +323,15 @@ static struct snd_soc_dai_driver cx20442_dai = {
 	},
 };
 
-static int cx20442_set_bias_level(struct snd_soc_codec *codec,
+static int cx20442_set_bias_level(struct snd_soc_component *component,
 		enum snd_soc_bias_level level)
 {
-	struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+	struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component);
 	int err = 0;
 
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
-		if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_STANDBY)
+		if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_STANDBY)
 			break;
 		if (IS_ERR(cx20442->por))
 			err = PTR_ERR(cx20442->por);
@@ -339,7 +339,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
 			err = regulator_enable(cx20442->por);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_PREPARE)
+		if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_PREPARE)
 			break;
 		if (IS_ERR(cx20442->por))
 			err = PTR_ERR(cx20442->por);
@@ -353,7 +353,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
 	return err;
 }
 
-static int cx20442_codec_probe(struct snd_soc_codec *codec)
+static int cx20442_component_probe(struct snd_soc_component *component)
 {
 	struct cx20442_priv *cx20442;
 
@@ -361,21 +361,21 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
 	if (cx20442 == NULL)
 		return -ENOMEM;
 
-	cx20442->por = regulator_get(codec->dev, "POR");
+	cx20442->por = regulator_get(component->dev, "POR");
 	if (IS_ERR(cx20442->por))
-		dev_warn(codec->dev, "failed to get the regulator");
+		dev_warn(component->dev, "failed to get the regulator");
 	cx20442->tty = NULL;
 
-	snd_soc_codec_set_drvdata(codec, cx20442);
-	codec->component.card->pop_time = 0;
+	snd_soc_component_set_drvdata(component, cx20442);
+	component->card->pop_time = 0;
 
 	return 0;
 }
 
 /* power down chip */
-static int cx20442_codec_remove(struct snd_soc_codec *codec)
+static void cx20442_component_remove(struct snd_soc_component *component)
 {
-	struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+	struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component);
 
 	if (cx20442->tty) {
 		struct tty_struct *tty = cx20442->tty;
@@ -387,36 +387,30 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
 		regulator_put(cx20442->por);
 	}
 
-	snd_soc_codec_set_drvdata(codec, NULL);
+	snd_soc_component_set_drvdata(component, NULL);
 	kfree(cx20442);
-	return 0;
 }
 
-static const struct snd_soc_codec_driver cx20442_codec_dev = {
-	.probe = 	cx20442_codec_probe,
-	.remove = 	cx20442_codec_remove,
-	.set_bias_level = cx20442_set_bias_level,
-	.read = cx20442_read_reg_cache,
-	.write = cx20442_write,
-
-	.component_driver = {
-		.dapm_widgets		= cx20442_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(cx20442_dapm_widgets),
-		.dapm_routes		= cx20442_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(cx20442_audio_map),
-	},
+static const struct snd_soc_component_driver cx20442_component_dev = {
+	.probe			= cx20442_component_probe,
+	.remove			= cx20442_component_remove,
+	.set_bias_level		= cx20442_set_bias_level,
+	.read			= cx20442_read_reg_cache,
+	.write			= cx20442_write,
+	.dapm_widgets		= cx20442_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(cx20442_dapm_widgets),
+	.dapm_routes		= cx20442_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(cx20442_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int cx20442_platform_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&cx20442_codec_dev, &cx20442_dai, 1);
-}
-
-static int cx20442_platform_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&cx20442_component_dev, &cx20442_dai, 1);
 }
 
 static struct platform_driver cx20442_platform_driver = {
@@ -424,7 +418,6 @@ static struct platform_driver cx20442_platform_driver = {
 		.name = "cx20442-codec",
 		},
 	.probe = cx20442_platform_probe,
-	.remove = cx20442_platform_remove,
 };
 
 module_platform_driver(cx20442_platform_driver);
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 1af443c..a664111 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -331,12 +331,12 @@ static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel,
 static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 
 	if (ucontrol->value.integer.value[0]) {
 		/* Check if noise suppression is enabled */
-		if (snd_soc_read(codec, DA7210_CONTROL) & DA7210_NOISE_SUP_EN) {
-			dev_dbg(codec->dev,
+		if (snd_soc_component_read32(component, DA7210_CONTROL) & DA7210_NOISE_SUP_EN) {
+			dev_dbg(component->dev,
 				"Disable noise suppression to enable ALC\n");
 			return -EINVAL;
 		}
@@ -354,32 +354,32 @@ static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
 static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	u8 val;
 
 	if (ucontrol->value.integer.value[0]) {
 		/* Check if ALC is enabled */
-		if (snd_soc_read(codec, DA7210_ADC) & DA7210_ADC_ALC_EN)
+		if (snd_soc_component_read32(component, DA7210_ADC) & DA7210_ADC_ALC_EN)
 			goto err;
 
 		/* Check ZC for HP and AUX1 PGA */
-		if ((snd_soc_read(codec, DA7210_ZERO_CROSS) &
+		if ((snd_soc_component_read32(component, DA7210_ZERO_CROSS) &
 			(DA7210_AUX1_L_ZC | DA7210_AUX1_R_ZC | DA7210_HP_L_ZC |
 			DA7210_HP_R_ZC)) != (DA7210_AUX1_L_ZC |
 			DA7210_AUX1_R_ZC | DA7210_HP_L_ZC | DA7210_HP_R_ZC))
 			goto err;
 
 		/* Check INPGA_L_VOL and INPGA_R_VOL */
-		val = snd_soc_read(codec, DA7210_IN_GAIN);
+		val = snd_soc_component_read32(component, DA7210_IN_GAIN);
 		if (((val & DA7210_INPGA_L_VOL) < DA7210_INPGA_MIN_VOL_NS) ||
 			(((val & DA7210_INPGA_R_VOL) >> 4) <
 			DA7210_INPGA_MIN_VOL_NS))
 			goto err;
 
 		/* Check AUX1_L_VOL and AUX1_R_VOL */
-		if (((snd_soc_read(codec, DA7210_AUX1_L) & DA7210_AUX1_L_VOL) <
+		if (((snd_soc_component_read32(component, DA7210_AUX1_L) & DA7210_AUX1_L_VOL) <
 		    DA7210_AUX1_MIN_VOL_NS) ||
-		    ((snd_soc_read(codec, DA7210_AUX1_R) & DA7210_AUX1_R_VOL) <
+		    ((snd_soc_component_read32(component, DA7210_AUX1_R) & DA7210_AUX1_R_VOL) <
 		    DA7210_AUX1_MIN_VOL_NS))
 			goto err;
 	}
@@ -760,19 +760,19 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
 	u32 dai_cfg1;
 	u32 fs, sysclk;
 
 	/* set DAI source to Left and Right ADC */
-	snd_soc_write(codec, DA7210_DAI_SRC_SEL,
+	snd_soc_component_write(component, DA7210_DAI_SRC_SEL,
 		     DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
 
 	/* Enable DAI */
-	snd_soc_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
+	snd_soc_component_write(component, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
 
-	dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
+	dai_cfg1 = 0xFC & snd_soc_component_read32(component, DA7210_DAI_CFG1);
 
 	switch (params_width(params)) {
 	case 16:
@@ -791,7 +791,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
+	snd_soc_component_write(component, DA7210_DAI_CFG1, dai_cfg1);
 
 	switch (params_rate(params)) {
 	case 8000:
@@ -839,17 +839,17 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* Disable active mode */
-	snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
+	snd_soc_component_update_bits(component, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
 
-	snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
+	snd_soc_component_update_bits(component, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
 
 	if (da7210->mclk_rate && (da7210->mclk_rate != sysclk)) {
 		/* PLL mode, disable PLL bypass */
-		snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, 0);
+		snd_soc_component_update_bits(component, DA7210_PLL_DIV3, DA7210_PLL_BYP, 0);
 
 		if (!da7210->master) {
 			/* PLL slave mode, also enable SRM */
-			snd_soc_update_bits(codec, DA7210_PLL,
+			snd_soc_component_update_bits(component, DA7210_PLL,
 						   (DA7210_MCLK_SRM_EN |
 						    DA7210_MCLK_DET_EN),
 						   (DA7210_MCLK_SRM_EN |
@@ -857,13 +857,13 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
 		}
 	} else {
 		/* PLL bypass mode, enable PLL bypass and Auto Detection */
-		snd_soc_update_bits(codec, DA7210_PLL, DA7210_MCLK_DET_EN,
+		snd_soc_component_update_bits(component, DA7210_PLL, DA7210_MCLK_DET_EN,
 						       DA7210_MCLK_DET_EN);
-		snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP,
+		snd_soc_component_update_bits(component, DA7210_PLL_DIV3, DA7210_PLL_BYP,
 							    DA7210_PLL_BYP);
 	}
 	/* Enable active mode */
-	snd_soc_update_bits(codec, DA7210_STARTUP1,
+	snd_soc_component_update_bits(component, DA7210_STARTUP1,
 			    DA7210_SC_MST_EN, DA7210_SC_MST_EN);
 
 	return 0;
@@ -874,16 +874,16 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
  */
 static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
 	u32 dai_cfg1;
 	u32 dai_cfg3;
 
-	dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
-	dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
+	dai_cfg1 = 0x7f & snd_soc_component_read32(component, DA7210_DAI_CFG1);
+	dai_cfg3 = 0xfc & snd_soc_component_read32(component, DA7210_DAI_CFG3);
 
-	if ((snd_soc_read(codec, DA7210_PLL) & DA7210_PLL_EN) &&
-		(!(snd_soc_read(codec, DA7210_PLL_DIV3) & DA7210_PLL_BYP)))
+	if ((snd_soc_component_read32(component, DA7210_PLL) & DA7210_PLL_EN) &&
+		(!(snd_soc_component_read32(component, DA7210_PLL_DIV3) & DA7210_PLL_BYP)))
 		return -EINVAL;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -923,21 +923,21 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
 	 */
 	dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
 
-	snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
-	snd_soc_write(codec, DA7210_DAI_CFG3, dai_cfg3);
+	snd_soc_component_write(component, DA7210_DAI_CFG1, dai_cfg1);
+	snd_soc_component_write(component, DA7210_DAI_CFG3, dai_cfg3);
 
 	return 0;
 }
 
 static int da7210_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u8 mute_reg = snd_soc_read(codec, DA7210_DAC_HPF) & 0xFB;
+	struct snd_soc_component *component = dai->component;
+	u8 mute_reg = snd_soc_component_read32(component, DA7210_DAC_HPF) & 0xFB;
 
 	if (mute)
-		snd_soc_write(codec, DA7210_DAC_HPF, mute_reg | 0x4);
+		snd_soc_component_write(component, DA7210_DAC_HPF, mute_reg | 0x4);
 	else
-		snd_soc_write(codec, DA7210_DAC_HPF, mute_reg);
+		snd_soc_component_write(component, DA7210_DAC_HPF, mute_reg);
 	return 0;
 }
 
@@ -947,8 +947,8 @@ static int da7210_mute(struct snd_soc_dai *dai, int mute)
 static int da7210_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case DA7210_CLKSRC_MCLK:
@@ -988,8 +988,8 @@ static int da7210_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int da7210_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 			      int source, unsigned int fref, unsigned int fout)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
 
 	u8 pll_div1, pll_div2, pll_div3, cnt;
 
@@ -1014,18 +1014,18 @@ static int da7210_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		goto err;
 
 	/* Disable active mode */
-	snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
+	snd_soc_component_update_bits(component, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
 	/* Write PLL dividers */
-	snd_soc_write(codec, DA7210_PLL_DIV1, pll_div1);
-	snd_soc_write(codec, DA7210_PLL_DIV2, pll_div2);
-	snd_soc_update_bits(codec, DA7210_PLL_DIV3,
+	snd_soc_component_write(component, DA7210_PLL_DIV1, pll_div1);
+	snd_soc_component_write(component, DA7210_PLL_DIV2, pll_div2);
+	snd_soc_component_update_bits(component, DA7210_PLL_DIV3,
 				   DA7210_PLL_DIV_L_MASK, pll_div3);
 
 	/* Enable PLL */
-	snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
+	snd_soc_component_update_bits(component, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
 
 	/* Enable active mode */
-	snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN,
+	snd_soc_component_update_bits(component, DA7210_STARTUP1, DA7210_SC_MST_EN,
 						    DA7210_SC_MST_EN);
 	return 0;
 err:
@@ -1064,53 +1064,53 @@ static struct snd_soc_dai_driver da7210_dai = {
 	.symmetric_rates = 1,
 };
 
-static int da7210_probe(struct snd_soc_codec *codec)
+static int da7210_probe(struct snd_soc_component *component)
 {
-	struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+	struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
 
-	dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
+	dev_info(component->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
 
 	da7210->mclk_rate       = 0;    /* This will be set from set_sysclk() */
 	da7210->master          = 0;    /* This will be set from set_fmt() */
 
 	/* Enable internal regulator & bias current */
-	snd_soc_write(codec, DA7210_CONTROL, DA7210_REG_EN | DA7210_BIAS_EN);
+	snd_soc_component_write(component, DA7210_CONTROL, DA7210_REG_EN | DA7210_BIAS_EN);
 
 	/*
 	 * ADC settings
 	 */
 
 	/* Enable Left & Right MIC PGA and Mic Bias */
-	snd_soc_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
-	snd_soc_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
+	snd_soc_component_write(component, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
+	snd_soc_component_write(component, DA7210_MIC_R, DA7210_MIC_R_EN);
 
 	/* Enable Left and Right input PGA */
-	snd_soc_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
-	snd_soc_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
+	snd_soc_component_write(component, DA7210_INMIX_L, DA7210_IN_L_EN);
+	snd_soc_component_write(component, DA7210_INMIX_R, DA7210_IN_R_EN);
 
 	/* Enable Left and Right ADC */
-	snd_soc_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
+	snd_soc_component_write(component, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
 
 	/*
 	 * DAC settings
 	 */
 
 	/* Enable Left and Right DAC */
-	snd_soc_write(codec, DA7210_DAC_SEL,
+	snd_soc_component_write(component, DA7210_DAC_SEL,
 		     DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
 		     DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
 
 	/* Enable Left and Right out PGA */
-	snd_soc_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
-	snd_soc_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
+	snd_soc_component_write(component, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
+	snd_soc_component_write(component, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
 
 	/* Enable Left and Right HeadPhone PGA */
-	snd_soc_write(codec, DA7210_HP_CFG,
+	snd_soc_component_write(component, DA7210_HP_CFG,
 		     DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
 		     DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
 
 	/* Enable ramp mode for DAC gain update */
-	snd_soc_write(codec, DA7210_SOFTMUTE, DA7210_RAMP_EN);
+	snd_soc_component_write(component, DA7210_SOFTMUTE, DA7210_RAMP_EN);
 
 	/*
 	 * For DA7210 codec, there are two ways to enable/disable analog IOs
@@ -1138,43 +1138,44 @@ static int da7210_probe(struct snd_soc_codec *codec)
 	 */
 
 	/* Enable Line out amplifiers */
-	snd_soc_write(codec, DA7210_OUT1_L, DA7210_OUT1_L_EN);
-	snd_soc_write(codec, DA7210_OUT1_R, DA7210_OUT1_R_EN);
-	snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN |
+	snd_soc_component_write(component, DA7210_OUT1_L, DA7210_OUT1_L_EN);
+	snd_soc_component_write(component, DA7210_OUT1_R, DA7210_OUT1_R_EN);
+	snd_soc_component_write(component, DA7210_OUT2, DA7210_OUT2_EN |
 		     DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R);
 
 	/* Enable Aux1 */
-	snd_soc_write(codec, DA7210_AUX1_L, DA7210_AUX1_L_EN);
-	snd_soc_write(codec, DA7210_AUX1_R, DA7210_AUX1_R_EN);
+	snd_soc_component_write(component, DA7210_AUX1_L, DA7210_AUX1_L_EN);
+	snd_soc_component_write(component, DA7210_AUX1_R, DA7210_AUX1_R_EN);
 	/* Enable Aux2 */
-	snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN);
+	snd_soc_component_write(component, DA7210_AUX2, DA7210_AUX2_EN);
 
 	/* Set PLL Master clock range 10-20 MHz, enable PLL bypass */
-	snd_soc_write(codec, DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ |
+	snd_soc_component_write(component, DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ |
 					      DA7210_PLL_BYP);
 
 	/* Diable PLL and bypass it */
-	snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
+	snd_soc_component_write(component, DA7210_PLL, DA7210_PLL_FS_48000);
 
 	/* Activate all enabled subsystem */
-	snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
+	snd_soc_component_write(component, DA7210_STARTUP1, DA7210_SC_MST_EN);
 
-	dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
+	dev_info(component->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_da7210 = {
+static const struct snd_soc_component_driver soc_component_dev_da7210 = {
 	.probe			= da7210_probe,
-
-	.component_driver = {
-		.controls		= da7210_snd_controls,
-		.num_controls		= ARRAY_SIZE(da7210_snd_controls),
-		.dapm_widgets		= da7210_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(da7210_dapm_widgets),
-		.dapm_routes		= da7210_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(da7210_audio_map),
-	},
+	.controls		= da7210_snd_controls,
+	.num_controls		= ARRAY_SIZE(da7210_snd_controls),
+	.dapm_widgets		= da7210_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(da7210_dapm_widgets),
+	.dapm_routes		= da7210_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(da7210_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 #if IS_ENABLED(CONFIG_I2C)
@@ -1232,20 +1233,14 @@ static int da7210_i2c_probe(struct i2c_client *i2c,
 	if (ret != 0)
 		dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_da7210, &da7210_dai, 1);
+	ret =  devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_da7210, &da7210_dai, 1);
 	if (ret < 0)
-		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 
 	return ret;
 }
 
-static int da7210_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id da7210_i2c_id[] = {
 	{ "da7210", 0 },
 	{ }
@@ -1258,7 +1253,6 @@ static struct i2c_driver da7210_i2c_driver = {
 		.name = "da7210",
 	},
 	.probe		= da7210_i2c_probe,
-	.remove		= da7210_i2c_remove,
 	.id_table	= da7210_i2c_id,
 };
 #endif
@@ -1325,24 +1319,17 @@ static int da7210_spi_probe(struct spi_device *spi)
 	if (ret != 0)
 		dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_da7210, &da7210_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_da7210, &da7210_dai, 1);
 
 	return ret;
 }
 
-static int da7210_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver da7210_spi_driver = {
 	.driver = {
 		.name = "da7210",
 	},
 	.probe = da7210_spi_probe,
-	.remove = da7210_spi_remove
 };
 #endif
 
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index b2b4e90..54cb5f2 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -194,7 +194,7 @@ static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_release_rate,
  * Control Functions
  */
 
-static int da7213_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
+static int da7213_get_alc_data(struct snd_soc_component *component, u8 reg_val)
 {
 	int mid_data, top_data;
 	int sum = 0;
@@ -203,17 +203,17 @@ static int da7213_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
 	for (iteration = 0; iteration < DA7213_ALC_AVG_ITERATIONS;
 	     iteration++) {
 		/* Select the left or right channel and capture data */
-		snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL, reg_val);
+		snd_soc_component_write(component, DA7213_ALC_CIC_OP_LVL_CTRL, reg_val);
 
 		/* Select middle 8 bits for read back from data register */
-		snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL,
+		snd_soc_component_write(component, DA7213_ALC_CIC_OP_LVL_CTRL,
 			      reg_val | DA7213_ALC_DATA_MIDDLE);
-		mid_data = snd_soc_read(codec, DA7213_ALC_CIC_OP_LVL_DATA);
+		mid_data = snd_soc_component_read32(component, DA7213_ALC_CIC_OP_LVL_DATA);
 
 		/* Select top 8 bits for read back from data register */
-		snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL,
+		snd_soc_component_write(component, DA7213_ALC_CIC_OP_LVL_CTRL,
 			      reg_val | DA7213_ALC_DATA_TOP);
-		top_data = snd_soc_read(codec, DA7213_ALC_CIC_OP_LVL_DATA);
+		top_data = snd_soc_component_read32(component, DA7213_ALC_CIC_OP_LVL_DATA);
 
 		sum += ((mid_data << 8) | (top_data << 16));
 	}
@@ -221,17 +221,17 @@ static int da7213_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
 	return sum / DA7213_ALC_AVG_ITERATIONS;
 }
 
-static void da7213_alc_calib_man(struct snd_soc_codec *codec)
+static void da7213_alc_calib_man(struct snd_soc_component *component)
 {
 	u8 reg_val;
 	int avg_left_data, avg_right_data, offset_l, offset_r;
 
 	/* Calculate average for Left and Right data */
 	/* Left Data */
-	avg_left_data = da7213_get_alc_data(codec,
+	avg_left_data = da7213_get_alc_data(component,
 			DA7213_ALC_CIC_OP_CHANNEL_LEFT);
 	/* Right Data */
-	avg_right_data = da7213_get_alc_data(codec,
+	avg_right_data = da7213_get_alc_data(component,
 			 DA7213_ALC_CIC_OP_CHANNEL_RIGHT);
 
 	/* Calculate DC offset */
@@ -239,122 +239,122 @@ static void da7213_alc_calib_man(struct snd_soc_codec *codec)
 	offset_r = -avg_right_data;
 
 	reg_val = (offset_l & DA7213_ALC_OFFSET_15_8) >> 8;
-	snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_M_L, reg_val);
+	snd_soc_component_write(component, DA7213_ALC_OFFSET_MAN_M_L, reg_val);
 	reg_val = (offset_l & DA7213_ALC_OFFSET_19_16) >> 16;
-	snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_U_L, reg_val);
+	snd_soc_component_write(component, DA7213_ALC_OFFSET_MAN_U_L, reg_val);
 
 	reg_val = (offset_r & DA7213_ALC_OFFSET_15_8) >> 8;
-	snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_M_R, reg_val);
+	snd_soc_component_write(component, DA7213_ALC_OFFSET_MAN_M_R, reg_val);
 	reg_val = (offset_r & DA7213_ALC_OFFSET_19_16) >> 16;
-	snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_U_R, reg_val);
+	snd_soc_component_write(component, DA7213_ALC_OFFSET_MAN_U_R, reg_val);
 
 	/* Enable analog/digital gain mode & offset cancellation */
-	snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
+	snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
 			    DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
 			    DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE);
 }
 
-static void da7213_alc_calib_auto(struct snd_soc_codec *codec)
+static void da7213_alc_calib_auto(struct snd_soc_component *component)
 {
 	u8 alc_ctrl1;
 
 	/* Begin auto calibration and wait for completion */
-	snd_soc_update_bits(codec, DA7213_ALC_CTRL1, DA7213_ALC_AUTO_CALIB_EN,
+	snd_soc_component_update_bits(component, DA7213_ALC_CTRL1, DA7213_ALC_AUTO_CALIB_EN,
 			    DA7213_ALC_AUTO_CALIB_EN);
 	do {
-		alc_ctrl1 = snd_soc_read(codec, DA7213_ALC_CTRL1);
+		alc_ctrl1 = snd_soc_component_read32(component, DA7213_ALC_CTRL1);
 	} while (alc_ctrl1 & DA7213_ALC_AUTO_CALIB_EN);
 
 	/* If auto calibration fails, fall back to digital gain only mode */
 	if (alc_ctrl1 & DA7213_ALC_CALIB_OVERFLOW) {
-		dev_warn(codec->dev,
+		dev_warn(component->dev,
 			 "ALC auto calibration failed with overflow\n");
-		snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
+		snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
 				    DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
 				    0);
 	} else {
 		/* Enable analog/digital gain mode & offset cancellation */
-		snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
+		snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
 				    DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
 				    DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE);
 	}
 
 }
 
-static void da7213_alc_calib(struct snd_soc_codec *codec)
+static void da7213_alc_calib(struct snd_soc_component *component)
 {
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 	u8 adc_l_ctrl, adc_r_ctrl;
 	u8 mixin_l_sel, mixin_r_sel;
 	u8 mic_1_ctrl, mic_2_ctrl;
 
 	/* Save current values from ADC control registers */
-	adc_l_ctrl = snd_soc_read(codec, DA7213_ADC_L_CTRL);
-	adc_r_ctrl = snd_soc_read(codec, DA7213_ADC_R_CTRL);
+	adc_l_ctrl = snd_soc_component_read32(component, DA7213_ADC_L_CTRL);
+	adc_r_ctrl = snd_soc_component_read32(component, DA7213_ADC_R_CTRL);
 
 	/* Save current values from MIXIN_L/R_SELECT registers */
-	mixin_l_sel = snd_soc_read(codec, DA7213_MIXIN_L_SELECT);
-	mixin_r_sel = snd_soc_read(codec, DA7213_MIXIN_R_SELECT);
+	mixin_l_sel = snd_soc_component_read32(component, DA7213_MIXIN_L_SELECT);
+	mixin_r_sel = snd_soc_component_read32(component, DA7213_MIXIN_R_SELECT);
 
 	/* Save current values from MIC control registers */
-	mic_1_ctrl = snd_soc_read(codec, DA7213_MIC_1_CTRL);
-	mic_2_ctrl = snd_soc_read(codec, DA7213_MIC_2_CTRL);
+	mic_1_ctrl = snd_soc_component_read32(component, DA7213_MIC_1_CTRL);
+	mic_2_ctrl = snd_soc_component_read32(component, DA7213_MIC_2_CTRL);
 
 	/* Enable ADC Left and Right */
-	snd_soc_update_bits(codec, DA7213_ADC_L_CTRL, DA7213_ADC_EN,
+	snd_soc_component_update_bits(component, DA7213_ADC_L_CTRL, DA7213_ADC_EN,
 			    DA7213_ADC_EN);
-	snd_soc_update_bits(codec, DA7213_ADC_R_CTRL, DA7213_ADC_EN,
+	snd_soc_component_update_bits(component, DA7213_ADC_R_CTRL, DA7213_ADC_EN,
 			    DA7213_ADC_EN);
 
 	/* Enable MIC paths */
-	snd_soc_update_bits(codec, DA7213_MIXIN_L_SELECT,
+	snd_soc_component_update_bits(component, DA7213_MIXIN_L_SELECT,
 			    DA7213_MIXIN_L_MIX_SELECT_MIC_1 |
 			    DA7213_MIXIN_L_MIX_SELECT_MIC_2,
 			    DA7213_MIXIN_L_MIX_SELECT_MIC_1 |
 			    DA7213_MIXIN_L_MIX_SELECT_MIC_2);
-	snd_soc_update_bits(codec, DA7213_MIXIN_R_SELECT,
+	snd_soc_component_update_bits(component, DA7213_MIXIN_R_SELECT,
 			    DA7213_MIXIN_R_MIX_SELECT_MIC_2 |
 			    DA7213_MIXIN_R_MIX_SELECT_MIC_1,
 			    DA7213_MIXIN_R_MIX_SELECT_MIC_2 |
 			    DA7213_MIXIN_R_MIX_SELECT_MIC_1);
 
 	/* Mute MIC PGAs */
-	snd_soc_update_bits(codec, DA7213_MIC_1_CTRL, DA7213_MUTE_EN,
+	snd_soc_component_update_bits(component, DA7213_MIC_1_CTRL, DA7213_MUTE_EN,
 			    DA7213_MUTE_EN);
-	snd_soc_update_bits(codec, DA7213_MIC_2_CTRL, DA7213_MUTE_EN,
+	snd_soc_component_update_bits(component, DA7213_MIC_2_CTRL, DA7213_MUTE_EN,
 			    DA7213_MUTE_EN);
 
 	/* Perform calibration */
 	if (da7213->alc_calib_auto)
-		da7213_alc_calib_auto(codec);
+		da7213_alc_calib_auto(component);
 	else
-		da7213_alc_calib_man(codec);
+		da7213_alc_calib_man(component);
 
 	/* Restore MIXIN_L/R_SELECT registers to their original states */
-	snd_soc_write(codec, DA7213_MIXIN_L_SELECT, mixin_l_sel);
-	snd_soc_write(codec, DA7213_MIXIN_R_SELECT, mixin_r_sel);
+	snd_soc_component_write(component, DA7213_MIXIN_L_SELECT, mixin_l_sel);
+	snd_soc_component_write(component, DA7213_MIXIN_R_SELECT, mixin_r_sel);
 
 	/* Restore ADC control registers to their original states */
-	snd_soc_write(codec, DA7213_ADC_L_CTRL, adc_l_ctrl);
-	snd_soc_write(codec, DA7213_ADC_R_CTRL, adc_r_ctrl);
+	snd_soc_component_write(component, DA7213_ADC_L_CTRL, adc_l_ctrl);
+	snd_soc_component_write(component, DA7213_ADC_R_CTRL, adc_r_ctrl);
 
 	/* Restore original values of MIC control registers */
-	snd_soc_write(codec, DA7213_MIC_1_CTRL, mic_1_ctrl);
-	snd_soc_write(codec, DA7213_MIC_2_CTRL, mic_2_ctrl);
+	snd_soc_component_write(component, DA7213_MIC_1_CTRL, mic_1_ctrl);
+	snd_soc_component_write(component, DA7213_MIC_2_CTRL, mic_2_ctrl);
 }
 
 static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
 
 	/* If ALC in operation, make sure calibrated offsets are updated */
 	if ((!ret) && (da7213->alc_en))
-		da7213_alc_calib(codec);
+		da7213_alc_calib(component);
 
 	return ret;
 }
@@ -362,14 +362,14 @@ static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol,
 static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol,
 			    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 
 	/* Force ALC offset calibration if enabling ALC */
 	if (ucontrol->value.integer.value[0] ||
 	    ucontrol->value.integer.value[1]) {
 		if (!da7213->alc_en) {
-			da7213_alc_calib(codec);
+			da7213_alc_calib(component);
 			da7213->alc_en = true;
 		}
 	} else {
@@ -735,8 +735,8 @@ static const struct snd_kcontrol_new da7213_dapm_mixoutr_controls[] = {
 static int da7213_dai_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 	u8 pll_ctrl, pll_status;
 	int i = 0;
 	bool srm_lock = false;
@@ -745,29 +745,29 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_PRE_PMU:
 		/* Enable DAI clks for master mode */
 		if (da7213->master)
-			snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE,
+			snd_soc_component_update_bits(component, DA7213_DAI_CLK_MODE,
 					    DA7213_DAI_CLK_EN_MASK,
 					    DA7213_DAI_CLK_EN_MASK);
 
 		/* PC synchronised to DAI */
-		snd_soc_update_bits(codec, DA7213_PC_COUNT,
+		snd_soc_component_update_bits(component, DA7213_PC_COUNT,
 				    DA7213_PC_FREERUN_MASK, 0);
 
 		/* If SRM not enabled then nothing more to do */
-		pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
+		pll_ctrl = snd_soc_component_read32(component, DA7213_PLL_CTRL);
 		if (!(pll_ctrl & DA7213_PLL_SRM_EN))
 			return 0;
 
 		/* Assist 32KHz mode PLL lock */
 		if (pll_ctrl & DA7213_PLL_32K_MODE) {
-			snd_soc_write(codec, 0xF0, 0x8B);
-			snd_soc_write(codec, 0xF2, 0x03);
-			snd_soc_write(codec, 0xF0, 0x00);
+			snd_soc_component_write(component, 0xF0, 0x8B);
+			snd_soc_component_write(component, 0xF2, 0x03);
+			snd_soc_component_write(component, 0xF0, 0x00);
 		}
 
 		/* Check SRM has locked */
 		do {
-			pll_status = snd_soc_read(codec, DA7213_PLL_STATUS);
+			pll_status = snd_soc_component_read32(component, DA7213_PLL_STATUS);
 			if (pll_status & DA7219_PLL_SRM_LOCK) {
 				srm_lock = true;
 			} else {
@@ -777,26 +777,26 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
 		} while ((i < DA7213_SRM_CHECK_RETRIES) && (!srm_lock));
 
 		if (!srm_lock)
-			dev_warn(codec->dev, "SRM failed to lock\n");
+			dev_warn(component->dev, "SRM failed to lock\n");
 
 		return 0;
 	case SND_SOC_DAPM_POST_PMD:
 		/* Revert 32KHz PLL lock udpates if applied previously */
-		pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
+		pll_ctrl = snd_soc_component_read32(component, DA7213_PLL_CTRL);
 		if (pll_ctrl & DA7213_PLL_32K_MODE) {
-			snd_soc_write(codec, 0xF0, 0x8B);
-			snd_soc_write(codec, 0xF2, 0x01);
-			snd_soc_write(codec, 0xF0, 0x00);
+			snd_soc_component_write(component, 0xF0, 0x8B);
+			snd_soc_component_write(component, 0xF2, 0x01);
+			snd_soc_component_write(component, 0xF0, 0x00);
 		}
 
 		/* PC free-running */
-		snd_soc_update_bits(codec, DA7213_PC_COUNT,
+		snd_soc_component_update_bits(component, DA7213_PC_COUNT,
 				    DA7213_PC_FREERUN_MASK,
 				    DA7213_PC_FREERUN_MASK);
 
 		/* Disable DAI clks if in master mode */
 		if (da7213->master)
-			snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE,
+			snd_soc_component_update_bits(component, DA7213_DAI_CLK_MODE,
 					    DA7213_DAI_CLK_EN_MASK, 0);
 		return 0;
 	default:
@@ -1150,7 +1150,7 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 dai_ctrl = 0;
 	u8 fs;
 
@@ -1208,17 +1208,17 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_WORD_LENGTH_MASK,
+	snd_soc_component_update_bits(component, DA7213_DAI_CTRL, DA7213_DAI_WORD_LENGTH_MASK,
 			    dai_ctrl);
-	snd_soc_write(codec, DA7213_SR, fs);
+	snd_soc_component_write(component, DA7213_SR, fs);
 
 	return 0;
 }
 
 static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 	u8 dai_clk_mode = 0, dai_ctrl = 0;
 	u8 dai_offset = 0;
 
@@ -1305,27 +1305,27 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	/* By default only 64 BCLK per WCLK is supported */
 	dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_64;
 
-	snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode);
-	snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
+	snd_soc_component_write(component, DA7213_DAI_CLK_MODE, dai_clk_mode);
+	snd_soc_component_update_bits(component, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
 			    dai_ctrl);
-	snd_soc_write(codec, DA7213_DAI_OFFSET, dai_offset);
+	snd_soc_component_write(component, DA7213_DAI_OFFSET, dai_offset);
 
 	return 0;
 }
 
 static int da7213_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (mute) {
-		snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
+		snd_soc_component_update_bits(component, DA7213_DAC_L_CTRL,
 				    DA7213_MUTE_EN, DA7213_MUTE_EN);
-		snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
+		snd_soc_component_update_bits(component, DA7213_DAC_R_CTRL,
 				    DA7213_MUTE_EN, DA7213_MUTE_EN);
 	} else {
-		snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
+		snd_soc_component_update_bits(component, DA7213_DAC_L_CTRL,
 				    DA7213_MUTE_EN, 0);
-		snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
+		snd_soc_component_update_bits(component, DA7213_DAC_R_CTRL,
 				    DA7213_MUTE_EN, 0);
 	}
 
@@ -1338,8 +1338,8 @@ static int da7213_mute(struct snd_soc_dai *dai, int mute)
 static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	if ((da7213->clk_src == clk_id) && (da7213->mclk_rate == freq))
@@ -1353,11 +1353,11 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 	switch (clk_id) {
 	case DA7213_CLKSRC_MCLK:
-		snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7213_PLL_CTRL,
 				    DA7213_PLL_MCLK_SQR_EN, 0);
 		break;
 	case DA7213_CLKSRC_MCLK_SQR:
-		snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7213_PLL_CTRL,
 				    DA7213_PLL_MCLK_SQR_EN,
 				    DA7213_PLL_MCLK_SQR_EN);
 		break;
@@ -1387,8 +1387,8 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 			      int source, unsigned int fref, unsigned int fout)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 
 	u8 pll_ctrl, indiv_bits, indiv;
 	u8 pll_frac_top, pll_frac_bot, pll_integer;
@@ -1398,7 +1398,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	/* Workout input divider based on MCLK rate */
 	if (da7213->mclk_rate == 32768) {
 		if (!da7213->master) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"32KHz only valid if codec is clock master\n");
 			return -EINVAL;
 		}
@@ -1411,7 +1411,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
 	} else {
 		if (da7213->mclk_rate < 5000000) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"PLL input clock %d below valid range\n",
 				da7213->mclk_rate);
 			return -EINVAL;
@@ -1428,7 +1428,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 			indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ;
 			indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL;
 		} else {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"PLL input clock %d above valid range\n",
 				da7213->mclk_rate);
 			return -EINVAL;
@@ -1441,7 +1441,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	/* Configure PLL */
 	switch (source) {
 	case DA7213_SYSCLK_MCLK:
-		snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7213_PLL_CTRL,
 				    DA7213_PLL_INDIV_MASK |
 				    DA7213_PLL_MODE_MASK, pll_ctrl);
 		return 0;
@@ -1453,7 +1453,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		break;
 	case DA7213_SYSCLK_PLL_32KHZ:
 		if (da7213->mclk_rate != 32768) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"32KHz mode only valid with 32KHz MCLK\n");
 			return -EINVAL;
 		}
@@ -1462,7 +1462,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		fout = DA7213_PLL_FREQ_OUT_94310400;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid PLL config\n");
+		dev_err(component->dev, "Invalid PLL config\n");
 		return -EINVAL;
 	}
 
@@ -1474,22 +1474,22 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	pll_frac_bot = (frac_div) & DA7213_BYTE_MASK;
 
 	/* Write PLL dividers */
-	snd_soc_write(codec, DA7213_PLL_FRAC_TOP, pll_frac_top);
-	snd_soc_write(codec, DA7213_PLL_FRAC_BOT, pll_frac_bot);
-	snd_soc_write(codec, DA7213_PLL_INTEGER, pll_integer);
+	snd_soc_component_write(component, DA7213_PLL_FRAC_TOP, pll_frac_top);
+	snd_soc_component_write(component, DA7213_PLL_FRAC_BOT, pll_frac_bot);
+	snd_soc_component_write(component, DA7213_PLL_INTEGER, pll_integer);
 
 	/* Enable PLL */
 	pll_ctrl |= DA7213_PLL_EN;
-	snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+	snd_soc_component_update_bits(component, DA7213_PLL_CTRL,
 			    DA7213_PLL_INDIV_MASK | DA7213_PLL_MODE_MASK,
 			    pll_ctrl);
 
 	/* Assist 32KHz mode PLL lock */
 	if (source == DA7213_SYSCLK_PLL_32KHZ) {
-		snd_soc_write(codec, 0xF0, 0x8B);
-		snd_soc_write(codec, 0xF1, 0x03);
-		snd_soc_write(codec, 0xF1, 0x01);
-		snd_soc_write(codec, 0xF0, 0x00);
+		snd_soc_component_write(component, 0xF0, 0x8B);
+		snd_soc_component_write(component, 0xF1, 0x03);
+		snd_soc_component_write(component, 0xF1, 0x01);
+		snd_soc_component_write(component, 0xF0, 0x00);
 	}
 
 	return 0;
@@ -1526,10 +1526,10 @@ static struct snd_soc_dai_driver da7213_dai = {
 	.symmetric_rates = 1,
 };
 
-static int da7213_set_bias_level(struct snd_soc_codec *codec,
+static int da7213_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1537,11 +1537,11 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		/* Enable MCLK for transition to ON state */
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
 			if (da7213->mclk) {
 				ret = clk_prepare_enable(da7213->mclk);
 				if (ret) {
-					dev_err(codec->dev,
+					dev_err(component->dev,
 						"Failed to enable mclk\n");
 					return ret;
 				}
@@ -1549,9 +1549,9 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
 		}
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Enable VMID reference & master bias */
-			snd_soc_update_bits(codec, DA7213_REFERENCES,
+			snd_soc_component_update_bits(component, DA7213_REFERENCES,
 					    DA7213_VMID_EN | DA7213_BIAS_EN,
 					    DA7213_VMID_EN | DA7213_BIAS_EN);
 		} else {
@@ -1562,7 +1562,7 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* Disable VMID reference & master bias */
-		snd_soc_update_bits(codec, DA7213_REFERENCES,
+		snd_soc_component_update_bits(component, DA7213_REFERENCES,
 				    DA7213_VMID_EN | DA7213_BIAS_EN, 0);
 		break;
 	}
@@ -1588,7 +1588,7 @@ MODULE_DEVICE_TABLE(acpi, da7213_acpi_match);
 #endif
 
 static enum da7213_micbias_voltage
-	da7213_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
+	da7213_of_micbias_lvl(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 1600:
@@ -1600,39 +1600,39 @@ static enum da7213_micbias_voltage
 	case 3000:
 		return DA7213_MICBIAS_3_0V;
 	default:
-		dev_warn(codec->dev, "Invalid micbias level\n");
+		dev_warn(component->dev, "Invalid micbias level\n");
 		return DA7213_MICBIAS_2_2V;
 	}
 }
 
 static enum da7213_dmic_data_sel
-	da7213_of_dmic_data_sel(struct snd_soc_codec *codec, const char *str)
+	da7213_of_dmic_data_sel(struct snd_soc_component *component, const char *str)
 {
 	if (!strcmp(str, "lrise_rfall")) {
 		return DA7213_DMIC_DATA_LRISE_RFALL;
 	} else if (!strcmp(str, "lfall_rrise")) {
 		return DA7213_DMIC_DATA_LFALL_RRISE;
 	} else {
-		dev_warn(codec->dev, "Invalid DMIC data select type\n");
+		dev_warn(component->dev, "Invalid DMIC data select type\n");
 		return DA7213_DMIC_DATA_LRISE_RFALL;
 	}
 }
 
 static enum da7213_dmic_samplephase
-	da7213_of_dmic_samplephase(struct snd_soc_codec *codec, const char *str)
+	da7213_of_dmic_samplephase(struct snd_soc_component *component, const char *str)
 {
 	if (!strcmp(str, "on_clkedge")) {
 		return DA7213_DMIC_SAMPLE_ON_CLKEDGE;
 	} else if (!strcmp(str, "between_clkedge")) {
 		return DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE;
 	} else {
-		dev_warn(codec->dev, "Invalid DMIC sample phase\n");
+		dev_warn(component->dev, "Invalid DMIC sample phase\n");
 		return DA7213_DMIC_SAMPLE_ON_CLKEDGE;
 	}
 }
 
 static enum da7213_dmic_clk_rate
-	da7213_of_dmic_clkrate(struct snd_soc_codec *codec, u32 val)
+	da7213_of_dmic_clkrate(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 1500000:
@@ -1640,46 +1640,46 @@ static enum da7213_dmic_clk_rate
 	case 3000000:
 		return DA7213_DMIC_CLK_3_0MHZ;
 	default:
-		dev_warn(codec->dev, "Invalid DMIC clock rate\n");
+		dev_warn(component->dev, "Invalid DMIC clock rate\n");
 		return DA7213_DMIC_CLK_1_5MHZ;
 	}
 }
 
 static struct da7213_platform_data
-	*da7213_fw_to_pdata(struct snd_soc_codec *codec)
+	*da7213_fw_to_pdata(struct snd_soc_component *component)
 {
-	struct device *dev = codec->dev;
+	struct device *dev = component->dev;
 	struct da7213_platform_data *pdata;
 	const char *fw_str;
 	u32 fw_val32;
 
-	pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
+	pdata = devm_kzalloc(component->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return NULL;
 
 	if (device_property_read_u32(dev, "dlg,micbias1-lvl", &fw_val32) >= 0)
-		pdata->micbias1_lvl = da7213_of_micbias_lvl(codec, fw_val32);
+		pdata->micbias1_lvl = da7213_of_micbias_lvl(component, fw_val32);
 	else
 		pdata->micbias1_lvl = DA7213_MICBIAS_2_2V;
 
 	if (device_property_read_u32(dev, "dlg,micbias2-lvl", &fw_val32) >= 0)
-		pdata->micbias2_lvl = da7213_of_micbias_lvl(codec, fw_val32);
+		pdata->micbias2_lvl = da7213_of_micbias_lvl(component, fw_val32);
 	else
 		pdata->micbias2_lvl = DA7213_MICBIAS_2_2V;
 
 	if (!device_property_read_string(dev, "dlg,dmic-data-sel", &fw_str))
-		pdata->dmic_data_sel = da7213_of_dmic_data_sel(codec, fw_str);
+		pdata->dmic_data_sel = da7213_of_dmic_data_sel(component, fw_str);
 	else
 		pdata->dmic_data_sel = DA7213_DMIC_DATA_LRISE_RFALL;
 
 	if (!device_property_read_string(dev, "dlg,dmic-samplephase", &fw_str))
 		pdata->dmic_samplephase =
-			da7213_of_dmic_samplephase(codec, fw_str);
+			da7213_of_dmic_samplephase(component, fw_str);
 	else
 		pdata->dmic_samplephase = DA7213_DMIC_SAMPLE_ON_CLKEDGE;
 
 	if (device_property_read_u32(dev, "dlg,dmic-clkrate", &fw_val32) >= 0)
-		pdata->dmic_clk_rate = da7213_of_dmic_clkrate(codec, fw_val32);
+		pdata->dmic_clk_rate = da7213_of_dmic_clkrate(component, fw_val32);
 	else
 		pdata->dmic_clk_rate = DA7213_DMIC_CLK_3_0MHZ;
 
@@ -1687,41 +1687,41 @@ static struct da7213_platform_data
 }
 
 
-static int da7213_probe(struct snd_soc_codec *codec)
+static int da7213_probe(struct snd_soc_component *component)
 {
-	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 
 	/* Default to using ALC auto offset calibration mode. */
-	snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
+	snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
 			    DA7213_ALC_CALIB_MODE_MAN, 0);
 	da7213->alc_calib_auto = true;
 
 	/* Default PC counter to free-running */
-	snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK,
+	snd_soc_component_update_bits(component, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK,
 			    DA7213_PC_FREERUN_MASK);
 
 	/* Enable all Gain Ramps */
-	snd_soc_update_bits(codec, DA7213_AUX_L_CTRL,
+	snd_soc_component_update_bits(component, DA7213_AUX_L_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_AUX_R_CTRL,
+	snd_soc_component_update_bits(component, DA7213_AUX_R_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_MIXIN_L_CTRL,
+	snd_soc_component_update_bits(component, DA7213_MIXIN_L_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_MIXIN_R_CTRL,
+	snd_soc_component_update_bits(component, DA7213_MIXIN_R_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_ADC_L_CTRL,
+	snd_soc_component_update_bits(component, DA7213_ADC_L_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_ADC_R_CTRL,
+	snd_soc_component_update_bits(component, DA7213_ADC_R_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
+	snd_soc_component_update_bits(component, DA7213_DAC_L_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
+	snd_soc_component_update_bits(component, DA7213_DAC_R_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA7213_HP_L_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA7213_HP_R_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-	snd_soc_update_bits(codec, DA7213_LINE_CTRL,
+	snd_soc_component_update_bits(component, DA7213_LINE_CTRL,
 			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
 
 	/*
@@ -1732,28 +1732,28 @@ static int da7213_probe(struct snd_soc_codec *codec)
 	 * being managed by DAPM while other (non power related) bits are
 	 * enabled here
 	 */
-	snd_soc_update_bits(codec, DA7213_MIXIN_L_CTRL,
+	snd_soc_component_update_bits(component, DA7213_MIXIN_L_CTRL,
 			    DA7213_MIXIN_MIX_EN, DA7213_MIXIN_MIX_EN);
-	snd_soc_update_bits(codec, DA7213_MIXIN_R_CTRL,
+	snd_soc_component_update_bits(component, DA7213_MIXIN_R_CTRL,
 			    DA7213_MIXIN_MIX_EN, DA7213_MIXIN_MIX_EN);
 
-	snd_soc_update_bits(codec, DA7213_MIXOUT_L_CTRL,
+	snd_soc_component_update_bits(component, DA7213_MIXOUT_L_CTRL,
 			    DA7213_MIXOUT_MIX_EN, DA7213_MIXOUT_MIX_EN);
-	snd_soc_update_bits(codec, DA7213_MIXOUT_R_CTRL,
+	snd_soc_component_update_bits(component, DA7213_MIXOUT_R_CTRL,
 			    DA7213_MIXOUT_MIX_EN, DA7213_MIXOUT_MIX_EN);
 
-	snd_soc_update_bits(codec, DA7213_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA7213_HP_L_CTRL,
 			    DA7213_HP_AMP_OE, DA7213_HP_AMP_OE);
-	snd_soc_update_bits(codec, DA7213_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA7213_HP_R_CTRL,
 			    DA7213_HP_AMP_OE, DA7213_HP_AMP_OE);
 
-	snd_soc_update_bits(codec, DA7213_LINE_CTRL,
+	snd_soc_component_update_bits(component, DA7213_LINE_CTRL,
 			    DA7213_LINE_AMP_OE, DA7213_LINE_AMP_OE);
 
 	/* Handle DT/Platform data */
-	da7213->pdata = dev_get_platdata(codec->dev);
+	da7213->pdata = dev_get_platdata(component->dev);
 	if (!da7213->pdata)
-		da7213->pdata = da7213_fw_to_pdata(codec);
+		da7213->pdata = da7213_fw_to_pdata(component);
 
 	/* Set platform data values */
 	if (da7213->pdata) {
@@ -1779,7 +1779,7 @@ static int da7213_probe(struct snd_soc_codec *codec)
 					 DA7213_MICBIAS2_LEVEL_SHIFT);
 			break;
 		}
-		snd_soc_update_bits(codec, DA7213_MICBIAS_CTRL,
+		snd_soc_component_update_bits(component, DA7213_MICBIAS_CTRL,
 				    DA7213_MICBIAS1_LEVEL_MASK |
 				    DA7213_MICBIAS2_LEVEL_MASK, micbias_lvl);
 
@@ -1805,14 +1805,14 @@ static int da7213_probe(struct snd_soc_codec *codec)
 				     DA7213_DMIC_CLK_RATE_SHIFT);
 			break;
 		}
-		snd_soc_update_bits(codec, DA7213_MIC_CONFIG,
+		snd_soc_component_update_bits(component, DA7213_MIC_CONFIG,
 				    DA7213_DMIC_DATA_SEL_MASK |
 				    DA7213_DMIC_SAMPLEPHASE_MASK |
 				    DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
 	}
 
 	/* Check if MCLK provided */
-	da7213->mclk = devm_clk_get(codec->dev, "mclk");
+	da7213->mclk = devm_clk_get(component->dev, "mclk");
 	if (IS_ERR(da7213->mclk)) {
 		if (PTR_ERR(da7213->mclk) != -ENOENT)
 			return PTR_ERR(da7213->mclk);
@@ -1823,18 +1823,19 @@ static int da7213_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_da7213 = {
+static const struct snd_soc_component_driver soc_component_dev_da7213 = {
 	.probe			= da7213_probe,
 	.set_bias_level		= da7213_set_bias_level,
-
-	.component_driver = {
-		.controls		= da7213_snd_controls,
-		.num_controls		= ARRAY_SIZE(da7213_snd_controls),
-		.dapm_widgets		= da7213_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(da7213_dapm_widgets),
-		.dapm_routes		= da7213_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(da7213_audio_map),
-	},
+	.controls		= da7213_snd_controls,
+	.num_controls		= ARRAY_SIZE(da7213_snd_controls),
+	.dapm_widgets		= da7213_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(da7213_dapm_widgets),
+	.dapm_routes		= da7213_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(da7213_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config da7213_regmap_config = {
@@ -1866,21 +1867,15 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_da7213, &da7213_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_da7213, &da7213_dai, 1);
 	if (ret < 0) {
-		dev_err(&i2c->dev, "Failed to register da7213 codec: %d\n",
+		dev_err(&i2c->dev, "Failed to register da7213 component: %d\n",
 			ret);
 	}
 	return ret;
 }
 
-static int da7213_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id da7213_i2c_id[] = {
 	{ "da7213", 0 },
 	{ }
@@ -1895,7 +1890,6 @@ static struct i2c_driver da7213_i2c_driver = {
 		.acpi_match_table = ACPI_PTR(da7213_acpi_match),
 	},
 	.probe		= da7213_i2c_probe,
-	.remove		= da7213_remove,
 	.id_table	= da7213_i2c_id,
 };
 
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c
index 96c644a..ddc90ac 100644
--- a/sound/soc/codecs/da7218.c
+++ b/sound/soc/codecs/da7218.c
@@ -291,7 +291,7 @@ static const struct soc_enum da7218_cp_tau_delay =
  */
 
 /* ALC */
-static void da7218_alc_calib(struct snd_soc_codec *codec)
+static void da7218_alc_calib(struct snd_soc_component *component)
 {
 	u8 mic_1_ctrl, mic_2_ctrl;
 	u8 mixin_1_ctrl, mixin_2_ctrl;
@@ -302,59 +302,59 @@ static void da7218_alc_calib(struct snd_soc_codec *codec)
 	bool calibrated = false;
 
 	/* Save current state of MIC control registers */
-	mic_1_ctrl = snd_soc_read(codec, DA7218_MIC_1_CTRL);
-	mic_2_ctrl = snd_soc_read(codec, DA7218_MIC_2_CTRL);
+	mic_1_ctrl = snd_soc_component_read32(component, DA7218_MIC_1_CTRL);
+	mic_2_ctrl = snd_soc_component_read32(component, DA7218_MIC_2_CTRL);
 
 	/* Save current state of input mixer control registers */
-	mixin_1_ctrl = snd_soc_read(codec, DA7218_MIXIN_1_CTRL);
-	mixin_2_ctrl = snd_soc_read(codec, DA7218_MIXIN_2_CTRL);
+	mixin_1_ctrl = snd_soc_component_read32(component, DA7218_MIXIN_1_CTRL);
+	mixin_2_ctrl = snd_soc_component_read32(component, DA7218_MIXIN_2_CTRL);
 
 	/* Save current state of input filter control registers */
-	in_1l_filt_ctrl = snd_soc_read(codec, DA7218_IN_1L_FILTER_CTRL);
-	in_1r_filt_ctrl = snd_soc_read(codec, DA7218_IN_1R_FILTER_CTRL);
-	in_2l_filt_ctrl = snd_soc_read(codec, DA7218_IN_2L_FILTER_CTRL);
-	in_2r_filt_ctrl = snd_soc_read(codec, DA7218_IN_2R_FILTER_CTRL);
+	in_1l_filt_ctrl = snd_soc_component_read32(component, DA7218_IN_1L_FILTER_CTRL);
+	in_1r_filt_ctrl = snd_soc_component_read32(component, DA7218_IN_1R_FILTER_CTRL);
+	in_2l_filt_ctrl = snd_soc_component_read32(component, DA7218_IN_2L_FILTER_CTRL);
+	in_2r_filt_ctrl = snd_soc_component_read32(component, DA7218_IN_2R_FILTER_CTRL);
 
 	/* Save current state of input HPF control registers */
-	in_1_hpf_ctrl = snd_soc_read(codec, DA7218_IN_1_HPF_FILTER_CTRL);
-	in_2_hpf_ctrl = snd_soc_read(codec, DA7218_IN_2_HPF_FILTER_CTRL);
+	in_1_hpf_ctrl = snd_soc_component_read32(component, DA7218_IN_1_HPF_FILTER_CTRL);
+	in_2_hpf_ctrl = snd_soc_component_read32(component, DA7218_IN_2_HPF_FILTER_CTRL);
 
 	/* Enable then Mute MIC PGAs */
-	snd_soc_update_bits(codec, DA7218_MIC_1_CTRL, DA7218_MIC_1_AMP_EN_MASK,
+	snd_soc_component_update_bits(component, DA7218_MIC_1_CTRL, DA7218_MIC_1_AMP_EN_MASK,
 			    DA7218_MIC_1_AMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_MIC_2_CTRL, DA7218_MIC_2_AMP_EN_MASK,
+	snd_soc_component_update_bits(component, DA7218_MIC_2_CTRL, DA7218_MIC_2_AMP_EN_MASK,
 			    DA7218_MIC_2_AMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_MIC_1_CTRL,
+	snd_soc_component_update_bits(component, DA7218_MIC_1_CTRL,
 			    DA7218_MIC_1_AMP_MUTE_EN_MASK,
 			    DA7218_MIC_1_AMP_MUTE_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_MIC_2_CTRL,
+	snd_soc_component_update_bits(component, DA7218_MIC_2_CTRL,
 			    DA7218_MIC_2_AMP_MUTE_EN_MASK,
 			    DA7218_MIC_2_AMP_MUTE_EN_MASK);
 
 	/* Enable input mixers unmuted */
-	snd_soc_update_bits(codec, DA7218_MIXIN_1_CTRL,
+	snd_soc_component_update_bits(component, DA7218_MIXIN_1_CTRL,
 			    DA7218_MIXIN_1_AMP_EN_MASK |
 			    DA7218_MIXIN_1_AMP_MUTE_EN_MASK,
 			    DA7218_MIXIN_1_AMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_MIXIN_2_CTRL,
+	snd_soc_component_update_bits(component, DA7218_MIXIN_2_CTRL,
 			    DA7218_MIXIN_2_AMP_EN_MASK |
 			    DA7218_MIXIN_2_AMP_MUTE_EN_MASK,
 			    DA7218_MIXIN_2_AMP_EN_MASK);
 
 	/* Enable input filters unmuted */
-	snd_soc_update_bits(codec, DA7218_IN_1L_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_1L_FILTER_CTRL,
 			    DA7218_IN_1L_FILTER_EN_MASK |
 			    DA7218_IN_1L_MUTE_EN_MASK,
 			    DA7218_IN_1L_FILTER_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_IN_1R_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_1R_FILTER_CTRL,
 			    DA7218_IN_1R_FILTER_EN_MASK |
 			    DA7218_IN_1R_MUTE_EN_MASK,
 			    DA7218_IN_1R_FILTER_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_IN_2L_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_2L_FILTER_CTRL,
 			    DA7218_IN_2L_FILTER_EN_MASK |
 			    DA7218_IN_2L_MUTE_EN_MASK,
 			    DA7218_IN_2L_FILTER_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_IN_2R_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_2R_FILTER_CTRL,
 			    DA7218_IN_2R_FILTER_EN_MASK |
 			    DA7218_IN_2R_MUTE_EN_MASK,
 			    DA7218_IN_2R_FILTER_EN_MASK);
@@ -364,16 +364,16 @@ static void da7218_alc_calib(struct snd_soc_codec *codec)
 	 * rates above 32KHz the ADC signals will be stopped and will cause
 	 * calibration to lock up.
 	 */
-	snd_soc_update_bits(codec, DA7218_IN_1_HPF_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_1_HPF_FILTER_CTRL,
 			    DA7218_IN_1_VOICE_EN_MASK, 0);
-	snd_soc_update_bits(codec, DA7218_IN_2_HPF_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_2_HPF_FILTER_CTRL,
 			    DA7218_IN_2_VOICE_EN_MASK, 0);
 
 	/* Perform auto calibration */
-	snd_soc_update_bits(codec, DA7218_CALIB_CTRL, DA7218_CALIB_AUTO_EN_MASK,
+	snd_soc_component_update_bits(component, DA7218_CALIB_CTRL, DA7218_CALIB_AUTO_EN_MASK,
 			    DA7218_CALIB_AUTO_EN_MASK);
 	do {
-		calib_ctrl = snd_soc_read(codec, DA7218_CALIB_CTRL);
+		calib_ctrl = snd_soc_component_read32(component, DA7218_CALIB_CTRL);
 		if (calib_ctrl & DA7218_CALIB_AUTO_EN_MASK) {
 			++i;
 			usleep_range(DA7218_ALC_CALIB_DELAY_MIN,
@@ -386,51 +386,51 @@ static void da7218_alc_calib(struct snd_soc_codec *codec)
 
 	/* If auto calibration fails, disable DC offset, hybrid ALC */
 	if ((!calibrated) || (calib_ctrl & DA7218_CALIB_OVERFLOW_MASK)) {
-		dev_warn(codec->dev,
+		dev_warn(component->dev,
 			 "ALC auto calibration failed - %s\n",
 			 (calibrated) ? "overflow" : "timeout");
-		snd_soc_update_bits(codec, DA7218_CALIB_CTRL,
+		snd_soc_component_update_bits(component, DA7218_CALIB_CTRL,
 				    DA7218_CALIB_OFFSET_EN_MASK, 0);
-		snd_soc_update_bits(codec, DA7218_ALC_CTRL1,
+		snd_soc_component_update_bits(component, DA7218_ALC_CTRL1,
 				    DA7218_ALC_SYNC_MODE_MASK, 0);
 
 	} else {
 		/* Enable DC offset cancellation */
-		snd_soc_update_bits(codec, DA7218_CALIB_CTRL,
+		snd_soc_component_update_bits(component, DA7218_CALIB_CTRL,
 				    DA7218_CALIB_OFFSET_EN_MASK,
 				    DA7218_CALIB_OFFSET_EN_MASK);
 
 		/* Enable ALC hybrid mode */
-		snd_soc_update_bits(codec, DA7218_ALC_CTRL1,
+		snd_soc_component_update_bits(component, DA7218_ALC_CTRL1,
 				    DA7218_ALC_SYNC_MODE_MASK,
 				    DA7218_ALC_SYNC_MODE_CH1 |
 				    DA7218_ALC_SYNC_MODE_CH2);
 	}
 
 	/* Restore input HPF control registers to original states */
-	snd_soc_write(codec, DA7218_IN_1_HPF_FILTER_CTRL, in_1_hpf_ctrl);
-	snd_soc_write(codec, DA7218_IN_2_HPF_FILTER_CTRL, in_2_hpf_ctrl);
+	snd_soc_component_write(component, DA7218_IN_1_HPF_FILTER_CTRL, in_1_hpf_ctrl);
+	snd_soc_component_write(component, DA7218_IN_2_HPF_FILTER_CTRL, in_2_hpf_ctrl);
 
 	/* Restore input filter control registers to original states */
-	snd_soc_write(codec, DA7218_IN_1L_FILTER_CTRL, in_1l_filt_ctrl);
-	snd_soc_write(codec, DA7218_IN_1R_FILTER_CTRL, in_1r_filt_ctrl);
-	snd_soc_write(codec, DA7218_IN_2L_FILTER_CTRL, in_2l_filt_ctrl);
-	snd_soc_write(codec, DA7218_IN_2R_FILTER_CTRL, in_2r_filt_ctrl);
+	snd_soc_component_write(component, DA7218_IN_1L_FILTER_CTRL, in_1l_filt_ctrl);
+	snd_soc_component_write(component, DA7218_IN_1R_FILTER_CTRL, in_1r_filt_ctrl);
+	snd_soc_component_write(component, DA7218_IN_2L_FILTER_CTRL, in_2l_filt_ctrl);
+	snd_soc_component_write(component, DA7218_IN_2R_FILTER_CTRL, in_2r_filt_ctrl);
 
 	/* Restore input mixer control registers to original state */
-	snd_soc_write(codec, DA7218_MIXIN_1_CTRL, mixin_1_ctrl);
-	snd_soc_write(codec, DA7218_MIXIN_2_CTRL, mixin_2_ctrl);
+	snd_soc_component_write(component, DA7218_MIXIN_1_CTRL, mixin_1_ctrl);
+	snd_soc_component_write(component, DA7218_MIXIN_2_CTRL, mixin_2_ctrl);
 
 	/* Restore MIC control registers to original states */
-	snd_soc_write(codec, DA7218_MIC_1_CTRL, mic_1_ctrl);
-	snd_soc_write(codec, DA7218_MIC_2_CTRL, mic_2_ctrl);
+	snd_soc_component_write(component, DA7218_MIC_1_CTRL, mic_1_ctrl);
+	snd_soc_component_write(component, DA7218_MIC_2_CTRL, mic_2_ctrl);
 }
 
 static int da7218_mixin_gain_put(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = snd_soc_put_volsw(kcontrol, ucontrol);
@@ -440,7 +440,7 @@ static int da7218_mixin_gain_put(struct snd_kcontrol *kcontrol,
 	 * make sure calibrated offsets are updated.
 	 */
 	if ((ret == 1) && (da7218->alc_en))
-		da7218_alc_calib(codec);
+		da7218_alc_calib(component);
 
 	return ret;
 }
@@ -450,8 +450,8 @@ static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *) kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	unsigned int lvalue = ucontrol->value.integer.value[0];
 	unsigned int rvalue = ucontrol->value.integer.value[1];
 	unsigned int lshift = mc->shift;
@@ -460,7 +460,7 @@ static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,
 
 	/* Force ALC offset calibration if enabling ALC */
 	if ((lvalue || rvalue) && (!da7218->alc_en))
-		da7218_alc_calib(codec);
+		da7218_alc_calib(component);
 
 	/* Update bits to detail which channels are enabled/disabled */
 	da7218->alc_en &= ~mask;
@@ -473,8 +473,8 @@ static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,
 static int da7218_tonegen_freq_get(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mixer_ctrl =
 		(struct soc_mixer_control *) kcontrol->private_value;
 	unsigned int reg = mixer_ctrl->reg;
@@ -497,8 +497,8 @@ static int da7218_tonegen_freq_get(struct snd_kcontrol *kcontrol,
 static int da7218_tonegen_freq_put(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mixer_ctrl =
 		(struct soc_mixer_control *) kcontrol->private_value;
 	unsigned int reg = mixer_ctrl->reg;
@@ -517,8 +517,8 @@ static int da7218_tonegen_freq_put(struct snd_kcontrol *kcontrol,
 static int da7218_mic_lvl_det_sw_put(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mixer_ctrl =
 		(struct soc_mixer_control *) kcontrol->private_value;
 	unsigned int lvalue = ucontrol->value.integer.value[0];
@@ -537,15 +537,15 @@ static int da7218_mic_lvl_det_sw_put(struct snd_kcontrol *kcontrol,
 	 * power the path (IN_FILTER widget events). This handling avoids
 	 * unwanted level detect events.
 	 */
-	return snd_soc_write(codec, mixer_ctrl->reg,
+	return snd_soc_component_write(component, mixer_ctrl->reg,
 			     (da7218->in_filt_en & da7218->mic_lvl_det_en));
 }
 
 static int da7218_mic_lvl_det_sw_get(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mixer_ctrl =
 		(struct soc_mixer_control *) kcontrol->private_value;
 	unsigned int lshift = mixer_ctrl->shift;
@@ -564,8 +564,8 @@ static int da7218_mic_lvl_det_sw_get(struct snd_kcontrol *kcontrol,
 static int da7218_biquad_coeff_get(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	struct soc_bytes_ext *bytes_ext =
 		(struct soc_bytes_ext *) kcontrol->private_value;
 
@@ -589,8 +589,8 @@ static int da7218_biquad_coeff_get(struct snd_kcontrol *kcontrol,
 static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	struct soc_bytes_ext *bytes_ext =
 		(struct soc_bytes_ext *) kcontrol->private_value;
 	u8 reg, out_filt1l;
@@ -617,8 +617,8 @@ static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,
 	}
 
 	/* Make sure at least out filter1 enabled to allow programming */
-	out_filt1l = snd_soc_read(codec, DA7218_OUT_1L_FILTER_CTRL);
-	snd_soc_write(codec, DA7218_OUT_1L_FILTER_CTRL,
+	out_filt1l = snd_soc_component_read32(component, DA7218_OUT_1L_FILTER_CTRL);
+	snd_soc_component_write(component, DA7218_OUT_1L_FILTER_CTRL,
 		      out_filt1l | DA7218_OUT_1L_FILTER_EN_MASK);
 
 	for (i = 0; i < bytes_ext->max; ++i) {
@@ -628,7 +628,7 @@ static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,
 	}
 
 	/* Restore filter to previous setting */
-	snd_soc_write(codec, DA7218_OUT_1L_FILTER_CTRL, out_filt1l);
+	snd_soc_component_write(component, DA7218_OUT_1L_FILTER_CTRL, out_filt1l);
 
 	return 0;
 }
@@ -1349,8 +1349,8 @@ static const struct snd_kcontrol_new da7218_st_out_filtr_mix_controls[] = {
 static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,
 				  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	u8 mask;
 
 	switch (w->reg) {
@@ -1389,7 +1389,7 @@ static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,
 	}
 
 	/* Enable configured level detection paths */
-	snd_soc_write(codec, DA7218_LVL_DET_CTRL,
+	snd_soc_component_write(component, DA7218_LVL_DET_CTRL,
 		      (da7218->in_filt_en & da7218->mic_lvl_det_en));
 
 	return 0;
@@ -1398,8 +1398,8 @@ static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,
 static int da7218_dai_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	u8 pll_ctrl, pll_status, refosc_cal;
 	int i;
 	bool success;
@@ -1408,14 +1408,14 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_POST_PMU:
 		if (da7218->master)
 			/* Enable DAI clks for master mode */
-			snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
+			snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,
 					    DA7218_DAI_CLK_EN_MASK,
 					    DA7218_DAI_CLK_EN_MASK);
 
 		/* Tune reference oscillator */
-		snd_soc_write(codec, DA7218_PLL_REFOSC_CAL,
+		snd_soc_component_write(component, DA7218_PLL_REFOSC_CAL,
 			      DA7218_PLL_REFOSC_CAL_START_MASK);
-		snd_soc_write(codec, DA7218_PLL_REFOSC_CAL,
+		snd_soc_component_write(component, DA7218_PLL_REFOSC_CAL,
 			      DA7218_PLL_REFOSC_CAL_START_MASK |
 			      DA7218_PLL_REFOSC_CAL_EN_MASK);
 
@@ -1423,7 +1423,7 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
 		i = 0;
 		success = false;
 		do {
-			refosc_cal = snd_soc_read(codec, DA7218_PLL_REFOSC_CAL);
+			refosc_cal = snd_soc_component_read32(component, DA7218_PLL_REFOSC_CAL);
 			if (!(refosc_cal & DA7218_PLL_REFOSC_CAL_START_MASK)) {
 				success = true;
 			} else {
@@ -1434,15 +1434,15 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
 		} while ((i < DA7218_REF_OSC_CHECK_TRIES) && (!success));
 
 		if (!success)
-			dev_warn(codec->dev,
+			dev_warn(component->dev,
 				 "Reference oscillator failed calibration\n");
 
 		/* PC synchronised to DAI */
-		snd_soc_write(codec, DA7218_PC_COUNT,
+		snd_soc_component_write(component, DA7218_PC_COUNT,
 			      DA7218_PC_RESYNC_AUTO_MASK);
 
 		/* If SRM not enabled, we don't need to check status */
-		pll_ctrl = snd_soc_read(codec, DA7218_PLL_CTRL);
+		pll_ctrl = snd_soc_component_read32(component, DA7218_PLL_CTRL);
 		if ((pll_ctrl & DA7218_PLL_MODE_MASK) != DA7218_PLL_MODE_SRM)
 			return 0;
 
@@ -1450,7 +1450,7 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
 		i = 0;
 		success = false;
 		do {
-			pll_status = snd_soc_read(codec, DA7218_PLL_STATUS);
+			pll_status = snd_soc_component_read32(component, DA7218_PLL_STATUS);
 			if (pll_status & DA7218_PLL_SRM_STATUS_SRM_LOCK) {
 				success = true;
 			} else {
@@ -1460,16 +1460,16 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
 		} while ((i < DA7218_SRM_CHECK_TRIES) && (!success));
 
 		if (!success)
-			dev_warn(codec->dev, "SRM failed to lock\n");
+			dev_warn(component->dev, "SRM failed to lock\n");
 
 		return 0;
 	case SND_SOC_DAPM_POST_PMD:
 		/* PC free-running */
-		snd_soc_write(codec, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
+		snd_soc_component_write(component, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
 
 		if (da7218->master)
 			/* Disable DAI clks for master mode */
-			snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
+			snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,
 					    DA7218_DAI_CLK_EN_MASK, 0);
 
 		return 0;
@@ -1481,8 +1481,8 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
 static int da7218_cp_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
 	/*
 	 * If this is DA7217 and we're using single supply for differential
@@ -1493,11 +1493,11 @@ static int da7218_cp_event(struct snd_soc_dapm_widget *w,
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
+		snd_soc_component_update_bits(component, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
 				    DA7218_CP_EN_MASK);
 		return 0;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
+		snd_soc_component_update_bits(component, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
 				    0);
 		return 0;
 	default:
@@ -1508,17 +1508,17 @@ static int da7218_cp_event(struct snd_soc_dapm_widget *w,
 static int da7218_hp_pga_event(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* Enable headphone output */
-		snd_soc_update_bits(codec, w->reg, DA7218_HP_AMP_OE_MASK,
+		snd_soc_component_update_bits(component, w->reg, DA7218_HP_AMP_OE_MASK,
 				    DA7218_HP_AMP_OE_MASK);
 		return 0;
 	case SND_SOC_DAPM_PRE_PMD:
 		/* Headphone output high impedance */
-		snd_soc_update_bits(codec, w->reg, DA7218_HP_AMP_OE_MASK, 0);
+		snd_soc_component_update_bits(component, w->reg, DA7218_HP_AMP_OE_MASK, 0);
 		return 0;
 	default:
 		return -EINVAL;
@@ -1813,8 +1813,8 @@ static const struct snd_soc_dapm_route da7218_audio_map[] = {
 static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	if (da7218->mclk_rate == freq)
@@ -1828,12 +1828,12 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 	switch (clk_id) {
 	case DA7218_CLKSRC_MCLK_SQR:
-		snd_soc_update_bits(codec, DA7218_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7218_PLL_CTRL,
 				    DA7218_PLL_MCLK_SQR_EN_MASK,
 				    DA7218_PLL_MCLK_SQR_EN_MASK);
 		break;
 	case DA7218_CLKSRC_MCLK:
-		snd_soc_update_bits(codec, DA7218_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7218_PLL_CTRL,
 				    DA7218_PLL_MCLK_SQR_EN_MASK, 0);
 		break;
 	default:
@@ -1859,8 +1859,8 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 			      int source, unsigned int fref, unsigned int fout)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
 	u8 pll_ctrl, indiv_bits, indiv;
 	u8 pll_frac_top, pll_frac_bot, pll_integer;
@@ -1869,7 +1869,7 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
 	/* Verify 2MHz - 54MHz MCLK provided, and set input divider */
 	if (da7218->mclk_rate < 2000000) {
-		dev_err(codec->dev, "PLL input clock %d below valid range\n",
+		dev_err(component->dev, "PLL input clock %d below valid range\n",
 			da7218->mclk_rate);
 		return -EINVAL;
 	} else if (da7218->mclk_rate <= 4500000) {
@@ -1888,7 +1888,7 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		indiv_bits = DA7218_PLL_INDIV_36_TO_54_MHZ;
 		indiv = DA7218_PLL_INDIV_36_TO_54_MHZ_VAL;
 	} else {
-		dev_err(codec->dev, "PLL input clock %d above valid range\n",
+		dev_err(component->dev, "PLL input clock %d above valid range\n",
 			da7218->mclk_rate);
 		return -EINVAL;
 	}
@@ -1899,7 +1899,7 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	switch (source) {
 	case DA7218_SYSCLK_MCLK:
 		pll_ctrl |= DA7218_PLL_MODE_BYPASS;
-		snd_soc_update_bits(codec, DA7218_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7218_PLL_CTRL,
 				    DA7218_PLL_INDIV_MASK |
 				    DA7218_PLL_MODE_MASK, pll_ctrl);
 		return 0;
@@ -1910,7 +1910,7 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		pll_ctrl |= DA7218_PLL_MODE_SRM;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid PLL config\n");
+		dev_err(component->dev, "Invalid PLL config\n");
 		return -EINVAL;
 	}
 
@@ -1922,10 +1922,10 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	pll_frac_bot = (frac_div) & DA7218_BYTE_MASK;
 
 	/* Write PLL config & dividers */
-	snd_soc_write(codec, DA7218_PLL_FRAC_TOP, pll_frac_top);
-	snd_soc_write(codec, DA7218_PLL_FRAC_BOT, pll_frac_bot);
-	snd_soc_write(codec, DA7218_PLL_INTEGER, pll_integer);
-	snd_soc_update_bits(codec, DA7218_PLL_CTRL,
+	snd_soc_component_write(component, DA7218_PLL_FRAC_TOP, pll_frac_top);
+	snd_soc_component_write(component, DA7218_PLL_FRAC_BOT, pll_frac_bot);
+	snd_soc_component_write(component, DA7218_PLL_INTEGER, pll_integer);
+	snd_soc_component_update_bits(component, DA7218_PLL_CTRL,
 			    DA7218_PLL_MODE_MASK | DA7218_PLL_INDIV_MASK,
 			    pll_ctrl);
 
@@ -1934,8 +1934,8 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
 static int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	u8 dai_clk_mode = 0, dai_ctrl = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -2012,8 +2012,8 @@ static int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	/* By default 64 BCLKs per WCLK is supported */
 	dai_clk_mode |= DA7218_DAI_BCLKS_PER_WCLK_64;
 
-	snd_soc_write(codec, DA7218_DAI_CLK_MODE, dai_clk_mode);
-	snd_soc_update_bits(codec, DA7218_DAI_CTRL, DA7218_DAI_FORMAT_MASK,
+	snd_soc_component_write(component, DA7218_DAI_CLK_MODE, dai_clk_mode);
+	snd_soc_component_update_bits(component, DA7218_DAI_CTRL, DA7218_DAI_FORMAT_MASK,
 			    dai_ctrl);
 
 	return 0;
@@ -2023,16 +2023,16 @@ static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,
 				   unsigned int tx_mask, unsigned int rx_mask,
 				   int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 dai_bclks_per_wclk;
 	u32 frame_size;
 
 	/* No channels enabled so disable TDM, revert to 64-bit frames */
 	if (!tx_mask) {
-		snd_soc_update_bits(codec, DA7218_DAI_TDM_CTRL,
+		snd_soc_component_update_bits(component, DA7218_DAI_TDM_CTRL,
 				    DA7218_DAI_TDM_CH_EN_MASK |
 				    DA7218_DAI_TDM_MODE_EN_MASK, 0);
-		snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
+		snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,
 				    DA7218_DAI_BCLKS_PER_WCLK_MASK,
 				    DA7218_DAI_BCLKS_PER_WCLK_64);
 		return 0;
@@ -2040,14 +2040,14 @@ static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,
 
 	/* Check we have valid slots */
 	if (fls(tx_mask) > DA7218_DAI_TDM_MAX_SLOTS) {
-		dev_err(codec->dev, "Invalid number of slots, max = %d\n",
+		dev_err(component->dev, "Invalid number of slots, max = %d\n",
 			DA7218_DAI_TDM_MAX_SLOTS);
 		return -EINVAL;
 	}
 
 	/* Check we have a valid offset given (first 2 bytes of rx_mask) */
 	if (rx_mask >> DA7218_2BYTE_SHIFT) {
-		dev_err(codec->dev, "Invalid slot offset, max = %d\n",
+		dev_err(component->dev, "Invalid slot offset, max = %d\n",
 			DA7218_2BYTE_MASK);
 		return -EINVAL;
 	}
@@ -2068,18 +2068,18 @@ static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,
 		dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_256;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid frame size\n");
+		dev_err(component->dev, "Invalid frame size\n");
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
+	snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,
 			    DA7218_DAI_BCLKS_PER_WCLK_MASK,
 			    dai_bclks_per_wclk);
-	snd_soc_write(codec, DA7218_DAI_OFFSET_LOWER,
+	snd_soc_component_write(component, DA7218_DAI_OFFSET_LOWER,
 		      (rx_mask & DA7218_BYTE_MASK));
-	snd_soc_write(codec, DA7218_DAI_OFFSET_UPPER,
+	snd_soc_component_write(component, DA7218_DAI_OFFSET_UPPER,
 		      ((rx_mask >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK));
-	snd_soc_update_bits(codec, DA7218_DAI_TDM_CTRL,
+	snd_soc_component_update_bits(component, DA7218_DAI_TDM_CTRL,
 			    DA7218_DAI_TDM_CH_EN_MASK |
 			    DA7218_DAI_TDM_MODE_EN_MASK,
 			    (tx_mask << DA7218_DAI_TDM_CH_EN_SHIFT) |
@@ -2092,7 +2092,7 @@ static int da7218_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 dai_ctrl = 0, fs;
 	unsigned int channels;
 
@@ -2115,7 +2115,7 @@ static int da7218_hw_params(struct snd_pcm_substream *substream,
 
 	channels = params_channels(params);
 	if ((channels < 1) || (channels > DA7218_DAI_CH_NUM_MAX)) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Invalid number of channels, only 1 to %d supported\n",
 			DA7218_DAI_CH_NUM_MAX);
 		return -EINVAL;
@@ -2160,11 +2160,11 @@ static int da7218_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, DA7218_DAI_CTRL,
+	snd_soc_component_update_bits(component, DA7218_DAI_CTRL,
 			    DA7218_DAI_WORD_LENGTH_MASK | DA7218_DAI_CH_NUM_MASK,
 			    dai_ctrl);
 	/* SRs tied for ADCs and DACs. */
-	snd_soc_write(codec, DA7218_SR,
+	snd_soc_component_write(component, DA7218_SR,
 		      (fs << DA7218_SR_DAC_SHIFT) | (fs << DA7218_SR_ADC_SHIFT));
 
 	return 0;
@@ -2208,15 +2208,15 @@ static struct snd_soc_dai_driver da7218_dai = {
  * HP Detect
  */
 
-int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int da7218_hpldet(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
 	if (da7218->dev_id == DA7217_DEV_ID)
 		return -EINVAL;
 
 	da7218->jack = jack;
-	snd_soc_update_bits(codec, DA7218_HPLDET_JACK,
+	snd_soc_component_update_bits(component, DA7218_HPLDET_JACK,
 			    DA7218_HPLDET_JACK_EN_MASK,
 			    jack ? DA7218_HPLDET_JACK_EN_MASK : 0);
 
@@ -2224,23 +2224,23 @@ int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 }
 EXPORT_SYMBOL_GPL(da7218_hpldet);
 
-static void da7218_micldet_irq(struct snd_soc_codec *codec)
+static void da7218_micldet_irq(struct snd_soc_component *component)
 {
 	char *envp[] = {
 		"EVENT=MIC_LEVEL_DETECT",
 		NULL,
 	};
 
-	kobject_uevent_env(&codec->dev->kobj, KOBJ_CHANGE, envp);
+	kobject_uevent_env(&component->dev->kobj, KOBJ_CHANGE, envp);
 }
 
-static void da7218_hpldet_irq(struct snd_soc_codec *codec)
+static void da7218_hpldet_irq(struct snd_soc_component *component)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	u8 jack_status;
 	int report;
 
-	jack_status = snd_soc_read(codec, DA7218_EVENT_STATUS);
+	jack_status = snd_soc_component_read32(component, DA7218_EVENT_STATUS);
 
 	if (jack_status & DA7218_HPLDET_JACK_STS_MASK)
 		report = SND_JACK_HEADPHONE;
@@ -2256,24 +2256,24 @@ static void da7218_hpldet_irq(struct snd_soc_codec *codec)
 
 static irqreturn_t da7218_irq_thread(int irq, void *data)
 {
-	struct snd_soc_codec *codec = data;
+	struct snd_soc_component *component = data;
 	u8 status;
 
 	/* Read IRQ status reg */
-	status = snd_soc_read(codec, DA7218_EVENT);
+	status = snd_soc_component_read32(component, DA7218_EVENT);
 	if (!status)
 		return IRQ_NONE;
 
 	/* Mic level detect */
 	if (status & DA7218_LVL_DET_EVENT_MASK)
-		da7218_micldet_irq(codec);
+		da7218_micldet_irq(component);
 
 	/* HP detect */
 	if (status & DA7218_HPLDET_JACK_EVENT_MASK)
-		da7218_hpldet_irq(codec);
+		da7218_hpldet_irq(component);
 
 	/* Clear interrupts */
-	snd_soc_write(codec, DA7218_EVENT, status);
+	snd_soc_component_write(component, DA7218_EVENT, status);
 
 	return IRQ_HANDLED;
 }
@@ -2300,7 +2300,7 @@ static inline int da7218_of_get_id(struct device *dev)
 }
 
 static enum da7218_micbias_voltage
-	da7218_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
+	da7218_of_micbias_lvl(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 1200:
@@ -2322,13 +2322,13 @@ static enum da7218_micbias_voltage
 	case 3000:
 		return DA7218_MICBIAS_3_0V;
 	default:
-		dev_warn(codec->dev, "Invalid micbias level");
+		dev_warn(component->dev, "Invalid micbias level");
 		return DA7218_MICBIAS_1_6V;
 	}
 }
 
 static enum da7218_mic_amp_in_sel
-	da7218_of_mic_amp_in_sel(struct snd_soc_codec *codec, const char *str)
+	da7218_of_mic_amp_in_sel(struct snd_soc_component *component, const char *str)
 {
 	if (!strcmp(str, "diff")) {
 		return DA7218_MIC_AMP_IN_SEL_DIFF;
@@ -2337,39 +2337,39 @@ static enum da7218_mic_amp_in_sel
 	} else if (!strcmp(str, "se_n")) {
 		return DA7218_MIC_AMP_IN_SEL_SE_N;
 	} else {
-		dev_warn(codec->dev, "Invalid mic input type selection");
+		dev_warn(component->dev, "Invalid mic input type selection");
 		return DA7218_MIC_AMP_IN_SEL_DIFF;
 	}
 }
 
 static enum da7218_dmic_data_sel
-	da7218_of_dmic_data_sel(struct snd_soc_codec *codec, const char *str)
+	da7218_of_dmic_data_sel(struct snd_soc_component *component, const char *str)
 {
 	if (!strcmp(str, "lrise_rfall")) {
 		return DA7218_DMIC_DATA_LRISE_RFALL;
 	} else if (!strcmp(str, "lfall_rrise")) {
 		return DA7218_DMIC_DATA_LFALL_RRISE;
 	} else {
-		dev_warn(codec->dev, "Invalid DMIC data type selection");
+		dev_warn(component->dev, "Invalid DMIC data type selection");
 		return DA7218_DMIC_DATA_LRISE_RFALL;
 	}
 }
 
 static enum da7218_dmic_samplephase
-	da7218_of_dmic_samplephase(struct snd_soc_codec *codec, const char *str)
+	da7218_of_dmic_samplephase(struct snd_soc_component *component, const char *str)
 {
 	if (!strcmp(str, "on_clkedge")) {
 		return DA7218_DMIC_SAMPLE_ON_CLKEDGE;
 	} else if (!strcmp(str, "between_clkedge")) {
 		return DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE;
 	} else {
-		dev_warn(codec->dev, "Invalid DMIC sample phase");
+		dev_warn(component->dev, "Invalid DMIC sample phase");
 		return DA7218_DMIC_SAMPLE_ON_CLKEDGE;
 	}
 }
 
 static enum da7218_dmic_clk_rate
-	da7218_of_dmic_clkrate(struct snd_soc_codec *codec, u32 val)
+	da7218_of_dmic_clkrate(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 1500000:
@@ -2377,13 +2377,13 @@ static enum da7218_dmic_clk_rate
 	case 3000000:
 		return DA7218_DMIC_CLK_3_0MHZ;
 	default:
-		dev_warn(codec->dev, "Invalid DMIC clock rate");
+		dev_warn(component->dev, "Invalid DMIC clock rate");
 		return DA7218_DMIC_CLK_3_0MHZ;
 	}
 }
 
 static enum da7218_hpldet_jack_rate
-	da7218_of_jack_rate(struct snd_soc_codec *codec, u32 val)
+	da7218_of_jack_rate(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 5:
@@ -2403,13 +2403,13 @@ static enum da7218_hpldet_jack_rate
 	case 640:
 		return DA7218_HPLDET_JACK_RATE_640US;
 	default:
-		dev_warn(codec->dev, "Invalid jack detect rate");
+		dev_warn(component->dev, "Invalid jack detect rate");
 		return DA7218_HPLDET_JACK_RATE_40US;
 	}
 }
 
 static enum da7218_hpldet_jack_debounce
-	da7218_of_jack_debounce(struct snd_soc_codec *codec, u32 val)
+	da7218_of_jack_debounce(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 0:
@@ -2421,13 +2421,13 @@ static enum da7218_hpldet_jack_debounce
 	case 4:
 		return DA7218_HPLDET_JACK_DEBOUNCE_4;
 	default:
-		dev_warn(codec->dev, "Invalid jack debounce");
+		dev_warn(component->dev, "Invalid jack debounce");
 		return DA7218_HPLDET_JACK_DEBOUNCE_2;
 	}
 }
 
 static enum da7218_hpldet_jack_thr
-	da7218_of_jack_thr(struct snd_soc_codec *codec, u32 val)
+	da7218_of_jack_thr(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 84:
@@ -2439,76 +2439,76 @@ static enum da7218_hpldet_jack_thr
 	case 96:
 		return DA7218_HPLDET_JACK_THR_96PCT;
 	default:
-		dev_warn(codec->dev, "Invalid jack threshold level");
+		dev_warn(component->dev, "Invalid jack threshold level");
 		return DA7218_HPLDET_JACK_THR_84PCT;
 	}
 }
 
-static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
+static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_component *component)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
-	struct device_node *np = codec->dev->of_node;
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
+	struct device_node *np = component->dev->of_node;
 	struct device_node *hpldet_np;
 	struct da7218_pdata *pdata;
 	struct da7218_hpldet_pdata *hpldet_pdata;
 	const char *of_str;
 	u32 of_val32;
 
-	pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
+	pdata = devm_kzalloc(component->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return NULL;
 
 	if (of_property_read_u32(np, "dlg,micbias1-lvl-millivolt", &of_val32) >= 0)
-		pdata->micbias1_lvl = da7218_of_micbias_lvl(codec, of_val32);
+		pdata->micbias1_lvl = da7218_of_micbias_lvl(component, of_val32);
 	else
 		pdata->micbias1_lvl = DA7218_MICBIAS_1_6V;
 
 	if (of_property_read_u32(np, "dlg,micbias2-lvl-millivolt", &of_val32) >= 0)
-		pdata->micbias2_lvl = da7218_of_micbias_lvl(codec, of_val32);
+		pdata->micbias2_lvl = da7218_of_micbias_lvl(component, of_val32);
 	else
 		pdata->micbias2_lvl = DA7218_MICBIAS_1_6V;
 
 	if (!of_property_read_string(np, "dlg,mic1-amp-in-sel", &of_str))
 		pdata->mic1_amp_in_sel =
-			da7218_of_mic_amp_in_sel(codec, of_str);
+			da7218_of_mic_amp_in_sel(component, of_str);
 	else
 		pdata->mic1_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;
 
 	if (!of_property_read_string(np, "dlg,mic2-amp-in-sel", &of_str))
 		pdata->mic2_amp_in_sel =
-			da7218_of_mic_amp_in_sel(codec, of_str);
+			da7218_of_mic_amp_in_sel(component, of_str);
 	else
 		pdata->mic2_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;
 
 	if (!of_property_read_string(np, "dlg,dmic1-data-sel", &of_str))
-		pdata->dmic1_data_sel =	da7218_of_dmic_data_sel(codec, of_str);
+		pdata->dmic1_data_sel =	da7218_of_dmic_data_sel(component, of_str);
 	else
 		pdata->dmic1_data_sel =	DA7218_DMIC_DATA_LRISE_RFALL;
 
 	if (!of_property_read_string(np, "dlg,dmic1-samplephase", &of_str))
 		pdata->dmic1_samplephase =
-			da7218_of_dmic_samplephase(codec, of_str);
+			da7218_of_dmic_samplephase(component, of_str);
 	else
 		pdata->dmic1_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;
 
 	if (of_property_read_u32(np, "dlg,dmic1-clkrate-hz", &of_val32) >= 0)
-		pdata->dmic1_clk_rate = da7218_of_dmic_clkrate(codec, of_val32);
+		pdata->dmic1_clk_rate = da7218_of_dmic_clkrate(component, of_val32);
 	else
 		pdata->dmic1_clk_rate = DA7218_DMIC_CLK_3_0MHZ;
 
 	if (!of_property_read_string(np, "dlg,dmic2-data-sel", &of_str))
-		pdata->dmic2_data_sel = da7218_of_dmic_data_sel(codec, of_str);
+		pdata->dmic2_data_sel = da7218_of_dmic_data_sel(component, of_str);
 	else
 		pdata->dmic2_data_sel =	DA7218_DMIC_DATA_LRISE_RFALL;
 
 	if (!of_property_read_string(np, "dlg,dmic2-samplephase", &of_str))
 		pdata->dmic2_samplephase =
-			da7218_of_dmic_samplephase(codec, of_str);
+			da7218_of_dmic_samplephase(component, of_str);
 	else
 		pdata->dmic2_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;
 
 	if (of_property_read_u32(np, "dlg,dmic2-clkrate-hz", &of_val32) >= 0)
-		pdata->dmic2_clk_rate = da7218_of_dmic_clkrate(codec, of_val32);
+		pdata->dmic2_clk_rate = da7218_of_dmic_clkrate(component, of_val32);
 	else
 		pdata->dmic2_clk_rate = DA7218_DMIC_CLK_3_0MHZ;
 
@@ -2522,7 +2522,7 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
 		if (!hpldet_np)
 			return pdata;
 
-		hpldet_pdata = devm_kzalloc(codec->dev, sizeof(*hpldet_pdata),
+		hpldet_pdata = devm_kzalloc(component->dev, sizeof(*hpldet_pdata),
 					    GFP_KERNEL);
 		if (!hpldet_pdata) {
 			of_node_put(hpldet_np);
@@ -2533,14 +2533,14 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
 		if (of_property_read_u32(hpldet_np, "dlg,jack-rate-us",
 					 &of_val32) >= 0)
 			hpldet_pdata->jack_rate =
-				da7218_of_jack_rate(codec, of_val32);
+				da7218_of_jack_rate(component, of_val32);
 		else
 			hpldet_pdata->jack_rate = DA7218_HPLDET_JACK_RATE_40US;
 
 		if (of_property_read_u32(hpldet_np, "dlg,jack-debounce",
 					 &of_val32) >= 0)
 			hpldet_pdata->jack_debounce =
-				da7218_of_jack_debounce(codec, of_val32);
+				da7218_of_jack_debounce(component, of_val32);
 		else
 			hpldet_pdata->jack_debounce =
 				DA7218_HPLDET_JACK_DEBOUNCE_2;
@@ -2548,7 +2548,7 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
 		if (of_property_read_u32(hpldet_np, "dlg,jack-threshold-pct",
 					 &of_val32) >= 0)
 			hpldet_pdata->jack_thr =
-				da7218_of_jack_thr(codec, of_val32);
+				da7218_of_jack_thr(component, of_val32);
 		else
 			hpldet_pdata->jack_thr = DA7218_HPLDET_JACK_THR_84PCT;
 
@@ -2572,10 +2572,10 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
  * Codec driver functions
  */
 
-static int da7218_set_bias_level(struct snd_soc_codec *codec,
+static int da7218_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -2583,11 +2583,11 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		/* Enable MCLK for transition to ON state */
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
 			if (da7218->mclk) {
 				ret = clk_prepare_enable(da7218->mclk);
 				if (ret) {
-					dev_err(codec->dev, "Failed to enable mclk\n");
+					dev_err(component->dev, "Failed to enable mclk\n");
 					return ret;
 				}
 			}
@@ -2595,14 +2595,14 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
 
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Master bias */
-			snd_soc_update_bits(codec, DA7218_REFERENCES,
+			snd_soc_component_update_bits(component, DA7218_REFERENCES,
 					    DA7218_BIAS_EN_MASK,
 					    DA7218_BIAS_EN_MASK);
 
 			/* Internal LDO */
-			snd_soc_update_bits(codec, DA7218_LDO_CTRL,
+			snd_soc_component_update_bits(component, DA7218_LDO_CTRL,
 					    DA7218_LDO_EN_MASK,
 					    DA7218_LDO_EN_MASK);
 		} else {
@@ -2615,11 +2615,11 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
 		/* Only disable if jack detection disabled */
 		if (!da7218->jack) {
 			/* Internal LDO */
-			snd_soc_update_bits(codec, DA7218_LDO_CTRL,
+			snd_soc_component_update_bits(component, DA7218_LDO_CTRL,
 					    DA7218_LDO_EN_MASK, 0);
 
 			/* Master bias */
-			snd_soc_update_bits(codec, DA7218_REFERENCES,
+			snd_soc_component_update_bits(component, DA7218_REFERENCES,
 					    DA7218_BIAS_EN_MASK, 0);
 		}
 		break;
@@ -2634,9 +2634,9 @@ static const char *da7218_supply_names[DA7218_NUM_SUPPLIES] = {
 	[DA7218_SUPPLY_VDDIO] = "VDDIO",
 };
 
-static int da7218_handle_supplies(struct snd_soc_codec *codec)
+static int da7218_handle_supplies(struct snd_soc_component *component)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	struct regulator *vddio;
 	u8 io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_2_5V_3_6V;
 	int i, ret;
@@ -2645,10 +2645,10 @@ static int da7218_handle_supplies(struct snd_soc_codec *codec)
 	for (i = 0; i < DA7218_NUM_SUPPLIES; ++i)
 		da7218->supplies[i].supply = da7218_supply_names[i];
 
-	ret = devm_regulator_bulk_get(codec->dev, DA7218_NUM_SUPPLIES,
+	ret = devm_regulator_bulk_get(component->dev, DA7218_NUM_SUPPLIES,
 				      da7218->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to get supplies\n");
+		dev_err(component->dev, "Failed to get supplies\n");
 		return ret;
 	}
 
@@ -2656,29 +2656,29 @@ static int da7218_handle_supplies(struct snd_soc_codec *codec)
 	vddio = da7218->supplies[DA7218_SUPPLY_VDDIO].consumer;
 	ret = regulator_get_voltage(vddio);
 	if (ret < 1500000)
-		dev_warn(codec->dev, "Invalid VDDIO voltage\n");
+		dev_warn(component->dev, "Invalid VDDIO voltage\n");
 	else if (ret < 2500000)
 		io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_1_5V_2_5V;
 
 	/* Enable main supplies */
 	ret = regulator_bulk_enable(DA7218_NUM_SUPPLIES, da7218->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to enable supplies\n");
+		dev_err(component->dev, "Failed to enable supplies\n");
 		return ret;
 	}
 
 	/* Ensure device in active mode */
-	snd_soc_write(codec, DA7218_SYSTEM_ACTIVE, DA7218_SYSTEM_ACTIVE_MASK);
+	snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, DA7218_SYSTEM_ACTIVE_MASK);
 
 	/* Update IO voltage level range */
-	snd_soc_write(codec, DA7218_IO_CTRL, io_voltage_lvl);
+	snd_soc_component_write(component, DA7218_IO_CTRL, io_voltage_lvl);
 
 	return 0;
 }
 
-static void da7218_handle_pdata(struct snd_soc_codec *codec)
+static void da7218_handle_pdata(struct snd_soc_component *component)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	struct da7218_pdata *pdata = da7218->pdata;
 
 	if (pdata) {
@@ -2719,14 +2719,14 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
 			break;
 		}
 
-		snd_soc_write(codec, DA7218_MICBIAS_CTRL, micbias_lvl);
+		snd_soc_component_write(component, DA7218_MICBIAS_CTRL, micbias_lvl);
 
 		/* Mic */
 		switch (pdata->mic1_amp_in_sel) {
 		case DA7218_MIC_AMP_IN_SEL_DIFF:
 		case DA7218_MIC_AMP_IN_SEL_SE_P:
 		case DA7218_MIC_AMP_IN_SEL_SE_N:
-			snd_soc_write(codec, DA7218_MIC_1_SELECT,
+			snd_soc_component_write(component, DA7218_MIC_1_SELECT,
 				      pdata->mic1_amp_in_sel);
 			break;
 		}
@@ -2735,7 +2735,7 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
 		case DA7218_MIC_AMP_IN_SEL_DIFF:
 		case DA7218_MIC_AMP_IN_SEL_SE_P:
 		case DA7218_MIC_AMP_IN_SEL_SE_N:
-			snd_soc_write(codec, DA7218_MIC_2_SELECT,
+			snd_soc_component_write(component, DA7218_MIC_2_SELECT,
 				      pdata->mic2_amp_in_sel);
 			break;
 		}
@@ -2765,7 +2765,7 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
 			break;
 		}
 
-		snd_soc_update_bits(codec, DA7218_DMIC_1_CTRL,
+		snd_soc_component_update_bits(component, DA7218_DMIC_1_CTRL,
 				    DA7218_DMIC_1_DATA_SEL_MASK |
 				    DA7218_DMIC_1_SAMPLEPHASE_MASK |
 				    DA7218_DMIC_1_CLK_RATE_MASK, dmic_cfg);
@@ -2795,7 +2795,7 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
 			break;
 		}
 
-		snd_soc_update_bits(codec, DA7218_DMIC_2_CTRL,
+		snd_soc_component_update_bits(component, DA7218_DMIC_2_CTRL,
 				    DA7218_DMIC_2_DATA_SEL_MASK |
 				    DA7218_DMIC_2_SAMPLEPHASE_MASK |
 				    DA7218_DMIC_2_CLK_RATE_MASK, dmic_cfg);
@@ -2806,9 +2806,9 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
 				pdata->hp_diff_single_supply;
 
 			if (da7218->hp_single_supply) {
-				snd_soc_write(codec, DA7218_HP_DIFF_UNLOCK,
+				snd_soc_component_write(component, DA7218_HP_DIFF_UNLOCK,
 					      DA7218_HP_DIFF_UNLOCK_VAL);
-				snd_soc_update_bits(codec, DA7218_HP_DIFF_CTRL,
+				snd_soc_component_update_bits(component, DA7218_HP_DIFF_CTRL,
 						    DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK,
 						    DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK);
 			}
@@ -2857,7 +2857,7 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
 					 DA7218_HPLDET_JACK_THR_SHIFT);
 				break;
 			}
-			snd_soc_update_bits(codec, DA7218_HPLDET_JACK,
+			snd_soc_component_update_bits(component, DA7218_HPLDET_JACK,
 					    DA7218_HPLDET_JACK_RATE_MASK |
 					    DA7218_HPLDET_JACK_DEBOUNCE_MASK |
 					    DA7218_HPLDET_JACK_THR_MASK,
@@ -2873,31 +2873,31 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
 			if (hpldet_pdata->discharge)
 				hpldet_cfg |= DA7218_HPLDET_DISCHARGE_EN_MASK;
 
-			snd_soc_write(codec, DA7218_HPLDET_CTRL, hpldet_cfg);
+			snd_soc_component_write(component, DA7218_HPLDET_CTRL, hpldet_cfg);
 		}
 	}
 }
 
-static int da7218_probe(struct snd_soc_codec *codec)
+static int da7218_probe(struct snd_soc_component *component)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	/* Regulator configuration */
-	ret = da7218_handle_supplies(codec);
+	ret = da7218_handle_supplies(component);
 	if (ret)
 		return ret;
 
 	/* Handle DT/Platform data */
-	if (codec->dev->of_node)
-		da7218->pdata = da7218_of_to_pdata(codec);
+	if (component->dev->of_node)
+		da7218->pdata = da7218_of_to_pdata(component);
 	else
-		da7218->pdata = dev_get_platdata(codec->dev);
+		da7218->pdata = dev_get_platdata(component->dev);
 
-	da7218_handle_pdata(codec);
+	da7218_handle_pdata(component);
 
 	/* Check if MCLK provided, if not the clock is NULL */
-	da7218->mclk = devm_clk_get(codec->dev, "mclk");
+	da7218->mclk = devm_clk_get(component->dev, "mclk");
 	if (IS_ERR(da7218->mclk)) {
 		if (PTR_ERR(da7218->mclk) != -ENOENT) {
 			ret = PTR_ERR(da7218->mclk);
@@ -2908,74 +2908,74 @@ static int da7218_probe(struct snd_soc_codec *codec)
 	}
 
 	/* Default PC to free-running */
-	snd_soc_write(codec, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
+	snd_soc_component_write(component, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
 
 	/*
 	 * Default Output Filter mixers to off otherwise DAPM will power
 	 * Mic to HP passthrough paths by default at startup.
 	 */
-	snd_soc_write(codec, DA7218_DROUTING_OUTFILT_1L, 0);
-	snd_soc_write(codec, DA7218_DROUTING_OUTFILT_1R, 0);
+	snd_soc_component_write(component, DA7218_DROUTING_OUTFILT_1L, 0);
+	snd_soc_component_write(component, DA7218_DROUTING_OUTFILT_1R, 0);
 
 	/* Default CP to normal load, power mode */
-	snd_soc_update_bits(codec, DA7218_CP_CTRL,
+	snd_soc_component_update_bits(component, DA7218_CP_CTRL,
 			    DA7218_CP_SMALL_SWITCH_FREQ_EN_MASK, 0);
 
 	/* Default gain ramping */
-	snd_soc_update_bits(codec, DA7218_MIXIN_1_CTRL,
+	snd_soc_component_update_bits(component, DA7218_MIXIN_1_CTRL,
 			    DA7218_MIXIN_1_AMP_RAMP_EN_MASK,
 			    DA7218_MIXIN_1_AMP_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_MIXIN_2_CTRL,
+	snd_soc_component_update_bits(component, DA7218_MIXIN_2_CTRL,
 			    DA7218_MIXIN_2_AMP_RAMP_EN_MASK,
 			    DA7218_MIXIN_2_AMP_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_IN_1L_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_1L_FILTER_CTRL,
 			    DA7218_IN_1L_RAMP_EN_MASK,
 			    DA7218_IN_1L_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_IN_1R_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_1R_FILTER_CTRL,
 			    DA7218_IN_1R_RAMP_EN_MASK,
 			    DA7218_IN_1R_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_IN_2L_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_2L_FILTER_CTRL,
 			    DA7218_IN_2L_RAMP_EN_MASK,
 			    DA7218_IN_2L_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_IN_2R_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_IN_2R_FILTER_CTRL,
 			    DA7218_IN_2R_RAMP_EN_MASK,
 			    DA7218_IN_2R_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_DGS_GAIN_CTRL,
+	snd_soc_component_update_bits(component, DA7218_DGS_GAIN_CTRL,
 			    DA7218_DGS_RAMP_EN_MASK, DA7218_DGS_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_OUT_1L_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_OUT_1L_FILTER_CTRL,
 			    DA7218_OUT_1L_RAMP_EN_MASK,
 			    DA7218_OUT_1L_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_OUT_1R_FILTER_CTRL,
+	snd_soc_component_update_bits(component, DA7218_OUT_1R_FILTER_CTRL,
 			    DA7218_OUT_1R_RAMP_EN_MASK,
 			    DA7218_OUT_1R_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA7218_HP_L_CTRL,
 			    DA7218_HP_L_AMP_RAMP_EN_MASK,
 			    DA7218_HP_L_AMP_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7218_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA7218_HP_R_CTRL,
 			    DA7218_HP_R_AMP_RAMP_EN_MASK,
 			    DA7218_HP_R_AMP_RAMP_EN_MASK);
 
 	/* Default infinite tone gen, start/stop by Kcontrol */
-	snd_soc_write(codec, DA7218_TONE_GEN_CYCLES, DA7218_BEEP_CYCLES_MASK);
+	snd_soc_component_write(component, DA7218_TONE_GEN_CYCLES, DA7218_BEEP_CYCLES_MASK);
 
 	/* DA7217 specific config */
 	if (da7218->dev_id == DA7217_DEV_ID) {
-		snd_soc_update_bits(codec, DA7218_HP_DIFF_CTRL,
+		snd_soc_component_update_bits(component, DA7218_HP_DIFF_CTRL,
 				    DA7218_HP_AMP_DIFF_MODE_EN_MASK,
 				    DA7218_HP_AMP_DIFF_MODE_EN_MASK);
 
 		/* Only DA7218 supports HP detect, mask off for DA7217 */
-		snd_soc_write(codec, DA7218_EVENT_MASK,
+		snd_soc_component_write(component, DA7218_EVENT_MASK,
 			      DA7218_HPLDET_JACK_EVENT_IRQ_MSK_MASK);
 	}
 
 	if (da7218->irq) {
-		ret = devm_request_threaded_irq(codec->dev, da7218->irq, NULL,
+		ret = devm_request_threaded_irq(component->dev, da7218->irq, NULL,
 						da7218_irq_thread,
 						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-						"da7218", codec);
+						"da7218", component);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
+			dev_err(component->dev, "Failed to request IRQ %d: %d\n",
 				da7218->irq, ret);
 			goto err_disable_reg;
 		}
@@ -2990,39 +2990,37 @@ static int da7218_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int da7218_remove(struct snd_soc_codec *codec)
+static void da7218_remove(struct snd_soc_component *component)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
 	regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int da7218_suspend(struct snd_soc_codec *codec)
+static int da7218_suspend(struct snd_soc_component *component)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
-	da7218_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	da7218_set_bias_level(component, SND_SOC_BIAS_OFF);
 
 	/* Put device into standby mode if jack detection disabled */
 	if (!da7218->jack)
-		snd_soc_write(codec, DA7218_SYSTEM_ACTIVE, 0);
+		snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, 0);
 
 	return 0;
 }
 
-static int da7218_resume(struct snd_soc_codec *codec)
+static int da7218_resume(struct snd_soc_component *component)
 {
-	struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
 	/* Put device into active mode if previously moved to standby */
 	if (!da7218->jack)
-		snd_soc_write(codec, DA7218_SYSTEM_ACTIVE,
+		snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE,
 			      DA7218_SYSTEM_ACTIVE_MASK);
 
-	da7218_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	da7218_set_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	return 0;
 }
@@ -3031,21 +3029,22 @@ static int da7218_resume(struct snd_soc_codec *codec)
 #define da7218_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_da7218 = {
+static const struct snd_soc_component_driver soc_component_dev_da7218 = {
 	.probe			= da7218_probe,
 	.remove			= da7218_remove,
 	.suspend		= da7218_suspend,
 	.resume			= da7218_resume,
 	.set_bias_level		= da7218_set_bias_level,
-
-	.component_driver = {
-		.controls		= da7218_snd_controls,
-		.num_controls		= ARRAY_SIZE(da7218_snd_controls),
-		.dapm_widgets		= da7218_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(da7218_dapm_widgets),
-		.dapm_routes		= da7218_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(da7218_audio_map),
-	},
+	.controls		= da7218_snd_controls,
+	.num_controls		= ARRAY_SIZE(da7218_snd_controls),
+	.dapm_widgets		= da7218_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(da7218_dapm_widgets),
+	.dapm_routes		= da7218_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(da7218_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 
@@ -3295,21 +3294,15 @@ static int da7218_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_da7218, &da7218_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_da7218, &da7218_dai, 1);
 	if (ret < 0) {
-		dev_err(&i2c->dev, "Failed to register da7218 codec: %d\n",
+		dev_err(&i2c->dev, "Failed to register da7218 component: %d\n",
 			ret);
 	}
 	return ret;
 }
 
-static int da7218_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id da7218_i2c_id[] = {
 	{ "da7217", DA7217_DEV_ID },
 	{ "da7218", DA7218_DEV_ID },
@@ -3323,7 +3316,6 @@ static struct i2c_driver da7218_i2c_driver = {
 		.of_match_table = of_match_ptr(da7218_of_match),
 	},
 	.probe		= da7218_i2c_probe,
-	.remove		= da7218_i2c_remove,
 	.id_table	= da7218_i2c_id,
 };
 
diff --git a/sound/soc/codecs/da7218.h b/sound/soc/codecs/da7218.h
index 4f7ec21..19e6cee 100644
--- a/sound/soc/codecs/da7218.h
+++ b/sound/soc/codecs/da7218.h
@@ -1410,6 +1410,6 @@ struct da7218_priv {
 };
 
 /* HP detect control */
-int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int da7218_hpldet(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #endif /* _DA7218_H */
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c
index 1d1d10d..a49ab75 100644
--- a/sound/soc/codecs/da7219-aad.c
+++ b/sound/soc/codecs/da7219-aad.c
@@ -32,9 +32,9 @@
  * Detection control
  */
 
-void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
 	da7219->aad->jack = jack;
 	da7219->aad->jack_inserted = false;
@@ -43,7 +43,7 @@ void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 	snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
 
 	/* Enable/Disable jack detection */
-	snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 			    DA7219_ACCDET_EN_MASK,
 			    (jack ? DA7219_ACCDET_EN_MASK : 0));
 }
@@ -57,17 +57,17 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
 {
 	struct da7219_aad_priv *da7219_aad =
 		container_of(work, struct da7219_aad_priv, btn_det_work);
-	struct snd_soc_codec *codec = da7219_aad->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = da7219_aad->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	u8 statusa, micbias_ctrl;
 	bool micbias_up = false;
 	int retries = 0;
 
 	/* Drive headphones/lineout */
-	snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 			    DA7219_HP_L_AMP_OE_MASK,
 			    DA7219_HP_L_AMP_OE_MASK);
-	snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 			    DA7219_HP_R_AMP_OE_MASK,
 			    DA7219_HP_R_AMP_OE_MASK);
 
@@ -76,7 +76,7 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
 	snd_soc_dapm_sync(dapm);
 
 	do {
-		statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
+		statusa = snd_soc_component_read32(component, DA7219_ACCDET_STATUS_A);
 		if (statusa & DA7219_MICBIAS_UP_STS_MASK)
 			micbias_up = true;
 		else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
@@ -84,7 +84,7 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
 	} while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
 
 	if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES)
-		dev_warn(codec->dev, "Mic bias status check timed out");
+		dev_warn(component->dev, "Mic bias status check timed out");
 
 	/*
 	 * Mic bias pulse required to enable mic, must be done before enabling
@@ -92,16 +92,16 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
 	 */
 	if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
 		/* Pulse higher level voltage */
-		micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
-		snd_soc_update_bits(codec, DA7219_MICBIAS_CTRL,
+		micbias_ctrl = snd_soc_component_read32(component, DA7219_MICBIAS_CTRL);
+		snd_soc_component_update_bits(component, DA7219_MICBIAS_CTRL,
 				    DA7219_MICBIAS1_LEVEL_MASK,
 				    da7219_aad->micbias_pulse_lvl);
 		msleep(da7219_aad->micbias_pulse_time);
-		snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_ctrl);
+		snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_ctrl);
 
 	}
 
-	snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 			    DA7219_BUTTON_CONFIG_MASK,
 			    da7219_aad->btn_cfg);
 }
@@ -110,9 +110,9 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 {
 	struct da7219_aad_priv *da7219_aad =
 		container_of(work, struct da7219_aad_priv, hptest_work);
-	struct snd_soc_codec *codec = da7219_aad->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = da7219_aad->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
 	u16 tonegen_freq_hptest;
 	u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8;
@@ -127,7 +127,7 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 	if (da7219->mclk) {
 		ret = clk_prepare_enable(da7219->mclk);
 		if (ret) {
-			dev_err(codec->dev, "Failed to enable mclk - %d\n", ret);
+			dev_err(component->dev, "Failed to enable mclk - %d\n", ret);
 			mutex_unlock(&da7219->pll_lock);
 			mutex_unlock(&da7219->ctrl_lock);
 			snd_soc_dapm_mutex_unlock(dapm);
@@ -142,90 +142,90 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 	 * If MCLK is present, but PLL is not enabled then we enable it here to
 	 * ensure a consistent detection procedure.
 	 */
-	pll_srm_sts = snd_soc_read(codec, DA7219_PLL_SRM_STS);
+	pll_srm_sts = snd_soc_component_read32(component, DA7219_PLL_SRM_STS);
 	if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) {
 		tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
 
-		pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL);
+		pll_ctrl = snd_soc_component_read32(component, DA7219_PLL_CTRL);
 		if ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS)
-			da7219_set_pll(codec, DA7219_SYSCLK_PLL,
+			da7219_set_pll(component, DA7219_SYSCLK_PLL,
 				       DA7219_PLL_FREQ_OUT_98304);
 	} else {
 		tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
 	}
 
 	/* Ensure gain ramping at fastest rate */
-	gain_ramp_ctrl = snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
-	snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
+	gain_ramp_ctrl = snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL);
+	snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
 
 	/* Bypass cache so it saves current settings */
 	regcache_cache_bypass(da7219->regmap, true);
 
 	/* Make sure Tone Generator is disabled */
-	snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
+	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
 
 	/* Enable HPTest block, 1KOhms check */
-	snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
+	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
 			    DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK,
 			    DA7219_HPTEST_EN_MASK |
 			    DA7219_HPTEST_RES_SEL_1KOHMS);
 
 	/* Set gains to 0db */
-	snd_soc_write(codec, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
-	snd_soc_write(codec, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
-	snd_soc_write(codec, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
-	snd_soc_write(codec, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
+	snd_soc_component_write(component, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
+	snd_soc_component_write(component, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
+	snd_soc_component_write(component, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
+	snd_soc_component_write(component, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
 
 	/* Disable DAC filters, EQs and soft mute */
-	snd_soc_update_bits(codec, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
+	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
 			    0);
-	snd_soc_update_bits(codec, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
+	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
 			    0);
-	snd_soc_update_bits(codec, DA7219_DAC_FILTERS5,
+	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS5,
 			    DA7219_DAC_SOFTMUTE_EN_MASK, 0);
 
 	/* Enable HP left & right paths */
-	snd_soc_update_bits(codec, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
+	snd_soc_component_update_bits(component, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
 			    DA7219_CP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_DIG_ROUTING_DAC,
+	snd_soc_component_update_bits(component, DA7219_DIG_ROUTING_DAC,
 			    DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK,
 			    DA7219_DAC_L_SRC_TONEGEN |
 			    DA7219_DAC_R_SRC_TONEGEN);
-	snd_soc_update_bits(codec, DA7219_DAC_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL,
 			    DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK,
 			    DA7219_DAC_L_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_DAC_R_CTRL,
+	snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL,
 			    DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK,
 			    DA7219_DAC_R_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_MIXOUT_L_SELECT,
+	snd_soc_component_update_bits(component, DA7219_MIXOUT_L_SELECT,
 			    DA7219_MIXOUT_L_MIX_SELECT_MASK,
 			    DA7219_MIXOUT_L_MIX_SELECT_MASK);
-	snd_soc_update_bits(codec, DA7219_MIXOUT_R_SELECT,
+	snd_soc_component_update_bits(component, DA7219_MIXOUT_R_SELECT,
 			    DA7219_MIXOUT_R_MIX_SELECT_MASK,
 			    DA7219_MIXOUT_R_MIX_SELECT_MASK);
-	snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1L,
+	snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1L,
 			    DA7219_OUTFILT_ST_1L_SRC_MASK,
 			    DA7219_DMIX_ST_SRC_OUTFILT1L);
-	snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1R,
+	snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1R,
 			    DA7219_OUTFILT_ST_1R_SRC_MASK,
 			    DA7219_DMIX_ST_SRC_OUTFILT1R);
-	snd_soc_update_bits(codec, DA7219_MIXOUT_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_MIXOUT_L_CTRL,
 			    DA7219_MIXOUT_L_AMP_EN_MASK,
 			    DA7219_MIXOUT_L_AMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_MIXOUT_R_CTRL,
+	snd_soc_component_update_bits(component, DA7219_MIXOUT_R_CTRL,
 			    DA7219_MIXOUT_R_AMP_EN_MASK,
 			    DA7219_MIXOUT_R_AMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 			    DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK,
 			    DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 			    DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK,
 			    DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
 	msleep(DA7219_SETTLING_DELAY);
-	snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 			    DA7219_HP_L_AMP_MUTE_EN_MASK |
 			    DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0);
-	snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 			    DA7219_HP_R_AMP_MUTE_EN_MASK |
 			    DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0);
 
@@ -237,26 +237,26 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 		msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
 
 	/* Configure & start Tone Generator */
-	snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
+	snd_soc_component_write(component, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
 	regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
 			 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
-	snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2,
+	snd_soc_component_update_bits(component, DA7219_TONE_GEN_CFG2,
 			    DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK,
 			    DA7219_SWG_SEL_SRAMP |
 			    DA7219_TONE_GEN_GAIN_MINUS_15DB);
-	snd_soc_write(codec, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
+	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
 
 	msleep(DA7219_AAD_HPTEST_PERIOD);
 
 	/* Grab comparator reading */
-	accdet_cfg8 = snd_soc_read(codec, DA7219_ACCDET_CONFIG_8);
+	accdet_cfg8 = snd_soc_component_read32(component, DA7219_ACCDET_CONFIG_8);
 	if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
 		report |= SND_JACK_HEADPHONE;
 	else
 		report |= SND_JACK_LINEOUT;
 
 	/* Stop tone generator */
-	snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
+	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
 
 	msleep(DA7219_AAD_HPTEST_PERIOD);
 
@@ -294,7 +294,7 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 	regcache_cache_bypass(da7219->regmap, false);
 
 	/* Disable HPTest block */
-	snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
+	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
 			    DA7219_HPTEST_EN_MASK, 0);
 
 	/*
@@ -305,18 +305,18 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 		msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
 
 	/* Restore gain ramping rate */
-	snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
+	snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
 
 	/* Drive Headphones/lineout */
-	snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
+	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
 			    DA7219_HP_L_AMP_OE_MASK);
-	snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
+	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
 			    DA7219_HP_R_AMP_OE_MASK);
 
 	/* Restore PLL to previous configuration, if re-configured */
 	if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) &&
 	    ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS))
-		da7219_set_pll(codec, DA7219_SYSCLK_MCLK, 0);
+		da7219_set_pll(component, DA7219_SYSCLK_MCLK, 0);
 
 	/* Remove MCLK, if previously enabled */
 	if (da7219->mclk)
@@ -343,9 +343,9 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 {
 	struct da7219_aad_priv *da7219_aad = data;
-	struct snd_soc_codec *codec = da7219_aad->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = da7219_aad->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	u8 events[DA7219_AAD_IRQ_REG_MAX];
 	u8 statusa;
 	int i, report = 0, mask = 0;
@@ -358,13 +358,13 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 		return IRQ_NONE;
 
 	/* Read status register for jack insertion & type status */
-	statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
+	statusa = snd_soc_component_read32(component, DA7219_ACCDET_STATUS_A);
 
 	/* Clear events */
 	regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
 			  events, DA7219_AAD_IRQ_REG_MAX);
 
-	dev_dbg(codec->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
+	dev_dbg(component->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
 		events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
 		statusa);
 
@@ -430,13 +430,13 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 			da7219_aad->jack_inserted = false;
 
 			/* Un-drive headphones/lineout */
-			snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+			snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 					    DA7219_HP_R_AMP_OE_MASK, 0);
-			snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+			snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 					    DA7219_HP_L_AMP_OE_MASK, 0);
 
 			/* Ensure button detection disabled */
-			snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+			snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 					    DA7219_BUTTON_CONFIG_MASK, 0);
 
 			/* Disable mic bias */
@@ -459,7 +459,7 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
  */
 
 static enum da7219_aad_micbias_pulse_lvl
-	da7219_aad_fw_micbias_pulse_lvl(struct snd_soc_codec *codec, u32 val)
+	da7219_aad_fw_micbias_pulse_lvl(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 2800:
@@ -467,13 +467,13 @@ static enum da7219_aad_micbias_pulse_lvl
 	case 2900:
 		return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
 	default:
-		dev_warn(codec->dev, "Invalid micbias pulse level");
+		dev_warn(component->dev, "Invalid micbias pulse level");
 		return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
 	}
 }
 
 static enum da7219_aad_btn_cfg
-	da7219_aad_fw_btn_cfg(struct snd_soc_codec *codec, u32 val)
+	da7219_aad_fw_btn_cfg(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 2:
@@ -491,13 +491,13 @@ static enum da7219_aad_btn_cfg
 	case 500:
 		return DA7219_AAD_BTN_CFG_500MS;
 	default:
-		dev_warn(codec->dev, "Invalid button config");
+		dev_warn(component->dev, "Invalid button config");
 		return DA7219_AAD_BTN_CFG_10MS;
 	}
 }
 
 static enum da7219_aad_mic_det_thr
-	da7219_aad_fw_mic_det_thr(struct snd_soc_codec *codec, u32 val)
+	da7219_aad_fw_mic_det_thr(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 200:
@@ -509,13 +509,13 @@ static enum da7219_aad_mic_det_thr
 	case 1000:
 		return DA7219_AAD_MIC_DET_THR_1000_OHMS;
 	default:
-		dev_warn(codec->dev, "Invalid mic detect threshold");
+		dev_warn(component->dev, "Invalid mic detect threshold");
 		return DA7219_AAD_MIC_DET_THR_500_OHMS;
 	}
 }
 
 static enum da7219_aad_jack_ins_deb
-	da7219_aad_fw_jack_ins_deb(struct snd_soc_codec *codec, u32 val)
+	da7219_aad_fw_jack_ins_deb(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 5:
@@ -535,13 +535,13 @@ static enum da7219_aad_jack_ins_deb
 	case 1000:
 		return DA7219_AAD_JACK_INS_DEB_1S;
 	default:
-		dev_warn(codec->dev, "Invalid jack insert debounce");
+		dev_warn(component->dev, "Invalid jack insert debounce");
 		return DA7219_AAD_JACK_INS_DEB_20MS;
 	}
 }
 
 static enum da7219_aad_jack_det_rate
-	da7219_aad_fw_jack_det_rate(struct snd_soc_codec *codec, const char *str)
+	da7219_aad_fw_jack_det_rate(struct snd_soc_component *component, const char *str)
 {
 	if (!strcmp(str, "32ms_64ms")) {
 		return DA7219_AAD_JACK_DET_RATE_32_64MS;
@@ -552,13 +552,13 @@ static enum da7219_aad_jack_det_rate
 	} else if (!strcmp(str, "256ms_512ms")) {
 		return DA7219_AAD_JACK_DET_RATE_256_512MS;
 	} else {
-		dev_warn(codec->dev, "Invalid jack detect rate");
+		dev_warn(component->dev, "Invalid jack detect rate");
 		return DA7219_AAD_JACK_DET_RATE_256_512MS;
 	}
 }
 
 static enum da7219_aad_jack_rem_deb
-	da7219_aad_fw_jack_rem_deb(struct snd_soc_codec *codec, u32 val)
+	da7219_aad_fw_jack_rem_deb(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 1:
@@ -570,13 +570,13 @@ static enum da7219_aad_jack_rem_deb
 	case 20:
 		return DA7219_AAD_JACK_REM_DEB_20MS;
 	default:
-		dev_warn(codec->dev, "Invalid jack removal debounce");
+		dev_warn(component->dev, "Invalid jack removal debounce");
 		return DA7219_AAD_JACK_REM_DEB_1MS;
 	}
 }
 
 static enum da7219_aad_btn_avg
-	da7219_aad_fw_btn_avg(struct snd_soc_codec *codec, u32 val)
+	da7219_aad_fw_btn_avg(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 1:
@@ -588,13 +588,13 @@ static enum da7219_aad_btn_avg
 	case 8:
 		return DA7219_AAD_BTN_AVG_8;
 	default:
-		dev_warn(codec->dev, "Invalid button average value");
+		dev_warn(component->dev, "Invalid button average value");
 		return DA7219_AAD_BTN_AVG_2;
 	}
 }
 
 static enum da7219_aad_adc_1bit_rpt
-	da7219_aad_fw_adc_1bit_rpt(struct snd_soc_codec *codec, u32 val)
+	da7219_aad_fw_adc_1bit_rpt(struct snd_soc_component *component, u32 val)
 {
 	switch (val) {
 	case 1:
@@ -606,14 +606,14 @@ static enum da7219_aad_adc_1bit_rpt
 	case 8:
 		return DA7219_AAD_ADC_1BIT_RPT_8;
 	default:
-		dev_warn(codec->dev, "Invalid ADC 1-bit repeat value");
+		dev_warn(component->dev, "Invalid ADC 1-bit repeat value");
 		return DA7219_AAD_ADC_1BIT_RPT_1;
 	}
 }
 
-static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *codec)
+static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_component *component)
 {
-	struct device *dev = codec->dev;
+	struct device *dev = component->dev;
 	struct i2c_client *i2c = to_i2c_client(dev);
 	struct fwnode_handle *aad_np;
 	struct da7219_aad_pdata *aad_pdata;
@@ -624,7 +624,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
 	if (!aad_np)
 		return NULL;
 
-	aad_pdata = devm_kzalloc(codec->dev, sizeof(*aad_pdata), GFP_KERNEL);
+	aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL);
 	if (!aad_pdata)
 		return NULL;
 
@@ -633,7 +633,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
 	if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
 				     &fw_val32) >= 0)
 		aad_pdata->micbias_pulse_lvl =
-			da7219_aad_fw_micbias_pulse_lvl(codec, fw_val32);
+			da7219_aad_fw_micbias_pulse_lvl(component, fw_val32);
 	else
 		aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
 
@@ -642,31 +642,31 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
 		aad_pdata->micbias_pulse_time = fw_val32;
 
 	if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0)
-		aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(codec, fw_val32);
+		aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(component, fw_val32);
 	else
 		aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
 
 	if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
 		aad_pdata->mic_det_thr =
-			da7219_aad_fw_mic_det_thr(codec, fw_val32);
+			da7219_aad_fw_mic_det_thr(component, fw_val32);
 	else
 		aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
 
 	if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
 		aad_pdata->jack_ins_deb =
-			da7219_aad_fw_jack_ins_deb(codec, fw_val32);
+			da7219_aad_fw_jack_ins_deb(component, fw_val32);
 	else
 		aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
 
 	if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
 		aad_pdata->jack_det_rate =
-			da7219_aad_fw_jack_det_rate(codec, fw_str);
+			da7219_aad_fw_jack_det_rate(component, fw_str);
 	else
 		aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
 
 	if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0)
 		aad_pdata->jack_rem_deb =
-			da7219_aad_fw_jack_rem_deb(codec, fw_val32);
+			da7219_aad_fw_jack_rem_deb(component, fw_val32);
 	else
 		aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
 
@@ -691,22 +691,22 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
 		aad_pdata->c_mic_btn_thr = 0x3E;
 
 	if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0)
-		aad_pdata->btn_avg = da7219_aad_fw_btn_avg(codec, fw_val32);
+		aad_pdata->btn_avg = da7219_aad_fw_btn_avg(component, fw_val32);
 	else
 		aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
 
 	if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
 		aad_pdata->adc_1bit_rpt =
-			da7219_aad_fw_adc_1bit_rpt(codec, fw_val32);
+			da7219_aad_fw_adc_1bit_rpt(component, fw_val32);
 	else
 		aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
 
 	return aad_pdata;
 }
 
-static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
+static void da7219_aad_handle_pdata(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct da7219_aad_priv *da7219_aad = da7219->aad;
 	struct da7219_pdata *pdata = da7219->pdata;
 
@@ -752,7 +752,7 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
 				DA7219_MIC_DET_THRESH_SHIFT);
 			mask |= DA7219_MIC_DET_THRESH_MASK;
 		}
-		snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, mask, cfg);
+		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, mask, cfg);
 
 		cfg = 0;
 		mask = 0;
@@ -787,15 +787,15 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
 				DA7219_JACKDET_REM_DEB_SHIFT);
 			mask |= DA7219_JACKDET_REM_DEB_MASK;
 		}
-		snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_2, mask, cfg);
+		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_2, mask, cfg);
 
-		snd_soc_write(codec, DA7219_ACCDET_CONFIG_3,
+		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_3,
 			      aad_pdata->a_d_btn_thr);
-		snd_soc_write(codec, DA7219_ACCDET_CONFIG_4,
+		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_4,
 			      aad_pdata->d_b_btn_thr);
-		snd_soc_write(codec, DA7219_ACCDET_CONFIG_5,
+		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_5,
 			      aad_pdata->b_c_btn_thr);
-		snd_soc_write(codec, DA7219_ACCDET_CONFIG_6,
+		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_6,
 			      aad_pdata->c_mic_btn_thr);
 
 		cfg = 0;
@@ -818,7 +818,7 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
 			       DA7219_ADC_1_BIT_REPEAT_SHIFT);
 			mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
 		}
-		snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_7, mask, cfg);
+		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_7, mask, cfg);
 	}
 }
 
@@ -827,16 +827,16 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
  * Suspend/Resume
  */
 
-void da7219_aad_suspend(struct snd_soc_codec *codec)
+void da7219_aad_suspend(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct da7219_aad_priv *da7219_aad = da7219->aad;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	u8 micbias_ctrl;
 
 	if (da7219_aad->jack) {
 		/* Disable jack detection during suspend */
-		snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 				    DA7219_ACCDET_EN_MASK, 0);
 
 		/*
@@ -846,7 +846,7 @@ void da7219_aad_suspend(struct snd_soc_codec *codec)
 		 * suspend then this will be dealt with through the IRQ handler.
 		 */
 		if (da7219_aad->jack_inserted) {
-			micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
+			micbias_ctrl = snd_soc_component_read32(component, DA7219_MICBIAS_CTRL);
 			if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
 				snd_soc_dapm_disable_pin(dapm, "Mic Bias");
 				snd_soc_dapm_sync(dapm);
@@ -856,11 +856,11 @@ void da7219_aad_suspend(struct snd_soc_codec *codec)
 	}
 }
 
-void da7219_aad_resume(struct snd_soc_codec *codec)
+void da7219_aad_resume(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct da7219_aad_priv *da7219_aad = da7219->aad;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	if (da7219_aad->jack) {
 		/* Re-enable micbias if previously enabled for 4-pole jack */
@@ -872,7 +872,7 @@ void da7219_aad_resume(struct snd_soc_codec *codec)
 		}
 
 		/* Re-enable jack detection */
-		snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 				    DA7219_ACCDET_EN_MASK,
 				    DA7219_ACCDET_EN_MASK);
 	}
@@ -883,28 +883,28 @@ void da7219_aad_resume(struct snd_soc_codec *codec)
  * Init/Exit
  */
 
-int da7219_aad_init(struct snd_soc_codec *codec)
+int da7219_aad_init(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct da7219_aad_priv *da7219_aad;
 	u8 mask[DA7219_AAD_IRQ_REG_MAX];
 	int ret;
 
-	da7219_aad = devm_kzalloc(codec->dev, sizeof(*da7219_aad), GFP_KERNEL);
+	da7219_aad = devm_kzalloc(component->dev, sizeof(*da7219_aad), GFP_KERNEL);
 	if (!da7219_aad)
 		return -ENOMEM;
 
 	da7219->aad = da7219_aad;
-	da7219_aad->codec = codec;
+	da7219_aad->component = component;
 
 	/* Handle any DT/ACPI/platform data */
 	if (da7219->pdata && !da7219->pdata->aad_pdata)
-		da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(codec);
+		da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(component);
 
-	da7219_aad_handle_pdata(codec);
+	da7219_aad_handle_pdata(component);
 
 	/* Disable button detection */
-	snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 			    DA7219_BUTTON_CONFIG_MASK, 0);
 
 	INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
@@ -915,7 +915,7 @@ int da7219_aad_init(struct snd_soc_codec *codec)
 				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 				   "da7219-aad", da7219_aad);
 	if (ret) {
-		dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
+		dev_err(component->dev, "Failed to request IRQ: %d\n", ret);
 		return ret;
 	}
 
@@ -928,9 +928,9 @@ int da7219_aad_init(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(da7219_aad_init);
 
-void da7219_aad_exit(struct snd_soc_codec *codec)
+void da7219_aad_exit(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct da7219_aad_priv *da7219_aad = da7219->aad;
 	u8 mask[DA7219_AAD_IRQ_REG_MAX];
 
diff --git a/sound/soc/codecs/da7219-aad.h b/sound/soc/codecs/da7219-aad.h
index 117a3d7..b9c4a27 100644
--- a/sound/soc/codecs/da7219-aad.h
+++ b/sound/soc/codecs/da7219-aad.h
@@ -189,7 +189,7 @@ enum da7219_aad_event_regs {
 
 /* Private data */
 struct da7219_aad_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	int irq;
 
 	u8 micbias_pulse_lvl;
@@ -206,14 +206,14 @@ struct da7219_aad_priv {
 };
 
 /* AAD control */
-void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 /* Suspend/Resume */
-void da7219_aad_suspend(struct snd_soc_codec *codec);
-void da7219_aad_resume(struct snd_soc_codec *codec);
+void da7219_aad_suspend(struct snd_soc_component *component);
+void da7219_aad_resume(struct snd_soc_component *component);
 
 /* Init/Exit */
-int da7219_aad_init(struct snd_soc_codec *codec);
-void da7219_aad_exit(struct snd_soc_codec *codec);
+int da7219_aad_init(struct snd_soc_component *component);
+void da7219_aad_exit(struct snd_soc_component *component);
 
 #endif /* __DA7219_AAD_H */
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index 6f08853..980a6a8 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -13,6 +13,8 @@
 
 #include <linux/acpi.h>
 #include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/i2c.h>
 #include <linux/of_device.h>
 #include <linux/property.h>
@@ -256,8 +258,8 @@ static const struct soc_enum da7219_cp_track_mode =
 static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	mutex_lock(&da7219->ctrl_lock);
@@ -270,8 +272,8 @@ static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
 static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	mutex_lock(&da7219->ctrl_lock);
@@ -284,8 +286,8 @@ static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
 static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	mutex_lock(&da7219->ctrl_lock);
@@ -298,8 +300,8 @@ static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
 static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	mutex_lock(&da7219->ctrl_lock);
@@ -310,55 +312,55 @@ static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
 }
 
 /* ALC */
-static void da7219_alc_calib(struct snd_soc_codec *codec)
+static void da7219_alc_calib(struct snd_soc_component *component)
 {
 	u8 mic_ctrl, mixin_ctrl, adc_ctrl, calib_ctrl;
 
 	/* Save current state of mic control register */
-	mic_ctrl = snd_soc_read(codec, DA7219_MIC_1_CTRL);
+	mic_ctrl = snd_soc_component_read32(component, DA7219_MIC_1_CTRL);
 
 	/* Save current state of input mixer control register */
-	mixin_ctrl = snd_soc_read(codec, DA7219_MIXIN_L_CTRL);
+	mixin_ctrl = snd_soc_component_read32(component, DA7219_MIXIN_L_CTRL);
 
 	/* Save current state of input ADC control register */
-	adc_ctrl = snd_soc_read(codec, DA7219_ADC_L_CTRL);
+	adc_ctrl = snd_soc_component_read32(component, DA7219_ADC_L_CTRL);
 
 	/* Enable then Mute MIC PGAs */
-	snd_soc_update_bits(codec, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK,
+	snd_soc_component_update_bits(component, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK,
 			    DA7219_MIC_1_AMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_MIC_1_CTRL,
+	snd_soc_component_update_bits(component, DA7219_MIC_1_CTRL,
 			    DA7219_MIC_1_AMP_MUTE_EN_MASK,
 			    DA7219_MIC_1_AMP_MUTE_EN_MASK);
 
 	/* Enable input mixers unmuted */
-	snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_MIXIN_L_CTRL,
 			    DA7219_MIXIN_L_AMP_EN_MASK |
 			    DA7219_MIXIN_L_AMP_MUTE_EN_MASK,
 			    DA7219_MIXIN_L_AMP_EN_MASK);
 
 	/* Enable input filters unmuted */
-	snd_soc_update_bits(codec, DA7219_ADC_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_ADC_L_CTRL,
 			    DA7219_ADC_L_MUTE_EN_MASK | DA7219_ADC_L_EN_MASK,
 			    DA7219_ADC_L_EN_MASK);
 
 	/* Perform auto calibration */
-	snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
+	snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
 			    DA7219_ALC_AUTO_CALIB_EN_MASK,
 			    DA7219_ALC_AUTO_CALIB_EN_MASK);
 	do {
-		calib_ctrl = snd_soc_read(codec, DA7219_ALC_CTRL1);
+		calib_ctrl = snd_soc_component_read32(component, DA7219_ALC_CTRL1);
 	} while (calib_ctrl & DA7219_ALC_AUTO_CALIB_EN_MASK);
 
 	/* If auto calibration fails, disable DC offset, hybrid ALC */
 	if (calib_ctrl & DA7219_ALC_CALIB_OVERFLOW_MASK) {
-		dev_warn(codec->dev,
+		dev_warn(component->dev,
 			 "ALC auto calibration failed with overflow\n");
-		snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
+		snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
 				    DA7219_ALC_OFFSET_EN_MASK |
 				    DA7219_ALC_SYNC_MODE_MASK, 0);
 	} else {
 		/* Enable DC offset cancellation, hybrid mode */
-		snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
+		snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
 				    DA7219_ALC_OFFSET_EN_MASK |
 				    DA7219_ALC_SYNC_MODE_MASK,
 				    DA7219_ALC_OFFSET_EN_MASK |
@@ -366,20 +368,20 @@ static void da7219_alc_calib(struct snd_soc_codec *codec)
 	}
 
 	/* Restore input filter control register to original state */
-	snd_soc_write(codec, DA7219_ADC_L_CTRL, adc_ctrl);
+	snd_soc_component_write(component, DA7219_ADC_L_CTRL, adc_ctrl);
 
 	/* Restore input mixer control registers to original state */
-	snd_soc_write(codec, DA7219_MIXIN_L_CTRL, mixin_ctrl);
+	snd_soc_component_write(component, DA7219_MIXIN_L_CTRL, mixin_ctrl);
 
 	/* Restore MIC control registers to original states */
-	snd_soc_write(codec, DA7219_MIC_1_CTRL, mic_ctrl);
+	snd_soc_component_write(component, DA7219_MIC_1_CTRL, mic_ctrl);
 }
 
 static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = snd_soc_put_volsw(kcontrol, ucontrol);
@@ -389,7 +391,7 @@ static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
 	 * make sure calibrated offsets are updated.
 	 */
 	if ((ret == 1) && (da7219->alc_en))
-		da7219_alc_calib(codec);
+		da7219_alc_calib(component);
 
 	return ret;
 }
@@ -397,13 +399,13 @@ static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
 static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
 
 	/* Force ALC offset calibration if enabling ALC */
 	if ((ucontrol->value.integer.value[0]) && (!da7219->alc_en)) {
-		da7219_alc_calib(codec);
+		da7219_alc_calib(component);
 		da7219->alc_en = true;
 	} else {
 		da7219->alc_en = false;
@@ -416,8 +418,8 @@ static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
 static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mixer_ctrl =
 		(struct soc_mixer_control *) kcontrol->private_value;
 	unsigned int reg = mixer_ctrl->reg;
@@ -443,8 +445,8 @@ static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
 static int da7219_tonegen_freq_put(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mixer_ctrl =
 		(struct soc_mixer_control *) kcontrol->private_value;
 	unsigned int reg = mixer_ctrl->reg;
@@ -769,32 +771,43 @@ static const struct snd_kcontrol_new da7219_st_out_filtr_mix_controls[] = {
 static int da7219_dai_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	u8 pll_ctrl, pll_status;
-	int i = 0;
+	int i = 0, ret;
 	bool srm_lock = false;
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		if (da7219->master)
+		if (da7219->master) {
 			/* Enable DAI clks for master mode */
-			snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
-					    DA7219_DAI_CLK_EN_MASK,
-					    DA7219_DAI_CLK_EN_MASK);
+			if (da7219->dai_clks) {
+				ret = clk_prepare_enable(da7219->dai_clks);
+				if (ret) {
+					dev_err(component->dev,
+						"Failed to enable dai_clks\n");
+					return ret;
+				}
+			} else {
+				snd_soc_component_update_bits(component,
+							      DA7219_DAI_CLK_MODE,
+							      DA7219_DAI_CLK_EN_MASK,
+							      DA7219_DAI_CLK_EN_MASK);
+			}
+		}
 
 		/* PC synchronised to DAI */
-		snd_soc_update_bits(codec, DA7219_PC_COUNT,
+		snd_soc_component_update_bits(component, DA7219_PC_COUNT,
 				    DA7219_PC_FREERUN_MASK, 0);
 
 		/* Slave mode, if SRM not enabled no need for status checks */
-		pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL);
+		pll_ctrl = snd_soc_component_read32(component, DA7219_PLL_CTRL);
 		if ((pll_ctrl & DA7219_PLL_MODE_MASK) != DA7219_PLL_MODE_SRM)
 			return 0;
 
 		/* Check SRM has locked */
 		do {
-			pll_status = snd_soc_read(codec, DA7219_PLL_SRM_STS);
+			pll_status = snd_soc_component_read32(component, DA7219_PLL_SRM_STS);
 			if (pll_status & DA7219_PLL_SRM_STS_SRM_LOCK) {
 				srm_lock = true;
 			} else {
@@ -804,19 +817,26 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
 		} while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock));
 
 		if (!srm_lock)
-			dev_warn(codec->dev, "SRM failed to lock\n");
+			dev_warn(component->dev, "SRM failed to lock\n");
 
 		return 0;
 	case SND_SOC_DAPM_POST_PMD:
 		/* PC free-running */
-		snd_soc_update_bits(codec, DA7219_PC_COUNT,
+		snd_soc_component_update_bits(component, DA7219_PC_COUNT,
 				    DA7219_PC_FREERUN_MASK,
 				    DA7219_PC_FREERUN_MASK);
 
 		/* Disable DAI clks if in master mode */
-		if (da7219->master)
-			snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
-					    DA7219_DAI_CLK_EN_MASK, 0);
+		if (da7219->master) {
+			if (da7219->dai_clks)
+				clk_disable_unprepare(da7219->dai_clks);
+			else
+				snd_soc_component_update_bits(component,
+							      DA7219_DAI_CLK_MODE,
+							      DA7219_DAI_CLK_EN_MASK,
+							      0);
+		}
+
 		return 0;
 	default:
 		return -EINVAL;
@@ -841,7 +861,7 @@ static int da7219_settling_event(struct snd_soc_dapm_widget *w,
 static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	u8 hp_ctrl, min_gain_mask;
 
 	switch (w->reg) {
@@ -860,7 +880,7 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMD:
 		/* Enable minimum gain on HP to avoid pops */
-		snd_soc_update_bits(codec, hp_ctrl, min_gain_mask,
+		snd_soc_component_update_bits(component, hp_ctrl, min_gain_mask,
 				    min_gain_mask);
 
 		msleep(DA7219_MIN_GAIN_DELAY);
@@ -868,7 +888,7 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
 		break;
 	case SND_SOC_DAPM_POST_PMU:
 		/* Remove minimum gain on HP */
-		snd_soc_update_bits(codec, hp_ctrl, min_gain_mask, 0);
+		snd_soc_component_update_bits(component, hp_ctrl, min_gain_mask, 0);
 
 		break;
 	}
@@ -879,22 +899,22 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
 static int da7219_gain_ramp_event(struct snd_soc_dapm_widget *w,
 				  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 	case SND_SOC_DAPM_PRE_PMD:
 		/* Ensure nominal gain ramping for DAPM sequence */
 		da7219->gain_ramp_ctrl =
-			snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
-		snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
+			snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL);
+		snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL,
 			      DA7219_GAIN_RAMP_RATE_NOMINAL);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
 	case SND_SOC_DAPM_POST_PMD:
 		/* Restore previous gain ramp settings */
-		snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
+		snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL,
 			      da7219->gain_ramp_ctrl);
 		break;
 	}
@@ -1116,8 +1136,8 @@ static const struct snd_soc_dapm_route da7219_audio_map[] = {
 static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
@@ -1133,12 +1153,12 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 	switch (clk_id) {
 	case DA7219_CLKSRC_MCLK_SQR:
-		snd_soc_update_bits(codec, DA7219_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
 				    DA7219_PLL_MCLK_SQR_EN_MASK,
 				    DA7219_PLL_MCLK_SQR_EN_MASK);
 		break;
 	case DA7219_CLKSRC_MCLK:
-		snd_soc_update_bits(codec, DA7219_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
 				    DA7219_PLL_MCLK_SQR_EN_MASK, 0);
 		break;
 	default:
@@ -1167,9 +1187,9 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
+int da7219_set_pll(struct snd_soc_component *component, int source, unsigned int fout)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
 	u8 pll_ctrl, indiv_bits, indiv;
 	u8 pll_frac_top, pll_frac_bot, pll_integer;
@@ -1178,7 +1198,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
 
 	/* Verify 2MHz - 54MHz MCLK provided, and set input divider */
 	if (da7219->mclk_rate < 2000000) {
-		dev_err(codec->dev, "PLL input clock %d below valid range\n",
+		dev_err(component->dev, "PLL input clock %d below valid range\n",
 			da7219->mclk_rate);
 		return -EINVAL;
 	} else if (da7219->mclk_rate <= 4500000) {
@@ -1197,7 +1217,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
 		indiv_bits = DA7219_PLL_INDIV_36_TO_54_MHZ;
 		indiv = DA7219_PLL_INDIV_36_TO_54_MHZ_VAL;
 	} else {
-		dev_err(codec->dev, "PLL input clock %d above valid range\n",
+		dev_err(component->dev, "PLL input clock %d above valid range\n",
 			da7219->mclk_rate);
 		return -EINVAL;
 	}
@@ -1208,7 +1228,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
 	switch (source) {
 	case DA7219_SYSCLK_MCLK:
 		pll_ctrl |= DA7219_PLL_MODE_BYPASS;
-		snd_soc_update_bits(codec, DA7219_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
 				    DA7219_PLL_INDIV_MASK |
 				    DA7219_PLL_MODE_MASK, pll_ctrl);
 		return 0;
@@ -1219,7 +1239,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
 		pll_ctrl |= DA7219_PLL_MODE_SRM;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid PLL config\n");
+		dev_err(component->dev, "Invalid PLL config\n");
 		return -EINVAL;
 	}
 
@@ -1231,10 +1251,10 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
 	pll_frac_bot = (frac_div) & DA7219_BYTE_MASK;
 
 	/* Write PLL config & dividers */
-	snd_soc_write(codec, DA7219_PLL_FRAC_TOP, pll_frac_top);
-	snd_soc_write(codec, DA7219_PLL_FRAC_BOT, pll_frac_bot);
-	snd_soc_write(codec, DA7219_PLL_INTEGER, pll_integer);
-	snd_soc_update_bits(codec, DA7219_PLL_CTRL,
+	snd_soc_component_write(component, DA7219_PLL_FRAC_TOP, pll_frac_top);
+	snd_soc_component_write(component, DA7219_PLL_FRAC_BOT, pll_frac_bot);
+	snd_soc_component_write(component, DA7219_PLL_INTEGER, pll_integer);
+	snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
 			    DA7219_PLL_INDIV_MASK | DA7219_PLL_MODE_MASK,
 			    pll_ctrl);
 
@@ -1244,12 +1264,12 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
 static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 			      int source, unsigned int fref, unsigned int fout)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	mutex_lock(&da7219->pll_lock);
-	ret = da7219_set_pll(codec, source, fout);
+	ret = da7219_set_pll(component, source, fout);
 	mutex_unlock(&da7219->pll_lock);
 
 	return ret;
@@ -1257,8 +1277,8 @@ static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
 static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	u8 dai_clk_mode = 0, dai_ctrl = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1335,11 +1355,11 @@ static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	/* By default 64 BCLKs per WCLK is supported */
 	dai_clk_mode |= DA7219_DAI_BCLKS_PER_WCLK_64;
 
-	snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
+	snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
 			    DA7219_DAI_BCLKS_PER_WCLK_MASK |
 			    DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK,
 			    dai_clk_mode);
-	snd_soc_update_bits(codec, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK,
+	snd_soc_component_update_bits(component, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK,
 			    dai_ctrl);
 
 	return 0;
@@ -1349,18 +1369,18 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
 				   unsigned int tx_mask, unsigned int rx_mask,
 				   int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	u8 dai_bclks_per_wclk;
 	u16 offset;
 	u32 frame_size;
 
 	/* No channels enabled so disable TDM, revert to 64-bit frames */
 	if (!tx_mask) {
-		snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
+		snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL,
 				    DA7219_DAI_TDM_CH_EN_MASK |
 				    DA7219_DAI_TDM_MODE_EN_MASK, 0);
-		snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
+		snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
 				    DA7219_DAI_BCLKS_PER_WCLK_MASK,
 				    DA7219_DAI_BCLKS_PER_WCLK_64);
 		return 0;
@@ -1368,14 +1388,14 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
 
 	/* Check we have valid slots */
 	if (fls(tx_mask) > DA7219_DAI_TDM_MAX_SLOTS) {
-		dev_err(codec->dev, "Invalid number of slots, max = %d\n",
+		dev_err(component->dev, "Invalid number of slots, max = %d\n",
 			DA7219_DAI_TDM_MAX_SLOTS);
 		return -EINVAL;
 	}
 
 	/* Check we have a valid offset given */
 	if (rx_mask > DA7219_DAI_OFFSET_MAX) {
-		dev_err(codec->dev, "Invalid slot offset, max = %d\n",
+		dev_err(component->dev, "Invalid slot offset, max = %d\n",
 			DA7219_DAI_OFFSET_MAX);
 		return -EINVAL;
 	}
@@ -1396,11 +1416,11 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
 		dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid frame size %d\n", frame_size);
+		dev_err(component->dev, "Invalid frame size %d\n", frame_size);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
+	snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
 			    DA7219_DAI_BCLKS_PER_WCLK_MASK,
 			    dai_bclks_per_wclk);
 
@@ -1408,7 +1428,7 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
 	regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER,
 			  &offset, sizeof(offset));
 
-	snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
+	snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL,
 			    DA7219_DAI_TDM_CH_EN_MASK |
 			    DA7219_DAI_TDM_MODE_EN_MASK,
 			    (tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) |
@@ -1421,7 +1441,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 dai_ctrl = 0, fs;
 	unsigned int channels;
 
@@ -1444,7 +1464,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
 
 	channels = params_channels(params);
 	if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Invalid number of channels, only 1 to %d supported\n",
 			DA7219_DAI_CH_NUM_MAX);
 		return -EINVAL;
@@ -1489,11 +1509,11 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, DA7219_DAI_CTRL,
+	snd_soc_component_update_bits(component, DA7219_DAI_CTRL,
 			    DA7219_DAI_WORD_LENGTH_MASK |
 			    DA7219_DAI_CH_NUM_MASK,
 			    dai_ctrl);
-	snd_soc_write(codec, DA7219_SR, fs);
+	snd_soc_component_write(component, DA7219_SR, fs);
 
 	return 0;
 }
@@ -1585,9 +1605,9 @@ static enum da7219_mic_amp_in_sel
 	}
 }
 
-static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
+static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_component *component)
 {
-	struct device *dev = codec->dev;
+	struct device *dev = component->dev;
 	struct da7219_pdata *pdata;
 	const char *of_str;
 	u32 of_val32;
@@ -1598,6 +1618,12 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
 
 	pdata->wakeup_source = device_property_read_bool(dev, "wakeup-source");
 
+	pdata->dai_clks_name = "da7219-dai-clks";
+	if (device_property_read_string(dev, "clock-output-names",
+					&pdata->dai_clks_name))
+		dev_warn(dev, "Using default clk name: %s\n",
+			 pdata->dai_clks_name);
+
 	if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0)
 		pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32);
 	else
@@ -1616,10 +1642,10 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
  * Codec driver functions
  */
 
-static int da7219_set_bias_level(struct snd_soc_codec *codec,
+static int da7219_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1627,11 +1653,11 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		/* Enable MCLK for transition to ON state */
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
 			if (da7219->mclk) {
 				ret = clk_prepare_enable(da7219->mclk);
 				if (ret) {
-					dev_err(codec->dev,
+					dev_err(component->dev,
 						"Failed to enable mclk\n");
 					return ret;
 				}
@@ -1640,13 +1666,13 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
 
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			/* Master bias */
-			snd_soc_update_bits(codec, DA7219_REFERENCES,
+			snd_soc_component_update_bits(component, DA7219_REFERENCES,
 					    DA7219_BIAS_EN_MASK,
 					    DA7219_BIAS_EN_MASK);
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) {
 			/* Remove MCLK */
 			if (da7219->mclk)
 				clk_disable_unprepare(da7219->mclk);
@@ -1655,7 +1681,7 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_OFF:
 		/* Only disable master bias if we're not a wake-up source */
 		if (!da7219->wakeup_source)
-			snd_soc_update_bits(codec, DA7219_REFERENCES,
+			snd_soc_component_update_bits(component, DA7219_REFERENCES,
 					    DA7219_BIAS_EN_MASK, 0);
 
 		break;
@@ -1670,9 +1696,9 @@ static const char *da7219_supply_names[DA7219_NUM_SUPPLIES] = {
 	[DA7219_SUPPLY_VDDIO] = "VDDIO",
 };
 
-static int da7219_handle_supplies(struct snd_soc_codec *codec)
+static int da7219_handle_supplies(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct regulator *vddio;
 	u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V;
 	int i, ret;
@@ -1681,10 +1707,10 @@ static int da7219_handle_supplies(struct snd_soc_codec *codec)
 	for (i = 0; i < DA7219_NUM_SUPPLIES; ++i)
 		da7219->supplies[i].supply = da7219_supply_names[i];
 
-	ret = devm_regulator_bulk_get(codec->dev, DA7219_NUM_SUPPLIES,
+	ret = devm_regulator_bulk_get(component->dev, DA7219_NUM_SUPPLIES,
 				      da7219->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to get supplies");
+		dev_err(component->dev, "Failed to get supplies");
 		return ret;
 	}
 
@@ -1692,29 +1718,111 @@ static int da7219_handle_supplies(struct snd_soc_codec *codec)
 	vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer;
 	ret = regulator_get_voltage(vddio);
 	if (ret < 1200000)
-		dev_warn(codec->dev, "Invalid VDDIO voltage\n");
+		dev_warn(component->dev, "Invalid VDDIO voltage\n");
 	else if (ret < 2800000)
 		io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V;
 
 	/* Enable main supplies */
 	ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to enable supplies");
+		dev_err(component->dev, "Failed to enable supplies");
 		return ret;
 	}
 
 	/* Ensure device in active mode */
-	snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK);
+	snd_soc_component_write(component, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK);
 
 	/* Update IO voltage level range */
-	snd_soc_write(codec, DA7219_IO_CTRL, io_voltage_lvl);
+	snd_soc_component_write(component, DA7219_IO_CTRL, io_voltage_lvl);
 
 	return 0;
 }
 
-static void da7219_handle_pdata(struct snd_soc_codec *codec)
+#ifdef CONFIG_COMMON_CLK
+static int da7219_dai_clks_prepare(struct clk_hw *hw)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 =
+		container_of(hw, struct da7219_priv, dai_clks_hw);
+	struct snd_soc_component *component = da7219->aad->component;
+
+	snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
+				      DA7219_DAI_CLK_EN_MASK,
+				      DA7219_DAI_CLK_EN_MASK);
+
+	return 0;
+}
+
+static void da7219_dai_clks_unprepare(struct clk_hw *hw)
+{
+	struct da7219_priv *da7219 =
+		container_of(hw, struct da7219_priv, dai_clks_hw);
+	struct snd_soc_component *component = da7219->aad->component;
+
+	snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
+				      DA7219_DAI_CLK_EN_MASK, 0);
+}
+
+static int da7219_dai_clks_is_prepared(struct clk_hw *hw)
+{
+	struct da7219_priv *da7219 =
+		container_of(hw, struct da7219_priv, dai_clks_hw);
+	struct snd_soc_component *component = da7219->aad->component;
+	u8 clk_reg;
+
+	clk_reg = snd_soc_component_read32(component, DA7219_DAI_CLK_MODE);
+
+	return !!(clk_reg & DA7219_DAI_CLK_EN_MASK);
+}
+
+static const struct clk_ops da7219_dai_clks_ops = {
+	.prepare = da7219_dai_clks_prepare,
+	.unprepare = da7219_dai_clks_unprepare,
+	.is_prepared = da7219_dai_clks_is_prepared,
+};
+
+static void da7219_register_dai_clks(struct snd_soc_component *component)
+{
+	struct device *dev = component->dev;
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
+	struct da7219_pdata *pdata = da7219->pdata;
+	struct clk_init_data init = {};
+	struct clk *dai_clks;
+	struct clk_lookup *dai_clks_lookup;
+
+	init.parent_names = NULL;
+	init.num_parents = 0;
+	init.name = pdata->dai_clks_name;
+	init.ops = &da7219_dai_clks_ops;
+	da7219->dai_clks_hw.init = &init;
+
+	dai_clks = devm_clk_register(dev, &da7219->dai_clks_hw);
+	if (IS_ERR(dai_clks)) {
+		dev_warn(dev, "Failed to register DAI clocks: %ld\n",
+			 PTR_ERR(dai_clks));
+		return;
+	}
+	da7219->dai_clks = dai_clks;
+
+	/* If we're using DT, then register as provider accordingly */
+	if (dev->of_node) {
+		devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
+					    &da7219->dai_clks_hw);
+	} else {
+		dai_clks_lookup = clkdev_create(dai_clks, pdata->dai_clks_name,
+						"%s", dev_name(dev));
+		if (!dai_clks_lookup)
+			dev_warn(dev, "Failed to create DAI clkdev");
+		else
+			da7219->dai_clks_lookup = dai_clks_lookup;
+	}
+}
+#else
+static inline void da7219_register_dai_clks(struct snd_soc_component *component) {}
+#endif /* CONFIG_COMMON_CLK */
+
+static void da7219_handle_pdata(struct snd_soc_component *component)
+{
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	struct da7219_pdata *pdata = da7219->pdata;
 
 	if (pdata) {
@@ -1722,6 +1830,8 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
 
 		da7219->wakeup_source = pdata->wakeup_source;
 
+		da7219_register_dai_clks(component);
+
 		/* Mic Bias voltages */
 		switch (pdata->micbias_lvl) {
 		case DA7219_MICBIAS_1_6V:
@@ -1735,14 +1845,14 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
 			break;
 		}
 
-		snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_lvl);
+		snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_lvl);
 
 		/* Mic */
 		switch (pdata->mic_amp_in_sel) {
 		case DA7219_MIC_AMP_IN_SEL_DIFF:
 		case DA7219_MIC_AMP_IN_SEL_SE_P:
 		case DA7219_MIC_AMP_IN_SEL_SE_N:
-			snd_soc_write(codec, DA7219_MIC_1_SELECT,
+			snd_soc_component_write(component, DA7219_MIC_1_SELECT,
 				      pdata->mic_amp_in_sel);
 			break;
 		}
@@ -1753,9 +1863,9 @@ static struct reg_sequence da7219_rev_aa_patch[] = {
 	{ DA7219_REFERENCES, 0x08 },
 };
 
-static int da7219_probe(struct snd_soc_codec *codec)
+static int da7219_probe(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	unsigned int rev;
 	int ret;
 
@@ -1763,13 +1873,13 @@ static int da7219_probe(struct snd_soc_codec *codec)
 	mutex_init(&da7219->pll_lock);
 
 	/* Regulator configuration */
-	ret = da7219_handle_supplies(codec);
+	ret = da7219_handle_supplies(component);
 	if (ret)
 		return ret;
 
 	ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev);
 	if (ret) {
-		dev_err(codec->dev, "Failed to read chip revision: %d\n", ret);
+		dev_err(component->dev, "Failed to read chip revision: %d\n", ret);
 		goto err_disable_reg;
 	}
 
@@ -1778,7 +1888,7 @@ static int da7219_probe(struct snd_soc_codec *codec)
 		ret = regmap_register_patch(da7219->regmap, da7219_rev_aa_patch,
 					    ARRAY_SIZE(da7219_rev_aa_patch));
 		if (ret) {
-			dev_err(codec->dev, "Failed to register AA patch: %d\n",
+			dev_err(component->dev, "Failed to register AA patch: %d\n",
 				ret);
 			goto err_disable_reg;
 		}
@@ -1788,14 +1898,14 @@ static int da7219_probe(struct snd_soc_codec *codec)
 	}
 
 	/* Handle DT/ACPI/Platform data */
-	da7219->pdata = dev_get_platdata(codec->dev);
+	da7219->pdata = dev_get_platdata(component->dev);
 	if (!da7219->pdata)
-		da7219->pdata = da7219_fw_to_pdata(codec);
+		da7219->pdata = da7219_fw_to_pdata(component);
 
-	da7219_handle_pdata(codec);
+	da7219_handle_pdata(component);
 
 	/* Check if MCLK provided */
-	da7219->mclk = devm_clk_get(codec->dev, "mclk");
+	da7219->mclk = devm_clk_get(component->dev, "mclk");
 	if (IS_ERR(da7219->mclk)) {
 		if (PTR_ERR(da7219->mclk) != -ENOENT) {
 			ret = PTR_ERR(da7219->mclk);
@@ -1806,39 +1916,39 @@ static int da7219_probe(struct snd_soc_codec *codec)
 	}
 
 	/* Default PC counter to free-running */
-	snd_soc_update_bits(codec, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK,
+	snd_soc_component_update_bits(component, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK,
 			    DA7219_PC_FREERUN_MASK);
 
 	/* Default gain ramping */
-	snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_MIXIN_L_CTRL,
 			    DA7219_MIXIN_L_AMP_RAMP_EN_MASK,
 			    DA7219_MIXIN_L_AMP_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK,
+	snd_soc_component_update_bits(component, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK,
 			    DA7219_ADC_L_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK,
+	snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK,
 			    DA7219_DAC_L_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK,
+	snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK,
 			    DA7219_DAC_R_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 			    DA7219_HP_L_AMP_RAMP_EN_MASK,
 			    DA7219_HP_L_AMP_RAMP_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 			    DA7219_HP_R_AMP_RAMP_EN_MASK,
 			    DA7219_HP_R_AMP_RAMP_EN_MASK);
 
 	/* Default minimum gain on HP to avoid pops during DAPM sequencing */
-	snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 			    DA7219_HP_L_AMP_MIN_GAIN_EN_MASK,
 			    DA7219_HP_L_AMP_MIN_GAIN_EN_MASK);
-	snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 			    DA7219_HP_R_AMP_MIN_GAIN_EN_MASK,
 			    DA7219_HP_R_AMP_MIN_GAIN_EN_MASK);
 
 	/* Default infinite tone gen, start/stop by Kcontrol */
-	snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
+	snd_soc_component_write(component, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
 
 	/* Initialise AAD block */
-	ret = da7219_aad_init(codec);
+	ret = da7219_aad_init(component);
 	if (ret)
 		goto err_disable_reg;
 
@@ -1850,39 +1960,44 @@ static int da7219_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int da7219_remove(struct snd_soc_codec *codec)
+static void da7219_remove(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
-	da7219_aad_exit(codec);
+	da7219_aad_exit(component);
+
+#ifdef CONFIG_COMMON_CLK
+	if (da7219->dai_clks_lookup)
+		clkdev_drop(da7219->dai_clks_lookup);
+#endif
 
 	/* Supplies */
-	return regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
+	regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
 }
 
 #ifdef CONFIG_PM
-static int da7219_suspend(struct snd_soc_codec *codec)
+static int da7219_suspend(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
 	/* Suspend AAD if we're not a wake-up source */
 	if (!da7219->wakeup_source)
-		da7219_aad_suspend(codec);
+		da7219_aad_suspend(component);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
 	return 0;
 }
 
-static int da7219_resume(struct snd_soc_codec *codec)
+static int da7219_resume(struct snd_soc_component *component)
 {
-	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	/* Resume AAD if previously suspended */
 	if (!da7219->wakeup_source)
-		da7219_aad_resume(codec);
+		da7219_aad_resume(component);
 
 	return 0;
 }
@@ -1891,21 +2006,22 @@ static int da7219_resume(struct snd_soc_codec *codec)
 #define da7219_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_da7219 = {
+static const struct snd_soc_component_driver soc_component_dev_da7219 = {
 	.probe			= da7219_probe,
 	.remove			= da7219_remove,
 	.suspend		= da7219_suspend,
 	.resume			= da7219_resume,
 	.set_bias_level		= da7219_set_bias_level,
-
-	.component_driver = {
-		.controls		= da7219_snd_controls,
-		.num_controls		= ARRAY_SIZE(da7219_snd_controls),
-		.dapm_widgets		= da7219_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(da7219_dapm_widgets),
-		.dapm_routes		= da7219_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(da7219_audio_map),
-	},
+	.controls		= da7219_snd_controls,
+	.num_controls		= ARRAY_SIZE(da7219_snd_controls),
+	.dapm_widgets		= da7219_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(da7219_dapm_widgets),
+	.dapm_routes		= da7219_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(da7219_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 
@@ -2090,7 +2206,7 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
 		}
 	}
 
-	/* Soft reset codec */
+	/* Soft reset component */
 	regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1,
 			  DA7219_ACCDET_EN_MASK, 0);
 	regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL,
@@ -2101,10 +2217,11 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
 
 	regcache_cache_bypass(da7219->regmap, false);
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_da7219,
 				     &da7219_dai, 1);
 	if (ret < 0) {
-		dev_err(&i2c->dev, "Failed to register da7219 codec: %d\n",
+		dev_err(&i2c->dev, "Failed to register da7219 component: %d\n",
 			ret);
 	}
 	return ret;
@@ -2112,7 +2229,6 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
 
 static int da7219_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h
index 8d6c3c8..1b00023 100644
--- a/sound/soc/codecs/da7219.h
+++ b/sound/soc/codecs/da7219.h
@@ -14,6 +14,9 @@
 #ifndef __DA7219_H
 #define __DA7219_H
 
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <sound/da7219.h>
@@ -813,6 +816,12 @@ struct da7219_priv {
 	struct mutex ctrl_lock;
 	struct mutex pll_lock;
 
+#ifdef CONFIG_COMMON_CLK
+	struct clk_hw dai_clks_hw;
+#endif
+	struct clk_lookup *dai_clks_lookup;
+	struct clk *dai_clks;
+
 	struct clk *mclk;
 	unsigned int mclk_rate;
 	int clk_src;
@@ -822,6 +831,6 @@ struct da7219_priv {
 	u8 gain_ramp_ctrl;
 };
 
-int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout);
+int da7219_set_pll(struct snd_soc_component *component, int source, unsigned int fout);
 
 #endif /* __DA7219_H */
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index 83db4d2..de275df 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -168,7 +168,7 @@ static const struct reg_default da732x_reg_cache[] = {
 	{ DA732X_REG_UNLOCK		, 0x00 },
 };
 
-static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk)
+static inline int da732x_get_input_div(struct snd_soc_component *component, int sysclk)
 {
 	int val;
 	int ret;
@@ -192,28 +192,28 @@ static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk)
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, DA732X_REG_PLL_CTRL, val);
+	snd_soc_component_write(component, DA732X_REG_PLL_CTRL, val);
 
 	return ret;
 }
 
-static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state)
+static void da732x_set_charge_pump(struct snd_soc_component *component, int state)
 {
 	switch (state) {
 	case DA732X_ENABLE_CP:
-		snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN);
-		snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN |
+		snd_soc_component_write(component, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN);
+		snd_soc_component_write(component, DA732X_REG_CP_HP2, DA732X_HP_CP_EN |
 			      DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP);
-		snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN |
+		snd_soc_component_write(component, DA732X_REG_CP_CTRL1, DA732X_CP_EN |
 			      DA732X_CP_CTRL_CPVDD1);
-		snd_soc_write(codec, DA732X_REG_CP_CTRL2,
+		snd_soc_component_write(component, DA732X_REG_CP_CTRL2,
 			      DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST);
-		snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ);
+		snd_soc_component_write(component, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ);
 		break;
 	case DA732X_DISABLE_CP:
-		snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS);
-		snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS);
-		snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS);
+		snd_soc_component_write(component, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS);
+		snd_soc_component_write(component, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS);
+		snd_soc_component_write(component, DA732X_REG_CP_CTRL1, DA723X_CP_DIS);
 		break;
 	default:
 		pr_err("Wrong charge pump state\n");
@@ -331,7 +331,7 @@ static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum,
 static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
 	unsigned int reg = enum_ctrl->reg;
 	unsigned int sel = ucontrol->value.enumerated.item[0];
@@ -351,7 +351,7 @@ static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits);
+	snd_soc_component_update_bits(component, reg, DA732X_HPF_MASK, bits);
 
 	return 0;
 }
@@ -359,12 +359,12 @@ static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
 static int da732x_hpf_get(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
 	unsigned int reg = enum_ctrl->reg;
 	int val;
 
-	val = snd_soc_read(codec, reg) & DA732X_HPF_MASK;
+	val = snd_soc_component_read32(component, reg) & DA732X_HPF_MASK;
 
 	switch (val) {
 	case DA732X_HPF_VOICE_EN:
@@ -609,18 +609,18 @@ static const struct snd_kcontrol_new da732x_snd_controls[] = {
 static int da732x_adc_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		switch (w->reg) {
 		case DA732X_REG_ADC1_PD:
-			snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
+			snd_soc_component_update_bits(component, DA732X_REG_CLK_EN3,
 					    DA732X_ADCA_BB_CLK_EN,
 					    DA732X_ADCA_BB_CLK_EN);
 			break;
 		case DA732X_REG_ADC2_PD:
-			snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
+			snd_soc_component_update_bits(component, DA732X_REG_CLK_EN3,
 					    DA732X_ADCC_BB_CLK_EN,
 					    DA732X_ADCC_BB_CLK_EN);
 			break;
@@ -628,24 +628,24 @@ static int da732x_adc_event(struct snd_soc_dapm_widget *w,
 			return -EINVAL;
 		}
 
-		snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
+		snd_soc_component_update_bits(component, w->reg, DA732X_ADC_RST_MASK,
 				    DA732X_ADC_SET_ACT);
-		snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
+		snd_soc_component_update_bits(component, w->reg, DA732X_ADC_PD_MASK,
 				    DA732X_ADC_ON);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
+		snd_soc_component_update_bits(component, w->reg, DA732X_ADC_PD_MASK,
 				    DA732X_ADC_OFF);
-		snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
+		snd_soc_component_update_bits(component, w->reg, DA732X_ADC_RST_MASK,
 				    DA732X_ADC_SET_RST);
 
 		switch (w->reg) {
 		case DA732X_REG_ADC1_PD:
-			snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
+			snd_soc_component_update_bits(component, DA732X_REG_CLK_EN3,
 					    DA732X_ADCA_BB_CLK_EN, 0);
 			break;
 		case DA732X_REG_ADC2_PD:
-			snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
+			snd_soc_component_update_bits(component, DA732X_REG_CLK_EN3,
 					    DA732X_ADCC_BB_CLK_EN, 0);
 			break;
 		default:
@@ -663,16 +663,16 @@ static int da732x_adc_event(struct snd_soc_dapm_widget *w,
 static int da732x_out_pga_event(struct snd_soc_dapm_widget *w,
 				struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, w->reg,
+		snd_soc_component_update_bits(component, w->reg,
 				    (1 << w->shift) | DA732X_OUT_HIZ_EN,
 				    (1 << w->shift) | DA732X_OUT_HIZ_EN);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, w->reg,
+		snd_soc_component_update_bits(component, w->reg,
 				    (1 << w->shift) | DA732X_OUT_HIZ_EN,
 				    (1 << w->shift) | DA732X_OUT_HIZ_DIS);
 		break;
@@ -949,7 +949,7 @@ static int da732x_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u32 aif = 0;
 	u32 reg_aif;
 	u32 fs;
@@ -1011,15 +1011,15 @@ static int da732x_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif);
-	snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs);
+	snd_soc_component_update_bits(component, reg_aif, DA732X_AIF_WORD_MASK, aif);
+	snd_soc_component_update_bits(component, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs);
 
 	return 0;
 }
 
 static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u32 aif_mclk, pc_count;
 	u32 reg_aif1, aif1;
 	u32 reg_aif3, aif3;
@@ -1107,29 +1107,29 @@ static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk);
-	snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1);
-	snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV |
+	snd_soc_component_write(component, DA732X_REG_AIF_MCLK, aif_mclk);
+	snd_soc_component_update_bits(component, reg_aif1, DA732X_AIF1_CLK_MASK, aif1);
+	snd_soc_component_update_bits(component, reg_aif3, DA732X_AIF_BCLK_INV |
 			    DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3);
-	snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count);
+	snd_soc_component_write(component, DA732X_REG_PC_CTRL, pc_count);
 
 	return 0;
 }
 
 
 
-static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
+static int da732x_set_dai_pll(struct snd_soc_component *component, int pll_id,
 			      int source, unsigned int freq_in,
 			      unsigned int freq_out)
 {
-	struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
+	struct da732x_priv *da732x = snd_soc_component_get_drvdata(component);
 	int fref, indiv;
 	u8 div_lo, div_mid, div_hi;
 	u64 frac_div;
 
 	/* Disable PLL */
 	if (freq_out == 0) {
-		snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
+		snd_soc_component_update_bits(component, DA732X_REG_PLL_CTRL,
 				    DA732X_PLL_EN, 0);
 		da732x->pll_en = false;
 		return 0;
@@ -1147,17 +1147,17 @@ static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
 		case 24576000:
 		case 45160000:
 		case 49152000:
-			snd_soc_write(codec, DA732X_REG_PLL_CTRL,
+			snd_soc_component_write(component, DA732X_REG_PLL_CTRL,
 				      DA732X_PLL_BYPASS);
 			return 0;
 		default:
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Cannot use PLL Bypass, invalid SYSCLK rate\n");
 			return -EINVAL;
 		}
 	}
 
-	indiv = da732x_get_input_div(codec, da732x->sysclk);
+	indiv = da732x_get_input_div(component, da732x->sysclk);
 	if (indiv < 0)
 		return indiv;
 
@@ -1168,11 +1168,11 @@ static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
 	div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK;
 	div_lo = (frac_div) & DA732X_U8_MASK;
 
-	snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo);
-	snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid);
-	snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi);
+	snd_soc_component_write(component, DA732X_REG_PLL_DIV_LO, div_lo);
+	snd_soc_component_write(component, DA732X_REG_PLL_DIV_MID, div_mid);
+	snd_soc_component_write(component, DA732X_REG_PLL_DIV_HI, div_hi);
 
-	snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN,
+	snd_soc_component_update_bits(component, DA732X_REG_PLL_CTRL, DA732X_PLL_EN,
 			    DA732X_PLL_EN);
 
 	da732x->pll_en = true;
@@ -1183,8 +1183,8 @@ static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
 static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 				 unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct da732x_priv *da732x = snd_soc_component_get_drvdata(component);
 
 	da732x->sysclk = freq;
 
@@ -1268,21 +1268,21 @@ static const struct regmap_config da732x_regmap = {
 };
 
 
-static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
+static void da732x_dac_offset_adjust(struct snd_soc_component *component)
 {
 	u8 offset[DA732X_HP_DACS];
 	u8 sign[DA732X_HP_DACS];
 	u8 step = DA732X_DAC_OFFSET_STEP;
 
 	/* Initialize DAC offset calibration circuits and registers */
-	snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
+	snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFFSET,
 		      DA732X_HP_DAC_OFFSET_TRIM_VAL);
-	snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
+	snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFFSET,
 		      DA732X_HP_DAC_OFFSET_TRIM_VAL);
-	snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
+	snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFF_CNTL,
 		      DA732X_HP_DAC_OFF_CALIBRATION |
 		      DA732X_HP_DAC_OFF_SCALE_STEPS);
-	snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
+	snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFF_CNTL,
 		      DA732X_HP_DAC_OFF_CALIBRATION |
 		      DA732X_HP_DAC_OFF_SCALE_STEPS);
 
@@ -1290,9 +1290,9 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
 	msleep(DA732X_WAIT_FOR_STABILIZATION);
 
 	/* Check DAC offset sign */
-	sign[DA732X_HPL_DAC] = (snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
+	sign[DA732X_HPL_DAC] = (snd_soc_component_read32(component, DA732X_REG_HPL_DAC_OFF_CNTL) &
 				DA732X_HP_DAC_OFF_CNTL_COMPO);
-	sign[DA732X_HPR_DAC] = (snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
+	sign[DA732X_HPR_DAC] = (snd_soc_component_read32(component, DA732X_REG_HPR_DAC_OFF_CNTL) &
 				DA732X_HP_DAC_OFF_CNTL_COMPO);
 
 	/* Binary search DAC offset values (both channels at once) */
@@ -1302,17 +1302,17 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
 	do {
 		offset[DA732X_HPL_DAC] |= step;
 		offset[DA732X_HPR_DAC] |= step;
-		snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
+		snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFFSET,
 			      ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK);
-		snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
+		snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFFSET,
 			      ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK);
 
 		msleep(DA732X_WAIT_FOR_STABILIZATION);
 
-		if ((snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
+		if ((snd_soc_component_read32(component, DA732X_REG_HPL_DAC_OFF_CNTL) &
 		     DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC])
 			offset[DA732X_HPL_DAC] &= ~step;
-		if ((snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
+		if ((snd_soc_component_read32(component, DA732X_REG_HPR_DAC_OFF_CNTL) &
 		     DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC])
 			offset[DA732X_HPR_DAC] &= ~step;
 
@@ -1320,19 +1320,19 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
 	} while (step);
 
 	/* Write final DAC offsets to registers */
-	snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
+	snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFFSET,
 		      ~offset[DA732X_HPL_DAC] &	DA732X_HP_DAC_OFF_MASK);
-	snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
+	snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFFSET,
 		      ~offset[DA732X_HPR_DAC] &	DA732X_HP_DAC_OFF_MASK);
 
 	/* End DAC calibration mode */
-	snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
+	snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFF_CNTL,
 		DA732X_HP_DAC_OFF_SCALE_STEPS);
-	snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
+	snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFF_CNTL,
 		DA732X_HP_DAC_OFF_SCALE_STEPS);
 }
 
-static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
+static void da732x_output_offset_adjust(struct snd_soc_component *component)
 {
 	u8 offset[DA732X_HP_AMPS];
 	u8 sign[DA732X_HP_AMPS];
@@ -1342,26 +1342,26 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
 	offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL;
 
 	/* Initialize output offset calibration circuits and registers  */
-	snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
-	snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
-	snd_soc_write(codec, DA732X_REG_HPL,
+	snd_soc_component_write(component, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
+	snd_soc_component_write(component, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
+	snd_soc_component_write(component, DA732X_REG_HPL,
 		      DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
-	snd_soc_write(codec, DA732X_REG_HPR,
+	snd_soc_component_write(component, DA732X_REG_HPR,
 		      DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
 
 	/* Wait for voltage stabilization */
 	msleep(DA732X_WAIT_FOR_STABILIZATION);
 
 	/* Check output offset sign */
-	sign[DA732X_HPL_AMP] = snd_soc_read(codec, DA732X_REG_HPL) &
+	sign[DA732X_HPL_AMP] = snd_soc_component_read32(component, DA732X_REG_HPL) &
 			       DA732X_HP_OUT_COMPO;
-	sign[DA732X_HPR_AMP] = snd_soc_read(codec, DA732X_REG_HPR) &
+	sign[DA732X_HPR_AMP] = snd_soc_component_read32(component, DA732X_REG_HPR) &
 			       DA732X_HP_OUT_COMPO;
 
-	snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
+	snd_soc_component_write(component, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
 		      (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
 		      DA732X_HP_OUT_EN);
-	snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP |
+	snd_soc_component_write(component, DA732X_REG_HPR, DA732X_HP_OUT_COMP |
 		      (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
 		      DA732X_HP_OUT_EN);
 
@@ -1369,17 +1369,17 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
 	do {
 		offset[DA732X_HPL_AMP] |= step;
 		offset[DA732X_HPR_AMP] |= step;
-		snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET,
+		snd_soc_component_write(component, DA732X_REG_HPL_OUT_OFFSET,
 			      offset[DA732X_HPL_AMP]);
-		snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET,
+		snd_soc_component_write(component, DA732X_REG_HPR_OUT_OFFSET,
 			      offset[DA732X_HPR_AMP]);
 
 		msleep(DA732X_WAIT_FOR_STABILIZATION);
 
-		if ((snd_soc_read(codec, DA732X_REG_HPL) &
+		if ((snd_soc_component_read32(component, DA732X_REG_HPL) &
 		     DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP])
 			offset[DA732X_HPL_AMP] &= ~step;
-		if ((snd_soc_read(codec, DA732X_REG_HPR) &
+		if ((snd_soc_component_read32(component, DA732X_REG_HPR) &
 		     DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP])
 			offset[DA732X_HPR_AMP] &= ~step;
 
@@ -1387,80 +1387,80 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
 	} while (step);
 
 	/* Write final DAC offsets to registers */
-	snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]);
-	snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]);
+	snd_soc_component_write(component, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]);
+	snd_soc_component_write(component, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]);
 }
 
-static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec)
+static void da732x_hp_dc_offset_cancellation(struct snd_soc_component *component)
 {
 	/* Make sure that we have Soft Mute enabled */
-	snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN |
+	snd_soc_component_write(component, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN |
 		      DA732X_GAIN_RAMPED | DA732X_16_SAMPLES);
-	snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN |
+	snd_soc_component_write(component, DA732X_REG_DAC1_SEL, DA732X_DACL_EN |
 		      DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM |
 		      DA732X_DACL_MUTE | DA732X_DACR_MUTE);
-	snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN |
+	snd_soc_component_write(component, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN |
 		      DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN);
-	snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN |
+	snd_soc_component_write(component, DA732X_REG_HPR, DA732X_HP_OUT_EN |
 		      DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN);
 
-	da732x_dac_offset_adjust(codec);
-	da732x_output_offset_adjust(codec);
+	da732x_dac_offset_adjust(component);
+	da732x_output_offset_adjust(component);
 
-	snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS);
-	snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS);
-	snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS);
+	snd_soc_component_write(component, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS);
+	snd_soc_component_write(component, DA732X_REG_HPL, DA732X_HP_DIS);
+	snd_soc_component_write(component, DA732X_REG_HPR, DA732X_HP_DIS);
 }
 
-static int da732x_set_bias_level(struct snd_soc_codec *codec,
+static int da732x_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
+	struct da732x_priv *da732x = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
+		snd_soc_component_update_bits(component, DA732X_REG_BIAS_EN,
 				    DA732X_BIAS_BOOST_MASK,
 				    DA732X_BIAS_BOOST_100PC);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Init Codec */
-			snd_soc_write(codec, DA732X_REG_REF1,
+			snd_soc_component_write(component, DA732X_REG_REF1,
 				      DA732X_VMID_FASTCHG);
-			snd_soc_write(codec, DA732X_REG_BIAS_EN,
+			snd_soc_component_write(component, DA732X_REG_BIAS_EN,
 				      DA732X_BIAS_EN);
 
 			mdelay(DA732X_STARTUP_DELAY);
 
 			/* Disable Fast Charge and enable DAC ref voltage */
-			snd_soc_write(codec, DA732X_REG_REF1,
+			snd_soc_component_write(component, DA732X_REG_REF1,
 				      DA732X_REFBUFX2_EN);
 
 			/* Enable bypass DSP routing */
-			snd_soc_write(codec, DA732X_REG_DATA_ROUTE,
+			snd_soc_component_write(component, DA732X_REG_DATA_ROUTE,
 				      DA732X_BYPASS_DSP);
 
 			/* Enable Digital subsystem */
-			snd_soc_write(codec, DA732X_REG_DSP_CTRL,
+			snd_soc_component_write(component, DA732X_REG_DSP_CTRL,
 				      DA732X_DIGITAL_EN);
 
-			snd_soc_write(codec, DA732X_REG_SPARE1_OUT,
+			snd_soc_component_write(component, DA732X_REG_SPARE1_OUT,
 				      DA732X_HP_DRIVER_EN |
 				      DA732X_HP_GATE_LOW |
 				      DA732X_HP_LOOP_GAIN_CTRL);
-			snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL,
+			snd_soc_component_write(component, DA732X_REG_HP_LIN1_GNDSEL,
 				      DA732X_HP_OUT_GNDSEL);
 
-			da732x_set_charge_pump(codec, DA732X_ENABLE_CP);
+			da732x_set_charge_pump(component, DA732X_ENABLE_CP);
 
-			snd_soc_write(codec, DA732X_REG_CLK_EN1,
+			snd_soc_component_write(component, DA732X_REG_CLK_EN1,
 			      DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN);
 
 			/* Enable Zero Crossing */
-			snd_soc_write(codec, DA732X_REG_INP_ZC_EN,
+			snd_soc_component_write(component, DA732X_REG_INP_ZC_EN,
 				      DA732X_MIC1_PRE_ZC_EN |
 				      DA732X_MIC1_ZC_EN |
 				      DA732X_MIC2_PRE_ZC_EN |
@@ -1469,28 +1469,28 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
 				      DA732X_AUXR_ZC_EN |
 				      DA732X_MIC3_PRE_ZC_EN |
 				      DA732X_MIC3_ZC_EN);
-			snd_soc_write(codec, DA732X_REG_OUT_ZC_EN,
+			snd_soc_component_write(component, DA732X_REG_OUT_ZC_EN,
 				      DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN |
 				      DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN |
 				      DA732X_LIN4_ZC_EN);
 
-			da732x_hp_dc_offset_cancellation(codec);
+			da732x_hp_dc_offset_cancellation(component);
 
 			regcache_cache_only(da732x->regmap, false);
 			regcache_sync(da732x->regmap);
 		} else {
-			snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
+			snd_soc_component_update_bits(component, DA732X_REG_BIAS_EN,
 					    DA732X_BIAS_BOOST_MASK,
 					    DA732X_BIAS_BOOST_50PC);
-			snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
+			snd_soc_component_update_bits(component, DA732X_REG_PLL_CTRL,
 					    DA732X_PLL_EN, 0);
 			da732x->pll_en = false;
 		}
 		break;
 	case SND_SOC_BIAS_OFF:
 		regcache_cache_only(da732x->regmap, true);
-		da732x_set_charge_pump(codec, DA732X_DISABLE_CP);
-		snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
+		da732x_set_charge_pump(component, DA732X_DISABLE_CP);
+		snd_soc_component_update_bits(component, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
 				    DA732X_BIAS_DIS);
 		da732x->pll_en = false;
 		break;
@@ -1499,17 +1499,19 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_da732x = {
+static const struct snd_soc_component_driver soc_component_dev_da732x = {
 	.set_bias_level		= da732x_set_bias_level,
-	.component_driver = {
-		.controls		= da732x_snd_controls,
-		.num_controls		= ARRAY_SIZE(da732x_snd_controls),
-		.dapm_widgets		= da732x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(da732x_dapm_widgets),
-		.dapm_routes		= da732x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(da732x_dapm_routes),
-	},
+	.controls		= da732x_snd_controls,
+	.num_controls		= ARRAY_SIZE(da732x_snd_controls),
+	.dapm_widgets		= da732x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(da732x_dapm_widgets),
+	.dapm_routes		= da732x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(da732x_dapm_routes),
 	.set_pll		= da732x_set_dai_pll,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int da732x_i2c_probe(struct i2c_client *i2c,
@@ -1543,10 +1545,11 @@ static int da732x_i2c_probe(struct i2c_client *i2c,
 		 (reg & DA732X_ID_MAJOR_MASK) >> 4,
 		 (reg & DA732X_ID_MINOR_MASK));
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_da732x,
 				     da732x_dai, ARRAY_SIZE(da732x_dai));
 	if (ret != 0)
-		dev_err(&i2c->dev, "Failed to register codec.\n");
+		dev_err(&i2c->dev, "Failed to register component.\n");
 
 err:
 	return ret;
@@ -1554,8 +1557,6 @@ static int da732x_i2c_probe(struct i2c_client *i2c,
 
 static int da732x_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
index bd7faae..afdf90c 100644
--- a/sound/soc/codecs/da9055.c
+++ b/sound/soc/codecs/da9055.c
@@ -451,7 +451,7 @@ static const char * const da9055_hold_time_txt[] = {
 static SOC_ENUM_SINGLE_DECL(da9055_hold_time,
 			    DA9055_ALC_CTRL3, 0, da9055_hold_time_txt);
 
-static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
+static int da9055_get_alc_data(struct snd_soc_component *component, u8 reg_val)
 {
 	int mid_data, top_data;
 	int sum = 0;
@@ -460,17 +460,17 @@ static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
 	for (iteration = 0; iteration < DA9055_ALC_AVG_ITERATIONS;
 	     iteration++) {
 		/* Select the left or right channel and capture data */
-		snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL, reg_val);
+		snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL, reg_val);
 
 		/* Select middle 8 bits for read back from data register */
-		snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL,
+		snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL,
 			      reg_val | DA9055_ALC_DATA_MIDDLE);
-		mid_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA);
+		mid_data = snd_soc_component_read32(component, DA9055_ALC_CIC_OP_LVL_DATA);
 
 		/* Select top 8 bits for read back from data register */
-		snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL,
+		snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL,
 			      reg_val | DA9055_ALC_DATA_TOP);
-		top_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA);
+		top_data = snd_soc_component_read32(component, DA9055_ALC_CIC_OP_LVL_DATA);
 
 		sum += ((mid_data << 8) | (top_data << 16));
 	}
@@ -481,7 +481,7 @@ static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
 static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	u8 reg_val, adc_left, adc_right, mic_left, mic_right;
 	int avg_left_data, avg_right_data, offset_l, offset_r;
 
@@ -492,31 +492,31 @@ static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,
 		 */
 
 		/* Save current values from Mic control registers */
-		mic_left = snd_soc_read(codec, DA9055_MIC_L_CTRL);
-		mic_right = snd_soc_read(codec, DA9055_MIC_R_CTRL);
+		mic_left = snd_soc_component_read32(component, DA9055_MIC_L_CTRL);
+		mic_right = snd_soc_component_read32(component, DA9055_MIC_R_CTRL);
 
 		/* Mute Mic PGA Left and Right */
-		snd_soc_update_bits(codec, DA9055_MIC_L_CTRL,
+		snd_soc_component_update_bits(component, DA9055_MIC_L_CTRL,
 				    DA9055_MIC_L_MUTE_EN, DA9055_MIC_L_MUTE_EN);
-		snd_soc_update_bits(codec, DA9055_MIC_R_CTRL,
+		snd_soc_component_update_bits(component, DA9055_MIC_R_CTRL,
 				    DA9055_MIC_R_MUTE_EN, DA9055_MIC_R_MUTE_EN);
 
 		/* Save current values from ADC control registers */
-		adc_left = snd_soc_read(codec, DA9055_ADC_L_CTRL);
-		adc_right = snd_soc_read(codec, DA9055_ADC_R_CTRL);
+		adc_left = snd_soc_component_read32(component, DA9055_ADC_L_CTRL);
+		adc_right = snd_soc_component_read32(component, DA9055_ADC_R_CTRL);
 
 		/* Enable ADC Left and Right */
-		snd_soc_update_bits(codec, DA9055_ADC_L_CTRL,
+		snd_soc_component_update_bits(component, DA9055_ADC_L_CTRL,
 				    DA9055_ADC_L_EN, DA9055_ADC_L_EN);
-		snd_soc_update_bits(codec, DA9055_ADC_R_CTRL,
+		snd_soc_component_update_bits(component, DA9055_ADC_R_CTRL,
 				    DA9055_ADC_R_EN, DA9055_ADC_R_EN);
 
 		/* Calculate average for Left and Right data */
 		/* Left Data */
-		avg_left_data = da9055_get_alc_data(codec,
+		avg_left_data = da9055_get_alc_data(component,
 				DA9055_ALC_CIC_OP_CHANNEL_LEFT);
 		/* Right Data */
-		avg_right_data = da9055_get_alc_data(codec,
+		avg_right_data = da9055_get_alc_data(component,
 				 DA9055_ALC_CIC_OP_CHANNEL_RIGHT);
 
 		/* Calculate DC offset */
@@ -524,22 +524,22 @@ static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,
 		offset_r = -avg_right_data;
 
 		reg_val = (offset_l & DA9055_ALC_OFFSET_15_8) >> 8;
-		snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_L, reg_val);
+		snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2M_L, reg_val);
 		reg_val = (offset_l & DA9055_ALC_OFFSET_17_16) >> 16;
-		snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_L, reg_val);
+		snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2U_L, reg_val);
 
 		reg_val = (offset_r & DA9055_ALC_OFFSET_15_8) >> 8;
-		snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_R, reg_val);
+		snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2M_R, reg_val);
 		reg_val = (offset_r & DA9055_ALC_OFFSET_17_16) >> 16;
-		snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_R, reg_val);
+		snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2U_R, reg_val);
 
 		/* Restore original values of ADC control registers */
-		snd_soc_write(codec, DA9055_ADC_L_CTRL, adc_left);
-		snd_soc_write(codec, DA9055_ADC_R_CTRL, adc_right);
+		snd_soc_component_write(component, DA9055_ADC_L_CTRL, adc_left);
+		snd_soc_component_write(component, DA9055_ADC_R_CTRL, adc_right);
 
 		/* Restore original values of Mic control registers */
-		snd_soc_write(codec, DA9055_MIC_L_CTRL, mic_left);
-		snd_soc_write(codec, DA9055_MIC_R_CTRL, mic_right);
+		snd_soc_component_write(component, DA9055_MIC_L_CTRL, mic_left);
+		snd_soc_component_write(component, DA9055_MIC_R_CTRL, mic_right);
 	}
 
 	return snd_soc_put_volsw(kcontrol, ucontrol);
@@ -1052,8 +1052,8 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
 	u8 aif_ctrl, fs;
 	u32 sysclk;
 
@@ -1075,7 +1075,7 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* Set AIF format */
-	snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_WORD_LENGTH_MASK,
+	snd_soc_component_update_bits(component, DA9055_AIF_CTRL, DA9055_AIF_WORD_LENGTH_MASK,
 			    aif_ctrl);
 
 	switch (params_rate(params)) {
@@ -1125,7 +1125,7 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
 
 	if (da9055->mclk_rate) {
 		/* PLL Mode, Write actual FS */
-		snd_soc_write(codec, DA9055_SR, fs);
+		snd_soc_component_write(component, DA9055_SR, fs);
 	} else {
 		/*
 		 * Non-PLL Mode
@@ -1134,24 +1134,24 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
 		 * to derive its sys clk. As sys clk has to be 256 * Fs, we
 		 * need to write constant sample rate i.e. 48KHz.
 		 */
-		snd_soc_write(codec, DA9055_SR, DA9055_SR_48000);
+		snd_soc_component_write(component, DA9055_SR, DA9055_SR_48000);
 	}
 
 	if (da9055->mclk_rate && (da9055->mclk_rate != sysclk)) {
 		/* PLL Mode */
 		if (!da9055->master) {
 			/* PLL slave mode, enable PLL and also SRM */
-			snd_soc_update_bits(codec, DA9055_PLL_CTRL,
+			snd_soc_component_update_bits(component, DA9055_PLL_CTRL,
 					    DA9055_PLL_EN | DA9055_PLL_SRM_EN,
 					    DA9055_PLL_EN | DA9055_PLL_SRM_EN);
 		} else {
 			/* PLL master mode, only enable PLL */
-			snd_soc_update_bits(codec, DA9055_PLL_CTRL,
+			snd_soc_component_update_bits(component, DA9055_PLL_CTRL,
 					    DA9055_PLL_EN, DA9055_PLL_EN);
 		}
 	} else {
 		/* Non PLL Mode, disable PLL */
-		snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
+		snd_soc_component_update_bits(component, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
 	}
 
 	return 0;
@@ -1160,8 +1160,8 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
 /* Set DAI mode and Format */
 static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
 	u8 aif_clk_mode, aif_ctrl, mode;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1180,7 +1180,7 @@ static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	}
 
 	/* Don't allow change of mode if PLL is enabled */
-	if ((snd_soc_read(codec, DA9055_PLL_CTRL) & DA9055_PLL_EN) &&
+	if ((snd_soc_component_read32(component, DA9055_PLL_CTRL) & DA9055_PLL_EN) &&
 	    (da9055->master != mode))
 		return -EINVAL;
 
@@ -1207,27 +1207,27 @@ static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	/* By default only 32 BCLK per WCLK is supported */
 	aif_clk_mode |= DA9055_AIF_BCLKS_PER_WCLK_32;
 
-	snd_soc_update_bits(codec, DA9055_AIF_CLK_MODE,
+	snd_soc_component_update_bits(component, DA9055_AIF_CLK_MODE,
 			    (DA9055_AIF_CLK_MODE_MASK | DA9055_AIF_BCLK_MASK),
 			    aif_clk_mode);
-	snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_FORMAT_MASK,
+	snd_soc_component_update_bits(component, DA9055_AIF_CTRL, DA9055_AIF_FORMAT_MASK,
 			    aif_ctrl);
 	return 0;
 }
 
 static int da9055_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (mute) {
-		snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+		snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,
 				    DA9055_DAC_L_MUTE_EN, DA9055_DAC_L_MUTE_EN);
-		snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+		snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,
 				    DA9055_DAC_R_MUTE_EN, DA9055_DAC_R_MUTE_EN);
 	} else {
-		snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+		snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,
 				    DA9055_DAC_L_MUTE_EN, 0);
-		snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+		snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,
 				    DA9055_DAC_R_MUTE_EN, 0);
 	}
 
@@ -1240,8 +1240,8 @@ static int da9055_mute(struct snd_soc_dai *dai, int mute)
 static int da9055_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case DA9055_CLKSRC_MCLK:
@@ -1283,13 +1283,13 @@ static int da9055_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int da9055_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 			      int source, unsigned int fref, unsigned int fout)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
 
 	u8 pll_frac_top, pll_frac_bot, pll_integer, cnt;
 
 	/* Disable PLL before setting the divisors */
-	snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
+	snd_soc_component_update_bits(component, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
 
 	/* In slave mode, there is only one set of divisors */
 	if (!da9055->master && (fout != 2822400))
@@ -1312,9 +1312,9 @@ static int da9055_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		goto pll_err;
 
 	/* Write PLL dividers */
-	snd_soc_write(codec, DA9055_PLL_FRAC_TOP, pll_frac_top);
-	snd_soc_write(codec, DA9055_PLL_FRAC_BOT, pll_frac_bot);
-	snd_soc_write(codec, DA9055_PLL_INTEGER, pll_integer);
+	snd_soc_component_write(component, DA9055_PLL_FRAC_TOP, pll_frac_top);
+	snd_soc_component_write(component, DA9055_PLL_FRAC_BOT, pll_frac_bot);
+	snd_soc_component_write(component, DA9055_PLL_INTEGER, pll_integer);
 
 	return 0;
 pll_err:
@@ -1353,7 +1353,7 @@ static struct snd_soc_dai_driver da9055_dai = {
 	.symmetric_rates = 1,
 };
 
-static int da9055_set_bias_level(struct snd_soc_codec *codec,
+static int da9055_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
@@ -1361,48 +1361,48 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Enable VMID reference & master bias */
-			snd_soc_update_bits(codec, DA9055_REFERENCES,
+			snd_soc_component_update_bits(component, DA9055_REFERENCES,
 					    DA9055_VMID_EN | DA9055_BIAS_EN,
 					    DA9055_VMID_EN | DA9055_BIAS_EN);
 		}
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* Disable VMID reference & master bias */
-		snd_soc_update_bits(codec, DA9055_REFERENCES,
+		snd_soc_component_update_bits(component, DA9055_REFERENCES,
 				    DA9055_VMID_EN | DA9055_BIAS_EN, 0);
 		break;
 	}
 	return 0;
 }
 
-static int da9055_probe(struct snd_soc_codec *codec)
+static int da9055_probe(struct snd_soc_component *component)
 {
-	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+	struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
 
 	/* Enable all Gain Ramps */
-	snd_soc_update_bits(codec, DA9055_AUX_L_CTRL,
+	snd_soc_component_update_bits(component, DA9055_AUX_L_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_AUX_R_CTRL,
+	snd_soc_component_update_bits(component, DA9055_AUX_R_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL,
+	snd_soc_component_update_bits(component, DA9055_MIXIN_L_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL,
+	snd_soc_component_update_bits(component, DA9055_MIXIN_R_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_ADC_L_CTRL,
+	snd_soc_component_update_bits(component, DA9055_ADC_L_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_ADC_R_CTRL,
+	snd_soc_component_update_bits(component, DA9055_ADC_R_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+	snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+	snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_HP_L_CTRL,
+	snd_soc_component_update_bits(component, DA9055_HP_L_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_HP_R_CTRL,
+	snd_soc_component_update_bits(component, DA9055_HP_R_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-	snd_soc_update_bits(codec, DA9055_LINE_CTRL,
+	snd_soc_component_update_bits(component, DA9055_LINE_CTRL,
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
 
 	/*
@@ -1412,28 +1412,28 @@ static int da9055_probe(struct snd_soc_codec *codec)
 	 * being managed by DAPM while other (non power related) bits are
 	 * enabled here
 	 */
-	snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL,
+	snd_soc_component_update_bits(component, DA9055_MIXIN_L_CTRL,
 			    DA9055_MIXIN_L_MIX_EN, DA9055_MIXIN_L_MIX_EN);
-	snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL,
+	snd_soc_component_update_bits(component, DA9055_MIXIN_R_CTRL,
 			    DA9055_MIXIN_R_MIX_EN, DA9055_MIXIN_R_MIX_EN);
 
-	snd_soc_update_bits(codec, DA9055_MIXOUT_L_CTRL,
+	snd_soc_component_update_bits(component, DA9055_MIXOUT_L_CTRL,
 			    DA9055_MIXOUT_L_MIX_EN, DA9055_MIXOUT_L_MIX_EN);
-	snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL,
+	snd_soc_component_update_bits(component, DA9055_MIXOUT_R_CTRL,
 			    DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN);
 
 	/* Set this as per your system configuration */
-	snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ);
+	snd_soc_component_write(component, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ);
 
 	/* Set platform data values */
 	if (da9055->pdata) {
 		/* set mic bias source */
 		if (da9055->pdata->micbias_source) {
-			snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT,
+			snd_soc_component_update_bits(component, DA9055_MIXIN_R_SELECT,
 					    DA9055_MICBIAS2_EN,
 					    DA9055_MICBIAS2_EN);
 		} else {
-			snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT,
+			snd_soc_component_update_bits(component, DA9055_MIXIN_R_SELECT,
 					    DA9055_MICBIAS2_EN, 0);
 		}
 		/* set mic bias voltage */
@@ -1442,7 +1442,7 @@ static int da9055_probe(struct snd_soc_codec *codec)
 		case DA9055_MICBIAS_2_1V:
 		case DA9055_MICBIAS_1_8V:
 		case DA9055_MICBIAS_1_6V:
-			snd_soc_update_bits(codec, DA9055_MIC_CONFIG,
+			snd_soc_component_update_bits(component, DA9055_MIC_CONFIG,
 					    DA9055_MICBIAS_LEVEL_MASK,
 					    (da9055->pdata->micbias) << 4);
 			break;
@@ -1451,18 +1451,19 @@ static int da9055_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_da9055 = {
+static const struct snd_soc_component_driver soc_component_dev_da9055 = {
 	.probe			= da9055_probe,
 	.set_bias_level		= da9055_set_bias_level,
-
-	.component_driver = {
-		.controls		= da9055_snd_controls,
-		.num_controls		= ARRAY_SIZE(da9055_snd_controls),
-		.dapm_widgets		= da9055_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(da9055_dapm_widgets),
-		.dapm_routes		= da9055_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(da9055_audio_map),
-	},
+	.controls		= da9055_snd_controls,
+	.num_controls		= ARRAY_SIZE(da9055_snd_controls),
+	.dapm_widgets		= da9055_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(da9055_dapm_widgets),
+	.dapm_routes		= da9055_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(da9055_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config da9055_regmap_config = {
@@ -1499,21 +1500,15 @@ static int da9055_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_da9055, &da9055_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_da9055, &da9055_dai, 1);
 	if (ret < 0) {
-		dev_err(&i2c->dev, "Failed to register da9055 codec: %d\n",
+		dev_err(&i2c->dev, "Failed to register da9055 component: %d\n",
 			ret);
 	}
 	return ret;
 }
 
-static int da9055_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 /*
  * DO NOT change the device Ids. The naming is intentionally specific as both
  * the CODEC and PMIC parts of this chip are instantiated separately as I2C
@@ -1540,7 +1535,6 @@ static struct i2c_driver da9055_i2c_driver = {
 		.of_match_table = of_match_ptr(da9055_of_match),
 	},
 	.probe		= da9055_i2c_probe,
-	.remove		= da9055_remove,
 	.id_table	= da9055_i2c_id,
 };
 
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index cf83c42..8c4926d 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/platform_device.h>
@@ -29,34 +30,33 @@
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 
-static int dmic_daiops_trigger(struct snd_pcm_substream *substream,
-		int cmd, struct snd_soc_dai *dai)
-{
-	struct gpio_desc *dmic_en = snd_soc_dai_get_drvdata(dai);
+struct dmic {
+	struct gpio_desc *gpio_en;
+	int wakeup_delay;
+};
 
-	if (!dmic_en)
-		return 0;
+static int dmic_aif_event(struct snd_soc_dapm_widget *w,
+			  struct snd_kcontrol *kcontrol, int event) {
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct dmic *dmic = snd_soc_component_get_drvdata(component);
 
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-	case SNDRV_PCM_TRIGGER_RESUME:
-	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		gpiod_set_value(dmic_en, 1);
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		if (dmic->gpio_en)
+			gpiod_set_value(dmic->gpio_en, 1);
+
+		if (dmic->wakeup_delay)
+			msleep(dmic->wakeup_delay);
 		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-	case SNDRV_PCM_TRIGGER_SUSPEND:
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		gpiod_set_value(dmic_en, 0);
+	case SND_SOC_DAPM_POST_PMD:
+		if (dmic->gpio_en)
+			gpiod_set_value(dmic->gpio_en, 0);
 		break;
 	}
 
 	return 0;
 }
 
-static const struct snd_soc_dai_ops dmic_dai_ops = {
-	.trigger	= dmic_daiops_trigger,
-};
-
 static struct snd_soc_dai_driver dmic_dai = {
 	.name = "dmic-hifi",
 	.capture = {
@@ -68,26 +68,33 @@ static struct snd_soc_dai_driver dmic_dai = {
 			| SNDRV_PCM_FMTBIT_S24_LE
 			| SNDRV_PCM_FMTBIT_S16_LE,
 	},
-	.ops    = &dmic_dai_ops,
 };
 
-static int dmic_codec_probe(struct snd_soc_codec *codec)
+static int dmic_component_probe(struct snd_soc_component *component)
 {
-	struct gpio_desc *dmic_en;
+	struct dmic *dmic;
 
-	dmic_en = devm_gpiod_get_optional(codec->dev,
-					"dmicen", GPIOD_OUT_LOW);
-	if (IS_ERR(dmic_en))
-		return PTR_ERR(dmic_en);
+	dmic = devm_kzalloc(component->dev, sizeof(*dmic), GFP_KERNEL);
+	if (!dmic)
+		return -ENOMEM;
 
-	snd_soc_codec_set_drvdata(codec, dmic_en);
+	dmic->gpio_en = devm_gpiod_get_optional(component->dev,
+						"dmicen", GPIOD_OUT_LOW);
+	if (IS_ERR(dmic->gpio_en))
+		return PTR_ERR(dmic->gpio_en);
+
+	device_property_read_u32(component->dev, "wakeup-delay-ms",
+				 &dmic->wakeup_delay);
+
+	snd_soc_component_set_drvdata(component, dmic);
 
 	return 0;
 }
 
 static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
-	SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
-			     SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_OUT_E("DMIC AIF", "Capture", 0,
+			       SND_SOC_NOPM, 0, 0, dmic_aif_event,
+			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 	SND_SOC_DAPM_INPUT("DMic"),
 };
 
@@ -95,14 +102,16 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"DMIC AIF", NULL, "DMic"},
 };
 
-static const struct snd_soc_codec_driver soc_dmic = {
-	.probe = dmic_codec_probe,
-	.component_driver = {
-		.dapm_widgets		= dmic_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(dmic_dapm_widgets),
-		.dapm_routes		= intercon,
-		.num_dapm_routes	= ARRAY_SIZE(intercon),
-	},
+static const struct snd_soc_component_driver soc_dmic = {
+	.probe			= dmic_component_probe,
+	.dapm_widgets		= dmic_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(dmic_dapm_widgets),
+	.dapm_routes		= intercon,
+	.num_dapm_routes	= ARRAY_SIZE(intercon),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int dmic_dev_probe(struct platform_device *pdev)
@@ -129,16 +138,10 @@ static int dmic_dev_probe(struct platform_device *pdev)
 		}
 	}
 
-	return snd_soc_register_codec(&pdev->dev,
+	return devm_snd_soc_register_component(&pdev->dev,
 			&soc_dmic, dai_drv, 1);
 }
 
-static int dmic_dev_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 MODULE_ALIAS("platform:dmic-codec");
 
 static const struct of_device_id dmic_dev_match[] = {
@@ -152,7 +155,6 @@ static struct platform_driver dmic_driver = {
 		.of_match_table = dmic_dev_match,
 	},
 	.probe = dmic_dev_probe,
-	.remove = dmic_dev_remove,
 };
 
 module_platform_driver(dmic_driver);
diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c
index 3869025..58515bb 100644
--- a/sound/soc/codecs/es7134.c
+++ b/sound/soc/codecs/es7134.c
@@ -69,28 +69,24 @@ static const struct snd_soc_dapm_route es7134_dapm_routes[] = {
 	{ "AOUTR", NULL, "DAC" },
 };
 
-static const struct snd_soc_codec_driver es7134_codec_driver = {
-	.component_driver = {
-		.dapm_widgets		= es7134_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(es7134_dapm_widgets),
-		.dapm_routes		= es7134_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(es7134_dapm_routes),
-	},
+static const struct snd_soc_component_driver es7134_component_driver = {
+	.dapm_widgets		= es7134_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(es7134_dapm_widgets),
+	.dapm_routes		= es7134_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(es7134_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int es7134_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-				      &es7134_codec_driver,
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &es7134_component_driver,
 				      &es7134_dai, 1);
 }
 
-static int es7134_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id es7134_ids[] = {
 	{ .compatible = "everest,es7134", },
@@ -106,7 +102,6 @@ static struct platform_driver es7134_driver = {
 		.of_match_table = of_match_ptr(es7134_ids),
 	},
 	.probe = es7134_probe,
-	.remove = es7134_remove,
 };
 
 module_platform_driver(es7134_driver);
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index da2d353..e97d12d 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -356,8 +356,8 @@ static const struct snd_soc_dapm_route es8316_dapm_routes[] = {
 static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
 	int i;
 	int count = 0;
 
@@ -385,19 +385,19 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u8 serdata1 = 0;
 	u8 serdata2 = 0;
 	u8 clksw;
 	u8 mask;
 
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-		dev_err(codec->dev, "Codec driver only supports slave mode\n");
+		dev_err(component->dev, "Codec driver only supports slave mode\n");
 		return -EINVAL;
 	}
 
 	if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) {
-		dev_err(codec->dev, "Codec driver only supports I2S format\n");
+		dev_err(component->dev, "Codec driver only supports I2S format\n");
 		return -EINVAL;
 	}
 
@@ -420,15 +420,15 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	}
 
 	mask = ES8316_SERDATA1_MASTER | ES8316_SERDATA1_BCLK_INV;
-	snd_soc_update_bits(codec, ES8316_SERDATA1, mask, serdata1);
+	snd_soc_component_update_bits(component, ES8316_SERDATA1, mask, serdata1);
 
 	mask = ES8316_SERDATA2_FMT_MASK | ES8316_SERDATA2_ADCLRP;
-	snd_soc_update_bits(codec, ES8316_SERDATA_ADC, mask, serdata2);
-	snd_soc_update_bits(codec, ES8316_SERDATA_DAC, mask, serdata2);
+	snd_soc_component_update_bits(component, ES8316_SERDATA_ADC, mask, serdata2);
+	snd_soc_component_update_bits(component, ES8316_SERDATA_DAC, mask, serdata2);
 
 	/* Enable BCLK and MCLK inputs in slave mode */
 	clksw = ES8316_CLKMGR_CLKSW_MCLK_ON | ES8316_CLKMGR_CLKSW_BCLK_ON;
-	snd_soc_update_bits(codec, ES8316_CLKMGR_CLKSW, clksw, clksw);
+	snd_soc_component_update_bits(component, ES8316_CLKMGR_CLKSW, clksw, clksw);
 
 	return 0;
 }
@@ -436,11 +436,11 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int es8316_pcm_startup(struct snd_pcm_substream *substream,
 			      struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
 
 	if (es8316->sysclk == 0) {
-		dev_err(codec->dev, "No sysclk provided\n");
+		dev_err(component->dev, "No sysclk provided\n");
 		return -EINVAL;
 	}
 
@@ -458,13 +458,12 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->codec;
-	struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
 	u8 wordlen = 0;
 
 	if (!es8316->sysclk) {
-		dev_err(codec->dev, "No MCLK configured\n");
+		dev_err(component->dev, "No MCLK configured\n");
 		return -EINVAL;
 	}
 
@@ -485,16 +484,16 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, ES8316_SERDATA_DAC,
+	snd_soc_component_update_bits(component, ES8316_SERDATA_DAC,
 			    ES8316_SERDATA2_LEN_MASK, wordlen);
-	snd_soc_update_bits(codec, ES8316_SERDATA_ADC,
+	snd_soc_component_update_bits(component, ES8316_SERDATA_ADC,
 			    ES8316_SERDATA2_LEN_MASK, wordlen);
 	return 0;
 }
 
 static int es8316_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, ES8316_DAC_SET1, 0x20,
+	snd_soc_component_update_bits(dai->component, ES8316_DAC_SET1, 0x20,
 			    mute ? 0x20 : 0);
 	return 0;
 }
@@ -530,42 +529,41 @@ static struct snd_soc_dai_driver es8316_dai = {
 	.symmetric_rates = 1,
 };
 
-static int es8316_probe(struct snd_soc_codec *codec)
+static int es8316_probe(struct snd_soc_component *component)
 {
 	/* Reset codec and enable current state machine */
-	snd_soc_write(codec, ES8316_RESET, 0x3f);
+	snd_soc_component_write(component, ES8316_RESET, 0x3f);
 	usleep_range(5000, 5500);
-	snd_soc_write(codec, ES8316_RESET, ES8316_RESET_CSM_ON);
+	snd_soc_component_write(component, ES8316_RESET, ES8316_RESET_CSM_ON);
 	msleep(30);
 
 	/*
 	 * Documentation is unclear, but this value from the vendor driver is
 	 * needed otherwise audio output is silent.
 	 */
-	snd_soc_write(codec, ES8316_SYS_VMIDSEL, 0xff);
+	snd_soc_component_write(component, ES8316_SYS_VMIDSEL, 0xff);
 
 	/*
 	 * Documentation for this register is unclear and incomplete,
 	 * but here is a vendor-provided value that improves volume
 	 * and quality for Intel CHT platforms.
 	 */
-	snd_soc_write(codec, ES8316_CLKMGR_ADCOSR, 0x32);
+	snd_soc_component_write(component, ES8316_CLKMGR_ADCOSR, 0x32);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_es8316 = {
-	.probe		= es8316_probe,
-	.idle_bias_off	= true,
-
-	.component_driver = {
-		.controls		= es8316_snd_controls,
-		.num_controls		= ARRAY_SIZE(es8316_snd_controls),
-		.dapm_widgets		= es8316_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(es8316_dapm_widgets),
-		.dapm_routes		= es8316_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(es8316_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_es8316 = {
+	.probe			= es8316_probe,
+	.controls		= es8316_snd_controls,
+	.num_controls		= ARRAY_SIZE(es8316_snd_controls),
+	.dapm_widgets		= es8316_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(es8316_dapm_widgets),
+	.dapm_routes		= es8316_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(es8316_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config es8316_regmap = {
@@ -592,16 +590,11 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client,
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_es8316,
+	return devm_snd_soc_register_component(&i2c_client->dev,
+				      &soc_component_dev_es8316,
 				      &es8316_dai, 1);
 }
 
-static int es8316_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id es8316_i2c_id[] = {
 	{"es8316", 0 },
 	{}
@@ -627,7 +620,6 @@ static struct i2c_driver es8316_i2c_driver = {
 		.of_match_table		= of_match_ptr(es8316_of_match),
 	},
 	.probe		= es8316_i2c_probe,
-	.remove		= es8316_i2c_remove,
 	.id_table	= es8316_i2c_id,
 };
 module_i2c_driver(es8316_i2c_driver);
diff --git a/sound/soc/codecs/es8328-i2c.c b/sound/soc/codecs/es8328-i2c.c
index 318ab28..19baa32 100644
--- a/sound/soc/codecs/es8328-i2c.c
+++ b/sound/soc/codecs/es8328-i2c.c
@@ -39,19 +39,12 @@ static int es8328_i2c_probe(struct i2c_client *i2c,
 			devm_regmap_init_i2c(i2c, &es8328_regmap_config));
 }
 
-static int es8328_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-	return 0;
-}
-
 static struct i2c_driver es8328_i2c_driver = {
 	.driver = {
 		.name		= "es8328",
 		.of_match_table = es8328_of_match,
 	},
 	.probe    = es8328_i2c_probe,
-	.remove   = es8328_i2c_remove,
 	.id_table = es8328_id,
 };
 
diff --git a/sound/soc/codecs/es8328-spi.c b/sound/soc/codecs/es8328-spi.c
index 8fbd935..d242bd1 100644
--- a/sound/soc/codecs/es8328-spi.c
+++ b/sound/soc/codecs/es8328-spi.c
@@ -28,19 +28,12 @@ static int es8328_spi_probe(struct spi_device *spi)
 			devm_regmap_init_spi(spi, &es8328_regmap_config));
 }
 
-static int es8328_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver es8328_spi_driver = {
 	.driver = {
 		.name		= "es8328",
 		.of_match_table	= es8328_of_match,
 	},
 	.probe	= es8328_spi_probe,
-	.remove	= es8328_spi_remove,
 };
 
 module_spi_driver(es8328_spi_driver);
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index bcdb891..e9fc2fd 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -116,9 +116,9 @@ static const struct {
 	{ 48000, ES8328_DACCONTROL6_DEEMPH_48k },
 };
 
-static int es8328_set_deemph(struct snd_soc_codec *codec)
+static int es8328_set_deemph(struct snd_soc_component *component)
 {
-	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 	int val, i, best;
 
 	/*
@@ -138,17 +138,17 @@ static int es8328_set_deemph(struct snd_soc_codec *codec)
 		val = ES8328_DACCONTROL6_DEEMPH_OFF;
 	}
 
-	dev_dbg(codec->dev, "Set deemphasis %d\n", val);
+	dev_dbg(component->dev, "Set deemphasis %d\n", val);
 
-	return snd_soc_update_bits(codec, ES8328_DACCONTROL6,
+	return snd_soc_component_update_bits(component, ES8328_DACCONTROL6,
 			ES8328_DACCONTROL6_DEEMPH_MASK, val);
 }
 
 static int es8328_get_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = es8328->deemph;
 	return 0;
@@ -157,15 +157,15 @@ static int es8328_get_deemph(struct snd_kcontrol *kcontrol,
 static int es8328_put_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 	unsigned int deemph = ucontrol->value.integer.value[0];
 	int ret;
 
 	if (deemph > 1)
 		return -EINVAL;
 
-	ret = es8328_set_deemph(codec);
+	ret = es8328_set_deemph(component);
 	if (ret < 0)
 		return ret;
 
@@ -455,7 +455,7 @@ static const struct snd_soc_dapm_route es8328_dapm_routes[] = {
 
 static int es8328_mute(struct snd_soc_dai *dai, int mute)
 {
-	return snd_soc_update_bits(dai->codec, ES8328_DACCONTROL3,
+	return snd_soc_component_update_bits(dai->component, ES8328_DACCONTROL3,
 			ES8328_DACCONTROL3_DACMUTE,
 			mute ? ES8328_DACCONTROL3_DACMUTE : 0);
 }
@@ -463,8 +463,8 @@ static int es8328_mute(struct snd_soc_dai *dai, int mute)
 static int es8328_startup(struct snd_pcm_substream *substream,
 			  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 
 	if (es8328->master && es8328->sysclk_constraints)
 		snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -478,8 +478,8 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 	int i;
 	int reg;
 	int wl;
@@ -492,7 +492,7 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
 
 	if (es8328->master) {
 		if (!es8328->sysclk_constraints) {
-			dev_err(codec->dev, "No MCLK configured\n");
+			dev_err(component->dev, "No MCLK configured\n");
 			return -EINVAL;
 		}
 
@@ -502,7 +502,7 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
 				break;
 
 		if (i == es8328->sysclk_constraints->count) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"LRCLK %d unsupported with current clock\n",
 				params_rate(params));
 			return -EINVAL;
@@ -513,7 +513,7 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
 		es8328->mclkdiv2 = 0;
 	}
 
-	snd_soc_update_bits(codec, ES8328_MASTERMODE,
+	snd_soc_component_update_bits(component, ES8328_MASTERMODE,
 			ES8328_MASTERMODE_MCLKDIV2,
 			es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0);
 
@@ -538,25 +538,25 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		snd_soc_update_bits(codec, ES8328_DACCONTROL1,
+		snd_soc_component_update_bits(component, ES8328_DACCONTROL1,
 				ES8328_DACCONTROL1_DACWL_MASK,
 				wl << ES8328_DACCONTROL1_DACWL_SHIFT);
 
 		es8328->playback_fs = params_rate(params);
-		es8328_set_deemph(codec);
+		es8328_set_deemph(component);
 	} else
-		snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
+		snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,
 				ES8328_ADCCONTROL4_ADCWL_MASK,
 				wl << ES8328_ADCCONTROL4_ADCWL_SHIFT);
 
-	return snd_soc_update_bits(codec, reg, ES8328_RATEMASK, ratio);
+	return snd_soc_component_update_bits(component, reg, ES8328_RATEMASK, ratio);
 }
 
 static int es8328_set_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 	int mclkdiv2 = 0;
 
 	switch (freq) {
@@ -589,22 +589,22 @@ static int es8328_set_sysclk(struct snd_soc_dai *codec_dai,
 static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 	u8 dac_mode = 0;
 	u8 adc_mode = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
 		/* Master serial port mode, with BCLK generated automatically */
-		snd_soc_update_bits(codec, ES8328_MASTERMODE,
+		snd_soc_component_update_bits(component, ES8328_MASTERMODE,
 				    ES8328_MASTERMODE_MSC,
 				    ES8328_MASTERMODE_MSC);
 		es8328->master = true;
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
 		/* Slave serial port mode */
-		snd_soc_update_bits(codec, ES8328_MASTERMODE,
+		snd_soc_component_update_bits(component, ES8328_MASTERMODE,
 				    ES8328_MASTERMODE_MSC, 0);
 		es8328->master = false;
 		break;
@@ -634,15 +634,15 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF)
 		return -EINVAL;
 
-	snd_soc_update_bits(codec, ES8328_DACCONTROL1,
+	snd_soc_component_update_bits(component, ES8328_DACCONTROL1,
 			ES8328_DACCONTROL1_DACFORMAT_MASK, dac_mode);
-	snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
+	snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,
 			ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode);
 
 	return 0;
 }
 
-static int es8328_set_bias_level(struct snd_soc_codec *codec,
+static int es8328_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
@@ -651,8 +651,8 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VREF, VMID=2x50k, digital enabled */
-		snd_soc_write(codec, ES8328_CHIPPOWER, 0);
-		snd_soc_update_bits(codec, ES8328_CONTROL1,
+		snd_soc_component_write(component, ES8328_CHIPPOWER, 0);
+		snd_soc_component_update_bits(component, ES8328_CONTROL1,
 				ES8328_CONTROL1_VMIDSEL_MASK |
 				ES8328_CONTROL1_ENREF,
 				ES8328_CONTROL1_VMIDSEL_50k |
@@ -660,8 +660,8 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_update_bits(codec, ES8328_CONTROL1,
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_update_bits(component, ES8328_CONTROL1,
 					ES8328_CONTROL1_VMIDSEL_MASK |
 					ES8328_CONTROL1_ENREF,
 					ES8328_CONTROL1_VMIDSEL_5k |
@@ -671,12 +671,12 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
 			msleep(100);
 		}
 
-		snd_soc_write(codec, ES8328_CONTROL2,
+		snd_soc_component_write(component, ES8328_CONTROL2,
 				ES8328_CONTROL2_OVERCURRENT_ON |
 				ES8328_CONTROL2_THERMAL_SHUTDOWN_ON);
 
 		/* VREF, VMID=2*500k, digital stopped */
-		snd_soc_update_bits(codec, ES8328_CONTROL1,
+		snd_soc_component_update_bits(component, ES8328_CONTROL1,
 				ES8328_CONTROL1_VMIDSEL_MASK |
 				ES8328_CONTROL1_ENREF,
 				ES8328_CONTROL1_VMIDSEL_500k |
@@ -684,7 +684,7 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, ES8328_CONTROL1,
+		snd_soc_component_update_bits(component, ES8328_CONTROL1,
 				ES8328_CONTROL1_VMIDSEL_MASK |
 				ES8328_CONTROL1_ENREF,
 				0);
@@ -721,80 +721,80 @@ static struct snd_soc_dai_driver es8328_dai = {
 	.symmetric_rates = 1,
 };
 
-static int es8328_suspend(struct snd_soc_codec *codec)
+static int es8328_suspend(struct snd_soc_component *component)
 {
 	struct es8328_priv *es8328;
 	int ret;
 
-	es8328 = snd_soc_codec_get_drvdata(codec);
+	es8328 = snd_soc_component_get_drvdata(component);
 
 	clk_disable_unprepare(es8328->clk);
 
 	ret = regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),
 			es8328->supplies);
 	if (ret) {
-		dev_err(codec->dev, "unable to disable regulators\n");
+		dev_err(component->dev, "unable to disable regulators\n");
 		return ret;
 	}
 	return 0;
 }
 
-static int es8328_resume(struct snd_soc_codec *codec)
+static int es8328_resume(struct snd_soc_component *component)
 {
-	struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+	struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 	struct es8328_priv *es8328;
 	int ret;
 
-	es8328 = snd_soc_codec_get_drvdata(codec);
+	es8328 = snd_soc_component_get_drvdata(component);
 
 	ret = clk_prepare_enable(es8328->clk);
 	if (ret) {
-		dev_err(codec->dev, "unable to enable clock\n");
+		dev_err(component->dev, "unable to enable clock\n");
 		return ret;
 	}
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies),
 					es8328->supplies);
 	if (ret) {
-		dev_err(codec->dev, "unable to enable regulators\n");
+		dev_err(component->dev, "unable to enable regulators\n");
 		return ret;
 	}
 
 	regcache_mark_dirty(regmap);
 	ret = regcache_sync(regmap);
 	if (ret) {
-		dev_err(codec->dev, "unable to sync regcache\n");
+		dev_err(component->dev, "unable to sync regcache\n");
 		return ret;
 	}
 
 	return 0;
 }
 
-static int es8328_codec_probe(struct snd_soc_codec *codec)
+static int es8328_component_probe(struct snd_soc_component *component)
 {
 	struct es8328_priv *es8328;
 	int ret;
 
-	es8328 = snd_soc_codec_get_drvdata(codec);
+	es8328 = snd_soc_component_get_drvdata(component);
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies),
 					es8328->supplies);
 	if (ret) {
-		dev_err(codec->dev, "unable to enable regulators\n");
+		dev_err(component->dev, "unable to enable regulators\n");
 		return ret;
 	}
 
 	/* Setup clocks */
-	es8328->clk = devm_clk_get(codec->dev, NULL);
+	es8328->clk = devm_clk_get(component->dev, NULL);
 	if (IS_ERR(es8328->clk)) {
-		dev_err(codec->dev, "codec clock missing or invalid\n");
+		dev_err(component->dev, "codec clock missing or invalid\n");
 		ret = PTR_ERR(es8328->clk);
 		goto clk_fail;
 	}
 
 	ret = clk_prepare_enable(es8328->clk);
 	if (ret) {
-		dev_err(codec->dev, "unable to prepare codec clk\n");
+		dev_err(component->dev, "unable to prepare codec clk\n");
 		goto clk_fail;
 	}
 
@@ -806,19 +806,17 @@ static int es8328_codec_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int es8328_remove(struct snd_soc_codec *codec)
+static void es8328_remove(struct snd_soc_component *component)
 {
 	struct es8328_priv *es8328;
 
-	es8328 = snd_soc_codec_get_drvdata(codec);
+	es8328 = snd_soc_component_get_drvdata(component);
 
 	if (es8328->clk)
 		clk_disable_unprepare(es8328->clk);
 
 	regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),
 			       es8328->supplies);
-
-	return 0;
 }
 
 const struct regmap_config es8328_regmap_config = {
@@ -830,22 +828,23 @@ const struct regmap_config es8328_regmap_config = {
 };
 EXPORT_SYMBOL_GPL(es8328_regmap_config);
 
-static const struct snd_soc_codec_driver es8328_codec_driver = {
-	.probe		  = es8328_codec_probe,
-	.suspend	  = es8328_suspend,
-	.resume		  = es8328_resume,
-	.remove		  = es8328_remove,
-	.set_bias_level	  = es8328_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= es8328_snd_controls,
-		.num_controls		= ARRAY_SIZE(es8328_snd_controls),
-		.dapm_widgets		= es8328_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(es8328_dapm_widgets),
-		.dapm_routes		= es8328_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(es8328_dapm_routes),
-	},
+static const struct snd_soc_component_driver es8328_component_driver = {
+	.probe			= es8328_component_probe,
+	.remove			= es8328_remove,
+	.suspend		= es8328_suspend,
+	.resume			= es8328_resume,
+	.set_bias_level		= es8328_set_bias_level,
+	.controls		= es8328_snd_controls,
+	.num_controls		= ARRAY_SIZE(es8328_snd_controls),
+	.dapm_widgets		= es8328_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(es8328_dapm_widgets),
+	.dapm_routes		= es8328_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(es8328_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 int es8328_probe(struct device *dev, struct regmap *regmap)
@@ -875,8 +874,8 @@ int es8328_probe(struct device *dev, struct regmap *regmap)
 
 	dev_set_drvdata(dev, es8328);
 
-	return snd_soc_register_codec(dev,
-			&es8328_codec_driver, &es8328_dai, 1);
+	return devm_snd_soc_register_component(dev,
+			&es8328_component_driver, &es8328_dai, 1);
 }
 EXPORT_SYMBOL_GPL(es8328_probe);
 
diff --git a/sound/soc/codecs/gtm601.c b/sound/soc/codecs/gtm601.c
index 926b1a4..c11ed60 100644
--- a/sound/soc/codecs/gtm601.c
+++ b/sound/soc/codecs/gtm601.c
@@ -19,7 +19,6 @@
 #include <linux/device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/ac97_codec.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
 
@@ -51,25 +50,21 @@ static struct snd_soc_dai_driver gtm601_dai = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = {
-	.component_driver = {
-		.dapm_widgets		= gtm601_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(gtm601_dapm_widgets),
-		.dapm_routes		= gtm601_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(gtm601_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_gtm601 = {
+	.dapm_widgets		= gtm601_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(gtm601_dapm_widgets),
+	.dapm_routes		= gtm601_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(gtm601_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int gtm601_platform_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_gtm601, &gtm601_dai, 1);
-}
-
-static int gtm601_platform_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_gtm601, &gtm601_dai, 1);
 }
 
 #if defined(CONFIG_OF)
@@ -86,7 +81,6 @@ static struct platform_driver gtm601_codec_driver = {
 		.of_match_table = of_match_ptr(gtm601_codec_of_match),
 	},
 	.probe = gtm601_platform_probe,
-	.remove = gtm601_platform_remove,
 };
 
 module_platform_driver(gtm601_codec_driver);
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index dba6f4c..84f7a7a 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -718,10 +718,22 @@ static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev,
 static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
 			     hda_nid_t nid, unsigned int pwr_state)
 {
+	int count;
+	unsigned int state;
+
 	if (get_wcaps(&edev->hdev, nid) & AC_WCAP_POWER) {
-		if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state))
-			snd_hdac_codec_write(&edev->hdev, nid, 0,
-				AC_VERB_SET_POWER_STATE, pwr_state);
+		if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state)) {
+			for (count = 0; count < 10; count++) {
+				snd_hdac_codec_read(&edev->hdev, nid, 0,
+						AC_VERB_SET_POWER_STATE,
+						pwr_state);
+				state = snd_hdac_sync_power_state(&edev->hdev,
+						nid, pwr_state);
+				if (!(state & AC_PWRST_ERROR))
+					break;
+			}
+		}
+
 	}
 }
 
@@ -1536,7 +1548,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
 	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
 	struct hdac_hdmi_pin *pin = NULL;
 	struct hdac_hdmi_port *hport = NULL;
-	struct snd_soc_codec *codec = edev->scodec;
+	struct snd_soc_component *component = edev->scodec;
 	int i;
 
 	/* Don't know how this mapping is derived */
@@ -1551,7 +1563,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
 	 * connection states are updated in anyway at the end of the resume,
 	 * we can skip it when received during PM process.
 	 */
-	if (snd_power_get_state(codec->component.card->snd_card) !=
+	if (snd_power_get_state(component->card->snd_card) !=
 			SNDRV_CTL_POWER_D0)
 		return;
 
@@ -1609,10 +1621,10 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
 	char kc_name[NAME_SIZE], xname[NAME_SIZE];
 	char *name;
 	int i = 0, j;
-	struct snd_soc_codec *codec = edev->scodec;
+	struct snd_soc_component *component = edev->scodec;
 	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
 
-	kc = devm_kcalloc(codec->dev, hdmi->num_ports,
+	kc = devm_kcalloc(component->dev, hdmi->num_ports,
 				sizeof(*kc), GFP_KERNEL);
 
 	if (!kc)
@@ -1622,11 +1634,11 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
 		for (j = 0; j < pin->num_ports; j++) {
 			snprintf(xname, sizeof(xname), "hif%d-%d Jack",
 						pin->nid, pin->ports[j].id);
-			name = devm_kstrdup(codec->dev, xname, GFP_KERNEL);
+			name = devm_kstrdup(component->dev, xname, GFP_KERNEL);
 			if (!name)
 				return -ENOMEM;
 			snprintf(kc_name, sizeof(kc_name), "%s Switch", xname);
-			kc[i].name = devm_kstrdup(codec->dev, kc_name,
+			kc[i].name = devm_kstrdup(component->dev, kc_name,
 							GFP_KERNEL);
 			if (!kc[i].name)
 				return -ENOMEM;
@@ -1644,10 +1656,10 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
 	return snd_soc_add_card_controls(card, kc, i);
 }
 
-int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
+int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
 			struct snd_soc_dapm_context *dapm)
 {
-	struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+	struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
 	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
 	struct hdac_hdmi_pin *pin;
 	struct snd_soc_dapm_widget *widgets;
@@ -1722,8 +1734,8 @@ EXPORT_SYMBOL_GPL(hdac_hdmi_jack_port_init);
 int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
 				struct snd_soc_jack *jack)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
 	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
 	struct hdac_hdmi_pcm *pcm;
 	struct snd_pcm *snd_pcm;
@@ -1784,16 +1796,16 @@ static void hdac_hdmi_present_sense_all_pins(struct hdac_ext_device *edev,
 	}
 }
 
-static int hdmi_codec_probe(struct snd_soc_codec *codec)
+static int hdmi_codec_probe(struct snd_soc_component *component)
 {
-	struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+	struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
 	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
 	struct snd_soc_dapm_context *dapm =
-		snd_soc_component_get_dapm(&codec->component);
+		snd_soc_component_get_dapm(component);
 	struct hdac_ext_link *hlink = NULL;
 	int ret;
 
-	edev->scodec = codec;
+	edev->scodec = component;
 
 	/*
 	 * hold the ref while we probe, also no need to drop the ref on
@@ -1834,12 +1846,11 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int hdmi_codec_remove(struct snd_soc_codec *codec)
+static void hdmi_codec_remove(struct snd_soc_component *component)
 {
-	struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+	struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
 
 	pm_runtime_disable(&edev->hdev.dev);
-	return 0;
 }
 
 #ifdef CONFIG_PM
@@ -1891,10 +1902,12 @@ static void hdmi_codec_complete(struct device *dev)
 #define hdmi_codec_complete NULL
 #endif
 
-static const struct snd_soc_codec_driver hdmi_hda_codec = {
-	.probe		= hdmi_codec_probe,
-	.remove		= hdmi_codec_remove,
-	.idle_bias_off	= true,
+static const struct snd_soc_component_driver hdmi_hda_codec = {
+	.probe			= hdmi_codec_probe,
+	.remove			= hdmi_codec_remove,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx,
@@ -2042,7 +2055,7 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
 	snd_hdac_refresh_widgets(hdev, true);
 
 	/* ASoC specific initialization */
-	ret = snd_soc_register_codec(&hdev->dev, &hdmi_hda_codec,
+	ret = devm_snd_soc_register_component(&hdev->dev, &hdmi_hda_codec,
 					hdmi_dais, num_dais);
 
 	snd_hdac_ext_bus_link_put(edev->ebus, hlink);
@@ -2059,8 +2072,6 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
 	struct hdac_hdmi_port *port, *port_next;
 	int i;
 
-	snd_soc_unregister_codec(&edev->hdev.dev);
-
 	list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
 		pcm->cvt = NULL;
 		if (list_empty(&pcm->port_list))
diff --git a/sound/soc/codecs/hdac_hdmi.h b/sound/soc/codecs/hdac_hdmi.h
index b5b57a5..4fa2fc9 100644
--- a/sound/soc/codecs/hdac_hdmi.h
+++ b/sound/soc/codecs/hdac_hdmi.h
@@ -5,6 +5,6 @@
 int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm,
 				struct snd_soc_jack *jack);
 
-int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
+int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
 			struct snd_soc_dapm_context *dapm);
 #endif /* __HDAC_HDMI_H__ */
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index c1830ccd..6fa1188 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -730,14 +730,16 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
 	return ret;
 }
 
-static const struct snd_soc_codec_driver hdmi_codec = {
-	.component_driver = {
-		.dapm_widgets		= hdmi_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(hdmi_widgets),
-		.dapm_routes		= hdmi_routes,
-		.num_dapm_routes	= ARRAY_SIZE(hdmi_routes),
-		.of_xlate_dai_id	= hdmi_of_xlate_dai_id,
-	},
+static const struct snd_soc_component_driver hdmi_driver = {
+	.dapm_widgets		= hdmi_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(hdmi_widgets),
+	.dapm_routes		= hdmi_routes,
+	.num_dapm_routes	= ARRAY_SIZE(hdmi_routes),
+	.of_xlate_dai_id	= hdmi_of_xlate_dai_id,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int hdmi_codec_probe(struct platform_device *pdev)
@@ -784,10 +786,10 @@ static int hdmi_codec_probe(struct platform_device *pdev)
 	if (hcd->spdif)
 		hcp->daidrv[i] = hdmi_spdif_dai;
 
-	ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
+	ret = devm_snd_soc_register_component(dev, &hdmi_driver, hcp->daidrv,
 				     dai_count);
 	if (ret) {
-		dev_err(dev, "%s: snd_soc_register_codec() failed (%d)\n",
+		dev_err(dev, "%s: snd_soc_register_component() failed (%d)\n",
 			__func__, ret);
 		return ret;
 	}
@@ -796,19 +798,11 @@ static int hdmi_codec_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int hdmi_codec_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-
-	return 0;
-}
-
 static struct platform_driver hdmi_codec_driver = {
 	.driver = {
 		.name = HDMI_CODEC_DRV_NAME,
 	},
 	.probe = hdmi_codec_probe,
-	.remove = hdmi_codec_remove,
 };
 
 module_platform_driver(hdmi_codec_driver);
diff --git a/sound/soc/codecs/ics43432.c b/sound/soc/codecs/ics43432.c
index 6512062..148d6d6 100644
--- a/sound/soc/codecs/ics43432.c
+++ b/sound/soc/codecs/ics43432.c
@@ -37,21 +37,20 @@ static struct snd_soc_dai_driver ics43432_dai = {
 	},
 };
 
-static const struct snd_soc_codec_driver ics43432_codec_driver = {
+static const struct snd_soc_component_driver ics43432_component_driver = {
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int ics43432_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &ics43432_codec_driver,
+	return devm_snd_soc_register_component(&pdev->dev,
+			&ics43432_component_driver,
 			&ics43432_dai, 1);
 }
 
-static int ics43432_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id ics43432_ids[] = {
 	{ .compatible = "invensense,ics43432", },
@@ -66,7 +65,6 @@ static struct platform_driver ics43432_driver = {
 		.of_match_table = of_match_ptr(ics43432_ids),
 	},
 	.probe = ics43432_probe,
-	.remove = ics43432_remove,
 };
 
 module_platform_driver(ics43432_driver);
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c
index 6b59b6f..85a336b 100644
--- a/sound/soc/codecs/inno_rk3036.c
+++ b/sound/soc/codecs/inno_rk3036.c
@@ -196,10 +196,10 @@ static const struct snd_soc_dapm_route rk3036_codec_dapm_routes[] = {
 
 static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int reg01_val = 0,  reg02_val = 0, reg03_val = 0;
 
-	dev_dbg(codec->dev, "rk3036_codec dai set fmt : %08x\n", fmt);
+	dev_dbg(component->dev, "rk3036_codec dai set fmt : %08x\n", fmt);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
@@ -211,7 +211,7 @@ static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 			     INNO_R01_I2SMODE_MASTER;
 		break;
 	default:
-		dev_err(codec->dev, "invalid fmt\n");
+		dev_err(component->dev, "invalid fmt\n");
 		return -EINVAL;
 	}
 
@@ -229,7 +229,7 @@ static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		reg02_val |= INNO_R02_DACM_LJM;
 		break;
 	default:
-		dev_err(codec->dev, "set dai format failed\n");
+		dev_err(component->dev, "set dai format failed\n");
 		return -EINVAL;
 	}
 
@@ -251,15 +251,15 @@ static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		reg03_val |= INNO_R03_BCP_REVERSAL;
 		break;
 	default:
-		dev_err(codec->dev, "set dai format failed\n");
+		dev_err(component->dev, "set dai format failed\n");
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, INNO_R01, INNO_R01_I2SMODE_MSK |
+	snd_soc_component_update_bits(component, INNO_R01, INNO_R01_I2SMODE_MSK |
 			    INNO_R01_PINDIR_MSK, reg01_val);
-	snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK |
+	snd_soc_component_update_bits(component, INNO_R02, INNO_R02_LRCP_MSK |
 			    INNO_R02_DACM_MSK, reg02_val);
-	snd_soc_update_bits(codec, INNO_R03, INNO_R03_BCP_MSK, reg03_val);
+	snd_soc_component_update_bits(component, INNO_R03, INNO_R03_BCP_MSK, reg03_val);
 
 	return 0;
 }
@@ -268,7 +268,7 @@ static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream,
 				      struct snd_pcm_hw_params *hw_params,
 				      struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int reg02_val = 0, reg03_val = 0;
 
 	switch (params_format(hw_params)) {
@@ -291,9 +291,9 @@ static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream,
 	reg02_val |= INNO_R02_LRCP_NORMAL;
 	reg03_val |= INNO_R03_FWL_32BIT | INNO_R03_DACR_WORK;
 
-	snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK |
+	snd_soc_component_update_bits(component, INNO_R02, INNO_R02_LRCP_MSK |
 			    INNO_R02_VWL_MSK, reg02_val);
-	snd_soc_update_bits(codec, INNO_R03, INNO_R03_DACR_MSK |
+	snd_soc_component_update_bits(component, INNO_R03, INNO_R03_DACR_MSK |
 			    INNO_R03_FWL_MSK, reg03_val);
 	return 0;
 }
@@ -330,43 +330,42 @@ static struct snd_soc_dai_driver rk3036_codec_dai_driver[] = {
 	},
 };
 
-static void rk3036_codec_reset(struct snd_soc_codec *codec)
+static void rk3036_codec_reset(struct snd_soc_component *component)
 {
-	snd_soc_write(codec, INNO_R00,
+	snd_soc_component_write(component, INNO_R00,
 		      INNO_R00_CSR_RESET | INNO_R00_CDCR_RESET);
-	snd_soc_write(codec, INNO_R00,
+	snd_soc_component_write(component, INNO_R00,
 		      INNO_R00_CSR_WORK | INNO_R00_CDCR_WORK);
 }
 
-static int rk3036_codec_probe(struct snd_soc_codec *codec)
+static int rk3036_codec_probe(struct snd_soc_component *component)
 {
-	rk3036_codec_reset(codec);
+	rk3036_codec_reset(component);
 	return 0;
 }
 
-static int rk3036_codec_remove(struct snd_soc_codec *codec)
+static void rk3036_codec_remove(struct snd_soc_component *component)
 {
-	rk3036_codec_reset(codec);
-	return 0;
+	rk3036_codec_reset(component);
 }
 
-static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec,
+static int rk3036_codec_set_bias_level(struct snd_soc_component *component,
 				       enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_STANDBY:
 		/* set a big current for capacitor charging. */
-		snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR);
+		snd_soc_component_write(component, INNO_R10, INNO_R10_MAX_CUR);
 		/* start precharge */
-		snd_soc_write(codec, INNO_R06, INNO_R06_DAC_PRECHARGE);
+		snd_soc_component_write(component, INNO_R06, INNO_R06_DAC_PRECHARGE);
 
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* set a big current for capacitor discharging. */
-		snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR);
+		snd_soc_component_write(component, INNO_R10, INNO_R10_MAX_CUR);
 		/* start discharge. */
-		snd_soc_write(codec, INNO_R06, INNO_R06_DAC_DISCHARGE);
+		snd_soc_component_write(component, INNO_R06, INNO_R06_DAC_DISCHARGE);
 
 		break;
 	default:
@@ -376,18 +375,20 @@ static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static const struct snd_soc_codec_driver rk3036_codec_driver = {
+static const struct snd_soc_component_driver rk3036_codec_driver = {
 	.probe			= rk3036_codec_probe,
 	.remove			= rk3036_codec_remove,
 	.set_bias_level		= rk3036_codec_set_bias_level,
-	.component_driver = {
-		.controls		= rk3036_codec_dapm_controls,
-		.num_controls		= ARRAY_SIZE(rk3036_codec_dapm_controls),
-		.dapm_routes		= rk3036_codec_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rk3036_codec_dapm_routes),
-		.dapm_widgets		= rk3036_codec_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rk3036_codec_dapm_widgets),
-	},
+	.controls		= rk3036_codec_dapm_controls,
+	.num_controls		= ARRAY_SIZE(rk3036_codec_dapm_controls),
+	.dapm_routes		= rk3036_codec_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rk3036_codec_dapm_routes),
+	.dapm_widgets		= rk3036_codec_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rk3036_codec_dapm_widgets),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rk3036_codec_regmap_config = {
@@ -449,7 +450,7 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev)
 	priv->dev = &pdev->dev;
 	dev_set_drvdata(&pdev->dev, priv);
 
-	ret = snd_soc_register_codec(&pdev->dev, &rk3036_codec_driver,
+	ret = devm_snd_soc_register_component(&pdev->dev, &rk3036_codec_driver,
 				     rk3036_codec_dai_driver,
 				     ARRAY_SIZE(rk3036_codec_dai_driver));
 	if (ret) {
@@ -464,7 +465,6 @@ static int rk3036_codec_platform_remove(struct platform_device *pdev)
 {
 	struct rk3036_codec_priv *priv = dev_get_drvdata(&pdev->dev);
 
-	snd_soc_unregister_codec(&pdev->dev);
 	clk_disable_unprepare(priv->pclk);
 
 	return 0;
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index 5ca9928..1664203 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -867,7 +867,7 @@ static const struct snd_soc_dapm_route isabelle_intercon[] = {
 
 static int isabelle_hs_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, ISABELLE_DAC1_SOFTRAMP_REG,
+	snd_soc_component_update_bits(dai->component, ISABELLE_DAC1_SOFTRAMP_REG,
 			BIT(4), (mute ? BIT(4) : 0));
 
 	return 0;
@@ -875,7 +875,7 @@ static int isabelle_hs_mute(struct snd_soc_dai *dai, int mute)
 
 static int isabelle_hf_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, ISABELLE_DAC2_SOFTRAMP_REG,
+	snd_soc_component_update_bits(dai->component, ISABELLE_DAC2_SOFTRAMP_REG,
 			BIT(4), (mute ? BIT(4) : 0));
 
 	return 0;
@@ -883,13 +883,13 @@ static int isabelle_hf_mute(struct snd_soc_dai *dai, int mute)
 
 static int isabelle_line_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, ISABELLE_DAC3_SOFTRAMP_REG,
+	snd_soc_component_update_bits(dai->component, ISABELLE_DAC3_SOFTRAMP_REG,
 			BIT(4), (mute ? BIT(4) : 0));
 
 	return 0;
 }
 
-static int isabelle_set_bias_level(struct snd_soc_codec *codec,
+static int isabelle_set_bias_level(struct snd_soc_component *component,
 				enum snd_soc_bias_level level)
 {
 	switch (level) {
@@ -899,12 +899,12 @@ static int isabelle_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG,
+		snd_soc_component_update_bits(component, ISABELLE_PWR_EN_REG,
 				ISABELLE_CHIP_EN, BIT(0));
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG,
+		snd_soc_component_update_bits(component, ISABELLE_PWR_EN_REG,
 				ISABELLE_CHIP_EN, 0);
 		break;
 	}
@@ -916,7 +916,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
 			      struct snd_pcm_hw_params *params,
 			      struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 aif = 0;
 	unsigned int fs_val = 0;
 
@@ -952,7 +952,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, ISABELLE_FS_RATE_CFG_REG,
+	snd_soc_component_update_bits(component, ISABELLE_FS_RATE_CFG_REG,
 			ISABELLE_FS_RATE_MASK, fs_val);
 
 	/* bit size */
@@ -967,7 +967,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG,
+	snd_soc_component_update_bits(component, ISABELLE_INTF_CFG_REG,
 			ISABELLE_AIF_LENGTH_MASK, aif);
 
 	return 0;
@@ -975,7 +975,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
 
 static int isabelle_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int aif_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1003,7 +1003,7 @@ static int isabelle_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG,
+	snd_soc_component_update_bits(component, ISABELLE_INTF_CFG_REG,
 			(ISABELLE_AIF_MS | ISABELLE_AIF_FMT_MASK), aif_val);
 
 	return 0;
@@ -1087,17 +1087,17 @@ static struct snd_soc_dai_driver isabelle_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_isabelle = {
-	.set_bias_level = isabelle_set_bias_level,
-	.component_driver = {
-		.controls		= isabelle_snd_controls,
-		.num_controls		= ARRAY_SIZE(isabelle_snd_controls),
-		.dapm_widgets		= isabelle_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(isabelle_dapm_widgets),
-		.dapm_routes		= isabelle_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(isabelle_intercon),
-	},
-	.idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_isabelle = {
+	.set_bias_level		= isabelle_set_bias_level,
+	.controls		= isabelle_snd_controls,
+	.num_controls		= ARRAY_SIZE(isabelle_snd_controls),
+	.dapm_widgets		= isabelle_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(isabelle_dapm_widgets),
+	.dapm_routes		= isabelle_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(isabelle_intercon),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config isabelle_regmap_config = {
@@ -1125,23 +1125,17 @@ static int isabelle_i2c_probe(struct i2c_client *i2c,
 	}
 	i2c_set_clientdata(i2c, isabelle_regmap);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-				&soc_codec_dev_isabelle, isabelle_dai,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				&soc_component_dev_isabelle, isabelle_dai,
 				ARRAY_SIZE(isabelle_dai));
 	if (ret < 0) {
-		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 		return ret;
 	}
 
 	return ret;
 }
 
-static int isabelle_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id isabelle_i2c_id[] = {
 	{ "isabelle", 0 },
 	{ }
@@ -1153,7 +1147,6 @@ static struct i2c_driver isabelle_i2c_driver = {
 		.name = "isabelle",
 	},
 	.probe = isabelle_i2c_probe,
-	.remove = isabelle_i2c_remove,
 	.id_table = isabelle_i2c_id,
 };
 
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 6324ccd..9395b58 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -157,7 +157,7 @@ static const struct snd_soc_dapm_route jz4740_codec_dapm_routes[] = {
 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);
+	struct jz4740_codec *jz4740_codec = snd_soc_component_get_drvdata(dai->component);
 	uint32_t val;
 
 	switch (params_rate(params)) {
@@ -236,10 +236,10 @@ static void jz4740_codec_wakeup(struct regmap *regmap)
 	regcache_sync(regmap);
 }
 
-static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
+static int jz4740_codec_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
+	struct jz4740_codec *jz4740_codec = snd_soc_component_get_drvdata(component);
 	struct regmap *regmap = jz4740_codec->regmap;
 	unsigned int mask;
 	unsigned int value;
@@ -257,7 +257,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* The only way to clear the suspend flag is to reset the codec */
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			jz4740_codec_wakeup(regmap);
 
 		mask = JZ4740_CODEC_1_VREF_DISABLE |
@@ -283,9 +283,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
+static int jz4740_codec_dev_probe(struct snd_soc_component *component)
 {
-	struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
+	struct jz4740_codec *jz4740_codec = snd_soc_component_get_drvdata(component);
 
 	regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1,
 			JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
@@ -293,19 +293,21 @@ static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
-	.probe = jz4740_codec_dev_probe,
-	.set_bias_level = jz4740_codec_set_bias_level,
-	.suspend_bias_off = true,
+static const struct snd_soc_component_driver soc_codec_dev_jz4740_codec = {
+	.probe			= jz4740_codec_dev_probe,
+	.set_bias_level		= jz4740_codec_set_bias_level,
+	.controls		= jz4740_codec_controls,
+	.num_controls		= ARRAY_SIZE(jz4740_codec_controls),
+	.dapm_widgets		= jz4740_codec_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(jz4740_codec_dapm_widgets),
+	.dapm_routes		= jz4740_codec_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(jz4740_codec_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 
-	.component_driver = {
-		.controls		= jz4740_codec_controls,
-		.num_controls		= ARRAY_SIZE(jz4740_codec_controls),
-		.dapm_widgets		= jz4740_codec_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(jz4740_codec_dapm_widgets),
-		.dapm_routes		= jz4740_codec_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(jz4740_codec_dapm_routes),
-	},
 };
 
 static const struct regmap_config jz4740_codec_regmap_config = {
@@ -343,7 +345,7 @@ static int jz4740_codec_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, jz4740_codec);
 
-	ret = snd_soc_register_codec(&pdev->dev,
+	ret = devm_snd_soc_register_component(&pdev->dev,
 			&soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
 	if (ret)
 		dev_err(&pdev->dev, "Failed to register codec\n");
@@ -351,16 +353,8 @@ static int jz4740_codec_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static int jz4740_codec_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-
-	return 0;
-}
-
 static struct platform_driver jz4740_codec_driver = {
 	.probe = jz4740_codec_probe,
-	.remove = jz4740_codec_remove,
 	.driver = {
 		.name = "jz4740-codec",
 	},
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 41e09d1..59a646c 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -1110,7 +1110,7 @@ static int lm49453_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 clk_div = 0;
 
 	/* Setting DAC clock dividers based on substream sample rate. */
@@ -1134,15 +1134,15 @@ static int lm49453_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, LM49453_P0_ADC_CLK_DIV_REG, clk_div);
-	snd_soc_write(codec, LM49453_P0_DAC_HP_CLK_DIV_REG, clk_div);
+	snd_soc_component_write(component, LM49453_P0_ADC_CLK_DIV_REG, clk_div);
+	snd_soc_component_write(component, LM49453_P0_DAC_HP_CLK_DIV_REG, clk_div);
 
 	return 0;
 }
 
 static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	u16 aif_val;
 	int mode = 0;
@@ -1185,11 +1185,11 @@ static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, LM49453_P0_AUDIO_PORT1_BASIC_REG,
+	snd_soc_component_update_bits(component, LM49453_P0_AUDIO_PORT1_BASIC_REG,
 			    LM49453_AUDIO_PORT1_BASIC_FMT_MASK|BIT(0)|BIT(5),
 			    (aif_val | mode | clk_phase));
 
-	snd_soc_write(codec, LM49453_P0_AUDIO_PORT1_RX_MSB_REG, clk_shift);
+	snd_soc_component_write(component, LM49453_P0_AUDIO_PORT1_RX_MSB_REG, clk_shift);
 
 	return 0;
 }
@@ -1197,7 +1197,7 @@ static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 static int lm49453_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 				  unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 pll_clk = 0;
 
 	switch (freq) {
@@ -1216,50 +1216,50 @@ static int lm49453_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG, BIT(4), pll_clk);
+	snd_soc_component_update_bits(component, LM49453_P0_PMC_SETUP_REG, BIT(4), pll_clk);
 
 	return 0;
 }
 
 static int lm49453_hp_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(1)|BIT(0),
+	snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(1)|BIT(0),
 			    (mute ? (BIT(1)|BIT(0)) : 0));
 	return 0;
 }
 
 static int lm49453_lo_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(3)|BIT(2),
+	snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(3)|BIT(2),
 			    (mute ? (BIT(3)|BIT(2)) : 0));
 	return 0;
 }
 
 static int lm49453_ls_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(5)|BIT(4),
+	snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(5)|BIT(4),
 			    (mute ? (BIT(5)|BIT(4)) : 0));
 	return 0;
 }
 
 static int lm49453_ep_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(4),
+	snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(4),
 			    (mute ? BIT(4) : 0));
 	return 0;
 }
 
 static int lm49453_ha_mute(struct snd_soc_dai *dai, int mute)
 {
-	snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(7)|BIT(6),
+	snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(7)|BIT(6),
 			    (mute ? (BIT(7)|BIT(6)) : 0));
 	return 0;
 }
 
-static int lm49453_set_bias_level(struct snd_soc_codec *codec,
+static int lm49453_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
+	struct lm49453_priv *lm49453 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -1267,15 +1267,15 @@ static int lm49453_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			regcache_sync(lm49453->regmap);
 
-		snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
+		snd_soc_component_update_bits(component, LM49453_P0_PMC_SETUP_REG,
 				    LM49453_PMC_SETUP_CHIP_EN, LM49453_CHIP_EN);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
+		snd_soc_component_update_bits(component, LM49453_P0_PMC_SETUP_REG,
 				    LM49453_PMC_SETUP_CHIP_EN, 0);
 		break;
 	}
@@ -1389,17 +1389,17 @@ static struct snd_soc_dai_driver lm49453_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
-	.set_bias_level = lm49453_set_bias_level,
-	.component_driver = {
-		.controls		= lm49453_snd_controls,
-		.num_controls		= ARRAY_SIZE(lm49453_snd_controls),
-		.dapm_widgets		= lm49453_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(lm49453_dapm_widgets),
-		.dapm_routes		= lm49453_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(lm49453_audio_map),
-	},
-	.idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_lm49453 = {
+	.set_bias_level		= lm49453_set_bias_level,
+	.controls		= lm49453_snd_controls,
+	.num_controls		= ARRAY_SIZE(lm49453_snd_controls),
+	.dapm_widgets		= lm49453_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(lm49453_dapm_widgets),
+	.dapm_routes		= lm49453_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(lm49453_audio_map),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config lm49453_regmap_config = {
@@ -1434,18 +1434,17 @@ static int lm49453_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-				      &soc_codec_dev_lm49453,
+	ret =  devm_snd_soc_register_component(&i2c->dev,
+				      &soc_component_dev_lm49453,
 				      lm49453_dai, ARRAY_SIZE(lm49453_dai));
 	if (ret < 0)
-		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 
 	return ret;
 }
 
 static int lm49453_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/max9759.c b/sound/soc/codecs/max9759.c
new file mode 100644
index 0000000..ecfb4a8
--- /dev/null
+++ b/sound/soc/codecs/max9759.c
@@ -0,0 +1,207 @@
+// SPDX-Licence-Identifier: GPL-2.0
+/*
+ * MAX9759 Amplifier Driver
+ *
+ * Copyright (c) 2017 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#define DRV_NAME "max9759"
+
+struct max9759 {
+	struct gpio_desc *gpiod_shutdown;
+	struct gpio_desc *gpiod_mute;
+	struct gpio_descs *gpiod_gain;
+	bool is_mute;
+	unsigned int gain;
+};
+
+static int pga_event(struct snd_soc_dapm_widget *w,
+		     struct snd_kcontrol *control, int event)
+{
+	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
+	struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		gpiod_set_value_cansleep(priv->gpiod_shutdown, 0);
+	else
+		gpiod_set_value_cansleep(priv->gpiod_shutdown, 1);
+
+	return 0;
+}
+
+/* From 6dB to 24dB in steps of 6dB */
+static const DECLARE_TLV_DB_SCALE(speaker_gain_tlv, 600, 600, 0);
+
+static int speaker_gain_control_get(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
+	struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+	ucontrol->value.integer.value[0] = priv->gain;
+
+	return 0;
+}
+
+static const bool speaker_gain_table[4][2] = {
+	/* G1, G2 */
+	{true, true},	/* +6dB */
+	{false, true},	/* +12dB */
+	{true, false},	/* +18dB */
+	{false, false},	/* +24dB */
+};
+
+static int speaker_gain_control_put(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
+	struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+	if (ucontrol->value.integer.value[0] > 3)
+		return -EINVAL;
+
+	priv->gain = ucontrol->value.integer.value[0];
+
+	/* G1 */
+	gpiod_set_value_cansleep(priv->gpiod_gain->desc[0],
+				 speaker_gain_table[priv->gain][0]);
+	/* G2 */
+	gpiod_set_value_cansleep(priv->gpiod_gain->desc[1],
+				 speaker_gain_table[priv->gain][1]);
+
+	return 1;
+}
+
+static int speaker_mute_get(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
+	struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+	ucontrol->value.integer.value[0] = !priv->is_mute;
+
+	return 0;
+}
+
+static int speaker_mute_put(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
+	struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+	priv->is_mute = !ucontrol->value.integer.value[0];
+
+	gpiod_set_value_cansleep(priv->gpiod_mute, priv->is_mute);
+
+	return 1;
+}
+
+static const struct snd_kcontrol_new max9759_dapm_controls[] = {
+	SOC_SINGLE_EXT_TLV("Speaker Gain Volume", 0, 0, 3, 0,
+			   speaker_gain_control_get, speaker_gain_control_put,
+			   speaker_gain_tlv),
+	SOC_SINGLE_BOOL_EXT("Playback Switch", 0,
+			    speaker_mute_get, speaker_mute_put),
+};
+
+static const struct snd_soc_dapm_widget max9759_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("INL"),
+	SND_SOC_DAPM_INPUT("INR"),
+	SND_SOC_DAPM_PGA_E("PGA", SND_SOC_NOPM, 0, 0, NULL, 0, pga_event,
+			   (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)),
+	SND_SOC_DAPM_OUTPUT("OUTL"),
+	SND_SOC_DAPM_OUTPUT("OUTR"),
+};
+
+static const struct snd_soc_dapm_route max9759_dapm_routes[] = {
+	{ "PGA", NULL, "INL" },
+	{ "PGA", NULL, "INR" },
+	{ "OUTL", NULL, "PGA" },
+	{ "OUTR", NULL, "PGA" },
+};
+
+static const struct snd_soc_component_driver max9759_component_driver = {
+	.controls		= max9759_dapm_controls,
+	.num_controls		= ARRAY_SIZE(max9759_dapm_controls),
+	.dapm_widgets		= max9759_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max9759_dapm_widgets),
+	.dapm_routes		= max9759_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(max9759_dapm_routes),
+};
+
+static int max9759_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct max9759 *priv;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+
+	priv->gpiod_shutdown = devm_gpiod_get(dev, "shutdown", GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->gpiod_shutdown)) {
+		err = PTR_ERR(priv->gpiod_shutdown);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'shutdown' gpio: %d", err);
+		return err;
+	}
+
+	priv->gpiod_mute = devm_gpiod_get(dev, "mute", GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->gpiod_mute)) {
+		err = PTR_ERR(priv->gpiod_mute);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'mute' gpio: %d", err);
+		return err;
+	}
+	priv->is_mute = true;
+
+	priv->gpiod_gain = devm_gpiod_get_array(dev, "gain", GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->gpiod_gain)) {
+		err = PTR_ERR(priv->gpiod_gain);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'gain' gpios: %d", err);
+		return err;
+	}
+	priv->gain = 0;
+
+	if (priv->gpiod_gain->ndescs != 2) {
+		dev_err(dev, "Invalid 'gain' gpios count: %d",
+			priv->gpiod_gain->ndescs);
+		return -EINVAL;
+	}
+
+	return devm_snd_soc_register_component(dev, &max9759_component_driver,
+					       NULL, 0);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id max9759_ids[] = {
+	{ .compatible = "maxim,max9759", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, max9759_ids);
+#endif
+
+static struct platform_driver max9759_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table = of_match_ptr(max9759_ids),
+	},
+	.probe = max9759_probe,
+};
+
+module_platform_driver(max9759_driver);
+
+MODULE_DESCRIPTION("ASoC MAX9759 amplifier driver");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index f0bb830..865f64c 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -307,7 +307,7 @@ static const struct regmap_config max98088_regmap = {
 /*
  * Load equalizer DSP coefficient configurations registers
  */
-static void m98088_eq_band(struct snd_soc_codec *codec, unsigned int dai,
+static void m98088_eq_band(struct snd_soc_component *component, unsigned int dai,
                    unsigned int band, u16 *coefs)
 {
        unsigned int eq_reg;
@@ -325,8 +325,8 @@ static void m98088_eq_band(struct snd_soc_codec *codec, unsigned int dai,
 
        /* Step through the registers and coefs */
        for (i = 0; i < M98088_COEFS_PER_BAND; i++) {
-               snd_soc_write(codec, eq_reg++, M98088_BYTE1(coefs[i]));
-               snd_soc_write(codec, eq_reg++, M98088_BYTE0(coefs[i]));
+               snd_soc_component_write(component, eq_reg++, M98088_BYTE1(coefs[i]));
+               snd_soc_component_write(component, eq_reg++, M98088_BYTE0(coefs[i]));
        }
 }
 
@@ -380,12 +380,12 @@ static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum,
 static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        unsigned int sel = ucontrol->value.integer.value[0];
 
        max98088->mic1pre = sel;
-       snd_soc_update_bits(codec, M98088_REG_35_LVL_MIC1, M98088_MICPRE_MASK,
+       snd_soc_component_update_bits(component, M98088_REG_35_LVL_MIC1, M98088_MICPRE_MASK,
                (1+sel)<<M98088_MICPRE_SHIFT);
 
        return 0;
@@ -394,8 +394,8 @@ static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,
 static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = max98088->mic1pre;
        return 0;
@@ -404,12 +404,12 @@ static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol,
 static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        unsigned int sel = ucontrol->value.integer.value[0];
 
        max98088->mic2pre = sel;
-       snd_soc_update_bits(codec, M98088_REG_36_LVL_MIC2, M98088_MICPRE_MASK,
+       snd_soc_component_update_bits(component, M98088_REG_36_LVL_MIC2, M98088_MICPRE_MASK,
                (1+sel)<<M98088_MICPRE_SHIFT);
 
        return 0;
@@ -418,8 +418,8 @@ static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol,
 static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = max98088->mic2pre;
        return 0;
@@ -617,21 +617,21 @@ static const struct snd_kcontrol_new max98088_right_ADC_mixer_controls[] = {
 static int max98088_mic_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                if (w->reg == M98088_REG_35_LVL_MIC1) {
-                       snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK,
+                       snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK,
                                (1+max98088->mic1pre)<<M98088_MICPRE_SHIFT);
                } else {
-                       snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK,
+                       snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK,
                                (1+max98088->mic2pre)<<M98088_MICPRE_SHIFT);
                }
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK, 0);
+               snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK, 0);
                break;
        default:
                return -EINVAL;
@@ -647,8 +647,8 @@ static int max98088_mic_event(struct snd_soc_dapm_widget *w,
 static int max98088_line_pga(struct snd_soc_dapm_widget *w,
                             int event, int line, u8 channel)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        u8 *state;
 
 	if (WARN_ON(!(channel == 1 || channel == 2)))
@@ -668,13 +668,13 @@ static int max98088_line_pga(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                *state |= channel;
-               snd_soc_update_bits(codec, w->reg,
+               snd_soc_component_update_bits(component, w->reg,
                        (1 << w->shift), (1 << w->shift));
                break;
        case SND_SOC_DAPM_POST_PMD:
                *state &= ~channel;
                if (*state == 0) {
-                       snd_soc_update_bits(codec, w->reg,
+                       snd_soc_component_update_bits(component, w->reg,
                                (1 << w->shift), 0);
                }
                break;
@@ -963,8 +963,8 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        unsigned long long ni;
        unsigned int rate;
@@ -976,51 +976,51 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 16:
-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,
                        M98088_DAI_WS, 0);
                break;
        case 24:
-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,
                        M98088_DAI_WS, M98088_DAI_WS);
                break;
        default:
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
+       snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
 
        if (rate_value(rate, &regval))
                return -EINVAL;
 
-       snd_soc_update_bits(codec, M98088_REG_11_DAI1_CLKMODE,
+       snd_soc_component_update_bits(component, M98088_REG_11_DAI1_CLKMODE,
                M98088_CLKMODE_MASK, regval);
        cdata->rate = rate;
 
        /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98088_REG_14_DAI1_FORMAT)
+       if (snd_soc_component_read32(component, M98088_REG_14_DAI1_FORMAT)
                & M98088_DAI_MAS) {
                if (max98088->sysclk == 0) {
-                       dev_err(codec->dev, "Invalid system clock frequency\n");
+                       dev_err(component->dev, "Invalid system clock frequency\n");
                        return -EINVAL;
                }
                ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
                                * (unsigned long long int)rate;
                do_div(ni, (unsigned long long int)max98088->sysclk);
-               snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
+               snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI,
                        (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
+               snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO,
                        ni & 0xFF);
        }
 
        /* Update sample rate mode */
        if (rate < 50000)
-               snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
+               snd_soc_component_update_bits(component, M98088_REG_18_DAI1_FILTERS,
                        M98088_DAI_DHF, 0);
        else
-               snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
+               snd_soc_component_update_bits(component, M98088_REG_18_DAI1_FILTERS,
                        M98088_DAI_DHF, M98088_DAI_DHF);
 
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
+       snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
                M98088_SHDNRUN);
 
        return 0;
@@ -1030,8 +1030,8 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        unsigned long long ni;
        unsigned int rate;
@@ -1043,51 +1043,51 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 16:
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,
                        M98088_DAI_WS, 0);
                break;
        case 24:
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,
                        M98088_DAI_WS, M98088_DAI_WS);
                break;
        default:
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
+       snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
 
        if (rate_value(rate, &regval))
                return -EINVAL;
 
-       snd_soc_update_bits(codec, M98088_REG_19_DAI2_CLKMODE,
+       snd_soc_component_update_bits(component, M98088_REG_19_DAI2_CLKMODE,
                M98088_CLKMODE_MASK, regval);
        cdata->rate = rate;
 
        /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98088_REG_1C_DAI2_FORMAT)
+       if (snd_soc_component_read32(component, M98088_REG_1C_DAI2_FORMAT)
                & M98088_DAI_MAS) {
                if (max98088->sysclk == 0) {
-                       dev_err(codec->dev, "Invalid system clock frequency\n");
+                       dev_err(component->dev, "Invalid system clock frequency\n");
                        return -EINVAL;
                }
                ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
                                * (unsigned long long int)rate;
                do_div(ni, (unsigned long long int)max98088->sysclk);
-               snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
+               snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI,
                        (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
+               snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO,
                        ni & 0xFF);
        }
 
        /* Update sample rate mode */
        if (rate < 50000)
-               snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
+               snd_soc_component_update_bits(component, M98088_REG_20_DAI2_FILTERS,
                        M98088_DAI_DHF, 0);
        else
-               snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
+               snd_soc_component_update_bits(component, M98088_REG_20_DAI2_FILTERS,
                        M98088_DAI_DHF, M98088_DAI_DHF);
 
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
+       snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
                M98088_SHDNRUN);
 
        return 0;
@@ -1096,8 +1096,8 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
 static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
                                   int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        /* Requested clock frequency is already setup */
        if (freq == max98088->sysclk)
@@ -1108,18 +1108,18 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
         *         0x02 (when master clk is 20MHz to 30MHz)..
         */
        if ((freq >= 10000000) && (freq < 20000000)) {
-               snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x10);
+               snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x10);
        } else if ((freq >= 20000000) && (freq < 30000000)) {
-               snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x20);
+               snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x20);
        } else {
-               dev_err(codec->dev, "Invalid master clock frequency\n");
+               dev_err(component->dev, "Invalid master clock frequency\n");
                return -EINVAL;
        }
 
-       if (snd_soc_read(codec, M98088_REG_51_PWR_SYS)  & M98088_SHDNRUN) {
-               snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
+       if (snd_soc_component_read32(component, M98088_REG_51_PWR_SYS)  & M98088_SHDNRUN) {
+               snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS,
                        M98088_SHDNRUN, 0);
-               snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
+               snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS,
                        M98088_SHDNRUN, M98088_SHDNRUN);
        }
 
@@ -1132,8 +1132,8 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
 static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        u8 reg15val;
        u8 reg14val = 0;
@@ -1146,9 +1146,9 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Slave mode PLL */
-                       snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
+                       snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI,
                                0x80);
-                       snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
+                       snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO,
                                0x00);
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
@@ -1158,7 +1158,7 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
                default:
-                       dev_err(codec->dev, "Clock mode unsupported");
+                       dev_err(component->dev, "Clock mode unsupported");
                        return -EINVAL;
                }
 
@@ -1188,14 +1188,14 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,
                        M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
                        M98088_DAI_WCI, reg14val);
 
                reg15val = M98088_DAI_BSEL64;
                if (max98088->digmic)
                        reg15val |= M98088_DAI_OSR64;
-               snd_soc_write(codec, M98088_REG_15_DAI1_CLOCK, reg15val);
+               snd_soc_component_write(component, M98088_REG_15_DAI1_CLOCK, reg15val);
        }
 
        return 0;
@@ -1204,8 +1204,8 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
 static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        u8 reg1Cval = 0;
 
@@ -1217,9 +1217,9 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Slave mode PLL */
-                       snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
+                       snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI,
                                0x80);
-                       snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
+                       snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO,
                                0x00);
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
@@ -1229,7 +1229,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
                default:
-                       dev_err(codec->dev, "Clock mode unsupported");
+                       dev_err(component->dev, "Clock mode unsupported");
                        return -EINVAL;
                }
 
@@ -1259,11 +1259,11 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,
                        M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
                        M98088_DAI_WCI, reg1Cval);
 
-               snd_soc_write(codec, M98088_REG_1D_DAI2_CLOCK,
+               snd_soc_component_write(component, M98088_REG_1D_DAI2_CLOCK,
                        M98088_DAI_BSEL64);
        }
 
@@ -1272,7 +1272,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 
 static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int reg;
 
        if (mute)
@@ -1280,14 +1280,14 @@ static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute)
        else
                reg = 0;
 
-       snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY,
+       snd_soc_component_update_bits(component, M98088_REG_2F_LVL_DAI1_PLAY,
                            M98088_DAI_MUTE_MASK, reg);
        return 0;
 }
 
 static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int reg;
 
        if (mute)
@@ -1295,15 +1295,15 @@ static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
        else
                reg = 0;
 
-       snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY,
+       snd_soc_component_update_bits(component, M98088_REG_31_LVL_DAI2_PLAY,
                            M98088_DAI_MUTE_MASK, reg);
        return 0;
 }
 
-static int max98088_set_bias_level(struct snd_soc_codec *codec,
+static int max98088_set_bias_level(struct snd_soc_component *component,
                                   enum snd_soc_bias_level level)
 {
-	struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+	struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -1313,15 +1313,15 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			regcache_sync(max98088->regmap);
 
-		snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
+		snd_soc_component_update_bits(component, M98088_REG_4C_PWR_EN_IN,
 				   M98088_MBEN, M98088_MBEN);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
+		snd_soc_component_update_bits(component, M98088_REG_4C_PWR_EN_IN,
 				    M98088_MBEN, 0);
 		regcache_mark_dirty(max98088->regmap);
 		break;
@@ -1380,7 +1380,7 @@ static struct snd_soc_dai_driver max98088_dai[] = {
 
 static const char *eq_mode_name[] = {"EQ1 Mode", "EQ2 Mode"};
 
-static int max98088_get_channel(struct snd_soc_codec *codec, const char *name)
+static int max98088_get_channel(struct snd_soc_component *component, const char *name)
 {
 	int i;
 
@@ -1389,13 +1389,13 @@ static int max98088_get_channel(struct snd_soc_codec *codec, const char *name)
 			return i;
 
 	/* Shouldn't happen */
-	dev_err(codec->dev, "Bad EQ channel name '%s'\n", name);
+	dev_err(component->dev, "Bad EQ channel name '%s'\n", name);
 	return -EINVAL;
 }
 
-static void max98088_setup_eq1(struct snd_soc_codec *codec)
+static void max98088_setup_eq1(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
        struct max98088_eq_cfg *coef_set;
        int best, best_val, save, i, sel, fs;
@@ -1420,29 +1420,29 @@ static void max98088_setup_eq1(struct snd_soc_codec *codec)
                }
        }
 
-       dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
+       dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",
                pdata->eq_cfg[best].name,
                pdata->eq_cfg[best].rate, fs);
 
        /* Disable EQ while configuring, and save current on/off state */
-       save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL);
-       snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0);
+       save = snd_soc_component_read32(component, M98088_REG_49_CFG_LEVEL);
+       snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0);
 
        coef_set = &pdata->eq_cfg[sel];
 
-       m98088_eq_band(codec, 0, 0, coef_set->band1);
-       m98088_eq_band(codec, 0, 1, coef_set->band2);
-       m98088_eq_band(codec, 0, 2, coef_set->band3);
-       m98088_eq_band(codec, 0, 3, coef_set->band4);
-       m98088_eq_band(codec, 0, 4, coef_set->band5);
+       m98088_eq_band(component, 0, 0, coef_set->band1);
+       m98088_eq_band(component, 0, 1, coef_set->band2);
+       m98088_eq_band(component, 0, 2, coef_set->band3);
+       m98088_eq_band(component, 0, 3, coef_set->band4);
+       m98088_eq_band(component, 0, 4, coef_set->band5);
 
        /* Restore the original on/off state */
-       snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, save);
+       snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, save);
 }
 
-static void max98088_setup_eq2(struct snd_soc_codec *codec)
+static void max98088_setup_eq2(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
        struct max98088_eq_cfg *coef_set;
        int best, best_val, save, i, sel, fs;
@@ -1467,34 +1467,34 @@ static void max98088_setup_eq2(struct snd_soc_codec *codec)
                }
        }
 
-       dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
+       dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",
                pdata->eq_cfg[best].name,
                pdata->eq_cfg[best].rate, fs);
 
        /* Disable EQ while configuring, and save current on/off state */
-       save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL);
-       snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0);
+       save = snd_soc_component_read32(component, M98088_REG_49_CFG_LEVEL);
+       snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0);
 
        coef_set = &pdata->eq_cfg[sel];
 
-       m98088_eq_band(codec, 1, 0, coef_set->band1);
-       m98088_eq_band(codec, 1, 1, coef_set->band2);
-       m98088_eq_band(codec, 1, 2, coef_set->band3);
-       m98088_eq_band(codec, 1, 3, coef_set->band4);
-       m98088_eq_band(codec, 1, 4, coef_set->band5);
+       m98088_eq_band(component, 1, 0, coef_set->band1);
+       m98088_eq_band(component, 1, 1, coef_set->band2);
+       m98088_eq_band(component, 1, 2, coef_set->band3);
+       m98088_eq_band(component, 1, 3, coef_set->band4);
+       m98088_eq_band(component, 1, 4, coef_set->band5);
 
        /* Restore the original on/off state */
-       snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN,
+       snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN,
                save);
 }
 
 static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
-       int channel = max98088_get_channel(codec, kcontrol->id.name);
+       int channel = max98088_get_channel(component, kcontrol->id.name);
        struct max98088_cdata *cdata;
 	int sel = ucontrol->value.enumerated.item[0];
 
@@ -1510,10 +1510,10 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
 
        switch (channel) {
        case 0:
-               max98088_setup_eq1(codec);
+               max98088_setup_eq1(component);
                break;
        case 1:
-               max98088_setup_eq2(codec);
+               max98088_setup_eq2(component);
                break;
        }
 
@@ -1523,9 +1523,9 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
 static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-       int channel = max98088_get_channel(codec, kcontrol->id.name);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
+       int channel = max98088_get_channel(component, kcontrol->id.name);
        struct max98088_cdata *cdata;
 
        if (channel < 0)
@@ -1536,9 +1536,9 @@ static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
+static void max98088_handle_eq_pdata(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
        struct max98088_eq_cfg *cfg;
        unsigned int cfgcnt;
@@ -1591,19 +1591,19 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
        max98088->eq_enum.texts = max98088->eq_texts;
        max98088->eq_enum.items = max98088->eq_textcnt;
 
-       ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
+       ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));
        if (ret != 0)
-               dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
+               dev_err(component->dev, "Failed to add EQ control: %d\n", ret);
 }
 
-static void max98088_handle_pdata(struct snd_soc_codec *codec)
+static void max98088_handle_pdata(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
        u8 regval = 0;
 
        if (!pdata) {
-               dev_dbg(codec->dev, "No platform data\n");
+               dev_dbg(component->dev, "No platform data\n");
                return;
        }
 
@@ -1616,21 +1616,21 @@ static void max98088_handle_pdata(struct snd_soc_codec *codec)
 
        max98088->digmic = (regval ? 1 : 0);
 
-       snd_soc_write(codec, M98088_REG_48_CFG_MIC, regval);
+       snd_soc_component_write(component, M98088_REG_48_CFG_MIC, regval);
 
        /* Configure receiver output */
        regval = ((pdata->receiver_mode) ? M98088_REC_LINEMODE : 0);
-       snd_soc_update_bits(codec, M98088_REG_2A_MIC_REC_CNTL,
+       snd_soc_component_update_bits(component, M98088_REG_2A_MIC_REC_CNTL,
                M98088_REC_LINEMODE_MASK, regval);
 
        /* Configure equalizers */
        if (pdata->eq_cfgcnt)
-               max98088_handle_eq_pdata(codec);
+               max98088_handle_eq_pdata(component);
 }
 
-static int max98088_probe(struct snd_soc_codec *codec)
+static int max98088_probe(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        int ret = 0;
 
@@ -1658,60 +1658,59 @@ static int max98088_probe(struct snd_soc_codec *codec)
        max98088->mic1pre = 0;
        max98088->mic2pre = 0;
 
-       ret = snd_soc_read(codec, M98088_REG_FF_REV_ID);
+       ret = snd_soc_component_read32(component, M98088_REG_FF_REV_ID);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to read device revision: %d\n",
+               dev_err(component->dev, "Failed to read device revision: %d\n",
                        ret);
                goto err_access;
        }
-       dev_info(codec->dev, "revision %c\n", ret - 0x40 + 'A');
+       dev_info(component->dev, "revision %c\n", ret - 0x40 + 'A');
 
-       snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV);
+       snd_soc_component_write(component, M98088_REG_51_PWR_SYS, M98088_PWRSV);
 
-       snd_soc_write(codec, M98088_REG_0F_IRQ_ENABLE, 0x00);
+       snd_soc_component_write(component, M98088_REG_0F_IRQ_ENABLE, 0x00);
 
-       snd_soc_write(codec, M98088_REG_22_MIX_DAC,
+       snd_soc_component_write(component, M98088_REG_22_MIX_DAC,
                M98088_DAI1L_TO_DACL|M98088_DAI2L_TO_DACL|
                M98088_DAI1R_TO_DACR|M98088_DAI2R_TO_DACR);
 
-       snd_soc_write(codec, M98088_REG_4E_BIAS_CNTL, 0xF0);
-       snd_soc_write(codec, M98088_REG_50_DAC_BIAS2, 0x0F);
+       snd_soc_component_write(component, M98088_REG_4E_BIAS_CNTL, 0xF0);
+       snd_soc_component_write(component, M98088_REG_50_DAC_BIAS2, 0x0F);
 
-       snd_soc_write(codec, M98088_REG_16_DAI1_IOCFG,
+       snd_soc_component_write(component, M98088_REG_16_DAI1_IOCFG,
                M98088_S1NORMAL|M98088_SDATA);
 
-       snd_soc_write(codec, M98088_REG_1E_DAI2_IOCFG,
+       snd_soc_component_write(component, M98088_REG_1E_DAI2_IOCFG,
                M98088_S2NORMAL|M98088_SDATA);
 
-       max98088_handle_pdata(codec);
+       max98088_handle_pdata(component);
 
 err_access:
        return ret;
 }
 
-static int max98088_remove(struct snd_soc_codec *codec)
+static void max98088_remove(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        kfree(max98088->eq_texts);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98088 = {
-	.probe   = max98088_probe,
-	.remove  = max98088_remove,
-	.set_bias_level = max98088_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= max98088_snd_controls,
-		.num_controls		= ARRAY_SIZE(max98088_snd_controls),
-		.dapm_widgets		= max98088_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(max98088_dapm_widgets),
-		.dapm_routes		= max98088_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(max98088_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_max98088 = {
+	.probe			= max98088_probe,
+	.remove			= max98088_remove,
+	.set_bias_level		= max98088_set_bias_level,
+	.controls		= max98088_snd_controls,
+	.num_controls		= ARRAY_SIZE(max98088_snd_controls),
+	.dapm_widgets		= max98088_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98088_dapm_widgets),
+	.dapm_routes		= max98088_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max98088_audio_map),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int max98088_i2c_probe(struct i2c_client *i2c,
@@ -1734,17 +1733,11 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
        i2c_set_clientdata(i2c, max98088);
        max98088->pdata = i2c->dev.platform_data;
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_max98088, &max98088_dai[0], 2);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_max98088, &max98088_dai[0], 2);
        return ret;
 }
 
-static int max98088_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max98088_i2c_id[] = {
        { "max98088", MAX98088 },
        { "max98089", MAX98089 },
@@ -1757,7 +1750,6 @@ static struct i2c_driver max98088_i2c_driver = {
 		.name = "max98088",
 	},
 	.probe  = max98088_i2c_probe,
-	.remove = max98088_i2c_remove,
 	.id_table = max98088_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index f5075d1..c97f218 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -284,7 +284,7 @@ static int max98090_reset(struct max98090_priv *max98090)
 	ret = regmap_write(max98090->regmap, M98090_REG_SOFTWARE_RESET,
 		M98090_SWRESET_MASK);
 	if (ret < 0) {
-		dev_err(max98090->codec->dev,
+		dev_err(max98090->component->dev,
 			"Failed to reset codec: %d\n", ret);
 		return ret;
 	}
@@ -354,12 +354,12 @@ static const DECLARE_TLV_DB_RANGE(max98090_rcv_lout_tlv,
 static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int mask = (1 << fls(mc->max)) - 1;
-	unsigned int val = snd_soc_read(codec, mc->reg);
+	unsigned int val = snd_soc_component_read32(component, mc->reg);
 	unsigned int *select;
 
 	switch (mc->reg) {
@@ -394,13 +394,13 @@ static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol,
 static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int mask = (1 << fls(mc->max)) - 1;
 	unsigned int sel = ucontrol->value.integer.value[0];
-	unsigned int val = snd_soc_read(codec, mc->reg);
+	unsigned int val = snd_soc_component_read32(component, mc->reg);
 	unsigned int *select;
 
 	switch (mc->reg) {
@@ -429,7 +429,7 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
 		sel = val;
 	}
 
-	snd_soc_update_bits(codec, mc->reg,
+	snd_soc_component_update_bits(component, mc->reg,
 		mask << mc->shift,
 		sel << mc->shift);
 
@@ -733,10 +733,10 @@ static const struct snd_kcontrol_new max98091_snd_controls[] = {
 static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
 				 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
-	unsigned int val = snd_soc_read(codec, w->reg);
+	unsigned int val = snd_soc_component_read32(component, w->reg);
 
 	if (w->reg == M98090_REG_MIC1_INPUT_LEVEL)
 		val = (val & M98090_MIC_PA1EN_MASK) >> M98090_MIC_PA1EN_SHIFT;
@@ -768,10 +768,10 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
 	}
 
 	if (w->reg == M98090_REG_MIC1_INPUT_LEVEL)
-		snd_soc_update_bits(codec, w->reg, M98090_MIC_PA1EN_MASK,
+		snd_soc_component_update_bits(component, w->reg, M98090_MIC_PA1EN_MASK,
 			val << M98090_MIC_PA1EN_SHIFT);
 	else
-		snd_soc_update_bits(codec, w->reg, M98090_MIC_PA2EN_MASK,
+		snd_soc_component_update_bits(component, w->reg, M98090_MIC_PA2EN_MASK,
 			val << M98090_MIC_PA2EN_SHIFT);
 
 	return 0;
@@ -780,8 +780,8 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
 static int max98090_shdn_event(struct snd_soc_dapm_widget *w,
 				 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
 	if (event & SND_SOC_DAPM_POST_PMU)
 		max98090->shdn_pending = true;
@@ -1441,16 +1441,16 @@ static const struct snd_soc_dapm_route max98091_dapm_routes[] = {
 	{"DMIC4", NULL, "AHPF"},
 };
 
-static int max98090_add_widgets(struct snd_soc_codec *codec)
+static int max98090_add_widgets(struct snd_soc_component *component)
 {
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-	snd_soc_add_codec_controls(codec, max98090_snd_controls,
+	snd_soc_add_component_controls(component, max98090_snd_controls,
 		ARRAY_SIZE(max98090_snd_controls));
 
 	if (max98090->devtype == MAX98091) {
-		snd_soc_add_codec_controls(codec, max98091_snd_controls,
+		snd_soc_add_component_controls(component, max98091_snd_controls,
 			ARRAY_SIZE(max98091_snd_controls));
 	}
 
@@ -1497,24 +1497,24 @@ static const unsigned long long mi_value[] = {
 	8125, 1625, 1500, 25
 };
 
-static void max98090_configure_bclk(struct snd_soc_codec *codec)
+static void max98090_configure_bclk(struct snd_soc_component *component)
 {
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 	unsigned long long ni;
 	int i;
 
 	if (!max98090->sysclk) {
-		dev_err(codec->dev, "No SYSCLK configured\n");
+		dev_err(component->dev, "No SYSCLK configured\n");
 		return;
 	}
 
 	if (!max98090->bclk || !max98090->lrclk) {
-		dev_err(codec->dev, "No audio clocks configured\n");
+		dev_err(component->dev, "No audio clocks configured\n");
 		return;
 	}
 
 	/* Skip configuration when operating as slave */
-	if (!(snd_soc_read(codec, M98090_REG_MASTER_MODE) &
+	if (!(snd_soc_component_read32(component, M98090_REG_MASTER_MODE) &
 		M98090_MAS_MASK)) {
 		return;
 	}
@@ -1523,14 +1523,14 @@ static void max98090_configure_bclk(struct snd_soc_codec *codec)
 	for (i = 0; i < ARRAY_SIZE(pclk_rates); i++) {
 		if ((pclk_rates[i] == max98090->sysclk) &&
 			(lrclk_rates[i] == max98090->lrclk)) {
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Found supported PCLK to LRCLK rates 0x%x\n",
 				i + 0x8);
 
-			snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+			snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
 				M98090_FREQ_MASK,
 				(i + 0x8) << M98090_FREQ_SHIFT);
-			snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+			snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
 				M98090_USE_M1_MASK, 0);
 			return;
 		}
@@ -1540,24 +1540,24 @@ static void max98090_configure_bclk(struct snd_soc_codec *codec)
 	for (i = 0; i < ARRAY_SIZE(user_pclk_rates); i++) {
 		if ((user_pclk_rates[i] == max98090->sysclk) &&
 			(user_lrclk_rates[i] == max98090->lrclk)) {
-			dev_dbg(codec->dev,
+			dev_dbg(component->dev,
 				"Found user supported PCLK to LRCLK rates\n");
-			dev_dbg(codec->dev, "i %d ni %lld mi %lld\n",
+			dev_dbg(component->dev, "i %d ni %lld mi %lld\n",
 				i, ni_value[i], mi_value[i]);
 
-			snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+			snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
 				M98090_FREQ_MASK, 0);
-			snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+			snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
 				M98090_USE_M1_MASK,
 					1 << M98090_USE_M1_SHIFT);
 
-			snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_MSB,
+			snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_MSB,
 				(ni_value[i] >> 8) & 0x7F);
-			snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_LSB,
+			snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_LSB,
 				ni_value[i] & 0xFF);
-			snd_soc_write(codec, M98090_REG_CLOCK_RATIO_MI_MSB,
+			snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_MI_MSB,
 				(mi_value[i] >> 8) & 0x7F);
-			snd_soc_write(codec, M98090_REG_CLOCK_RATIO_MI_LSB,
+			snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_MI_LSB,
 				mi_value[i] & 0xFF);
 
 			return;
@@ -1567,9 +1567,9 @@ static void max98090_configure_bclk(struct snd_soc_codec *codec)
 	/*
 	 * Calculate based on MI = 65536 (not as good as either method above)
 	 */
-	snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+	snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
 		M98090_FREQ_MASK, 0);
-	snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+	snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
 		M98090_USE_M1_MASK, 0);
 
 	/*
@@ -1580,18 +1580,18 @@ static void max98090_configure_bclk(struct snd_soc_codec *codec)
 	ni = 65536ULL * (max98090->lrclk < 50000 ? 96ULL : 48ULL)
 			* (unsigned long long int)max98090->lrclk;
 	do_div(ni, (unsigned long long int)max98090->sysclk);
-	dev_info(codec->dev, "No better method found\n");
-	dev_info(codec->dev, "Calculating ni %lld with mi 65536\n", ni);
-	snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_MSB,
+	dev_info(component->dev, "No better method found\n");
+	dev_info(component->dev, "Calculating ni %lld with mi 65536\n", ni);
+	snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_MSB,
 		(ni >> 8) & 0x7F);
-	snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_LSB, ni & 0xFF);
+	snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_LSB, ni & 0xFF);
 }
 
 static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
 				 unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 	struct max98090_cdata *cdata;
 	u8 regval;
 
@@ -1605,11 +1605,11 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 		case SND_SOC_DAIFMT_CBS_CFS:
 			/* Set to slave mode PLL - MAS mode off */
-			snd_soc_write(codec,
+			snd_soc_component_write(component,
 				M98090_REG_CLOCK_RATIO_NI_MSB, 0x00);
-			snd_soc_write(codec,
+			snd_soc_component_write(component,
 				M98090_REG_CLOCK_RATIO_NI_LSB, 0x00);
-			snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+			snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
 				M98090_USE_M1_MASK, 0);
 			max98090->master = false;
 			break;
@@ -1633,10 +1633,10 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		case SND_SOC_DAIFMT_CBS_CFM:
 		case SND_SOC_DAIFMT_CBM_CFS:
 		default:
-			dev_err(codec->dev, "DAI clock mode unsupported");
+			dev_err(component->dev, "DAI clock mode unsupported");
 			return -EINVAL;
 		}
-		snd_soc_write(codec, M98090_REG_MASTER_MODE, regval);
+		snd_soc_component_write(component, M98090_REG_MASTER_MODE, regval);
 
 		regval = 0;
 		switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1651,7 +1651,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		case SND_SOC_DAIFMT_DSP_A:
 			/* Not supported mode */
 		default:
-			dev_err(codec->dev, "DAI format unsupported");
+			dev_err(component->dev, "DAI format unsupported");
 			return -EINVAL;
 		}
 
@@ -1668,7 +1668,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
 			regval |= M98090_BCI_MASK|M98090_WCI_MASK;
 			break;
 		default:
-			dev_err(codec->dev, "DAI invert mode unsupported");
+			dev_err(component->dev, "DAI invert mode unsupported");
 			return -EINVAL;
 		}
 
@@ -1681,7 +1681,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		if (max98090->tdm_slots > 1)
 			regval ^= M98090_BCI_MASK;
 
-		snd_soc_write(codec,
+		snd_soc_component_write(component,
 			M98090_REG_INTERFACE_FORMAT, regval);
 	}
 
@@ -1691,8 +1691,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
 static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
 	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 	struct max98090_cdata *cdata;
 	cdata = &max98090->dai[0];
 
@@ -1704,13 +1704,13 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
 
 	if (max98090->tdm_slots > 1) {
 		/* SLOTL SLOTR SLOTDLY */
-		snd_soc_write(codec, M98090_REG_TDM_FORMAT,
+		snd_soc_component_write(component, M98090_REG_TDM_FORMAT,
 			0 << M98090_TDM_SLOTL_SHIFT |
 			1 << M98090_TDM_SLOTR_SHIFT |
 			0 << M98090_TDM_SLOTDLY_SHIFT);
 
 		/* FSW TDM */
-		snd_soc_update_bits(codec, M98090_REG_TDM_CONTROL,
+		snd_soc_component_update_bits(component, M98090_REG_TDM_CONTROL,
 			M98090_TDM_MASK,
 			M98090_TDM_MASK);
 	}
@@ -1724,10 +1724,10 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-static int max98090_set_bias_level(struct snd_soc_codec *codec,
+static int max98090_set_bias_level(struct snd_soc_component *component,
 				   enum snd_soc_bias_level level)
 {
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1745,7 +1745,7 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
 		if (IS_ERR(max98090->mclk))
 			break;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
 			clk_disable_unprepare(max98090->mclk);
 		} else {
 			ret = clk_prepare_enable(max98090->mclk);
@@ -1755,10 +1755,10 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regcache_sync(max98090->regmap);
 			if (ret != 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to sync cache: %d\n", ret);
 				return ret;
 			}
@@ -1767,7 +1767,7 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_OFF:
 		/* Set internal pull-up to lowest power mode */
-		snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
+		snd_soc_component_update_bits(component, M98090_REG_JACK_DETECT,
 			M98090_JDWK_MASK, M98090_JDWK_MASK);
 		regcache_mark_dirty(max98090->regmap);
 		break;
@@ -1928,8 +1928,8 @@ 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;
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 	struct max98090_cdata *cdata;
 
 	cdata = &max98090->dai[0];
@@ -1941,7 +1941,7 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
 
 	switch (params_width(params)) {
 	case 16:
-		snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT,
+		snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
 			M98090_WS_MASK, 0);
 		break;
 	default:
@@ -1949,24 +1949,24 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (max98090->master)
-		max98090_configure_bclk(codec);
+		max98090_configure_bclk(component);
 
 	cdata->rate = max98090->lrclk;
 
 	/* Update filter mode */
 	if (max98090->lrclk < 24000)
-		snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
+		snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
 			M98090_MODE_MASK, 0);
 	else
-		snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
+		snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
 			M98090_MODE_MASK, M98090_MODE_MASK);
 
 	/* Update sample rate mode */
 	if (max98090->lrclk < 50000)
-		snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
+		snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
 			M98090_DHF_MASK, 0);
 	else
-		snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
+		snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
 			M98090_DHF_MASK, M98090_DHF_MASK);
 
 	max98090_configure_dmic(max98090, max98090->dmic_freq, max98090->pclk,
@@ -1981,8 +1981,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
 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;
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
 	/* Requested clock frequency is already setup */
 	if (freq == max98090->sysclk)
@@ -1999,19 +1999,19 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
 	 *		 0x03 (when master clk is 40MHz to 60MHz)..
 	 */
 	if ((freq >= 10000000) && (freq <= 20000000)) {
-		snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
+		snd_soc_component_write(component, M98090_REG_SYSTEM_CLOCK,
 			M98090_PSCLK_DIV1);
 		max98090->pclk = freq;
 	} else if ((freq > 20000000) && (freq <= 40000000)) {
-		snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
+		snd_soc_component_write(component, M98090_REG_SYSTEM_CLOCK,
 			M98090_PSCLK_DIV2);
 		max98090->pclk = freq >> 1;
 	} else if ((freq > 40000000) && (freq <= 60000000)) {
-		snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
+		snd_soc_component_write(component, M98090_REG_SYSTEM_CLOCK,
 			M98090_PSCLK_DIV4);
 		max98090->pclk = freq >> 2;
 	} else {
-		dev_err(codec->dev, "Invalid master clock frequency\n");
+		dev_err(component->dev, "Invalid master clock frequency\n");
 		return -EINVAL;
 	}
 
@@ -2022,11 +2022,11 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
 
 static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int regval;
 
 	regval = mute ? M98090_DVM_MASK : 0;
-	snd_soc_update_bits(codec, M98090_REG_DAI_PLAYBACK_LEVEL,
+	snd_soc_component_update_bits(component, M98090_REG_DAI_PLAYBACK_LEVEL,
 		M98090_DVM_MASK, regval);
 
 	return 0;
@@ -2035,8 +2035,8 @@ static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -2065,7 +2065,7 @@ static void max98090_pll_det_enable_work(struct work_struct *work)
 	struct max98090_priv *max98090 =
 		container_of(work, struct max98090_priv,
 			     pll_det_enable_work.work);
-	struct snd_soc_codec *codec = max98090->codec;
+	struct snd_soc_component *component = max98090->component;
 	unsigned int status, mask;
 
 	/*
@@ -2088,7 +2088,7 @@ static void max98090_pll_det_enable_work(struct work_struct *work)
 				   msecs_to_jiffies(100));
 
 	/* Enable PLL unlock interrupt */
-	snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
+	snd_soc_component_update_bits(component, M98090_REG_INTERRUPT_S,
 			    M98090_IULK_MASK,
 			    1 << M98090_IULK_SHIFT);
 }
@@ -2097,12 +2097,12 @@ static void max98090_pll_det_disable_work(struct work_struct *work)
 {
 	struct max98090_priv *max98090 =
 		container_of(work, struct max98090_priv, pll_det_disable_work);
-	struct snd_soc_codec *codec = max98090->codec;
+	struct snd_soc_component *component = max98090->component;
 
 	cancel_delayed_work_sync(&max98090->pll_det_enable_work);
 
 	/* Disable PLL unlock interrupt */
-	snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
+	snd_soc_component_update_bits(component, M98090_REG_INTERRUPT_S,
 			    M98090_IULK_MASK, 0);
 }
 
@@ -2110,18 +2110,18 @@ static void max98090_pll_work(struct work_struct *work)
 {
 	struct max98090_priv *max98090 =
 		container_of(work, struct max98090_priv, pll_work);
-	struct snd_soc_codec *codec = max98090->codec;
+	struct snd_soc_component *component = max98090->component;
 
-	if (!snd_soc_codec_is_active(codec))
+	if (!snd_soc_component_is_active(component))
 		return;
 
-	dev_info_ratelimited(codec->dev, "PLL unlocked\n");
+	dev_info_ratelimited(component->dev, "PLL unlocked\n");
 
 	/* Toggle shutdown OFF then ON */
-	snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
+	snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
 			    M98090_SHDNN_MASK, 0);
 	msleep(10);
-	snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
+	snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
 			    M98090_SHDNN_MASK, M98090_SHDNN_MASK);
 
 	/* Give PLL time to lock */
@@ -2133,7 +2133,7 @@ static void max98090_jack_work(struct work_struct *work)
 	struct max98090_priv *max98090 = container_of(work,
 		struct max98090_priv,
 		jack_work.work);
-	struct snd_soc_codec *codec = max98090->codec;
+	struct snd_soc_component *component = max98090->component;
 	int status = 0;
 	int reg;
 
@@ -2141,25 +2141,25 @@ static void max98090_jack_work(struct work_struct *work)
 	if (max98090->jack_state == M98090_JACK_STATE_NO_HEADSET) {
 
 		/* Strong pull up allows mic detection */
-		snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
+		snd_soc_component_update_bits(component, M98090_REG_JACK_DETECT,
 			M98090_JDWK_MASK, 0);
 
 		msleep(50);
 
-		reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
+		reg = snd_soc_component_read32(component, M98090_REG_JACK_STATUS);
 
 		/* Weak pull up allows only insertion detection */
-		snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
+		snd_soc_component_update_bits(component, M98090_REG_JACK_DETECT,
 			M98090_JDWK_MASK, M98090_JDWK_MASK);
 	} else {
-		reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
+		reg = snd_soc_component_read32(component, M98090_REG_JACK_STATUS);
 	}
 
-	reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
+	reg = snd_soc_component_read32(component, M98090_REG_JACK_STATUS);
 
 	switch (reg & (M98090_LSNS_MASK | M98090_JKSNS_MASK)) {
 		case M98090_LSNS_MASK | M98090_JKSNS_MASK:
-			dev_dbg(codec->dev, "No Headset Detected\n");
+			dev_dbg(component->dev, "No Headset Detected\n");
 
 			max98090->jack_state = M98090_JACK_STATE_NO_HEADSET;
 
@@ -2171,7 +2171,7 @@ static void max98090_jack_work(struct work_struct *work)
 			if (max98090->jack_state ==
 				M98090_JACK_STATE_HEADSET) {
 
-				dev_dbg(codec->dev,
+				dev_dbg(component->dev,
 					"Headset Button Down Detected\n");
 
 				/*
@@ -2188,7 +2188,7 @@ static void max98090_jack_work(struct work_struct *work)
 			/* Line is reported as Headphone */
 			/* Nokia Headset is reported as Headphone */
 			/* Mono Headphone is reported as Headphone */
-			dev_dbg(codec->dev, "Headphone Detected\n");
+			dev_dbg(component->dev, "Headphone Detected\n");
 
 			max98090->jack_state = M98090_JACK_STATE_HEADPHONE;
 
@@ -2197,7 +2197,7 @@ static void max98090_jack_work(struct work_struct *work)
 			break;
 
 		case M98090_JKSNS_MASK:
-			dev_dbg(codec->dev, "Headset Detected\n");
+			dev_dbg(component->dev, "Headset Detected\n");
 
 			max98090->jack_state = M98090_JACK_STATE_HEADSET;
 
@@ -2206,7 +2206,7 @@ static void max98090_jack_work(struct work_struct *work)
 			break;
 
 		default:
-			dev_dbg(codec->dev, "Unrecognized Jack Status\n");
+			dev_dbg(component->dev, "Unrecognized Jack Status\n");
 			break;
 	}
 
@@ -2217,21 +2217,21 @@ static void max98090_jack_work(struct work_struct *work)
 static irqreturn_t max98090_interrupt(int irq, void *data)
 {
 	struct max98090_priv *max98090 = data;
-	struct snd_soc_codec *codec = max98090->codec;
+	struct snd_soc_component *component = max98090->component;
 	int ret;
 	unsigned int mask;
 	unsigned int active;
 
 	/* Treat interrupt before codec is initialized as spurious */
-	if (codec == NULL)
+	if (component == NULL)
 		return IRQ_NONE;
 
-	dev_dbg(codec->dev, "***** max98090_interrupt *****\n");
+	dev_dbg(component->dev, "***** max98090_interrupt *****\n");
 
 	ret = regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask);
 
 	if (ret != 0) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"failed to read M98090_REG_INTERRUPT_S: %d\n",
 			ret);
 		return IRQ_NONE;
@@ -2240,13 +2240,13 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
 	ret = regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &active);
 
 	if (ret != 0) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"failed to read M98090_REG_DEVICE_STATUS: %d\n",
 			ret);
 		return IRQ_NONE;
 	}
 
-	dev_dbg(codec->dev, "active=0x%02x mask=0x%02x -> active=0x%02x\n",
+	dev_dbg(component->dev, "active=0x%02x mask=0x%02x -> active=0x%02x\n",
 		active, mask, active & mask);
 
 	active &= mask;
@@ -2255,20 +2255,20 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
 		return IRQ_NONE;
 
 	if (active & M98090_CLD_MASK)
-		dev_err(codec->dev, "M98090_CLD_MASK\n");
+		dev_err(component->dev, "M98090_CLD_MASK\n");
 
 	if (active & M98090_SLD_MASK)
-		dev_dbg(codec->dev, "M98090_SLD_MASK\n");
+		dev_dbg(component->dev, "M98090_SLD_MASK\n");
 
 	if (active & M98090_ULK_MASK) {
-		dev_dbg(codec->dev, "M98090_ULK_MASK\n");
+		dev_dbg(component->dev, "M98090_ULK_MASK\n");
 		schedule_work(&max98090->pll_work);
 	}
 
 	if (active & M98090_JDET_MASK) {
-		dev_dbg(codec->dev, "M98090_JDET_MASK\n");
+		dev_dbg(component->dev, "M98090_JDET_MASK\n");
 
-		pm_wakeup_event(codec->dev, 100);
+		pm_wakeup_event(component->dev, 100);
 
 		queue_delayed_work(system_power_efficient_wq,
 				   &max98090->jack_work,
@@ -2276,10 +2276,10 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
 	}
 
 	if (active & M98090_DRCACT_MASK)
-		dev_dbg(codec->dev, "M98090_DRCACT_MASK\n");
+		dev_dbg(component->dev, "M98090_DRCACT_MASK\n");
 
 	if (active & M98090_DRCCLP_MASK)
-		dev_err(codec->dev, "M98090_DRCCLP_MASK\n");
+		dev_err(component->dev, "M98090_DRCCLP_MASK\n");
 
 	return IRQ_HANDLED;
 }
@@ -2287,7 +2287,7 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
 /**
  * max98090_mic_detect - Enable microphone detection via the MAX98090 IRQ
  *
- * @codec:  MAX98090 codec
+ * @component:  MAX98090 component
  * @jack:   jack to report detection events on
  *
  * Enable microphone detection via IRQ on the MAX98090.  If GPIOs are
@@ -2297,20 +2297,20 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
  *
  * If no jack is supplied detection will be disabled.
  */
-int max98090_mic_detect(struct snd_soc_codec *codec,
+int max98090_mic_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *jack)
 {
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "max98090_mic_detect\n");
+	dev_dbg(component->dev, "max98090_mic_detect\n");
 
 	max98090->jack = jack;
 	if (jack) {
-		snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
+		snd_soc_component_update_bits(component, M98090_REG_INTERRUPT_S,
 			M98090_IJDET_MASK,
 			1 << M98090_IJDET_SHIFT);
 	} else {
-		snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
+		snd_soc_component_update_bits(component, M98090_REG_INTERRUPT_S,
 			M98090_IJDET_MASK,
 			0);
 	}
@@ -2360,22 +2360,22 @@ static struct snd_soc_dai_driver max98090_dai[] = {
 }
 };
 
-static int max98090_probe(struct snd_soc_codec *codec)
+static int max98090_probe(struct snd_soc_component *component)
 {
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 	struct max98090_cdata *cdata;
 	enum max98090_type devtype;
 	int ret = 0;
 	int err;
 	unsigned int micbias;
 
-	dev_dbg(codec->dev, "max98090_probe\n");
+	dev_dbg(component->dev, "max98090_probe\n");
 
-	max98090->mclk = devm_clk_get(codec->dev, "mclk");
+	max98090->mclk = devm_clk_get(component->dev, "mclk");
 	if (PTR_ERR(max98090->mclk) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	max98090->codec = codec;
+	max98090->component = component;
 
 	/* Reset the codec, the DSP core, and disable all interrupts */
 	max98090_reset(max98090);
@@ -2394,26 +2394,26 @@ static int max98090_probe(struct snd_soc_codec *codec)
 	max98090->pa1en = 0;
 	max98090->pa2en = 0;
 
-	ret = snd_soc_read(codec, M98090_REG_REVISION_ID);
+	ret = snd_soc_component_read32(component, M98090_REG_REVISION_ID);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to read device revision: %d\n",
+		dev_err(component->dev, "Failed to read device revision: %d\n",
 			ret);
 		goto err_access;
 	}
 
 	if ((ret >= M98090_REVA) && (ret <= M98090_REVA + 0x0f)) {
 		devtype = MAX98090;
-		dev_info(codec->dev, "MAX98090 REVID=0x%02x\n", ret);
+		dev_info(component->dev, "MAX98090 REVID=0x%02x\n", ret);
 	} else if ((ret >= M98091_REVA) && (ret <= M98091_REVA + 0x0f)) {
 		devtype = MAX98091;
-		dev_info(codec->dev, "MAX98091 REVID=0x%02x\n", ret);
+		dev_info(component->dev, "MAX98091 REVID=0x%02x\n", ret);
 	} else {
 		devtype = MAX98090;
-		dev_err(codec->dev, "Unrecognized revision 0x%02x\n", ret);
+		dev_err(component->dev, "Unrecognized revision 0x%02x\n", ret);
 	}
 
 	if (max98090->devtype != devtype) {
-		dev_warn(codec->dev, "Mismatch in DT specified CODEC type.\n");
+		dev_warn(component->dev, "Mismatch in DT specified CODEC type.\n");
 		max98090->devtype = devtype;
 	}
 
@@ -2427,7 +2427,7 @@ static int max98090_probe(struct snd_soc_codec *codec)
 	INIT_WORK(&max98090->pll_work, max98090_pll_work);
 
 	/* Enable jack detection */
-	snd_soc_write(codec, M98090_REG_JACK_DETECT,
+	snd_soc_component_write(component, M98090_REG_JACK_DETECT,
 		M98090_JDETEN_MASK | M98090_JDEB_25MS);
 
 	/*
@@ -2435,75 +2435,76 @@ static int max98090_probe(struct snd_soc_codec *codec)
 	 * An old interrupt ocurring prior to installing the ISR
 	 * can keep a new interrupt from generating a trigger.
 	 */
-	snd_soc_read(codec, M98090_REG_DEVICE_STATUS);
+	snd_soc_component_read32(component, M98090_REG_DEVICE_STATUS);
 
 	/* High Performance is default */
-	snd_soc_update_bits(codec, M98090_REG_DAC_CONTROL,
+	snd_soc_component_update_bits(component, M98090_REG_DAC_CONTROL,
 		M98090_DACHP_MASK,
 		1 << M98090_DACHP_SHIFT);
-	snd_soc_update_bits(codec, M98090_REG_DAC_CONTROL,
+	snd_soc_component_update_bits(component, M98090_REG_DAC_CONTROL,
 		M98090_PERFMODE_MASK,
 		0 << M98090_PERFMODE_SHIFT);
-	snd_soc_update_bits(codec, M98090_REG_ADC_CONTROL,
+	snd_soc_component_update_bits(component, M98090_REG_ADC_CONTROL,
 		M98090_ADCHP_MASK,
 		1 << M98090_ADCHP_SHIFT);
 
 	/* Turn on VCM bandgap reference */
-	snd_soc_write(codec, M98090_REG_BIAS_CONTROL,
+	snd_soc_component_write(component, M98090_REG_BIAS_CONTROL,
 		M98090_VCM_MODE_MASK);
 
-	err = device_property_read_u32(codec->dev, "maxim,micbias", &micbias);
+	err = device_property_read_u32(component->dev, "maxim,micbias", &micbias);
 	if (err) {
 		micbias = M98090_MBVSEL_2V8;
-		dev_info(codec->dev, "use default 2.8v micbias\n");
+		dev_info(component->dev, "use default 2.8v micbias\n");
 	} else if (micbias > M98090_MBVSEL_2V8) {
-		dev_err(codec->dev, "micbias out of range 0x%x\n", micbias);
+		dev_err(component->dev, "micbias out of range 0x%x\n", micbias);
 		micbias = M98090_MBVSEL_2V8;
 	}
 
-	snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE,
+	snd_soc_component_update_bits(component, M98090_REG_MIC_BIAS_VOLTAGE,
 		M98090_MBVSEL_MASK, micbias);
 
-	max98090_add_widgets(codec);
+	max98090_add_widgets(component);
 
 err_access:
 	return ret;
 }
 
-static int max98090_remove(struct snd_soc_codec *codec)
+static void max98090_remove(struct snd_soc_component *component)
 {
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
 	cancel_delayed_work_sync(&max98090->jack_work);
 	cancel_delayed_work_sync(&max98090->pll_det_enable_work);
 	cancel_work_sync(&max98090->pll_det_disable_work);
 	cancel_work_sync(&max98090->pll_work);
-	max98090->codec = NULL;
-
-	return 0;
+	max98090->component = NULL;
 }
 
-static void max98090_seq_notifier(struct snd_soc_dapm_context *dapm,
+static void max98090_seq_notifier(struct snd_soc_component *component,
 	enum snd_soc_dapm_type event, int subseq)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+	struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
 	if (max98090->shdn_pending) {
-		snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
+		snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
 				M98090_SHDNN_MASK, 0);
 		msleep(40);
-		snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
+		snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
 				M98090_SHDNN_MASK, M98090_SHDNN_MASK);
 		max98090->shdn_pending = false;
 	}
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98090 = {
-	.probe   = max98090_probe,
-	.remove  = max98090_remove,
-	.seq_notifier = max98090_seq_notifier,
-	.set_bias_level = max98090_set_bias_level,
+static const struct snd_soc_component_driver soc_component_dev_max98090 = {
+	.probe			= max98090_probe,
+	.remove			= max98090_remove,
+	.seq_notifier		= max98090_seq_notifier,
+	.set_bias_level		= max98090_set_bias_level,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config max98090_regmap = {
@@ -2570,8 +2571,8 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_max98090, max98090_dai,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_max98090, max98090_dai,
 			ARRAY_SIZE(max98090_dai));
 err_enable:
 	return ret;
@@ -2595,7 +2596,7 @@ static void max98090_i2c_shutdown(struct i2c_client *i2c)
 static int max98090_i2c_remove(struct i2c_client *client)
 {
 	max98090_i2c_shutdown(client);
-	snd_soc_unregister_codec(&client->dev);
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h
index bc610d9..b1572a2 100644
--- a/sound/soc/codecs/max98090.h
+++ b/sound/soc/codecs/max98090.h
@@ -1519,7 +1519,7 @@ struct max98090_cdata {
 
 struct max98090_priv {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	enum max98090_type devtype;
 	struct max98090_pdata *pdata;
 	struct clk *mclk;
@@ -1546,7 +1546,7 @@ struct max98090_priv {
 	bool shdn_pending;
 };
 
-int max98090_mic_detect(struct snd_soc_codec *codec,
+int max98090_mic_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *jack);
 
 #endif
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 5ead87d..6bf2d0b 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -251,7 +251,7 @@ static const struct regmap_config max98095_regmap = {
 /*
  * Load equalizer DSP coefficient configurations registers
  */
-static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
+static void m98095_eq_band(struct snd_soc_component *component, unsigned int dai,
 		    unsigned int band, u16 *coefs)
 {
 	unsigned int eq_reg;
@@ -269,15 +269,15 @@ static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
 
 	/* Step through the registers and coefs */
 	for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
-		snd_soc_write(codec, eq_reg++, M98095_BYTE1(coefs[i]));
-		snd_soc_write(codec, eq_reg++, M98095_BYTE0(coefs[i]));
+		snd_soc_component_write(component, eq_reg++, M98095_BYTE1(coefs[i]));
+		snd_soc_component_write(component, eq_reg++, M98095_BYTE0(coefs[i]));
 	}
 }
 
 /*
  * Load biquad filter coefficient configurations registers
  */
-static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
+static void m98095_biquad_band(struct snd_soc_component *component, unsigned int dai,
 		    unsigned int band, u16 *coefs)
 {
 	unsigned int bq_reg;
@@ -295,8 +295,8 @@ static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
 
 	/* Step through the registers and coefs */
 	for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
-		snd_soc_write(codec, bq_reg++, M98095_BYTE1(coefs[i]));
-		snd_soc_write(codec, bq_reg++, M98095_BYTE0(coefs[i]));
+		snd_soc_component_write(component, bq_reg++, M98095_BYTE1(coefs[i]));
+		snd_soc_component_write(component, bq_reg++, M98095_BYTE0(coefs[i]));
 	}
 }
 
@@ -353,12 +353,12 @@ static SOC_ENUM_SINGLE_DECL(max98095_dai3_dac_filter_enum,
 static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	unsigned int sel = ucontrol->value.integer.value[0];
 
 	max98095->mic1pre = sel;
-	snd_soc_update_bits(codec, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
+	snd_soc_component_update_bits(component, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
 		(1+sel)<<M98095_MICPRE_SHIFT);
 
 	return 0;
@@ -367,8 +367,8 @@ static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
 static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = max98095->mic1pre;
 	return 0;
@@ -377,12 +377,12 @@ static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
 static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	unsigned int sel = ucontrol->value.integer.value[0];
 
 	max98095->mic2pre = sel;
-	snd_soc_update_bits(codec, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
+	snd_soc_component_update_bits(component, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
 		(1+sel)<<M98095_MICPRE_SHIFT);
 
 	return 0;
@@ -391,8 +391,8 @@ static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
 static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = max98095->mic2pre;
 	return 0;
@@ -598,21 +598,21 @@ static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = {
 static int max98095_mic_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		if (w->reg == M98095_05F_LVL_MIC1) {
-			snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
+			snd_soc_component_update_bits(component, w->reg, M98095_MICPRE_MASK,
 				(1+max98095->mic1pre)<<M98095_MICPRE_SHIFT);
 		} else {
-			snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
+			snd_soc_component_update_bits(component, w->reg, M98095_MICPRE_MASK,
 				(1+max98095->mic2pre)<<M98095_MICPRE_SHIFT);
 		}
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK, 0);
+		snd_soc_component_update_bits(component, w->reg, M98095_MICPRE_MASK, 0);
 		break;
 	default:
 		return -EINVAL;
@@ -628,8 +628,8 @@ static int max98095_mic_event(struct snd_soc_dapm_widget *w,
 static int max98095_line_pga(struct snd_soc_dapm_widget *w,
 			     int event, u8 channel)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	u8 *state;
 
 	if (WARN_ON(!(channel == 1 || channel == 2)))
@@ -640,13 +640,13 @@ static int max98095_line_pga(struct snd_soc_dapm_widget *w,
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		*state |= channel;
-		snd_soc_update_bits(codec, w->reg,
+		snd_soc_component_update_bits(component, w->reg,
 			(1 << w->shift), (1 << w->shift));
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		*state &= ~channel;
 		if (*state == 0) {
-			snd_soc_update_bits(codec, w->reg,
+			snd_soc_component_update_bits(component, w->reg,
 				(1 << w->shift), 0);
 		}
 		break;
@@ -676,15 +676,15 @@ static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w,
 static int max98095_lineout_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, w->reg,
+		snd_soc_component_update_bits(component, w->reg,
 			(1 << (w->shift+2)), (1 << (w->shift+2)));
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, w->reg,
+		snd_soc_component_update_bits(component, w->reg,
 			(1 << (w->shift+2)), 0);
 		break;
 	default:
@@ -942,8 +942,8 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_pcm_hw_params *params,
 				   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_cdata *cdata;
 	unsigned long long ni;
 	unsigned int rate;
@@ -955,11 +955,11 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
 
 	switch (params_width(params)) {
 	case 16:
-		snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
+		snd_soc_component_update_bits(component, M98095_02A_DAI1_FORMAT,
 			M98095_DAI_WS, 0);
 		break;
 	case 24:
-		snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
+		snd_soc_component_update_bits(component, M98095_02A_DAI1_FORMAT,
 			M98095_DAI_WS, M98095_DAI_WS);
 		break;
 	default:
@@ -969,31 +969,31 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
 	if (rate_value(rate, &regval))
 		return -EINVAL;
 
-	snd_soc_update_bits(codec, M98095_027_DAI1_CLKMODE,
+	snd_soc_component_update_bits(component, M98095_027_DAI1_CLKMODE,
 		M98095_CLKMODE_MASK, regval);
 	cdata->rate = rate;
 
 	/* Configure NI when operating as master */
-	if (snd_soc_read(codec, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
+	if (snd_soc_component_read32(component, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
 		if (max98095->sysclk == 0) {
-			dev_err(codec->dev, "Invalid system clock frequency\n");
+			dev_err(component->dev, "Invalid system clock frequency\n");
 			return -EINVAL;
 		}
 		ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
 				* (unsigned long long int)rate;
 		do_div(ni, (unsigned long long int)max98095->sysclk);
-		snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
+		snd_soc_component_write(component, M98095_028_DAI1_CLKCFG_HI,
 			(ni >> 8) & 0x7F);
-		snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
+		snd_soc_component_write(component, M98095_029_DAI1_CLKCFG_LO,
 			ni & 0xFF);
 	}
 
 	/* Update sample rate mode */
 	if (rate < 50000)
-		snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
+		snd_soc_component_update_bits(component, M98095_02E_DAI1_FILTERS,
 			M98095_DAI_DHF, 0);
 	else
-		snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
+		snd_soc_component_update_bits(component, M98095_02E_DAI1_FILTERS,
 			M98095_DAI_DHF, M98095_DAI_DHF);
 
 	return 0;
@@ -1003,8 +1003,8 @@ static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_pcm_hw_params *params,
 				   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_cdata *cdata;
 	unsigned long long ni;
 	unsigned int rate;
@@ -1016,11 +1016,11 @@ static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
 
 	switch (params_width(params)) {
 	case 16:
-		snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
+		snd_soc_component_update_bits(component, M98095_034_DAI2_FORMAT,
 			M98095_DAI_WS, 0);
 		break;
 	case 24:
-		snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
+		snd_soc_component_update_bits(component, M98095_034_DAI2_FORMAT,
 			M98095_DAI_WS, M98095_DAI_WS);
 		break;
 	default:
@@ -1030,31 +1030,31 @@ static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
 	if (rate_value(rate, &regval))
 		return -EINVAL;
 
-	snd_soc_update_bits(codec, M98095_031_DAI2_CLKMODE,
+	snd_soc_component_update_bits(component, M98095_031_DAI2_CLKMODE,
 		M98095_CLKMODE_MASK, regval);
 	cdata->rate = rate;
 
 	/* Configure NI when operating as master */
-	if (snd_soc_read(codec, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
+	if (snd_soc_component_read32(component, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
 		if (max98095->sysclk == 0) {
-			dev_err(codec->dev, "Invalid system clock frequency\n");
+			dev_err(component->dev, "Invalid system clock frequency\n");
 			return -EINVAL;
 		}
 		ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
 				* (unsigned long long int)rate;
 		do_div(ni, (unsigned long long int)max98095->sysclk);
-		snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
+		snd_soc_component_write(component, M98095_032_DAI2_CLKCFG_HI,
 			(ni >> 8) & 0x7F);
-		snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
+		snd_soc_component_write(component, M98095_033_DAI2_CLKCFG_LO,
 			ni & 0xFF);
 	}
 
 	/* Update sample rate mode */
 	if (rate < 50000)
-		snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
+		snd_soc_component_update_bits(component, M98095_038_DAI2_FILTERS,
 			M98095_DAI_DHF, 0);
 	else
-		snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
+		snd_soc_component_update_bits(component, M98095_038_DAI2_FILTERS,
 			M98095_DAI_DHF, M98095_DAI_DHF);
 
 	return 0;
@@ -1064,8 +1064,8 @@ static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_pcm_hw_params *params,
 				   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_cdata *cdata;
 	unsigned long long ni;
 	unsigned int rate;
@@ -1077,11 +1077,11 @@ static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
 
 	switch (params_width(params)) {
 	case 16:
-		snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
+		snd_soc_component_update_bits(component, M98095_03E_DAI3_FORMAT,
 			M98095_DAI_WS, 0);
 		break;
 	case 24:
-		snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
+		snd_soc_component_update_bits(component, M98095_03E_DAI3_FORMAT,
 			M98095_DAI_WS, M98095_DAI_WS);
 		break;
 	default:
@@ -1091,31 +1091,31 @@ static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
 	if (rate_value(rate, &regval))
 		return -EINVAL;
 
-	snd_soc_update_bits(codec, M98095_03B_DAI3_CLKMODE,
+	snd_soc_component_update_bits(component, M98095_03B_DAI3_CLKMODE,
 		M98095_CLKMODE_MASK, regval);
 	cdata->rate = rate;
 
 	/* Configure NI when operating as master */
-	if (snd_soc_read(codec, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
+	if (snd_soc_component_read32(component, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
 		if (max98095->sysclk == 0) {
-			dev_err(codec->dev, "Invalid system clock frequency\n");
+			dev_err(component->dev, "Invalid system clock frequency\n");
 			return -EINVAL;
 		}
 		ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
 				* (unsigned long long int)rate;
 		do_div(ni, (unsigned long long int)max98095->sysclk);
-		snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
+		snd_soc_component_write(component, M98095_03C_DAI3_CLKCFG_HI,
 			(ni >> 8) & 0x7F);
-		snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
+		snd_soc_component_write(component, M98095_03D_DAI3_CLKCFG_LO,
 			ni & 0xFF);
 	}
 
 	/* Update sample rate mode */
 	if (rate < 50000)
-		snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
+		snd_soc_component_update_bits(component, M98095_042_DAI3_FILTERS,
 			M98095_DAI_DHF, 0);
 	else
-		snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
+		snd_soc_component_update_bits(component, M98095_042_DAI3_FILTERS,
 			M98095_DAI_DHF, M98095_DAI_DHF);
 
 	return 0;
@@ -1124,8 +1124,8 @@ static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
 static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
 				   int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
 	/* Requested clock frequency is already setup */
 	if (freq == max98095->sysclk)
@@ -1142,13 +1142,13 @@ static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
 	 *         0x03 (when master clk is 40MHz to 60MHz)..
 	 */
 	if ((freq >= 10000000) && (freq < 20000000)) {
-		snd_soc_write(codec, M98095_026_SYS_CLK, 0x10);
+		snd_soc_component_write(component, M98095_026_SYS_CLK, 0x10);
 	} else if ((freq >= 20000000) && (freq < 40000000)) {
-		snd_soc_write(codec, M98095_026_SYS_CLK, 0x20);
+		snd_soc_component_write(component, M98095_026_SYS_CLK, 0x20);
 	} else if ((freq >= 40000000) && (freq < 60000000)) {
-		snd_soc_write(codec, M98095_026_SYS_CLK, 0x30);
+		snd_soc_component_write(component, M98095_026_SYS_CLK, 0x30);
 	} else {
-		dev_err(codec->dev, "Invalid master clock frequency\n");
+		dev_err(component->dev, "Invalid master clock frequency\n");
 		return -EINVAL;
 	}
 
@@ -1161,8 +1161,8 @@ static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
 static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
 				 unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_cdata *cdata;
 	u8 regval = 0;
 
@@ -1174,9 +1174,9 @@ static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
 		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 		case SND_SOC_DAIFMT_CBS_CFS:
 			/* Slave mode PLL */
-			snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
+			snd_soc_component_write(component, M98095_028_DAI1_CLKCFG_HI,
 				0x80);
-			snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
+			snd_soc_component_write(component, M98095_029_DAI1_CLKCFG_LO,
 				0x00);
 			break;
 		case SND_SOC_DAIFMT_CBM_CFM:
@@ -1186,7 +1186,7 @@ static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
 		case SND_SOC_DAIFMT_CBS_CFM:
 		case SND_SOC_DAIFMT_CBM_CFS:
 		default:
-			dev_err(codec->dev, "Clock mode unsupported");
+			dev_err(component->dev, "Clock mode unsupported");
 			return -EINVAL;
 		}
 
@@ -1216,11 +1216,11 @@ static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
 			return -EINVAL;
 		}
 
-		snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
+		snd_soc_component_update_bits(component, M98095_02A_DAI1_FORMAT,
 			M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
 			M98095_DAI_WCI, regval);
 
-		snd_soc_write(codec, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
+		snd_soc_component_write(component, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
 	}
 
 	return 0;
@@ -1229,8 +1229,8 @@ static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
 static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 				 unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_cdata *cdata;
 	u8 regval = 0;
 
@@ -1242,9 +1242,9 @@ static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 		case SND_SOC_DAIFMT_CBS_CFS:
 			/* Slave mode PLL */
-			snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
+			snd_soc_component_write(component, M98095_032_DAI2_CLKCFG_HI,
 				0x80);
-			snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
+			snd_soc_component_write(component, M98095_033_DAI2_CLKCFG_LO,
 				0x00);
 			break;
 		case SND_SOC_DAIFMT_CBM_CFM:
@@ -1254,7 +1254,7 @@ static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 		case SND_SOC_DAIFMT_CBS_CFM:
 		case SND_SOC_DAIFMT_CBM_CFS:
 		default:
-			dev_err(codec->dev, "Clock mode unsupported");
+			dev_err(component->dev, "Clock mode unsupported");
 			return -EINVAL;
 		}
 
@@ -1284,11 +1284,11 @@ static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 			return -EINVAL;
 		}
 
-		snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
+		snd_soc_component_update_bits(component, M98095_034_DAI2_FORMAT,
 			M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
 			M98095_DAI_WCI, regval);
 
-		snd_soc_write(codec, M98095_035_DAI2_CLOCK,
+		snd_soc_component_write(component, M98095_035_DAI2_CLOCK,
 			M98095_DAI_BSEL64);
 	}
 
@@ -1298,8 +1298,8 @@ static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
 				 unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_cdata *cdata;
 	u8 regval = 0;
 
@@ -1311,9 +1311,9 @@ static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
 		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 		case SND_SOC_DAIFMT_CBS_CFS:
 			/* Slave mode PLL */
-			snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
+			snd_soc_component_write(component, M98095_03C_DAI3_CLKCFG_HI,
 				0x80);
-			snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
+			snd_soc_component_write(component, M98095_03D_DAI3_CLKCFG_LO,
 				0x00);
 			break;
 		case SND_SOC_DAIFMT_CBM_CFM:
@@ -1323,7 +1323,7 @@ static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
 		case SND_SOC_DAIFMT_CBS_CFM:
 		case SND_SOC_DAIFMT_CBM_CFS:
 		default:
-			dev_err(codec->dev, "Clock mode unsupported");
+			dev_err(component->dev, "Clock mode unsupported");
 			return -EINVAL;
 		}
 
@@ -1353,21 +1353,21 @@ static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
 			return -EINVAL;
 		}
 
-		snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
+		snd_soc_component_update_bits(component, M98095_03E_DAI3_FORMAT,
 			M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
 			M98095_DAI_WCI, regval);
 
-		snd_soc_write(codec, M98095_03F_DAI3_CLOCK,
+		snd_soc_component_write(component, M98095_03F_DAI3_CLOCK,
 			M98095_DAI_BSEL64);
 	}
 
 	return 0;
 }
 
-static int max98095_set_bias_level(struct snd_soc_codec *codec,
+static int max98095_set_bias_level(struct snd_soc_component *component,
 				   enum snd_soc_bias_level level)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1385,7 +1385,7 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
 		if (IS_ERR(max98095->mclk))
 			break;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
 			clk_disable_unprepare(max98095->mclk);
 		} else {
 			ret = clk_prepare_enable(max98095->mclk);
@@ -1395,21 +1395,21 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regcache_sync(max98095->regmap);
 
 			if (ret != 0) {
-				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				dev_err(component->dev, "Failed to sync cache: %d\n", ret);
 				return ret;
 			}
 		}
 
-		snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
+		snd_soc_component_update_bits(component, M98095_090_PWR_EN_IN,
 				M98095_MBEN, M98095_MBEN);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
+		snd_soc_component_update_bits(component, M98095_090_PWR_EN_IN,
 				M98095_MBEN, 0);
 		regcache_mark_dirty(max98095->regmap);
 		break;
@@ -1494,8 +1494,8 @@ static int max98095_get_eq_channel(const char *name)
 static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_pdata *pdata = max98095->pdata;
 	int channel = max98095_get_eq_channel(kcontrol->id.name);
 	struct max98095_cdata *cdata;
@@ -1528,7 +1528,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
 		}
 	}
 
-	dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
+	dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",
 		pdata->eq_cfg[best].name,
 		pdata->eq_cfg[best].rate, fs);
 
@@ -1537,29 +1537,29 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
 	regmask = (channel == 0) ? M98095_EQ1EN : M98095_EQ2EN;
 
 	/* Disable filter while configuring, and save current on/off state */
-	regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
-	snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
+	regsave = snd_soc_component_read32(component, M98095_088_CFG_LEVEL);
+	snd_soc_component_update_bits(component, M98095_088_CFG_LEVEL, regmask, 0);
 
 	mutex_lock(&max98095->lock);
-	snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
-	m98095_eq_band(codec, channel, 0, coef_set->band1);
-	m98095_eq_band(codec, channel, 1, coef_set->band2);
-	m98095_eq_band(codec, channel, 2, coef_set->band3);
-	m98095_eq_band(codec, channel, 3, coef_set->band4);
-	m98095_eq_band(codec, channel, 4, coef_set->band5);
-	snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
+	snd_soc_component_update_bits(component, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
+	m98095_eq_band(component, channel, 0, coef_set->band1);
+	m98095_eq_band(component, channel, 1, coef_set->band2);
+	m98095_eq_band(component, channel, 2, coef_set->band3);
+	m98095_eq_band(component, channel, 3, coef_set->band4);
+	m98095_eq_band(component, channel, 4, coef_set->band5);
+	snd_soc_component_update_bits(component, M98095_00F_HOST_CFG, M98095_SEG, 0);
 	mutex_unlock(&max98095->lock);
 
 	/* Restore the original on/off state */
-	snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
+	snd_soc_component_update_bits(component, M98095_088_CFG_LEVEL, regmask, regsave);
 	return 0;
 }
 
 static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	int channel = max98095_get_eq_channel(kcontrol->id.name);
 	struct max98095_cdata *cdata;
 
@@ -1569,9 +1569,9 @@ static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
+static void max98095_handle_eq_pdata(struct snd_soc_component *component)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_pdata *pdata = max98095->pdata;
 	struct max98095_eq_cfg *cfg;
 	unsigned int cfgcnt;
@@ -1624,14 +1624,14 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
 	max98095->eq_enum.texts = max98095->eq_texts;
 	max98095->eq_enum.items = max98095->eq_textcnt;
 
-	ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
+	ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));
 	if (ret != 0)
-		dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
+		dev_err(component->dev, "Failed to add EQ control: %d\n", ret);
 }
 
 static const char *bq_mode_name[] = {"Biquad1 Mode", "Biquad2 Mode"};
 
-static int max98095_get_bq_channel(struct snd_soc_codec *codec,
+static int max98095_get_bq_channel(struct snd_soc_component *component,
 				   const char *name)
 {
 	int i;
@@ -1641,17 +1641,17 @@ static int max98095_get_bq_channel(struct snd_soc_codec *codec,
 			return i;
 
 	/* Shouldn't happen */
-	dev_err(codec->dev, "Bad biquad channel name '%s'\n", name);
+	dev_err(component->dev, "Bad biquad channel name '%s'\n", name);
 	return -EINVAL;
 }
 
 static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_pdata *pdata = max98095->pdata;
-	int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
+	int channel = max98095_get_bq_channel(component, kcontrol->id.name);
 	struct max98095_cdata *cdata;
 	unsigned int sel = ucontrol->value.enumerated.item[0];
 	struct max98095_biquad_cfg *coef_set;
@@ -1682,7 +1682,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
 		}
 	}
 
-	dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
+	dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",
 		pdata->bq_cfg[best].name,
 		pdata->bq_cfg[best].rate, fs);
 
@@ -1691,27 +1691,27 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
 	regmask = (channel == 0) ? M98095_BQ1EN : M98095_BQ2EN;
 
 	/* Disable filter while configuring, and save current on/off state */
-	regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
-	snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
+	regsave = snd_soc_component_read32(component, M98095_088_CFG_LEVEL);
+	snd_soc_component_update_bits(component, M98095_088_CFG_LEVEL, regmask, 0);
 
 	mutex_lock(&max98095->lock);
-	snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
-	m98095_biquad_band(codec, channel, 0, coef_set->band1);
-	m98095_biquad_band(codec, channel, 1, coef_set->band2);
-	snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
+	snd_soc_component_update_bits(component, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
+	m98095_biquad_band(component, channel, 0, coef_set->band1);
+	m98095_biquad_band(component, channel, 1, coef_set->band2);
+	snd_soc_component_update_bits(component, M98095_00F_HOST_CFG, M98095_SEG, 0);
 	mutex_unlock(&max98095->lock);
 
 	/* Restore the original on/off state */
-	snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
+	snd_soc_component_update_bits(component, M98095_088_CFG_LEVEL, regmask, regsave);
 	return 0;
 }
 
 static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-	int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
+	int channel = max98095_get_bq_channel(component, kcontrol->id.name);
 	struct max98095_cdata *cdata;
 
 	if (channel < 0)
@@ -1723,9 +1723,9 @@ static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
+static void max98095_handle_bq_pdata(struct snd_soc_component *component)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_pdata *pdata = max98095->pdata;
 	struct max98095_biquad_cfg *cfg;
 	unsigned int cfgcnt;
@@ -1779,19 +1779,19 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
 	max98095->bq_enum.texts = max98095->bq_texts;
 	max98095->bq_enum.items = max98095->bq_textcnt;
 
-	ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
+	ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));
 	if (ret != 0)
-		dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
+		dev_err(component->dev, "Failed to add Biquad control: %d\n", ret);
 }
 
-static void max98095_handle_pdata(struct snd_soc_codec *codec)
+static void max98095_handle_pdata(struct snd_soc_component *component)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_pdata *pdata = max98095->pdata;
 	u8 regval = 0;
 
 	if (!pdata) {
-		dev_dbg(codec->dev, "No platform data\n");
+		dev_dbg(component->dev, "No platform data\n");
 		return;
 	}
 
@@ -1802,27 +1802,27 @@ static void max98095_handle_pdata(struct snd_soc_codec *codec)
 	if (pdata->digmic_right_mode)
 		regval |= M98095_DIGMIC_R;
 
-	snd_soc_write(codec, M98095_087_CFG_MIC, regval);
+	snd_soc_component_write(component, M98095_087_CFG_MIC, regval);
 
 	/* Configure equalizers */
 	if (pdata->eq_cfgcnt)
-		max98095_handle_eq_pdata(codec);
+		max98095_handle_eq_pdata(component);
 
 	/* Configure bi-quad filters */
 	if (pdata->bq_cfgcnt)
-		max98095_handle_bq_pdata(codec);
+		max98095_handle_bq_pdata(component);
 }
 
 static irqreturn_t max98095_report_jack(int irq, void *data)
 {
-	struct snd_soc_codec *codec = data;
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = data;
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	unsigned int value;
 	int hp_report = 0;
 	int mic_report = 0;
 
 	/* Read the Jack Status Register */
-	value = snd_soc_read(codec, M98095_007_JACK_AUTO_STS);
+	value = snd_soc_component_read32(component, M98095_007_JACK_AUTO_STS);
 
 	/* If ddone is not set, then detection isn't finished yet */
 	if ((value & M98095_DDONE) == 0)
@@ -1853,9 +1853,9 @@ static irqreturn_t max98095_report_jack(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static int max98095_jack_detect_enable(struct snd_soc_codec *codec)
+static int max98095_jack_detect_enable(struct snd_soc_component *component)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 	int detect_enable = M98095_JDEN;
 	unsigned int slew = M98095_DEFAULT_SLEW_DELAY;
@@ -1866,41 +1866,41 @@ static int max98095_jack_detect_enable(struct snd_soc_codec *codec)
 	if (max98095->pdata->jack_detect_delay)
 		slew = max98095->pdata->jack_detect_delay;
 
-	ret = snd_soc_write(codec, M98095_08E_JACK_DC_SLEW, slew);
+	ret = snd_soc_component_write(component, M98095_08E_JACK_DC_SLEW, slew);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
+		dev_err(component->dev, "Failed to cfg auto detect %d\n", ret);
 		return ret;
 	}
 
 	/* configure auto detection to be enabled */
-	ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, detect_enable);
+	ret = snd_soc_component_write(component, M98095_089_JACK_DET_AUTO, detect_enable);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
+		dev_err(component->dev, "Failed to cfg auto detect %d\n", ret);
 		return ret;
 	}
 
 	return ret;
 }
 
-static int max98095_jack_detect_disable(struct snd_soc_codec *codec)
+static int max98095_jack_detect_disable(struct snd_soc_component *component)
 {
 	int ret = 0;
 
 	/* configure auto detection to be disabled */
-	ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, 0x0);
+	ret = snd_soc_component_write(component, M98095_089_JACK_DET_AUTO, 0x0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
+		dev_err(component->dev, "Failed to cfg auto detect %d\n", ret);
 		return ret;
 	}
 
 	return ret;
 }
 
-int max98095_jack_detect(struct snd_soc_codec *codec,
+int max98095_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-	struct i2c_client *client = to_i2c_client(codec->dev);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
+	struct i2c_client *client = to_i2c_client(component->dev);
 	int ret = 0;
 
 	max98095->headphone_jack = hp_jack;
@@ -1910,44 +1910,44 @@ int max98095_jack_detect(struct snd_soc_codec *codec,
 	if (!hp_jack && !mic_jack)
 		return -EINVAL;
 
-	max98095_jack_detect_enable(codec);
+	max98095_jack_detect_enable(component);
 
 	/* enable interrupts for headphone jack detection */
-	ret = snd_soc_update_bits(codec, M98095_013_JACK_INT_EN,
+	ret = snd_soc_component_update_bits(component, M98095_013_JACK_INT_EN,
 		M98095_IDDONE, M98095_IDDONE);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to cfg jack irqs %d\n", ret);
+		dev_err(component->dev, "Failed to cfg jack irqs %d\n", ret);
 		return ret;
 	}
 
-	max98095_report_jack(client->irq, codec);
+	max98095_report_jack(client->irq, component);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(max98095_jack_detect);
 
 #ifdef CONFIG_PM
-static int max98095_suspend(struct snd_soc_codec *codec)
+static int max98095_suspend(struct snd_soc_component *component)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
 	if (max98095->headphone_jack || max98095->mic_jack)
-		max98095_jack_detect_disable(codec);
+		max98095_jack_detect_disable(component);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
 	return 0;
 }
 
-static int max98095_resume(struct snd_soc_codec *codec)
+static int max98095_resume(struct snd_soc_component *component)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-	struct i2c_client *client = to_i2c_client(codec->dev);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
+	struct i2c_client *client = to_i2c_client(component->dev);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	if (max98095->headphone_jack || max98095->mic_jack) {
-		max98095_jack_detect_enable(codec);
-		max98095_report_jack(client->irq, codec);
+		max98095_jack_detect_enable(component);
+		max98095_report_jack(client->irq, component);
 	}
 
 	return 0;
@@ -1957,30 +1957,30 @@ static int max98095_resume(struct snd_soc_codec *codec)
 #define max98095_resume NULL
 #endif
 
-static int max98095_reset(struct snd_soc_codec *codec)
+static int max98095_reset(struct snd_soc_component *component)
 {
 	int i, ret;
 
 	/* Gracefully reset the DSP core and the codec hardware
 	 * in a proper sequence */
-	ret = snd_soc_write(codec, M98095_00F_HOST_CFG, 0);
+	ret = snd_soc_component_write(component, M98095_00F_HOST_CFG, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
+		dev_err(component->dev, "Failed to reset DSP: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_write(codec, M98095_097_PWR_SYS, 0);
+	ret = snd_soc_component_write(component, M98095_097_PWR_SYS, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
+		dev_err(component->dev, "Failed to reset component: %d\n", ret);
 		return ret;
 	}
 
 	/* Reset to hardware default for registers, as there is not
 	 * a soft reset hardware control register */
 	for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
-		ret = snd_soc_write(codec, i, snd_soc_read(codec, i));
+		ret = snd_soc_component_write(component, i, snd_soc_component_read32(component, i));
 		if (ret < 0) {
-			dev_err(codec->dev, "Failed to reset: %d\n", ret);
+			dev_err(component->dev, "Failed to reset: %d\n", ret);
 			return ret;
 		}
 	}
@@ -1988,21 +1988,21 @@ static int max98095_reset(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int max98095_probe(struct snd_soc_codec *codec)
+static int max98095_probe(struct snd_soc_component *component)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 	struct max98095_cdata *cdata;
 	struct i2c_client *client;
 	int ret = 0;
 
-	max98095->mclk = devm_clk_get(codec->dev, "mclk");
+	max98095->mclk = devm_clk_get(component->dev, "mclk");
 	if (PTR_ERR(max98095->mclk) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
 	/* reset the codec, the DSP core, and disable all interrupts */
-	max98095_reset(codec);
+	max98095_reset(component);
 
-	client = to_i2c_client(codec->dev);
+	client = to_i2c_client(component->dev);
 
 	/* initialize private data */
 
@@ -2037,85 +2037,85 @@ static int max98095_probe(struct snd_soc_codec *codec)
 		ret = request_threaded_irq(client->irq, NULL,
 			max98095_report_jack,
 			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
-			IRQF_ONESHOT, "max98095", codec);
+			IRQF_ONESHOT, "max98095", component);
 		if (ret) {
-			dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
+			dev_err(component->dev, "Failed to request IRQ: %d\n", ret);
 			goto err_access;
 		}
 	}
 
-	ret = snd_soc_read(codec, M98095_0FF_REV_ID);
+	ret = snd_soc_component_read32(component, M98095_0FF_REV_ID);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failure reading hardware revision: %d\n",
+		dev_err(component->dev, "Failure reading hardware revision: %d\n",
 			ret);
 		goto err_irq;
 	}
-	dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
+	dev_info(component->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
 
-	snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
+	snd_soc_component_write(component, M98095_097_PWR_SYS, M98095_PWRSV);
 
-	snd_soc_write(codec, M98095_048_MIX_DAC_LR,
+	snd_soc_component_write(component, M98095_048_MIX_DAC_LR,
 		M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR);
 
-	snd_soc_write(codec, M98095_049_MIX_DAC_M,
+	snd_soc_component_write(component, M98095_049_MIX_DAC_M,
 		M98095_DAI2M_TO_DACM|M98095_DAI3M_TO_DACM);
 
-	snd_soc_write(codec, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
-	snd_soc_write(codec, M98095_045_CFG_DSP, M98095_DSPNORMAL);
-	snd_soc_write(codec, M98095_04E_CFG_HP, M98095_HPNORMAL);
+	snd_soc_component_write(component, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
+	snd_soc_component_write(component, M98095_045_CFG_DSP, M98095_DSPNORMAL);
+	snd_soc_component_write(component, M98095_04E_CFG_HP, M98095_HPNORMAL);
 
-	snd_soc_write(codec, M98095_02C_DAI1_IOCFG,
+	snd_soc_component_write(component, M98095_02C_DAI1_IOCFG,
 		M98095_S1NORMAL|M98095_SDATA);
 
-	snd_soc_write(codec, M98095_036_DAI2_IOCFG,
+	snd_soc_component_write(component, M98095_036_DAI2_IOCFG,
 		M98095_S2NORMAL|M98095_SDATA);
 
-	snd_soc_write(codec, M98095_040_DAI3_IOCFG,
+	snd_soc_component_write(component, M98095_040_DAI3_IOCFG,
 		M98095_S3NORMAL|M98095_SDATA);
 
-	max98095_handle_pdata(codec);
+	max98095_handle_pdata(component);
 
 	/* take the codec out of the shut down */
-	snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN,
+	snd_soc_component_update_bits(component, M98095_097_PWR_SYS, M98095_SHDNRUN,
 		M98095_SHDNRUN);
 
 	return 0;
 
 err_irq:
 	if (client->irq)
-		free_irq(client->irq, codec);
+		free_irq(client->irq, component);
 err_access:
 	return ret;
 }
 
-static int max98095_remove(struct snd_soc_codec *codec)
+static void max98095_remove(struct snd_soc_component *component)
 {
-	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-	struct i2c_client *client = to_i2c_client(codec->dev);
+	struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
+	struct i2c_client *client = to_i2c_client(component->dev);
 
 	if (max98095->headphone_jack || max98095->mic_jack)
-		max98095_jack_detect_disable(codec);
+		max98095_jack_detect_disable(component);
 
 	if (client->irq)
-		free_irq(client->irq, codec);
-
-	return 0;
+		free_irq(client->irq, component);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98095 = {
-	.probe   = max98095_probe,
-	.remove  = max98095_remove,
-	.suspend = max98095_suspend,
-	.resume  = max98095_resume,
-	.set_bias_level = max98095_set_bias_level,
-	.component_driver = {
-		.controls		= max98095_snd_controls,
-		.num_controls		= ARRAY_SIZE(max98095_snd_controls),
-		.dapm_widgets		= max98095_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(max98095_dapm_widgets),
-		.dapm_routes		= max98095_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(max98095_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_max98095 = {
+	.probe			= max98095_probe,
+	.remove			= max98095_remove,
+	.suspend		= max98095_suspend,
+	.resume			= max98095_resume,
+	.set_bias_level		= max98095_set_bias_level,
+	.controls		= max98095_snd_controls,
+	.num_controls		= ARRAY_SIZE(max98095_snd_controls),
+	.dapm_widgets		= max98095_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98095_dapm_widgets),
+	.dapm_routes		= max98095_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max98095_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int max98095_i2c_probe(struct i2c_client *i2c,
@@ -2142,17 +2142,12 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, max98095);
 	max98095->pdata = i2c->dev.platform_data;
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_max98095,
 				     max98095_dai, ARRAY_SIZE(max98095_dai));
 	return ret;
 }
 
-static int max98095_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id max98095_i2c_id[] = {
 	{ "max98095", MAX98095 },
 	{ }
@@ -2171,7 +2166,6 @@ static struct i2c_driver max98095_i2c_driver = {
 		.of_match_table = of_match_ptr(max98095_of_match),
 	},
 	.probe  = max98095_i2c_probe,
-	.remove = max98095_i2c_remove,
 	.id_table = max98095_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max98095.h b/sound/soc/codecs/max98095.h
index 2ebbe4e..67886ca 100644
--- a/sound/soc/codecs/max98095.h
+++ b/sound/soc/codecs/max98095.h
@@ -315,7 +315,7 @@
 /* Default Delay used in Slew Rate Calculation for Jack detection */
 #define M98095_DEFAULT_SLEW_DELAY		0x18
 
-extern int max98095_jack_detect(struct snd_soc_codec *codec,
+extern int max98095_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack);
 
 #endif
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c
index 426ed2d..d469576 100644
--- a/sound/soc/codecs/max98357a.c
+++ b/sound/soc/codecs/max98357a.c
@@ -59,27 +59,29 @@ static const struct snd_soc_dapm_route max98357a_dapm_routes[] = {
 	{"Speaker", NULL, "HiFi Playback"},
 };
 
-static int max98357a_codec_probe(struct snd_soc_codec *codec)
+static int max98357a_component_probe(struct snd_soc_component *component)
 {
 	struct gpio_desc *sdmode;
 
-	sdmode = devm_gpiod_get_optional(codec->dev, "sdmode", GPIOD_OUT_LOW);
+	sdmode = devm_gpiod_get_optional(component->dev, "sdmode", GPIOD_OUT_LOW);
 	if (IS_ERR(sdmode))
 		return PTR_ERR(sdmode);
 
-	snd_soc_codec_set_drvdata(codec, sdmode);
+	snd_soc_component_set_drvdata(component, sdmode);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver max98357a_codec_driver = {
-	.probe			= max98357a_codec_probe,
-	.component_driver = {
-		.dapm_widgets		= max98357a_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(max98357a_dapm_widgets),
-		.dapm_routes		= max98357a_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(max98357a_dapm_routes),
-	},
+static const struct snd_soc_component_driver max98357a_component_driver = {
+	.probe			= max98357a_component_probe,
+	.dapm_widgets		= max98357a_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98357a_dapm_widgets),
+	.dapm_routes		= max98357a_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(max98357a_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct snd_soc_dai_ops max98357a_dai_ops = {
@@ -107,14 +109,13 @@ static struct snd_soc_dai_driver max98357a_dai_driver = {
 
 static int max98357a_platform_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &max98357a_codec_driver,
+	return devm_snd_soc_register_component(&pdev->dev,
+			&max98357a_component_driver,
 			&max98357a_dai_driver, 1);
 }
 
 static int max98357a_platform_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c
index 7bc2a17..d4ba139 100644
--- a/sound/soc/codecs/max98371.c
+++ b/sound/soc/codecs/max98371.c
@@ -187,15 +187,15 @@ static const struct snd_kcontrol_new max98371_snd_controls[] = {
 static int max98371_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98371_priv *max98371 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
 		break;
 	default:
-		dev_err(codec->dev, "DAI clock mode unsupported");
+		dev_err(component->dev, "DAI clock mode unsupported");
 		return -EINVAL;
 	}
 
@@ -210,7 +210,7 @@ static int max98371_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		val |= MAX98371_DAI_LEFT;
 		break;
 	default:
-		dev_err(codec->dev, "DAI wrong mode unsupported");
+		dev_err(component->dev, "DAI wrong mode unsupported");
 		return -EINVAL;
 	}
 	regmap_update_bits(max98371->regmap, MAX98371_FMT,
@@ -222,8 +222,8 @@ static int max98371_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;
-	struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98371_priv *max98371 = snd_soc_component_get_drvdata(component);
 	int blr_clk_ratio, ch_size, channels = params_channels(params);
 	int rate = params_rate(params);
 
@@ -348,15 +348,17 @@ static struct snd_soc_dai_driver max98371_dai[] = {
 	}
 };
 
-static const struct snd_soc_codec_driver max98371_codec = {
-	.component_driver = {
-		.controls = max98371_snd_controls,
-		.num_controls = ARRAY_SIZE(max98371_snd_controls),
-		.dapm_routes = max98371_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(max98371_audio_map),
-		.dapm_widgets = max98371_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets),
-	},
+static const struct snd_soc_component_driver max98371_component = {
+	.controls		= max98371_snd_controls,
+	.num_controls		= ARRAY_SIZE(max98371_snd_controls),
+	.dapm_routes		= max98371_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max98371_audio_map),
+	.dapm_widgets		= max98371_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98371_dapm_widgets),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config max98371_regmap = {
@@ -397,21 +399,15 @@ static int max98371_i2c_probe(struct i2c_client *i2c,
 	}
 	dev_info(&i2c->dev, "device version %x\n", reg);
 
-	ret = snd_soc_register_codec(&i2c->dev, &max98371_codec,
+	ret = devm_snd_soc_register_component(&i2c->dev, &max98371_component,
 			max98371_dai, ARRAY_SIZE(max98371_dai));
 	if (ret < 0) {
-		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 		return ret;
 	}
 	return ret;
 }
 
-static int max98371_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id max98371_i2c_id[] = {
 	{ "max98371", 0 },
 	{ }
@@ -432,7 +428,6 @@ static struct i2c_driver max98371_i2c_driver = {
 		.of_match_table = of_match_ptr(max98371_of_match),
 	},
 	.probe  = max98371_i2c_probe,
-	.remove = max98371_i2c_remove,
 	.id_table = max98371_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max98371.h b/sound/soc/codecs/max98371.h
index 9f63309..06e9ba7 100644
--- a/sound/soc/codecs/max98371.h
+++ b/sound/soc/codecs/max98371.h
@@ -62,6 +62,5 @@
 
 struct max98371_priv {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
 };
 #endif
diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c
index 562e887..a925861 100644
--- a/sound/soc/codecs/max98373.c
+++ b/sound/soc/codecs/max98373.c
@@ -112,12 +112,12 @@ static struct reg_default max98373_reg[] = {
 
 static int max98373_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 	unsigned int format = 0;
 	unsigned int invert = 0;
 
-	dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+	dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 	case SND_SOC_DAIFMT_NB_NF:
@@ -126,7 +126,7 @@ static int max98373_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		invert = MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE;
 		break;
 	default:
-		dev_err(codec->dev, "DAI invert mode unsupported\n");
+		dev_err(component->dev, "DAI invert mode unsupported\n");
 		return -EINVAL;
 	}
 
@@ -177,10 +177,10 @@ static int max98373_get_bclk_sel(int bclk)
 	return 0;
 }
 
-static int max98373_set_clock(struct snd_soc_codec *codec,
+static int max98373_set_clock(struct snd_soc_component *component,
 	struct snd_pcm_hw_params *params)
 {
-	struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 	/* BCLK/LRCLK ratio calculation */
 	int blr_clk_ratio = params_channels(params) * max98373->ch_size;
 	int value;
@@ -189,7 +189,7 @@ static int max98373_set_clock(struct snd_soc_codec *codec,
 		/* BCLK configuration */
 		value = max98373_get_bclk_sel(blr_clk_ratio);
 		if (!value) {
-			dev_err(codec->dev, "format unsupported %d\n",
+			dev_err(component->dev, "format unsupported %d\n",
 				params_format(params));
 			return -EINVAL;
 		}
@@ -206,8 +206,8 @@ static int max98373_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;
-	struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 	unsigned int sampling_rate = 0;
 	unsigned int chan_sz = 0;
 
@@ -223,7 +223,7 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
 		chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_32;
 		break;
 	default:
-		dev_err(codec->dev, "format unsupported %d\n",
+		dev_err(component->dev, "format unsupported %d\n",
 			params_format(params));
 		goto err;
 	}
@@ -234,7 +234,7 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
 		MAX98373_R2024_PCM_DATA_FMT_CFG,
 		MAX98373_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
 
-	dev_dbg(codec->dev, "format supported %d",
+	dev_dbg(component->dev, "format supported %d",
 		params_format(params));
 
 	/* sampling rate configuration */
@@ -267,7 +267,7 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
 		sampling_rate = MAX98373_PCM_SR_SET1_SR_48000;
 		break;
 	default:
-		dev_err(codec->dev, "rate %d not supported\n",
+		dev_err(component->dev, "rate %d not supported\n",
 			params_rate(params));
 		goto err;
 	}
@@ -295,7 +295,7 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
 			MAX98373_PCM_SR_SET2_IVADC_SR_MASK,
 			sampling_rate);
 
-	return max98373_set_clock(codec, params);
+	return max98373_set_clock(component, params);
 err:
 	return -EINVAL;
 }
@@ -304,8 +304,8 @@ static int max98373_dai_tdm_slot(struct snd_soc_dai *dai,
 	unsigned int tx_mask, unsigned int rx_mask,
 	int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 	int bsel = 0;
 	unsigned int chan_sz = 0;
 	unsigned int mask;
@@ -319,7 +319,7 @@ static int max98373_dai_tdm_slot(struct snd_soc_dai *dai,
 	/* BCLK configuration */
 	bsel = max98373_get_bclk_sel(slots * slot_width);
 	if (bsel == 0) {
-		dev_err(codec->dev, "BCLK %d not supported\n",
+		dev_err(component->dev, "BCLK %d not supported\n",
 			slots * slot_width);
 		return -EINVAL;
 	}
@@ -341,7 +341,7 @@ static int max98373_dai_tdm_slot(struct snd_soc_dai *dai,
 		chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_32;
 		break;
 	default:
-		dev_err(codec->dev, "format unsupported %d\n",
+		dev_err(component->dev, "format unsupported %d\n",
 			slot_width);
 		return -EINVAL;
 	}
@@ -394,8 +394,8 @@ static const struct snd_soc_dai_ops max98373_dai_ops = {
 static int max98373_dac_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -721,11 +721,9 @@ static struct snd_soc_dai_driver max98373_dai[] = {
 	}
 };
 
-static int max98373_probe(struct snd_soc_codec *codec)
+static int max98373_probe(struct snd_soc_component *component)
 {
-	struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
-
-	codec->control_data = max98373->regmap;
+	struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 
 	/* Software Reset */
 	regmap_write(max98373->regmap,
@@ -828,16 +826,18 @@ static const struct dev_pm_ops max98373_pm = {
 	SET_SYSTEM_SLEEP_PM_OPS(max98373_suspend, max98373_resume)
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98373 = {
-	.probe = max98373_probe,
-	.component_driver = {
-		.controls = max98373_snd_controls,
-		.num_controls = ARRAY_SIZE(max98373_snd_controls),
-		.dapm_widgets = max98373_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(max98373_dapm_widgets),
-		.dapm_routes = max98373_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(max98373_audio_map),
-	},
+static const struct snd_soc_component_driver soc_codec_dev_max98373 = {
+	.probe			= max98373_probe,
+	.controls		= max98373_snd_controls,
+	.num_controls		= ARRAY_SIZE(max98373_snd_controls),
+	.dapm_widgets		= max98373_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98373_dapm_widgets),
+	.dapm_routes		= max98373_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max98373_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config max98373_regmap = {
@@ -920,7 +920,7 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
 	max98373_slot_config(i2c, max98373);
 
 	/* codec registeration */
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98373,
+	ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373,
 		max98373_dai, ARRAY_SIZE(max98373_dai));
 	if (ret < 0)
 		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
@@ -928,12 +928,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
 	return ret;
 }
 
-static int max98373_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id max98373_i2c_id[] = {
 	{ "max98373", 0},
 	{ },
@@ -965,7 +959,6 @@ static struct i2c_driver max98373_i2c_driver = {
 		.pm = &max98373_pm,
 	},
 	.probe = max98373_i2c_probe,
-	.remove = max98373_i2c_remove,
 	.id_table = max98373_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index a3dfc91..74d7f52 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -130,8 +130,8 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max9850_priv *max9850 = snd_soc_component_get_drvdata(component);
 	u64 lrclk_div;
 	u8 sf, da;
 
@@ -139,14 +139,14 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 
 	/* lrclk_div = 2^22 * rate / iclk with iclk = mclk / sf */
-	sf = (snd_soc_read(codec, MAX9850_CLOCK) >> 2) + 1;
+	sf = (snd_soc_component_read32(component, MAX9850_CLOCK) >> 2) + 1;
 	lrclk_div = (1 << 22);
 	lrclk_div *= params_rate(params);
 	lrclk_div *= sf;
 	do_div(lrclk_div, max9850->sysclk);
 
-	snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
-	snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
+	snd_soc_component_write(component, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
+	snd_soc_component_write(component, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
 
 	switch (params_width(params)) {
 	case 16:
@@ -161,7 +161,7 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, MAX9850_DIGITAL_AUDIO, 0x3, da);
+	snd_soc_component_update_bits(component, MAX9850_DIGITAL_AUDIO, 0x3, da);
 
 	return 0;
 }
@@ -169,16 +169,16 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
 static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max9850_priv *max9850 = snd_soc_component_get_drvdata(component);
 
 	/* calculate mclk -> iclk divider */
 	if (freq <= 13000000)
-		snd_soc_write(codec, MAX9850_CLOCK, 0x0);
+		snd_soc_component_write(component, MAX9850_CLOCK, 0x0);
 	else if (freq <= 26000000)
-		snd_soc_write(codec, MAX9850_CLOCK, 0x4);
+		snd_soc_component_write(component, MAX9850_CLOCK, 0x4);
 	else if (freq <= 40000000)
-		snd_soc_write(codec, MAX9850_CLOCK, 0x8);
+		snd_soc_component_write(component, MAX9850_CLOCK, 0x8);
 	else
 		return -EINVAL;
 
@@ -188,7 +188,7 @@ static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u8 da = 0;
 
 	/* set master/slave audio interface */
@@ -234,15 +234,15 @@ static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 	}
 
 	/* set da */
-	snd_soc_write(codec, MAX9850_DIGITAL_AUDIO, da);
+	snd_soc_component_write(component, MAX9850_DIGITAL_AUDIO, da);
 
 	return 0;
 }
 
-static int max9850_set_bias_level(struct snd_soc_codec *codec,
+static int max9850_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
+	struct max9850_priv *max9850 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -251,10 +251,10 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regcache_sync(max9850->regmap);
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to sync cache: %d\n", ret);
 				return ret;
 			}
@@ -289,31 +289,32 @@ static struct snd_soc_dai_driver max9850_dai = {
 	.ops = &max9850_dai_ops,
 };
 
-static int max9850_probe(struct snd_soc_codec *codec)
+static int max9850_probe(struct snd_soc_component *component)
 {
 	/* enable zero-detect */
-	snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
+	snd_soc_component_update_bits(component, MAX9850_GENERAL_PURPOSE, 1, 1);
 	/* enable slew-rate control */
-	snd_soc_update_bits(codec, MAX9850_VOLUME, 0x40, 0x40);
+	snd_soc_component_update_bits(component, MAX9850_VOLUME, 0x40, 0x40);
 	/* set slew-rate 125ms */
-	snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
+	snd_soc_component_update_bits(component, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max9850 = {
-	.probe =	max9850_probe,
-	.set_bias_level = max9850_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= max9850_controls,
-		.num_controls		= ARRAY_SIZE(max9850_controls),
-		.dapm_widgets		= max9850_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(max9850_dapm_widgets),
-		.dapm_routes		= max9850_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(max9850_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_max9850 = {
+	.probe			= max9850_probe,
+	.set_bias_level		= max9850_set_bias_level,
+	.controls		= max9850_controls,
+	.num_controls		= ARRAY_SIZE(max9850_controls),
+	.dapm_widgets		= max9850_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max9850_dapm_widgets),
+	.dapm_routes		= max9850_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(max9850_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int max9850_i2c_probe(struct i2c_client *i2c,
@@ -333,17 +334,11 @@ static int max9850_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, max9850);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_max9850, &max9850_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_max9850, &max9850_dai, 1);
 	return ret;
 }
 
-static int max9850_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id max9850_i2c_id[] = {
 	{ "max9850", 0 },
 	{ }
@@ -355,7 +350,6 @@ static struct i2c_driver max9850_i2c_driver = {
 		.name = "max9850",
 	},
 	.probe = max9850_i2c_probe,
-	.remove = max9850_i2c_remove,
 	.id_table = max9850_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c
index a2dc6a4..5bbf889 100644
--- a/sound/soc/codecs/max9860.c
+++ b/sound/soc/codecs/max9860.c
@@ -261,8 +261,8 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max9860_priv *max9860 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max9860_priv *max9860 = snd_soc_component_get_drvdata(component);
 	u8 master;
 	u8 ifc1a = 0;
 	u8 ifc1b = 0;
@@ -270,7 +270,7 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
 	unsigned long n;
 	int ret;
 
-	dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n",
+	dev_dbg(component->dev, "hw_params %u Hz, %u channels\n",
 		params_rate(params),
 		params_channels(params));
 
@@ -306,7 +306,7 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
 		break;
 	case SND_SOC_DAIFMT_DSP_A:
 		if (params_width(params) != 16) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"DSP_A works for 16 bits per sample only.\n");
 			return -EINVAL;
 		}
@@ -315,7 +315,7 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
 		break;
 	case SND_SOC_DAIFMT_DSP_B:
 		if (params_width(params) != 16) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"DSP_B works for 16 bits per sample only.\n");
 			return -EINVAL;
 		}
@@ -352,16 +352,16 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "IFC1A  %02x\n", ifc1a);
+	dev_dbg(component->dev, "IFC1A  %02x\n", ifc1a);
 	ret = regmap_write(max9860->regmap, MAX9860_IFC1A, ifc1a);
 	if (ret) {
-		dev_err(codec->dev, "Failed to set IFC1A: %d\n", ret);
+		dev_err(component->dev, "Failed to set IFC1A: %d\n", ret);
 		return ret;
 	}
-	dev_dbg(codec->dev, "IFC1B  %02x\n", ifc1b);
+	dev_dbg(component->dev, "IFC1B  %02x\n", ifc1b);
 	ret = regmap_write(max9860->regmap, MAX9860_IFC1B, ifc1b);
 	if (ret) {
-		dev_err(codec->dev, "Failed to set IFC1B: %d\n", ret);
+		dev_err(component->dev, "Failed to set IFC1B: %d\n", ret);
 		return ret;
 	}
 
@@ -417,33 +417,33 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	sysclk |= max9860->psclk;
-	dev_dbg(codec->dev, "SYSCLK %02x\n", sysclk);
+	dev_dbg(component->dev, "SYSCLK %02x\n", sysclk);
 	ret = regmap_write(max9860->regmap,
 			   MAX9860_SYSCLK, sysclk);
 	if (ret) {
-		dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
+		dev_err(component->dev, "Failed to set SYSCLK: %d\n", ret);
 		return ret;
 	}
-	dev_dbg(codec->dev, "N %lu\n", n);
+	dev_dbg(component->dev, "N %lu\n", n);
 	ret = regmap_write(max9860->regmap,
 			   MAX9860_AUDIOCLKHIGH, n >> 8);
 	if (ret) {
-		dev_err(codec->dev, "Failed to set NHI: %d\n", ret);
+		dev_err(component->dev, "Failed to set NHI: %d\n", ret);
 		return ret;
 	}
 	ret = regmap_write(max9860->regmap,
 			   MAX9860_AUDIOCLKLOW, n & 0xff);
 	if (ret) {
-		dev_err(codec->dev, "Failed to set NLO: %d\n", ret);
+		dev_err(component->dev, "Failed to set NLO: %d\n", ret);
 		return ret;
 	}
 
 	if (!master) {
-		dev_dbg(codec->dev, "Enable PLL\n");
+		dev_dbg(component->dev, "Enable PLL\n");
 		ret = regmap_update_bits(max9860->regmap, MAX9860_AUDIOCLKHIGH,
 					 MAX9860_PLL, MAX9860_PLL);
 		if (ret) {
-			dev_err(codec->dev, "Failed to enable PLL: %d\n", ret);
+			dev_err(component->dev, "Failed to enable PLL: %d\n", ret);
 			return ret;
 		}
 	}
@@ -453,8 +453,8 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
 
 static int max9860_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max9860_priv *max9860 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max9860_priv *max9860 = snd_soc_component_get_drvdata(component);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -500,10 +500,10 @@ static struct snd_soc_dai_driver max9860_dai = {
 	.symmetric_rates = 1,
 };
 
-static int max9860_set_bias_level(struct snd_soc_codec *codec,
+static int max9860_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct max9860_priv *max9860 = dev_get_drvdata(codec->dev);
+	struct max9860_priv *max9860 = dev_get_drvdata(component->dev);
 	int ret;
 
 	switch (level) {
@@ -515,7 +515,7 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec,
 		ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
 					 MAX9860_SHDN, MAX9860_SHDN);
 		if (ret) {
-			dev_err(codec->dev, "Failed to remove SHDN: %d\n", ret);
+			dev_err(component->dev, "Failed to remove SHDN: %d\n", ret);
 			return ret;
 		}
 		break;
@@ -524,7 +524,7 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec,
 		ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
 					 MAX9860_SHDN, 0);
 		if (ret) {
-			dev_err(codec->dev, "Failed to request SHDN: %d\n",
+			dev_err(component->dev, "Failed to request SHDN: %d\n",
 				ret);
 			return ret;
 		}
@@ -534,18 +534,17 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static const struct snd_soc_codec_driver max9860_codec_driver = {
-	.set_bias_level = max9860_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= max9860_controls,
-		.num_controls		= ARRAY_SIZE(max9860_controls),
-		.dapm_widgets		= max9860_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(max9860_dapm_widgets),
-		.dapm_routes		= max9860_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(max9860_dapm_routes),
-	},
+static const struct snd_soc_component_driver max9860_component_driver = {
+	.set_bias_level		= max9860_set_bias_level,
+	.controls		= max9860_controls,
+	.num_controls		= ARRAY_SIZE(max9860_controls),
+	.dapm_widgets		= max9860_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max9860_dapm_widgets),
+	.dapm_routes		= max9860_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(max9860_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 #ifdef CONFIG_PM
@@ -698,7 +697,7 @@ static int max9860_probe(struct i2c_client *i2c,
 	pm_runtime_enable(dev);
 	pm_runtime_idle(dev);
 
-	ret = snd_soc_register_codec(dev, &max9860_codec_driver,
+	ret = devm_snd_soc_register_component(dev, &max9860_component_driver,
 				     &max9860_dai, 1);
 	if (ret) {
 		dev_err(dev, "Failed to register CODEC: %d\n", ret);
@@ -719,7 +718,6 @@ static int max9860_remove(struct i2c_client *i2c)
 	struct device *dev = &i2c->dev;
 	struct max9860_priv *max9860 = dev_get_drvdata(dev);
 
-	snd_soc_unregister_codec(dev);
 	pm_runtime_disable(dev);
 	regulator_disable(max9860->dvddio);
 	return 0;
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c
index 2f60924..4ea3287 100644
--- a/sound/soc/codecs/max9867.c
+++ b/sound/soc/codecs/max9867.c
@@ -179,8 +179,8 @@ static inline int get_ni_value(int mclk, int rate)
 static int max9867_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;
-	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 	unsigned int ni_h, ni_l;
 	int value;
 
@@ -227,7 +227,7 @@ static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
 				bclk_value = MAX9867_IFC1B_PCLK_16;
 				break;
 			default:
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"unsupported sampling rate\n");
 				return -EINVAL;
 			}
@@ -239,7 +239,7 @@ static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
 			bclk_value = MAX9867_IFC1B_32BIT;
 			break;
 		default:
-			dev_err(codec->dev, "unsupported sampling rate\n");
+			dev_err(component->dev, "unsupported sampling rate\n");
 			return -EINVAL;
 		}
 		regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
@@ -251,8 +251,8 @@ static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
 static int max9867_prepare(struct snd_pcm_substream *substream,
 			 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 
 	regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
 		MAX9867_SHTDOWN_MASK, MAX9867_SHTDOWN_MASK);
@@ -261,8 +261,8 @@ static int max9867_prepare(struct snd_pcm_substream *substream,
 
 static int max9867_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 
 	if (mute)
 		regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
@@ -276,8 +276,8 @@ static int max9867_mute(struct snd_soc_dai *dai, int mute)
 static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 	int value = 0;
 
 	/* Set the prescaler based on the master clock frequency*/
@@ -291,7 +291,9 @@ static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		value |= MAX9867_PSCLK_40_60;
 		max9867->pclk =  freq/4;
 	} else {
-		pr_err("bad clock frequency %d", freq);
+		dev_err(component->dev,
+			"Invalid clock frequency %uHz (required 10-60MHz)\n",
+			freq);
 		return -EINVAL;
 	}
 	value = value << MAX9867_PSCLK_SHIFT;
@@ -306,8 +308,8 @@ static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 	u8 iface1A = 0, iface1B = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -323,10 +325,16 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	/* for i2s compatible mode */
-	iface1A |= MAX9867_I2S_DLY;
-	/* SDOUT goes to hiz state after all data is transferred */
-	iface1A |= MAX9867_SDOUT_HIZ;
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		iface1A |= MAX9867_I2S_DLY;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		iface1A |= MAX9867_TDM_MODE | MAX9867_SDOUT_HIZ;
+		break;
+	default:
+		return -EINVAL;
+	}
 
 	/* Clock inversion bits, BCI and WCI */
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -367,19 +375,20 @@ static struct snd_soc_dai_driver max9867_dai[] = {
 	.name = "max9867-aif1",
 	.playback = {
 		.stream_name = "HiFi Playback",
-		.channels_min = 1,
+		.channels_min = 2,
 		.channels_max = 2,
 		.rates = MAX9867_RATES,
 		.formats = MAX9867_FORMATS,
 	},
 	.capture = {
 		.stream_name = "HiFi Capture",
-		.channels_min = 1,
+		.channels_min = 2,
 		.channels_max = 2,
 		.rates = MAX9867_RATES,
 		.formats = MAX9867_FORMATS,
 	},
 	.ops = &max9867_dai_ops,
+	.symmetric_rates = 1,
 	}
 };
 
@@ -404,25 +413,17 @@ static int max9867_resume(struct device *dev)
 }
 #endif
 
-static int max9867_probe(struct snd_soc_codec *codec)
-{
-	struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
-
-	dev_dbg(codec->dev, "max98090_probe\n");
-	max9867->codec = codec;
-	return 0;
-}
-
-static const struct snd_soc_codec_driver max9867_codec = {
-	.probe = max9867_probe,
-	.component_driver = {
-		.controls		= max9867_snd_controls,
-		.num_controls		= ARRAY_SIZE(max9867_snd_controls),
-		.dapm_routes		= max9867_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(max9867_audio_map),
-		.dapm_widgets		= max9867_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(max9867_dapm_widgets),
-	},
+static const struct snd_soc_component_driver max9867_component = {
+	.controls		= max9867_snd_controls,
+	.num_controls		= ARRAY_SIZE(max9867_snd_controls),
+	.dapm_routes		= max9867_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max9867_audio_map),
+	.dapm_widgets		= max9867_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max9867_dapm_widgets),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static bool max9867_volatile_register(struct device *dev, unsigned int reg)
@@ -486,8 +487,7 @@ static int max9867_i2c_probe(struct i2c_client *i2c,
 	max9867->regmap = devm_regmap_init_i2c(i2c, &max9867_regmap);
 	if (IS_ERR(max9867->regmap)) {
 		ret = PTR_ERR(max9867->regmap);
-		dev_err(&i2c->dev,
-				"Failed to allocate regmap: %d\n", ret);
+		dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
 		return ret;
 	}
 	ret = regmap_read(max9867->regmap,
@@ -497,21 +497,15 @@ static int max9867_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 	dev_info(&i2c->dev, "device revision: %x\n", reg);
-	ret = snd_soc_register_codec(&i2c->dev, &max9867_codec,
+	ret = devm_snd_soc_register_component(&i2c->dev, &max9867_component,
 			max9867_dai, ARRAY_SIZE(max9867_dai));
 	if (ret < 0) {
-		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 		return ret;
 	}
 	return ret;
 }
 
-static int max9867_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id max9867_i2c_id[] = {
 	{ "max9867", 0 },
 	{ }
@@ -535,7 +529,6 @@ static struct i2c_driver max9867_i2c_driver = {
 		.pm = &max9867_pm_ops,
 	},
 	.probe  = max9867_i2c_probe,
-	.remove = max9867_i2c_remove,
 	.id_table = max9867_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max9867.h b/sound/soc/codecs/max9867.h
index 65590b4..55cd997 100644
--- a/sound/soc/codecs/max9867.h
+++ b/sound/soc/codecs/max9867.h
@@ -75,7 +75,6 @@
 /* codec private data */
 struct max9867_priv {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
 	unsigned int sysclk;
 	unsigned int pclk;
 	unsigned int master;
diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c
index 921f95f..2987773 100644
--- a/sound/soc/codecs/max98925.c
+++ b/sound/soc/codecs/max98925.c
@@ -99,8 +99,8 @@ static const struct snd_kcontrol_new max98925_dai_sel_mux =
 static int max98925_dac_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -256,7 +256,7 @@ static const struct {
 	},
 };
 
-static inline int max98925_rate_value(struct snd_soc_codec *codec,
+static inline int max98925_rate_value(struct snd_soc_component *component,
 		int rate, int clock, int *value, int *n, int *m)
 {
 	int ret = -EINVAL;
@@ -297,11 +297,11 @@ static void max98925_set_sense_data(struct max98925_priv *max98925)
 static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
 				 unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 	unsigned int invert = 0;
 
-	dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+	dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
 		/* set DAI to slave mode */
@@ -322,7 +322,7 @@ static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
 	case SND_SOC_DAIFMT_CBS_CFM:
 	case SND_SOC_DAIFMT_CBM_CFS:
 	default:
-		dev_err(codec->dev, "DAI clock mode unsupported");
+		dev_err(component->dev, "DAI clock mode unsupported");
 		return -EINVAL;
 	}
 
@@ -339,7 +339,7 @@ static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		invert = M98925_DAI_BCI_MASK | M98925_DAI_WCI_MASK;
 		break;
 	default:
-		dev_err(codec->dev, "DAI invert mode unsupported");
+		dev_err(component->dev, "DAI invert mode unsupported");
 		return -EINVAL;
 	}
 
@@ -352,7 +352,7 @@ static int max98925_set_clock(struct max98925_priv *max98925,
 		struct snd_pcm_hw_params *params)
 {
 	unsigned int dai_sr = 0, clock, mdll, n, m;
-	struct snd_soc_codec *codec = max98925->codec;
+	struct snd_soc_component *component = max98925->component;
 	int rate = params_rate(params);
 	/* BCLK/LRCLK ratio calculation */
 	int blr_clk_ratio = params_channels(params) * max98925->ch_size;
@@ -395,12 +395,12 @@ static int max98925_set_clock(struct max98925_priv *max98925,
 		mdll  = M98925_MDLL_MULT_MCLKx8;
 		break;
 	default:
-		dev_info(max98925->codec->dev, "unsupported sysclk %d\n",
+		dev_info(max98925->component->dev, "unsupported sysclk %d\n",
 					max98925->sysclk);
 		return -EINVAL;
 	}
 
-	if (max98925_rate_value(codec, rate, clock, &dai_sr, &n, &m))
+	if (max98925_rate_value(component, rate, clock, &dai_sr, &n, &m))
 		return -EINVAL;
 
 	/* set DAI_SR to correct LRCLK frequency */
@@ -427,8 +427,8 @@ static int max98925_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;
-	struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 
 	switch (params_width(params)) {
 	case 16:
@@ -454,7 +454,7 @@ static int max98925_dai_hw_params(struct snd_pcm_substream *substream,
 				__func__, params_format(params));
 		return -EINVAL;
 	}
-	dev_dbg(codec->dev, "%s: format supported %d",
+	dev_dbg(component->dev, "%s: format supported %d",
 				__func__, params_format(params));
 	return max98925_set_clock(max98925, params);
 }
@@ -462,8 +462,8 @@ static int max98925_dai_hw_params(struct snd_pcm_substream *substream,
 static int max98925_dai_set_sysclk(struct snd_soc_dai *dai,
 				   int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case 0:
@@ -516,11 +516,11 @@ static struct snd_soc_dai_driver max98925_dai[] = {
 	}
 };
 
-static int max98925_probe(struct snd_soc_codec *codec)
+static int max98925_probe(struct snd_soc_component *component)
 {
-	struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+	struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 
-	max98925->codec = codec;
+	max98925->component = component;
 	regmap_write(max98925->regmap, MAX98925_GLOBAL_ENABLE, 0x00);
 	/* It's not the default but we need to set DAI_DLY */
 	regmap_write(max98925->regmap,
@@ -538,16 +538,18 @@ static int max98925_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98925 = {
-	.probe            = max98925_probe,
-	.component_driver = {
-		.controls		= max98925_snd_controls,
-		.num_controls		= ARRAY_SIZE(max98925_snd_controls),
-		.dapm_routes		= max98925_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(max98925_audio_map),
-		.dapm_widgets		= max98925_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(max98925_dapm_widgets),
-	},
+static const struct snd_soc_component_driver soc_component_dev_max98925 = {
+	.probe			= max98925_probe,
+	.controls		= max98925_snd_controls,
+	.num_controls		= ARRAY_SIZE(max98925_snd_controls),
+	.dapm_routes		= max98925_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max98925_audio_map),
+	.dapm_widgets		= max98925_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98925_dapm_widgets),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config max98925_regmap = {
@@ -612,20 +614,15 @@ static int max98925_i2c_probe(struct i2c_client *i2c,
 
 	dev_info(&i2c->dev, "device version 0x%02X\n", reg);
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98925,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_max98925,
 			max98925_dai, ARRAY_SIZE(max98925_dai));
 	if (ret < 0)
 		dev_err(&i2c->dev,
-				"Failed to register codec: %d\n", ret);
+				"Failed to register component: %d\n", ret);
 	return ret;
 }
 
-static int max98925_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id max98925_i2c_id[] = {
 	{ "max98925", 0 },
 	{ }
@@ -645,7 +642,6 @@ static struct i2c_driver max98925_i2c_driver = {
 		.pm = NULL,
 	},
 	.probe  = max98925_i2c_probe,
-	.remove = max98925_i2c_remove,
 	.id_table = max98925_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max98925.h b/sound/soc/codecs/max98925.h
index 3783248..96f9708 100644
--- a/sound/soc/codecs/max98925.h
+++ b/sound/soc/codecs/max98925.h
@@ -821,7 +821,7 @@
 
 struct max98925_priv {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct max98925_pdata *pdata;
 	unsigned int sysclk;
 	unsigned int v_slot;
diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c
index 7b1d1b0..d9b1f68 100644
--- a/sound/soc/codecs/max98926.c
+++ b/sound/soc/codecs/max98926.c
@@ -336,18 +336,18 @@ static void max98926_set_sense_data(struct max98926_priv *max98926)
 static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
 	unsigned int invert = 0;
 
-	dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+	dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
 		max98926_set_sense_data(max98926);
 		break;
 	default:
-		dev_err(codec->dev, "DAI clock mode unsupported\n");
+		dev_err(component->dev, "DAI clock mode unsupported\n");
 		return -EINVAL;
 	}
 
@@ -364,7 +364,7 @@ static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai,
 		invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK;
 		break;
 	default:
-		dev_err(codec->dev, "DAI invert mode unsupported\n");
+		dev_err(component->dev, "DAI invert mode unsupported\n");
 		return -EINVAL;
 	}
 
@@ -381,8 +381,8 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream,
 {
 	int dai_sr = -EINVAL;
 	int rate = params_rate(params), i;
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
 	int blr_clk_ratio;
 
 	switch (params_format(params)) {
@@ -408,7 +408,7 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream,
 		max98926->ch_size = 32;
 		break;
 	default:
-		dev_dbg(codec->dev, "format unsupported %d\n",
+		dev_dbg(component->dev, "format unsupported %d\n",
 			params_format(params));
 		return -EINVAL;
 	}
@@ -485,27 +485,29 @@ static struct snd_soc_dai_driver max98926_dai[] = {
 }
 };
 
-static int max98926_probe(struct snd_soc_codec *codec)
+static int max98926_probe(struct snd_soc_component *component)
 {
-	struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
+	struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
 
-	max98926->codec = codec;
+	max98926->component = component;
 
 	/* Hi-Z all the slots */
 	regmap_write(max98926->regmap, MAX98926_DOUT_HIZ_CFG4, 0xF0);
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98926 = {
-	.probe	= max98926_probe,
-	.component_driver = {
-		.controls		= max98926_snd_controls,
-		.num_controls		= ARRAY_SIZE(max98926_snd_controls),
-		.dapm_routes		= max98926_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(max98926_audio_map),
-		.dapm_widgets		= max98926_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(max98926_dapm_widgets),
-	},
+static const struct snd_soc_component_driver soc_component_dev_max98926 = {
+	.probe			= max98926_probe,
+	.controls		= max98926_snd_controls,
+	.num_controls		= ARRAY_SIZE(max98926_snd_controls),
+	.dapm_routes		= max98926_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max98926_audio_map),
+	.dapm_widgets		= max98926_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98926_dapm_widgets),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config max98926_regmap = {
@@ -563,22 +565,17 @@ static int max98926_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98926,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_max98926,
 			max98926_dai, ARRAY_SIZE(max98926_dai));
 	if (ret < 0)
 		dev_err(&i2c->dev,
-				"Failed to register codec: %d\n", ret);
+				"Failed to register component: %d\n", ret);
 	dev_info(&i2c->dev, "device version: %x\n", reg);
 err_out:
 	return ret;
 }
 
-static int max98926_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id max98926_i2c_id[] = {
 	{ "max98926", 0 },
 	{ }
@@ -598,7 +595,6 @@ static struct i2c_driver max98926_i2c_driver = {
 		.pm = NULL,
 	},
 	.probe	= max98926_i2c_probe,
-	.remove = max98926_i2c_remove,
 	.id_table = max98926_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max98926.h b/sound/soc/codecs/max98926.h
index 9d7ab6d..ccf2c3f 100644
--- a/sound/soc/codecs/max98926.h
+++ b/sound/soc/codecs/max98926.h
@@ -838,7 +838,7 @@
 
 struct max98926_priv {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	unsigned int sysclk;
 	unsigned int v_slot;
 	unsigned int i_slot;
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
index f701fdc..065303a 100644
--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -142,14 +142,14 @@ static struct reg_default max98927_reg[] = {
 
 static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 	unsigned int mode = 0;
 	unsigned int format = 0;
 	bool use_pdm = false;
 	unsigned int invert = 0;
 
-	dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+	dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
@@ -160,7 +160,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		mode = MAX98927_PCM_MASTER_MODE_MASTER;
 		break;
 	default:
-		dev_err(codec->dev, "DAI clock mode unsupported\n");
+		dev_err(component->dev, "DAI clock mode unsupported\n");
 		return -EINVAL;
 	}
 
@@ -176,7 +176,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
 		break;
 	default:
-		dev_err(codec->dev, "DAI invert mode unsupported\n");
+		dev_err(component->dev, "DAI invert mode unsupported\n");
 		return -EINVAL;
 	}
 
@@ -268,7 +268,7 @@ static int max98927_get_bclk_sel(int bclk)
 static int max98927_set_clock(struct max98927_priv *max98927,
 	struct snd_pcm_hw_params *params)
 {
-	struct snd_soc_codec *codec = max98927->codec;
+	struct snd_soc_component *component = max98927->component;
 	/* BCLK/LRCLK ratio calculation */
 	int blr_clk_ratio = params_channels(params) * max98927->ch_size;
 	int value;
@@ -281,7 +281,7 @@ static int max98927_set_clock(struct max98927_priv *max98927,
 				break;
 		}
 		if (i == ARRAY_SIZE(rate_table)) {
-			dev_err(codec->dev, "failed to find proper clock rate.\n");
+			dev_err(component->dev, "failed to find proper clock rate.\n");
 			return -EINVAL;
 		}
 		regmap_update_bits(max98927->regmap,
@@ -294,7 +294,7 @@ static int max98927_set_clock(struct max98927_priv *max98927,
 		/* BCLK configuration */
 		value = max98927_get_bclk_sel(blr_clk_ratio);
 		if (!value) {
-			dev_err(codec->dev, "format unsupported %d\n",
+			dev_err(component->dev, "format unsupported %d\n",
 				params_format(params));
 			return -EINVAL;
 		}
@@ -311,8 +311,8 @@ static int max98927_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;
-	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 	unsigned int sampling_rate = 0;
 	unsigned int chan_sz = 0;
 
@@ -328,7 +328,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
 		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
 		break;
 	default:
-		dev_err(codec->dev, "format unsupported %d\n",
+		dev_err(component->dev, "format unsupported %d\n",
 			params_format(params));
 		goto err;
 	}
@@ -339,7 +339,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
 		MAX98927_R0020_PCM_MODE_CFG,
 		MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
 
-	dev_dbg(codec->dev, "format supported %d",
+	dev_dbg(component->dev, "format supported %d",
 		params_format(params));
 
 	/* sampling rate configuration */
@@ -372,7 +372,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
 		sampling_rate = MAX98927_PCM_SR_SET1_SR_48000;
 		break;
 	default:
-		dev_err(codec->dev, "rate %d not supported\n",
+		dev_err(component->dev, "rate %d not supported\n",
 			params_rate(params));
 		goto err;
 	}
@@ -407,8 +407,8 @@ static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
 	unsigned int tx_mask, unsigned int rx_mask,
 	int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 	int bsel = 0;
 	unsigned int chan_sz = 0;
 
@@ -417,7 +417,7 @@ static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
 	/* BCLK configuration */
 	bsel = max98927_get_bclk_sel(slots * slot_width);
 	if (bsel == 0) {
-		dev_err(codec->dev, "BCLK %d not supported\n",
+		dev_err(component->dev, "BCLK %d not supported\n",
 			slots * slot_width);
 		return -EINVAL;
 	}
@@ -439,7 +439,7 @@ static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
 		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
 		break;
 	default:
-		dev_err(codec->dev, "format unsupported %d\n",
+		dev_err(component->dev, "format unsupported %d\n",
 			slot_width);
 		return -EINVAL;
 	}
@@ -483,8 +483,8 @@ static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
 static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
 	int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 
 	max98927->sysclk = freq;
 	return 0;
@@ -500,8 +500,8 @@ static const struct snd_soc_dai_ops max98927_dai_ops = {
 static int max98927_dac_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -677,11 +677,11 @@ static struct snd_soc_dai_driver max98927_dai[] = {
 	}
 };
 
-static int max98927_probe(struct snd_soc_codec *codec)
+static int max98927_probe(struct snd_soc_component *component)
 {
-	struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+	struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 
-	max98927->codec = codec;
+	max98927->component = component;
 
 	/* Software Reset */
 	regmap_write(max98927->regmap,
@@ -823,16 +823,18 @@ static const struct dev_pm_ops max98927_pm = {
 	SET_SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume)
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
-	.probe = max98927_probe,
-	.component_driver = {
-		.controls = max98927_snd_controls,
-		.num_controls = ARRAY_SIZE(max98927_snd_controls),
-		.dapm_widgets = max98927_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
-		.dapm_routes = max98927_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_max98927 = {
+	.probe			= max98927_probe,
+	.controls		= max98927_snd_controls,
+	.num_controls		= ARRAY_SIZE(max98927_snd_controls),
+	.dapm_widgets		= max98927_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98927_dapm_widgets),
+	.dapm_routes		= max98927_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max98927_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config max98927_regmap = {
@@ -914,20 +916,15 @@ static int max98927_i2c_probe(struct i2c_client *i2c,
 	max98927_slot_config(i2c, max98927);
 
 	/* codec registeration */
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+		&soc_component_dev_max98927,
 		max98927_dai, ARRAY_SIZE(max98927_dai));
 	if (ret < 0)
-		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 
 	return ret;
 }
 
-static int max98927_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id max98927_i2c_id[] = {
 	{ "max98927", 0},
 	{ },
@@ -959,7 +956,6 @@ static struct i2c_driver max98927_i2c_driver = {
 		.pm = &max98927_pm,
 	},
 	.probe  = max98927_i2c_probe,
-	.remove = max98927_i2c_remove,
 	.id_table = max98927_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
index 9ea8397..42a9a24 100644
--- a/sound/soc/codecs/max98927.h
+++ b/sound/soc/codecs/max98927.h
@@ -258,7 +258,7 @@
 
 struct max98927_priv {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct max98927_pdata *pdata;
 	unsigned int spk_gain;
 	unsigned int sysclk;
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index be7a45f..7b0d261 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -107,13 +107,13 @@ static int mc13783_pcm_hw_params_dac(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int rate = params_rate(params);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(mc13783_rates); i++) {
 		if (rate == mc13783_rates[i]) {
-			snd_soc_update_bits(codec, MC13783_AUDIO_DAC,
+			snd_soc_component_update_bits(component, MC13783_AUDIO_DAC,
 					0xf << 17, i << 17);
 			return 0;
 		}
@@ -126,7 +126,7 @@ static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int rate = params_rate(params);
 	unsigned int val;
 
@@ -141,7 +141,7 @@ static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, MC13783_AUDIO_CODEC, AUDIO_CODEC_CDCFS8K16K,
+	snd_soc_component_update_bits(component, MC13783_AUDIO_CODEC, AUDIO_CODEC_CDCFS8K16K,
 			val);
 
 	return 0;
@@ -160,7 +160,7 @@ static int mc13783_pcm_hw_params_sync(struct snd_pcm_substream *substream,
 static int mc13783_set_fmt(struct snd_soc_dai *dai, unsigned int fmt,
 			unsigned int reg)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val = 0;
 	unsigned int mask = AUDIO_CFS(3) | AUDIO_BCL_INV | AUDIO_CFS_INV |
 				AUDIO_CSM | AUDIO_C_CLK_EN | AUDIO_C_RESET;
@@ -208,7 +208,7 @@ static int mc13783_set_fmt(struct snd_soc_dai *dai, unsigned int fmt,
 
 	val |= AUDIO_C_RESET;
 
-	snd_soc_update_bits(codec, reg, mask, val);
+	snd_soc_component_update_bits(component, reg, mask, val);
 
 	return 0;
 }
@@ -255,7 +255,7 @@ static int mc13783_set_sysclk(struct snd_soc_dai *dai,
 				  int clk_id, unsigned int freq, int dir,
 				  unsigned int reg)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int clk;
 	unsigned int val = 0;
 	unsigned int mask = AUDIO_CLK(0x7) | AUDIO_CLK_SEL;
@@ -275,7 +275,7 @@ static int mc13783_set_sysclk(struct snd_soc_dai *dai,
 
 	val |= AUDIO_CLK(clk);
 
-	snd_soc_update_bits(codec, reg, mask, val);
+	snd_soc_component_update_bits(component, reg, mask, val);
 
 	return 0;
 }
@@ -308,7 +308,7 @@ static int mc13783_set_tdm_slot_dac(struct snd_soc_dai *dai,
 	unsigned int tx_mask, unsigned int rx_mask, int slots,
 	int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val = 0;
 	unsigned int mask = SSI_NETWORK_DAC_SLOT_MASK |
 				SSI_NETWORK_DAC_RXSLOT_MASK;
@@ -344,7 +344,7 @@ static int mc13783_set_tdm_slot_dac(struct snd_soc_dai *dai,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, MC13783_SSI_NETWORK, mask, val);
+	snd_soc_component_update_bits(component, MC13783_SSI_NETWORK, mask, val);
 
 	return 0;
 }
@@ -353,7 +353,7 @@ static int mc13783_set_tdm_slot_codec(struct snd_soc_dai *dai,
 	unsigned int tx_mask, unsigned int rx_mask, int slots,
 	int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val = 0;
 	unsigned int mask = 0x3f;
 
@@ -366,7 +366,7 @@ static int mc13783_set_tdm_slot_codec(struct snd_soc_dai *dai,
 	val |= (0x00 << 2);	/* primary timeslot RX/TX(?) is 0 */
 	val |= (0x01 << 4);	/* secondary timeslot TX is 1 */
 
-	snd_soc_update_bits(codec, MC13783_SSI_NETWORK, mask, val);
+	snd_soc_component_update_bits(component, MC13783_SSI_NETWORK, mask, val);
 
 	return 0;
 }
@@ -606,12 +606,12 @@ static struct snd_kcontrol_new mc13783_control_list[] = {
 	SOC_SINGLE("MC2 Capture Bias Switch", MC13783_AUDIO_TX, 1, 1, 0),
 };
 
-static int mc13783_probe(struct snd_soc_codec *codec)
+static int mc13783_probe(struct snd_soc_component *component)
 {
-	struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct mc13783_priv *priv = snd_soc_component_get_drvdata(component);
 
-	snd_soc_codec_init_regmap(codec,
-				  dev_get_regmap(codec->dev->parent, NULL));
+	snd_soc_component_init_regmap(component,
+				  dev_get_regmap(component->dev->parent, NULL));
 
 	/* these are the reset values */
 	mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893);
@@ -638,14 +638,12 @@ static int mc13783_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int mc13783_remove(struct snd_soc_codec *codec)
+static void mc13783_remove(struct snd_soc_component *component)
 {
-	struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct mc13783_priv *priv = snd_soc_component_get_drvdata(component);
 
 	/* Make sure VAUDIOON is off */
 	mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_RX0, 0x3, 0);
-
-	return 0;
 }
 
 #define MC13783_RATES_RECORD (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
@@ -731,17 +729,19 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = {
 	}
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
-	.probe		= mc13783_probe,
-	.remove		= mc13783_remove,
-	.component_driver = {
-		.controls		= mc13783_control_list,
-		.num_controls		= ARRAY_SIZE(mc13783_control_list),
-		.dapm_widgets		= mc13783_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(mc13783_dapm_widgets),
-		.dapm_routes		= mc13783_routes,
-		.num_dapm_routes	= ARRAY_SIZE(mc13783_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_mc13783 = {
+	.probe			= mc13783_probe,
+	.remove			= mc13783_remove,
+	.controls		= mc13783_control_list,
+	.num_controls		= ARRAY_SIZE(mc13783_control_list),
+	.dapm_widgets		= mc13783_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(mc13783_dapm_widgets),
+	.dapm_routes		= mc13783_routes,
+	.num_dapm_routes	= ARRAY_SIZE(mc13783_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int __init mc13783_codec_probe(struct platform_device *pdev)
@@ -782,10 +782,10 @@ static int __init mc13783_codec_probe(struct platform_device *pdev)
 	priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
 
 	if (priv->adc_ssi_port == priv->dac_ssi_port)
-		ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
+		ret = devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_mc13783,
 			mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync));
 	else
-		ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
+		ret = devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_mc13783,
 			mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async));
 
 	return ret;
@@ -793,8 +793,6 @@ static int __init mc13783_codec_probe(struct platform_device *pdev)
 
 static int mc13783_codec_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 5cc960d..a5fa490 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -338,8 +338,8 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *hw_params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
 	int i = get_coeff(priv->mclk, params_rate(hw_params));
 	int srate;
 
@@ -351,23 +351,23 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream,
 	if (priv->clk_in) {
 		switch (priv->mclk / params_rate(hw_params)) {
 		case 256:
-			snd_soc_update_bits(codec, ML26124_CLK_CTL,
+			snd_soc_component_update_bits(component, ML26124_CLK_CTL,
 					    BIT(0) | BIT(1), 1);
 			break;
 		case 512:
-			snd_soc_update_bits(codec, ML26124_CLK_CTL,
+			snd_soc_component_update_bits(component, ML26124_CLK_CTL,
 					    BIT(0) | BIT(1), 2);
 			break;
 		case 1024:
-			snd_soc_update_bits(codec, ML26124_CLK_CTL,
+			snd_soc_component_update_bits(component, ML26124_CLK_CTL,
 					    BIT(0) | BIT(1), 3);
 			break;
 		default:
-			dev_err(codec->dev, "Unsupported MCLKI\n");
+			dev_err(component->dev, "Unsupported MCLKI\n");
 			break;
 		}
 	} else {
-		snd_soc_update_bits(codec, ML26124_CLK_CTL,
+		snd_soc_component_update_bits(component, ML26124_CLK_CTL,
 				    BIT(0) | BIT(1), 0);
 	}
 
@@ -375,35 +375,35 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream,
 	if (srate < 0)
 		return srate;
 
-	snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf, srate);
-	snd_soc_update_bits(codec, ML26124_PLLNL, 0xff, coeff_div[i].pllnl);
-	snd_soc_update_bits(codec, ML26124_PLLNH, 0x1, coeff_div[i].pllnh);
-	snd_soc_update_bits(codec, ML26124_PLLML, 0xff, coeff_div[i].pllml);
-	snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f, coeff_div[i].pllmh);
-	snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f, coeff_div[i].plldiv);
+	snd_soc_component_update_bits(component, ML26124_SMPLING_RATE, 0xf, srate);
+	snd_soc_component_update_bits(component, ML26124_PLLNL, 0xff, coeff_div[i].pllnl);
+	snd_soc_component_update_bits(component, ML26124_PLLNH, 0x1, coeff_div[i].pllnh);
+	snd_soc_component_update_bits(component, ML26124_PLLML, 0xff, coeff_div[i].pllml);
+	snd_soc_component_update_bits(component, ML26124_PLLMH, 0x3f, coeff_div[i].pllmh);
+	snd_soc_component_update_bits(component, ML26124_PLLDIV, 0x1f, coeff_div[i].plldiv);
 
 	return 0;
 }
 
 static int ml26124_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
 
 	switch (priv->substream->stream) {
 	case SNDRV_PCM_STREAM_CAPTURE:
-		snd_soc_update_bits(codec, ML26124_REC_PLYBAK_RUN, BIT(0), 1);
+		snd_soc_component_update_bits(component, ML26124_REC_PLYBAK_RUN, BIT(0), 1);
 		break;
 	case SNDRV_PCM_STREAM_PLAYBACK:
-		snd_soc_update_bits(codec, ML26124_REC_PLYBAK_RUN, BIT(1), 2);
+		snd_soc_component_update_bits(component, ML26124_REC_PLYBAK_RUN, BIT(1), 2);
 		break;
 	}
 
 	if (mute)
-		snd_soc_update_bits(codec, ML26124_DVOL_CTL, BIT(4),
+		snd_soc_component_update_bits(component, ML26124_DVOL_CTL, BIT(4),
 				    DVOL_CTL_DVMUTE_ON);
 	else
-		snd_soc_update_bits(codec, ML26124_DVOL_CTL, BIT(4),
+		snd_soc_component_update_bits(component, ML26124_DVOL_CTL, BIT(4),
 				    DVOL_CTL_DVMUTE_OFF);
 
 	return 0;
@@ -413,7 +413,7 @@ static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
 	unsigned char mode;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -426,7 +426,7 @@ static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, ML26124_SAI_MODE_SEL, BIT(0), mode);
+	snd_soc_component_update_bits(component, ML26124_SAI_MODE_SEL, BIT(0), mode);
 
 	/* interface format */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -450,8 +450,8 @@ static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int ml26124_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case ML26124_USE_PLLOUT:
@@ -469,17 +469,17 @@ static int ml26124_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-static int ml26124_set_bias_level(struct snd_soc_codec *codec,
+static int ml26124_set_bias_level(struct snd_soc_component *component,
 		enum snd_soc_bias_level level)
 {
-	struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		snd_soc_update_bits(codec, ML26124_PW_SPAMP_PW_MNG,
+		snd_soc_component_update_bits(component, ML26124_PW_SPAMP_PW_MNG,
 				    ML26124_R26_MASK, ML26124_BLT_PREAMP_ON);
 		msleep(100);
-		snd_soc_update_bits(codec, ML26124_PW_SPAMP_PW_MNG,
+		snd_soc_component_update_bits(component, ML26124_PW_SPAMP_PW_MNG,
 				    ML26124_R26_MASK,
 				    ML26124_MICBEN_ON | ML26124_BLT_ALL_ON);
 		break;
@@ -487,8 +487,8 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* VMID ON */
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_update_bits(component, ML26124_PW_REF_PW_MNG,
 					    ML26124_VMID, ML26124_VMID);
 			msleep(500);
 			regcache_sync(priv->regmap);
@@ -496,7 +496,7 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* VMID OFF */
-		snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
+		snd_soc_component_update_bits(component, ML26124_PW_REF_PW_MNG,
 				    ML26124_VMID, 0);
 		break;
 	}
@@ -528,27 +528,29 @@ static struct snd_soc_dai_driver ml26124_dai = {
 	.symmetric_rates = 1,
 };
 
-static int ml26124_probe(struct snd_soc_codec *codec)
+static int ml26124_probe(struct snd_soc_component *component)
 {
 	/* Software Reset */
-	snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1);
-	snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0);
+	snd_soc_component_update_bits(component, ML26124_SW_RST, 0x01, 1);
+	snd_soc_component_update_bits(component, ML26124_SW_RST, 0x01, 0);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
-	.probe =	ml26124_probe,
-	.set_bias_level = ml26124_set_bias_level,
-	.suspend_bias_off = true,
-	.component_driver = {
-		.controls		= ml26124_snd_controls,
-		.num_controls		= ARRAY_SIZE(ml26124_snd_controls),
-		.dapm_widgets		= ml26124_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ml26124_dapm_widgets),
-		.dapm_routes		= ml26124_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(ml26124_intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ml26124 = {
+	.probe			= ml26124_probe,
+	.set_bias_level		= ml26124_set_bias_level,
+	.controls		= ml26124_snd_controls,
+	.num_controls		= ARRAY_SIZE(ml26124_snd_controls),
+	.dapm_widgets		= ml26124_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ml26124_dapm_widgets),
+	.dapm_routes		= ml26124_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(ml26124_intercon),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config ml26124_i2c_regmap = {
@@ -580,14 +582,8 @@ static int ml26124_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	return snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_ml26124, &ml26124_dai, 1);
-}
-
-static int ml26124_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
+	return devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_ml26124, &ml26124_dai, 1);
 }
 
 static const struct i2c_device_id ml26124_i2c_id[] = {
@@ -601,7 +597,6 @@ static struct i2c_driver ml26124_i2c_driver = {
 		.name = "ml26124",
 	},
 	.probe = ml26124_i2c_probe,
-	.remove = ml26124_i2c_remove,
 	.id_table = ml26124_i2c_id,
 };
 
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 44062bb..12ee83d 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -288,7 +288,7 @@ struct pm8916_wcd_analog_priv {
 	int	mbhc_btn0_released;
 	bool	detect_accessory_type;
 	struct clk *mclk;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
 	struct snd_soc_jack *jack;
 	bool hphl_jack_type_normally_open;
@@ -338,18 +338,18 @@ static const struct snd_kcontrol_new pm8916_wcd_analog_snd_controls[] = {
 	SOC_SINGLE_TLV("ADC3 Volume", CDC_A_TX_3_EN, 3, 8, 0, analog_gain),
 };
 
-static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
+static void pm8916_wcd_analog_micbias_enable(struct snd_soc_component *component)
 {
-	struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+	struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
-	snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
+	snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
 			    MICB_1_CTL_EXT_PRECHARG_EN_MASK |
 			    MICB_1_CTL_INT_PRECHARG_BYP_MASK,
 			    MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL
 			    | MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
 
 	if (wcd->micbias_mv) {
-		snd_soc_update_bits(codec, CDC_A_MICB_1_VAL,
+		snd_soc_component_update_bits(component, CDC_A_MICB_1_VAL,
 				    MICB_1_VAL_MICB_OUT_VAL_MASK,
 				    MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
 		/*
@@ -360,20 +360,20 @@ static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
 			msleep(50);
 	}
 
-	snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
+	snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
 			    MICB_1_CTL_EXT_PRECHARG_EN_MASK |
 			    MICB_1_CTL_INT_PRECHARG_BYP_MASK, 0);
 
 }
 
-static int pm8916_wcd_analog_enable_micbias_ext(struct snd_soc_codec
-						 *codec, int event,
+static int pm8916_wcd_analog_enable_micbias_ext(struct snd_soc_component
+						 *component, int event,
 						 int reg, unsigned int cap_mode)
 {
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		pm8916_wcd_analog_micbias_enable(codec);
-		snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
+		pm8916_wcd_analog_micbias_enable(component);
+		snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
 				    MICB_1_EN_BYP_CAP_MASK, cap_mode);
 		break;
 	}
@@ -381,25 +381,25 @@ static int pm8916_wcd_analog_enable_micbias_ext(struct snd_soc_codec
 	return 0;
 }
 
-static int pm8916_wcd_analog_enable_micbias_int(struct snd_soc_codec
-						 *codec, int event,
+static int pm8916_wcd_analog_enable_micbias_int(struct snd_soc_component
+						 *component, int event,
 						 int reg, u32 cap_mode)
 {
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, CDC_A_MICB_1_INT_RBIAS,
+		snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS,
 				    MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
 				    MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
-		snd_soc_update_bits(codec, reg, MICB_1_EN_PULL_DOWN_EN_MASK, 0);
-		snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
+		snd_soc_component_update_bits(component, reg, MICB_1_EN_PULL_DOWN_EN_MASK, 0);
+		snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
 				    MICB_1_EN_OPA_STG2_TAIL_CURR_MASK,
 				    MICB_1_EN_OPA_STG2_TAIL_CURR_1_60UA);
 
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-		pm8916_wcd_analog_micbias_enable(codec);
-		snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
+		pm8916_wcd_analog_micbias_enable(component);
+		snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
 				    MICB_1_EN_BYP_CAP_MASK, cap_mode);
 		break;
 	}
@@ -412,10 +412,10 @@ static int pm8916_wcd_analog_enable_micbias_ext1(struct
 						  *w, struct snd_kcontrol
 						  *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
-	return pm8916_wcd_analog_enable_micbias_ext(codec, event, w->reg,
+	return pm8916_wcd_analog_enable_micbias_ext(component, event, w->reg,
 						     wcd->micbias1_cap_mode);
 }
 
@@ -424,10 +424,10 @@ static int pm8916_wcd_analog_enable_micbias_ext2(struct
 						  *w, struct snd_kcontrol
 						  *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
-	return pm8916_wcd_analog_enable_micbias_ext(codec, event, w->reg,
+	return pm8916_wcd_analog_enable_micbias_ext(component, event, w->reg,
 						     wcd->micbias2_cap_mode);
 
 }
@@ -437,35 +437,35 @@ static int pm8916_wcd_analog_enable_micbias_int1(struct
 						  *w, struct snd_kcontrol
 						  *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
-	return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg,
+	return pm8916_wcd_analog_enable_micbias_int(component, event, w->reg,
 						     wcd->micbias1_cap_mode);
 }
 
 static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
 				      bool micbias2_enabled)
 {
-	struct snd_soc_codec *codec = priv->codec;
+	struct snd_soc_component *component = priv->component;
 	u32 coarse, fine, reg_val, reg_addr;
 	int *vrefs, i;
 
 	if (!micbias2_enabled) { /* use internal 100uA Current source */
 		/* Enable internal 2.2k Internal Rbias Resistor */
-		snd_soc_update_bits(codec, CDC_A_MICB_1_INT_RBIAS,
+		snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS,
 				    MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
 				    MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
 		/* Remove pull down on MIC BIAS2 */
-		snd_soc_update_bits(codec, CDC_A_MICB_2_EN,
+		snd_soc_component_update_bits(component, CDC_A_MICB_2_EN,
 				   CDC_A_MICB_2_PULL_DOWN_EN_MASK,
 				   0);
 		/* enable 100uA internal current source */
-		snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL,
+		snd_soc_component_update_bits(component, CDC_A_MBHC_FSM_CTL,
 				    CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK,
 				    CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA);
 	}
-	snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL,
+	snd_soc_component_update_bits(component, CDC_A_MBHC_FSM_CTL,
 			CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK,
 			CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN);
 
@@ -482,7 +482,7 @@ static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
 		fine = ((vrefs[i] % 100) / 12);
 		reg_val = (coarse << CDC_A_MBHC_BTN_VREF_COARSE_SHIFT) |
 			 (fine << CDC_A_MBHC_BTN_VREF_FINE_SHIFT);
-		snd_soc_update_bits(codec, reg_addr,
+		snd_soc_component_update_bits(component, reg_addr,
 			       CDC_A_MBHC_BTN_VREF_MASK,
 			       reg_val);
 		reg_addr++;
@@ -493,12 +493,12 @@ static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
 
 static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
 {
-	struct snd_soc_codec *codec = wcd->codec;
+	struct snd_soc_component *component = wcd->component;
 	bool micbias_enabled = false;
 	u32 plug_type = 0;
 	u32 int_en_mask;
 
-	snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1,
+	snd_soc_component_write(component, CDC_A_MBHC_DET_CTL_1,
 		      CDC_A_MBHC_DET_CTL_L_DET_EN |
 		      CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION |
 		      CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO |
@@ -510,23 +510,23 @@ static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
 	if (wcd->gnd_jack_type_normally_open)
 		plug_type |= CDC_A_GND_PLUG_TYPE_NO;
 
-	snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2,
+	snd_soc_component_write(component, CDC_A_MBHC_DET_CTL_2,
 		      CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 |
 		      CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD |
 		      plug_type |
 		      CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN);
 
 
-	snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER,
+	snd_soc_component_write(component, CDC_A_MBHC_DBNC_TIMER,
 		      CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS |
 		      CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS);
 
 	/* enable MBHC clock */
-	snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL,
+	snd_soc_component_update_bits(component, CDC_D_CDC_DIG_CLK_CTL,
 			    DIG_CLK_CTL_D_MBHC_CLK_EN_MASK,
 			    DIG_CLK_CTL_D_MBHC_CLK_EN);
 
-	if (snd_soc_read(codec, CDC_A_MICB_2_EN) & CDC_A_MICB_2_EN_ENABLE)
+	if (snd_soc_component_read32(component, CDC_A_MICB_2_EN) & CDC_A_MICB_2_EN_ENABLE)
 		micbias_enabled = true;
 
 	pm8916_mbhc_configure_bias(wcd, micbias_enabled);
@@ -535,8 +535,8 @@ static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
 	if (wcd->mbhc_btn_enabled)
 		int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET;
 
-	snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0);
-	snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
+	snd_soc_component_update_bits(component, CDC_D_INT_EN_CLR, int_en_mask, 0);
+	snd_soc_component_update_bits(component, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
 	wcd->mbhc_btn0_released = false;
 	wcd->detect_accessory_type = true;
 }
@@ -546,8 +546,8 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct
 						  *w, struct snd_kcontrol
 						  *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -558,7 +558,7 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct
 		break;
 	}
 
-	return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg,
+	return pm8916_wcd_analog_enable_micbias_int(component, event, w->reg,
 						     wcd->micbias2_cap_mode);
 }
 
@@ -566,7 +566,7 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
 					 struct snd_kcontrol *kcontrol,
 					 int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	u16 adc_reg = CDC_A_TX_1_2_TEST_CTL_2;
 	u8 init_bit_shift;
 
@@ -578,7 +578,7 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		if (w->reg == CDC_A_TX_2_EN)
-			snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
+			snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
 					    MICB_1_CTL_CFILT_REF_SEL_MASK,
 					    MICB_1_CTL_CFILT_REF_SEL_HPF_REF);
 		/*
@@ -587,17 +587,17 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
 		 * happen when the input voltage is changing too much.
 		 */
 		usleep_range(10000, 10010);
-		snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
+		snd_soc_component_update_bits(component, adc_reg, 1 << init_bit_shift,
 				    1 << init_bit_shift);
 		switch (w->reg) {
 		case CDC_A_TX_1_EN:
-			snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX1_CTL,
+			snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX1_CTL,
 					    CONN_TX1_SERIAL_TX1_MUX,
 					    CONN_TX1_SERIAL_TX1_ADC_1);
 			break;
 		case CDC_A_TX_2_EN:
 		case CDC_A_TX_3_EN:
-			snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX2_CTL,
+			snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX2_CTL,
 					    CONN_TX2_SERIAL_TX2_MUX,
 					    CONN_TX2_SERIAL_TX2_ADC_2);
 			break;
@@ -609,21 +609,21 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
 		 * to reduce the tx pop
 		 */
 		usleep_range(12000, 12010);
-		snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
+		snd_soc_component_update_bits(component, adc_reg, 1 << init_bit_shift, 0x00);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		switch (w->reg) {
 		case CDC_A_TX_1_EN:
-			snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX1_CTL,
+			snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX1_CTL,
 					    CONN_TX1_SERIAL_TX1_MUX,
 					    CONN_TX1_SERIAL_TX1_ZERO);
 			break;
 		case CDC_A_TX_2_EN:
-			snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
+			snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
 					    MICB_1_CTL_CFILT_REF_SEL_MASK, 0);
 			/* fall through */
 		case CDC_A_TX_3_EN:
-			snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX2_CTL,
+			snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX2_CTL,
 					    CONN_TX2_SERIAL_TX2_MUX,
 					    CONN_TX2_SERIAL_TX2_ZERO);
 			break;
@@ -639,11 +639,11 @@ static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w,
 					    struct snd_kcontrol *kcontrol,
 					    int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, CDC_A_SPKR_PWRSTG_CTL,
+		snd_soc_component_update_bits(component, CDC_A_SPKR_PWRSTG_CTL,
 				    SPKR_PWRSTG_CTL_DAC_EN_MASK |
 				    SPKR_PWRSTG_CTL_BBM_MASK |
 				    SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
@@ -653,29 +653,29 @@ static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w,
 				    SPKR_PWRSTG_CTL_HBRDGE_EN |
 				    SPKR_PWRSTG_CTL_CLAMP_EN);
 
-		snd_soc_update_bits(codec, CDC_A_RX_EAR_CTL,
+		snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
 				    RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK,
 				    RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, CDC_A_SPKR_DRV_CTL,
+		snd_soc_component_update_bits(component, CDC_A_SPKR_DRV_CTL,
 				    SPKR_DRV_CTL_DEF_MASK,
 				    SPKR_DRV_CTL_DEF_VAL);
-		snd_soc_update_bits(codec, w->reg,
+		snd_soc_component_update_bits(component, w->reg,
 				    SPKR_DRV_CLASSD_PA_EN_MASK,
 				    SPKR_DRV_CLASSD_PA_EN_ENABLE);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, CDC_A_SPKR_PWRSTG_CTL,
+		snd_soc_component_update_bits(component, CDC_A_SPKR_PWRSTG_CTL,
 				    SPKR_PWRSTG_CTL_DAC_EN_MASK|
 				    SPKR_PWRSTG_CTL_BBM_MASK |
 				    SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
 				    SPKR_PWRSTG_CTL_CLAMP_EN_MASK, 0);
 
-		snd_soc_update_bits(codec, CDC_A_SPKR_DAC_CTL,
+		snd_soc_component_update_bits(component, CDC_A_SPKR_DAC_CTL,
 				    SPKR_DAC_CTL_DAC_RESET_MASK,
 				    SPKR_DAC_CTL_DAC_RESET_NORMAL);
-		snd_soc_update_bits(codec, CDC_A_RX_EAR_CTL,
+		snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
 				    RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK, 0);
 		break;
 	}
@@ -701,36 +701,36 @@ static const struct reg_default wcd_reg_defaults_2_0[] = {
 	{CDC_A_MASTER_BIAS_CTL, 0x30},
 };
 
-static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec)
+static int pm8916_wcd_analog_probe(struct snd_soc_component *component)
 {
-	struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev);
+	struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
 	int err, reg;
 
 	err = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 	if (err != 0) {
-		dev_err(codec->dev, "failed to enable regulators (%d)\n", err);
+		dev_err(component->dev, "failed to enable regulators (%d)\n", err);
 		return err;
 	}
 
-	snd_soc_codec_init_regmap(codec,
-				  dev_get_regmap(codec->dev->parent, NULL));
-	snd_soc_codec_set_drvdata(codec, priv);
-	priv->pmic_rev = snd_soc_read(codec, CDC_D_REVISION1);
-	priv->codec_version = snd_soc_read(codec, CDC_D_PERPH_SUBTYPE);
+	snd_soc_component_init_regmap(component,
+				  dev_get_regmap(component->dev->parent, NULL));
+	snd_soc_component_set_drvdata(component, priv);
+	priv->pmic_rev = snd_soc_component_read32(component, CDC_D_REVISION1);
+	priv->codec_version = snd_soc_component_read32(component, CDC_D_PERPH_SUBTYPE);
 
-	dev_info(codec->dev, "PMIC REV: %d\t CODEC Version: %d\n",
+	dev_info(component->dev, "PMIC REV: %d\t CODEC Version: %d\n",
 		 priv->pmic_rev, priv->codec_version);
 
-	snd_soc_write(codec, CDC_D_PERPH_RESET_CTL4, 0x01);
-	snd_soc_write(codec, CDC_A_PERPH_RESET_CTL4, 0x01);
+	snd_soc_component_write(component, CDC_D_PERPH_RESET_CTL4, 0x01);
+	snd_soc_component_write(component, CDC_A_PERPH_RESET_CTL4, 0x01);
 
 	for (reg = 0; reg < ARRAY_SIZE(wcd_reg_defaults_2_0); reg++)
-		snd_soc_write(codec, wcd_reg_defaults_2_0[reg].reg,
+		snd_soc_component_write(component, wcd_reg_defaults_2_0[reg].reg,
 			      wcd_reg_defaults_2_0[reg].def);
 
-	priv->codec = codec;
+	priv->component = component;
 
-	snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL,
+	snd_soc_component_update_bits(component, CDC_D_CDC_RST_CTL,
 			    RST_CTL_DIG_SW_RST_N_MASK,
 			    RST_CTL_DIG_SW_RST_N_REMOVE_RESET);
 
@@ -739,14 +739,14 @@ static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int pm8916_wcd_analog_remove(struct snd_soc_codec *codec)
+static void pm8916_wcd_analog_remove(struct snd_soc_component *component)
 {
-	struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev);
+	struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
 
-	snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL,
+	snd_soc_component_update_bits(component, CDC_D_CDC_RST_CTL,
 			    RST_CTL_DIG_SW_RST_N_MASK, 0);
 
-	return regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
+	regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
 				      priv->supplies);
 }
 
@@ -934,11 +934,11 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY("A_MCLK2", CDC_D_CDC_TOP_CLK_CTL, 3, 0, NULL, 0),
 };
 
-static int pm8916_wcd_analog_set_jack(struct snd_soc_codec *codec,
+static int pm8916_wcd_analog_set_jack(struct snd_soc_component *component,
 				      struct snd_soc_jack *jack,
 				      void *data)
 {
-	struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+	struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
 	wcd->jack = jack;
 
@@ -950,8 +950,8 @@ static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg)
 	struct pm8916_wcd_analog_priv *priv = arg;
 
 	if (priv->detect_accessory_type) {
-		struct snd_soc_codec *codec = priv->codec;
-		u32 val = snd_soc_read(codec, CDC_A_MBHC_RESULT_1);
+		struct snd_soc_component *component = priv->component;
+		u32 val = snd_soc_component_read32(component, CDC_A_MBHC_RESULT_1);
 
 		/* check if its BTN0 thats released */
 		if ((val != -1) && !(val & CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK))
@@ -967,10 +967,10 @@ static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg)
 static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
 {
 	struct pm8916_wcd_analog_priv *priv = arg;
-	struct snd_soc_codec *codec = priv->codec;
+	struct snd_soc_component *component = priv->component;
 	u32 btn_result;
 
-	btn_result = snd_soc_read(codec, CDC_A_MBHC_RESULT_1) &
+	btn_result = snd_soc_component_read32(component, CDC_A_MBHC_RESULT_1) &
 				  CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK;
 
 	switch (btn_result) {
@@ -993,7 +993,7 @@ static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
 					    SND_JACK_BTN_0, btn_mask);
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Unexpected button press result (%x)", btn_result);
 		break;
 	}
@@ -1004,15 +1004,15 @@ static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
 static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg)
 {
 	struct pm8916_wcd_analog_priv *priv = arg;
-	struct snd_soc_codec *codec = priv->codec;
+	struct snd_soc_component *component = priv->component;
 	bool ins = false;
 
-	if (snd_soc_read(codec, CDC_A_MBHC_DET_CTL_1) &
+	if (snd_soc_component_read32(component, CDC_A_MBHC_DET_CTL_1) &
 				CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK)
 		ins = true;
 
 	/* Set the detection type appropriately */
-	snd_soc_update_bits(codec, CDC_A_MBHC_DET_CTL_1,
+	snd_soc_component_update_bits(component, CDC_A_MBHC_DET_CTL_1,
 			    CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK,
 			    (!ins << CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT));
 
@@ -1020,7 +1020,7 @@ static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg)
 	if (ins) { /* hs insertion */
 		bool micbias_enabled = false;
 
-		if (snd_soc_read(codec, CDC_A_MICB_2_EN) &
+		if (snd_soc_component_read32(component, CDC_A_MICB_2_EN) &
 				CDC_A_MICB_2_EN_ENABLE)
 			micbias_enabled = true;
 
@@ -1075,18 +1075,20 @@ static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = {
 	       },
 };
 
-static const struct snd_soc_codec_driver pm8916_wcd_analog = {
-	.probe = pm8916_wcd_analog_probe,
-	.remove = pm8916_wcd_analog_remove,
-	.set_jack = pm8916_wcd_analog_set_jack,
-	.component_driver = {
-		.controls = pm8916_wcd_analog_snd_controls,
-		.num_controls = ARRAY_SIZE(pm8916_wcd_analog_snd_controls),
-		.dapm_widgets = pm8916_wcd_analog_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(pm8916_wcd_analog_dapm_widgets),
-		.dapm_routes = pm8916_wcd_analog_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(pm8916_wcd_analog_audio_map),
-	},
+static const struct snd_soc_component_driver pm8916_wcd_analog = {
+	.probe			= pm8916_wcd_analog_probe,
+	.remove			= pm8916_wcd_analog_remove,
+	.set_jack		= pm8916_wcd_analog_set_jack,
+	.controls		= pm8916_wcd_analog_snd_controls,
+	.num_controls		= ARRAY_SIZE(pm8916_wcd_analog_snd_controls),
+	.dapm_widgets		= pm8916_wcd_analog_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pm8916_wcd_analog_dapm_widgets),
+	.dapm_routes		= pm8916_wcd_analog_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(pm8916_wcd_analog_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int pm8916_wcd_analog_parse_dt(struct device *dev,
@@ -1223,7 +1225,7 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
 
 	dev_set_drvdata(dev, priv);
 
-	return snd_soc_register_codec(dev, &pm8916_wcd_analog,
+	return devm_snd_soc_register_component(dev, &pm8916_wcd_analog,
 				      pm8916_wcd_analog_dai,
 				      ARRAY_SIZE(pm8916_wcd_analog_dai));
 }
@@ -1232,7 +1234,6 @@ static int pm8916_wcd_analog_spmi_remove(struct platform_device *pdev)
 {
 	struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(&pdev->dev);
 
-	snd_soc_unregister_codec(&pdev->dev);
 	clk_disable_unprepare(priv->mclk);
 
 	return 0;
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c
index 13354d6..3063ded 100644
--- a/sound/soc/codecs/msm8916-wcd-digital.c
+++ b/sound/soc/codecs/msm8916-wcd-digital.c
@@ -348,14 +348,14 @@ static int msm8916_wcd_digital_enable_interpolator(
 						struct snd_kcontrol *kcontrol,
 						int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* apply the digital gain after the interpolator is enabled */
 		usleep_range(10000, 10100);
-		snd_soc_write(codec, rx_gain_reg[w->shift],
-			      snd_soc_read(codec, rx_gain_reg[w->shift]));
+		snd_soc_component_write(component, rx_gain_reg[w->shift],
+			      snd_soc_component_read32(component, rx_gain_reg[w->shift]));
 		break;
 	}
 	return 0;
@@ -365,7 +365,7 @@ static int msm8916_wcd_digital_enable_dec(struct snd_soc_dapm_widget *w,
 					  struct snd_kcontrol *kcontrol,
 					  int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int decimator = w->shift + 1;
 	u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
 	u8 dec_hpf_cut_of_freq;
@@ -377,46 +377,46 @@ static int msm8916_wcd_digital_enable_dec(struct snd_soc_dapm_widget *w,
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		/* Enable TX digital mute */
-		snd_soc_update_bits(codec, tx_vol_ctl_reg,
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 				    TX_VOL_CTL_CFG_MUTE_EN_MASK,
 				    TX_VOL_CTL_CFG_MUTE_EN_ENABLE);
-		dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg) &
+		dec_hpf_cut_of_freq = snd_soc_component_read32(component, tx_mux_ctl_reg) &
 					TX_MUX_CTL_CUT_OFF_FREQ_MASK;
 		dec_hpf_cut_of_freq >>= TX_MUX_CTL_CUT_OFF_FREQ_SHIFT;
 		if (dec_hpf_cut_of_freq != TX_MUX_CTL_CF_NEG_3DB_150HZ) {
 			/* set cut of freq to CF_MIN_3DB_150HZ (0x1) */
-			snd_soc_update_bits(codec, tx_mux_ctl_reg,
+			snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 					    TX_MUX_CTL_CUT_OFF_FREQ_MASK,
 					    TX_MUX_CTL_CF_NEG_3DB_150HZ);
 		}
 		break;
 	case SND_SOC_DAPM_POST_PMU:
 		/* enable HPF */
-		snd_soc_update_bits(codec, tx_mux_ctl_reg,
+		snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 				    TX_MUX_CTL_HPF_BP_SEL_MASK,
 				    TX_MUX_CTL_HPF_BP_SEL_NO_BYPASS);
 		/* apply the digital gain after the decimator is enabled */
-		snd_soc_write(codec, tx_gain_reg[w->shift],
-			      snd_soc_read(codec, tx_gain_reg[w->shift]));
-		snd_soc_update_bits(codec, tx_vol_ctl_reg,
+		snd_soc_component_write(component, tx_gain_reg[w->shift],
+			      snd_soc_component_read32(component, tx_gain_reg[w->shift]));
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 				    TX_VOL_CTL_CFG_MUTE_EN_MASK, 0);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, tx_vol_ctl_reg,
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 				    TX_VOL_CTL_CFG_MUTE_EN_MASK,
 				    TX_VOL_CTL_CFG_MUTE_EN_ENABLE);
-		snd_soc_update_bits(codec, tx_mux_ctl_reg,
+		snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 				    TX_MUX_CTL_HPF_BP_SEL_MASK,
 				    TX_MUX_CTL_HPF_BP_SEL_BYPASS);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
+		snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift,
 				    1 << w->shift);
-		snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
-		snd_soc_update_bits(codec, tx_mux_ctl_reg,
+		snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift, 0x0);
+		snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 				    TX_MUX_CTL_HPF_BP_SEL_MASK,
 				    TX_MUX_CTL_HPF_BP_SEL_BYPASS);
-		snd_soc_update_bits(codec, tx_vol_ctl_reg,
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 				    TX_VOL_CTL_CFG_MUTE_EN_MASK, 0);
 		break;
 	}
@@ -428,35 +428,35 @@ static int msm8916_wcd_digital_enable_dmic(struct snd_soc_dapm_widget *w,
 					   struct snd_kcontrol *kcontrol,
 					   int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int dmic;
 	int ret;
 	/* get dmic number out of widget name */
 	char *dmic_num = strpbrk(w->name, "12");
 
 	if (dmic_num == NULL) {
-		dev_err(codec->dev, "Invalid DMIC\n");
+		dev_err(component->dev, "Invalid DMIC\n");
 		return -EINVAL;
 	}
 	ret = kstrtouint(dmic_num, 10, &dmic);
 	if (ret < 0 || dmic > 2) {
-		dev_err(codec->dev, "Invalid DMIC line on the codec\n");
+		dev_err(component->dev, "Invalid DMIC line on the component\n");
 		return -EINVAL;
 	}
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, LPASS_CDC_CLK_DMIC_B1_CTL,
+		snd_soc_component_update_bits(component, LPASS_CDC_CLK_DMIC_B1_CTL,
 				    DMIC_B1_CTL_DMIC0_CLK_SEL_MASK,
 				    DMIC_B1_CTL_DMIC0_CLK_SEL_DIV3);
 		switch (dmic) {
 		case 1:
-			snd_soc_update_bits(codec, LPASS_CDC_TX1_DMIC_CTL,
+			snd_soc_component_update_bits(component, LPASS_CDC_TX1_DMIC_CTL,
 					    TXN_DMIC_CTL_CLK_SEL_MASK,
 					    TXN_DMIC_CTL_CLK_SEL_DIV3);
 			break;
 		case 2:
-			snd_soc_update_bits(codec, LPASS_CDC_TX2_DMIC_CTL,
+			snd_soc_component_update_bits(component, LPASS_CDC_TX2_DMIC_CTL,
 					    TXN_DMIC_CTL_CLK_SEL_MASK,
 					    TXN_DMIC_CTL_CLK_SEL_DIV3);
 			break;
@@ -575,20 +575,20 @@ static int msm8916_wcd_digital_get_clks(struct platform_device *pdev,
 	return 0;
 }
 
-static int msm8916_wcd_digital_codec_probe(struct snd_soc_codec *codec)
+static int msm8916_wcd_digital_component_probe(struct snd_soc_component *component)
 {
-	struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(codec->dev);
+	struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(component->dev);
 
-	snd_soc_codec_set_drvdata(codec, priv);
+	snd_soc_component_set_drvdata(component, priv);
 
 	return 0;
 }
 
-static int msm8916_wcd_digital_codec_set_sysclk(struct snd_soc_codec *codec,
+static int msm8916_wcd_digital_component_set_sysclk(struct snd_soc_component *component,
 						int clk_id, int source,
 						unsigned int freq, int dir)
 {
-	struct msm8916_wcd_digital_priv *p = dev_get_drvdata(codec->dev);
+	struct msm8916_wcd_digital_priv *p = dev_get_drvdata(component->dev);
 
 	return clk_set_rate(p->mclk, freq);
 }
@@ -618,18 +618,18 @@ static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream,
 		rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_48_KHZ;
 		break;
 	default:
-		dev_err(dai->codec->dev, "Invalid sampling rate %d\n",
+		dev_err(dai->component->dev, "Invalid sampling rate %d\n",
 			params_rate(params));
 		return -EINVAL;
 	}
 
 	switch (substream->stream) {
 	case SNDRV_PCM_STREAM_CAPTURE:
-		snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_TX_I2S_CTL,
+		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 				    TX_I2S_CTL_TX_I2S_FS_RATE_MASK, tx_fs_rate);
 		break;
 	case SNDRV_PCM_STREAM_PLAYBACK:
-		snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_RX_I2S_CTL,
+		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 				    RX_I2S_CTL_RX_I2S_FS_RATE_MASK, rx_fs_rate);
 		break;
 	default:
@@ -638,18 +638,19 @@ static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream,
 
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
-		snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_TX_I2S_CTL,
+		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 				    TX_I2S_CTL_TX_I2S_MODE_MASK,
 				    TX_I2S_CTL_TX_I2S_MODE_16);
-		snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_RX_I2S_CTL,
+		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 				    RX_I2S_CTL_RX_I2S_MODE_MASK,
 				    RX_I2S_CTL_RX_I2S_MODE_16);
 		break;
+
 	case SNDRV_PCM_FORMAT_S32_LE:
-		snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_TX_I2S_CTL,
+		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 				    TX_I2S_CTL_TX_I2S_MODE_MASK,
 				    TX_I2S_CTL_TX_I2S_MODE_32);
-		snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_RX_I2S_CTL,
+		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 				    RX_I2S_CTL_RX_I2S_MODE_MASK,
 				    RX_I2S_CTL_RX_I2S_MODE_32);
 		break;
@@ -780,32 +781,32 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
 static int msm8916_wcd_digital_startup(struct snd_pcm_substream *substream,
 				       struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	struct msm8916_wcd_digital_priv *msm8916_wcd;
 	unsigned long mclk_rate;
 
-	msm8916_wcd = snd_soc_codec_get_drvdata(codec);
-	snd_soc_update_bits(codec, LPASS_CDC_CLK_MCLK_CTL,
+	msm8916_wcd = snd_soc_component_get_drvdata(component);
+	snd_soc_component_update_bits(component, LPASS_CDC_CLK_MCLK_CTL,
 			    MCLK_CTL_MCLK_EN_MASK,
 			    MCLK_CTL_MCLK_EN_ENABLE);
-	snd_soc_update_bits(codec, LPASS_CDC_CLK_PDM_CTL,
+	snd_soc_component_update_bits(component, LPASS_CDC_CLK_PDM_CTL,
 			    LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK,
 			    LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_FB);
 
 	mclk_rate = clk_get_rate(msm8916_wcd->mclk);
 	switch (mclk_rate) {
 	case 12288000:
-		snd_soc_update_bits(codec, LPASS_CDC_TOP_CTL,
+		snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL,
 				    TOP_CTL_DIG_MCLK_FREQ_MASK,
 				    TOP_CTL_DIG_MCLK_FREQ_F_12_288MHZ);
 		break;
 	case 9600000:
-		snd_soc_update_bits(codec, LPASS_CDC_TOP_CTL,
+		snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL,
 				    TOP_CTL_DIG_MCLK_FREQ_MASK,
 				    TOP_CTL_DIG_MCLK_FREQ_F_9_6MHZ);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid mclk rate %ld\n", mclk_rate);
+		dev_err(component->dev, "Invalid mclk rate %ld\n", mclk_rate);
 		break;
 	}
 	return 0;
@@ -814,7 +815,7 @@ static int msm8916_wcd_digital_startup(struct snd_pcm_substream *substream,
 static void msm8916_wcd_digital_shutdown(struct snd_pcm_substream *substream,
 					 struct snd_soc_dai *dai)
 {
-	snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_PDM_CTL,
+	snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_PDM_CTL,
 			    LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 0);
 }
 
@@ -851,18 +852,19 @@ static struct snd_soc_dai_driver msm8916_wcd_digital_dai[] = {
 	       },
 };
 
-static const struct snd_soc_codec_driver msm8916_wcd_digital = {
-	.probe = msm8916_wcd_digital_codec_probe,
-	.set_sysclk = msm8916_wcd_digital_codec_set_sysclk,
-	.component_driver = {
-		.controls = msm8916_wcd_digital_snd_controls,
-		.num_controls = ARRAY_SIZE(msm8916_wcd_digital_snd_controls),
-		.dapm_widgets = msm8916_wcd_digital_dapm_widgets,
-		.num_dapm_widgets =
-				 ARRAY_SIZE(msm8916_wcd_digital_dapm_widgets),
-		.dapm_routes = msm8916_wcd_digital_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(msm8916_wcd_digital_audio_map),
-	},
+static const struct snd_soc_component_driver msm8916_wcd_digital = {
+	.probe			= msm8916_wcd_digital_component_probe,
+	.set_sysclk		= msm8916_wcd_digital_component_set_sysclk,
+	.controls		= msm8916_wcd_digital_snd_controls,
+	.num_controls		= ARRAY_SIZE(msm8916_wcd_digital_snd_controls),
+	.dapm_widgets		= msm8916_wcd_digital_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(msm8916_wcd_digital_dapm_widgets),
+	.dapm_routes		= msm8916_wcd_digital_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(msm8916_wcd_digital_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config msm8916_codec_regmap_config = {
@@ -915,7 +917,7 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev)
 
 	dev_set_drvdata(dev, priv);
 
-	return snd_soc_register_codec(dev, &msm8916_wcd_digital,
+	return devm_snd_soc_register_component(dev, &msm8916_wcd_digital,
 				      msm8916_wcd_digital_dai,
 				      ARRAY_SIZE(msm8916_wcd_digital_dai));
 }
@@ -924,7 +926,6 @@ static int msm8916_wcd_digital_remove(struct platform_device *pdev)
 {
 	struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(&pdev->dev);
 
-	snd_soc_unregister_codec(&pdev->dev);
 	clk_disable_unprepare(priv->mclk);
 	clk_disable_unprepare(priv->ahbclk);
 
diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c
index b08fb7e..17104f8 100644
--- a/sound/soc/codecs/nau8540.c
+++ b/sound/soc/codecs/nau8540.c
@@ -236,8 +236,8 @@ static const struct snd_kcontrol_new digital_ch1_mux =
 static int adc_power_control(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *k, int  event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
 	if (SND_SOC_DAPM_EVENT_ON(event)) {
 		msleep(300);
@@ -258,8 +258,8 @@ static int adc_power_control(struct snd_soc_dapm_widget *w,
 static int aiftx_power_control(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *k, int  event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
 	if (SND_SOC_DAPM_EVENT_OFF(event)) {
 		regmap_write(nau8540->regmap, NAU8540_REG_RST, 0x0001);
@@ -379,8 +379,8 @@ static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr)
 static int nau8540_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, osr;
 
 	/* CLK_ADC = OSR * FS
@@ -422,8 +422,8 @@ static int nau8540_hw_params(struct snd_pcm_substream *substream,
 
 static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 	unsigned int ctrl1_val = 0, ctrl2_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -493,8 +493,8 @@ static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int nau8540_set_tdm_slot(struct snd_soc_dai *dai,
 	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 	unsigned int ctrl2_val = 0, ctrl4_val = 0;
 
 	if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf)))
@@ -649,10 +649,10 @@ static void nau8540_fll_apply(struct regmap *regmap,
 }
 
 /* freq_out must be 256*Fs in order to achieve the best performance */
-static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+static int nau8540_set_pll(struct snd_soc_component *component, int pll_id, int source,
 		unsigned int freq_in, unsigned int freq_out)
 {
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 	struct nau8540_fll fll_param;
 	int ret, fs;
 
@@ -702,10 +702,10 @@ static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
 	return 0;
 }
 
-static int nau8540_set_sysclk(struct snd_soc_codec *codec,
+static int nau8540_set_sysclk(struct snd_soc_component *component,
 	int clk_id, int source, unsigned int freq, int dir)
 {
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case NAU8540_CLK_DIS:
@@ -777,9 +777,9 @@ static void nau8540_init_regs(struct nau8540 *nau8540)
 		NAU8540_I2S_DO34_TRI, NAU8540_I2S_DO34_TRI);
 }
 
-static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec)
+static int __maybe_unused nau8540_suspend(struct snd_soc_component *component)
 {
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(nau8540->regmap, true);
 	regcache_mark_dirty(nau8540->regmap);
@@ -787,9 +787,9 @@ static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec)
+static int __maybe_unused nau8540_resume(struct snd_soc_component *component)
 {
-	struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(nau8540->regmap, false);
 	regcache_sync(nau8540->regmap);
@@ -797,21 +797,22 @@ static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver nau8540_codec_driver = {
-	.set_sysclk = nau8540_set_sysclk,
-	.set_pll = nau8540_set_pll,
-	.suspend = nau8540_suspend,
-	.resume = nau8540_resume,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls = nau8540_snd_controls,
-		.num_controls = ARRAY_SIZE(nau8540_snd_controls),
-		.dapm_widgets = nau8540_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(nau8540_dapm_widgets),
-		.dapm_routes = nau8540_dapm_routes,
-		.num_dapm_routes = ARRAY_SIZE(nau8540_dapm_routes),
-	},
+static const struct snd_soc_component_driver nau8540_component_driver = {
+	.set_sysclk		= nau8540_set_sysclk,
+	.set_pll		= nau8540_set_pll,
+	.suspend		= nau8540_suspend,
+	.resume			= nau8540_resume,
+	.controls		= nau8540_snd_controls,
+	.num_controls		= ARRAY_SIZE(nau8540_snd_controls),
+	.dapm_widgets		= nau8540_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(nau8540_dapm_widgets),
+	.dapm_routes		= nau8540_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(nau8540_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config nau8540_regmap_config = {
@@ -856,17 +857,10 @@ static int nau8540_i2c_probe(struct i2c_client *i2c,
 	nau8540_reset_chip(nau8540->regmap);
 	nau8540_init_regs(nau8540);
 
-	return snd_soc_register_codec(dev,
-		&nau8540_codec_driver, &nau8540_dai, 1);
+	return devm_snd_soc_register_component(dev,
+		&nau8540_component_driver, &nau8540_dai, 1);
 }
 
-static int nau8540_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
-
 static const struct i2c_device_id nau8540_i2c_ids[] = {
 	{ "nau8540", 0 },
 	{ }
@@ -887,7 +881,6 @@ static struct i2c_driver nau8540_i2c_driver = {
 		.of_match_table = of_match_ptr(nau8540_of_ids),
 	},
 	.probe = nau8540_i2c_probe,
-	.remove = nau8540_i2c_remove,
 	.id_table = nau8540_i2c_ids,
 };
 module_i2c_driver(nau8540_i2c_driver);
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c
index c8e2451..ca2ba1c 100644
--- a/sound/soc/codecs/nau8810.c
+++ b/sound/soc/codecs/nau8810.c
@@ -167,8 +167,8 @@ static bool nau8810_volatile_reg(struct device *dev, unsigned int reg)
 static int nau8810_eq_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 	struct soc_bytes_ext *params = (void *)kcontrol->private_value;
 	int i, reg, reg_val;
 	u16 *val;
@@ -198,8 +198,8 @@ static int nau8810_eq_get(struct snd_kcontrol *kcontrol,
 static int nau8810_eq_put(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 	struct soc_bytes_ext *params = (void *)kcontrol->private_value;
 	void *data;
 	u16 *val, value;
@@ -219,7 +219,7 @@ static int nau8810_eq_put(struct snd_kcontrol *kcontrol,
 		value = be16_to_cpu(*(val + i));
 		ret = regmap_write(nau8810->regmap, reg + i, value);
 		if (ret) {
-			dev_err(codec->dev, "EQ configuration fail, register: %x ret: %d\n",
+			dev_err(component->dev, "EQ configuration fail, register: %x ret: %d\n",
 				reg + i, ret);
 			kfree(data);
 			return ret;
@@ -399,8 +399,8 @@ static const struct snd_kcontrol_new nau8810_loopback =
 static int check_mclk_select_pll(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 	unsigned int value;
 
 	regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &value);
@@ -485,8 +485,8 @@ static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
 static int nau8810_set_sysclk(struct snd_soc_dai *dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 
 	nau8810->clk_id = clk_id;
 	nau8810->sysclk = freq;
@@ -538,8 +538,8 @@ static int nau88l0_calc_pll(unsigned int pll_in,
 static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 	struct regmap *map = nau8810->regmap;
 	struct nau8810_pll *pll_param = &nau8810->pll;
 	int ret, fs;
@@ -577,8 +577,8 @@ static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int nau8810_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 	u16 ctrl1_val = 0, ctrl2_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -667,8 +667,8 @@ static int nau8810_mclk_clkdiv(struct nau8810 *nau8810, int rate)
 static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 	int val_len = 0, val_rate = 0, ret = 0;
 
 	switch (params_width(params)) {
@@ -723,10 +723,10 @@ static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream,
 	return ret;
 }
 
-static int nau8810_set_bias_level(struct snd_soc_codec *codec,
+static int nau8810_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+	struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 	struct regmap *map = nau8810->regmap;
 
 	switch (level) {
@@ -741,7 +741,7 @@ static int nau8810_set_bias_level(struct snd_soc_codec *codec,
 			NAU8810_IOBUF_EN | NAU8810_ABIAS_EN,
 			NAU8810_IOBUF_EN | NAU8810_ABIAS_EN);
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_sync(map);
 			regmap_update_bits(map, NAU8810_REG_POWER1,
 				NAU8810_REFIMP_MASK, NAU8810_REFIMP_3K);
@@ -808,18 +808,19 @@ static const struct regmap_config nau8810_regmap_config = {
 	.num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults),
 };
 
-static const struct snd_soc_codec_driver nau8810_codec_driver = {
-	.set_bias_level = nau8810_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls = nau8810_snd_controls,
-		.num_controls = ARRAY_SIZE(nau8810_snd_controls),
-		.dapm_widgets = nau8810_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(nau8810_dapm_widgets),
-		.dapm_routes = nau8810_dapm_routes,
-		.num_dapm_routes = ARRAY_SIZE(nau8810_dapm_routes),
-	},
+static const struct snd_soc_component_driver nau8810_component_driver = {
+	.set_bias_level		= nau8810_set_bias_level,
+	.controls		= nau8810_snd_controls,
+	.num_controls		= ARRAY_SIZE(nau8810_snd_controls),
+	.dapm_widgets		= nau8810_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(nau8810_dapm_widgets),
+	.dapm_routes		= nau8810_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(nau8810_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int nau8810_i2c_probe(struct i2c_client *i2c,
@@ -842,15 +843,8 @@ static int nau8810_i2c_probe(struct i2c_client *i2c,
 
 	regmap_write(nau8810->regmap, NAU8810_REG_RESET, 0x00);
 
-	return snd_soc_register_codec(dev,
-		&nau8810_codec_driver, &nau8810_dai, 1);
-}
-
-static int nau8810_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
+	return devm_snd_soc_register_component(dev,
+		&nau8810_component_driver, &nau8810_dai, 1);
 }
 
 static const struct i2c_device_id nau8810_i2c_id[] = {
@@ -873,7 +867,6 @@ static struct i2c_driver nau8810_i2c_driver = {
 		.of_match_table = of_match_ptr(nau8810_of_match),
 	},
 	.probe =    nau8810_i2c_probe,
-	.remove =   nau8810_i2c_remove,
 	.id_table = nau8810_i2c_id,
 };
 
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c
index 088e0ce..637e952 100644
--- a/sound/soc/codecs/nau8824.c
+++ b/sound/soc/codecs/nau8824.c
@@ -414,8 +414,8 @@ static const struct snd_kcontrol_new nau8824_snd_controls[] = {
 static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -437,8 +437,8 @@ static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w,
 static int nau8824_spk_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -461,8 +461,8 @@ static int nau8824_spk_event(struct snd_soc_dapm_widget *w,
 static int nau8824_pump_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -487,10 +487,14 @@ static int nau8824_pump_event(struct snd_soc_dapm_widget *w,
 static int system_clock_control(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *k, int  event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
+	struct regmap *regmap = nau8824->regmap;
+	unsigned int value;
+	bool clk_fll, error;
 
 	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		dev_dbg(nau8824->dev, "system clock control : POWER OFF\n");
 		/* Set clock source to disable or internal clock before the
 		 * playback or capture end. Codec needs clock for Jack
 		 * detection and button press if jack inserted; otherwise,
@@ -502,15 +506,48 @@ static int system_clock_control(struct snd_soc_dapm_widget *w,
 		} else {
 			nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0);
 		}
+	} else {
+		dev_dbg(nau8824->dev, "system clock control : POWER ON\n");
+		/* Check the clock source setting is proper or not
+		 * no matter the source is from FLL or MCLK.
+		 */
+		regmap_read(regmap, NAU8824_REG_FLL1, &value);
+		clk_fll = value & NAU8824_FLL_RATIO_MASK;
+		/* It's error to use internal clock when playback */
+		regmap_read(regmap, NAU8824_REG_FLL6, &value);
+		error = value & NAU8824_DCO_EN;
+		if (!error) {
+			/* Check error depending on source is FLL or MCLK. */
+			regmap_read(regmap, NAU8824_REG_CLK_DIVIDER, &value);
+			if (clk_fll)
+				error = !(value & NAU8824_CLK_SRC_VCO);
+			else
+				error = value & NAU8824_CLK_SRC_VCO;
+		}
+		/* Recover the clock source setting if error. */
+		if (error) {
+			if (clk_fll) {
+				regmap_update_bits(regmap,
+					NAU8824_REG_FLL6, NAU8824_DCO_EN, 0);
+				regmap_update_bits(regmap,
+					NAU8824_REG_CLK_DIVIDER,
+					NAU8824_CLK_SRC_MASK,
+					NAU8824_CLK_SRC_VCO);
+			} else {
+				nau8824_config_sysclk(nau8824,
+					NAU8824_CLK_MCLK, 0);
+			}
+		}
 	}
+
 	return 0;
 }
 
 static int dmic_clock_control(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *k, int  event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 	int src;
 
 	/* The DMIC clock is gotten from system clock (256fs) divided by
@@ -591,7 +628,8 @@ static const struct snd_kcontrol_new nau8824_dacr_mux =
 
 static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY("System Clock", SND_SOC_NOPM, 0, 0,
-			system_clock_control, SND_SOC_DAPM_POST_PMD),
+		system_clock_control, SND_SOC_DAPM_POST_PMD |
+		SND_SOC_DAPM_POST_PMU),
 
 	SND_SOC_DAPM_INPUT("HSMIC1"),
 	SND_SOC_DAPM_INPUT("HSMIC2"),
@@ -988,8 +1026,8 @@ static int nau8824_clock_check(struct nau8824 *nau8824,
 static int nau8824_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
 
 	nau8824_sema_acquire(nau8824, HZ);
@@ -1072,8 +1110,8 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
 
 static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 	unsigned int ctrl1_val = 0, ctrl2_val = 0;
 
 	nau8824_sema_acquire(nau8824, HZ);
@@ -1149,8 +1187,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int nau8824_set_tdm_slot(struct snd_soc_dai *dai,
 	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 	unsigned int tslot_l = 0, ctrl_val = 0;
 
 	if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf)) ||
@@ -1288,10 +1326,10 @@ static void nau8824_fll_apply(struct regmap *regmap,
 }
 
 /* freq_out must be 256*Fs in order to achieve the best performance */
-static int nau8824_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+static int nau8824_set_pll(struct snd_soc_component *component, int pll_id, int source,
 		unsigned int freq_in, unsigned int freq_out)
 {
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 	struct nau8824_fll fll_param;
 	int ret, fs;
 
@@ -1374,10 +1412,10 @@ static int nau8824_config_sysclk(struct nau8824 *nau8824,
 	return 0;
 }
 
-static int nau8824_set_sysclk(struct snd_soc_codec *codec,
+static int nau8824_set_sysclk(struct snd_soc_component *component,
 	int clk_id, int source, unsigned int freq, int dir)
 {
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
 	return nau8824_config_sysclk(nau8824, clk_id, freq);
 }
@@ -1403,10 +1441,10 @@ static void nau8824_resume_setup(struct nau8824 *nau8824)
 	}
 }
 
-static int nau8824_set_bias_level(struct snd_soc_codec *codec,
+static int nau8824_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -1416,7 +1454,7 @@ static int nau8824_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Setup codec configuration after resume */
 			nau8824_resume_setup(nau8824);
 		}
@@ -1434,23 +1472,23 @@ static int nau8824_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int nau8824_codec_probe(struct snd_soc_codec *codec)
+static int nau8824_component_probe(struct snd_soc_component *component)
 {
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	nau8824->dapm = dapm;
 
 	return 0;
 }
 
-static int __maybe_unused nau8824_suspend(struct snd_soc_codec *codec)
+static int __maybe_unused nau8824_suspend(struct snd_soc_component *component)
 {
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
 	if (nau8824->irq) {
 		disable_irq(nau8824->irq);
-		snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+		snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 	}
 	regcache_cache_only(nau8824->regmap, true);
 	regcache_mark_dirty(nau8824->regmap);
@@ -1458,9 +1496,9 @@ static int __maybe_unused nau8824_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec)
+static int __maybe_unused nau8824_resume(struct snd_soc_component *component)
 {
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(nau8824->regmap, false);
 	regcache_sync(nau8824->regmap);
@@ -1475,23 +1513,24 @@ static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver nau8824_codec_driver = {
-	.probe = nau8824_codec_probe,
-	.set_sysclk = nau8824_set_sysclk,
-	.set_pll = nau8824_set_pll,
-	.set_bias_level = nau8824_set_bias_level,
-	.suspend = nau8824_suspend,
-	.resume = nau8824_resume,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls = nau8824_snd_controls,
-		.num_controls = ARRAY_SIZE(nau8824_snd_controls),
-		.dapm_widgets = nau8824_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(nau8824_dapm_widgets),
-		.dapm_routes = nau8824_dapm_routes,
-		.num_dapm_routes = ARRAY_SIZE(nau8824_dapm_routes),
-	},
+static const struct snd_soc_component_driver nau8824_component_driver = {
+	.probe			= nau8824_component_probe,
+	.set_sysclk		= nau8824_set_sysclk,
+	.set_pll		= nau8824_set_pll,
+	.set_bias_level		= nau8824_set_bias_level,
+	.suspend		= nau8824_suspend,
+	.resume			= nau8824_resume,
+	.controls		= nau8824_snd_controls,
+	.num_controls		= ARRAY_SIZE(nau8824_snd_controls),
+	.dapm_widgets		= nau8824_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(nau8824_dapm_widgets),
+	.dapm_routes		= nau8824_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(nau8824_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct snd_soc_dai_ops nau8824_dai_ops = {
@@ -1547,10 +1586,10 @@ static const struct regmap_config nau8824_regmap_config = {
  * events will be routed to the given jack.  Jack can be null to stop
  * reporting.
  */
-int nau8824_enable_jack_detect(struct snd_soc_codec *codec,
+int nau8824_enable_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *jack)
 {
-	struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+	struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	nau8824->jack = jack;
@@ -1838,15 +1877,8 @@ static int nau8824_i2c_probe(struct i2c_client *i2c,
 	if (i2c->irq)
 		nau8824_setup_irq(nau8824);
 
-	return snd_soc_register_codec(dev,
-		&nau8824_codec_driver, &nau8824_dai, 1);
-}
-
-
-static int nau8824_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
+	return devm_snd_soc_register_component(dev,
+		&nau8824_component_driver, &nau8824_dai, 1);
 }
 
 static const struct i2c_device_id nau8824_i2c_ids[] = {
@@ -1878,7 +1910,6 @@ static struct i2c_driver nau8824_i2c_driver = {
 		.acpi_match_table = ACPI_PTR(nau8824_acpi_match),
 	},
 	.probe = nau8824_i2c_probe,
-	.remove = nau8824_i2c_remove,
 	.id_table = nau8824_i2c_ids,
 };
 module_i2c_driver(nau8824_i2c_driver);
diff --git a/sound/soc/codecs/nau8824.h b/sound/soc/codecs/nau8824.h
index 21eae24..6184a2b 100644
--- a/sound/soc/codecs/nau8824.h
+++ b/sound/soc/codecs/nau8824.h
@@ -471,7 +471,7 @@ struct nau8824_osr_attr {
 };
 
 
-int nau8824_enable_jack_detect(struct snd_soc_codec *codec,
+int nau8824_enable_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *jack);
 
 #endif				/* _NAU8824_H */
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index a1b697b..dc6ea49 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -914,8 +914,8 @@ static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
 static int nau8825_adc_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -938,8 +938,8 @@ static int nau8825_adc_event(struct snd_soc_dapm_widget *w,
 static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -962,8 +962,8 @@ static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
 static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -1244,8 +1244,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
 
 	nau8825_sema_acquire(nau8825, 3 * HZ);
@@ -1329,8 +1329,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
 
 static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 	unsigned int ctrl1_val = 0, ctrl2_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1427,10 +1427,10 @@ static struct snd_soc_dai_driver nau8825_dai = {
  * events will be routed to the given jack.  Jack can be null to stop
  * reporting.
  */
-int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
+int nau8825_enable_jack_detect(struct snd_soc_component *component,
 				struct snd_soc_jack *jack)
 {
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 	struct regmap *regmap = nau8825->regmap;
 
 	nau8825->jack = jack;
@@ -1952,24 +1952,22 @@ static const struct regmap_config nau8825_regmap_config = {
 	.num_reg_defaults = ARRAY_SIZE(nau8825_reg_defaults),
 };
 
-static int nau8825_codec_probe(struct snd_soc_codec *codec)
+static int nau8825_component_probe(struct snd_soc_component *component)
 {
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	nau8825->dapm = dapm;
 
 	return 0;
 }
 
-static int nau8825_codec_remove(struct snd_soc_codec *codec)
+static void nau8825_component_remove(struct snd_soc_component *component)
 {
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
 	/* Cancel and reset cross tak suppresstion detection funciton */
 	nau8825_xtalk_cancel(nau8825);
-
-	return 0;
 }
 
 /**
@@ -2084,20 +2082,20 @@ static void nau8825_fll_apply(struct nau8825 *nau8825,
 }
 
 /* freq_out must be 256*Fs in order to achieve the best performance */
-static int nau8825_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+static int nau8825_set_pll(struct snd_soc_component *component, int pll_id, int source,
 		unsigned int freq_in, unsigned int freq_out)
 {
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 	struct nau8825_fll fll_param;
 	int ret, fs;
 
 	fs = freq_out / 256;
 	ret = nau8825_calc_fll_param(freq_in, fs, &fll_param);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupported input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupported input clock %d\n", freq_in);
 		return ret;
 	}
-	dev_dbg(codec->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
+	dev_dbg(component->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
 		fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
 		fll_param.fll_int, fll_param.clk_ref_div);
 
@@ -2298,10 +2296,10 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
 	return 0;
 }
 
-static int nau8825_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int nau8825_set_sysclk(struct snd_soc_component *component, int clk_id,
 	int source, unsigned int freq, int dir)
 {
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
 	return nau8825_configure_sysclk(nau8825, clk_id, freq);
 }
@@ -2331,10 +2329,10 @@ static int nau8825_resume_setup(struct nau8825 *nau8825)
 	return 0;
 }
 
-static int nau8825_set_bias_level(struct snd_soc_codec *codec,
+static int nau8825_set_bias_level(struct snd_soc_component *component,
 				   enum snd_soc_bias_level level)
 {
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -2345,11 +2343,11 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			if (nau8825->mclk_freq) {
 				ret = clk_prepare_enable(nau8825->mclk);
 				if (ret) {
-					dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
+					dev_err(nau8825->dev, "Unable to prepare component mclk\n");
 					return ret;
 				}
 			}
@@ -2383,12 +2381,12 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
+static int __maybe_unused nau8825_suspend(struct snd_soc_component *component)
 {
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
 	disable_irq(nau8825->irq);
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 	/* Power down codec power; don't suppoet button wakeup */
 	snd_soc_dapm_disable_pin(nau8825->dapm, "SAR");
 	snd_soc_dapm_disable_pin(nau8825->dapm, "MICBIAS");
@@ -2399,9 +2397,9 @@ static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
+static int __maybe_unused nau8825_resume(struct snd_soc_component *component)
 {
-	struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+	struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	regcache_cache_only(nau8825->regmap, false);
@@ -2415,24 +2413,25 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver nau8825_codec_driver = {
-	.probe = nau8825_codec_probe,
-	.remove = nau8825_codec_remove,
-	.set_sysclk = nau8825_set_sysclk,
-	.set_pll = nau8825_set_pll,
-	.set_bias_level = nau8825_set_bias_level,
-	.suspend_bias_off = true,
-	.suspend = nau8825_suspend,
-	.resume = nau8825_resume,
-
-	.component_driver = {
-		.controls		= nau8825_controls,
-		.num_controls		= ARRAY_SIZE(nau8825_controls),
-		.dapm_widgets		= nau8825_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(nau8825_dapm_widgets),
-		.dapm_routes		= nau8825_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(nau8825_dapm_routes),
-	},
+static const struct snd_soc_component_driver nau8825_component_driver = {
+	.probe			= nau8825_component_probe,
+	.remove			= nau8825_component_remove,
+	.set_sysclk		= nau8825_set_sysclk,
+	.set_pll		= nau8825_set_pll,
+	.set_bias_level		= nau8825_set_bias_level,
+	.suspend		= nau8825_suspend,
+	.resume			= nau8825_resume,
+	.controls		= nau8825_controls,
+	.num_controls		= ARRAY_SIZE(nau8825_controls),
+	.dapm_widgets		= nau8825_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(nau8825_dapm_widgets),
+	.dapm_routes		= nau8825_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(nau8825_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static void nau8825_reset_chip(struct regmap *regmap)
@@ -2619,13 +2618,13 @@ static int nau8825_i2c_probe(struct i2c_client *i2c,
 	if (i2c->irq)
 		nau8825_setup_irq(nau8825);
 
-	return snd_soc_register_codec(&i2c->dev, &nau8825_codec_driver,
+	return devm_snd_soc_register_component(&i2c->dev,
+		&nau8825_component_driver,
 		&nau8825_dai, 1);
 }
 
 static int nau8825_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h
index f7e7321..f6074c6 100644
--- a/sound/soc/codecs/nau8825.h
+++ b/sound/soc/codecs/nau8825.h
@@ -480,7 +480,7 @@ struct nau8825 {
 	bool xtalk_baktab_initialized; /* True if initialized. */
 };
 
-int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
+int nau8825_enable_jack_detect(struct snd_soc_component *component,
 				struct snd_soc_jack *jack);
 
 
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c
index c7e28dd..84777d3 100644
--- a/sound/soc/codecs/pcm1681.c
+++ b/sound/soc/codecs/pcm1681.c
@@ -90,9 +90,9 @@ struct pcm1681_private {
 
 static const int pcm1681_deemph[] = { 44100, 48000, 32000 };
 
-static int pcm1681_set_deemph(struct snd_soc_codec *codec)
+static int pcm1681_set_deemph(struct snd_soc_component *component)
 {
-	struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 	int i = 0, val = -1, enable = 0;
 
 	if (priv->deemph) {
@@ -120,8 +120,8 @@ static int pcm1681_set_deemph(struct snd_soc_codec *codec)
 static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = priv->deemph;
 
@@ -131,23 +131,23 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol,
 static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 
 	priv->deemph = ucontrol->value.integer.value[0];
 
-	return pcm1681_set_deemph(codec);
+	return pcm1681_set_deemph(component);
 }
 
 static int pcm1681_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 
 	/* The PCM1681 can only be slave to all clocks */
 	if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-		dev_err(codec->dev, "Invalid clocking mode\n");
+		dev_err(component->dev, "Invalid clocking mode\n");
 		return -EINVAL;
 	}
 
@@ -158,8 +158,8 @@ static int pcm1681_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int pcm1681_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 	int val;
 
 	if (mute)
@@ -174,8 +174,8 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 	int val = 0, ret;
 
 	priv->rate = params_rate(params);
@@ -200,7 +200,7 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream,
 		val = 0x05;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI format\n");
+		dev_err(component->dev, "Invalid DAI format\n");
 		return -EINVAL;
 	}
 
@@ -208,7 +208,7 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream,
 	if (ret < 0)
 		return ret;
 
-	return pcm1681_set_deemph(codec);
+	return pcm1681_set_deemph(component);
 }
 
 static const struct snd_soc_dai_ops pcm1681_dai_ops = {
@@ -288,15 +288,17 @@ static const struct regmap_config pcm1681_regmap = {
 	.readable_reg		= pcm1681_accessible_reg,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_pcm1681 = {
-	.component_driver = {
-		.controls		= pcm1681_controls,
-		.num_controls		= ARRAY_SIZE(pcm1681_controls),
-		.dapm_widgets		= pcm1681_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(pcm1681_dapm_widgets),
-		.dapm_routes		= pcm1681_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(pcm1681_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_pcm1681 = {
+	.controls		= pcm1681_controls,
+	.num_controls		= ARRAY_SIZE(pcm1681_controls),
+	.dapm_widgets		= pcm1681_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pcm1681_dapm_widgets),
+	.dapm_routes		= pcm1681_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pcm1681_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct i2c_device_id pcm1681_i2c_id[] = {
@@ -324,16 +326,11 @@ static int pcm1681_i2c_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, priv);
 
-	return snd_soc_register_codec(&client->dev, &soc_codec_dev_pcm1681,
+	return devm_snd_soc_register_component(&client->dev,
+		&soc_component_dev_pcm1681,
 		&pcm1681_dai, 1);
 }
 
-static int pcm1681_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static struct i2c_driver pcm1681_i2c_driver = {
 	.driver = {
 		.name	= "pcm1681",
@@ -341,7 +338,6 @@ static struct i2c_driver pcm1681_i2c_driver = {
 	},
 	.id_table	= pcm1681_i2c_id,
 	.probe		= pcm1681_i2c_probe,
-	.remove		= pcm1681_i2c_remove,
 };
 
 module_i2c_driver(pcm1681_i2c_driver);
diff --git a/sound/soc/codecs/pcm1789-i2c.c b/sound/soc/codecs/pcm1789-i2c.c
new file mode 100644
index 0000000..327ec58
--- /dev/null
+++ b/sound/soc/codecs/pcm1789-i2c.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+// Audio driver for PCM1789 I2C
+// Copyright (C) 2018 Bootlin
+// Mylène Josserand <mylene.josserand@bootlin.com>
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#include "pcm1789.h"
+
+static int pcm1789_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	int ret;
+
+	regmap = devm_regmap_init_i2c(client, &pcm1789_regmap_config);
+	if (IS_ERR(regmap)) {
+		ret = PTR_ERR(regmap);
+		dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);
+		return ret;
+	}
+
+	return pcm1789_common_init(&client->dev, regmap);
+}
+
+static int pcm1789_i2c_remove(struct i2c_client *client)
+{
+	return pcm1789_common_exit(&client->dev);
+}
+
+static const struct of_device_id pcm1789_of_match[] = {
+	{ .compatible = "ti,pcm1789", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pcm1789_of_match);
+
+static const struct i2c_device_id pcm1789_i2c_ids[] = {
+	{ "pcm1789", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, pcm1789_i2c_ids);
+
+static struct i2c_driver pcm1789_i2c_driver = {
+	.driver = {
+		.name	= "pcm1789",
+		.of_match_table = of_match_ptr(pcm1789_of_match),
+	},
+	.id_table	= pcm1789_i2c_ids,
+	.probe		= pcm1789_i2c_probe,
+	.remove	= pcm1789_i2c_remove,
+};
+
+module_i2c_driver(pcm1789_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC PCM1789 I2C driver");
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@bootlin.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm1789.c b/sound/soc/codecs/pcm1789.c
new file mode 100644
index 0000000..507ac94
--- /dev/null
+++ b/sound/soc/codecs/pcm1789.c
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0
+// Audio driver for PCM1789
+// Copyright (C) 2018 Bootlin
+// Mylène Josserand <mylene.josserand@bootlin.com>
+
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "pcm1789.h"
+
+#define PCM1789_MUTE_CONTROL	0x10
+#define PCM1789_FMT_CONTROL	0x11
+#define PCM1789_SOFT_MUTE	0x14
+#define PCM1789_DAC_VOL_LEFT	0x18
+#define PCM1789_DAC_VOL_RIGHT	0x19
+
+#define PCM1789_FMT_MASK	0x07
+#define PCM1789_MUTE_MASK	0x03
+#define PCM1789_MUTE_SRET	0x06
+
+struct pcm1789_private {
+	struct regmap *regmap;
+	unsigned int format;
+	unsigned int rate;
+	struct gpio_desc *reset;
+	struct work_struct work;
+	struct device *dev;
+};
+
+static const struct reg_default pcm1789_reg_defaults[] = {
+	{ PCM1789_FMT_CONTROL, 0x00 },
+	{ PCM1789_SOFT_MUTE, 0x00 },
+	{ PCM1789_DAC_VOL_LEFT, 0xff },
+	{ PCM1789_DAC_VOL_RIGHT, 0xff },
+};
+
+static bool pcm1789_accessible_reg(struct device *dev, unsigned int reg)
+{
+	return reg >= PCM1789_MUTE_CONTROL && reg <= PCM1789_DAC_VOL_RIGHT;
+}
+
+static bool pcm1789_writeable_reg(struct device *dev, unsigned int reg)
+{
+	return pcm1789_accessible_reg(dev, reg);
+}
+
+static int pcm1789_set_dai_fmt(struct snd_soc_dai *codec_dai,
+			       unsigned int format)
+{
+	struct snd_soc_component *component = codec_dai->component;
+	struct pcm1789_private *priv = snd_soc_component_get_drvdata(component);
+
+	priv->format = format;
+
+	return 0;
+}
+
+static int pcm1789_digital_mute(struct snd_soc_dai *codec_dai, int mute)
+{
+	struct snd_soc_component *component = codec_dai->component;
+	struct pcm1789_private *priv = snd_soc_component_get_drvdata(component);
+
+	return regmap_update_bits(priv->regmap, PCM1789_SOFT_MUTE,
+				  PCM1789_MUTE_MASK,
+				  mute ? 0 : PCM1789_MUTE_MASK);
+}
+
+static int pcm1789_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params,
+			     struct snd_soc_dai *codec_dai)
+{
+	struct snd_soc_component *component = codec_dai->component;
+	struct pcm1789_private *priv = snd_soc_component_get_drvdata(component);
+	int val = 0, ret;
+
+	priv->rate = params_rate(params);
+
+	switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_RIGHT_J:
+		switch (params_width(params)) {
+		case 24:
+			val = 2;
+			break;
+		case 16:
+			val = 3;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		switch (params_width(params)) {
+		case 16:
+		case 24:
+		case 32:
+			val = 0;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		switch (params_width(params)) {
+		case 16:
+		case 24:
+		case 32:
+			val = 1;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		dev_err(component->dev, "Invalid DAI format\n");
+		return -EINVAL;
+	}
+
+	ret = regmap_update_bits(priv->regmap, PCM1789_FMT_CONTROL,
+				 PCM1789_FMT_MASK, val);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void pcm1789_work_queue(struct work_struct *work)
+{
+	struct pcm1789_private *priv = container_of(work,
+						    struct pcm1789_private,
+						    work);
+
+	/* Perform a software reset to remove codec from desynchronized state */
+	if (regmap_update_bits(priv->regmap, PCM1789_MUTE_CONTROL,
+			       0x3 << PCM1789_MUTE_SRET, 0) < 0)
+		dev_err(priv->dev, "Error while setting SRET");
+}
+
+static int pcm1789_trigger(struct snd_pcm_substream *substream, int cmd,
+			   struct snd_soc_dai *dai)
+{
+	struct snd_soc_component *component = dai->component;
+	struct pcm1789_private *priv = snd_soc_component_get_drvdata(component);
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		schedule_work(&priv->work);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static const struct snd_soc_dai_ops pcm1789_dai_ops = {
+	.set_fmt	= pcm1789_set_dai_fmt,
+	.hw_params	= pcm1789_hw_params,
+	.digital_mute	= pcm1789_digital_mute,
+	.trigger	= pcm1789_trigger,
+};
+
+static const DECLARE_TLV_DB_SCALE(pcm1789_dac_tlv, -12000, 50, 1);
+
+static const struct snd_kcontrol_new pcm1789_controls[] = {
+	SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1789_DAC_VOL_LEFT,
+			       PCM1789_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0,
+			       pcm1789_dac_tlv),
+};
+
+static const struct snd_soc_dapm_widget pcm1789_dapm_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("IOUTL+"),
+	SND_SOC_DAPM_OUTPUT("IOUTL-"),
+	SND_SOC_DAPM_OUTPUT("IOUTR+"),
+	SND_SOC_DAPM_OUTPUT("IOUTR-"),
+};
+
+static const struct snd_soc_dapm_route pcm1789_dapm_routes[] = {
+	{ "IOUTL+", NULL, "Playback" },
+	{ "IOUTL-", NULL, "Playback" },
+	{ "IOUTR+", NULL, "Playback" },
+	{ "IOUTR-", NULL, "Playback" },
+};
+
+static struct snd_soc_dai_driver pcm1789_dai = {
+	.name = "pcm1789-hifi",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
+		.rate_min = 10000,
+		.rate_max = 200000,
+		.formats = PCM1789_FORMATS,
+	},
+	.ops = &pcm1789_dai_ops,
+};
+
+const struct regmap_config pcm1789_regmap_config = {
+	.reg_bits		= 8,
+	.val_bits		= 8,
+	.max_register		= PCM1789_DAC_VOL_RIGHT,
+	.reg_defaults		= pcm1789_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(pcm1789_reg_defaults),
+	.writeable_reg		= pcm1789_writeable_reg,
+	.readable_reg		= pcm1789_accessible_reg,
+};
+EXPORT_SYMBOL_GPL(pcm1789_regmap_config);
+
+static const struct snd_soc_component_driver soc_component_dev_pcm1789 = {
+	.controls		= pcm1789_controls,
+	.num_controls		= ARRAY_SIZE(pcm1789_controls),
+	.dapm_widgets		= pcm1789_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pcm1789_dapm_widgets),
+	.dapm_routes		= pcm1789_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pcm1789_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
+
+int pcm1789_common_init(struct device *dev, struct regmap *regmap)
+{
+	struct pcm1789_private *pcm1789;
+
+	pcm1789 = devm_kzalloc(dev, sizeof(struct pcm1789_private),
+			       GFP_KERNEL);
+	if (!pcm1789)
+		return -ENOMEM;
+
+	pcm1789->regmap = regmap;
+	pcm1789->dev = dev;
+	dev_set_drvdata(dev, pcm1789);
+
+	pcm1789->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(pcm1789->reset))
+		return PTR_ERR(pcm1789->reset);
+
+	gpiod_set_value_cansleep(pcm1789->reset, 0);
+	msleep(300);
+
+	INIT_WORK(&pcm1789->work, pcm1789_work_queue);
+
+	return devm_snd_soc_register_component(dev, &soc_component_dev_pcm1789,
+					       &pcm1789_dai, 1);
+}
+EXPORT_SYMBOL_GPL(pcm1789_common_init);
+
+int pcm1789_common_exit(struct device *dev)
+{
+	struct pcm1789_private *priv = dev_get_drvdata(dev);
+
+	if (&priv->work)
+		flush_work(&priv->work);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pcm1789_common_exit);
+
+MODULE_DESCRIPTION("ASoC PCM1789 driver");
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm1789.h b/sound/soc/codecs/pcm1789.h
new file mode 100644
index 0000000..c446d78
--- /dev/null
+++ b/sound/soc/codecs/pcm1789.h
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+// Definitions for PCM1789 audio driver
+// Copyright (C) 2018 Bootlin
+// Mylène Josserand <mylene.josserand@bootlin.com>
+
+#ifndef __PCM1789_H__
+#define __PCM1789_H__
+
+#define PCM1789_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
+			 SNDRV_PCM_FMTBIT_S16_LE)
+
+extern const struct regmap_config pcm1789_regmap_config;
+
+int pcm1789_common_init(struct device *dev, struct regmap *regmap);
+int pcm1789_common_exit(struct device *dev);
+
+#endif
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c
index 4118106..0374796 100644
--- a/sound/soc/codecs/pcm179x-i2c.c
+++ b/sound/soc/codecs/pcm179x-i2c.c
@@ -39,11 +39,6 @@ static int pcm179x_i2c_probe(struct i2c_client *client,
 	return pcm179x_common_init(&client->dev, regmap);
 }
 
-static int pcm179x_i2c_remove(struct i2c_client *client)
-{
-	return pcm179x_common_exit(&client->dev);
-}
-
 static const struct of_device_id pcm179x_of_match[] = {
 	{ .compatible = "ti,pcm1792a", },
 	{ }
@@ -63,7 +58,6 @@ static struct i2c_driver pcm179x_i2c_driver = {
 	},
 	.id_table	= pcm179x_i2c_ids,
 	.probe		= pcm179x_i2c_probe,
-	.remove		= pcm179x_i2c_remove,
 };
 
 module_i2c_driver(pcm179x_i2c_driver);
diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c
index da924d4..89ad715 100644
--- a/sound/soc/codecs/pcm179x-spi.c
+++ b/sound/soc/codecs/pcm179x-spi.c
@@ -38,11 +38,6 @@ static int pcm179x_spi_probe(struct spi_device *spi)
 	return pcm179x_common_init(&spi->dev, regmap);
 }
 
-static int pcm179x_spi_remove(struct spi_device *spi)
-{
-	return pcm179x_common_exit(&spi->dev);
-}
-
 static const struct of_device_id pcm179x_of_match[] = {
 	{ .compatible = "ti,pcm1792a", },
 	{ }
@@ -62,7 +57,6 @@ static struct spi_driver pcm179x_spi_driver = {
 	},
 	.id_table = pcm179x_spi_ids,
 	.probe = pcm179x_spi_probe,
-	.remove = pcm179x_spi_remove,
 };
 
 module_spi_driver(pcm179x_spi_driver);
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c
index 82a3d9d..4b311c0 100644
--- a/sound/soc/codecs/pcm179x.c
+++ b/sound/soc/codecs/pcm179x.c
@@ -77,8 +77,8 @@ struct pcm179x_private {
 static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct pcm179x_private *priv = snd_soc_component_get_drvdata(component);
 
 	priv->format = format;
 
@@ -87,8 +87,8 @@ static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int pcm179x_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm179x_private *priv = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regmap_update_bits(priv->regmap, PCM179X_SOFT_MUTE,
@@ -103,8 +103,8 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm179x_private *priv = snd_soc_component_get_drvdata(component);
 	int val = 0, ret;
 
 	priv->rate = params_rate(params);
@@ -137,7 +137,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream,
 		}
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI format\n");
+		dev_err(component->dev, "Invalid DAI format\n");
 		return -EINVAL;
 	}
 
@@ -205,15 +205,17 @@ const struct regmap_config pcm179x_regmap_config = {
 };
 EXPORT_SYMBOL_GPL(pcm179x_regmap_config);
 
-static const struct snd_soc_codec_driver soc_codec_dev_pcm179x = {
-	.component_driver = {
-		.controls		= pcm179x_controls,
-		.num_controls		= ARRAY_SIZE(pcm179x_controls),
-		.dapm_widgets		= pcm179x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(pcm179x_dapm_widgets),
-		.dapm_routes		= pcm179x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(pcm179x_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_pcm179x = {
+	.controls		= pcm179x_controls,
+	.num_controls		= ARRAY_SIZE(pcm179x_controls),
+	.dapm_widgets		= pcm179x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pcm179x_dapm_widgets),
+	.dapm_routes		= pcm179x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pcm179x_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 int pcm179x_common_init(struct device *dev, struct regmap *regmap)
@@ -228,18 +230,11 @@ int pcm179x_common_init(struct device *dev, struct regmap *regmap)
 	pcm179x->regmap = regmap;
 	dev_set_drvdata(dev, pcm179x);
 
-	return snd_soc_register_codec(dev,
-			&soc_codec_dev_pcm179x, &pcm179x_dai, 1);
+	return devm_snd_soc_register_component(dev,
+			&soc_component_dev_pcm179x, &pcm179x_dai, 1);
 }
 EXPORT_SYMBOL_GPL(pcm179x_common_init);
 
-int pcm179x_common_exit(struct device *dev)
-{
-	snd_soc_unregister_codec(dev);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pcm179x_common_exit);
-
 MODULE_DESCRIPTION("ASoC PCM179X driver");
 MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
 MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h
index 11e3312..cf8681c9 100644
--- a/sound/soc/codecs/pcm179x.h
+++ b/sound/soc/codecs/pcm179x.h
@@ -23,6 +23,5 @@
 extern const struct regmap_config pcm179x_regmap_config;
 
 int pcm179x_common_init(struct device *dev, struct regmap *regmap);
-int pcm179x_common_exit(struct device *dev);
 
 #endif
diff --git a/sound/soc/codecs/pcm186x-i2c.c b/sound/soc/codecs/pcm186x-i2c.c
index 5436212..0214dc6 100644
--- a/sound/soc/codecs/pcm186x-i2c.c
+++ b/sound/soc/codecs/pcm186x-i2c.c
@@ -36,13 +36,6 @@ static int pcm186x_i2c_probe(struct i2c_client *i2c,
 	return pcm186x_probe(&i2c->dev, type, irq, regmap);
 }
 
-static int pcm186x_i2c_remove(struct i2c_client *i2c)
-{
-	pcm186x_remove(&i2c->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id pcm186x_i2c_id[] = {
 	{ "pcm1862", PCM1862 },
 	{ "pcm1863", PCM1863 },
@@ -54,7 +47,6 @@ MODULE_DEVICE_TABLE(i2c, pcm186x_i2c_id);
 
 static struct i2c_driver pcm186x_i2c_driver = {
 	.probe		= pcm186x_i2c_probe,
-	.remove		= pcm186x_i2c_remove,
 	.id_table	= pcm186x_i2c_id,
 	.driver		= {
 		.name	= "pcm186x",
diff --git a/sound/soc/codecs/pcm186x-spi.c b/sound/soc/codecs/pcm186x-spi.c
index 2366f8e..b56e198 100644
--- a/sound/soc/codecs/pcm186x-spi.c
+++ b/sound/soc/codecs/pcm186x-spi.c
@@ -36,13 +36,6 @@ static int pcm186x_spi_probe(struct spi_device *spi)
 	return pcm186x_probe(&spi->dev, type, irq, regmap);
 }
 
-static int pcm186x_spi_remove(struct spi_device *spi)
-{
-	pcm186x_remove(&spi->dev);
-
-	return 0;
-}
-
 static const struct spi_device_id pcm186x_spi_id[] = {
 	{ "pcm1862", PCM1862 },
 	{ "pcm1863", PCM1863 },
@@ -54,7 +47,6 @@ MODULE_DEVICE_TABLE(spi, pcm186x_spi_id);
 
 static struct spi_driver pcm186x_spi_driver = {
 	.probe		= pcm186x_spi_probe,
-	.remove		= pcm186x_spi_remove,
 	.id_table	= pcm186x_spi_id,
 	.driver		= {
 		.name	= "pcm186x",
diff --git a/sound/soc/codecs/pcm186x.c b/sound/soc/codecs/pcm186x.c
index cdb5142..88fde70 100644
--- a/sound/soc/codecs/pcm186x.c
+++ b/sound/soc/codecs/pcm186x.c
@@ -262,9 +262,8 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-
-	struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
 	unsigned int rate = params_rate(params);
 	unsigned int format = params_format(params);
 	unsigned int width = params_width(params);
@@ -274,7 +273,7 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
 	u8 tdm_tx_sel = 0;
 	u8 pcm_cfg = 0;
 
-	dev_dbg(codec->dev, "%s() rate=%u format=0x%x width=%u channels=%u\n",
+	dev_dbg(component->dev, "%s() rate=%u format=0x%x width=%u channels=%u\n",
 		__func__, rate, format, width, channels);
 
 	switch (width) {
@@ -306,7 +305,7 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, PCM186X_PCM_CFG,
+	snd_soc_component_update_bits(component, PCM186X_PCM_CFG,
 			    PCM186X_PCM_CFG_RX_WLEN_MASK |
 			    PCM186X_PCM_CFG_TX_WLEN_MASK,
 			    pcm_cfg);
@@ -329,14 +328,14 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
 			return -EINVAL;
 		}
 
-		snd_soc_update_bits(codec, PCM186X_TDM_TX_SEL,
+		snd_soc_component_update_bits(component, PCM186X_TDM_TX_SEL,
 				    PCM186X_TDM_TX_SEL_MASK, tdm_tx_sel);
 
 		/* In DSP/TDM mode, the LRCLK divider must be 256 */
 		div_lrck = 256;
 
 		/* Configure 1/256 duty cycle for LRCK */
-		snd_soc_update_bits(codec, PCM186X_PCM_CFG,
+		snd_soc_component_update_bits(component, PCM186X_PCM_CFG,
 				    PCM186X_PCM_CFG_TDM_LRCK_MODE,
 				    PCM186X_PCM_CFG_TDM_LRCK_MODE);
 	}
@@ -345,12 +344,12 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
 	if (priv->is_master_mode) {
 		div_bck = priv->sysclk / (div_lrck * rate);
 
-		dev_dbg(codec->dev,
+		dev_dbg(component->dev,
 			"%s() master_clk=%u div_bck=%u div_lrck=%u\n",
 			__func__, priv->sysclk, div_bck, div_lrck);
 
-		snd_soc_write(codec, PCM186X_BCK_DIV, div_bck - 1);
-		snd_soc_write(codec, PCM186X_LRK_DIV, div_lrck - 1);
+		snd_soc_component_write(component, PCM186X_BCK_DIV, div_bck - 1);
+		snd_soc_component_write(component, PCM186X_LRK_DIV, div_lrck - 1);
 	}
 
 	return 0;
@@ -358,18 +357,18 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
 
 static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
 	u8 clk_ctrl = 0;
 	u8 pcm_cfg = 0;
 
-	dev_dbg(codec->dev, "%s() format=0x%x\n", __func__, format);
+	dev_dbg(component->dev, "%s() format=0x%x\n", __func__, format);
 
 	/* set master/slave audio interface */
 	switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
 		if (!priv->sysclk) {
-			dev_err(codec->dev, "operating in master mode requires sysclock to be configured\n");
+			dev_err(component->dev, "operating in master mode requires sysclock to be configured\n");
 			return -EINVAL;
 		}
 		clk_ctrl |= PCM186X_CLK_CTRL_MST_MODE;
@@ -379,7 +378,7 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
 		priv->is_master_mode = false;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI master/slave interface\n");
+		dev_err(component->dev, "Invalid DAI master/slave interface\n");
 		return -EINVAL;
 	}
 
@@ -388,7 +387,7 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
 	case SND_SOC_DAIFMT_NB_NF:
 		break;
 	default:
-		dev_err(codec->dev, "Inverted DAI clocks not supported\n");
+		dev_err(component->dev, "Inverted DAI clocks not supported\n");
 		return -EINVAL;
 	}
 
@@ -410,16 +409,16 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
 		pcm_cfg = PCM186X_PCM_CFG_FMT_TDM;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI format\n");
+		dev_err(component->dev, "Invalid DAI format\n");
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, PCM186X_CLK_CTRL,
+	snd_soc_component_update_bits(component, PCM186X_CLK_CTRL,
 			    PCM186X_CLK_CTRL_MST_MODE, clk_ctrl);
 
-	snd_soc_write(codec, PCM186X_TDM_TX_OFFSET, priv->tdm_offset);
+	snd_soc_component_write(component, PCM186X_TDM_TX_OFFSET, priv->tdm_offset);
 
-	snd_soc_update_bits(codec, PCM186X_PCM_CFG,
+	snd_soc_component_update_bits(component, PCM186X_PCM_CFG,
 			    PCM186X_PCM_CFG_FMT_MASK, pcm_cfg);
 
 	return 0;
@@ -428,16 +427,16 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
 static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 				unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
 	unsigned int first_slot, last_slot, tdm_offset;
 
-	dev_dbg(codec->dev,
+	dev_dbg(component->dev,
 		"%s() tx_mask=0x%x rx_mask=0x%x slots=%d slot_width=%d\n",
 		__func__, tx_mask, rx_mask, slots, slot_width);
 
 	if (!tx_mask) {
-		dev_err(codec->dev, "tdm tx mask must not be 0\n");
+		dev_err(component->dev, "tdm tx mask must not be 0\n");
 		return -EINVAL;
 	}
 
@@ -445,14 +444,14 @@ static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	last_slot = __fls(tx_mask);
 
 	if (last_slot - first_slot != hweight32(tx_mask) - 1) {
-		dev_err(codec->dev, "tdm tx mask must be contiguous\n");
+		dev_err(component->dev, "tdm tx mask must be contiguous\n");
 		return -EINVAL;
 	}
 
 	tdm_offset = first_slot * slot_width;
 
 	if (tdm_offset > 255) {
-		dev_err(codec->dev, "tdm tx slot selection out of bounds\n");
+		dev_err(component->dev, "tdm tx slot selection out of bounds\n");
 		return -EINVAL;
 	}
 
@@ -464,10 +463,10 @@ static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int pcm186x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 				  unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s() clk_id=%d freq=%u dir=%d\n",
+	dev_dbg(component->dev, "%s() clk_id=%d freq=%u dir=%d\n",
 		__func__, clk_id, freq, dir);
 
 	priv->sysclk = freq;
@@ -506,9 +505,9 @@ static struct snd_soc_dai_driver pcm1865_dai = {
 	.ops = &pcm186x_dai_ops,
 };
 
-static int pcm186x_power_on(struct snd_soc_codec *codec)
+static int pcm186x_power_on(struct snd_soc_component *component)
 {
-	struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
@@ -519,25 +518,25 @@ static int pcm186x_power_on(struct snd_soc_codec *codec)
 	regcache_cache_only(priv->regmap, false);
 	ret = regcache_sync(priv->regmap);
 	if (ret) {
-		dev_err(codec->dev, "Failed to restore cache\n");
+		dev_err(component->dev, "Failed to restore cache\n");
 		regcache_cache_only(priv->regmap, true);
 		regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
 				       priv->supplies);
 		return ret;
 	}
 
-	snd_soc_update_bits(codec, PCM186X_POWER_CTRL,
+	snd_soc_component_update_bits(component, PCM186X_POWER_CTRL,
 			    PCM186X_PWR_CTRL_PWRDN, 0);
 
 	return 0;
 }
 
-static int pcm186x_power_off(struct snd_soc_codec *codec)
+static int pcm186x_power_off(struct snd_soc_component *component)
 {
-	struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	snd_soc_update_bits(codec, PCM186X_POWER_CTRL,
+	snd_soc_component_update_bits(component, PCM186X_POWER_CTRL,
 			    PCM186X_PWR_CTRL_PWRDN, PCM186X_PWR_CTRL_PWRDN);
 
 	regcache_cache_only(priv->regmap, true);
@@ -550,11 +549,11 @@ static int pcm186x_power_off(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int pcm186x_set_bias_level(struct snd_soc_codec *codec,
+static int pcm186x_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__,
-		snd_soc_codec_get_bias_level(codec), level);
+	dev_dbg(component->dev, "## %s: %d -> %d\n", __func__,
+		snd_soc_component_get_bias_level(component), level);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -562,42 +561,44 @@ static int pcm186x_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
-			pcm186x_power_on(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+			pcm186x_power_on(component);
 		break;
 	case SND_SOC_BIAS_OFF:
-		pcm186x_power_off(codec);
+		pcm186x_power_off(component);
 		break;
 	}
 
 	return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_pcm1863 = {
-	.set_bias_level = pcm186x_set_bias_level,
-
-	.component_driver = {
-		.controls = pcm1863_snd_controls,
-		.num_controls = ARRAY_SIZE(pcm1863_snd_controls),
-		.dapm_widgets = pcm1863_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(pcm1863_dapm_widgets),
-		.dapm_routes = pcm1863_dapm_routes,
-		.num_dapm_routes = ARRAY_SIZE(pcm1863_dapm_routes),
-	},
+static struct snd_soc_component_driver soc_codec_dev_pcm1863 = {
+	.set_bias_level		= pcm186x_set_bias_level,
+	.controls		= pcm1863_snd_controls,
+	.num_controls		= ARRAY_SIZE(pcm1863_snd_controls),
+	.dapm_widgets		= pcm1863_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pcm1863_dapm_widgets),
+	.dapm_routes		= pcm1863_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pcm1863_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_pcm1865 = {
-	.set_bias_level = pcm186x_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls = pcm1865_snd_controls,
-		.num_controls = ARRAY_SIZE(pcm1865_snd_controls),
-		.dapm_widgets = pcm1865_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(pcm1865_dapm_widgets),
-		.dapm_routes = pcm1865_dapm_routes,
-		.num_dapm_routes = ARRAY_SIZE(pcm1865_dapm_routes),
-	},
+static struct snd_soc_component_driver soc_codec_dev_pcm1865 = {
+	.set_bias_level		= pcm186x_set_bias_level,
+	.controls		= pcm1865_snd_controls,
+	.num_controls		= ARRAY_SIZE(pcm1865_snd_controls),
+	.dapm_widgets		= pcm1865_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pcm1865_dapm_widgets),
+	.dapm_routes		= pcm1865_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pcm1865_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static bool pcm186x_volatile(struct device *dev, unsigned int reg)
@@ -687,13 +688,13 @@ int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq,
 	switch (type) {
 	case PCM1865:
 	case PCM1864:
-		ret = snd_soc_register_codec(dev, &soc_codec_dev_pcm1865,
+		ret = devm_snd_soc_register_component(dev, &soc_codec_dev_pcm1865,
 					     &pcm1865_dai, 1);
 		break;
 	case PCM1863:
 	case PCM1862:
 	default:
-		ret = snd_soc_register_codec(dev, &soc_codec_dev_pcm1863,
+		ret = devm_snd_soc_register_component(dev, &soc_codec_dev_pcm1863,
 					     &pcm1863_dai, 1);
 	}
 	if (ret) {
@@ -705,14 +706,6 @@ int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq,
 }
 EXPORT_SYMBOL_GPL(pcm186x_probe);
 
-int pcm186x_remove(struct device *dev)
-{
-	snd_soc_unregister_codec(dev);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pcm186x_remove);
-
 MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>");
 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
 MODULE_DESCRIPTION("PCM186x Universal Audio ADC driver");
diff --git a/sound/soc/codecs/pcm186x.h b/sound/soc/codecs/pcm186x.h
index b630111..2c6ba55 100644
--- a/sound/soc/codecs/pcm186x.h
+++ b/sound/soc/codecs/pcm186x.h
@@ -215,6 +215,5 @@ extern const struct regmap_config pcm186x_regmap;
 
 int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq,
 		  struct regmap *regmap);
-int pcm186x_remove(struct device *dev);
 
 #endif /* _PCM186X_H_ */
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index e59d8ff..c6ce9bd 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -32,8 +32,8 @@ static int pcm3008_dac_ev(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol,
 			  int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct pcm3008_setup_data *setup = codec->dev->platform_data;
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct pcm3008_setup_data *setup = component->dev->platform_data;
 
 	gpio_set_value_cansleep(setup->pdda_pin,
 				SND_SOC_DAPM_EVENT_ON(event));
@@ -45,8 +45,8 @@ static int pcm3008_adc_ev(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol,
 			  int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct pcm3008_setup_data *setup = codec->dev->platform_data;
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct pcm3008_setup_data *setup = component->dev->platform_data;
 
 	gpio_set_value_cansleep(setup->pdad_pin,
 				SND_SOC_DAPM_EVENT_ON(event));
@@ -98,13 +98,15 @@ static struct snd_soc_dai_driver pcm3008_dai = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
-	.component_driver = {
-		.dapm_widgets		= pcm3008_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(pcm3008_dapm_widgets),
-		.dapm_routes		= pcm3008_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(pcm3008_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_pcm3008 = {
+	.dapm_widgets		= pcm3008_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pcm3008_dapm_widgets),
+	.dapm_routes		= pcm3008_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pcm3008_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int pcm3008_codec_probe(struct platform_device *pdev)
@@ -146,22 +148,14 @@ static int pcm3008_codec_probe(struct platform_device *pdev)
 	if (ret != 0)
 		return ret;
 
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_pcm3008, &pcm3008_dai, 1);
-}
-
-static int pcm3008_codec_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_pcm3008, &pcm3008_dai, 1);
 }
 
 MODULE_ALIAS("platform:pcm3008-codec");
 
 static struct platform_driver pcm3008_codec_driver = {
 	.probe		= pcm3008_codec_probe,
-	.remove		= pcm3008_codec_remove,
 	.driver		= {
 		.name	= "pcm3008-codec",
 	},
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
index b9d1207..3356c91 100644
--- a/sound/soc/codecs/pcm3168a.c
+++ b/sound/soc/codecs/pcm3168a.c
@@ -287,8 +287,8 @@ static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a)
 
 static int pcm3168a_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
 
 	regmap_write(pcm3168a->regmap, PCM3168A_DAC_MUTE, mute ? 0xff : 0);
 
@@ -298,7 +298,7 @@ static int pcm3168a_digital_mute(struct snd_soc_dai *dai, int mute)
 static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
 				  int clk_id, unsigned int freq, int dir)
 {
-	struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(dai->codec);
+	struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component);
 	int ret;
 
 	if (freq > PCM1368A_MAX_SYSCLK)
@@ -316,8 +316,8 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
 static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
 			       unsigned int format, bool dac)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
 	u32 fmt, reg, mask, shift;
 	bool master_mode;
 
@@ -338,7 +338,7 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
 		fmt = PCM3168A_FMT_DSP_B;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported dai format\n");
+		dev_err(component->dev, "unsupported dai format\n");
 		return -EINVAL;
 	}
 
@@ -350,7 +350,7 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
 		master_mode = true;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported master/slave mode\n");
+		dev_err(component->dev, "unsupported master/slave mode\n");
 		return -EINVAL;
 	}
 
@@ -396,8 +396,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
 	bool tx, master_mode;
 	u32 val, mask, shift, reg;
 	unsigned int rate, fmt, ratio, max_ratio;
@@ -430,7 +430,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (i == max_ratio) {
-		dev_err(codec->dev, "unsupported sysclk ratio\n");
+		dev_err(component->dev, "unsupported sysclk ratio\n");
 		return -EINVAL;
 	}
 
@@ -438,21 +438,21 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
 	switch (min_frame_size) {
 	case 32:
 		if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
-			dev_err(codec->dev, "32-bit frames are supported only for slave mode using right justified\n");
+			dev_err(component->dev, "32-bit frames are supported only for slave mode using right justified\n");
 			return -EINVAL;
 		}
 		fmt = PCM3168A_FMT_RIGHT_J_16;
 		break;
 	case 48:
 		if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
-			dev_err(codec->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
+			dev_err(component->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
 			return -EINVAL;
 		}
 		break;
 	case 64:
 		break;
 	default:
-		dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
+		dev_err(component->dev, "unsupported frame size: %d\n", min_frame_size);
 		return -EINVAL;
 	}
 
@@ -595,16 +595,16 @@ const struct regmap_config pcm3168a_regmap = {
 };
 EXPORT_SYMBOL_GPL(pcm3168a_regmap);
 
-static const struct snd_soc_codec_driver pcm3168a_driver = {
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= pcm3168a_snd_controls,
-		.num_controls		= ARRAY_SIZE(pcm3168a_snd_controls),
-		.dapm_widgets		= pcm3168a_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(pcm3168a_dapm_widgets),
-		.dapm_routes		= pcm3168a_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(pcm3168a_dapm_routes)
-	},
+static const struct snd_soc_component_driver pcm3168a_driver = {
+	.controls		= pcm3168a_snd_controls,
+	.num_controls		= ARRAY_SIZE(pcm3168a_snd_controls),
+	.dapm_widgets		= pcm3168a_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pcm3168a_dapm_widgets),
+	.dapm_routes		= pcm3168a_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pcm3168a_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 int pcm3168a_probe(struct device *dev, struct regmap *regmap)
@@ -669,10 +669,10 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap)
 	pm_runtime_enable(dev);
 	pm_runtime_idle(dev);
 
-	ret = snd_soc_register_codec(dev, &pcm3168a_driver, pcm3168a_dais,
+	ret = devm_snd_soc_register_component(dev, &pcm3168a_driver, pcm3168a_dais,
 			ARRAY_SIZE(pcm3168a_dais));
 	if (ret) {
-		dev_err(dev, "failed to register codec: %d\n", ret);
+		dev_err(dev, "failed to register component: %d\n", ret);
 		goto err_regulator;
 	}
 
@@ -692,7 +692,6 @@ void pcm3168a_remove(struct device *dev)
 {
 	struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
 
-	snd_soc_unregister_codec(dev);
 	pm_runtime_disable(dev);
 	regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
 				pcm3168a->supplies);
diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c
index 8ba322a..39ac285 100644
--- a/sound/soc/codecs/pcm5102a.c
+++ b/sound/soc/codecs/pcm5102a.c
@@ -32,20 +32,19 @@ static struct snd_soc_dai_driver pcm5102a_dai = {
 	},
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_pcm5102a;
+static struct snd_soc_component_driver soc_component_dev_pcm5102a = {
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
 
 static int pcm5102a_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a,
+	return devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_pcm5102a,
 			&pcm5102a_dai, 1);
 }
 
-static int pcm5102a_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 static const struct of_device_id pcm5102a_of_match[] = {
 	{ .compatible = "ti,pcm5102a", },
 	{ }
@@ -54,7 +53,6 @@ MODULE_DEVICE_TABLE(of, pcm5102a_of_match);
 
 static struct platform_driver pcm5102a_codec_driver = {
 	.probe		= pcm5102a_probe,
-	.remove		= pcm5102a_remove,
 	.driver		= {
 		.name	= "pcm5102a-codec",
 		.of_match_table = pcm5102a_of_match,
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index e0f3556..f0f2d4f 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -226,8 +226,8 @@ static bool pcm512x_volatile(struct device *dev, unsigned int reg)
 static int pcm512x_overclock_pll_get(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = pcm512x->overclock_pll;
 	return 0;
@@ -236,10 +236,10 @@ static int pcm512x_overclock_pll_get(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
-	switch (snd_soc_codec_get_bias_level(codec)) {
+	switch (snd_soc_component_get_bias_level(component)) {
 	case SND_SOC_BIAS_OFF:
 	case SND_SOC_BIAS_STANDBY:
 		break;
@@ -254,8 +254,8 @@ static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_dsp_get(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = pcm512x->overclock_dsp;
 	return 0;
@@ -264,10 +264,10 @@ static int pcm512x_overclock_dsp_get(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
-	switch (snd_soc_codec_get_bias_level(codec)) {
+	switch (snd_soc_component_get_bias_level(component)) {
 	case SND_SOC_BIAS_OFF:
 	case SND_SOC_BIAS_STANDBY:
 		break;
@@ -282,8 +282,8 @@ static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_dac_get(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = pcm512x->overclock_dac;
 	return 0;
@@ -292,10 +292,10 @@ static int pcm512x_overclock_dac_get(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
-	switch (snd_soc_codec_get_bias_level(codec)) {
+	switch (snd_soc_component_get_bias_level(component)) {
 	case SND_SOC_BIAS_OFF:
 	case SND_SOC_BIAS_STANDBY:
 		break;
@@ -522,8 +522,8 @@ static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params,
 static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream,
 				      struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 	struct device *dev = dai->dev;
 	struct snd_pcm_hw_constraint_ratnums *constraints_no_pll;
 	struct snd_ratnum *rats_no_pll;
@@ -564,8 +564,8 @@ static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream,
 static int pcm512x_dai_startup_slave(struct snd_pcm_substream *substream,
 				     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 	struct device *dev = dai->dev;
 	struct regmap *regmap = pcm512x->regmap;
 
@@ -590,8 +590,8 @@ static int pcm512x_dai_startup_slave(struct snd_pcm_substream *substream,
 static int pcm512x_dai_startup(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
 	switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -606,10 +606,10 @@ static int pcm512x_dai_startup(struct snd_pcm_substream *substream,
 	}
 }
 
-static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
+static int pcm512x_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev);
+	struct pcm512x_priv *pcm512x = dev_get_drvdata(component->dev);
 	int ret;
 
 	switch (level) {
@@ -621,7 +621,7 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
 					 PCM512x_RQST, 0);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to remove standby: %d\n",
+			dev_err(component->dev, "Failed to remove standby: %d\n",
 				ret);
 			return ret;
 		}
@@ -631,7 +631,7 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
 					 PCM512x_RQST, PCM512x_RQST);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to request standby: %d\n",
+			dev_err(component->dev, "Failed to request standby: %d\n",
 				ret);
 			return ret;
 		}
@@ -645,8 +645,8 @@ static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai,
 				      unsigned long bclk_rate)
 {
 	struct device *dev = dai->dev;
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 	unsigned long sck_rate;
 	int pow2;
 
@@ -691,8 +691,8 @@ static int pcm512x_find_pll_coeff(struct snd_soc_dai *dai,
 				  unsigned long pll_rate)
 {
 	struct device *dev = dai->dev;
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 	unsigned long common;
 	int R, J, D, P;
 	unsigned long K; /* 10000 * J.D */
@@ -798,8 +798,8 @@ static unsigned long pcm512x_pllin_dac_rate(struct snd_soc_dai *dai,
 					    unsigned long osr_rate,
 					    unsigned long pllin_rate)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 	unsigned long dac_rate;
 
 	if (!pcm512x->pll_out)
@@ -829,8 +829,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
 				struct snd_pcm_hw_params *params)
 {
 	struct device *dev = dai->dev;
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 	unsigned long pllin_rate = 0;
 	unsigned long pll_rate;
 	unsigned long sck_rate;
@@ -949,7 +949,7 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF,
 					 PCM512x_SDAC, PCM512x_SDAC_GPIO);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to set gpio as dacref: %d\n", ret);
 			return ret;
 		}
@@ -958,7 +958,7 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_DACIN,
 					 PCM512x_GREF, gpio);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to set gpio %d as dacin: %d\n",
 				pcm512x->pll_in, ret);
 			return ret;
@@ -987,7 +987,7 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF,
 					 PCM512x_SDAC, PCM512x_SDAC_SCK);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to set sck as dacref: %d\n", ret);
 			return ret;
 		}
@@ -1082,18 +1082,18 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_FS_SPEED_MODE,
 				 PCM512x_FSSP, fssp);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to set fs speed: %d\n", ret);
+		dev_err(component->dev, "Failed to set fs speed: %d\n", ret);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "DSP divider %d\n", dsp_div);
-	dev_dbg(codec->dev, "DAC divider %d\n", dac_div);
-	dev_dbg(codec->dev, "NCP divider %d\n", ncp_div);
-	dev_dbg(codec->dev, "OSR divider %d\n", osr_div);
-	dev_dbg(codec->dev, "BCK divider %d\n", bclk_div);
-	dev_dbg(codec->dev, "LRCK divider %d\n", lrclk_div);
-	dev_dbg(codec->dev, "IDAC %d\n", idac);
-	dev_dbg(codec->dev, "1<<FSSP %d\n", 1 << fssp);
+	dev_dbg(component->dev, "DSP divider %d\n", dsp_div);
+	dev_dbg(component->dev, "DAC divider %d\n", dac_div);
+	dev_dbg(component->dev, "NCP divider %d\n", ncp_div);
+	dev_dbg(component->dev, "OSR divider %d\n", osr_div);
+	dev_dbg(component->dev, "BCK divider %d\n", bclk_div);
+	dev_dbg(component->dev, "LRCK divider %d\n", lrclk_div);
+	dev_dbg(component->dev, "IDAC %d\n", idac);
+	dev_dbg(component->dev, "1<<FSSP %d\n", 1 << fssp);
 
 	return 0;
 }
@@ -1102,15 +1102,15 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 	int alen;
 	int gpio;
 	int clock_output;
 	int master_mode;
 	int ret;
 
-	dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n",
+	dev_dbg(component->dev, "hw_params %u Hz, %u channels\n",
 		params_rate(params),
 		params_channels(params));
 
@@ -1128,7 +1128,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 		alen = PCM512x_ALEN_32;
 		break;
 	default:
-		dev_err(codec->dev, "Bad frame size: %d\n",
+		dev_err(component->dev, "Bad frame size: %d\n",
 			params_width(params));
 		return -EINVAL;
 	}
@@ -1141,7 +1141,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 					 | PCM512x_BCKO | PCM512x_LRKO,
 					 0);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to enable slave mode: %d\n", ret);
 			return ret;
 		}
@@ -1149,7 +1149,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
 					 PCM512x_DCAS, 0);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to enable clock divider autoset: %d\n",
 				ret);
 			return ret;
@@ -1170,20 +1170,20 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_I2S_1,
 				 PCM512x_ALEN, alen);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to set frame size: %d\n", ret);
+		dev_err(component->dev, "Failed to set frame size: %d\n", ret);
 		return ret;
 	}
 
 	if (pcm512x->pll_out) {
 		ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_A, 0x11);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to set FLEX_A: %d\n", ret);
+			dev_err(component->dev, "Failed to set FLEX_A: %d\n", ret);
 			return ret;
 		}
 
 		ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_B, 0xff);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to set FLEX_B: %d\n", ret);
+			dev_err(component->dev, "Failed to set FLEX_B: %d\n", ret);
 			return ret;
 		}
 
@@ -1196,7 +1196,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 					 | PCM512x_IDSK | PCM512x_IDCH
 					 | PCM512x_DCAS);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to ignore auto-clock failures: %d\n",
 				ret);
 			return ret;
@@ -1211,7 +1211,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 					 | PCM512x_IDSK | PCM512x_IDCH
 					 | PCM512x_DCAS | PCM512x_IPLK);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to ignore auto-clock failures: %d\n",
 				ret);
 			return ret;
@@ -1220,7 +1220,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN,
 					 PCM512x_PLLE, 0);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to disable pll: %d\n", ret);
+			dev_err(component->dev, "Failed to disable pll: %d\n", ret);
 			return ret;
 		}
 	}
@@ -1233,7 +1233,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_REF,
 					 PCM512x_SREF, PCM512x_SREF_GPIO);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to set gpio as pllref: %d\n", ret);
 			return ret;
 		}
@@ -1242,7 +1242,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_PLLIN,
 					 PCM512x_GREF, gpio);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to set gpio %d as pllin: %d\n",
 				pcm512x->pll_in, ret);
 			return ret;
@@ -1251,7 +1251,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN,
 					 PCM512x_PLLE, PCM512x_PLLE);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to enable pll: %d\n", ret);
+			dev_err(component->dev, "Failed to enable pll: %d\n", ret);
 			return ret;
 		}
 	}
@@ -1260,7 +1260,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 				 PCM512x_BCKP | PCM512x_BCKO | PCM512x_LRKO,
 				 clock_output);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable clock output: %d\n", ret);
+		dev_err(component->dev, "Failed to enable clock output: %d\n", ret);
 		return ret;
 	}
 
@@ -1268,7 +1268,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 				 PCM512x_RLRK | PCM512x_RBCK,
 				 master_mode);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable master mode: %d\n", ret);
+		dev_err(component->dev, "Failed to enable master mode: %d\n", ret);
 		return ret;
 	}
 
@@ -1277,7 +1277,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN,
 					 gpio, gpio);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to enable gpio %d: %d\n",
+			dev_err(component->dev, "Failed to enable gpio %d: %d\n",
 				pcm512x->pll_out, ret);
 			return ret;
 		}
@@ -1286,7 +1286,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 		ret = regmap_update_bits(pcm512x->regmap, gpio,
 					 PCM512x_GxSL, PCM512x_GxSL_PLLCK);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to output pll on %d: %d\n",
+			dev_err(component->dev, "Failed to output pll on %d: %d\n",
 				ret, pcm512x->pll_out);
 			return ret;
 		}
@@ -1295,14 +1295,14 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
 				 PCM512x_RQSY, PCM512x_RQSY_HALT);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to halt clocks: %d\n", ret);
+		dev_err(component->dev, "Failed to halt clocks: %d\n", ret);
 		return ret;
 	}
 
 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
 				 PCM512x_RQSY, PCM512x_RQSY_RESUME);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to resume clocks: %d\n", ret);
+		dev_err(component->dev, "Failed to resume clocks: %d\n", ret);
 		return ret;
 	}
 
@@ -1311,8 +1311,8 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 
 static int pcm512x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
 	pcm512x->fmt = fmt;
 
@@ -1341,18 +1341,17 @@ static struct snd_soc_dai_driver pcm512x_dai = {
 	.ops = &pcm512x_dai_ops,
 };
 
-static const struct snd_soc_codec_driver pcm512x_codec_driver = {
-	.set_bias_level = pcm512x_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= pcm512x_controls,
-		.num_controls		= ARRAY_SIZE(pcm512x_controls),
-		.dapm_widgets		= pcm512x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(pcm512x_dapm_widgets),
-		.dapm_routes		= pcm512x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(pcm512x_dapm_routes),
-	},
+static const struct snd_soc_component_driver pcm512x_component_driver = {
+	.set_bias_level		= pcm512x_set_bias_level,
+	.controls		= pcm512x_controls,
+	.num_controls		= ARRAY_SIZE(pcm512x_controls),
+	.dapm_widgets		= pcm512x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pcm512x_dapm_widgets),
+	.dapm_routes		= pcm512x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pcm512x_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_range_cfg pcm512x_range = {
@@ -1498,7 +1497,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
 	}
 #endif
 
-	ret = snd_soc_register_codec(dev, &pcm512x_codec_driver,
+	ret = devm_snd_soc_register_component(dev, &pcm512x_component_driver,
 				    &pcm512x_dai, 1);
 	if (ret != 0) {
 		dev_err(dev, "Failed to register CODEC: %d\n", ret);
@@ -1523,7 +1522,6 @@ void pcm512x_remove(struct device *dev)
 {
 	struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
 
-	snd_soc_unregister_codec(dev);
 	pm_runtime_disable(dev);
 	if (!IS_ERR(pcm512x->sclk))
 		clk_disable_unprepare(pcm512x->sclk);
diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c
index 8f92e5c..d88e673 100644
--- a/sound/soc/codecs/rt274.c
+++ b/sound/soc/codecs/rt274.c
@@ -38,7 +38,7 @@ struct rt274_priv {
 	struct reg_default *index_cache;
 	int index_cache_size;
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct i2c_client *i2c;
 	struct snd_soc_jack *jack;
 	struct delayed_work jack_detect_work;
@@ -338,13 +338,13 @@ static bool rt274_readable_register(struct device *dev, unsigned int reg)
 }
 
 #ifdef CONFIG_PM
-static void rt274_index_sync(struct snd_soc_codec *codec)
+static void rt274_index_sync(struct snd_soc_component *component)
 {
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < INDEX_CACHE_SIZE; i++) {
-		snd_soc_write(codec, rt274->index_cache[i].reg,
+		snd_soc_component_write(component, rt274->index_cache[i].reg,
 				  rt274->index_cache[i].def);
 	}
 }
@@ -357,7 +357,7 @@ static int rt274_jack_detect(struct rt274_priv *rt274, bool *hp, bool *mic)
 	*hp = false;
 	*mic = false;
 
-	if (!rt274->codec)
+	if (!rt274->component)
 		return -EINVAL;
 
 	regmap_read(rt274->regmap, RT274_GET_HP_SENSE, &buf);
@@ -393,10 +393,10 @@ static void rt274_jack_detect_work(struct work_struct *work)
 
 static irqreturn_t rt274_irq(int irq, void *data);
 
-static int rt274_mic_detect(struct snd_soc_codec *codec,
+static int rt274_mic_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *jack,  void *data)
 {
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
 	if (jack == NULL) {
 		/* Disable jack detection */
@@ -609,8 +609,8 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0;
 	int d_len_code = 0, c_len_code = 0;
 
@@ -620,7 +620,7 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
 	case 48000:
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported sample rate %d\n",
+		dev_err(component->dev, "Unsupported sample rate %d\n",
 					params_rate(params));
 		return -EINVAL;
 	}
@@ -628,7 +628,7 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
 	case 12288000:
 	case 24576000:
 		if (params_rate(params) != 48000) {
-			dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+			dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
 					params_rate(params), rt274->sys_clk);
 			return -EINVAL;
 		}
@@ -636,7 +636,7 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
 	case 11289600:
 	case 22579200:
 		if (params_rate(params) != 44100) {
-			dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+			dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
 					params_rate(params), rt274->sys_clk);
 			return -EINVAL;
 		}
@@ -647,7 +647,7 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
 		/* bit 3:0 Number of Channel */
 		val |= (params_channels(params) - 1);
 	} else {
-		dev_err(codec->dev, "Unsupported channels %d\n",
+		dev_err(component->dev, "Unsupported channels %d\n",
 					params_channels(params));
 		return -EINVAL;
 	}
@@ -685,29 +685,29 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
 	if (rt274->master)
 		c_len_code = 0x3;
 
-	snd_soc_update_bits(codec,
+	snd_soc_component_update_bits(component,
 		RT274_I2S_CTRL1, 0xc018, d_len_code << 3 | c_len_code << 14);
-	dev_dbg(codec->dev, "format val = 0x%x\n", val);
+	dev_dbg(component->dev, "format val = 0x%x\n", val);
 
-	snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x407f, val);
-	snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x407f, val);
+	snd_soc_component_update_bits(component, RT274_DAC_FORMAT, 0x407f, val);
+	snd_soc_component_update_bits(component, RT274_ADC_FORMAT, 0x407f, val);
 
 	return 0;
 }
 
 static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_M);
 		rt274->master = true;
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_S);
 		rt274->master = false;
 		break;
@@ -717,27 +717,27 @@ static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+		snd_soc_component_update_bits(component, RT274_I2S_CTRL1,
 					RT274_I2S_FMT_MASK, RT274_I2S_FMT_I2S);
 		break;
 	case SND_SOC_DAIFMT_LEFT_J:
-		snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+		snd_soc_component_update_bits(component, RT274_I2S_CTRL1,
 					RT274_I2S_FMT_MASK, RT274_I2S_FMT_LJ);
 		break;
 	case SND_SOC_DAIFMT_DSP_A:
-		snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+		snd_soc_component_update_bits(component, RT274_I2S_CTRL1,
 					RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMA);
 		break;
 	case SND_SOC_DAIFMT_DSP_B:
-		snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+		snd_soc_component_update_bits(component, RT274_I2S_CTRL1,
 					RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMB);
 		break;
 	default:
 		return -EINVAL;
 	}
 	/* bit 15 Stream Type 0:PCM 1:Non-PCM */
-	snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x8000, 0);
-	snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x8000, 0);
+	snd_soc_component_update_bits(component, RT274_DAC_FORMAT, 0x8000, 0);
+	snd_soc_component_update_bits(component, RT274_ADC_FORMAT, 0x8000, 0);
 
 	return 0;
 }
@@ -745,47 +745,47 @@ static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
 	switch (source) {
 	case RT274_PLL2_S_MCLK:
-		snd_soc_update_bits(codec, RT274_PLL2_CTRL,
+		snd_soc_component_update_bits(component, RT274_PLL2_CTRL,
 				RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_MCLK);
 		break;
 	default:
-		dev_warn(codec->dev, "invalid pll source, use BCLK\n");
+		dev_warn(component->dev, "invalid pll source, use BCLK\n");
 	case RT274_PLL2_S_BCLK:
-		snd_soc_update_bits(codec, RT274_PLL2_CTRL,
+		snd_soc_component_update_bits(component, RT274_PLL2_CTRL,
 				RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_BCLK);
 		break;
 	}
 
 	if (source == RT274_PLL2_S_BCLK) {
-		snd_soc_update_bits(codec, RT274_MCLK_CTRL,
+		snd_soc_component_update_bits(component, RT274_MCLK_CTRL,
 				(0x3 << 12), (0x3 << 12));
 		switch (rt274->fs) {
 		case 50:
-			snd_soc_write(codec, 0x7a, 0xaab6);
-			snd_soc_write(codec, 0x7b, 0x0301);
-			snd_soc_write(codec, 0x7c, 0x04fe);
+			snd_soc_component_write(component, 0x7a, 0xaab6);
+			snd_soc_component_write(component, 0x7b, 0x0301);
+			snd_soc_component_write(component, 0x7c, 0x04fe);
 			break;
 		case 64:
-			snd_soc_write(codec, 0x7a, 0xaa96);
-			snd_soc_write(codec, 0x7b, 0x8003);
-			snd_soc_write(codec, 0x7c, 0x081e);
+			snd_soc_component_write(component, 0x7a, 0xaa96);
+			snd_soc_component_write(component, 0x7b, 0x8003);
+			snd_soc_component_write(component, 0x7c, 0x081e);
 			break;
 		case 128:
-			snd_soc_write(codec, 0x7a, 0xaa96);
-			snd_soc_write(codec, 0x7b, 0x8003);
-			snd_soc_write(codec, 0x7c, 0x080e);
+			snd_soc_component_write(component, 0x7a, 0xaa96);
+			snd_soc_component_write(component, 0x7b, 0x8003);
+			snd_soc_component_write(component, 0x7c, 0x080e);
 			break;
 		default:
-			dev_warn(codec->dev, "invalid freq_in, assume 4.8M\n");
+			dev_warn(component->dev, "invalid freq_in, assume 4.8M\n");
 		case 100:
-			snd_soc_write(codec, 0x7a, 0xaab6);
-			snd_soc_write(codec, 0x7b, 0x0301);
-			snd_soc_write(codec, 0x7c, 0x047e);
+			snd_soc_component_write(component, 0x7a, 0xaab6);
+			snd_soc_component_write(component, 0x7b, 0x0301);
+			snd_soc_component_write(component, 0x7c, 0x047e);
 			break;
 		}
 	}
@@ -796,11 +796,11 @@ static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt274_set_dai_sysclk(struct snd_soc_dai *dai,
 				int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 	unsigned int clk_src, mclk_en;
 
-	dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
+	dev_dbg(component->dev, "%s freq=%d\n", __func__, freq);
 
 	switch (clk_id) {
 	case RT274_SCLK_S_MCLK:
@@ -818,43 +818,43 @@ static int rt274_set_dai_sysclk(struct snd_soc_dai *dai,
 	default:
 		mclk_en = RT274_MCLK_MODE_DIS;
 		clk_src = RT274_CLK_SRC_MCLK;
-		dev_warn(codec->dev, "invalid sysclk source, use PLL1\n");
+		dev_warn(component->dev, "invalid sysclk source, use PLL1\n");
 		break;
 	}
-	snd_soc_update_bits(codec, RT274_MCLK_CTRL,
+	snd_soc_component_update_bits(component, RT274_MCLK_CTRL,
 			RT274_MCLK_MODE_MASK, mclk_en);
-	snd_soc_update_bits(codec, RT274_CLK_CTRL,
+	snd_soc_component_update_bits(component, RT274_CLK_CTRL,
 			RT274_CLK_SRC_MASK, clk_src);
 
 	switch (freq) {
 	case 19200000:
 		if (clk_id == RT274_SCLK_S_MCLK) {
-			dev_err(codec->dev, "Should not use MCLK\n");
+			dev_err(component->dev, "Should not use MCLK\n");
 			return -EINVAL;
 		}
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL2, 0x40, 0x40);
 		break;
 	case 24000000:
 		if (clk_id == RT274_SCLK_S_MCLK) {
-			dev_err(codec->dev, "Should not use MCLK\n");
+			dev_err(component->dev, "Should not use MCLK\n");
 			return -EINVAL;
 		}
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL2, 0x40, 0x0);
 		break;
 	case 12288000:
 	case 11289600:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_MCLK_CTRL, 0x1fcf, 0x0008);
 		break;
 	case 24576000:
 	case 22579200:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_MCLK_CTRL, 0x1fcf, 0x1543);
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported system clock\n");
+		dev_err(component->dev, "Unsupported system clock\n");
 		return -EINVAL;
 	}
 
@@ -866,16 +866,16 @@ static int rt274_set_dai_sysclk(struct snd_soc_dai *dai,
 
 static int rt274_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+	dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
 	rt274->fs = ratio;
 	if ((ratio / 50) == 0)
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL1, 0x1000, 0x1000);
 	else
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL1, 0x1000, 0x0);
 
 
@@ -886,28 +886,28 @@ static int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			unsigned int rx_mask, int slots, int slot_width)
 
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (rx_mask || tx_mask) {
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_EN);
 	} else {
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_DIS);
 		return 0;
 	}
 
 	switch (slots) {
 	case 4:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_4CH);
 		break;
 	case 2:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_2CH);
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Support 2 or 4 slots TDM only\n");
 		return -EINVAL;
 	}
@@ -915,20 +915,20 @@ static int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	return 0;
 }
 
-static int rt274_set_bias_level(struct snd_soc_codec *codec,
+static int rt274_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
 		if (SND_SOC_BIAS_STANDBY ==
-			snd_soc_codec_get_bias_level(codec)) {
-			snd_soc_write(codec,
+			snd_soc_component_get_bias_level(component)) {
+			snd_soc_component_write(component,
 				RT274_SET_AUDIO_POWER, AC_PWRST_D0);
 		}
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_write(codec,
+		snd_soc_component_write(component,
 			RT274_SET_AUDIO_POWER, AC_PWRST_D3);
 		break;
 
@@ -968,11 +968,11 @@ static irqreturn_t rt274_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static int rt274_probe(struct snd_soc_codec *codec)
+static int rt274_probe(struct snd_soc_component *component)
 {
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
-	rt274->codec = codec;
+	rt274->component = component;
 
 	if (rt274->i2c->irq) {
 		INIT_DELAYED_WORK(&rt274->jack_detect_work,
@@ -984,19 +984,17 @@ static int rt274_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt274_remove(struct snd_soc_codec *codec)
+static void rt274_remove(struct snd_soc_component *component)
 {
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
 	cancel_delayed_work_sync(&rt274->jack_detect_work);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt274_suspend(struct snd_soc_codec *codec)
+static int rt274_suspend(struct snd_soc_component *component)
 {
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt274->regmap, true);
 	regcache_mark_dirty(rt274->regmap);
@@ -1004,12 +1002,12 @@ static int rt274_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt274_resume(struct snd_soc_codec *codec)
+static int rt274_resume(struct snd_soc_component *component)
 {
-	struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+	struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt274->regmap, false);
-	rt274_index_sync(codec);
+	rt274_index_sync(component);
 	regcache_sync(rt274->regmap);
 
 	return 0;
@@ -1055,22 +1053,22 @@ static struct snd_soc_dai_driver rt274_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt274 = {
-	.probe = rt274_probe,
-	.remove = rt274_remove,
-	.suspend = rt274_suspend,
-	.resume = rt274_resume,
-	.set_bias_level = rt274_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt274_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt274_snd_controls),
-		.dapm_widgets		= rt274_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt274_dapm_widgets),
-		.dapm_routes		= rt274_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt274_dapm_routes),
-	},
-	.set_jack = rt274_mic_detect,
+static const struct snd_soc_component_driver soc_component_dev_rt274 = {
+	.probe			= rt274_probe,
+	.remove			= rt274_remove,
+	.suspend		= rt274_suspend,
+	.resume			= rt274_resume,
+	.set_bias_level		= rt274_set_bias_level,
+	.set_jack		= rt274_mic_detect,
+	.controls		= rt274_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt274_snd_controls),
+	.dapm_widgets		= rt274_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt274_dapm_widgets),
+	.dapm_routes		= rt274_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt274_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt274_regmap = {
@@ -1191,7 +1189,8 @@ static int rt274_i2c_probe(struct i2c_client *i2c,
 		}
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt274,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_rt274,
 				     rt274_dai, ARRAY_SIZE(rt274_dai));
 
 	return ret;
@@ -1203,7 +1202,6 @@ static int rt274_i2c_remove(struct i2c_client *i2c)
 
 	if (i2c->irq)
 		free_irq(i2c->irq, rt274);
-	snd_soc_unregister_codec(&i2c->dev);
 
 	return 0;
 }
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index af6325c..0b0f748 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -40,7 +40,7 @@ struct rt286_priv {
 	struct reg_default *index_cache;
 	int index_cache_size;
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt286_platform_data pdata;
 	struct i2c_client *i2c;
 	struct snd_soc_jack *jack;
@@ -187,13 +187,13 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg)
 }
 
 #ifdef CONFIG_PM
-static void rt286_index_sync(struct snd_soc_codec *codec)
+static void rt286_index_sync(struct snd_soc_component *component)
 {
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < INDEX_CACHE_SIZE; i++) {
-		snd_soc_write(codec, rt286->index_cache[i].reg,
+		snd_soc_component_write(component, rt286->index_cache[i].reg,
 				  rt286->index_cache[i].def);
 	}
 }
@@ -220,10 +220,10 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 	*hp = false;
 	*mic = false;
 
-	if (!rt286->codec)
+	if (!rt286->component)
 		return -EINVAL;
 
-	dapm = snd_soc_codec_get_dapm(rt286->codec);
+	dapm = snd_soc_component_get_dapm(rt286->component);
 
 	if (rt286->pdata.cbj_en) {
 		regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
@@ -275,9 +275,10 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 		regmap_read(rt286->regmap, RT286_GET_MIC1_SENSE, &buf);
 		*mic = buf & 0x80000000;
 	}
-
-	snd_soc_dapm_disable_pin(dapm, "HV");
-	snd_soc_dapm_disable_pin(dapm, "VREF");
+	if (!*mic) {
+		snd_soc_dapm_disable_pin(dapm, "HV");
+		snd_soc_dapm_disable_pin(dapm, "VREF");
+	}
 	if (!*hp)
 		snd_soc_dapm_disable_pin(dapm, "LDO1");
 	snd_soc_dapm_sync(dapm);
@@ -305,10 +306,10 @@ static void rt286_jack_detect_work(struct work_struct *work)
 		SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
 }
 
-int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
 	rt286->jack = jack;
 
@@ -334,8 +335,8 @@ EXPORT_SYMBOL_GPL(rt286_mic_detect);
 static int is_mclk_mode(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
 	if (rt286->clk_id == RT286_SCLK_S_MCLK)
 		return 1;
@@ -434,15 +435,15 @@ SOC_DAPM_ENUM("SPO source", rt286_spo_enum);
 static int rt286_spk_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_write(codec,
+		snd_soc_component_write(component,
 			RT286_SPK_EAPD, RT286_SET_EAPD_HIGH);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_write(codec,
+		snd_soc_component_write(component,
 			RT286_SPK_EAPD, RT286_SET_EAPD_LOW);
 		break;
 
@@ -456,14 +457,14 @@ static int rt286_spk_event(struct snd_soc_dapm_widget *w,
 static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
 				  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_write(codec, RT286_SET_PIN_DMIC1, 0x20);
+		snd_soc_component_write(component, RT286_SET_PIN_DMIC1, 0x20);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_write(codec, RT286_SET_PIN_DMIC1, 0);
+		snd_soc_component_write(component, RT286_SET_PIN_DMIC1, 0);
 		break;
 	default:
 		return 0;
@@ -475,14 +476,14 @@ static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
 static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08);
+		snd_soc_component_update_bits(component, RT286_POWER_CTRL2, 0x38, 0x08);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30);
+		snd_soc_component_update_bits(component, RT286_POWER_CTRL2, 0x38, 0x30);
 		break;
 	default:
 		return 0;
@@ -494,19 +495,19 @@ static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
 static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
 		break;
 	default:
@@ -674,8 +675,8 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0;
 	int d_len_code;
 
@@ -687,7 +688,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
 	case 48000:
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported sample rate %d\n",
+		dev_err(component->dev, "Unsupported sample rate %d\n",
 					params_rate(params));
 		return -EINVAL;
 	}
@@ -695,7 +696,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
 	case 12288000:
 	case 24576000:
 		if (params_rate(params) != 48000) {
-			dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+			dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
 					params_rate(params), rt286->sys_clk);
 			return -EINVAL;
 		}
@@ -703,7 +704,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
 	case 11289600:
 	case 22579200:
 		if (params_rate(params) != 44100) {
-			dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+			dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
 					params_rate(params), rt286->sys_clk);
 			return -EINVAL;
 		}
@@ -714,7 +715,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
 		/* bit 3:0 Number of Channel */
 		val |= (params_channels(params) - 1);
 	} else {
-		dev_err(codec->dev, "Unsupported channels %d\n",
+		dev_err(component->dev, "Unsupported channels %d\n",
 					params_channels(params));
 		return -EINVAL;
 	}
@@ -745,27 +746,27 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec,
+	snd_soc_component_update_bits(component,
 		RT286_I2S_CTRL1, 0x0018, d_len_code << 3);
-	dev_dbg(codec->dev, "format val = 0x%x\n", val);
+	dev_dbg(component->dev, "format val = 0x%x\n", val);
 
-	snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x407f, val);
-	snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val);
+	snd_soc_component_update_bits(component, RT286_DAC_FORMAT, 0x407f, val);
+	snd_soc_component_update_bits(component, RT286_ADC_FORMAT, 0x407f, val);
 
 	return 0;
 }
 
 static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL1, 0x800, 0x800);
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL1, 0x800, 0x0);
 		break;
 	default:
@@ -774,27 +775,27 @@ static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL1, 0x300, 0x0);
 		break;
 	case SND_SOC_DAIFMT_LEFT_J:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL1, 0x300, 0x1 << 8);
 		break;
 	case SND_SOC_DAIFMT_DSP_A:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL1, 0x300, 0x2 << 8);
 		break;
 	case SND_SOC_DAIFMT_DSP_B:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL1, 0x300, 0x3 << 8);
 		break;
 	default:
 		return -EINVAL;
 	}
 	/* bit 15 Stream Type 0:PCM 1:Non-PCM */
-	snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x8000, 0);
-	snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x8000, 0);
+	snd_soc_component_update_bits(component, RT286_DAC_FORMAT, 0x8000, 0);
+	snd_soc_component_update_bits(component, RT286_ADC_FORMAT, 0x8000, 0);
 
 	return 0;
 }
@@ -802,58 +803,58 @@ static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
 				int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
+	dev_dbg(component->dev, "%s freq=%d\n", __func__, freq);
 
 	if (RT286_SCLK_S_MCLK == clk_id) {
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL2, 0x0100, 0x0);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_PLL_CTRL1, 0x20, 0x20);
 	} else {
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL2, 0x0100, 0x0100);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_PLL_CTRL, 0x4, 0x4);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_PLL_CTRL1, 0x20, 0x0);
 	}
 
 	switch (freq) {
 	case 19200000:
 		if (RT286_SCLK_S_MCLK == clk_id) {
-			dev_err(codec->dev, "Should not use MCLK\n");
+			dev_err(component->dev, "Should not use MCLK\n");
 			return -EINVAL;
 		}
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL2, 0x40, 0x40);
 		break;
 	case 24000000:
 		if (RT286_SCLK_S_MCLK == clk_id) {
-			dev_err(codec->dev, "Should not use MCLK\n");
+			dev_err(component->dev, "Should not use MCLK\n");
 			return -EINVAL;
 		}
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL2, 0x40, 0x0);
 		break;
 	case 12288000:
 	case 11289600:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL2, 0x8, 0x0);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_CLK_DIV, 0xfc1e, 0x0004);
 		break;
 	case 24576000:
 	case 22579200:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL2, 0x8, 0x8);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_CLK_DIV, 0xfc1e, 0x5406);
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported system clock\n");
+		dev_err(component->dev, "Unsupported system clock\n");
 		return -EINVAL;
 	}
 
@@ -865,42 +866,42 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
 
 static int rt286_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+	dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
 	if (50 == ratio)
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL1, 0x1000, 0x1000);
 	else
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_I2S_CTRL1, 0x1000, 0x0);
 
 
 	return 0;
 }
 
-static int rt286_set_bias_level(struct snd_soc_codec *codec,
+static int rt286_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
-		if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
-			snd_soc_write(codec,
+		if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
+			snd_soc_component_write(component,
 				RT286_SET_AUDIO_POWER, AC_PWRST_D0);
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 				RT286_DC_GAIN, 0x200, 0x200);
 		}
 		break;
 
 	case SND_SOC_BIAS_ON:
 		mdelay(10);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT286_DC_GAIN, 0x200, 0x0);
 
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_write(codec,
+		snd_soc_component_write(component,
 			RT286_SET_AUDIO_POWER, AC_PWRST_D3);
 		break;
 
@@ -937,11 +938,11 @@ static irqreturn_t rt286_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static int rt286_probe(struct snd_soc_codec *codec)
+static int rt286_probe(struct snd_soc_component *component)
 {
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
-	rt286->codec = codec;
+	rt286->component = component;
 
 	if (rt286->i2c->irq) {
 		regmap_update_bits(rt286->regmap,
@@ -956,19 +957,17 @@ static int rt286_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt286_remove(struct snd_soc_codec *codec)
+static void rt286_remove(struct snd_soc_component *component)
 {
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
 	cancel_delayed_work_sync(&rt286->jack_detect_work);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt286_suspend(struct snd_soc_codec *codec)
+static int rt286_suspend(struct snd_soc_component *component)
 {
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt286->regmap, true);
 	regcache_mark_dirty(rt286->regmap);
@@ -976,12 +975,12 @@ static int rt286_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt286_resume(struct snd_soc_codec *codec)
+static int rt286_resume(struct snd_soc_component *component)
 {
-	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+	struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt286->regmap, false);
-	rt286_index_sync(codec);
+	rt286_index_sync(component);
 	regcache_sync(rt286->regmap);
 
 	return 0;
@@ -1046,21 +1045,21 @@ static struct snd_soc_dai_driver rt286_dai[] = {
 
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt286 = {
-	.probe = rt286_probe,
-	.remove = rt286_remove,
-	.suspend = rt286_suspend,
-	.resume = rt286_resume,
-	.set_bias_level = rt286_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt286_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt286_snd_controls),
-		.dapm_widgets		= rt286_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt286_dapm_widgets),
-		.dapm_routes		= rt286_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt286_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt286 = {
+	.probe			= rt286_probe,
+	.remove			= rt286_remove,
+	.suspend		= rt286_suspend,
+	.resume			= rt286_resume,
+	.set_bias_level		= rt286_set_bias_level,
+	.controls		= rt286_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt286_snd_controls),
+	.dapm_widgets		= rt286_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt286_dapm_widgets),
+	.dapm_routes		= rt286_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt286_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt286_regmap = {
@@ -1243,7 +1242,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
 		}
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt286,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_rt286,
 				     rt286_dai, ARRAY_SIZE(rt286_dai));
 
 	return ret;
@@ -1255,7 +1255,6 @@ static int rt286_i2c_remove(struct i2c_client *i2c)
 
 	if (i2c->irq)
 		free_irq(i2c->irq, rt286);
-	snd_soc_unregister_codec(&i2c->dev);
 
 	return 0;
 }
diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h
index 7130edb..c63d0e7 100644
--- a/sound/soc/codecs/rt286.h
+++ b/sound/soc/codecs/rt286.h
@@ -199,7 +199,7 @@ enum {
 	RT286_AIFS,
 };
 
-int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #endif /* __RT286_H__ */
 
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
index ce96376..06cdba4 100644
--- a/sound/soc/codecs/rt298.c
+++ b/sound/soc/codecs/rt298.c
@@ -39,7 +39,7 @@ struct rt298_priv {
 	struct reg_default *index_cache;
 	int index_cache_size;
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt298_platform_data pdata;
 	struct i2c_client *i2c;
 	struct snd_soc_jack *jack;
@@ -194,13 +194,13 @@ static bool rt298_readable_register(struct device *dev, unsigned int reg)
 }
 
 #ifdef CONFIG_PM
-static void rt298_index_sync(struct snd_soc_codec *codec)
+static void rt298_index_sync(struct snd_soc_component *component)
 {
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < INDEX_CACHE_SIZE; i++) {
-		snd_soc_write(codec, rt298->index_cache[i].reg,
+		snd_soc_component_write(component, rt298->index_cache[i].reg,
 				  rt298->index_cache[i].def);
 	}
 }
@@ -227,10 +227,10 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic)
 	*hp = false;
 	*mic = false;
 
-	if (!rt298->codec)
+	if (!rt298->component)
 		return -EINVAL;
 
-	dapm = snd_soc_codec_get_dapm(rt298->codec);
+	dapm = snd_soc_component_get_dapm(rt298->component);
 
 	if (rt298->pdata.cbj_en) {
 		regmap_read(rt298->regmap, RT298_GET_HP_SENSE, &buf);
@@ -290,9 +290,10 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic)
 		regmap_read(rt298->regmap, RT298_GET_MIC1_SENSE, &buf);
 		*mic = buf & 0x80000000;
 	}
-
-	snd_soc_dapm_disable_pin(dapm, "HV");
-	snd_soc_dapm_disable_pin(dapm, "VREF");
+	if (!*mic) {
+		snd_soc_dapm_disable_pin(dapm, "HV");
+		snd_soc_dapm_disable_pin(dapm, "VREF");
+	}
 	if (!*hp)
 		snd_soc_dapm_disable_pin(dapm, "LDO1");
 	snd_soc_dapm_sync(dapm);
@@ -323,9 +324,9 @@ static void rt298_jack_detect_work(struct work_struct *work)
 		SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
 }
 
-int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 	struct snd_soc_dapm_context *dapm;
 	bool hp = false;
 	bool mic = false;
@@ -334,7 +335,7 @@ int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 	/* If jack in NULL, disable HS jack */
 	if (!jack) {
 		regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x0);
-		dapm = snd_soc_codec_get_dapm(codec);
+		dapm = snd_soc_component_get_dapm(component);
 		snd_soc_dapm_disable_pin(dapm, "LDO1");
 		snd_soc_dapm_sync(dapm);
 		return 0;
@@ -360,8 +361,8 @@ EXPORT_SYMBOL_GPL(rt298_mic_detect);
 static int is_mclk_mode(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
 	if (rt298->clk_id == RT298_SCLK_S_MCLK)
 		return 1;
@@ -458,15 +459,15 @@ SOC_DAPM_ENUM("SPO source", rt298_spo_enum);
 static int rt298_spk_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_write(codec,
+		snd_soc_component_write(component,
 			RT298_SPK_EAPD, RT298_SET_EAPD_HIGH);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_write(codec,
+		snd_soc_component_write(component,
 			RT298_SPK_EAPD, RT298_SET_EAPD_LOW);
 		break;
 
@@ -480,14 +481,14 @@ static int rt298_spk_event(struct snd_soc_dapm_widget *w,
 static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w,
 				  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_write(codec, RT298_SET_PIN_DMIC1, 0x20);
+		snd_soc_component_write(component, RT298_SET_PIN_DMIC1, 0x20);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_write(codec, RT298_SET_PIN_DMIC1, 0);
+		snd_soc_component_write(component, RT298_SET_PIN_DMIC1, 0);
 		break;
 	default:
 		return 0;
@@ -499,39 +500,39 @@ static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w,
 static int rt298_adc_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int nid;
 
 	nid = (w->reg >> 20) & 0xff;
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
 			0x7080, 0x7000);
 		 /* If MCLK doesn't exist, reset AD filter */
-		if (!(snd_soc_read(codec, RT298_VAD_CTRL) & 0x200)) {
+		if (!(snd_soc_component_read32(component, RT298_VAD_CTRL) & 0x200)) {
 			pr_info("NO MCLK\n");
 			switch (nid) {
 			case RT298_ADC_IN1:
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					RT298_D_FILTER_CTRL, 0x2, 0x2);
 				mdelay(10);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					RT298_D_FILTER_CTRL, 0x2, 0x0);
 				break;
 			case RT298_ADC_IN2:
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					RT298_D_FILTER_CTRL, 0x4, 0x4);
 				mdelay(10);
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					RT298_D_FILTER_CTRL, 0x4, 0x0);
 				break;
 			}
 		}
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
 			0x7080, 0x7080);
 		break;
@@ -545,19 +546,19 @@ static int rt298_adc_event(struct snd_soc_dapm_widget *w,
 static int rt298_mic1_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_A_BIAS_CTRL3, 0xc000, 0x8000);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_A_BIAS_CTRL2, 0xc000, 0x8000);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_A_BIAS_CTRL3, 0xc000, 0x0000);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_A_BIAS_CTRL2, 0xc000, 0x0000);
 		break;
 	default:
@@ -745,8 +746,8 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0;
 	int d_len_code;
 
@@ -756,7 +757,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
 	case 48000:
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported sample rate %d\n",
+		dev_err(component->dev, "Unsupported sample rate %d\n",
 					params_rate(params));
 		return -EINVAL;
 	}
@@ -764,7 +765,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
 	case 12288000:
 	case 24576000:
 		if (params_rate(params) != 48000) {
-			dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+			dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
 					params_rate(params), rt298->sys_clk);
 			return -EINVAL;
 		}
@@ -772,7 +773,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
 	case 11289600:
 	case 22579200:
 		if (params_rate(params) != 44100) {
-			dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+			dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
 					params_rate(params), rt298->sys_clk);
 			return -EINVAL;
 		}
@@ -783,7 +784,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
 		/* bit 3:0 Number of Channel */
 		val |= (params_channels(params) - 1);
 	} else {
-		dev_err(codec->dev, "Unsupported channels %d\n",
+		dev_err(component->dev, "Unsupported channels %d\n",
 					params_channels(params));
 		return -EINVAL;
 	}
@@ -814,27 +815,27 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec,
+	snd_soc_component_update_bits(component,
 		RT298_I2S_CTRL1, 0x0018, d_len_code << 3);
-	dev_dbg(codec->dev, "format val = 0x%x\n", val);
+	dev_dbg(component->dev, "format val = 0x%x\n", val);
 
-	snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x407f, val);
-	snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x407f, val);
+	snd_soc_component_update_bits(component, RT298_DAC_FORMAT, 0x407f, val);
+	snd_soc_component_update_bits(component, RT298_ADC_FORMAT, 0x407f, val);
 
 	return 0;
 }
 
 static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL1, 0x800, 0x800);
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL1, 0x800, 0x0);
 		break;
 	default:
@@ -843,27 +844,27 @@ static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL1, 0x300, 0x0);
 		break;
 	case SND_SOC_DAIFMT_LEFT_J:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL1, 0x300, 0x1 << 8);
 		break;
 	case SND_SOC_DAIFMT_DSP_A:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL1, 0x300, 0x2 << 8);
 		break;
 	case SND_SOC_DAIFMT_DSP_B:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL1, 0x300, 0x3 << 8);
 		break;
 	default:
 		return -EINVAL;
 	}
 	/* bit 15 Stream Type 0:PCM 1:Non-PCM */
-	snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x8000, 0);
-	snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x8000, 0);
+	snd_soc_component_update_bits(component, RT298_DAC_FORMAT, 0x8000, 0);
+	snd_soc_component_update_bits(component, RT298_ADC_FORMAT, 0x8000, 0);
 
 	return 0;
 }
@@ -871,56 +872,56 @@ static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
 				int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
+	dev_dbg(component->dev, "%s freq=%d\n", __func__, freq);
 
 	if (RT298_SCLK_S_MCLK == clk_id) {
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL2, 0x0100, 0x0);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_PLL_CTRL1, 0x20, 0x20);
 	} else {
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL2, 0x0100, 0x0100);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_PLL_CTRL1, 0x20, 0x0);
 	}
 
 	switch (freq) {
 	case 19200000:
 		if (RT298_SCLK_S_MCLK == clk_id) {
-			dev_err(codec->dev, "Should not use MCLK\n");
+			dev_err(component->dev, "Should not use MCLK\n");
 			return -EINVAL;
 		}
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL2, 0x40, 0x40);
 		break;
 	case 24000000:
 		if (RT298_SCLK_S_MCLK == clk_id) {
-			dev_err(codec->dev, "Should not use MCLK\n");
+			dev_err(component->dev, "Should not use MCLK\n");
 			return -EINVAL;
 		}
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL2, 0x40, 0x0);
 		break;
 	case 12288000:
 	case 11289600:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL2, 0x8, 0x0);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_CLK_DIV, 0xfc1e, 0x0004);
 		break;
 	case 24576000:
 	case 22579200:
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL2, 0x8, 0x8);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_CLK_DIV, 0xfc1e, 0x5406);
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported system clock\n");
+		dev_err(component->dev, "Unsupported system clock\n");
 		return -EINVAL;
 	}
 
@@ -932,39 +933,39 @@ static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
 
 static int rt298_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+	dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
 	if (50 == ratio)
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL1, 0x1000, 0x1000);
 	else
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 			RT298_I2S_CTRL1, 0x1000, 0x0);
 
 
 	return 0;
 }
 
-static int rt298_set_bias_level(struct snd_soc_codec *codec,
+static int rt298_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
 		if (SND_SOC_BIAS_STANDBY ==
-			snd_soc_codec_get_bias_level(codec)) {
-			snd_soc_write(codec,
+			snd_soc_component_get_bias_level(component)) {
+			snd_soc_component_write(component,
 				RT298_SET_AUDIO_POWER, AC_PWRST_D0);
-			snd_soc_update_bits(codec, 0x0d, 0x200, 0x200);
-			snd_soc_update_bits(codec, 0x52, 0x80, 0x0);
+			snd_soc_component_update_bits(component, 0x0d, 0x200, 0x200);
+			snd_soc_component_update_bits(component, 0x52, 0x80, 0x0);
 			mdelay(20);
-			snd_soc_update_bits(codec, 0x0d, 0x200, 0x0);
-			snd_soc_update_bits(codec, 0x52, 0x80, 0x80);
+			snd_soc_component_update_bits(component, 0x0d, 0x200, 0x0);
+			snd_soc_component_update_bits(component, 0x52, 0x80, 0x80);
 		}
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_write(codec,
+		snd_soc_component_write(component,
 			RT298_SET_AUDIO_POWER, AC_PWRST_D3);
 		break;
 
@@ -1003,11 +1004,11 @@ static irqreturn_t rt298_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static int rt298_probe(struct snd_soc_codec *codec)
+static int rt298_probe(struct snd_soc_component *component)
 {
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
-	rt298->codec = codec;
+	rt298->component = component;
 
 	if (rt298->i2c->irq) {
 		regmap_update_bits(rt298->regmap,
@@ -1022,19 +1023,17 @@ static int rt298_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt298_remove(struct snd_soc_codec *codec)
+static void rt298_remove(struct snd_soc_component *component)
 {
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
 	cancel_delayed_work_sync(&rt298->jack_detect_work);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt298_suspend(struct snd_soc_codec *codec)
+static int rt298_suspend(struct snd_soc_component *component)
 {
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
 	rt298->is_hp_in = -1;
 	regcache_cache_only(rt298->regmap, true);
@@ -1043,12 +1042,12 @@ static int rt298_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt298_resume(struct snd_soc_codec *codec)
+static int rt298_resume(struct snd_soc_component *component)
 {
-	struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+	struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt298->regmap, false);
-	rt298_index_sync(codec);
+	rt298_index_sync(component);
 	regcache_sync(rt298->regmap);
 
 	return 0;
@@ -1113,21 +1112,21 @@ static struct snd_soc_dai_driver rt298_dai[] = {
 
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt298 = {
-	.probe = rt298_probe,
-	.remove = rt298_remove,
-	.suspend = rt298_suspend,
-	.resume = rt298_resume,
-	.set_bias_level = rt298_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt298_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt298_snd_controls),
-		.dapm_widgets		= rt298_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt298_dapm_widgets),
-		.dapm_routes		= rt298_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt298_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt298 = {
+	.probe			= rt298_probe,
+	.remove			= rt298_remove,
+	.suspend		= rt298_suspend,
+	.resume			= rt298_resume,
+	.set_bias_level		= rt298_set_bias_level,
+	.controls		= rt298_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt298_snd_controls),
+	.dapm_widgets		= rt298_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt298_dapm_widgets),
+	.dapm_routes		= rt298_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt298_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt298_regmap = {
@@ -1288,7 +1287,8 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
 		}
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt298,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_rt298,
 				     rt298_dai, ARRAY_SIZE(rt298_dai));
 
 	return ret;
@@ -1300,7 +1300,6 @@ static int rt298_i2c_remove(struct i2c_client *i2c)
 
 	if (i2c->irq)
 		free_irq(i2c->irq, rt298);
-	snd_soc_unregister_codec(&i2c->dev);
 
 	return 0;
 }
diff --git a/sound/soc/codecs/rt298.h b/sound/soc/codecs/rt298.h
index 3638f3d..b4db935 100644
--- a/sound/soc/codecs/rt298.h
+++ b/sound/soc/codecs/rt298.h
@@ -210,7 +210,7 @@ enum {
 	RT298_AIFS,
 };
 
-int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #endif /* __RT298_H__ */
 
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
index 2144edc..18686ff 100644
--- a/sound/soc/codecs/rt5514-spi.c
+++ b/sound/soc/codecs/rt5514-spi.c
@@ -35,6 +35,8 @@
 
 #include "rt5514-spi.h"
 
+#define DRV_NAME "rt5514-spi"
+
 static struct spi_device *rt5514_spi;
 
 struct rt5514_dsp {
@@ -211,8 +213,9 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
 			       struct snd_pcm_hw_params *hw_params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 	struct rt5514_dsp *rt5514_dsp =
-			snd_soc_platform_get_drvdata(rtd->platform);
+		snd_soc_component_get_drvdata(component);
 	int ret;
 	u8 buf[8];
 
@@ -235,8 +238,9 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
 static int rt5514_spi_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 	struct rt5514_dsp *rt5514_dsp =
-			snd_soc_platform_get_drvdata(rtd->platform);
+		snd_soc_component_get_drvdata(component);
 
 	mutex_lock(&rt5514_dsp->dma_lock);
 	rt5514_dsp->substream = NULL;
@@ -252,8 +256,9 @@ static snd_pcm_uframes_t rt5514_spi_pcm_pointer(
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 	struct rt5514_dsp *rt5514_dsp =
-		snd_soc_platform_get_drvdata(rtd->platform);
+		snd_soc_component_get_drvdata(component);
 
 	return bytes_to_frames(runtime, rt5514_dsp->dma_offset);
 }
@@ -267,18 +272,18 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = {
 	.page		= snd_pcm_lib_get_vmalloc_page,
 };
 
-static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform)
+static int rt5514_spi_pcm_probe(struct snd_soc_component *component)
 {
 	struct rt5514_dsp *rt5514_dsp;
 	int ret;
 
-	rt5514_dsp = devm_kzalloc(platform->dev, sizeof(*rt5514_dsp),
+	rt5514_dsp = devm_kzalloc(component->dev, sizeof(*rt5514_dsp),
 			GFP_KERNEL);
 
 	rt5514_dsp->dev = &rt5514_spi->dev;
 	mutex_init(&rt5514_dsp->dma_lock);
 	INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work);
-	snd_soc_platform_set_drvdata(platform, rt5514_dsp);
+	snd_soc_component_set_drvdata(component, rt5514_dsp);
 
 	if (rt5514_spi->irq) {
 		ret = devm_request_threaded_irq(&rt5514_spi->dev,
@@ -296,15 +301,12 @@ static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform)
 	return 0;
 }
 
-static const struct snd_soc_platform_driver rt5514_spi_platform = {
+static const struct snd_soc_component_driver rt5514_spi_component = {
+	.name  = DRV_NAME,
 	.probe = rt5514_spi_pcm_probe,
 	.ops = &rt5514_spi_pcm_ops,
 };
 
-static const struct snd_soc_component_driver rt5514_spi_dai_component = {
-	.name		= "rt5514-spi-dai",
-};
-
 /**
  * rt5514_spi_burst_read - Read data from SPI by rt5514 address.
  * @addr: Start address.
@@ -445,14 +447,8 @@ static int rt5514_spi_probe(struct spi_device *spi)
 
 	rt5514_spi = spi;
 
-	ret = devm_snd_soc_register_platform(&spi->dev, &rt5514_spi_platform);
-	if (ret < 0) {
-		dev_err(&spi->dev, "Failed to register platform.\n");
-		return ret;
-	}
-
 	ret = devm_snd_soc_register_component(&spi->dev,
-					      &rt5514_spi_dai_component,
+					      &rt5514_spi_component,
 					      &rt5514_spi_dai, 1);
 	if (ret < 0) {
 		dev_err(&spi->dev, "Failed to register component.\n");
@@ -474,9 +470,9 @@ static int __maybe_unused rt5514_suspend(struct device *dev)
 
 static int __maybe_unused rt5514_resume(struct device *dev)
 {
-	struct snd_soc_platform *platform = snd_soc_lookup_platform(dev);
+	struct snd_soc_component *component = snd_soc_lookup_component(dev, DRV_NAME);
 	struct rt5514_dsp *rt5514_dsp =
-		snd_soc_platform_get_drvdata(platform);
+		snd_soc_component_get_drvdata(component);
 	int irq = to_spi_device(dev)->irq;
 	u8 buf[8];
 
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index 198df01..e8a66b0 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -327,14 +327,13 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
-	struct snd_soc_codec *codec = rt5514->codec;
 	const struct firmware *fw = NULL;
 	u8 buf[8];
 
 	if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled)
 		return 0;
 
-	if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+	if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 		rt5514->dsp_enabled = ucontrol->value.integer.value[0];
 
 		if (rt5514->dsp_enabled) {
@@ -342,11 +341,11 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
 				!IS_ERR(rt5514->dsp_calib_clk)) {
 				if (clk_set_rate(rt5514->dsp_calib_clk,
 					rt5514->pdata.dsp_calib_clk_rate))
-					dev_err(codec->dev,
+					dev_err(component->dev,
 						"Can't set rate for mclk");
 
 				if (clk_prepare_enable(rt5514->dsp_calib_clk))
-					dev_err(codec->dev,
+					dev_err(component->dev,
 						"Can't enable dsp_calib_clk");
 
 				rt5514_calibration(rt5514, true);
@@ -354,11 +353,11 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
 				msleep(20);
 #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
 				rt5514_spi_burst_read(RT5514_PLL3_CALIB_CTRL6 |
-					RT5514_DSP_MAPPING,
-					(u8 *)&buf, sizeof(buf));
+					RT5514_DSP_MAPPING, buf, sizeof(buf));
 #else
-				dev_err(codec->dev, "There is no SPI driver for"
+				dev_err(component->dev, "There is no SPI driver for"
 					" loading the firmware\n");
+				memset(buf, 0, sizeof(buf));
 #endif
 				rt5514->pll3_cal_value = buf[0] | buf[1] << 8 |
 					buf[2] << 16 | buf[3] << 24;
@@ -369,26 +368,26 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
 
 			rt5514_enable_dsp_prepare(rt5514);
 
-			request_firmware(&fw, RT5514_FIRMWARE1, codec->dev);
+			request_firmware(&fw, RT5514_FIRMWARE1, component->dev);
 			if (fw) {
 #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
 				rt5514_spi_burst_write(0x4ff60000, fw->data,
 					((fw->size/8)+1)*8);
 #else
-				dev_err(codec->dev, "There is no SPI driver for"
+				dev_err(component->dev, "There is no SPI driver for"
 					" loading the firmware\n");
 #endif
 				release_firmware(fw);
 				fw = NULL;
 			}
 
-			request_firmware(&fw, RT5514_FIRMWARE2, codec->dev);
+			request_firmware(&fw, RT5514_FIRMWARE2, component->dev);
 			if (fw) {
 #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
 				rt5514_spi_burst_write(0x4ffc0000, fw->data,
 					((fw->size/8)+1)*8);
 #else
-				dev_err(codec->dev, "There is no SPI driver for"
+				dev_err(component->dev, "There is no SPI driver for"
 					" loading the firmware\n");
 #endif
 				release_firmware(fw);
@@ -492,7 +491,7 @@ static const struct snd_kcontrol_new rt5514_sto2_dmic_mux =
  * Choose divider parameter that gives the highest possible DMIC frequency in
  * 1MHz - 3MHz range.
  */
-static int rt5514_calc_dmic_clk(struct snd_soc_codec *codec, int rate)
+static int rt5514_calc_dmic_clk(struct snd_soc_component *component, int rate)
 {
 	int div[] = {2, 3, 4, 8, 12, 16, 24, 32};
 	int i;
@@ -508,20 +507,20 @@ static int rt5514_calc_dmic_clk(struct snd_soc_codec *codec, int rate)
 			return i;
 	}
 
-	dev_warn(codec->dev, "Base clock rate %d is too high\n", rate);
+	dev_warn(component->dev, "Base clock rate %d is too high\n", rate);
 	return -EINVAL;
 }
 
 static int rt5514_set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 	int idx;
 
-	idx = rt5514_calc_dmic_clk(codec, rt5514->sysclk);
+	idx = rt5514_calc_dmic_clk(component, rt5514->sysclk);
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else
 		regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL1,
 			RT5514_CLK_DMIC_OUT_SEL_MASK,
@@ -536,8 +535,8 @@ static int rt5514_set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 
 	if (rt5514->sysclk_src == RT5514_SCLK_S_PLL1)
 		return 1;
@@ -548,8 +547,8 @@ static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int rt5514_i2s_use_asrc(struct snd_soc_dapm_widget *source,
 	struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 
 	return (rt5514->sysclk > rt5514->lrck * 384);
 }
@@ -751,21 +750,21 @@ static const struct snd_soc_dapm_route rt5514_dapm_routes[] = {
 static int rt5514_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 	int pre_div, bclk_ms, frame_size;
 	unsigned int val_len = 0;
 
 	rt5514->lrck = params_rate(params);
 	pre_div = rl6231_get_clk_info(rt5514->sysclk, rt5514->lrck);
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting\n");
+		dev_err(component->dev, "Unsupported clock setting\n");
 		return -EINVAL;
 	}
 
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return -EINVAL;
 	}
 
@@ -808,8 +807,8 @@ static int rt5514_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5514_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -862,8 +861,8 @@ static int rt5514_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	if (freq == rt5514->sysclk && clk_id == rt5514->sysclk_src)
@@ -879,7 +878,7 @@ static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai,
 		break;
 
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
 
@@ -897,13 +896,13 @@ static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5514->pll_in = 0;
 		rt5514->pll_out = 0;
@@ -930,17 +929,17 @@ static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		break;
 
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
@@ -961,8 +960,8 @@ static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0, val2 = 0;
 
 	if (rx_mask || tx_mask)
@@ -1047,10 +1046,10 @@ static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	return 0;
 }
 
-static int rt5514_set_bias_level(struct snd_soc_codec *codec,
+static int rt5514_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1058,7 +1057,7 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec,
 		if (IS_ERR(rt5514->mclk))
 			break;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
 			clk_disable_unprepare(rt5514->mclk);
 		} else {
 			ret = clk_prepare_enable(rt5514->mclk);
@@ -1068,7 +1067,7 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/*
 			 * If the DSP is enabled in start of recording, the DSP
 			 * should be disabled, and sync back to normal recording
@@ -1092,13 +1091,13 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5514_probe(struct snd_soc_codec *codec)
+static int rt5514_probe(struct snd_soc_component *component)
 {
-	struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
-	struct platform_device *pdev = container_of(codec->dev,
+	struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
+	struct platform_device *pdev = container_of(component->dev,
 						   struct platform_device, dev);
 
-	rt5514->mclk = devm_clk_get(codec->dev, "mclk");
+	rt5514->mclk = devm_clk_get(component->dev, "mclk");
 	if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
@@ -1109,7 +1108,7 @@ static int rt5514_probe(struct snd_soc_codec *codec)
 			return -EPROBE_DEFER;
 	}
 
-	rt5514->codec = codec;
+	rt5514->component = component;
 	rt5514->pll3_cal_value = 0x0078b000;
 
 	return 0;
@@ -1162,18 +1161,18 @@ static struct snd_soc_dai_driver rt5514_dai[] = {
 	}
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5514 = {
-	.probe = rt5514_probe,
-	.idle_bias_off = true,
-	.set_bias_level = rt5514_set_bias_level,
-	.component_driver = {
-		.controls		= rt5514_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5514_snd_controls),
-		.dapm_widgets		= rt5514_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5514_dapm_widgets),
-		.dapm_routes		= rt5514_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5514_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5514 = {
+	.probe			= rt5514_probe,
+	.set_bias_level		= rt5514_set_bias_level,
+	.controls		= rt5514_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5514_snd_controls),
+	.dapm_widgets		= rt5514_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5514_dapm_widgets),
+	.dapm_routes		= rt5514_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5514_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt5514_i2c_regmap = {
@@ -1313,17 +1312,11 @@ static int rt5514_i2c_probe(struct i2c_client *i2c,
 	if (ret != 0)
 		dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
 
-	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5514,
+	return devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_rt5514,
 			rt5514_dai, ARRAY_SIZE(rt5514_dai));
 }
 
-static int rt5514_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-
-	return 0;
-}
-
 static const struct dev_pm_ops rt5514_i2_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume)
 };
@@ -1336,7 +1329,6 @@ static struct i2c_driver rt5514_i2c_driver = {
 		.pm = &rt5514_i2_pm_ops,
 	},
 	.probe = rt5514_i2c_probe,
-	.remove   = rt5514_i2c_remove,
 	.id_table = rt5514_i2c_id,
 };
 module_i2c_driver(rt5514_i2c_driver);
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h
index f0f3400..d1ef0b3 100644
--- a/sound/soc/codecs/rt5514.h
+++ b/sound/soc/codecs/rt5514.h
@@ -272,7 +272,7 @@ enum {
 
 struct rt5514_priv {
 	struct rt5514_platform_data pdata;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct regmap *i2c_regmap, *regmap;
 	struct clk *mclk, *dsp_calib_clk;
 	int sysclk;
diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c
index 0e5f54a..3dc795f 100644
--- a/sound/soc/codecs/rt5616.c
+++ b/sound/soc/codecs/rt5616.c
@@ -142,7 +142,7 @@ static const struct reg_default rt5616_reg[] = {
 };
 
 struct rt5616_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct delayed_work patch_work;
 	struct regmap *regmap;
 	struct clk *mclk;
@@ -351,7 +351,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 {
 	unsigned int val;
 
-	val = snd_soc_read(snd_soc_dapm_to_codec(source->dapm), RT5616_GLB_CLK);
+	val = snd_soc_component_read32(snd_soc_dapm_to_component(source->dapm), RT5616_GLB_CLK);
 	val &= RT5616_SCLK_SRC_MASK;
 	if (val == RT5616_SCLK_SRC_PLL1)
 		return 1;
@@ -466,16 +466,16 @@ static const struct snd_kcontrol_new rt5616_lout_mix[] = {
 static int rt5616_adc_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
+		snd_soc_component_update_bits(component, RT5616_ADC_DIG_VOL,
 				    RT5616_L_MUTE | RT5616_R_MUTE, 0);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
+		snd_soc_component_update_bits(component, RT5616_ADC_DIG_VOL,
 				    RT5616_L_MUTE | RT5616_R_MUTE,
 				    RT5616_L_MUTE | RT5616_R_MUTE);
 		break;
@@ -490,51 +490,51 @@ static int rt5616_adc_event(struct snd_soc_dapm_widget *w,
 static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
 				    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* depop parameters */
-		snd_soc_update_bits(codec, RT5616_DEPOP_M2,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M2,
 				    RT5616_DEPOP_MASK, RT5616_DEPOP_MAN);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |
 				    RT5616_HP_CB_MASK, RT5616_HP_CP_PU |
 				    RT5616_HP_SG_DIS | RT5616_HP_CB_PU);
-		snd_soc_write(codec, RT5616_PR_BASE +
+		snd_soc_component_write(component, RT5616_PR_BASE +
 			      RT5616_HP_DCC_INT1, 0x9f00);
 		/* headphone amp power on */
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
 				    RT5616_PWR_FV1 | RT5616_PWR_FV2, 0);
-		snd_soc_update_bits(codec, RT5616_PWR_VOL,
+		snd_soc_component_update_bits(component, RT5616_PWR_VOL,
 				    RT5616_PWR_HV_L | RT5616_PWR_HV_R,
 				    RT5616_PWR_HV_L | RT5616_PWR_HV_R);
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
 				    RT5616_PWR_HP_L | RT5616_PWR_HP_R |
 				    RT5616_PWR_HA, RT5616_PWR_HP_L |
 				    RT5616_PWR_HP_R | RT5616_PWR_HA);
 		msleep(50);
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
 				    RT5616_PWR_FV1 | RT5616_PWR_FV2,
 				    RT5616_PWR_FV1 | RT5616_PWR_FV2);
 
-		snd_soc_update_bits(codec, RT5616_CHARGE_PUMP,
+		snd_soc_component_update_bits(component, RT5616_CHARGE_PUMP,
 				    RT5616_PM_HP_MASK, RT5616_PM_HP_HV);
-		snd_soc_update_bits(codec, RT5616_PR_BASE +
+		snd_soc_component_update_bits(component, RT5616_PR_BASE +
 				    RT5616_CHOP_DAC_ADC, 0x0200, 0x0200);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_HP_CO_MASK | RT5616_HP_SG_MASK,
 				    RT5616_HP_CO_EN | RT5616_HP_SG_EN);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5616_PR_BASE +
+		snd_soc_component_update_bits(component, RT5616_PR_BASE +
 				    RT5616_CHOP_DAC_ADC, 0x0200, 0x0);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
 				    RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
 				    RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
 		/* headphone amp power down */
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_SMT_TRIG_MASK |
 				    RT5616_HP_CD_PD_MASK | RT5616_HP_CO_MASK |
 				    RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |
@@ -542,7 +542,7 @@ static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
 				    RT5616_SMT_TRIG_DIS | RT5616_HP_CD_PD_EN |
 				    RT5616_HP_CO_DIS | RT5616_HP_CP_PD |
 				    RT5616_HP_SG_EN | RT5616_HP_CB_PD);
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
 				    RT5616_PWR_HP_L | RT5616_PWR_HP_R |
 				    RT5616_PWR_HA, 0);
 		break;
@@ -556,61 +556,61 @@ static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
 static int rt5616_hp_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* headphone unmute sequence */
-		snd_soc_update_bits(codec, RT5616_DEPOP_M3,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M3,
 				    RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
 				    RT5616_CP_FQ3_MASK,
 				    RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ1_SFT |
 				    RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT |
 				    RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ3_SFT);
-		snd_soc_write(codec, RT5616_PR_BASE +
+		snd_soc_component_write(component, RT5616_PR_BASE +
 			      RT5616_MAMP_INT_REG2, 0xfc00);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_SMT_TRIG_MASK, RT5616_SMT_TRIG_EN);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_RSTN_MASK, RT5616_RSTN_EN);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_RSTN_MASK | RT5616_HP_L_SMT_MASK |
 				    RT5616_HP_R_SMT_MASK, RT5616_RSTN_DIS |
 				    RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
-		snd_soc_update_bits(codec, RT5616_HP_VOL,
+		snd_soc_component_update_bits(component, RT5616_HP_VOL,
 				    RT5616_L_MUTE | RT5616_R_MUTE, 0);
 		msleep(100);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
 				    RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
 				    RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
 		msleep(20);
-		snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
+		snd_soc_component_update_bits(component, RT5616_HP_CALIB_AMP_DET,
 				    RT5616_HPD_PS_MASK, RT5616_HPD_PS_EN);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
 		/* headphone mute sequence */
-		snd_soc_update_bits(codec, RT5616_DEPOP_M3,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M3,
 				    RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
 				    RT5616_CP_FQ3_MASK,
 				    RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ1_SFT |
 				    RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT |
 				    RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ3_SFT);
-		snd_soc_write(codec, RT5616_PR_BASE +
+		snd_soc_component_write(component, RT5616_PR_BASE +
 			      RT5616_MAMP_INT_REG2, 0xfc00);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_HP_SG_MASK, RT5616_HP_SG_EN);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_RSTP_MASK, RT5616_RSTP_EN);
-		snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+		snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
 				    RT5616_RSTP_MASK | RT5616_HP_L_SMT_MASK |
 				    RT5616_HP_R_SMT_MASK, RT5616_RSTP_DIS |
 				    RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
-		snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
+		snd_soc_component_update_bits(component, RT5616_HP_CALIB_AMP_DET,
 				    RT5616_HPD_PS_MASK, RT5616_HPD_PS_DIS);
 		msleep(90);
-		snd_soc_update_bits(codec, RT5616_HP_VOL,
+		snd_soc_component_update_bits(component, RT5616_HP_VOL,
 				    RT5616_L_MUTE | RT5616_R_MUTE,
 				    RT5616_L_MUTE | RT5616_R_MUTE);
 		msleep(30);
@@ -626,21 +626,21 @@ static int rt5616_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5616_lout_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
 				    RT5616_PWR_LM, RT5616_PWR_LM);
-		snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
+		snd_soc_component_update_bits(component, RT5616_LOUT_CTRL1,
 				    RT5616_L_MUTE | RT5616_R_MUTE, 0);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
+		snd_soc_component_update_bits(component, RT5616_LOUT_CTRL1,
 				    RT5616_L_MUTE | RT5616_R_MUTE,
 				    RT5616_L_MUTE | RT5616_R_MUTE);
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
 				    RT5616_PWR_LM, 0);
 		break;
 
@@ -654,16 +654,16 @@ static int rt5616_lout_event(struct snd_soc_dapm_widget *w,
 static int rt5616_bst1_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG2,
 				    RT5616_PWR_BST1_OP2, RT5616_PWR_BST1_OP2);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG2,
 				    RT5616_PWR_BST1_OP2, 0);
 		break;
 
@@ -677,16 +677,16 @@ static int rt5616_bst1_event(struct snd_soc_dapm_widget *w,
 static int rt5616_bst2_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG2,
 				    RT5616_PWR_BST2_OP2, RT5616_PWR_BST2_OP2);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5616_PWR_ANLG2,
 				    RT5616_PWR_BST2_OP2, 0);
 		break;
 
@@ -960,8 +960,8 @@ static int rt5616_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, mask_clk;
 	int pre_div, bclk_ms, frame_size;
 
@@ -970,12 +970,12 @@ static int rt5616_hw_params(struct snd_pcm_substream *substream,
 	pre_div = rl6231_get_clk_info(rt5616->sysclk, rt5616->lrck[dai->id]);
 
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting\n");
+		dev_err(component->dev, "Unsupported clock setting\n");
 		return -EINVAL;
 	}
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return -EINVAL;
 	}
 	bclk_ms = frame_size > 32 ? 1 : 0;
@@ -1004,17 +1004,17 @@ static int rt5616_hw_params(struct snd_pcm_substream *substream,
 
 	mask_clk = RT5616_I2S_PD1_MASK;
 	val_clk = pre_div << RT5616_I2S_PD1_SFT;
-	snd_soc_update_bits(codec, RT5616_I2S1_SDP,
+	snd_soc_component_update_bits(component, RT5616_I2S1_SDP,
 			    RT5616_I2S_DL_MASK, val_len);
-	snd_soc_update_bits(codec, RT5616_ADDA_CLK1, mask_clk, val_clk);
+	snd_soc_component_update_bits(component, RT5616_ADDA_CLK1, mask_clk, val_clk);
 
 	return 0;
 }
 
 static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1055,7 +1055,7 @@ static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5616_I2S1_SDP,
+	snd_soc_component_update_bits(component, RT5616_I2S1_SDP,
 			    RT5616_I2S_MS_MASK | RT5616_I2S_BP_MASK |
 			    RT5616_I2S_DF_MASK, reg_val);
 
@@ -1065,8 +1065,8 @@ static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	if (freq == rt5616->sysclk && clk_id == rt5616->sysclk_src)
@@ -1080,11 +1080,11 @@ static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
 		reg_val |= RT5616_SCLK_SRC_PLL1;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5616_GLB_CLK,
+	snd_soc_component_update_bits(component, RT5616_GLB_CLK,
 			    RT5616_SCLK_SRC_MASK, reg_val);
 	rt5616->sysclk = freq;
 	rt5616->sysclk_src = clk_id;
@@ -1097,8 +1097,8 @@ static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			      unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -1107,11 +1107,11 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5616->pll_in = 0;
 		rt5616->pll_out = 0;
-		snd_soc_update_bits(codec, RT5616_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5616_GLB_CLK,
 				    RT5616_SCLK_SRC_MASK,
 				    RT5616_SCLK_SRC_MCLK);
 		return 0;
@@ -1119,34 +1119,34 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 
 	switch (source) {
 	case RT5616_PLL1_S_MCLK:
-		snd_soc_update_bits(codec, RT5616_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5616_GLB_CLK,
 				    RT5616_PLL1_SRC_MASK,
 				    RT5616_PLL1_SRC_MCLK);
 		break;
 	case RT5616_PLL1_S_BCLK1:
 	case RT5616_PLL1_S_BCLK2:
-		snd_soc_update_bits(codec, RT5616_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5616_GLB_CLK,
 				    RT5616_PLL1_SRC_MASK,
 				    RT5616_PLL1_SRC_BCLK1);
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
-	snd_soc_write(codec, RT5616_PLL_CTRL1,
+	snd_soc_component_write(component, RT5616_PLL_CTRL1,
 		      pll_code.n_code << RT5616_PLL_N_SFT | pll_code.k_code);
-	snd_soc_write(codec, RT5616_PLL_CTRL2,
+	snd_soc_component_write(component, RT5616_PLL_CTRL2,
 		      (pll_code.m_bp ? 0 : pll_code.m_code) <<
 		      RT5616_PLL_M_SFT |
 		      pll_code.m_bp << RT5616_PLL_M_BP_SFT);
@@ -1158,10 +1158,10 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 	return 0;
 }
 
-static int rt5616_set_bias_level(struct snd_soc_codec *codec,
+static int rt5616_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+	struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1180,7 +1180,7 @@ static int rt5616_set_bias_level(struct snd_soc_codec *codec,
 		if (IS_ERR(rt5616->mclk))
 			break;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
 			clk_disable_unprepare(rt5616->mclk);
 		} else {
 			ret = clk_prepare_enable(rt5616->mclk);
@@ -1190,30 +1190,30 @@ static int rt5616_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
 					    RT5616_PWR_VREF1 | RT5616_PWR_MB |
 					    RT5616_PWR_BG | RT5616_PWR_VREF2,
 					    RT5616_PWR_VREF1 | RT5616_PWR_MB |
 					    RT5616_PWR_BG | RT5616_PWR_VREF2);
 			mdelay(10);
-			snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
 					    RT5616_PWR_FV1 | RT5616_PWR_FV2,
 					    RT5616_PWR_FV1 | RT5616_PWR_FV2);
-			snd_soc_update_bits(codec, RT5616_D_MISC,
+			snd_soc_component_update_bits(component, RT5616_D_MISC,
 					    RT5616_D_GATE_EN,
 					    RT5616_D_GATE_EN);
 		}
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, RT5616_D_MISC, RT5616_D_GATE_EN, 0);
-		snd_soc_write(codec, RT5616_PWR_DIG1, 0x0000);
-		snd_soc_write(codec, RT5616_PWR_DIG2, 0x0000);
-		snd_soc_write(codec, RT5616_PWR_VOL, 0x0000);
-		snd_soc_write(codec, RT5616_PWR_MIXER, 0x0000);
-		snd_soc_write(codec, RT5616_PWR_ANLG1, 0x0000);
-		snd_soc_write(codec, RT5616_PWR_ANLG2, 0x0000);
+		snd_soc_component_update_bits(component, RT5616_D_MISC, RT5616_D_GATE_EN, 0);
+		snd_soc_component_write(component, RT5616_PWR_DIG1, 0x0000);
+		snd_soc_component_write(component, RT5616_PWR_DIG2, 0x0000);
+		snd_soc_component_write(component, RT5616_PWR_VOL, 0x0000);
+		snd_soc_component_write(component, RT5616_PWR_MIXER, 0x0000);
+		snd_soc_component_write(component, RT5616_PWR_ANLG1, 0x0000);
+		snd_soc_component_write(component, RT5616_PWR_ANLG2, 0x0000);
 		break;
 
 	default:
@@ -1223,24 +1223,24 @@ static int rt5616_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5616_probe(struct snd_soc_codec *codec)
+static int rt5616_probe(struct snd_soc_component *component)
 {
-	struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+	struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 
 	/* Check if MCLK provided */
-	rt5616->mclk = devm_clk_get(codec->dev, "mclk");
+	rt5616->mclk = devm_clk_get(component->dev, "mclk");
 	if (PTR_ERR(rt5616->mclk) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	rt5616->codec = codec;
+	rt5616->component = component;
 
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5616_suspend(struct snd_soc_codec *codec)
+static int rt5616_suspend(struct snd_soc_component *component)
 {
-	struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+	struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5616->regmap, true);
 	regcache_mark_dirty(rt5616->regmap);
@@ -1248,9 +1248,9 @@ static int rt5616_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt5616_resume(struct snd_soc_codec *codec)
+static int rt5616_resume(struct snd_soc_component *component)
 {
-	struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+	struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5616->regmap, false);
 	regcache_sync(rt5616->regmap);
@@ -1294,20 +1294,20 @@ static struct snd_soc_dai_driver rt5616_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5616 = {
-	.probe = rt5616_probe,
-	.suspend = rt5616_suspend,
-	.resume = rt5616_resume,
-	.set_bias_level = rt5616_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt5616_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5616_snd_controls),
-		.dapm_widgets		= rt5616_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5616_dapm_widgets),
-		.dapm_routes		= rt5616_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5616_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5616 = {
+	.probe			= rt5616_probe,
+	.suspend		= rt5616_suspend,
+	.resume			= rt5616_resume,
+	.set_bias_level		= rt5616_set_bias_level,
+	.controls		= rt5616_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5616_snd_controls),
+	.dapm_widgets		= rt5616_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5616_dapm_widgets),
+	.dapm_routes		= rt5616_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5616_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt5616_regmap = {
@@ -1387,14 +1387,13 @@ static int rt5616_i2c_probe(struct i2c_client *i2c,
 	regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
 			   RT5616_PWR_LDO_DVO_MASK, RT5616_PWR_LDO_DVO_1_2V);
 
-	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5616,
+	return devm_snd_soc_register_component(&i2c->dev,
+				      &soc_component_dev_rt5616,
 				      rt5616_dai, ARRAY_SIZE(rt5616_dai));
 }
 
 static int rt5616_i2c_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&i2c->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index 55b04c5..cf6dce6 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -71,30 +71,30 @@ static const struct reg_default rt5631_reg[] = {
 /**
  * rt5631_write_index - write index register of 2nd layer
  */
-static void rt5631_write_index(struct snd_soc_codec *codec,
+static void rt5631_write_index(struct snd_soc_component *component,
 		unsigned int reg, unsigned int value)
 {
-	snd_soc_write(codec, RT5631_INDEX_ADD, reg);
-	snd_soc_write(codec, RT5631_INDEX_DATA, value);
+	snd_soc_component_write(component, RT5631_INDEX_ADD, reg);
+	snd_soc_component_write(component, RT5631_INDEX_DATA, value);
 }
 
 /**
  * rt5631_read_index - read index register of 2nd layer
  */
-static unsigned int rt5631_read_index(struct snd_soc_codec *codec,
+static unsigned int rt5631_read_index(struct snd_soc_component *component,
 				unsigned int reg)
 {
 	unsigned int value;
 
-	snd_soc_write(codec, RT5631_INDEX_ADD, reg);
-	value = snd_soc_read(codec, RT5631_INDEX_DATA);
+	snd_soc_component_write(component, RT5631_INDEX_ADD, reg);
+	value = snd_soc_component_read32(component, RT5631_INDEX_DATA);
 
 	return value;
 }
 
-static int rt5631_reset(struct snd_soc_codec *codec)
+static int rt5631_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, RT5631_RESET, 0);
+	return snd_soc_component_write(component, RT5631_RESET, 0);
 }
 
 static bool rt5631_volatile_register(struct device *dev, unsigned int reg)
@@ -187,8 +187,8 @@ static const DECLARE_TLV_DB_RANGE(mic_bst_tlv,
 static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = rt5631->dmic_used_flag;
 
@@ -198,8 +198,8 @@ static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
 static int rt5631_dmic_put(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
 	rt5631->dmic_used_flag = ucontrol->value.integer.value[0];
 	return 0;
@@ -286,78 +286,78 @@ static const struct snd_kcontrol_new rt5631_snd_controls[] = {
 static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, RT5631_GLOBAL_CLK_CTRL);
+	reg = snd_soc_component_read32(component, RT5631_GLOBAL_CLK_CTRL);
 	return reg & RT5631_SYSCLK_SOUR_SEL_PLL;
 }
 
 static int check_dmic_used(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 	return rt5631->dmic_used_flag;
 }
 
 static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, RT5631_OUTMIXER_L_CTRL);
+	reg = snd_soc_component_read32(component, RT5631_OUTMIXER_L_CTRL);
 	return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L);
 }
 
 static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, RT5631_OUTMIXER_R_CTRL);
+	reg = snd_soc_component_read32(component, RT5631_OUTMIXER_R_CTRL);
 	return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R);
 }
 
 static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, RT5631_SPK_MIXER_CTRL);
+	reg = snd_soc_component_read32(component, RT5631_SPK_MIXER_CTRL);
 	return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L);
 }
 
 static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, RT5631_SPK_MIXER_CTRL);
+	reg = snd_soc_component_read32(component, RT5631_SPK_MIXER_CTRL);
 	return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R);
 }
 
 static int check_adcl_select(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, RT5631_ADC_REC_MIXER);
+	reg = snd_soc_component_read32(component, RT5631_ADC_REC_MIXER);
 	return !(reg & RT5631_M_MIC1_TO_RECMIXER_L);
 }
 
 static int check_adcr_select(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, RT5631_ADC_REC_MIXER);
+	reg = snd_soc_component_read32(component, RT5631_ADC_REC_MIXER);
 	return !(reg & RT5631_M_MIC2_TO_RECMIXER_R);
 }
 
@@ -367,36 +367,36 @@ static int check_adcr_select(struct snd_soc_dapm_widget *source,
  *
  * When power on/off headphone, the depop sequence is done by hardware.
  */
-static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable)
+static void onebit_depop_power_stage(struct snd_soc_component *component, int enable)
 {
 	unsigned int soft_vol, hp_zc;
 
 	/* enable one-bit depop function */
-	snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+	snd_soc_component_update_bits(component, RT5631_DEPOP_FUN_CTRL_2,
 				RT5631_EN_ONE_BIT_DEPOP, 0);
 
 	/* keep soft volume and zero crossing setting */
-	soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
-	snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
-	hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+	soft_vol = snd_soc_component_read32(component, RT5631_SOFT_VOL_CTRL);
+	snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, 0);
+	hp_zc = snd_soc_component_read32(component, RT5631_INT_ST_IRQ_CTRL_2);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
 	if (enable) {
 		/* config one-bit depop parameter */
-		rt5631_write_index(codec, RT5631_TEST_MODE_CTRL, 0x84c0);
-		rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x309f);
-		rt5631_write_index(codec, RT5631_CP_INTL_REG2, 0x6530);
+		rt5631_write_index(component, RT5631_TEST_MODE_CTRL, 0x84c0);
+		rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x309f);
+		rt5631_write_index(component, RT5631_CP_INTL_REG2, 0x6530);
 		/* power on capless block */
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2,
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_2,
 				RT5631_EN_CAP_FREE_DEPOP);
 	} else {
 		/* power off capless block */
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0);
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_2, 0);
 		msleep(100);
 	}
 
 	/* recover soft volume and zero crossing setting */
-	snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
+	snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, soft_vol);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
 }
 
 /**
@@ -405,36 +405,36 @@ static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable)
  *
  * When mute/unmute headphone, the depop sequence is done by hardware.
  */
-static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable)
+static void onebit_depop_mute_stage(struct snd_soc_component *component, int enable)
 {
 	unsigned int soft_vol, hp_zc;
 
 	/* enable one-bit depop function */
-	snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+	snd_soc_component_update_bits(component, RT5631_DEPOP_FUN_CTRL_2,
 				RT5631_EN_ONE_BIT_DEPOP, 0);
 
 	/* keep soft volume and zero crossing setting */
-	soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
-	snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
-	hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+	soft_vol = snd_soc_component_read32(component, RT5631_SOFT_VOL_CTRL);
+	snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, 0);
+	hp_zc = snd_soc_component_read32(component, RT5631_INT_ST_IRQ_CTRL_2);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
 	if (enable) {
 		schedule_timeout_uninterruptible(msecs_to_jiffies(10));
 		/* config one-bit depop parameter */
-		rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f);
-		snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+		rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x307f);
+		snd_soc_component_update_bits(component, RT5631_HP_OUT_VOL,
 				RT5631_L_MUTE | RT5631_R_MUTE, 0);
 		msleep(300);
 	} else {
-		snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+		snd_soc_component_update_bits(component, RT5631_HP_OUT_VOL,
 			RT5631_L_MUTE | RT5631_R_MUTE,
 			RT5631_L_MUTE | RT5631_R_MUTE);
 		msleep(100);
 	}
 
 	/* recover soft volume and zero crossing setting */
-	snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
+	snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, soft_vol);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
 }
 
 /**
@@ -443,70 +443,70 @@ static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable)
  *
  * When power on/off headphone, the depop sequence is done in step by step.
  */
-static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable)
+static void depop_seq_power_stage(struct snd_soc_component *component, int enable)
 {
 	unsigned int soft_vol, hp_zc;
 
 	/* depop control by register */
-	snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+	snd_soc_component_update_bits(component, RT5631_DEPOP_FUN_CTRL_2,
 		RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
 
 	/* keep soft volume and zero crossing setting */
-	soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
-	snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
-	hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+	soft_vol = snd_soc_component_read32(component, RT5631_SOFT_VOL_CTRL);
+	snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, 0);
+	hp_zc = snd_soc_component_read32(component, RT5631_INT_ST_IRQ_CTRL_2);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
 	if (enable) {
 		/* config depop sequence parameter */
-		rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303e);
+		rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x303e);
 
 		/* power on headphone and charge pump */
-		snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+		snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
 			RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
 			RT5631_PWR_HP_R_AMP,
 			RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
 			RT5631_PWR_HP_R_AMP);
 
 		/* power on soft generator and depop mode2 */
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
 			RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP);
 		msleep(100);
 
 		/* stop depop mode */
-		snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+		snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
 			RT5631_PWR_HP_DEPOP_DIS, RT5631_PWR_HP_DEPOP_DIS);
 	} else {
 		/* config depop sequence parameter */
-		rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303F);
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+		rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x303F);
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
 			RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
 			RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
 		msleep(75);
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
 			RT5631_POW_ON_SOFT_GEN | RT5631_PD_HPAMP_L_ST_UP |
 			RT5631_PD_HPAMP_R_ST_UP);
 
 		/* start depop mode */
-		snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+		snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
 				RT5631_PWR_HP_DEPOP_DIS, 0);
 
 		/* config depop sequence parameter */
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
 			RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP |
 			RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
 		msleep(80);
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
 			RT5631_POW_ON_SOFT_GEN);
 
 		/* power down headphone and charge pump */
-		snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+		snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
 			RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
 			RT5631_PWR_HP_R_AMP, 0);
 	}
 
 	/* recover soft volume and zero crossing setting */
-	snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
+	snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, soft_vol);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
 }
 
 /**
@@ -515,75 +515,75 @@ static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable)
  *
  * When mute/unmute headphone, the depop sequence is done in step by step.
  */
-static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable)
+static void depop_seq_mute_stage(struct snd_soc_component *component, int enable)
 {
 	unsigned int soft_vol, hp_zc;
 
 	/* depop control by register */
-	snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+	snd_soc_component_update_bits(component, RT5631_DEPOP_FUN_CTRL_2,
 		RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
 
 	/* keep soft volume and zero crossing setting */
-	soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
-	snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
-	hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+	soft_vol = snd_soc_component_read32(component, RT5631_SOFT_VOL_CTRL);
+	snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, 0);
+	hp_zc = snd_soc_component_read32(component, RT5631_INT_ST_IRQ_CTRL_2);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
 	if (enable) {
 		schedule_timeout_uninterruptible(msecs_to_jiffies(10));
 
 		/* config depop sequence parameter */
-		rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+		rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x302f);
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
 			RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
 			RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
 			RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
 
-		snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+		snd_soc_component_update_bits(component, RT5631_HP_OUT_VOL,
 				RT5631_L_MUTE | RT5631_R_MUTE, 0);
 		msleep(160);
 	} else {
 		/* config depop sequence parameter */
-		rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
-		snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+		rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x302f);
+		snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
 			RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
 			RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
 			RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
 
-		snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+		snd_soc_component_update_bits(component, RT5631_HP_OUT_VOL,
 			RT5631_L_MUTE | RT5631_R_MUTE,
 			RT5631_L_MUTE | RT5631_R_MUTE);
 		msleep(150);
 	}
 
 	/* recover soft volume and zero crossing setting */
-	snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
+	snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, soft_vol);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
 }
 
 static int hp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMD:
 		if (rt5631->codec_version) {
-			onebit_depop_mute_stage(codec, 0);
-			onebit_depop_power_stage(codec, 0);
+			onebit_depop_mute_stage(component, 0);
+			onebit_depop_power_stage(component, 0);
 		} else {
-			depop_seq_mute_stage(codec, 0);
-			depop_seq_power_stage(codec, 0);
+			depop_seq_mute_stage(component, 0);
+			depop_seq_power_stage(component, 0);
 		}
 		break;
 
 	case SND_SOC_DAPM_POST_PMU:
 		if (rt5631->codec_version) {
-			onebit_depop_power_stage(codec, 1);
-			onebit_depop_mute_stage(codec, 1);
+			onebit_depop_power_stage(component, 1);
+			onebit_depop_mute_stage(component, 1);
 		} else {
-			depop_seq_power_stage(codec, 1);
-			depop_seq_mute_stage(codec, 1);
+			depop_seq_power_stage(component, 1);
+			depop_seq_mute_stage(component, 1);
 		}
 		break;
 
@@ -597,20 +597,20 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 static int set_dmic_params(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
 	switch (rt5631->rx_rate) {
 	case 44100:
 	case 48000:
-		snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+		snd_soc_component_update_bits(component, RT5631_DIG_MIC_CTRL,
 			RT5631_DMIC_CLK_CTRL_MASK,
 			RT5631_DMIC_CLK_CTRL_TO_32FS);
 		break;
 
 	case 32000:
 	case 22050:
-		snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+		snd_soc_component_update_bits(component, RT5631_DIG_MIC_CTRL,
 			RT5631_DMIC_CLK_CTRL_MASK,
 			RT5631_DMIC_CLK_CTRL_TO_64FS);
 		break;
@@ -618,7 +618,7 @@ static int set_dmic_params(struct snd_soc_dapm_widget *w,
 	case 16000:
 	case 11025:
 	case 8000:
-		snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+		snd_soc_component_update_bits(component, RT5631_DIG_MIC_CTRL,
 			RT5631_DMIC_CLK_CTRL_MASK,
 			RT5631_DMIC_CLK_CTRL_TO_128FS);
 		break;
@@ -1352,16 +1352,16 @@ static int get_coeff(int mclk, int rate, int timesofbclk)
 static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 	int timesofbclk = 32, coeff;
 	unsigned int iface = 0;
 
-	dev_dbg(codec->dev, "enter %s\n", __func__);
+	dev_dbg(component->dev, "enter %s\n", __func__);
 
 	rt5631->bclk_rate = snd_soc_params_to_bclk(params);
 	if (rt5631->bclk_rate < 0) {
-		dev_err(codec->dev, "Fail to get BCLK rate\n");
+		dev_err(component->dev, "Fail to get BCLK rate\n");
 		return rt5631->bclk_rate;
 	}
 	rt5631->rx_rate = params_rate(params);
@@ -1373,7 +1373,7 @@ static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
 		coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
 					timesofbclk);
 	if (coeff < 0) {
-		dev_err(codec->dev, "Fail to get coeff\n");
+		dev_err(component->dev, "Fail to get coeff\n");
 		return coeff;
 	}
 
@@ -1393,9 +1393,9 @@ static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5631_SDP_CTRL,
+	snd_soc_component_update_bits(component, RT5631_SDP_CTRL,
 		RT5631_SDP_I2S_DL_MASK, iface);
-	snd_soc_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL,
+	snd_soc_component_write(component, RT5631_STEREO_AD_DA_CLK_CTRL,
 					coeff_div[coeff].reg_val);
 
 	return 0;
@@ -1404,11 +1404,11 @@ static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
 static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
 						unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 	unsigned int iface = 0;
 
-	dev_dbg(codec->dev, "enter %s\n", __func__);
+	dev_dbg(component->dev, "enter %s\n", __func__);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -1448,7 +1448,7 @@ static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, RT5631_SDP_CTRL, iface);
+	snd_soc_component_write(component, RT5631_SDP_CTRL, iface);
 
 	return 0;
 }
@@ -1456,10 +1456,10 @@ static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "enter %s, syclk=%d\n", __func__, freq);
+	dev_dbg(component->dev, "enter %s, syclk=%d\n", __func__, freq);
 
 	if ((freq >= (256 * 8000)) && (freq <= (512 * 96000))) {
 		rt5631->sysclk = freq;
@@ -1472,16 +1472,16 @@ static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 	int i, ret = -EINVAL;
 
-	dev_dbg(codec->dev, "enter %s\n", __func__);
+	dev_dbg(component->dev, "enter %s\n", __func__);
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
-		snd_soc_update_bits(codec, RT5631_GLOBAL_CLK_CTRL,
+		snd_soc_component_update_bits(component, RT5631_GLOBAL_CLK_CTRL,
 			RT5631_SYSCLK_SOUR_SEL_MASK,
 			RT5631_SYSCLK_SOUR_SEL_MCLK);
 
@@ -1492,13 +1492,13 @@ static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++)
 			if (freq_in == codec_master_pll_div[i].pll_in &&
 			freq_out == codec_master_pll_div[i].pll_out) {
-				dev_info(codec->dev,
+				dev_info(component->dev,
 					"change PLL in master mode\n");
-				snd_soc_write(codec, RT5631_PLL_CTRL,
+				snd_soc_component_write(component, RT5631_PLL_CTRL,
 					codec_master_pll_div[i].reg_val);
 				schedule_timeout_uninterruptible(
 					msecs_to_jiffies(20));
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					RT5631_GLOBAL_CLK_CTRL,
 					RT5631_SYSCLK_SOUR_SEL_MASK |
 					RT5631_PLLCLK_SOUR_SEL_MASK,
@@ -1511,13 +1511,13 @@ static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++)
 			if (freq_in == codec_slave_pll_div[i].pll_in &&
 			freq_out == codec_slave_pll_div[i].pll_out) {
-				dev_info(codec->dev,
+				dev_info(component->dev,
 					"change PLL in slave mode\n");
-				snd_soc_write(codec, RT5631_PLL_CTRL,
+				snd_soc_component_write(component, RT5631_PLL_CTRL,
 					codec_slave_pll_div[i].reg_val);
 				schedule_timeout_uninterruptible(
 					msecs_to_jiffies(20));
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 					RT5631_GLOBAL_CLK_CTRL,
 					RT5631_SYSCLK_SOUR_SEL_MASK |
 					RT5631_PLLCLK_SOUR_SEL_MASK,
@@ -1531,26 +1531,26 @@ static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	return ret;
 }
 
-static int rt5631_set_bias_level(struct snd_soc_codec *codec,
+static int rt5631_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD2,
+		snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD2,
 			RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL,
 			RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
 				RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
 				RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
 			msleep(80);
-			snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+			snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
 				RT5631_PWR_FAST_VREF_CTRL,
 				RT5631_PWR_FAST_VREF_CTRL);
 			regcache_cache_only(rt5631->regmap, false);
@@ -1559,10 +1559,10 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
-		snd_soc_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
-		snd_soc_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
-		snd_soc_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
+		snd_soc_component_write(component, RT5631_PWR_MANAG_ADD1, 0x0000);
+		snd_soc_component_write(component, RT5631_PWR_MANAG_ADD2, 0x0000);
+		snd_soc_component_write(component, RT5631_PWR_MANAG_ADD3, 0x0000);
+		snd_soc_component_write(component, RT5631_PWR_MANAG_ADD4, 0x0000);
 		break;
 
 	default:
@@ -1572,48 +1572,48 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5631_probe(struct snd_soc_codec *codec)
+static int rt5631_probe(struct snd_soc_component *component)
 {
-	struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+	struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
-	val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
+	val = rt5631_read_index(component, RT5631_ADDA_MIXER_INTL_REG3);
 	if (val & 0x0002)
 		rt5631->codec_version = 1;
 	else
 		rt5631->codec_version = 0;
 
-	rt5631_reset(codec);
-	snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+	rt5631_reset(component);
+	snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
 		RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
 		RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
 	msleep(80);
-	snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+	snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
 		RT5631_PWR_FAST_VREF_CTRL, RT5631_PWR_FAST_VREF_CTRL);
 	/* enable HP zero cross */
-	snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18);
+	snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18);
 	/* power off ClassD auto Recovery */
 	if (rt5631->codec_version)
-		snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
+		snd_soc_component_update_bits(component, RT5631_INT_ST_IRQ_CTRL_2,
 					0x2000, 0x2000);
 	else
-		snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
+		snd_soc_component_update_bits(component, RT5631_INT_ST_IRQ_CTRL_2,
 					0x2000, 0);
 	/* DMIC */
 	if (rt5631->dmic_used_flag) {
-		snd_soc_update_bits(codec, RT5631_GPIO_CTRL,
+		snd_soc_component_update_bits(component, RT5631_GPIO_CTRL,
 			RT5631_GPIO_PIN_FUN_SEL_MASK |
 			RT5631_GPIO_DMIC_FUN_SEL_MASK,
 			RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC |
 			RT5631_GPIO_DMIC_FUN_SEL_DIMC);
-		snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+		snd_soc_component_update_bits(component, RT5631_DIG_MIC_CTRL,
 			RT5631_DMIC_L_CH_LATCH_MASK |
 			RT5631_DMIC_R_CH_LATCH_MASK,
 			RT5631_DMIC_L_CH_LATCH_FALLING |
 			RT5631_DMIC_R_CH_LATCH_RISING);
 	}
 
-	snd_soc_codec_init_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_init_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	return 0;
 }
@@ -1653,18 +1653,20 @@ static struct snd_soc_dai_driver rt5631_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
-	.probe = rt5631_probe,
-	.set_bias_level = rt5631_set_bias_level,
-	.suspend_bias_off = true,
-	.component_driver = {
-		.controls		= rt5631_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5631_snd_controls),
-		.dapm_widgets		= rt5631_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5631_dapm_widgets),
-		.dapm_routes		= rt5631_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5631_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5631 = {
+	.probe			= rt5631_probe,
+	.set_bias_level		= rt5631_set_bias_level,
+	.controls		= rt5631_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5631_snd_controls),
+	.dapm_widgets		= rt5631_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5631_dapm_widgets),
+	.dapm_routes		= rt5631_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5631_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct i2c_device_id rt5631_i2c_id[] = {
@@ -1712,14 +1714,14 @@ static int rt5631_i2c_probe(struct i2c_client *i2c,
 	if (IS_ERR(rt5631->regmap))
 		return PTR_ERR(rt5631->regmap);
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_rt5631,
 			rt5631_dai, ARRAY_SIZE(rt5631_dai));
 	return ret;
 }
 
 static int rt5631_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 438fe52..0556742 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -166,9 +166,9 @@ static const struct reg_default rt5640_reg[] = {
 	{ 0xff, 0x6231 },
 };
 
-static int rt5640_reset(struct snd_soc_codec *codec)
+static int rt5640_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, RT5640_RESET, 0);
+	return snd_soc_component_write(component, RT5640_RESET, 0);
 }
 
 static bool rt5640_volatile_register(struct device *dev, unsigned int reg)
@@ -461,17 +461,17 @@ static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 	int idx, rate;
 
 	rate = rt5640->sysclk / rl6231_get_pre_div(rt5640->regmap,
 		RT5640_ADDA_CLK1, RT5640_I2S_PD1_SFT);
 	idx = rl6231_calc_dmic_clk(rate);
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else
-		snd_soc_update_bits(codec, RT5640_DMIC, RT5640_DMIC_CLK_MASK,
+		snd_soc_component_update_bits(component, RT5640_DMIC, RT5640_DMIC_CLK_MASK,
 					idx << RT5640_DMIC_CLK_SFT);
 	return idx;
 }
@@ -479,10 +479,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int val;
 
-	val = snd_soc_read(codec, RT5640_GLB_CLK);
+	val = snd_soc_component_read32(component, RT5640_GLB_CLK);
 	val &= RT5640_SCLK_SRC_MASK;
 	if (val == RT5640_SCLK_SRC_PLL1)
 		return 1;
@@ -493,8 +493,8 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
 	if (!rt5640->asrc_en)
 		return 0;
@@ -930,9 +930,9 @@ static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP,
 static const struct snd_kcontrol_new rt5640_sdi_mux =
 	SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
 
-static void hp_amp_power_on(struct snd_soc_codec *codec)
+static void hp_amp_power_on(struct snd_soc_component *component)
 {
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
 	/* depop parameters */
 	regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
@@ -956,9 +956,9 @@ static void hp_amp_power_on(struct snd_soc_codec *codec)
 		RT5640_PWR_FV1 | RT5640_PWR_FV2);
 }
 
-static void rt5640_pmu_depop(struct snd_soc_codec *codec)
+static void rt5640_pmu_depop(struct snd_soc_component *component)
 {
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
 	regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
 		RT5640_DEPOP_MASK | RT5640_DIG_DP_MASK,
@@ -984,12 +984,12 @@ static void rt5640_pmu_depop(struct snd_soc_codec *codec)
 static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		rt5640_pmu_depop(codec);
+		rt5640_pmu_depop(component);
 		rt5640->hp_mute = 0;
 		break;
 
@@ -1008,22 +1008,22 @@ static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5640_lout_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		hp_amp_power_on(codec);
-		snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+		hp_amp_power_on(component);
+		snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
 			RT5640_PWR_LM, RT5640_PWR_LM);
-		snd_soc_update_bits(codec, RT5640_OUTPUT,
+		snd_soc_component_update_bits(component, RT5640_OUTPUT,
 			RT5640_L_MUTE | RT5640_R_MUTE, 0);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5640_OUTPUT,
+		snd_soc_component_update_bits(component, RT5640_OUTPUT,
 			RT5640_L_MUTE | RT5640_R_MUTE,
 			RT5640_L_MUTE | RT5640_R_MUTE);
-		snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
 			RT5640_PWR_LM, 0);
 		break;
 
@@ -1037,11 +1037,11 @@ static int rt5640_lout_event(struct snd_soc_dapm_widget *w,
 static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		hp_amp_power_on(codec);
+		hp_amp_power_on(component);
 		break;
 	default:
 		return 0;
@@ -1053,8 +1053,8 @@ static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
 static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -1671,14 +1671,14 @@ static const struct snd_soc_dapm_route rt5639_specific_dapm_routes[] = {
 	{"IF2 DAC R", NULL, "DAC R2 Power"},
 };
 
-static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
+static int get_sdp_info(struct snd_soc_component *component, int dai_id)
 {
 	int ret = 0, val;
 
-	if (codec == NULL)
+	if (component == NULL)
 		return -EINVAL;
 
-	val = snd_soc_read(codec, RT5640_I2S1_SDP);
+	val = snd_soc_component_read32(component, RT5640_I2S1_SDP);
 	val = (val & RT5640_I2S_IF_MASK) >> RT5640_I2S_IF_SFT;
 	switch (dai_id) {
 	case RT5640_AIF1:
@@ -1722,21 +1722,21 @@ static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
 static int rt5640_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, mask_clk;
 	int dai_sel, pre_div, bclk_ms, frame_size;
 
 	rt5640->lrck[dai->id] = params_rate(params);
 	pre_div = rl6231_get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]);
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+		dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
 			rt5640->lrck[dai->id], dai->id);
 		return -EINVAL;
 	}
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return frame_size;
 	}
 	if (frame_size > 32)
@@ -1766,26 +1766,26 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	dai_sel = get_sdp_info(codec, dai->id);
+	dai_sel = get_sdp_info(component, dai->id);
 	if (dai_sel < 0) {
-		dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
+		dev_err(component->dev, "Failed to get sdp info: %d\n", dai_sel);
 		return -EINVAL;
 	}
 	if (dai_sel & RT5640_U_IF1) {
 		mask_clk = RT5640_I2S_BCLK_MS1_MASK | RT5640_I2S_PD1_MASK;
 		val_clk = bclk_ms << RT5640_I2S_BCLK_MS1_SFT |
 			pre_div << RT5640_I2S_PD1_SFT;
-		snd_soc_update_bits(codec, RT5640_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5640_I2S1_SDP,
 			RT5640_I2S_DL_MASK, val_len);
-		snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5640_ADDA_CLK1, mask_clk, val_clk);
 	}
 	if (dai_sel & RT5640_U_IF2) {
 		mask_clk = RT5640_I2S_BCLK_MS2_MASK | RT5640_I2S_PD2_MASK;
 		val_clk = bclk_ms << RT5640_I2S_BCLK_MS2_SFT |
 			pre_div << RT5640_I2S_PD2_SFT;
-		snd_soc_update_bits(codec, RT5640_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5640_I2S2_SDP,
 			RT5640_I2S_DL_MASK, val_len);
-		snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5640_ADDA_CLK1, mask_clk, val_clk);
 	}
 
 	return 0;
@@ -1793,8 +1793,8 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 	int dai_sel;
 
@@ -1836,18 +1836,18 @@ static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	dai_sel = get_sdp_info(codec, dai->id);
+	dai_sel = get_sdp_info(component, dai->id);
 	if (dai_sel < 0) {
-		dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
+		dev_err(component->dev, "Failed to get sdp info: %d\n", dai_sel);
 		return -EINVAL;
 	}
 	if (dai_sel & RT5640_U_IF1) {
-		snd_soc_update_bits(codec, RT5640_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5640_I2S1_SDP,
 			RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK |
 			RT5640_I2S_DF_MASK, reg_val);
 	}
 	if (dai_sel & RT5640_U_IF2) {
-		snd_soc_update_bits(codec, RT5640_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5640_I2S2_SDP,
 			RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK |
 			RT5640_I2S_DF_MASK, reg_val);
 	}
@@ -1858,8 +1858,8 @@ static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	if (freq == rt5640->sysclk && clk_id == rt5640->sysclk_src)
@@ -1876,10 +1876,10 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
 		reg_val |= RT5640_SCLK_SRC_RCCLK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, RT5640_GLB_CLK,
+	snd_soc_component_update_bits(component, RT5640_GLB_CLK,
 		RT5640_SCLK_SRC_MASK, reg_val);
 	rt5640->sysclk = freq;
 	rt5640->sysclk_src = clk_id;
@@ -1891,8 +1891,8 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -1901,46 +1901,46 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5640->pll_in = 0;
 		rt5640->pll_out = 0;
-		snd_soc_update_bits(codec, RT5640_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5640_GLB_CLK,
 			RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_MCLK);
 		return 0;
 	}
 
 	switch (source) {
 	case RT5640_PLL1_S_MCLK:
-		snd_soc_update_bits(codec, RT5640_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5640_GLB_CLK,
 			RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_MCLK);
 		break;
 	case RT5640_PLL1_S_BCLK1:
-		snd_soc_update_bits(codec, RT5640_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5640_GLB_CLK,
 			RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK1);
 		break;
 	case RT5640_PLL1_S_BCLK2:
-		snd_soc_update_bits(codec, RT5640_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5640_GLB_CLK,
 			RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK2);
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
-	snd_soc_write(codec, RT5640_PLL_CTRL1,
+	snd_soc_component_write(component, RT5640_PLL_CTRL1,
 		pll_code.n_code << RT5640_PLL_N_SFT | pll_code.k_code);
-	snd_soc_write(codec, RT5640_PLL_CTRL2,
+	snd_soc_component_write(component, RT5640_PLL_CTRL2,
 		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5640_PLL_M_SFT |
 		pll_code.m_bp << RT5640_PLL_M_BP_SFT);
 
@@ -1951,10 +1951,10 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 	return 0;
 }
 
-static int rt5640_set_bias_level(struct snd_soc_codec *codec,
+static int rt5640_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1972,7 +1972,7 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
 		if (IS_ERR(rt5640->mclk))
 			break;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
 			clk_disable_unprepare(rt5640->mclk);
 		} else {
 			ret = clk_prepare_enable(rt5640->mclk);
@@ -1982,33 +1982,33 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (SND_SOC_BIAS_OFF == snd_soc_codec_get_bias_level(codec)) {
-			snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+		if (SND_SOC_BIAS_OFF == snd_soc_component_get_bias_level(component)) {
+			snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
 				RT5640_PWR_VREF1 | RT5640_PWR_MB |
 				RT5640_PWR_BG | RT5640_PWR_VREF2,
 				RT5640_PWR_VREF1 | RT5640_PWR_MB |
 				RT5640_PWR_BG | RT5640_PWR_VREF2);
 			usleep_range(10000, 15000);
-			snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
 				RT5640_PWR_FV1 | RT5640_PWR_FV2,
 				RT5640_PWR_FV1 | RT5640_PWR_FV2);
-			snd_soc_update_bits(codec, RT5640_DUMMY1,
+			snd_soc_component_update_bits(component, RT5640_DUMMY1,
 						0x0301, 0x0301);
-			snd_soc_update_bits(codec, RT5640_MICBIAS,
+			snd_soc_component_update_bits(component, RT5640_MICBIAS,
 						0x0030, 0x0030);
 		}
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, RT5640_DEPOP_M1, 0x0004);
-		snd_soc_write(codec, RT5640_DEPOP_M2, 0x1100);
-		snd_soc_update_bits(codec, RT5640_DUMMY1, 0x1, 0);
-		snd_soc_write(codec, RT5640_PWR_DIG1, 0x0000);
-		snd_soc_write(codec, RT5640_PWR_DIG2, 0x0000);
-		snd_soc_write(codec, RT5640_PWR_VOL, 0x0000);
-		snd_soc_write(codec, RT5640_PWR_MIXER, 0x0000);
-		snd_soc_write(codec, RT5640_PWR_ANLG1, 0x0000);
-		snd_soc_write(codec, RT5640_PWR_ANLG2, 0x0000);
+		snd_soc_component_write(component, RT5640_DEPOP_M1, 0x0004);
+		snd_soc_component_write(component, RT5640_DEPOP_M2, 0x1100);
+		snd_soc_component_update_bits(component, RT5640_DUMMY1, 0x1, 0);
+		snd_soc_component_write(component, RT5640_PWR_DIG1, 0x0000);
+		snd_soc_component_write(component, RT5640_PWR_DIG2, 0x0000);
+		snd_soc_component_write(component, RT5640_PWR_VOL, 0x0000);
+		snd_soc_component_write(component, RT5640_PWR_MIXER, 0x0000);
+		snd_soc_component_write(component, RT5640_PWR_ANLG1, 0x0000);
+		snd_soc_component_write(component, RT5640_PWR_ANLG2, 0x0000);
 		break;
 
 	default:
@@ -2018,10 +2018,10 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-int rt5640_dmic_enable(struct snd_soc_codec *codec,
+int rt5640_dmic_enable(struct snd_soc_component *component,
 		       bool dmic1_data_pin, bool dmic2_data_pin)
 {
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
 	regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
 		RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL);
@@ -2044,10 +2044,10 @@ int rt5640_dmic_enable(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(rt5640_dmic_enable);
 
-int rt5640_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src)
 {
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 	unsigned int asrc2_mask = 0;
 	unsigned int asrc2_value = 0;
 
@@ -2099,43 +2099,43 @@ int rt5640_sel_asrc_clk_src(struct snd_soc_codec *codec,
 			| (clk_src << RT5640_MAD_R_M_SFT);
 	}
 
-	snd_soc_update_bits(codec, RT5640_ASRC_2,
+	snd_soc_component_update_bits(component, RT5640_ASRC_2,
 		asrc2_mask, asrc2_value);
 
-	if (snd_soc_read(codec, RT5640_ASRC_2)) {
+	if (snd_soc_component_read32(component, RT5640_ASRC_2)) {
 		rt5640->asrc_en = true;
-		snd_soc_update_bits(codec, RT5640_JD_CTRL, 0x3, 0x3);
+		snd_soc_component_update_bits(component, RT5640_JD_CTRL, 0x3, 0x3);
 	} else {
 		rt5640->asrc_en = false;
-		snd_soc_update_bits(codec, RT5640_JD_CTRL, 0x3, 0x0);
+		snd_soc_component_update_bits(component, RT5640_JD_CTRL, 0x3, 0x0);
 	}
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src);
 
-static int rt5640_probe(struct snd_soc_codec *codec)
+static int rt5640_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
 	/* Check if MCLK provided */
-	rt5640->mclk = devm_clk_get(codec->dev, "mclk");
+	rt5640->mclk = devm_clk_get(component->dev, "mclk");
 	if (PTR_ERR(rt5640->mclk) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	rt5640->codec = codec;
+	rt5640->component = component;
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
-	snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
-	snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
-	snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
+	snd_soc_component_update_bits(component, RT5640_DUMMY1, 0x0301, 0x0301);
+	snd_soc_component_update_bits(component, RT5640_MICBIAS, 0x0030, 0x0030);
+	snd_soc_component_update_bits(component, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
 
-	switch (snd_soc_read(codec, RT5640_RESET) & RT5640_ID_MASK) {
+	switch (snd_soc_component_read32(component, RT5640_RESET) & RT5640_ID_MASK) {
 	case RT5640_ID_5640:
 	case RT5640_ID_5642:
-		snd_soc_add_codec_controls(codec,
+		snd_soc_add_component_controls(component,
 			rt5640_specific_snd_controls,
 			ARRAY_SIZE(rt5640_specific_snd_controls));
 		snd_soc_dapm_new_controls(dapm,
@@ -2154,32 +2154,30 @@ static int rt5640_probe(struct snd_soc_codec *codec)
 			ARRAY_SIZE(rt5639_specific_dapm_routes));
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"The driver is for RT5639 RT5640 or RT5642 only\n");
 		return -ENODEV;
 	}
 
 	if (rt5640->pdata.dmic_en)
-		rt5640_dmic_enable(codec, rt5640->pdata.dmic1_data_pin,
+		rt5640_dmic_enable(component, rt5640->pdata.dmic1_data_pin,
 					  rt5640->pdata.dmic2_data_pin);
 
 	return 0;
 }
 
-static int rt5640_remove(struct snd_soc_codec *codec)
+static void rt5640_remove(struct snd_soc_component *component)
 {
-	rt5640_reset(codec);
-
-	return 0;
+	rt5640_reset(component);
 }
 
 #ifdef CONFIG_PM
-static int rt5640_suspend(struct snd_soc_codec *codec)
+static int rt5640_suspend(struct snd_soc_component *component)
 {
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
-	rt5640_reset(codec);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
+	rt5640_reset(component);
 	regcache_cache_only(rt5640->regmap, true);
 	regcache_mark_dirty(rt5640->regmap);
 	if (gpio_is_valid(rt5640->pdata.ldo1_en))
@@ -2188,9 +2186,9 @@ static int rt5640_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt5640_resume(struct snd_soc_codec *codec)
+static int rt5640_resume(struct snd_soc_component *component)
 {
-	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
 	if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
 		gpio_set_value_cansleep(rt5640->pdata.ldo1_en, 1);
@@ -2259,21 +2257,22 @@ static struct snd_soc_dai_driver rt5640_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5640 = {
-	.probe = rt5640_probe,
-	.remove = rt5640_remove,
-	.suspend = rt5640_suspend,
-	.resume = rt5640_resume,
-	.set_bias_level = rt5640_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt5640_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5640_snd_controls),
-		.dapm_widgets		= rt5640_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5640_dapm_widgets),
-		.dapm_routes		= rt5640_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5640_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5640 = {
+	.probe			= rt5640_probe,
+	.remove			= rt5640_remove,
+	.suspend		= rt5640_suspend,
+	.resume			= rt5640_resume,
+	.set_bias_level		= rt5640_set_bias_level,
+	.controls		= rt5640_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5640_snd_controls),
+	.dapm_widgets		= rt5640_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5640_dapm_widgets),
+	.dapm_routes		= rt5640_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5640_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+
 };
 
 static const struct regmap_config rt5640_regmap = {
@@ -2427,17 +2426,11 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 
 	rt5640->hp_mute = 1;
 
-	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
+	return devm_snd_soc_register_component(&i2c->dev,
+				      &soc_component_dev_rt5640,
 				      rt5640_dai, ARRAY_SIZE(rt5640_dai));
 }
 
-static int rt5640_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-
-	return 0;
-}
-
 static struct i2c_driver rt5640_i2c_driver = {
 	.driver = {
 		.name = "rt5640",
@@ -2445,7 +2438,6 @@ static struct i2c_driver rt5640_i2c_driver = {
 		.of_match_table = of_match_ptr(rt5640_of_match),
 	},
 	.probe = rt5640_i2c_probe,
-	.remove   = rt5640_i2c_remove,
 	.id_table = rt5640_i2c_id,
 };
 module_i2c_driver(rt5640_i2c_driver);
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index b8a81173..c473e8a 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -2102,7 +2102,7 @@ enum {
 };
 
 struct rt5640_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt5640_platform_data pdata;
 	struct regmap *regmap;
 	struct clk *mclk;
@@ -2121,9 +2121,9 @@ struct rt5640_priv {
 	bool asrc_en;
 };
 
-int rt5640_dmic_enable(struct snd_soc_codec *codec,
+int rt5640_dmic_enable(struct snd_soc_component *component,
 		       bool dmic1_data_pin, bool dmic2_data_pin);
-int rt5640_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src);
 
 #endif
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 8f140c8..bc8d829 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -407,7 +407,7 @@ static const char *const rt5645_supply_names[] = {
 };
 
 struct rt5645_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt5645_platform_data pdata;
 	struct regmap *regmap;
 	struct i2c_client *i2c;
@@ -437,9 +437,9 @@ struct rt5645_priv {
 	int v_id;
 };
 
-static int rt5645_reset(struct snd_soc_codec *codec)
+static int rt5645_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, RT5645_RESET, 0);
+	return snd_soc_component_write(component, RT5645_RESET, 0);
 }
 
 static bool rt5645_volatile_register(struct device *dev, unsigned int reg)
@@ -846,17 +846,17 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 	int idx, rate;
 
 	rate = rt5645->sysclk / rl6231_get_pre_div(rt5645->regmap,
 		RT5645_ADDA_CLK1, RT5645_I2S_PD1_SFT);
 	idx = rl6231_calc_dmic_clk(rate);
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else
-		snd_soc_update_bits(codec, RT5645_DMIC_CTRL1,
+		snd_soc_component_update_bits(component, RT5645_DMIC_CTRL1,
 			RT5645_DMIC_CLK_MASK, idx << RT5645_DMIC_CLK_SFT);
 	return idx;
 }
@@ -864,10 +864,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int val;
 
-	val = snd_soc_read(codec, RT5645_GLB_CLK);
+	val = snd_soc_component_read32(component, RT5645_GLB_CLK);
 	val &= RT5645_SCLK_SRC_MASK;
 	if (val == RT5645_SCLK_SRC_PLL1)
 		return 1;
@@ -878,7 +878,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg, shift, val;
 
 	switch (source->shift) {
@@ -910,7 +910,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
 		return 0;
 	}
 
-	val = (snd_soc_read(codec, reg) >> shift) & 0xf;
+	val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
 	switch (val) {
 	case 1:
 	case 2:
@@ -923,9 +923,9 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
 
 }
 
-static int rt5645_enable_hweq(struct snd_soc_codec *codec)
+static int rt5645_enable_hweq(struct snd_soc_component *component)
 {
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < RT5645_HWEQ_NUM; i++) {
@@ -941,7 +941,7 @@ static int rt5645_enable_hweq(struct snd_soc_codec *codec)
 
 /**
  * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -953,7 +953,7 @@ static int rt5645_enable_hweq(struct snd_soc_codec *codec)
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5645_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src)
 {
 	unsigned int asrc2_mask = 0;
@@ -1009,11 +1009,11 @@ int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
 	}
 
 	if (asrc2_mask)
-		snd_soc_update_bits(codec, RT5645_ASRC_2,
+		snd_soc_component_update_bits(component, RT5645_ASRC_2,
 			asrc2_mask, asrc2_value);
 
 	if (asrc3_mask)
-		snd_soc_update_bits(codec, RT5645_ASRC_3,
+		snd_soc_component_update_bits(component, RT5645_ASRC_3,
 			asrc3_mask, asrc3_value);
 
 	return 0;
@@ -1678,56 +1678,56 @@ static const struct snd_kcontrol_new pdm1_r_vol_control =
 	SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_PDM_OUT_CTRL,
 		RT5645_M_PDM1_R, 1, 1);
 
-static void hp_amp_power(struct snd_soc_codec *codec, int on)
+static void hp_amp_power(struct snd_soc_component *component, int on)
 {
 	static int hp_amp_power_count;
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
 	if (on) {
 		if (hp_amp_power_count <= 0) {
 			if (rt5645->codec_type == CODEC_TYPE_RT5650) {
-				snd_soc_write(codec, RT5645_DEPOP_M2, 0x3100);
-				snd_soc_write(codec, RT5645_CHARGE_PUMP,
+				snd_soc_component_write(component, RT5645_DEPOP_M2, 0x3100);
+				snd_soc_component_write(component, RT5645_CHARGE_PUMP,
 					0x0e06);
-				snd_soc_write(codec, RT5645_DEPOP_M1, 0x000d);
+				snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d);
 				regmap_write(rt5645->regmap, RT5645_PR_BASE +
 					RT5645_HP_DCC_INT1, 0x9f01);
 				msleep(20);
-				snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+				snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 					RT5645_HP_CO_MASK, RT5645_HP_CO_EN);
 				regmap_write(rt5645->regmap, RT5645_PR_BASE +
 					0x3e, 0x7400);
-				snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
+				snd_soc_component_write(component, RT5645_DEPOP_M3, 0x0737);
 				regmap_write(rt5645->regmap, RT5645_PR_BASE +
 					RT5645_MAMP_INT_REG2, 0xfc00);
-				snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
+				snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
 				msleep(90);
 				rt5645->hp_on = true;
 			} else {
 				/* depop parameters */
-				snd_soc_update_bits(codec, RT5645_DEPOP_M2,
+				snd_soc_component_update_bits(component, RT5645_DEPOP_M2,
 					RT5645_DEPOP_MASK, RT5645_DEPOP_MAN);
-				snd_soc_write(codec, RT5645_DEPOP_M1, 0x000d);
+				snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d);
 				regmap_write(rt5645->regmap, RT5645_PR_BASE +
 					RT5645_HP_DCC_INT1, 0x9f01);
 				mdelay(150);
 				/* headphone amp power on */
-				snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+				snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 					RT5645_PWR_FV1 | RT5645_PWR_FV2, 0);
-				snd_soc_update_bits(codec, RT5645_PWR_VOL,
+				snd_soc_component_update_bits(component, RT5645_PWR_VOL,
 					RT5645_PWR_HV_L | RT5645_PWR_HV_R,
 					RT5645_PWR_HV_L | RT5645_PWR_HV_R);
-				snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+				snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 					RT5645_PWR_HP_L | RT5645_PWR_HP_R |
 					RT5645_PWR_HA,
 					RT5645_PWR_HP_L | RT5645_PWR_HP_R |
 					RT5645_PWR_HA);
 				mdelay(5);
-				snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+				snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 					RT5645_PWR_FV1 | RT5645_PWR_FV2,
 					RT5645_PWR_FV1 | RT5645_PWR_FV2);
 
-				snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+				snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 					RT5645_HP_CO_MASK | RT5645_HP_SG_MASK,
 					RT5645_HP_CO_EN | RT5645_HP_SG_EN);
 				regmap_write(rt5645->regmap, RT5645_PR_BASE +
@@ -1743,15 +1743,15 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
 			if (rt5645->codec_type == CODEC_TYPE_RT5650) {
 				regmap_write(rt5645->regmap, RT5645_PR_BASE +
 					0x3e, 0x7400);
-				snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
+				snd_soc_component_write(component, RT5645_DEPOP_M3, 0x0737);
 				regmap_write(rt5645->regmap, RT5645_PR_BASE +
 					RT5645_MAMP_INT_REG2, 0xfc00);
-				snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
+				snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
 				msleep(100);
-				snd_soc_write(codec, RT5645_DEPOP_M1, 0x0001);
+				snd_soc_component_write(component, RT5645_DEPOP_M1, 0x0001);
 
 			} else {
-				snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+				snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 					RT5645_HP_SG_MASK |
 					RT5645_HP_L_SMT_MASK |
 					RT5645_HP_R_SMT_MASK,
@@ -1759,11 +1759,11 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
 					RT5645_HP_L_SMT_DIS |
 					RT5645_HP_R_SMT_DIS);
 				/* headphone amp power down */
-				snd_soc_write(codec, RT5645_DEPOP_M1, 0x0000);
-				snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+				snd_soc_component_write(component, RT5645_DEPOP_M1, 0x0000);
+				snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 					RT5645_PWR_HP_L | RT5645_PWR_HP_R |
 					RT5645_PWR_HA, 0);
-				snd_soc_update_bits(codec, RT5645_DEPOP_M2,
+				snd_soc_component_update_bits(component, RT5645_DEPOP_M2,
 					RT5645_DEPOP_MASK, 0);
 			}
 		}
@@ -1773,15 +1773,15 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
 static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		hp_amp_power(codec, 1);
+		hp_amp_power(component, 1);
 		/* headphone unmute sequence */
 		if (rt5645->codec_type == CODEC_TYPE_RT5645) {
-			snd_soc_update_bits(codec, RT5645_DEPOP_M3,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M3,
 				RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
 				RT5645_CP_FQ3_MASK,
 				(RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) |
@@ -1789,16 +1789,16 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
 				(RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT));
 			regmap_write(rt5645->regmap, RT5645_PR_BASE +
 				RT5645_MAMP_INT_REG2, 0xfc00);
-			snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 				RT5645_SMT_TRIG_MASK, RT5645_SMT_TRIG_EN);
-			snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 				RT5645_RSTN_MASK, RT5645_RSTN_EN);
-			snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 				RT5645_RSTN_MASK | RT5645_HP_L_SMT_MASK |
 				RT5645_HP_R_SMT_MASK, RT5645_RSTN_DIS |
 				RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN);
 			msleep(40);
-			snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 				RT5645_HP_SG_MASK | RT5645_HP_L_SMT_MASK |
 				RT5645_HP_R_SMT_MASK, RT5645_HP_SG_DIS |
 				RT5645_HP_L_SMT_DIS | RT5645_HP_R_SMT_DIS);
@@ -1808,7 +1808,7 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_PRE_PMD:
 		/* headphone mute sequence */
 		if (rt5645->codec_type == CODEC_TYPE_RT5645) {
-			snd_soc_update_bits(codec, RT5645_DEPOP_M3,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M3,
 				RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
 				RT5645_CP_FQ3_MASK,
 				(RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) |
@@ -1816,17 +1816,17 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
 				(RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT));
 			regmap_write(rt5645->regmap, RT5645_PR_BASE +
 				RT5645_MAMP_INT_REG2, 0xfc00);
-			snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 				RT5645_HP_SG_MASK, RT5645_HP_SG_EN);
-			snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 				RT5645_RSTP_MASK, RT5645_RSTP_EN);
-			snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+			snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
 				RT5645_RSTP_MASK | RT5645_HP_L_SMT_MASK |
 				RT5645_HP_R_SMT_MASK, RT5645_RSTP_DIS |
 				RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN);
 			msleep(30);
 		}
-		hp_amp_power(codec, 0);
+		hp_amp_power(component, 0);
 		break;
 
 	default:
@@ -1839,25 +1839,25 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		rt5645_enable_hweq(codec);
-		snd_soc_update_bits(codec, RT5645_PWR_DIG1,
+		rt5645_enable_hweq(component);
+		snd_soc_component_update_bits(component, RT5645_PWR_DIG1,
 			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
 			RT5645_PWR_CLS_D_L,
 			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
 			RT5645_PWR_CLS_D_L);
-		snd_soc_update_bits(codec, RT5645_GEN_CTRL3,
+		snd_soc_component_update_bits(component, RT5645_GEN_CTRL3,
 			RT5645_DET_CLK_MASK, RT5645_DET_CLK_MODE1);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5645_GEN_CTRL3,
+		snd_soc_component_update_bits(component, RT5645_GEN_CTRL3,
 			RT5645_DET_CLK_MASK, RT5645_DET_CLK_DIS);
-		snd_soc_write(codec, RT5645_EQ_CTRL2, 0);
-		snd_soc_update_bits(codec, RT5645_PWR_DIG1,
+		snd_soc_component_write(component, RT5645_EQ_CTRL2, 0);
+		snd_soc_component_update_bits(component, RT5645_PWR_DIG1,
 			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
 			RT5645_PWR_CLS_D_L, 0);
 		break;
@@ -1872,24 +1872,24 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
 static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		hp_amp_power(codec, 1);
-		snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+		hp_amp_power(component, 1);
+		snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 			RT5645_PWR_LM, RT5645_PWR_LM);
-		snd_soc_update_bits(codec, RT5645_LOUT1,
+		snd_soc_component_update_bits(component, RT5645_LOUT1,
 			RT5645_L_MUTE | RT5645_R_MUTE, 0);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5645_LOUT1,
+		snd_soc_component_update_bits(component, RT5645_LOUT1,
 			RT5645_L_MUTE | RT5645_R_MUTE,
 			RT5645_L_MUTE | RT5645_R_MUTE);
-		snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 			RT5645_PWR_LM, 0);
-		hp_amp_power(codec, 0);
+		hp_amp_power(component, 0);
 		break;
 
 	default:
@@ -1902,16 +1902,16 @@ static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
 static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5645_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5645_PWR_ANLG2,
 			RT5645_PWR_BST2_P, RT5645_PWR_BST2_P);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5645_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5645_PWR_ANLG2,
 			RT5645_PWR_BST2_P, 0);
 		break;
 
@@ -1925,8 +1925,8 @@ static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
 static int rt5650_hp_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *k, int  event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -1946,17 +1946,17 @@ static int rt5650_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *k, int  event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+		snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
 			RT5645_MICBIAS1_POW_CTRL_SEL_MASK,
 			RT5645_MICBIAS1_POW_CTRL_SEL_M);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+		snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
 			RT5645_MICBIAS1_POW_CTRL_SEL_MASK,
 			RT5645_MICBIAS1_POW_CTRL_SEL_A);
 		break;
@@ -1971,17 +1971,17 @@ static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w,
 static int rt5645_set_micbias2_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *k, int  event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+		snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
 			RT5645_MICBIAS2_POW_CTRL_SEL_MASK,
 			RT5645_MICBIAS2_POW_CTRL_SEL_M);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+		snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
 			RT5645_MICBIAS2_POW_CTRL_SEL_MASK,
 			RT5645_MICBIAS2_POW_CTRL_SEL_A);
 		break;
@@ -2768,20 +2768,20 @@ static const struct snd_soc_dapm_route rt5645_old_dapm_routes[] = {
 static int rt5645_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, mask_clk, dl_sft;
 	int pre_div, bclk_ms, frame_size;
 
 	rt5645->lrck[dai->id] = params_rate(params);
 	pre_div = rl6231_get_clk_info(rt5645->sysclk, rt5645->lrck[dai->id]);
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting\n");
+		dev_err(component->dev, "Unsupported clock setting\n");
 		return -EINVAL;
 	}
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return -EINVAL;
 	}
 
@@ -2822,20 +2822,20 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
 	case RT5645_AIF1:
 		mask_clk = RT5645_I2S_PD1_MASK;
 		val_clk = pre_div << RT5645_I2S_PD1_SFT;
-		snd_soc_update_bits(codec, RT5645_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5645_I2S1_SDP,
 			(0x3 << dl_sft), (val_len << dl_sft));
-		snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5645_ADDA_CLK1, mask_clk, val_clk);
 		break;
 	case  RT5645_AIF2:
 		mask_clk = RT5645_I2S_BCLK_MS2_MASK | RT5645_I2S_PD2_MASK;
 		val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT |
 			pre_div << RT5645_I2S_PD2_SFT;
-		snd_soc_update_bits(codec, RT5645_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5645_I2S2_SDP,
 			(0x3 << dl_sft), (val_len << dl_sft));
-		snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5645_ADDA_CLK1, mask_clk, val_clk);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 
@@ -2844,8 +2844,8 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0, pol_sft;
 
 	switch (rt5645->codec_type) {
@@ -2896,17 +2896,17 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	}
 	switch (dai->id) {
 	case RT5645_AIF1:
-		snd_soc_update_bits(codec, RT5645_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5645_I2S1_SDP,
 			RT5645_I2S_MS_MASK | (1 << pol_sft) |
 			RT5645_I2S_DF_MASK, reg_val);
 		break;
 	case RT5645_AIF2:
-		snd_soc_update_bits(codec, RT5645_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5645_I2S2_SDP,
 			RT5645_I2S_MS_MASK | (1 << pol_sft) |
 			RT5645_I2S_DF_MASK, reg_val);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 	return 0;
@@ -2915,8 +2915,8 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	if (freq == rt5645->sysclk && clk_id == rt5645->sysclk_src)
@@ -2933,10 +2933,10 @@ static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai,
 		reg_val |= RT5645_SCLK_SRC_RCCLK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, RT5645_GLB_CLK,
+	snd_soc_component_update_bits(component, RT5645_GLB_CLK,
 		RT5645_SCLK_SRC_MASK, reg_val);
 	rt5645->sysclk = freq;
 	rt5645->sysclk_src = clk_id;
@@ -2949,8 +2949,8 @@ static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -2959,54 +2959,54 @@ static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5645->pll_in = 0;
 		rt5645->pll_out = 0;
-		snd_soc_update_bits(codec, RT5645_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5645_GLB_CLK,
 			RT5645_SCLK_SRC_MASK, RT5645_SCLK_SRC_MCLK);
 		return 0;
 	}
 
 	switch (source) {
 	case RT5645_PLL1_S_MCLK:
-		snd_soc_update_bits(codec, RT5645_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5645_GLB_CLK,
 			RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_MCLK);
 		break;
 	case RT5645_PLL1_S_BCLK1:
 	case RT5645_PLL1_S_BCLK2:
 		switch (dai->id) {
 		case RT5645_AIF1:
-			snd_soc_update_bits(codec, RT5645_GLB_CLK,
+			snd_soc_component_update_bits(component, RT5645_GLB_CLK,
 				RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_BCLK1);
 			break;
 		case  RT5645_AIF2:
-			snd_soc_update_bits(codec, RT5645_GLB_CLK,
+			snd_soc_component_update_bits(component, RT5645_GLB_CLK,
 				RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_BCLK2);
 			break;
 		default:
-			dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+			dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 			return -EINVAL;
 		}
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
-	snd_soc_write(codec, RT5645_PLL_CTRL1,
+	snd_soc_component_write(component, RT5645_PLL_CTRL1,
 		pll_code.n_code << RT5645_PLL_N_SFT | pll_code.k_code);
-	snd_soc_write(codec, RT5645_PLL_CTRL2,
+	snd_soc_component_write(component, RT5645_PLL_CTRL2,
 		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5645_PLL_M_SFT |
 		pll_code.m_bp << RT5645_PLL_M_BP_SFT);
 
@@ -3020,8 +3020,8 @@ static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 	unsigned int i_slot_sft, o_slot_sft, i_width_sht, o_width_sht, en_sft;
 	unsigned int mask, val = 0;
 
@@ -3044,7 +3044,7 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	if (rx_mask || tx_mask) {
 		val |= (1 << en_sft);
 		if (rt5645->codec_type == CODEC_TYPE_RT5645)
-			snd_soc_update_bits(codec, RT5645_BASS_BACK,
+			snd_soc_component_update_bits(component, RT5645_BASS_BACK,
 				RT5645_G_BB_BST_MASK, RT5645_G_BB_BST_25DB);
 	}
 
@@ -3078,45 +3078,45 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 		break;
 	}
 
-	snd_soc_update_bits(codec, RT5645_TDM_CTRL_1, mask, val);
+	snd_soc_component_update_bits(component, RT5645_TDM_CTRL_1, mask, val);
 
 	return 0;
 }
 
-static int rt5645_set_bias_level(struct snd_soc_codec *codec,
+static int rt5645_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
-		if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
-			snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+		if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
+			snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 				RT5645_PWR_VREF1 | RT5645_PWR_MB |
 				RT5645_PWR_BG | RT5645_PWR_VREF2,
 				RT5645_PWR_VREF1 | RT5645_PWR_MB |
 				RT5645_PWR_BG | RT5645_PWR_VREF2);
 			mdelay(10);
-			snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 				RT5645_PWR_FV1 | RT5645_PWR_FV2,
 				RT5645_PWR_FV1 | RT5645_PWR_FV2);
-			snd_soc_update_bits(codec, RT5645_GEN_CTRL1,
+			snd_soc_component_update_bits(component, RT5645_GEN_CTRL1,
 				RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL);
 		}
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 			RT5645_PWR_VREF1 | RT5645_PWR_MB |
 			RT5645_PWR_BG | RT5645_PWR_VREF2,
 			RT5645_PWR_VREF1 | RT5645_PWR_MB |
 			RT5645_PWR_BG | RT5645_PWR_VREF2);
 		mdelay(10);
-		snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 			RT5645_PWR_FV1 | RT5645_PWR_FV2,
 			RT5645_PWR_FV1 | RT5645_PWR_FV2);
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
 			msleep(40);
 			if (rt5645->en_button_func)
 				queue_delayed_work(system_power_efficient_wq,
@@ -3126,11 +3126,11 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100);
+		snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1100);
 		if (!rt5645->en_button_func)
-			snd_soc_update_bits(codec, RT5645_GEN_CTRL1,
+			snd_soc_component_update_bits(component, RT5645_GEN_CTRL1,
 					RT5645_DIG_GATE_CTRL, 0);
-		snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
 				RT5645_PWR_VREF1 | RT5645_PWR_MB |
 				RT5645_PWR_BG | RT5645_PWR_VREF2 |
 				RT5645_PWR_FV1 | RT5645_PWR_FV2, 0x0);
@@ -3143,27 +3143,27 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
+static void rt5645_enable_push_button_irq(struct snd_soc_component *component,
 	bool enable)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	if (enable) {
 		snd_soc_dapm_force_enable_pin(dapm, "ADC L power");
 		snd_soc_dapm_force_enable_pin(dapm, "ADC R power");
 		snd_soc_dapm_sync(dapm);
 
-		snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD1, 0x3, 0x3);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component, RT5650_4BTN_IL_CMD1, 0x3, 0x3);
+		snd_soc_component_update_bits(component,
 					RT5645_INT_IRQ_ST, 0x8, 0x8);
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 					RT5650_4BTN_IL_CMD2, 0x8000, 0x8000);
-		snd_soc_read(codec, RT5650_4BTN_IL_CMD1);
+		snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1);
 		pr_debug("%s read %x = %x\n", __func__, RT5650_4BTN_IL_CMD1,
-			snd_soc_read(codec, RT5650_4BTN_IL_CMD1));
+			snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1));
 	} else {
-		snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD2, 0x8000, 0x0);
-		snd_soc_update_bits(codec, RT5645_INT_IRQ_ST, 0x8, 0x0);
+		snd_soc_component_update_bits(component, RT5650_4BTN_IL_CMD2, 0x8000, 0x0);
+		snd_soc_component_update_bits(component, RT5645_INT_IRQ_ST, 0x8, 0x0);
 
 		snd_soc_dapm_disable_pin(dapm, "ADC L power");
 		snd_soc_dapm_disable_pin(dapm, "ADC R power");
@@ -3171,10 +3171,10 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
 	}
 }
 
-static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5645_jack_detect(struct snd_soc_component *component, int jack_insert)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (jack_insert) {
@@ -3208,12 +3208,12 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 		msleep(600);
 		regmap_read(rt5645->regmap, RT5645_IN1_CTRL3, &val);
 		val &= 0x7;
-		dev_dbg(codec->dev, "val = %d\n", val);
+		dev_dbg(component->dev, "val = %d\n", val);
 
 		if (val == 1 || val == 2) {
 			rt5645->jack_type = SND_JACK_HEADSET;
 			if (rt5645->en_button_func) {
-				rt5645_enable_push_button_irq(codec, true);
+				rt5645_enable_push_button_irq(component, true);
 			}
 		} else {
 			snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
@@ -3235,7 +3235,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 			RT5645_CBJ_BST1_EN, 0);
 
 		if (rt5645->en_button_func)
-			rt5645_enable_push_button_irq(codec, false);
+			rt5645_enable_push_button_irq(component, false);
 
 		if (rt5645->pdata.jd_mode == 0)
 			snd_soc_dapm_disable_pin(dapm, "LDO2");
@@ -3249,25 +3249,25 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 	return rt5645->jack_type;
 }
 
-static int rt5645_button_detect(struct snd_soc_codec *codec)
+static int rt5645_button_detect(struct snd_soc_component *component)
 {
 	int btn_type, val;
 
-	val = snd_soc_read(codec, RT5650_4BTN_IL_CMD1);
+	val = snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1);
 	pr_debug("val=0x%x\n", val);
 	btn_type = val & 0xfff0;
-	snd_soc_write(codec, RT5650_4BTN_IL_CMD1, val);
+	snd_soc_component_write(component, RT5650_4BTN_IL_CMD1, val);
 
 	return btn_type;
 }
 
 static irqreturn_t rt5645_irq(int irq, void *data);
 
-int rt5645_set_jack_detect(struct snd_soc_codec *codec,
+int rt5645_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
 	struct snd_soc_jack *btn_jack)
 {
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
 	rt5645->hp_jack = hp_jack;
 	rt5645->mic_jack = mic_jack;
@@ -3291,16 +3291,16 @@ static void rt5645_jack_detect_work(struct work_struct *work)
 		container_of(work, struct rt5645_priv, jack_detect_work.work);
 	int val, btn_type, gpio_state = 0, report = 0;
 
-	if (!rt5645->codec)
+	if (!rt5645->component)
 		return;
 
 	switch (rt5645->pdata.jd_mode) {
 	case 0: /* Not using rt5645 JD */
 		if (rt5645->gpiod_hp_det) {
 			gpio_state = gpiod_get_value(rt5645->gpiod_hp_det);
-			dev_dbg(rt5645->codec->dev, "gpio_state = %d\n",
+			dev_dbg(rt5645->component->dev, "gpio_state = %d\n",
 				gpio_state);
-			report = rt5645_jack_detect(rt5645->codec, gpio_state);
+			report = rt5645_jack_detect(rt5645->component, gpio_state);
 		}
 		snd_soc_jack_report(rt5645->hp_jack,
 				    report, SND_JACK_HEADPHONE);
@@ -3308,20 +3308,20 @@ static void rt5645_jack_detect_work(struct work_struct *work)
 				    report, SND_JACK_MICROPHONE);
 		return;
 	default: /* read rt5645 jd1_1 status */
-		val = snd_soc_read(rt5645->codec, RT5645_INT_IRQ_ST) & 0x1000;
+		val = snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000;
 		break;
 
 	}
 
 	if (!val && (rt5645->jack_type == 0)) { /* jack in */
-		report = rt5645_jack_detect(rt5645->codec, 1);
+		report = rt5645_jack_detect(rt5645->component, 1);
 	} else if (!val && rt5645->jack_type != 0) {
 		/* for push button and jack out */
 		btn_type = 0;
-		if (snd_soc_read(rt5645->codec, RT5645_INT_IRQ_ST) & 0x4) {
+		if (snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x4) {
 			/* button pressed */
 			report = SND_JACK_HEADSET;
-			btn_type = rt5645_button_detect(rt5645->codec);
+			btn_type = rt5645_button_detect(rt5645->component);
 			/* rt5650 can report three kinds of button behavior,
 			   one click, double click and hold. However,
 			   currently we will report button pressed/released
@@ -3351,7 +3351,7 @@ static void rt5645_jack_detect_work(struct work_struct *work)
 			case 0x0000: /* unpressed */
 				break;
 			default:
-				dev_err(rt5645->codec->dev,
+				dev_err(rt5645->component->dev,
 					"Unexpected button code 0x%04x\n",
 					btn_type);
 				break;
@@ -3366,9 +3366,9 @@ static void rt5645_jack_detect_work(struct work_struct *work)
 	} else {
 		/* jack out */
 		report = 0;
-		snd_soc_update_bits(rt5645->codec,
+		snd_soc_component_update_bits(rt5645->component,
 				    RT5645_INT_IRQ_ST, 0x1, 0x0);
-		rt5645_jack_detect(rt5645->codec, 0);
+		rt5645_jack_detect(rt5645->component, 0);
 	}
 
 	snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE);
@@ -3406,12 +3406,12 @@ static void rt5645_btn_check_callback(struct timer_list *t)
 		   &rt5645->jack_detect_work, msecs_to_jiffies(5));
 }
 
-static int rt5645_probe(struct snd_soc_codec *codec)
+static int rt5645_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
-	rt5645->codec = codec;
+	rt5645->component = component;
 
 	switch (rt5645->codec_type) {
 	case CODEC_TYPE_RT5645:
@@ -3437,7 +3437,7 @@ static int rt5645_probe(struct snd_soc_codec *codec)
 		break;
 	}
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
 	/* for JD function */
 	if (rt5645->pdata.jd_mode) {
@@ -3447,24 +3447,23 @@ static int rt5645_probe(struct snd_soc_codec *codec)
 	}
 
 	if (rt5645->pdata.long_name)
-		codec->component.card->long_name = rt5645->pdata.long_name;
+		component->card->long_name = rt5645->pdata.long_name;
 
-	rt5645->eq_param = devm_kzalloc(codec->dev,
+	rt5645->eq_param = devm_kzalloc(component->dev,
 		RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL);
 
 	return 0;
 }
 
-static int rt5645_remove(struct snd_soc_codec *codec)
+static void rt5645_remove(struct snd_soc_component *component)
 {
-	rt5645_reset(codec);
-	return 0;
+	rt5645_reset(component);
 }
 
 #ifdef CONFIG_PM
-static int rt5645_suspend(struct snd_soc_codec *codec)
+static int rt5645_suspend(struct snd_soc_component *component)
 {
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5645->regmap, true);
 	regcache_mark_dirty(rt5645->regmap);
@@ -3472,9 +3471,9 @@ static int rt5645_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt5645_resume(struct snd_soc_codec *codec)
+static int rt5645_resume(struct snd_soc_component *component)
 {
-	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5645->regmap, false);
 	regcache_sync(rt5645->regmap);
@@ -3539,21 +3538,21 @@ static struct snd_soc_dai_driver rt5645_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5645 = {
-	.probe = rt5645_probe,
-	.remove = rt5645_remove,
-	.suspend = rt5645_suspend,
-	.resume = rt5645_resume,
-	.set_bias_level = rt5645_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt5645_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5645_snd_controls),
-		.dapm_widgets		= rt5645_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5645_dapm_widgets),
-		.dapm_routes		= rt5645_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5645_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5645 = {
+	.probe			= rt5645_probe,
+	.remove			= rt5645_remove,
+	.suspend		= rt5645_suspend,
+	.resume			= rt5645_resume,
+	.set_bias_level		= rt5645_set_bias_level,
+	.controls		= rt5645_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5645_snd_controls),
+	.dapm_widgets		= rt5645_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5645_dapm_widgets),
+	.dapm_routes		= rt5645_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5645_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt5645_regmap = {
@@ -4028,7 +4027,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
 		}
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645,
+	ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5645,
 				     rt5645_dai, ARRAY_SIZE(rt5645_dai));
 	if (ret)
 		goto err_irq;
@@ -4054,7 +4053,6 @@ static int rt5645_i2c_remove(struct i2c_client *i2c)
 	cancel_delayed_work_sync(&rt5645->rcclock_work);
 	del_timer_sync(&rt5645->btn_check_timer);
 
-	snd_soc_unregister_codec(&i2c->dev);
 	regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
 
 	return 0;
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index 940325b..cc24557 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -2200,10 +2200,10 @@ enum {
 	RT5645_AD_MONO_R_FILTER = (0x1 << 5),
 };
 
-int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5645_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src);
 
-int rt5645_set_jack_detect(struct snd_soc_codec *codec,
+int rt5645_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
 	struct snd_soc_jack *btn_jack);
 #endif /* __RT5645_H__ */
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index 45a7304..6b5669f 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -19,7 +19,6 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/acpi.h>
-#include <linux/dmi.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -32,10 +31,6 @@
 #include "rl6231.h"
 #include "rt5651.h"
 
-#define RT5651_JD_MAP(quirk)	((quirk) & GENMASK(7, 0))
-#define RT5651_IN2_DIFF		BIT(16)
-#define RT5651_DMIC_EN		BIT(17)
-
 #define RT5651_DEVICE_ID_VALUE 0x6281
 
 #define RT5651_PR_RANGE_BASE (0xff + 1)
@@ -43,8 +38,6 @@
 
 #define RT5651_PR_BASE (RT5651_PR_RANGE_BASE + (0 * RT5651_PR_SPACING))
 
-static unsigned long rt5651_quirk;
-
 static const struct regmap_range_cfg rt5651_ranges[] = {
 	{ .name = "PR", .range_min = RT5651_PR_BASE,
 	  .range_max = RT5651_PR_BASE + 0xb4,
@@ -384,36 +377,22 @@ static const struct snd_kcontrol_new rt5651_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 	int idx, rate;
 
 	rate = rt5651->sysclk / rl6231_get_pre_div(rt5651->regmap,
 		RT5651_ADDA_CLK1, RT5651_I2S_PD1_SFT);
 	idx = rl6231_calc_dmic_clk(rate);
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else
-		snd_soc_update_bits(codec, RT5651_DMIC, RT5651_DMIC_CLK_MASK,
+		snd_soc_component_update_bits(component, RT5651_DMIC, RT5651_DMIC_CLK_MASK,
 					idx << RT5651_DMIC_CLK_SFT);
 
 	return idx;
 }
 
-static int is_sysclk_from_pll(struct snd_soc_dapm_widget *source,
-			 struct snd_soc_dapm_widget *sink)
-{
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	unsigned int val;
-
-	val = snd_soc_read(codec, RT5651_GLB_CLK);
-	val &= RT5651_SCLK_SRC_MASK;
-	if (val == RT5651_SCLK_SRC_PLL1)
-		return 1;
-	else
-		return 0;
-}
-
 /* Digital Mixer */
 static const struct snd_kcontrol_new rt5651_sto1_adc_l_mix[] = {
 	SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO1_ADC_MIXER,
@@ -703,8 +682,8 @@ static const struct snd_kcontrol_new rt5651_pdm_r_mux =
 static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -741,8 +720,8 @@ static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w,
 static int rt5651_hp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -786,8 +765,8 @@ static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
 
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -806,16 +785,16 @@ static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w,
 static int rt5651_bst1_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
 			RT5651_PWR_BST1_OP2, RT5651_PWR_BST1_OP2);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
 			RT5651_PWR_BST1_OP2, 0);
 		break;
 
@@ -829,16 +808,16 @@ static int rt5651_bst1_event(struct snd_soc_dapm_widget *w,
 static int rt5651_bst2_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
 			RT5651_PWR_BST2_OP2, RT5651_PWR_BST2_OP2);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
 			RT5651_PWR_BST2_OP2, 0);
 		break;
 
@@ -852,16 +831,16 @@ static int rt5651_bst2_event(struct snd_soc_dapm_widget *w,
 static int rt5651_bst3_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
 			RT5651_PWR_BST3_OP2, RT5651_PWR_BST3_OP2);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
 			RT5651_PWR_BST3_OP2, 0);
 		break;
 
@@ -885,12 +864,6 @@ static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY_S("ADC ASRC", 1, RT5651_PLL_MODE_2,
 			      11, 0, NULL, 0),
 
-	SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2,
-			RT5651_PWR_PLL_BIT, 0, NULL, 0),
-	/* Input Side */
-	SND_SOC_DAPM_SUPPLY("JD Power", RT5651_PWR_ANLG2,
-		RT5651_PWM_JD_M_BIT, 0, NULL, 0),
-
 	/* micbias */
 	SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1,
 			RT5651_PWR_LDO_BIT, 0, NULL, 0),
@@ -1169,7 +1142,6 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
 	{"Stereo1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux"},
 	{"Stereo1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux"},
 	{"Stereo1 ADC MIXL", NULL, "Stereo1 Filter"},
-	{"Stereo1 Filter", NULL, "PLL1", is_sysclk_from_pll},
 	{"Stereo1 Filter", NULL, "ADC ASRC"},
 
 	{"Stereo1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux"},
@@ -1179,7 +1151,6 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
 	{"Stereo2 ADC MIXL", "ADC1 Switch", "Stereo2 ADC L1 Mux"},
 	{"Stereo2 ADC MIXL", "ADC2 Switch", "Stereo2 ADC L2 Mux"},
 	{"Stereo2 ADC MIXL", NULL, "Stereo2 Filter"},
-	{"Stereo2 Filter", NULL, "PLL1", is_sysclk_from_pll},
 	{"Stereo2 Filter", NULL, "ADC ASRC"},
 
 	{"Stereo2 ADC MIXR", "ADC1 Switch", "Stereo2 ADC R1 Mux"},
@@ -1246,10 +1217,8 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
 	{"PDM R Mux", "DD MIX", "DAC MIXR"},
 
 	{"DAC L1", NULL, "Stereo DAC MIXL"},
-	{"DAC L1", NULL, "PLL1", is_sysclk_from_pll},
 	{"DAC L1", NULL, "DAC L1 Power"},
 	{"DAC R1", NULL, "Stereo DAC MIXR"},
-	{"DAC R1", NULL, "PLL1", is_sysclk_from_pll},
 	{"DAC R1", NULL, "DAC R1 Power"},
 
 	{"DD MIXL", "DAC L1 Switch", "DAC MIXL"},
@@ -1313,8 +1282,8 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
 static int rt5651_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, mask_clk;
 	int pre_div, bclk_ms, frame_size;
 
@@ -1322,12 +1291,12 @@ static int rt5651_hw_params(struct snd_pcm_substream *substream,
 	pre_div = rl6231_get_clk_info(rt5651->sysclk, rt5651->lrck[dai->id]);
 
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting\n");
+		dev_err(component->dev, "Unsupported clock setting\n");
 		return -EINVAL;
 	}
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return -EINVAL;
 	}
 	bclk_ms = frame_size > 32 ? 1 : 0;
@@ -1358,19 +1327,19 @@ static int rt5651_hw_params(struct snd_pcm_substream *substream,
 	case RT5651_AIF1:
 		mask_clk = RT5651_I2S_PD1_MASK;
 		val_clk = pre_div << RT5651_I2S_PD1_SFT;
-		snd_soc_update_bits(codec, RT5651_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5651_I2S1_SDP,
 			RT5651_I2S_DL_MASK, val_len);
-		snd_soc_update_bits(codec, RT5651_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5651_ADDA_CLK1, mask_clk, val_clk);
 		break;
 	case RT5651_AIF2:
 		mask_clk = RT5651_I2S_BCLK_MS2_MASK | RT5651_I2S_PD2_MASK;
 		val_clk = pre_div << RT5651_I2S_PD2_SFT;
-		snd_soc_update_bits(codec, RT5651_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5651_I2S2_SDP,
 			RT5651_I2S_DL_MASK, val_len);
-		snd_soc_update_bits(codec, RT5651_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5651_ADDA_CLK1, mask_clk, val_clk);
 		break;
 	default:
-		dev_err(codec->dev, "Wrong dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Wrong dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 
@@ -1379,8 +1348,8 @@ static int rt5651_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1423,17 +1392,17 @@ static int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (dai->id) {
 	case RT5651_AIF1:
-		snd_soc_update_bits(codec, RT5651_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5651_I2S1_SDP,
 			RT5651_I2S_MS_MASK | RT5651_I2S_BP_MASK |
 			RT5651_I2S_DF_MASK, reg_val);
 		break;
 	case RT5651_AIF2:
-		snd_soc_update_bits(codec, RT5651_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5651_I2S2_SDP,
 			RT5651_I2S_MS_MASK | RT5651_I2S_BP_MASK |
 			RT5651_I2S_DF_MASK, reg_val);
 		break;
 	default:
-		dev_err(codec->dev, "Wrong dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Wrong dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 	return 0;
@@ -1442,9 +1411,10 @@ static int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5651_set_dai_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
+	unsigned int pll_bit = 0;
 
 	if (freq == rt5651->sysclk && clk_id == rt5651->sysclk_src)
 		return 0;
@@ -1455,15 +1425,18 @@ static int rt5651_set_dai_sysclk(struct snd_soc_dai *dai,
 		break;
 	case RT5651_SCLK_S_PLL1:
 		reg_val |= RT5651_SCLK_SRC_PLL1;
+		pll_bit |= RT5651_PWR_PLL;
 		break;
 	case RT5651_SCLK_S_RCCLK:
 		reg_val |= RT5651_SCLK_SRC_RCCLK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, RT5651_GLB_CLK,
+	snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
+		RT5651_PWR_PLL, pll_bit);
+	snd_soc_component_update_bits(component, RT5651_GLB_CLK,
 		RT5651_SCLK_SRC_MASK, reg_val);
 	rt5651->sysclk = freq;
 	rt5651->sysclk_src = clk_id;
@@ -1476,8 +1449,8 @@ static int rt5651_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -1486,46 +1459,46 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5651->pll_in = 0;
 		rt5651->pll_out = 0;
-		snd_soc_update_bits(codec, RT5651_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5651_GLB_CLK,
 			RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_MCLK);
 		return 0;
 	}
 
 	switch (source) {
 	case RT5651_PLL1_S_MCLK:
-		snd_soc_update_bits(codec, RT5651_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5651_GLB_CLK,
 			RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_MCLK);
 		break;
 	case RT5651_PLL1_S_BCLK1:
-		snd_soc_update_bits(codec, RT5651_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5651_GLB_CLK,
 				RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_BCLK1);
 		break;
 	case RT5651_PLL1_S_BCLK2:
-			snd_soc_update_bits(codec, RT5651_GLB_CLK,
+			snd_soc_component_update_bits(component, RT5651_GLB_CLK,
 				RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_BCLK2);
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
-	snd_soc_write(codec, RT5651_PLL_CTRL1,
+	snd_soc_component_write(component, RT5651_PLL_CTRL1,
 		pll_code.n_code << RT5651_PLL_N_SFT | pll_code.k_code);
-	snd_soc_write(codec, RT5651_PLL_CTRL2,
+	snd_soc_component_write(component, RT5651_PLL_CTRL2,
 		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5651_PLL_M_SFT |
 		pll_code.m_bp << RT5651_PLL_M_BP_SFT);
 
@@ -1536,46 +1509,44 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 	return 0;
 }
 
-static int rt5651_set_bias_level(struct snd_soc_codec *codec,
+static int rt5651_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
-
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
-		if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
-			snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
+		if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
+			if (snd_soc_component_read32(component, RT5651_PLL_MODE_1) & 0x9200)
+				snd_soc_component_update_bits(component, RT5651_D_MISC,
+						    0xc00, 0xc00);
+		}
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		if (SND_SOC_BIAS_OFF == snd_soc_component_get_bias_level(component)) {
+			snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
 				RT5651_PWR_VREF1 | RT5651_PWR_MB |
 				RT5651_PWR_BG | RT5651_PWR_VREF2,
 				RT5651_PWR_VREF1 | RT5651_PWR_MB |
 				RT5651_PWR_BG | RT5651_PWR_VREF2);
 			usleep_range(10000, 15000);
-			snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
 				RT5651_PWR_FV1 | RT5651_PWR_FV2,
 				RT5651_PWR_FV1 | RT5651_PWR_FV2);
-			snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
-				RT5651_PWR_LDO_DVO_MASK,
-				RT5651_PWR_LDO_DVO_1_2V);
-			snd_soc_update_bits(codec, RT5651_D_MISC, 0x1, 0x1);
-			if (snd_soc_read(codec, RT5651_PLL_MODE_1) & 0x9200)
-				snd_soc_update_bits(codec, RT5651_D_MISC,
-						    0xc00, 0xc00);
+			snd_soc_component_update_bits(component, RT5651_D_MISC, 0x1, 0x1);
 		}
 		break;
 
-	case SND_SOC_BIAS_STANDBY:
-		snd_soc_write(codec, RT5651_D_MISC, 0x0010);
-		snd_soc_write(codec, RT5651_PWR_DIG1, 0x0000);
-		snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000);
-		snd_soc_write(codec, RT5651_PWR_VOL, 0x0000);
-		snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000);
-		if (rt5651->pdata.jd_src) {
-			snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0204);
-			snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0002);
-		} else {
-			snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
-			snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
-		}
+	case SND_SOC_BIAS_OFF:
+		snd_soc_component_write(component, RT5651_D_MISC, 0x0010);
+		snd_soc_component_write(component, RT5651_PWR_DIG1, 0x0000);
+		snd_soc_component_write(component, RT5651_PWR_DIG2, 0x0000);
+		snd_soc_component_write(component, RT5651_PWR_VOL, 0x0000);
+		snd_soc_component_write(component, RT5651_PWR_MIXER, 0x0000);
+		/* Do not touch the LDO voltage select bits on bias-off */
+		snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
+			~RT5651_PWR_LDO_DVO_MASK, 0);
+		/* Leave PLL1 and jack-detect power as is, all others off */
+		snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
+				    ~(RT5651_PWR_PLL | RT5651_PWR_JD_M), 0);
 		break;
 
 	default:
@@ -1585,53 +1556,326 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5651_probe(struct snd_soc_codec *codec)
+static void rt5651_enable_micbias1_for_ovcd(struct snd_soc_component *component)
 {
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-	rt5651->codec = codec;
+	snd_soc_dapm_mutex_lock(dapm);
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "micbias1");
+	/* OVCD is unreliable when used with RCCLK as sysclk-source */
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Platform Clock");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
 
-	snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
-		RT5651_PWR_VREF1 | RT5651_PWR_MB |
-		RT5651_PWR_BG | RT5651_PWR_VREF2,
-		RT5651_PWR_VREF1 | RT5651_PWR_MB |
-		RT5651_PWR_BG | RT5651_PWR_VREF2);
-	usleep_range(10000, 15000);
-	snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
-		RT5651_PWR_FV1 | RT5651_PWR_FV2,
-		RT5651_PWR_FV1 | RT5651_PWR_FV2);
+static void rt5651_disable_micbias1_for_ovcd(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_dapm_mutex_lock(dapm);
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Platform Clock");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "micbias1");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "LDO");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
 
-	if (rt5651->pdata.jd_src) {
-		snd_soc_dapm_force_enable_pin(dapm, "JD Power");
-		snd_soc_dapm_force_enable_pin(dapm, "LDO");
-		snd_soc_dapm_sync(dapm);
+static void rt5651_clear_micbias1_ovcd(struct snd_soc_component *component)
+{
+	snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
+		RT5651_MB1_OC_CLR, 0);
+}
 
-		regmap_update_bits(rt5651->regmap, RT5651_MICBIAS,
-				   0x38, 0x38);
+static bool rt5651_micbias1_ovcd(struct snd_soc_component *component)
+{
+	int val;
+
+	val = snd_soc_component_read32(component, RT5651_IRQ_CTRL2);
+	dev_dbg(component->dev, "irq ctrl2 %#04x\n", val);
+
+	return (val & RT5651_MB1_OC_CLR);
+}
+
+static bool rt5651_jack_inserted(struct snd_soc_component *component)
+{
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+	int val;
+
+	val = snd_soc_component_read32(component, RT5651_INT_IRQ_ST);
+	dev_dbg(component->dev, "irq status %#04x\n", val);
+
+	switch (rt5651->jd_src) {
+	case RT5651_JD1_1:
+		val &= 0x1000;
+		break;
+	case RT5651_JD1_2:
+		val &= 0x2000;
+		break;
+	case RT5651_JD2:
+		val &= 0x4000;
+		break;
+	default:
+		break;
 	}
 
+	return val == 0;
+}
+
+/* Jack detect timings */
+#define JACK_SETTLE_TIME	100 /* milli seconds */
+#define JACK_DETECT_COUNT	5
+#define JACK_DETECT_MAXCOUNT	20  /* Aprox. 2 seconds worth of tries */
+
+static int rt5651_detect_headset(struct snd_soc_component *component)
+{
+	int i, headset_count = 0, headphone_count = 0;
+
+	/*
+	 * We get the insertion event before the jack is fully inserted at which
+	 * point the second ring on a TRRS connector may short the 2nd ring and
+	 * sleeve contacts, also the overcurrent detection is not entirely
+	 * reliable. So we try several times with a wait in between until we
+	 * detect the same type JACK_DETECT_COUNT times in a row.
+	 */
+	for (i = 0; i < JACK_DETECT_MAXCOUNT; i++) {
+		/* Clear any previous over-current status flag */
+		rt5651_clear_micbias1_ovcd(component);
+
+		msleep(JACK_SETTLE_TIME);
+
+		/* Check the jack is still connected before checking ovcd */
+		if (!rt5651_jack_inserted(component))
+			return 0;
+
+		if (rt5651_micbias1_ovcd(component)) {
+			/*
+			 * Over current detected, there is a short between the
+			 * 2nd ring contact and the ground, so a TRS connector
+			 * without a mic contact and thus plain headphones.
+			 */
+			dev_dbg(component->dev, "mic-gnd shorted\n");
+			headset_count = 0;
+			headphone_count++;
+			if (headphone_count == JACK_DETECT_COUNT)
+				return SND_JACK_HEADPHONE;
+		} else {
+			dev_dbg(component->dev, "mic-gnd open\n");
+			headphone_count = 0;
+			headset_count++;
+			if (headset_count == JACK_DETECT_COUNT)
+				return SND_JACK_HEADSET;
+		}
+	}
+
+	dev_err(component->dev, "Error detecting headset vs headphones, bad contact?, assuming headphones\n");
+	return SND_JACK_HEADPHONE;
+}
+
+static void rt5651_jack_detect_work(struct work_struct *work)
+{
+	struct rt5651_priv *rt5651 =
+		container_of(work, struct rt5651_priv, jack_detect_work);
+	int report = 0;
+
+	if (rt5651_jack_inserted(rt5651->component)) {
+		rt5651_enable_micbias1_for_ovcd(rt5651->component);
+		report = rt5651_detect_headset(rt5651->component);
+		rt5651_disable_micbias1_for_ovcd(rt5651->component);
+	}
+
+	snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
+}
+
+static irqreturn_t rt5651_irq(int irq, void *data)
+{
+	struct rt5651_priv *rt5651 = data;
+
+	queue_work(system_power_efficient_wq, &rt5651->jack_detect_work);
+
+	return IRQ_HANDLED;
+}
+
+static int rt5651_set_jack(struct snd_soc_component *component,
+			   struct snd_soc_jack *hp_jack, void *data)
+{
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+	int ret;
+
+	if (!rt5651->irq)
+		return -EINVAL;
+
+	/* IRQ output on GPIO1 */
+	snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1,
+		RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ);
+
+	/* Select jack detect source */
+	switch (rt5651->jd_src) {
+	case RT5651_JD1_1:
+		snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
+			RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_1);
+		snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
+			RT5651_JD1_1_IRQ_EN, RT5651_JD1_1_IRQ_EN);
+		break;
+	case RT5651_JD1_2:
+		snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
+			RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_2);
+		snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
+			RT5651_JD1_2_IRQ_EN, RT5651_JD1_2_IRQ_EN);
+		break;
+	case RT5651_JD2:
+		snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
+			RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD2);
+		snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
+			RT5651_JD2_IRQ_EN, RT5651_JD2_IRQ_EN);
+		break;
+	case RT5651_JD_NULL:
+		return 0;
+	default:
+		dev_err(component->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
+		return -EINVAL;
+	}
+
+	/* Enable jack detect power */
+	snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
+		RT5651_PWR_JD_M, RT5651_PWR_JD_M);
+
+	/* Set OVCD threshold current and scale-factor */
+	snd_soc_component_write(component, RT5651_PR_BASE + RT5651_BIAS_CUR4,
+				0xa800 | rt5651->ovcd_sf);
+
+	snd_soc_component_update_bits(component, RT5651_MICBIAS,
+				      RT5651_MIC1_OVCD_MASK |
+				      RT5651_MIC1_OVTH_MASK |
+				      RT5651_PWR_CLK12M_MASK |
+				      RT5651_PWR_MB_MASK,
+				      RT5651_MIC1_OVCD_EN |
+				      rt5651->ovcd_th |
+				      RT5651_PWR_MB_PU |
+				      RT5651_PWR_CLK12M_PU);
+
+	/*
+	 * The over-current-detect is only reliable in detecting the absence
+	 * of over-current, when the mic-contact in the jack is short-circuited,
+	 * the hardware periodically retries if it can apply the bias-current
+	 * leading to the ovcd status flip-flopping 1-0-1 with it being 0 about
+	 * 10% of the time, as we poll the ovcd status bit we might hit that
+	 * 10%, so we enable sticky mode and when checking OVCD we clear the
+	 * status, msleep() a bit and then check to get a reliable reading.
+	 */
+	snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
+		RT5651_MB1_OC_STKY_MASK, RT5651_MB1_OC_STKY_EN);
+
+	rt5651->hp_jack = hp_jack;
+
+	ret = devm_request_threaded_irq(component->dev, rt5651->irq, NULL,
+					rt5651_irq,
+					IRQF_TRIGGER_RISING |
+					IRQF_TRIGGER_FALLING |
+					IRQF_ONESHOT, "rt5651", rt5651);
+	if (ret) {
+		dev_err(component->dev, "Failed to reguest IRQ: %d\n", ret);
+		return ret;
+	}
+
+	/* sync initial jack state */
+	queue_work(system_power_efficient_wq, &rt5651->jack_detect_work);
+
+	return 0;
+}
+
+/*
+ * Note on some platforms the platform code may need to add device-properties,
+ * rather then relying only on properties set by the firmware. Therefor the
+ * property parsing MUST be done from the component driver's probe function,
+ * rather then from the i2c driver's probe function, so that the platform-code
+ * can attach extra properties before calling snd_soc_register_card().
+ */
+static void rt5651_apply_properties(struct snd_soc_component *component)
+{
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+	u32 val;
+
+	if (device_property_read_bool(component->dev, "realtek,in2-differential"))
+		snd_soc_component_update_bits(component, RT5651_IN1_IN2,
+				RT5651_IN_DF2, RT5651_IN_DF2);
+
+	if (device_property_read_bool(component->dev, "realtek,dmic-en"))
+		snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1,
+				RT5651_GP2_PIN_MASK, RT5651_GP2_PIN_DMIC1_SCL);
+
+	if (device_property_read_u32(component->dev,
+				     "realtek,jack-detect-source", &val) == 0)
+		rt5651->jd_src = val;
+
+	/*
+	 * Testing on various boards has shown that good defaults for the OVCD
+	 * threshold and scale-factor are 2000µA and 0.75. For an effective
+	 * limit of 1500µA, this seems to be more reliable then 1500µA and 1.0.
+	 */
+	rt5651->ovcd_th = RT5651_MIC1_OVTH_2000UA;
+	rt5651->ovcd_sf = RT5651_MIC_OVCD_SF_0P75;
+
+	if (device_property_read_u32(component->dev,
+			"realtek,over-current-threshold-microamp", &val) == 0) {
+		switch (val) {
+		case 600:
+			rt5651->ovcd_th = RT5651_MIC1_OVTH_600UA;
+			break;
+		case 1500:
+			rt5651->ovcd_th = RT5651_MIC1_OVTH_1500UA;
+			break;
+		case 2000:
+			rt5651->ovcd_th = RT5651_MIC1_OVTH_2000UA;
+			break;
+		default:
+			dev_warn(component->dev, "Warning: Invalid over-current-threshold-microamp value: %d, defaulting to 2000uA\n",
+				 val);
+		}
+	}
+
+	if (device_property_read_u32(component->dev,
+			"realtek,over-current-scale-factor", &val) == 0) {
+		if (val <= RT5651_OVCD_SF_1P5)
+			rt5651->ovcd_sf = val << RT5651_MIC_OVCD_SF_SFT;
+		else
+			dev_warn(component->dev, "Warning: Invalid over-current-scale-factor value: %d, defaulting to 0.75\n",
+				 val);
+	}
+}
+
+static int rt5651_probe(struct snd_soc_component *component)
+{
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+
+	rt5651->component = component;
+
+	snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
+		RT5651_PWR_LDO_DVO_MASK, RT5651_PWR_LDO_DVO_1_2V);
+
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
+
+	rt5651_apply_properties(component);
+
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5651_suspend(struct snd_soc_codec *codec)
+static int rt5651_suspend(struct snd_soc_component *component)
 {
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5651->regmap, true);
 	regcache_mark_dirty(rt5651->regmap);
 	return 0;
 }
 
-static int rt5651_resume(struct snd_soc_codec *codec)
+static int rt5651_resume(struct snd_soc_component *component)
 {
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5651->regmap, false);
-	snd_soc_cache_sync(codec);
+	snd_soc_component_cache_sync(component);
 
 	return 0;
 }
@@ -1692,20 +1936,21 @@ static struct snd_soc_dai_driver rt5651_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5651 = {
-	.probe = rt5651_probe,
-	.suspend = rt5651_suspend,
-	.resume = rt5651_resume,
-	.set_bias_level = rt5651_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt5651_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5651_snd_controls),
-		.dapm_widgets		= rt5651_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5651_dapm_widgets),
-		.dapm_routes		= rt5651_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5651_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5651 = {
+	.probe			= rt5651_probe,
+	.suspend		= rt5651_suspend,
+	.resume			= rt5651_resume,
+	.set_bias_level		= rt5651_set_bias_level,
+	.set_jack		= rt5651_set_jack,
+	.controls		= rt5651_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5651_snd_controls),
+	.dapm_widgets		= rt5651_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5651_dapm_widgets),
+	.dapm_routes		= rt5651_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5651_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt5651_regmap = {
@@ -1747,135 +1992,13 @@ static const struct i2c_device_id rt5651_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, rt5651_i2c_id);
 
-static int rt5651_quirk_cb(const struct dmi_system_id *id)
-{
-	rt5651_quirk = (unsigned long) id->driver_data;
-	return 1;
-}
-
-static const struct dmi_system_id rt5651_quirk_table[] = {
-	{
-		.callback = rt5651_quirk_cb,
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "KIANO"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
-		},
-		.driver_data = (unsigned long *) RT5651_JD1_1,
-	},
-	{}
-};
-
-static int rt5651_parse_dt(struct rt5651_priv *rt5651, struct device_node *np)
-{
-	if (of_property_read_bool(np, "realtek,in2-differential"))
-		rt5651_quirk |= RT5651_IN2_DIFF;
-	if (of_property_read_bool(np, "realtek,dmic-en"))
-		rt5651_quirk |= RT5651_DMIC_EN;
-
-	return 0;
-}
-
-static void rt5651_set_pdata(struct rt5651_priv *rt5651)
-{
-	if (rt5651_quirk & RT5651_IN2_DIFF)
-		rt5651->pdata.in2_diff = true;
-	if (rt5651_quirk & RT5651_DMIC_EN)
-		rt5651->pdata.dmic_en = true;
-	if (RT5651_JD_MAP(rt5651_quirk))
-		rt5651->pdata.jd_src = RT5651_JD_MAP(rt5651_quirk);
-}
-
-static irqreturn_t rt5651_irq(int irq, void *data)
-{
-	struct rt5651_priv *rt5651 = data;
-
-	queue_delayed_work(system_power_efficient_wq,
-			   &rt5651->jack_detect_work, msecs_to_jiffies(250));
-
-	return IRQ_HANDLED;
-}
-
-static int rt5651_jack_detect(struct snd_soc_codec *codec, int jack_insert)
-{
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	int jack_type;
-
-	if (jack_insert) {
-		snd_soc_dapm_force_enable_pin(dapm, "LDO");
-		snd_soc_dapm_sync(dapm);
-
-		snd_soc_update_bits(codec, RT5651_MICBIAS,
-				    RT5651_MIC1_OVCD_MASK |
-				    RT5651_MIC1_OVTH_MASK |
-				    RT5651_PWR_CLK12M_MASK |
-				    RT5651_PWR_MB_MASK,
-				    RT5651_MIC1_OVCD_EN |
-				    RT5651_MIC1_OVTH_600UA |
-				    RT5651_PWR_MB_PU |
-				    RT5651_PWR_CLK12M_PU);
-		msleep(100);
-		if (snd_soc_read(codec, RT5651_IRQ_CTRL2) & RT5651_MB1_OC_CLR)
-			jack_type = SND_JACK_HEADPHONE;
-		else
-			jack_type = SND_JACK_HEADSET;
-		snd_soc_update_bits(codec, RT5651_IRQ_CTRL2,
-				    RT5651_MB1_OC_CLR, 0);
-	} else { /* jack out */
-		jack_type = 0;
-
-		snd_soc_update_bits(codec, RT5651_MICBIAS,
-				    RT5651_MIC1_OVCD_MASK,
-				    RT5651_MIC1_OVCD_DIS);
-	}
-
-	return jack_type;
-}
-
-static void rt5651_jack_detect_work(struct work_struct *work)
-{
-	struct rt5651_priv *rt5651 =
-		container_of(work, struct rt5651_priv, jack_detect_work.work);
-
-	int report, val = 0;
-
-	if (!rt5651->codec)
-		return;
-
-	switch (rt5651->pdata.jd_src) {
-	case RT5651_JD1_1:
-		val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x1000;
-		break;
-	case RT5651_JD1_2:
-		val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x2000;
-		break;
-	case RT5651_JD2:
-		val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x4000;
-		break;
-	default:
-		break;
-	}
-
-	report = rt5651_jack_detect(rt5651->codec, !val);
-
-	snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
-}
-
-int rt5651_set_jack_detect(struct snd_soc_codec *codec,
-			   struct snd_soc_jack *hp_jack)
-{
-	struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
-
-	rt5651->hp_jack = hp_jack;
-	rt5651_irq(0, rt5651);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(rt5651_set_jack_detect);
-
+/*
+ * Note this function MUST not look at device-properties, see the comment
+ * above rt5651_apply_properties().
+ */
 static int rt5651_i2c_probe(struct i2c_client *i2c,
 		    const struct i2c_device_id *id)
 {
-	struct rt5651_platform_data *pdata = dev_get_platdata(&i2c->dev);
 	struct rt5651_priv *rt5651;
 	int ret;
 
@@ -1886,15 +2009,6 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, rt5651);
 
-	if (pdata)
-		rt5651->pdata = *pdata;
-	else if (i2c->dev.of_node)
-		rt5651_parse_dt(rt5651, i2c->dev.of_node);
-	else
-		dmi_check_system(rt5651_quirk_table);
-
-	rt5651_set_pdata(rt5651);
-
 	rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap);
 	if (IS_ERR(rt5651->regmap)) {
 		ret = PTR_ERR(rt5651->regmap);
@@ -1917,70 +2031,13 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
 	if (ret != 0)
 		dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
 
-	if (rt5651->pdata.in2_diff)
-		regmap_update_bits(rt5651->regmap, RT5651_IN1_IN2,
-					RT5651_IN_DF2, RT5651_IN_DF2);
-
-	if (rt5651->pdata.dmic_en)
-		regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
-				RT5651_GP2_PIN_MASK, RT5651_GP2_PIN_DMIC1_SCL);
-
+	rt5651->irq = i2c->irq;
 	rt5651->hp_mute = 1;
 
-	if (rt5651->pdata.jd_src) {
+	INIT_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
 
-		/* IRQ output on GPIO1 */
-		regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
-				   RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ);
-
-		switch (rt5651->pdata.jd_src) {
-		case RT5651_JD1_1:
-			regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
-					   RT5651_JD_TRG_SEL_MASK,
-					   RT5651_JD_TRG_SEL_JD1_1);
-			regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
-					   RT5651_JD1_1_IRQ_EN,
-					   RT5651_JD1_1_IRQ_EN);
-			break;
-		case RT5651_JD1_2:
-			regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
-					   RT5651_JD_TRG_SEL_MASK,
-					   RT5651_JD_TRG_SEL_JD1_2);
-			regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
-					   RT5651_JD1_2_IRQ_EN,
-					   RT5651_JD1_2_IRQ_EN);
-			break;
-		case RT5651_JD2:
-			regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
-					   RT5651_JD_TRG_SEL_MASK,
-					   RT5651_JD_TRG_SEL_JD2);
-			regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
-					   RT5651_JD2_IRQ_EN,
-					   RT5651_JD2_IRQ_EN);
-			break;
-		case RT5651_JD_NULL:
-			break;
-		default:
-			dev_warn(&i2c->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
-			break;
-		}
-	}
-
-	INIT_DELAYED_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
-
-	if (i2c->irq) {
-		ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
-						rt5651_irq,
-						IRQF_TRIGGER_RISING |
-						IRQF_TRIGGER_FALLING |
-						IRQF_ONESHOT, "rt5651", rt5651);
-		if (ret) {
-			dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
-			return ret;
-		}
-	}
-
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				&soc_component_dev_rt5651,
 				rt5651_dai, ARRAY_SIZE(rt5651_dai));
 
 	return ret;
@@ -1990,8 +2047,7 @@ static int rt5651_i2c_remove(struct i2c_client *i2c)
 {
 	struct rt5651_priv *rt5651 = i2c_get_clientdata(i2c);
 
-	cancel_delayed_work_sync(&rt5651->jack_detect_work);
-	snd_soc_unregister_codec(&i2c->dev);
+	cancel_work_sync(&rt5651->jack_detect_work);
 
 	return 0;
 }
diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h
index 4f8b202..3a0968c 100644
--- a/sound/soc/codecs/rt5651.h
+++ b/sound/soc/codecs/rt5651.h
@@ -12,7 +12,7 @@
 #ifndef __RT5651_H__
 #define __RT5651_H__
 
-#include <sound/rt5651.h>
+#include <dt-bindings/sound/rt5651.h>
 
 /* Info */
 #define RT5651_RESET				0x00
@@ -138,6 +138,7 @@
 /* Index of Codec Private Register definition */
 #define RT5651_BIAS_CUR1			0x12
 #define RT5651_BIAS_CUR3			0x14
+#define RT5651_BIAS_CUR4			0x15
 #define RT5651_CLSD_INT_REG1			0x1c
 #define RT5651_CHPUMP_INT_REG1			0x24
 #define RT5651_MAMP_INT_REG2			0x37
@@ -1966,6 +1967,15 @@
 #define RT5651_D_GATE_EN_SFT			0
 
 /* Codec Private Register definition */
+
+/* MIC Over current threshold scale factor (0x15) */
+#define RT5651_MIC_OVCD_SF_MASK			(0x3 << 8)
+#define RT5651_MIC_OVCD_SF_SFT			8
+#define RT5651_MIC_OVCD_SF_0P5			(0x0 << 8)
+#define RT5651_MIC_OVCD_SF_0P75			(0x1 << 8)
+#define RT5651_MIC_OVCD_SF_1P0			(0x2 << 8)
+#define RT5651_MIC_OVCD_SF_1P5			(0x3 << 8)
+
 /* 3D Speaker Control (0x63) */
 #define RT5651_3D_SPK_MASK			(0x1 << 15)
 #define RT5651_3D_SPK_SFT			15
@@ -2059,12 +2069,15 @@ struct rt5651_pll_code {
 };
 
 struct rt5651_priv {
-	struct snd_soc_codec *codec;
-	struct rt5651_platform_data pdata;
+	struct snd_soc_component *component;
 	struct regmap *regmap;
 	struct snd_soc_jack *hp_jack;
-	struct delayed_work jack_detect_work;
+	struct work_struct jack_detect_work;
+	unsigned int jd_src;
+	unsigned int ovcd_th;
+	unsigned int ovcd_sf;
 
+	int irq;
 	int sysclk;
 	int sysclk_src;
 	int lrck[RT5651_AIFS];
@@ -2079,6 +2092,4 @@ struct rt5651_priv {
 	bool hp_mute;
 };
 
-int rt5651_set_jack_detect(struct snd_soc_codec *codec,
-			   struct snd_soc_jack *hp_jack);
 #endif /* __RT5651_H__ */
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
index 07e7757..1c1a521 100644
--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -1238,26 +1238,26 @@ static SOC_VALUE_ENUM_SINGLE_DECL(
 static int rt5659_hp_vol_put(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int ret = snd_soc_put_volsw(kcontrol, ucontrol);
 
-	if (snd_soc_read(codec, RT5659_STO_NG2_CTRL_1) & RT5659_NG2_EN) {
-		snd_soc_update_bits(codec, RT5659_STO_NG2_CTRL_1,
+	if (snd_soc_component_read32(component, RT5659_STO_NG2_CTRL_1) & RT5659_NG2_EN) {
+		snd_soc_component_update_bits(component, RT5659_STO_NG2_CTRL_1,
 			RT5659_NG2_EN_MASK, RT5659_NG2_DIS);
-		snd_soc_update_bits(codec, RT5659_STO_NG2_CTRL_1,
+		snd_soc_component_update_bits(component, RT5659_STO_NG2_CTRL_1,
 			RT5659_NG2_EN_MASK, RT5659_NG2_EN);
 	}
 
 	return ret;
 }
 
-static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
+static void rt5659_enable_push_button_irq(struct snd_soc_component *component,
 	bool enable)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	if (enable) {
-		snd_soc_write(codec, RT5659_4BTN_IL_CMD_1, 0x000b);
+		snd_soc_component_write(component, RT5659_4BTN_IL_CMD_1, 0x000b);
 
 		/* MICBIAS1 and Mic Det Power for button detect*/
 		snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
@@ -1265,19 +1265,19 @@ static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
 			"Mic Det Power");
 		snd_soc_dapm_sync(dapm);
 
-		snd_soc_update_bits(codec, RT5659_PWR_ANLG_2,
+		snd_soc_component_update_bits(component, RT5659_PWR_ANLG_2,
 			RT5659_PWR_MB1, RT5659_PWR_MB1);
-		snd_soc_update_bits(codec, RT5659_PWR_VOL,
+		snd_soc_component_update_bits(component, RT5659_PWR_VOL,
 			RT5659_PWR_MIC_DET, RT5659_PWR_MIC_DET);
 
-		snd_soc_update_bits(codec, RT5659_IRQ_CTRL_2,
+		snd_soc_component_update_bits(component, RT5659_IRQ_CTRL_2,
 				RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_EN);
-		snd_soc_update_bits(codec, RT5659_4BTN_IL_CMD_2,
+		snd_soc_component_update_bits(component, RT5659_4BTN_IL_CMD_2,
 				RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_EN);
 	} else {
-		snd_soc_update_bits(codec, RT5659_4BTN_IL_CMD_2,
+		snd_soc_component_update_bits(component, RT5659_4BTN_IL_CMD_2,
 				RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_DIS);
-		snd_soc_update_bits(codec, RT5659_IRQ_CTRL_2,
+		snd_soc_component_update_bits(component, RT5659_IRQ_CTRL_2,
 				RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_DIS);
 		/* MICBIAS1 and Mic Det Power for button detect*/
 		snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
@@ -1288,7 +1288,7 @@ static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
 
 /**
  * rt5659_headset_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
@@ -1296,37 +1296,37 @@ static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
  * Returns detect status.
  */
 
-static int rt5659_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5659_headset_detect(struct snd_soc_component *component, int jack_insert)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
 	int reg_63;
 
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
 	if (jack_insert) {
 		snd_soc_dapm_force_enable_pin(dapm,
 			"Mic Det Power");
 		snd_soc_dapm_sync(dapm);
-		reg_63 = snd_soc_read(codec, RT5659_PWR_ANLG_1);
+		reg_63 = snd_soc_component_read32(component, RT5659_PWR_ANLG_1);
 
-		snd_soc_update_bits(codec, RT5659_PWR_ANLG_1,
+		snd_soc_component_update_bits(component, RT5659_PWR_ANLG_1,
 			RT5659_PWR_VREF2 | RT5659_PWR_MB,
 			RT5659_PWR_VREF2 | RT5659_PWR_MB);
 		msleep(20);
-		snd_soc_update_bits(codec, RT5659_PWR_ANLG_1,
+		snd_soc_component_update_bits(component, RT5659_PWR_ANLG_1,
 			RT5659_PWR_FV2, RT5659_PWR_FV2);
 
-		snd_soc_write(codec, RT5659_EJD_CTRL_2, 0x4160);
-		snd_soc_update_bits(codec, RT5659_EJD_CTRL_1,
+		snd_soc_component_write(component, RT5659_EJD_CTRL_2, 0x4160);
+		snd_soc_component_update_bits(component, RT5659_EJD_CTRL_1,
 			0x20, 0x0);
 		msleep(20);
-		snd_soc_update_bits(codec, RT5659_EJD_CTRL_1,
+		snd_soc_component_update_bits(component, RT5659_EJD_CTRL_1,
 			0x20, 0x20);
 
 		while (i < 5) {
 			msleep(sleep_time[i]);
-			val = snd_soc_read(codec, RT5659_EJD_CTRL_2) & 0x0003;
+			val = snd_soc_component_read32(component, RT5659_EJD_CTRL_2) & 0x0003;
 			i++;
 			if (val == 0x1 || val == 0x2 || val == 0x3)
 				break;
@@ -1335,10 +1335,10 @@ static int rt5659_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 		switch (val) {
 		case 1:
 			rt5659->jack_type = SND_JACK_HEADSET;
-			rt5659_enable_push_button_irq(codec, true);
+			rt5659_enable_push_button_irq(component, true);
 			break;
 		default:
-			snd_soc_write(codec, RT5659_PWR_ANLG_1, reg_63);
+			snd_soc_component_write(component, RT5659_PWR_ANLG_1, reg_63);
 			rt5659->jack_type = SND_JACK_HEADPHONE;
 			snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
 			snd_soc_dapm_sync(dapm);
@@ -1348,21 +1348,21 @@ static int rt5659_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 		snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
 		snd_soc_dapm_sync(dapm);
 		if (rt5659->jack_type == SND_JACK_HEADSET)
-			rt5659_enable_push_button_irq(codec, false);
+			rt5659_enable_push_button_irq(component, false);
 		rt5659->jack_type = 0;
 	}
 
-	dev_dbg(codec->dev, "jack_type = %d\n", rt5659->jack_type);
+	dev_dbg(component->dev, "jack_type = %d\n", rt5659->jack_type);
 	return rt5659->jack_type;
 }
 
-static int rt5659_button_detect(struct snd_soc_codec *codec)
+static int rt5659_button_detect(struct snd_soc_component *component)
 {
 	int btn_type, val;
 
-	val = snd_soc_read(codec, RT5659_4BTN_IL_CMD_1);
+	val = snd_soc_component_read32(component, RT5659_4BTN_IL_CMD_1);
 	btn_type = val & 0xfff0;
-	snd_soc_write(codec, RT5659_4BTN_IL_CMD_1, val);
+	snd_soc_component_write(component, RT5659_4BTN_IL_CMD_1, val);
 
 	return btn_type;
 }
@@ -1377,10 +1377,10 @@ static irqreturn_t rt5659_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-int rt5659_set_jack_detect(struct snd_soc_codec *codec,
+int rt5659_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack)
 {
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
 	rt5659->hs_jack = hs_jack;
 
@@ -1396,19 +1396,19 @@ static void rt5659_jack_detect_work(struct work_struct *work)
 		container_of(work, struct rt5659_priv, jack_detect_work.work);
 	int val, btn_type, report = 0;
 
-	if (!rt5659->codec)
+	if (!rt5659->component)
 		return;
 
-	val = snd_soc_read(rt5659->codec, RT5659_INT_ST_1) & 0x0080;
+	val = snd_soc_component_read32(rt5659->component, RT5659_INT_ST_1) & 0x0080;
 	if (!val) {
 		/* jack in */
 		if (rt5659->jack_type == 0) {
 			/* jack was out, report jack type */
-			report = rt5659_headset_detect(rt5659->codec, 1);
+			report = rt5659_headset_detect(rt5659->component, 1);
 		} else {
 			/* jack is already in, report button event */
 			report = SND_JACK_HEADSET;
-			btn_type = rt5659_button_detect(rt5659->codec);
+			btn_type = rt5659_button_detect(rt5659->component);
 			/**
 			 * rt5659 can report three kinds of button behavior,
 			 * one click, double click and hold. However,
@@ -1441,7 +1441,7 @@ static void rt5659_jack_detect_work(struct work_struct *work)
 				break;
 			default:
 				btn_type = 0;
-				dev_err(rt5659->codec->dev,
+				dev_err(rt5659->component->dev,
 					"Unexpected button code 0x%04x\n",
 					btn_type);
 				break;
@@ -1453,7 +1453,7 @@ static void rt5659_jack_detect_work(struct work_struct *work)
 		}
 	} else {
 		/* jack out */
-		report = rt5659_headset_detect(rt5659->codec, 0);
+		report = rt5659_headset_detect(rt5659->component, 0);
 	}
 
 	snd_soc_jack_report(rt5659->hs_jack, report, SND_JACK_HEADSET |
@@ -1461,6 +1461,61 @@ static void rt5659_jack_detect_work(struct work_struct *work)
 			    SND_JACK_BTN_2 | SND_JACK_BTN_3);
 }
 
+static void rt5659_jack_detect_intel_hd_header(struct work_struct *work)
+{
+	struct rt5659_priv *rt5659 =
+		container_of(work, struct rt5659_priv, jack_detect_work.work);
+	unsigned int value;
+	bool hp_flag, mic_flag;
+
+	if (!rt5659->hs_jack)
+		return;
+
+	/* headphone jack */
+	regmap_read(rt5659->regmap, RT5659_GPIO_STA, &value);
+	hp_flag = (!(value & 0x8)) ? true : false;
+
+	if (hp_flag != rt5659->hda_hp_plugged) {
+		rt5659->hda_hp_plugged = hp_flag;
+
+		if (hp_flag) {
+			regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+				0x10, 0x0);
+			rt5659->jack_type |= SND_JACK_HEADPHONE;
+		} else {
+			regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+				0x10, 0x10);
+			rt5659->jack_type = rt5659->jack_type &
+				(~SND_JACK_HEADPHONE);
+		}
+
+		snd_soc_jack_report(rt5659->hs_jack, rt5659->jack_type,
+			SND_JACK_HEADPHONE);
+	}
+
+	/* mic jack */
+	regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+	regmap_write(rt5659->regmap, RT5659_4BTN_IL_CMD_1, value);
+	mic_flag = (value & 0x2000) ? true : false;
+
+	if (mic_flag != rt5659->hda_mic_plugged) {
+		rt5659->hda_mic_plugged = mic_flag;
+		if (mic_flag) {
+			regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+				0x2, 0x2);
+			rt5659->jack_type |= SND_JACK_MICROPHONE;
+		} else {
+			regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+				0x2, 0x0);
+			rt5659->jack_type = rt5659->jack_type
+				& (~SND_JACK_MICROPHONE);
+		}
+
+		snd_soc_jack_report(rt5659->hs_jack, rt5659->jack_type,
+			SND_JACK_MICROPHONE);
+	}
+}
+
 static const struct snd_kcontrol_new rt5659_snd_controls[] = {
 	/* Speaker Output Volume */
 	SOC_DOUBLE_TLV("Speaker Playback Volume", RT5659_SPO_VOL,
@@ -1550,8 +1605,8 @@ static const struct snd_kcontrol_new rt5659_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 	int pd, idx = -EINVAL;
 
 	pd = rl6231_get_pre_div(rt5659->regmap,
@@ -1559,29 +1614,55 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	idx = rl6231_calc_dmic_clk(rt5659->sysclk / pd);
 
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else {
-		snd_soc_update_bits(codec, RT5659_DMIC_CTRL_1,
+		snd_soc_component_update_bits(component, RT5659_DMIC_CTRL_1,
 			RT5659_DMIC_CLK_MASK, idx << RT5659_DMIC_CLK_SFT);
 	}
 	return idx;
 }
 
-static int set_adc_clk(struct snd_soc_dapm_widget *w,
+static int set_adc1_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5659_CHOP_ADC,
-			RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK,
-			RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK);
+		snd_soc_component_update_bits(component, RT5659_CHOP_ADC,
+			RT5659_CKXEN_ADC1_MASK | RT5659_CKGEN_ADC1_MASK,
+			RT5659_CKXEN_ADC1_MASK | RT5659_CKGEN_ADC1_MASK);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5659_CHOP_ADC,
-			RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK, 0);
+		snd_soc_component_update_bits(component, RT5659_CHOP_ADC,
+			RT5659_CKXEN_ADC1_MASK | RT5659_CKGEN_ADC1_MASK, 0);
+		break;
+
+	default:
+		return 0;
+	}
+
+	return 0;
+
+}
+
+static int set_adc2_clk(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+		snd_soc_dapm_to_component(w->dapm);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		snd_soc_component_update_bits(component, RT5659_CHOP_ADC,
+			RT5659_CKXEN_ADC2_MASK | RT5659_CKGEN_ADC2_MASK,
+			RT5659_CKXEN_ADC2_MASK | RT5659_CKGEN_ADC2_MASK);
+		break;
+
+	case SND_SOC_DAPM_PRE_PMD:
+		snd_soc_component_update_bits(component, RT5659_CHOP_ADC,
+			RT5659_CKXEN_ADC2_MASK | RT5659_CKGEN_ADC2_MASK, 0);
 		break;
 
 	default:
@@ -1595,15 +1676,15 @@ static int set_adc_clk(struct snd_soc_dapm_widget *w,
 static int rt5659_charge_pump_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		/* Depop */
-		snd_soc_write(codec, RT5659_DEPOP_1, 0x0009);
+		snd_soc_component_write(component, RT5659_DEPOP_1, 0x0009);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_write(codec, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
+		snd_soc_component_write(component, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
 		break;
 	default:
 		return 0;
@@ -1616,9 +1697,9 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
 			 struct snd_soc_dapm_widget *sink)
 {
 	unsigned int val;
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
-	val = snd_soc_read(codec, RT5659_GLB_CLK);
+	val = snd_soc_component_read32(component, RT5659_GLB_CLK);
 	val &= RT5659_SCLK_SRC_MASK;
 	if (val == RT5659_SCLK_SRC_PLL1)
 		return 1;
@@ -1630,7 +1711,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w,
 			 struct snd_soc_dapm_widget *sink)
 {
 	unsigned int reg, shift, val;
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (w->shift) {
 	case RT5659_ADC_MONO_R_ASRC_SFT:
@@ -1661,13 +1742,13 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w,
 		return 0;
 	}
 
-	val = (snd_soc_read(codec, reg) >> shift) & 0xf;
+	val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
 	switch (val) {
 	case 1:
 	case 2:
 	case 3:
 		/* I2S_Pre_Div1 should be 1 in asrc mode */
-		snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+		snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
 			RT5659_I2S_PD1_MASK, RT5659_I2S_PD1_2);
 		return 1;
 	default:
@@ -2303,24 +2384,24 @@ static const struct snd_kcontrol_new pdm_r_switch =
 static int rt5659_spk_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, RT5659_CLASSD_CTRL_1,
+		snd_soc_component_update_bits(component, RT5659_CLASSD_CTRL_1,
 			RT5659_POW_CLSD_DB_MASK, RT5659_POW_CLSD_DB_EN);
-		snd_soc_update_bits(codec, RT5659_CLASSD_2,
+		snd_soc_component_update_bits(component, RT5659_CLASSD_2,
 			RT5659_M_RI_DIG, RT5659_M_RI_DIG);
-		snd_soc_write(codec, RT5659_CLASSD_1, 0x0803);
-		snd_soc_write(codec, RT5659_SPK_DC_CAILB_CTRL_3, 0x0000);
+		snd_soc_component_write(component, RT5659_CLASSD_1, 0x0803);
+		snd_soc_component_write(component, RT5659_SPK_DC_CAILB_CTRL_3, 0x0000);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_write(codec, RT5659_CLASSD_1, 0x0011);
-		snd_soc_update_bits(codec, RT5659_CLASSD_2,
+		snd_soc_component_write(component, RT5659_CLASSD_1, 0x0011);
+		snd_soc_component_update_bits(component, RT5659_CLASSD_2,
 			RT5659_M_RI_DIG, 0x0);
-		snd_soc_write(codec, RT5659_SPK_DC_CAILB_CTRL_3, 0x0003);
-		snd_soc_update_bits(codec, RT5659_CLASSD_CTRL_1,
+		snd_soc_component_write(component, RT5659_SPK_DC_CAILB_CTRL_3, 0x0003);
+		snd_soc_component_update_bits(component, RT5659_CLASSD_CTRL_1,
 			RT5659_POW_CLSD_DB_MASK, RT5659_POW_CLSD_DB_DIS);
 		break;
 
@@ -2335,15 +2416,15 @@ static int rt5659_spk_event(struct snd_soc_dapm_widget *w,
 static int rt5659_mono_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_write(codec, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e00);
+		snd_soc_component_write(component, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e00);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_write(codec, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e04);
+		snd_soc_component_write(component, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e04);
 		break;
 
 	default:
@@ -2357,16 +2438,16 @@ static int rt5659_mono_event(struct snd_soc_dapm_widget *w,
 static int rt5659_hp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_write(codec, RT5659_HP_CHARGE_PUMP_1, 0x0e1e);
-		snd_soc_update_bits(codec, RT5659_DEPOP_1, 0x0010, 0x0010);
+		snd_soc_component_write(component, RT5659_HP_CHARGE_PUMP_1, 0x0e1e);
+		snd_soc_component_update_bits(component, RT5659_DEPOP_1, 0x0010, 0x0010);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_write(codec, RT5659_DEPOP_1, 0x0000);
+		snd_soc_component_write(component, RT5659_DEPOP_1, 0x0000);
 		break;
 
 	default:
@@ -2500,13 +2581,13 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
 		RT5659_PWR_ADC_L1_BIT, 0, NULL, 0),
 	SND_SOC_DAPM_SUPPLY("ADC1 R Power", RT5659_PWR_DIG_1,
 		RT5659_PWR_ADC_R1_BIT, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("ADC2 L Power", RT5659_PWR_DIG_2,
+	SND_SOC_DAPM_SUPPLY("ADC2 L Power", RT5659_PWR_DIG_1,
 		RT5659_PWR_ADC_L2_BIT, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("ADC2 R Power", RT5659_PWR_DIG_2,
+	SND_SOC_DAPM_SUPPLY("ADC2 R Power", RT5659_PWR_DIG_1,
 		RT5659_PWR_ADC_R2_BIT, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("ADC1 clock", SND_SOC_NOPM, 0, 0, set_adc_clk,
+	SND_SOC_DAPM_SUPPLY("ADC1 clock", SND_SOC_NOPM, 0, 0, set_adc1_clk,
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-	SND_SOC_DAPM_SUPPLY("ADC2 clock", SND_SOC_NOPM, 0, 0, set_adc_clk,
+	SND_SOC_DAPM_SUPPLY("ADC2 clock", SND_SOC_NOPM, 0, 0, set_adc2_clk,
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
 	/* ADC Mux */
@@ -2818,11 +2899,6 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
 	{ "I2S2", NULL, "I2S2 ASRC" },
 	{ "I2S3", NULL, "I2S3 ASRC" },
 
-	{ "IN1P", NULL, "LDO2" },
-	{ "IN2P", NULL, "LDO2" },
-	{ "IN3P", NULL, "LDO2" },
-	{ "IN4P", NULL, "LDO2" },
-
 	{ "DMIC1", NULL, "DMIC L1" },
 	{ "DMIC1", NULL, "DMIC R1" },
 	{ "DMIC2", NULL, "DMIC L2" },
@@ -3237,21 +3313,21 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
 static int rt5659_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, mask_clk;
 	int pre_div, frame_size;
 
 	rt5659->lrck[dai->id] = params_rate(params);
 	pre_div = rl6231_get_clk_info(rt5659->sysclk, rt5659->lrck[dai->id]);
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+		dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
 			rt5659->lrck[dai->id], dai->id);
 		return -EINVAL;
 	}
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return -EINVAL;
 	}
 
@@ -3278,39 +3354,39 @@ static int rt5659_hw_params(struct snd_pcm_substream *substream,
 	case RT5659_AIF1:
 		mask_clk = RT5659_I2S_PD1_MASK;
 		val_clk = pre_div << RT5659_I2S_PD1_SFT;
-		snd_soc_update_bits(codec, RT5659_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5659_I2S1_SDP,
 			RT5659_I2S_DL_MASK, val_len);
 		break;
 	case RT5659_AIF2:
 		mask_clk = RT5659_I2S_PD2_MASK;
 		val_clk = pre_div << RT5659_I2S_PD2_SFT;
-		snd_soc_update_bits(codec, RT5659_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5659_I2S2_SDP,
 			RT5659_I2S_DL_MASK, val_len);
 		break;
 	case RT5659_AIF3:
 		mask_clk = RT5659_I2S_PD3_MASK;
 		val_clk = pre_div << RT5659_I2S_PD3_SFT;
-		snd_soc_update_bits(codec, RT5659_I2S3_SDP,
+		snd_soc_component_update_bits(component, RT5659_I2S3_SDP,
 			RT5659_I2S_DL_MASK, val_len);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5659_ADDA_CLK_1, mask_clk, val_clk);
+	snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1, mask_clk, val_clk);
 
 	switch (rt5659->lrck[dai->id]) {
 	case 192000:
-		snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+		snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
 			RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_32);
 		break;
 	case 96000:
-		snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+		snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
 			RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_64);
 		break;
 	default:
-		snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+		snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
 			RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_128);
 		break;
 	}
@@ -3320,8 +3396,8 @@ static int rt5659_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5659_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -3364,31 +3440,31 @@ static int rt5659_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (dai->id) {
 	case RT5659_AIF1:
-		snd_soc_update_bits(codec, RT5659_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5659_I2S1_SDP,
 			RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
 			RT5659_I2S_DF_MASK, reg_val);
 		break;
 	case RT5659_AIF2:
-		snd_soc_update_bits(codec, RT5659_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5659_I2S2_SDP,
 			RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
 			RT5659_I2S_DF_MASK, reg_val);
 		break;
 	case RT5659_AIF3:
-		snd_soc_update_bits(codec, RT5659_I2S3_SDP,
+		snd_soc_component_update_bits(component, RT5659_I2S3_SDP,
 			RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
 			RT5659_I2S_DF_MASK, reg_val);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 	return 0;
 }
 
-static int rt5659_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int rt5659_set_component_sysclk(struct snd_soc_component *component, int clk_id,
 				   int source, unsigned int freq, int dir)
 {
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	if (freq == rt5659->sysclk && clk_id == rt5659->sysclk_src)
@@ -3405,25 +3481,25 @@ static int rt5659_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
 		reg_val |= RT5659_SCLK_SRC_RCCLK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, RT5659_GLB_CLK,
+	snd_soc_component_update_bits(component, RT5659_GLB_CLK,
 		RT5659_SCLK_SRC_MASK, reg_val);
 	rt5659->sysclk = freq;
 	rt5659->sysclk_src = clk_id;
 
-	dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n",
+	dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
 		freq, clk_id);
 
 	return 0;
 }
 
-static int rt5659_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
+static int rt5659_set_component_pll(struct snd_soc_component *component, int pll_id,
 				int source, unsigned int freq_in,
 				unsigned int freq_out)
 {
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -3432,50 +3508,50 @@ static int rt5659_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5659->pll_in = 0;
 		rt5659->pll_out = 0;
-		snd_soc_update_bits(codec, RT5659_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5659_GLB_CLK,
 			RT5659_SCLK_SRC_MASK, RT5659_SCLK_SRC_MCLK);
 		return 0;
 	}
 
 	switch (source) {
 	case RT5659_PLL1_S_MCLK:
-		snd_soc_update_bits(codec, RT5659_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5659_GLB_CLK,
 			RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_MCLK);
 		break;
 	case RT5659_PLL1_S_BCLK1:
-		snd_soc_update_bits(codec, RT5659_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5659_GLB_CLK,
 				RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK1);
 		break;
 	case RT5659_PLL1_S_BCLK2:
-		snd_soc_update_bits(codec, RT5659_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5659_GLB_CLK,
 				RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK2);
 		break;
 	case RT5659_PLL1_S_BCLK3:
-		snd_soc_update_bits(codec, RT5659_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5659_GLB_CLK,
 				RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK3);
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
-	snd_soc_write(codec, RT5659_PLL_CTRL_1,
+	snd_soc_component_write(component, RT5659_PLL_CTRL_1,
 		pll_code.n_code << RT5659_PLL_N_SFT | pll_code.k_code);
-	snd_soc_write(codec, RT5659_PLL_CTRL_2,
+	snd_soc_component_write(component, RT5659_PLL_CTRL_2,
 		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5659_PLL_M_SFT |
 		pll_code.m_bp << RT5659_PLL_M_BP_SFT);
 
@@ -3489,7 +3565,7 @@ static int rt5659_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
 static int rt5659_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val = 0;
 
 	if (rx_mask || tx_mask)
@@ -3533,29 +3609,29 @@ static int rt5659_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5659_TDM_CTRL_1, 0x8ff0, val);
+	snd_soc_component_update_bits(component, RT5659_TDM_CTRL_1, 0x8ff0, val);
 
 	return 0;
 }
 
 static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+	dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
 
 	rt5659->bclk[dai->id] = ratio;
 
 	if (ratio == 64) {
 		switch (dai->id) {
 		case RT5659_AIF2:
-			snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+			snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
 				RT5659_I2S_BCLK_MS2_MASK,
 				RT5659_I2S_BCLK_MS2_64);
 			break;
 		case RT5659_AIF3:
-			snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+			snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
 				RT5659_I2S_BCLK_MS3_MASK,
 				RT5659_I2S_BCLK_MS3_64);
 			break;
@@ -3565,11 +3641,11 @@ static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 	return 0;
 }
 
-static int rt5659_set_bias_level(struct snd_soc_codec *codec,
+static int rt5659_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -3591,7 +3667,7 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
 		if (dapm->bias_level == SND_SOC_BIAS_OFF) {
 			ret = clk_prepare_enable(rt5659->mclk);
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"failed to enable MCLK: %d\n", ret);
 				return ret;
 			}
@@ -3617,37 +3693,35 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5659_probe(struct snd_soc_codec *codec)
+static int rt5659_probe(struct snd_soc_component *component)
 {
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
-	rt5659->codec = codec;
+	rt5659->component = component;
 
 	return 0;
 }
 
-static int rt5659_remove(struct snd_soc_codec *codec)
+static void rt5659_remove(struct snd_soc_component *component)
 {
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
 	regmap_write(rt5659->regmap, RT5659_RESET, 0);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5659_suspend(struct snd_soc_codec *codec)
+static int rt5659_suspend(struct snd_soc_component *component)
 {
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5659->regmap, true);
 	regcache_mark_dirty(rt5659->regmap);
 	return 0;
 }
 
-static int rt5659_resume(struct snd_soc_codec *codec)
+static int rt5659_resume(struct snd_soc_component *component)
 {
-	struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+	struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5659->regmap, false);
 	regcache_sync(rt5659->regmap);
@@ -3730,23 +3804,23 @@ static struct snd_soc_dai_driver rt5659_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5659 = {
-	.probe = rt5659_probe,
-	.remove = rt5659_remove,
-	.suspend = rt5659_suspend,
-	.resume = rt5659_resume,
-	.set_bias_level = rt5659_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt5659_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5659_snd_controls),
-		.dapm_widgets		= rt5659_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5659_dapm_widgets),
-		.dapm_routes		= rt5659_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5659_dapm_routes),
-	},
-	.set_sysclk = rt5659_set_codec_sysclk,
-	.set_pll = rt5659_set_codec_pll,
+static const struct snd_soc_component_driver soc_component_dev_rt5659 = {
+	.probe			= rt5659_probe,
+	.remove			= rt5659_remove,
+	.suspend		= rt5659_suspend,
+	.resume			= rt5659_resume,
+	.set_bias_level		= rt5659_set_bias_level,
+	.controls		= rt5659_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5659_snd_controls),
+	.dapm_widgets		= rt5659_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5659_dapm_widgets),
+	.dapm_routes		= rt5659_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5659_dapm_routes),
+	.set_sysclk		= rt5659_set_component_sysclk,
+	.set_pll		= rt5659_set_component_pll,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 
@@ -3849,7 +3923,7 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
 			break;
 
 		if (count > 30) {
-			dev_err(rt5659->codec->dev,
+			dev_err(rt5659->component->dev,
 				"HP Calibration 1 Failure\n");
 			return;
 		}
@@ -3874,7 +3948,7 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
 			break;
 
 		if (count > 85) {
-			dev_err(rt5659->codec->dev,
+			dev_err(rt5659->component->dev,
 				"HP Calibration 2 Failure\n");
 			return;
 		}
@@ -3922,7 +3996,7 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
 			break;
 
 		if (count > 10) {
-			dev_err(rt5659->codec->dev,
+			dev_err(rt5659->component->dev,
 				"SPK Calibration Failure\n");
 			return;
 		}
@@ -3955,7 +4029,7 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
 			break;
 
 		if (count > 35) {
-			dev_err(rt5659->codec->dev,
+			dev_err(rt5659->component->dev,
 				"Mono Calibration Failure\n");
 			return;
 		}
@@ -3990,6 +4064,54 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
 	regmap_write(rt5659->regmap, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
 }
 
+static void rt5659_intel_hd_header_probe_setup(struct rt5659_priv *rt5659)
+{
+	int value;
+
+	regmap_read(rt5659->regmap, RT5659_GPIO_STA, &value);
+	if (!(value & 0x8)) {
+		rt5659->hda_hp_plugged = true;
+		regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+			0x10, 0x0);
+	} else {
+		regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+			0x10, 0x10);
+	}
+
+	regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
+		RT5659_PWR_VREF2 | RT5659_PWR_MB,
+		RT5659_PWR_VREF2 | RT5659_PWR_MB);
+	msleep(20);
+	regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
+		RT5659_PWR_FV2, RT5659_PWR_FV2);
+
+	regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_3, RT5659_PWR_LDO2,
+		RT5659_PWR_LDO2);
+	regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_2, RT5659_PWR_MB1,
+		RT5659_PWR_MB1);
+	regmap_update_bits(rt5659->regmap, RT5659_PWR_VOL, RT5659_PWR_MIC_DET,
+		RT5659_PWR_MIC_DET);
+	msleep(20);
+
+	regmap_update_bits(rt5659->regmap, RT5659_4BTN_IL_CMD_2,
+		RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_EN);
+	regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+	regmap_write(rt5659->regmap, RT5659_4BTN_IL_CMD_1, value);
+	regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+
+	if (value & 0x2000) {
+		rt5659->hda_mic_plugged = true;
+		regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+			0x2, 0x2);
+	} else {
+		regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+			0x2, 0x0);
+	}
+
+	regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+		RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_EN);
+}
+
 static int rt5659_i2c_probe(struct i2c_client *i2c,
 		    const struct i2c_device_id *id)
 {
@@ -4174,16 +4296,23 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
 				RT5659_PWR_MB, RT5659_PWR_MB);
 		regmap_write(rt5659->regmap, RT5659_PWR_ANLG_2, 0x0001);
 		regmap_write(rt5659->regmap, RT5659_IRQ_CTRL_2, 0x0040);
+		INIT_DELAYED_WORK(&rt5659->jack_detect_work,
+			rt5659_jack_detect_work);
 		break;
-	case RT5659_JD_NULL:
+	case RT5659_JD_HDA_HEADER:
+		regmap_write(rt5659->regmap, RT5659_GPIO_CTRL_3, 0x8000);
+		regmap_write(rt5659->regmap, RT5659_RC_CLK_CTRL, 0x0900);
+		regmap_write(rt5659->regmap, RT5659_EJD_CTRL_1,  0x70c0);
+		regmap_write(rt5659->regmap, RT5659_JD_CTRL_1,   0x2000);
+		regmap_write(rt5659->regmap, RT5659_IRQ_CTRL_1,  0x0040);
+		INIT_DELAYED_WORK(&rt5659->jack_detect_work,
+			rt5659_jack_detect_intel_hd_header);
+		rt5659_intel_hd_header_probe_setup(rt5659);
 		break;
 	default:
-		dev_warn(&i2c->dev, "Currently, support JD3 only\n");
 		break;
 	}
 
-	INIT_DELAYED_WORK(&rt5659->jack_detect_work, rt5659_jack_detect_work);
-
 	if (i2c->irq) {
 		ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
 			rt5659_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
@@ -4196,17 +4325,11 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
 				   RT5659_GP1_PIN_MASK, RT5659_GP1_PIN_IRQ);
 	}
 
-	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
+	return devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_rt5659,
 			rt5659_dai, ARRAY_SIZE(rt5659_dai));
 }
 
-static int rt5659_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-
-	return 0;
-}
-
 static void rt5659_i2c_shutdown(struct i2c_client *client)
 {
 	struct rt5659_priv *rt5659 = i2c_get_clientdata(client);
@@ -4239,7 +4362,6 @@ static struct i2c_driver rt5659_i2c_driver = {
 		.acpi_match_table = ACPI_PTR(rt5659_acpi_match),
 	},
 	.probe = rt5659_i2c_probe,
-	.remove = rt5659_i2c_remove,
 	.shutdown = rt5659_i2c_shutdown,
 	.id_table = rt5659_i2c_id,
 };
diff --git a/sound/soc/codecs/rt5659.h b/sound/soc/codecs/rt5659.h
index 8f1aeef..8b576d7 100644
--- a/sound/soc/codecs/rt5659.h
+++ b/sound/soc/codecs/rt5659.h
@@ -1008,7 +1008,7 @@
 #define RT5659_PWR_ADC_R1			(0x1 << 3)
 #define RT5659_PWR_ADC_R1_BIT			3
 #define RT5659_PWR_ADC_L2			(0x1 << 2)
-#define RT5659_PWR_ADC_L2_BIT			4
+#define RT5659_PWR_ADC_L2_BIT			2
 #define RT5659_PWR_ADC_R2			(0x1 << 1)
 #define RT5659_PWR_ADC_R2_BIT			1
 #define RT5659_PWR_CLS_D			(0x1)
@@ -1743,10 +1743,14 @@
 #define RT5659_CKGEN_DAC2_SFT			4
 
 /* Chopper and Clock control for ADC (0x013b)*/
-#define RT5659_CKXEN_ADCC_MASK			(0x1 << 13)
-#define RT5659_CKXEN_ADCC_SFT			13
-#define RT5659_CKGEN_ADCC_MASK			(0x1 << 12)
-#define RT5659_CKGEN_ADCC_SFT			12
+#define RT5659_CKXEN_ADC1_MASK			(0x1 << 13)
+#define RT5659_CKXEN_ADC1_SFT			13
+#define RT5659_CKGEN_ADC1_MASK			(0x1 << 12)
+#define RT5659_CKGEN_ADC1_SFT			12
+#define RT5659_CKXEN_ADC2_MASK			(0x1 << 5)
+#define RT5659_CKXEN_ADC2_SFT			5
+#define RT5659_CKGEN_ADC2_MASK			(0x1 << 4)
+#define RT5659_CKGEN_ADC2_SFT			4
 
 /* Test Mode Control 1 (0x0145) */
 #define RT5659_AD2DA_LB_MASK			(0x1 << 9)
@@ -1789,7 +1793,7 @@ struct rt5659_pll_code {
 };
 
 struct rt5659_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt5659_platform_data pdata;
 	struct regmap *regmap;
 	struct gpio_desc *gpiod_ldo1_en;
@@ -1810,10 +1814,11 @@ struct rt5659_priv {
 	int pll_out;
 
 	int jack_type;
-
+	bool hda_hp_plugged;
+	bool hda_mic_plugged;
 };
 
-int rt5659_set_jack_detect(struct snd_soc_codec *codec,
+int rt5659_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack);
 
 #endif /* __RT5659_H__ */
diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c
index d22ef00..20a7551 100644
--- a/sound/soc/codecs/rt5660.c
+++ b/sound/soc/codecs/rt5660.c
@@ -354,17 +354,17 @@ static const struct snd_kcontrol_new rt5660_snd_controls[] = {
 static int rt5660_set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 	int idx, rate;
 
 	rate = rt5660->sysclk / rl6231_get_pre_div(rt5660->regmap,
 		RT5660_ADDA_CLK1, RT5660_I2S_PD1_SFT);
 	idx = rl6231_calc_dmic_clk(rate);
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else
-		snd_soc_update_bits(codec, RT5660_DMIC_CTRL1,
+		snd_soc_component_update_bits(component, RT5660_DMIC_CTRL1,
 			RT5660_DMIC_CLK_MASK, idx << RT5660_DMIC_CLK_SFT);
 
 	return idx;
@@ -373,10 +373,10 @@ static int rt5660_set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int rt5660_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int val;
 
-	val = snd_soc_read(codec, RT5660_GLB_CLK);
+	val = snd_soc_component_read32(component, RT5660_GLB_CLK);
 	val &= RT5660_SCLK_SRC_MASK;
 	if (val == RT5660_SCLK_SRC_PLL1)
 		return 1;
@@ -541,17 +541,17 @@ static const struct snd_kcontrol_new rt5660_if1_adc_swap_mux =
 static int rt5660_lout_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL,
+		snd_soc_component_update_bits(component, RT5660_LOUT_AMP_CTRL,
 			RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK,
 			RT5660_LOUT_CO_EN | RT5660_LOUT_CB_PU);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL,
+		snd_soc_component_update_bits(component, RT5660_LOUT_AMP_CTRL,
 			RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK,
 			RT5660_LOUT_CO_DIS | RT5660_LOUT_CB_PD);
 		break;
@@ -838,22 +838,22 @@ static const struct snd_soc_dapm_route rt5660_dapm_routes[] = {
 static int rt5660_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, mask_clk;
 	int pre_div, bclk_ms, frame_size;
 
 	rt5660->lrck[dai->id] = params_rate(params);
 	pre_div = rl6231_get_clk_info(rt5660->sysclk, rt5660->lrck[dai->id]);
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+		dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
 			rt5660->lrck[dai->id], dai->id);
 		return -EINVAL;
 	}
 
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return frame_size;
 	}
 
@@ -890,13 +890,13 @@ static int rt5660_hw_params(struct snd_pcm_substream *substream,
 		mask_clk = RT5660_I2S_BCLK_MS1_MASK | RT5660_I2S_PD1_MASK;
 		val_clk = bclk_ms << RT5660_I2S_BCLK_MS1_SFT |
 			pre_div << RT5660_I2S_PD1_SFT;
-		snd_soc_update_bits(codec, RT5660_I2S1_SDP, RT5660_I2S_DL_MASK,
+		snd_soc_component_update_bits(component, RT5660_I2S1_SDP, RT5660_I2S_DL_MASK,
 			val_len);
-		snd_soc_update_bits(codec, RT5660_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5660_ADDA_CLK1, mask_clk, val_clk);
 		break;
 
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 
@@ -905,8 +905,8 @@ static int rt5660_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -957,13 +957,13 @@ static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (dai->id) {
 	case RT5660_AIF1:
-		snd_soc_update_bits(codec, RT5660_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5660_I2S1_SDP,
 			RT5660_I2S_MS_MASK | RT5660_I2S_BP_MASK |
 			RT5660_I2S_DF_MASK, reg_val);
 		break;
 
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 
@@ -973,8 +973,8 @@ static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	if (freq == rt5660->sysclk && clk_id == rt5660->sysclk_src)
@@ -994,11 +994,11 @@ static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai,
 		break;
 
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5660_GLB_CLK, RT5660_SCLK_SRC_MASK,
+	snd_soc_component_update_bits(component, RT5660_GLB_CLK, RT5660_SCLK_SRC_MASK,
 		reg_val);
 
 	rt5660->sysclk = freq;
@@ -1012,8 +1012,8 @@ static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -1022,44 +1022,44 @@ static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5660->pll_in = 0;
 		rt5660->pll_out = 0;
-		snd_soc_update_bits(codec, RT5660_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5660_GLB_CLK,
 			RT5660_SCLK_SRC_MASK, RT5660_SCLK_SRC_MCLK);
 		return 0;
 	}
 
 	switch (source) {
 	case RT5660_PLL1_S_MCLK:
-		snd_soc_update_bits(codec, RT5660_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5660_GLB_CLK,
 			RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_MCLK);
 		break;
 
 	case RT5660_PLL1_S_BCLK:
-		snd_soc_update_bits(codec, RT5660_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5660_GLB_CLK,
 			RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_BCLK1);
 		break;
 
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
-	snd_soc_write(codec, RT5660_PLL_CTRL1,
+	snd_soc_component_write(component, RT5660_PLL_CTRL1,
 		pll_code.n_code << RT5660_PLL_N_SFT | pll_code.k_code);
-	snd_soc_write(codec, RT5660_PLL_CTRL2,
+	snd_soc_component_write(component, RT5660_PLL_CTRL2,
 		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5660_PLL_M_SFT |
 		pll_code.m_bp << RT5660_PLL_M_BP_SFT);
 
@@ -1070,10 +1070,10 @@ static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 	return 0;
 }
 
-static int rt5660_set_bias_level(struct snd_soc_codec *codec,
+static int rt5660_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1081,13 +1081,13 @@ static int rt5660_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, RT5660_GEN_CTRL1,
+		snd_soc_component_update_bits(component, RT5660_GEN_CTRL1,
 			RT5660_DIG_GATE_CTRL, RT5660_DIG_GATE_CTRL);
 
 		if (IS_ERR(rt5660->mclk))
 			break;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
 			clk_disable_unprepare(rt5660->mclk);
 		} else {
 			ret = clk_prepare_enable(rt5660->mclk);
@@ -1097,21 +1097,21 @@ static int rt5660_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_update_bits(codec, RT5660_PWR_ANLG1,
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_update_bits(component, RT5660_PWR_ANLG1,
 				RT5660_PWR_VREF1 | RT5660_PWR_MB |
 				RT5660_PWR_BG | RT5660_PWR_VREF2,
 				RT5660_PWR_VREF1 | RT5660_PWR_MB |
 				RT5660_PWR_BG | RT5660_PWR_VREF2);
 			usleep_range(10000, 15000);
-			snd_soc_update_bits(codec, RT5660_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5660_PWR_ANLG1,
 				RT5660_PWR_FV1 | RT5660_PWR_FV2,
 				RT5660_PWR_FV1 | RT5660_PWR_FV2);
 		}
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, RT5660_GEN_CTRL1,
+		snd_soc_component_update_bits(component, RT5660_GEN_CTRL1,
 			RT5660_DIG_GATE_CTRL, 0);
 		break;
 
@@ -1122,24 +1122,24 @@ static int rt5660_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5660_probe(struct snd_soc_codec *codec)
+static int rt5660_probe(struct snd_soc_component *component)
 {
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 
-	rt5660->codec = codec;
+	rt5660->component = component;
 
 	return 0;
 }
 
-static int rt5660_remove(struct snd_soc_codec *codec)
+static void rt5660_remove(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, RT5660_RESET, 0);
+	snd_soc_component_write(component, RT5660_RESET, 0);
 }
 
 #ifdef CONFIG_PM
-static int rt5660_suspend(struct snd_soc_codec *codec)
+static int rt5660_suspend(struct snd_soc_component *component)
 {
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5660->regmap, true);
 	regcache_mark_dirty(rt5660->regmap);
@@ -1147,9 +1147,9 @@ static int rt5660_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt5660_resume(struct snd_soc_codec *codec)
+static int rt5660_resume(struct snd_soc_component *component)
 {
-	struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+	struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 
 	if (rt5660->pdata.poweroff_codec_in_suspend)
 		msleep(350);
@@ -1197,21 +1197,21 @@ static struct snd_soc_dai_driver rt5660_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5660 = {
-	.probe = rt5660_probe,
-	.remove = rt5660_remove,
-	.suspend = rt5660_suspend,
-	.resume = rt5660_resume,
-	.set_bias_level = rt5660_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt5660_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5660_snd_controls),
-		.dapm_widgets		= rt5660_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5660_dapm_widgets),
-		.dapm_routes		= rt5660_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5660_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5660 = {
+	.probe			= rt5660_probe,
+	.remove			= rt5660_remove,
+	.suspend		= rt5660_suspend,
+	.resume			= rt5660_resume,
+	.set_bias_level		= rt5660_set_bias_level,
+	.controls		= rt5660_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5660_snd_controls),
+	.dapm_widgets		= rt5660_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5660_dapm_widgets),
+	.dapm_routes		= rt5660_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5660_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt5660_regmap = {
@@ -1329,17 +1329,11 @@ static int rt5660_i2c_probe(struct i2c_client *i2c,
 				RT5660_SEL_DMIC_DATA_IN1P);
 	}
 
-	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5660,
+	return devm_snd_soc_register_component(&i2c->dev,
+				      &soc_component_dev_rt5660,
 				      rt5660_dai, ARRAY_SIZE(rt5660_dai));
 }
 
-static int rt5660_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-
-	return 0;
-}
-
 static struct i2c_driver rt5660_i2c_driver = {
 	.driver = {
 		.name = "rt5660",
@@ -1347,7 +1341,6 @@ static struct i2c_driver rt5660_i2c_driver = {
 		.of_match_table = of_match_ptr(rt5660_of_match),
 	},
 	.probe = rt5660_i2c_probe,
-	.remove   = rt5660_i2c_remove,
 	.id_table = rt5660_i2c_id,
 };
 module_i2c_driver(rt5660_i2c_driver);
diff --git a/sound/soc/codecs/rt5660.h b/sound/soc/codecs/rt5660.h
index bba18fb6..c65de0a 100644
--- a/sound/soc/codecs/rt5660.h
+++ b/sound/soc/codecs/rt5660.h
@@ -831,7 +831,7 @@ enum {
 };
 
 struct rt5660_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt5660_platform_data pdata;
 	struct regmap *regmap;
 	struct clk *mclk;
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
index d329bf7..20c0aee 100644
--- a/sound/soc/codecs/rt5663.c
+++ b/sound/soc/codecs/rt5663.c
@@ -49,7 +49,7 @@ struct impedance_mapping_table {
 };
 
 struct rt5663_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt5663_platform_data pdata;
 	struct regmap *regmap;
 	struct delayed_work jack_detect_work, jd_unplug_work;
@@ -1384,57 +1384,57 @@ static const char * const rt5663_if1_adc_data_select[] = {
 static SOC_ENUM_SINGLE_DECL(rt5663_if1_adc_enum, RT5663_TDM_2,
 	RT5663_DATA_SWAP_ADCDAT1_SHIFT, rt5663_if1_adc_data_select);
 
-static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec,
+static void rt5663_enable_push_button_irq(struct snd_soc_component *component,
 	bool enable)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	if (enable) {
-		snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+		snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
 			RT5663_EN_4BTN_INL_MASK, RT5663_EN_4BTN_INL_EN);
 		/* reset in-line command */
-		snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+		snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
 			RT5663_RESET_4BTN_INL_MASK,
 			RT5663_RESET_4BTN_INL_RESET);
-		snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+		snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
 			RT5663_RESET_4BTN_INL_MASK,
 			RT5663_RESET_4BTN_INL_NOR);
 		switch (rt5663->codec_ver) {
 		case CODEC_VER_1:
-			snd_soc_update_bits(codec, RT5663_IRQ_3,
+			snd_soc_component_update_bits(component, RT5663_IRQ_3,
 				RT5663_V2_EN_IRQ_INLINE_MASK,
 				RT5663_V2_EN_IRQ_INLINE_NOR);
 			break;
 		case CODEC_VER_0:
-			snd_soc_update_bits(codec, RT5663_IRQ_2,
+			snd_soc_component_update_bits(component, RT5663_IRQ_2,
 				RT5663_EN_IRQ_INLINE_MASK,
 				RT5663_EN_IRQ_INLINE_NOR);
 			break;
 		default:
-			dev_err(codec->dev, "Unknown CODEC Version\n");
+			dev_err(component->dev, "Unknown CODEC Version\n");
 		}
 	} else {
 		switch (rt5663->codec_ver) {
 		case CODEC_VER_1:
-			snd_soc_update_bits(codec, RT5663_IRQ_3,
+			snd_soc_component_update_bits(component, RT5663_IRQ_3,
 				RT5663_V2_EN_IRQ_INLINE_MASK,
 				RT5663_V2_EN_IRQ_INLINE_BYP);
 			break;
 		case CODEC_VER_0:
-			snd_soc_update_bits(codec, RT5663_IRQ_2,
+			snd_soc_component_update_bits(component, RT5663_IRQ_2,
 				RT5663_EN_IRQ_INLINE_MASK,
 				RT5663_EN_IRQ_INLINE_BYP);
 			break;
 		default:
-			dev_err(codec->dev, "Unknown CODEC Version\n");
+			dev_err(component->dev, "Unknown CODEC Version\n");
 		}
-		snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+		snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
 			RT5663_EN_4BTN_INL_MASK, RT5663_EN_4BTN_INL_DIS);
 		/* reset in-line command */
-		snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+		snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
 			RT5663_RESET_4BTN_INL_MASK,
 			RT5663_RESET_4BTN_INL_RESET);
-		snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+		snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
 			RT5663_RESET_4BTN_INL_MASK,
 			RT5663_RESET_4BTN_INL_NOR);
 	}
@@ -1442,7 +1442,7 @@ static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec,
 
 /**
  * rt5663_v2_jack_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
@@ -1450,41 +1450,41 @@ static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec,
  * Returns detect status.
  */
 
-static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5663_v2_jack_detect(struct snd_soc_component *component, int jack_insert)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
 
-	dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert);
+	dev_dbg(component->dev, "%s jack_insert:%d\n", __func__, jack_insert);
 	if (jack_insert) {
-		snd_soc_write(codec, RT5663_CBJ_TYPE_2, 0x8040);
-		snd_soc_write(codec, RT5663_CBJ_TYPE_3, 0x1484);
+		snd_soc_component_write(component, RT5663_CBJ_TYPE_2, 0x8040);
+		snd_soc_component_write(component, RT5663_CBJ_TYPE_3, 0x1484);
 
 		snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
 		snd_soc_dapm_force_enable_pin(dapm, "MICBIAS2");
 		snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
 		snd_soc_dapm_force_enable_pin(dapm, "CBJ Power");
 		snd_soc_dapm_sync(dapm);
-		snd_soc_update_bits(codec, RT5663_RC_CLK,
+		snd_soc_component_update_bits(component, RT5663_RC_CLK,
 			RT5663_DIG_1M_CLK_MASK, RT5663_DIG_1M_CLK_EN);
-		snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x8);
+		snd_soc_component_update_bits(component, RT5663_RECMIX, 0x8, 0x8);
 
 		while (i < 5) {
 			msleep(sleep_time[i]);
-			val = snd_soc_read(codec, RT5663_CBJ_TYPE_2) & 0x0003;
+			val = snd_soc_component_read32(component, RT5663_CBJ_TYPE_2) & 0x0003;
 			if (val == 0x1 || val == 0x2 || val == 0x3)
 				break;
-			dev_dbg(codec->dev, "%s: MX-0011 val=%x sleep %d\n",
+			dev_dbg(component->dev, "%s: MX-0011 val=%x sleep %d\n",
 				__func__, val, sleep_time[i]);
 			i++;
 		}
-		dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
+		dev_dbg(component->dev, "%s val = %d\n", __func__, val);
 		switch (val) {
 		case 1:
 		case 2:
 			rt5663->jack_type = SND_JACK_HEADSET;
-			rt5663_enable_push_button_irq(codec, true);
+			rt5663_enable_push_button_irq(component, true);
 			break;
 		default:
 			snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
@@ -1496,10 +1496,10 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 			break;
 		}
 	} else {
-		snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x0);
+		snd_soc_component_update_bits(component, RT5663_RECMIX, 0x8, 0x0);
 
 		if (rt5663->jack_type == SND_JACK_HEADSET) {
-			rt5663_enable_push_button_irq(codec, false);
+			rt5663_enable_push_button_irq(component, false);
 			snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
 			snd_soc_dapm_disable_pin(dapm, "MICBIAS2");
 			snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
@@ -1509,60 +1509,60 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 		rt5663->jack_type = 0;
 	}
 
-	dev_dbg(codec->dev, "jack_type = %d\n", rt5663->jack_type);
+	dev_dbg(component->dev, "jack_type = %d\n", rt5663->jack_type);
 	return rt5663->jack_type;
 }
 
 /**
  * rt5663_jack_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
  *
  * Returns detect status.
  */
-static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5663_jack_detect(struct snd_soc_component *component, int jack_insert)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	int val, i = 0;
 
-	dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert);
+	dev_dbg(component->dev, "%s jack_insert:%d\n", __func__, jack_insert);
 
 	if (jack_insert) {
-		snd_soc_update_bits(codec, RT5663_DIG_MISC,
+		snd_soc_component_update_bits(component, RT5663_DIG_MISC,
 			RT5663_DIG_GATE_CTRL_MASK, RT5663_DIG_GATE_CTRL_EN);
-		snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
 			RT5663_SI_HP_MASK | RT5663_OSW_HP_L_MASK |
 			RT5663_OSW_HP_R_MASK, RT5663_SI_HP_EN |
 			RT5663_OSW_HP_L_DIS | RT5663_OSW_HP_R_DIS);
-		snd_soc_update_bits(codec, RT5663_DUMMY_1,
+		snd_soc_component_update_bits(component, RT5663_DUMMY_1,
 			RT5663_EMB_CLK_MASK | RT5663_HPA_CPL_BIAS_MASK |
 			RT5663_HPA_CPR_BIAS_MASK, RT5663_EMB_CLK_EN |
 			RT5663_HPA_CPL_BIAS_1 | RT5663_HPA_CPR_BIAS_1);
-		snd_soc_update_bits(codec, RT5663_CBJ_1,
+		snd_soc_component_update_bits(component, RT5663_CBJ_1,
 			RT5663_INBUF_CBJ_BST1_MASK | RT5663_CBJ_SENSE_BST1_MASK,
 			RT5663_INBUF_CBJ_BST1_ON | RT5663_CBJ_SENSE_BST1_L);
-		snd_soc_update_bits(codec, RT5663_IL_CMD_2,
+		snd_soc_component_update_bits(component, RT5663_IL_CMD_2,
 			RT5663_PWR_MIC_DET_MASK, RT5663_PWR_MIC_DET_ON);
 		/* BST1 power on for JD */
-		snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+		snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
 			RT5663_PWR_BST1_MASK, RT5663_PWR_BST1_ON);
-		snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1,
+		snd_soc_component_update_bits(component, RT5663_EM_JACK_TYPE_1,
 			RT5663_CBJ_DET_MASK | RT5663_EXT_JD_MASK |
 			RT5663_POL_EXT_JD_MASK, RT5663_CBJ_DET_EN |
 			RT5663_EXT_JD_EN | RT5663_POL_EXT_JD_EN);
-		snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+		snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
 			RT5663_PWR_MB_MASK | RT5663_LDO1_DVO_MASK |
 			RT5663_AMP_HP_MASK, RT5663_PWR_MB |
 			RT5663_LDO1_DVO_0_9V | RT5663_AMP_HP_3X);
-		snd_soc_update_bits(codec, RT5663_AUTO_1MRC_CLK,
+		snd_soc_component_update_bits(component, RT5663_AUTO_1MRC_CLK,
 			RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN);
-		snd_soc_update_bits(codec, RT5663_IRQ_1,
+		snd_soc_component_update_bits(component, RT5663_IRQ_1,
 			RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN);
-		snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1,
+		snd_soc_component_update_bits(component, RT5663_EM_JACK_TYPE_1,
 			RT5663_EM_JD_MASK, RT5663_EM_JD_RST);
-		snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1,
+		snd_soc_component_update_bits(component, RT5663_EM_JACK_TYPE_1,
 			RT5663_EM_JD_MASK, RT5663_EM_JD_NOR);
 
 		while (true) {
@@ -1577,10 +1577,10 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 			i++;
 		}
 
-		val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & 0x0003;
-		dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
+		val = snd_soc_component_read32(component, RT5663_EM_JACK_TYPE_2) & 0x0003;
+		dev_dbg(component->dev, "%s val = %d\n", __func__, val);
 
-		snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
 			RT5663_OSW_HP_L_MASK | RT5663_OSW_HP_R_MASK,
 			RT5663_OSW_HP_L_EN | RT5663_OSW_HP_R_EN);
 
@@ -1588,7 +1588,7 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 		case 1:
 		case 2:
 			rt5663->jack_type = SND_JACK_HEADSET;
-			rt5663_enable_push_button_irq(codec, true);
+			rt5663_enable_push_button_irq(component, true);
 
 			if (rt5663->pdata.impedance_sensing_num)
 				break;
@@ -1636,17 +1636,17 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 		}
 	} else {
 		if (rt5663->jack_type == SND_JACK_HEADSET)
-			rt5663_enable_push_button_irq(codec, false);
+			rt5663_enable_push_button_irq(component, false);
 		rt5663->jack_type = 0;
 	}
 
-	dev_dbg(codec->dev, "jack_type = %d\n", rt5663->jack_type);
+	dev_dbg(component->dev, "jack_type = %d\n", rt5663->jack_type);
 	return rt5663->jack_type;
 }
 
-static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
+static int rt5663_impedance_sensing(struct snd_soc_component *component)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	unsigned int value, i, reg84, reg26, reg2fa, reg91, reg10, reg80;
 
 	for (i = 0; i < rt5663->pdata.impedance_sensing_num; i++) {
@@ -1655,59 +1655,59 @@ static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
 	}
 
 	if (rt5663->jack_type == SND_JACK_HEADSET) {
-		snd_soc_write(codec, RT5663_MIC_DECRO_2,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_2,
 			rt5663->imp_table[i].dc_offset_l_manual_mic >> 16);
-		snd_soc_write(codec, RT5663_MIC_DECRO_3,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_3,
 			rt5663->imp_table[i].dc_offset_l_manual_mic & 0xffff);
-		snd_soc_write(codec, RT5663_MIC_DECRO_5,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_5,
 			rt5663->imp_table[i].dc_offset_r_manual_mic >> 16);
-		snd_soc_write(codec, RT5663_MIC_DECRO_6,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_6,
 			rt5663->imp_table[i].dc_offset_r_manual_mic & 0xffff);
 	} else {
-		snd_soc_write(codec, RT5663_MIC_DECRO_2,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_2,
 			rt5663->imp_table[i].dc_offset_l_manual >> 16);
-		snd_soc_write(codec, RT5663_MIC_DECRO_3,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_3,
 			rt5663->imp_table[i].dc_offset_l_manual & 0xffff);
-		snd_soc_write(codec, RT5663_MIC_DECRO_5,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_5,
 			rt5663->imp_table[i].dc_offset_r_manual >> 16);
-		snd_soc_write(codec, RT5663_MIC_DECRO_6,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_6,
 			rt5663->imp_table[i].dc_offset_r_manual & 0xffff);
 	}
 
-	reg84 = snd_soc_read(codec, RT5663_ASRC_2);
-	reg26 = snd_soc_read(codec, RT5663_STO1_ADC_MIXER);
-	reg2fa = snd_soc_read(codec, RT5663_DUMMY_1);
-	reg91 = snd_soc_read(codec, RT5663_HP_CHARGE_PUMP_1);
-	reg10 = snd_soc_read(codec, RT5663_RECMIX);
-	reg80 = snd_soc_read(codec, RT5663_GLB_CLK);
+	reg84 = snd_soc_component_read32(component, RT5663_ASRC_2);
+	reg26 = snd_soc_component_read32(component, RT5663_STO1_ADC_MIXER);
+	reg2fa = snd_soc_component_read32(component, RT5663_DUMMY_1);
+	reg91 = snd_soc_component_read32(component, RT5663_HP_CHARGE_PUMP_1);
+	reg10 = snd_soc_component_read32(component, RT5663_RECMIX);
+	reg80 = snd_soc_component_read32(component, RT5663_GLB_CLK);
 
-	snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000, 0);
-	snd_soc_write(codec, RT5663_ASRC_2, 0);
-	snd_soc_write(codec, RT5663_STO1_ADC_MIXER, 0x4040);
-	snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+	snd_soc_component_update_bits(component, RT5663_STO_DRE_1, 0x8000, 0);
+	snd_soc_component_write(component, RT5663_ASRC_2, 0);
+	snd_soc_component_write(component, RT5663_STO1_ADC_MIXER, 0x4040);
+	snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
 		RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
 		RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
 		RT5663_PWR_VREF1 | RT5663_PWR_VREF2);
 	usleep_range(10000, 10005);
-	snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+	snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
 		RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
 		RT5663_PWR_FV1 | RT5663_PWR_FV2);
-	snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
+	snd_soc_component_update_bits(component, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
 		RT5663_SCLK_SRC_RCCLK);
-	snd_soc_update_bits(codec, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
+	snd_soc_component_update_bits(component, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
 		RT5663_DIG_25M_CLK_EN);
-	snd_soc_update_bits(codec, RT5663_ADDA_CLK_1, RT5663_I2S_PD1_MASK, 0);
-	snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00);
-	snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc);
-	snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_1, 0x1232);
-	snd_soc_write(codec, RT5663_HP_LOGIC_2, 0x0005);
-	snd_soc_write(codec, RT5663_DEPOP_2, 0x3003);
-	snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0030);
-	snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0x0003);
-	snd_soc_update_bits(codec, RT5663_PWR_DIG_2,
+	snd_soc_component_update_bits(component, RT5663_ADDA_CLK_1, RT5663_I2S_PD1_MASK, 0);
+	snd_soc_component_write(component, RT5663_PRE_DIV_GATING_1, 0xff00);
+	snd_soc_component_write(component, RT5663_PRE_DIV_GATING_2, 0xfffc);
+	snd_soc_component_write(component, RT5663_HP_CHARGE_PUMP_1, 0x1232);
+	snd_soc_component_write(component, RT5663_HP_LOGIC_2, 0x0005);
+	snd_soc_component_write(component, RT5663_DEPOP_2, 0x3003);
+	snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0030, 0x0030);
+	snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0003, 0x0003);
+	snd_soc_component_update_bits(component, RT5663_PWR_DIG_2,
 		RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F,
 		RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F);
-	snd_soc_update_bits(codec, RT5663_PWR_DIG_1,
+	snd_soc_component_update_bits(component, RT5663_PWR_DIG_1,
 		RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 |
 		RT5663_PWR_LDO_DACREF_MASK | RT5663_PWR_ADC_L1 |
 		RT5663_PWR_ADC_R1,
@@ -1715,71 +1715,71 @@ static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
 		RT5663_PWR_LDO_DACREF_ON | RT5663_PWR_ADC_L1 |
 		RT5663_PWR_ADC_R1);
 	msleep(40);
-	snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+	snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
 		RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2,
 		RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2);
 	msleep(30);
-	snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371);
-	snd_soc_write(codec, RT5663_STO_DAC_MIXER, 0);
-	snd_soc_write(codec, RT5663_BYPASS_STO_DAC, 0x000c);
-	snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa);
-	snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224);
-	snd_soc_write(codec, RT5663_HP_OUT_EN, 0x8088);
-	snd_soc_write(codec, RT5663_CHOP_ADC, 0x3000);
-	snd_soc_write(codec, RT5663_ADDA_RST, 0xc000);
-	snd_soc_write(codec, RT5663_STO1_HPF_ADJ1, 0x3320);
-	snd_soc_write(codec, RT5663_HP_CALIB_2, 0x00c9);
-	snd_soc_write(codec, RT5663_DUMMY_1, 0x004c);
-	snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7733);
-	snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777);
-	snd_soc_write(codec, RT5663_STO_DRE_9, 0x0007);
-	snd_soc_write(codec, RT5663_STO_DRE_10, 0x0007);
-	snd_soc_write(codec, RT5663_DUMMY_2, 0x02a4);
-	snd_soc_write(codec, RT5663_RECMIX, 0x0005);
-	snd_soc_write(codec, RT5663_HP_IMP_SEN_1, 0x4334);
-	snd_soc_update_bits(codec, RT5663_IRQ_3, 0x0004, 0x0004);
-	snd_soc_write(codec, RT5663_HP_LOGIC_1, 0x2200);
-	snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x3000);
-	snd_soc_write(codec, RT5663_HP_LOGIC_1, 0x6200);
+	snd_soc_component_write(component, RT5663_HP_CHARGE_PUMP_2, 0x1371);
+	snd_soc_component_write(component, RT5663_STO_DAC_MIXER, 0);
+	snd_soc_component_write(component, RT5663_BYPASS_STO_DAC, 0x000c);
+	snd_soc_component_write(component, RT5663_HP_BIAS, 0xafaa);
+	snd_soc_component_write(component, RT5663_CHARGE_PUMP_1, 0x2224);
+	snd_soc_component_write(component, RT5663_HP_OUT_EN, 0x8088);
+	snd_soc_component_write(component, RT5663_CHOP_ADC, 0x3000);
+	snd_soc_component_write(component, RT5663_ADDA_RST, 0xc000);
+	snd_soc_component_write(component, RT5663_STO1_HPF_ADJ1, 0x3320);
+	snd_soc_component_write(component, RT5663_HP_CALIB_2, 0x00c9);
+	snd_soc_component_write(component, RT5663_DUMMY_1, 0x004c);
+	snd_soc_component_write(component, RT5663_ANA_BIAS_CUR_1, 0x7733);
+	snd_soc_component_write(component, RT5663_CHARGE_PUMP_2, 0x7777);
+	snd_soc_component_write(component, RT5663_STO_DRE_9, 0x0007);
+	snd_soc_component_write(component, RT5663_STO_DRE_10, 0x0007);
+	snd_soc_component_write(component, RT5663_DUMMY_2, 0x02a4);
+	snd_soc_component_write(component, RT5663_RECMIX, 0x0005);
+	snd_soc_component_write(component, RT5663_HP_IMP_SEN_1, 0x4334);
+	snd_soc_component_update_bits(component, RT5663_IRQ_3, 0x0004, 0x0004);
+	snd_soc_component_write(component, RT5663_HP_LOGIC_1, 0x2200);
+	snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0x3000);
+	snd_soc_component_write(component, RT5663_HP_LOGIC_1, 0x6200);
 
 	for (i = 0; i < 100; i++) {
 		msleep(20);
-		if (snd_soc_read(codec, RT5663_INT_ST_1) & 0x2)
+		if (snd_soc_component_read32(component, RT5663_INT_ST_1) & 0x2)
 			break;
 	}
 
-	value = snd_soc_read(codec, RT5663_HP_IMP_SEN_4);
+	value = snd_soc_component_read32(component, RT5663_HP_IMP_SEN_4);
 
-	snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0);
-	snd_soc_write(codec, RT5663_INT_ST_1, 0);
-	snd_soc_write(codec, RT5663_HP_LOGIC_1, 0);
-	snd_soc_update_bits(codec, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
+	snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0);
+	snd_soc_component_write(component, RT5663_INT_ST_1, 0);
+	snd_soc_component_write(component, RT5663_HP_LOGIC_1, 0);
+	snd_soc_component_update_bits(component, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
 		RT5663_DIG_25M_CLK_DIS);
-	snd_soc_write(codec, RT5663_GLB_CLK, reg80);
-	snd_soc_write(codec, RT5663_RECMIX, reg10);
-	snd_soc_write(codec, RT5663_DUMMY_2, 0x00a4);
-	snd_soc_write(codec, RT5663_DUMMY_1, reg2fa);
-	snd_soc_write(codec, RT5663_HP_CALIB_2, 0x00c8);
-	snd_soc_write(codec, RT5663_STO1_HPF_ADJ1, 0xb320);
-	snd_soc_write(codec, RT5663_ADDA_RST, 0xe400);
-	snd_soc_write(codec, RT5663_CHOP_ADC, 0x2000);
-	snd_soc_write(codec, RT5663_HP_OUT_EN, 0x0008);
-	snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+	snd_soc_component_write(component, RT5663_GLB_CLK, reg80);
+	snd_soc_component_write(component, RT5663_RECMIX, reg10);
+	snd_soc_component_write(component, RT5663_DUMMY_2, 0x00a4);
+	snd_soc_component_write(component, RT5663_DUMMY_1, reg2fa);
+	snd_soc_component_write(component, RT5663_HP_CALIB_2, 0x00c8);
+	snd_soc_component_write(component, RT5663_STO1_HPF_ADJ1, 0xb320);
+	snd_soc_component_write(component, RT5663_ADDA_RST, 0xe400);
+	snd_soc_component_write(component, RT5663_CHOP_ADC, 0x2000);
+	snd_soc_component_write(component, RT5663_HP_OUT_EN, 0x0008);
+	snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
 		RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2, 0);
-	snd_soc_update_bits(codec, RT5663_PWR_DIG_1,
+	snd_soc_component_update_bits(component, RT5663_PWR_DIG_1,
 		RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 |
 		RT5663_PWR_LDO_DACREF_MASK | RT5663_PWR_ADC_L1 |
 		RT5663_PWR_ADC_R1, 0);
-	snd_soc_update_bits(codec, RT5663_PWR_DIG_2,
+	snd_soc_component_update_bits(component, RT5663_PWR_DIG_2,
 		RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F, 0);
-	snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0);
-	snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0);
-	snd_soc_write(codec, RT5663_HP_LOGIC_2, 0);
-	snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_1, reg91);
-	snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+	snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0003, 0);
+	snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0030, 0);
+	snd_soc_component_write(component, RT5663_HP_LOGIC_2, 0);
+	snd_soc_component_write(component, RT5663_HP_CHARGE_PUMP_1, reg91);
+	snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
 		RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK, 0);
-	snd_soc_write(codec, RT5663_STO1_ADC_MIXER, reg26);
-	snd_soc_write(codec, RT5663_ASRC_2, reg84);
+	snd_soc_component_write(component, RT5663_STO1_ADC_MIXER, reg26);
+	snd_soc_component_write(component, RT5663_ASRC_2, reg84);
 
 	for (i = 0; i < rt5663->pdata.impedance_sensing_num; i++) {
 		if (value >= rt5663->imp_table[i].imp_min &&
@@ -1787,42 +1787,42 @@ static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
 			break;
 	}
 
-	snd_soc_update_bits(codec, RT5663_STO_DRE_9, RT5663_DRE_GAIN_HP_MASK,
+	snd_soc_component_update_bits(component, RT5663_STO_DRE_9, RT5663_DRE_GAIN_HP_MASK,
 		rt5663->imp_table[i].vol);
-	snd_soc_update_bits(codec, RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_MASK,
+	snd_soc_component_update_bits(component, RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_MASK,
 		rt5663->imp_table[i].vol);
 
 	if (rt5663->jack_type == SND_JACK_HEADSET) {
-		snd_soc_write(codec, RT5663_MIC_DECRO_2,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_2,
 			rt5663->imp_table[i].dc_offset_l_manual_mic >> 16);
-		snd_soc_write(codec, RT5663_MIC_DECRO_3,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_3,
 			rt5663->imp_table[i].dc_offset_l_manual_mic & 0xffff);
-		snd_soc_write(codec, RT5663_MIC_DECRO_5,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_5,
 			rt5663->imp_table[i].dc_offset_r_manual_mic >> 16);
-		snd_soc_write(codec, RT5663_MIC_DECRO_6,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_6,
 			rt5663->imp_table[i].dc_offset_r_manual_mic & 0xffff);
 	} else {
-		snd_soc_write(codec, RT5663_MIC_DECRO_2,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_2,
 			rt5663->imp_table[i].dc_offset_l_manual >> 16);
-		snd_soc_write(codec, RT5663_MIC_DECRO_3,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_3,
 			rt5663->imp_table[i].dc_offset_l_manual & 0xffff);
-		snd_soc_write(codec, RT5663_MIC_DECRO_5,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_5,
 			rt5663->imp_table[i].dc_offset_r_manual >> 16);
-		snd_soc_write(codec, RT5663_MIC_DECRO_6,
+		snd_soc_component_write(component, RT5663_MIC_DECRO_6,
 			rt5663->imp_table[i].dc_offset_r_manual & 0xffff);
 	}
 
 	return 0;
 }
 
-static int rt5663_button_detect(struct snd_soc_codec *codec)
+static int rt5663_button_detect(struct snd_soc_component *component)
 {
 	int btn_type, val;
 
-	val = snd_soc_read(codec, RT5663_IL_CMD_5);
-	dev_dbg(codec->dev, "%s: val=0x%x\n", __func__, val);
+	val = snd_soc_component_read32(component, RT5663_IL_CMD_5);
+	dev_dbg(component->dev, "%s: val=0x%x\n", __func__, val);
 	btn_type = val & 0xfff0;
-	snd_soc_write(codec, RT5663_IL_CMD_5, val);
+	snd_soc_component_write(component, RT5663_IL_CMD_5, val);
 
 	return btn_type;
 }
@@ -1840,10 +1840,10 @@ static irqreturn_t rt5663_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-int rt5663_set_jack_detect(struct snd_soc_codec *codec,
+int rt5663_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	rt5663->hs_jack = hs_jack;
 
@@ -1853,12 +1853,12 @@ int rt5663_set_jack_detect(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(rt5663_set_jack_detect);
 
-static bool rt5663_check_jd_status(struct snd_soc_codec *codec)
+static bool rt5663_check_jd_status(struct snd_soc_component *component)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
-	int val = snd_soc_read(codec, RT5663_INT_ST_1);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
+	int val = snd_soc_component_read32(component, RT5663_INT_ST_1);
 
-	dev_dbg(codec->dev, "%s val=%x\n", __func__, val);
+	dev_dbg(component->dev, "%s val=%x\n", __func__, val);
 
 	/* JD1 */
 	switch (rt5663->codec_ver) {
@@ -1867,7 +1867,7 @@ static bool rt5663_check_jd_status(struct snd_soc_codec *codec)
 	case CODEC_VER_0:
 		return !(val & 0x1000);
 	default:
-		dev_err(codec->dev, "Unknown CODEC Version\n");
+		dev_err(component->dev, "Unknown CODEC Version\n");
 	}
 
 	return false;
@@ -1877,28 +1877,28 @@ static void rt5663_jack_detect_work(struct work_struct *work)
 {
 	struct rt5663_priv *rt5663 =
 		container_of(work, struct rt5663_priv, jack_detect_work.work);
-	struct snd_soc_codec *codec = rt5663->codec;
+	struct snd_soc_component *component = rt5663->component;
 	int btn_type, report = 0;
 
-	if (!codec)
+	if (!component)
 		return;
 
-	if (rt5663_check_jd_status(codec)) {
+	if (rt5663_check_jd_status(component)) {
 		/* jack in */
 		if (rt5663->jack_type == 0) {
 			/* jack was out, report jack type */
 			switch (rt5663->codec_ver) {
 			case CODEC_VER_1:
 				report = rt5663_v2_jack_detect(
-						rt5663->codec, 1);
+						rt5663->component, 1);
 				break;
 			case CODEC_VER_0:
-				report = rt5663_jack_detect(rt5663->codec, 1);
+				report = rt5663_jack_detect(rt5663->component, 1);
 				if (rt5663->pdata.impedance_sensing_num)
-					rt5663_impedance_sensing(rt5663->codec);
+					rt5663_impedance_sensing(rt5663->component);
 				break;
 			default:
-				dev_err(codec->dev, "Unknown CODEC Version\n");
+				dev_err(component->dev, "Unknown CODEC Version\n");
 			}
 
 			/* Delay the jack insert report to avoid pop noise */
@@ -1906,7 +1906,7 @@ static void rt5663_jack_detect_work(struct work_struct *work)
 		} else {
 			/* jack is already in, report button event */
 			report = SND_JACK_HEADSET;
-			btn_type = rt5663_button_detect(rt5663->codec);
+			btn_type = rt5663_button_detect(rt5663->component);
 			/**
 			 * rt5663 can report three kinds of button behavior,
 			 * one click, double click and hold. However,
@@ -1939,7 +1939,7 @@ static void rt5663_jack_detect_work(struct work_struct *work)
 				break;
 			default:
 				btn_type = 0;
-				dev_err(rt5663->codec->dev,
+				dev_err(rt5663->component->dev,
 					"Unexpected button code 0x%04x\n",
 					btn_type);
 				break;
@@ -1959,16 +1959,16 @@ static void rt5663_jack_detect_work(struct work_struct *work)
 		/* jack out */
 		switch (rt5663->codec_ver) {
 		case CODEC_VER_1:
-			report = rt5663_v2_jack_detect(rt5663->codec, 0);
+			report = rt5663_v2_jack_detect(rt5663->component, 0);
 			break;
 		case CODEC_VER_0:
-			report = rt5663_jack_detect(rt5663->codec, 0);
+			report = rt5663_jack_detect(rt5663->component, 0);
 			break;
 		default:
-			dev_err(codec->dev, "Unknown CODEC Version\n");
+			dev_err(component->dev, "Unknown CODEC Version\n");
 		}
 	}
-	dev_dbg(codec->dev, "%s jack report: 0x%04x\n", __func__, report);
+	dev_dbg(component->dev, "%s jack report: 0x%04x\n", __func__, report);
 	snd_soc_jack_report(rt5663->hs_jack, report, SND_JACK_HEADSET |
 			    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 			    SND_JACK_BTN_2 | SND_JACK_BTN_3);
@@ -1978,22 +1978,22 @@ static void rt5663_jd_unplug_work(struct work_struct *work)
 {
 	struct rt5663_priv *rt5663 =
 		container_of(work, struct rt5663_priv, jd_unplug_work.work);
-	struct snd_soc_codec *codec = rt5663->codec;
+	struct snd_soc_component *component = rt5663->component;
 
-	if (!codec)
+	if (!component)
 		return;
 
-	if (!rt5663_check_jd_status(codec)) {
+	if (!rt5663_check_jd_status(component)) {
 		/* jack out */
 		switch (rt5663->codec_ver) {
 		case CODEC_VER_1:
-			rt5663_v2_jack_detect(rt5663->codec, 0);
+			rt5663_v2_jack_detect(rt5663->component, 0);
 			break;
 		case CODEC_VER_0:
-			rt5663_jack_detect(rt5663->codec, 0);
+			rt5663_jack_detect(rt5663->component, 0);
 			break;
 		default:
-			dev_err(codec->dev, "Unknown CODEC Version\n");
+			dev_err(component->dev, "Unknown CODEC Version\n");
 		}
 
 		snd_soc_jack_report(rt5663->hs_jack, 0, SND_JACK_HEADSET |
@@ -2047,9 +2047,9 @@ static int rt5663_is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
 	struct snd_soc_dapm_widget *sink)
 {
 	unsigned int val;
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
-	val = snd_soc_read(codec, RT5663_GLB_CLK);
+	val = snd_soc_component_read32(component, RT5663_GLB_CLK);
 	val &= RT5663_SCLK_SRC_MASK;
 	if (val == RT5663_SCLK_SRC_PLL1)
 		return 1;
@@ -2061,8 +2061,8 @@ static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w,
 	struct snd_soc_dapm_widget *sink)
 {
 	unsigned int reg, shift, val;
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	if (rt5663->codec_ver == CODEC_VER_1) {
 		switch (w->shift) {
@@ -2092,7 +2092,7 @@ static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w,
 		}
 	}
 
-	val = (snd_soc_read(codec, reg) >> shift) & 0x7;
+	val = (snd_soc_component_read32(component, reg) >> shift) & 0x7;
 
 	if (val)
 		return 1;
@@ -2103,23 +2103,23 @@ static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w,
 static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source,
 	struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	int da_asrc_en, ad_asrc_en;
 
-	da_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) &
+	da_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_2) &
 		RT5663_DA_STO1_TRACK_MASK) ? 1 : 0;
 	switch (rt5663->codec_ver) {
 	case CODEC_VER_1:
-		ad_asrc_en = (snd_soc_read(codec, RT5663_ASRC_3) &
+		ad_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_3) &
 			RT5663_V2_AD_STO1_TRACK_MASK) ? 1 : 0;
 		break;
 	case CODEC_VER_0:
-		ad_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) &
+		ad_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_2) &
 			RT5663_AD_STO1_TRACK_MASK) ? 1 : 0;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown CODEC Version\n");
+		dev_err(component->dev, "Unknown CODEC Version\n");
 		return 1;
 	}
 
@@ -2127,14 +2127,14 @@ static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source,
 		if (rt5663->sysclk > rt5663->lrck * 384)
 			return 1;
 
-	dev_err(codec->dev, "sysclk < 384 x fs, disable i2s asrc\n");
+	dev_err(component->dev, "sysclk < 384 x fs, disable i2s asrc\n");
 
 	return 0;
 }
 
 /**
  * rt5663_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -2146,10 +2146,10 @@ static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source,
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5663_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	unsigned int asrc2_mask = 0;
 	unsigned int asrc2_value = 0;
 	unsigned int asrc3_mask = 0;
@@ -2180,16 +2180,16 @@ int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
 			asrc2_value |= clk_src << RT5663_AD_STO1_TRACK_SHIFT;
 			break;
 		default:
-			dev_err(codec->dev, "Unknown CODEC Version\n");
+			dev_err(component->dev, "Unknown CODEC Version\n");
 		}
 	}
 
 	if (asrc2_mask)
-		snd_soc_update_bits(codec, RT5663_ASRC_2, asrc2_mask,
+		snd_soc_component_update_bits(component, RT5663_ASRC_2, asrc2_mask,
 			asrc2_value);
 
 	if (asrc3_mask)
-		snd_soc_update_bits(codec, RT5663_ASRC_3, asrc3_mask,
+		snd_soc_component_update_bits(component, RT5663_ASRC_3, asrc3_mask,
 			asrc3_value);
 
 	return 0;
@@ -2295,42 +2295,42 @@ static const struct snd_kcontrol_new rt5663_alg_dacr_mux =
 static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		if (rt5663->codec_ver == CODEC_VER_1) {
-			snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+			snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
 				RT5663_SEL_PM_HP_SHIFT, RT5663_SEL_PM_HP_HIGH);
-			snd_soc_update_bits(codec, RT5663_HP_LOGIC_2,
+			snd_soc_component_update_bits(component, RT5663_HP_LOGIC_2,
 				RT5663_HP_SIG_SRC1_MASK,
 				RT5663_HP_SIG_SRC1_SILENCE);
 		} else {
-			snd_soc_write(codec, RT5663_DEPOP_2, 0x3003);
-			snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+			snd_soc_component_write(component, RT5663_DEPOP_2, 0x3003);
+			snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
 				RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS);
-			snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371);
-			snd_soc_write(codec, RT5663_HP_BIAS, 0xabba);
-			snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224);
-			snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766);
-			snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa);
-			snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777);
-			snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000,
+			snd_soc_component_write(component, RT5663_HP_CHARGE_PUMP_2, 0x1371);
+			snd_soc_component_write(component, RT5663_HP_BIAS, 0xabba);
+			snd_soc_component_write(component, RT5663_CHARGE_PUMP_1, 0x2224);
+			snd_soc_component_write(component, RT5663_ANA_BIAS_CUR_1, 0x7766);
+			snd_soc_component_write(component, RT5663_HP_BIAS, 0xafaa);
+			snd_soc_component_write(component, RT5663_CHARGE_PUMP_2, 0x7777);
+			snd_soc_component_update_bits(component, RT5663_STO_DRE_1, 0x8000,
 				0x8000);
-			snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000,
+			snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000,
 				0x3000);
 		}
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
 		if (rt5663->codec_ver == CODEC_VER_1) {
-			snd_soc_update_bits(codec, RT5663_HP_LOGIC_2,
+			snd_soc_component_update_bits(component, RT5663_HP_LOGIC_2,
 				RT5663_HP_SIG_SRC1_MASK,
 				RT5663_HP_SIG_SRC1_REG);
 		} else {
-			snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0);
-			snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+			snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0x0);
+			snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
 				RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN);
 		}
 		break;
@@ -2345,23 +2345,23 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		if (rt5663->codec_ver == CODEC_VER_0) {
-			snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030,
+			snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0030,
 				0x0030);
-			snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003,
+			snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0003,
 				0x0003);
 		}
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
 		if (rt5663->codec_ver == CODEC_VER_0) {
-			snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0);
-			snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0);
+			snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0003, 0);
+			snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0030, 0);
 		}
 		break;
 
@@ -2375,17 +2375,17 @@ static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w,
 static int rt5663_bst2_power(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+		snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
 			RT5663_PWR_BST2_MASK | RT5663_PWR_BST2_OP_MASK,
 			RT5663_PWR_BST2 | RT5663_PWR_BST2_OP);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+		snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
 			RT5663_PWR_BST2_MASK | RT5663_PWR_BST2_OP_MASK, 0);
 		break;
 
@@ -2399,17 +2399,17 @@ static int rt5663_bst2_power(struct snd_soc_dapm_widget *w,
 static int rt5663_pre_div_power(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00);
-		snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc);
+		snd_soc_component_write(component, RT5663_PRE_DIV_GATING_1, 0xff00);
+		snd_soc_component_write(component, RT5663_PRE_DIV_GATING_2, 0xfffc);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0x0000);
-		snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0x0000);
+		snd_soc_component_write(component, RT5663_PRE_DIV_GATING_1, 0x0000);
+		snd_soc_component_write(component, RT5663_PRE_DIV_GATING_2, 0x0000);
 		break;
 
 	default:
@@ -2731,8 +2731,8 @@ static const struct snd_soc_dapm_route rt5663_specific_dapm_routes[] = {
 static int rt5663_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0;
 	int pre_div;
 
@@ -2743,7 +2743,7 @@ static int rt5663_hw_params(struct snd_pcm_substream *substream,
 
 	pre_div = rl6231_get_clk_info(rt5663->sysclk, rt5663->lrck);
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+		dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
 			rt5663->lrck, dai->id);
 		return -EINVAL;
 	}
@@ -2767,10 +2767,10 @@ static int rt5663_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5663_I2S1_SDP,
+	snd_soc_component_update_bits(component, RT5663_I2S1_SDP,
 		RT5663_I2S_DL_MASK, val_len);
 
-	snd_soc_update_bits(codec, RT5663_ADDA_CLK_1,
+	snd_soc_component_update_bits(component, RT5663_ADDA_CLK_1,
 		RT5663_I2S_PD1_MASK, pre_div << RT5663_I2S_PD1_SHIFT);
 
 	return 0;
@@ -2778,7 +2778,7 @@ static int rt5663_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -2817,7 +2817,7 @@ static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5663_I2S1_SDP, RT5663_I2S_MS_MASK |
+	snd_soc_component_update_bits(component, RT5663_I2S1_SDP, RT5663_I2S_MS_MASK |
 		RT5663_I2S_BP_MASK | RT5663_I2S_DF_MASK, reg_val);
 
 	return 0;
@@ -2826,8 +2826,8 @@ static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 	unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	if (freq == rt5663->sysclk && clk_id == rt5663->sysclk_src)
@@ -2844,15 +2844,15 @@ static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 		reg_val |= RT5663_SCLK_SRC_RCCLK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
+	snd_soc_component_update_bits(component, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
 		reg_val);
 	rt5663->sysclk = freq;
 	rt5663->sysclk_src = clk_id;
 
-	dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n",
+	dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
 		freq, clk_id);
 
 	return 0;
@@ -2861,8 +2861,8 @@ static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 	int mask, shift, val;
@@ -2872,11 +2872,11 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5663->pll_in = 0;
 		rt5663->pll_out = 0;
-		snd_soc_update_bits(codec, RT5663_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5663_GLB_CLK,
 			RT5663_SCLK_SRC_MASK, RT5663_SCLK_SRC_MCLK);
 		return 0;
 	}
@@ -2891,7 +2891,7 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		shift = RT5663_PLL1_SRC_SHIFT;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown CODEC Version\n");
+		dev_err(component->dev, "Unknown CODEC Version\n");
 		return -EINVAL;
 	}
 
@@ -2903,24 +2903,24 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		val = 0x1;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, RT5663_GLB_CLK, mask, (val << shift));
+	snd_soc_component_update_bits(component, RT5663_GLB_CLK, mask, (val << shift));
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp,
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp,
 		(pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code,
 		pll_code.k_code);
 
-	snd_soc_write(codec, RT5663_PLL_1,
+	snd_soc_component_write(component, RT5663_PLL_1,
 		pll_code.n_code << RT5663_PLL_N_SHIFT | pll_code.k_code);
-	snd_soc_write(codec, RT5663_PLL_2,
+	snd_soc_component_write(component, RT5663_PLL_2,
 		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5663_PLL_M_SHIFT |
 		pll_code.m_bp << RT5663_PLL_M_BP_SHIFT);
 
@@ -2934,8 +2934,8 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0, reg;
 
 	if (rx_mask || tx_mask)
@@ -2987,11 +2987,11 @@ static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 		reg = RT5663_TDM_1;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown CODEC Version\n");
+		dev_err(component->dev, "Unknown CODEC Version\n");
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, reg, RT5663_TDM_MODE_MASK |
+	snd_soc_component_update_bits(component, reg, RT5663_TDM_MODE_MASK |
 		RT5663_TDM_IN_CH_MASK | RT5663_TDM_OUT_CH_MASK |
 		RT5663_TDM_IN_LEN_MASK | RT5663_TDM_OUT_LEN_MASK, val);
 
@@ -3000,11 +3000,11 @@ static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 
 static int rt5663_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 	unsigned int reg;
 
-	dev_dbg(codec->dev, "%s ratio = %d\n", __func__, ratio);
+	dev_dbg(component->dev, "%s ratio = %d\n", __func__, ratio);
 
 	if (rt5663->codec_ver == CODEC_VER_1)
 		reg = RT5663_TDM_9;
@@ -3013,51 +3013,51 @@ static int rt5663_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 
 	switch (ratio) {
 	case 32:
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 			RT5663_TDM_LENGTN_MASK,
 			RT5663_TDM_LENGTN_16);
 		break;
 	case 40:
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 			RT5663_TDM_LENGTN_MASK,
 			RT5663_TDM_LENGTN_20);
 		break;
 	case 48:
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 			RT5663_TDM_LENGTN_MASK,
 			RT5663_TDM_LENGTN_24);
 		break;
 	case 64:
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 			RT5663_TDM_LENGTN_MASK,
 			RT5663_TDM_LENGTN_32);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid ratio!\n");
+		dev_err(component->dev, "Invalid ratio!\n");
 		return -EINVAL;
 	}
 
 	return 0;
 }
 
-static int rt5663_set_bias_level(struct snd_soc_codec *codec,
+static int rt5663_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+		snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
 			RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
 			RT5663_PWR_FV1 | RT5663_PWR_FV2);
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
 		if (rt5663->codec_ver == CODEC_VER_1) {
-			snd_soc_update_bits(codec, RT5663_DIG_MISC,
+			snd_soc_component_update_bits(component, RT5663_DIG_MISC,
 				RT5663_DIG_GATE_CTRL_MASK,
 				RT5663_DIG_GATE_CTRL_EN);
-			snd_soc_update_bits(codec, RT5663_SIG_CLK_DET,
+			snd_soc_component_update_bits(component, RT5663_SIG_CLK_DET,
 				RT5663_EN_ANA_CLK_DET_MASK |
 				RT5663_PWR_CLK_DET_MASK,
 				RT5663_EN_ANA_CLK_DET_AUTO |
@@ -3067,17 +3067,17 @@ static int rt5663_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_STANDBY:
 		if (rt5663->codec_ver == CODEC_VER_1)
-			snd_soc_update_bits(codec, RT5663_DIG_MISC,
+			snd_soc_component_update_bits(component, RT5663_DIG_MISC,
 				RT5663_DIG_GATE_CTRL_MASK,
 				RT5663_DIG_GATE_CTRL_DIS);
-		snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+		snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
 			RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
 			RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK |
 			RT5663_PWR_MB_MASK, RT5663_PWR_VREF1 |
 			RT5663_PWR_VREF2 | RT5663_PWR_MB);
 		usleep_range(10000, 10005);
 		if (rt5663->codec_ver == CODEC_VER_1) {
-			snd_soc_update_bits(codec, RT5663_SIG_CLK_DET,
+			snd_soc_component_update_bits(component, RT5663_SIG_CLK_DET,
 				RT5663_EN_ANA_CLK_DET_MASK |
 				RT5663_PWR_CLK_DET_MASK,
 				RT5663_EN_ANA_CLK_DET_DIS |
@@ -3086,7 +3086,7 @@ static int rt5663_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+		snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
 			RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
 			RT5663_PWR_FV1 | RT5663_PWR_FV2, 0x0);
 		break;
@@ -3098,12 +3098,12 @@ static int rt5663_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5663_probe(struct snd_soc_codec *codec)
+static int rt5663_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
-	rt5663->codec = codec;
+	rt5663->component = component;
 
 	switch (rt5663->codec_ver) {
 	case CODEC_VER_1:
@@ -3113,7 +3113,7 @@ static int rt5663_probe(struct snd_soc_codec *codec)
 		snd_soc_dapm_add_routes(dapm,
 			rt5663_v2_specific_dapm_routes,
 			ARRAY_SIZE(rt5663_v2_specific_dapm_routes));
-		snd_soc_add_codec_controls(codec, rt5663_v2_specific_controls,
+		snd_soc_add_component_controls(component, rt5663_v2_specific_controls,
 			ARRAY_SIZE(rt5663_v2_specific_controls));
 		break;
 	case CODEC_VER_0:
@@ -3123,11 +3123,11 @@ static int rt5663_probe(struct snd_soc_codec *codec)
 		snd_soc_dapm_add_routes(dapm,
 			rt5663_specific_dapm_routes,
 			ARRAY_SIZE(rt5663_specific_dapm_routes));
-		snd_soc_add_codec_controls(codec, rt5663_specific_controls,
+		snd_soc_add_component_controls(component, rt5663_specific_controls,
 			ARRAY_SIZE(rt5663_specific_controls));
 
 		if (!rt5663->imp_table)
-			snd_soc_add_codec_controls(codec, rt5663_hpvol_controls,
+			snd_soc_add_component_controls(component, rt5663_hpvol_controls,
 				ARRAY_SIZE(rt5663_hpvol_controls));
 		break;
 	}
@@ -3135,19 +3135,17 @@ static int rt5663_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt5663_remove(struct snd_soc_codec *codec)
+static void rt5663_remove(struct snd_soc_component *component)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	regmap_write(rt5663->regmap, RT5663_RESET, 0);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5663_suspend(struct snd_soc_codec *codec)
+static int rt5663_suspend(struct snd_soc_component *component)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5663->regmap, true);
 	regcache_mark_dirty(rt5663->regmap);
@@ -3155,9 +3153,9 @@ static int rt5663_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt5663_resume(struct snd_soc_codec *codec)
+static int rt5663_resume(struct snd_soc_component *component)
 {
-	struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+	struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5663->regmap, false);
 	regcache_sync(rt5663->regmap);
@@ -3206,21 +3204,22 @@ static struct snd_soc_dai_driver rt5663_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5663 = {
-	.probe = rt5663_probe,
-	.remove = rt5663_remove,
-	.suspend = rt5663_suspend,
-	.resume = rt5663_resume,
-	.set_bias_level = rt5663_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls = rt5663_snd_controls,
-		.num_controls = ARRAY_SIZE(rt5663_snd_controls),
-		.dapm_widgets = rt5663_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(rt5663_dapm_widgets),
-		.dapm_routes = rt5663_dapm_routes,
-		.num_dapm_routes = ARRAY_SIZE(rt5663_dapm_routes),
-	}
+static const struct snd_soc_component_driver soc_component_dev_rt5663 = {
+	.probe			= rt5663_probe,
+	.remove			= rt5663_remove,
+	.suspend		= rt5663_suspend,
+	.resume			= rt5663_resume,
+	.set_bias_level		= rt5663_set_bias_level,
+	.controls		= rt5663_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5663_snd_controls),
+	.dapm_widgets		= rt5663_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5663_dapm_widgets),
+	.dapm_routes		= rt5663_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5663_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+
 };
 
 static const struct regmap_config rt5663_v2_regmap = {
@@ -3610,7 +3609,8 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
 				__func__, ret);
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5663,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_rt5663,
 			rt5663_dai, ARRAY_SIZE(rt5663_dai));
 
 	if (ret) {
@@ -3628,8 +3628,6 @@ static int rt5663_i2c_remove(struct i2c_client *i2c)
 	if (i2c->irq)
 		free_irq(i2c->irq, rt5663);
 
-	snd_soc_unregister_codec(&i2c->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h
index 03adc80..865203c 100644
--- a/sound/soc/codecs/rt5663.h
+++ b/sound/soc/codecs/rt5663.h
@@ -1125,9 +1125,9 @@ enum {
 	RT5663_AD_STEREO_FILTER = 0x2,
 };
 
-int rt5663_set_jack_detect(struct snd_soc_codec *codec,
+int rt5663_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack);
-int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5663_sel_asrc_clk_src(struct snd_soc_component *component,
 	unsigned int filter_mask, unsigned int clk_src);
 
 #endif /* __RT5663_H__ */
diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c
index f05d362..6ba99f5 100644
--- a/sound/soc/codecs/rt5665.c
+++ b/sound/soc/codecs/rt5665.c
@@ -44,7 +44,7 @@ static const char *rt5665_supply_names[RT5665_NUM_SUPPLIES] = {
 };
 
 struct rt5665_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt5665_platform_data pdata;
 	struct regmap *regmap;
 	struct gpio_desc *gpiod_ldo1_en;
@@ -1000,13 +1000,13 @@ static const struct snd_kcontrol_new rt5665_if3_adc_swap_mux =
 static int rt5665_hp_vol_put(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int ret = snd_soc_put_volsw(kcontrol, ucontrol);
 
-	if (snd_soc_read(codec, RT5665_STO_NG2_CTRL_1) & RT5665_NG2_EN) {
-		snd_soc_update_bits(codec, RT5665_STO_NG2_CTRL_1,
+	if (snd_soc_component_read32(component, RT5665_STO_NG2_CTRL_1) & RT5665_NG2_EN) {
+		snd_soc_component_update_bits(component, RT5665_STO_NG2_CTRL_1,
 			RT5665_NG2_EN_MASK, RT5665_NG2_DIS);
-		snd_soc_update_bits(codec, RT5665_STO_NG2_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_STO_NG2_CTRL_1,
 			RT5665_NG2_EN_MASK, RT5665_NG2_EN);
 	}
 
@@ -1016,13 +1016,13 @@ static int rt5665_hp_vol_put(struct snd_kcontrol *kcontrol,
 static int rt5665_mono_vol_put(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int ret = snd_soc_put_volsw(kcontrol, ucontrol);
 
-	if (snd_soc_read(codec, RT5665_MONO_NG2_CTRL_1) & RT5665_NG2_EN) {
-		snd_soc_update_bits(codec, RT5665_MONO_NG2_CTRL_1,
+	if (snd_soc_component_read32(component, RT5665_MONO_NG2_CTRL_1) & RT5665_NG2_EN) {
+		snd_soc_component_update_bits(component, RT5665_MONO_NG2_CTRL_1,
 			RT5665_NG2_EN_MASK, RT5665_NG2_DIS);
-		snd_soc_update_bits(codec, RT5665_MONO_NG2_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_MONO_NG2_CTRL_1,
 			RT5665_NG2_EN_MASK, RT5665_NG2_EN);
 	}
 
@@ -1031,7 +1031,7 @@ static int rt5665_mono_vol_put(struct snd_kcontrol *kcontrol,
 
 /**
  * rt5665_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -1043,7 +1043,7 @@ static int rt5665_mono_vol_put(struct snd_kcontrol *kcontrol,
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5665_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src)
 {
 	unsigned int asrc2_mask = 0;
@@ -1114,63 +1114,63 @@ int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
 	}
 
 	if (asrc2_mask)
-		snd_soc_update_bits(codec, RT5665_ASRC_2,
+		snd_soc_component_update_bits(component, RT5665_ASRC_2,
 			asrc2_mask, asrc2_value);
 
 	if (asrc3_mask)
-		snd_soc_update_bits(codec, RT5665_ASRC_3,
+		snd_soc_component_update_bits(component, RT5665_ASRC_3,
 			asrc3_mask, asrc3_value);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(rt5665_sel_asrc_clk_src);
 
-static int rt5665_button_detect(struct snd_soc_codec *codec)
+static int rt5665_button_detect(struct snd_soc_component *component)
 {
 	int btn_type, val;
 
-	val = snd_soc_read(codec, RT5665_4BTN_IL_CMD_1);
+	val = snd_soc_component_read32(component, RT5665_4BTN_IL_CMD_1);
 	btn_type = val & 0xfff0;
-	snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, val);
+	snd_soc_component_write(component, RT5665_4BTN_IL_CMD_1, val);
 
 	return btn_type;
 }
 
-static void rt5665_enable_push_button_irq(struct snd_soc_codec *codec,
+static void rt5665_enable_push_button_irq(struct snd_soc_component *component,
 	bool enable)
 {
 	if (enable) {
-		snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x0003);
-		snd_soc_update_bits(codec, RT5665_SAR_IL_CMD_9, 0x1, 0x1);
-		snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048);
-		snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
+		snd_soc_component_write(component, RT5665_4BTN_IL_CMD_1, 0x0003);
+		snd_soc_component_update_bits(component, RT5665_SAR_IL_CMD_9, 0x1, 0x1);
+		snd_soc_component_write(component, RT5665_IL_CMD_1, 0x0048);
+		snd_soc_component_update_bits(component, RT5665_4BTN_IL_CMD_2,
 				RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK,
 				RT5665_4BTN_IL_EN | RT5665_4BTN_IL_NOR);
-		snd_soc_update_bits(codec, RT5665_IRQ_CTRL_3,
+		snd_soc_component_update_bits(component, RT5665_IRQ_CTRL_3,
 				RT5665_IL_IRQ_MASK, RT5665_IL_IRQ_EN);
 	} else {
-		snd_soc_update_bits(codec, RT5665_IRQ_CTRL_3,
+		snd_soc_component_update_bits(component, RT5665_IRQ_CTRL_3,
 				RT5665_IL_IRQ_MASK, RT5665_IL_IRQ_DIS);
-		snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
+		snd_soc_component_update_bits(component, RT5665_4BTN_IL_CMD_2,
 				RT5665_4BTN_IL_MASK, RT5665_4BTN_IL_DIS);
-		snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
+		snd_soc_component_update_bits(component, RT5665_4BTN_IL_CMD_2,
 				RT5665_4BTN_IL_RST_MASK, RT5665_4BTN_IL_RST);
 	}
 }
 
 /**
  * rt5665_headset_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
  *
  * Returns detect status.
  */
-static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5665_headset_detect(struct snd_soc_component *component, int jack_insert)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	unsigned int sar_hs_type, val;
 
 	if (jack_insert) {
@@ -1201,7 +1201,7 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 
 		usleep_range(10000, 15000);
 
-		rt5665->sar_adc_value = snd_soc_read(rt5665->codec,
+		rt5665->sar_adc_value = snd_soc_component_read32(rt5665->component,
 			RT5665_SAR_IL_CMD_4) & 0x7ff;
 
 		sar_hs_type = rt5665->pdata.sar_hs_type ?
@@ -1209,7 +1209,7 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 
 		if (rt5665->sar_adc_value > sar_hs_type) {
 			rt5665->jack_type = SND_JACK_HEADSET;
-			rt5665_enable_push_button_irq(codec, true);
+			rt5665_enable_push_button_irq(component, true);
 			} else {
 			rt5665->jack_type = SND_JACK_HEADPHONE;
 			regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1,
@@ -1225,11 +1225,11 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 		snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
 		snd_soc_dapm_sync(dapm);
 		if (rt5665->jack_type == SND_JACK_HEADSET)
-			rt5665_enable_push_button_irq(codec, false);
+			rt5665_enable_push_button_irq(component, false);
 		rt5665->jack_type = 0;
 	}
 
-	dev_dbg(codec->dev, "jack_type = %d\n", rt5665->jack_type);
+	dev_dbg(component->dev, "jack_type = %d\n", rt5665->jack_type);
 	return rt5665->jack_type;
 }
 
@@ -1248,9 +1248,9 @@ static void rt5665_jd_check_handler(struct work_struct *work)
 	struct rt5665_priv *rt5665 = container_of(work, struct rt5665_priv,
 		jd_check_work.work);
 
-	if (snd_soc_read(rt5665->codec, RT5665_AJD1_CTRL) & 0x0010) {
+	if (snd_soc_component_read32(rt5665->component, RT5665_AJD1_CTRL) & 0x0010) {
 		/* jack out */
-		rt5665->jack_type = rt5665_headset_detect(rt5665->codec, 0);
+		rt5665->jack_type = rt5665_headset_detect(rt5665->component, 0);
 
 		snd_soc_jack_report(rt5665->hs_jack, rt5665->jack_type,
 				SND_JACK_HEADSET |
@@ -1261,10 +1261,10 @@ static void rt5665_jd_check_handler(struct work_struct *work)
 	}
 }
 
-static int rt5665_set_jack_detect(struct snd_soc_codec *codec,
+static int rt5665_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack, void *data)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
 	switch (rt5665->pdata.jd_src) {
 	case RT5665_JD1:
@@ -1281,7 +1281,7 @@ static int rt5665_set_jack_detect(struct snd_soc_codec *codec,
 		break;
 
 	default:
-		dev_warn(codec->dev, "Wrong JD source\n");
+		dev_warn(component->dev, "Wrong JD source\n");
 		break;
 	}
 
@@ -1296,12 +1296,12 @@ static void rt5665_jack_detect_handler(struct work_struct *work)
 		container_of(work, struct rt5665_priv, jack_detect_work.work);
 	int val, btn_type;
 
-	while (!rt5665->codec) {
+	while (!rt5665->component) {
 		pr_debug("%s codec = null\n", __func__);
 		usleep_range(10000, 15000);
 	}
 
-	while (!rt5665->codec->component.card->instantiated) {
+	while (!rt5665->component->card->instantiated) {
 		pr_debug("%s\n", __func__);
 		usleep_range(10000, 15000);
 	}
@@ -1313,17 +1313,17 @@ static void rt5665_jack_detect_handler(struct work_struct *work)
 
 	mutex_lock(&rt5665->calibrate_mutex);
 
-	val = snd_soc_read(rt5665->codec, RT5665_AJD1_CTRL) & 0x0010;
+	val = snd_soc_component_read32(rt5665->component, RT5665_AJD1_CTRL) & 0x0010;
 	if (!val) {
 		/* jack in */
 		if (rt5665->jack_type == 0) {
 			/* jack was out, report jack type */
 			rt5665->jack_type =
-				rt5665_headset_detect(rt5665->codec, 1);
+				rt5665_headset_detect(rt5665->component, 1);
 		} else {
 			/* jack is already in, report button event */
 			rt5665->jack_type = SND_JACK_HEADSET;
-			btn_type = rt5665_button_detect(rt5665->codec);
+			btn_type = rt5665_button_detect(rt5665->component);
 			/**
 			 * rt5665 can report three kinds of button behavior,
 			 * one click, double click and hold. However,
@@ -1356,7 +1356,7 @@ static void rt5665_jack_detect_handler(struct work_struct *work)
 				break;
 			default:
 				btn_type = 0;
-				dev_err(rt5665->codec->dev,
+				dev_err(rt5665->component->dev,
 					"Unexpected button code 0x%04x\n",
 					btn_type);
 				break;
@@ -1364,7 +1364,7 @@ static void rt5665_jack_detect_handler(struct work_struct *work)
 		}
 	} else {
 		/* jack out */
-		rt5665->jack_type = rt5665_headset_detect(rt5665->codec, 0);
+		rt5665->jack_type = rt5665_headset_detect(rt5665->component, 0);
 	}
 
 	snd_soc_jack_report(rt5665->hs_jack, rt5665->jack_type,
@@ -1479,8 +1479,8 @@ static const struct snd_kcontrol_new rt5665_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 	int pd, idx = -EINVAL;
 
 	pd = rl6231_get_pre_div(rt5665->regmap,
@@ -1488,9 +1488,9 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	idx = rl6231_calc_dmic_clk(rt5665->sysclk / pd);
 
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else {
-		snd_soc_update_bits(codec, RT5665_DMIC_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_DMIC_CTRL_1,
 			RT5665_DMIC_CLK_MASK, idx << RT5665_DMIC_CLK_SFT);
 	}
 	return idx;
@@ -1499,16 +1499,16 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int rt5665_charge_pump_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, RT5665_HP_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, RT5665_HP_CHARGE_PUMP_1,
 			RT5665_PM_HP_MASK | RT5665_OSW_L_MASK,
 			RT5665_PM_HP_HV | RT5665_OSW_L_EN);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, RT5665_HP_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, RT5665_HP_CHARGE_PUMP_1,
 			RT5665_PM_HP_MASK | RT5665_OSW_L_MASK,
 			RT5665_PM_HP_LV | RT5665_OSW_L_DIS);
 		break;
@@ -1523,9 +1523,9 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
 			 struct snd_soc_dapm_widget *sink)
 {
 	unsigned int val;
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
-	val = snd_soc_read(codec, RT5665_GLB_CLK);
+	val = snd_soc_component_read32(component, RT5665_GLB_CLK);
 	val &= RT5665_SCLK_SRC_MASK;
 	if (val == RT5665_SCLK_SRC_PLL1)
 		return 1;
@@ -1537,7 +1537,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w,
 			 struct snd_soc_dapm_widget *sink)
 {
 	unsigned int reg, shift, val;
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (w->shift) {
 	case RT5665_ADC_MONO_R_ASRC_SFT:
@@ -1576,13 +1576,13 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w,
 		return 0;
 	}
 
-	val = (snd_soc_read(codec, reg) >> shift) & 0xf;
+	val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
 	switch (val) {
 	case RT5665_CLK_SEL_I2S1_ASRC:
 	case RT5665_CLK_SEL_I2S2_ASRC:
 	case RT5665_CLK_SEL_I2S3_ASRC:
 		/* I2S_Pre_Div1 should be 1 in asrc mode */
-		snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+		snd_soc_component_update_bits(component, RT5665_ADDA_CLK_1,
 			RT5665_I2S_PD1_MASK, RT5665_I2S_PD1_2);
 		return 1;
 	default:
@@ -2474,24 +2474,24 @@ static const struct snd_kcontrol_new pdm_r_switch =
 static int rt5665_mono_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, RT5665_MONO_NG2_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_MONO_NG2_CTRL_1,
 			RT5665_NG2_EN_MASK, RT5665_NG2_EN);
-		snd_soc_update_bits(codec, RT5665_MONO_AMP_CALIB_CTRL_1, 0x40,
+		snd_soc_component_update_bits(component, RT5665_MONO_AMP_CALIB_CTRL_1, 0x40,
 			0x0);
-		snd_soc_update_bits(codec, RT5665_MONO_OUT, 0x10, 0x10);
-		snd_soc_update_bits(codec, RT5665_MONO_OUT, 0x20, 0x20);
+		snd_soc_component_update_bits(component, RT5665_MONO_OUT, 0x10, 0x10);
+		snd_soc_component_update_bits(component, RT5665_MONO_OUT, 0x20, 0x20);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, RT5665_MONO_OUT, 0x20, 0);
-		snd_soc_update_bits(codec, RT5665_MONO_OUT, 0x10, 0);
-		snd_soc_update_bits(codec, RT5665_MONO_AMP_CALIB_CTRL_1, 0x40,
+		snd_soc_component_update_bits(component, RT5665_MONO_OUT, 0x20, 0);
+		snd_soc_component_update_bits(component, RT5665_MONO_OUT, 0x10, 0);
+		snd_soc_component_update_bits(component, RT5665_MONO_AMP_CALIB_CTRL_1, 0x40,
 			0x40);
-		snd_soc_update_bits(codec, RT5665_MONO_NG2_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_MONO_NG2_CTRL_1,
 			RT5665_NG2_EN_MASK, RT5665_NG2_DIS);
 		break;
 
@@ -2506,18 +2506,18 @@ static int rt5665_mono_event(struct snd_soc_dapm_widget *w,
 static int rt5665_hp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, RT5665_STO_NG2_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_STO_NG2_CTRL_1,
 			RT5665_NG2_EN_MASK, RT5665_NG2_EN);
-		snd_soc_write(codec, RT5665_HP_LOGIC_CTRL_2, 0x0003);
+		snd_soc_component_write(component, RT5665_HP_LOGIC_CTRL_2, 0x0003);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_write(codec, RT5665_HP_LOGIC_CTRL_2, 0x0002);
-		snd_soc_update_bits(codec, RT5665_STO_NG2_CTRL_1,
+		snd_soc_component_write(component, RT5665_HP_LOGIC_CTRL_2, 0x0002);
+		snd_soc_component_update_bits(component, RT5665_STO_NG2_CTRL_1,
 			RT5665_NG2_EN_MASK, RT5665_NG2_DIS);
 		break;
 
@@ -2532,16 +2532,16 @@ static int rt5665_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5665_lout_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5665_DEPOP_1,
+		snd_soc_component_update_bits(component, RT5665_DEPOP_1,
 			RT5665_PUMP_EN, RT5665_PUMP_EN);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5665_DEPOP_1,
+		snd_soc_component_update_bits(component, RT5665_DEPOP_1,
 			RT5665_PUMP_EN, 0);
 		break;
 
@@ -2572,23 +2572,23 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w,
 static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		switch (w->shift) {
 		case RT5665_PWR_VREF1_BIT:
-			snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+			snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
 				RT5665_PWR_FV1, 0);
 			break;
 
 		case RT5665_PWR_VREF2_BIT:
-			snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+			snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
 				RT5665_PWR_FV2, 0);
 			break;
 
 		case RT5665_PWR_VREF3_BIT:
-			snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+			snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
 				RT5665_PWR_FV3, 0);
 			break;
 
@@ -2601,17 +2601,17 @@ static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
 		usleep_range(15000, 20000);
 		switch (w->shift) {
 		case RT5665_PWR_VREF1_BIT:
-			snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+			snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
 				RT5665_PWR_FV1, RT5665_PWR_FV1);
 			break;
 
 		case RT5665_PWR_VREF2_BIT:
-			snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+			snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
 				RT5665_PWR_FV2, RT5665_PWR_FV2);
 			break;
 
 		case RT5665_PWR_VREF3_BIT:
-			snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+			snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
 				RT5665_PWR_FV3, RT5665_PWR_FV3);
 			break;
 
@@ -2630,7 +2630,7 @@ static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
 static int rt5665_i2s_pin_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int val1, val2, mask1 = 0, mask2 = 0;
 
 	switch (w->shift) {
@@ -2660,18 +2660,18 @@ static int rt5665_i2s_pin_event(struct snd_soc_dapm_widget *w,
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		if (mask1)
-			snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1,
+			snd_soc_component_update_bits(component, RT5665_GPIO_CTRL_1,
 					    mask1, val1);
 		if (mask2)
-			snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
+			snd_soc_component_update_bits(component, RT5665_GPIO_CTRL_2,
 					    mask2, val2);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		if (mask1)
-			snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1,
+			snd_soc_component_update_bits(component, RT5665_GPIO_CTRL_1,
 					    mask1, 0);
 		if (mask2)
-			snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
+			snd_soc_component_update_bits(component, RT5665_GPIO_CTRL_2,
 					    mask2, 0);
 		break;
 	default:
@@ -4052,7 +4052,7 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = {
 static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val = 0;
 
 	if (rx_mask || tx_mask)
@@ -4096,7 +4096,7 @@ static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5665_TDM_CTRL_1,
+	snd_soc_component_update_bits(component, RT5665_TDM_CTRL_1,
 		RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK |
 		RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK |
 		RT5665_TDM_OUT_LEN_MASK, val);
@@ -4108,24 +4108,24 @@ static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int rt5665_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, reg_clk, mask_clk, val_bits = 0x0100;
 	int pre_div, frame_size;
 
 	rt5665->lrck[dai->id] = params_rate(params);
 	pre_div = rl6231_get_clk_info(rt5665->sysclk, rt5665->lrck[dai->id]);
 	if (pre_div < 0) {
-		dev_warn(codec->dev, "Force using PLL");
-		snd_soc_codec_set_pll(codec, 0, RT5665_PLL1_S_MCLK,
+		dev_warn(component->dev, "Force using PLL");
+		snd_soc_component_set_pll(component, 0, RT5665_PLL1_S_MCLK,
 			rt5665->sysclk,	rt5665->lrck[dai->id] * 512);
-		snd_soc_codec_set_sysclk(codec, RT5665_SCLK_S_PLL1, 0,
+		snd_soc_component_set_sysclk(component, RT5665_SCLK_S_PLL1, 0,
 			rt5665->lrck[dai->id] * 512, 0);
 		pre_div = 1;
 	}
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return -EINVAL;
 	}
 
@@ -4160,7 +4160,7 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
 		reg_clk = RT5665_ADDA_CLK_1;
 		mask_clk = RT5665_I2S_PD1_MASK;
 		val_clk = pre_div << RT5665_I2S_PD1_SFT;
-		snd_soc_update_bits(codec, RT5665_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5665_I2S1_SDP,
 			RT5665_I2S_DL_MASK, val_len);
 		break;
 	case RT5665_AIF2_1:
@@ -4168,48 +4168,48 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
 		reg_clk = RT5665_ADDA_CLK_2;
 		mask_clk = RT5665_I2S_PD2_MASK;
 		val_clk = pre_div << RT5665_I2S_PD2_SFT;
-		snd_soc_update_bits(codec, RT5665_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5665_I2S2_SDP,
 			RT5665_I2S_DL_MASK, val_len);
 		break;
 	case RT5665_AIF3:
 		reg_clk = RT5665_ADDA_CLK_2;
 		mask_clk = RT5665_I2S_PD3_MASK;
 		val_clk = pre_div << RT5665_I2S_PD3_SFT;
-		snd_soc_update_bits(codec, RT5665_I2S3_SDP,
+		snd_soc_component_update_bits(component, RT5665_I2S3_SDP,
 			RT5665_I2S_DL_MASK, val_len);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, reg_clk, mask_clk, val_clk);
-	snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits);
+	snd_soc_component_update_bits(component, reg_clk, mask_clk, val_clk);
+	snd_soc_component_update_bits(component, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits);
 
 	switch (rt5665->lrck[dai->id]) {
 	case 192000:
-		snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+		snd_soc_component_update_bits(component, RT5665_ADDA_CLK_1,
 			RT5665_DAC_OSR_MASK | RT5665_ADC_OSR_MASK,
 			RT5665_DAC_OSR_32 | RT5665_ADC_OSR_32);
 		break;
 	case 96000:
-		snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+		snd_soc_component_update_bits(component, RT5665_ADDA_CLK_1,
 			RT5665_DAC_OSR_MASK | RT5665_ADC_OSR_MASK,
 			RT5665_DAC_OSR_64 | RT5665_ADC_OSR_64);
 		break;
 	default:
-		snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+		snd_soc_component_update_bits(component, RT5665_ADDA_CLK_1,
 			RT5665_DAC_OSR_MASK | RT5665_ADC_OSR_MASK,
 			RT5665_DAC_OSR_128 | RT5665_ADC_OSR_128);
 		break;
 	}
 
 	if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) {
-		snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_I2S_M_CLK_CTRL_1,
 			RT5665_I2S2_M_PD_MASK, pre_div << RT5665_I2S2_M_PD_SFT);
 	}
 	if (rt5665->master[RT5665_AIF3]) {
-		snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_I2S_M_CLK_CTRL_1,
 			RT5665_I2S3_M_PD_MASK, pre_div << RT5665_I2S3_M_PD_SFT);
 	}
 
@@ -4218,8 +4218,8 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5665_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -4263,32 +4263,32 @@ static int rt5665_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	switch (dai->id) {
 	case RT5665_AIF1_1:
 	case RT5665_AIF1_2:
-		snd_soc_update_bits(codec, RT5665_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5665_I2S1_SDP,
 			RT5665_I2S_MS_MASK | RT5665_I2S_BP_MASK |
 			RT5665_I2S_DF_MASK, reg_val);
 		break;
 	case RT5665_AIF2_1:
 	case RT5665_AIF2_2:
-		snd_soc_update_bits(codec, RT5665_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5665_I2S2_SDP,
 			RT5665_I2S_MS_MASK | RT5665_I2S_BP_MASK |
 			RT5665_I2S_DF_MASK, reg_val);
 		break;
 	case RT5665_AIF3:
-		snd_soc_update_bits(codec, RT5665_I2S3_SDP,
+		snd_soc_component_update_bits(component, RT5665_I2S3_SDP,
 			RT5665_I2S_MS_MASK | RT5665_I2S_BP_MASK |
 			RT5665_I2S_DF_MASK, reg_val);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 	return 0;
 }
 
-static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int rt5665_set_component_sysclk(struct snd_soc_component *component, int clk_id,
 				   int source, unsigned int freq, int dir)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0, src = 0;
 
 	if (freq == rt5665->sysclk && clk_id == rt5665->sysclk_src)
@@ -4308,34 +4308,34 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
 		src = RT5665_CLK_SRC_RCCLK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, RT5665_GLB_CLK,
+	snd_soc_component_update_bits(component, RT5665_GLB_CLK,
 		RT5665_SCLK_SRC_MASK, reg_val);
 
 	if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) {
-		snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_I2S_M_CLK_CTRL_1,
 			RT5665_I2S2_SRC_MASK, src << RT5665_I2S2_SRC_SFT);
 	}
 	if (rt5665->master[RT5665_AIF3]) {
-		snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1,
+		snd_soc_component_update_bits(component, RT5665_I2S_M_CLK_CTRL_1,
 			RT5665_I2S3_SRC_MASK, src << RT5665_I2S3_SRC_SFT);
 	}
 
 	rt5665->sysclk = freq;
 	rt5665->sysclk_src = clk_id;
 
-	dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
+	dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
 
 	return 0;
 }
 
-static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
+static int rt5665_set_component_pll(struct snd_soc_component *component, int pll_id,
 				int source, unsigned int freq_in,
 				unsigned int freq_out)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -4344,50 +4344,50 @@ static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5665->pll_in = 0;
 		rt5665->pll_out = 0;
-		snd_soc_update_bits(codec, RT5665_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5665_GLB_CLK,
 			RT5665_SCLK_SRC_MASK, RT5665_SCLK_SRC_MCLK);
 		return 0;
 	}
 
 	switch (source) {
 	case RT5665_PLL1_S_MCLK:
-		snd_soc_update_bits(codec, RT5665_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5665_GLB_CLK,
 			RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK);
 		break;
 	case RT5665_PLL1_S_BCLK1:
-		snd_soc_update_bits(codec, RT5665_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5665_GLB_CLK,
 				RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK1);
 		break;
 	case RT5665_PLL1_S_BCLK2:
-		snd_soc_update_bits(codec, RT5665_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5665_GLB_CLK,
 				RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK2);
 		break;
 	case RT5665_PLL1_S_BCLK3:
-		snd_soc_update_bits(codec, RT5665_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5665_GLB_CLK,
 				RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3);
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL Source %d\n", source);
+		dev_err(component->dev, "Unknown PLL Source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
-	snd_soc_write(codec, RT5665_PLL_CTRL_1,
+	snd_soc_component_write(component, RT5665_PLL_CTRL_1,
 		pll_code.n_code << RT5665_PLL_N_SFT | pll_code.k_code);
-	snd_soc_write(codec, RT5665_PLL_CTRL_2,
+	snd_soc_component_write(component, RT5665_PLL_CTRL_2,
 		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5665_PLL_M_SFT |
 		pll_code.m_bp << RT5665_PLL_M_BP_SFT);
 
@@ -4400,10 +4400,10 @@ static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
 
 static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+	dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
 
 	rt5665->bclk[dai->id] = ratio;
 
@@ -4411,12 +4411,12 @@ static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 		switch (dai->id) {
 		case RT5665_AIF2_1:
 		case RT5665_AIF2_2:
-			snd_soc_update_bits(codec, RT5665_ADDA_CLK_2,
+			snd_soc_component_update_bits(component, RT5665_ADDA_CLK_2,
 				RT5665_I2S_BCLK_MS2_MASK,
 				RT5665_I2S_BCLK_MS2_64);
 			break;
 		case RT5665_AIF3:
-			snd_soc_update_bits(codec, RT5665_ADDA_CLK_2,
+			snd_soc_component_update_bits(component, RT5665_ADDA_CLK_2,
 				RT5665_I2S_BCLK_MS3_MASK,
 				RT5665_I2S_BCLK_MS3_64);
 			break;
@@ -4426,10 +4426,10 @@ static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 	return 0;
 }
 
-static int rt5665_set_bias_level(struct snd_soc_codec *codec,
+static int rt5665_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
@@ -4459,39 +4459,37 @@ static int rt5665_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5665_probe(struct snd_soc_codec *codec)
+static int rt5665_probe(struct snd_soc_component *component)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
-	rt5665->codec = codec;
+	rt5665->component = component;
 
 	schedule_delayed_work(&rt5665->calibrate_work, msecs_to_jiffies(100));
 
 	return 0;
 }
 
-static int rt5665_remove(struct snd_soc_codec *codec)
+static void rt5665_remove(struct snd_soc_component *component)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
 	regmap_write(rt5665->regmap, RT5665_RESET, 0);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5665_suspend(struct snd_soc_codec *codec)
+static int rt5665_suspend(struct snd_soc_component *component)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5665->regmap, true);
 	regcache_mark_dirty(rt5665->regmap);
 	return 0;
 }
 
-static int rt5665_resume(struct snd_soc_codec *codec)
+static int rt5665_resume(struct snd_soc_component *component)
 {
-	struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5665->regmap, false);
 	regcache_sync(rt5665->regmap);
@@ -4605,24 +4603,24 @@ static struct snd_soc_dai_driver rt5665_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5665 = {
-	.probe = rt5665_probe,
-	.remove = rt5665_remove,
-	.suspend = rt5665_suspend,
-	.resume = rt5665_resume,
-	.set_bias_level = rt5665_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls = rt5665_snd_controls,
-		.num_controls = ARRAY_SIZE(rt5665_snd_controls),
-		.dapm_widgets = rt5665_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets),
-		.dapm_routes = rt5665_dapm_routes,
-		.num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes),
-	},
-	.set_sysclk = rt5665_set_codec_sysclk,
-	.set_pll = rt5665_set_codec_pll,
-	.set_jack = rt5665_set_jack_detect,
+static const struct snd_soc_component_driver soc_component_dev_rt5665 = {
+	.probe			= rt5665_probe,
+	.remove			= rt5665_remove,
+	.suspend		= rt5665_suspend,
+	.resume			= rt5665_resume,
+	.set_bias_level		= rt5665_set_bias_level,
+	.controls		= rt5665_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5665_snd_controls),
+	.dapm_widgets		= rt5665_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5665_dapm_widgets),
+	.dapm_routes		= rt5665_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5665_dapm_routes),
+	.set_sysclk		= rt5665_set_component_sysclk,
+	.set_pll		= rt5665_set_component_pll,
+	.set_jack		= rt5665_set_jack_detect,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 
@@ -4753,7 +4751,7 @@ static void rt5665_calibrate_handler(struct work_struct *work)
 	struct rt5665_priv *rt5665 = container_of(work, struct rt5665_priv,
 		calibrate_work.work);
 
-	while (!rt5665->codec->component.card->instantiated) {
+	while (!rt5665->component->card->instantiated) {
 		pr_debug("%s\n", __func__);
 		usleep_range(10000, 15000);
 	}
@@ -4828,9 +4826,6 @@ static int rt5665_i2c_probe(struct i2c_client *i2c,
 	case 0x0:
 		rt5665->id = CODEC_5666;
 		break;
-	case 0x6:
-		rt5665->id = CODEC_5668;
-		break;
 	case 0x3:
 	default:
 		rt5665->id = CODEC_5665;
@@ -4941,17 +4936,11 @@ static int rt5665_i2c_probe(struct i2c_client *i2c,
 
 	}
 
-	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5665,
+	return devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_rt5665,
 			rt5665_dai, ARRAY_SIZE(rt5665_dai));
 }
 
-static int rt5665_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-
-	return 0;
-}
-
 static void rt5665_i2c_shutdown(struct i2c_client *client)
 {
 	struct rt5665_priv *rt5665 = i2c_get_clientdata(client);
@@ -4963,7 +4952,6 @@ static void rt5665_i2c_shutdown(struct i2c_client *client)
 static const struct of_device_id rt5665_of_match[] = {
 	{.compatible = "realtek,rt5665"},
 	{.compatible = "realtek,rt5666"},
-	{.compatible = "realtek,rt5668"},
 	{},
 };
 MODULE_DEVICE_TABLE(of, rt5665_of_match);
@@ -4973,7 +4961,6 @@ MODULE_DEVICE_TABLE(of, rt5665_of_match);
 static const struct acpi_device_id rt5665_acpi_match[] = {
 	{"10EC5665", 0,},
 	{"10EC5666", 0,},
-	{"10EC5668", 0,},
 	{},
 };
 MODULE_DEVICE_TABLE(acpi, rt5665_acpi_match);
@@ -4986,7 +4973,6 @@ static struct i2c_driver rt5665_i2c_driver = {
 		.acpi_match_table = ACPI_PTR(rt5665_acpi_match),
 	},
 	.probe = rt5665_i2c_probe,
-	.remove = rt5665_i2c_remove,
 	.shutdown = rt5665_i2c_shutdown,
 	.id_table = rt5665_i2c_id,
 };
diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h
index 5ddebd6..b0a98ca 100644
--- a/sound/soc/codecs/rt5665.h
+++ b/sound/soc/codecs/rt5665.h
@@ -1978,7 +1978,6 @@ enum {
 enum {
 	CODEC_5665,
 	CODEC_5666,
-	CODEC_5668,
 };
 
 /* filter mask */
@@ -2003,7 +2002,7 @@ enum {
 	RT5665_CLK_SEL_SYS4,
 };
 
-int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5665_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src);
 
 #endif /* __RT5665_H__ */
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index c5094b4..dc7df33 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -423,7 +423,7 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
 
 /**
  * rt5670_headset_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
@@ -431,46 +431,46 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
  * Returns detect status.
  */
 
-static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5670_headset_detect(struct snd_soc_component *component, int jack_insert)
 {
 	int val;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	if (jack_insert) {
 		snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
 		snd_soc_dapm_sync(dapm);
-		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
-		snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x0);
+		snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
 			RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
 			RT5670_CBJ_MN_JD);
-		snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
-		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+		snd_soc_component_write(component, RT5670_GPIO_CTRL2, 0x0004);
+		snd_soc_component_update_bits(component, RT5670_GPIO_CTRL1,
 			RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
-		snd_soc_update_bits(codec, RT5670_CJ_CTRL1,
+		snd_soc_component_update_bits(component, RT5670_CJ_CTRL1,
 			RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN);
-		snd_soc_write(codec, RT5670_JD_CTRL3, 0x00f0);
-		snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+		snd_soc_component_write(component, RT5670_JD_CTRL3, 0x00f0);
+		snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
 			RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD);
-		snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+		snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
 			RT5670_CBJ_MN_JD, 0);
 		msleep(300);
-		val = snd_soc_read(codec, RT5670_CJ_CTRL3) & 0x7;
+		val = snd_soc_component_read32(component, RT5670_CJ_CTRL3) & 0x7;
 		if (val == 0x1 || val == 0x2) {
 			rt5670->jack_type = SND_JACK_HEADSET;
 			/* for push button */
-			snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x8);
-			snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
-			snd_soc_read(codec, RT5670_IL_CMD);
+			snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x8);
+			snd_soc_component_update_bits(component, RT5670_IL_CMD, 0x40, 0x40);
+			snd_soc_component_read32(component, RT5670_IL_CMD);
 		} else {
-			snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
+			snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
 			rt5670->jack_type = SND_JACK_HEADPHONE;
 			snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
 			snd_soc_dapm_sync(dapm);
 		}
 	} else {
-		snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
-		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
+		snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x0);
+		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
 		rt5670->jack_type = 0;
 		snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
 		snd_soc_dapm_sync(dapm);
@@ -479,35 +479,35 @@ static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 	return rt5670->jack_type;
 }
 
-void rt5670_jack_suspend(struct snd_soc_codec *codec)
+void rt5670_jack_suspend(struct snd_soc_component *component)
 {
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	rt5670->jack_type_saved = rt5670->jack_type;
-	rt5670_headset_detect(codec, 0);
+	rt5670_headset_detect(component, 0);
 }
 EXPORT_SYMBOL_GPL(rt5670_jack_suspend);
 
-void rt5670_jack_resume(struct snd_soc_codec *codec)
+void rt5670_jack_resume(struct snd_soc_component *component)
 {
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	if (rt5670->jack_type_saved)
-		rt5670_headset_detect(codec, 1);
+		rt5670_headset_detect(component, 1);
 }
 EXPORT_SYMBOL_GPL(rt5670_jack_resume);
 
-static int rt5670_button_detect(struct snd_soc_codec *codec)
+static int rt5670_button_detect(struct snd_soc_component *component)
 {
 	int btn_type, val;
 
-	val = snd_soc_read(codec, RT5670_IL_CMD);
+	val = snd_soc_component_read32(component, RT5670_IL_CMD);
 	btn_type = val & 0xff80;
-	snd_soc_write(codec, RT5670_IL_CMD, val);
+	snd_soc_component_write(component, RT5670_IL_CMD, val);
 	if (btn_type != 0) {
 		msleep(20);
-		val = snd_soc_read(codec, RT5670_IL_CMD);
-		snd_soc_write(codec, RT5670_IL_CMD, val);
+		val = snd_soc_component_read32(component, RT5670_IL_CMD);
+		snd_soc_component_write(component, RT5670_IL_CMD, val);
 	}
 
 	return btn_type;
@@ -521,25 +521,25 @@ static int rt5670_irq_detection(void *data)
 	int val, btn_type, report = jack->status;
 
 	if (rt5670->pdata.jd_mode == 1) /* 2 port */
-		val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0070;
+		val = snd_soc_component_read32(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070;
 	else
-		val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0020;
+		val = snd_soc_component_read32(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020;
 
 	switch (val) {
 	/* jack in */
 	case 0x30: /* 2 port */
 	case 0x0: /* 1 port or 2 port */
 		if (rt5670->jack_type == 0) {
-			report = rt5670_headset_detect(rt5670->codec, 1);
+			report = rt5670_headset_detect(rt5670->component, 1);
 			/* for push button and jack out */
 			gpio->debounce_time = 25;
 			break;
 		}
 		btn_type = 0;
-		if (snd_soc_read(rt5670->codec, RT5670_INT_IRQ_ST) & 0x4) {
+		if (snd_soc_component_read32(rt5670->component, RT5670_INT_IRQ_ST) & 0x4) {
 			/* button pressed */
 			report = SND_JACK_HEADSET;
-			btn_type = rt5670_button_detect(rt5670->codec);
+			btn_type = rt5670_button_detect(rt5670->component);
 			switch (btn_type) {
 			case 0x2000: /* up */
 				report |= SND_JACK_BTN_1;
@@ -551,7 +551,7 @@ static int rt5670_irq_detection(void *data)
 				report |= SND_JACK_BTN_2;
 				break;
 			default:
-				dev_err(rt5670->codec->dev,
+				dev_err(rt5670->component->dev,
 					"Unexpected button code 0x%04x\n",
 					btn_type);
 				break;
@@ -566,8 +566,8 @@ static int rt5670_irq_detection(void *data)
 	case 0x10: /* 2 port */
 	case 0x20: /* 1 port */
 		report = 0;
-		snd_soc_update_bits(rt5670->codec, RT5670_INT_IRQ_ST, 0x1, 0x0);
-		rt5670_headset_detect(rt5670->codec, 0);
+		snd_soc_component_update_bits(rt5670->component, RT5670_INT_IRQ_ST, 0x1, 0x0);
+		rt5670_headset_detect(rt5670->component, 0);
 		gpio->debounce_time = 150; /* for jack in */
 		break;
 	default:
@@ -577,14 +577,14 @@ static int rt5670_irq_detection(void *data)
 	return report;
 }
 
-int rt5670_set_jack_detect(struct snd_soc_codec *codec,
+int rt5670_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *jack)
 {
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	rt5670->jack = jack;
-	rt5670->hp_gpio.gpiod_dev = codec->dev;
+	rt5670->hp_gpio.gpiod_dev = component->dev;
 	rt5670->hp_gpio.name = "headset";
 	rt5670->hp_gpio.report = SND_JACK_HEADSET |
 		SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2;
@@ -596,7 +596,7 @@ int rt5670_set_jack_detect(struct snd_soc_codec *codec,
 	ret = snd_soc_jack_add_gpios(rt5670->jack, 1,
 			&rt5670->hp_gpio);
 	if (ret) {
-		dev_err(codec->dev, "Adding jack GPIO failed\n");
+		dev_err(component->dev, "Adding jack GPIO failed\n");
 		return ret;
 	}
 
@@ -699,17 +699,17 @@ static const struct snd_kcontrol_new rt5670_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 	int idx, rate;
 
 	rate = rt5670->sysclk / rl6231_get_pre_div(rt5670->regmap,
 		RT5670_ADDA_CLK1, RT5670_I2S_PD1_SFT);
 	idx = rl6231_calc_dmic_clk(rate);
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else
-		snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
+		snd_soc_component_update_bits(component, RT5670_DMIC_CTRL1,
 			RT5670_DMIC_CLK_MASK, idx << RT5670_DMIC_CLK_SFT);
 	return idx;
 }
@@ -717,8 +717,8 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	if (rt5670->sysclk_src == RT5670_SCLK_S_PLL1)
 		return 1;
@@ -729,7 +729,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg, shift, val;
 
 	switch (source->shift) {
@@ -765,7 +765,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
 		return 0;
 	}
 
-	val = (snd_soc_read(codec, reg) >> shift) & 0xf;
+	val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
 	switch (val) {
 	case 1:
 	case 2:
@@ -781,8 +781,8 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
 static int can_use_asrc(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	if (rt5670->sysclk > rt5670->lrck[RT5670_AIF1] * 384)
 		return 1;
@@ -793,7 +793,7 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
 
 /**
  * rt5670_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -805,7 +805,7 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5670_sel_asrc_clk_src(struct snd_soc_component *component,
 			    unsigned int filter_mask, unsigned int clk_src)
 {
 	unsigned int asrc2_mask = 0, asrc2_value = 0;
@@ -863,11 +863,11 @@ int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
 	}
 
 	if (asrc2_mask)
-		snd_soc_update_bits(codec, RT5670_ASRC_2,
+		snd_soc_component_update_bits(component, RT5670_ASRC_2,
 				    asrc2_mask, asrc2_value);
 
 	if (asrc3_mask)
-		snd_soc_update_bits(codec, RT5670_ASRC_3,
+		snd_soc_component_update_bits(component, RT5670_ASRC_3,
 				    asrc3_mask, asrc3_value);
 	return 0;
 }
@@ -1421,8 +1421,8 @@ static const struct snd_kcontrol_new rt5670_vad_adc_mux =
 static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -1457,8 +1457,8 @@ static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
 static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -1507,16 +1507,16 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
 				    RT5670_PWR_BST1_P, RT5670_PWR_BST1_P);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
 				    RT5670_PWR_BST1_P, 0);
 		break;
 
@@ -1530,16 +1530,16 @@ static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
 static int rt5670_bst2_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
 				    RT5670_PWR_BST2_P, RT5670_PWR_BST2_P);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+		snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
 				    RT5670_PWR_BST2_P, 0);
 		break;
 
@@ -2322,21 +2322,21 @@ static const struct snd_soc_dapm_route rt5672_specific_dapm_routes[] = {
 static int rt5670_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, mask_clk;
 	int pre_div, bclk_ms, frame_size;
 
 	rt5670->lrck[dai->id] = params_rate(params);
 	pre_div = rl6231_get_clk_info(rt5670->sysclk, rt5670->lrck[dai->id]);
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+		dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
 			rt5670->lrck[dai->id], dai->id);
 		return -EINVAL;
 	}
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return -EINVAL;
 	}
 	bclk_ms = frame_size > 32;
@@ -2368,20 +2368,20 @@ static int rt5670_hw_params(struct snd_pcm_substream *substream,
 		mask_clk = RT5670_I2S_BCLK_MS1_MASK | RT5670_I2S_PD1_MASK;
 		val_clk = bclk_ms << RT5670_I2S_BCLK_MS1_SFT |
 			pre_div << RT5670_I2S_PD1_SFT;
-		snd_soc_update_bits(codec, RT5670_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5670_I2S1_SDP,
 			RT5670_I2S_DL_MASK, val_len);
-		snd_soc_update_bits(codec, RT5670_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5670_ADDA_CLK1, mask_clk, val_clk);
 		break;
 	case RT5670_AIF2:
 		mask_clk = RT5670_I2S_BCLK_MS2_MASK | RT5670_I2S_PD2_MASK;
 		val_clk = bclk_ms << RT5670_I2S_BCLK_MS2_SFT |
 			pre_div << RT5670_I2S_PD2_SFT;
-		snd_soc_update_bits(codec, RT5670_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5670_I2S2_SDP,
 			RT5670_I2S_DL_MASK, val_len);
-		snd_soc_update_bits(codec, RT5670_ADDA_CLK1, mask_clk, val_clk);
+		snd_soc_component_update_bits(component, RT5670_ADDA_CLK1, mask_clk, val_clk);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 
@@ -2390,8 +2390,8 @@ static int rt5670_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -2434,26 +2434,26 @@ static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	switch (dai->id) {
 	case RT5670_AIF1:
-		snd_soc_update_bits(codec, RT5670_I2S1_SDP,
+		snd_soc_component_update_bits(component, RT5670_I2S1_SDP,
 			RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
 			RT5670_I2S_DF_MASK, reg_val);
 		break;
 	case RT5670_AIF2:
-		snd_soc_update_bits(codec, RT5670_I2S2_SDP,
+		snd_soc_component_update_bits(component, RT5670_I2S2_SDP,
 			RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
 			RT5670_I2S_DF_MASK, reg_val);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 		return -EINVAL;
 	}
 	return 0;
 }
 
-static int rt5670_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int rt5670_set_codec_sysclk(struct snd_soc_component *component, int clk_id,
 				   int source, unsigned int freq, int dir)
 {
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (clk_id) {
@@ -2467,16 +2467,16 @@ static int rt5670_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
 		reg_val |= RT5670_SCLK_SRC_RCCLK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, RT5670_GLB_CLK,
+	snd_soc_component_update_bits(component, RT5670_GLB_CLK,
 		RT5670_SCLK_SRC_MASK, reg_val);
 	rt5670->sysclk = freq;
 	if (clk_id != RT5670_SCLK_S_RCCLK)
 		rt5670->sysclk_src = clk_id;
 
-	dev_dbg(codec->dev, "Sysclk : %dHz clock id : %d\n", freq, clk_id);
+	dev_dbg(component->dev, "Sysclk : %dHz clock id : %d\n", freq, clk_id);
 
 	return 0;
 }
@@ -2484,8 +2484,8 @@ static int rt5670_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
 static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -2494,18 +2494,18 @@ static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5670->pll_in = 0;
 		rt5670->pll_out = 0;
-		snd_soc_update_bits(codec, RT5670_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5670_GLB_CLK,
 			RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_MCLK);
 		return 0;
 	}
 
 	switch (source) {
 	case RT5670_PLL1_S_MCLK:
-		snd_soc_update_bits(codec, RT5670_GLB_CLK,
+		snd_soc_component_update_bits(component, RT5670_GLB_CLK,
 			RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_MCLK);
 		break;
 	case RT5670_PLL1_S_BCLK1:
@@ -2514,36 +2514,36 @@ static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 	case RT5670_PLL1_S_BCLK4:
 		switch (dai->id) {
 		case RT5670_AIF1:
-			snd_soc_update_bits(codec, RT5670_GLB_CLK,
+			snd_soc_component_update_bits(component, RT5670_GLB_CLK,
 				RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK1);
 			break;
 		case RT5670_AIF2:
-			snd_soc_update_bits(codec, RT5670_GLB_CLK,
+			snd_soc_component_update_bits(component, RT5670_GLB_CLK,
 				RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK2);
 			break;
 		default:
-			dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+			dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
 			return -EINVAL;
 		}
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
-	snd_soc_write(codec, RT5670_PLL_CTRL1,
+	snd_soc_component_write(component, RT5670_PLL_CTRL1,
 		pll_code.n_code << RT5670_PLL_N_SFT | pll_code.k_code);
-	snd_soc_write(codec, RT5670_PLL_CTRL2,
+	snd_soc_component_write(component, RT5670_PLL_CTRL2,
 		(pll_code.m_bp ? 0 : pll_code.m_code) << RT5670_PLL_M_SFT |
 		pll_code.m_bp << RT5670_PLL_M_BP_SFT);
 
@@ -2557,7 +2557,7 @@ static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val = 0;
 
 	if (rx_mask || tx_mask)
@@ -2595,75 +2595,75 @@ static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, RT5670_TDM_CTRL_1, 0x7c00, val);
+	snd_soc_component_update_bits(component, RT5670_TDM_CTRL_1, 0x7c00, val);
 
 	return 0;
 }
 
 static int rt5670_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+	dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
 	if (dai->id != RT5670_AIF1)
 		return 0;
 
 	if ((ratio % 50) == 0)
-		snd_soc_update_bits(codec, RT5670_GEN_CTRL3,
+		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3,
 			RT5670_TDM_DATA_MODE_SEL, RT5670_TDM_DATA_MODE_50FS);
 	else
-		snd_soc_update_bits(codec, RT5670_GEN_CTRL3,
+		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3,
 			RT5670_TDM_DATA_MODE_SEL, RT5670_TDM_DATA_MODE_NOR);
 
 	return 0;
 }
 
-static int rt5670_set_bias_level(struct snd_soc_codec *codec,
+static int rt5670_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
-		if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
-			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+		if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
+			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
 				RT5670_PWR_VREF1 | RT5670_PWR_MB |
 				RT5670_PWR_BG | RT5670_PWR_VREF2,
 				RT5670_PWR_VREF1 | RT5670_PWR_MB |
 				RT5670_PWR_BG | RT5670_PWR_VREF2);
 			mdelay(10);
-			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
 				RT5670_PWR_FV1 | RT5670_PWR_FV2,
 				RT5670_PWR_FV1 | RT5670_PWR_FV2);
-			snd_soc_update_bits(codec, RT5670_CHARGE_PUMP,
+			snd_soc_component_update_bits(component, RT5670_CHARGE_PUMP,
 				RT5670_OSW_L_MASK | RT5670_OSW_R_MASK,
 				RT5670_OSW_L_DIS | RT5670_OSW_R_DIS);
-			snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x1);
-			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5670_DIG_MISC, 0x1, 0x1);
+			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
 				RT5670_LDO_SEL_MASK, 0x5);
 		}
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
 				RT5670_PWR_VREF1 | RT5670_PWR_VREF2 |
 				RT5670_PWR_FV1 | RT5670_PWR_FV2, 0);
-		snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+		snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
 				RT5670_LDO_SEL_MASK, 0x3);
 		break;
 	case SND_SOC_BIAS_OFF:
 		if (rt5670->pdata.jd_mode)
-			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
 				RT5670_PWR_VREF1 | RT5670_PWR_MB |
 				RT5670_PWR_BG | RT5670_PWR_VREF2 |
 				RT5670_PWR_FV1 | RT5670_PWR_FV2,
 				RT5670_PWR_MB | RT5670_PWR_BG);
 		else
-			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
 				RT5670_PWR_VREF1 | RT5670_PWR_MB |
 				RT5670_PWR_BG | RT5670_PWR_VREF2 |
 				RT5670_PWR_FV1 | RT5670_PWR_FV2, 0);
 
-		snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x0);
+		snd_soc_component_update_bits(component, RT5670_DIG_MISC, 0x1, 0x0);
 		break;
 
 	default:
@@ -2673,12 +2673,12 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int rt5670_probe(struct snd_soc_codec *codec)
+static int rt5670_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
-	switch (snd_soc_read(codec, RT5670_RESET) & RT5670_ID_MASK) {
+	switch (snd_soc_component_read32(component, RT5670_RESET) & RT5670_ID_MASK) {
 	case RT5670_ID_5670:
 	case RT5670_ID_5671:
 		snd_soc_dapm_new_controls(dapm,
@@ -2697,37 +2697,36 @@ static int rt5670_probe(struct snd_soc_codec *codec)
 			ARRAY_SIZE(rt5672_specific_dapm_routes));
 		break;
 	default:
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"The driver is for RT5670 RT5671 or RT5672 only\n");
 		return -ENODEV;
 	}
-	rt5670->codec = codec;
+	rt5670->component = component;
 
 	return 0;
 }
 
-static int rt5670_remove(struct snd_soc_codec *codec)
+static void rt5670_remove(struct snd_soc_component *component)
 {
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	regmap_write(rt5670->regmap, RT5670_RESET, 0);
 	snd_soc_jack_free_gpios(rt5670->jack, 1, &rt5670->hp_gpio);
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5670_suspend(struct snd_soc_codec *codec)
+static int rt5670_suspend(struct snd_soc_component *component)
 {
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5670->regmap, true);
 	regcache_mark_dirty(rt5670->regmap);
 	return 0;
 }
 
-static int rt5670_resume(struct snd_soc_codec *codec)
+static int rt5670_resume(struct snd_soc_component *component)
 {
-	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(rt5670->regmap, false);
 	regcache_sync(rt5670->regmap);
@@ -2794,22 +2793,22 @@ static struct snd_soc_dai_driver rt5670_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5670 = {
-	.probe = rt5670_probe,
-	.remove = rt5670_remove,
-	.suspend = rt5670_suspend,
-	.resume = rt5670_resume,
-	.set_bias_level = rt5670_set_bias_level,
-	.idle_bias_off = true,
-	.set_sysclk = rt5670_set_codec_sysclk,
-	.component_driver = {
-		.controls		= rt5670_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5670_snd_controls),
-		.dapm_widgets		= rt5670_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5670_dapm_widgets),
-		.dapm_routes		= rt5670_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5670_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5670 = {
+	.probe			= rt5670_probe,
+	.remove			= rt5670_remove,
+	.suspend		= rt5670_suspend,
+	.resume			= rt5670_resume,
+	.set_bias_level		= rt5670_set_bias_level,
+	.set_sysclk		= rt5670_set_codec_sysclk,
+	.controls		= rt5670_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5670_snd_controls),
+	.dapm_widgets		= rt5670_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5670_dapm_widgets),
+	.dapm_routes		= rt5670_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5670_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt5670_regmap = {
@@ -3171,7 +3170,8 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
 	pm_runtime_enable(&i2c->dev);
 	pm_request_idle(&i2c->dev);
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_rt5670,
 			rt5670_dai, ARRAY_SIZE(rt5670_dai));
 	if (ret < 0)
 		goto err;
@@ -3188,7 +3188,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
 static int rt5670_i2c_remove(struct i2c_client *i2c)
 {
 	pm_runtime_disable(&i2c->dev);
-	snd_soc_unregister_codec(&i2c->dev);
 
 	return 0;
 }
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
index 265df80..97e8eeb 100644
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -1986,11 +1986,11 @@ enum {
 	RT5670_DOWN_RATE_FILTER = (0x1 << 7),
 };
 
-int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5670_sel_asrc_clk_src(struct snd_soc_component *component,
 			    unsigned int filter_mask, unsigned int clk_src);
 
 struct rt5670_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt5670_platform_data pdata;
 	struct regmap *regmap;
 	struct snd_soc_jack *jack;
@@ -2012,8 +2012,8 @@ struct rt5670_priv {
 	int jack_type_saved;
 };
 
-void rt5670_jack_suspend(struct snd_soc_codec *codec);
-void rt5670_jack_resume(struct snd_soc_codec *codec);
-int rt5670_set_jack_detect(struct snd_soc_codec *codec,
+void rt5670_jack_suspend(struct snd_soc_component *component);
+void rt5670_jack_resume(struct snd_soc_component *component);
+int rt5670_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *jack);
 #endif /* __RT5670_H__ */
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 0791fec..bc1a23d 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -554,7 +554,7 @@ static bool rt5677_readable_register(struct device *dev, unsigned int reg)
 static int rt5677_dsp_mode_i2c_write_addr(struct rt5677_priv *rt5677,
 		unsigned int addr, unsigned int value, unsigned int opcode)
 {
-	struct snd_soc_codec *codec = rt5677->codec;
+	struct snd_soc_component *component = rt5677->component;
 	int ret;
 
 	mutex_lock(&rt5677->dsp_cmd_lock);
@@ -562,35 +562,35 @@ static int rt5677_dsp_mode_i2c_write_addr(struct rt5677_priv *rt5677,
 	ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_MSB,
 		addr >> 16);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret);
+		dev_err(component->dev, "Failed to set addr msb value: %d\n", ret);
 		goto err;
 	}
 
 	ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_LSB,
 		addr & 0xffff);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret);
+		dev_err(component->dev, "Failed to set addr lsb value: %d\n", ret);
 		goto err;
 	}
 
 	ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_DATA_MSB,
 		value >> 16);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set data msb value: %d\n", ret);
+		dev_err(component->dev, "Failed to set data msb value: %d\n", ret);
 		goto err;
 	}
 
 	ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_DATA_LSB,
 		value & 0xffff);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set data lsb value: %d\n", ret);
+		dev_err(component->dev, "Failed to set data lsb value: %d\n", ret);
 		goto err;
 	}
 
 	ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_OP_CODE,
 		opcode);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set op code value: %d\n", ret);
+		dev_err(component->dev, "Failed to set op code value: %d\n", ret);
 		goto err;
 	}
 
@@ -612,7 +612,7 @@ static int rt5677_dsp_mode_i2c_write_addr(struct rt5677_priv *rt5677,
 static int rt5677_dsp_mode_i2c_read_addr(
 	struct rt5677_priv *rt5677, unsigned int addr, unsigned int *value)
 {
-	struct snd_soc_codec *codec = rt5677->codec;
+	struct snd_soc_component *component = rt5677->component;
 	int ret;
 	unsigned int msb, lsb;
 
@@ -621,21 +621,21 @@ static int rt5677_dsp_mode_i2c_read_addr(
 	ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_MSB,
 		addr >> 16);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret);
+		dev_err(component->dev, "Failed to set addr msb value: %d\n", ret);
 		goto err;
 	}
 
 	ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_LSB,
 		addr & 0xffff);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret);
+		dev_err(component->dev, "Failed to set addr lsb value: %d\n", ret);
 		goto err;
 	}
 
 	ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_OP_CODE,
 		0x0002);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set op code value: %d\n", ret);
+		dev_err(component->dev, "Failed to set op code value: %d\n", ret);
 		goto err;
 	}
 
@@ -685,9 +685,9 @@ static int rt5677_dsp_mode_i2c_read(
 	return ret;
 }
 
-static void rt5677_set_dsp_mode(struct snd_soc_codec *codec, bool on)
+static void rt5677_set_dsp_mode(struct snd_soc_component *component, bool on)
 {
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	if (on) {
 		regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x2);
@@ -698,9 +698,9 @@ static void rt5677_set_dsp_mode(struct snd_soc_codec *codec, bool on)
 	}
 }
 
-static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
+static int rt5677_set_dsp_vad(struct snd_soc_component *component, bool on)
 {
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	static bool activity;
 	int ret;
 
@@ -740,17 +740,17 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
 		}
 		regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x07ff);
 		regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07fd);
-		rt5677_set_dsp_mode(codec, true);
+		rt5677_set_dsp_mode(component, true);
 
 		ret = request_firmware(&rt5677->fw1, RT5677_FIRMWARE1,
-			codec->dev);
+			component->dev);
 		if (ret == 0) {
 			rt5677_spi_write_firmware(0x50000000, rt5677->fw1);
 			release_firmware(rt5677->fw1);
 		}
 
 		ret = request_firmware(&rt5677->fw2, RT5677_FIRMWARE2,
-			codec->dev);
+			component->dev);
 		if (ret == 0) {
 			rt5677_spi_write_firmware(0x60000000, rt5677->fw2);
 			release_firmware(rt5677->fw2);
@@ -767,7 +767,7 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
 		regcache_cache_bypass(rt5677->regmap, true);
 
 		regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x1, 0x1);
-		rt5677_set_dsp_mode(codec, false);
+		rt5677_set_dsp_mode(component, false);
 		regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x0001);
 
 		regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
@@ -812,12 +812,11 @@ static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
-	struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
 	rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0];
 
-	if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
-		rt5677_set_dsp_vad(codec, rt5677->dsp_vad_en);
+	if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+		rt5677_set_dsp_vad(component, rt5677->dsp_vad_en);
 
 	return 0;
 }
@@ -911,15 +910,15 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	int idx, rate;
 
 	rate = rt5677->sysclk / rl6231_get_pre_div(rt5677->regmap,
 		RT5677_CLK_TREE_CTRL1, RT5677_I2S_PD1_SFT);
 	idx = rl6231_calc_dmic_clk(rate);
 	if (idx < 0)
-		dev_err(codec->dev, "Failed to set DMIC clock\n");
+		dev_err(component->dev, "Failed to set DMIC clock\n");
 	else
 		regmap_update_bits(rt5677->regmap, RT5677_DMIC_CTRL1,
 			RT5677_DMIC_CLK_MASK, idx << RT5677_DMIC_CLK_SFT);
@@ -929,8 +928,8 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	regmap_read(rt5677->regmap, RT5677_GLB_CLK1, &val);
@@ -944,8 +943,8 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int reg, shift, val;
 
 	if (source->reg == RT5677_ASRC_1) {
@@ -1027,8 +1026,8 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
 static int can_use_asrc(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	if (rt5677->sysclk > rt5677->lrck[RT5677_AIF1] * 384)
 		return 1;
@@ -1038,7 +1037,7 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
 
 /**
  * rt5677_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -1050,10 +1049,10 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5677_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src)
 {
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int asrc3_mask = 0, asrc3_value = 0;
 	unsigned int asrc4_mask = 0, asrc4_value = 0;
 	unsigned int asrc5_mask = 0, asrc5_value = 0;
@@ -1232,8 +1231,8 @@ EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src);
 static int rt5677_dmic_use_asrc(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int asrc_setting;
 
 	switch (source->shift) {
@@ -2393,8 +2392,8 @@ static const struct snd_kcontrol_new rt5677_if2_dac7_tdm_sel_mux =
 static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -2417,8 +2416,8 @@ static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
 static int rt5677_bst2_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -2441,8 +2440,8 @@ static int rt5677_bst2_event(struct snd_soc_dapm_widget *w,
 static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -2463,8 +2462,8 @@ static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w,
 static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -2485,8 +2484,8 @@ static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w,
 static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -2512,8 +2511,8 @@ static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
 static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int value;
 
 	switch (event) {
@@ -2535,8 +2534,8 @@ static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w,
 static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int value;
 
 	switch (event) {
@@ -2558,12 +2557,12 @@ static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w,
 static int rt5677_vref_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_ON &&
+		if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON &&
 			!rt5677->is_vref_slow) {
 			mdelay(20);
 			regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
@@ -4098,21 +4097,21 @@ static const struct snd_soc_dapm_route rt5677_dmic2_clk_2[] = {
 static int rt5677_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int val_len = 0, val_clk, mask_clk;
 	int pre_div, bclk_ms, frame_size;
 
 	rt5677->lrck[dai->id] = params_rate(params);
 	pre_div = rl6231_get_clk_info(rt5677->sysclk, rt5677->lrck[dai->id]);
 	if (pre_div < 0) {
-		dev_err(codec->dev, "Unsupported clock setting: sysclk=%dHz lrck=%dHz\n",
+		dev_err(component->dev, "Unsupported clock setting: sysclk=%dHz lrck=%dHz\n",
 			rt5677->sysclk, rt5677->lrck[dai->id]);
 		return -EINVAL;
 	}
 	frame_size = snd_soc_params_to_frame_size(params);
 	if (frame_size < 0) {
-		dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
 		return -EINVAL;
 	}
 	bclk_ms = frame_size > 32;
@@ -4183,8 +4182,8 @@ static int rt5677_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5677_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -4257,8 +4256,8 @@ static int rt5677_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5677_set_dai_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
 
 	if (freq == rt5677->sysclk && clk_id == rt5677->sysclk_src)
@@ -4275,7 +4274,7 @@ static int rt5677_set_dai_sysclk(struct snd_soc_dai *dai,
 		reg_val |= RT5677_SCLK_SRC_RCCLK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
 	regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK1,
@@ -4310,8 +4309,8 @@ static int rt5677_pll_calc(const unsigned int freq_in,
 static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 			unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	struct rl6231_pll_code pll_code;
 	int ret;
 
@@ -4320,7 +4319,7 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		return 0;
 
 	if (!freq_in || !freq_out) {
-		dev_dbg(codec->dev, "PLL disabled\n");
+		dev_dbg(component->dev, "PLL disabled\n");
 
 		rt5677->pll_in = 0;
 		rt5677->pll_out = 0;
@@ -4360,17 +4359,17 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 		}
 		break;
 	default:
-		dev_err(codec->dev, "Unknown PLL source %d\n", source);
+		dev_err(component->dev, "Unknown PLL source %d\n", source);
 		return -EINVAL;
 	}
 
 	ret = rt5677_pll_calc(freq_in, freq_out, &pll_code);
 	if (ret < 0) {
-		dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+		dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "m_bypass=%d m=%d n=%d k=%d\n",
+	dev_dbg(component->dev, "m_bypass=%d m=%d n=%d k=%d\n",
 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
 		pll_code.n_code, pll_code.k_code);
 
@@ -4390,8 +4389,8 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0, slot_width_25 = 0;
 
 	if (rx_mask || tx_mask)
@@ -4449,18 +4448,18 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	return 0;
 }
 
-static int rt5677_set_bias_level(struct snd_soc_codec *codec,
+static int rt5677_set_bias_level(struct snd_soc_component *component,
 			enum snd_soc_bias_level level)
 {
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
-			rt5677_set_dsp_vad(codec, false);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
+			rt5677_set_dsp_vad(component, false);
 
 			regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
 				RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK,
@@ -4495,7 +4494,7 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec,
 			RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000);
 
 		if (rt5677->dsp_vad_en)
-			rt5677_set_dsp_vad(codec, true);
+			rt5677_set_dsp_vad(component, true);
 		break;
 
 	default:
@@ -4696,13 +4695,13 @@ static void rt5677_free_gpio(struct i2c_client *i2c)
 }
 #endif
 
-static int rt5677_probe(struct snd_soc_codec *codec)
+static int rt5677_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 	int i;
 
-	rt5677->codec = codec;
+	rt5677->component = component;
 
 	if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) {
 		snd_soc_dapm_add_routes(dapm,
@@ -4714,7 +4713,7 @@ static int rt5677_probe(struct snd_soc_codec *codec)
 			ARRAY_SIZE(rt5677_dmic2_clk_1));
 	}
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
 	regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020);
 	regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00);
@@ -4753,21 +4752,19 @@ static int rt5677_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt5677_remove(struct snd_soc_codec *codec)
+static void rt5677_remove(struct snd_soc_component *component)
 {
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
 	gpiod_set_value_cansleep(rt5677->pow_ldo2, 0);
 	gpiod_set_value_cansleep(rt5677->reset_pin, 1);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5677_suspend(struct snd_soc_codec *codec)
+static int rt5677_suspend(struct snd_soc_component *component)
 {
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	if (!rt5677->dsp_vad_en) {
 		regcache_cache_only(rt5677->regmap, true);
@@ -4780,9 +4777,9 @@ static int rt5677_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int rt5677_resume(struct snd_soc_codec *codec)
+static int rt5677_resume(struct snd_soc_component *component)
 {
-	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
 	if (!rt5677->dsp_vad_en) {
 		rt5677->pll_src = 0;
@@ -4959,21 +4956,21 @@ static struct snd_soc_dai_driver rt5677_dai[] = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5677 = {
-	.probe = rt5677_probe,
-	.remove = rt5677_remove,
-	.suspend = rt5677_suspend,
-	.resume = rt5677_resume,
-	.set_bias_level = rt5677_set_bias_level,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= rt5677_snd_controls,
-		.num_controls		= ARRAY_SIZE(rt5677_snd_controls),
-		.dapm_widgets		= rt5677_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(rt5677_dapm_widgets),
-		.dapm_routes		= rt5677_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(rt5677_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_rt5677 = {
+	.probe			= rt5677_probe,
+	.remove			= rt5677_remove,
+	.suspend		= rt5677_suspend,
+	.resume			= rt5677_resume,
+	.set_bias_level		= rt5677_set_bias_level,
+	.controls		= rt5677_snd_controls,
+	.num_controls		= ARRAY_SIZE(rt5677_snd_controls),
+	.dapm_widgets		= rt5677_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(rt5677_dapm_widgets),
+	.dapm_routes		= rt5677_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(rt5677_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config rt5677_regmap_physical = {
@@ -5262,13 +5259,13 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
 	rt5677_init_gpio(i2c);
 	rt5677_init_irq(i2c);
 
-	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677,
+	return devm_snd_soc_register_component(&i2c->dev,
+				      &soc_component_dev_rt5677,
 				      rt5677_dai, ARRAY_SIZE(rt5677_dai));
 }
 
 static int rt5677_i2c_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&i2c->dev);
 	rt5677_free_irq(i2c);
 	rt5677_free_gpio(i2c);
 
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index 9723997..183d92b 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1790,7 +1790,7 @@ struct rt5677_platform_data {
 };
 
 struct rt5677_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct rt5677_platform_data pdata;
 	struct regmap *regmap, *regmap_physical;
 	const struct firmware *fw1, *fw2;
@@ -1816,7 +1816,7 @@ struct rt5677_priv {
 	bool is_vref_slow;
 };
 
-int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5677_sel_asrc_clk_src(struct snd_soc_component *component,
 		unsigned int filter_mask, unsigned int clk_src);
 
 #endif /* __RT5677_H__ */
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index c5c76ab..7c1d658 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -147,19 +147,19 @@ struct sgtl5000_priv {
 static int mic_bias_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* change mic bias resistor */
-		snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
+		snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
 			SGTL5000_BIAS_R_MASK,
 			sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
+		snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
 				SGTL5000_BIAS_R_MASK, 0);
 		break;
 	}
@@ -174,12 +174,12 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
 static int power_vag_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP;
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+		snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
 			SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
 		msleep(400);
 		break;
@@ -190,9 +190,9 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
 		 * operational to prevent inadvertently starving the
 		 * other one of them.
 		 */
-		if ((snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER) &
+		if ((snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) &
 				mask) != mask) {
-			snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+			snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
 				SGTL5000_VAG_POWERUP, 0);
 			msleep(400);
 		}
@@ -216,17 +216,54 @@ static SOC_ENUM_SINGLE_DECL(adc_enum,
 static const struct snd_kcontrol_new adc_mux =
 SOC_DAPM_ENUM("Capture Mux", adc_enum);
 
-/* input sources for DAC */
-static const char *dac_mux_text[] = {
+/* input sources for headphone */
+static const char *hp_mux_text[] = {
 	"DAC", "LINE_IN"
 };
 
-static SOC_ENUM_SINGLE_DECL(dac_enum,
+static SOC_ENUM_SINGLE_DECL(hp_enum,
 			    SGTL5000_CHIP_ANA_CTRL, 6,
+			    hp_mux_text);
+
+static const struct snd_kcontrol_new hp_mux =
+SOC_DAPM_ENUM("Headphone Mux", hp_enum);
+
+/* input sources for DAC */
+static const char *dac_mux_text[] = {
+	"ADC", "I2S", "Rsvrd", "DAP"
+};
+
+static SOC_ENUM_SINGLE_DECL(dac_enum,
+			    SGTL5000_CHIP_SSS_CTRL, SGTL5000_DAC_SEL_SHIFT,
 			    dac_mux_text);
 
 static const struct snd_kcontrol_new dac_mux =
-SOC_DAPM_ENUM("Headphone Mux", dac_enum);
+SOC_DAPM_ENUM("Digital Input Mux", dac_enum);
+
+/* input sources for DAP */
+static const char *dap_mux_text[] = {
+	"ADC", "I2S"
+};
+
+static SOC_ENUM_SINGLE_DECL(dap_enum,
+			    SGTL5000_CHIP_SSS_CTRL, SGTL5000_DAP_SEL_SHIFT,
+			    dap_mux_text);
+
+static const struct snd_kcontrol_new dap_mux =
+SOC_DAPM_ENUM("DAP Mux", dap_enum);
+
+/* input sources for DAP mix */
+static const char *dapmix_mux_text[] = {
+	"ADC", "I2S"
+};
+
+static SOC_ENUM_SINGLE_DECL(dapmix_enum,
+			    SGTL5000_CHIP_SSS_CTRL, SGTL5000_DAP_MIX_SEL_SHIFT,
+			    dapmix_mux_text);
+
+static const struct snd_kcontrol_new dapmix_mux =
+SOC_DAPM_ENUM("DAP MIX Mux", dapmix_enum);
+
 
 static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
 	SND_SOC_DAPM_INPUT("LINE_IN"),
@@ -243,7 +280,12 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
 	SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0),
 
 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
-	SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
+	SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &hp_mux),
+	SND_SOC_DAPM_MUX("Digital Input Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
+	SND_SOC_DAPM_MUX("DAP Mux", SGTL5000_DAP_CTRL, 0, 0, &dap_mux),
+	SND_SOC_DAPM_MUX("DAP MIX Mux", SGTL5000_DAP_CTRL, 4, 0, &dapmix_mux),
+	SND_SOC_DAPM_MIXER("DAP", SGTL5000_CHIP_DIG_POWER, 4, 0, NULL, 0),
+
 
 	/* aif for i2s input */
 	SND_SOC_DAPM_AIF_IN("AIFIN", "Playback",
@@ -270,7 +312,19 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
 	{"ADC", NULL, "Capture Mux"},		/* adc_mux --> adc */
 	{"AIFOUT", NULL, "ADC"},		/* adc --> i2s_out */
 
-	{"DAC", NULL, "AIFIN"},			/* i2s-->dac,skip audio mux */
+	{"DAP Mux", "ADC", "ADC"},		/* adc --> DAP mux */
+	{"DAP Mux", NULL, "AIFIN"},		/* i2s --> DAP mux */
+	{"DAP", NULL, "DAP Mux"},		/* DAP mux --> dap */
+
+	{"DAP MIX Mux", "ADC", "ADC"},		/* adc --> DAP MIX mux */
+	{"DAP MIX Mux", NULL, "AIFIN"},		/* i2s --> DAP MIX mux */
+	{"DAP", NULL, "DAP MIX Mux"},		/* DAP MIX mux --> dap */
+
+	{"Digital Input Mux", "ADC", "ADC"},	/* adc --> audio mux */
+	{"Digital Input Mux", NULL, "AIFIN"},	/* i2s --> audio mux */
+	{"Digital Input Mux", NULL, "DAP"},	/* dap --> audio mux */
+	{"DAC", NULL, "Digital Input Mux"},	/* audio mux --> dac */
+
 	{"Headphone Mux", "DAC", "DAC"},	/* dac --> hp_mux */
 	{"LO", NULL, "DAC"},			/* dac --> line_out */
 
@@ -318,12 +372,12 @@ static int dac_info_volsw(struct snd_kcontrol *kcontrol,
 static int dac_get_volsw(struct snd_kcontrol *kcontrol,
 			 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int reg;
 	int l;
 	int r;
 
-	reg = snd_soc_read(codec, SGTL5000_CHIP_DAC_VOL);
+	reg = snd_soc_component_read32(component, SGTL5000_CHIP_DAC_VOL);
 
 	/* get left channel volume */
 	l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
@@ -371,7 +425,7 @@ static int dac_get_volsw(struct snd_kcontrol *kcontrol,
 static int dac_put_volsw(struct snd_kcontrol *kcontrol,
 			 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int reg;
 	int l;
 	int r;
@@ -391,7 +445,7 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol,
 	reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT |
 		r << SGTL5000_DAC_VOL_RIGHT_SHIFT;
 
-	snd_soc_write(codec, SGTL5000_CHIP_DAC_VOL, reg);
+	snd_soc_component_write(component, SGTL5000_CHIP_DAC_VOL, reg);
 
 	return 0;
 }
@@ -409,9 +463,9 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol,
 static int avc_get_threshold(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int db, i;
-	u16 reg = snd_soc_read(codec, SGTL5000_DAP_AVC_THRESHOLD);
+	u16 reg = snd_soc_component_read32(component, SGTL5000_DAP_AVC_THRESHOLD);
 
 	/* register value 0 => -96dB */
 	if (!reg) {
@@ -442,7 +496,7 @@ static int avc_get_threshold(struct snd_kcontrol *kcontrol,
 static int avc_put_threshold(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int db;
 	u16 reg;
 
@@ -450,7 +504,7 @@ static int avc_put_threshold(struct snd_kcontrol *kcontrol,
 	if (db < 0 || db > 96)
 		return -EINVAL;
 	reg = avc_thr_db2reg[db];
-	snd_soc_write(codec, SGTL5000_DAP_AVC_THRESHOLD, reg);
+	snd_soc_component_write(component, SGTL5000_DAP_AVC_THRESHOLD, reg);
 
 	return 0;
 }
@@ -463,6 +517,12 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
 	1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0)
 );
 
+/* tlv for DAP channels, 0% - 100% - 200% */
+static const DECLARE_TLV_DB_SCALE(dap_volume, 0, 1, 0);
+
+/* tlv for bass bands, -11.75db to 12.0db, step .25db */
+static const DECLARE_TLV_DB_SCALE(bass_band, -1175, 25, 0);
+
 /* tlv for hp volume, -51.5db to 12.0db, step .5db */
 static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
 
@@ -514,6 +574,11 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
 			lineout_volume),
 	SOC_SINGLE("Lineout Playback Switch", SGTL5000_CHIP_ANA_CTRL, 8, 1, 1),
 
+	SOC_SINGLE_TLV("DAP Main channel", SGTL5000_DAP_MAIN_CHAN,
+	0, 0xffff, 0, dap_volume),
+
+	SOC_SINGLE_TLV("DAP Mix channel", SGTL5000_DAP_MIX_CHAN,
+	0, 0xffff, 0, dap_volume),
 	/* Automatic Volume Control (DAP AVC) */
 	SOC_SINGLE("AVC Switch", SGTL5000_DAP_AVC_CTRL, 0, 1, 0),
 	SOC_SINGLE("AVC Hard Limiter Switch", SGTL5000_DAP_AVC_CTRL, 5, 1, 0),
@@ -523,12 +588,27 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
 	SOC_SINGLE_EXT_TLV("AVC Threshold Volume", SGTL5000_DAP_AVC_THRESHOLD,
 			0, 96, 0, avc_get_threshold, avc_put_threshold,
 			avc_threshold),
+
+	SOC_SINGLE_TLV("BASS 0", SGTL5000_DAP_EQ_BASS_BAND0,
+	0, 0x5F, 0, bass_band),
+
+	SOC_SINGLE_TLV("BASS 1", SGTL5000_DAP_EQ_BASS_BAND1,
+	0, 0x5F, 0, bass_band),
+
+	SOC_SINGLE_TLV("BASS 2", SGTL5000_DAP_EQ_BASS_BAND2,
+	0, 0x5F, 0, bass_band),
+
+	SOC_SINGLE_TLV("BASS 3", SGTL5000_DAP_EQ_BASS_BAND3,
+	0, 0x5F, 0, bass_band),
+
+	SOC_SINGLE_TLV("BASS 4", SGTL5000_DAP_EQ_BASS_BAND4,
+	0, 0x5F, 0, bass_band),
 };
 
 /* mute the codec used by alsa core */
 static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 i2s_pwr = SGTL5000_I2S_IN_POWERUP;
 
 	/*
@@ -536,7 +616,7 @@ static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 	 * because LINE_IN would be muted aswell. We want to mute
 	 * only I2S block - this can be done by powering it off
 	 */
-	snd_soc_update_bits(codec, SGTL5000_CHIP_DIG_POWER,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_DIG_POWER,
 			i2s_pwr, mute ? 0 : i2s_pwr);
 
 	return 0;
@@ -545,8 +625,8 @@ static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 /* set codec format */
 static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 	u16 i2sctl = 0;
 
 	sgtl5000->master = 0;
@@ -604,7 +684,7 @@ static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, SGTL5000_CHIP_I2S_CTRL, i2sctl);
+	snd_soc_component_write(component, SGTL5000_CHIP_I2S_CTRL, i2sctl);
 
 	return 0;
 }
@@ -613,8 +693,8 @@ static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				   int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case SGTL5000_SYSCLK:
@@ -640,9 +720,9 @@ static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  * and above.
  * 3. usage of sys_mclk is preferred over pll to save power.
  */
-static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
+static int sgtl5000_set_clock(struct snd_soc_component *component, int frame_rate)
 {
-	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+	struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 	int clk_ctl = 0;
 	int sys_fs;	/* sample freq */
 
@@ -695,7 +775,7 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
 		clk_ctl |= SGTL5000_SYS_FS_96k << SGTL5000_SYS_FS_SHIFT;
 		break;
 	default:
-		dev_err(codec->dev, "frame rate %d not supported\n",
+		dev_err(component->dev, "frame rate %d not supported\n",
 			frame_rate);
 		return -EINVAL;
 	}
@@ -724,9 +804,9 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
 			clk_ctl |= SGTL5000_MCLK_FREQ_PLL <<
 				SGTL5000_MCLK_FREQ_SHIFT;
 		} else {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"PLL not supported in slave mode\n");
-			dev_err(codec->dev, "%d ratio is not supported. "
+			dev_err(component->dev, "%d ratio is not supported. "
 				"SYS_MCLK needs to be 256, 384 or 512 * fs\n",
 				sgtl5000->sysclk / frame_rate);
 			return -EINVAL;
@@ -759,31 +839,31 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
 		pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT |
 		    frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT;
 
-		snd_soc_write(codec, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
+		snd_soc_component_write(component, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
 		if (div2)
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 				SGTL5000_CHIP_CLK_TOP_CTRL,
 				SGTL5000_INPUT_FREQ_DIV2,
 				SGTL5000_INPUT_FREQ_DIV2);
 		else
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 				SGTL5000_CHIP_CLK_TOP_CTRL,
 				SGTL5000_INPUT_FREQ_DIV2,
 				0);
 
 		/* power up pll */
-		snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+		snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
 			SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
 			SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
 
 		/* if using pll, clk_ctrl must be set after pll power up */
-		snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
+		snd_soc_component_write(component, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
 	} else {
 		/* otherwise, clk_ctrl must be set before pll power down */
-		snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
+		snd_soc_component_write(component, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
 
 		/* power down pll */
-		snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+		snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
 			SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
 			0);
 	}
@@ -799,8 +879,8 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
 				  struct snd_pcm_hw_params *params,
 				  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 	int channels = params_channels(params);
 	int i2s_ctl = 0;
 	int stereo;
@@ -808,7 +888,7 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
 
 	/* sysclk should already set */
 	if (!sgtl5000->sysclk) {
-		dev_err(codec->dev, "%s: set sysclk first!\n", __func__);
+		dev_err(component->dev, "%s: set sysclk first!\n", __func__);
 		return -EFAULT;
 	}
 
@@ -818,11 +898,11 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
 		stereo = SGTL5000_ADC_STEREO;
 
 	/* set mono to save power */
-	snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, stereo,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, stereo,
 			channels == 1 ? 0 : stereo);
 
 	/* set codec clock base on lrclk */
-	ret = sgtl5000_set_clock(codec, params_rate(params));
+	ret = sgtl5000_set_clock(component, params_rate(params));
 	if (ret)
 		return ret;
 
@@ -856,7 +936,7 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_I2S_CTRL,
 			    SGTL5000_I2S_DLEN_MASK | SGTL5000_I2S_SCLKFREQ_MASK,
 			    i2s_ctl);
 
@@ -873,10 +953,10 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
  * stop:
  * on --> prepare --> standby
  */
-static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
+static int sgtl5000_set_bias_level(struct snd_soc_component *component,
 				   enum snd_soc_bias_level level)
 {
-	struct sgtl5000_priv *sgtl = snd_soc_codec_get_drvdata(codec);
+	struct sgtl5000_priv *sgtl = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -890,13 +970,13 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
 			return ret;
 		}
 
-		snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+		snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
 				    SGTL5000_REFTOP_POWERUP,
 				    SGTL5000_REFTOP_POWERUP);
 		break;
 	case SND_SOC_BIAS_OFF:
 		regcache_cache_only(sgtl->regmap, true);
-		snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+		snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
 				    SGTL5000_REFTOP_POWERUP, 0);
 		break;
 	}
@@ -1036,7 +1116,7 @@ static const u8 vol_quot_table[] = {
  * 1. vddd provided by external or not
  * 2. vdda and vddio voltage value. > 3.1v or not
  */
-static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
+static int sgtl5000_set_power_regs(struct snd_soc_component *component)
 {
 	int vddd;
 	int vdda;
@@ -1048,7 +1128,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 	int vol_quot;
 	int lo_vol;
 	size_t i;
-	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+	struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 
 	vdda  = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
 	vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer);
@@ -1061,14 +1141,14 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 	vddd  = vddd / 1000;
 
 	if (vdda <= 0 || vddio <= 0 || vddd < 0) {
-		dev_err(codec->dev, "regulator voltage not set correctly\n");
+		dev_err(component->dev, "regulator voltage not set correctly\n");
 
 		return -EINVAL;
 	}
 
 	/* according to datasheet, maximum voltage of supplies */
 	if (vdda > 3600 || vddio > 3600 || vddd > 1980) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"exceed max voltage vdda %dmV vddio %dmV vddd %dmV\n",
 			vdda, vddio, vddd);
 
@@ -1076,15 +1156,15 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 	}
 
 	/* reset value */
-	ana_pwr = snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER);
+	ana_pwr = snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER);
 	ana_pwr |= SGTL5000_DAC_STEREO |
 			SGTL5000_ADC_STEREO |
 			SGTL5000_REFTOP_POWERUP;
-	lreg_ctrl = snd_soc_read(codec, SGTL5000_CHIP_LINREG_CTRL);
+	lreg_ctrl = snd_soc_component_read32(component, SGTL5000_CHIP_LINREG_CTRL);
 
 	if (vddio < 3100 && vdda < 3100) {
 		/* enable internal oscillator used for charge pump */
-		snd_soc_update_bits(codec, SGTL5000_CHIP_CLK_TOP_CTRL,
+		snd_soc_component_update_bits(component, SGTL5000_CHIP_CLK_TOP_CTRL,
 					SGTL5000_INT_OSC_EN,
 					SGTL5000_INT_OSC_EN);
 		/* Enable VDDC charge pump */
@@ -1097,9 +1177,9 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 			    SGTL5000_VDDC_MAN_ASSN_SHIFT;
 	}
 
-	snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
+	snd_soc_component_write(component, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
 
-	snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr);
+	snd_soc_component_write(component, SGTL5000_CHIP_ANA_POWER, ana_pwr);
 
 	/*
 	 * set ADC/DAC VAG to vdda / 2,
@@ -1114,7 +1194,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 	else
 		vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
 
-	snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL,
 			SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT);
 
 	/* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
@@ -1128,7 +1208,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 		lo_vag = (lo_vag - SGTL5000_LINE_OUT_GND_BASE) /
 		    SGTL5000_LINE_OUT_GND_STP;
 
-	snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_LINE_OUT_CTRL,
 			SGTL5000_LINE_OUT_CURRENT_MASK |
 			SGTL5000_LINE_OUT_GND_MASK,
 			lo_vag << SGTL5000_LINE_OUT_GND_SHIFT |
@@ -1151,7 +1231,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 			break;
 	}
 
-	snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_VOL,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_LINE_OUT_VOL,
 		SGTL5000_LINE_OUT_VOL_RIGHT_MASK |
 		SGTL5000_LINE_OUT_VOL_LEFT_MASK,
 		lo_vol << SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT |
@@ -1199,62 +1279,56 @@ static int sgtl5000_enable_regulators(struct i2c_client *client)
 	return ret;
 }
 
-static int sgtl5000_probe(struct snd_soc_codec *codec)
+static int sgtl5000_probe(struct snd_soc_component *component)
 {
 	int ret;
 	u16 reg;
-	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+	struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 
 	/* power up sgtl5000 */
-	ret = sgtl5000_set_power_regs(codec);
+	ret = sgtl5000_set_power_regs(component);
 	if (ret)
 		goto err;
 
 	/* enable small pop, introduce 400ms delay in turning off */
-	snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL,
 				SGTL5000_SMALL_POP, 1);
 
 	/* disable short cut detector */
-	snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
+	snd_soc_component_write(component, SGTL5000_CHIP_SHORT_CTRL, 0);
 
-	/*
-	 * set i2s as default input of sound switch
-	 * TODO: add sound switch to control and dapm widge.
-	 */
-	snd_soc_write(codec, SGTL5000_CHIP_SSS_CTRL,
-			SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT);
-	snd_soc_write(codec, SGTL5000_CHIP_DIG_POWER,
+	snd_soc_component_write(component, SGTL5000_CHIP_DIG_POWER,
 			SGTL5000_ADC_EN | SGTL5000_DAC_EN);
 
 	/* enable dac volume ramp by default */
-	snd_soc_write(codec, SGTL5000_CHIP_ADCDAC_CTRL,
+	snd_soc_component_write(component, SGTL5000_CHIP_ADCDAC_CTRL,
 			SGTL5000_DAC_VOL_RAMP_EN |
 			SGTL5000_DAC_MUTE_RIGHT |
 			SGTL5000_DAC_MUTE_LEFT);
 
 	reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | 0x5f);
-	snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, reg);
+	snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg);
 
-	snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
+	snd_soc_component_write(component, SGTL5000_CHIP_ANA_CTRL,
 			SGTL5000_HP_ZCD_EN |
 			SGTL5000_ADC_ZCD_EN);
 
-	snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
 			SGTL5000_BIAS_R_MASK,
 			sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
 
-	snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
 			SGTL5000_BIAS_VOLT_MASK,
 			sgtl5000->micbias_voltage << SGTL5000_BIAS_VOLT_SHIFT);
 	/*
-	 * disable DAP
+	 * enable DAP Graphic EQ
 	 * TODO:
-	 * Enable DAP in kcontrol and dapm.
+	 * Add control for changing between PEQ/Tone Control/GEQ
 	 */
-	snd_soc_write(codec, SGTL5000_DAP_CTRL, 0);
+	snd_soc_component_write(component, SGTL5000_DAP_AUDIO_EQ, SGTL5000_DAP_SEL_GEQ);
 
 	/* Unmute DAC after start */
-	snd_soc_update_bits(codec, SGTL5000_CHIP_ADCDAC_CTRL,
+	snd_soc_component_update_bits(component, SGTL5000_CHIP_ADCDAC_CTRL,
 		SGTL5000_DAC_MUTE_LEFT | SGTL5000_DAC_MUTE_RIGHT, 0);
 
 	return 0;
@@ -1263,24 +1337,20 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int sgtl5000_remove(struct snd_soc_codec *codec)
-{
-	return 0;
-}
-
-static const struct snd_soc_codec_driver sgtl5000_driver = {
-	.probe = sgtl5000_probe,
-	.remove = sgtl5000_remove,
-	.set_bias_level = sgtl5000_set_bias_level,
-	.suspend_bias_off = true,
-	.component_driver = {
-		.controls		= sgtl5000_snd_controls,
-		.num_controls		= ARRAY_SIZE(sgtl5000_snd_controls),
-		.dapm_widgets		= sgtl5000_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(sgtl5000_dapm_widgets),
-		.dapm_routes		= sgtl5000_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(sgtl5000_dapm_routes),
-	},
+static const struct snd_soc_component_driver sgtl5000_driver = {
+	.probe			= sgtl5000_probe,
+	.set_bias_level		= sgtl5000_set_bias_level,
+	.controls		= sgtl5000_snd_controls,
+	.num_controls		= ARRAY_SIZE(sgtl5000_snd_controls),
+	.dapm_widgets		= sgtl5000_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sgtl5000_dapm_widgets),
+	.dapm_routes		= sgtl5000_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sgtl5000_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config sgtl5000_regmap = {
@@ -1479,7 +1549,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
 	/* Ensure sgtl5000 will start with sane register values */
 	sgtl5000_fill_defaults(client);
 
-	ret = snd_soc_register_codec(&client->dev,
+	ret = devm_snd_soc_register_component(&client->dev,
 			&sgtl5000_driver, &sgtl5000_dai, 1);
 	if (ret)
 		goto disable_clk;
@@ -1500,7 +1570,6 @@ static int sgtl5000_i2c_remove(struct i2c_client *client)
 {
 	struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
 	clk_disable_unprepare(sgtl5000->mclk);
 	regulator_bulk_disable(sgtl5000->num_supplies, sgtl5000->supplies);
 	regulator_bulk_free(sgtl5000->num_supplies, sgtl5000->supplies);
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index 22f3442..28cf637 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -399,4 +399,11 @@
 #define SGTL5000_SYSCLK				0x00
 #define SGTL5000_LRCLK				0x01
 
+/*
+ * SGTL5000_DAP_AUDIO_EQ
+ */
+#define SGTL5000_DAP_SEL_PEQ			1
+#define SGTL5000_DAP_SEL_TONE_CTRL		2
+#define SGTL5000_DAP_SEL_GEQ			3
+
 #endif
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index 7b91ee2..b779c28 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -140,14 +140,14 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 	si476x_core_lock(core);
 
-	err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
+	err = snd_soc_component_update_bits(codec_dai->component, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
 				  SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK,
 				  format);
 
 	si476x_core_unlock(core);
 
 	if (err < 0) {
-		dev_err(codec_dai->codec->dev, "Failed to set output format\n");
+		dev_err(codec_dai->component->dev, "Failed to set output format\n");
 		return err;
 	}
 
@@ -163,7 +163,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
 
 	rate = params_rate(params);
 	if (rate < 32000 || rate > 48000) {
-		dev_err(dai->codec->dev, "Rate: %d is not supported\n", rate);
+		dev_err(dai->component->dev, "Rate: %d is not supported\n", rate);
 		return -EINVAL;
 	}
 
@@ -186,19 +186,19 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
 
 	si476x_core_lock(core);
 
-	err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
+	err = snd_soc_component_write(dai->component, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
 			    rate);
 	if (err < 0) {
-		dev_err(dai->codec->dev, "Failed to set sample rate\n");
+		dev_err(dai->component->dev, "Failed to set sample rate\n");
 		goto out;
 	}
 
-	err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
+	err = snd_soc_component_update_bits(dai->component, 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");
+		dev_err(dai->component->dev, "Failed to set output width\n");
 		goto out;
 	}
 
@@ -239,28 +239,25 @@ static int si476x_probe(struct snd_soc_component *component)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_si476x = {
-	.component_driver = {
-		.probe			= si476x_probe,
-		.dapm_widgets		= si476x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(si476x_dapm_widgets),
-		.dapm_routes		= si476x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(si476x_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_si476x = {
+	.probe			= si476x_probe,
+	.dapm_widgets		= si476x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(si476x_dapm_widgets),
+	.dapm_routes		= si476x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(si476x_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int si476x_platform_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si476x,
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &soc_component_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 = {
@@ -268,7 +265,6 @@ static struct platform_driver si476x_platform_driver = {
 		.name	= "si476x-codec",
 	},
 	.probe		= si476x_platform_probe,
-	.remove		= si476x_platform_remove,
 };
 module_platform_driver(si476x_platform_driver);
 
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c
index 7ae8c18..e424499 100644
--- a/sound/soc/codecs/sirf-audio-codec.c
+++ b/sound/soc/codecs/sirf-audio-codec.c
@@ -120,8 +120,8 @@ static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,
 {
 #define ATLAS6_CODEC_ENABLE_BITS (1 << 29)
 #define ATLAS6_CODEC_RESET_BITS (1 << 28)
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		enable_and_reset_codec(sirf_audio_codec->regmap,
@@ -143,8 +143,8 @@ static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,
 {
 #define PRIMA2_CODEC_ENABLE_BITS (1 << 27)
 #define PRIMA2_CODEC_RESET_BITS (1 << 26)
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		enable_and_reset_codec(sirf_audio_codec->regmap,
@@ -333,8 +333,8 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
 		int cmd,
 		struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
 	int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
 	/*
@@ -346,7 +346,7 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		if (playback) {
-			snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
+			snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0,
 				IC_HSLEN | IC_HSREN, 0);
 			sirf_audio_codec_tx_disable(sirf_audio_codec);
 		} else
@@ -357,7 +357,7 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		if (playback) {
 			sirf_audio_codec_tx_enable(sirf_audio_codec);
-			snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
+			snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0,
 				IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN);
 		} else
 			sirf_audio_codec_rx_enable(sirf_audio_codec,
@@ -393,29 +393,29 @@ static struct snd_soc_dai_driver sirf_audio_codec_dai = {
 	.ops = &sirf_audio_codec_dai_ops,
 };
 
-static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
+static int sirf_audio_codec_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-	pm_runtime_enable(codec->dev);
+	pm_runtime_enable(component->dev);
 
-	if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) {
+	if (of_device_is_compatible(component->dev->of_node, "sirf,prima2-audio-codec")) {
 		snd_soc_dapm_new_controls(dapm,
 			prima2_output_driver_dapm_widgets,
 			ARRAY_SIZE(prima2_output_driver_dapm_widgets));
 		snd_soc_dapm_new_controls(dapm,
 			&prima2_codec_clock_dapm_widget, 1);
-		return snd_soc_add_codec_controls(codec,
+		return snd_soc_add_component_controls(component,
 			volume_controls_prima2,
 			ARRAY_SIZE(volume_controls_prima2));
 	}
-	if (of_device_is_compatible(codec->dev->of_node, "sirf,atlas6-audio-codec")) {
+	if (of_device_is_compatible(component->dev->of_node, "sirf,atlas6-audio-codec")) {
 		snd_soc_dapm_new_controls(dapm,
 			atlas6_output_driver_dapm_widgets,
 			ARRAY_SIZE(atlas6_output_driver_dapm_widgets));
 		snd_soc_dapm_new_controls(dapm,
 			&atlas6_codec_clock_dapm_widget, 1);
-		return snd_soc_add_codec_controls(codec,
+		return snd_soc_add_component_controls(component,
 			volume_controls_atlas6,
 			ARRAY_SIZE(volume_controls_atlas6));
 	}
@@ -423,22 +423,21 @@ static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
 	return -EINVAL;
 }
 
-static int sirf_audio_codec_remove(struct snd_soc_codec *codec)
+static void sirf_audio_codec_remove(struct snd_soc_component *component)
 {
-	pm_runtime_disable(codec->dev);
-	return 0;
+	pm_runtime_disable(component->dev);
 }
 
-static const struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = {
-	.probe = sirf_audio_codec_probe,
-	.remove = sirf_audio_codec_remove,
-	.component_driver = {
-		.dapm_widgets = sirf_audio_codec_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets),
-		.dapm_routes = sirf_audio_codec_map,
-		.num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map),
-	},
-	.idle_bias_off = true,
+static const struct snd_soc_component_driver soc_codec_device_sirf_audio_codec = {
+	.probe			= sirf_audio_codec_probe,
+	.remove			= sirf_audio_codec_remove,
+	.dapm_widgets		= sirf_audio_codec_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sirf_audio_codec_dapm_widgets),
+	.dapm_routes		= sirf_audio_codec_map,
+	.num_dapm_routes	= ARRAY_SIZE(sirf_audio_codec_map),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id sirf_audio_codec_of_match[] = {
@@ -495,7 +494,7 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&(pdev->dev),
+	ret = devm_snd_soc_register_component(&(pdev->dev),
 			&soc_codec_device_sirf_audio_codec,
 			&sirf_audio_codec_dai, 1);
 	if (ret) {
@@ -525,7 +524,6 @@ static int sirf_audio_codec_driver_remove(struct platform_device *pdev)
 	struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev);
 
 	clk_disable_unprepare(sirf_audio_codec->clk);
-	snd_soc_unregister_codec(&(pdev->dev));
 
 	return 0;
 }
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c
index c8fd636..ac69d49 100644
--- a/sound/soc/codecs/spdif_receiver.c
+++ b/sound/soc/codecs/spdif_receiver.c
@@ -38,13 +38,15 @@ static const struct snd_soc_dapm_route dir_routes[] = {
 			SNDRV_PCM_FMTBIT_S32_LE | \
 			SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
 
-static struct snd_soc_codec_driver soc_codec_spdif_dir = {
-	.component_driver = {
-		.dapm_widgets		= dir_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(dir_widgets),
-		.dapm_routes		= dir_routes,
-		.num_dapm_routes	= ARRAY_SIZE(dir_routes),
-	},
+static struct snd_soc_component_driver soc_codec_spdif_dir = {
+	.dapm_widgets		= dir_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(dir_widgets),
+	.dapm_routes		= dir_routes,
+	.num_dapm_routes	= ARRAY_SIZE(dir_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static struct snd_soc_dai_driver dir_stub_dai = {
@@ -60,16 +62,11 @@ static struct snd_soc_dai_driver dir_stub_dai = {
 
 static int spdif_dir_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dir,
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_codec_spdif_dir,
 			&dir_stub_dai, 1);
 }
 
-static int spdif_dir_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id spdif_dir_dt_ids[] = {
 	{ .compatible = "linux,spdif-dir", },
@@ -80,7 +77,6 @@ MODULE_DEVICE_TABLE(of, spdif_dir_dt_ids);
 
 static struct platform_driver spdif_dir_driver = {
 	.probe		= spdif_dir_probe,
-	.remove		= spdif_dir_remove,
 	.driver		= {
 		.name	= "spdif-dir",
 		.of_match_table = of_match_ptr(spdif_dir_dt_ids),
diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c
index 037aa1d..b4f7fc4 100644
--- a/sound/soc/codecs/spdif_transmitter.c
+++ b/sound/soc/codecs/spdif_transmitter.c
@@ -38,13 +38,15 @@ static const struct snd_soc_dapm_route dit_routes[] = {
 	{ "spdif-out", NULL, "Playback" },
 };
 
-static struct snd_soc_codec_driver soc_codec_spdif_dit = {
-	.component_driver = {
-		.dapm_widgets		= dit_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(dit_widgets),
-		.dapm_routes		= dit_routes,
-		.num_dapm_routes	= ARRAY_SIZE(dit_routes),
-	},
+static struct snd_soc_component_driver soc_codec_spdif_dit = {
+	.dapm_widgets		= dit_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(dit_widgets),
+	.dapm_routes		= dit_routes,
+	.num_dapm_routes	= ARRAY_SIZE(dit_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static struct snd_soc_dai_driver dit_stub_dai = {
@@ -60,16 +62,11 @@ static struct snd_soc_dai_driver dit_stub_dai = {
 
 static int spdif_dit_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dit,
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_codec_spdif_dit,
 			&dit_stub_dai, 1);
 }
 
-static int spdif_dit_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id spdif_dit_dt_ids[] = {
 	{ .compatible = "linux,spdif-dit", },
@@ -80,7 +77,6 @@ MODULE_DEVICE_TABLE(of, spdif_dit_dt_ids);
 
 static struct platform_driver spdif_dit_driver = {
 	.probe		= spdif_dit_probe,
-	.remove		= spdif_dit_remove,
 	.driver		= {
 		.name	= DRV_NAME,
 		.of_match_table = of_match_ptr(spdif_dit_dt_ids),
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index 15486fd1..4a1d42a 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -336,8 +336,8 @@ static int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
 static int ssm2518_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
 	unsigned int rate = params_rate(params);
 	unsigned int ctrl1, ctrl1_mask;
 	int mcs;
@@ -391,7 +391,7 @@ static int ssm2518_hw_params(struct snd_pcm_substream *substream,
 
 static int ssm2518_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 	unsigned int val;
 
 	if (mute)
@@ -405,7 +405,7 @@ static int ssm2518_mute(struct snd_soc_dai *dai, int mute)
 
 static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 	unsigned int ctrl1 = 0, ctrl2 = 0;
 	bool invert_fclk;
 	int ret;
@@ -498,10 +498,10 @@ static int ssm2518_set_power(struct ssm2518 *ssm2518, bool enable)
 	return ret;
 }
 
-static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
+static int ssm2518_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	switch (level) {
@@ -510,7 +510,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			ret = ssm2518_set_power(ssm2518, true);
 		break;
 	case SND_SOC_BIAS_OFF:
@@ -524,7 +524,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
 static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	unsigned int rx_mask, int slots, int width)
 {
-	struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 	unsigned int ctrl1, ctrl2;
 	int left_slot, right_slot;
 	int ret;
@@ -609,7 +609,7 @@ static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int ssm2518_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
-	struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 
 	if (ssm2518->constraints)
 		snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -641,10 +641,10 @@ static struct snd_soc_dai_driver ssm2518_dai = {
 	.ops = &ssm2518_dai_ops,
 };
 
-static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int ssm2518_set_sysclk(struct snd_soc_component *component, int clk_id,
 	int source, unsigned int freq, int dir)
 {
-	struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 
 	if (clk_id != SSM2518_SYSCLK)
@@ -710,19 +710,18 @@ static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 			SSM2518_POWER1_NO_BCLK, val);
 }
 
-static const struct snd_soc_codec_driver ssm2518_codec_driver = {
-	.set_bias_level = ssm2518_set_bias_level,
-	.set_sysclk = ssm2518_set_sysclk,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= ssm2518_snd_controls,
-		.num_controls		= ARRAY_SIZE(ssm2518_snd_controls),
-		.dapm_widgets		= ssm2518_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ssm2518_dapm_widgets),
-		.dapm_routes		= ssm2518_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ssm2518_routes),
-	},
+static const struct snd_soc_component_driver ssm2518_component_driver = {
+	.set_bias_level		= ssm2518_set_bias_level,
+	.set_sysclk		= ssm2518_set_sysclk,
+	.controls		= ssm2518_snd_controls,
+	.num_controls		= ARRAY_SIZE(ssm2518_snd_controls),
+	.dapm_widgets		= ssm2518_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ssm2518_dapm_widgets),
+	.dapm_routes		= ssm2518_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ssm2518_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config ssm2518_regmap_config = {
@@ -792,16 +791,11 @@ static int ssm2518_i2c_probe(struct i2c_client *i2c,
 	if (ret)
 		return ret;
 
-	return snd_soc_register_codec(&i2c->dev, &ssm2518_codec_driver,
+	return devm_snd_soc_register_component(&i2c->dev,
+			&ssm2518_component_driver,
 			&ssm2518_dai, 1);
 }
 
-static int ssm2518_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id ssm2518_dt_ids[] = {
 	{ .compatible = "adi,ssm2518", },
@@ -822,7 +816,6 @@ static struct i2c_driver ssm2518_driver = {
 		.of_match_table = of_match_ptr(ssm2518_dt_ids),
 	},
 	.probe = ssm2518_i2c_probe,
-	.remove = ssm2518_i2c_remove,
 	.id_table = ssm2518_i2c_ids,
 };
 module_i2c_driver(ssm2518_driver);
diff --git a/sound/soc/codecs/ssm2602-i2c.c b/sound/soc/codecs/ssm2602-i2c.c
index 173ba85..f1c2b1a 100644
--- a/sound/soc/codecs/ssm2602-i2c.c
+++ b/sound/soc/codecs/ssm2602-i2c.c
@@ -27,12 +27,6 @@ static int ssm2602_i2c_probe(struct i2c_client *client,
 		devm_regmap_init_i2c(client, &ssm2602_regmap_config));
 }
 
-static int ssm2602_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id ssm2602_i2c_id[] = {
 	{ "ssm2602", SSM2602 },
 	{ "ssm2603", SSM2602 },
@@ -55,7 +49,6 @@ static struct i2c_driver ssm2602_i2c_driver = {
 		.of_match_table = ssm2602_of_match,
 	},
 	.probe = ssm2602_i2c_probe,
-	.remove = ssm2602_i2c_remove,
 	.id_table = ssm2602_i2c_id,
 };
 module_i2c_driver(ssm2602_i2c_driver);
diff --git a/sound/soc/codecs/ssm2602-spi.c b/sound/soc/codecs/ssm2602-spi.c
index 842f373..8848628 100644
--- a/sound/soc/codecs/ssm2602-spi.c
+++ b/sound/soc/codecs/ssm2602-spi.c
@@ -20,12 +20,6 @@ static int ssm2602_spi_probe(struct spi_device *spi)
 		devm_regmap_init_spi(spi, &ssm2602_regmap_config));
 }
 
-static int ssm2602_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static const struct of_device_id ssm2602_of_match[] = {
 	{ .compatible = "adi,ssm2602", },
 	{ }
@@ -38,7 +32,6 @@ static struct spi_driver ssm2602_spi_driver = {
 		.of_match_table = ssm2602_of_match,
 	},
 	.probe		= ssm2602_spi_probe,
-	.remove		= ssm2602_spi_remove,
 };
 module_spi_driver(ssm2602_spi_driver);
 
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 9b341c2..501a4e7 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -54,10 +54,17 @@ struct ssm2602_priv {
  * using 2 wire for device control, so we cache them instead.
  * There is no point in caching the reset register
  */
-static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
-	0x0097, 0x0097, 0x0079, 0x0079,
-	0x000a, 0x0008, 0x009f, 0x000a,
-	0x0000, 0x0000
+static const struct reg_default ssm2602_reg[SSM2602_CACHEREGNUM] = {
+	{ .reg = 0x00, .def = 0x0097 },
+	{ .reg = 0x01, .def = 0x0097 },
+	{ .reg = 0x02, .def = 0x0079 },
+	{ .reg = 0x03, .def = 0x0079 },
+	{ .reg = 0x04, .def = 0x000a },
+	{ .reg = 0x05, .def = 0x0008 },
+	{ .reg = 0x06, .def = 0x009f },
+	{ .reg = 0x07, .def = 0x000a },
+	{ .reg = 0x08, .def = 0x0000 },
+	{ .reg = 0x09, .def = 0x0000 }
 };
 
 
@@ -273,8 +280,8 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 	int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params));
 	unsigned int iface;
 
@@ -308,8 +315,8 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
 static int ssm2602_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 
 	if (ssm2602->sysclk_constraints) {
 		snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -322,7 +329,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
 
 static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(dai->codec);
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(dai->component);
 
 	if (mute)
 		regmap_update_bits(ssm2602->regmap, SSM2602_APDIGI,
@@ -337,8 +344,8 @@ static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
 static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 
 	if (dir == SND_SOC_CLOCK_IN) {
 		if (clk_id != SSM2602_SYSCLK)
@@ -389,7 +396,7 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec_dai->codec);
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(codec_dai->component);
 	unsigned int iface = 0;
 
 	/* set master/slave audio interface */
@@ -445,10 +452,10 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
+static int ssm2602_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -511,19 +518,19 @@ static struct snd_soc_dai_driver ssm2602_dai = {
 	.symmetric_samplebits = 1,
 };
 
-static int ssm2602_resume(struct snd_soc_codec *codec)
+static int ssm2602_resume(struct snd_soc_component *component)
 {
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 
 	regcache_sync(ssm2602->regmap);
 
 	return 0;
 }
 
-static int ssm2602_codec_probe(struct snd_soc_codec *codec)
+static int ssm2602_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	regmap_update_bits(ssm2602->regmap, SSM2602_LOUT1V,
@@ -531,7 +538,7 @@ static int ssm2602_codec_probe(struct snd_soc_codec *codec)
 	regmap_update_bits(ssm2602->regmap, SSM2602_ROUT1V,
 			    ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
 
-	ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls,
+	ret = snd_soc_add_component_controls(component, ssm2602_snd_controls,
 			ARRAY_SIZE(ssm2602_snd_controls));
 	if (ret)
 		return ret;
@@ -545,9 +552,9 @@ static int ssm2602_codec_probe(struct snd_soc_codec *codec)
 			ARRAY_SIZE(ssm2602_routes));
 }
 
-static int ssm2604_codec_probe(struct snd_soc_codec *codec)
+static int ssm2604_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int ret;
 
 	ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets,
@@ -559,14 +566,14 @@ static int ssm2604_codec_probe(struct snd_soc_codec *codec)
 			ARRAY_SIZE(ssm2604_routes));
 }
 
-static int ssm260x_codec_probe(struct snd_soc_codec *codec)
+static int ssm260x_component_probe(struct snd_soc_component *component)
 {
-	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+	struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regmap_write(ssm2602->regmap, SSM2602_RESET, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+		dev_err(component->dev, "Failed to issue reset: %d\n", ret);
 		return ret;
 	}
 
@@ -581,30 +588,31 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec)
 
 	switch (ssm2602->type) {
 	case SSM2602:
-		ret = ssm2602_codec_probe(codec);
+		ret = ssm2602_component_probe(component);
 		break;
 	case SSM2604:
-		ret = ssm2604_codec_probe(codec);
+		ret = ssm2604_component_probe(component);
 		break;
 	}
 
 	return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
-	.probe =	ssm260x_codec_probe,
-	.resume =	ssm2602_resume,
-	.set_bias_level = ssm2602_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= ssm260x_snd_controls,
-		.num_controls		= ARRAY_SIZE(ssm260x_snd_controls),
-		.dapm_widgets		= ssm260x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ssm260x_dapm_widgets),
-		.dapm_routes		= ssm260x_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ssm260x_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_ssm2602 = {
+	.probe			= ssm260x_component_probe,
+	.resume			= ssm2602_resume,
+	.set_bias_level		= ssm2602_set_bias_level,
+	.controls		= ssm260x_snd_controls,
+	.num_controls		= ARRAY_SIZE(ssm260x_snd_controls),
+	.dapm_widgets		= ssm260x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ssm260x_dapm_widgets),
+	.dapm_routes		= ssm260x_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ssm260x_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static bool ssm2602_register_volatile(struct device *dev, unsigned int reg)
@@ -620,8 +628,8 @@ const struct regmap_config ssm2602_regmap_config = {
 	.volatile_reg = ssm2602_register_volatile,
 
 	.cache_type = REGCACHE_RBTREE,
-	.reg_defaults_raw = ssm2602_reg,
-	.num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg),
+	.reg_defaults = ssm2602_reg,
+	.num_reg_defaults = ARRAY_SIZE(ssm2602_reg),
 };
 EXPORT_SYMBOL_GPL(ssm2602_regmap_config);
 
@@ -641,7 +649,7 @@ int ssm2602_probe(struct device *dev, enum ssm2602_type type,
 	ssm2602->type = type;
 	ssm2602->regmap = regmap;
 
-	return snd_soc_register_codec(dev, &soc_codec_dev_ssm2602,
+	return devm_snd_soc_register_component(dev, &soc_component_dev_ssm2602,
 		&ssm2602_dai, 1);
 }
 EXPORT_SYMBOL_GPL(ssm2602_probe);
diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c
index 4afedde..90119ea 100644
--- a/sound/soc/codecs/ssm4567.c
+++ b/sound/soc/codecs/ssm4567.c
@@ -199,8 +199,8 @@ static const struct snd_soc_dapm_route ssm4567_routes[] = {
 static int ssm4567_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct ssm4567 *ssm4567 = snd_soc_component_get_drvdata(component);
 	unsigned int rate = params_rate(params);
 	unsigned int dacfs;
 
@@ -223,7 +223,7 @@ static int ssm4567_hw_params(struct snd_pcm_substream *substream,
 
 static int ssm4567_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(dai->codec);
+	struct ssm4567 *ssm4567 = snd_soc_component_get_drvdata(dai->component);
 	unsigned int val;
 
 	val = mute ? SSM4567_DAC_MUTE : 0;
@@ -366,10 +366,10 @@ static int ssm4567_set_power(struct ssm4567 *ssm4567, bool enable)
 	return ret;
 }
 
-static int ssm4567_set_bias_level(struct snd_soc_codec *codec,
+static int ssm4567_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(codec);
+	struct ssm4567 *ssm4567 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	switch (level) {
@@ -378,7 +378,7 @@ static int ssm4567_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			ret = ssm4567_set_power(ssm4567, true);
 		break;
 	case SND_SOC_BIAS_OFF:
@@ -417,18 +417,17 @@ static struct snd_soc_dai_driver ssm4567_dai = {
 	.ops = &ssm4567_dai_ops,
 };
 
-static const struct snd_soc_codec_driver ssm4567_codec_driver = {
-	.set_bias_level = ssm4567_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= ssm4567_snd_controls,
-		.num_controls		= ARRAY_SIZE(ssm4567_snd_controls),
-		.dapm_widgets		= ssm4567_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(ssm4567_dapm_widgets),
-		.dapm_routes		= ssm4567_routes,
-		.num_dapm_routes	= ARRAY_SIZE(ssm4567_routes),
-	},
+static const struct snd_soc_component_driver ssm4567_component_driver = {
+	.set_bias_level		= ssm4567_set_bias_level,
+	.controls		= ssm4567_snd_controls,
+	.num_controls		= ARRAY_SIZE(ssm4567_snd_controls),
+	.dapm_widgets		= ssm4567_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ssm4567_dapm_widgets),
+	.dapm_routes		= ssm4567_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ssm4567_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config ssm4567_regmap_config = {
@@ -469,16 +468,10 @@ static int ssm4567_i2c_probe(struct i2c_client *i2c,
 	if (ret)
 		return ret;
 
-	return snd_soc_register_codec(&i2c->dev, &ssm4567_codec_driver,
+	return devm_snd_soc_register_component(&i2c->dev, &ssm4567_component_driver,
 			&ssm4567_dai, 1);
 }
 
-static int ssm4567_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id ssm4567_i2c_ids[] = {
 	{ "ssm4567", 0 },
 	{ }
@@ -510,7 +503,6 @@ static struct i2c_driver ssm4567_driver = {
 		.acpi_match_table = ACPI_PTR(ssm4567_acpi_match),
 	},
 	.probe = ssm4567_i2c_probe,
-	.remove = ssm4567_i2c_remove,
 	.id_table = ssm4567_i2c_ids,
 };
 module_i2c_driver(ssm4567_driver);
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 5b88847..d5035f2 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -143,7 +143,7 @@ static const char *sta32x_supply_names[] = {
 struct sta32x_priv {
 	struct regmap *regmap;
 	struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct sta32x_platform_data *pdata;
 
 	unsigned int mclk;
@@ -270,8 +270,8 @@ static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol,
 static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 	int numcoef = kcontrol->private_value >> 16;
 	int index = kcontrol->private_value & 0xffff;
 	unsigned int cfud, val;
@@ -312,8 +312,8 @@ static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,
 static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 	int numcoef = kcontrol->private_value >> 16;
 	int index = kcontrol->private_value & 0xffff;
 	unsigned int cfud;
@@ -347,9 +347,9 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
+static int sta32x_sync_coef_shadow(struct snd_soc_component *component)
 {
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 	unsigned int cfud;
 	int i;
 
@@ -375,16 +375,16 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int sta32x_cache_sync(struct snd_soc_codec *codec)
+static int sta32x_cache_sync(struct snd_soc_component *component)
 {
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 	unsigned int mute;
 	int rc;
 
 	/* mute during register sync */
 	regmap_read(sta32x->regmap, STA32X_MMUTE, &mute);
 	regmap_write(sta32x->regmap, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
-	sta32x_sync_coef_shadow(codec);
+	sta32x_sync_coef_shadow(component);
 	rc = regcache_sync(sta32x->regmap);
 	regmap_write(sta32x->regmap, STA32X_MMUTE, mute);
 	return rc;
@@ -395,17 +395,17 @@ static void sta32x_watchdog(struct work_struct *work)
 {
 	struct sta32x_priv *sta32x = container_of(work, struct sta32x_priv,
 						  watchdog_work.work);
-	struct snd_soc_codec *codec = sta32x->codec;
+	struct snd_soc_component *component = sta32x->component;
 	unsigned int confa, confa_cached;
 
 	/* check if sta32x has reset itself */
-	confa_cached = snd_soc_read(codec, STA32X_CONFA);
+	confa_cached = snd_soc_component_read32(component, STA32X_CONFA);
 	regcache_cache_bypass(sta32x->regmap, true);
-	confa = snd_soc_read(codec, STA32X_CONFA);
+	confa = snd_soc_component_read32(component, STA32X_CONFA);
 	regcache_cache_bypass(sta32x->regmap, false);
 	if (confa != confa_cached) {
 		regcache_mark_dirty(sta32x->regmap);
-		sta32x_cache_sync(codec);
+		sta32x_cache_sync(component);
 	}
 
 	if (!sta32x->shutdown)
@@ -582,10 +582,10 @@ static int mcs_ratio_table[3][7] = {
 static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "mclk=%u\n", freq);
+	dev_dbg(component->dev, "mclk=%u\n", freq);
 	sta32x->mclk = freq;
 
 	return 0;
@@ -602,8 +602,8 @@ static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 	u8 confb = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -651,22 +651,22 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 	int i, mcs = -EINVAL, ir = -EINVAL;
 	unsigned int confa, confb;
 	unsigned int rate, ratio;
 	int ret;
 
 	if (!sta32x->mclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"sta32x->mclk is unset. Unable to determine ratio\n");
 		return -EIO;
 	}
 
 	rate = params_rate(params);
 	ratio = sta32x->mclk / rate;
-	dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio);
+	dev_dbg(component->dev, "rate: %u, ratio: %u\n", rate, ratio);
 
 	for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
 		if (interpolation_ratios[i].fs == rate) {
@@ -676,7 +676,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (ir < 0) {
-		dev_err(codec->dev, "Unsupported samplerate: %u\n", rate);
+		dev_err(component->dev, "Unsupported samplerate: %u\n", rate);
 		return -EINVAL;
 	}
 
@@ -688,7 +688,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (mcs < 0) {
-		dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio);
+		dev_err(component->dev, "Unresolvable ratio: %u\n", ratio);
 		return -EINVAL;
 	}
 
@@ -698,10 +698,10 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 
 	switch (params_width(params)) {
 	case 24:
-		dev_dbg(codec->dev, "24bit\n");
+		dev_dbg(component->dev, "24bit\n");
 		/* fall through */
 	case 32:
-		dev_dbg(codec->dev, "24bit or 32bit\n");
+		dev_dbg(component->dev, "24bit or 32bit\n");
 		switch (sta32x->format) {
 		case SND_SOC_DAIFMT_I2S:
 			confb |= 0x0;
@@ -716,7 +716,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 
 		break;
 	case 20:
-		dev_dbg(codec->dev, "20bit\n");
+		dev_dbg(component->dev, "20bit\n");
 		switch (sta32x->format) {
 		case SND_SOC_DAIFMT_I2S:
 			confb |= 0x4;
@@ -731,7 +731,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 
 		break;
 	case 18:
-		dev_dbg(codec->dev, "18bit\n");
+		dev_dbg(component->dev, "18bit\n");
 		switch (sta32x->format) {
 		case SND_SOC_DAIFMT_I2S:
 			confb |= 0x8;
@@ -746,7 +746,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 
 		break;
 	case 16:
-		dev_dbg(codec->dev, "16bit\n");
+		dev_dbg(component->dev, "16bit\n");
 		switch (sta32x->format) {
 		case SND_SOC_DAIFMT_I2S:
 			confb |= 0x0;
@@ -793,20 +793,20 @@ static int sta32x_startup_sequence(struct sta32x_priv *sta32x)
 
 /**
  * sta32x_set_bias_level - DAPM callback
- * @codec: the codec device
+ * @component: the component device
  * @level: DAPM power level
  *
- * This is called by ALSA to put the codec into low power mode
- * or to wake it up.  If the codec is powered off completely
+ * This is called by ALSA to put the component into low power mode
+ * or to wake it up.  If the component is powered off completely
  * all registers must be restored after power on.
  */
-static int sta32x_set_bias_level(struct snd_soc_codec *codec,
+static int sta32x_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	int ret;
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "level = %d\n", level);
+	dev_dbg(component->dev, "level = %d\n", level);
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
@@ -819,17 +819,17 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
 						    sta32x->supplies);
 			if (ret != 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n", ret);
 				return ret;
 			}
 
 			sta32x_startup_sequence(sta32x);
-			sta32x_cache_sync(codec);
+			sta32x_cache_sync(component);
 			sta32x_watchdog_start(sta32x);
 		}
 
@@ -874,21 +874,21 @@ static struct snd_soc_dai_driver sta32x_dai = {
 	.ops = &sta32x_dai_ops,
 };
 
-static int sta32x_probe(struct snd_soc_codec *codec)
+static int sta32x_probe(struct snd_soc_component *component)
 {
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 	struct sta32x_platform_data *pdata = sta32x->pdata;
 	int i, ret = 0, thermal = 0;
 	ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
 				    sta32x->supplies);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		return ret;
 	}
 
 	ret = sta32x_startup_sequence(sta32x);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to startup device\n");
+		dev_err(component->dev, "Failed to startup device\n");
 		return ret;
 	}
 
@@ -968,36 +968,36 @@ static int sta32x_probe(struct snd_soc_codec *codec)
 	if (sta32x->pdata->needs_esd_watchdog)
 		INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 	/* Bias level configuration will have done an extra enable */
 	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 
 	return 0;
 }
 
-static int sta32x_remove(struct snd_soc_codec *codec)
+static void sta32x_remove(struct snd_soc_component *component)
 {
-	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 
 	sta32x_watchdog_stop(sta32x);
 	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver sta32x_codec = {
-	.probe =		sta32x_probe,
-	.remove =		sta32x_remove,
-	.set_bias_level =	sta32x_set_bias_level,
-	.suspend_bias_off =	true,
-	.component_driver = {
-		.controls =		sta32x_snd_controls,
-		.num_controls =		ARRAY_SIZE(sta32x_snd_controls),
-		.dapm_widgets =		sta32x_dapm_widgets,
-		.num_dapm_widgets =	ARRAY_SIZE(sta32x_dapm_widgets),
-		.dapm_routes =		sta32x_dapm_routes,
-		.num_dapm_routes =	ARRAY_SIZE(sta32x_dapm_routes),
-	},
+static const struct snd_soc_component_driver sta32x_component = {
+	.probe			= sta32x_probe,
+	.remove			= sta32x_remove,
+	.set_bias_level		= sta32x_set_bias_level,
+	.controls		= sta32x_snd_controls,
+	.num_controls		= ARRAY_SIZE(sta32x_snd_controls),
+	.dapm_widgets		= sta32x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sta32x_dapm_widgets),
+	.dapm_routes		= sta32x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sta32x_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config sta32x_regmap = {
@@ -1121,19 +1121,14 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, sta32x);
 
-	ret = snd_soc_register_codec(dev, &sta32x_codec, &sta32x_dai, 1);
+	ret = devm_snd_soc_register_component(dev, &sta32x_component,
+					      &sta32x_dai, 1);
 	if (ret < 0)
-		dev_err(dev, "Failed to register codec (%d)\n", ret);
+		dev_err(dev, "Failed to register component (%d)\n", ret);
 
 	return ret;
 }
 
-static int sta32x_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id sta32x_i2c_id[] = {
 	{ "sta326", 0 },
 	{ "sta328", 0 },
@@ -1148,7 +1143,6 @@ static struct i2c_driver sta32x_i2c_driver = {
 		.of_match_table = of_match_ptr(st32x_dt_ids),
 	},
 	.probe =    sta32x_i2c_probe,
-	.remove =   sta32x_i2c_remove,
 	.id_table = sta32x_i2c_id,
 };
 
diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c
index 9644c20..0b87031 100644
--- a/sound/soc/codecs/sta350.c
+++ b/sound/soc/codecs/sta350.c
@@ -309,8 +309,8 @@ static int sta350_coefficient_info(struct snd_kcontrol *kcontrol,
 static int sta350_coefficient_get(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 	int numcoef = kcontrol->private_value >> 16;
 	int index = kcontrol->private_value & 0xffff;
 	unsigned int cfud, val;
@@ -351,8 +351,8 @@ static int sta350_coefficient_get(struct snd_kcontrol *kcontrol,
 static int sta350_coefficient_put(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 	int numcoef = kcontrol->private_value >> 16;
 	int index = kcontrol->private_value & 0xffff;
 	unsigned int cfud;
@@ -386,9 +386,9 @@ static int sta350_coefficient_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static int sta350_sync_coef_shadow(struct snd_soc_codec *codec)
+static int sta350_sync_coef_shadow(struct snd_soc_component *component)
 {
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 	unsigned int cfud;
 	int i;
 
@@ -414,16 +414,16 @@ static int sta350_sync_coef_shadow(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int sta350_cache_sync(struct snd_soc_codec *codec)
+static int sta350_cache_sync(struct snd_soc_component *component)
 {
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 	unsigned int mute;
 	int rc;
 
 	/* mute during register sync */
 	regmap_read(sta350->regmap, STA350_CFUD, &mute);
 	regmap_write(sta350->regmap, STA350_MMUTE, mute | STA350_MMUTE_MMUTE);
-	sta350_sync_coef_shadow(codec);
+	sta350_sync_coef_shadow(component);
 	rc = regcache_sync(sta350->regmap);
 	regmap_write(sta350->regmap, STA350_MMUTE, mute);
 	return rc;
@@ -613,10 +613,10 @@ static int mcs_ratio_table[3][6] = {
 static int sta350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "mclk=%u\n", freq);
+	dev_dbg(component->dev, "mclk=%u\n", freq);
 	sta350->mclk = freq;
 
 	return 0;
@@ -633,8 +633,8 @@ static int sta350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int sta350_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 	unsigned int confb = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -682,22 +682,22 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 	int i, mcs = -EINVAL, ir = -EINVAL;
 	unsigned int confa, confb;
 	unsigned int rate, ratio;
 	int ret;
 
 	if (!sta350->mclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"sta350->mclk is unset. Unable to determine ratio\n");
 		return -EIO;
 	}
 
 	rate = params_rate(params);
 	ratio = sta350->mclk / rate;
-	dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio);
+	dev_dbg(component->dev, "rate: %u, ratio: %u\n", rate, ratio);
 
 	for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
 		if (interpolation_ratios[i].fs == rate) {
@@ -707,7 +707,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (ir < 0) {
-		dev_err(codec->dev, "Unsupported samplerate: %u\n", rate);
+		dev_err(component->dev, "Unsupported samplerate: %u\n", rate);
 		return -EINVAL;
 	}
 
@@ -719,7 +719,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (mcs < 0) {
-		dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio);
+		dev_err(component->dev, "Unresolvable ratio: %u\n", ratio);
 		return -EINVAL;
 	}
 
@@ -729,10 +729,10 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 
 	switch (params_width(params)) {
 	case 24:
-		dev_dbg(codec->dev, "24bit\n");
+		dev_dbg(component->dev, "24bit\n");
 		/* fall through */
 	case 32:
-		dev_dbg(codec->dev, "24bit or 32bit\n");
+		dev_dbg(component->dev, "24bit or 32bit\n");
 		switch (sta350->format) {
 		case SND_SOC_DAIFMT_I2S:
 			confb |= 0x0;
@@ -747,7 +747,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 
 		break;
 	case 20:
-		dev_dbg(codec->dev, "20bit\n");
+		dev_dbg(component->dev, "20bit\n");
 		switch (sta350->format) {
 		case SND_SOC_DAIFMT_I2S:
 			confb |= 0x4;
@@ -762,7 +762,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 
 		break;
 	case 18:
-		dev_dbg(codec->dev, "18bit\n");
+		dev_dbg(component->dev, "18bit\n");
 		switch (sta350->format) {
 		case SND_SOC_DAIFMT_I2S:
 			confb |= 0x8;
@@ -777,7 +777,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 
 		break;
 	case 16:
-		dev_dbg(codec->dev, "16bit\n");
+		dev_dbg(component->dev, "16bit\n");
 		switch (sta350->format) {
 		case SND_SOC_DAIFMT_I2S:
 			confb |= 0x0;
@@ -827,20 +827,20 @@ static int sta350_startup_sequence(struct sta350_priv *sta350)
 
 /**
  * sta350_set_bias_level - DAPM callback
- * @codec: the codec device
+ * @component: the component device
  * @level: DAPM power level
  *
- * This is called by ALSA to put the codec into low power mode
- * or to wake it up.  If the codec is powered off completely
+ * This is called by ALSA to put the component into low power mode
+ * or to wake it up.  If the component is powered off completely
  * all registers must be restored after power on.
  */
-static int sta350_set_bias_level(struct snd_soc_codec *codec,
+static int sta350_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	dev_dbg(codec->dev, "level = %d\n", level);
+	dev_dbg(component->dev, "level = %d\n", level);
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
@@ -853,18 +853,18 @@ static int sta350_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(
 				ARRAY_SIZE(sta350->supplies),
 				sta350->supplies);
 			if (ret < 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n",
 					ret);
 				return ret;
 			}
 			sta350_startup_sequence(sta350);
-			sta350_cache_sync(codec);
+			sta350_cache_sync(component);
 		}
 
 		/* Power down */
@@ -911,22 +911,22 @@ static struct snd_soc_dai_driver sta350_dai = {
 	.ops = &sta350_dai_ops,
 };
 
-static int sta350_probe(struct snd_soc_codec *codec)
+static int sta350_probe(struct snd_soc_component *component)
 {
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 	struct sta350_platform_data *pdata = sta350->pdata;
 	int i, ret = 0, thermal = 0;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(sta350->supplies),
 				    sta350->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		return ret;
 	}
 
 	ret = sta350_startup_sequence(sta350);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to startup device\n");
+		dev_err(component->dev, "Failed to startup device\n");
 		return ret;
 	}
 
@@ -1036,35 +1036,35 @@ static int sta350_probe(struct snd_soc_codec *codec)
 	sta350->coef_shadow[60] = 0x400000;
 	sta350->coef_shadow[61] = 0x400000;
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 	/* Bias level configuration will have done an extra enable */
 	regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);
 
 	return 0;
 }
 
-static int sta350_remove(struct snd_soc_codec *codec)
+static void sta350_remove(struct snd_soc_component *component)
 {
-	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 
 	regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver sta350_codec = {
-	.probe =		sta350_probe,
-	.remove =		sta350_remove,
-	.set_bias_level =	sta350_set_bias_level,
-	.suspend_bias_off =	true,
-	.component_driver = {
-		.controls =		sta350_snd_controls,
-		.num_controls =		ARRAY_SIZE(sta350_snd_controls),
-		.dapm_widgets =		sta350_dapm_widgets,
-		.num_dapm_widgets =	ARRAY_SIZE(sta350_dapm_widgets),
-		.dapm_routes =		sta350_dapm_routes,
-		.num_dapm_routes =	ARRAY_SIZE(sta350_dapm_routes),
-	},
+static const struct snd_soc_component_driver sta350_component = {
+	.probe			= sta350_probe,
+	.remove			= sta350_remove,
+	.set_bias_level		= sta350_set_bias_level,
+	.controls		= sta350_snd_controls,
+	.num_controls		= ARRAY_SIZE(sta350_snd_controls),
+	.dapm_widgets		= sta350_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sta350_dapm_widgets),
+	.dapm_routes		= sta350_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sta350_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config sta350_regmap = {
@@ -1244,16 +1244,15 @@ static int sta350_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, sta350);
 
-	ret = snd_soc_register_codec(dev, &sta350_codec, &sta350_dai, 1);
+	ret = devm_snd_soc_register_component(dev, &sta350_component, &sta350_dai, 1);
 	if (ret < 0)
-		dev_err(dev, "Failed to register codec (%d)\n", ret);
+		dev_err(dev, "Failed to register component (%d)\n", ret);
 
 	return ret;
 }
 
 static int sta350_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index 6607343..2881a0f 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -151,28 +151,28 @@ static const struct snd_kcontrol_new sta529_snd_controls[] = {
 	SOC_ENUM("PWM Select", pwm_src),
 };
 
-static int sta529_set_bias_level(struct snd_soc_codec *codec, enum
+static int sta529_set_bias_level(struct snd_soc_component *component, enum
 		snd_soc_bias_level level)
 {
-	struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
+	struct sta529 *sta529 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, STA529_FFXCFG0, POWER_CNTLMSAK,
+		snd_soc_component_update_bits(component, STA529_FFXCFG0, POWER_CNTLMSAK,
 				POWER_UP);
-		snd_soc_update_bits(codec, STA529_MISC,	FFX_CLK_MSK,
+		snd_soc_component_update_bits(component, STA529_MISC,	FFX_CLK_MSK,
 				FFX_CLK_ENB);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			regcache_sync(sta529->regmap);
-		snd_soc_update_bits(codec, STA529_FFXCFG0,
+		snd_soc_component_update_bits(component, STA529_FFXCFG0,
 					POWER_CNTLMSAK, POWER_STDBY);
 		/* Making FFX output to zero */
-		snd_soc_update_bits(codec, STA529_FFXCFG0, FFX_MASK,
+		snd_soc_component_update_bits(component, STA529_FFXCFG0, FFX_MASK,
 				FFX_OFF);
-		snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
+		snd_soc_component_update_bits(component, STA529_MISC, FFX_CLK_MSK,
 				FFX_CLK_DIS);
 		break;
 	case SND_SOC_BIAS_OFF:
@@ -187,7 +187,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params,
 		struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int pdata, play_freq_val, record_freq_val;
 	int bclk_to_fs_ratio;
 
@@ -205,7 +205,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
 		bclk_to_fs_ratio = 2;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported format\n");
+		dev_err(component->dev, "Unsupported format\n");
 		return -EINVAL;
 	}
 
@@ -228,23 +228,23 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
 		record_freq_val = 0;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported rate\n");
+		dev_err(component->dev, "Unsupported rate\n");
 		return -EINVAL;
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		snd_soc_update_bits(codec, STA529_S2PCFG1, PDATA_LEN_MSK,
+		snd_soc_component_update_bits(component, STA529_S2PCFG1, PDATA_LEN_MSK,
 				pdata << 6);
-		snd_soc_update_bits(codec, STA529_S2PCFG1, BCLK_TO_FS_MSK,
+		snd_soc_component_update_bits(component, STA529_S2PCFG1, BCLK_TO_FS_MSK,
 				bclk_to_fs_ratio << 4);
-		snd_soc_update_bits(codec, STA529_MISC, PLAY_FREQ_RANGE_MSK,
+		snd_soc_component_update_bits(component, STA529_MISC, PLAY_FREQ_RANGE_MSK,
 				play_freq_val << 4);
 	} else {
-		snd_soc_update_bits(codec, STA529_P2SCFG1, PDATA_LEN_MSK,
+		snd_soc_component_update_bits(component, STA529_P2SCFG1, PDATA_LEN_MSK,
 				pdata << 6);
-		snd_soc_update_bits(codec, STA529_P2SCFG1, BCLK_TO_FS_MSK,
+		snd_soc_component_update_bits(component, STA529_P2SCFG1, BCLK_TO_FS_MSK,
 				bclk_to_fs_ratio << 4);
-		snd_soc_update_bits(codec, STA529_MISC, CAP_FREQ_RANGE_MSK,
+		snd_soc_component_update_bits(component, STA529_MISC, CAP_FREQ_RANGE_MSK,
 				record_freq_val << 2);
 	}
 
@@ -258,14 +258,14 @@ static int sta529_mute(struct snd_soc_dai *dai, int mute)
 	if (mute)
 		val |= CODEC_MUTE_VAL;
 
-	snd_soc_update_bits(dai->codec, STA529_FFXCFG0, AUDIO_MUTE_MSK, val);
+	snd_soc_component_update_bits(dai->component, STA529_FFXCFG0, AUDIO_MUTE_MSK, val);
 
 	return 0;
 }
 
 static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u8 mode = 0;
 
 	/* interface format */
@@ -283,7 +283,7 @@ static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, STA529_S2PCFG0, DATA_FORMAT_MSK, mode);
+	snd_soc_component_update_bits(component, STA529_S2PCFG0, DATA_FORMAT_MSK, mode);
 
 	return 0;
 }
@@ -313,14 +313,15 @@ static struct snd_soc_dai_driver sta529_dai = {
 	.ops	= &sta529_dai_ops,
 };
 
-static const struct snd_soc_codec_driver sta529_codec_driver = {
-	.set_bias_level = sta529_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= sta529_snd_controls,
-		.num_controls		= ARRAY_SIZE(sta529_snd_controls),
-	},
+static const struct snd_soc_component_driver sta529_component_driver = {
+	.set_bias_level		= sta529_set_bias_level,
+	.controls		= sta529_snd_controls,
+	.num_controls		= ARRAY_SIZE(sta529_snd_controls),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config sta529_regmap = {
@@ -354,21 +355,14 @@ static int sta529_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, sta529);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&sta529_codec_driver, &sta529_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&sta529_component_driver, &sta529_dai, 1);
 	if (ret != 0)
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
 
 	return ret;
 }
 
-static int sta529_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id sta529_i2c_id[] = {
 	{ "sta529", 0 },
 	{ }
@@ -387,7 +381,6 @@ static struct i2c_driver sta529_i2c_driver = {
 		.of_match_table = sta529_of_match,
 	},
 	.probe		= sta529_i2c_probe,
-	.remove		= sta529_i2c_remove,
 	.id_table	= sta529_i2c_id,
 };
 
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index c66363a..f62101a 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -168,58 +168,58 @@ static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
 static int ac97_analog_prepare(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned short reg;
 
 	/* enable variable rate audio, disable SPDIF output */
-	snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x5, 0x1);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x5, 0x1);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		reg = AC97_PCM_FRONT_DAC_RATE;
 	else
 		reg = AC97_PCM_LR_ADC_RATE;
 
-	return snd_soc_write(codec, reg, runtime->rate);
+	return snd_soc_component_write(component, reg, runtime->rate);
 }
 
 static int ac97_digital_prepare(struct snd_pcm_substream *substream,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned short reg;
 
-	snd_soc_write(codec, AC97_SPDIF, 0x2002);
+	snd_soc_component_write(component, AC97_SPDIF, 0x2002);
 
 	/* Enable VRA and SPDIF out */
-	snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x5, 0x5);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x5, 0x5);
 
 	reg = AC97_PCM_FRONT_DAC_RATE;
 
-	return snd_soc_write(codec, reg, runtime->rate);
+	return snd_soc_component_write(component, reg, runtime->rate);
 }
 
-static int stac9766_set_bias_level(struct snd_soc_codec *codec,
+static int stac9766_set_bias_level(struct snd_soc_component *component,
 				   enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_ON: /* full On */
 	case SND_SOC_BIAS_PREPARE: /* partial On */
 	case SND_SOC_BIAS_STANDBY: /* Off, with power */
-		snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
+		snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
 		break;
 	case SND_SOC_BIAS_OFF: /* Off, without power */
 		/* disable everything including AC link */
-		snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
+		snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
 		break;
 	}
 	return 0;
 }
 
-static int stac9766_codec_resume(struct snd_soc_codec *codec)
+static int stac9766_component_resume(struct snd_soc_component *component)
 {
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
 	return snd_ac97_reset(ac97, true, STAC9766_VENDOR_ID,
 		STAC9766_VENDOR_ID_MASK);
@@ -272,13 +272,13 @@ static struct snd_soc_dai_driver stac9766_dai[] = {
 }
 };
 
-static int stac9766_codec_probe(struct snd_soc_codec *codec)
+static int stac9766_component_probe(struct snd_soc_component *component)
 {
 	struct snd_ac97 *ac97;
 	struct regmap *regmap;
 	int ret;
 
-	ac97 = snd_soc_new_ac97_codec(codec, STAC9766_VENDOR_ID,
+	ac97 = snd_soc_new_ac97_component(component, STAC9766_VENDOR_ID,
 			STAC9766_VENDOR_ID_MASK);
 	if (IS_ERR(ac97))
 		return PTR_ERR(ac97);
@@ -289,46 +289,42 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
 		goto err_free_ac97;
 	}
 
-	snd_soc_codec_init_regmap(codec, regmap);
-	snd_soc_codec_set_drvdata(codec, ac97);
+	snd_soc_component_init_regmap(component, regmap);
+	snd_soc_component_set_drvdata(component, ac97);
 
 	return 0;
 err_free_ac97:
-	snd_soc_free_ac97_codec(ac97);
+	snd_soc_free_ac97_component(ac97);
 	return ret;
 }
 
-static int stac9766_codec_remove(struct snd_soc_codec *codec)
+static void stac9766_component_remove(struct snd_soc_component *component)
 {
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
-	snd_soc_codec_exit_regmap(codec);
-	snd_soc_free_ac97_codec(ac97);
-	return 0;
+	snd_soc_component_exit_regmap(component);
+	snd_soc_free_ac97_component(ac97);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
-	.component_driver = {
-		.controls		= stac9766_snd_ac97_controls,
-		.num_controls		= ARRAY_SIZE(stac9766_snd_ac97_controls),
-	},
-	.set_bias_level = stac9766_set_bias_level,
-	.suspend_bias_off = true,
-	.probe = stac9766_codec_probe,
-	.remove = stac9766_codec_remove,
-	.resume = stac9766_codec_resume,
+static const struct snd_soc_component_driver soc_component_dev_stac9766 = {
+	.controls		= stac9766_snd_ac97_controls,
+	.num_controls		= ARRAY_SIZE(stac9766_snd_ac97_controls),
+	.set_bias_level		= stac9766_set_bias_level,
+	.probe			= stac9766_component_probe,
+	.remove			= stac9766_component_remove,
+	.resume			= stac9766_component_resume,
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+
 };
 
 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 stac9766_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai));
 }
 
 static struct platform_driver stac9766_codec_driver = {
@@ -337,7 +333,6 @@ static struct platform_driver stac9766_codec_driver = {
 	},
 
 	.probe = stac9766_probe,
-	.remove = stac9766_remove,
 };
 
 module_platform_driver(stac9766_codec_driver);
diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c
index 62c6187..7316c80 100644
--- a/sound/soc/codecs/sti-sas.c
+++ b/sound/soc/codecs/sti-sas.c
@@ -106,7 +106,7 @@ static int sti_sas_write_reg(void *context, unsigned int reg,
 	return status;
 }
 
-static int  sti_sas_init_sas_registers(struct snd_soc_codec *codec,
+static int  sti_sas_init_sas_registers(struct snd_soc_component *component,
 				       struct sti_sas_data *data)
 {
 	int ret;
@@ -116,35 +116,35 @@ static int  sti_sas_init_sas_registers(struct snd_soc_codec *codec,
 	 */
 
 	/* Initialise bi-phase formatter to disabled */
-	ret = snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
+	ret = snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
 				  SPDIF_BIPHASE_ENABLE_MASK, 0);
 
 	if (!ret)
 		/* Initialise bi-phase formatter idle value to 0 */
-		ret = snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
+		ret = snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
 					  SPDIF_BIPHASE_IDLE_MASK, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to update SPDIF registers\n");
+		dev_err(component->dev, "Failed to update SPDIF registers\n");
 		return ret;
 	}
 
 	/* Init DAC configuration */
 	/* init configuration */
-	ret =  snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+	ret =  snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
 				   STIH407_DAC_STANDBY_MASK,
 				   STIH407_DAC_STANDBY_MASK);
 
 	if (!ret)
-		ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+		ret = snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
 					  STIH407_DAC_STANDBY_ANA_MASK,
 					  STIH407_DAC_STANDBY_ANA_MASK);
 	if (!ret)
-		ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+		ret = snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
 					  STIH407_DAC_SOFTMUTE_MASK,
 					  STIH407_DAC_SOFTMUTE_MASK);
 
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to update DAC registers\n");
+		dev_err(component->dev, "Failed to update DAC registers\n");
 		return ret;
 	}
 
@@ -158,7 +158,7 @@ static int sti_sas_dac_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
 	/* Sanity check only */
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: Unsupporter master mask 0x%x\n",
 			__func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
 		return -EINVAL;
@@ -183,14 +183,14 @@ static const struct snd_soc_dapm_route stih407_sas_route[] = {
 
 static int stih407_sas_dac_mute(struct snd_soc_dai *dai, int mute, int stream)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (mute) {
-		return snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+		return snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
 					    STIH407_DAC_SOFTMUTE_MASK,
 					    STIH407_DAC_SOFTMUTE_MASK);
 	} else {
-		return snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+		return snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
 					    STIH407_DAC_SOFTMUTE_MASK,
 					    0);
 	}
@@ -203,7 +203,7 @@ static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai,
 				 unsigned int fmt)
 {
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-		dev_err(dai->codec->dev,
+		dev_err(dai->component->dev,
 			"%s: ERROR: Unsupporter master mask 0x%x\n",
 			__func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
 		return -EINVAL;
@@ -221,19 +221,19 @@ static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai,
 static int sti_sas_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		return snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
+		return snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
 					    SPDIF_BIPHASE_ENABLE_MASK,
 					    SPDIF_BIPHASE_ENABLE_MASK);
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-		return snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
+		return snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
 					    SPDIF_BIPHASE_ENABLE_MASK,
 					    0);
 	default:
@@ -260,8 +260,8 @@ static bool sti_sas_volatile_register(struct device *dev, unsigned int reg)
 static int sti_sas_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 			      unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = dai->component;
+	struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
 
 	if (dir == SND_SOC_CLOCK_OUT)
 		return 0;
@@ -285,20 +285,20 @@ static int sti_sas_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 static int sti_sas_prepare(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = dai->component;
+	struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	switch (dai->id) {
 	case STI_SAS_DAI_SPDIF_OUT:
 		if ((drvdata->spdif.mclk / runtime->rate) != 128) {
-			dev_err(codec->dev, "unexpected mclk-fs ratio\n");
+			dev_err(component->dev, "unexpected mclk-fs ratio\n");
 			return -EINVAL;
 		}
 		break;
 	case STI_SAS_DAI_ANALOG_OUT:
 		if ((drvdata->dac.mclk / runtime->rate) != 256) {
-			dev_err(codec->dev, "unexpected mclk-fs ratio\n");
+			dev_err(component->dev, "unexpected mclk-fs ratio\n");
 			return -EINVAL;
 		}
 		break;
@@ -375,29 +375,33 @@ static struct snd_soc_dai_driver sti_sas_dai[] = {
 };
 
 #ifdef CONFIG_PM_SLEEP
-static int sti_sas_resume(struct snd_soc_codec *codec)
+static int sti_sas_resume(struct snd_soc_component *component)
 {
-	struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
+	struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
 
-	return sti_sas_init_sas_registers(codec, drvdata);
+	return sti_sas_init_sas_registers(component, drvdata);
 }
 #else
 #define sti_sas_resume NULL
 #endif
 
-static int sti_sas_codec_probe(struct snd_soc_codec *codec)
+static int sti_sas_component_probe(struct snd_soc_component *component)
 {
-	struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
+	struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
 	int ret;
 
-	ret = sti_sas_init_sas_registers(codec, drvdata);
+	ret = sti_sas_init_sas_registers(component, drvdata);
 
 	return ret;
 }
 
-static struct snd_soc_codec_driver sti_sas_driver = {
-	.probe = sti_sas_codec_probe,
-	.resume = sti_sas_resume,
+static struct snd_soc_component_driver sti_sas_driver = {
+	.probe			= sti_sas_component_probe,
+	.resume			= sti_sas_resume,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id sti_sas_dev_match[] = {
@@ -452,34 +456,26 @@ static int sti_sas_driver_probe(struct platform_device *pdev)
 	sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops;
 
 	/* Set dapms*/
-	sti_sas_driver.component_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
-	sti_sas_driver.component_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
+	sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
+	sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
 
-	sti_sas_driver.component_driver.dapm_routes = drvdata->dev_data->dapm_routes;
-	sti_sas_driver.component_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
+	sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes;
+	sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
 
 	/* Store context */
 	dev_set_drvdata(&pdev->dev, drvdata);
 
-	return snd_soc_register_codec(&pdev->dev, &sti_sas_driver,
+	return devm_snd_soc_register_component(&pdev->dev, &sti_sas_driver,
 					sti_sas_dai,
 					ARRAY_SIZE(sti_sas_dai));
 }
 
-static int sti_sas_driver_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-
-	return 0;
-}
-
 static struct platform_driver sti_sas_platform_driver = {
 	.driver = {
 		.name = "sti-sas-codec",
 		.of_match_table = sti_sas_dev_match,
 	},
 	.probe = sti_sas_driver_probe,
-	.remove = sti_sas_driver_remove,
 };
 
 module_platform_driver(sti_sas_platform_driver);
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index 87307dd..355ecaf 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -70,7 +70,7 @@ static const char *tas2552_supply_names[TAS2552_NUM_SUPPLIES] = {
 };
 
 struct tas2552_data {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct regmap *regmap;
 	struct i2c_client *tas2552_client;
 	struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
@@ -88,22 +88,22 @@ struct tas2552_data {
 static int tas2552_post_event(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_write(codec, TAS2552_RESERVED_0D, 0xc0);
-		snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5),
+		snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xc0);
+		snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5),
 				    (1 << 5));
-		snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 0);
-		snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS, 0);
+		snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 0);
+		snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS, 0);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS,
+		snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS,
 				    TAS2552_SWS);
-		snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 1);
-		snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
-		snd_soc_write(codec, TAS2552_RESERVED_0D, 0xbe);
+		snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 1);
+		snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
+		snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xbe);
 		break;
 	}
 	return 0;
@@ -149,21 +149,21 @@ static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown)
 {
 	u8 cfg1_reg = 0;
 
-	if (!tas2552->codec)
+	if (!tas2552->component)
 		return;
 
 	if (sw_shutdown)
 		cfg1_reg = TAS2552_SWS;
 
-	snd_soc_update_bits(tas2552->codec, TAS2552_CFG_1, TAS2552_SWS,
+	snd_soc_component_update_bits(tas2552->component, TAS2552_CFG_1, TAS2552_SWS,
 			    cfg1_reg);
 }
 #endif
 
-static int tas2552_setup_pll(struct snd_soc_codec *codec,
+static int tas2552_setup_pll(struct snd_soc_component *component,
 			     struct snd_pcm_hw_params *params)
 {
-	struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
+	struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 	bool bypass_pll = false;
 	unsigned int pll_clk = params_rate(params) * 512;
 	unsigned int pll_clkin = tas2552->pll_clkin;
@@ -177,15 +177,15 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec,
 		pll_clkin += tas2552->tdm_delay;
 	}
 
-	pll_enable = snd_soc_read(codec, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
-	snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
+	pll_enable = snd_soc_component_read32(component, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
+	snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
 
 	if (pll_clkin == pll_clk)
 		bypass_pll = true;
 
 	if (bypass_pll) {
 		/* By pass the PLL configuration */
-		snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
+		snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_2,
 				    TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
 	} else {
 		/* Fill in the PLL control registers for J & D
@@ -195,7 +195,7 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec,
 		unsigned int d, q, t;
 		u8 j;
 		u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK;
-		u8 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1);
+		u8 p = snd_soc_component_read32(component, TAS2552_PLL_CTRL_1);
 
 		p = (p >> 7);
 
@@ -221,20 +221,20 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec,
 			goto recalc;
 		}
 
-		snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
+		snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
 				    pll_sel);
 
-		snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
+		snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_1,
 				    TAS2552_PLL_J_MASK, j);
 		/* Will clear the PLL_BYPASS bit */
-		snd_soc_write(codec, TAS2552_PLL_CTRL_2,
+		snd_soc_component_write(component, TAS2552_PLL_CTRL_2,
 			      TAS2552_PLL_D_UPPER(d));
-		snd_soc_write(codec, TAS2552_PLL_CTRL_3,
+		snd_soc_component_write(component, TAS2552_PLL_CTRL_3,
 			      TAS2552_PLL_D_LOWER(d));
 	}
 
 	/* Restore PLL status */
-	snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
+	snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
 			    pll_enable);
 
 	return 0;
@@ -244,8 +244,8 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = dai->component;
+	struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 	int cpf;
 	u8 ser_ctrl1_reg, wclk_rate;
 
@@ -267,7 +267,7 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 		cpf = 64 + tas2552->tdm_delay;
 		break;
 	default:
-		dev_err(codec->dev, "Not supported sample size: %d\n",
+		dev_err(component->dev, "Not supported sample size: %d\n",
 			params_width(params));
 		return -EINVAL;
 	}
@@ -281,7 +281,7 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 	else
 		ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_256;
 
-	snd_soc_update_bits(codec, TAS2552_SER_CTRL_1,
+	snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1,
 			    TAS2552_WORDLENGTH_MASK | TAS2552_CLKSPERFRAME_MASK,
 			    ser_ctrl1_reg);
 
@@ -316,15 +316,15 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 		wclk_rate = TAS2552_WCLK_FREQ_176_192KHZ;
 		break;
 	default:
-		dev_err(codec->dev, "Not supported sample rate: %d\n",
+		dev_err(component->dev, "Not supported sample rate: %d\n",
 			params_rate(params));
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
+	snd_soc_component_update_bits(component, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
 			    wclk_rate);
 
-	return tas2552_setup_pll(codec, params);
+	return tas2552_setup_pll(component, params);
 }
 
 #define TAS2552_DAI_FMT_MASK	(TAS2552_BCLKDIR | \
@@ -333,8 +333,8 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 static int tas2552_prepare(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 	int delay = 0;
 
 	/* TDM slot selection only valid in DSP_A/_B mode */
@@ -344,15 +344,15 @@ static int tas2552_prepare(struct snd_pcm_substream *substream,
 		delay += tas2552->tdm_delay;
 
 	/* Configure data delay */
-	snd_soc_write(codec, TAS2552_SER_CTRL_2, delay);
+	snd_soc_component_write(component, TAS2552_SER_CTRL_2, delay);
 
 	return 0;
 }
 
 static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = dai->component;
+	struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 	u8 serial_format;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -369,7 +369,7 @@ static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR);
 		break;
 	default:
-		dev_vdbg(codec->dev, "DAI Format master is not found\n");
+		dev_vdbg(component->dev, "DAI Format master is not found\n");
 		return -EINVAL;
 	}
 
@@ -388,12 +388,12 @@ static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		serial_format |= TAS2552_DATAFORMAT_LEFT_J;
 		break;
 	default:
-		dev_vdbg(codec->dev, "DAI Format is not found\n");
+		dev_vdbg(component->dev, "DAI Format is not found\n");
 		return -EINVAL;
 	}
 	tas2552->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
-	snd_soc_update_bits(codec, TAS2552_SER_CTRL_1, TAS2552_DAI_FMT_MASK,
+	snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1, TAS2552_DAI_FMT_MASK,
 			    serial_format);
 	return 0;
 }
@@ -401,8 +401,8 @@ static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 				  unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = dai->component;
+	struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 	u8 reg, mask, val;
 
 	switch (clk_id) {
@@ -410,7 +410,7 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 	case TAS2552_PLL_CLKIN_IVCLKIN:
 		if (freq < 512000 || freq > 24576000) {
 			/* out of range PLL_CLKIN, fall back to use BCLK */
-			dev_warn(codec->dev, "Out of range PLL_CLKIN: %u\n",
+			dev_warn(component->dev, "Out of range PLL_CLKIN: %u\n",
 				 freq);
 			clk_id = TAS2552_PLL_CLKIN_BCLK;
 			freq = 0;
@@ -435,11 +435,11 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 		tas2552->pdm_clk = freq;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clk id: %d\n", clk_id);
+		dev_err(component->dev, "Invalid clk id: %d\n", clk_id);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, reg, mask, val);
+	snd_soc_component_update_bits(component, reg, mask, val);
 
 	return 0;
 }
@@ -448,26 +448,26 @@ static int tas2552_set_dai_tdm_slot(struct snd_soc_dai *dai,
 				    unsigned int tx_mask, unsigned int rx_mask,
 				    int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 	unsigned int lsb;
 
 	if (unlikely(!tx_mask)) {
-		dev_err(codec->dev, "tx masks need to be non 0\n");
+		dev_err(component->dev, "tx masks need to be non 0\n");
 		return -EINVAL;
 	}
 
 	/* TDM based on DSP mode requires slots to be adjacent */
 	lsb = __ffs(tx_mask);
 	if ((lsb + 1) != __fls(tx_mask)) {
-		dev_err(codec->dev, "Invalid mask, slots must be adjacent\n");
+		dev_err(component->dev, "Invalid mask, slots must be adjacent\n");
 		return -EINVAL;
 	}
 
 	tas2552->tdm_delay = lsb * slot_width;
 
 	/* DOUT in high-impedance on inactive bit clocks */
-	snd_soc_update_bits(codec, TAS2552_DOUT,
+	snd_soc_component_update_bits(component, TAS2552_DOUT,
 			    TAS2552_SDOUT_TRISTATE, TAS2552_SDOUT_TRISTATE);
 
 	return 0;
@@ -476,12 +476,12 @@ static int tas2552_set_dai_tdm_slot(struct snd_soc_dai *dai,
 static int tas2552_mute(struct snd_soc_dai *dai, int mute)
 {
 	u8 cfg1_reg = 0;
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (mute)
 		cfg1_reg |= TAS2552_MUTE;
 
-	snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);
+	snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);
 
 	return 0;
 }
@@ -570,41 +570,41 @@ static const struct snd_kcontrol_new tas2552_snd_controls[] = {
 	SOC_ENUM("DIN source", tas2552_din_source_enum),
 };
 
-static int tas2552_codec_probe(struct snd_soc_codec *codec)
+static int tas2552_component_probe(struct snd_soc_component *component)
 {
-	struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+	struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	tas2552->codec = codec;
+	tas2552->component = component;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
 				    tas2552->supplies);
 
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n",
+		dev_err(component->dev, "Failed to enable supplies: %d\n",
 			ret);
 		return ret;
 	}
 
 	gpiod_set_value(tas2552->enable_gpio, 1);
 
-	ret = pm_runtime_get_sync(codec->dev);
+	ret = pm_runtime_get_sync(component->dev);
 	if (ret < 0) {
-		dev_err(codec->dev, "Enabling device failed: %d\n",
+		dev_err(component->dev, "Enabling device failed: %d\n",
 			ret);
 		goto probe_fail;
 	}
 
-	snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
-	snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
+	snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
+	snd_soc_component_write(component, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
 					    TAS2552_DIN_SRC_SEL_AVG_L_R);
-	snd_soc_write(codec, TAS2552_OUTPUT_DATA,
+	snd_soc_component_write(component, TAS2552_OUTPUT_DATA,
 		      TAS2552_PDM_DATA_SEL_V_I |
 		      TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA));
-	snd_soc_write(codec, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
+	snd_soc_component_write(component, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
 						     TAS2552_APT_THRESH_20_17);
 
-	snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
+	snd_soc_component_write(component, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
 					    TAS2552_LIM_EN);
 
 	return 0;
@@ -617,42 +617,40 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int tas2552_codec_remove(struct snd_soc_codec *codec)
+static void tas2552_component_remove(struct snd_soc_component *component)
 {
-	struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+	struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 
-	pm_runtime_put(codec->dev);
+	pm_runtime_put(component->dev);
 
 	gpiod_set_value(tas2552->enable_gpio, 0);
-
-	return 0;
 };
 
 #ifdef CONFIG_PM
-static int tas2552_suspend(struct snd_soc_codec *codec)
+static int tas2552_suspend(struct snd_soc_component *component)
 {
-	struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+	struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
 					tas2552->supplies);
 
 	if (ret != 0)
-		dev_err(codec->dev, "Failed to disable supplies: %d\n",
+		dev_err(component->dev, "Failed to disable supplies: %d\n",
 			ret);
 	return ret;
 }
 
-static int tas2552_resume(struct snd_soc_codec *codec)
+static int tas2552_resume(struct snd_soc_component *component)
 {
-	struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+	struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
 				    tas2552->supplies);
 
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n",
+		dev_err(component->dev, "Failed to enable supplies: %d\n",
 			ret);
 	}
 
@@ -663,21 +661,20 @@ static int tas2552_resume(struct snd_soc_codec *codec)
 #define tas2552_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_tas2552 = {
-	.probe = tas2552_codec_probe,
-	.remove = tas2552_codec_remove,
-	.suspend =	tas2552_suspend,
-	.resume = tas2552_resume,
-	.ignore_pmdown_time = true,
-
-	.component_driver = {
-		.controls		= tas2552_snd_controls,
-		.num_controls		= ARRAY_SIZE(tas2552_snd_controls),
-		.dapm_widgets		= tas2552_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(tas2552_dapm_widgets),
-		.dapm_routes		= tas2552_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(tas2552_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_tas2552 = {
+	.probe			= tas2552_component_probe,
+	.remove			= tas2552_component_remove,
+	.suspend		= tas2552_suspend,
+	.resume			= tas2552_resume,
+	.controls		= tas2552_snd_controls,
+	.num_controls		= ARRAY_SIZE(tas2552_snd_controls),
+	.dapm_widgets		= tas2552_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tas2552_dapm_widgets),
+	.dapm_routes		= tas2552_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(tas2552_audio_map),
+	.idle_bias_on		= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config tas2552_regmap_config = {
@@ -736,18 +733,17 @@ static int tas2552_probe(struct i2c_client *client,
 
 	dev_set_drvdata(&client->dev, data);
 
-	ret = snd_soc_register_codec(&client->dev,
-				      &soc_codec_dev_tas2552,
+	ret = devm_snd_soc_register_component(&client->dev,
+				      &soc_component_dev_tas2552,
 				      tas2552_dai, ARRAY_SIZE(tas2552_dai));
 	if (ret < 0)
-		dev_err(&client->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&client->dev, "Failed to register component: %d\n", ret);
 
 	return ret;
 }
 
 static int tas2552_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	pm_runtime_disable(&client->dev);
 	return 0;
 }
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c
index 199272d..5efc4b7 100644
--- a/sound/soc/codecs/tas5086.c
+++ b/sound/soc/codecs/tas5086.c
@@ -261,9 +261,9 @@ struct tas5086_private {
 
 static int tas5086_deemph[] = { 0, 32000, 44100, 48000 };
 
-static int tas5086_set_deemph(struct snd_soc_codec *codec)
+static int tas5086_set_deemph(struct snd_soc_component *component)
 {
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 	int i, val = 0;
 
 	if (priv->deemph) {
@@ -282,8 +282,8 @@ static int tas5086_set_deemph(struct snd_soc_codec *codec)
 static int tas5086_get_deemph(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = priv->deemph;
 
@@ -293,20 +293,20 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol,
 static int tas5086_put_deemph(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
 	priv->deemph = ucontrol->value.integer.value[0];
 
-	return tas5086_set_deemph(codec);
+	return tas5086_set_deemph(component);
 }
 
 
 static int tas5086_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				  int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case TAS5086_CLK_IDX_MCLK:
@@ -323,12 +323,12 @@ static int tas5086_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int tas5086_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			       unsigned int format)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
 	/* The TAS5086 can only be slave to all clocks */
 	if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-		dev_err(codec->dev, "Invalid clocking mode\n");
+		dev_err(component->dev, "Invalid clocking mode\n");
 		return -EINVAL;
 	}
 
@@ -361,8 +361,8 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 	int val;
 	int ret;
 
@@ -373,7 +373,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
 			     ARRAY_SIZE(tas5086_sample_rates), priv->rate);
 
 	if (val < 0) {
-		dev_err(codec->dev, "Invalid sample rate\n");
+		dev_err(component->dev, "Invalid sample rate\n");
 		return -EINVAL;
 	}
 
@@ -387,7 +387,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
 	val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios),
 			     priv->mclk / priv->rate);
 	if (val < 0) {
-		dev_err(codec->dev, "Invalid MCLK / Fs ratio\n");
+		dev_err(component->dev, "Invalid MCLK / Fs ratio\n");
 		return -EINVAL;
 	}
 
@@ -424,7 +424,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
 		val = 0x06;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI format\n");
+		dev_err(component->dev, "Invalid DAI format\n");
 		return -EINVAL;
 	}
 
@@ -440,7 +440,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
 		val += 2;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid bit width\n");
+		dev_err(component->dev, "Invalid bit width\n");
 		return -EINVAL;
 	}
 
@@ -454,13 +454,13 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
 	if (ret < 0)
 		return ret;
 
-	return tas5086_set_deemph(codec);
+	return tas5086_set_deemph(component);
 }
 
 static int tas5086_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0;
 
 	if (mute)
@@ -773,9 +773,9 @@ static struct snd_soc_dai_driver tas5086_dai = {
 };
 
 #ifdef CONFIG_PM
-static int tas5086_soc_suspend(struct snd_soc_codec *codec)
+static int tas5086_soc_suspend(struct snd_soc_component *component)
 {
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	/* Shut down all channels */
@@ -788,9 +788,9 @@ static int tas5086_soc_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int tas5086_soc_resume(struct snd_soc_codec *codec)
+static int tas5086_soc_resume(struct snd_soc_component *component)
 {
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
@@ -800,7 +800,7 @@ static int tas5086_soc_resume(struct snd_soc_codec *codec)
 	tas5086_reset(priv);
 	regcache_mark_dirty(priv->regmap);
 
-	ret = tas5086_init(codec->dev, priv);
+	ret = tas5086_init(component->dev, priv);
 	if (ret < 0)
 		return ret;
 
@@ -823,22 +823,22 @@ static const struct of_device_id tas5086_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, tas5086_dt_ids);
 #endif
 
-static int tas5086_probe(struct snd_soc_codec *codec)
+static int tas5086_probe(struct snd_soc_component *component)
 {
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 	int i, ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+		dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
 		return ret;
 	}
 
 	priv->pwm_start_mid_z = 0;
 	priv->charge_period = 1300000; /* hardware default is 1300 ms */
 
-	if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) {
-		struct device_node *of_node = codec->dev->of_node;
+	if (of_match_device(of_match_ptr(tas5086_dt_ids), component->dev)) {
+		struct device_node *of_node = component->dev->of_node;
 
 		of_property_read_u32(of_node, "ti,charge-period",
 				     &priv->charge_period);
@@ -855,7 +855,7 @@ static int tas5086_probe(struct snd_soc_codec *codec)
 	}
 
 	tas5086_reset(priv);
-	ret = tas5086_init(codec->dev, priv);
+	ret = tas5086_init(component->dev, priv);
 	if (ret < 0)
 		goto exit_disable_regulators;
 
@@ -872,32 +872,32 @@ static int tas5086_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int tas5086_remove(struct snd_soc_codec *codec)
+static void tas5086_remove(struct snd_soc_component *component)
 {
-	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
 	if (gpio_is_valid(priv->gpio_nreset))
 		/* Set codec to the reset state */
 		gpio_set_value(priv->gpio_nreset, 0);
 
 	regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
-
-	return 0;
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_tas5086 = {
+static const struct snd_soc_component_driver soc_component_dev_tas5086 = {
 	.probe			= tas5086_probe,
 	.remove			= tas5086_remove,
 	.suspend		= tas5086_soc_suspend,
 	.resume			= tas5086_soc_resume,
-	.component_driver = {
-		.controls		= tas5086_controls,
-		.num_controls		= ARRAY_SIZE(tas5086_controls),
-		.dapm_widgets		= tas5086_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(tas5086_dapm_widgets),
-		.dapm_routes		= tas5086_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(tas5086_dapm_routes),
-	},
+	.controls		= tas5086_controls,
+	.num_controls		= ARRAY_SIZE(tas5086_controls),
+	.dapm_widgets		= tas5086_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tas5086_dapm_widgets),
+	.dapm_routes		= tas5086_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tas5086_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct i2c_device_id tas5086_i2c_id[] = {
@@ -985,7 +985,8 @@ static int tas5086_i2c_probe(struct i2c_client *i2c,
 	regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
 
 	if (ret == 0)
-		ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_tas5086,
+		ret = devm_snd_soc_register_component(&i2c->dev,
+					     &soc_component_dev_tas5086,
 					     &tas5086_dai, 1);
 
 	return ret;
@@ -993,7 +994,6 @@ static int tas5086_i2c_probe(struct i2c_client *i2c,
 
 static int tas5086_i2c_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&i2c->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c
index a094999..52f34c9 100644
--- a/sound/soc/codecs/tas571x.c
+++ b/sound/soc/codecs/tas571x.c
@@ -51,7 +51,7 @@ struct tas571x_private {
 	unsigned int			format;
 	struct gpio_desc		*reset_gpio;
 	struct gpio_desc		*pdn_gpio;
-	struct snd_soc_codec_driver	codec_driver;
+	struct snd_soc_component_driver	component_driver;
 };
 
 static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
@@ -242,8 +242,8 @@ static int tas571x_coefficient_info(struct snd_kcontrol *kcontrol,
 static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
 	int numcoef = kcontrol->private_value >> 16;
 	int index = kcontrol->private_value & 0xffff;
 
@@ -254,8 +254,8 @@ static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,
 static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
 	int numcoef = kcontrol->private_value >> 16;
 	int index = kcontrol->private_value & 0xffff;
 
@@ -265,7 +265,7 @@ static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,
 
 static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
 {
-	struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);
 
 	priv->format = format;
 
@@ -276,7 +276,7 @@ static int tas571x_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);
 	u32 val;
 
 	switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -304,13 +304,13 @@ static int tas571x_hw_params(struct snd_pcm_substream *substream,
 
 static int tas571x_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 sysctl2;
 	int ret;
 
 	sysctl2 = mute ? TAS571X_SYS_CTRL_2_SDN_MASK : 0;
 
-	ret = snd_soc_update_bits(codec,
+	ret = snd_soc_component_update_bits(component,
 			    TAS571X_SYS_CTRL_2_REG,
 		     TAS571X_SYS_CTRL_2_SDN_MASK,
 		     sysctl2);
@@ -319,10 +319,10 @@ static int tas571x_mute(struct snd_soc_dai *dai, int mute)
 	return ret;
 }
 
-static int tas571x_set_bias_level(struct snd_soc_codec *codec,
+static int tas571x_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct tas571x_private *priv = snd_soc_codec_get_drvdata(codec);
+	struct tas571x_private *priv = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -331,11 +331,11 @@ static int tas571x_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			if (!IS_ERR(priv->mclk)) {
 				ret = clk_prepare_enable(priv->mclk);
 				if (ret) {
-					dev_err(codec->dev,
+					dev_err(component->dev,
 						"Failed to enable master clock: %d\n",
 						ret);
 					return ret;
@@ -643,16 +643,15 @@ static const struct snd_soc_dapm_route tas571x_dapm_routes[] = {
 	{ "OUT_D", NULL, "DACR" },
 };
 
-static const struct snd_soc_codec_driver tas571x_codec = {
-	.set_bias_level = tas571x_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.dapm_widgets		= tas571x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(tas571x_dapm_widgets),
-		.dapm_routes		= tas571x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(tas571x_dapm_routes),
-	},
+static const struct snd_soc_component_driver tas571x_component = {
+	.set_bias_level		= tas571x_set_bias_level,
+	.dapm_widgets		= tas571x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tas571x_dapm_widgets),
+	.dapm_routes		= tas571x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tas571x_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static struct snd_soc_dai_driver tas571x_dai = {
@@ -746,9 +745,9 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 
 	usleep_range(50000, 60000);
 
-	memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver));
-	priv->codec_driver.component_driver.controls = priv->chip->controls;
-	priv->codec_driver.component_driver.num_controls = priv->chip->num_controls;
+	memcpy(&priv->component_driver, &tas571x_component, sizeof(priv->component_driver));
+	priv->component_driver.controls = priv->chip->controls;
+	priv->component_driver.num_controls = priv->chip->num_controls;
 
 	if (priv->chip->vol_reg_size == 2) {
 		/*
@@ -761,7 +760,8 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 			return ret;
 	}
 
-	return snd_soc_register_codec(&client->dev, &priv->codec_driver,
+	return devm_snd_soc_register_component(&client->dev,
+				      &priv->component_driver,
 				      &tas571x_dai, 1);
 }
 
@@ -769,7 +769,6 @@ static int tas571x_i2c_remove(struct i2c_client *client)
 {
 	struct tas571x_private *priv = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
 	regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);
 
 	return 0;
diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c
index f3006f3..ae3d032 100644
--- a/sound/soc/codecs/tas5720.c
+++ b/sound/soc/codecs/tas5720.c
@@ -49,7 +49,7 @@ static const char * const tas5720_supply_names[] = {
 #define TAS5720_NUM_SUPPLIES	ARRAY_SIZE(tas5720_supply_names)
 
 struct tas5720_data {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct regmap *regmap;
 	struct i2c_client *tas5720_client;
 	enum tas572x_type devtype;
@@ -62,7 +62,7 @@ static int tas5720_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int rate = params_rate(params);
 	bool ssz_ds;
 	int ret;
@@ -77,14 +77,14 @@ static int tas5720_hw_params(struct snd_pcm_substream *substream,
 		ssz_ds = true;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported sample rate: %u\n", rate);
+		dev_err(component->dev, "unsupported sample rate: %u\n", rate);
 		return -EINVAL;
 	}
 
-	ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL1_REG,
+	ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG,
 				  TAS5720_SSZ_DS, ssz_ds);
 	if (ret < 0) {
-		dev_err(codec->dev, "error setting sample rate: %d\n", ret);
+		dev_err(component->dev, "error setting sample rate: %d\n", ret);
 		return ret;
 	}
 
@@ -93,12 +93,12 @@ static int tas5720_hw_params(struct snd_pcm_substream *substream,
 
 static int tas5720_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 serial_format;
 	int ret;
 
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-		dev_vdbg(codec->dev, "DAI Format master is not found\n");
+		dev_vdbg(component->dev, "DAI Format master is not found\n");
 		return -EINVAL;
 	}
 
@@ -132,15 +132,15 @@ static int tas5720_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		serial_format = TAS5720_SAIF_LEFTJ;
 		break;
 	default:
-		dev_vdbg(codec->dev, "DAI Format is not found\n");
+		dev_vdbg(component->dev, "DAI Format is not found\n");
 		return -EINVAL;
 	}
 
-	ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL1_REG,
+	ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG,
 				  TAS5720_SAIF_FORMAT_MASK,
 				  serial_format);
 	if (ret < 0) {
-		dev_err(codec->dev, "error setting SAIF format: %d\n", ret);
+		dev_err(component->dev, "error setting SAIF format: %d\n", ret);
 		return ret;
 	}
 
@@ -151,12 +151,12 @@ static int tas5720_set_dai_tdm_slot(struct snd_soc_dai *dai,
 				    unsigned int tx_mask, unsigned int rx_mask,
 				    int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int first_slot;
 	int ret;
 
 	if (!tx_mask) {
-		dev_err(codec->dev, "tx masks must not be 0\n");
+		dev_err(component->dev, "tx masks must not be 0\n");
 		return -EINVAL;
 	}
 
@@ -168,39 +168,39 @@ static int tas5720_set_dai_tdm_slot(struct snd_soc_dai *dai,
 	first_slot = __ffs(tx_mask);
 
 	if (first_slot > 7) {
-		dev_err(codec->dev, "slot selection out of bounds (%u)\n",
+		dev_err(component->dev, "slot selection out of bounds (%u)\n",
 			first_slot);
 		return -EINVAL;
 	}
 
 	/* Enable manual TDM slot selection (instead of I2C ID based) */
-	ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL1_REG,
+	ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG,
 				  TAS5720_TDM_CFG_SRC, TAS5720_TDM_CFG_SRC);
 	if (ret < 0)
-		goto error_snd_soc_update_bits;
+		goto error_snd_soc_component_update_bits;
 
 	/* Configure the TDM slot to process audio from */
-	ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG,
+	ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
 				  TAS5720_TDM_SLOT_SEL_MASK, first_slot);
 	if (ret < 0)
-		goto error_snd_soc_update_bits;
+		goto error_snd_soc_component_update_bits;
 
 	return 0;
 
-error_snd_soc_update_bits:
-	dev_err(codec->dev, "error configuring TDM mode: %d\n", ret);
+error_snd_soc_component_update_bits:
+	dev_err(component->dev, "error configuring TDM mode: %d\n", ret);
 	return ret;
 }
 
 static int tas5720_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int ret;
 
-	ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG,
+	ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
 				  TAS5720_MUTE, mute ? TAS5720_MUTE : 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "error (un-)muting device: %d\n", ret);
+		dev_err(component->dev, "error (un-)muting device: %d\n", ret);
 		return ret;
 	}
 
@@ -211,7 +211,7 @@ static void tas5720_fault_check_work(struct work_struct *work)
 {
 	struct tas5720_data *tas5720 = container_of(work, struct tas5720_data,
 			fault_check_work.work);
-	struct device *dev = tas5720->codec->dev;
+	struct device *dev = tas5720->component->dev;
 	unsigned int curr_fault;
 	int ret;
 
@@ -267,18 +267,18 @@ static void tas5720_fault_check_work(struct work_struct *work)
 			      msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL));
 }
 
-static int tas5720_codec_probe(struct snd_soc_codec *codec)
+static int tas5720_codec_probe(struct snd_soc_component *component)
 {
-	struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+	struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
 	unsigned int device_id, expected_device_id;
 	int ret;
 
-	tas5720->codec = codec;
+	tas5720->component = component;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(tas5720->supplies),
 				    tas5720->supplies);
 	if (ret != 0) {
-		dev_err(codec->dev, "failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "failed to enable supplies: %d\n", ret);
 		return ret;
 	}
 
@@ -289,7 +289,7 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
 	 */
 	ret = regmap_read(tas5720->regmap, TAS5720_DEVICE_ID_REG, &device_id);
 	if (ret < 0) {
-		dev_err(codec->dev, "failed to read device ID register: %d\n",
+		dev_err(component->dev, "failed to read device ID register: %d\n",
 			ret);
 		goto probe_fail;
 	}
@@ -302,19 +302,19 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
 		expected_device_id = TAS5722_DEVICE_ID;
 		break;
 	default:
-		dev_err(codec->dev, "unexpected private driver data\n");
+		dev_err(component->dev, "unexpected private driver data\n");
 		return -EINVAL;
 	}
 
 	if (device_id != expected_device_id)
-		dev_warn(codec->dev, "wrong device ID. expected: %u read: %u\n",
+		dev_warn(component->dev, "wrong device ID. expected: %u read: %u\n",
 			 expected_device_id, device_id);
 
 	/* Set device to mute */
-	ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG,
+	ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
 				  TAS5720_MUTE, TAS5720_MUTE);
 	if (ret < 0)
-		goto error_snd_soc_update_bits;
+		goto error_snd_soc_component_update_bits;
 
 	/*
 	 * Enter shutdown mode - our default when not playing audio - to
@@ -322,17 +322,17 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
 	 * side doing so as all device registers are preserved and the wakeup
 	 * of the codec is rather quick which we do using a dapm widget.
 	 */
-	ret = snd_soc_update_bits(codec, TAS5720_POWER_CTRL_REG,
+	ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG,
 				  TAS5720_SDZ, 0);
 	if (ret < 0)
-		goto error_snd_soc_update_bits;
+		goto error_snd_soc_component_update_bits;
 
 	INIT_DELAYED_WORK(&tas5720->fault_check_work, tas5720_fault_check_work);
 
 	return 0;
 
-error_snd_soc_update_bits:
-	dev_err(codec->dev, "error configuring device registers: %d\n", ret);
+error_snd_soc_component_update_bits:
+	dev_err(component->dev, "error configuring device registers: %d\n", ret);
 
 probe_fail:
 	regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies),
@@ -340,9 +340,9 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int tas5720_codec_remove(struct snd_soc_codec *codec)
+static void tas5720_codec_remove(struct snd_soc_component *component)
 {
-	struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+	struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	cancel_delayed_work_sync(&tas5720->fault_check_work);
@@ -350,24 +350,22 @@ static int tas5720_codec_remove(struct snd_soc_codec *codec)
 	ret = regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies),
 				     tas5720->supplies);
 	if (ret < 0)
-		dev_err(codec->dev, "failed to disable supplies: %d\n", ret);
-
-	return ret;
+		dev_err(component->dev, "failed to disable supplies: %d\n", ret);
 };
 
 static int tas5720_dac_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	if (event & SND_SOC_DAPM_POST_PMU) {
 		/* Take TAS5720 out of shutdown mode */
-		ret = snd_soc_update_bits(codec, TAS5720_POWER_CTRL_REG,
+		ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG,
 					  TAS5720_SDZ, TAS5720_SDZ);
 		if (ret < 0) {
-			dev_err(codec->dev, "error waking codec: %d\n", ret);
+			dev_err(component->dev, "error waking component: %d\n", ret);
 			return ret;
 		}
 
@@ -390,10 +388,10 @@ static int tas5720_dac_event(struct snd_soc_dapm_widget *w,
 		cancel_delayed_work_sync(&tas5720->fault_check_work);
 
 		/* Place TAS5720 in shutdown mode to minimize current draw */
-		ret = snd_soc_update_bits(codec, TAS5720_POWER_CTRL_REG,
+		ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG,
 					  TAS5720_SDZ, 0);
 		if (ret < 0) {
-			dev_err(codec->dev, "error shutting down codec: %d\n",
+			dev_err(component->dev, "error shutting down component: %d\n",
 				ret);
 			return ret;
 		}
@@ -403,9 +401,9 @@ static int tas5720_dac_event(struct snd_soc_dapm_widget *w,
 }
 
 #ifdef CONFIG_PM
-static int tas5720_suspend(struct snd_soc_codec *codec)
+static int tas5720_suspend(struct snd_soc_component *component)
 {
-	struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+	struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	regcache_cache_only(tas5720->regmap, true);
@@ -414,20 +412,20 @@ static int tas5720_suspend(struct snd_soc_codec *codec)
 	ret = regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies),
 				     tas5720->supplies);
 	if (ret < 0)
-		dev_err(codec->dev, "failed to disable supplies: %d\n", ret);
+		dev_err(component->dev, "failed to disable supplies: %d\n", ret);
 
 	return ret;
 }
 
-static int tas5720_resume(struct snd_soc_codec *codec)
+static int tas5720_resume(struct snd_soc_component *component)
 {
-	struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+	struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(tas5720->supplies),
 				    tas5720->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "failed to enable supplies: %d\n", ret);
 		return ret;
 	}
 
@@ -435,7 +433,7 @@ static int tas5720_resume(struct snd_soc_codec *codec)
 
 	ret = regcache_sync(tas5720->regmap);
 	if (ret < 0) {
-		dev_err(codec->dev, "failed to sync regcache: %d\n", ret);
+		dev_err(component->dev, "failed to sync regcache: %d\n", ret);
 		return ret;
 	}
 
@@ -512,20 +510,21 @@ static const struct snd_soc_dapm_route tas5720_audio_map[] = {
 	{ "OUT", NULL, "DAC" },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_tas5720 = {
-	.probe = tas5720_codec_probe,
-	.remove = tas5720_codec_remove,
-	.suspend = tas5720_suspend,
-	.resume = tas5720_resume,
-
-	.component_driver = {
-		.controls		= tas5720_snd_controls,
-		.num_controls		= ARRAY_SIZE(tas5720_snd_controls),
-		.dapm_widgets		= tas5720_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(tas5720_dapm_widgets),
-		.dapm_routes		= tas5720_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(tas5720_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_tas5720 = {
+	.probe			= tas5720_codec_probe,
+	.remove			= tas5720_codec_remove,
+	.suspend		= tas5720_suspend,
+	.resume			= tas5720_resume,
+	.controls		= tas5720_snd_controls,
+	.num_controls		= ARRAY_SIZE(tas5720_snd_controls),
+	.dapm_widgets		= tas5720_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tas5720_dapm_widgets),
+	.dapm_routes		= tas5720_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(tas5720_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /* PCM rates supported by the TAS5720 driver */
@@ -614,26 +613,17 @@ static int tas5720_probe(struct i2c_client *client,
 
 	dev_set_drvdata(dev, data);
 
-	ret = snd_soc_register_codec(&client->dev,
-				     &soc_codec_dev_tas5720,
+	ret = devm_snd_soc_register_component(&client->dev,
+				     &soc_component_dev_tas5720,
 				     tas5720_dai, ARRAY_SIZE(tas5720_dai));
 	if (ret < 0) {
-		dev_err(dev, "failed to register codec: %d\n", ret);
+		dev_err(dev, "failed to register component: %d\n", ret);
 		return ret;
 	}
 
 	return 0;
 }
 
-static int tas5720_remove(struct i2c_client *client)
-{
-	struct device *dev = &client->dev;
-
-	snd_soc_unregister_codec(dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id tas5720_id[] = {
 	{ "tas5720", TAS5720 },
 	{ "tas5722", TAS5722 },
@@ -656,7 +646,6 @@ static struct i2c_driver tas5720_i2c_driver = {
 		.of_match_table = of_match_ptr(tas5720_of_match),
 	},
 	.probe = tas5720_probe,
-	.remove = tas5720_remove,
 	.id_table = tas5720_id,
 };
 
diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c
index 49b87f6..4f3a16c 100644
--- a/sound/soc/codecs/tas6424.c
+++ b/sound/soc/codecs/tas6424.c
@@ -66,10 +66,10 @@ static const struct snd_kcontrol_new tas6424_snd_controls[] = {
 static int tas6424_dac_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s() event=0x%0x\n", __func__, event);
+	dev_dbg(component->dev, "%s() event=0x%0x\n", __func__, event);
 
 	if (event & SND_SOC_DAPM_POST_PMU) {
 		/* Observe codec shutdown-to-active time */
@@ -105,12 +105,12 @@ static int tas6424_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int rate = params_rate(params);
 	unsigned int width = params_width(params);
 	u8 sap_ctrl = 0;
 
-	dev_dbg(codec->dev, "%s() rate=%u width=%u\n", __func__, rate, width);
+	dev_dbg(component->dev, "%s() rate=%u width=%u\n", __func__, rate, width);
 
 	switch (rate) {
 	case 44100:
@@ -123,7 +123,7 @@ static int tas6424_hw_params(struct snd_pcm_substream *substream,
 		sap_ctrl |= TAS6424_SAP_RATE_96000;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported sample rate: %u\n", rate);
+		dev_err(component->dev, "unsupported sample rate: %u\n", rate);
 		return -EINVAL;
 	}
 
@@ -134,11 +134,11 @@ static int tas6424_hw_params(struct snd_pcm_substream *substream,
 	case 24:
 		break;
 	default:
-		dev_err(codec->dev, "unsupported sample width: %u\n", width);
+		dev_err(component->dev, "unsupported sample width: %u\n", width);
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, TAS6424_SAP_CTRL,
+	snd_soc_component_update_bits(component, TAS6424_SAP_CTRL,
 			    TAS6424_SAP_RATE_MASK |
 			    TAS6424_SAP_TDM_SLOT_SZ_16,
 			    sap_ctrl);
@@ -148,17 +148,17 @@ static int tas6424_hw_params(struct snd_pcm_substream *substream,
 
 static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 serial_format = 0;
 
-	dev_dbg(codec->dev, "%s() fmt=0x%0x\n", __func__, fmt);
+	dev_dbg(component->dev, "%s() fmt=0x%0x\n", __func__, fmt);
 
 	/* clock masters */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI master/slave interface\n");
+		dev_err(component->dev, "Invalid DAI master/slave interface\n");
 		return -EINVAL;
 	}
 
@@ -167,7 +167,7 @@ static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	case SND_SOC_DAIFMT_NB_NF:
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI clock signal polarity\n");
+		dev_err(component->dev, "Invalid DAI clock signal polarity\n");
 		return -EINVAL;
 	}
 
@@ -191,11 +191,11 @@ static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		serial_format |= TAS6424_SAP_LEFTJ;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI interface format\n");
+		dev_err(component->dev, "Invalid DAI interface format\n");
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, TAS6424_SAP_CTRL,
+	snd_soc_component_update_bits(component, TAS6424_SAP_CTRL,
 			    TAS6424_SAP_FMT_MASK, serial_format);
 
 	return 0;
@@ -205,11 +205,11 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
 				    unsigned int tx_mask, unsigned int rx_mask,
 				    int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int first_slot, last_slot;
 	bool sap_tdm_slot_last;
 
-	dev_dbg(codec->dev, "%s() tx_mask=%d rx_mask=%d\n", __func__,
+	dev_dbg(component->dev, "%s() tx_mask=%d rx_mask=%d\n", __func__,
 		tx_mask, rx_mask);
 
 	if (!tx_mask || !rx_mask)
@@ -224,7 +224,7 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
 	last_slot = __fls(rx_mask);
 
 	if (last_slot - first_slot != 4) {
-		dev_err(codec->dev, "tdm mask must cover 4 contiguous slots\n");
+		dev_err(component->dev, "tdm mask must cover 4 contiguous slots\n");
 		return -EINVAL;
 	}
 
@@ -236,11 +236,11 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
 		sap_tdm_slot_last = true;
 		break;
 	default:
-		dev_err(codec->dev, "tdm mask must start at slot 0 or 4\n");
+		dev_err(component->dev, "tdm mask must start at slot 0 or 4\n");
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, TAS6424_SAP_CTRL, TAS6424_SAP_TDM_SLOT_LAST,
+	snd_soc_component_update_bits(component, TAS6424_SAP_CTRL, TAS6424_SAP_TDM_SLOT_LAST,
 			    sap_tdm_slot_last ? TAS6424_SAP_TDM_SLOT_LAST : 0);
 
 	return 0;
@@ -248,27 +248,27 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
 
 static int tas6424_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val;
 
-	dev_dbg(codec->dev, "%s() mute=%d\n", __func__, mute);
+	dev_dbg(component->dev, "%s() mute=%d\n", __func__, mute);
 
 	if (mute)
 		val = TAS6424_ALL_STATE_MUTE;
 	else
 		val = TAS6424_ALL_STATE_PLAY;
 
-	snd_soc_write(codec, TAS6424_CH_STATE_CTRL, val);
+	snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, val);
 
 	return 0;
 }
 
-static int tas6424_power_off(struct snd_soc_codec *codec)
+static int tas6424_power_off(struct snd_soc_component *component)
 {
-	struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec);
+	struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	snd_soc_write(codec, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_HIZ);
+	snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_HIZ);
 
 	regcache_cache_only(tas6424->regmap, true);
 	regcache_mark_dirty(tas6424->regmap);
@@ -276,22 +276,22 @@ static int tas6424_power_off(struct snd_soc_codec *codec)
 	ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies),
 				     tas6424->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "failed to disable supplies: %d\n", ret);
+		dev_err(component->dev, "failed to disable supplies: %d\n", ret);
 		return ret;
 	}
 
 	return 0;
 }
 
-static int tas6424_power_on(struct snd_soc_codec *codec)
+static int tas6424_power_on(struct snd_soc_component *component)
 {
-	struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec);
+	struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies),
 				    tas6424->supplies);
 	if (ret < 0) {
-		dev_err(codec->dev, "failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "failed to enable supplies: %d\n", ret);
 		return ret;
 	}
 
@@ -299,11 +299,11 @@ static int tas6424_power_on(struct snd_soc_codec *codec)
 
 	ret = regcache_sync(tas6424->regmap);
 	if (ret < 0) {
-		dev_err(codec->dev, "failed to sync regcache: %d\n", ret);
+		dev_err(component->dev, "failed to sync regcache: %d\n", ret);
 		return ret;
 	}
 
-	snd_soc_write(codec, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE);
+	snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE);
 
 	/* any time we come out of HIZ, the output channels automatically run DC
 	 * load diagnostics, wait here until this completes
@@ -313,39 +313,38 @@ static int tas6424_power_on(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int tas6424_set_bias_level(struct snd_soc_codec *codec,
+static int tas6424_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	dev_dbg(codec->dev, "%s() level=%d\n", __func__, level);
+	dev_dbg(component->dev, "%s() level=%d\n", __func__, level);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
-			tas6424_power_on(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+			tas6424_power_on(component);
 		break;
 	case SND_SOC_BIAS_OFF:
-		tas6424_power_off(codec);
+		tas6424_power_off(component);
 		break;
 	}
 
 	return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_tas6424 = {
-	.set_bias_level = tas6424_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls = tas6424_snd_controls,
-		.num_controls = ARRAY_SIZE(tas6424_snd_controls),
-		.dapm_widgets = tas6424_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(tas6424_dapm_widgets),
-		.dapm_routes = tas6424_audio_map,
-		.num_dapm_routes = ARRAY_SIZE(tas6424_audio_map),
-	},
+static struct snd_soc_component_driver soc_codec_dev_tas6424 = {
+	.set_bias_level		= tas6424_set_bias_level,
+	.controls		= tas6424_snd_controls,
+	.num_controls		= ARRAY_SIZE(tas6424_snd_controls),
+	.dapm_widgets		= tas6424_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tas6424_dapm_widgets),
+	.dapm_routes		= tas6424_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(tas6424_audio_map),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static struct snd_soc_dai_ops tas6424_speaker_dai_ops = {
@@ -654,7 +653,7 @@ static int tas6424_i2c_probe(struct i2c_client *client,
 
 	INIT_DELAYED_WORK(&tas6424->fault_check_work, tas6424_fault_check_work);
 
-	ret = snd_soc_register_codec(dev, &soc_codec_dev_tas6424,
+	ret = devm_snd_soc_register_component(dev, &soc_codec_dev_tas6424,
 				     tas6424_dai, ARRAY_SIZE(tas6424_dai));
 	if (ret < 0) {
 		dev_err(dev, "unable to register codec: %d\n", ret);
@@ -670,8 +669,6 @@ static int tas6424_i2c_remove(struct i2c_client *client)
 	struct tas6424_data *tas6424 = dev_get_drvdata(dev);
 	int ret;
 
-	snd_soc_unregister_codec(dev);
-
 	cancel_delayed_work_sync(&tas6424->fault_check_work);
 
 	ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies),
diff --git a/sound/soc/codecs/tda7419.c b/sound/soc/codecs/tda7419.c
new file mode 100644
index 0000000..225c210
--- /dev/null
+++ b/sound/soc/codecs/tda7419.c
@@ -0,0 +1,654 @@
+/*
+ * TDA7419 audio processor driver
+ *
+ * Copyright 2018 Konsulko Group
+ *
+ * Author: Matt Porter <mporter@konsulko.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#define TDA7419_MAIN_SRC_REG		0x00
+#define TDA7419_LOUDNESS_REG		0x01
+#define TDA7419_MUTE_CLK_REG		0x02
+#define TDA7419_VOLUME_REG		0x03
+#define TDA7419_TREBLE_REG		0x04
+#define TDA7419_MIDDLE_REG		0x05
+#define TDA7419_BASS_REG		0x06
+#define TDA7419_SECOND_SRC_REG		0x07
+#define TDA7419_SUB_MID_BASS_REG	0x08
+#define TDA7419_MIXING_GAIN_REG		0x09
+#define TDA7419_ATTENUATOR_LF_REG	0x0a
+#define TDA7419_ATTENUATOR_RF_REG	0x0b
+#define TDA7419_ATTENUATOR_LR_REG	0x0c
+#define TDA7419_ATTENUATOR_RR_REG	0x0d
+#define TDA7419_MIXING_LEVEL_REG	0x0e
+#define TDA7419_ATTENUATOR_SUB_REG	0x0f
+#define TDA7419_SA_CLK_AC_REG		0x10
+#define TDA7419_TESTING_REG		0x11
+
+#define TDA7419_MAIN_SRC_SEL		0
+#define TDA7419_MAIN_SRC_GAIN		3
+#define TDA7419_MAIN_SRC_AUTOZERO	7
+
+#define TDA7419_LOUDNESS_ATTEN		0
+#define TDA7419_LOUDNESS_CENTER_FREQ	4
+#define TDA7419_LOUDNESS_BOOST		6
+#define TDA7419_LOUDNESS_SOFT_STEP	7
+
+#define TDA7419_VOLUME_SOFT_STEP	7
+
+#define TDA7419_SOFT_MUTE		0
+#define TDA7419_MUTE_INFLUENCE		1
+#define TDA7419_SOFT_MUTE_TIME		2
+#define TDA7419_SOFT_STEP_TIME		4
+#define TDA7419_CLK_FAST_MODE		7
+
+#define TDA7419_TREBLE_CENTER_FREQ	5
+#define TDA7419_REF_OUT_SELECT		7
+
+#define TDA7419_MIDDLE_Q_FACTOR		5
+#define TDA7419_MIDDLE_SOFT_STEP	7
+
+#define TDA7419_BASS_Q_FACTOR		5
+#define TDA7419_BASS_SOFT_STEP		7
+
+#define TDA7419_SECOND_SRC_SEL		0
+#define TDA7419_SECOND_SRC_GAIN		3
+#define TDA7419_REAR_SPKR_SRC		7
+
+#define TDA7419_SUB_CUT_OFF_FREQ	0
+#define TDA7419_MIDDLE_CENTER_FREQ	2
+#define TDA7419_BASS_CENTER_FREQ	4
+#define TDA7419_BASS_DC_MODE		6
+#define TDA7419_SMOOTHING_FILTER	7
+
+#define TDA7419_MIX_LF			0
+#define TDA7419_MIX_RF			1
+#define TDA7419_MIX_ENABLE		2
+#define TDA7419_SUB_ENABLE		3
+#define TDA7419_HPF_GAIN		4
+
+#define TDA7419_SA_Q_FACTOR		0
+#define TDA7419_RESET_MODE		1
+#define TDA7419_SA_SOURCE		2
+#define TDA7419_SA_RUN			3
+#define TDA7419_RESET			4
+#define TDA7419_CLK_SOURCE		5
+#define TDA7419_COUPLING_MODE		6
+
+struct tda7419_data {
+	struct regmap *regmap;
+};
+
+static bool tda7419_readable_reg(struct device *dev, unsigned int reg)
+{
+	return false;
+}
+
+static const struct reg_default tda7419_regmap_defaults[] = {
+	{ TDA7419_MAIN_SRC_REG,	0xfe },
+	{ TDA7419_LOUDNESS_REG, 0xfe },
+	{ TDA7419_MUTE_CLK_REG, 0xfe },
+	{ TDA7419_VOLUME_REG, 0xfe },
+	{ TDA7419_TREBLE_REG, 0xfe },
+	{ TDA7419_MIDDLE_REG, 0xfe },
+	{ TDA7419_BASS_REG, 0xfe },
+	{ TDA7419_SECOND_SRC_REG, 0xfe },
+	{ TDA7419_SUB_MID_BASS_REG, 0xfe },
+	{ TDA7419_MIXING_GAIN_REG, 0xfe },
+	{ TDA7419_ATTENUATOR_LF_REG, 0xfe },
+	{ TDA7419_ATTENUATOR_RF_REG, 0xfe },
+	{ TDA7419_ATTENUATOR_LR_REG, 0xfe },
+	{ TDA7419_ATTENUATOR_RR_REG, 0xfe },
+	{ TDA7419_MIXING_LEVEL_REG, 0xfe },
+	{ TDA7419_ATTENUATOR_SUB_REG, 0xfe },
+	{ TDA7419_SA_CLK_AC_REG, 0xfe },
+	{ TDA7419_TESTING_REG, 0xfe },
+};
+
+static const struct regmap_config tda7419_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TDA7419_TESTING_REG,
+	.cache_type = REGCACHE_RBTREE,
+	.readable_reg = tda7419_readable_reg,
+	.reg_defaults = tda7419_regmap_defaults,
+	.num_reg_defaults = ARRAY_SIZE(tda7419_regmap_defaults),
+};
+
+struct tda7419_vol_control {
+	int min, max;
+	unsigned int reg, rreg, mask, thresh;
+	unsigned int invert:1;
+};
+
+static inline bool tda7419_vol_is_stereo(struct tda7419_vol_control *tvc)
+{
+	if (tvc->reg == tvc->rreg)
+		return 0;
+
+	return 1;
+}
+
+static int tda7419_vol_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	struct tda7419_vol_control *tvc =
+		(struct tda7419_vol_control *)kcontrol->private_value;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = tda7419_vol_is_stereo(tvc) ? 2 : 1;
+	uinfo->value.integer.min = tvc->min;
+	uinfo->value.integer.max = tvc->max;
+
+	return 0;
+}
+
+static inline int tda7419_vol_get_value(int val, unsigned int mask,
+					int min, int thresh,
+					unsigned int invert)
+{
+	val &= mask;
+	if (val < thresh) {
+		if (invert)
+			val = 0 - val;
+	} else if (val > thresh) {
+		if (invert)
+			val = val - thresh;
+		else
+			val = thresh - val;
+	}
+
+	if (val < min)
+		val = min;
+
+	return val;
+}
+
+static int tda7419_vol_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+	struct tda7419_vol_control *tvc =
+		(struct tda7419_vol_control *)kcontrol->private_value;
+	unsigned int reg = tvc->reg;
+	unsigned int rreg = tvc->rreg;
+	unsigned int mask = tvc->mask;
+	int min = tvc->min;
+	int thresh = tvc->thresh;
+	unsigned int invert = tvc->invert;
+	int val;
+	int ret;
+
+	ret = snd_soc_component_read(component, reg, &val);
+	if (ret < 0)
+		return ret;
+	ucontrol->value.integer.value[0] =
+		tda7419_vol_get_value(val, mask, min, thresh, invert);
+
+	if (tda7419_vol_is_stereo(tvc)) {
+		ret = snd_soc_component_read(component, rreg, &val);
+		if (ret < 0)
+			return ret;
+		ucontrol->value.integer.value[1] =
+			tda7419_vol_get_value(val, mask, min, thresh, invert);
+	}
+
+	return 0;
+}
+
+static inline int tda7419_vol_put_value(int val, int thresh,
+					unsigned int invert)
+{
+	if (val < 0) {
+		if (invert)
+			val = abs(val);
+		else
+			val = thresh - val;
+	} else if ((val > 0) && invert) {
+		val += thresh;
+	}
+
+	return val;
+}
+
+static int tda7419_vol_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+		snd_kcontrol_chip(kcontrol);
+	struct tda7419_vol_control *tvc =
+		(struct tda7419_vol_control *)kcontrol->private_value;
+	unsigned int reg = tvc->reg;
+	unsigned int rreg = tvc->rreg;
+	unsigned int mask = tvc->mask;
+	int thresh = tvc->thresh;
+	unsigned int invert = tvc->invert;
+	int val;
+	int ret;
+
+	val = tda7419_vol_put_value(ucontrol->value.integer.value[0],
+				    thresh, invert);
+	ret = snd_soc_component_update_bits(component, reg,
+					    mask, val);
+	if (ret < 0)
+		return ret;
+
+	if (tda7419_vol_is_stereo(tvc)) {
+		val = tda7419_vol_put_value(ucontrol->value.integer.value[1],
+					    thresh, invert);
+		ret = snd_soc_component_update_bits(component, rreg,
+						    mask, val);
+	}
+
+	return ret;
+}
+
+#define TDA7419_SINGLE_VALUE(xreg, xmask, xmin, xmax, xthresh, xinvert) \
+	((unsigned long)&(struct tda7419_vol_control) \
+	{.reg = xreg, .rreg = xreg, .mask = xmask, .min = xmin, \
+	 .max = xmax, .thresh = xthresh, .invert = xinvert})
+
+#define TDA7419_DOUBLE_R_VALUE(xregl, xregr, xmask, xmin, xmax, xthresh, \
+			       xinvert) \
+	((unsigned long)&(struct tda7419_vol_control) \
+	{.reg = xregl, .rreg = xregr, .mask = xmask, .min = xmin, \
+	 .max = xmax, .thresh = xthresh, .invert = xinvert})
+
+#define TDA7419_SINGLE_TLV(xname, xreg, xmask, xmin, xmax, xthresh, \
+			   xinvert, xtlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+		SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+	.tlv.p = (xtlv_array), \
+	.info = tda7419_vol_info, \
+	.get = tda7419_vol_get, \
+	.put = tda7419_vol_put, \
+	.private_value = TDA7419_SINGLE_VALUE(xreg, xmask, xmin, \
+					      xmax, xthresh, xinvert), \
+}
+
+#define TDA7419_DOUBLE_R_TLV(xname, xregl, xregr, xmask, xmin, xmax, \
+			     xthresh, xinvert, xtlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+		SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+	.tlv.p = (xtlv_array), \
+	.info = tda7419_vol_info, \
+	.get = tda7419_vol_get, \
+	.put = tda7419_vol_put, \
+	.private_value = TDA7419_DOUBLE_R_VALUE(xregl, xregr, xmask, \
+						xmin, xmax, xthresh, \
+						xinvert), \
+}
+
+static const char * const enum_src_sel[] = {
+	"QD", "SE1", "SE2", "SE3", "SE", "Mute", "Mute", "Mute"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_main_src_sel,
+	TDA7419_MAIN_SRC_REG, TDA7419_MAIN_SRC_SEL, enum_src_sel);
+static const struct snd_kcontrol_new soc_mux_main_src_sel =
+	SOC_DAPM_ENUM("Main Source Select", soc_enum_main_src_sel);
+static DECLARE_TLV_DB_SCALE(tlv_src_gain, 0, 100, 0);
+static DECLARE_TLV_DB_SCALE(tlv_loudness_atten, -1500, 100, 0);
+static const char * const enum_loudness_center_freq[] = {
+	"Flat", "400 Hz", "800 Hz", "2400 Hz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_loudness_center_freq,
+	TDA7419_LOUDNESS_REG, TDA7419_LOUDNESS_CENTER_FREQ,
+	enum_loudness_center_freq);
+static const char * const enum_mute_influence[] = {
+	"Pin and IIC", "IIC"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_mute_influence,
+	TDA7419_MUTE_CLK_REG, TDA7419_MUTE_INFLUENCE, enum_mute_influence);
+static const char * const enum_soft_mute_time[] = {
+	"0.48 ms", "0.96 ms", "123 ms", "123 ms"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_soft_mute_time,
+	TDA7419_MUTE_CLK_REG, TDA7419_SOFT_MUTE_TIME, enum_soft_mute_time);
+static const char * const enum_soft_step_time[] = {
+	"0.160 ms", "0.321 ms", "0.642 ms", "1.28 ms",
+	"2.56 ms", "5.12 ms", "10.24 ms", "20.48 ms"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_soft_step_time,
+	TDA7419_MUTE_CLK_REG, TDA7419_SOFT_STEP_TIME, enum_soft_step_time);
+static DECLARE_TLV_DB_SCALE(tlv_volume, -8000, 100, 1);
+static const char * const enum_treble_center_freq[] = {
+	"10.0 kHz", "12.5 kHz", "15.0 kHz", "17.5 kHz"};
+static DECLARE_TLV_DB_SCALE(tlv_filter, -1500, 100, 0);
+static SOC_ENUM_SINGLE_DECL(soc_enum_treble_center_freq,
+	TDA7419_TREBLE_REG, TDA7419_TREBLE_CENTER_FREQ,
+	enum_treble_center_freq);
+static const char * const enum_ref_out_select[] = {
+	"External Vref (4 V)", "Internal Vref (3.3 V)"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_ref_out_select,
+	TDA7419_TREBLE_REG, TDA7419_REF_OUT_SELECT, enum_ref_out_select);
+static const char * const enum_middle_q_factor[] = {
+	"0.5", "0.75", "1.0", "1.25"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_middle_q_factor,
+	TDA7419_MIDDLE_REG, TDA7419_MIDDLE_Q_FACTOR, enum_middle_q_factor);
+static const char * const enum_bass_q_factor[] = {
+	"1.0", "1.25", "1.5", "2.0"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_bass_q_factor,
+	TDA7419_BASS_REG, TDA7419_BASS_Q_FACTOR, enum_bass_q_factor);
+static SOC_ENUM_SINGLE_DECL(soc_enum_second_src_sel,
+	TDA7419_SECOND_SRC_REG, TDA7419_SECOND_SRC_SEL, enum_src_sel);
+static const struct snd_kcontrol_new soc_mux_second_src_sel =
+	SOC_DAPM_ENUM("Second Source Select", soc_enum_second_src_sel);
+static const char * const enum_rear_spkr_src[] = {
+	"Main", "Second"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_rear_spkr_src,
+	TDA7419_SECOND_SRC_REG, TDA7419_REAR_SPKR_SRC, enum_rear_spkr_src);
+static const struct snd_kcontrol_new soc_mux_rear_spkr_src =
+	SOC_DAPM_ENUM("Rear Speaker Source", soc_enum_rear_spkr_src);
+static const char * const enum_sub_cut_off_freq[] = {
+	"Flat", "80 Hz", "120 Hz", "160 Hz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_sub_cut_off_freq,
+	TDA7419_SUB_MID_BASS_REG, TDA7419_SUB_CUT_OFF_FREQ,
+	enum_sub_cut_off_freq);
+static const char * const enum_middle_center_freq[] = {
+	"500 Hz", "1000 Hz", "1500 Hz", "2500 Hz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_middle_center_freq,
+	TDA7419_SUB_MID_BASS_REG, TDA7419_MIDDLE_CENTER_FREQ,
+	enum_middle_center_freq);
+static const char * const enum_bass_center_freq[] = {
+	"60 Hz", "80 Hz", "100 Hz", "200 Hz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_bass_center_freq,
+	TDA7419_SUB_MID_BASS_REG, TDA7419_BASS_CENTER_FREQ,
+	enum_bass_center_freq);
+static const char * const enum_sa_q_factor[] = {
+	"3.5", "1.75" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_sa_q_factor,
+	TDA7419_SA_CLK_AC_REG, TDA7419_SA_Q_FACTOR, enum_sa_q_factor);
+static const char * const enum_reset_mode[] = {
+	"IIC", "Auto" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_reset_mode,
+	TDA7419_SA_CLK_AC_REG, TDA7419_RESET_MODE, enum_reset_mode);
+static const char * const enum_sa_src[] = {
+	"Bass", "In Gain" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_sa_src,
+	TDA7419_SA_CLK_AC_REG, TDA7419_SA_SOURCE, enum_sa_src);
+static const char * const enum_clk_src[] = {
+	"Internal", "External" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_clk_src,
+	TDA7419_SA_CLK_AC_REG, TDA7419_CLK_SOURCE, enum_clk_src);
+static const char * const enum_coupling_mode[] = {
+	"DC Coupling (without HPF)", "AC Coupling after In Gain",
+	"DC Coupling (with HPF)", "AC Coupling after Bass" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_coupling_mode,
+	TDA7419_SA_CLK_AC_REG, TDA7419_COUPLING_MODE, enum_coupling_mode);
+
+/* ASoC Controls */
+static struct snd_kcontrol_new tda7419_controls[] = {
+SOC_SINGLE_TLV("Main Source Capture Volume", TDA7419_MAIN_SRC_REG,
+	       TDA7419_MAIN_SRC_GAIN, 15, 0, tlv_src_gain),
+SOC_SINGLE("Main Source AutoZero Switch", TDA7419_MAIN_SRC_REG,
+	   TDA7419_MAIN_SRC_AUTOZERO, 1, 1),
+SOC_SINGLE_TLV("Loudness Playback Volume", TDA7419_LOUDNESS_REG,
+	       TDA7419_LOUDNESS_ATTEN, 15, 1, tlv_loudness_atten),
+SOC_ENUM("Loudness Center Frequency", soc_enum_loudness_center_freq),
+SOC_SINGLE("Loudness High Boost Switch", TDA7419_LOUDNESS_REG,
+	   TDA7419_LOUDNESS_BOOST, 1, 1),
+SOC_SINGLE("Loudness Soft Step Switch", TDA7419_LOUDNESS_REG,
+	   TDA7419_LOUDNESS_SOFT_STEP, 1, 1),
+SOC_SINGLE("Soft Mute Switch", TDA7419_MUTE_CLK_REG, TDA7419_SOFT_MUTE, 1, 1),
+SOC_ENUM("Mute Influence", soc_enum_mute_influence),
+SOC_ENUM("Soft Mute Time", soc_enum_soft_mute_time),
+SOC_ENUM("Soft Step Time", soc_enum_soft_step_time),
+SOC_SINGLE("Clock Fast Mode Switch", TDA7419_MUTE_CLK_REG,
+	   TDA7419_CLK_FAST_MODE, 1, 1),
+TDA7419_SINGLE_TLV("Master Playback Volume", TDA7419_VOLUME_REG,
+		   0x7f, -80, 15, 0x10, 0, tlv_volume),
+SOC_SINGLE("Volume Soft Step Switch", TDA7419_VOLUME_REG,
+	   TDA7419_VOLUME_SOFT_STEP, 1, 1),
+TDA7419_SINGLE_TLV("Treble Playback Volume", TDA7419_TREBLE_REG,
+		   0x1f, -15, 15, 0x10, 1, tlv_filter),
+SOC_ENUM("Treble Center Frequency", soc_enum_treble_center_freq),
+SOC_ENUM("Reference Output Select", soc_enum_ref_out_select),
+TDA7419_SINGLE_TLV("Middle Playback Volume", TDA7419_MIDDLE_REG,
+		   0x1f, -15, 15, 0x10, 1, tlv_filter),
+SOC_ENUM("Middle Q Factor", soc_enum_middle_q_factor),
+SOC_SINGLE("Middle Soft Step Switch", TDA7419_MIDDLE_REG,
+	   TDA7419_MIDDLE_SOFT_STEP, 1, 1),
+TDA7419_SINGLE_TLV("Bass Playback Volume", TDA7419_BASS_REG,
+		   0x1f, -15, 15, 0x10, 1, tlv_filter),
+SOC_ENUM("Bass Q Factor", soc_enum_bass_q_factor),
+SOC_SINGLE("Bass Soft Step Switch", TDA7419_BASS_REG,
+	   TDA7419_BASS_SOFT_STEP, 1, 1),
+SOC_SINGLE_TLV("Second Source Capture Volume", TDA7419_SECOND_SRC_REG,
+	       TDA7419_SECOND_SRC_GAIN, 15, 0, tlv_src_gain),
+SOC_ENUM("Subwoofer Cut-off Frequency", soc_enum_sub_cut_off_freq),
+SOC_ENUM("Middle Center Frequency", soc_enum_middle_center_freq),
+SOC_ENUM("Bass Center Frequency", soc_enum_bass_center_freq),
+SOC_SINGLE("Bass DC Mode Switch", TDA7419_SUB_MID_BASS_REG,
+	   TDA7419_BASS_DC_MODE, 1, 1),
+SOC_SINGLE("Smoothing Filter Switch", TDA7419_SUB_MID_BASS_REG,
+	   TDA7419_SMOOTHING_FILTER, 1, 1),
+TDA7419_DOUBLE_R_TLV("Front Speaker Playback Volume", TDA7419_ATTENUATOR_LF_REG,
+		     TDA7419_ATTENUATOR_RF_REG, 0x7f, -80, 15, 0x10, 0,
+		     tlv_volume),
+SOC_SINGLE("Left Front Soft Step Switch", TDA7419_ATTENUATOR_LF_REG,
+	   TDA7419_VOLUME_SOFT_STEP, 1, 1),
+SOC_SINGLE("Right Front Soft Step Switch", TDA7419_ATTENUATOR_RF_REG,
+	   TDA7419_VOLUME_SOFT_STEP, 1, 1),
+TDA7419_DOUBLE_R_TLV("Rear Speaker Playback Volume", TDA7419_ATTENUATOR_LR_REG,
+		     TDA7419_ATTENUATOR_RR_REG, 0x7f, -80, 15, 0x10, 0,
+		     tlv_volume),
+SOC_SINGLE("Left Rear Soft Step Switch", TDA7419_ATTENUATOR_LR_REG,
+	   TDA7419_VOLUME_SOFT_STEP, 1, 1),
+SOC_SINGLE("Right Rear Soft Step Switch", TDA7419_ATTENUATOR_RR_REG,
+	   TDA7419_VOLUME_SOFT_STEP, 1, 1),
+TDA7419_SINGLE_TLV("Mixing Capture Volume", TDA7419_MIXING_LEVEL_REG,
+		   0x7f, -80, 15, 0x10, 0, tlv_volume),
+SOC_SINGLE("Mixing Level Soft Step Switch", TDA7419_MIXING_LEVEL_REG,
+	   TDA7419_VOLUME_SOFT_STEP, 1, 1),
+TDA7419_SINGLE_TLV("Subwoofer Playback Volume", TDA7419_ATTENUATOR_SUB_REG,
+		   0x7f, -80, 15, 0x10, 0, tlv_volume),
+SOC_SINGLE("Subwoofer Soft Step Switch", TDA7419_ATTENUATOR_SUB_REG,
+	   TDA7419_VOLUME_SOFT_STEP, 1, 1),
+SOC_ENUM("Spectrum Analyzer Q Factor", soc_enum_sa_q_factor),
+SOC_ENUM("Spectrum Analyzer Reset Mode", soc_enum_reset_mode),
+SOC_ENUM("Spectrum Analyzer Source", soc_enum_sa_src),
+SOC_SINGLE("Spectrum Analyzer Run Switch", TDA7419_SA_CLK_AC_REG,
+	   TDA7419_SA_RUN, 1, 1),
+SOC_SINGLE("Spectrum Analyzer Reset Switch", TDA7419_SA_CLK_AC_REG,
+	   TDA7419_RESET, 1, 1),
+SOC_ENUM("Clock Source", soc_enum_clk_src),
+SOC_ENUM("Coupling Mode", soc_enum_coupling_mode),
+};
+
+static const struct snd_kcontrol_new soc_mixer_lf_output_controls[] = {
+	SOC_DAPM_SINGLE("Mix to LF Speaker Switch",
+			TDA7419_MIXING_GAIN_REG,
+			TDA7419_MIX_LF, 1, 1),
+};
+
+static const struct snd_kcontrol_new soc_mixer_rf_output_controls[] = {
+	SOC_DAPM_SINGLE("Mix to RF Speaker Switch",
+			TDA7419_MIXING_GAIN_REG,
+			TDA7419_MIX_RF, 1, 1),
+};
+
+static const struct snd_kcontrol_new soc_mix_enable_switch_controls[] = {
+	SOC_DAPM_SINGLE("Switch", TDA7419_MIXING_GAIN_REG,
+			TDA7419_MIX_ENABLE, 1, 1),
+};
+
+static const struct snd_kcontrol_new soc_sub_enable_switch_controls[] = {
+	SOC_DAPM_SINGLE("Switch", TDA7419_MIXING_GAIN_REG,
+			TDA7419_MIX_ENABLE, 1, 1),
+};
+
+static const struct snd_soc_dapm_widget tda7419_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("SE3L"),
+	SND_SOC_DAPM_INPUT("SE3R"),
+	SND_SOC_DAPM_INPUT("SE2L"),
+	SND_SOC_DAPM_INPUT("SE2R"),
+	SND_SOC_DAPM_INPUT("SE1L"),
+	SND_SOC_DAPM_INPUT("SE1R"),
+	SND_SOC_DAPM_INPUT("DIFFL"),
+	SND_SOC_DAPM_INPUT("DIFFR"),
+	SND_SOC_DAPM_INPUT("MIX"),
+
+	SND_SOC_DAPM_MUX("Main Source Select", SND_SOC_NOPM,
+			 0, 0, &soc_mux_main_src_sel),
+	SND_SOC_DAPM_MUX("Second Source Select", SND_SOC_NOPM,
+			 0, 0, &soc_mux_second_src_sel),
+	SND_SOC_DAPM_MUX("Rear Speaker Source", SND_SOC_NOPM,
+			 0, 0, &soc_mux_rear_spkr_src),
+
+	SND_SOC_DAPM_SWITCH("Mix Enable", SND_SOC_NOPM,
+			0, 0, &soc_mix_enable_switch_controls[0]),
+	SND_SOC_DAPM_MIXER_NAMED_CTL("LF Output Mixer", SND_SOC_NOPM,
+			0, 0, &soc_mixer_lf_output_controls[0],
+			ARRAY_SIZE(soc_mixer_lf_output_controls)),
+	SND_SOC_DAPM_MIXER_NAMED_CTL("RF Output Mixer", SND_SOC_NOPM,
+			0, 0, &soc_mixer_rf_output_controls[0],
+			ARRAY_SIZE(soc_mixer_rf_output_controls)),
+
+	SND_SOC_DAPM_SWITCH("Subwoofer Enable",
+			SND_SOC_NOPM, 0, 0,
+			&soc_sub_enable_switch_controls[0]),
+
+	SND_SOC_DAPM_OUTPUT("OUTLF"),
+	SND_SOC_DAPM_OUTPUT("OUTRF"),
+	SND_SOC_DAPM_OUTPUT("OUTLR"),
+	SND_SOC_DAPM_OUTPUT("OUTRR"),
+	SND_SOC_DAPM_OUTPUT("OUTSW"),
+};
+
+static const struct snd_soc_dapm_route tda7419_dapm_routes[] = {
+	{"Main Source Select", "SE3", "SE3L"},
+	{"Main Source Select", "SE3", "SE3R"},
+	{"Main Source Select", "SE2", "SE2L"},
+	{"Main Source Select", "SE2", "SE2R"},
+	{"Main Source Select", "SE1", "SE1L"},
+	{"Main Source Select", "SE1", "SE1R"},
+	{"Main Source Select", "SE", "DIFFL"},
+	{"Main Source Select", "SE", "DIFFR"},
+	{"Main Source Select", "QD", "DIFFL"},
+	{"Main Source Select", "QD", "DIFFR"},
+
+	{"Second Source Select", "SE3", "SE3L"},
+	{"Second Source Select", "SE3", "SE3R"},
+	{"Second Source Select", "SE2", "SE2L"},
+	{"Second Source Select", "SE2", "SE2R"},
+	{"Second Source Select", "SE1", "SE1L"},
+	{"Second Source Select", "SE1", "SE1R"},
+	{"Second Source Select", "SE", "DIFFL"},
+	{"Second Source Select", "SE", "DIFFR"},
+	{"Second Source Select", "QD", "DIFFL"},
+	{"Second Source Select", "QD", "DIFFR"},
+
+	{"Rear Speaker Source", "Main", "Main Source Select"},
+	{"Rear Speaker Source", "Second", "Second Source Select"},
+
+	{"Subwoofer Enable", "Switch", "Main Source Select"},
+
+	{"Mix Enable", "Switch", "MIX"},
+
+	{"LF Output Mixer", NULL, "Main Source Select"},
+	{"LF Output Mixer", "Mix to LF Speaker Switch", "Mix Enable"},
+	{"RF Output Mixer", NULL, "Main Source Select"},
+	{"RF Output Mixer", "Mix to RF Speaker Switch", "Mix Enable"},
+
+	{"OUTLF", NULL, "LF Output Mixer"},
+	{"OUTRF", NULL, "RF Output Mixer"},
+	{"OUTLR", NULL, "Rear Speaker Source"},
+	{"OUTRR", NULL, "Rear Speaker Source"},
+	{"OUTSW", NULL, "Subwoofer Enable"},
+};
+
+static const struct snd_soc_component_driver tda7419_component_driver = {
+	.name			= "tda7419",
+	.controls		= tda7419_controls,
+	.num_controls		= ARRAY_SIZE(tda7419_controls),
+	.dapm_widgets		= tda7419_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tda7419_dapm_widgets),
+	.dapm_routes		= tda7419_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tda7419_dapm_routes),
+};
+
+static int tda7419_probe(struct i2c_client *i2c,
+			 const struct i2c_device_id *id)
+{
+	struct tda7419_data *tda7419;
+	int i, ret;
+
+	tda7419 = devm_kzalloc(&i2c->dev,
+			       sizeof(struct tda7419_data),
+			       GFP_KERNEL);
+	if (tda7419 == NULL)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, tda7419);
+
+	tda7419->regmap = devm_regmap_init_i2c(i2c, &tda7419_regmap_config);
+	if (IS_ERR(tda7419->regmap)) {
+		ret = PTR_ERR(tda7419->regmap);
+		dev_err(&i2c->dev, "error initializing regmap: %d\n",
+				ret);
+		return ret;
+	}
+
+	/*
+	 * Reset registers to power-on defaults. The part does not provide a
+	 * soft-reset function and the registers are not readable. This ensures
+	 * that the cache matches register contents even if the registers have
+	 * been previously initialized and not power cycled before probe.
+	 */
+	for (i = 0; i < ARRAY_SIZE(tda7419_regmap_defaults); i++)
+		regmap_write(tda7419->regmap,
+			     tda7419_regmap_defaults[i].reg,
+			     tda7419_regmap_defaults[i].def);
+
+	ret = devm_snd_soc_register_component(&i2c->dev,
+		&tda7419_component_driver, NULL, 0);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "error registering component: %d\n",
+				ret);
+	}
+
+	return ret;
+}
+
+static const struct i2c_device_id tda7419_i2c_id[] = {
+	{ "tda7419", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tda7419_i2c_id);
+
+static const struct of_device_id tda7419_of_match[] = {
+	{ .compatible = "st,tda7419" },
+	{ },
+};
+
+static struct i2c_driver tda7419_driver = {
+	.driver = {
+		.name   = "tda7419",
+		.of_match_table = tda7419_of_match,
+	},
+	.probe          = tda7419_probe,
+	.id_table       = tda7419_i2c_id,
+};
+
+module_i2c_driver(tda7419_driver);
+
+MODULE_AUTHOR("Matt Porter <mporter@konsulko.com>");
+MODULE_DESCRIPTION("TDA7419 audio processor driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c
index e7ca764..6d213c6 100644
--- a/sound/soc/codecs/tfa9879.c
+++ b/sound/soc/codecs/tfa9879.c
@@ -30,8 +30,8 @@ static int tfa9879_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tfa9879_priv *tfa9879 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tfa9879_priv *tfa9879 = snd_soc_component_get_drvdata(component);
 	int fs;
 	int i2s_set = 0;
 
@@ -88,11 +88,11 @@ static int tfa9879_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (tfa9879->lsb_justified)
-		snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
+		snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
 				    TFA9879_I2S_SET_MASK,
 				    i2s_set << TFA9879_I2S_SET_SHIFT);
 
-	snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
+	snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
 			    TFA9879_I2S_FS_MASK,
 			    fs << TFA9879_I2S_FS_SHIFT);
 	return 0;
@@ -100,9 +100,9 @@ static int tfa9879_hw_params(struct snd_pcm_substream *substream,
 
 static int tfa9879_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	snd_soc_update_bits(codec, TFA9879_MISC_CONTROL,
+	snd_soc_component_update_bits(component, TFA9879_MISC_CONTROL,
 			    TFA9879_S_MUTE_MASK,
 			    !!mute << TFA9879_S_MUTE_SHIFT);
 
@@ -111,8 +111,8 @@ static int tfa9879_digital_mute(struct snd_soc_dai *dai, int mute)
 
 static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tfa9879_priv *tfa9879 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tfa9879_priv *tfa9879 = snd_soc_component_get_drvdata(component);
 	int i2s_set;
 	int sck_pol;
 
@@ -151,10 +151,10 @@ static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
+	snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
 			    TFA9879_SCK_POL_MASK,
 			    sck_pol << TFA9879_SCK_POL_SHIFT);
-	snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
+	snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
 			    TFA9879_I2S_SET_MASK,
 			    i2s_set << TFA9879_I2S_SET_SHIFT);
 	return 0;
@@ -230,15 +230,17 @@ static const struct snd_soc_dapm_route tfa9879_dapm_routes[] = {
 	{ "DAC", NULL, "POWER" },
 };
 
-static const struct snd_soc_codec_driver tfa9879_codec = {
-	.component_driver = {
-		.controls		= tfa9879_controls,
-		.num_controls		= ARRAY_SIZE(tfa9879_controls),
-		.dapm_widgets		= tfa9879_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(tfa9879_dapm_widgets),
-		.dapm_routes		= tfa9879_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(tfa9879_dapm_routes),
-	},
+static const struct snd_soc_component_driver tfa9879_component = {
+	.controls		= tfa9879_controls,
+	.num_controls		= ARRAY_SIZE(tfa9879_controls),
+	.dapm_widgets		= tfa9879_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tfa9879_dapm_widgets),
+	.dapm_routes		= tfa9879_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tfa9879_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config tfa9879_regmap = {
@@ -295,17 +297,10 @@ static int tfa9879_i2c_probe(struct i2c_client *i2c,
 		regmap_write(tfa9879->regmap,
 			     tfa9879_regs[i].reg, tfa9879_regs[i].def);
 
-	return snd_soc_register_codec(&i2c->dev, &tfa9879_codec,
+	return devm_snd_soc_register_component(&i2c->dev, &tfa9879_component,
 				      &tfa9879_dai, 1);
 }
 
-static int tfa9879_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id tfa9879_i2c_id[] = {
 	{ "tfa9879", 0 },
 	{ }
@@ -324,7 +319,6 @@ static struct i2c_driver tfa9879_i2c_driver = {
 		.of_match_table = tfa9879_of_match,
 	},
 	.probe = tfa9879_i2c_probe,
-	.remove = tfa9879_i2c_remove,
 	.id_table = tfa9879_i2c_id,
 };
 
diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c
index 78a94af..1d7c117 100644
--- a/sound/soc/codecs/tlv320aic23-i2c.c
+++ b/sound/soc/codecs/tlv320aic23-i2c.c
@@ -31,12 +31,6 @@ static int tlv320aic23_i2c_probe(struct i2c_client *i2c,
 	return tlv320aic23_probe(&i2c->dev, regmap);
 }
 
-static int tlv320aic23_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-	return 0;
-}
-
 static const struct i2c_device_id tlv320aic23_id[] = {
 	{"tlv320aic23", 0},
 	{}
@@ -56,7 +50,6 @@ static struct i2c_driver tlv320aic23_i2c_driver = {
 		   .of_match_table = of_match_ptr(tlv320aic23_of_match),
 		   },
 	.probe = tlv320aic23_i2c_probe,
-	.remove = tlv320aic23_i2c_remove,
 	.id_table = tlv320aic23_id,
 };
 
diff --git a/sound/soc/codecs/tlv320aic23-spi.c b/sound/soc/codecs/tlv320aic23-spi.c
index f801ae0..d8c9ec1 100644
--- a/sound/soc/codecs/tlv320aic23-spi.c
+++ b/sound/soc/codecs/tlv320aic23-spi.c
@@ -34,18 +34,11 @@ static int aic23_spi_probe(struct spi_device *spi)
 	return tlv320aic23_probe(&spi->dev, regmap);
 }
 
-static int aic23_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver aic23_spi = {
 	.driver = {
 		.name = "tlv320aic23",
 	},
 	.probe = aic23_spi_probe,
-	.remove = aic23_spi_remove,
 };
 
 module_spi_driver(aic23_spi);
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 7490921..47480cb 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -82,7 +82,7 @@ static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
 static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	u16 val, reg;
 
 	val = (ucontrol->value.integer.value[0] & 0x07);
@@ -96,8 +96,8 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
 	*/
 	val = (val >= 4) ? 4  : (3 - val);
 
-	reg = snd_soc_read(codec, TLV320AIC23_ANLG) & (~0x1C0);
-	snd_soc_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
+	reg = snd_soc_component_read32(component, TLV320AIC23_ANLG) & (~0x1C0);
+	snd_soc_component_write(component, TLV320AIC23_ANLG, reg | (val << 6));
 
 	return 0;
 }
@@ -105,10 +105,10 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
 static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	u16 val;
 
-	val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0);
+	val = snd_soc_component_read32(component, TLV320AIC23_ANLG) & (0x1C0);
 	val = val >> 6;
 	val = (val >= 4) ? 4  : (3 -  val);
 	ucontrol->value.integer.value[0] = val;
@@ -296,10 +296,10 @@ static int find_rate(int mclk, u32 need_adc, u32 need_dac)
 }
 
 #ifdef DEBUG
-static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
+static void get_current_sample_rates(struct snd_soc_component *component, int mclk,
 		u32 *sample_rate_adc, u32 *sample_rate_dac)
 {
-	int src = snd_soc_read(codec, TLV320AIC23_SRATE);
+	int src = snd_soc_component_read32(component, TLV320AIC23_SRATE);
 	int sr = (src >> 2) & 0x0f;
 	int val = (mclk / bosr_usb_divisor_table[src & 3]);
 	int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
@@ -313,7 +313,7 @@ static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
 }
 #endif
 
-static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
+static int set_sample_rate_control(struct snd_soc_component *component, int mclk,
 		u32 sample_rate_adc, u32 sample_rate_dac)
 {
 	/* Search for the right sample rate */
@@ -323,11 +323,11 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
 				__func__, sample_rate_adc, sample_rate_dac);
 		return -EINVAL;
 	}
-	snd_soc_write(codec, TLV320AIC23_SRATE, data);
+	snd_soc_component_write(component, TLV320AIC23_SRATE, data);
 #ifdef DEBUG
 	{
 		u32 adc, dac;
-		get_current_sample_rates(codec, mclk, &adc, &dac);
+		get_current_sample_rates(component, mclk, &adc, &dac);
 		printk(KERN_DEBUG "actual samplerate = %u,%u reg=%x\n",
 			adc, dac, data);
 	}
@@ -339,10 +339,10 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 iface_reg;
 	int ret;
-	struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
+	struct aic23 *aic23 = snd_soc_component_get_drvdata(component);
 	u32 sample_rate_adc = aic23->requested_adc;
 	u32 sample_rate_dac = aic23->requested_dac;
 	u32 sample_rate = params_rate(params);
@@ -356,12 +356,12 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
 		if (!sample_rate_dac)
 			sample_rate_dac = sample_rate;
 	}
-	ret = set_sample_rate_control(codec, aic23->mclk, sample_rate_adc,
+	ret = set_sample_rate_control(component, aic23->mclk, sample_rate_adc,
 			sample_rate_dac);
 	if (ret < 0)
 		return ret;
 
-	iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
+	iface_reg = snd_soc_component_read32(component, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
 
 	switch (params_width(params)) {
 	case 16:
@@ -376,7 +376,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
 		iface_reg |= (0x03 << 2);
 		break;
 	}
-	snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
+	snd_soc_component_write(component, TLV320AIC23_DIGT_FMT, iface_reg);
 
 	return 0;
 }
@@ -384,10 +384,10 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
 static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
 				   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	/* set active */
-	snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
+	snd_soc_component_write(component, TLV320AIC23_ACTIVE, 0x0001);
 
 	return 0;
 }
@@ -395,13 +395,13 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
 static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct aic23 *aic23 = snd_soc_component_get_drvdata(component);
 
 	/* deactivate */
-	if (!snd_soc_codec_is_active(codec)) {
+	if (!snd_soc_component_is_active(component)) {
 		udelay(50);
-		snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
+		snd_soc_component_write(component, TLV320AIC23_ACTIVE, 0x0);
 	}
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		aic23->requested_dac = 0;
@@ -411,17 +411,17 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
 
 static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 reg;
 
-	reg = snd_soc_read(codec, TLV320AIC23_DIGT);
+	reg = snd_soc_component_read32(component, TLV320AIC23_DIGT);
 	if (mute)
 		reg |= TLV320AIC23_DACM_MUTE;
 
 	else
 		reg &= ~TLV320AIC23_DACM_MUTE;
 
-	snd_soc_write(codec, TLV320AIC23_DIGT, reg);
+	snd_soc_component_write(component, TLV320AIC23_DIGT, reg);
 
 	return 0;
 }
@@ -429,10 +429,10 @@ static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
 static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
 				   unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface_reg;
 
-	iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
+	iface_reg = snd_soc_component_read32(component, TLV320AIC23_DIGT_FMT) & (~0x03);
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -468,7 +468,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 	}
 
-	snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
+	snd_soc_component_write(component, TLV320AIC23_DIGT_FMT, iface_reg);
 
 	return 0;
 }
@@ -481,29 +481,29 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
+static int tlv320aic23_set_bias_level(struct snd_soc_component *component,
 				      enum snd_soc_bias_level level)
 {
-	u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0x17f;
+	u16 reg = snd_soc_component_read32(component, TLV320AIC23_PWR) & 0x17f;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		/* vref/mid, osc on, dac unmute */
 		reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
 			TLV320AIC23_DAC_OFF);
-		snd_soc_write(codec, TLV320AIC23_PWR, reg);
+		snd_soc_component_write(component, TLV320AIC23_PWR, reg);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* everything off except vref/vmid, */
-		snd_soc_write(codec, TLV320AIC23_PWR,
+		snd_soc_component_write(component, TLV320AIC23_PWR,
 			      reg | TLV320AIC23_CLK_OFF);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* everything off, dac mute, inactive */
-		snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
-		snd_soc_write(codec, TLV320AIC23_PWR, 0x1ff);
+		snd_soc_component_write(component, TLV320AIC23_ACTIVE, 0x0);
+		snd_soc_component_write(component, TLV320AIC23_PWR, 0x1ff);
 		break;
 	}
 	return 0;
@@ -539,58 +539,59 @@ static struct snd_soc_dai_driver tlv320aic23_dai = {
 	.ops = &tlv320aic23_dai_ops,
 };
 
-static int tlv320aic23_resume(struct snd_soc_codec *codec)
+static int tlv320aic23_resume(struct snd_soc_component *component)
 {
-	struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
+	struct aic23 *aic23 = snd_soc_component_get_drvdata(component);
 	regcache_mark_dirty(aic23->regmap);
 	regcache_sync(aic23->regmap);
 
 	return 0;
 }
 
-static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
+static int tlv320aic23_component_probe(struct snd_soc_component *component)
 {
 	/* Reset codec */
-	snd_soc_write(codec, TLV320AIC23_RESET, 0);
+	snd_soc_component_write(component, TLV320AIC23_RESET, 0);
 
-	snd_soc_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
+	snd_soc_component_write(component, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
 
 	/* Unmute input */
-	snd_soc_update_bits(codec, TLV320AIC23_LINVOL,
+	snd_soc_component_update_bits(component, TLV320AIC23_LINVOL,
 			    TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
 
-	snd_soc_update_bits(codec, TLV320AIC23_RINVOL,
+	snd_soc_component_update_bits(component, TLV320AIC23_RINVOL,
 			    TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
 
-	snd_soc_update_bits(codec, TLV320AIC23_ANLG,
+	snd_soc_component_update_bits(component, TLV320AIC23_ANLG,
 			    TLV320AIC23_BYPASS_ON | TLV320AIC23_MICM_MUTED,
 			    0);
 
 	/* Default output volume */
-	snd_soc_write(codec, TLV320AIC23_LCHNVOL,
+	snd_soc_component_write(component, TLV320AIC23_LCHNVOL,
 		      TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
-	snd_soc_write(codec, TLV320AIC23_RCHNVOL,
+	snd_soc_component_write(component, TLV320AIC23_RCHNVOL,
 		      TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
 
-	snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
+	snd_soc_component_write(component, TLV320AIC23_ACTIVE, 0x1);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
-	.probe = tlv320aic23_codec_probe,
-	.resume = tlv320aic23_resume,
-	.set_bias_level = tlv320aic23_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= tlv320aic23_snd_controls,
-		.num_controls		= ARRAY_SIZE(tlv320aic23_snd_controls),
-		.dapm_widgets		= tlv320aic23_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(tlv320aic23_dapm_widgets),
-		.dapm_routes		= tlv320aic23_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(tlv320aic23_intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_tlv320aic23 = {
+	.probe			= tlv320aic23_component_probe,
+	.resume			= tlv320aic23_resume,
+	.set_bias_level		= tlv320aic23_set_bias_level,
+	.controls		= tlv320aic23_snd_controls,
+	.num_controls		= ARRAY_SIZE(tlv320aic23_snd_controls),
+	.dapm_widgets		= tlv320aic23_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tlv320aic23_dapm_widgets),
+	.dapm_routes		= tlv320aic23_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(tlv320aic23_intercon),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
@@ -608,7 +609,8 @@ int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
 
 	dev_set_drvdata(dev, aic23);
 
-	return snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23,
+	return devm_snd_soc_register_component(dev,
+				      &soc_component_dev_tlv320aic23,
 				      &tlv320aic23_dai, 1);
 }
 EXPORT_SYMBOL(tlv320aic23_probe);
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 89421ca..b91b8d5f 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -30,7 +30,7 @@ MODULE_LICENSE("GPL");
 struct aic26 {
 	struct spi_device *spi;
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	int master;
 	int datfm;
 	int mclk;
@@ -64,8 +64,8 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
 			   struct snd_pcm_hw_params *params,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
 	int fsref, divisor, wlen, pval, jval, dval, qval;
 	u16 reg;
 
@@ -112,20 +112,20 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
 	dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval);
 	qval = 0;
 	reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
-	snd_soc_write(codec, AIC26_REG_PLL_PROG1, reg);
+	snd_soc_component_write(component, AIC26_REG_PLL_PROG1, reg);
 	reg = dval << 2;
-	snd_soc_write(codec, AIC26_REG_PLL_PROG2, reg);
+	snd_soc_component_write(component, AIC26_REG_PLL_PROG2, reg);
 
 	/* Audio Control 3 (master mode, fsref rate) */
 	if (aic26->master)
 		reg = 0x0800;
 	if (fsref == 48000)
 		reg = 0x2000;
-	snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL3, 0xf800, reg);
+	snd_soc_component_update_bits(component, AIC26_REG_AUDIO_CTRL3, 0xf800, reg);
 
 	/* Audio Control 1 (FSref divisor) */
 	reg = wlen | aic26->datfm | (divisor << 3) | divisor;
-	snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL1, 0xfff, reg);
+	snd_soc_component_update_bits(component, AIC26_REG_AUDIO_CTRL1, 0xfff, reg);
 
 	return 0;
 }
@@ -135,8 +135,8 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
  */
 static int aic26_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
 	u16 reg;
 
 	dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
@@ -146,7 +146,7 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute)
 		reg = 0x8080;
 	else
 		reg = 0;
-	snd_soc_update_bits(codec, AIC26_REG_DAC_GAIN, 0x8000, reg);
+	snd_soc_component_update_bits(component, AIC26_REG_DAC_GAIN, 0x8000, reg);
 
 	return 0;
 }
@@ -154,8 +154,8 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute)
 static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
 			    int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
 
 	dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
 		" freq=%i, dir=%i)\n",
@@ -171,8 +171,8 @@ static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
 
 static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
 
 	dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
 		codec_dai, fmt);
@@ -265,7 +265,7 @@ static ssize_t aic26_keyclick_show(struct device *dev,
 	struct aic26 *aic26 = dev_get_drvdata(dev);
 	int val, amp, freq, len;
 
-	val = snd_soc_read(aic26->codec, AIC26_REG_AUDIO_CTRL2);
+	val = snd_soc_component_read32(aic26->component, AIC26_REG_AUDIO_CTRL2);
 	amp = (val >> 12) & 0x7;
 	freq = (125 << ((val >> 8) & 0x7)) >> 1;
 	len = 2 * (1 + ((val >> 4) & 0xf));
@@ -280,7 +280,7 @@ static ssize_t aic26_keyclick_set(struct device *dev,
 {
 	struct aic26 *aic26 = dev_get_drvdata(dev);
 
-	snd_soc_update_bits(aic26->codec, AIC26_REG_AUDIO_CTRL2,
+	snd_soc_component_update_bits(aic26->component, AIC26_REG_AUDIO_CTRL2,
 			    0x8000, 0x800);
 
 	return count;
@@ -291,44 +291,46 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
 /* ---------------------------------------------------------------------
  * SoC CODEC portion of driver: probe and release routines
  */
-static int aic26_probe(struct snd_soc_codec *codec)
+static int aic26_probe(struct snd_soc_component *component)
 {
-	struct aic26 *aic26 = dev_get_drvdata(codec->dev);
+	struct aic26 *aic26 = dev_get_drvdata(component->dev);
 	int ret, reg;
 
-	aic26->codec = codec;
+	aic26->component = component;
 
 	/* Reset the codec to power on defaults */
-	snd_soc_write(codec, AIC26_REG_RESET, 0xBB00);
+	snd_soc_component_write(component, AIC26_REG_RESET, 0xBB00);
 
 	/* Power up CODEC */
-	snd_soc_write(codec, AIC26_REG_POWER_CTRL, 0);
+	snd_soc_component_write(component, AIC26_REG_POWER_CTRL, 0);
 
 	/* Audio Control 3 (master mode, fsref rate) */
-	reg = snd_soc_read(codec, AIC26_REG_AUDIO_CTRL3);
+	reg = snd_soc_component_read32(component, AIC26_REG_AUDIO_CTRL3);
 	reg &= ~0xf800;
 	reg |= 0x0800; /* set master mode */
-	snd_soc_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
+	snd_soc_component_write(component, AIC26_REG_AUDIO_CTRL3, reg);
 
 	/* Register the sysfs files for debugging */
 	/* Create SysFS files */
-	ret = device_create_file(codec->dev, &dev_attr_keyclick);
+	ret = device_create_file(component->dev, &dev_attr_keyclick);
 	if (ret)
-		dev_info(codec->dev, "error creating sysfs files\n");
+		dev_info(component->dev, "error creating sysfs files\n");
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver aic26_soc_codec_dev = {
-	.probe = aic26_probe,
-	.component_driver = {
-		.controls		= aic26_snd_controls,
-		.num_controls		= ARRAY_SIZE(aic26_snd_controls),
-		.dapm_widgets		= tlv320aic26_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(tlv320aic26_dapm_widgets),
-		.dapm_routes		= tlv320aic26_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(tlv320aic26_dapm_routes),
-	},
+static const struct snd_soc_component_driver aic26_soc_component_dev = {
+	.probe			= aic26_probe,
+	.controls		= aic26_snd_controls,
+	.num_controls		= ARRAY_SIZE(aic26_snd_controls),
+	.dapm_widgets		= tlv320aic26_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tlv320aic26_dapm_widgets),
+	.dapm_routes		= tlv320aic26_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tlv320aic26_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config aic26_regmap = {
@@ -361,23 +363,16 @@ static int aic26_spi_probe(struct spi_device *spi)
 	dev_set_drvdata(&spi->dev, aic26);
 	aic26->master = 1;
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&aic26_soc_codec_dev, &aic26_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&aic26_soc_component_dev, &aic26_dai, 1);
 	return ret;
 }
 
-static int aic26_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver aic26_spi = {
 	.driver = {
 		.name = "tlv320aic26-codec",
 	},
 	.probe = aic26_spi_probe,
-	.remove = aic26_spi_remove,
 };
 
 module_spi_driver(aic26_spi);
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 858cb8b..bf92d36 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -153,7 +153,7 @@ struct aic31xx_disable_nb {
 };
 
 struct aic31xx_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	u8 i2c_regs_status;
 	struct device *dev;
 	struct regmap *regmap;
@@ -166,6 +166,7 @@ struct aic31xx_priv {
 	unsigned int sysclk;
 	u8 p_div;
 	int rate_div_line;
+	bool master_dapm_route_applied;
 };
 
 struct aic31xx_rate_divs {
@@ -348,8 +349,8 @@ static int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg,
 static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
 				    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 	unsigned int reg = AIC31XX_DACFLAG1;
 	unsigned int mask;
 
@@ -377,7 +378,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
 		reg = AIC31XX_ADCFLAG;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown widget '%s' calling %s\n",
+		dev_err(component->dev, "Unknown widget '%s' calling %s\n",
 			w->name, __func__);
 		return -EINVAL;
 	}
@@ -388,7 +389,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_POST_PMD:
 		return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100);
 	default:
-		dev_dbg(codec->dev,
+		dev_dbg(component->dev,
 			"Unhandled dapm widget event %d from %s\n",
 			event, w->name);
 	}
@@ -444,30 +445,30 @@ static const struct snd_kcontrol_new aic31xx_dapm_spr_switch =
 static int mic_bias_event(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* change mic bias voltage to user defined */
-		snd_soc_update_bits(codec, AIC31XX_MICBIAS,
+		snd_soc_component_update_bits(component, AIC31XX_MICBIAS,
 				    AIC31XX_MICBIAS_MASK,
 				    aic31xx->micbias_vg <<
 				    AIC31XX_MICBIAS_SHIFT);
-		dev_dbg(codec->dev, "%s: turned on\n", __func__);
+		dev_dbg(component->dev, "%s: turned on\n", __func__);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
 		/* turn mic bias off */
-		snd_soc_update_bits(codec, AIC31XX_MICBIAS,
+		snd_soc_component_update_bits(component, AIC31XX_MICBIAS,
 				    AIC31XX_MICBIAS_MASK, 0);
-		dev_dbg(codec->dev, "%s: turned off\n", __func__);
+		dev_dbg(component->dev, "%s: turned off\n", __func__);
 		break;
 	}
 	return 0;
 }
 
 static const struct snd_soc_dapm_widget common31xx_dapm_widgets[] = {
-	SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("AIF IN", "Playback", 0, SND_SOC_NOPM, 0, 0),
 
 	SND_SOC_DAPM_MUX("DAC Left Input",
 			 SND_SOC_NOPM, 0, 0, &ldac_in_control),
@@ -500,6 +501,10 @@ static const struct snd_soc_dapm_widget common31xx_dapm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event,
 			    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
+	/* Keep BCLK/WCLK enabled even if DAC/ADC is powered down */
+	SND_SOC_DAPM_SUPPLY("Activate I2S clocks", AIC31XX_IFACE2, 2, 0,
+			    NULL, 0),
+
 	/* Outputs */
 	SND_SOC_DAPM_OUTPUT("HPL"),
 	SND_SOC_DAPM_OUTPUT("HPR"),
@@ -552,6 +557,8 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
 	SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0,
 			   aic31xx_right_output_switches,
 			   ARRAY_SIZE(aic31xx_right_output_switches)),
+
+	SND_SOC_DAPM_AIF_OUT("AIF OUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
 };
 
 static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = {
@@ -583,12 +590,12 @@ static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = {
 static const struct snd_soc_dapm_route
 common31xx_audio_map[] = {
 	/* DAC Input Routing */
-	{"DAC Left Input", "Left Data", "DAC IN"},
-	{"DAC Left Input", "Right Data", "DAC IN"},
-	{"DAC Left Input", "Mono", "DAC IN"},
-	{"DAC Right Input", "Left Data", "DAC IN"},
-	{"DAC Right Input", "Right Data", "DAC IN"},
-	{"DAC Right Input", "Mono", "DAC IN"},
+	{"DAC Left Input", "Left Data", "AIF IN"},
+	{"DAC Left Input", "Right Data", "AIF IN"},
+	{"DAC Left Input", "Mono", "AIF IN"},
+	{"DAC Right Input", "Left Data", "AIF IN"},
+	{"DAC Right Input", "Right Data", "AIF IN"},
+	{"DAC Right Input", "Mono", "AIF IN"},
 	{"DAC Left", NULL, "DAC Left Input"},
 	{"DAC Right", NULL, "DAC Right Input"},
 
@@ -639,6 +646,8 @@ aic31xx_audio_map[] = {
 
 	{"ADC", NULL, "MIC_GAIN_CTL"},
 
+	{"AIF OUT", NULL, "ADC"},
+
 	/* Left Output */
 	{"Output Left", "From Left DAC", "DAC Left"},
 	{"Output Left", "From MIC1LP", "MIC1LP"},
@@ -670,34 +679,61 @@ aic310x_audio_map[] = {
 	{"SPK", NULL, "SPK ClassD"},
 };
 
-static int aic31xx_add_controls(struct snd_soc_codec *codec)
+/*
+ * Always connected DAPM routes for codec clock master modes.
+ * If the codec is the master on the I2S bus, we need to power up components
+ * to have valid DAC_CLK.
+ *
+ * In order to have the I2S clocks on the bus either the DACs/ADC need to be
+ * enabled, or the P0/R29/D2 (Keep bclk/wclk in power down) need to be set.
+ *
+ * Otherwise the codec will not generate clocks on the bus.
+ */
+static const struct snd_soc_dapm_route
+common31xx_cm_audio_map[] = {
+	{"HPL", NULL, "AIF IN"},
+	{"HPR", NULL, "AIF IN"},
+
+	{"AIF IN", NULL, "Activate I2S clocks"},
+};
+
+static const struct snd_soc_dapm_route
+aic31xx_cm_audio_map[] = {
+	{"AIF OUT", NULL, "MIC1LP"},
+	{"AIF OUT", NULL, "MIC1RP"},
+	{"AIF OUT", NULL, "MIC1LM"},
+
+	{"AIF OUT", NULL, "Activate I2S clocks"},
+};
+
+static int aic31xx_add_controls(struct snd_soc_component *component)
 {
 	int ret = 0;
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 
 	if (!(aic31xx->codec_type & DAC31XX_BIT))
-		ret = snd_soc_add_codec_controls(
-			codec, aic31xx_snd_controls,
+		ret = snd_soc_add_component_controls(
+			component, aic31xx_snd_controls,
 			ARRAY_SIZE(aic31xx_snd_controls));
 	if (ret)
 		return ret;
 
 	if (aic31xx->codec_type & AIC31XX_STEREO_CLASS_D_BIT)
-		ret = snd_soc_add_codec_controls(
-			codec, aic311x_snd_controls,
+		ret = snd_soc_add_component_controls(
+			component, aic311x_snd_controls,
 			ARRAY_SIZE(aic311x_snd_controls));
 	else
-		ret = snd_soc_add_codec_controls(
-			codec, aic310x_snd_controls,
+		ret = snd_soc_add_component_controls(
+			component, aic310x_snd_controls,
 			ARRAY_SIZE(aic310x_snd_controls));
 
 	return ret;
 }
 
-static int aic31xx_add_widgets(struct snd_soc_codec *codec)
+static int aic31xx_add_widgets(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	if (aic31xx->codec_type & DAC31XX_BIT) {
@@ -751,10 +787,10 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int aic31xx_setup_pll(struct snd_soc_codec *codec,
+static int aic31xx_setup_pll(struct snd_soc_component *component,
 			     struct snd_pcm_hw_params *params)
 {
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 	int bclk_score = snd_soc_params_to_frame_size(params);
 	int mclk_p;
 	int bclk_n = 0;
@@ -762,15 +798,15 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
 	int i;
 
 	if (!aic31xx->sysclk || !aic31xx->p_div) {
-		dev_err(codec->dev, "Master clock not supplied\n");
+		dev_err(component->dev, "Master clock not supplied\n");
 		return -EINVAL;
 	}
 	mclk_p = aic31xx->sysclk / aic31xx->p_div;
 
 	/* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */
-	snd_soc_update_bits(codec, AIC31XX_CLKMUX,
+	snd_soc_component_update_bits(component, AIC31XX_CLKMUX,
 			    AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL);
-	snd_soc_update_bits(codec, AIC31XX_IFACE2,
+	snd_soc_component_update_bits(component, AIC31XX_IFACE2,
 			    AIC31XX_BDIVCLK_MASK, AIC31XX_DAC2BCLK);
 
 	for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) {
@@ -789,14 +825,14 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
 	}
 
 	if (match == -1) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"%s: Sample rate (%u) and format not supported\n",
 			__func__, params_rate(params));
 		/* See bellow for details how fix this. */
 		return -EINVAL;
 	}
 	if (bclk_score != 0) {
-		dev_warn(codec->dev, "Can not produce exact bitclock");
+		dev_warn(component->dev, "Can not produce exact bitclock");
 		/* This is fine if using dsp format, but if using i2s
 		   there may be trouble. To fix the issue edit the
 		   aic31xx_divs table for your mclk and sample
@@ -808,39 +844,39 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
 	i = match;
 
 	/* PLL configuration */
-	snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
+	snd_soc_component_update_bits(component, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
 			    (aic31xx->p_div << 4) | 0x01);
-	snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j);
+	snd_soc_component_write(component, AIC31XX_PLLJ, aic31xx_divs[i].pll_j);
 
-	snd_soc_write(codec, AIC31XX_PLLDMSB,
+	snd_soc_component_write(component, AIC31XX_PLLDMSB,
 		      aic31xx_divs[i].pll_d >> 8);
-	snd_soc_write(codec, AIC31XX_PLLDLSB,
+	snd_soc_component_write(component, AIC31XX_PLLDLSB,
 		      aic31xx_divs[i].pll_d & 0xff);
 
 	/* DAC dividers configuration */
-	snd_soc_update_bits(codec, AIC31XX_NDAC, AIC31XX_PLL_MASK,
+	snd_soc_component_update_bits(component, AIC31XX_NDAC, AIC31XX_PLL_MASK,
 			    aic31xx_divs[i].ndac);
-	snd_soc_update_bits(codec, AIC31XX_MDAC, AIC31XX_PLL_MASK,
+	snd_soc_component_update_bits(component, AIC31XX_MDAC, AIC31XX_PLL_MASK,
 			    aic31xx_divs[i].mdac);
 
-	snd_soc_write(codec, AIC31XX_DOSRMSB, aic31xx_divs[i].dosr >> 8);
-	snd_soc_write(codec, AIC31XX_DOSRLSB, aic31xx_divs[i].dosr & 0xff);
+	snd_soc_component_write(component, AIC31XX_DOSRMSB, aic31xx_divs[i].dosr >> 8);
+	snd_soc_component_write(component, AIC31XX_DOSRLSB, aic31xx_divs[i].dosr & 0xff);
 
 	/* ADC dividers configuration. Write reset value 1 if not used. */
-	snd_soc_update_bits(codec, AIC31XX_NADC, AIC31XX_PLL_MASK,
+	snd_soc_component_update_bits(component, AIC31XX_NADC, AIC31XX_PLL_MASK,
 			    aic31xx_divs[i].nadc ? aic31xx_divs[i].nadc : 1);
-	snd_soc_update_bits(codec, AIC31XX_MADC, AIC31XX_PLL_MASK,
+	snd_soc_component_update_bits(component, AIC31XX_MADC, AIC31XX_PLL_MASK,
 			    aic31xx_divs[i].madc ? aic31xx_divs[i].madc : 1);
 
-	snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr);
+	snd_soc_component_write(component, AIC31XX_AOSR, aic31xx_divs[i].aosr);
 
 	/* Bit clock divider configuration. */
-	snd_soc_update_bits(codec, AIC31XX_BCLKN,
+	snd_soc_component_update_bits(component, AIC31XX_BCLKN,
 			    AIC31XX_PLL_MASK, bclk_n);
 
 	aic31xx->rate_div_line = i;
 
-	dev_dbg(codec->dev,
+	dev_dbg(component->dev,
 		"pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n",
 		aic31xx_divs[i].pll_j,
 		aic31xx_divs[i].pll_d,
@@ -861,10 +897,10 @@ static int aic31xx_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u8 data = 0;
 
-	dev_dbg(codec->dev, "## %s: width %d rate %d\n",
+	dev_dbg(component->dev, "## %s: width %d rate %d\n",
 		__func__, params_width(params),
 		params_rate(params));
 
@@ -884,43 +920,90 @@ static int aic31xx_hw_params(struct snd_pcm_substream *substream,
 			AIC31XX_IFACE1_DATALEN_SHIFT);
 		break;
 	default:
-		dev_err(codec->dev, "%s: Unsupported width %d\n",
+		dev_err(component->dev, "%s: Unsupported width %d\n",
 			__func__, params_width(params));
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, AIC31XX_IFACE1,
+	snd_soc_component_update_bits(component, AIC31XX_IFACE1,
 			    AIC31XX_IFACE1_DATALEN_MASK,
 			    data);
 
-	return aic31xx_setup_pll(codec, params);
+	return aic31xx_setup_pll(component, params);
 }
 
 static int aic31xx_dac_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	if (mute) {
-		snd_soc_update_bits(codec, AIC31XX_DACMUTE,
+		snd_soc_component_update_bits(component, AIC31XX_DACMUTE,
 				    AIC31XX_DACMUTE_MASK,
 				    AIC31XX_DACMUTE_MASK);
 	} else {
-		snd_soc_update_bits(codec, AIC31XX_DACMUTE,
+		snd_soc_component_update_bits(component, AIC31XX_DACMUTE,
 				    AIC31XX_DACMUTE_MASK, 0x0);
 	}
 
 	return 0;
 }
 
+static int aic31xx_clock_master_routes(struct snd_soc_component *component,
+				       unsigned int fmt)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
+	int ret;
+
+	fmt &= SND_SOC_DAIFMT_MASTER_MASK;
+	if (fmt == SND_SOC_DAIFMT_CBS_CFS &&
+	    aic31xx->master_dapm_route_applied) {
+		/*
+		 * Remove the DAPM route(s) for codec clock master modes,
+		 * if applied
+		 */
+		ret = snd_soc_dapm_del_routes(dapm, common31xx_cm_audio_map,
+					ARRAY_SIZE(common31xx_cm_audio_map));
+		if (!ret && !(aic31xx->codec_type & DAC31XX_BIT))
+			ret = snd_soc_dapm_del_routes(dapm,
+					aic31xx_cm_audio_map,
+					ARRAY_SIZE(aic31xx_cm_audio_map));
+
+		if (ret)
+			return ret;
+
+		aic31xx->master_dapm_route_applied = false;
+	} else if (fmt != SND_SOC_DAIFMT_CBS_CFS &&
+		   !aic31xx->master_dapm_route_applied) {
+		/*
+		 * Add the needed DAPM route(s) for codec clock master modes,
+		 * if it is not done already
+		 */
+		ret = snd_soc_dapm_add_routes(dapm, common31xx_cm_audio_map,
+					ARRAY_SIZE(common31xx_cm_audio_map));
+		if (!ret && !(aic31xx->codec_type & DAC31XX_BIT))
+			ret = snd_soc_dapm_add_routes(dapm,
+					aic31xx_cm_audio_map,
+					ARRAY_SIZE(aic31xx_cm_audio_map));
+
+		if (ret)
+			return ret;
+
+		aic31xx->master_dapm_route_applied = true;
+	}
+
+	return 0;
+}
+
 static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			       unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u8 iface_reg1 = 0;
 	u8 iface_reg2 = 0;
 	u8 dsp_a_val = 0;
 
-	dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt);
+	dev_dbg(component->dev, "## %s: fmt = 0x%x\n", __func__, fmt);
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -936,7 +1019,7 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	case SND_SOC_DAIFMT_CBS_CFS:
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI master/slave interface\n");
+		dev_err(component->dev, "Invalid DAI master/slave interface\n");
 		return -EINVAL;
 	}
 
@@ -948,7 +1031,7 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		iface_reg2 |= AIC31XX_BCLKINV_MASK;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI clock signal polarity\n");
+		dev_err(component->dev, "Invalid DAI clock signal polarity\n");
 		return -EINVAL;
 	}
 
@@ -977,32 +1060,32 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			       AIC31XX_IFACE1_DATATYPE_SHIFT);
 		break;
 	default:
-		dev_err(codec->dev, "Invalid DAI interface format\n");
+		dev_err(component->dev, "Invalid DAI interface format\n");
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, AIC31XX_IFACE1,
+	snd_soc_component_update_bits(component, AIC31XX_IFACE1,
 			    AIC31XX_IFACE1_DATATYPE_MASK |
 			    AIC31XX_IFACE1_MASTER_MASK,
 			    iface_reg1);
-	snd_soc_update_bits(codec, AIC31XX_DATA_OFFSET,
+	snd_soc_component_update_bits(component, AIC31XX_DATA_OFFSET,
 			    AIC31XX_DATA_OFFSET_MASK,
 			    dsp_a_val);
-	snd_soc_update_bits(codec, AIC31XX_IFACE2,
+	snd_soc_component_update_bits(component, AIC31XX_IFACE2,
 			    AIC31XX_BCLKINV_MASK,
 			    iface_reg2);
 
-	return 0;
+	return aic31xx_clock_master_routes(component, fmt);
 }
 
 static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				  int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 	int i;
 
-	dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n",
+	dev_dbg(component->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n",
 		__func__, clk_id, freq, dir);
 
 	for (i = 1; i < 8; i++)
@@ -1025,7 +1108,7 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	}
 
 	/* set clock on MCLK, BCLK, or GPIO1 as PLL input */
-	snd_soc_update_bits(codec, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
+	snd_soc_component_update_bits(component, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
 			    clk_id << AIC31XX_PLL_CLKIN_SHIFT);
 
 	aic31xx->sysclk = freq;
@@ -1071,42 +1154,42 @@ static int aic31xx_reset(struct aic31xx_priv *aic31xx)
 	return ret;
 }
 
-static void aic31xx_clk_on(struct snd_soc_codec *codec)
+static void aic31xx_clk_on(struct snd_soc_component *component)
 {
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 	u8 mask = AIC31XX_PM_MASK;
 	u8 on = AIC31XX_PM_MASK;
 
-	dev_dbg(codec->dev, "codec clock -> on (rate %d)\n",
+	dev_dbg(component->dev, "codec clock -> on (rate %d)\n",
 		aic31xx_divs[aic31xx->rate_div_line].rate);
-	snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, on);
+	snd_soc_component_update_bits(component, AIC31XX_PLLPR, mask, on);
 	mdelay(10);
-	snd_soc_update_bits(codec, AIC31XX_NDAC, mask, on);
-	snd_soc_update_bits(codec, AIC31XX_MDAC, mask, on);
+	snd_soc_component_update_bits(component, AIC31XX_NDAC, mask, on);
+	snd_soc_component_update_bits(component, AIC31XX_MDAC, mask, on);
 	if (aic31xx_divs[aic31xx->rate_div_line].nadc)
-		snd_soc_update_bits(codec, AIC31XX_NADC, mask, on);
+		snd_soc_component_update_bits(component, AIC31XX_NADC, mask, on);
 	if (aic31xx_divs[aic31xx->rate_div_line].madc)
-		snd_soc_update_bits(codec, AIC31XX_MADC, mask, on);
-	snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, on);
+		snd_soc_component_update_bits(component, AIC31XX_MADC, mask, on);
+	snd_soc_component_update_bits(component, AIC31XX_BCLKN, mask, on);
 }
 
-static void aic31xx_clk_off(struct snd_soc_codec *codec)
+static void aic31xx_clk_off(struct snd_soc_component *component)
 {
 	u8 mask = AIC31XX_PM_MASK;
 	u8 off = 0;
 
-	dev_dbg(codec->dev, "codec clock -> off\n");
-	snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, off);
-	snd_soc_update_bits(codec, AIC31XX_MADC, mask, off);
-	snd_soc_update_bits(codec, AIC31XX_NADC, mask, off);
-	snd_soc_update_bits(codec, AIC31XX_MDAC, mask, off);
-	snd_soc_update_bits(codec, AIC31XX_NDAC, mask, off);
-	snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, off);
+	dev_dbg(component->dev, "codec clock -> off\n");
+	snd_soc_component_update_bits(component, AIC31XX_BCLKN, mask, off);
+	snd_soc_component_update_bits(component, AIC31XX_MADC, mask, off);
+	snd_soc_component_update_bits(component, AIC31XX_NADC, mask, off);
+	snd_soc_component_update_bits(component, AIC31XX_MDAC, mask, off);
+	snd_soc_component_update_bits(component, AIC31XX_NDAC, mask, off);
+	snd_soc_component_update_bits(component, AIC31XX_PLLPR, mask, off);
 }
 
-static int aic31xx_power_on(struct snd_soc_codec *codec)
+static int aic31xx_power_on(struct snd_soc_component *component)
 {
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies),
@@ -1123,7 +1206,7 @@ static int aic31xx_power_on(struct snd_soc_codec *codec)
 
 	ret = regcache_sync(aic31xx->regmap);
 	if (ret) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Failed to restore cache: %d\n", ret);
 		regcache_cache_only(aic31xx->regmap, true);
 		regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
@@ -1134,57 +1217,57 @@ static int aic31xx_power_on(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static void aic31xx_power_off(struct snd_soc_codec *codec)
+static void aic31xx_power_off(struct snd_soc_component *component)
 {
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 
 	regcache_cache_only(aic31xx->regmap, true);
 	regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
 			       aic31xx->supplies);
 }
 
-static int aic31xx_set_bias_level(struct snd_soc_codec *codec,
+static int aic31xx_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__,
-		snd_soc_codec_get_bias_level(codec), level);
+	dev_dbg(component->dev, "## %s: %d -> %d\n", __func__,
+		snd_soc_component_get_bias_level(component), level);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
 	case SND_SOC_BIAS_PREPARE:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY)
-			aic31xx_clk_on(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY)
+			aic31xx_clk_on(component);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		switch (snd_soc_codec_get_bias_level(codec)) {
+		switch (snd_soc_component_get_bias_level(component)) {
 		case SND_SOC_BIAS_OFF:
-			aic31xx_power_on(codec);
+			aic31xx_power_on(component);
 			break;
 		case SND_SOC_BIAS_PREPARE:
-			aic31xx_clk_off(codec);
+			aic31xx_clk_off(component);
 			break;
 		default:
 			BUG();
 		}
 		break;
 	case SND_SOC_BIAS_OFF:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY)
-			aic31xx_power_off(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY)
+			aic31xx_power_off(component);
 		break;
 	}
 
 	return 0;
 }
 
-static int aic31xx_codec_probe(struct snd_soc_codec *codec)
+static int aic31xx_codec_probe(struct snd_soc_component *component)
 {
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 	int i, ret;
 
 	dev_dbg(aic31xx->dev, "## %s\n", __func__);
 
-	aic31xx->codec = codec;
+	aic31xx->component = component;
 
 	for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) {
 		aic31xx->disable_nb[i].nb.notifier_call =
@@ -1193,7 +1276,7 @@ static int aic31xx_codec_probe(struct snd_soc_codec *codec)
 		ret = regulator_register_notifier(aic31xx->supplies[i].consumer,
 						  &aic31xx->disable_nb[i].nb);
 		if (ret) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to request regulator notifier: %d\n",
 				ret);
 			return ret;
@@ -1203,43 +1286,42 @@ static int aic31xx_codec_probe(struct snd_soc_codec *codec)
 	regcache_cache_only(aic31xx->regmap, true);
 	regcache_mark_dirty(aic31xx->regmap);
 
-	ret = aic31xx_add_controls(codec);
+	ret = aic31xx_add_controls(component);
 	if (ret)
 		return ret;
 
-	ret = aic31xx_add_widgets(codec);
+	ret = aic31xx_add_widgets(component);
 	if (ret)
 		return ret;
 
 	return 0;
 }
 
-static int aic31xx_codec_remove(struct snd_soc_codec *codec)
+static void aic31xx_codec_remove(struct snd_soc_component *component)
 {
-	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++)
 		regulator_unregister_notifier(aic31xx->supplies[i].consumer,
 					      &aic31xx->disable_nb[i].nb);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_driver_aic31xx = {
+static const struct snd_soc_component_driver soc_codec_driver_aic31xx = {
 	.probe			= aic31xx_codec_probe,
 	.remove			= aic31xx_codec_remove,
 	.set_bias_level		= aic31xx_set_bias_level,
-	.suspend_bias_off	= true,
-
-	.component_driver = {
-		.controls		= common31xx_snd_controls,
-		.num_controls		= ARRAY_SIZE(common31xx_snd_controls),
-		.dapm_widgets		= common31xx_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(common31xx_dapm_widgets),
-		.dapm_routes		= common31xx_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(common31xx_audio_map),
-	},
+	.controls		= common31xx_snd_controls,
+	.num_controls		= ARRAY_SIZE(common31xx_snd_controls),
+	.dapm_widgets		= common31xx_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(common31xx_dapm_widgets),
+	.dapm_routes		= common31xx_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(common31xx_audio_map),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct snd_soc_dai_ops aic31xx_dai_ops = {
@@ -1375,23 +1457,17 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
 	}
 
 	if (aic31xx->codec_type & DAC31XX_BIT)
-		return snd_soc_register_codec(&i2c->dev,
+		return devm_snd_soc_register_component(&i2c->dev,
 				&soc_codec_driver_aic31xx,
 				dac31xx_dai_driver,
 				ARRAY_SIZE(dac31xx_dai_driver));
 	else
-		return snd_soc_register_codec(&i2c->dev,
+		return devm_snd_soc_register_component(&i2c->dev,
 				&soc_codec_driver_aic31xx,
 				aic31xx_dai_driver,
 				ARRAY_SIZE(aic31xx_dai_driver));
 }
 
-static int aic31xx_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-	return 0;
-}
-
 static const struct i2c_device_id aic31xx_i2c_id[] = {
 	{ "tlv320aic310x", AIC3100 },
 	{ "tlv320aic311x", AIC3110 },
@@ -1412,7 +1488,6 @@ static struct i2c_driver aic31xx_i2c_driver = {
 		.acpi_match_table = ACPI_PTR(aic31xx_acpi_match),
 	},
 	.probe		= aic31xx_i2c_probe,
-	.remove		= aic31xx_i2c_remove,
 	.id_table	= aic31xx_i2c_id,
 };
 module_i2c_driver(aic31xx_i2c_driver);
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h
index 15ac7cb..0b58758 100644
--- a/sound/soc/codecs/tlv320aic31xx.h
+++ b/sound/soc/codecs/tlv320aic31xx.h
@@ -160,6 +160,7 @@ struct aic31xx_pdata {
 #define AIC31XX_DACMOD2BCLK		0x01
 #define AIC31XX_ADC2BCLK		0x02
 #define AIC31XX_ADCMOD2BCLK		0x03
+#define AIC31XX_KEEP_I2SCLK		BIT(2)
 
 /* AIC31XX_ADCFLAG */
 #define AIC31XX_ADCPWRSTATUS_MASK	BIT(6)
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index fea0193..e2b5a11 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -82,10 +82,10 @@ struct aic32x4_priv {
 static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	u8 val;
 
-	val = snd_soc_read(codec, AIC32X4_DINCTL);
+	val = snd_soc_component_read32(component, AIC32X4_DINCTL);
 
 	ucontrol->value.integer.value[0] = (val & 0x01);
 
@@ -95,11 +95,11 @@ static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	u8 val;
 	u8 gpio_check;
 
-	val = snd_soc_read(codec, AIC32X4_DOUTCTL);
+	val = snd_soc_component_read32(component, AIC32X4_DOUTCTL);
 	gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED);
 	if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) {
 		printk(KERN_ERR "%s: MFP2 is not configure as a GPIO output\n",
@@ -115,7 +115,7 @@ static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol,
 	else
 		val &= ~AIC32X4_MFP2_GPIO_OUT_HIGH;
 
-	snd_soc_write(codec, AIC32X4_DOUTCTL, val);
+	snd_soc_component_write(component, AIC32X4_DOUTCTL, val);
 
 	return 0;
 };
@@ -123,10 +123,10 @@ static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_get_mfp3_gpio(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	u8 val;
 
-	val = snd_soc_read(codec, AIC32X4_SCLKCTL);
+	val = snd_soc_component_read32(component, AIC32X4_SCLKCTL);
 
 	ucontrol->value.integer.value[0] = (val & 0x01);
 
@@ -136,11 +136,11 @@ static int aic32x4_get_mfp3_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	u8 val;
 	u8 gpio_check;
 
-	val = snd_soc_read(codec, AIC32X4_MISOCTL);
+	val = snd_soc_component_read32(component, AIC32X4_MISOCTL);
 	gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED);
 	if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) {
 		printk(KERN_ERR "%s: MFP4 is not configure as a GPIO output\n",
@@ -156,7 +156,7 @@ static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol,
 	else
 		val &= ~AIC32X4_MFP5_GPIO_OUT_HIGH;
 
-	snd_soc_write(codec, AIC32X4_MISOCTL, val);
+	snd_soc_component_write(component, AIC32X4_MISOCTL, val);
 
 	return 0;
 };
@@ -164,10 +164,10 @@ static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_get_mfp5_gpio(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	u8 val;
 
-	val = snd_soc_read(codec, AIC32X4_GPIOCTL);
+	val = snd_soc_component_read32(component, AIC32X4_GPIOCTL);
 	ucontrol->value.integer.value[0] = ((val & 0x2) >> 1);
 
 	return 0;
@@ -176,11 +176,11 @@ static int aic32x4_get_mfp5_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_set_mfp5_gpio(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	u8 val;
 	u8 gpio_check;
 
-	val = snd_soc_read(codec, AIC32X4_GPIOCTL);
+	val = snd_soc_component_read32(component, AIC32X4_GPIOCTL);
 	gpio_check = (val & AIC32X4_MFP5_GPIO_OUTPUT);
 	if (gpio_check != AIC32X4_MFP5_GPIO_OUTPUT) {
 		printk(KERN_ERR "%s: MFP5 is not configure as a GPIO output\n",
@@ -196,7 +196,7 @@ static int aic32x4_set_mfp5_gpio(struct snd_kcontrol *kcontrol,
 	else
 		val &= 0xfe;
 
-	snd_soc_write(codec, AIC32X4_GPIOCTL, val);
+	snd_soc_component_write(component, AIC32X4_GPIOCTL, val);
 
 	return 0;
 };
@@ -597,8 +597,8 @@ static inline int aic32x4_get_divs(int mclk, int rate)
 static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				  int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case 12000000:
@@ -613,7 +613,7 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u8 iface_reg_1 = 0;
 	u8 iface_reg_2 = 0;
 	u8 iface_reg_3 = 0;
@@ -657,12 +657,12 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, AIC32X4_IFACE1,
+	snd_soc_component_update_bits(component, AIC32X4_IFACE1,
 			    AIC32X4_IFACE1_DATATYPE_MASK |
 			    AIC32X4_IFACE1_MASTER_MASK, iface_reg_1);
-	snd_soc_update_bits(codec, AIC32X4_IFACE2,
+	snd_soc_component_update_bits(component, AIC32X4_IFACE2,
 			    AIC32X4_DATA_OFFSET_MASK, iface_reg_2);
-	snd_soc_update_bits(codec, AIC32X4_IFACE3,
+	snd_soc_component_update_bits(component, AIC32X4_IFACE3,
 			    AIC32X4_BCLKINV_MASK, iface_reg_3);
 
 	return 0;
@@ -672,8 +672,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 	u8 iface1_reg = 0;
 	u8 dacsetup_reg = 0;
 	int i;
@@ -685,54 +685,54 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* MCLK as PLL_CLKIN */
-	snd_soc_update_bits(codec, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK,
+	snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK,
 			    AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT);
 	/* PLL as CODEC_CLKIN */
-	snd_soc_update_bits(codec, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK,
+	snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK,
 			    AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT);
 	/* DAC_MOD_CLK as BDIV_CLKIN */
-	snd_soc_update_bits(codec, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK,
+	snd_soc_component_update_bits(component, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK,
 			    AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT);
 
 	/* We will fix R value to 1 and will make P & J=K.D as variable */
-	snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01);
+	snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01);
 
 	/* PLL P value */
-	snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK,
+	snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK,
 			    aic32x4_divs[i].p_val << AIC32X4_PLL_P_SHIFT);
 
 	/* PLL J value */
-	snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
+	snd_soc_component_write(component, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
 
 	/* PLL D value */
-	snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
-	snd_soc_write(codec, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff));
+	snd_soc_component_write(component, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
+	snd_soc_component_write(component, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff));
 
 	/* NDAC divider value */
-	snd_soc_update_bits(codec, AIC32X4_NDAC,
+	snd_soc_component_update_bits(component, AIC32X4_NDAC,
 			    AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac);
 
 	/* MDAC divider value */
-	snd_soc_update_bits(codec, AIC32X4_MDAC,
+	snd_soc_component_update_bits(component, AIC32X4_MDAC,
 			    AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac);
 
 	/* DOSR MSB & LSB values */
-	snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
-	snd_soc_write(codec, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff));
+	snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
+	snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff));
 
 	/* NADC divider value */
-	snd_soc_update_bits(codec, AIC32X4_NADC,
+	snd_soc_component_update_bits(component, AIC32X4_NADC,
 			    AIC32X4_NADC_MASK, aic32x4_divs[i].nadc);
 
 	/* MADC divider value */
-	snd_soc_update_bits(codec, AIC32X4_MADC,
+	snd_soc_component_update_bits(component, AIC32X4_MADC,
 			    AIC32X4_MADC_MASK, aic32x4_divs[i].madc);
 
 	/* AOSR value */
-	snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
+	snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr);
 
 	/* BCLK N divider */
-	snd_soc_update_bits(codec, AIC32X4_BCLKN,
+	snd_soc_component_update_bits(component, AIC32X4_BCLKN,
 			    AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N);
 
 	switch (params_width(params)) {
@@ -753,7 +753,7 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
 			       AIC32X4_IFACE1_DATALEN_SHIFT);
 		break;
 	}
-	snd_soc_update_bits(codec, AIC32X4_IFACE1,
+	snd_soc_component_update_bits(component, AIC32X4_IFACE1,
 			    AIC32X4_IFACE1_DATALEN_MASK, iface1_reg);
 
 	if (params_channels(params) == 1) {
@@ -764,7 +764,7 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
 		else
 			dacsetup_reg = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN;
 	}
-	snd_soc_update_bits(codec, AIC32X4_DACSETUP,
+	snd_soc_component_update_bits(component, AIC32X4_DACSETUP,
 			    AIC32X4_DAC_CHAN_MASK, dacsetup_reg);
 
 	return 0;
@@ -772,18 +772,18 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
 
 static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	snd_soc_update_bits(codec, AIC32X4_DACMUTE,
+	snd_soc_component_update_bits(component, AIC32X4_DACMUTE,
 			    AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0);
 
 	return 0;
 }
 
-static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
+static int aic32x4_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -791,59 +791,59 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
 		/* Switch on master clock */
 		ret = clk_prepare_enable(aic32x4->mclk);
 		if (ret) {
-			dev_err(codec->dev, "Failed to enable master clock\n");
+			dev_err(component->dev, "Failed to enable master clock\n");
 			return ret;
 		}
 
 		/* Switch on PLL */
-		snd_soc_update_bits(codec, AIC32X4_PLLPR,
+		snd_soc_component_update_bits(component, AIC32X4_PLLPR,
 				    AIC32X4_PLLEN, AIC32X4_PLLEN);
 
 		/* Switch on NDAC Divider */
-		snd_soc_update_bits(codec, AIC32X4_NDAC,
+		snd_soc_component_update_bits(component, AIC32X4_NDAC,
 				    AIC32X4_NDACEN, AIC32X4_NDACEN);
 
 		/* Switch on MDAC Divider */
-		snd_soc_update_bits(codec, AIC32X4_MDAC,
+		snd_soc_component_update_bits(component, AIC32X4_MDAC,
 				    AIC32X4_MDACEN, AIC32X4_MDACEN);
 
 		/* Switch on NADC Divider */
-		snd_soc_update_bits(codec, AIC32X4_NADC,
+		snd_soc_component_update_bits(component, AIC32X4_NADC,
 				    AIC32X4_NADCEN, AIC32X4_NADCEN);
 
 		/* Switch on MADC Divider */
-		snd_soc_update_bits(codec, AIC32X4_MADC,
+		snd_soc_component_update_bits(component, AIC32X4_MADC,
 				    AIC32X4_MADCEN, AIC32X4_MADCEN);
 
 		/* Switch on BCLK_N Divider */
-		snd_soc_update_bits(codec, AIC32X4_BCLKN,
+		snd_soc_component_update_bits(component, AIC32X4_BCLKN,
 				    AIC32X4_BCLKEN, AIC32X4_BCLKEN);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* Switch off BCLK_N Divider */
-		snd_soc_update_bits(codec, AIC32X4_BCLKN,
+		snd_soc_component_update_bits(component, AIC32X4_BCLKN,
 				    AIC32X4_BCLKEN, 0);
 
 		/* Switch off MADC Divider */
-		snd_soc_update_bits(codec, AIC32X4_MADC,
+		snd_soc_component_update_bits(component, AIC32X4_MADC,
 				    AIC32X4_MADCEN, 0);
 
 		/* Switch off NADC Divider */
-		snd_soc_update_bits(codec, AIC32X4_NADC,
+		snd_soc_component_update_bits(component, AIC32X4_NADC,
 				    AIC32X4_NADCEN, 0);
 
 		/* Switch off MDAC Divider */
-		snd_soc_update_bits(codec, AIC32X4_MDAC,
+		snd_soc_component_update_bits(component, AIC32X4_MDAC,
 				    AIC32X4_MDACEN, 0);
 
 		/* Switch off NDAC Divider */
-		snd_soc_update_bits(codec, AIC32X4_NDAC,
+		snd_soc_component_update_bits(component, AIC32X4_NDAC,
 				    AIC32X4_NDACEN, 0);
 
 		/* Switch off PLL */
-		snd_soc_update_bits(codec, AIC32X4_PLLPR,
+		snd_soc_component_update_bits(component, AIC32X4_PLLPR,
 				    AIC32X4_PLLEN, 0);
 
 		/* Switch off master clock */
@@ -884,55 +884,55 @@ static struct snd_soc_dai_driver aic32x4_dai = {
 	.symmetric_rates = 1,
 };
 
-static void aic32x4_setup_gpios(struct snd_soc_codec *codec)
+static void aic32x4_setup_gpios(struct snd_soc_component *component)
 {
-	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 
 	/* setup GPIO functions */
 	/* MFP1 */
 	if (aic32x4->setup->gpio_func[0] != AIC32X4_MFPX_DEFAULT_VALUE) {
-		snd_soc_write(codec, AIC32X4_DINCTL,
+		snd_soc_component_write(component, AIC32X4_DINCTL,
 		      aic32x4->setup->gpio_func[0]);
-		snd_soc_add_codec_controls(codec, aic32x4_mfp1,
+		snd_soc_add_component_controls(component, aic32x4_mfp1,
 			ARRAY_SIZE(aic32x4_mfp1));
 	}
 
 	/* MFP2 */
 	if (aic32x4->setup->gpio_func[1] != AIC32X4_MFPX_DEFAULT_VALUE) {
-		snd_soc_write(codec, AIC32X4_DOUTCTL,
+		snd_soc_component_write(component, AIC32X4_DOUTCTL,
 		      aic32x4->setup->gpio_func[1]);
-		snd_soc_add_codec_controls(codec, aic32x4_mfp2,
+		snd_soc_add_component_controls(component, aic32x4_mfp2,
 			ARRAY_SIZE(aic32x4_mfp2));
 	}
 
 	/* MFP3 */
 	if (aic32x4->setup->gpio_func[2] != AIC32X4_MFPX_DEFAULT_VALUE) {
-		snd_soc_write(codec, AIC32X4_SCLKCTL,
+		snd_soc_component_write(component, AIC32X4_SCLKCTL,
 		      aic32x4->setup->gpio_func[2]);
-		snd_soc_add_codec_controls(codec, aic32x4_mfp3,
+		snd_soc_add_component_controls(component, aic32x4_mfp3,
 			ARRAY_SIZE(aic32x4_mfp3));
 	}
 
 	/* MFP4 */
 	if (aic32x4->setup->gpio_func[3] != AIC32X4_MFPX_DEFAULT_VALUE) {
-		snd_soc_write(codec, AIC32X4_MISOCTL,
+		snd_soc_component_write(component, AIC32X4_MISOCTL,
 		      aic32x4->setup->gpio_func[3]);
-		snd_soc_add_codec_controls(codec, aic32x4_mfp4,
+		snd_soc_add_component_controls(component, aic32x4_mfp4,
 			ARRAY_SIZE(aic32x4_mfp4));
 	}
 
 	/* MFP5 */
 	if (aic32x4->setup->gpio_func[4] != AIC32X4_MFPX_DEFAULT_VALUE) {
-		snd_soc_write(codec, AIC32X4_GPIOCTL,
+		snd_soc_component_write(component, AIC32X4_GPIOCTL,
 		      aic32x4->setup->gpio_func[4]);
-		snd_soc_add_codec_controls(codec, aic32x4_mfp5,
+		snd_soc_add_component_controls(component, aic32x4_mfp5,
 			ARRAY_SIZE(aic32x4_mfp5));
 	}
 }
 
-static int aic32x4_codec_probe(struct snd_soc_codec *codec)
+static int aic32x4_component_probe(struct snd_soc_component *component)
 {
-	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 	u32 tmp_reg;
 
 	if (gpio_is_valid(aic32x4->rstn_gpio)) {
@@ -940,42 +940,42 @@ static int aic32x4_codec_probe(struct snd_soc_codec *codec)
 		gpio_set_value(aic32x4->rstn_gpio, 1);
 	}
 
-	snd_soc_write(codec, AIC32X4_RESET, 0x01);
+	snd_soc_component_write(component, AIC32X4_RESET, 0x01);
 
 	if (aic32x4->setup)
-		aic32x4_setup_gpios(codec);
+		aic32x4_setup_gpios(component);
 
 	/* Power platform configuration */
 	if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
-		snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
+		snd_soc_component_write(component, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
 						      AIC32X4_MICBIAS_2075V);
 	}
 	if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE)
-		snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
+		snd_soc_component_write(component, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
 
 	tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
 			AIC32X4_LDOCTLEN : 0;
-	snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);
+	snd_soc_component_write(component, AIC32X4_LDOCTL, tmp_reg);
 
-	tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
+	tmp_reg = snd_soc_component_read32(component, AIC32X4_CMMODE);
 	if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36)
 		tmp_reg |= AIC32X4_LDOIN_18_36;
 	if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED)
 		tmp_reg |= AIC32X4_LDOIN2HP;
-	snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
+	snd_soc_component_write(component, AIC32X4_CMMODE, tmp_reg);
 
 	/* Mic PGA routing */
 	if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K)
-		snd_soc_write(codec, AIC32X4_LMICPGANIN,
+		snd_soc_component_write(component, AIC32X4_LMICPGANIN,
 				AIC32X4_LMICPGANIN_IN2R_10K);
 	else
-		snd_soc_write(codec, AIC32X4_LMICPGANIN,
+		snd_soc_component_write(component, AIC32X4_LMICPGANIN,
 				AIC32X4_LMICPGANIN_CM1L_10K);
 	if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K)
-		snd_soc_write(codec, AIC32X4_RMICPGANIN,
+		snd_soc_component_write(component, AIC32X4_RMICPGANIN,
 				AIC32X4_RMICPGANIN_IN1L_10K);
 	else
-		snd_soc_write(codec, AIC32X4_RMICPGANIN,
+		snd_soc_component_write(component, AIC32X4_RMICPGANIN,
 				AIC32X4_RMICPGANIN_CM1R_10K);
 
 	/*
@@ -983,27 +983,28 @@ static int aic32x4_codec_probe(struct snd_soc_codec *codec)
 	 * 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 |
+	tmp_reg = snd_soc_component_read32(component, AIC32X4_ADCSETUP);
+	snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg |
 				AIC32X4_LADC_EN | AIC32X4_RADC_EN);
-	snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg);
+	snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
-	.probe = aic32x4_codec_probe,
-	.set_bias_level = aic32x4_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= aic32x4_snd_controls,
-		.num_controls		= ARRAY_SIZE(aic32x4_snd_controls),
-		.dapm_widgets		= aic32x4_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(aic32x4_dapm_widgets),
-		.dapm_routes		= aic32x4_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(aic32x4_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_aic32x4 = {
+	.probe			= aic32x4_component_probe,
+	.set_bias_level		= aic32x4_set_bias_level,
+	.controls		= aic32x4_snd_controls,
+	.num_controls		= ARRAY_SIZE(aic32x4_snd_controls),
+	.dapm_widgets		= aic32x4_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(aic32x4_dapm_widgets),
+	.dapm_routes		= aic32x4_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(aic32x4_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4,
@@ -1181,10 +1182,10 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap)
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(dev,
-			&soc_codec_dev_aic32x4, &aic32x4_dai, 1);
+	ret = devm_snd_soc_register_component(dev,
+			&soc_component_dev_aic32x4, &aic32x4_dai, 1);
 	if (ret) {
-		dev_err(dev, "Failed to register codec\n");
+		dev_err(dev, "Failed to register component\n");
 		aic32x4_disable_regulators(aic32x4);
 		return ret;
 	}
@@ -1199,8 +1200,6 @@ int aic32x4_remove(struct device *dev)
 
 	aic32x4_disable_regulators(aic32x4);
 
-	snd_soc_unregister_codec(dev);
-
 	return 0;
 }
 EXPORT_SYMBOL(aic32x4_remove);
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index b751cad..6a271e6 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -72,7 +72,7 @@ struct aic3x_disable_nb {
 
 /* codec private data */
 struct aic3x_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct regmap *regmap;
 	struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
 	struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
@@ -162,8 +162,8 @@ static const struct regmap_config aic3x_regmap = {
 static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
 					struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int reg = mc->reg;
@@ -172,7 +172,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 	unsigned short val;
-	struct snd_soc_dapm_update update = { 0 };
+	struct snd_soc_dapm_update update = {};
 	int connect, change;
 
 	val = (ucontrol->value.integer.value[0] & mask);
@@ -189,7 +189,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
 	mask <<= shift;
 	val <<= shift;
 
-	change = snd_soc_test_bits(codec, reg, mask, val);
+	change = snd_soc_component_test_bits(component, reg, mask, val);
 	if (change) {
 		update.kcontrol = kcontrol;
 		update.reg = reg;
@@ -215,19 +215,19 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
 static int mic_bias_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* change mic bias voltage to user defined */
-		snd_soc_update_bits(codec, MICBIAS_CTRL,
+		snd_soc_component_update_bits(component, MICBIAS_CTRL,
 				MICBIAS_LEVEL_MASK,
 				aic3x->micbias_vg << MICBIAS_LEVEL_SHIFT);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, MICBIAS_CTRL,
+		snd_soc_component_update_bits(component, MICBIAS_CTRL,
 				MICBIAS_LEVEL_MASK, 0);
 		break;
 	}
@@ -993,10 +993,10 @@ static const struct snd_soc_dapm_route intercon_3007[] = {
 	{"SPOM", NULL, "Right Class-D Out"},
 };
 
-static int aic3x_add_widgets(struct snd_soc_codec *codec)
+static int aic3x_add_widgets(struct snd_soc_component *component)
 {
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	switch (aic3x->model) {
 	case AIC3X_MODEL_3X:
@@ -1035,8 +1035,8 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 			   struct snd_pcm_hw_params *params,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 	int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
 	u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
 	u16 d, pll_d = 1;
@@ -1047,7 +1047,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 		width = params_width(params);
 
 	/* select data word length */
-	data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
+	data = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
 	switch (width) {
 	case 16:
 		break;
@@ -1061,7 +1061,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 		data |= (0x03 << 4);
 		break;
 	}
-	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, data);
+	snd_soc_component_write(component, AIC3X_ASD_INTF_CTRLB, data);
 
 	/* Fsref can be 44100 or 48000 */
 	fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000;
@@ -1076,15 +1076,15 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 
 	if (bypass_pll) {
 		pll_q &= 0xf;
-		snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
-		snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
+		snd_soc_component_write(component, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
+		snd_soc_component_write(component, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
 		/* disable PLL if it is bypassed */
-		snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
+		snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
 
 	} else {
-		snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
+		snd_soc_component_write(component, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
 		/* enable PLL when it is used */
-		snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+		snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG,
 				    PLL_ENABLE, PLL_ENABLE);
 	}
 
@@ -1094,7 +1094,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 	data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
 	if (params_rate(params) >= 64000)
 		data |= DUAL_RATE_MODE;
-	snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
+	snd_soc_component_write(component, AIC3X_CODEC_DATAPATH_REG, data);
 
 	/* codec sample rate select */
 	data = (fsref * 20) / params_rate(params);
@@ -1103,7 +1103,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 	data /= 5;
 	data -= 2;
 	data |= (data << 4);
-	snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
+	snd_soc_component_write(component, AIC3X_SAMPLE_RATE_SEL_REG, data);
 
 	if (bypass_pll)
 		return 0;
@@ -1172,13 +1172,13 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 	}
 
 found:
-	snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
-	snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
+	snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
+	snd_soc_component_write(component, AIC3X_OVRF_STATUS_AND_PLLR_REG,
 		      pll_r << PLLR_SHIFT);
-	snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
-	snd_soc_write(codec, AIC3X_PLL_PROGC_REG,
+	snd_soc_component_write(component, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
+	snd_soc_component_write(component, AIC3X_PLL_PROGC_REG,
 		      (pll_d >> 6) << PLLD_MSB_SHIFT);
-	snd_soc_write(codec, AIC3X_PLL_PROGD_REG,
+	snd_soc_component_write(component, AIC3X_PLL_PROGD_REG,
 		      (pll_d & 0x3F) << PLLD_LSB_SHIFT);
 
 	return 0;
@@ -1187,8 +1187,8 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 static int aic3x_prepare(struct snd_pcm_substream *substream,
 			 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 	int delay = 0;
 	int width = aic3x->slot_width;
 
@@ -1202,23 +1202,23 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
 		delay += aic3x->tdm_delay*width;
 
 	/* Configure data delay */
-	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
+	snd_soc_component_write(component, AIC3X_ASD_INTF_CTRLC, delay);
 
 	return 0;
 }
 
 static int aic3x_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u8 ldac_reg = snd_soc_read(codec, LDAC_VOL) & ~MUTE_ON;
-	u8 rdac_reg = snd_soc_read(codec, RDAC_VOL) & ~MUTE_ON;
+	struct snd_soc_component *component = dai->component;
+	u8 ldac_reg = snd_soc_component_read32(component, LDAC_VOL) & ~MUTE_ON;
+	u8 rdac_reg = snd_soc_component_read32(component, RDAC_VOL) & ~MUTE_ON;
 
 	if (mute) {
-		snd_soc_write(codec, LDAC_VOL, ldac_reg | MUTE_ON);
-		snd_soc_write(codec, RDAC_VOL, rdac_reg | MUTE_ON);
+		snd_soc_component_write(component, LDAC_VOL, ldac_reg | MUTE_ON);
+		snd_soc_component_write(component, RDAC_VOL, rdac_reg | MUTE_ON);
 	} else {
-		snd_soc_write(codec, LDAC_VOL, ldac_reg);
-		snd_soc_write(codec, RDAC_VOL, rdac_reg);
+		snd_soc_component_write(component, LDAC_VOL, ldac_reg);
+		snd_soc_component_write(component, RDAC_VOL, rdac_reg);
 	}
 
 	return 0;
@@ -1227,13 +1227,13 @@ static int aic3x_mute(struct snd_soc_dai *dai, int mute)
 static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 
 	/* set clock on MCLK or GPIO2 or BCLK */
-	snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
+	snd_soc_component_update_bits(component, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
 				clk_id << PLLCLK_IN_SHIFT);
-	snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
+	snd_soc_component_update_bits(component, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
 				clk_id << CLKDIV_IN_SHIFT);
 
 	aic3x->sysclk = freq;
@@ -1243,12 +1243,12 @@ static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			     unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 	u8 iface_areg, iface_breg;
 
-	iface_areg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
-	iface_breg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
+	iface_areg = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLA) & 0x3f;
+	iface_breg = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLB) & 0x3f;
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1289,8 +1289,8 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	aic3x->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
 	/* set iface */
-	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
-	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
+	snd_soc_component_write(component, AIC3X_ASD_INTF_CTRLA, iface_areg);
+	snd_soc_component_write(component, AIC3X_ASD_INTF_CTRLB, iface_breg);
 
 	return 0;
 }
@@ -1299,24 +1299,24 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
 				  unsigned int tx_mask, unsigned int rx_mask,
 				  int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 	unsigned int lsb;
 
 	if (tx_mask != rx_mask) {
-		dev_err(codec->dev, "tx and rx masks must be symmetric\n");
+		dev_err(component->dev, "tx and rx masks must be symmetric\n");
 		return -EINVAL;
 	}
 
 	if (unlikely(!tx_mask)) {
-		dev_err(codec->dev, "tx and rx masks need to be non 0\n");
+		dev_err(component->dev, "tx and rx masks need to be non 0\n");
 		return -EINVAL;
 	}
 
 	/* TDM based on DSP mode requires slots to be adjacent */
 	lsb = __ffs(tx_mask);
 	if ((lsb + 1) != __fls(tx_mask)) {
-		dev_err(codec->dev, "Invalid mask, slots must be adjacent\n");
+		dev_err(component->dev, "Invalid mask, slots must be adjacent\n");
 		return -EINVAL;
 	}
 
@@ -1327,7 +1327,7 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
 	case 32:
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported slot width %d\n", slot_width);
+		dev_err(component->dev, "Unsupported slot width %d\n", slot_width);
 		return -EINVAL;
 	}
 
@@ -1336,7 +1336,7 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
 	aic3x->slot_width = slot_width;
 
 	/* DOUT in high-impedance on inactive bit clocks */
-	snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA,
+	snd_soc_component_update_bits(component, AIC3X_ASD_INTF_CTRLA,
 			    DOUT_TRISTATE, DOUT_TRISTATE);
 
 	return 0;
@@ -1362,9 +1362,9 @@ static int aic3x_regulator_event(struct notifier_block *nb,
 	return 0;
 }
 
-static int aic3x_set_power(struct snd_soc_codec *codec, int power)
+static int aic3x_set_power(struct snd_soc_component *component, int power)
 {
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 	unsigned int pll_c, pll_d;
 	int ret;
 
@@ -1388,12 +1388,12 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
 		 * writing one of them and thus caused other one also not
 		 * being written
 		 */
-		pll_c = snd_soc_read(codec, AIC3X_PLL_PROGC_REG);
-		pll_d = snd_soc_read(codec, AIC3X_PLL_PROGD_REG);
+		pll_c = snd_soc_component_read32(component, AIC3X_PLL_PROGC_REG);
+		pll_d = snd_soc_component_read32(component, AIC3X_PLL_PROGD_REG);
 		if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def ||
 			pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) {
-			snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c);
-			snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d);
+			snd_soc_component_write(component, AIC3X_PLL_PROGC_REG, pll_c);
+			snd_soc_component_write(component, AIC3X_PLL_PROGD_REG, pll_d);
 		}
 
 		/*
@@ -1407,7 +1407,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
 		 * possible VDD leakage currents in case the supply regulators
 		 * remain on
 		 */
-		snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
+		snd_soc_component_write(component, AIC3X_RESET, SOFT_RESET);
 		regcache_mark_dirty(aic3x->regmap);
 		aic3x->power = 0;
 		/* HW writes are needless when bias is off */
@@ -1419,35 +1419,35 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
 	return ret;
 }
 
-static int aic3x_set_bias_level(struct snd_soc_codec *codec,
+static int aic3x_set_bias_level(struct snd_soc_component *component,
 				enum snd_soc_bias_level level)
 {
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
 	case SND_SOC_BIAS_PREPARE:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY &&
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY &&
 		    aic3x->master) {
 			/* enable pll */
-			snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+			snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG,
 					    PLL_ENABLE, PLL_ENABLE);
 		}
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		if (!aic3x->power)
-			aic3x_set_power(codec, 1);
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE &&
+			aic3x_set_power(component, 1);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE &&
 		    aic3x->master) {
 			/* disable pll */
-			snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+			snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG,
 					    PLL_ENABLE, 0);
 		}
 		break;
 	case SND_SOC_BIAS_OFF:
 		if (aic3x->power)
-			aic3x_set_power(codec, 0);
+			aic3x_set_power(component, 0);
 		break;
 	}
 
@@ -1486,96 +1486,96 @@ static struct snd_soc_dai_driver aic3x_dai = {
 	.symmetric_rates = 1,
 };
 
-static void aic3x_mono_init(struct snd_soc_codec *codec)
+static void aic3x_mono_init(struct snd_soc_component *component)
 {
 	/* DAC to Mono Line Out default volume and route to Output mixer */
-	snd_soc_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
-	snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
+	snd_soc_component_write(component, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
+	snd_soc_component_write(component, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
 
 	/* unmute all outputs */
-	snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE);
+	snd_soc_component_update_bits(component, MONOLOPM_CTRL, UNMUTE, UNMUTE);
 
 	/* PGA to Mono Line Out default volume, disconnect from Output Mixer */
-	snd_soc_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL);
-	snd_soc_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL);
 
 	/* Line2 to Mono Out default volume, disconnect from Output Mixer */
-	snd_soc_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL);
-	snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
 }
 
 /*
  * initialise the AIC3X driver
  * register the mixer and dsp interfaces with the kernel
  */
-static int aic3x_init(struct snd_soc_codec *codec)
+static int aic3x_init(struct snd_soc_component *component)
 {
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 
-	snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
-	snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
+	snd_soc_component_write(component, AIC3X_PAGE_SELECT, PAGE0_SELECT);
+	snd_soc_component_write(component, AIC3X_RESET, SOFT_RESET);
 
 	/* DAC default volume and mute */
-	snd_soc_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
-	snd_soc_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
+	snd_soc_component_write(component, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
+	snd_soc_component_write(component, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
 
 	/* DAC to HP default volume and route to Output mixer */
-	snd_soc_write(codec, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON);
-	snd_soc_write(codec, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON);
-	snd_soc_write(codec, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON);
-	snd_soc_write(codec, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON);
+	snd_soc_component_write(component, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON);
+	snd_soc_component_write(component, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON);
+	snd_soc_component_write(component, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON);
+	snd_soc_component_write(component, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON);
 	/* DAC to Line Out default volume and route to Output mixer */
-	snd_soc_write(codec, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
-	snd_soc_write(codec, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
+	snd_soc_component_write(component, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
+	snd_soc_component_write(component, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
 
 	/* unmute all outputs */
-	snd_soc_update_bits(codec, LLOPM_CTRL, UNMUTE, UNMUTE);
-	snd_soc_update_bits(codec, RLOPM_CTRL, UNMUTE, UNMUTE);
-	snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE);
-	snd_soc_update_bits(codec, HPROUT_CTRL, UNMUTE, UNMUTE);
-	snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE);
-	snd_soc_update_bits(codec, HPRCOM_CTRL, UNMUTE, UNMUTE);
+	snd_soc_component_update_bits(component, LLOPM_CTRL, UNMUTE, UNMUTE);
+	snd_soc_component_update_bits(component, RLOPM_CTRL, UNMUTE, UNMUTE);
+	snd_soc_component_update_bits(component, HPLOUT_CTRL, UNMUTE, UNMUTE);
+	snd_soc_component_update_bits(component, HPROUT_CTRL, UNMUTE, UNMUTE);
+	snd_soc_component_update_bits(component, HPLCOM_CTRL, UNMUTE, UNMUTE);
+	snd_soc_component_update_bits(component, HPRCOM_CTRL, UNMUTE, UNMUTE);
 
 	/* ADC default volume and unmute */
-	snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN);
-	snd_soc_write(codec, RADC_VOL, DEFAULT_GAIN);
+	snd_soc_component_write(component, LADC_VOL, DEFAULT_GAIN);
+	snd_soc_component_write(component, RADC_VOL, DEFAULT_GAIN);
 	/* By default route Line1 to ADC PGA mixer */
-	snd_soc_write(codec, LINE1L_2_LADC_CTRL, 0x0);
-	snd_soc_write(codec, LINE1R_2_RADC_CTRL, 0x0);
+	snd_soc_component_write(component, LINE1L_2_LADC_CTRL, 0x0);
+	snd_soc_component_write(component, LINE1R_2_RADC_CTRL, 0x0);
 
 	/* PGA to HP Bypass default volume, disconnect from Output Mixer */
-	snd_soc_write(codec, PGAL_2_HPLOUT_VOL, DEFAULT_VOL);
-	snd_soc_write(codec, PGAR_2_HPROUT_VOL, DEFAULT_VOL);
-	snd_soc_write(codec, PGAL_2_HPLCOM_VOL, DEFAULT_VOL);
-	snd_soc_write(codec, PGAR_2_HPRCOM_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, PGAL_2_HPLOUT_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, PGAR_2_HPROUT_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, PGAL_2_HPLCOM_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, PGAR_2_HPRCOM_VOL, DEFAULT_VOL);
 	/* PGA to Line Out default volume, disconnect from Output Mixer */
-	snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
-	snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
+	snd_soc_component_write(component, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
 
 	/* On tlv320aic3104, these registers are reserved and must not be written */
 	if (aic3x->model != AIC3X_MODEL_3104) {
 		/* Line2 to HP Bypass default volume, disconnect from Output Mixer */
-		snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
-		snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
-		snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
-		snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
+		snd_soc_component_write(component, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
+		snd_soc_component_write(component, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
+		snd_soc_component_write(component, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
+		snd_soc_component_write(component, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
 		/* Line2 Line Out default volume, disconnect from Output Mixer */
-		snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
-		snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
+		snd_soc_component_write(component, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
+		snd_soc_component_write(component, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
 	}
 
 	switch (aic3x->model) {
 	case AIC3X_MODEL_3X:
 	case AIC3X_MODEL_33:
-		aic3x_mono_init(codec);
+		aic3x_mono_init(component);
 		break;
 	case AIC3X_MODEL_3007:
-		snd_soc_write(codec, CLASSD_CTRL, 0);
+		snd_soc_component_write(component, CLASSD_CTRL, 0);
 		break;
 	}
 
 	/*  Output common-mode voltage = 1.5 V */
-	snd_soc_update_bits(codec, HPOUT_SC, HPOUT_SC_OCMV_MASK,
+	snd_soc_component_update_bits(component, HPOUT_SC, HPOUT_SC_OCMV_MASK,
 			    aic3x->ocmv << HPOUT_SC_OCMV_SHIFT);
 
 	return 0;
@@ -1594,13 +1594,13 @@ static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
 	return false;
 }
 
-static int aic3x_probe(struct snd_soc_codec *codec)
+static int aic3x_probe(struct snd_soc_component *component)
 {
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 	int ret, i;
 
 	INIT_LIST_HEAD(&aic3x->list);
-	aic3x->codec = codec;
+	aic3x->component = component;
 
 	for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
 		aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
@@ -1608,7 +1608,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 		ret = regulator_register_notifier(aic3x->supplies[i].consumer,
 						  &aic3x->disable_nb[i].nb);
 		if (ret) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to request regulator notifier: %d\n",
 				 ret);
 			goto err_notif;
@@ -1616,32 +1616,32 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 	}
 
 	regcache_mark_dirty(aic3x->regmap);
-	aic3x_init(codec);
+	aic3x_init(component);
 
 	if (aic3x->setup) {
 		if (aic3x->model != AIC3X_MODEL_3104) {
 			/* setup GPIO functions */
-			snd_soc_write(codec, AIC3X_GPIO1_REG,
+			snd_soc_component_write(component, AIC3X_GPIO1_REG,
 				      (aic3x->setup->gpio_func[0] & 0xf) << 4);
-			snd_soc_write(codec, AIC3X_GPIO2_REG,
+			snd_soc_component_write(component, AIC3X_GPIO2_REG,
 				      (aic3x->setup->gpio_func[1] & 0xf) << 4);
 		} else {
-			dev_warn(codec->dev, "GPIO functionality is not supported on tlv320aic3104\n");
+			dev_warn(component->dev, "GPIO functionality is not supported on tlv320aic3104\n");
 		}
 	}
 
 	switch (aic3x->model) {
 	case AIC3X_MODEL_3X:
 	case AIC3X_MODEL_33:
-		snd_soc_add_codec_controls(codec, aic3x_extra_snd_controls,
+		snd_soc_add_component_controls(component, aic3x_extra_snd_controls,
 				ARRAY_SIZE(aic3x_extra_snd_controls));
-		snd_soc_add_codec_controls(codec, aic3x_mono_controls,
+		snd_soc_add_component_controls(component, aic3x_mono_controls,
 				ARRAY_SIZE(aic3x_mono_controls));
 		break;
 	case AIC3X_MODEL_3007:
-		snd_soc_add_codec_controls(codec, aic3x_extra_snd_controls,
+		snd_soc_add_component_controls(component, aic3x_extra_snd_controls,
 				ARRAY_SIZE(aic3x_extra_snd_controls));
-		snd_soc_add_codec_controls(codec,
+		snd_soc_add_component_controls(component,
 				&aic3x_classd_amp_gain_ctrl, 1);
 		break;
 	case AIC3X_MODEL_3104:
@@ -1653,7 +1653,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 	case AIC3X_MICBIAS_2_0V:
 	case AIC3X_MICBIAS_2_5V:
 	case AIC3X_MICBIAS_AVDDV:
-		snd_soc_update_bits(codec, MICBIAS_CTRL,
+		snd_soc_component_update_bits(component, MICBIAS_CTRL,
 				    MICBIAS_LEVEL_MASK,
 				    (aic3x->micbias_vg) << MICBIAS_LEVEL_SHIFT);
 		break;
@@ -1666,7 +1666,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 		break;
 	}
 
-	aic3x_add_widgets(codec);
+	aic3x_add_widgets(component);
 
 	return 0;
 
@@ -1677,32 +1677,30 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int aic3x_remove(struct snd_soc_codec *codec)
+static void aic3x_remove(struct snd_soc_component *component)
 {
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 	int i;
 
 	list_del(&aic3x->list);
 	for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
 		regulator_unregister_notifier(aic3x->supplies[i].consumer,
 					      &aic3x->disable_nb[i].nb);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_aic3x = {
-	.set_bias_level = aic3x_set_bias_level,
-	.idle_bias_off = true,
-	.probe = aic3x_probe,
-	.remove = aic3x_remove,
-	.component_driver = {
-		.controls		= aic3x_snd_controls,
-		.num_controls		= ARRAY_SIZE(aic3x_snd_controls),
-		.dapm_widgets		= aic3x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(aic3x_dapm_widgets),
-		.dapm_routes		= intercon,
-		.num_dapm_routes	= ARRAY_SIZE(intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_aic3x = {
+	.set_bias_level		= aic3x_set_bias_level,
+	.probe			= aic3x_probe,
+	.remove			= aic3x_remove,
+	.controls		= aic3x_snd_controls,
+	.num_controls		= ARRAY_SIZE(aic3x_snd_controls),
+	.dapm_widgets		= aic3x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(aic3x_dapm_widgets),
+	.dapm_routes		= intercon,
+	.num_dapm_routes	= ARRAY_SIZE(intercon),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static void aic3x_configure_ocmv(struct i2c_client *client)
@@ -1876,8 +1874,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
 				ret);
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_aic3x, &aic3x_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_aic3x, &aic3x_dai, 1);
 
 	if (ret != 0)
 		goto err_gpio;
@@ -1898,7 +1896,6 @@ static int aic3x_i2c_remove(struct i2c_client *client)
 {
 	struct aic3x_priv *aic3x = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
 	if (gpio_is_valid(aic3x->gpio_reset) &&
 	    !aic3x_is_shared_reset(aic3x)) {
 		gpio_set_value(aic3x->gpio_reset, 0);
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 8c71d2f..a957eae 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -63,9 +63,9 @@
 	(((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate))))
 
 static void dac33_calculate_times(struct snd_pcm_substream *substream,
-				  struct snd_soc_codec *codec);
+				  struct snd_soc_component *component);
 static int dac33_prepare_chip(struct snd_pcm_substream *substream,
-			      struct snd_soc_codec *codec);
+			      struct snd_soc_component *component);
 
 enum dac33_state {
 	DAC33_IDLE = 0,
@@ -91,7 +91,7 @@ static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
 struct tlv320dac33_priv {
 	struct mutex mutex;
 	struct work_struct work;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
 	struct snd_pcm_substream *substream;
 	int power_gpio;
@@ -171,10 +171,10 @@ static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
 };
 
 /* Register read and write */
-static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
+static inline unsigned int dac33_read_reg_cache(struct snd_soc_component *component,
 						unsigned reg)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	u8 *cache = dac33->reg_cache;
 	if (reg >= DAC33_CACHEREGNUM)
 		return 0;
@@ -182,10 +182,10 @@ static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
 	return cache[reg];
 }
 
-static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
+static inline void dac33_write_reg_cache(struct snd_soc_component *component,
 					 u8 reg, u8 value)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	u8 *cache = dac33->reg_cache;
 	if (reg >= DAC33_CACHEREGNUM)
 		return;
@@ -193,10 +193,10 @@ static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
 	cache[reg] = value;
 }
 
-static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
+static int dac33_read(struct snd_soc_component *component, unsigned int reg,
 		      u8 *value)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	int val, ret = 0;
 
 	*value = reg & 0xff;
@@ -205,24 +205,24 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
 	if (dac33->chip_power) {
 		val = i2c_smbus_read_byte_data(dac33->i2c, value[0]);
 		if (val < 0) {
-			dev_err(codec->dev, "Read failed (%d)\n", val);
-			value[0] = dac33_read_reg_cache(codec, reg);
+			dev_err(component->dev, "Read failed (%d)\n", val);
+			value[0] = dac33_read_reg_cache(component, reg);
 			ret = val;
 		} else {
 			value[0] = val;
-			dac33_write_reg_cache(codec, reg, val);
+			dac33_write_reg_cache(component, reg, val);
 		}
 	} else {
-		value[0] = dac33_read_reg_cache(codec, reg);
+		value[0] = dac33_read_reg_cache(component, reg);
 	}
 
 	return ret;
 }
 
-static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
+static int dac33_write(struct snd_soc_component *component, unsigned int reg,
 		       unsigned int value)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	u8 data[2];
 	int ret = 0;
 
@@ -234,11 +234,11 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
 	data[0] = reg & 0xff;
 	data[1] = value & 0xff;
 
-	dac33_write_reg_cache(codec, data[0], data[1]);
+	dac33_write_reg_cache(component, data[0], data[1]);
 	if (dac33->chip_power) {
 		ret = i2c_master_send(dac33->i2c, data, 2);
 		if (ret != 2)
-			dev_err(codec->dev, "Write failed (%d)\n", ret);
+			dev_err(component->dev, "Write failed (%d)\n", ret);
 		else
 			ret = 0;
 	}
@@ -246,24 +246,24 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
 	return ret;
 }
 
-static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
+static int dac33_write_locked(struct snd_soc_component *component, unsigned int reg,
 			      unsigned int value)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	mutex_lock(&dac33->mutex);
-	ret = dac33_write(codec, reg, value);
+	ret = dac33_write(component, reg, value);
 	mutex_unlock(&dac33->mutex);
 
 	return ret;
 }
 
 #define DAC33_I2C_ADDR_AUTOINC	0x80
-static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
+static int dac33_write16(struct snd_soc_component *component, unsigned int reg,
 		       unsigned int value)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	u8 data[3];
 	int ret = 0;
 
@@ -277,15 +277,15 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
 	data[1] = (value >> 8) & 0xff;
 	data[2] = value & 0xff;
 
-	dac33_write_reg_cache(codec, data[0], data[1]);
-	dac33_write_reg_cache(codec, data[0] + 1, data[2]);
+	dac33_write_reg_cache(component, data[0], data[1]);
+	dac33_write_reg_cache(component, data[0] + 1, data[2]);
 
 	if (dac33->chip_power) {
 		/* We need to set autoincrement mode for 16 bit writes */
 		data[0] |= DAC33_I2C_ADDR_AUTOINC;
 		ret = i2c_master_send(dac33->i2c, data, 3);
 		if (ret != 3)
-			dev_err(codec->dev, "Write failed (%d)\n", ret);
+			dev_err(component->dev, "Write failed (%d)\n", ret);
 		else
 			ret = 0;
 	}
@@ -293,52 +293,52 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
 	return ret;
 }
 
-static void dac33_init_chip(struct snd_soc_codec *codec)
+static void dac33_init_chip(struct snd_soc_component *component)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
 	if (unlikely(!dac33->chip_power))
 		return;
 
 	/* A : DAC sample rate Fsref/1.5 */
-	dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
+	dac33_write(component, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
 	/* B : DAC src=normal, not muted */
-	dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
+	dac33_write(component, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
 					     DAC33_DACSRCL_LEFT);
 	/* C : (defaults) */
-	dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
+	dac33_write(component, DAC33_DAC_CTRL_C, 0x00);
 
 	/* 73 : volume soft stepping control,
 	 clock source = internal osc (?) */
-	dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
+	dac33_write(component, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
 
 	/* Restore only selected registers (gains mostly) */
-	dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
-		    dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
-	dac33_write(codec, DAC33_RDAC_DIG_VOL_CTRL,
-		    dac33_read_reg_cache(codec, DAC33_RDAC_DIG_VOL_CTRL));
+	dac33_write(component, DAC33_LDAC_DIG_VOL_CTRL,
+		    dac33_read_reg_cache(component, DAC33_LDAC_DIG_VOL_CTRL));
+	dac33_write(component, DAC33_RDAC_DIG_VOL_CTRL,
+		    dac33_read_reg_cache(component, DAC33_RDAC_DIG_VOL_CTRL));
 
-	dac33_write(codec, DAC33_LINEL_TO_LLO_VOL,
-		    dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL));
-	dac33_write(codec, DAC33_LINER_TO_RLO_VOL,
-		    dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
+	dac33_write(component, DAC33_LINEL_TO_LLO_VOL,
+		    dac33_read_reg_cache(component, DAC33_LINEL_TO_LLO_VOL));
+	dac33_write(component, DAC33_LINER_TO_RLO_VOL,
+		    dac33_read_reg_cache(component, DAC33_LINER_TO_RLO_VOL));
 
-	dac33_write(codec, DAC33_OUT_AMP_CTRL,
-		    dac33_read_reg_cache(codec, DAC33_OUT_AMP_CTRL));
+	dac33_write(component, DAC33_OUT_AMP_CTRL,
+		    dac33_read_reg_cache(component, DAC33_OUT_AMP_CTRL));
 
-	dac33_write(codec, DAC33_LDAC_PWR_CTRL,
-		    dac33_read_reg_cache(codec, DAC33_LDAC_PWR_CTRL));
-	dac33_write(codec, DAC33_RDAC_PWR_CTRL,
-		    dac33_read_reg_cache(codec, DAC33_RDAC_PWR_CTRL));
+	dac33_write(component, DAC33_LDAC_PWR_CTRL,
+		    dac33_read_reg_cache(component, DAC33_LDAC_PWR_CTRL));
+	dac33_write(component, DAC33_RDAC_PWR_CTRL,
+		    dac33_read_reg_cache(component, DAC33_RDAC_PWR_CTRL));
 }
 
-static inline int dac33_read_id(struct snd_soc_codec *codec)
+static inline int dac33_read_id(struct snd_soc_component *component)
 {
 	int i, ret = 0;
 	u8 reg;
 
 	for (i = 0; i < 3; i++) {
-		ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, &reg);
+		ret = dac33_read(component, DAC33_DEVICE_ID_MSB + i, &reg);
 		if (ret < 0)
 			break;
 	}
@@ -346,44 +346,44 @@ static inline int dac33_read_id(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
+static inline void dac33_soft_power(struct snd_soc_component *component, int power)
 {
 	u8 reg;
 
-	reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
+	reg = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
 	if (power)
 		reg |= DAC33_PDNALLB;
 	else
 		reg &= ~(DAC33_PDNALLB | DAC33_OSCPDNB |
 			 DAC33_DACRPDNB | DAC33_DACLPDNB);
-	dac33_write(codec, DAC33_PWR_CTRL, reg);
+	dac33_write(component, DAC33_PWR_CTRL, reg);
 }
 
-static inline void dac33_disable_digital(struct snd_soc_codec *codec)
+static inline void dac33_disable_digital(struct snd_soc_component *component)
 {
 	u8 reg;
 
 	/* Stop the DAI clock */
-	reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
+	reg = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
 	reg &= ~DAC33_BCLKON;
-	dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg);
+	dac33_write(component, DAC33_SER_AUDIOIF_CTRL_B, reg);
 
 	/* Power down the Oscillator, and DACs */
-	reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
+	reg = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
 	reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
-	dac33_write(codec, DAC33_PWR_CTRL, reg);
+	dac33_write(component, DAC33_PWR_CTRL, reg);
 }
 
-static int dac33_hard_power(struct snd_soc_codec *codec, int power)
+static int dac33_hard_power(struct snd_soc_component *component, int power)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	mutex_lock(&dac33->mutex);
 
 	/* Safety check */
 	if (unlikely(power == dac33->chip_power)) {
-		dev_dbg(codec->dev, "Trying to set the same power state: %s\n",
+		dev_dbg(component->dev, "Trying to set the same power state: %s\n",
 			power ? "ON" : "OFF");
 		goto exit;
 	}
@@ -392,7 +392,7 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
 		ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
 					  dac33->supplies);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to enable supplies: %d\n", ret);
 				goto exit;
 		}
@@ -402,14 +402,14 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
 
 		dac33->chip_power = 1;
 	} else {
-		dac33_soft_power(codec, 0);
+		dac33_soft_power(component, 0);
 		if (dac33->power_gpio >= 0)
 			gpio_set_value(dac33->power_gpio, 0);
 
 		ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
 					     dac33->supplies);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to disable supplies: %d\n", ret);
 			goto exit;
 		}
@@ -425,18 +425,18 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
 static int dac33_playback_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		if (likely(dac33->substream)) {
-			dac33_calculate_times(dac33->substream, codec);
-			dac33_prepare_chip(dac33->substream, codec);
+			dac33_calculate_times(dac33->substream, component);
+			dac33_prepare_chip(dac33->substream, component);
 		}
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		dac33_disable_digital(codec);
+		dac33_disable_digital(component);
 		break;
 	}
 	return 0;
@@ -445,8 +445,8 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w,
 static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
 			 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = dac33->fifo_mode;
 
@@ -456,14 +456,14 @@ static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
 static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
 			 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	if (dac33->fifo_mode == ucontrol->value.enumerated.item[0])
 		return 0;
 	/* Do not allow changes while stream is running*/
-	if (snd_soc_codec_is_active(codec))
+	if (snd_soc_component_is_active(component))
 		return -EPERM;
 
 	if (ucontrol->value.enumerated.item[0] >= DAC33_FIFO_LAST_MODE)
@@ -623,7 +623,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"RIGHT_LO", NULL, "Codec Power"},
 };
 
-static int dac33_set_bias_level(struct snd_soc_codec *codec,
+static int dac33_set_bias_level(struct snd_soc_component *component,
 				enum snd_soc_bias_level level)
 {
 	int ret;
@@ -634,20 +634,20 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			/* Coming from OFF, switch on the codec */
-			ret = dac33_hard_power(codec, 1);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			/* Coming from OFF, switch on the component */
+			ret = dac33_hard_power(component, 1);
 			if (ret != 0)
 				return ret;
 
-			dac33_init_chip(codec);
+			dac33_init_chip(component);
 		}
 		break;
 	case SND_SOC_BIAS_OFF:
-		/* Do not power off, when the codec is already off */
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		/* Do not power off, when the component is already off */
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			return 0;
-		ret = dac33_hard_power(codec, 0);
+		ret = dac33_hard_power(component, 0);
 		if (ret != 0)
 			return ret;
 		break;
@@ -658,13 +658,13 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
 
 static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
 {
-	struct snd_soc_codec *codec = dac33->codec;
+	struct snd_soc_component *component = dac33->component;
 	unsigned int delay;
 	unsigned long flags;
 
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_MODE1:
-		dac33_write16(codec, DAC33_NSAMPLE_MSB,
+		dac33_write16(component, DAC33_NSAMPLE_MSB,
 			DAC33_THRREG(dac33->nsample));
 
 		/* Take the timestamps */
@@ -673,13 +673,13 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
 		dac33->t_stamp1 = dac33->t_stamp2;
 		spin_unlock_irqrestore(&dac33->lock, flags);
 
-		dac33_write16(codec, DAC33_PREFILL_MSB,
+		dac33_write16(component, DAC33_PREFILL_MSB,
 				DAC33_THRREG(dac33->alarm_threshold));
 		/* Enable Alarm Threshold IRQ with a delay */
 		delay = SAMPLES_TO_US(dac33->burst_rate,
 				     dac33->alarm_threshold) + 1000;
 		usleep_range(delay, delay + 500);
-		dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
+		dac33_write(component, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
 		break;
 	case DAC33_FIFO_MODE7:
 		/* Take the timestamp */
@@ -689,14 +689,14 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
 		dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
 		spin_unlock_irqrestore(&dac33->lock, flags);
 
-		dac33_write16(codec, DAC33_PREFILL_MSB,
+		dac33_write16(component, DAC33_PREFILL_MSB,
 				DAC33_THRREG(DAC33_MODE7_MARGIN));
 
 		/* Enable Upper Threshold IRQ */
-		dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
+		dac33_write(component, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
 		break;
 	default:
-		dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
+		dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
 							dac33->fifo_mode);
 		break;
 	}
@@ -704,7 +704,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
 
 static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
 {
-	struct snd_soc_codec *codec = dac33->codec;
+	struct snd_soc_component *component = dac33->component;
 	unsigned long flags;
 
 	switch (dac33->fifo_mode) {
@@ -714,14 +714,14 @@ static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
 		dac33->t_stamp2 = ktime_to_us(ktime_get());
 		spin_unlock_irqrestore(&dac33->lock, flags);
 
-		dac33_write16(codec, DAC33_NSAMPLE_MSB,
+		dac33_write16(component, DAC33_NSAMPLE_MSB,
 				DAC33_THRREG(dac33->nsample));
 		break;
 	case DAC33_FIFO_MODE7:
 		/* At the moment we are not using interrupts in mode7 */
 		break;
 	default:
-		dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
+		dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
 							dac33->fifo_mode);
 		break;
 	}
@@ -729,12 +729,12 @@ static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
 
 static void dac33_work(struct work_struct *work)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct tlv320dac33_priv *dac33;
 	u8 reg;
 
 	dac33 = container_of(work, struct tlv320dac33_priv, work);
-	codec = dac33->codec;
+	component = dac33->component;
 
 	mutex_lock(&dac33->mutex);
 	switch (dac33->state) {
@@ -750,12 +750,12 @@ static void dac33_work(struct work_struct *work)
 	case DAC33_FLUSH:
 		dac33->state = DAC33_IDLE;
 		/* Mask all interrupts from dac33 */
-		dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
+		dac33_write(component, DAC33_FIFO_IRQ_MASK, 0);
 
 		/* flush fifo */
-		reg = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
+		reg = dac33_read_reg_cache(component, DAC33_FIFO_CTRL_A);
 		reg |= DAC33_FIFOFLUSH;
-		dac33_write(codec, DAC33_FIFO_CTRL_A, reg);
+		dac33_write(component, DAC33_FIFO_CTRL_A, reg);
 		break;
 	}
 	mutex_unlock(&dac33->mutex);
@@ -763,8 +763,8 @@ static void dac33_work(struct work_struct *work)
 
 static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
 {
-	struct snd_soc_codec *codec = dev;
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dev;
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	unsigned long flags;
 
 	spin_lock_irqsave(&dac33->lock, flags);
@@ -778,25 +778,25 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
 	return IRQ_HANDLED;
 }
 
-static void dac33_oscwait(struct snd_soc_codec *codec)
+static void dac33_oscwait(struct snd_soc_component *component)
 {
 	int timeout = 60;
 	u8 reg;
 
 	do {
 		usleep_range(1000, 2000);
-		dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
+		dac33_read(component, DAC33_INT_OSC_STATUS, &reg);
 	} while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
 	if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"internal oscillator calibration failed\n");
 }
 
 static int dac33_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
 	/* Stream started, save the substream pointer */
 	dac33->substream = substream;
@@ -807,8 +807,8 @@ static int dac33_startup(struct snd_pcm_substream *substream,
 static void dac33_shutdown(struct snd_pcm_substream *substream,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
 	dac33->substream = NULL;
 }
@@ -819,8 +819,8 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
 			   struct snd_pcm_hw_params *params,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
 	/* Check parameters for validity */
 	switch (params_rate(params)) {
@@ -828,7 +828,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
 	case 48000:
 		break;
 	default:
-		dev_err(codec->dev, "unsupported rate %d\n",
+		dev_err(component->dev, "unsupported rate %d\n",
 			params_rate(params));
 		return -EINVAL;
 	}
@@ -843,7 +843,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
 		dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 64);
 		break;
 	default:
-		dev_err(codec->dev, "unsupported width %d\n",
+		dev_err(component->dev, "unsupported width %d\n",
 			params_width(params));
 		return -EINVAL;
 	}
@@ -862,9 +862,9 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
  * Use the known, working sequence of register writes to initialize the dac33.
  */
 static int dac33_prepare_chip(struct snd_pcm_substream *substream,
-			      struct snd_soc_codec *codec)
+			      struct snd_soc_component *component)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
 	u8 aictrl_a, aictrl_b, fifoctrl_a;
 
@@ -876,16 +876,16 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 					 dac33->refclk);
 		break;
 	default:
-		dev_err(codec->dev, "unsupported rate %d\n",
+		dev_err(component->dev, "unsupported rate %d\n",
 			substream->runtime->rate);
 		return -EINVAL;
 	}
 
 
-	aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
+	aictrl_a = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A);
 	aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
 	/* Read FIFO control A, and clear FIFO flush bit */
-	fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
+	fifoctrl_a = dac33_read_reg_cache(component, DAC33_FIFO_CTRL_A);
 	fifoctrl_a &= ~DAC33_FIFOFLUSH;
 
 	fifoctrl_a &= ~DAC33_WIDTH;
@@ -898,7 +898,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 		aictrl_a |= (DAC33_NCYCL_32 | DAC33_WLEN_24);
 		break;
 	default:
-		dev_err(codec->dev, "unsupported format %d\n",
+		dev_err(component->dev, "unsupported format %d\n",
 			substream->runtime->format);
 		return -EINVAL;
 	}
@@ -914,57 +914,57 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 		return 0;
 	}
 
-	dac33_soft_power(codec, 0);
-	dac33_soft_power(codec, 1);
+	dac33_soft_power(component, 0);
+	dac33_soft_power(component, 1);
 
-	reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
-	dac33_write(codec, DAC33_INT_OSC_CTRL, reg_tmp);
+	reg_tmp = dac33_read_reg_cache(component, DAC33_INT_OSC_CTRL);
+	dac33_write(component, DAC33_INT_OSC_CTRL, reg_tmp);
 
 	/* Write registers 0x08 and 0x09 (MSB, LSB) */
-	dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
+	dac33_write16(component, DAC33_INT_OSC_FREQ_RAT_A, oscset);
 
 	/* OSC calibration time */
-	dac33_write(codec, DAC33_CALIB_TIME, 96);
+	dac33_write(component, DAC33_CALIB_TIME, 96);
 
 	/* adjustment treshold & step */
-	dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
+	dac33_write(component, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
 						 DAC33_ADJSTEP(1));
 
 	/* div=4 / gain=1 / div */
-	dac33_write(codec, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
+	dac33_write(component, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
 
-	pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
+	pwr_ctrl = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
 	pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
-	dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
+	dac33_write(component, DAC33_PWR_CTRL, pwr_ctrl);
 
-	dac33_oscwait(codec);
+	dac33_oscwait(component);
 
 	if (dac33->fifo_mode) {
 		/* Generic for all FIFO modes */
 		/* 50-51 : ASRC Control registers */
-		dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
-		dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
+		dac33_write(component, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
+		dac33_write(component, DAC33_ASRC_CTRL_B, 1); /* ??? */
 
 		/* Write registers 0x34 and 0x35 (MSB, LSB) */
-		dac33_write16(codec, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
+		dac33_write16(component, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
 
 		/* Set interrupts to high active */
-		dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
+		dac33_write(component, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
 	} else {
 		/* FIFO bypass mode */
 		/* 50-51 : ASRC Control registers */
-		dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
-		dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
+		dac33_write(component, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
+		dac33_write(component, DAC33_ASRC_CTRL_B, 0); /* ??? */
 	}
 
 	/* Interrupt behaviour configuration */
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_MODE1:
-		dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
+		dac33_write(component, DAC33_FIFO_IRQ_MODE_B,
 			    DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
 		break;
 	case DAC33_FIFO_MODE7:
-		dac33_write(codec, DAC33_FIFO_IRQ_MODE_A,
+		dac33_write(component, DAC33_FIFO_IRQ_MODE_A,
 			DAC33_UTM(DAC33_FIFO_IRQ_MODE_LEVEL));
 		break;
 	default:
@@ -972,7 +972,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
+	aictrl_b = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
 
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_MODE1:
@@ -1014,9 +1014,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
-	dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
-	dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
+	dac33_write(component, DAC33_FIFO_CTRL_A, fifoctrl_a);
+	dac33_write(component, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
+	dac33_write(component, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
 
 	/*
 	 * BCLK divide ratio
@@ -1028,17 +1028,17 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 	 * 255: 255
 	 */
 	if (dac33->fifo_mode)
-		dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
+		dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C,
 							dac33->burst_bclkdiv);
 	else
 		if (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE)
-			dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
+			dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C, 32);
 		else
-			dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 16);
+			dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C, 16);
 
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_MODE1:
-		dac33_write16(codec, DAC33_ATHR_MSB,
+		dac33_write16(component, DAC33_ATHR_MSB,
 			      DAC33_THRREG(dac33->alarm_threshold));
 		break;
 	case DAC33_FIFO_MODE7:
@@ -1046,8 +1046,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 		 * Configure the threshold levels, and leave 10 sample space
 		 * at the bottom, and also at the top of the FIFO
 		 */
-		dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
-		dac33_write16(codec, DAC33_LTHR_MSB,
+		dac33_write16(component, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
+		dac33_write16(component, DAC33_LTHR_MSB,
 			      DAC33_THRREG(DAC33_MODE7_MARGIN));
 		break;
 	default:
@@ -1060,9 +1060,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 }
 
 static void dac33_calculate_times(struct snd_pcm_substream *substream,
-				  struct snd_soc_codec *codec)
+				  struct snd_soc_component *component)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	unsigned int period_size = substream->runtime->period_size;
 	unsigned int rate = substream->runtime->rate;
 	unsigned int nsample_limit;
@@ -1119,8 +1119,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream,
 static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	switch (cmd) {
@@ -1151,8 +1151,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
 			struct snd_pcm_substream *substream,
 			struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	unsigned long long t0, t1, t_now;
 	unsigned int time_delta, uthr;
 	int samples_out, samples_in, samples;
@@ -1284,7 +1284,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
 		}
 		break;
 	default:
-		dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
+		dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
 							dac33->fifo_mode);
 		break;
 	}
@@ -1295,12 +1295,12 @@ static snd_pcm_sframes_t dac33_dai_delay(
 static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	u8 ioc_reg, asrcb_reg;
 
-	ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
-	asrcb_reg = dac33_read_reg_cache(codec, DAC33_ASRC_CTRL_B);
+	ioc_reg = dac33_read_reg_cache(component, DAC33_INT_OSC_CTRL);
+	asrcb_reg = dac33_read_reg_cache(component, DAC33_ASRC_CTRL_B);
 	switch (clk_id) {
 	case TLV320DAC33_MCLK:
 		ioc_reg |= DAC33_REFSEL;
@@ -1311,13 +1311,13 @@ static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		asrcb_reg &= ~DAC33_SRCREFSEL;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock ID (%d)\n", clk_id);
+		dev_err(component->dev, "Invalid clock ID (%d)\n", clk_id);
 		break;
 	}
 	dac33->refclk = freq;
 
-	dac33_write_reg_cache(codec, DAC33_INT_OSC_CTRL, ioc_reg);
-	dac33_write_reg_cache(codec, DAC33_ASRC_CTRL_B, asrcb_reg);
+	dac33_write_reg_cache(component, DAC33_INT_OSC_CTRL, ioc_reg);
+	dac33_write_reg_cache(component, DAC33_ASRC_CTRL_B, asrcb_reg);
 
 	return 0;
 }
@@ -1325,12 +1325,12 @@ static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			     unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	u8 aictrl_a, aictrl_b;
 
-	aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
-	aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
+	aictrl_a = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A);
+	aictrl_b = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -1340,7 +1340,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	case SND_SOC_DAIFMT_CBS_CFS:
 		/* Codec Slave */
 		if (dac33->fifo_mode) {
-			dev_err(codec->dev, "FIFO mode requires master mode\n");
+			dev_err(component->dev, "FIFO mode requires master mode\n");
 			return -EINVAL;
 		} else
 			aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
@@ -1366,35 +1366,35 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		aictrl_a |= DAC33_AFMT_LEFT_J;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported format (%u)\n",
+		dev_err(component->dev, "Unsupported format (%u)\n",
 			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 		return -EINVAL;
 	}
 
-	dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
-	dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
+	dac33_write_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
+	dac33_write_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
 
 	return 0;
 }
 
-static int dac33_soc_probe(struct snd_soc_codec *codec)
+static int dac33_soc_probe(struct snd_soc_component *component)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
-	dac33->codec = codec;
+	dac33->component = component;
 
 	/* Read the tlv320dac33 ID registers */
-	ret = dac33_hard_power(codec, 1);
+	ret = dac33_hard_power(component, 1);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
+		dev_err(component->dev, "Failed to power up component: %d\n", ret);
 		goto err_power;
 	}
-	ret = dac33_read_id(codec);
-	dac33_hard_power(codec, 0);
+	ret = dac33_read_id(component);
+	dac33_hard_power(component, 0);
 
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to read chip ID: %d\n", ret);
+		dev_err(component->dev, "Failed to read chip ID: %d\n", ret);
 		ret = -ENODEV;
 		goto err_power;
 	}
@@ -1403,9 +1403,9 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
 	if (dac33->irq >= 0) {
 		ret = request_irq(dac33->irq, dac33_interrupt_handler,
 				  IRQF_TRIGGER_RISING,
-				  codec->component.name, codec);
+				  component->name, component);
 		if (ret < 0) {
-			dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
+			dev_err(component->dev, "Could not request IRQ%d (%d)\n",
 						dac33->irq, ret);
 			dac33->irq = -1;
 		}
@@ -1416,41 +1416,38 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
 
 	/* Only add the FIFO controls, if we have valid IRQ number */
 	if (dac33->irq >= 0)
-		snd_soc_add_codec_controls(codec, dac33_mode_snd_controls,
+		snd_soc_add_component_controls(component, dac33_mode_snd_controls,
 				     ARRAY_SIZE(dac33_mode_snd_controls));
 
 err_power:
 	return ret;
 }
 
-static int dac33_soc_remove(struct snd_soc_codec *codec)
+static void dac33_soc_remove(struct snd_soc_component *component)
 {
-	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
 	if (dac33->irq >= 0) {
-		free_irq(dac33->irq, dac33->codec);
+		free_irq(dac33->irq, dac33->component);
 		flush_work(&dac33->work);
 	}
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
-	.read = dac33_read_reg_cache,
-	.write = dac33_write_locked,
-	.set_bias_level = dac33_set_bias_level,
-	.idle_bias_off = true,
-
-	.probe = dac33_soc_probe,
-	.remove = dac33_soc_remove,
-
-	.component_driver = {
-		.controls		= dac33_snd_controls,
-		.num_controls		= ARRAY_SIZE(dac33_snd_controls),
-		.dapm_widgets		= dac33_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(dac33_dapm_widgets),
-		.dapm_routes		= audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_tlv320dac33 = {
+	.read			= dac33_read_reg_cache,
+	.write			= dac33_write_locked,
+	.set_bias_level		= dac33_set_bias_level,
+	.probe			= dac33_soc_probe,
+	.remove			= dac33_soc_remove,
+	.controls		= dac33_snd_controls,
+	.num_controls		= ARRAY_SIZE(dac33_snd_controls),
+	.dapm_widgets		= dac33_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(dac33_dapm_widgets),
+	.dapm_routes		= audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(audio_map),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 #define DAC33_RATES	(SNDRV_PCM_RATE_44100 | \
@@ -1544,8 +1541,8 @@ static int dac33_i2c_probe(struct i2c_client *client,
 		goto err_get;
 	}
 
-	ret = snd_soc_register_codec(&client->dev,
-			&soc_codec_dev_tlv320dac33, &dac33_dai, 1);
+	ret = devm_snd_soc_register_component(&client->dev,
+			&soc_component_dev_tlv320dac33, &dac33_dai, 1);
 	if (ret < 0)
 		goto err_get;
 
@@ -1562,12 +1559,11 @@ static int dac33_i2c_remove(struct i2c_client *client)
 	struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client);
 
 	if (unlikely(dac33->chip_power))
-		dac33_hard_power(dac33->codec, 0);
+		dac33_hard_power(dac33->component, 0);
 
 	if (dac33->power_gpio >= 0)
 		gpio_free(dac33->power_gpio);
 
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/tscs42xx.c b/sound/soc/codecs/tscs42xx.c
index e7661d0..bbfc73a 100644
--- a/sound/soc/codecs/tscs42xx.c
+++ b/sound/soc/codecs/tscs42xx.c
@@ -3,14 +3,19 @@
 // Copyright 2017 Tempo Semiconductor, Inc.
 // Author: Steven Eckhoff <steven.eckhoff.opensource@gmail.com>
 
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/regmap.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <sound/tlv.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
-#include <sound/tlv.h>
 
 #include "tscs42xx.h"
 
@@ -91,15 +96,15 @@ static const struct regmap_config tscs42xx_regmap = {
 };
 
 #define MAX_PLL_LOCK_20MS_WAITS 1
-static bool plls_locked(struct snd_soc_codec *codec)
+static bool plls_locked(struct snd_soc_component *component)
 {
 	int ret;
 	int count = MAX_PLL_LOCK_20MS_WAITS;
 
 	do {
-		ret = snd_soc_read(codec, R_PLLCTL0);
+		ret = snd_soc_component_read32(component, R_PLLCTL0);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to read PLL lock status (%d)\n", ret);
 			return false;
 		} else if (ret > 0) {
@@ -131,10 +136,10 @@ static int sample_rate_to_pll_freq_out(int sample_rate)
 }
 
 #define DACCRSTAT_MAX_TRYS 10
-static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
+static int write_coeff_ram(struct snd_soc_component *component, u8 *coeff_ram,
 	unsigned int addr, unsigned int coeff_cnt)
 {
-	struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+	struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
 	int cnt;
 	int trys;
 	int ret;
@@ -142,9 +147,9 @@ static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
 	for (cnt = 0; cnt < coeff_cnt; cnt++, addr++) {
 
 		for (trys = 0; trys < DACCRSTAT_MAX_TRYS; trys++) {
-			ret = snd_soc_read(codec, R_DACCRSTAT);
+			ret = snd_soc_component_read32(component, R_DACCRSTAT);
 			if (ret < 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to read stat (%d)\n", ret);
 				return ret;
 			}
@@ -154,14 +159,14 @@ static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
 
 		if (trys == DACCRSTAT_MAX_TRYS) {
 			ret = -EIO;
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"dac coefficient write error (%d)\n", ret);
 			return ret;
 		}
 
 		ret = regmap_write(tscs42xx->regmap, R_DACCRADDR, addr);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to write dac ram address (%d)\n", ret);
 			return ret;
 		}
@@ -170,7 +175,7 @@ static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
 			&coeff_ram[addr * COEFF_SIZE],
 			COEFF_SIZE);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to write dac ram (%d)\n", ret);
 			return ret;
 		}
@@ -179,9 +184,9 @@ static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
 	return 0;
 }
 
-static int power_up_audio_plls(struct snd_soc_codec *codec)
+static int power_up_audio_plls(struct snd_soc_component *component)
 {
-	struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+	struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
 	int freq_out;
 	int ret;
 	unsigned int mask;
@@ -199,20 +204,20 @@ static int power_up_audio_plls(struct snd_soc_codec *codec)
 		break;
 	default:
 		ret = -EINVAL;
-		dev_err(codec->dev, "Unrecognized PLL output freq (%d)\n", ret);
+		dev_err(component->dev, "Unrecognized PLL output freq (%d)\n", ret);
 		return ret;
 	}
 
 	mutex_lock(&tscs42xx->pll_lock);
 
-	ret = snd_soc_update_bits(codec, R_PLLCTL1C, mask, val);
+	ret = snd_soc_component_update_bits(component, R_PLLCTL1C, mask, val);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to turn PLL on (%d)\n", ret);
+		dev_err(component->dev, "Failed to turn PLL on (%d)\n", ret);
 		goto exit;
 	}
 
-	if (!plls_locked(codec)) {
-		dev_err(codec->dev, "Failed to lock plls\n");
+	if (!plls_locked(component)) {
+		dev_err(component->dev, "Failed to lock plls\n");
 		ret = -ENOMSG;
 		goto exit;
 	}
@@ -224,25 +229,25 @@ static int power_up_audio_plls(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int power_down_audio_plls(struct snd_soc_codec *codec)
+static int power_down_audio_plls(struct snd_soc_component *component)
 {
-	struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+	struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	mutex_lock(&tscs42xx->pll_lock);
 
-	ret = snd_soc_update_bits(codec, R_PLLCTL1C,
+	ret = snd_soc_component_update_bits(component, R_PLLCTL1C,
 			RM_PLLCTL1C_PDB_PLL1,
 			RV_PLLCTL1C_PDB_PLL1_DISABLE);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to turn PLL off (%d)\n", ret);
+		dev_err(component->dev, "Failed to turn PLL off (%d)\n", ret);
 		goto exit;
 	}
-	ret = snd_soc_update_bits(codec, R_PLLCTL1C,
+	ret = snd_soc_component_update_bits(component, R_PLLCTL1C,
 			RM_PLLCTL1C_PDB_PLL2,
 			RV_PLLCTL1C_PDB_PLL2_DISABLE);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to turn PLL off (%d)\n", ret);
+		dev_err(component->dev, "Failed to turn PLL off (%d)\n", ret);
 		goto exit;
 	}
 
@@ -256,8 +261,8 @@ static int power_down_audio_plls(struct snd_soc_codec *codec)
 static int coeff_ram_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
 	struct coeff_ram_ctl *ctl =
 		(struct coeff_ram_ctl *)kcontrol->private_value;
 	struct soc_bytes_ext *params = &ctl->bytes_ext;
@@ -275,8 +280,8 @@ static int coeff_ram_get(struct snd_kcontrol *kcontrol,
 static int coeff_ram_put(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
 	struct coeff_ram_ctl *ctl =
 		(struct coeff_ram_ctl *)kcontrol->private_value;
 	struct soc_bytes_ext *params = &ctl->bytes_ext;
@@ -292,11 +297,11 @@ static int coeff_ram_put(struct snd_kcontrol *kcontrol,
 
 	mutex_lock(&tscs42xx->pll_lock);
 
-	if (plls_locked(codec)) {
-		ret = write_coeff_ram(codec, tscs42xx->coeff_ram,
+	if (plls_locked(component)) {
+		ret = write_coeff_ram(component, tscs42xx->coeff_ram,
 			ctl->addr, coeff_cnt);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to flush coeff ram cache (%d)\n", ret);
 			goto exit;
 		}
@@ -358,13 +363,13 @@ static int dapm_micb_event(struct snd_soc_dapm_widget *w,
 static int pll_event(struct snd_soc_dapm_widget *w,
 		     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	int ret;
 
 	if (SND_SOC_DAPM_EVENT_ON(event))
-		ret = power_up_audio_plls(codec);
+		ret = power_up_audio_plls(component);
 	else
-		ret = power_down_audio_plls(codec);
+		ret = power_down_audio_plls(component);
 
 	return ret;
 }
@@ -372,14 +377,14 @@ static int pll_event(struct snd_soc_dapm_widget *w,
 static int dac_event(struct snd_soc_dapm_widget *w,
 		     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	mutex_lock(&tscs42xx->coeff_ram_lock);
 
 	if (tscs42xx->coeff_ram_synced == false) {
-		ret = write_coeff_ram(codec, tscs42xx->coeff_ram, 0x00,
+		ret = write_coeff_ram(component, tscs42xx->coeff_ram, 0x00,
 			COEFF_RAM_COEFF_COUNT);
 		if (ret < 0)
 			goto exit;
@@ -790,7 +795,7 @@ static const struct snd_kcontrol_new tscs42xx_snd_controls[] = {
 		R_DACMBCREL3L, 2),
 };
 
-static int setup_sample_format(struct snd_soc_codec *codec,
+static int setup_sample_format(struct snd_soc_component *component,
 		snd_pcm_format_t format)
 {
 	unsigned int width;
@@ -811,21 +816,21 @@ static int setup_sample_format(struct snd_soc_codec *codec,
 		break;
 	default:
 		ret = -EINVAL;
-		dev_err(codec->dev, "Unsupported format width (%d)\n", ret);
+		dev_err(component->dev, "Unsupported format width (%d)\n", ret);
 		return ret;
 	}
-	ret = snd_soc_update_bits(codec, R_AIC1, RM_AIC1_WL, width);
+	ret = snd_soc_component_update_bits(component, R_AIC1, RM_AIC1_WL, width);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set sample width (%d)\n", ret);
+		dev_err(component->dev, "Failed to set sample width (%d)\n", ret);
 		return ret;
 	}
 
 	return 0;
 }
 
-static int setup_sample_rate(struct snd_soc_codec *codec, unsigned int rate)
+static int setup_sample_rate(struct snd_soc_component *component, unsigned int rate)
 {
-	struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+	struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
 	unsigned int br, bm;
 	int ret;
 
@@ -871,29 +876,29 @@ static int setup_sample_rate(struct snd_soc_codec *codec, unsigned int rate)
 		bm = RV_DACSR_DBM_2;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported sample rate %d\n", rate);
+		dev_err(component->dev, "Unsupported sample rate %d\n", rate);
 		return -EINVAL;
 	}
 
 	/* DAC and ADC share bit and frame clock */
-	ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBR, br);
+	ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBR, br);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to update register (%d)\n", ret);
+		dev_err(component->dev, "Failed to update register (%d)\n", ret);
 		return ret;
 	}
-	ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBM, bm);
+	ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBM, bm);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to update register (%d)\n", ret);
+		dev_err(component->dev, "Failed to update register (%d)\n", ret);
 		return ret;
 	}
-	ret = snd_soc_update_bits(codec, R_ADCSR, RM_DACSR_DBR, br);
+	ret = snd_soc_component_update_bits(component, R_ADCSR, RM_DACSR_DBR, br);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to update register (%d)\n", ret);
+		dev_err(component->dev, "Failed to update register (%d)\n", ret);
 		return ret;
 	}
-	ret = snd_soc_update_bits(codec, R_ADCSR, RM_DACSR_DBM, bm);
+	ret = snd_soc_component_update_bits(component, R_ADCSR, RM_DACSR_DBM, bm);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to update register (%d)\n", ret);
+		dev_err(component->dev, "Failed to update register (%d)\n", ret);
 		return ret;
 	}
 
@@ -1025,7 +1030,7 @@ static const struct pll_ctl *get_pll_ctl(int input_freq)
 	return pll_ctl;
 }
 
-static int set_pll_ctl_from_input_freq(struct snd_soc_codec *codec,
+static int set_pll_ctl_from_input_freq(struct snd_soc_component *component,
 		const int input_freq)
 {
 	int ret;
@@ -1035,18 +1040,18 @@ static int set_pll_ctl_from_input_freq(struct snd_soc_codec *codec,
 	pll_ctl = get_pll_ctl(input_freq);
 	if (!pll_ctl) {
 		ret = -EINVAL;
-		dev_err(codec->dev, "No PLL input entry for %d (%d)\n",
+		dev_err(component->dev, "No PLL input entry for %d (%d)\n",
 			input_freq, ret);
 		return ret;
 	}
 
 	for (i = 0; i < PLL_REG_SETTINGS_COUNT; ++i) {
-		ret = snd_soc_update_bits(codec,
+		ret = snd_soc_component_update_bits(component,
 			pll_ctl->settings[i].addr,
 			pll_ctl->settings[i].mask,
 			pll_ctl->settings[i].val);
 		if (ret < 0) {
-			dev_err(codec->dev, "Failed to set pll ctl (%d)\n",
+			dev_err(component->dev, "Failed to set pll ctl (%d)\n",
 				ret);
 			return ret;
 		}
@@ -1059,33 +1064,33 @@ static int tscs42xx_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params,
 		struct snd_soc_dai *codec_dai)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int ret;
 
-	ret = setup_sample_format(codec, params_format(params));
+	ret = setup_sample_format(component, params_format(params));
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to setup sample format (%d)\n",
+		dev_err(component->dev, "Failed to setup sample format (%d)\n",
 			ret);
 		return ret;
 	}
 
-	ret = setup_sample_rate(codec, params_rate(params));
+	ret = setup_sample_rate(component, params_rate(params));
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to setup sample rate (%d)\n", ret);
+		dev_err(component->dev, "Failed to setup sample rate (%d)\n", ret);
 		return ret;
 	}
 
 	return 0;
 }
 
-static inline int dac_mute(struct snd_soc_codec *codec)
+static inline int dac_mute(struct snd_soc_component *component)
 {
 	int ret;
 
-	ret = snd_soc_update_bits(codec, R_CNVRTR1, RM_CNVRTR1_DACMU,
+	ret = snd_soc_component_update_bits(component, R_CNVRTR1, RM_CNVRTR1_DACMU,
 		RV_CNVRTR1_DACMU_ENABLE);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to mute DAC (%d)\n",
+		dev_err(component->dev, "Failed to mute DAC (%d)\n",
 				ret);
 		return ret;
 	}
@@ -1093,14 +1098,14 @@ static inline int dac_mute(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static inline int dac_unmute(struct snd_soc_codec *codec)
+static inline int dac_unmute(struct snd_soc_component *component)
 {
 	int ret;
 
-	ret = snd_soc_update_bits(codec, R_CNVRTR1, RM_CNVRTR1_DACMU,
+	ret = snd_soc_component_update_bits(component, R_CNVRTR1, RM_CNVRTR1_DACMU,
 		RV_CNVRTR1_DACMU_DISABLE);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to unmute DAC (%d)\n",
+		dev_err(component->dev, "Failed to unmute DAC (%d)\n",
 				ret);
 		return ret;
 	}
@@ -1108,14 +1113,14 @@ static inline int dac_unmute(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static inline int adc_mute(struct snd_soc_codec *codec)
+static inline int adc_mute(struct snd_soc_component *component)
 {
 	int ret;
 
-	ret = snd_soc_update_bits(codec, R_CNVRTR0, RM_CNVRTR0_ADCMU,
+	ret = snd_soc_component_update_bits(component, R_CNVRTR0, RM_CNVRTR0_ADCMU,
 		RV_CNVRTR0_ADCMU_ENABLE);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to mute ADC (%d)\n",
+		dev_err(component->dev, "Failed to mute ADC (%d)\n",
 				ret);
 		return ret;
 	}
@@ -1123,14 +1128,14 @@ static inline int adc_mute(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static inline int adc_unmute(struct snd_soc_codec *codec)
+static inline int adc_unmute(struct snd_soc_component *component)
 {
 	int ret;
 
-	ret = snd_soc_update_bits(codec, R_CNVRTR0, RM_CNVRTR0_ADCMU,
+	ret = snd_soc_component_update_bits(component, R_CNVRTR0, RM_CNVRTR0_ADCMU,
 		RV_CNVRTR0_ADCMU_DISABLE);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to unmute ADC (%d)\n",
+		dev_err(component->dev, "Failed to unmute ADC (%d)\n",
 				ret);
 		return ret;
 	}
@@ -1140,19 +1145,19 @@ static inline int adc_unmute(struct snd_soc_codec *codec)
 
 static int tscs42xx_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int ret;
 
 	if (mute)
 		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-			ret = dac_mute(codec);
+			ret = dac_mute(component);
 		else
-			ret = adc_mute(codec);
+			ret = adc_mute(component);
 	else
 		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-			ret = dac_unmute(codec);
+			ret = dac_unmute(component);
 		else
-			ret = adc_unmute(codec);
+			ret = adc_unmute(component);
 
 	return ret;
 }
@@ -1160,23 +1165,23 @@ static int tscs42xx_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 static int tscs42xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int ret;
 
 	/* Slave mode not supported since it needs always-on frame clock */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
-		ret = snd_soc_update_bits(codec, R_AIC1, RM_AIC1_MS,
+		ret = snd_soc_component_update_bits(component, R_AIC1, RM_AIC1_MS,
 				RV_AIC1_MS_MASTER);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to set codec DAI master (%d)\n", ret);
 			return ret;
 		}
 		break;
 	default:
 		ret = -EINVAL;
-		dev_err(codec->dev, "Unsupported format (%d)\n", ret);
+		dev_err(component->dev, "Unsupported format (%d)\n", ret);
 		return ret;
 	}
 
@@ -1186,8 +1191,8 @@ static int tscs42xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai,
 		unsigned int ratio)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
 	unsigned int value;
 	int ret = 0;
 
@@ -1202,18 +1207,18 @@ static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai,
 		value = RV_DACSR_DBCM_64;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported bclk ratio (%d)\n", ret);
+		dev_err(component->dev, "Unsupported bclk ratio (%d)\n", ret);
 		return -EINVAL;
 	}
 
-	ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBCM, value);
+	ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBCM, value);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set DAC BCLK ratio (%d)\n", ret);
+		dev_err(component->dev, "Failed to set DAC BCLK ratio (%d)\n", ret);
 		return ret;
 	}
-	ret = snd_soc_update_bits(codec, R_ADCSR, RM_ADCSR_ABCM, value);
+	ret = snd_soc_component_update_bits(component, R_ADCSR, RM_ADCSR_ABCM, value);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set ADC BCLK ratio (%d)\n", ret);
+		dev_err(component->dev, "Failed to set ADC BCLK ratio (%d)\n", ret);
 		return ret;
 	}
 
@@ -1229,40 +1234,40 @@ static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai,
 static int tscs42xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int ret;
 
 	switch (clk_id) {
 	case TSCS42XX_PLL_SRC_XTAL:
 	case TSCS42XX_PLL_SRC_MCLK1:
-		ret = snd_soc_write(codec, R_PLLREFSEL,
+		ret = snd_soc_component_write(component, R_PLLREFSEL,
 				RV_PLLREFSEL_PLL1_REF_SEL_XTAL_MCLK1 |
 				RV_PLLREFSEL_PLL2_REF_SEL_XTAL_MCLK1);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to set pll reference input (%d)\n",
 				ret);
 			return ret;
 		}
 		break;
 	case TSCS42XX_PLL_SRC_MCLK2:
-		ret = snd_soc_write(codec, R_PLLREFSEL,
+		ret = snd_soc_component_write(component, R_PLLREFSEL,
 				RV_PLLREFSEL_PLL1_REF_SEL_MCLK2 |
 				RV_PLLREFSEL_PLL2_REF_SEL_MCLK2);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to set PLL reference (%d)\n", ret);
 			return ret;
 		}
 		break;
 	default:
-		dev_err(codec->dev, "pll src is unsupported\n");
+		dev_err(component->dev, "pll src is unsupported\n");
 		return -EINVAL;
 	}
 
-	ret = set_pll_ctl_from_input_freq(codec, freq);
+	ret = set_pll_ctl_from_input_freq(component, freq);
 	if (ret < 0) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Failed to setup PLL input freq (%d)\n", ret);
 		return ret;
 	}
@@ -1304,24 +1309,28 @@ static int part_is_valid(struct tscs42xx *tscs42xx)
 	};
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_tscs42xx = {
-	.component_driver = {
-		.dapm_widgets = tscs42xx_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(tscs42xx_dapm_widgets),
-		.dapm_routes = tscs42xx_intercon,
-		.num_dapm_routes = ARRAY_SIZE(tscs42xx_intercon),
-		.controls =	tscs42xx_snd_controls,
-		.num_controls = ARRAY_SIZE(tscs42xx_snd_controls),
-	},
+static struct snd_soc_component_driver soc_codec_dev_tscs42xx = {
+	.dapm_widgets		= tscs42xx_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tscs42xx_dapm_widgets),
+	.dapm_routes		= tscs42xx_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(tscs42xx_intercon),
+	.controls		= tscs42xx_snd_controls,
+	.num_controls		= ARRAY_SIZE(tscs42xx_snd_controls),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static inline void init_coeff_ram_cache(struct tscs42xx *tscs42xx)
 {
-	const u8 norm_addrs[] = { 0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1f,
-		0x20, 0x25, 0x2a, 0x2f, 0x34, 0x39, 0x3f, 0x40, 0x45, 0x4a,
-		0x4f, 0x54, 0x59, 0x5f, 0x60, 0x65, 0x6a, 0x6f, 0x74, 0x79,
-		0x7f, 0x80, 0x85, 0x8c, 0x91, 0x96, 0x97, 0x9c, 0xa3, 0xa8,
-		0xad, 0xaf, 0xb0, 0xb5, 0xba, 0xbf, 0xc4, 0xc9, };
+	static const u8 norm_addrs[] = {
+		0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1f, 0x20, 0x25, 0x2a,
+		0x2f, 0x34, 0x39, 0x3f, 0x40, 0x45, 0x4a, 0x4f, 0x54, 0x59,
+		0x5f, 0x60, 0x65, 0x6a, 0x6f, 0x74, 0x79, 0x7f, 0x80, 0x85,
+		0x8c, 0x91, 0x96, 0x97, 0x9c, 0xa3, 0xa8, 0xad, 0xaf, 0xb0,
+		0xb5, 0xba, 0xbf, 0xc4, 0xc9,
+	};
 	u8 *coeff_ram = tscs42xx->coeff_ram;
 	int i;
 
@@ -1407,7 +1416,7 @@ static int tscs42xx_i2c_probe(struct i2c_client *i2c,
 	mutex_init(&tscs42xx->coeff_ram_lock);
 	mutex_init(&tscs42xx->pll_lock);
 
-	ret = snd_soc_register_codec(tscs42xx->dev, &soc_codec_dev_tscs42xx,
+	ret = devm_snd_soc_register_component(tscs42xx->dev, &soc_codec_dev_tscs42xx,
 			&tscs42xx_dai, 1);
 	if (ret) {
 		dev_err(tscs42xx->dev, "Failed to register codec (%d)\n", ret);
@@ -1417,13 +1426,6 @@ static int tscs42xx_i2c_probe(struct i2c_client *i2c,
 	return 0;
 }
 
-static int tscs42xx_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id tscs42xx_i2c_id[] = {
 	{ "tscs42A1", 0 },
 	{ "tscs42A2", 0 },
@@ -1441,11 +1443,9 @@ MODULE_DEVICE_TABLE(of, tscs42xx_of_match);
 static struct i2c_driver tscs42xx_i2c_driver = {
 	.driver = {
 		.name = "tscs42xx",
-		.owner = THIS_MODULE,
 		.of_match_table = tscs42xx_of_match,
 	},
 	.probe =    tscs42xx_i2c_probe,
-	.remove =   tscs42xx_i2c_remove,
 	.id_table = tscs42xx_i2c_id,
 };
 
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index e4d7f39..25b752c 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -86,9 +86,9 @@ static void tw4030_init_ctl_cache(struct twl4030_priv *twl4030)
 	}
 }
 
-static unsigned int twl4030_read(struct snd_soc_codec *codec, unsigned int reg)
+static unsigned int twl4030_read(struct snd_soc_component *component, unsigned int reg)
 {
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	u8 value = 0;
 
 	if (reg >= TWL4030_CACHEREGNUM)
@@ -151,10 +151,10 @@ static bool twl4030_can_write_to_chip(struct twl4030_priv *twl4030,
 	return write_to_reg;
 }
 
-static int twl4030_write(struct snd_soc_codec *codec, unsigned int reg,
+static int twl4030_write(struct snd_soc_component *component, unsigned int reg,
 			 unsigned int value)
 {
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	/* Update the ctl cache */
 	switch (reg) {
@@ -186,9 +186,9 @@ static inline void twl4030_wait_ms(int time)
 	}
 }
 
-static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
+static void twl4030_codec_enable(struct snd_soc_component *component, int enable)
 {
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	int mode;
 
 	if (enable == twl4030->codec_powered)
@@ -227,16 +227,16 @@ static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata,
 		pdata->hs_extmute = 1;
 }
 
-static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec)
+static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_component *component)
 {
-	struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+	struct twl4030_codec_data *pdata = dev_get_platdata(component->dev);
 	struct device_node *twl4030_codec_node = NULL;
 
-	twl4030_codec_node = of_get_child_by_name(codec->dev->parent->of_node,
+	twl4030_codec_node = of_get_child_by_name(component->dev->parent->of_node,
 						  "codec");
 
 	if (!pdata && twl4030_codec_node) {
-		pdata = devm_kzalloc(codec->dev,
+		pdata = devm_kzalloc(component->dev,
 				     sizeof(struct twl4030_codec_data),
 				     GFP_KERNEL);
 		if (!pdata) {
@@ -250,28 +250,28 @@ static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec)
 	return pdata;
 }
 
-static void twl4030_init_chip(struct snd_soc_codec *codec)
+static void twl4030_init_chip(struct snd_soc_component *component)
 {
 	struct twl4030_codec_data *pdata;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	u8 reg, byte;
 	int i = 0;
 
-	pdata = twl4030_get_pdata(codec);
+	pdata = twl4030_get_pdata(component);
 
 	if (pdata && pdata->hs_extmute) {
 		if (gpio_is_valid(pdata->hs_extmute_gpio)) {
 			int ret;
 
 			if (!pdata->hs_extmute_gpio)
-				dev_warn(codec->dev,
+				dev_warn(component->dev,
 					"Extmute GPIO is 0 is this correct?\n");
 
 			ret = gpio_request_one(pdata->hs_extmute_gpio,
 					       GPIOF_OUT_INIT_LOW,
 					       "hs_extmute");
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to get hs_extmute GPIO\n");
 				pdata->hs_extmute_gpio = -1;
 			}
@@ -292,16 +292,16 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
 	tw4030_init_ctl_cache(twl4030);
 
 	/* anti-pop when changing analog gain */
-	reg = twl4030_read(codec, TWL4030_REG_MISC_SET_1);
-	twl4030_write(codec, TWL4030_REG_MISC_SET_1,
+	reg = twl4030_read(component, TWL4030_REG_MISC_SET_1);
+	twl4030_write(component, TWL4030_REG_MISC_SET_1,
 		      reg | TWL4030_SMOOTH_ANAVOL_EN);
 
-	twl4030_write(codec, TWL4030_REG_OPTION,
+	twl4030_write(component, TWL4030_REG_OPTION,
 		      TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
 		      TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
 
 	/* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */
-	twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
+	twl4030_write(component, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
 
 	/* Machine dependent setup */
 	if (!pdata)
@@ -309,18 +309,18 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
 
 	twl4030->pdata = pdata;
 
-	reg = twl4030_read(codec, TWL4030_REG_HS_POPN_SET);
+	reg = twl4030_read(component, TWL4030_REG_HS_POPN_SET);
 	reg &= ~TWL4030_RAMP_DELAY;
 	reg |= (pdata->ramp_delay_value << 2);
-	twl4030_write(codec, TWL4030_REG_HS_POPN_SET, reg);
+	twl4030_write(component, TWL4030_REG_HS_POPN_SET, reg);
 
 	/* initiate offset cancellation */
-	twl4030_codec_enable(codec, 1);
+	twl4030_codec_enable(component, 1);
 
-	reg = twl4030_read(codec, TWL4030_REG_ANAMICL);
+	reg = twl4030_read(component, TWL4030_REG_ANAMICL);
 	reg &= ~TWL4030_OFFSET_CNCL_SEL;
 	reg |= pdata->offset_cncl_path;
-	twl4030_write(codec, TWL4030_REG_ANAMICL,
+	twl4030_write(component, TWL4030_REG_ANAMICL,
 		      reg | TWL4030_CNCL_OFFSET_START);
 
 	/*
@@ -339,12 +339,12 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
 		 ((byte & TWL4030_CNCL_OFFSET_START) ==
 		  TWL4030_CNCL_OFFSET_START));
 
-	twl4030_codec_enable(codec, 0);
+	twl4030_codec_enable(component, 0);
 }
 
-static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
+static void twl4030_apll_enable(struct snd_soc_component *component, int enable)
 {
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	if (enable) {
 		twl4030->apll_enabled++;
@@ -567,13 +567,13 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
 static int pin_name##pga_event(struct snd_soc_dapm_widget *w,		\
 			       struct snd_kcontrol *kcontrol, int event) \
 {									\
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);	\
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); \
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);	\
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); \
 									\
 	switch (event) {						\
 	case SND_SOC_DAPM_POST_PMU:					\
 		twl4030->pin_name##_enabled = 1;			\
-		twl4030_write(codec, reg, twl4030_read(codec, reg));	\
+		twl4030_write(component, reg, twl4030_read(component, reg));	\
 		break;							\
 	case SND_SOC_DAPM_POST_PMD:					\
 		twl4030->pin_name##_enabled = 0;			\
@@ -589,47 +589,47 @@ TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
 TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
 TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
 
-static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
+static void handsfree_ramp(struct snd_soc_component *component, int reg, int ramp)
 {
 	unsigned char hs_ctl;
 
-	hs_ctl = twl4030_read(codec, reg);
+	hs_ctl = twl4030_read(component, reg);
 
 	if (ramp) {
 		/* HF ramp-up */
 		hs_ctl |= TWL4030_HF_CTL_REF_EN;
-		twl4030_write(codec, reg, hs_ctl);
+		twl4030_write(component, reg, hs_ctl);
 		udelay(10);
 		hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
-		twl4030_write(codec, reg, hs_ctl);
+		twl4030_write(component, reg, hs_ctl);
 		udelay(40);
 		hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
 		hs_ctl |= TWL4030_HF_CTL_HB_EN;
-		twl4030_write(codec, reg, hs_ctl);
+		twl4030_write(component, reg, hs_ctl);
 	} else {
 		/* HF ramp-down */
 		hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
 		hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
-		twl4030_write(codec, reg, hs_ctl);
+		twl4030_write(component, reg, hs_ctl);
 		hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
-		twl4030_write(codec, reg, hs_ctl);
+		twl4030_write(component, reg, hs_ctl);
 		udelay(40);
 		hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
-		twl4030_write(codec, reg, hs_ctl);
+		twl4030_write(component, reg, hs_ctl);
 	}
 }
 
 static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		handsfree_ramp(codec, TWL4030_REG_HFL_CTL, 1);
+		handsfree_ramp(component, TWL4030_REG_HFL_CTL, 1);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		handsfree_ramp(codec, TWL4030_REG_HFL_CTL, 0);
+		handsfree_ramp(component, TWL4030_REG_HFL_CTL, 0);
 		break;
 	}
 	return 0;
@@ -638,14 +638,14 @@ static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
 static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		handsfree_ramp(codec, TWL4030_REG_HFR_CTL, 1);
+		handsfree_ramp(component, TWL4030_REG_HFR_CTL, 1);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		handsfree_ramp(codec, TWL4030_REG_HFR_CTL, 0);
+		handsfree_ramp(component, TWL4030_REG_HFR_CTL, 0);
 		break;
 	}
 	return 0;
@@ -654,23 +654,23 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
 static int vibramux_event(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
-	twl4030_write(codec, TWL4030_REG_VIBRA_SET, 0xff);
+	twl4030_write(component, TWL4030_REG_VIBRA_SET, 0xff);
 	return 0;
 }
 
 static int apll_event(struct snd_soc_dapm_widget *w,
 		      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		twl4030_apll_enable(codec, 1);
+		twl4030_apll_enable(component, 1);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		twl4030_apll_enable(codec, 0);
+		twl4030_apll_enable(component, 0);
 		break;
 	}
 	return 0;
@@ -679,41 +679,41 @@ static int apll_event(struct snd_soc_dapm_widget *w,
 static int aif_event(struct snd_soc_dapm_widget *w,
 		     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	u8 audio_if;
 
-	audio_if = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
+	audio_if = twl4030_read(component, TWL4030_REG_AUDIO_IF);
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		/* Enable AIF */
 		/* enable the PLL before we use it to clock the DAI */
-		twl4030_apll_enable(codec, 1);
+		twl4030_apll_enable(component, 1);
 
-		twl4030_write(codec, TWL4030_REG_AUDIO_IF,
+		twl4030_write(component, TWL4030_REG_AUDIO_IF,
 			      audio_if | TWL4030_AIF_EN);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		/* disable the DAI before we stop it's source PLL */
-		twl4030_write(codec, TWL4030_REG_AUDIO_IF,
+		twl4030_write(component, TWL4030_REG_AUDIO_IF,
 			      audio_if &  ~TWL4030_AIF_EN);
-		twl4030_apll_enable(codec, 0);
+		twl4030_apll_enable(component, 0);
 		break;
 	}
 	return 0;
 }
 
-static void headset_ramp(struct snd_soc_codec *codec, int ramp)
+static void headset_ramp(struct snd_soc_component *component, int ramp)
 {
 	unsigned char hs_gain, hs_pop;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	struct twl4030_codec_data *pdata = twl4030->pdata;
 	/* Base values for ramp delay calculation: 2^19 - 2^26 */
 	unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
 				    8388608, 16777216, 33554432, 67108864};
 	unsigned int delay;
 
-	hs_gain = twl4030_read(codec, TWL4030_REG_HS_GAIN_SET);
-	hs_pop = twl4030_read(codec, TWL4030_REG_HS_POPN_SET);
+	hs_gain = twl4030_read(component, TWL4030_REG_HS_GAIN_SET);
+	hs_pop = twl4030_read(component, TWL4030_REG_HS_POPN_SET);
 	delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
 		twl4030->sysclk) + 1;
 
@@ -724,26 +724,26 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
 			gpio_set_value(pdata->hs_extmute_gpio, 1);
 		} else {
 			hs_pop |= TWL4030_EXTMUTE;
-			twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+			twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
 		}
 	}
 
 	if (ramp) {
 		/* Headset ramp-up according to the TRM */
 		hs_pop |= TWL4030_VMID_EN;
-		twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+		twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
 		/* Actually write to the register */
 		twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain,
 				 TWL4030_REG_HS_GAIN_SET);
 		hs_pop |= TWL4030_RAMP_EN;
-		twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+		twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
 		/* Wait ramp delay time + 1, so the VMID can settle */
 		twl4030_wait_ms(delay);
 	} else {
 		/* Headset ramp-down _not_ according to
 		 * the TRM, but in a way that it is working */
 		hs_pop &= ~TWL4030_RAMP_EN;
-		twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+		twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
 		/* Wait ramp delay time + 1, so the VMID can settle */
 		twl4030_wait_ms(delay);
 		/* Bypass the reg_cache to mute the headset */
@@ -751,7 +751,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
 				 TWL4030_REG_HS_GAIN_SET);
 
 		hs_pop &= ~TWL4030_VMID_EN;
-		twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+		twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
 	}
 
 	/* Disable external mute */
@@ -760,7 +760,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
 			gpio_set_value(pdata->hs_extmute_gpio, 0);
 		} else {
 			hs_pop &= ~TWL4030_EXTMUTE;
-			twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+			twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
 		}
 	}
 }
@@ -768,21 +768,21 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
 static int headsetlpga_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* Do the ramp-up only once */
 		if (!twl4030->hsr_enabled)
-			headset_ramp(codec, 1);
+			headset_ramp(component, 1);
 
 		twl4030->hsl_enabled = 1;
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		/* Do the ramp-down only if both headsetL/R is disabled */
 		if (!twl4030->hsr_enabled)
-			headset_ramp(codec, 0);
+			headset_ramp(component, 0);
 
 		twl4030->hsl_enabled = 0;
 		break;
@@ -793,21 +793,21 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w,
 static int headsetrpga_event(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* Do the ramp-up only once */
 		if (!twl4030->hsl_enabled)
-			headset_ramp(codec, 1);
+			headset_ramp(component, 1);
 
 		twl4030->hsr_enabled = 1;
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		/* Do the ramp-down only if both headsetL/R is disabled */
 		if (!twl4030->hsl_enabled)
-			headset_ramp(codec, 0);
+			headset_ramp(component, 0);
 
 		twl4030->hsr_enabled = 0;
 		break;
@@ -818,8 +818,8 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
 static int digimic_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	struct twl4030_codec_data *pdata = twl4030->pdata;
 
 	if (pdata && pdata->digimic_delay)
@@ -842,7 +842,7 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg = mc->reg;
 	unsigned int shift = mc->shift;
 	unsigned int rshift = mc->rshift;
@@ -850,14 +850,14 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
 	int mask = (1 << fls(max)) - 1;
 
 	ucontrol->value.integer.value[0] =
-		(twl4030_read(codec, reg) >> shift) & mask;
+		(twl4030_read(component, reg) >> shift) & mask;
 	if (ucontrol->value.integer.value[0])
 		ucontrol->value.integer.value[0] =
 			max + 1 - ucontrol->value.integer.value[0];
 
 	if (shift != rshift) {
 		ucontrol->value.integer.value[1] =
-			(twl4030_read(codec, reg) >> rshift) & mask;
+			(twl4030_read(component, reg) >> rshift) & mask;
 		if (ucontrol->value.integer.value[1])
 			ucontrol->value.integer.value[1] =
 				max + 1 - ucontrol->value.integer.value[1];
@@ -871,7 +871,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg = mc->reg;
 	unsigned int shift = mc->shift;
 	unsigned int rshift = mc->rshift;
@@ -892,7 +892,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
 			val2 = max + 1 - val2;
 		val |= val2 << rshift;
 	}
-	return snd_soc_update_bits(codec, reg, val_mask, val);
+	return snd_soc_component_update_bits(component, reg, val_mask, val);
 }
 
 static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
@@ -900,7 +900,7 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg = mc->reg;
 	unsigned int reg2 = mc->rreg;
 	unsigned int shift = mc->shift;
@@ -908,9 +908,9 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
 	int mask = (1<<fls(max))-1;
 
 	ucontrol->value.integer.value[0] =
-		(twl4030_read(codec, reg) >> shift) & mask;
+		(twl4030_read(component, reg) >> shift) & mask;
 	ucontrol->value.integer.value[1] =
-		(twl4030_read(codec, reg2) >> shift) & mask;
+		(twl4030_read(component, reg2) >> shift) & mask;
 
 	if (ucontrol->value.integer.value[0])
 		ucontrol->value.integer.value[0] =
@@ -927,7 +927,7 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg = mc->reg;
 	unsigned int reg2 = mc->rreg;
 	unsigned int shift = mc->shift;
@@ -948,11 +948,11 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
 	val = val << shift;
 	val2 = val2 << shift;
 
-	err = snd_soc_update_bits(codec, reg, val_mask, val);
+	err = snd_soc_component_update_bits(component, reg, val_mask, val);
 	if (err < 0)
 		return err;
 
-	err = snd_soc_update_bits(codec, reg2, val_mask, val2);
+	err = snd_soc_component_update_bits(component, reg2, val_mask, val2);
 	return err;
 }
 
@@ -968,11 +968,11 @@ static SOC_ENUM_SINGLE_DECL(twl4030_op_modes_enum,
 static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	if (twl4030->configured) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"operation mode cannot be changed on-the-fly\n");
 		return -EBUSY;
 	}
@@ -1579,7 +1579,7 @@ static const struct snd_soc_dapm_route intercon[] = {
 
 };
 
-static int twl4030_set_bias_level(struct snd_soc_codec *codec,
+static int twl4030_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
 	switch (level) {
@@ -1588,11 +1588,11 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
-			twl4030_codec_enable(codec, 1);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+			twl4030_codec_enable(component, 1);
 		break;
 	case SND_SOC_BIAS_OFF:
-		twl4030_codec_enable(codec, 0);
+		twl4030_codec_enable(component, 0);
 		break;
 	}
 
@@ -1628,12 +1628,12 @@ static void twl4030_constraints(struct twl4030_priv *twl4030,
 
 /* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for
  * capture has to be enabled/disabled. */
-static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
+static void twl4030_tdm_enable(struct snd_soc_component *component, int direction,
 			       int enable)
 {
 	u8 reg, mask;
 
-	reg = twl4030_read(codec, TWL4030_REG_OPTION);
+	reg = twl4030_read(component, TWL4030_REG_OPTION);
 
 	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
 		mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN;
@@ -1645,14 +1645,14 @@ static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
 	else
 		reg &= ~mask;
 
-	twl4030_write(codec, TWL4030_REG_OPTION, reg);
+	twl4030_write(component, TWL4030_REG_OPTION, reg);
 }
 
 static int twl4030_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	if (twl4030->master_substream) {
 		twl4030->slave_substream = substream;
@@ -1662,7 +1662,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
 		if (twl4030->configured)
 			twl4030_constraints(twl4030, twl4030->master_substream);
 	} else {
-		if (!(twl4030_read(codec, TWL4030_REG_CODEC_MODE) &
+		if (!(twl4030_read(component, TWL4030_REG_CODEC_MODE) &
 			TWL4030_OPTION_1)) {
 			/* In option2 4 channel is not supported, set the
 			 * constraint for the first stream for channels, the
@@ -1680,8 +1680,8 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
 static void twl4030_shutdown(struct snd_pcm_substream *substream,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	if (twl4030->master_substream == substream)
 		twl4030->master_substream = twl4030->slave_substream;
@@ -1697,27 +1697,27 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
 
 	 /* If the closing substream had 4 channel, do the necessary cleanup */
 	if (substream->runtime->channels == 4)
-		twl4030_tdm_enable(codec, substream->stream, 0);
+		twl4030_tdm_enable(component, substream->stream, 0);
 }
 
 static int twl4030_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	u8 mode, old_mode, format, old_format;
 
 	 /* If the substream has 4 channel, do the necessary setup */
 	if (params_channels(params) == 4) {
-		format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
-		mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE);
+		format = twl4030_read(component, TWL4030_REG_AUDIO_IF);
+		mode = twl4030_read(component, TWL4030_REG_CODEC_MODE);
 
 		/* Safety check: are we in the correct operating mode and
 		 * the interface is in TDM mode? */
 		if ((mode & TWL4030_OPTION_1) &&
 		    ((format & TWL4030_AIF_FORMAT) == TWL4030_AIF_FORMAT_TDM))
-			twl4030_tdm_enable(codec, substream->stream, 1);
+			twl4030_tdm_enable(component, substream->stream, 1);
 		else
 			return -EINVAL;
 	}
@@ -1727,7 +1727,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 		return 0;
 
 	/* bit rate */
-	old_mode = twl4030_read(codec,
+	old_mode = twl4030_read(component,
 				TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
 	mode = old_mode & ~TWL4030_APLL_RATE;
 
@@ -1763,13 +1763,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 		mode |= TWL4030_APLL_RATE_96000;
 		break;
 	default:
-		dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
+		dev_err(component->dev, "%s: unknown rate %d\n", __func__,
 			params_rate(params));
 		return -EINVAL;
 	}
 
 	/* sample size */
-	old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
+	old_format = twl4030_read(component, TWL4030_REG_AUDIO_IF);
 	format = old_format;
 	format &= ~TWL4030_DATA_WIDTH;
 	switch (params_width(params)) {
@@ -1780,7 +1780,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 		format |= TWL4030_DATA_WIDTH_32S_24W;
 		break;
 	default:
-		dev_err(codec->dev, "%s: unsupported bits/sample %d\n",
+		dev_err(component->dev, "%s: unsupported bits/sample %d\n",
 			__func__, params_width(params));
 		return -EINVAL;
 	}
@@ -1791,13 +1791,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 			 * If the codec is powered, than we need to toggle the
 			 * codec power.
 			 */
-			twl4030_codec_enable(codec, 0);
-			twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-			twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
-			twl4030_codec_enable(codec, 1);
+			twl4030_codec_enable(component, 0);
+			twl4030_write(component, TWL4030_REG_CODEC_MODE, mode);
+			twl4030_write(component, TWL4030_REG_AUDIO_IF, format);
+			twl4030_codec_enable(component, 1);
 		} else {
-			twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-			twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+			twl4030_write(component, TWL4030_REG_CODEC_MODE, mode);
+			twl4030_write(component, TWL4030_REG_AUDIO_IF, format);
 		}
 	}
 
@@ -1821,8 +1821,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 				  unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case 19200000:
@@ -1830,12 +1830,12 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 	case 38400000:
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq);
+		dev_err(component->dev, "Unsupported HFCLKIN: %u\n", freq);
 		return -EINVAL;
 	}
 
 	if ((freq / 1000) != twl4030->sysclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Mismatch in HFCLKIN: %u (configured: %u)\n",
 			freq, twl4030->sysclk * 1000);
 		return -EINVAL;
@@ -1846,12 +1846,12 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 
 static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	u8 old_format, format;
 
 	/* get format */
-	old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
+	old_format = twl4030_read(component, TWL4030_REG_AUDIO_IF);
 	format = old_format;
 
 	/* set master/slave audio interface */
@@ -1887,11 +1887,11 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 			 * If the codec is powered, than we need to toggle the
 			 * codec power.
 			 */
-			twl4030_codec_enable(codec, 0);
-			twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
-			twl4030_codec_enable(codec, 1);
+			twl4030_codec_enable(component, 0);
+			twl4030_write(component, TWL4030_REG_AUDIO_IF, format);
+			twl4030_codec_enable(component, 1);
 		} else {
-			twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+			twl4030_write(component, TWL4030_REG_AUDIO_IF, format);
 		}
 	}
 
@@ -1900,25 +1900,25 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u8 reg = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
+	struct snd_soc_component *component = dai->component;
+	u8 reg = twl4030_read(component, TWL4030_REG_AUDIO_IF);
 
 	if (tristate)
 		reg |= TWL4030_AIF_TRI_EN;
 	else
 		reg &= ~TWL4030_AIF_TRI_EN;
 
-	return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
+	return twl4030_write(component, TWL4030_REG_AUDIO_IF, reg);
 }
 
 /* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
  * (VTXL, VTXR) for uplink has to be enabled/disabled. */
-static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
+static void twl4030_voice_enable(struct snd_soc_component *component, int direction,
 				 int enable)
 {
 	u8 reg, mask;
 
-	reg = twl4030_read(codec, TWL4030_REG_OPTION);
+	reg = twl4030_read(component, TWL4030_REG_OPTION);
 
 	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
 		mask = TWL4030_ARXL1_VRX_EN;
@@ -1930,21 +1930,21 @@ static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
 	else
 		reg &= ~mask;
 
-	twl4030_write(codec, TWL4030_REG_OPTION, reg);
+	twl4030_write(component, TWL4030_REG_OPTION, reg);
 }
 
 static int twl4030_voice_startup(struct snd_pcm_substream *substream,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	u8 mode;
 
 	/* If the system master clock is not 26MHz, the voice PCM interface is
 	 * not available.
 	 */
 	if (twl4030->sysclk != 26000) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
 			__func__, twl4030->sysclk);
 		return -EINVAL;
@@ -1953,11 +1953,11 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
 	/* If the codec mode is not option2, the voice PCM interface is not
 	 * available.
 	 */
-	mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE)
+	mode = twl4030_read(component, TWL4030_REG_CODEC_MODE)
 		& TWL4030_OPT_MODE;
 
 	if (mode != TWL4030_OPTION_2) {
-		dev_err(codec->dev, "%s: the codec mode is not option2\n",
+		dev_err(component->dev, "%s: the codec mode is not option2\n",
 			__func__);
 		return -EINVAL;
 	}
@@ -1968,25 +1968,25 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
 static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
 				   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	/* Enable voice digital filters */
-	twl4030_voice_enable(codec, substream->stream, 0);
+	twl4030_voice_enable(component, substream->stream, 0);
 }
 
 static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_pcm_hw_params *params,
 				   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	u8 old_mode, mode;
 
 	/* Enable voice digital filters */
-	twl4030_voice_enable(codec, substream->stream, 1);
+	twl4030_voice_enable(component, substream->stream, 1);
 
 	/* bit rate */
-	old_mode = twl4030_read(codec,
+	old_mode = twl4030_read(component,
 				TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
 	mode = old_mode;
 
@@ -1998,7 +1998,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
 		mode |= TWL4030_SEL_16K;
 		break;
 	default:
-		dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
+		dev_err(component->dev, "%s: unknown rate %d\n", __func__,
 			params_rate(params));
 		return -EINVAL;
 	}
@@ -2009,11 +2009,11 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
 			 * If the codec is powered, than we need to toggle the
 			 * codec power.
 			 */
-			twl4030_codec_enable(codec, 0);
-			twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-			twl4030_codec_enable(codec, 1);
+			twl4030_codec_enable(component, 0);
+			twl4030_write(component, TWL4030_REG_CODEC_MODE, mode);
+			twl4030_codec_enable(component, 1);
 		} else {
-			twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
+			twl4030_write(component, TWL4030_REG_CODEC_MODE, mode);
 		}
 	}
 
@@ -2023,17 +2023,17 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
 static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 					int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
 	if (freq != 26000000) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
 			__func__, freq / 1000);
 		return -EINVAL;
 	}
 	if ((freq / 1000) != twl4030->sysclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Mismatch in HFCLKIN: %u (configured: %u)\n",
 			freq, twl4030->sysclk * 1000);
 		return -EINVAL;
@@ -2044,12 +2044,12 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
 				     unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	u8 old_format, format;
 
 	/* get format */
-	old_format = twl4030_read(codec, TWL4030_REG_VOICE_IF);
+	old_format = twl4030_read(component, TWL4030_REG_VOICE_IF);
 	format = old_format;
 
 	/* set master/slave audio interface */
@@ -2082,11 +2082,11 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			 * If the codec is powered, than we need to toggle the
 			 * codec power.
 			 */
-			twl4030_codec_enable(codec, 0);
-			twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
-			twl4030_codec_enable(codec, 1);
+			twl4030_codec_enable(component, 0);
+			twl4030_write(component, TWL4030_REG_VOICE_IF, format);
+			twl4030_codec_enable(component, 1);
 		} else {
-			twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
+			twl4030_write(component, TWL4030_REG_VOICE_IF, format);
 		}
 	}
 
@@ -2095,15 +2095,15 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u8 reg = twl4030_read(codec, TWL4030_REG_VOICE_IF);
+	struct snd_soc_component *component = dai->component;
+	u8 reg = twl4030_read(component, TWL4030_REG_VOICE_IF);
 
 	if (tristate)
 		reg |= TWL4030_VIF_TRI_EN;
 	else
 		reg &= ~TWL4030_VIF_TRI_EN;
 
-	return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
+	return twl4030_write(component, TWL4030_REG_VOICE_IF, reg);
 }
 
 #define TWL4030_RATES	 (SNDRV_PCM_RATE_8000_48000)
@@ -2164,69 +2164,60 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
 },
 };
 
-static int twl4030_soc_probe(struct snd_soc_codec *codec)
+static int twl4030_soc_probe(struct snd_soc_component *component)
 {
 	struct twl4030_priv *twl4030;
 
-	twl4030 = devm_kzalloc(codec->dev, sizeof(struct twl4030_priv),
+	twl4030 = devm_kzalloc(component->dev, sizeof(struct twl4030_priv),
 			       GFP_KERNEL);
 	if (!twl4030)
 		return -ENOMEM;
-	snd_soc_codec_set_drvdata(codec, twl4030);
+	snd_soc_component_set_drvdata(component, twl4030);
 	/* Set the defaults, and power up the codec */
 	twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
 
-	twl4030_init_chip(codec);
+	twl4030_init_chip(component);
 
 	return 0;
 }
 
-static int twl4030_soc_remove(struct snd_soc_codec *codec)
+static void twl4030_soc_remove(struct snd_soc_component *component)
 {
-	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 	struct twl4030_codec_data *pdata = twl4030->pdata;
 
 	if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio))
 		gpio_free(pdata->hs_extmute_gpio);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
-	.probe = twl4030_soc_probe,
-	.remove = twl4030_soc_remove,
-	.read = twl4030_read,
-	.write = twl4030_write,
-	.set_bias_level = twl4030_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= twl4030_snd_controls,
-		.num_controls		= ARRAY_SIZE(twl4030_snd_controls),
-		.dapm_widgets		= twl4030_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(twl4030_dapm_widgets),
-		.dapm_routes		= intercon,
-		.num_dapm_routes	= ARRAY_SIZE(intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_twl4030 = {
+	.probe			= twl4030_soc_probe,
+	.remove			= twl4030_soc_remove,
+	.read			= twl4030_read,
+	.write			= twl4030_write,
+	.set_bias_level		= twl4030_set_bias_level,
+	.controls		= twl4030_snd_controls,
+	.num_controls		= ARRAY_SIZE(twl4030_snd_controls),
+	.dapm_widgets		= twl4030_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(twl4030_dapm_widgets),
+	.dapm_routes		= intercon,
+	.num_dapm_routes	= ARRAY_SIZE(intercon),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int twl4030_codec_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &soc_component_dev_twl4030,
 				      twl4030_dai, ARRAY_SIZE(twl4030_dai));
 }
 
-static int twl4030_codec_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 MODULE_ALIAS("platform:twl4030-codec");
 
 static struct platform_driver twl4030_codec_driver = {
 	.probe		= twl4030_codec_probe,
-	.remove		= twl4030_codec_remove,
 	.driver		= {
 		.name	= "twl4030-codec",
 	},
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 573a523..bfd1abd 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -76,7 +76,7 @@ struct twl6040_data {
 	unsigned int clk_in;
 	unsigned int sysclk;
 	struct twl6040_jack_data hs_jack;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct mutex mutex;
 };
 
@@ -106,12 +106,12 @@ static const struct snd_pcm_hw_constraint_list sysclk_constraints[] = {
 	{ .count = ARRAY_SIZE(hp_rates), .list = hp_rates, },
 };
 
-#define to_twl6040(codec)	dev_get_drvdata((codec)->dev->parent)
+#define to_twl6040(component)	dev_get_drvdata((component)->dev->parent)
 
-static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg)
+static unsigned int twl6040_read(struct snd_soc_component *component, unsigned int reg)
 {
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-	struct twl6040 *twl6040 = to_twl6040(codec);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
+	struct twl6040 *twl6040 = to_twl6040(component);
 	u8 value;
 
 	if (reg >= TWL6040_CACHEREGNUM)
@@ -133,10 +133,10 @@ static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg)
 	return value;
 }
 
-static bool twl6040_can_write_to_chip(struct snd_soc_codec *codec,
+static bool twl6040_can_write_to_chip(struct snd_soc_component *component,
 				  unsigned int reg)
 {
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	switch (reg) {
 	case TWL6040_REG_HSLCTL:
@@ -152,10 +152,10 @@ static bool twl6040_can_write_to_chip(struct snd_soc_codec *codec,
 	}
 }
 
-static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec,
+static inline void twl6040_update_dl12_cache(struct snd_soc_component *component,
 					     u8 reg, u8 value)
 {
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	switch (reg) {
 	case TWL6040_REG_HSLCTL:
@@ -170,54 +170,54 @@ static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec,
 	}
 }
 
-static int twl6040_write(struct snd_soc_codec *codec,
+static int twl6040_write(struct snd_soc_component *component,
 			unsigned int reg, unsigned int value)
 {
-	struct twl6040 *twl6040 = to_twl6040(codec);
+	struct twl6040 *twl6040 = to_twl6040(component);
 
 	if (reg >= TWL6040_CACHEREGNUM)
 		return -EIO;
 
-	twl6040_update_dl12_cache(codec, reg, value);
-	if (twl6040_can_write_to_chip(codec, reg))
+	twl6040_update_dl12_cache(component, reg, value);
+	if (twl6040_can_write_to_chip(component, reg))
 		return twl6040_reg_write(twl6040, reg, value);
 	else
 		return 0;
 }
 
-static void twl6040_init_chip(struct snd_soc_codec *codec)
+static void twl6040_init_chip(struct snd_soc_component *component)
 {
-	twl6040_read(codec, TWL6040_REG_TRIM1);
-	twl6040_read(codec, TWL6040_REG_TRIM2);
-	twl6040_read(codec, TWL6040_REG_TRIM3);
-	twl6040_read(codec, TWL6040_REG_HSOTRIM);
-	twl6040_read(codec, TWL6040_REG_HFOTRIM);
+	twl6040_read(component, TWL6040_REG_TRIM1);
+	twl6040_read(component, TWL6040_REG_TRIM2);
+	twl6040_read(component, TWL6040_REG_TRIM3);
+	twl6040_read(component, TWL6040_REG_HSOTRIM);
+	twl6040_read(component, TWL6040_REG_HFOTRIM);
 
 	/* Change chip defaults */
 	/* No imput selected for microphone amplifiers */
-	twl6040_write(codec, TWL6040_REG_MICLCTL, 0x18);
-	twl6040_write(codec, TWL6040_REG_MICRCTL, 0x18);
+	twl6040_write(component, TWL6040_REG_MICLCTL, 0x18);
+	twl6040_write(component, TWL6040_REG_MICRCTL, 0x18);
 
 	/*
 	 * We need to lower the default gain values, so the ramp code
 	 * can work correctly for the first playback.
 	 * This reduces the pop noise heard at the first playback.
 	 */
-	twl6040_write(codec, TWL6040_REG_HSGAIN, 0xff);
-	twl6040_write(codec, TWL6040_REG_EARCTL, 0x1e);
-	twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1d);
-	twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1d);
-	twl6040_write(codec, TWL6040_REG_LINEGAIN, 0);
+	twl6040_write(component, TWL6040_REG_HSGAIN, 0xff);
+	twl6040_write(component, TWL6040_REG_EARCTL, 0x1e);
+	twl6040_write(component, TWL6040_REG_HFLGAIN, 0x1d);
+	twl6040_write(component, TWL6040_REG_HFRGAIN, 0x1d);
+	twl6040_write(component, TWL6040_REG_LINEGAIN, 0);
 }
 
 /* set headset dac and driver power mode */
-static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
+static int headset_power_mode(struct snd_soc_component *component, int high_perf)
 {
 	int hslctl, hsrctl;
 	int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE;
 
-	hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL);
-	hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL);
+	hslctl = twl6040_read(component, TWL6040_REG_HSLCTL);
+	hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL);
 
 	if (high_perf) {
 		hslctl &= ~mask;
@@ -227,8 +227,8 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
 		hsrctl |= mask;
 	}
 
-	twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
-	twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
+	twl6040_write(component, TWL6040_REG_HSLCTL, hslctl);
+	twl6040_write(component, TWL6040_REG_HSRCTL, hsrctl);
 
 	return 0;
 }
@@ -236,7 +236,7 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
 static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
 			struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	u8 hslctl, hsrctl;
 
 	/*
@@ -244,8 +244,8 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
 	 * Both HS DAC need to be turned on (before the HS driver) and off at
 	 * the same time.
 	 */
-	hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL);
-	hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL);
+	hslctl = twl6040_read(component, TWL6040_REG_HSLCTL);
+	hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL);
 	if (SND_SOC_DAPM_EVENT_ON(event)) {
 		hslctl |= TWL6040_HSDACENA;
 		hsrctl |= TWL6040_HSDACENA;
@@ -253,8 +253,8 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
 		hslctl &= ~TWL6040_HSDACENA;
 		hsrctl &= ~TWL6040_HSDACENA;
 	}
-	twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
-	twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
+	twl6040_write(component, TWL6040_REG_HSLCTL, hslctl);
+	twl6040_write(component, TWL6040_REG_HSRCTL, hsrctl);
 
 	msleep(1);
 	return 0;
@@ -263,17 +263,17 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
 static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
 			struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	if (SND_SOC_DAPM_EVENT_ON(event)) {
 		/* Earphone doesn't support low power mode */
 		priv->hs_power_mode_locked = 1;
-		ret = headset_power_mode(codec, 1);
+		ret = headset_power_mode(component, 1);
 	} else {
 		priv->hs_power_mode_locked = 0;
-		ret = headset_power_mode(codec, priv->hs_power_mode);
+		ret = headset_power_mode(component, priv->hs_power_mode);
 	}
 
 	msleep(1);
@@ -281,16 +281,16 @@ static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
 	return ret;
 }
 
-static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
+static void twl6040_hs_jack_report(struct snd_soc_component *component,
 				   struct snd_soc_jack *jack, int report)
 {
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 	int status;
 
 	mutex_lock(&priv->mutex);
 
 	/* Sync status */
-	status = twl6040_read(codec, TWL6040_REG_STATUS);
+	status = twl6040_read(component, TWL6040_REG_STATUS);
 	if (status & TWL6040_PLUGCOMP)
 		snd_soc_jack_report(jack, report, report);
 	else
@@ -299,16 +299,16 @@ static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
 	mutex_unlock(&priv->mutex);
 }
 
-void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
+void twl6040_hs_jack_detect(struct snd_soc_component *component,
 				struct snd_soc_jack *jack, int report)
 {
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 	struct twl6040_jack_data *hs_jack = &priv->hs_jack;
 
 	hs_jack->jack = jack;
 	hs_jack->report = report;
 
-	twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
+	twl6040_hs_jack_report(component, hs_jack->jack, hs_jack->report);
 }
 EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
 
@@ -316,17 +316,17 @@ static void twl6040_accessory_work(struct work_struct *work)
 {
 	struct twl6040_data *priv = container_of(work,
 					struct twl6040_data, hs_jack.work.work);
-	struct snd_soc_codec *codec = priv->codec;
+	struct snd_soc_component *component = priv->component;
 	struct twl6040_jack_data *hs_jack = &priv->hs_jack;
 
-	twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
+	twl6040_hs_jack_report(component, hs_jack->jack, hs_jack->report);
 }
 
 /* audio interrupt handler */
 static irqreturn_t twl6040_audio_handler(int irq, void *data)
 {
-	struct snd_soc_codec *codec = data;
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = data;
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	queue_delayed_work(system_power_efficient_wq,
 			   &priv->hs_jack.work, msecs_to_jiffies(200));
@@ -337,12 +337,12 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data)
 static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int val;
 
 	/* Do not allow changes while Input/FF efect is running */
-	val = twl6040_read(codec, e->reg);
+	val = twl6040_read(component, e->reg);
 	if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL))
 		return -EBUSY;
 
@@ -486,8 +486,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum,
 static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = priv->hs_power_mode;
 
@@ -497,13 +497,13 @@ static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
 static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 	int high_perf = ucontrol->value.enumerated.item[0];
 	int ret = 0;
 
 	if (!priv->hs_power_mode_locked)
-		ret = headset_power_mode(codec, high_perf);
+		ret = headset_power_mode(component, high_perf);
 
 	if (!ret)
 		priv->hs_power_mode = high_perf;
@@ -514,8 +514,8 @@ static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
 static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = priv->pll_power_mode;
 
@@ -525,17 +525,17 @@ static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol,
 static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	priv->pll_power_mode = ucontrol->value.enumerated.item[0];
 
 	return 0;
 }
 
-int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
+int twl6040_get_dl1_gain(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	if (snd_soc_dapm_get_pin_status(dapm, "EP"))
 		return -1; /* -1dB */
@@ -543,7 +543,7 @@ int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
 	if (snd_soc_dapm_get_pin_status(dapm, "HSOR") ||
 		snd_soc_dapm_get_pin_status(dapm, "HSOL")) {
 
-		u8 val = twl6040_read(codec, TWL6040_REG_HSLCTL);
+		u8 val = twl6040_read(component, TWL6040_REG_HSLCTL);
 		if (val & TWL6040_HSDACMODE)
 			/* HSDACL in LP mode */
 			return -8; /* -8dB */
@@ -555,26 +555,26 @@ int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain);
 
-int twl6040_get_clk_id(struct snd_soc_codec *codec)
+int twl6040_get_clk_id(struct snd_soc_component *component)
 {
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	return priv->pll_power_mode;
 }
 EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
 
-int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
+int twl6040_get_trim_value(struct snd_soc_component *component, enum twl6040_trim trim)
 {
 	if (unlikely(trim >= TWL6040_TRIM_INVAL))
 		return -EINVAL;
 
-	return twl6040_read(codec, TWL6040_REG_TRIM1 + trim);
+	return twl6040_read(component, TWL6040_REG_TRIM1 + trim);
 }
 EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
 
-int twl6040_get_hs_step_size(struct snd_soc_codec *codec)
+int twl6040_get_hs_step_size(struct snd_soc_component *component)
 {
-	struct twl6040 *twl6040 = to_twl6040(codec);
+	struct twl6040 *twl6040 = to_twl6040(component);
 
 	if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3)
 		/* For ES under ES_1.3 HS step is 2 mV */
@@ -829,11 +829,11 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"VIBRAR", NULL, "Vibra Right Driver"},
 };
 
-static int twl6040_set_bias_level(struct snd_soc_codec *codec,
+static int twl6040_set_bias_level(struct snd_soc_component *component,
 				enum snd_soc_bias_level level)
 {
-	struct twl6040 *twl6040 = to_twl6040(codec);
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct twl6040 *twl6040 = to_twl6040(component);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	switch (level) {
@@ -856,7 +856,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
 		priv->codec_powered = 1;
 
 		/* Set external boost GPO */
-		twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
+		twl6040_write(component, TWL6040_REG_GPOCTL, 0x02);
 		break;
 	case SND_SOC_BIAS_OFF:
 		if (!priv->codec_powered)
@@ -873,8 +873,8 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
 static int twl6040_startup(struct snd_pcm_substream *substream,
 			struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	snd_pcm_hw_constraint_list(substream->runtime, 0,
 				SNDRV_PCM_HW_PARAM_RATE,
@@ -887,8 +887,8 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
 			struct snd_pcm_hw_params *params,
 			struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 	int rate;
 
 	rate = params_rate(params);
@@ -899,7 +899,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
 	case 88200:
 		/* These rates are not supported when HPPLL is in use */
 		if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) {
-			dev_err(codec->dev, "HPPLL does not support rate %d\n",
+			dev_err(component->dev, "HPPLL does not support rate %d\n",
 				rate);
 			return -EINVAL;
 		}
@@ -913,7 +913,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
 		priv->sysclk = 19200000;
 		break;
 	default:
-		dev_err(codec->dev, "unsupported rate %d\n", rate);
+		dev_err(component->dev, "unsupported rate %d\n", rate);
 		return -EINVAL;
 	}
 
@@ -923,20 +923,20 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
 static int twl6040_prepare(struct snd_pcm_substream *substream,
 			struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct twl6040 *twl6040 = to_twl6040(codec);
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct twl6040 *twl6040 = to_twl6040(component);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	if (!priv->sysclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"no mclk configured, call set_sysclk() on init\n");
 		return -EINVAL;
 	}
 
 	ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk);
 	if (ret) {
-		dev_err(codec->dev, "Can not set PLL (%d)\n", ret);
+		dev_err(component->dev, "Can not set PLL (%d)\n", ret);
 		return -EPERM;
 	}
 
@@ -946,8 +946,8 @@ static int twl6040_prepare(struct snd_pcm_substream *substream,
 static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case TWL6040_SYSCLK_SEL_LPPLL:
@@ -956,26 +956,26 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		priv->clk_in = freq;
 		break;
 	default:
-		dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
+		dev_err(component->dev, "unknown clk_id %d\n", clk_id);
 		return -EINVAL;
 	}
 
 	return 0;
 }
 
-static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id,
+static void twl6040_mute_path(struct snd_soc_component *component, enum twl6040_dai_id id,
 			     int mute)
 {
-	struct twl6040 *twl6040 = to_twl6040(codec);
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct twl6040 *twl6040 = to_twl6040(component);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 	int hslctl, hsrctl, earctl;
 	int hflctl, hfrctl;
 
 	switch (id) {
 	case TWL6040_DAI_DL1:
-		hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL);
-		hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL);
-		earctl = twl6040_read(codec, TWL6040_REG_EARCTL);
+		hslctl = twl6040_read(component, TWL6040_REG_HSLCTL);
+		hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL);
+		earctl = twl6040_read(component, TWL6040_REG_EARCTL);
 
 		if (mute) {
 			/* Power down drivers and DACs */
@@ -991,8 +991,8 @@ static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id i
 		priv->dl1_unmuted = !mute;
 		break;
 	case TWL6040_DAI_DL2:
-		hflctl = twl6040_read(codec, TWL6040_REG_HFLCTL);
-		hfrctl = twl6040_read(codec, TWL6040_REG_HFRCTL);
+		hflctl = twl6040_read(component, TWL6040_REG_HFLCTL);
+		hfrctl = twl6040_read(component, TWL6040_REG_HFRCTL);
 
 		if (mute) {
 			/* Power down drivers and DACs */
@@ -1015,12 +1015,12 @@ static int twl6040_digital_mute(struct snd_soc_dai *dai, int mute)
 {
 	switch (dai->id) {
 	case TWL6040_DAI_LEGACY:
-		twl6040_mute_path(dai->codec, TWL6040_DAI_DL1, mute);
-		twl6040_mute_path(dai->codec, TWL6040_DAI_DL2, mute);
+		twl6040_mute_path(dai->component, TWL6040_DAI_DL1, mute);
+		twl6040_mute_path(dai->component, TWL6040_DAI_DL2, mute);
 		break;
 	case TWL6040_DAI_DL1:
 	case TWL6040_DAI_DL2:
-		twl6040_mute_path(dai->codec, dai->id, mute);
+		twl6040_mute_path(dai->component, dai->id, mute);
 		break;
 	default:
 		break;
@@ -1107,23 +1107,23 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
 },
 };
 
-static int twl6040_probe(struct snd_soc_codec *codec)
+static int twl6040_probe(struct snd_soc_component *component)
 {
 	struct twl6040_data *priv;
-	struct platform_device *pdev = to_platform_device(codec->dev);
+	struct platform_device *pdev = to_platform_device(component->dev);
 	int ret = 0;
 
-	priv = devm_kzalloc(codec->dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(component->dev, sizeof(*priv), GFP_KERNEL);
 	if (priv == NULL)
 		return -ENOMEM;
 
-	snd_soc_codec_set_drvdata(codec, priv);
+	snd_soc_component_set_drvdata(component, priv);
 
-	priv->codec = codec;
+	priv->component = component;
 
 	priv->plug_irq = platform_get_irq(pdev, 0);
 	if (priv->plug_irq < 0) {
-		dev_err(codec->dev, "invalid irq: %d\n", priv->plug_irq);
+		dev_err(component->dev, "invalid irq: %d\n", priv->plug_irq);
 		return priv->plug_irq;
 	}
 
@@ -1134,64 +1134,55 @@ static int twl6040_probe(struct snd_soc_codec *codec)
 	ret = request_threaded_irq(priv->plug_irq, NULL,
 					twl6040_audio_handler,
 					IRQF_NO_SUSPEND | IRQF_ONESHOT,
-					"twl6040_irq_plug", codec);
+					"twl6040_irq_plug", component);
 	if (ret) {
-		dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret);
+		dev_err(component->dev, "PLUG IRQ request failed: %d\n", ret);
 		return ret;
 	}
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
-	twl6040_init_chip(codec);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
+	twl6040_init_chip(component);
 
 	return 0;
 }
 
-static int twl6040_remove(struct snd_soc_codec *codec)
+static void twl6040_remove(struct snd_soc_component *component)
 {
-	struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
-	free_irq(priv->plug_irq, codec);
-
-	return 0;
+	free_irq(priv->plug_irq, component);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
-	.probe = twl6040_probe,
-	.remove = twl6040_remove,
-	.read = twl6040_read,
-	.write = twl6040_write,
-	.set_bias_level = twl6040_set_bias_level,
-	.suspend_bias_off = true,
-	.ignore_pmdown_time = true,
-
-	.component_driver = {
-		.controls		= twl6040_snd_controls,
-		.num_controls		= ARRAY_SIZE(twl6040_snd_controls),
-		.dapm_widgets		= twl6040_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(twl6040_dapm_widgets),
-		.dapm_routes		= intercon,
-		.num_dapm_routes	= ARRAY_SIZE(intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_twl6040 = {
+	.probe			= twl6040_probe,
+	.remove			= twl6040_remove,
+	.read			= twl6040_read,
+	.write			= twl6040_write,
+	.set_bias_level		= twl6040_set_bias_level,
+	.controls		= twl6040_snd_controls,
+	.num_controls		= ARRAY_SIZE(twl6040_snd_controls),
+	.dapm_widgets		= twl6040_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(twl6040_dapm_widgets),
+	.dapm_routes		= intercon,
+	.num_dapm_routes	= ARRAY_SIZE(intercon),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int twl6040_codec_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040,
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &soc_component_dev_twl6040,
 				      twl6040_dai, ARRAY_SIZE(twl6040_dai));
 }
 
-static int twl6040_codec_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 static struct platform_driver twl6040_codec_driver = {
 	.driver = {
 		.name = "twl6040-codec",
 	},
 	.probe = twl6040_codec_probe,
-	.remove = twl6040_codec_remove,
 };
 
 module_platform_driver(twl6040_codec_driver);
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index 0611406..3d9f957 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -34,11 +34,11 @@ enum twl6040_trim {
 #define TWL6040_HSF_TRIM_LEFT(x)	(x & 0x0f)
 #define TWL6040_HSF_TRIM_RIGHT(x)	((x >> 4) & 0x0f)
 
-int twl6040_get_dl1_gain(struct snd_soc_codec *codec);
-void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
+int twl6040_get_dl1_gain(struct snd_soc_component *component);
+void twl6040_hs_jack_detect(struct snd_soc_component *component,
 			    struct snd_soc_jack *jack, int report);
-int twl6040_get_clk_id(struct snd_soc_codec *codec);
-int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim);
-int twl6040_get_hs_step_size(struct snd_soc_codec *codec);
+int twl6040_get_clk_id(struct snd_soc_component *component);
+int twl6040_get_trim_value(struct snd_soc_component *component, enum twl6040_trim trim);
+int twl6040_get_hs_step_size(struct snd_soc_component *component);
 
 #endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 77c9cc4..3c935a9 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -110,9 +110,9 @@ static int uda134x_regmap_write(void *context, unsigned int reg,
 	return 0;
 }
 
-static inline void uda134x_reset(struct snd_soc_codec *codec)
+static inline void uda134x_reset(struct snd_soc_component *component)
 {
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 	unsigned int mask = 1<<6;
 
 	regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, mask, mask);
@@ -122,7 +122,7 @@ static inline void uda134x_reset(struct snd_soc_codec *codec)
 
 static int uda134x_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(dai->codec);
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(dai->component);
 	unsigned int mask = 1<<2;
 	unsigned int val;
 
@@ -139,8 +139,8 @@ static int uda134x_mute(struct snd_soc_dai *dai, int mute)
 static int uda134x_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 	struct snd_pcm_runtime *master_runtime;
 
 	if (uda134x->master_substream) {
@@ -168,8 +168,8 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
 static void uda134x_shutdown(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 
 	if (uda134x->master_substream == substream)
 		uda134x->master_substream = uda134x->slave_substream;
@@ -181,8 +181,8 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 	unsigned int hw_params = 0;
 
 	if (substream == uda134x->slave_substream) {
@@ -248,8 +248,8 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
 static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				  int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 
 	pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
 		 clk_id, freq, dir);
@@ -270,8 +270,8 @@ static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			       unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 
 	pr_debug("%s fmt: %08X\n", __func__, fmt);
 
@@ -294,10 +294,10 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-static int uda134x_set_bias_level(struct snd_soc_codec *codec,
+static int uda134x_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 	struct uda134x_platform_data *pd = uda134x->pd;
 	pr_debug("%s bias level %d\n", __func__, level);
 
@@ -446,10 +446,10 @@ static struct snd_soc_dai_driver uda134x_dai = {
 	.ops = &uda134x_dai_ops,
 };
 
-static int uda134x_soc_probe(struct snd_soc_codec *codec)
+static int uda134x_soc_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 	struct uda134x_platform_data *pd = uda134x->pd;
 	const struct snd_soc_dapm_widget *widgets;
 	unsigned num_widgets;
@@ -473,7 +473,7 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
 	if (pd->power)
 		pd->power(1);
 
-	uda134x_reset(codec);
+	uda134x_reset(component);
 
 	if (pd->model == UDA134X_UDA1341) {
 		widgets = uda1341_dapm_widgets;
@@ -493,15 +493,15 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
 	switch (pd->model) {
 	case UDA134X_UDA1340:
 	case UDA134X_UDA1344:
-		ret = snd_soc_add_codec_controls(codec, uda1340_snd_controls,
+		ret = snd_soc_add_component_controls(component, uda1340_snd_controls,
 					ARRAY_SIZE(uda1340_snd_controls));
 	break;
 	case UDA134X_UDA1341:
-		ret = snd_soc_add_codec_controls(codec, uda1341_snd_controls,
+		ret = snd_soc_add_component_controls(component, uda1341_snd_controls,
 					ARRAY_SIZE(uda1341_snd_controls));
 	break;
 	case UDA134X_UDA1345:
-		ret = snd_soc_add_codec_controls(codec, uda1345_snd_controls,
+		ret = snd_soc_add_component_controls(component, uda1345_snd_controls,
 					ARRAY_SIZE(uda1345_snd_controls));
 	break;
 	default:
@@ -518,17 +518,18 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_uda134x = {
-	.probe =        uda134x_soc_probe,
-	.set_bias_level = uda134x_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.dapm_widgets		= uda134x_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(uda134x_dapm_widgets),
-		.dapm_routes		= uda134x_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(uda134x_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_uda134x = {
+	.probe			= uda134x_soc_probe,
+	.set_bias_level		= uda134x_set_bias_level,
+	.dapm_widgets		= uda134x_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(uda134x_dapm_widgets),
+	.dapm_routes		= uda134x_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(uda134x_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config uda134x_regmap_config = {
@@ -571,14 +572,8 @@ static int uda134x_codec_probe(struct platform_device *pdev)
 	if (IS_ERR(uda134x->regmap))
 		return PTR_ERR(uda134x->regmap);
 
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_uda134x, &uda134x_dai, 1);
-}
-
-static int uda134x_codec_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_uda134x, &uda134x_dai, 1);
 }
 
 static struct platform_driver uda134x_codec_driver = {
@@ -586,7 +581,6 @@ static struct platform_driver uda134x_codec_driver = {
 		.name = "uda134x-codec",
 	},
 	.probe = uda134x_codec_probe,
-	.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 c73e6a1..584a032 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -34,7 +34,7 @@
 
 /* codec private data */
 struct uda1380_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	unsigned int dac_clk;
 	struct work_struct work;
 	struct i2c_client *i2c;
@@ -61,10 +61,10 @@ static unsigned long uda1380_cache_dirty;
 /*
  * read uda1380 register cache
  */
-static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
+static inline unsigned int uda1380_read_reg_cache(struct snd_soc_component *component,
 	unsigned int reg)
 {
-	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
 	u16 *cache = uda1380->reg_cache;
 
 	if (reg == UDA1380_RESET)
@@ -77,10 +77,10 @@ static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
 /*
  * write uda1380 register cache
  */
-static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
+static inline void uda1380_write_reg_cache(struct snd_soc_component *component,
 	u16 reg, unsigned int value)
 {
-	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
 	u16 *cache = uda1380->reg_cache;
 
 	if (reg >= UDA1380_CACHEREGNUM)
@@ -93,10 +93,10 @@ static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
 /*
  * write to the UDA1380 register space
  */
-static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
+static int uda1380_write(struct snd_soc_component *component, unsigned int reg,
 	unsigned int value)
 {
-	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
 	u8 data[3];
 
 	/* data is
@@ -108,12 +108,12 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
 	data[1] = (value & 0xff00) >> 8;
 	data[2] = value & 0x00ff;
 
-	uda1380_write_reg_cache(codec, reg, value);
+	uda1380_write_reg_cache(component, reg, value);
 
 	/* the interpolator & decimator regs must only be written when the
 	 * codec DAI is active.
 	 */
-	if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL))
+	if (!snd_soc_component_is_active(component) && (reg >= UDA1380_MVOL))
 		return 0;
 	pr_debug("uda1380: hw write %x val %x\n", reg, value);
 	if (i2c_master_send(uda1380->i2c, data, 3) == 3) {
@@ -133,9 +133,9 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
 		return -EIO;
 }
 
-static void uda1380_sync_cache(struct snd_soc_codec *codec)
+static void uda1380_sync_cache(struct snd_soc_component *component)
 {
-	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
 	int reg;
 	u8 data[3];
 	u16 *cache = uda1380->reg_cache;
@@ -146,15 +146,15 @@ static void uda1380_sync_cache(struct snd_soc_codec *codec)
 		data[1] = (cache[reg] & 0xff00) >> 8;
 		data[2] = cache[reg] & 0x00ff;
 		if (i2c_master_send(uda1380->i2c, data, 3) != 3)
-			dev_err(codec->dev, "%s: write to reg 0x%x failed\n",
+			dev_err(component->dev, "%s: write to reg 0x%x failed\n",
 				__func__, reg);
 	}
 }
 
-static int uda1380_reset(struct snd_soc_codec *codec)
+static int uda1380_reset(struct snd_soc_component *component)
 {
-	struct uda1380_platform_data *pdata = codec->dev->platform_data;
-	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+	struct uda1380_platform_data *pdata = component->dev->platform_data;
+	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
 
 	if (gpio_is_valid(pdata->gpio_reset)) {
 		gpio_set_value(pdata->gpio_reset, 1);
@@ -168,7 +168,7 @@ static int uda1380_reset(struct snd_soc_codec *codec)
 		data[2] = 0;
 
 		if (i2c_master_send(uda1380->i2c, data, 3) != 3) {
-			dev_err(codec->dev, "%s: failed\n", __func__);
+			dev_err(component->dev, "%s: failed\n", __func__);
 			return -EIO;
 		}
 	}
@@ -179,15 +179,15 @@ static int uda1380_reset(struct snd_soc_codec *codec)
 static void uda1380_flush_work(struct work_struct *work)
 {
 	struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
-	struct snd_soc_codec *uda1380_codec = uda1380->codec;
+	struct snd_soc_component *uda1380_component = uda1380->component;
 	int bit, reg;
 
 	for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
 		reg = 0x10 + bit;
 		pr_debug("uda1380: flush reg %x val %x:\n", reg,
-				uda1380_read_reg_cache(uda1380_codec, reg));
-		uda1380_write(uda1380_codec, reg,
-				uda1380_read_reg_cache(uda1380_codec, reg));
+				uda1380_read_reg_cache(uda1380_component, reg));
+		uda1380_write(uda1380_component, reg,
+				uda1380_read_reg_cache(uda1380_component, reg));
 		clear_bit(bit, &uda1380_cache_dirty);
 	}
 
@@ -420,11 +420,11 @@ static const struct snd_soc_dapm_route uda1380_dapm_routes[] = {
 static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int iface;
 
 	/* set up DAI based upon fmt */
-	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+	iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -442,7 +442,7 @@ static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
 		return -EINVAL;
 
-	uda1380_write_reg_cache(codec, UDA1380_IFACE, iface);
+	uda1380_write_reg_cache(component, UDA1380_IFACE, iface);
 
 	return 0;
 }
@@ -450,11 +450,11 @@ static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
 static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int iface;
 
 	/* set up DAI based upon fmt */
-	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+	iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
 	iface &= ~R01_SFORI_MASK;
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -472,7 +472,7 @@ static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
 		return -EINVAL;
 
-	uda1380_write(codec, UDA1380_IFACE, iface);
+	uda1380_write(component, UDA1380_IFACE, iface);
 
 	return 0;
 }
@@ -480,11 +480,11 @@ static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
 static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int iface;
 
 	/* set up DAI based upon fmt */
-	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+	iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
 	iface &= ~(R01_SIM | R01_SFORO_MASK);
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -501,7 +501,7 @@ static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
 		iface |= R01_SIM;
 
-	uda1380_write(codec, UDA1380_IFACE, iface);
+	uda1380_write(component, UDA1380_IFACE, iface);
 
 	return 0;
 }
@@ -509,20 +509,20 @@ static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
 static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
 		struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
-	int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
+	struct snd_soc_component *component = dai->component;
+	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
+	int mixer = uda1380_read_reg_cache(component, UDA1380_MIXER);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		uda1380_write_reg_cache(codec, UDA1380_MIXER,
+		uda1380_write_reg_cache(component, UDA1380_MIXER,
 					mixer & ~R14_SILENCE);
 		schedule_work(&uda1380->work);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		uda1380_write_reg_cache(codec, UDA1380_MIXER,
+		uda1380_write_reg_cache(component, UDA1380_MIXER,
 					mixer | R14_SILENCE);
 		schedule_work(&uda1380->work);
 		break;
@@ -534,13 +534,13 @@ static int uda1380_pcm_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;
-	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
+	struct snd_soc_component *component = dai->component;
+	u16 clk = uda1380_read_reg_cache(component, UDA1380_CLK);
 
 	/* set WSPLL power and divider if running from this clock */
 	if (clk & R00_DAC_CLK) {
 		int rate = params_rate(params);
-		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
+		u16 pm = uda1380_read_reg_cache(component, UDA1380_PM);
 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
 		switch (rate) {
 		case 6250 ... 12500:
@@ -556,7 +556,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
 			clk |= 0x3;
 			break;
 		}
-		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
+		uda1380_write(component, UDA1380_PM, R02_PON_PLL | pm);
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -564,20 +564,20 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
 	else
 		clk |= R00_EN_ADC | R00_EN_DEC;
 
-	uda1380_write(codec, UDA1380_CLK, clk);
+	uda1380_write(component, UDA1380_CLK, clk);
 	return 0;
 }
 
 static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
+	struct snd_soc_component *component = dai->component;
+	u16 clk = uda1380_read_reg_cache(component, UDA1380_CLK);
 
 	/* shut down WSPLL power if running from this clock */
 	if (clk & R00_DAC_CLK) {
-		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
-		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
+		u16 pm = uda1380_read_reg_cache(component, UDA1380_PM);
+		uda1380_write(component, UDA1380_PM, ~R02_PON_PLL & pm);
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -585,33 +585,33 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
 	else
 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
 
-	uda1380_write(codec, UDA1380_CLK, clk);
+	uda1380_write(component, UDA1380_CLK, clk);
 }
 
-static int uda1380_set_bias_level(struct snd_soc_codec *codec,
+static int uda1380_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
+	int pm = uda1380_read_reg_cache(component, UDA1380_PM);
 	int reg;
-	struct uda1380_platform_data *pdata = codec->dev->platform_data;
+	struct uda1380_platform_data *pdata = component->dev->platform_data;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		/* ADC, DAC on */
-		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
+		uda1380_write(component, UDA1380_PM, R02_PON_BIAS | pm);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			if (gpio_is_valid(pdata->gpio_power)) {
 				gpio_set_value(pdata->gpio_power, 1);
 				mdelay(1);
-				uda1380_reset(codec);
+				uda1380_reset(component);
 			}
 
-			uda1380_sync_cache(codec);
+			uda1380_sync_cache(component);
 		}
-		uda1380_write(codec, UDA1380_PM, 0x0);
+		uda1380_write(component, UDA1380_PM, 0x0);
 		break;
 	case SND_SOC_BIAS_OFF:
 		if (!gpio_is_valid(pdata->gpio_power))
@@ -694,16 +694,16 @@ static struct snd_soc_dai_driver uda1380_dai[] = {
 },
 };
 
-static int uda1380_probe(struct snd_soc_codec *codec)
+static int uda1380_probe(struct snd_soc_component *component)
 {
-	struct uda1380_platform_data *pdata =codec->dev->platform_data;
-	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+	struct uda1380_platform_data *pdata =component->dev->platform_data;
+	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	uda1380->codec = codec;
+	uda1380->component = component;
 
 	if (!gpio_is_valid(pdata->gpio_power)) {
-		ret = uda1380_reset(codec);
+		ret = uda1380_reset(component);
 		if (ret)
 			return ret;
 	}
@@ -713,10 +713,10 @@ static int uda1380_probe(struct snd_soc_codec *codec)
 	/* set clock input */
 	switch (pdata->dac_clk) {
 	case UDA1380_DAC_CLK_SYSCLK:
-		uda1380_write_reg_cache(codec, UDA1380_CLK, 0);
+		uda1380_write_reg_cache(component, UDA1380_CLK, 0);
 		break;
 	case UDA1380_DAC_CLK_WSPLL:
-		uda1380_write_reg_cache(codec, UDA1380_CLK,
+		uda1380_write_reg_cache(component, UDA1380_CLK,
 			R00_DAC_CLK);
 		break;
 	}
@@ -724,21 +724,22 @@ static int uda1380_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
-	.probe =	uda1380_probe,
-	.read =		uda1380_read_reg_cache,
-	.write =	uda1380_write,
-	.set_bias_level = uda1380_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= uda1380_snd_controls,
-		.num_controls		= ARRAY_SIZE(uda1380_snd_controls),
-		.dapm_widgets		= uda1380_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(uda1380_dapm_widgets),
-		.dapm_routes		= uda1380_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(uda1380_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_uda1380 = {
+	.probe			= uda1380_probe,
+	.read			= uda1380_read_reg_cache,
+	.write			= uda1380_write,
+	.set_bias_level		= uda1380_set_bias_level,
+	.controls		= uda1380_snd_controls,
+	.num_controls		= ARRAY_SIZE(uda1380_snd_controls),
+	.dapm_widgets		= uda1380_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(uda1380_dapm_widgets),
+	.dapm_routes		= uda1380_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(uda1380_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int uda1380_i2c_probe(struct i2c_client *i2c,
@@ -780,17 +781,11 @@ static int uda1380_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, uda1380);
 	uda1380->i2c = i2c;
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
 	return ret;
 }
 
-static int uda1380_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-	return 0;
-}
-
 static const struct i2c_device_id uda1380_i2c_id[] = {
 	{ "uda1380", 0 },
 	{ }
@@ -809,7 +804,6 @@ static struct i2c_driver uda1380_i2c_driver = {
 		.of_match_table = uda1380_of_match,
 	},
 	.probe =    uda1380_i2c_probe,
-	.remove =   uda1380_i2c_remove,
 	.id_table = uda1380_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 942f164..929ef1f 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -172,8 +172,8 @@ static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core,
 static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
 				      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = wl1273->mode;
 
@@ -190,14 +190,14 @@ static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
 static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
 				      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
 	if (wl1273->mode == ucontrol->value.enumerated.item[0])
 		return 0;
 
 	/* Do not allow changes while stream is running */
-	if (snd_soc_codec_is_active(codec))
+	if (snd_soc_component_is_active(component))
 		return -EPERM;
 
 	if (ucontrol->value.enumerated.item[0] >=  ARRAY_SIZE(wl1273_audio_route))
@@ -213,10 +213,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route);
 static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s: enter.\n", __func__);
+	dev_dbg(component->dev, "%s: enter.\n", __func__);
 
 	ucontrol->value.enumerated.item[0] = wl1273->core->audio_mode;
 
@@ -226,11 +226,11 @@ static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
 static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 	int val, r = 0;
 
-	dev_dbg(codec->dev, "%s: enter.\n", __func__);
+	dev_dbg(component->dev, "%s: enter.\n", __func__);
 
 	val = ucontrol->value.enumerated.item[0];
 	if (wl1273->core->audio_mode == val)
@@ -250,10 +250,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings);
 static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
 				    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s: enter.\n", __func__);
+	dev_dbg(component->dev, "%s: enter.\n", __func__);
 
 	ucontrol->value.integer.value[0] = wl1273->core->volume;
 
@@ -263,11 +263,11 @@ static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
 static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,
 				    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 	int r;
 
-	dev_dbg(codec->dev, "%s: enter.\n", __func__);
+	dev_dbg(component->dev, "%s: enter.\n", __func__);
 
 	r = wl1273->core->set_volume(wl1273->core,
 				     ucontrol->value.integer.value[0]);
@@ -301,8 +301,8 @@ static const struct snd_soc_dapm_route wl1273_dapm_routes[] = {
 static int wl1273_startup(struct snd_pcm_substream *substream,
 			  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
 	switch (wl1273->mode) {
 	case WL1273_MODE_BT:
@@ -335,7 +335,7 @@ static int wl1273_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(dai->codec);
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(dai->component);
 	struct wl1273_core *core = wl1273->core;
 	unsigned int rate, width, r;
 
@@ -415,14 +415,14 @@ static struct snd_soc_dai_driver wl1273_dai = {
 };
 
 /* Audio interface format for the soc_card driver */
-int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt)
+int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt)
 {
 	struct wl1273_priv *wl1273;
 
-	if (codec == NULL || fmt == NULL)
+	if (component == NULL || fmt == NULL)
 		return -EINVAL;
 
-	wl1273 = snd_soc_codec_get_drvdata(codec);
+	wl1273 = snd_soc_component_get_drvdata(component);
 
 	switch (wl1273->mode) {
 	case WL1273_MODE_FM_RX:
@@ -446,15 +446,15 @@ int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt)
 }
 EXPORT_SYMBOL_GPL(wl1273_get_format);
 
-static int wl1273_probe(struct snd_soc_codec *codec)
+static int wl1273_probe(struct snd_soc_component *component)
 {
-	struct wl1273_core **core = codec->dev->platform_data;
+	struct wl1273_core **core = component->dev->platform_data;
 	struct wl1273_priv *wl1273;
 
-	dev_dbg(codec->dev, "%s.\n", __func__);
+	dev_dbg(component->dev, "%s.\n", __func__);
 
 	if (!core) {
-		dev_err(codec->dev, "Platform data is missing.\n");
+		dev_err(component->dev, "Platform data is missing.\n");
 		return -EINVAL;
 	}
 
@@ -465,44 +465,43 @@ static int wl1273_probe(struct snd_soc_codec *codec)
 	wl1273->mode = WL1273_MODE_BT;
 	wl1273->core = *core;
 
-	snd_soc_codec_set_drvdata(codec, wl1273);
+	snd_soc_component_set_drvdata(component, wl1273);
 
 	return 0;
 }
 
-static int wl1273_remove(struct snd_soc_codec *codec)
+static void wl1273_remove(struct snd_soc_component *component)
 {
-	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+	struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "%s\n", __func__);
+	dev_dbg(component->dev, "%s\n", __func__);
 	kfree(wl1273);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
-	.probe = wl1273_probe,
-	.remove = wl1273_remove,
-
-	.component_driver = {
-		.controls		= wl1273_controls,
-		.num_controls		= ARRAY_SIZE(wl1273_controls),
-		.dapm_widgets		= wl1273_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wl1273_dapm_widgets),
-		.dapm_routes		= wl1273_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wl1273_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wl1273 = {
+	.probe			= wl1273_probe,
+	.remove			= wl1273_remove,
+	.controls		= wl1273_controls,
+	.num_controls		= ARRAY_SIZE(wl1273_controls),
+	.dapm_widgets		= wl1273_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wl1273_dapm_widgets),
+	.dapm_routes		= wl1273_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wl1273_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wl1273_platform_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl1273,
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &soc_component_dev_wl1273,
 				      &wl1273_dai, 1);
 }
 
 static int wl1273_platform_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wl1273.h b/sound/soc/codecs/wl1273.h
index 43ec7e6..43a81d5 100644
--- a/sound/soc/codecs/wl1273.h
+++ b/sound/soc/codecs/wl1273.h
@@ -25,6 +25,6 @@
 #ifndef __WL1273_CODEC_H__
 #define __WL1273_CODEC_H__
 
-int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt);
+int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt);
 
 #endif	/* End of __WL1273_CODEC_H__ */
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index 0147d2f..abd2def 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -90,7 +90,7 @@ enum wm0010_state {
 };
 
 struct wm0010_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 
 	struct mutex lock;
 	struct device *dev;
@@ -157,9 +157,9 @@ static const char *wm0010_state_to_str(enum wm0010_state state)
 }
 
 /* Called with wm0010->lock held */
-static void wm0010_halt(struct snd_soc_codec *codec)
+static void wm0010_halt(struct snd_soc_component *component)
 {
-	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 	unsigned long flags;
 	enum wm0010_state state;
 
@@ -193,7 +193,7 @@ static void wm0010_halt(struct snd_soc_codec *codec)
 
 struct wm0010_boot_xfer {
 	struct list_head list;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct completion *done;
 	struct spi_message m;
 	struct spi_transfer t;
@@ -218,13 +218,13 @@ static void wm0010_mark_boot_failure(struct wm0010_priv *wm0010)
 static void wm0010_boot_xfer_complete(void *data)
 {
 	struct wm0010_boot_xfer *xfer = data;
-	struct snd_soc_codec *codec = xfer->codec;
-	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = xfer->component;
+	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 	u32 *out32 = xfer->t.rx_buf;
 	int i;
 
 	if (xfer->m.status != 0) {
-		dev_err(codec->dev, "SPI transfer failed: %d\n",
+		dev_err(component->dev, "SPI transfer failed: %d\n",
 			xfer->m.status);
 		wm0010_mark_boot_failure(wm0010);
 		if (xfer->done)
@@ -233,11 +233,11 @@ static void wm0010_boot_xfer_complete(void *data)
 	}
 
 	for (i = 0; i < xfer->t.len / 4; i++) {
-		dev_dbg(codec->dev, "%d: %04x\n", i, out32[i]);
+		dev_dbg(component->dev, "%d: %04x\n", i, out32[i]);
 
 		switch (be32_to_cpu(out32[i])) {
 		case 0xe0e0e0e0:
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"%d: ROM error reported in stage 2\n", i);
 			wm0010_mark_boot_failure(wm0010);
 			break;
@@ -245,82 +245,82 @@ static void wm0010_boot_xfer_complete(void *data)
 		case 0x55555555:
 			if (wm0010->state < WM0010_STAGE2)
 				break;
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"%d: ROM bootloader running in stage 2\n", i);
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		case 0x0fed0000:
-			dev_dbg(codec->dev, "Stage2 loader running\n");
+			dev_dbg(component->dev, "Stage2 loader running\n");
 			break;
 
 		case 0x0fed0007:
-			dev_dbg(codec->dev, "CODE_HDR packet received\n");
+			dev_dbg(component->dev, "CODE_HDR packet received\n");
 			break;
 
 		case 0x0fed0008:
-			dev_dbg(codec->dev, "CODE_DATA packet received\n");
+			dev_dbg(component->dev, "CODE_DATA packet received\n");
 			break;
 
 		case 0x0fed0009:
-			dev_dbg(codec->dev, "Download complete\n");
+			dev_dbg(component->dev, "Download complete\n");
 			break;
 
 		case 0x0fed000c:
-			dev_dbg(codec->dev, "Application start\n");
+			dev_dbg(component->dev, "Application start\n");
 			break;
 
 		case 0x0fed000e:
-			dev_dbg(codec->dev, "PLL packet received\n");
+			dev_dbg(component->dev, "PLL packet received\n");
 			wm0010->pll_running = true;
 			break;
 
 		case 0x0fed0025:
-			dev_err(codec->dev, "Device reports image too long\n");
+			dev_err(component->dev, "Device reports image too long\n");
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		case 0x0fed002c:
-			dev_err(codec->dev, "Device reports bad SPI packet\n");
+			dev_err(component->dev, "Device reports bad SPI packet\n");
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		case 0x0fed0031:
-			dev_err(codec->dev, "Device reports SPI read overflow\n");
+			dev_err(component->dev, "Device reports SPI read overflow\n");
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		case 0x0fed0032:
-			dev_err(codec->dev, "Device reports SPI underclock\n");
+			dev_err(component->dev, "Device reports SPI underclock\n");
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		case 0x0fed0033:
-			dev_err(codec->dev, "Device reports bad header packet\n");
+			dev_err(component->dev, "Device reports bad header packet\n");
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		case 0x0fed0034:
-			dev_err(codec->dev, "Device reports invalid packet type\n");
+			dev_err(component->dev, "Device reports invalid packet type\n");
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		case 0x0fed0035:
-			dev_err(codec->dev, "Device reports data before header error\n");
+			dev_err(component->dev, "Device reports data before header error\n");
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		case 0x0fed0038:
-			dev_err(codec->dev, "Device reports invalid PLL packet\n");
+			dev_err(component->dev, "Device reports invalid PLL packet\n");
 			break;
 
 		case 0x0fed003a:
-			dev_err(codec->dev, "Device reports packet alignment error\n");
+			dev_err(component->dev, "Device reports packet alignment error\n");
 			wm0010_mark_boot_failure(wm0010);
 			break;
 
 		default:
-			dev_err(codec->dev, "Unrecognised return 0x%x\n",
+			dev_err(component->dev, "Unrecognised return 0x%x\n",
 			    be32_to_cpu(out32[i]));
 			wm0010_mark_boot_failure(wm0010);
 			break;
@@ -342,10 +342,10 @@ static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len)
 		data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
 }
 
-static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
+static int wm0010_firmware_load(const char *name, struct snd_soc_component *component)
 {
-	struct spi_device *spi = to_spi_device(codec->dev);
-	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	struct spi_device *spi = to_spi_device(component->dev);
+	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 	struct list_head xfer_list;
 	struct wm0010_boot_xfer *xfer;
 	int ret;
@@ -359,9 +359,9 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
 
 	INIT_LIST_HEAD(&xfer_list);
 
-	ret = request_firmware(&fw, name, codec->dev);
+	ret = request_firmware(&fw, name, component->dev);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request application(%s): %d\n",
+		dev_err(component->dev, "Failed to request application(%s): %d\n",
 			name, ret);
 		return ret;
 	}
@@ -377,25 +377,25 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
 
 	/* First record should be INFO */
 	if (rec->command != DFW_CMD_INFO) {
-		dev_err(codec->dev, "First record not INFO\r\n");
+		dev_err(component->dev, "First record not INFO\r\n");
 		ret = -EINVAL;
 		goto abort;
 	}
 
 	if (inforec->info_version != INFO_VERSION) {
-		dev_err(codec->dev,
+		dev_err(component->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",
+	dev_dbg(component->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");
+		dev_err(component->dev, "Not a WM0010 firmware file.\r\n");
 		ret = -EINVAL;
 		goto abort;
 	}
@@ -405,7 +405,7 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
 	rec = (void *)&rec->data[rec->length];
 
 	while (offset < fw->size) {
-		dev_dbg(codec->dev,
+		dev_dbg(component->dev,
 			"Packet: command %d, data length = 0x%x\r\n",
 			rec->command, rec->length);
 		len = rec->length + 8;
@@ -416,7 +416,7 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
 			goto abort;
 		}
 
-		xfer->codec = codec;
+		xfer->component = component;
 		list_add_tail(&xfer->list, &xfer_list);
 
 		out = kzalloc(len, GFP_KERNEL | GFP_DMA);
@@ -460,18 +460,18 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
 		rec = (void *)&rec->data[rec->length];
 
 		if (offset >= fw->size) {
-			dev_dbg(codec->dev, "All transfers scheduled\n");
+			dev_dbg(component->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);
+			dev_err(component->dev, "Write failed: %d\n", ret);
 			goto abort1;
 		}
 
 		if (wm0010->boot_failed) {
-			dev_dbg(codec->dev, "Boot fail!\n");
+			dev_dbg(component->dev, "Boot fail!\n");
 			ret = -EINVAL;
 			goto abort1;
 		}
@@ -496,10 +496,10 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int wm0010_stage2_load(struct snd_soc_codec *codec)
+static int wm0010_stage2_load(struct snd_soc_component *component)
 {
-	struct spi_device *spi = to_spi_device(codec->dev);
-	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	struct spi_device *spi = to_spi_device(component->dev);
+	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 	const struct firmware *fw;
 	struct spi_message m;
 	struct spi_transfer t;
@@ -508,14 +508,14 @@ static int wm0010_stage2_load(struct snd_soc_codec *codec)
 	int i;
 	int ret = 0;
 
-	ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
+	ret = request_firmware(&fw, "wm0010_stage2.bin", component->dev);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
+		dev_err(component->dev, "Failed to request stage2 loader: %d\n",
 			ret);
 		return ret;
 	}
 
-	dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
+	dev_dbg(component->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 | GFP_DMA);
@@ -541,19 +541,19 @@ static int wm0010_stage2_load(struct snd_soc_codec *codec)
 	t.speed_hz = wm0010->sysclk / 10;
 	spi_message_add_tail(&t, &m);
 
-	dev_dbg(codec->dev, "Starting initial download at %dHz\n",
+	dev_dbg(component->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);
+		dev_err(component->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",
+			dev_err(component->dev, "Boot ROM error: %x in %d\n",
 				out[i], i);
 			wm0010_mark_boot_failure(wm0010);
 			ret = -EBUSY;
@@ -570,10 +570,10 @@ static int wm0010_stage2_load(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int wm0010_boot(struct snd_soc_codec *codec)
+static int wm0010_boot(struct snd_soc_component *component)
 {
-	struct spi_device *spi = to_spi_device(codec->dev);
-	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	struct spi_device *spi = to_spi_device(component->dev);
+	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 	unsigned long flags;
 	int ret;
 	struct spi_message m;
@@ -590,7 +590,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
 
 	if (wm0010->sysclk > 26000000) {
-		dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n");
+		dev_err(component->dev, "Max DSP clock frequency is 26MHz\n");
 		ret = -ECANCELED;
 		goto err;
 	}
@@ -598,7 +598,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 	mutex_lock(&wm0010->lock);
 	wm0010->pll_running = false;
 
-	dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);
+	dev_dbg(component->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies),
 				    wm0010->core_supplies);
@@ -623,19 +623,19 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 
 	if (!wait_for_completion_timeout(&wm0010->boot_completion,
 					 msecs_to_jiffies(20)))
-		dev_err(codec->dev, "Failed to get interrupt from DSP\n");
+		dev_err(component->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);
 
-	ret = wm0010_stage2_load(codec);
+	ret = wm0010_stage2_load(component);
 	if (ret)
 		goto abort;
 
 	if (!wait_for_completion_timeout(&wm0010->boot_completion,
 					 msecs_to_jiffies(20)))
-		dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n");
+		dev_err(component->dev, "Failed to get interrupt from DSP loader.\n");
 
 	spin_lock_irqsave(&wm0010->irq_lock, flags);
 	wm0010->state = WM0010_STAGE2;
@@ -676,14 +676,14 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 
 		ret = spi_sync(spi, &m);
 		if (ret) {
-			dev_err(codec->dev, "First PLL write failed: %d\n", ret);
+			dev_err(component->dev, "First PLL write failed: %d\n", ret);
 			goto abort_swap;
 		}
 
 		/* Use a second send of the message to get the return status */
 		ret = spi_sync(spi, &m);
 		if (ret) {
-			dev_err(codec->dev, "Second PLL write failed: %d\n", ret);
+			dev_err(component->dev, "Second PLL write failed: %d\n", ret);
 			goto abort_swap;
 		}
 
@@ -692,7 +692,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 		/* Look for PLL active code from the DSP */
 		for (i = 0; i < len / 4; i++) {
 			if (*p == 0x0e00ed0f) {
-				dev_dbg(codec->dev, "PLL packet received\n");
+				dev_dbg(component->dev, "PLL packet received\n");
 				wm0010->pll_running = true;
 				break;
 			}
@@ -702,9 +702,9 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 		kfree(img_swap);
 		kfree(out);
 	} else
-		dev_dbg(codec->dev, "Not enabling DSP PLL.");
+		dev_dbg(component->dev, "Not enabling DSP PLL.");
 
-	ret = wm0010_firmware_load("wm0010.dfw", codec);
+	ret = wm0010_firmware_load("wm0010.dfw", component);
 
 	if (ret != 0)
 		goto abort;
@@ -723,7 +723,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 	kfree(out);
 abort:
 	/* Put the chip back into reset */
-	wm0010_halt(codec);
+	wm0010_halt(component);
 	mutex_unlock(&wm0010->lock);
 	return ret;
 
@@ -735,22 +735,22 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int wm0010_set_bias_level(struct snd_soc_codec *codec,
+static int wm0010_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE)
-			wm0010_boot(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE)
+			wm0010_boot(component);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) {
 			mutex_lock(&wm0010->lock);
-			wm0010_halt(codec);
+			wm0010_halt(component);
 			mutex_unlock(&wm0010->lock);
 		}
 		break;
@@ -761,10 +761,10 @@ static int wm0010_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
+static int wm0010_set_sysclk(struct snd_soc_component *component, int source,
 			     int clk_id, unsigned int freq, int dir)
 {
-	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 	unsigned int i;
 
 	wm0010->sysclk = freq;
@@ -783,20 +783,19 @@ static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
 	return 0;
 }
 
-static int wm0010_probe(struct snd_soc_codec *codec);
+static int wm0010_probe(struct snd_soc_component *component);
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm0010 = {
-	.probe = wm0010_probe,
-	.set_bias_level = wm0010_set_bias_level,
-	.set_sysclk = wm0010_set_sysclk,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.dapm_widgets		= wm0010_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm0010_dapm_widgets),
-		.dapm_routes		= wm0010_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm0010_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm0010 = {
+	.probe			= wm0010_probe,
+	.set_bias_level		= wm0010_set_bias_level,
+	.set_sysclk		= wm0010_set_sysclk,
+	.dapm_widgets		= wm0010_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm0010_dapm_widgets),
+	.dapm_routes		= wm0010_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm0010_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
@@ -860,11 +859,11 @@ static irqreturn_t wm0010_irq(int irq, void *data)
 	return IRQ_NONE;
 }
 
-static int wm0010_probe(struct snd_soc_codec *codec)
+static int wm0010_probe(struct snd_soc_component *component)
 {
-	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 
-	wm0010->codec = codec;
+	wm0010->component = component;
 
 	return 0;
 }
@@ -967,8 +966,8 @@ static int wm0010_spi_probe(struct spi_device *spi)
 	else
 		wm0010->board_max_spi_speed = 0;
 
-	ret = snd_soc_register_codec(&spi->dev,
-				     &soc_codec_dev_wm0010, wm0010_dai,
+	ret = devm_snd_soc_register_component(&spi->dev,
+				     &soc_component_dev_wm0010, wm0010_dai,
 				     ARRAY_SIZE(wm0010_dai));
 	if (ret < 0)
 		return ret;
@@ -980,8 +979,6 @@ static int wm0010_spi_remove(struct spi_device *spi)
 {
 	struct wm0010_priv *wm0010 = spi_get_drvdata(spi);
 
-	snd_soc_unregister_codec(&spi->dev);
-
 	gpio_set_value_cansleep(wm0010->gpio_reset,
 				wm0010->gpio_reset_value);
 
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index cf5f058..9727eec 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -32,10 +32,10 @@ struct wm1250_priv {
 	struct gpio gpios[WM1250_EV1_NUM_GPIOS];
 };
 
-static int wm1250_ev1_set_bias_level(struct snd_soc_codec *codec,
+static int wm1250_ev1_set_bias_level(struct snd_soc_component *component,
 				     enum snd_soc_bias_level level)
 {
-	struct wm1250_priv *wm1250 = dev_get_drvdata(codec->dev);
+	struct wm1250_priv *wm1250 = dev_get_drvdata(component->dev);
 	int ena;
 
 	if (wm1250)
@@ -81,7 +81,7 @@ static int wm1250_ev1_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct wm1250_priv *wm1250 = snd_soc_codec_get_drvdata(dai->codec);
+	struct wm1250_priv *wm1250 = snd_soc_component_get_drvdata(dai->component);
 
 	switch (params_rate(params)) {
 	case 8000:
@@ -141,15 +141,15 @@ static struct snd_soc_dai_driver wm1250_ev1_dai = {
 	.ops = &wm1250_ev1_ops,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
-	.component_driver = {
-		.dapm_widgets		= wm1250_ev1_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm1250_ev1_dapm_widgets),
-		.dapm_routes		= wm1250_ev1_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm1250_ev1_dapm_routes),
-	},
-	.set_bias_level = wm1250_ev1_set_bias_level,
-	.idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_wm1250_ev1 = {
+	.dapm_widgets		= wm1250_ev1_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm1250_ev1_dapm_widgets),
+	.dapm_routes		= wm1250_ev1_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm1250_ev1_dapm_routes),
+	.set_bias_level		= wm1250_ev1_set_bias_level,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm1250_ev1_pdata(struct i2c_client *i2c)
@@ -224,7 +224,7 @@ static int wm1250_ev1_probe(struct i2c_client *i2c,
 	if (ret != 0)
 		return ret;
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
+	ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_wm1250_ev1,
 				     &wm1250_ev1_dai, 1);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
@@ -237,7 +237,6 @@ static int wm1250_ev1_probe(struct i2c_client *i2c,
 
 static int wm1250_ev1_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&i2c->dev);
 	wm1250_ev1_free(i2c);
 
 	return 0;
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index abfa052..c5ae072 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -607,8 +607,8 @@ static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
 static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
 	ucontrol->value.integer.value[0] = wm2000->anc_active;
 
@@ -618,8 +618,8 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
 static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 	unsigned int anc_active = ucontrol->value.integer.value[0];
 	int ret;
 
@@ -640,8 +640,8 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
 static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
 	ucontrol->value.integer.value[0] = wm2000->spk_ena;
 
@@ -651,8 +651,8 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
 static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 	unsigned int val = ucontrol->value.integer.value[0];
 	int ret;
 
@@ -683,8 +683,8 @@ static const struct snd_kcontrol_new wm2000_controls[] = {
 static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
 				  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 	int ret;
 
 	mutex_lock(&wm2000->lock);
@@ -724,16 +724,16 @@ static const struct snd_soc_dapm_route wm2000_audio_map[] = {
 };
 
 #ifdef CONFIG_PM
-static int wm2000_suspend(struct snd_soc_codec *codec)
+static int wm2000_suspend(struct snd_soc_component *component)
 {
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
 	return wm2000_anc_transition(wm2000, ANC_OFF);
 }
 
-static int wm2000_resume(struct snd_soc_codec *codec)
+static int wm2000_resume(struct snd_soc_component *component)
 {
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
 	return wm2000_anc_set_mode(wm2000);
 }
@@ -782,9 +782,9 @@ static const struct regmap_config wm2000_regmap = {
 	.readable_reg = wm2000_readable_reg,
 };
 
-static int wm2000_probe(struct snd_soc_codec *codec)
+static int wm2000_probe(struct snd_soc_component *component)
 {
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
 	/* This will trigger a transition to standby mode by default */
 	wm2000_anc_set_mode(wm2000);
@@ -792,27 +792,28 @@ static int wm2000_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int wm2000_remove(struct snd_soc_codec *codec)
+static void wm2000_remove(struct snd_soc_component *component)
 {
-	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+	struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
-	return wm2000_anc_transition(wm2000, ANC_OFF);
+	wm2000_anc_transition(wm2000, ANC_OFF);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm2000 = {
-	.probe = wm2000_probe,
-	.remove = wm2000_remove,
-	.suspend = wm2000_suspend,
-	.resume = wm2000_resume,
-
-	.component_driver = {
-		.controls		= wm2000_controls,
-		.num_controls		= ARRAY_SIZE(wm2000_controls),
-		.dapm_widgets		= wm2000_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm2000_dapm_widgets),
-		.dapm_routes		= wm2000_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(wm2000_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm2000 = {
+	.probe			= wm2000_probe,
+	.remove			= wm2000_remove,
+	.suspend		= wm2000_suspend,
+	.resume			= wm2000_resume,
+	.controls		= wm2000_controls,
+	.num_controls		= ARRAY_SIZE(wm2000_controls),
+	.dapm_widgets		= wm2000_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm2000_dapm_widgets),
+	.dapm_routes		= wm2000_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(wm2000_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm2000_i2c_probe(struct i2c_client *i2c,
@@ -916,7 +917,8 @@ static int wm2000_i2c_probe(struct i2c_client *i2c,
 
 	wm2000_reset(wm2000);
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+					&soc_component_dev_wm2000, NULL, 0);
 
 err_supplies:
 	regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
@@ -926,13 +928,6 @@ static int wm2000_i2c_probe(struct i2c_client *i2c,
 	return ret;
 }
 
-static int wm2000_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm2000_i2c_id[] = {
 	{ "wm2000", 0 },
 	{ }
@@ -944,7 +939,6 @@ static struct i2c_driver wm2000_i2c_driver = {
 		.name = "wm2000",
 	},
 	.probe = wm2000_i2c_probe,
-	.remove = wm2000_i2c_remove,
 	.id_table = wm2000_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index 5c2f572..d5f4bbf 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -87,7 +87,7 @@ struct wm2200_priv {
 	struct wm_adsp dsp[2];
 	struct regmap *regmap;
 	struct device *dev;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm2200_pdata pdata;
 	struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
 
@@ -1550,14 +1550,14 @@ static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
 	WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
 };
 
-static int wm2200_probe(struct snd_soc_codec *codec)
+static int wm2200_probe(struct snd_soc_component *component)
 {
-	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	wm2200->codec = codec;
+	wm2200->component = component;
 
-	ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2);
+	ret = snd_soc_add_component_controls(component, wm_adsp_fw_controls, 2);
 	if (ret != 0)
 		return ret;
 
@@ -1566,7 +1566,7 @@ static int wm2200_probe(struct snd_soc_codec *codec)
 
 static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int lrclk, bclk, fmt_val;
 
 	lrclk = 0;
@@ -1580,7 +1580,7 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		fmt_val = 2;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported DAI format %d\n",
+		dev_err(component->dev, "Unsupported DAI format %d\n",
 			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 		return -EINVAL;
 	}
@@ -1599,7 +1599,7 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		bclk |= WM2200_AIF1_BCLK_MSTR;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported master mode %d\n",
+		dev_err(component->dev, "Unsupported master mode %d\n",
 			fmt & SND_SOC_DAIFMT_MASTER_MASK);
 		return -EINVAL;
 	}
@@ -1621,15 +1621,15 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
+	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
 			    WM2200_AIF1_BCLK_INV, bclk);
-	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
+	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_2,
 			    WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
 			    lrclk);
-	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3,
+	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_3,
 			    WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
 			    lrclk);
-	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
+	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_5,
 			    WM2200_AIF1_FMT_MASK, fmt_val);
 
 	return 0;
@@ -1698,8 +1698,8 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
 	int i, bclk, lrclk, wl, fl, sr_code;
 	int *bclk_rates;
 
@@ -1711,7 +1711,7 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
 	if (fl < 0)
 		return fl;
 
-	dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
+	dev_dbg(component->dev, "Word length %d bits, frame length %d bits\n",
 		wl, fl);
 
 	/* Target BCLK rate */
@@ -1720,7 +1720,7 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
 		return bclk;
 
 	if (!wm2200->sysclk) {
-		dev_err(codec->dev, "SYSCLK has no rate set\n");
+		dev_err(component->dev, "SYSCLK has no rate set\n");
 		return -EINVAL;
 	}
 
@@ -1728,13 +1728,13 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
 		if (wm2200_sr_code[i] == params_rate(params))
 			break;
 	if (i == ARRAY_SIZE(wm2200_sr_code)) {
-		dev_err(codec->dev, "Unsupported sample rate: %dHz\n",
+		dev_err(component->dev, "Unsupported sample rate: %dHz\n",
 			params_rate(params));
 		return -EINVAL;
 	}
 	sr_code = i;
 
-	dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
+	dev_dbg(component->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
 		bclk, wm2200->sysclk);
 
 	if (wm2200->sysclk % 4000)
@@ -1746,38 +1746,38 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
 		if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
 			break;
 	if (i == WM2200_NUM_BCLK_RATES) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"No valid BCLK for %dHz found from %dHz SYSCLK\n",
 			bclk, wm2200->sysclk);
 		return -EINVAL;
 	}
 
 	bclk = i;
-	dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
-	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1,
+	dev_dbg(component->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
+	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_1,
 			    WM2200_AIF1_BCLK_DIV_MASK, bclk);
 
 	lrclk = bclk_rates[bclk] / params_rate(params);
-	dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
+	dev_dbg(component->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
 	    wm2200->symmetric_rates)
-		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7,
+		snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_7,
 				    WM2200_AIF1RX_BCPF_MASK, lrclk);
 	else
-		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6,
+		snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_6,
 				    WM2200_AIF1TX_BCPF_MASK, lrclk);
 
 	i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9,
+		snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_9,
 				    WM2200_AIF1RX_WL_MASK |
 				    WM2200_AIF1RX_SLOT_LEN_MASK, i);
 	else
-		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8,
+		snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_8,
 				    WM2200_AIF1TX_WL_MASK |
 				    WM2200_AIF1TX_SLOT_LEN_MASK, i);
 
-	snd_soc_update_bits(codec, WM2200_CLOCKING_4,
+	snd_soc_component_update_bits(component, WM2200_CLOCKING_4,
 			    WM2200_SAMPLE_RATE_1_MASK, sr_code);
 
 	return 0;
@@ -1788,10 +1788,10 @@ static const struct snd_soc_dai_ops wm2200_dai_ops = {
 	.hw_params = wm2200_hw_params,
 };
 
-static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int wm2200_set_sysclk(struct snd_soc_component *component, int clk_id,
 			     int source, unsigned int freq, int dir)
 {
-	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
 	int fval;
 
 	switch (clk_id) {
@@ -1799,7 +1799,7 @@ static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 		break;
 
 	default:
-		dev_err(codec->dev, "Unknown clock %d\n", clk_id);
+		dev_err(component->dev, "Unknown clock %d\n", clk_id);
 		return -EINVAL;
 	}
 
@@ -1810,7 +1810,7 @@ static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 	case WM2200_CLKSRC_BCLK1:
 		break;
 	default:
-		dev_err(codec->dev, "Invalid source %d\n", source);
+		dev_err(component->dev, "Invalid source %d\n", source);
 		return -EINVAL;
 	}
 
@@ -1820,7 +1820,7 @@ static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 		fval = 2;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
+		dev_err(component->dev, "Invalid clock rate: %d\n", freq);
 		return -EINVAL;
 	}
 
@@ -1828,7 +1828,7 @@ static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 	 * match.
 	 */
 
-	snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
+	snd_soc_component_update_bits(component, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
 			    WM2200_SYSCLK_SRC_MASK,
 			    fval << WM2200_SYSCLK_FREQ_SHIFT | source);
 
@@ -1936,23 +1936,23 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 	return 0;
 }
 
-static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+static int wm2200_set_fll(struct snd_soc_component *component, int fll_id, int source,
 			  unsigned int Fref, unsigned int Fout)
 {
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
-	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
+	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
 	struct _fll_div factors;
 	int ret, i, timeout;
 	unsigned long time_left;
 
 	if (!Fout) {
-		dev_dbg(codec->dev, "FLL disabled");
+		dev_dbg(component->dev, "FLL disabled");
 
 		if (wm2200->fll_fout)
-			pm_runtime_put(codec->dev);
+			pm_runtime_put(component->dev);
 
 		wm2200->fll_fout = 0;
-		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1,
 				    WM2200_FLL_ENA, 0);
 		return 0;
 	}
@@ -1963,7 +1963,7 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	case WM2200_FLL_SRC_BCLK:
 		break;
 	default:
-		dev_err(codec->dev, "Invalid FLL source %d\n", source);
+		dev_err(component->dev, "Invalid FLL source %d\n", source);
 		return -EINVAL;
 	}
 
@@ -1972,44 +1972,44 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		return ret;
 
 	/* Disable the FLL while we reconfigure */
-	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
+	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
 
-	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2,
+	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_2,
 			    WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
 			    (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
 			    factors.fll_fratio);
 	if (factors.theta) {
-		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
+		snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_3,
 				    WM2200_FLL_FRACN_ENA,
 				    WM2200_FLL_FRACN_ENA);
-		snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
+		snd_soc_component_update_bits(component, WM2200_FLL_EFS_2,
 				    WM2200_FLL_EFS_ENA,
 				    WM2200_FLL_EFS_ENA);
 	} else {
-		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
+		snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_3,
 				    WM2200_FLL_FRACN_ENA, 0);
-		snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
+		snd_soc_component_update_bits(component, WM2200_FLL_EFS_2,
 				    WM2200_FLL_EFS_ENA, 0);
 	}
 
-	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
+	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
 			    factors.theta);
-	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
+	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
 			    factors.n);
-	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7,
+	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_7,
 			    WM2200_FLL_CLK_REF_DIV_MASK |
 			    WM2200_FLL_CLK_REF_SRC_MASK,
 			    (factors.fll_refclk_div
 			     << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
-	snd_soc_update_bits(codec, WM2200_FLL_EFS_1,
+	snd_soc_component_update_bits(component, WM2200_FLL_EFS_1,
 			    WM2200_FLL_LAMBDA_MASK, factors.lambda);
 
 	/* Clear any pending completions */
 	try_wait_for_completion(&wm2200->fll_lock);
 
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
-	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
+	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1,
 			    WM2200_FLL_ENA, WM2200_FLL_ENA);
 
 	if (i2c->irq)
@@ -2017,7 +2017,7 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	else
 		timeout = 50;
 
-	snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
+	snd_soc_component_update_bits(component, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
 			    WM2200_SYSCLK_ENA);
 
 	/* Poll for the lock; will use the interrupt to exit quickly */
@@ -2032,10 +2032,10 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 			msleep(1);
 		}
 
-		ret = snd_soc_read(codec,
+		ret = snd_soc_component_read32(component,
 				   WM2200_INTERRUPT_RAW_STATUS_2);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to read FLL status: %d\n",
 				ret);
 			continue;
@@ -2044,8 +2044,8 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 			break;
 	}
 	if (i == timeout) {
-		dev_err(codec->dev, "FLL lock timed out\n");
-		pm_runtime_put(codec->dev);
+		dev_err(component->dev, "FLL lock timed out\n");
+		pm_runtime_put(component->dev);
 		return -ETIMEDOUT;
 	}
 
@@ -2053,29 +2053,29 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	wm2200->fll_fref = Fref;
 	wm2200->fll_fout = Fout;
 
-	dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
+	dev_dbg(component->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
 
 	return 0;
 }
 
 static int wm2200_dai_probe(struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
 	unsigned int val = 0;
 	int ret;
 
-	ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1);
+	ret = snd_soc_component_read32(component, WM2200_GPIO_CTRL_1);
 	if (ret >= 0) {
 		if ((ret & WM2200_GP1_FN_MASK) != 0) {
 			wm2200->symmetric_rates = true;
 			val = WM2200_AIF1TX_LRCLK_SRC;
 		}
 	} else {
-		dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret);
+		dev_err(component->dev, "Failed to read GPIO 1 config: %d\n", ret);
 	}
 
-	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
+	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_2,
 			    WM2200_AIF1TX_LRCLK_SRC, val);
 
 	return 0;
@@ -2106,22 +2106,18 @@ static struct snd_soc_dai_driver wm2200_dai = {
 	.ops = &wm2200_dai_ops,
 };
 
-static const struct snd_soc_codec_driver soc_codec_wm2200 = {
-	.probe = wm2200_probe,
-
-	.idle_bias_off = true,
-	.ignore_pmdown_time = true,
-	.set_sysclk = wm2200_set_sysclk,
-	.set_pll = wm2200_set_fll,
-
-	.component_driver = {
-		.controls		= wm2200_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm2200_snd_controls),
-		.dapm_widgets		= wm2200_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm2200_dapm_widgets),
-		.dapm_routes		= wm2200_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm2200_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_wm2200 = {
+	.probe			= wm2200_probe,
+	.set_sysclk		= wm2200_set_sysclk,
+	.set_pll		= wm2200_set_fll,
+	.controls		= wm2200_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm2200_snd_controls),
+	.dapm_widgets		= wm2200_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm2200_dapm_widgets),
+	.dapm_routes		= wm2200_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm2200_dapm_routes),
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static irqreturn_t wm2200_irq(int irq, void *data)
@@ -2408,7 +2404,7 @@ static int wm2200_i2c_probe(struct i2c_client *i2c,
 	pm_runtime_enable(&i2c->dev);
 	pm_request_idle(&i2c->dev);
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200,
+	ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_wm2200,
 				     &wm2200_dai, 1);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
@@ -2435,7 +2431,6 @@ 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)
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 138a84e..87f9a99 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -55,7 +55,7 @@ struct wm5100_fll {
 struct wm5100_priv {
 	struct device *dev;
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 
 	struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
 
@@ -118,16 +118,16 @@ static int wm5100_sr_regs[WM5100_SYNC_SRS] = {
 	WM5100_CLOCKING_6,
 };
 
-static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
+static int wm5100_alloc_sr(struct snd_soc_component *component, int rate)
 {
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 	int sr_code, sr_free, i;
 
 	for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
 		if (wm5100_sr_code[i] == rate)
 			break;
 	if (i == ARRAY_SIZE(wm5100_sr_code)) {
-		dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
+		dev_err(component->dev, "Unsupported sample rate: %dHz\n", rate);
 		return -EINVAL;
 	}
 	sr_code = i;
@@ -140,50 +140,50 @@ static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
 				sr_free = i;
 				continue;
 			}
-			if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
+			if ((snd_soc_component_read32(component, wm5100_sr_regs[i]) &
 			     WM5100_SAMPLE_RATE_1_MASK) == sr_code)
 				break;
 		}
 
 		if (i < ARRAY_SIZE(wm5100_sr_regs)) {
 			wm5100->sr_ref[i]++;
-			dev_dbg(codec->dev, "SR %dHz, slot %d, ref %d\n",
+			dev_dbg(component->dev, "SR %dHz, slot %d, ref %d\n",
 				rate, i, wm5100->sr_ref[i]);
 			return i;
 		}
 
 		if (sr_free == -1) {
-			dev_err(codec->dev, "All SR slots already in use\n");
+			dev_err(component->dev, "All SR slots already in use\n");
 			return -EBUSY;
 		}
 
-		dev_dbg(codec->dev, "Allocating SR slot %d for %dHz\n",
+		dev_dbg(component->dev, "Allocating SR slot %d for %dHz\n",
 			sr_free, rate);
 		wm5100->sr_ref[sr_free]++;
-		snd_soc_update_bits(codec, wm5100_sr_regs[sr_free],
+		snd_soc_component_update_bits(component, wm5100_sr_regs[sr_free],
 				    WM5100_SAMPLE_RATE_1_MASK,
 				    sr_code);
 
 		return sr_free;
 
 	} else {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"SR %dHz incompatible with %dHz SYSCLK and %dHz ASYNCCLK\n",
 			rate, wm5100->sysclk, wm5100->asyncclk);
 		return -EINVAL;
 	}
 }
 
-static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
+static void wm5100_free_sr(struct snd_soc_component *component, int rate)
 {
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 	int i, sr_code;
 
 	for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
 		if (wm5100_sr_code[i] == rate)
 			break;
 	if (i == ARRAY_SIZE(wm5100_sr_code)) {
-		dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
+		dev_err(component->dev, "Unsupported sample rate: %dHz\n", rate);
 		return;
 	}
 	sr_code = wm5100_sr_code[i];
@@ -192,16 +192,16 @@ static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
 		if (!wm5100->sr_ref[i])
 			continue;
 
-		if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
+		if ((snd_soc_component_read32(component, wm5100_sr_regs[i]) &
 		     WM5100_SAMPLE_RATE_1_MASK) == sr_code)
 			break;
 	}
 	if (i < ARRAY_SIZE(wm5100_sr_regs)) {
 		wm5100->sr_ref[i]--;
-		dev_dbg(codec->dev, "Dereference SR %dHz, count now %d\n",
+		dev_dbg(component->dev, "Dereference SR %dHz, count now %d\n",
 			rate, wm5100->sr_ref[i]);
 	} else {
-		dev_warn(codec->dev, "Freeing unreferenced sample rate %dHz\n",
+		dev_warn(component->dev, "Freeing unreferenced sample rate %dHz\n",
 			 rate);
 	}
 }
@@ -733,40 +733,39 @@ WM5100_MIXER_CONTROLS("LHPF3", WM5100_HPLP3MIX_INPUT_1_SOURCE),
 WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE),
 };
 
-static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm,
+static void wm5100_seq_notifier(struct snd_soc_component *component,
 				enum snd_soc_dapm_type event, int subseq)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 	u16 val, expect, i;
 
 	/* Wait for the outputs to flag themselves as enabled */
 	if (wm5100->out_ena[0]) {
-		expect = snd_soc_read(codec, WM5100_CHANNEL_ENABLES_1);
+		expect = snd_soc_component_read32(component, WM5100_CHANNEL_ENABLES_1);
 		for (i = 0; i < 200; i++) {
-			val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_1);
+			val = snd_soc_component_read32(component, WM5100_OUTPUT_STATUS_1);
 			if (val == expect) {
 				wm5100->out_ena[0] = false;
 				break;
 			}
 		}
 		if (i == 200) {
-			dev_err(codec->dev, "Timeout waiting for OUTPUT1 %x\n",
+			dev_err(component->dev, "Timeout waiting for OUTPUT1 %x\n",
 				expect);
 		}
 	}
 
 	if (wm5100->out_ena[1]) {
-		expect = snd_soc_read(codec, WM5100_OUTPUT_ENABLES_2);
+		expect = snd_soc_component_read32(component, WM5100_OUTPUT_ENABLES_2);
 		for (i = 0; i < 200; i++) {
-			val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_2);
+			val = snd_soc_component_read32(component, WM5100_OUTPUT_STATUS_2);
 			if (val == expect) {
 				wm5100->out_ena[1] = false;
 				break;
 			}
 		}
 		if (i == 200) {
-			dev_err(codec->dev, "Timeout waiting for OUTPUT2 %x\n",
+			dev_err(component->dev, "Timeout waiting for OUTPUT2 %x\n",
 				expect);
 		}
 	}
@@ -776,8 +775,8 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol,
 			 int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 
 	switch (w->reg) {
 	case WM5100_CHANNEL_ENABLES_1:
@@ -841,17 +840,17 @@ static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol,
 			  int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
+	ret = snd_soc_component_read32(component, WM5100_INTERRUPT_RAW_STATUS_3);
 	ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
 		WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
 		WM5100_CLKGEN_ERR_ASYNC_STS;
 	wm5100_log_status3(wm5100, ret);
 
-	ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
+	ret = snd_soc_component_read32(component, WM5100_INTERRUPT_RAW_STATUS_4);
 	wm5100_log_status4(wm5100, ret);
 
 	return 0;
@@ -1282,7 +1281,7 @@ static const struct reg_sequence wm5100_reva_patches[] = {
 
 static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int lrclk, bclk, mask, base;
 
 	base = dai->driver->base;
@@ -1298,7 +1297,7 @@ static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		mask = 2;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported DAI format %d\n",
+		dev_err(component->dev, "Unsupported DAI format %d\n",
 			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 		return -EINVAL;
 	}
@@ -1317,7 +1316,7 @@ static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		bclk |= WM5100_AIF1_BCLK_MSTR;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported master mode %d\n",
+		dev_err(component->dev, "Unsupported master mode %d\n",
 			fmt & SND_SOC_DAIFMT_MASTER_MASK);
 		return -EINVAL;
 	}
@@ -1339,13 +1338,13 @@ static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR |
+	snd_soc_component_update_bits(component, base + 1, WM5100_AIF1_BCLK_MSTR |
 			    WM5100_AIF1_BCLK_INV, bclk);
-	snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
+	snd_soc_component_update_bits(component, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
 			    WM5100_AIF1TX_LRCLK_INV, lrclk);
-	snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
+	snd_soc_component_update_bits(component, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
 			    WM5100_AIF1TX_LRCLK_INV, lrclk);
-	snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask);
+	snd_soc_component_update_bits(component, base + 5, WM5100_AIF1_FMT_MASK, mask);
 
 	return 0;
 }
@@ -1400,8 +1399,8 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 	bool async = wm5100->aif_async[dai->id];
 	int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
 	int *bclk_rates;
@@ -1416,7 +1415,7 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
 	if (fl < 0)
 		return fl;
 
-	dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
+	dev_dbg(component->dev, "Word length %d bits, frame length %d bits\n",
 		wl, fl);
 
 	/* Target BCLK rate */
@@ -1427,7 +1426,7 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
 	/* Root for BCLK depends on SYS/ASYNCCLK */
 	if (!async) {
 		aif_rate = wm5100->sysclk;
-		sr = wm5100_alloc_sr(codec, params_rate(params));
+		sr = wm5100_alloc_sr(component, params_rate(params));
 		if (sr < 0)
 			return sr;
 	} else {
@@ -1439,23 +1438,23 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
 			if (params_rate(params) == wm5100_sr_code[i])
 				break;
 		if (i == ARRAY_SIZE(wm5100_sr_code)) {
-			dev_err(codec->dev, "Invalid rate %dHzn",
+			dev_err(component->dev, "Invalid rate %dHzn",
 				params_rate(params));
 			return -EINVAL;
 		}
 
 		/* TODO: We should really check for symmetry */
-		snd_soc_update_bits(codec, WM5100_CLOCKING_8,
+		snd_soc_component_update_bits(component, WM5100_CLOCKING_8,
 				    WM5100_ASYNC_SAMPLE_RATE_MASK, i);
 	}
 
 	if (!aif_rate) {
-		dev_err(codec->dev, "%s has no rate set\n",
+		dev_err(component->dev, "%s has no rate set\n",
 			async ? "ASYNCCLK" : "SYSCLK");
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
+	dev_dbg(component->dev, "Target BCLK is %dHz, using %dHz %s\n",
 		bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
 
 	if (aif_rate % 4000)
@@ -1467,37 +1466,37 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
 		if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
 			break;
 	if (i == WM5100_NUM_BCLK_RATES) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"No valid BCLK for %dHz found from %dHz %s\n",
 			bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
 		return -EINVAL;
 	}
 
 	bclk = i;
-	dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
-	snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
+	dev_dbg(component->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
+	snd_soc_component_update_bits(component, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
 
 	lrclk = bclk_rates[bclk] / params_rate(params);
-	dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
+	dev_dbg(component->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
 	    wm5100->aif_symmetric[dai->id])
-		snd_soc_update_bits(codec, base + 7,
+		snd_soc_component_update_bits(component, base + 7,
 				    WM5100_AIF1RX_BCPF_MASK, lrclk);
 	else
-		snd_soc_update_bits(codec, base + 6,
+		snd_soc_component_update_bits(component, base + 6,
 				    WM5100_AIF1TX_BCPF_MASK, lrclk);
 
 	i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		snd_soc_update_bits(codec, base + 9,
+		snd_soc_component_update_bits(component, base + 9,
 				    WM5100_AIF1RX_WL_MASK |
 				    WM5100_AIF1RX_SLOT_LEN_MASK, i);
 	else
-		snd_soc_update_bits(codec, base + 8,
+		snd_soc_component_update_bits(component, base + 8,
 				    WM5100_AIF1TX_WL_MASK |
 				    WM5100_AIF1TX_SLOT_LEN_MASK, i);
 
-	snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
+	snd_soc_component_update_bits(component, base + 4, WM5100_AIF1_RATE_MASK, sr);
 
 	return 0;
 }
@@ -1507,10 +1506,10 @@ static const struct snd_soc_dai_ops wm5100_dai_ops = {
 	.hw_params = wm5100_hw_params,
 };
 
-static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int wm5100_set_sysclk(struct snd_soc_component *component, int clk_id,
 			     int source, unsigned int freq, int dir)
 {
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 	int *rate_store;
 	int fval, audio_rate, ret, reg;
 
@@ -1529,7 +1528,7 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 		case WM5100_CLKSRC_MCLK1:
 		case WM5100_CLKSRC_MCLK2:
 		case WM5100_CLKSRC_SYSCLK:
-			snd_soc_update_bits(codec, WM5100_CLOCKING_1,
+			snd_soc_component_update_bits(component, WM5100_CLOCKING_1,
 					    WM5100_CLK_32K_SRC_MASK,
 					    source);
 			break;
@@ -1550,7 +1549,7 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 			wm5100->aif_async[clk_id - 1] = true;
 			break;
 		default:
-			dev_err(codec->dev, "Invalid source %d\n", source);
+			dev_err(component->dev, "Invalid source %d\n", source);
 			return -EINVAL;
 		}	
 		return 0;
@@ -1559,35 +1558,35 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 		switch (freq) {
 		case 5644800:
 		case 6144000:
-			snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
+			snd_soc_component_update_bits(component, WM5100_MISC_GPIO_1,
 					    WM5100_OPCLK_SEL_MASK, 0);
 			break;
 		case 11289600:
 		case 12288000:
-			snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
+			snd_soc_component_update_bits(component, WM5100_MISC_GPIO_1,
 					    WM5100_OPCLK_SEL_MASK, 0);
 			break;
 		case 22579200:
 		case 24576000:
-			snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
+			snd_soc_component_update_bits(component, WM5100_MISC_GPIO_1,
 					    WM5100_OPCLK_SEL_MASK, 0);
 			break;
 		default:
-			dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
+			dev_err(component->dev, "Unsupported OPCLK %dHz\n",
 				freq);
 			return -EINVAL;
 		}
 		return 0;
 
 	default:
-		dev_err(codec->dev, "Unknown clock %d\n", clk_id);
+		dev_err(component->dev, "Unknown clock %d\n", clk_id);
 		return -EINVAL;
 	}
 
 	switch (source) {
 	case WM5100_CLKSRC_SYSCLK:
 	case WM5100_CLKSRC_ASYNCCLK:
-		dev_err(codec->dev, "Invalid source %d\n", source);
+		dev_err(component->dev, "Invalid source %d\n", source);
 		return -EINVAL;
 	}
 
@@ -1605,7 +1604,7 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 		fval = 2;
 		break;
 	default:
-		dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
+		dev_err(component->dev, "Invalid clock rate: %d\n", freq);
 		return -EINVAL;
 	}
 
@@ -1632,7 +1631,7 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 	 * match.
 	 */
 
-	snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
+	snd_soc_component_update_bits(component, reg, WM5100_SYSCLK_FREQ_MASK |
 			    WM5100_SYSCLK_SRC_MASK,
 			    fval << WM5100_SYSCLK_FREQ_SHIFT | source);
 
@@ -1641,13 +1640,13 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 	 * this clock rate.
 	 */
 	if (clk_id == WM5100_CLK_SYSCLK) {
-		dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
+		dev_dbg(component->dev, "Setting primary audio rate to %dHz",
 			audio_rate);
 		if (0 && *rate_store)
-			wm5100_free_sr(codec, audio_rate);
-		ret = wm5100_alloc_sr(codec, audio_rate);
+			wm5100_free_sr(component, audio_rate);
+		ret = wm5100_alloc_sr(component, audio_rate);
 		if (ret != 0)
-			dev_warn(codec->dev, "Primary audio slot is %d\n",
+			dev_warn(component->dev, "Primary audio slot is %d\n",
 				 ret);
 	}
 
@@ -1755,11 +1754,11 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 	return 0;
 }
 
-static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+static int wm5100_set_fll(struct snd_soc_component *component, int fll_id, int source,
 			  unsigned int Fref, unsigned int Fout)
 {
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 	struct _fll_div factors;
 	struct wm5100_fll *fll;
 	int ret, base, lock, i, timeout;
@@ -1777,16 +1776,16 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		lock = WM5100_FLL2_LOCK_STS;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
+		dev_err(component->dev, "Unknown FLL %d\n",fll_id);
 		return -EINVAL;
 	}
 
 	if (!Fout) {
-		dev_dbg(codec->dev, "FLL%d disabled", fll_id);
+		dev_dbg(component->dev, "FLL%d disabled", fll_id);
 		if (fll->fout)
-			pm_runtime_put(codec->dev);
+			pm_runtime_put(component->dev);
 		fll->fout = 0;
-		snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
+		snd_soc_component_update_bits(component, base + 1, WM5100_FLL1_ENA, 0);
 		return 0;
 	}
 
@@ -1800,7 +1799,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	case WM5100_FLL_SRC_AIF3BCLK:
 		break;
 	default:
-		dev_err(codec->dev, "Invalid FLL source %d\n", source);
+		dev_err(component->dev, "Invalid FLL source %d\n", source);
 		return -EINVAL;
 	}
 
@@ -1809,36 +1808,36 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		return ret;
 
 	/* Disable the FLL while we reconfigure */
-	snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
+	snd_soc_component_update_bits(component, base + 1, WM5100_FLL1_ENA, 0);
 
-	snd_soc_update_bits(codec, base + 2,
+	snd_soc_component_update_bits(component, base + 2,
 			    WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
 			    (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
 			    factors.fll_fratio);
-	snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
+	snd_soc_component_update_bits(component, base + 3, WM5100_FLL1_THETA_MASK,
 			    factors.theta);
-	snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
-	snd_soc_update_bits(codec, base + 6,
+	snd_soc_component_update_bits(component, base + 5, WM5100_FLL1_N_MASK, factors.n);
+	snd_soc_component_update_bits(component, base + 6,
 			    WM5100_FLL1_REFCLK_DIV_MASK |
 			    WM5100_FLL1_REFCLK_SRC_MASK,
 			    (factors.fll_refclk_div
 			     << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
-	snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
+	snd_soc_component_update_bits(component, base + 7, WM5100_FLL1_LAMBDA_MASK,
 			    factors.lambda);
 
 	/* Clear any pending completions */
 	try_wait_for_completion(&fll->lock);
 
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
-	snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
+	snd_soc_component_update_bits(component, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
 
 	if (i2c->irq)
 		timeout = 2;
 	else
 		timeout = 50;
 
-	snd_soc_update_bits(codec, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA,
+	snd_soc_component_update_bits(component, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA,
 			    WM5100_SYSCLK_ENA);
 
 	/* Poll for the lock; will use interrupt when we can test */
@@ -1852,10 +1851,10 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 			msleep(1);
 		}
 
-		ret = snd_soc_read(codec,
+		ret = snd_soc_component_read32(component,
 				   WM5100_INTERRUPT_RAW_STATUS_3);
 		if (ret < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to read FLL status: %d\n",
 				ret);
 			continue;
@@ -1864,8 +1863,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 			break;
 	}
 	if (i == timeout) {
-		dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
-		pm_runtime_put(codec->dev);
+		dev_err(component->dev, "FLL%d lock timed out\n", fll_id);
+		pm_runtime_put(component->dev);
 		return -ETIMEDOUT;
 	}
 
@@ -1873,7 +1872,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	fll->fref = Fref;
 	fll->fout = Fout;
 
-	dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
+	dev_dbg(component->dev, "FLL%d running %dHz->%dHz\n", fll_id,
 		Fref, Fout);
 
 	return 0;
@@ -2099,10 +2098,10 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
 	}
 }
 
-int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int wm5100_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	if (jack) {
 		wm5100->jack = jack;
@@ -2113,7 +2112,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 
 		/* Slowest detection rate, gives debounce for initial
 		 * detection */
-		snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
+		snd_soc_component_update_bits(component, WM5100_MIC_DETECT_1,
 				    WM5100_ACCDET_BIAS_STARTTIME_MASK |
 				    WM5100_ACCDET_RATE_MASK,
 				    (7 << WM5100_ACCDET_BIAS_STARTTIME_SHIFT) |
@@ -2132,18 +2131,18 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 		/* We start off just enabling microphone detection - even a
 		 * plain headphone will trigger detection.
 		 */
-		snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
+		snd_soc_component_update_bits(component, WM5100_MIC_DETECT_1,
 				    WM5100_ACCDET_ENA, WM5100_ACCDET_ENA);
 
-		snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
+		snd_soc_component_update_bits(component, WM5100_INTERRUPT_STATUS_3_MASK,
 				    WM5100_IM_ACCDET_EINT, 0);
 	} else {
-		snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
+		snd_soc_component_update_bits(component, WM5100_INTERRUPT_STATUS_3_MASK,
 				    WM5100_IM_HPDET_EINT |
 				    WM5100_IM_ACCDET_EINT,
 				    WM5100_IM_HPDET_EINT |
 				    WM5100_IM_ACCDET_EINT);
-		snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
+		snd_soc_component_update_bits(component, WM5100_MIC_DETECT_1,
 				    WM5100_ACCDET_ENA, 0);
 		wm5100->jack = NULL;
 	}
@@ -2330,22 +2329,22 @@ static void wm5100_free_gpio(struct i2c_client *i2c)
 }
 #endif
 
-static int wm5100_probe(struct snd_soc_codec *codec)
+static int wm5100_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 	int ret, i;
 
-	wm5100->codec = codec;
+	wm5100->component = component;
 
 	for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
-		snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
+		snd_soc_component_update_bits(component, wm5100_dig_vu[i], WM5100_OUT_VU,
 				    WM5100_OUT_VU);
 
 	/* Don't debounce interrupts to support use of SYSCLK only */
-	snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
-	snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
+	snd_soc_component_write(component, WM5100_IRQ_DEBOUNCE_1, 0);
+	snd_soc_component_write(component, WM5100_IRQ_DEBOUNCE_2, 0);
 
 	/* TODO: check if we're symmetric */
 
@@ -2370,34 +2369,30 @@ static int wm5100_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int wm5100_remove(struct snd_soc_codec *codec)
+static void wm5100_remove(struct snd_soc_component *component)
 {
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 
 	if (wm5100->pdata.hp_pol) {
 		gpio_free(wm5100->pdata.hp_pol);
 	}
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
-	.probe =	wm5100_probe,
-	.remove =	wm5100_remove,
-
-	.set_sysclk = wm5100_set_sysclk,
-	.set_pll = wm5100_set_fll,
-	.idle_bias_off = 1,
-
-	.seq_notifier = wm5100_seq_notifier,
-	.component_driver = {
-		.controls		= wm5100_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm5100_snd_controls),
-		.dapm_widgets		= wm5100_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm5100_dapm_widgets),
-		.dapm_routes		= wm5100_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm5100_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm5100 = {
+	.probe			= wm5100_probe,
+	.remove			= wm5100_remove,
+	.set_sysclk		= wm5100_set_sysclk,
+	.set_pll		= wm5100_set_fll,
+	.seq_notifier		= wm5100_seq_notifier,
+	.controls		= wm5100_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm5100_snd_controls),
+	.dapm_widgets		= wm5100_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm5100_dapm_widgets),
+	.dapm_routes		= wm5100_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm5100_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm5100_regmap = {
@@ -2614,8 +2609,8 @@ static int wm5100_i2c_probe(struct i2c_client *i2c,
 	pm_runtime_enable(&i2c->dev);
 	pm_request_idle(&i2c->dev);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-				     &soc_codec_dev_wm5100, wm5100_dai,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_wm5100, wm5100_dai,
 				     ARRAY_SIZE(wm5100_dai));
 	if (ret < 0) {
 		dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
@@ -2648,7 +2643,6 @@ static int wm5100_i2c_remove(struct i2c_client *i2c)
 {
 	struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
 
-	snd_soc_unregister_codec(&i2c->dev);
 	if (i2c->irq)
 		free_irq(i2c->irq, wm5100);
 	wm5100_free_gpio(i2c);
diff --git a/sound/soc/codecs/wm5100.h b/sound/soc/codecs/wm5100.h
index 935a9b7..6076493 100644
--- a/sound/soc/codecs/wm5100.h
+++ b/sound/soc/codecs/wm5100.h
@@ -17,7 +17,7 @@
 #include <sound/soc.h>
 #include <linux/regmap.h>
 
-int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int wm5100_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #define WM5100_CLK_AIF1     1
 #define WM5100_CLK_AIF2     2
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index fc066ca..1ac8338 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -34,6 +34,8 @@
 #include "wm5102.h"
 #include "wm_adsp.h"
 
+#define DRV_NAME "wm5102-codec"
+
 struct wm5102_priv {
 	struct arizona_priv core;
 	struct arizona_fll fll[2];
@@ -581,8 +583,8 @@ static const struct reg_default wm5102_sysclk_revb_patch[] = {
 static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	struct regmap *regmap = arizona->regmap;
 	const struct reg_default *patch = NULL;
 	int i, patch_size;
@@ -618,10 +620,10 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
 }
 
 static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
-		   struct snd_kcontrol *kcontrol, int event)
+				struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	unsigned int v = 0;
 	int ret;
 
@@ -629,7 +631,7 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_PRE_PMU:
 		ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to read SYSCLK state: %d\n", ret);
 			return -EIO;
 		}
@@ -637,9 +639,9 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
 		v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT;
 
 		if (v >= 3) {
-			ret = arizona_dvfs_up(codec, ARIZONA_DVFS_ADSP1_RQ);
+			ret = arizona_dvfs_up(component, ARIZONA_DVFS_ADSP1_RQ);
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to raise DVFS: %d\n", ret);
 				return ret;
 			}
@@ -647,9 +649,9 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		ret = arizona_dvfs_down(codec, ARIZONA_DVFS_ADSP1_RQ);
+		ret = arizona_dvfs_down(component, ARIZONA_DVFS_ADSP1_RQ);
 		if (ret)
-			dev_warn(codec->dev,
+			dev_warn(component->dev,
 				 "Failed to lower DVFS: %d\n", ret);
 		break;
 
@@ -663,8 +665,8 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
 static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 
 	mutex_lock(&arizona->dac_comp_lock);
 	put_unaligned_be16(arizona->dac_comp_coeff,
@@ -677,8 +679,8 @@ static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
 static int wm5102_out_comp_coeff_put(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 
 	mutex_lock(&arizona->dac_comp_lock);
 	memcpy(&arizona->dac_comp_coeff, ucontrol->value.bytes.data,
@@ -692,8 +694,8 @@ static int wm5102_out_comp_coeff_put(struct snd_kcontrol *kcontrol,
 static int wm5102_out_comp_switch_get(struct snd_kcontrol *kcontrol,
 				      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 
 	mutex_lock(&arizona->dac_comp_lock);
 	ucontrol->value.integer.value[0] = arizona->dac_comp_enabled;
@@ -705,8 +707,8 @@ static int wm5102_out_comp_switch_get(struct snd_kcontrol *kcontrol,
 static int wm5102_out_comp_switch_put(struct snd_kcontrol *kcontrol,
 				      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 
 	mutex_lock(&arizona->dac_comp_lock);
 	arizona->dac_comp_enabled = ucontrol->value.integer.value[0];
@@ -715,7 +717,7 @@ static int wm5102_out_comp_switch_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static const char *wm5102_osr_text[] = {
+static const char * const wm5102_osr_text[] = {
 	"Low power", "Normal", "High performance",
 };
 
@@ -1060,7 +1062,7 @@ 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[] = {
+static const char * const wm5102_aec_loopback_texts[] = {
 	"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
 	"SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R",
 };
@@ -1315,8 +1317,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
 ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
 
 SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-		       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-		       &wm5102_aec_loopback_mux),
+		 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5102_aec_loopback_mux),
 
 SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
 		   ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
@@ -1734,10 +1735,10 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
 	{ "DRC1 Signal Activity", NULL, "DRC1R" },
 };
 
-static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-			  unsigned int Fref, unsigned int Fout)
+static int wm5102_set_fll(struct snd_soc_component *component, int fll_id,
+			  int source, unsigned int Fref, unsigned int Fout)
 {
-	struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
+	struct wm5102_priv *wm5102 = snd_soc_component_get_drvdata(component);
 
 	switch (fll_id) {
 	case WM5102_FLL1:
@@ -1910,7 +1911,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = {
 static int wm5102_open(struct snd_compr_stream *stream)
 {
 	struct snd_soc_pcm_runtime *rtd = stream->private_data;
-	struct wm5102_priv *priv = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct wm5102_priv *priv = snd_soc_component_get_drvdata(component);
 
 	return wm_adsp_compr_open(&priv->core.adsp[0], stream);
 }
@@ -1930,30 +1932,29 @@ static irqreturn_t wm5102_adsp2_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static int wm5102_codec_probe(struct snd_soc_codec *codec)
+static int wm5102_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-	struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm5102_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->core.arizona;
 	int ret;
 
-	snd_soc_codec_init_regmap(codec, arizona->regmap);
+	snd_soc_component_init_regmap(component, arizona->regmap);
 
-	ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec);
+	ret = wm_adsp2_component_probe(&priv->core.adsp[0], component);
 	if (ret)
 		return ret;
 
-	ret = snd_soc_add_codec_controls(codec,
-					 arizona_adsp2_rate_controls, 1);
+	ret = snd_soc_add_component_controls(component,
+					     arizona_adsp2_rate_controls, 1);
 	if (ret)
 		goto err_adsp2_codec_probe;
 
-	ret = arizona_init_spk(codec);
+	ret = arizona_init_spk(component);
 	if (ret < 0)
 		return ret;
 
-	arizona_init_gpio(codec);
+	arizona_init_gpio(component);
 
 	snd_soc_component_disable_pin(component, "HAPTICS");
 
@@ -1962,20 +1963,18 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 
 err_adsp2_codec_probe:
-	wm_adsp2_codec_remove(&priv->core.adsp[0], codec);
+	wm_adsp2_component_remove(&priv->core.adsp[0], component);
 
 	return ret;
 }
 
-static int wm5102_codec_remove(struct snd_soc_codec *codec)
+static void wm5102_component_remove(struct snd_soc_component *component)
 {
-	struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct wm5102_priv *priv = snd_soc_component_get_drvdata(component);
 
-	wm_adsp2_codec_remove(&priv->core.adsp[0], codec);
+	wm_adsp2_component_remove(&priv->core.adsp[0], component);
 
 	priv->core.arizona->dapm = NULL;
-
-	return 0;
 }
 
 #define WM5102_DIG_VU 0x0200
@@ -1992,37 +1991,32 @@ static unsigned int wm5102_digital_vu[] = {
 	ARIZONA_DAC_DIGITAL_VOLUME_5R,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
-	.probe = wm5102_codec_probe,
-	.remove = wm5102_codec_remove,
-
-	.idle_bias_off = true,
-
-	.set_sysclk = arizona_set_sysclk,
-	.set_pll = wm5102_set_fll,
-
-	.component_driver = {
-		.controls		= wm5102_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm5102_snd_controls),
-		.dapm_widgets		= wm5102_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm5102_dapm_widgets),
-		.dapm_routes		= wm5102_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm5102_dapm_routes),
-	},
+static struct snd_compr_ops wm5102_compr_ops = {
+	.open		= wm5102_open,
+	.free		= wm_adsp_compr_free,
+	.set_params	= wm_adsp_compr_set_params,
+	.get_caps	= wm_adsp_compr_get_caps,
+	.trigger	= wm_adsp_compr_trigger,
+	.pointer	= wm_adsp_compr_pointer,
+	.copy		= wm_adsp_compr_copy,
 };
 
-static const struct snd_compr_ops wm5102_compr_ops = {
-	.open = wm5102_open,
-	.free = wm_adsp_compr_free,
-	.set_params = wm_adsp_compr_set_params,
-	.get_caps = wm_adsp_compr_get_caps,
-	.trigger = wm_adsp_compr_trigger,
-	.pointer = wm_adsp_compr_pointer,
-	.copy = wm_adsp_compr_copy,
-};
-
-static const struct snd_soc_platform_driver wm5102_compr_platform = {
-	.compr_ops = &wm5102_compr_ops,
+static const struct snd_soc_component_driver soc_component_dev_wm5102 = {
+	.probe			= wm5102_component_probe,
+	.remove			= wm5102_component_remove,
+	.set_sysclk		= arizona_set_sysclk,
+	.set_pll		= wm5102_set_fll,
+	.name			= DRV_NAME,
+	.compr_ops		= &wm5102_compr_ops,
+	.controls		= wm5102_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm5102_snd_controls),
+	.dapm_widgets		= wm5102_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm5102_dapm_widgets),
+	.dapm_routes		= wm5102_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm5102_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm5102_probe(struct platform_device *pdev)
@@ -2109,23 +2103,17 @@ static int wm5102_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_dsp_irq;
 
-	ret = snd_soc_register_platform(&pdev->dev, &wm5102_compr_platform);
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &soc_component_dev_wm5102,
+					      wm5102_dai,
+					      ARRAY_SIZE(wm5102_dai));
 	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+		dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
 		goto err_spk_irqs;
 	}
 
-	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
-				      wm5102_dai, ARRAY_SIZE(wm5102_dai));
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
-		goto err_platform;
-	}
-
 	return ret;
 
-err_platform:
-	snd_soc_unregister_platform(&pdev->dev);
 err_spk_irqs:
 	arizona_free_spk_irqs(arizona);
 err_dsp_irq:
@@ -2139,8 +2127,6 @@ static int wm5102_remove(struct platform_device *pdev)
 	struct wm5102_priv *wm5102 = platform_get_drvdata(pdev);
 	struct arizona *arizona = wm5102->core.arizona;
 
-	snd_soc_unregister_platform(&pdev->dev);
-	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 	wm_adsp2_remove(&wm5102->core.adsp[0]);
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index fb0cf9c..fb9835d 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -35,6 +35,8 @@
 
 #define WM5110_NUM_ADSP 4
 
+#define DRV_NAME "wm5110-codec"
+
 struct wm5110_priv {
 	struct arizona_priv core;
 	struct arizona_fll fll[2];
@@ -159,8 +161,8 @@ static const struct reg_default wm5110_sysclk_reve_patch[] = {
 static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	struct regmap *regmap = arizona->regmap;
 	const struct reg_default *patch = NULL;
 	int i, patch_size;
@@ -196,14 +198,14 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w,
 static int wm5110_adsp_power_ev(struct snd_soc_dapm_widget *w,
 				struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	unsigned int v;
 	int ret;
 
 	ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to read SYSCLK state: %d\n", ret);
+		dev_err(component->dev, "Failed to read SYSCLK state: %d\n", ret);
 		return ret;
 	}
 
@@ -286,10 +288,10 @@ static const struct reg_sequence wm5110_dre_right_enable[] = {
 
 static int wm5110_hp_pre_enable(struct snd_soc_dapm_widget *w)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
-	unsigned int val = snd_soc_read(codec, ARIZONA_DRE_ENABLE);
+	unsigned int val = snd_soc_component_read32(component, ARIZONA_DRE_ENABLE);
 	const struct reg_sequence *wseq;
 	int nregs;
 
@@ -323,26 +325,32 @@ static int wm5110_hp_pre_enable(struct snd_soc_dapm_widget *w)
 
 static int wm5110_hp_pre_disable(struct snd_soc_dapm_widget *w)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
-	unsigned int val = snd_soc_read(codec, ARIZONA_DRE_ENABLE);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
+	unsigned int val = snd_soc_component_read32(component, ARIZONA_DRE_ENABLE);
 
 	switch (w->shift) {
 	case ARIZONA_OUT1L_ENA_SHIFT:
 		if (!(val & ARIZONA_DRE1L_ENA_MASK)) {
-			snd_soc_update_bits(codec, ARIZONA_SPARE_TRIGGERS,
-					    ARIZONA_WS_TRG1, ARIZONA_WS_TRG1);
-			snd_soc_update_bits(codec, ARIZONA_SPARE_TRIGGERS,
-					    ARIZONA_WS_TRG1, 0);
+			snd_soc_component_update_bits(component,
+						      ARIZONA_SPARE_TRIGGERS,
+						      ARIZONA_WS_TRG1,
+						      ARIZONA_WS_TRG1);
+			snd_soc_component_update_bits(component,
+						      ARIZONA_SPARE_TRIGGERS,
+						      ARIZONA_WS_TRG1, 0);
 			priv->out_down_delay += 27;
 		}
 		break;
 	case ARIZONA_OUT1R_ENA_SHIFT:
 		if (!(val & ARIZONA_DRE1R_ENA_MASK)) {
-			snd_soc_update_bits(codec, ARIZONA_SPARE_TRIGGERS,
-					    ARIZONA_WS_TRG2, ARIZONA_WS_TRG2);
-			snd_soc_update_bits(codec, ARIZONA_SPARE_TRIGGERS,
-					    ARIZONA_WS_TRG2, 0);
+			snd_soc_component_update_bits(component,
+						      ARIZONA_SPARE_TRIGGERS,
+						      ARIZONA_WS_TRG2,
+						      ARIZONA_WS_TRG2);
+			snd_soc_component_update_bits(component,
+						      ARIZONA_SPARE_TRIGGERS,
+						      ARIZONA_WS_TRG2, 0);
 			priv->out_down_delay += 27;
 		}
 		break;
@@ -356,8 +364,8 @@ static int wm5110_hp_pre_disable(struct snd_soc_dapm_widget *w)
 static int wm5110_hp_ev(struct snd_soc_dapm_widget *w,
 			struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 
 	switch (priv->arizona->rev) {
 	case 0 ... 3:
@@ -395,9 +403,9 @@ static int wm5110_clear_pga_volume(struct arizona *arizona, int output)
 static int wm5110_put_dre(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int ena, dre;
@@ -456,8 +464,8 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol,
 static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int ret;
 
 	/*
@@ -476,8 +484,8 @@ static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol,
 static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int ret;
 
 	/*
@@ -496,9 +504,9 @@ static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol,
 static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
-	struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
+	struct wm5110_priv *wm5110 = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 	unsigned int reg, mask;
 	struct reg_sequence analog_seq[] = {
@@ -517,9 +525,9 @@ static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
 		wm5110->in_post_pending++;
 		return 0;
 	case SND_SOC_DAPM_PRE_PMU:
-		wm5110->in_pga_cache[w->shift] = snd_soc_read(codec, reg);
+		wm5110->in_pga_cache[w->shift] = snd_soc_component_read32(component, reg);
 
-		snd_soc_update_bits(codec, reg, mask,
+		snd_soc_component_update_bits(component, reg, mask,
 				    0x40 << ARIZONA_IN1L_PGA_VOL_SHIFT);
 
 		wm5110->in_pre_pending--;
@@ -536,8 +544,8 @@ static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
 
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, reg, mask,
-				    wm5110->in_pga_cache[w->shift]);
+		snd_soc_component_update_bits(component, reg, mask,
+					      wm5110->in_pga_cache[w->shift]);
 
 		wm5110->in_post_pending--;
 		if (wm5110->in_post_pending == 0)
@@ -555,13 +563,13 @@ static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
 static int wm5110_in_ev(struct snd_soc_dapm_widget *w,
 			struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->arizona;
 
 	switch (arizona->rev) {
 	case 0 ... 4:
-		if (arizona_input_analog(codec, w->shift))
+		if (arizona_input_analog(component, w->shift))
 			wm5110_in_analog_ev(w, kcontrol, event);
 
 		break;
@@ -861,14 +869,14 @@ SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
 	   ARIZONA_SPK2R_MUTE_SHIFT, 1, 1),
 
 SOC_DOUBLE_EXT("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE,
-	   ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0,
-	   snd_soc_get_volsw, wm5110_put_dre),
+	       ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0,
+	       snd_soc_get_volsw, wm5110_put_dre),
 SOC_DOUBLE_EXT("HPOUT2 DRE Switch", ARIZONA_DRE_ENABLE,
-	   ARIZONA_DRE2L_ENA_SHIFT, ARIZONA_DRE2R_ENA_SHIFT, 1, 0,
-	   snd_soc_get_volsw, wm5110_put_dre),
+	       ARIZONA_DRE2L_ENA_SHIFT, ARIZONA_DRE2R_ENA_SHIFT, 1, 0,
+	       snd_soc_get_volsw, wm5110_put_dre),
 SOC_DOUBLE_EXT("HPOUT3 DRE Switch", ARIZONA_DRE_ENABLE,
-	   ARIZONA_DRE3L_ENA_SHIFT, ARIZONA_DRE3R_ENA_SHIFT, 1, 0,
-	   snd_soc_get_volsw, wm5110_put_dre),
+	       ARIZONA_DRE3L_ENA_SHIFT, ARIZONA_DRE3R_ENA_SHIFT, 1, 0,
+	       snd_soc_get_volsw, wm5110_put_dre),
 
 SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
 SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
@@ -1034,7 +1042,7 @@ ARIZONA_MUX_ENUMS(ISRC3DEC2, ARIZONA_ISRC3DEC2MIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ISRC3DEC3, ARIZONA_ISRC3DEC3MIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ISRC3DEC4, ARIZONA_ISRC3DEC4MIX_INPUT_1_SOURCE);
 
-static const char *wm5110_aec_loopback_texts[] = {
+static const char * const wm5110_aec_loopback_texts[] = {
 	"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
 	"SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", "SPKDAT2L", "SPKDAT2R",
 };
@@ -1272,18 +1280,17 @@ SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3,
 		 ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-		       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-		       &wm5110_aec_loopback_mux),
+		 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5110_aec_loopback_mux),
 
 SND_SOC_DAPM_SUPPLY("RXANC NG External Clock", SND_SOC_NOPM,
-		   ARIZONA_EXT_NG_SEL_SET_SHIFT, 0, arizona_anc_ev,
-		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+		    ARIZONA_EXT_NG_SEL_SET_SHIFT, 0, arizona_anc_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_PGA("RXANCL NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_PGA("RXANCR NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
 
 SND_SOC_DAPM_SUPPLY("RXANC NG Clock", SND_SOC_NOPM,
-		   ARIZONA_CLK_NG_ENA_SET_SHIFT, 0, arizona_anc_ev,
-		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+		    ARIZONA_CLK_NG_ENA_SET_SHIFT, 0, arizona_anc_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_PGA("RXANCL NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_PGA("RXANCR NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
 
@@ -2032,10 +2039,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
 	{ "DSP3 Voice Trigger", "Switch", "DSP3" },
 };
 
-static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-			  unsigned int Fref, unsigned int Fout)
+static int wm5110_set_fll(struct snd_soc_component *component, int fll_id,
+			  int source, unsigned int Fref, unsigned int Fout)
 {
-	struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
+	struct wm5110_priv *wm5110 = snd_soc_component_get_drvdata(component);
 
 	switch (fll_id) {
 	case WM5110_FLL1:
@@ -2229,7 +2236,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
 static int wm5110_open(struct snd_compr_stream *stream)
 {
 	struct snd_soc_pcm_runtime *rtd = stream->private_data;
-	struct wm5110_priv *priv = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct wm5110_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->core.arizona;
 	int n_adsp;
 
@@ -2275,33 +2283,32 @@ static irqreturn_t wm5110_adsp2_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static int wm5110_codec_probe(struct snd_soc_codec *codec)
+static int wm5110_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-	struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm5110_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->core.arizona;
 	int i, ret;
 
 	arizona->dapm = dapm;
-	snd_soc_codec_init_regmap(codec, arizona->regmap);
+	snd_soc_component_init_regmap(component, arizona->regmap);
 
-	ret = arizona_init_spk(codec);
+	ret = arizona_init_spk(component);
 	if (ret < 0)
 		return ret;
 
-	arizona_init_gpio(codec);
-	arizona_init_mono(codec);
+	arizona_init_gpio(component);
+	arizona_init_mono(component);
 
 	for (i = 0; i < WM5110_NUM_ADSP; ++i) {
-		ret = wm_adsp2_codec_probe(&priv->core.adsp[i], codec);
+		ret = wm_adsp2_component_probe(&priv->core.adsp[i], component);
 		if (ret)
 			goto err_adsp2_codec_probe;
 	}
 
-	ret = snd_soc_add_codec_controls(codec,
-					 arizona_adsp2_rate_controls,
-					 WM5110_NUM_ADSP);
+	ret = snd_soc_add_component_controls(component,
+					     arizona_adsp2_rate_controls,
+					     WM5110_NUM_ADSP);
 	if (ret)
 		goto err_adsp2_codec_probe;
 
@@ -2311,22 +2318,20 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
 
 err_adsp2_codec_probe:
 	for (--i; i >= 0; --i)
-		wm_adsp2_codec_remove(&priv->core.adsp[i], codec);
+		wm_adsp2_component_remove(&priv->core.adsp[i], component);
 
 	return ret;
 }
 
-static int wm5110_codec_remove(struct snd_soc_codec *codec)
+static void wm5110_component_remove(struct snd_soc_component *component)
 {
-	struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct wm5110_priv *priv = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < WM5110_NUM_ADSP; ++i)
-		wm_adsp2_codec_remove(&priv->core.adsp[i], codec);
+		wm_adsp2_component_remove(&priv->core.adsp[i], component);
 
 	priv->core.arizona->dapm = NULL;
-
-	return 0;
 }
 
 #define WM5110_DIG_VU 0x0200
@@ -2346,37 +2351,32 @@ static unsigned int wm5110_digital_vu[] = {
 	ARIZONA_DAC_DIGITAL_VOLUME_6R,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
-	.probe = wm5110_codec_probe,
-	.remove = wm5110_codec_remove,
-
-	.idle_bias_off = true,
-
-	.set_sysclk = arizona_set_sysclk,
-	.set_pll = wm5110_set_fll,
-
-	.component_driver = {
-		.controls		= wm5110_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm5110_snd_controls),
-		.dapm_widgets		= wm5110_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm5110_dapm_widgets),
-		.dapm_routes		= wm5110_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm5110_dapm_routes),
-	},
+static struct snd_compr_ops wm5110_compr_ops = {
+	.open		= wm5110_open,
+	.free		= wm_adsp_compr_free,
+	.set_params	= wm_adsp_compr_set_params,
+	.get_caps	= wm_adsp_compr_get_caps,
+	.trigger	= wm_adsp_compr_trigger,
+	.pointer	= wm_adsp_compr_pointer,
+	.copy		= wm_adsp_compr_copy,
 };
 
-static const struct snd_compr_ops wm5110_compr_ops = {
-	.open = wm5110_open,
-	.free = wm_adsp_compr_free,
-	.set_params = wm_adsp_compr_set_params,
-	.get_caps = wm_adsp_compr_get_caps,
-	.trigger = wm_adsp_compr_trigger,
-	.pointer = wm_adsp_compr_pointer,
-	.copy = wm_adsp_compr_copy,
-};
-
-static const struct snd_soc_platform_driver wm5110_compr_platform = {
-	.compr_ops = &wm5110_compr_ops,
+static const struct snd_soc_component_driver soc_component_dev_wm5110 = {
+	.probe			= wm5110_component_probe,
+	.remove			= wm5110_component_remove,
+	.set_sysclk		= arizona_set_sysclk,
+	.set_pll		= wm5110_set_fll,
+	.name			= DRV_NAME,
+	.compr_ops		= &wm5110_compr_ops,
+	.controls		= wm5110_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm5110_snd_controls),
+	.dapm_widgets		= wm5110_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm5110_dapm_widgets),
+	.dapm_routes		= wm5110_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm5110_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm5110_probe(struct platform_device *pdev)
@@ -2464,23 +2464,17 @@ static int wm5110_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_dsp_irq;
 
-	ret = snd_soc_register_platform(&pdev->dev, &wm5110_compr_platform);
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &soc_component_dev_wm5110,
+					      wm5110_dai,
+					      ARRAY_SIZE(wm5110_dai));
 	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+		dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
 		goto err_spk_irqs;
 	}
 
-	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,
-				      wm5110_dai, ARRAY_SIZE(wm5110_dai));
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
-		goto err_platform;
-	}
-
 	return ret;
 
-err_platform:
-	snd_soc_unregister_platform(&pdev->dev);
 err_spk_irqs:
 	arizona_free_spk_irqs(arizona);
 err_dsp_irq:
@@ -2495,8 +2489,6 @@ static int wm5110_remove(struct platform_device *pdev)
 	struct arizona *arizona = wm5110->core.arizona;
 	int i;
 
-	snd_soc_unregister_platform(&pdev->dev);
-	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 	for (i = 0; i < WM5110_NUM_ADSP; i++)
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index fc79c67..e92ebe5 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -256,8 +256,8 @@ static void wm8350_pga_work(struct work_struct *work)
 static int pga_event(struct snd_soc_dapm_widget *w,
 		     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
 	struct wm8350_output *out;
 
 	switch (w->shift) {
@@ -299,8 +299,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
 static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8350_data *wm8350_priv = snd_soc_component_get_drvdata(component);
 	struct wm8350_output *out = NULL;
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
@@ -334,16 +334,16 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
 		return ret;
 
 	/* now hit the volume update bits (always bit 8) */
-	val = snd_soc_read(codec, reg);
-	snd_soc_write(codec, reg, val | WM8350_OUT1_VU);
+	val = snd_soc_component_read32(component, reg);
+	snd_soc_component_write(component, reg, val | WM8350_OUT1_VU);
 	return 1;
 }
 
 static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8350_data *wm8350_priv = snd_soc_component_get_drvdata(component);
 	struct wm8350_output *out1 = &wm8350_priv->out1;
 	struct wm8350_output *out2 = &wm8350_priv->out2;
 	struct soc_mixer_control *mc =
@@ -753,8 +753,8 @@ static const struct snd_soc_dapm_route wm8350_dapm_routes[] = {
 static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
 	struct wm8350 *wm8350 = wm8350_data->wm8350;
 	u16 fll_4;
 
@@ -769,9 +769,9 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	case WM8350_MCLK_SEL_PLL_32K:
 		wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
 				WM8350_MCLK_SEL);
-		fll_4 = snd_soc_read(codec, WM8350_FLL_CONTROL_4) &
+		fll_4 = snd_soc_component_read32(component, WM8350_FLL_CONTROL_4) &
 		    ~WM8350_FLL_CLK_SRC_MASK;
-		snd_soc_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
+		snd_soc_component_write(component, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
 		break;
 	}
 
@@ -788,44 +788,44 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 val;
 
 	switch (div_id) {
 	case WM8350_ADC_CLKDIV:
-		val = snd_soc_read(codec, WM8350_ADC_DIVIDER) &
+		val = snd_soc_component_read32(component, WM8350_ADC_DIVIDER) &
 		    ~WM8350_ADC_CLKDIV_MASK;
-		snd_soc_write(codec, WM8350_ADC_DIVIDER, val | div);
+		snd_soc_component_write(component, WM8350_ADC_DIVIDER, val | div);
 		break;
 	case WM8350_DAC_CLKDIV:
-		val = snd_soc_read(codec, WM8350_DAC_CLOCK_CONTROL) &
+		val = snd_soc_component_read32(component, WM8350_DAC_CLOCK_CONTROL) &
 		    ~WM8350_DAC_CLKDIV_MASK;
-		snd_soc_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div);
+		snd_soc_component_write(component, WM8350_DAC_CLOCK_CONTROL, val | div);
 		break;
 	case WM8350_BCLK_CLKDIV:
-		val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
+		val = snd_soc_component_read32(component, WM8350_CLOCK_CONTROL_1) &
 		    ~WM8350_BCLK_DIV_MASK;
-		snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+		snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
 		break;
 	case WM8350_OPCLK_CLKDIV:
-		val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
+		val = snd_soc_component_read32(component, WM8350_CLOCK_CONTROL_1) &
 		    ~WM8350_OPCLK_DIV_MASK;
-		snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+		snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
 		break;
 	case WM8350_SYS_CLKDIV:
-		val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
+		val = snd_soc_component_read32(component, WM8350_CLOCK_CONTROL_1) &
 		    ~WM8350_MCLK_DIV_MASK;
-		snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+		snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
 		break;
 	case WM8350_DACLR_CLKDIV:
-		val = snd_soc_read(codec, WM8350_DAC_LR_RATE) &
+		val = snd_soc_component_read32(component, WM8350_DAC_LR_RATE) &
 		    ~WM8350_DACLRC_RATE_MASK;
-		snd_soc_write(codec, WM8350_DAC_LR_RATE, val | div);
+		snd_soc_component_write(component, WM8350_DAC_LR_RATE, val | div);
 		break;
 	case WM8350_ADCLR_CLKDIV:
-		val = snd_soc_read(codec, WM8350_ADC_LR_RATE) &
+		val = snd_soc_component_read32(component, WM8350_ADC_LR_RATE) &
 		    ~WM8350_ADCLRC_RATE_MASK;
-		snd_soc_write(codec, WM8350_ADC_LR_RATE, val | div);
+		snd_soc_component_write(component, WM8350_ADC_LR_RATE, val | div);
 		break;
 	default:
 		return -EINVAL;
@@ -836,14 +836,14 @@ static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
 
 static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 iface = snd_soc_read(codec, WM8350_AI_FORMATING) &
+	struct snd_soc_component *component = codec_dai->component;
+	u16 iface = snd_soc_component_read32(component, WM8350_AI_FORMATING) &
 	    ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
-	u16 master = snd_soc_read(codec, WM8350_AI_DAC_CONTROL) &
+	u16 master = snd_soc_component_read32(component, WM8350_AI_DAC_CONTROL) &
 	    ~WM8350_BCLK_MSTR;
-	u16 dac_lrc = snd_soc_read(codec, WM8350_DAC_LR_RATE) &
+	u16 dac_lrc = snd_soc_component_read32(component, WM8350_DAC_LR_RATE) &
 	    ~WM8350_DACLRC_ENA;
-	u16 adc_lrc = snd_soc_read(codec, WM8350_ADC_LR_RATE) &
+	u16 adc_lrc = snd_soc_component_read32(component, WM8350_ADC_LR_RATE) &
 	    ~WM8350_ADCLRC_ENA;
 
 	/* set master/slave audio interface */
@@ -896,10 +896,10 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8350_AI_FORMATING, iface);
-	snd_soc_write(codec, WM8350_AI_DAC_CONTROL, master);
-	snd_soc_write(codec, WM8350_DAC_LR_RATE, dac_lrc);
-	snd_soc_write(codec, WM8350_ADC_LR_RATE, adc_lrc);
+	snd_soc_component_write(component, WM8350_AI_FORMATING, iface);
+	snd_soc_component_write(component, WM8350_AI_DAC_CONTROL, master);
+	snd_soc_component_write(component, WM8350_DAC_LR_RATE, dac_lrc);
+	snd_soc_component_write(component, WM8350_ADC_LR_RATE, adc_lrc);
 	return 0;
 }
 
@@ -907,10 +907,10 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *codec_dai)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
 	struct wm8350 *wm8350 = wm8350_data->wm8350;
-	u16 iface = snd_soc_read(codec, WM8350_AI_FORMATING) &
+	u16 iface = snd_soc_component_read32(component, WM8350_AI_FORMATING) &
 	    ~WM8350_AIF_WL_MASK;
 
 	/* bit size */
@@ -928,7 +928,7 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8350_AI_FORMATING, iface);
+	snd_soc_component_write(component, WM8350_AI_FORMATING, iface);
 
 	/* The sloping stopband filter is recommended for use with
 	 * lower sample rates to improve performance.
@@ -947,7 +947,7 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8350_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int val;
 
 	if (mute)
@@ -955,7 +955,7 @@ static int wm8350_mute(struct snd_soc_dai *dai, int mute)
 	else
 		val = 0;
 
-	snd_soc_update_bits(codec, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA, val);
+	snd_soc_component_update_bits(component, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA, val);
 
 	return 0;
 }
@@ -1024,8 +1024,8 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
 			  int pll_id, int source, unsigned int freq_in,
 			  unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
 	struct wm8350 *wm8350 = priv->wm8350;
 	struct _fll_div fll_div;
 	int ret = 0;
@@ -1050,17 +1050,17 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
 		fll_div.ratio);
 
 	/* set up N.K & dividers */
-	fll_1 = snd_soc_read(codec, WM8350_FLL_CONTROL_1) &
+	fll_1 = snd_soc_component_read32(component, WM8350_FLL_CONTROL_1) &
 	    ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
-	snd_soc_write(codec, WM8350_FLL_CONTROL_1,
+	snd_soc_component_write(component, WM8350_FLL_CONTROL_1,
 			   fll_1 | (fll_div.div << 8) | 0x50);
-	snd_soc_write(codec, WM8350_FLL_CONTROL_2,
+	snd_soc_component_write(component, WM8350_FLL_CONTROL_2,
 			   (fll_div.ratio << 11) | (fll_div.
 						    n & WM8350_FLL_N_MASK));
-	snd_soc_write(codec, WM8350_FLL_CONTROL_3, fll_div.k);
-	fll_4 = snd_soc_read(codec, WM8350_FLL_CONTROL_4) &
+	snd_soc_component_write(component, WM8350_FLL_CONTROL_3, fll_div.k);
+	fll_4 = snd_soc_component_read32(component, WM8350_FLL_CONTROL_4) &
 	    ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
-	snd_soc_write(codec, WM8350_FLL_CONTROL_4,
+	snd_soc_component_write(component, WM8350_FLL_CONTROL_4,
 			   fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
 			   (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
 
@@ -1074,10 +1074,10 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-static int wm8350_set_bias_level(struct snd_soc_codec *codec,
+static int wm8350_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
 	struct wm8350 *wm8350 = priv->wm8350;
 	struct wm8350_audio_platform_data *platform =
 		wm8350->codec.platform_data;
@@ -1101,7 +1101,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
 						    priv->supplies);
 			if (ret != 0)
@@ -1310,7 +1310,7 @@ static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
 /**
  * wm8350_hp_jack_detect - Enable headphone jack detection.
  *
- * @codec:  WM8350 codec
+ * @component:  WM8350 component
  * @which:  left or right jack detect signal
  * @jack:   jack to report detection events on
  * @report: value to report
@@ -1318,10 +1318,10 @@ static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
  * Enables the headphone jack detection of the WM8350.  If no report
  * is specified then detection is disabled.
  */
-int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
+int wm8350_hp_jack_detect(struct snd_soc_component *component, enum wm8350_jack which,
 			  struct snd_soc_jack *jack, int report)
 {
-	struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
 	struct wm8350 *wm8350 = priv->wm8350;
 	int ena;
 
@@ -1389,7 +1389,7 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
 /**
  * wm8350_mic_jack_detect - Enable microphone jack detection.
  *
- * @codec:         WM8350 codec
+ * @component:         WM8350 component
  * @jack:          jack to report detection events on
  * @detect_report: value to report when presence detected
  * @short_report:  value to report when microphone short detected
@@ -1397,11 +1397,11 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
  * Enables the microphone jack detection of the WM8350.  If both reports
  * are specified as zero then detection is disabled.
  */
-int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
+int wm8350_mic_jack_detect(struct snd_soc_component *component,
 			   struct snd_soc_jack *jack,
 			   int detect_report, int short_report)
 {
-	struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+	struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
 	struct wm8350 *wm8350 = priv->wm8350;
 
 	priv->mic.jack = jack;
@@ -1455,26 +1455,26 @@ static struct snd_soc_dai_driver wm8350_dai = {
 	.ops = &wm8350_dai_ops,
 };
 
-static  int wm8350_codec_probe(struct snd_soc_codec *codec)
+static  int wm8350_component_probe(struct snd_soc_component *component)
 {
-	struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
+	struct wm8350 *wm8350 = dev_get_platdata(component->dev);
 	struct wm8350_data *priv;
 	struct wm8350_output *out1;
 	struct wm8350_output *out2;
 	int ret, i;
 
 	if (wm8350->codec.platform_data == NULL) {
-		dev_err(codec->dev, "No audio platform data supplied\n");
+		dev_err(component->dev, "No audio platform data supplied\n");
 		return -EINVAL;
 	}
 
-	priv = devm_kzalloc(codec->dev, sizeof(struct wm8350_data),
+	priv = devm_kzalloc(component->dev, sizeof(struct wm8350_data),
 			    GFP_KERNEL);
 	if (priv == NULL)
 		return -ENOMEM;
 
-	snd_soc_codec_init_regmap(codec, wm8350->regmap);
-	snd_soc_codec_set_drvdata(codec, priv);
+	snd_soc_component_init_regmap(component, wm8350->regmap);
+	snd_soc_component_set_drvdata(component, priv);
 
 	priv->wm8350 = wm8350;
 
@@ -1497,9 +1497,9 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
 	wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
 
 	/* Enable robust clocking mode in ADC */
-	snd_soc_write(codec, WM8350_SECURITY, 0xa7);
-	snd_soc_write(codec, 0xde, 0x13);
-	snd_soc_write(codec, WM8350_SECURITY, 0);
+	snd_soc_component_write(component, WM8350_SECURITY, 0xa7);
+	snd_soc_component_write(component, 0xde, 0x13);
+	snd_soc_component_write(component, WM8350_SECURITY, 0);
 
 	/* read OUT1 & OUT2 volumes */
 	out1 = &priv->out1;
@@ -1552,10 +1552,10 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int  wm8350_codec_remove(struct snd_soc_codec *codec)
+static void wm8350_component_remove(struct snd_soc_component *component)
 {
-	struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
-	struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
+	struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
+	struct wm8350 *wm8350 = dev_get_platdata(component->dev);
 
 	wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
 			  WM8350_JDL_ENA | WM8350_JDR_ENA);
@@ -1578,44 +1578,37 @@ static int  wm8350_codec_remove(struct snd_soc_codec *codec)
 	flush_delayed_work(&priv->pga_work);
 
 	wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
-	.probe =	wm8350_codec_probe,
-	.remove =	wm8350_codec_remove,
-	.set_bias_level = wm8350_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8350_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8350_snd_controls),
-		.dapm_widgets		= wm8350_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8350_dapm_widgets),
-		.dapm_routes		= wm8350_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8350_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8350 = {
+	.probe			= wm8350_component_probe,
+	.remove			= wm8350_component_remove,
+	.set_bias_level		= wm8350_set_bias_level,
+	.controls		= wm8350_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8350_snd_controls),
+	.dapm_widgets		= wm8350_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8350_dapm_widgets),
+	.dapm_routes		= wm8350_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8350_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8350_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350,
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_wm8350,
 			&wm8350_dai, 1);
 }
 
-static int wm8350_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 static struct platform_driver wm8350_codec_driver = {
 	.driver = {
 		   .name = "wm8350-codec",
 		   },
 	.probe = wm8350_probe,
-	.remove = wm8350_remove,
 };
 
 module_platform_driver(wm8350_codec_driver);
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
index 74108eb..1191326 100644
--- a/sound/soc/codecs/wm8350.h
+++ b/sound/soc/codecs/wm8350.h
@@ -20,9 +20,9 @@ enum wm8350_jack {
 	WM8350_JDR = 2,
 };
 
-int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
+int wm8350_hp_jack_detect(struct snd_soc_component *component, enum wm8350_jack which,
 			  struct snd_soc_jack *jack, int report);
-int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
+int wm8350_mic_jack_detect(struct snd_soc_component *component,
 			   struct snd_soc_jack *jack,
 			   int detect_report, int short_report);
 
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index a36adf8..57b2206 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -65,9 +65,9 @@ struct wm8400_priv {
 	int fll_in, fll_out;
 };
 
-static void wm8400_codec_reset(struct snd_soc_codec *codec)
+static void wm8400_component_reset(struct snd_soc_component *component)
 {
-	struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
+	struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
 
 	wm8400_reset_codec_reg_cache(wm8400->wm8400);
 }
@@ -91,7 +91,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0);
 static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
         struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	int reg = mc->reg;
@@ -103,8 +103,8 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
                 return ret;
 
         /* now hit the volume update bits (always bit 8) */
-        val = snd_soc_read(codec, reg);
-        return snd_soc_write(codec, reg, val | 0x0100);
+        val = snd_soc_component_read32(component, reg);
+        return snd_soc_component_write(component, reg, val | 0x0100);
 }
 
 #define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
@@ -324,7 +324,7 @@ SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
 static int outmixer_event (struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol * kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	u32 reg_shift = mc->shift;
@@ -333,7 +333,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
 
 	switch (reg_shift) {
 	case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
-		reg = snd_soc_read(codec, WM8400_OUTPUT_MIXER1);
+		reg = snd_soc_component_read32(component, WM8400_OUTPUT_MIXER1);
 		if (reg & WM8400_LDLO) {
 			printk(KERN_WARNING
 			"Cannot set as Output Mixer 1 LDLO Set\n");
@@ -341,7 +341,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
 		}
 		break;
 	case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
-		reg = snd_soc_read(codec, WM8400_OUTPUT_MIXER2);
+		reg = snd_soc_component_read32(component, WM8400_OUTPUT_MIXER2);
 		if (reg & WM8400_RDRO) {
 			printk(KERN_WARNING
 			"Cannot set as Output Mixer 2 RDRO Set\n");
@@ -349,7 +349,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
 		}
 		break;
 	case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
-		reg = snd_soc_read(codec, WM8400_SPEAKER_MIXER);
+		reg = snd_soc_component_read32(component, WM8400_SPEAKER_MIXER);
 		if (reg & WM8400_LDSPK) {
 			printk(KERN_WARNING
 			"Cannot set as Speaker Mixer LDSPK Set\n");
@@ -357,7 +357,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
 		}
 		break;
 	case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
-		reg = snd_soc_read(codec, WM8400_SPEAKER_MIXER);
+		reg = snd_soc_component_read32(component, WM8400_SPEAKER_MIXER);
 		if (reg & WM8400_RDSPK) {
 			printk(KERN_WARNING
 			"Cannot set as Speaker Mixer RDSPK Set\n");
@@ -849,8 +849,8 @@ static const struct snd_soc_dapm_route wm8400_dapm_routes[] = {
 static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
 
 	wm8400->sysclk = freq;
 	return 0;
@@ -938,8 +938,8 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 			      int source, unsigned int freq_in,
 			      unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
 	struct fll_factors factors;
 	int ret;
 	u16 reg;
@@ -962,13 +962,13 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	wm8400->fll_in = freq_in;
 
 	/* We *must* disable the FLL before any changes */
-	reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_2);
+	reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_2);
 	reg &= ~WM8400_FLL_ENA;
-	snd_soc_write(codec, WM8400_POWER_MANAGEMENT_2, reg);
+	snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_2, reg);
 
-	reg = snd_soc_read(codec, WM8400_FLL_CONTROL_1);
+	reg = snd_soc_component_read32(component, WM8400_FLL_CONTROL_1);
 	reg &= ~WM8400_FLL_OSC_ENA;
-	snd_soc_write(codec, WM8400_FLL_CONTROL_1, reg);
+	snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg);
 
 	if (!freq_out)
 		return 0;
@@ -976,15 +976,15 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
 	reg |= WM8400_FLL_FRAC | factors.fratio;
 	reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT;
-	snd_soc_write(codec, WM8400_FLL_CONTROL_1, reg);
+	snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg);
 
-	snd_soc_write(codec, WM8400_FLL_CONTROL_2, factors.k);
-	snd_soc_write(codec, WM8400_FLL_CONTROL_3, factors.n);
+	snd_soc_component_write(component, WM8400_FLL_CONTROL_2, factors.k);
+	snd_soc_component_write(component, WM8400_FLL_CONTROL_3, factors.n);
 
-	reg = snd_soc_read(codec, WM8400_FLL_CONTROL_4);
+	reg = snd_soc_component_read32(component, WM8400_FLL_CONTROL_4);
 	reg &= ~WM8400_FLL_OUTDIV_MASK;
 	reg |= factors.outdiv;
-	snd_soc_write(codec, WM8400_FLL_CONTROL_4, reg);
+	snd_soc_component_write(component, WM8400_FLL_CONTROL_4, reg);
 
 	return 0;
 }
@@ -995,11 +995,11 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 audio1, audio3;
 
-	audio1 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_1);
-	audio3 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_3);
+	audio1 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_1);
+	audio3 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_3);
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1040,37 +1040,37 @@ static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
-	snd_soc_write(codec, WM8400_AUDIO_INTERFACE_3, audio3);
+	snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_1, audio1);
+	snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_3, audio3);
 	return 0;
 }
 
 static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
 	switch (div_id) {
 	case WM8400_MCLK_DIV:
-		reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
+		reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) &
 			~WM8400_MCLK_DIV_MASK;
-		snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
+		snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
 		break;
 	case WM8400_DACCLK_DIV:
-		reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
+		reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) &
 			~WM8400_DAC_CLKDIV_MASK;
-		snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
+		snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
 		break;
 	case WM8400_ADCCLK_DIV:
-		reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
+		reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) &
 			~WM8400_ADC_CLKDIV_MASK;
-		snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
+		snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
 		break;
 	case WM8400_BCLK_DIV:
-		reg = snd_soc_read(codec, WM8400_CLOCKING_1) &
+		reg = snd_soc_component_read32(component, WM8400_CLOCKING_1) &
 			~WM8400_BCLK_DIV_MASK;
-		snd_soc_write(codec, WM8400_CLOCKING_1, reg | div);
+		snd_soc_component_write(component, WM8400_CLOCKING_1, reg | div);
 		break;
 	default:
 		return -EINVAL;
@@ -1086,8 +1086,8 @@ static int wm8400_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;
-	u16 audio1 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_1);
+	struct snd_soc_component *component = dai->component;
+	u16 audio1 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_1);
 
 	audio1 &= ~WM8400_AIF_WL_MASK;
 	/* bit size */
@@ -1105,28 +1105,28 @@ static int wm8400_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
+	snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_1, audio1);
 	return 0;
 }
 
 static int wm8400_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 val = snd_soc_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
+	struct snd_soc_component *component = dai->component;
+	u16 val = snd_soc_component_read32(component, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
 
 	if (mute)
-		snd_soc_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
+		snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
 	else
-		snd_soc_write(codec, WM8400_DAC_CTRL, val);
+		snd_soc_component_write(component, WM8400_DAC_CTRL, val);
 
 	return 0;
 }
 
 /* TODO: set bias for best performance at standby */
-static int wm8400_set_bias_level(struct snd_soc_codec *codec,
+static int wm8400_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
+	struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
 	u16 val;
 	int ret;
 
@@ -1136,13 +1136,13 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID=2*50k */
-		val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1) &
+		val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1) &
 			~WM8400_VMID_MODE_MASK;
-		snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2);
+		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x2);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(power),
 						    &power[0]);
 			if (ret != 0) {
@@ -1152,74 +1152,74 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
 				return ret;
 			}
 
-			snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
+			snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1,
 				     WM8400_CODEC_ENA | WM8400_SYSCLK_ENA);
 
 			/* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
-			snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
+			snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
 				     WM8400_BUFDCOPEN | WM8400_POBCTRL);
 
 			msleep(50);
 
 			/* Enable VREF & VMID at 2x50k */
-			val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
+			val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1);
 			val |= 0x2 | WM8400_VREF_ENA;
-			snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
+			snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
 
 			/* Enable BUFIOEN */
-			snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
+			snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
 				     WM8400_BUFDCOPEN | WM8400_POBCTRL |
 				     WM8400_BUFIOEN);
 
 			/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
-			snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN);
+			snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_BUFIOEN);
 		}
 
 		/* VMID=2*300k */
-		val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1) &
+		val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1) &
 			~WM8400_VMID_MODE_MASK;
-		snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4);
+		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x4);
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* Enable POBCTRL and SOFT_ST */
-		snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
+		snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
 			WM8400_POBCTRL | WM8400_BUFIOEN);
 
 		/* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
-		snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
+		snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
 			WM8400_BUFDCOPEN | WM8400_POBCTRL |
 			WM8400_BUFIOEN);
 
 		/* mute DAC */
-		val = snd_soc_read(codec, WM8400_DAC_CTRL);
-		snd_soc_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
+		val = snd_soc_component_read32(component, WM8400_DAC_CTRL);
+		snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
 
 		/* Enable any disabled outputs */
-		val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
+		val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1);
 		val |= WM8400_SPK_ENA | WM8400_OUT3_ENA |
 			WM8400_OUT4_ENA | WM8400_LOUT_ENA |
 			WM8400_ROUT_ENA;
-		snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
+		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
 
 		/* Disable VMID */
 		val &= ~WM8400_VMID_MODE_MASK;
-		snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
+		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
 
 		msleep(300);
 
 		/* Enable all output discharge bits */
-		snd_soc_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
+		snd_soc_component_write(component, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
 			WM8400_DIS_RLINE | WM8400_DIS_OUT3 |
 			WM8400_DIS_OUT4 | WM8400_DIS_LOUT |
 			WM8400_DIS_ROUT);
 
 		/* Disable VREF */
 		val &= ~WM8400_VREF_ENA;
-		snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
+		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
 
 		/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
-		snd_soc_write(codec, WM8400_ANTIPOP2, 0x0);
+		snd_soc_component_write(component, WM8400_ANTIPOP2, 0x0);
 
 		ret = regulator_bulk_disable(ARRAY_SIZE(power),
 					     &power[0]);
@@ -1273,93 +1273,86 @@ static struct snd_soc_dai_driver wm8400_dai = {
 	.ops = &wm8400_dai_ops,
 };
 
-static int wm8400_codec_probe(struct snd_soc_codec *codec)
+static int wm8400_component_probe(struct snd_soc_component *component)
 {
-	struct wm8400 *wm8400 = dev_get_platdata(codec->dev);
+	struct wm8400 *wm8400 = dev_get_platdata(component->dev);
 	struct wm8400_priv *priv;
 	int ret;
 	u16 reg;
 
-	priv = devm_kzalloc(codec->dev, sizeof(struct wm8400_priv),
+	priv = devm_kzalloc(component->dev, sizeof(struct wm8400_priv),
 			    GFP_KERNEL);
 	if (priv == NULL)
 		return -ENOMEM;
 
-	snd_soc_codec_init_regmap(codec, wm8400->regmap);
-	snd_soc_codec_set_drvdata(codec, priv);
+	snd_soc_component_init_regmap(component, wm8400->regmap);
+	snd_soc_component_set_drvdata(component, priv);
 	priv->wm8400 = wm8400;
 
 	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);
+		dev_err(component->dev, "Failed to get regulators: %d\n", ret);
 		return ret;
 	}
 
-	wm8400_codec_reset(codec);
+	wm8400_component_reset(component);
 
-	reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
-	snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
+	reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1);
+	snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
 
 	/* Latch volume update bits */
-	reg = snd_soc_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
-	snd_soc_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
+	reg = snd_soc_component_read32(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
+	snd_soc_component_write(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
 		     reg & WM8400_IPVU);
-	reg = snd_soc_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
-	snd_soc_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
+	reg = snd_soc_component_read32(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
+	snd_soc_component_write(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
 		     reg & WM8400_IPVU);
 
-	snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
-	snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
+	snd_soc_component_write(component, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
+	snd_soc_component_write(component, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
 
 	return 0;
 }
 
-static int  wm8400_codec_remove(struct snd_soc_codec *codec)
+static void  wm8400_component_remove(struct snd_soc_component *component)
 {
 	u16 reg;
 
-	reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
-	snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
+	reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1);
+	snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1,
 		     reg & (~WM8400_CODEC_ENA));
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
-	.probe =	wm8400_codec_probe,
-	.remove =	wm8400_codec_remove,
-	.set_bias_level = wm8400_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8400_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8400_snd_controls),
-		.dapm_widgets		= wm8400_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8400_dapm_widgets),
-		.dapm_routes		= wm8400_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8400_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8400 = {
+	.probe			= wm8400_component_probe,
+	.remove			= wm8400_component_remove,
+	.set_bias_level		= wm8400_set_bias_level,
+	.controls		= wm8400_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8400_snd_controls),
+	.dapm_widgets		= wm8400_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8400_dapm_widgets),
+	.dapm_routes		= wm8400_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8400_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8400_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400,
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_wm8400,
 			&wm8400_dai, 1);
 }
 
-static int wm8400_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 static struct platform_driver wm8400_codec_driver = {
 	.driver = {
 		   .name = "wm8400-codec",
 		   },
 	.probe = wm8400_probe,
-	.remove = wm8400_remove,
 };
 
 module_platform_driver(wm8400_codec_driver);
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 119ceac..1a2412d 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -106,7 +106,7 @@ static bool wm8510_volatile(struct device *dev, unsigned int reg)
 #define WM8510_POWER1_BIASEN  0x08
 #define WM8510_POWER1_BUFIOEN 0x10
 
-#define wm8510_reset(c)	snd_soc_write(c, WM8510_RESET, 0)
+#define wm8510_reset(c)	snd_soc_component_write(c, WM8510_RESET, 0)
 
 /* codec private data */
 struct wm8510_priv {
@@ -316,32 +316,32 @@ static void pll_factors(unsigned int target, unsigned int source)
 static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
 	if (freq_in == 0 || freq_out == 0) {
 		/* Clock CODEC directly from MCLK */
-		reg = snd_soc_read(codec, WM8510_CLOCK);
-		snd_soc_write(codec, WM8510_CLOCK, reg & 0x0ff);
+		reg = snd_soc_component_read32(component, WM8510_CLOCK);
+		snd_soc_component_write(component, WM8510_CLOCK, reg & 0x0ff);
 
 		/* Turn off PLL */
-		reg = snd_soc_read(codec, WM8510_POWER1);
-		snd_soc_write(codec, WM8510_POWER1, reg & 0x1df);
+		reg = snd_soc_component_read32(component, WM8510_POWER1);
+		snd_soc_component_write(component, WM8510_POWER1, reg & 0x1df);
 		return 0;
 	}
 
 	pll_factors(freq_out*4, freq_in);
 
-	snd_soc_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
-	snd_soc_write(codec, WM8510_PLLK1, pll_div.k >> 18);
-	snd_soc_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
-	snd_soc_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff);
-	reg = snd_soc_read(codec, WM8510_POWER1);
-	snd_soc_write(codec, WM8510_POWER1, reg | 0x020);
+	snd_soc_component_write(component, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
+	snd_soc_component_write(component, WM8510_PLLK1, pll_div.k >> 18);
+	snd_soc_component_write(component, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
+	snd_soc_component_write(component, WM8510_PLLK3, pll_div.k & 0x1ff);
+	reg = snd_soc_component_read32(component, WM8510_POWER1);
+	snd_soc_component_write(component, WM8510_POWER1, reg | 0x020);
 
 	/* Run CODEC from PLL instead of MCLK */
-	reg = snd_soc_read(codec, WM8510_CLOCK);
-	snd_soc_write(codec, WM8510_CLOCK, reg | 0x100);
+	reg = snd_soc_component_read32(component, WM8510_CLOCK);
+	snd_soc_component_write(component, WM8510_CLOCK, reg | 0x100);
 
 	return 0;
 }
@@ -352,29 +352,29 @@ static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
 	switch (div_id) {
 	case WM8510_OPCLKDIV:
-		reg = snd_soc_read(codec, WM8510_GPIO) & 0x1cf;
-		snd_soc_write(codec, WM8510_GPIO, reg | div);
+		reg = snd_soc_component_read32(component, WM8510_GPIO) & 0x1cf;
+		snd_soc_component_write(component, WM8510_GPIO, reg | div);
 		break;
 	case WM8510_MCLKDIV:
-		reg = snd_soc_read(codec, WM8510_CLOCK) & 0x11f;
-		snd_soc_write(codec, WM8510_CLOCK, reg | div);
+		reg = snd_soc_component_read32(component, WM8510_CLOCK) & 0x11f;
+		snd_soc_component_write(component, WM8510_CLOCK, reg | div);
 		break;
 	case WM8510_ADCCLK:
-		reg = snd_soc_read(codec, WM8510_ADC) & 0x1f7;
-		snd_soc_write(codec, WM8510_ADC, reg | div);
+		reg = snd_soc_component_read32(component, WM8510_ADC) & 0x1f7;
+		snd_soc_component_write(component, WM8510_ADC, reg | div);
 		break;
 	case WM8510_DACCLK:
-		reg = snd_soc_read(codec, WM8510_DAC) & 0x1f7;
-		snd_soc_write(codec, WM8510_DAC, reg | div);
+		reg = snd_soc_component_read32(component, WM8510_DAC) & 0x1f7;
+		snd_soc_component_write(component, WM8510_DAC, reg | div);
 		break;
 	case WM8510_BCLKDIV:
-		reg = snd_soc_read(codec, WM8510_CLOCK) & 0x1e3;
-		snd_soc_write(codec, WM8510_CLOCK, reg | div);
+		reg = snd_soc_component_read32(component, WM8510_CLOCK) & 0x1e3;
+		snd_soc_component_write(component, WM8510_CLOCK, reg | div);
 		break;
 	default:
 		return -EINVAL;
@@ -386,9 +386,9 @@ static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
-	u16 clk = snd_soc_read(codec, WM8510_CLOCK) & 0x1fe;
+	u16 clk = snd_soc_component_read32(component, WM8510_CLOCK) & 0x1fe;
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -435,8 +435,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8510_IFACE, iface);
-	snd_soc_write(codec, WM8510_CLOCK, clk);
+	snd_soc_component_write(component, WM8510_IFACE, iface);
+	snd_soc_component_write(component, WM8510_CLOCK, clk);
 	return 0;
 }
 
@@ -444,9 +444,9 @@ static int wm8510_pcm_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;
-	u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
-	u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
+	struct snd_soc_component *component = dai->component;
+	u16 iface = snd_soc_component_read32(component, WM8510_IFACE) & 0x19f;
+	u16 adn = snd_soc_component_read32(component, WM8510_ADD) & 0x1f1;
 
 	/* bit size */
 	switch (params_width(params)) {
@@ -485,56 +485,56 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8510_IFACE, iface);
-	snd_soc_write(codec, WM8510_ADD, adn);
+	snd_soc_component_write(component, WM8510_IFACE, iface);
+	snd_soc_component_write(component, WM8510_ADD, adn);
 	return 0;
 }
 
 static int wm8510_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8510_DAC) & 0xffbf;
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8510_DAC) & 0xffbf;
 
 	if (mute)
-		snd_soc_write(codec, WM8510_DAC, mute_reg | 0x40);
+		snd_soc_component_write(component, WM8510_DAC, mute_reg | 0x40);
 	else
-		snd_soc_write(codec, WM8510_DAC, mute_reg);
+		snd_soc_component_write(component, WM8510_DAC, mute_reg);
 	return 0;
 }
 
 /* liam need to make this lower power with dapm */
-static int wm8510_set_bias_level(struct snd_soc_codec *codec,
+static int wm8510_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
-	u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
+	struct wm8510_priv *wm8510 = snd_soc_component_get_drvdata(component);
+	u16 power1 = snd_soc_component_read32(component, WM8510_POWER1) & ~0x3;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		power1 |= 0x1;  /* VMID 50k */
-		snd_soc_write(codec, WM8510_POWER1, power1);
+		snd_soc_component_write(component, WM8510_POWER1, power1);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
 		power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_sync(wm8510->regmap);
 
 			/* Initial cap charge at VMID 5k */
-			snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
+			snd_soc_component_write(component, WM8510_POWER1, power1 | 0x3);
 			mdelay(100);
 		}
 
 		power1 |= 0x2;  /* VMID 500k */
-		snd_soc_write(codec, WM8510_POWER1, power1);
+		snd_soc_component_write(component, WM8510_POWER1, power1);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, WM8510_POWER1, 0);
-		snd_soc_write(codec, WM8510_POWER2, 0);
-		snd_soc_write(codec, WM8510_POWER3, 0);
+		snd_soc_component_write(component, WM8510_POWER1, 0);
+		snd_soc_component_write(component, WM8510_POWER2, 0);
+		snd_soc_component_write(component, WM8510_POWER3, 0);
 		break;
 	}
 
@@ -574,26 +574,27 @@ static struct snd_soc_dai_driver wm8510_dai = {
 	.symmetric_rates = 1,
 };
 
-static int wm8510_probe(struct snd_soc_codec *codec)
+static int wm8510_probe(struct snd_soc_component *component)
 {
-	wm8510_reset(codec);
+	wm8510_reset(component);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
-	.probe =	wm8510_probe,
-	.set_bias_level = wm8510_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8510_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8510_snd_controls),
-		.dapm_widgets		= wm8510_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8510_dapm_widgets),
-		.dapm_routes		= wm8510_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8510_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8510 = {
+	.probe			= wm8510_probe,
+	.set_bias_level		= wm8510_set_bias_level,
+	.controls		= wm8510_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8510_snd_controls),
+	.dapm_widgets		= wm8510_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8510_dapm_widgets),
+	.dapm_routes		= wm8510_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8510_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8510_of_match[] = {
@@ -631,25 +632,18 @@ static int wm8510_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8510);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8510, &wm8510_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8510, &wm8510_dai, 1);
 
 	return ret;
 }
 
-static int wm8510_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver wm8510_spi_driver = {
 	.driver = {
 		.name	= "wm8510",
 		.of_match_table = wm8510_of_match,
 	},
 	.probe		= wm8510_spi_probe,
-	.remove		= wm8510_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -671,18 +665,12 @@ static int wm8510_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8510);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8510, &wm8510_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8510, &wm8510_dai, 1);
 
 	return ret;
 }
 
-static int wm8510_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8510_i2c_id[] = {
 	{ "wm8510", 0 },
 	{ }
@@ -695,7 +683,6 @@ static struct i2c_driver wm8510_i2c_driver = {
 		.of_match_table = wm8510_of_match,
 	},
 	.probe =    wm8510_i2c_probe,
-	.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 c7c33e9..f4a9e25 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -125,14 +125,14 @@ static const struct {
 static int wm8523_startup(struct snd_pcm_substream *substream,
 			  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 
 	/* The set of sample rates that can be supported depends on the
 	 * MCLK supplied to the CODEC - enforce this.
 	 */
 	if (!wm8523->sysclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"No MCLK configured, call set_sysclk() on init\n");
 		return -EINVAL;
 	}
@@ -148,11 +148,11 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 	int i;
-	u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
-	u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);
+	u16 aifctrl1 = snd_soc_component_read32(component, WM8523_AIF_CTRL1);
+	u16 aifctrl2 = snd_soc_component_read32(component, WM8523_AIF_CTRL2);
 
 	/* Find a supported LRCLK ratio */
 	for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
@@ -163,7 +163,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
 
 	/* Should never happen, should be handled by constraints */
 	if (i == ARRAY_SIZE(lrclk_ratios)) {
-		dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
+		dev_err(component->dev, "MCLK/fs ratio %d unsupported\n",
 			wm8523->sysclk / params_rate(params));
 		return -EINVAL;
 	}
@@ -178,7 +178,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
 				break;
 
 		if (i == ARRAY_SIZE(bclk_ratios)) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"No matching BCLK/fs ratio for word length %d\n",
 				params_width(params));
 			return -EINVAL;
@@ -203,8 +203,8 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
-	snd_soc_write(codec, WM8523_AIF_CTRL2, aifctrl2);
+	snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1);
+	snd_soc_component_write(component, WM8523_AIF_CTRL2, aifctrl2);
 
 	return 0;
 }
@@ -212,8 +212,8 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
 static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 	int i;
 
@@ -239,13 +239,13 @@ static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		case 96000:
 		case 176400:
 		case 192000:
-			dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
+			dev_dbg(component->dev, "Supported sample rate: %dHz\n",
 				val);
 			wm8523->rate_constraint_list[i] = val;
 			wm8523->rate_constraint.count++;
 			break;
 		default:
-			dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
+			dev_dbg(component->dev, "Skipping sample rate: %dHz\n",
 				val);
 		}
 	}
@@ -261,8 +261,8 @@ static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
+	struct snd_soc_component *component = codec_dai->component;
+	u16 aifctrl1 = snd_soc_component_read32(component, WM8523_AIF_CTRL1);
 
 	aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK |
 		      WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK);
@@ -312,15 +312,15 @@ static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
+	snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1);
 
 	return 0;
 }
 
-static int wm8523_set_bias_level(struct snd_soc_codec *codec,
+static int wm8523_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+	struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -329,16 +329,16 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* Full power on */
-		snd_soc_update_bits(codec, WM8523_PSCTRL1,
+		snd_soc_component_update_bits(component, WM8523_PSCTRL1,
 				    WM8523_SYS_ENA_MASK, 3);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
 						    wm8523->supplies);
 			if (ret != 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n",
 					ret);
 				return ret;
@@ -348,21 +348,21 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
 			regcache_sync(wm8523->regmap);
 
 			/* Initial power up */
-			snd_soc_update_bits(codec, WM8523_PSCTRL1,
+			snd_soc_component_update_bits(component, WM8523_PSCTRL1,
 					    WM8523_SYS_ENA_MASK, 1);
 
 			msleep(100);
 		}
 
 		/* Power up to mute */
-		snd_soc_update_bits(codec, WM8523_PSCTRL1,
+		snd_soc_component_update_bits(component, WM8523_PSCTRL1,
 				    WM8523_SYS_ENA_MASK, 2);
 
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* The chip runs through the power down sequence for us. */
-		snd_soc_update_bits(codec, WM8523_PSCTRL1,
+		snd_soc_component_update_bits(component, WM8523_PSCTRL1,
 				    WM8523_SYS_ENA_MASK, 0);
 		msleep(100);
 
@@ -397,35 +397,36 @@ static struct snd_soc_dai_driver wm8523_dai = {
 	.ops = &wm8523_dai_ops,
 };
 
-static int wm8523_probe(struct snd_soc_codec *codec)
+static int wm8523_probe(struct snd_soc_component *component)
 {
-	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+	struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 
 	wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
 	wm8523->rate_constraint.count =
 		ARRAY_SIZE(wm8523->rate_constraint_list);
 
 	/* Change some default settings - latch VU and enable ZC */
-	snd_soc_update_bits(codec, WM8523_DAC_GAINR,
+	snd_soc_component_update_bits(component, WM8523_DAC_GAINR,
 			    WM8523_DACR_VU, WM8523_DACR_VU);
-	snd_soc_update_bits(codec, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
+	snd_soc_component_update_bits(component, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
-	.probe =	wm8523_probe,
-	.set_bias_level = wm8523_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8523_controls,
-		.num_controls		= ARRAY_SIZE(wm8523_controls),
-		.dapm_widgets		= wm8523_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8523_dapm_widgets),
-		.dapm_routes		= wm8523_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8523_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8523 = {
+	.probe			= wm8523_probe,
+	.set_bias_level		= wm8523_set_bias_level,
+	.controls		= wm8523_controls,
+	.num_controls		= ARRAY_SIZE(wm8523_controls),
+	.dapm_widgets		= wm8523_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8523_dapm_widgets),
+	.dapm_routes		= wm8523_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8523_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8523_of_match[] = {
@@ -511,8 +512,8 @@ static int wm8523_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8523);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8523, &wm8523_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8523, &wm8523_dai, 1);
 
 	return ret;
 
@@ -521,12 +522,6 @@ static int wm8523_i2c_probe(struct i2c_client *i2c,
 	return ret;
 }
 
-static int wm8523_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8523_i2c_id[] = {
 	{ "wm8523", 0 },
 	{ }
@@ -539,7 +534,6 @@ static struct i2c_driver wm8523_i2c_driver = {
 		.of_match_table = wm8523_of_match,
 	},
 	.probe =    wm8523_i2c_probe,
-	.remove =   wm8523_i2c_remove,
 	.id_table = wm8523_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8524.c b/sound/soc/codecs/wm8524.c
index 856a695..fde444d 100644
--- a/sound/soc/codecs/wm8524.c
+++ b/sound/soc/codecs/wm8524.c
@@ -62,14 +62,14 @@ static const struct {
 static int wm8524_startup(struct snd_pcm_substream *substream,
 			  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
 
 	/* The set of sample rates that can be supported depends on the
 	 * MCLK supplied to the CODEC - enforce this.
 	 */
 	if (!wm8524->sysclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"No MCLK configured, call set_sysclk() on init\n");
 		return -EINVAL;
 	}
@@ -86,8 +86,8 @@ static int wm8524_startup(struct snd_pcm_substream *substream,
 static void wm8524_shutdown(struct snd_pcm_substream *substream,
 			  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
 
 	gpiod_set_value_cansleep(wm8524->mute, 0);
 }
@@ -95,8 +95,8 @@ static void wm8524_shutdown(struct snd_pcm_substream *substream,
 static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
 	unsigned int val;
 	int i, j = 0;
 
@@ -118,13 +118,13 @@ static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		case 96000:
 		case 176400:
 		case 192000:
-			dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
+			dev_dbg(component->dev, "Supported sample rate: %dHz\n",
 				val);
 			wm8524->rate_constraint_list[j++] = val;
 			wm8524->rate_constraint.count++;
 			break;
 		default:
-			dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
+			dev_dbg(component->dev, "Skipping sample rate: %dHz\n",
 				val);
 		}
 	}
@@ -152,7 +152,7 @@ static int wm8524_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int wm8524_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-	struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(dai->codec);
+	struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(dai->component);
 
 	if (wm8524->mute)
 		gpiod_set_value_cansleep(wm8524->mute, mute);
@@ -184,9 +184,9 @@ static struct snd_soc_dai_driver wm8524_dai = {
 	.ops = &wm8524_dai_ops,
 };
 
-static int wm8524_probe(struct snd_soc_codec *codec)
+static int wm8524_probe(struct snd_soc_component *component)
 {
-	struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec);
+	struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
 
 	wm8524->rate_constraint.list = &wm8524->rate_constraint_list[0];
 	wm8524->rate_constraint.count =
@@ -195,15 +195,16 @@ static int wm8524_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8524 = {
-	.probe =	wm8524_probe,
-
-	.component_driver = {
-		.dapm_widgets		= wm8524_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8524_dapm_widgets),
-		.dapm_routes		= wm8524_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8524_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8524 = {
+	.probe			= wm8524_probe,
+	.dapm_widgets		= wm8524_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8524_dapm_widgets),
+	.dapm_routes		= wm8524_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8524_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8524_of_match[] = {
@@ -231,23 +232,16 @@ static int wm8524_codec_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret =  snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_wm8524, &wm8524_dai, 1);
+	ret = devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_wm8524, &wm8524_dai, 1);
 	if (ret < 0)
-		dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
 
 	return ret;
 }
 
-static int wm8524_codec_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
 static struct platform_driver wm8524_codec_driver = {
 	.probe		= wm8524_codec_probe,
-	.remove		= wm8524_codec_remove,
 	.driver		= {
 		.name	= "wm8524-codec",
 		.of_match_table = wm8524_of_match,
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 910801d..fa4ad1b 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -262,8 +262,8 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
 	unsigned int reg = mc->reg;
 	unsigned int reg2 = mc->rreg;
 	int ret;
@@ -279,8 +279,8 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
 		return ret;
 
 	/* Now write again with the volume update bit set */
-	snd_soc_update_bits(codec, reg, 0x100, 0x100);
-	snd_soc_update_bits(codec, reg2, 0x100, 0x100);
+	snd_soc_component_update_bits(component, reg, 0x100, 0x100);
+	snd_soc_component_update_bits(component, reg2, 0x100, 0x100);
 
 	return 0;
 }
@@ -465,8 +465,8 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
 	int offset;
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
 	struct pll_state *state;
 	struct _pll_div pll_div;
 	unsigned int reg;
@@ -505,25 +505,25 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	/* Always disable the PLL - it is not safe to leave it running
 	 * while reprogramming it.
 	 */
-	snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, pwr_mask);
+	snd_soc_component_update_bits(component, WM8580_PWRDN2, pwr_mask, pwr_mask);
 
 	if (!freq_in || !freq_out)
 		return 0;
 
-	snd_soc_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
-	snd_soc_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff);
-	snd_soc_write(codec, WM8580_PLLA3 + offset,
+	snd_soc_component_write(component, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
+	snd_soc_component_write(component, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff);
+	snd_soc_component_write(component, WM8580_PLLA3 + offset,
 		     (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
 
-	reg = snd_soc_read(codec, WM8580_PLLA4 + offset);
+	reg = snd_soc_component_read32(component, WM8580_PLLA4 + offset);
 	reg &= ~0x1b;
 	reg |= pll_div.prescale | pll_div.postscale << 1 |
 		pll_div.freqmode << 3;
 
-	snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
+	snd_soc_component_write(component, WM8580_PLLA4 + offset, reg);
 
 	/* All done, turn it on */
-	snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, 0);
+	snd_soc_component_update_bits(component, WM8580_PWRDN2, pwr_mask, 0);
 
 	return 0;
 }
@@ -539,8 +539,8 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
 	u16 paifa = 0;
 	u16 paifb = 0;
 	int i, ratio, osr;
@@ -572,12 +572,12 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
 		if (ratio == wm8580_sysclk_ratios[i])
 			break;
 	if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {
-		dev_err(codec->dev, "Invalid clock ratio %d/%d\n",
+		dev_err(component->dev, "Invalid clock ratio %d/%d\n",
 			wm8580->sysclk[dai->driver->id], params_rate(params));
 		return -EINVAL;
 	}
 	paifa |= i;
-	dev_dbg(codec->dev, "Running at %dfs with %dHz clock\n",
+	dev_dbg(component->dev, "Running at %dfs with %dHz clock\n",
 		wm8580_sysclk_ratios[i], wm8580->sysclk[dai->driver->id]);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -585,21 +585,21 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
 		case 128:
 		case 192:
 			osr = WM8580_DACOSR;
-			dev_dbg(codec->dev, "Selecting 64x OSR\n");
+			dev_dbg(component->dev, "Selecting 64x OSR\n");
 			break;
 		default:
 			osr = 0;
-			dev_dbg(codec->dev, "Selecting 128x OSR\n");
+			dev_dbg(component->dev, "Selecting 128x OSR\n");
 			break;
 		}
 
-		snd_soc_update_bits(codec, WM8580_PAIF3, WM8580_DACOSR, osr);
+		snd_soc_component_update_bits(component, WM8580_PAIF3, WM8580_DACOSR, osr);
 	}
 
-	snd_soc_update_bits(codec, WM8580_PAIF1 + dai->driver->id,
+	snd_soc_component_update_bits(component, WM8580_PAIF1 + dai->driver->id,
 			    WM8580_AIF_RATE_MASK | WM8580_AIF_BCLKSEL_MASK,
 			    paifa);
-	snd_soc_update_bits(codec, WM8580_PAIF3 + dai->driver->id,
+	snd_soc_component_update_bits(component, WM8580_PAIF3 + dai->driver->id,
 			    WM8580_AIF_LENGTH_MASK, paifb);
 	return 0;
 }
@@ -607,13 +607,13 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
 static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
 				      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int aifa;
 	unsigned int aifb;
 	int can_invert_lrclk;
 
-	aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->driver->id);
-	aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->driver->id);
+	aifa = snd_soc_component_read32(component, WM8580_PAIF1 + codec_dai->driver->id);
+	aifb = snd_soc_component_read32(component, WM8580_PAIF3 + codec_dai->driver->id);
 
 	aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
 
@@ -679,8 +679,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8580_PAIF1 + codec_dai->driver->id, aifa);
-	snd_soc_write(codec, WM8580_PAIF3 + codec_dai->driver->id, aifb);
+	snd_soc_component_write(component, WM8580_PAIF1 + codec_dai->driver->id, aifa);
+	snd_soc_component_write(component, WM8580_PAIF3 + codec_dai->driver->id, aifb);
 
 	return 0;
 }
@@ -688,12 +688,12 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
 static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 				 int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int reg;
 
 	switch (div_id) {
 	case WM8580_MCLK:
-		reg = snd_soc_read(codec, WM8580_PLLB4);
+		reg = snd_soc_component_read32(component, WM8580_PLLB4);
 		reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
 
 		switch (div) {
@@ -715,11 +715,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		default:
 			return -EINVAL;
 		}
-		snd_soc_write(codec, WM8580_PLLB4, reg);
+		snd_soc_component_write(component, WM8580_PLLB4, reg);
 		break;
 
 	case WM8580_CLKOUTSRC:
-		reg = snd_soc_read(codec, WM8580_PLLB4);
+		reg = snd_soc_component_read32(component, WM8580_PLLB4);
 		reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
 
 		switch (div) {
@@ -741,7 +741,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		default:
 			return -EINVAL;
 		}
-		snd_soc_write(codec, WM8580_PLLB4, reg);
+		snd_soc_component_write(component, WM8580_PLLB4, reg);
 		break;
 
 	default:
@@ -754,8 +754,8 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 			     unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
 	int ret, sel, sel_mask, sel_shift;
 
 	switch (dai->driver->id) {
@@ -790,14 +790,14 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 		sel = 3 << sel_shift;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown clock %d\n", clk_id);
+		dev_err(component->dev, "Unknown clock %d\n", clk_id);
 		return -EINVAL;
 	}
 
 	/* We really should validate PLL settings but not yet */
 	wm8580->sysclk[dai->driver->id] = freq;
 
-	ret = snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
+	ret = snd_soc_component_update_bits(component, WM8580_CLKSEL, sel_mask, sel);
 	if (ret < 0)
 		return ret;
 
@@ -806,22 +806,22 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 
 static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, WM8580_DAC_CONTROL5);
+	reg = snd_soc_component_read32(component, WM8580_DAC_CONTROL5);
 
 	if (mute)
 		reg |= WM8580_DAC_CONTROL5_MUTEALL;
 	else
 		reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
 
-	snd_soc_write(codec, WM8580_DAC_CONTROL5, reg);
+	snd_soc_component_write(component, WM8580_DAC_CONTROL5, reg);
 
 	return 0;
 }
 
-static int wm8580_set_bias_level(struct snd_soc_codec *codec,
+static int wm8580_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
 	switch (level) {
@@ -830,20 +830,20 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Power up and get individual control of the DACs */
-			snd_soc_update_bits(codec, WM8580_PWRDN1,
+			snd_soc_component_update_bits(component, WM8580_PWRDN1,
 					    WM8580_PWRDN1_PWDN |
 					    WM8580_PWRDN1_ALLDACPD, 0);
 
 			/* Make VMID high impedance */
-			snd_soc_update_bits(codec, WM8580_ADC_CONTROL1,
+			snd_soc_component_update_bits(component, WM8580_ADC_CONTROL1,
 					    0x100, 0);
 		}
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, WM8580_PWRDN1,
+		snd_soc_component_update_bits(component, WM8580_PWRDN1,
 				    WM8580_PWRDN1_PWDN, WM8580_PWRDN1_PWDN);
 		break;
 	}
@@ -853,8 +853,8 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
 static int wm8580_playback_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
 
 	return snd_pcm_hw_constraint_minmax(substream->runtime,
 		SNDRV_PCM_HW_PARAM_CHANNELS, 1, wm8580->drvdata->num_dacs * 2);
@@ -907,15 +907,15 @@ static struct snd_soc_dai_driver wm8580_dai[] = {
 	},
 };
 
-static int wm8580_probe(struct snd_soc_codec *codec)
+static int wm8580_probe(struct snd_soc_component *component)
 {
-	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int ret = 0;
 
 	switch (wm8580->drvdata->num_dacs) {
 	case 4:
-		snd_soc_add_codec_controls(codec, wm8581_snd_controls,
+		snd_soc_add_component_controls(component, wm8581_snd_controls,
 					ARRAY_SIZE(wm8581_snd_controls));
 		snd_soc_dapm_new_controls(dapm, wm8581_dapm_widgets,
 					ARRAY_SIZE(wm8581_dapm_widgets));
@@ -929,14 +929,14 @@ static int wm8580_probe(struct snd_soc_codec *codec)
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
 				    wm8580->supplies);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		goto err_regulator_get;
 	}
 
 	/* Get the codec into a known state */
-	ret = snd_soc_write(codec, WM8580_RESET, 0);
+	ret = snd_soc_component_write(component, WM8580_RESET, 0);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
+		dev_err(component->dev, "Failed to reset component: %d\n", ret);
 		goto err_regulator_enable;
 	}
 
@@ -949,28 +949,27 @@ static int wm8580_probe(struct snd_soc_codec *codec)
 }
 
 /* power down chip */
-static int wm8580_remove(struct snd_soc_codec *codec)
+static void wm8580_remove(struct snd_soc_component *component)
 {
-	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
 
 	regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
-	.probe =	wm8580_probe,
-	.remove =	wm8580_remove,
-	.set_bias_level = wm8580_set_bias_level,
-
-	.component_driver = {
-		.controls		= wm8580_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8580_snd_controls),
-		.dapm_widgets		= wm8580_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8580_dapm_widgets),
-		.dapm_routes		= wm8580_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8580_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8580 = {
+	.probe			= wm8580_probe,
+	.remove			= wm8580_remove,
+	.set_bias_level		= wm8580_set_bias_level,
+	.controls		= wm8580_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8580_snd_controls),
+	.dapm_widgets		= wm8580_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8580_dapm_widgets),
+	.dapm_routes		= wm8580_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8580_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8580_regmap = {
@@ -1037,18 +1036,12 @@ static int wm8580_i2c_probe(struct i2c_client *i2c,
 		return -EINVAL;
 	}
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
 
 	return ret;
 }
 
-static int wm8580_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8580_i2c_id[] = {
 	{ "wm8580", (kernel_ulong_t)&wm8580_data },
 	{ "wm8581", (kernel_ulong_t)&wm8581_data },
@@ -1062,7 +1055,6 @@ static struct i2c_driver wm8580_i2c_driver = {
 		.of_match_table = wm8580_of_match,
 	},
 	.probe =    wm8580_i2c_probe,
-	.remove =   wm8580_i2c_remove,
 	.id_table = wm8580_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 2b376c9..1da08d2 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -58,7 +58,7 @@ static bool wm8711_volatile(struct device *dev, unsigned int reg)
 	}
 }
 
-#define wm8711_reset(c)	snd_soc_write(c, WM8711_RESET, 0)
+#define wm8711_reset(c)	snd_soc_component_write(c, WM8711_RESET, 0)
 
 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
 
@@ -159,14 +159,14 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8711_priv *wm8711 =  snd_soc_codec_get_drvdata(codec);
-	u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfff3;
+	struct snd_soc_component *component = dai->component;
+	struct wm8711_priv *wm8711 =  snd_soc_component_get_drvdata(component);
+	u16 iface = snd_soc_component_read32(component, WM8711_IFACE) & 0xfff3;
 	int i = get_coeff(wm8711->sysclk, params_rate(params));
 	u16 srate = (coeff_div[i].sr << 2) |
 		(coeff_div[i].bosr << 1) | coeff_div[i].usb;
 
-	snd_soc_write(codec, WM8711_SRATE, srate);
+	snd_soc_component_write(component, WM8711_SRATE, srate);
 
 	/* bit size */
 	switch (params_width(params)) {
@@ -180,17 +180,17 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8711_IFACE, iface);
+	snd_soc_component_write(component, WM8711_IFACE, iface);
 	return 0;
 }
 
 static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
 			      struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	/* set active */
-	snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
+	snd_soc_component_write(component, WM8711_ACTIVE, 0x0001);
 
 	return 0;
 }
@@ -198,24 +198,24 @@ static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
 static void wm8711_shutdown(struct snd_pcm_substream *substream,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	/* deactivate */
-	if (!snd_soc_codec_is_active(codec)) {
+	if (!snd_soc_component_is_active(component)) {
 		udelay(50);
-		snd_soc_write(codec, WM8711_ACTIVE, 0x0);
+		snd_soc_component_write(component, WM8711_ACTIVE, 0x0);
 	}
 }
 
 static int wm8711_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8711_APDIGI) & 0xfff7;
 
 	if (mute)
-		snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
+		snd_soc_component_write(component, WM8711_APDIGI, mute_reg | 0x8);
 	else
-		snd_soc_write(codec, WM8711_APDIGI, mute_reg);
+		snd_soc_component_write(component, WM8711_APDIGI, mute_reg);
 
 	return 0;
 }
@@ -223,8 +223,8 @@ static int wm8711_mute(struct snd_soc_dai *dai, int mute)
 static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8711_priv *wm8711 =  snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8711_priv *wm8711 =  snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case 11289600:
@@ -241,8 +241,8 @@ static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0x000c;
+	struct snd_soc_component *component = codec_dai->component;
+	u16 iface = snd_soc_component_read32(component, WM8711_IFACE) & 0x000c;
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -293,31 +293,31 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	}
 
 	/* set iface */
-	snd_soc_write(codec, WM8711_IFACE, iface);
+	snd_soc_component_write(component, WM8711_IFACE, iface);
 	return 0;
 }
 
-static int wm8711_set_bias_level(struct snd_soc_codec *codec,
+static int wm8711_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
-	u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
+	struct wm8711_priv *wm8711 = snd_soc_component_get_drvdata(component);
+	u16 reg = snd_soc_component_read32(component, WM8711_PWR) & 0xff7f;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		snd_soc_write(codec, WM8711_PWR, reg);
+		snd_soc_component_write(component, WM8711_PWR, reg);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			regcache_sync(wm8711->regmap);
 
-		snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
+		snd_soc_component_write(component, WM8711_PWR, reg | 0x0040);
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, WM8711_ACTIVE, 0x0);
-		snd_soc_write(codec, WM8711_PWR, 0xffff);
+		snd_soc_component_write(component, WM8711_ACTIVE, 0x0);
+		snd_soc_component_write(component, WM8711_PWR, 0xffff);
 		break;
 	}
 	return 0;
@@ -349,37 +349,38 @@ static struct snd_soc_dai_driver wm8711_dai = {
 	.ops = &wm8711_ops,
 };
 
-static int wm8711_probe(struct snd_soc_codec *codec)
+static int wm8711_probe(struct snd_soc_component *component)
 {
 	int ret;
 
-	ret = wm8711_reset(codec);
+	ret = wm8711_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
+		dev_err(component->dev, "Failed to issue reset\n");
 		return ret;
 	}
 
 	/* Latch the update bits */
-	snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8711_LOUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8711_ROUT1V, 0x0100, 0x0100);
 
 	return ret;
 
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
-	.probe =	wm8711_probe,
-	.set_bias_level = wm8711_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8711_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8711_snd_controls),
-		.dapm_widgets		= wm8711_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8711_dapm_widgets),
-		.dapm_routes		= wm8711_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(wm8711_intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8711 = {
+	.probe			= wm8711_probe,
+	.set_bias_level		= wm8711_set_bias_level,
+	.controls		= wm8711_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8711_snd_controls),
+	.dapm_widgets		= wm8711_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8711_dapm_widgets),
+	.dapm_routes		= wm8711_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(wm8711_intercon),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8711_of_match[] = {
@@ -417,26 +418,18 @@ static int wm8711_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8711);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8711, &wm8711_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8711, &wm8711_dai, 1);
 
 	return ret;
 }
 
-static int wm8711_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-
-	return 0;
-}
-
 static struct spi_driver wm8711_spi_driver = {
 	.driver = {
 		.name	= "wm8711",
 		.of_match_table = wm8711_of_match,
 	},
 	.probe		= wm8711_spi_probe,
-	.remove		= wm8711_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -458,18 +451,12 @@ static int wm8711_i2c_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, wm8711);
 
-	ret =  snd_soc_register_codec(&client->dev,
-			&soc_codec_dev_wm8711, &wm8711_dai, 1);
+	ret = devm_snd_soc_register_component(&client->dev,
+			&soc_component_dev_wm8711, &wm8711_dai, 1);
 
 	return ret;
 }
 
-static int wm8711_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8711_i2c_id[] = {
 	{ "wm8711", 0 },
 	{ }
@@ -482,7 +469,6 @@ static struct i2c_driver wm8711_i2c_driver = {
 		.of_match_table = wm8711_of_match,
 	},
 	.probe =    wm8711_i2c_probe,
-	.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 7fde077..087ec6d 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -19,7 +19,6 @@
 #include <linux/device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/ac97_codec.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
 
@@ -41,7 +40,6 @@ static const struct snd_soc_dapm_route wm8727_dapm_routes[] = {
 			SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
 			SNDRV_PCM_RATE_192000)
 
-
 static struct snd_soc_dai_driver wm8727_dai = {
 	.name = "wm8727-hifi",
 	.playback = {
@@ -53,25 +51,21 @@ static struct snd_soc_dai_driver wm8727_dai = {
 		},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8727 = {
-	.component_driver = {
-		.dapm_widgets		= wm8727_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8727_dapm_widgets),
-		.dapm_routes		= wm8727_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8727_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8727 = {
+	.dapm_widgets		= wm8727_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8727_dapm_widgets),
+	.dapm_routes		= wm8727_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8727_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8727_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_wm8727, &wm8727_dai, 1);
-}
-
-static int wm8727_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_wm8727, &wm8727_dai, 1);
 }
 
 static struct platform_driver wm8727_codec_driver = {
@@ -80,7 +74,6 @@ static struct platform_driver wm8727_codec_driver = {
 	},
 
 	.probe = wm8727_probe,
-	.remove = wm8727_remove,
 };
 
 module_platform_driver(wm8727_codec_driver);
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 797cc6e..839aee3 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -74,13 +74,13 @@ static const struct snd_soc_dapm_route wm8728_intercon[] = {
 
 static int wm8728_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8728_DACCTL);
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8728_DACCTL);
 
 	if (mute)
-		snd_soc_write(codec, WM8728_DACCTL, mute_reg | 1);
+		snd_soc_component_write(component, WM8728_DACCTL, mute_reg | 1);
 	else
-		snd_soc_write(codec, WM8728_DACCTL, mute_reg & ~1);
+		snd_soc_component_write(component, WM8728_DACCTL, mute_reg & ~1);
 
 	return 0;
 }
@@ -89,8 +89,8 @@ static int wm8728_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;
-	u16 dac = snd_soc_read(codec, WM8728_DACCTL);
+	struct snd_soc_component *component = dai->component;
+	u16 dac = snd_soc_component_read32(component, WM8728_DACCTL);
 
 	dac &= ~0x18;
 
@@ -107,7 +107,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8728_DACCTL, dac);
+	snd_soc_component_write(component, WM8728_DACCTL, dac);
 
 	return 0;
 }
@@ -115,8 +115,8 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
 static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 iface = snd_soc_read(codec, WM8728_IFCTL);
+	struct snd_soc_component *component = codec_dai->component;
+	u16 iface = snd_soc_component_read32(component, WM8728_IFCTL);
 
 	/* Currently only I2S is supported by the driver, though the
 	 * hardware is more flexible.
@@ -156,24 +156,24 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8728_IFCTL, iface);
+	snd_soc_component_write(component, WM8728_IFCTL, iface);
 	return 0;
 }
 
-static int wm8728_set_bias_level(struct snd_soc_codec *codec,
+static int wm8728_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
+	struct wm8728_priv *wm8728 = snd_soc_component_get_drvdata(component);
 	u16 reg;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Power everything up... */
-			reg = snd_soc_read(codec, WM8728_DACCTL);
-			snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
+			reg = snd_soc_component_read32(component, WM8728_DACCTL);
+			snd_soc_component_write(component, WM8728_DACCTL, reg & ~0x4);
 
 			/* ..then sync in the register cache. */
 			regcache_sync(wm8728->regmap);
@@ -181,8 +181,8 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		reg = snd_soc_read(codec, WM8728_DACCTL);
-		snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
+		reg = snd_soc_component_read32(component, WM8728_DACCTL);
+		snd_soc_component_write(component, WM8728_DACCTL, reg | 0x4);
 		break;
 	}
 	return 0;
@@ -211,18 +211,19 @@ static struct snd_soc_dai_driver wm8728_dai = {
 	.ops = &wm8728_dai_ops,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
-	.set_bias_level = wm8728_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8728_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8728_snd_controls),
-		.dapm_widgets		= wm8728_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8728_dapm_widgets),
-		.dapm_routes		= wm8728_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(wm8728_intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8728 = {
+	.set_bias_level		= wm8728_set_bias_level,
+	.controls		= wm8728_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8728_snd_controls),
+	.dapm_widgets		= wm8728_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8728_dapm_widgets),
+	.dapm_routes		= wm8728_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(wm8728_intercon),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8728_of_match[] = {
@@ -258,26 +259,18 @@ static int wm8728_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8728);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8728, &wm8728_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8728, &wm8728_dai, 1);
 
 	return ret;
 }
 
-static int wm8728_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-
-	return 0;
-}
-
 static struct spi_driver wm8728_spi_driver = {
 	.driver = {
 		.name	= "wm8728",
 		.of_match_table = wm8728_of_match,
 	},
 	.probe		= wm8728_spi_probe,
-	.remove		= wm8728_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -299,18 +292,12 @@ static int wm8728_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8728);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8728, &wm8728_dai, 1);
+	ret =  devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8728, &wm8728_dai, 1);
 
 	return ret;
 }
 
-static int wm8728_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8728_i2c_id[] = {
 	{ "wm8728", 0 },
 	{ }
@@ -323,7 +310,6 @@ static struct i2c_driver wm8728_i2c_driver = {
 		.of_match_table = wm8728_of_match,
 	},
 	.probe =    wm8728_i2c_probe,
-	.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 4f9a1eb..7c8fad8 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -88,9 +88,9 @@ static SOC_ENUM_SINGLE_DECL(wm8731_insel_enum,
 
 static int wm8731_deemph[] = { 0, 32000, 44100, 48000 };
 
-static int wm8731_set_deemph(struct snd_soc_codec *codec)
+static int wm8731_set_deemph(struct snd_soc_component *component)
 {
-	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 	int val, i, best;
 
 	/* If we're using deemphasis select the nearest available sample
@@ -110,17 +110,17 @@ static int wm8731_set_deemph(struct snd_soc_codec *codec)
 		val = 0;
 	}
 
-	dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
+	dev_dbg(component->dev, "Set deemphasis %d (%dHz)\n",
 		best, wm8731_deemph[best]);
 
-	return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val);
+	return snd_soc_component_update_bits(component, WM8731_APDIGI, 0x6, val);
 }
 
 static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = wm8731->deemph;
 
@@ -130,8 +130,8 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
 static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 	unsigned int deemph = ucontrol->value.integer.value[0];
 	int ret = 0;
 
@@ -142,7 +142,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
 	if (wm8731->deemph != deemph) {
 		wm8731->deemph = deemph;
 
-		wm8731_set_deemph(codec);
+		wm8731_set_deemph(component);
 
 		ret = 1;
 	}
@@ -214,8 +214,8 @@ SND_SOC_DAPM_INPUT("LLINEIN"),
 static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
 			    struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 
 	return wm8731->sysclk_type == WM8731_SYSCLK_XTAL;
 }
@@ -337,16 +337,16 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
-	u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
+	struct snd_soc_component *component = dai->component;
+	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
+	u16 iface = snd_soc_component_read32(component, WM8731_IFACE) & 0xfff3;
 	int i = get_coeff(wm8731->sysclk, params_rate(params));
 	u16 srate = (coeff_div[i].sr << 2) |
 		(coeff_div[i].bosr << 1) | coeff_div[i].usb;
 
 	wm8731->playback_fs = params_rate(params);
 
-	snd_soc_write(codec, WM8731_SRATE, srate);
+	snd_soc_component_write(component, WM8731_SRATE, srate);
 
 	/* bit size */
 	switch (params_width(params)) {
@@ -363,30 +363,30 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	wm8731_set_deemph(codec);
+	wm8731_set_deemph(component);
 
-	snd_soc_write(codec, WM8731_IFACE, iface);
+	snd_soc_component_write(component, WM8731_IFACE, iface);
 	return 0;
 }
 
 static int wm8731_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8731_APDIGI) & 0xfff7;
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8731_APDIGI) & 0xfff7;
 
 	if (mute)
-		snd_soc_write(codec, WM8731_APDIGI, mute_reg | 0x8);
+		snd_soc_component_write(component, WM8731_APDIGI, mute_reg | 0x8);
 	else
-		snd_soc_write(codec, WM8731_APDIGI, mute_reg);
+		snd_soc_component_write(component, WM8731_APDIGI, mute_reg);
 	return 0;
 }
 
 static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case WM8731_SYSCLK_XTAL:
@@ -429,7 +429,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
 
 	/* set master/slave audio interface */
@@ -481,14 +481,14 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	}
 
 	/* set iface */
-	snd_soc_write(codec, WM8731_IFACE, iface);
+	snd_soc_component_write(component, WM8731_IFACE, iface);
 	return 0;
 }
 
-static int wm8731_set_bias_level(struct snd_soc_codec *codec,
+static int wm8731_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 	int ret;
 	u16 reg;
 
@@ -503,7 +503,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
 						    wm8731->supplies);
 			if (ret != 0)
@@ -513,13 +513,13 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 		}
 
 		/* Clear PWROFF, gate CLKOUT, everything else as-is */
-		reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
-		snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
+		reg = snd_soc_component_read32(component, WM8731_PWR) & 0xff7f;
+		snd_soc_component_write(component, WM8731_PWR, reg | 0x0040);
 		break;
 	case SND_SOC_BIAS_OFF:
 		if (wm8731->mclk)
 			clk_disable_unprepare(wm8731->mclk);
-		snd_soc_write(codec, WM8731_PWR, 0xffff);
+		snd_soc_component_write(component, WM8731_PWR, 0xffff);
 		regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
 				       wm8731->supplies);
 		regcache_mark_dirty(wm8731->regmap);
@@ -531,7 +531,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 static int wm8731_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
-	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(dai->codec);
+	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(dai->component);
 
 	if (wm8731->constraints)
 		snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -628,18 +628,19 @@ static int wm8731_hw_init(struct device *dev, struct wm8731_priv *wm8731)
 	return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
-	.set_bias_level = wm8731_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8731_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8731_snd_controls),
-		.dapm_widgets		= wm8731_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8731_dapm_widgets),
-		.dapm_routes		= wm8731_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(wm8731_intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8731 = {
+	.set_bias_level		= wm8731_set_bias_level,
+	.controls		= wm8731_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8731_snd_controls),
+	.dapm_widgets		= wm8731_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8731_dapm_widgets),
+	.dapm_routes		= wm8731_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(wm8731_intercon),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8731_of_match[] = {
@@ -704,8 +705,8 @@ static int wm8731_spi_probe(struct spi_device *spi)
 	if (ret != 0)
 		return ret;
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8731, &wm8731_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8731, &wm8731_dai, 1);
 	if (ret != 0) {
 		dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
 		return ret;
@@ -716,7 +717,6 @@ static int wm8731_spi_probe(struct spi_device *spi)
 
 static int wm8731_spi_remove(struct spi_device *spi)
 {
-	snd_soc_unregister_codec(&spi->dev);
 	return 0;
 }
 
@@ -775,8 +775,8 @@ static int wm8731_i2c_probe(struct i2c_client *i2c,
 	if (ret != 0)
 		return ret;
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8731, &wm8731_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8731, &wm8731_dai, 1);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
 		return ret;
@@ -787,7 +787,6 @@ static int wm8731_i2c_probe(struct i2c_client *i2c,
 
 static int wm8731_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index f0cb1c4..e9ae821e 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -74,9 +74,9 @@ static bool wm8737_volatile(struct device *dev, unsigned int reg)
 	}
 }
 
-static int wm8737_reset(struct snd_soc_codec *codec)
+static int wm8737_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, WM8737_RESET, 0);
+	return snd_soc_component_write(component, WM8737_RESET, 0);
 }
 
 static const DECLARE_TLV_DB_RANGE(micboost_tlv,
@@ -328,8 +328,8 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component);
 	int i;
 	u16 clocking = 0;
 	u16 af = 0;
@@ -348,7 +348,7 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (i == ARRAY_SIZE(coeff_div)) {
-		dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
+		dev_err(component->dev, "%dHz MCLK can't support %dHz\n",
 			wm8737->mclk, params_rate(params));
 		return -EINVAL;
 	}
@@ -371,8 +371,8 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
-	snd_soc_update_bits(codec, WM8737_CLOCKING,
+	snd_soc_component_update_bits(component, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
+	snd_soc_component_update_bits(component, WM8737_CLOCKING,
 			    WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
 			    clocking);
 
@@ -382,8 +382,8 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
 static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
@@ -394,7 +394,7 @@ static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		}
 	}
 
-	dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
+	dev_err(component->dev, "MCLK rate %dHz not supported\n", freq);
 
 	return -EINVAL;
 }
@@ -403,7 +403,7 @@ static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 af = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -445,16 +445,16 @@ static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
+	snd_soc_component_update_bits(component, WM8737_AUDIO_FORMAT,
 			    WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
 
 	return 0;
 }
 
-static int wm8737_set_bias_level(struct snd_soc_codec *codec,
+static int wm8737_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+	struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -463,16 +463,16 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID at 2*75k */
-		snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+		snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL,
 				    WM8737_VMIDSEL_MASK, 0);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
 						    wm8737->supplies);
 			if (ret != 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n",
 					ret);
 				return ret;
@@ -481,12 +481,12 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec,
 			regcache_sync(wm8737->regmap);
 
 			/* Fast VMID ramp at 2*2.5k */
-			snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+			snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL,
 					    WM8737_VMIDSEL_MASK,
 					    2 << WM8737_VMIDSEL_SHIFT);
 
 			/* Bring VMID up */
-			snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
+			snd_soc_component_update_bits(component, WM8737_POWER_MANAGEMENT,
 					    WM8737_VMID_MASK |
 					    WM8737_VREF_MASK,
 					    WM8737_VMID_MASK |
@@ -496,14 +496,14 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec,
 		}
 
 		/* VMID at 2*300k */
-		snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+		snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL,
 				    WM8737_VMIDSEL_MASK,
 				    1 << WM8737_VMIDSEL_SHIFT);
 
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
+		snd_soc_component_update_bits(component, WM8737_POWER_MANAGEMENT,
 				    WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
 
 		regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
@@ -537,30 +537,30 @@ static struct snd_soc_dai_driver wm8737_dai = {
 	.ops = &wm8737_dai_ops,
 };
 
-static int wm8737_probe(struct snd_soc_codec *codec)
+static int wm8737_probe(struct snd_soc_component *component)
 {
-	struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+	struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
 				    wm8737->supplies);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		goto err_get;
 	}
 
-	ret = wm8737_reset(codec);
+	ret = wm8737_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
+		dev_err(component->dev, "Failed to issue reset\n");
 		goto err_enable;
 	}
 
-	snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
+	snd_soc_component_update_bits(component, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
 			    WM8737_LVU);
-	snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
+	snd_soc_component_update_bits(component, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
 			    WM8737_RVU);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	/* Bias level configuration will have done an extra enable */
 	regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
@@ -573,19 +573,20 @@ static int wm8737_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
-	.probe		= wm8737_probe,
-	.set_bias_level = wm8737_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8737_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8737_snd_controls),
-		.dapm_widgets		= wm8737_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8737_dapm_widgets),
-		.dapm_routes		= intercon,
-		.num_dapm_routes	= ARRAY_SIZE(intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8737 = {
+	.probe			= wm8737_probe,
+	.set_bias_level		= wm8737_set_bias_level,
+	.controls		= wm8737_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8737_snd_controls),
+	.dapm_widgets		= wm8737_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8737_dapm_widgets),
+	.dapm_routes		= intercon,
+	.num_dapm_routes	= ARRAY_SIZE(intercon),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8737_of_match[] = {
@@ -635,20 +636,13 @@ static int wm8737_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8737);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-				      &soc_codec_dev_wm8737, &wm8737_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				&soc_component_dev_wm8737, &wm8737_dai, 1);
 
 	return ret;
 
 }
 
-static int wm8737_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm8737_i2c_id[] = {
 	{ "wm8737", 0 },
 	{ }
@@ -661,7 +655,6 @@ static struct i2c_driver wm8737_i2c_driver = {
 		.of_match_table = wm8737_of_match,
 	},
 	.probe =    wm8737_i2c_probe,
-	.remove =   wm8737_i2c_remove,
 	.id_table = wm8737_i2c_id,
 };
 #endif
@@ -693,26 +686,18 @@ static int wm8737_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8737);
 
-	ret = snd_soc_register_codec(&spi->dev,
-				     &soc_codec_dev_wm8737, &wm8737_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+				&soc_component_dev_wm8737, &wm8737_dai, 1);
 
 	return ret;
 }
 
-static int wm8737_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-
-	return 0;
-}
-
 static struct spi_driver wm8737_spi_driver = {
 	.driver = {
 		.name	= "wm8737",
 		.of_match_table = wm8737_of_match,
 	},
 	.probe		= wm8737_spi_probe,
-	.remove		= wm8737_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index a394dbe..1fedf74 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -59,9 +59,9 @@ static const struct reg_default wm8741_reg_defaults[] = {
 	{ 32, 0x0002 },     /* R32 - ADDITONAL_CONTROL_1 */
 };
 
-static int wm8741_reset(struct snd_soc_codec *codec)
+static int wm8741_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, WM8741_RESET, 0);
+	return snd_soc_component_write(component, WM8741_RESET, 0);
 }
 
 static const DECLARE_TLV_DB_SCALE(dac_tlv_fine, -12700, 13, 0);
@@ -179,8 +179,8 @@ static const struct snd_pcm_hw_constraint_list constraints_36864 = {
 static int wm8741_startup(struct snd_pcm_substream *substream,
 			  struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
 	if (wm8741->sysclk)
 		snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -194,8 +194,8 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 	unsigned int iface;
 	int i;
 
@@ -203,7 +203,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
 	 * MCLK supplied to the CODEC - enforce this.
 	 */
 	if (!wm8741->sysclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"No MCLK configured, call set_sysclk() on init or in hw_params\n");
 		return -EINVAL;
 	}
@@ -215,7 +215,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (i == wm8741->sysclk_constraints->count) {
-		dev_err(codec->dev, "LRCLK %d unsupported with MCLK %d\n",
+		dev_err(component->dev, "LRCLK %d unsupported with MCLK %d\n",
 			params_rate(params), wm8741->sysclk);
 		return -EINVAL;
 	}
@@ -235,15 +235,15 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
 		iface = 0x3;
 		break;
 	default:
-		dev_dbg(codec->dev, "wm8741_hw_params:    Unsupported bit size param = %d",
+		dev_dbg(component->dev, "wm8741_hw_params:    Unsupported bit size param = %d",
 			params_width(params));
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "wm8741_hw_params:    bit size param = %d, rate param = %d",
+	dev_dbg(component->dev, "wm8741_hw_params:    bit size param = %d, rate param = %d",
 		params_width(params), params_rate(params));
 
-	snd_soc_update_bits(codec, WM8741_FORMAT_CONTROL, WM8741_IWL_MASK,
+	snd_soc_component_update_bits(component, WM8741_FORMAT_CONTROL, WM8741_IWL_MASK,
 			    iface);
 
 	return 0;
@@ -252,10 +252,10 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
 static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
+	dev_dbg(component->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
 
 	switch (freq) {
 	case 0:
@@ -297,7 +297,7 @@ static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int iface;
 
 	/* check master/slave audio interface */
@@ -347,11 +347,11 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	}
 
 
-	dev_dbg(codec->dev, "wm8741_set_dai_fmt:    Format=%x, Clock Inv=%x\n",
+	dev_dbg(component->dev, "wm8741_set_dai_fmt:    Format=%x, Clock Inv=%x\n",
 				fmt & SND_SOC_DAIFMT_FORMAT_MASK,
 				((fmt & SND_SOC_DAIFMT_INV_MASK)));
 
-	snd_soc_update_bits(codec, WM8741_FORMAT_CONTROL,
+	snd_soc_component_update_bits(component, WM8741_FORMAT_CONTROL,
 			    WM8741_BCP_MASK | WM8741_LRP_MASK | WM8741_FMT_MASK,
 			    iface);
 
@@ -386,18 +386,18 @@ static struct snd_soc_dai_driver wm8741_dai = {
 };
 
 #ifdef CONFIG_PM
-static int wm8741_resume(struct snd_soc_codec *codec)
+static int wm8741_resume(struct snd_soc_component *component)
 {
-	snd_soc_cache_sync(codec);
+	snd_soc_component_cache_sync(component);
 	return 0;
 }
 #else
 #define wm8741_resume NULL
 #endif
 
-static int wm8741_configure(struct snd_soc_codec *codec)
+static int wm8741_configure(struct snd_soc_component *component)
 {
-	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
 	/* Configure differential mode */
 	switch (wm8741->pdata.diff_mode) {
@@ -405,7 +405,7 @@ static int wm8741_configure(struct snd_soc_codec *codec)
 	case WM8741_DIFF_MODE_STEREO_REVERSED:
 	case WM8741_DIFF_MODE_MONO_LEFT:
 	case WM8741_DIFF_MODE_MONO_RIGHT:
-		snd_soc_update_bits(codec, WM8741_MODE_CONTROL_2,
+		snd_soc_component_update_bits(component, WM8741_MODE_CONTROL_2,
 				WM8741_DIFF_MASK,
 				wm8741->pdata.diff_mode << WM8741_DIFF_SHIFT);
 		break;
@@ -414,36 +414,36 @@ static int wm8741_configure(struct snd_soc_codec *codec)
 	}
 
 	/* Change some default settings - latch VU */
-	snd_soc_update_bits(codec, WM8741_DACLLSB_ATTENUATION,
+	snd_soc_component_update_bits(component, WM8741_DACLLSB_ATTENUATION,
 			WM8741_UPDATELL, WM8741_UPDATELL);
-	snd_soc_update_bits(codec, WM8741_DACLMSB_ATTENUATION,
+	snd_soc_component_update_bits(component, WM8741_DACLMSB_ATTENUATION,
 			WM8741_UPDATELM, WM8741_UPDATELM);
-	snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
+	snd_soc_component_update_bits(component, WM8741_DACRLSB_ATTENUATION,
 			WM8741_UPDATERL, WM8741_UPDATERL);
-	snd_soc_update_bits(codec, WM8741_DACRMSB_ATTENUATION,
+	snd_soc_component_update_bits(component, WM8741_DACRMSB_ATTENUATION,
 			WM8741_UPDATERM, WM8741_UPDATERM);
 
 	return 0;
 }
 
-static int wm8741_add_controls(struct snd_soc_codec *codec)
+static int wm8741_add_controls(struct snd_soc_component *component)
 {
-	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
 	switch (wm8741->pdata.diff_mode) {
 	case WM8741_DIFF_MODE_STEREO:
 	case WM8741_DIFF_MODE_STEREO_REVERSED:
-		snd_soc_add_codec_controls(codec,
+		snd_soc_add_component_controls(component,
 				wm8741_snd_controls_stereo,
 				ARRAY_SIZE(wm8741_snd_controls_stereo));
 		break;
 	case WM8741_DIFF_MODE_MONO_LEFT:
-		snd_soc_add_codec_controls(codec,
+		snd_soc_add_component_controls(component,
 				wm8741_snd_controls_mono_left,
 				ARRAY_SIZE(wm8741_snd_controls_mono_left));
 		break;
 	case WM8741_DIFF_MODE_MONO_RIGHT:
-		snd_soc_add_codec_controls(codec,
+		snd_soc_add_component_controls(component,
 				wm8741_snd_controls_mono_right,
 				ARRAY_SIZE(wm8741_snd_controls_mono_right));
 		break;
@@ -454,37 +454,37 @@ static int wm8741_add_controls(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int wm8741_probe(struct snd_soc_codec *codec)
+static int wm8741_probe(struct snd_soc_component *component)
 {
-	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
 				    wm8741->supplies);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		goto err_get;
 	}
 
-	ret = wm8741_reset(codec);
+	ret = wm8741_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
+		dev_err(component->dev, "Failed to issue reset\n");
 		goto err_enable;
 	}
 
-	ret = wm8741_configure(codec);
+	ret = wm8741_configure(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to change default settings\n");
+		dev_err(component->dev, "Failed to change default settings\n");
 		goto err_enable;
 	}
 
-	ret = wm8741_add_controls(codec);
+	ret = wm8741_add_controls(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to add controls\n");
+		dev_err(component->dev, "Failed to add controls\n");
 		goto err_enable;
 	}
 
-	dev_dbg(codec->dev, "Successful registration\n");
+	dev_dbg(component->dev, "Successful registration\n");
 	return ret;
 
 err_enable:
@@ -493,26 +493,25 @@ static int wm8741_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static int wm8741_remove(struct snd_soc_codec *codec)
+static void wm8741_remove(struct snd_soc_component *component)
 {
-	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
 	regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
-	.probe =	wm8741_probe,
-	.remove =	wm8741_remove,
-	.resume =	wm8741_resume,
-
-	.component_driver = {
-		.dapm_widgets		= wm8741_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8741_dapm_widgets),
-		.dapm_routes		= wm8741_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8741_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8741 = {
+	.probe			= wm8741_probe,
+	.remove			= wm8741_remove,
+	.resume			= wm8741_resume,
+	.dapm_widgets		= wm8741_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8741_dapm_widgets),
+	.dapm_routes		= wm8741_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8741_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8741_of_match[] = {
@@ -585,18 +584,12 @@ static int wm8741_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8741);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-				     &soc_codec_dev_wm8741, &wm8741_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_wm8741, &wm8741_dai, 1);
 
 	return ret;
 }
 
-static int wm8741_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8741_i2c_id[] = {
 	{ "wm8741", 0 },
 	{ }
@@ -609,7 +602,6 @@ static struct i2c_driver wm8741_i2c_driver = {
 		.of_match_table = wm8741_of_match,
 	},
 	.probe =    wm8741_i2c_probe,
-	.remove =   wm8741_i2c_remove,
 	.id_table = wm8741_i2c_id,
 };
 #endif
@@ -650,24 +642,17 @@ static int wm8741_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8741);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8741, &wm8741_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8741, &wm8741_dai, 1);
 	return ret;
 }
 
-static int wm8741_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver wm8741_spi_driver = {
 	.driver = {
 		.name	= "wm8741",
 		.of_match_table = wm8741_of_match,
 	},
 	.probe		= wm8741_spi_probe,
-	.remove		= wm8741_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 0da2bba..97239bc 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -86,7 +86,7 @@ struct wm8750_priv {
 	unsigned int sysclk;
 };
 
-#define wm8750_reset(c)	snd_soc_write(c, WM8750_RESET, 0)
+#define wm8750_reset(c)	snd_soc_component_write(c, WM8750_RESET, 0)
 
 /*
  * WM8750 Controls
@@ -502,8 +502,8 @@ static inline int get_coeff(int mclk, int rate)
 static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8750_priv *wm8750 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case 11289600:
@@ -520,7 +520,7 @@ static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
 
 	/* set master/slave audio interface */
@@ -571,7 +571,7 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8750_IFACE, iface);
+	snd_soc_component_write(component, WM8750_IFACE, iface);
 	return 0;
 }
 
@@ -579,10 +579,10 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
-	u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
-	u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
+	struct snd_soc_component *component = dai->component;
+	struct wm8750_priv *wm8750 = snd_soc_component_get_drvdata(component);
+	u16 iface = snd_soc_component_read32(component, WM8750_IFACE) & 0x1f3;
+	u16 srate = snd_soc_component_read32(component, WM8750_SRATE) & 0x1c0;
 	int coeff = get_coeff(wm8750->sysclk, params_rate(params));
 
 	/* bit size */
@@ -601,9 +601,9 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* set iface & srate */
-	snd_soc_write(codec, WM8750_IFACE, iface);
+	snd_soc_component_write(component, WM8750_IFACE, iface);
 	if (coeff >= 0)
-		snd_soc_write(codec, WM8750_SRATE, srate |
+		snd_soc_component_write(component, WM8750_SRATE, srate |
 			(coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
 
 	return 0;
@@ -611,44 +611,44 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8750_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8750_ADCDAC) & 0xfff7;
 
 	if (mute)
-		snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
+		snd_soc_component_write(component, WM8750_ADCDAC, mute_reg | 0x8);
 	else
-		snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
+		snd_soc_component_write(component, WM8750_ADCDAC, mute_reg);
 	return 0;
 }
 
-static int wm8750_set_bias_level(struct snd_soc_codec *codec,
+static int wm8750_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
+	u16 pwr_reg = snd_soc_component_read32(component, WM8750_PWR1) & 0xfe3e;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		/* set vmid to 50k and unmute dac */
-		snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
+		snd_soc_component_write(component, WM8750_PWR1, pwr_reg | 0x00c0);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_cache_sync(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_cache_sync(component);
 
 			/* Set VMID to 5k */
-			snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
+			snd_soc_component_write(component, WM8750_PWR1, pwr_reg | 0x01c1);
 
 			/* ...and ramp */
 			msleep(1000);
 		}
 
 		/* mute dac and set vmid to 500k, enable VREF */
-		snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
+		snd_soc_component_write(component, WM8750_PWR1, pwr_reg | 0x0141);
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, WM8750_PWR1, 0x0001);
+		snd_soc_component_write(component, WM8750_PWR1, 0x0001);
 		break;
 	}
 	return 0;
@@ -685,42 +685,43 @@ static struct snd_soc_dai_driver wm8750_dai = {
 	.ops = &wm8750_dai_ops,
 };
 
-static int wm8750_probe(struct snd_soc_codec *codec)
+static int wm8750_probe(struct snd_soc_component *component)
 {
 	int ret;
 
-	ret = wm8750_reset(codec);
+	ret = wm8750_reset(component);
 	if (ret < 0) {
 		printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
 		return ret;
 	}
 
 	/* set the update bits */
-	snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8750_LOUT1V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8750_ROUT1V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8750_LOUT2V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8750_ROUT2V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8750_LDAC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8750_RDAC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8750_LOUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8750_ROUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8750_LOUT2V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8750_ROUT2V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8750_LINVOL, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8750_RINVOL, 0x0100, 0x0100);
 
 	return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
-	.probe =	wm8750_probe,
-	.set_bias_level = wm8750_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8750_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8750_snd_controls),
-		.dapm_widgets		= wm8750_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8750_dapm_widgets),
-		.dapm_routes		= wm8750_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8750_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8750 = {
+	.probe			= wm8750_probe,
+	.set_bias_level		= wm8750_set_bias_level,
+	.controls		= wm8750_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8750_snd_controls),
+	.dapm_widgets		= wm8750_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8750_dapm_widgets),
+	.dapm_routes		= wm8750_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8750_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8750_of_match[] = {
@@ -758,17 +759,11 @@ static int wm8750_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8750);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8750, &wm8750_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8750, &wm8750_dai, 1);
 	return ret;
 }
 
-static int wm8750_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static const struct spi_device_id wm8750_spi_ids[] = {
 	{ "wm8750", 0 },
 	{ "wm8987", 0 },
@@ -783,7 +778,6 @@ static struct spi_driver wm8750_spi_driver = {
 	},
 	.id_table	= wm8750_spi_ids,
 	.probe		= wm8750_spi_probe,
-	.remove		= wm8750_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -806,17 +800,11 @@ static int wm8750_i2c_probe(struct i2c_client *i2c,
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8750, &wm8750_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8750, &wm8750_dai, 1);
 	return ret;
 }
 
-static int wm8750_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8750_i2c_id[] = {
 	{ "wm8750", 0 },
 	{ "wm8987", 0 },
@@ -830,7 +818,6 @@ static struct i2c_driver wm8750_i2c_driver = {
 		.of_match_table = wm8750_of_match,
 	},
 	.probe =    wm8750_i2c_probe,
-	.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 0271a52..1e2823e 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -55,9 +55,9 @@ static int caps_charge = 2000;
 module_param(caps_charge, int, 0);
 MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
 
-static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_hifi_write_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt);
-static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_voice_write_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt);
 
 /*
@@ -150,7 +150,7 @@ struct wm8753_priv {
 	struct delayed_work charge_work;
 };
 
-#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
+#define wm8753_reset(c) snd_soc_component_write(c, WM8753_RESET, 0)
 
 /*
  * WM8753 Controls
@@ -229,8 +229,8 @@ SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase),
 static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = wm8753->dai_func;
 	return 0;
@@ -239,17 +239,17 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
 static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 	u16 ioctl;
 
 	if (wm8753->dai_func == ucontrol->value.enumerated.item[0])
 		return 0;
 
-	if (snd_soc_codec_is_active(codec))
+	if (snd_soc_component_is_active(component))
 		return -EBUSY;
 
-	ioctl = snd_soc_read(codec, WM8753_IOCTL);
+	ioctl = snd_soc_component_read32(component, WM8753_IOCTL);
 
 	wm8753->dai_func = ucontrol->value.enumerated.item[0];
 
@@ -257,11 +257,11 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
 		return 1;
 
 	ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2);
-	snd_soc_write(codec, WM8753_IOCTL, ioctl);
+	snd_soc_component_write(component, WM8753_IOCTL, ioctl);
 
 
-	wm8753_hifi_write_dai_fmt(codec, wm8753->hifi_fmt);
-	wm8753_voice_write_dai_fmt(codec, wm8753->voice_fmt);
+	wm8753_hifi_write_dai_fmt(component, wm8753->hifi_fmt);
+	wm8753_voice_write_dai_fmt(component, wm8753->voice_fmt);
 
 	return 1;
 }
@@ -745,7 +745,7 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 {
 	u16 reg, enable;
 	int offset;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2)
 		return -ENODEV;
@@ -753,17 +753,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	if (pll_id == WM8753_PLL1) {
 		offset = 0;
 		enable = 0x10;
-		reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
+		reg = snd_soc_component_read32(component, WM8753_CLOCK) & 0xffef;
 	} else {
 		offset = 4;
 		enable = 0x8;
-		reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
+		reg = snd_soc_component_read32(component, WM8753_CLOCK) & 0xfff7;
 	}
 
 	if (!freq_in || !freq_out) {
 		/* disable PLL  */
-		snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
-		snd_soc_write(codec, WM8753_CLOCK, reg);
+		snd_soc_component_write(component, WM8753_PLL1CTL1 + offset, 0x0026);
+		snd_soc_component_write(component, WM8753_CLOCK, reg);
 		return 0;
 	} else {
 		u16 value = 0;
@@ -774,20 +774,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		/* set up N and K PLL divisor ratios */
 		/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
 		value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
-		snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
+		snd_soc_component_write(component, WM8753_PLL1CTL2 + offset, value);
 
 		/* bits 8:0 = PLL_K[17:9] */
 		value = (pll_div.k & 0x03fe00) >> 9;
-		snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
+		snd_soc_component_write(component, WM8753_PLL1CTL3 + offset, value);
 
 		/* bits 8:0 = PLL_K[8:0] */
 		value = pll_div.k & 0x0001ff;
-		snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
+		snd_soc_component_write(component, WM8753_PLL1CTL4 + offset, value);
 
 		/* set PLL as input and enable */
-		snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
+		snd_soc_component_write(component, WM8753_PLL1CTL1 + offset, 0x0027 |
 			(pll_div.div2 << 3));
-		snd_soc_write(codec, WM8753_CLOCK, reg | enable);
+		snd_soc_component_write(component, WM8753_CLOCK, reg | enable);
 	}
 	return 0;
 }
@@ -866,8 +866,8 @@ static int get_coeff(int mclk, int rate)
 static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case 11289600:
@@ -890,10 +890,10 @@ static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 /*
  * Set's ADC and Voice DAC format.
  */
-static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
-	u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
+	u16 voice = snd_soc_component_read32(component, WM8753_PCM) & 0x01ec;
 
 	/* interface format */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -915,7 +915,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8753_PCM, voice);
+	snd_soc_component_write(component, WM8753_PCM, voice);
 	return 0;
 }
 
@@ -926,10 +926,10 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-	u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
-	u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
+	struct snd_soc_component *component = dai->component;
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
+	u16 voice = snd_soc_component_read32(component, WM8753_PCM) & 0x01f3;
+	u16 srate = snd_soc_component_read32(component, WM8753_SRATE1) & 0x017f;
 
 	/* bit size */
 	switch (params_width(params)) {
@@ -949,22 +949,22 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
 	/* sample rate */
 	if (params_rate(params) * 384 == wm8753->pcmclk)
 		srate |= 0x80;
-	snd_soc_write(codec, WM8753_SRATE1, srate);
+	snd_soc_component_write(component, WM8753_SRATE1, srate);
 
-	snd_soc_write(codec, WM8753_PCM, voice);
+	snd_soc_component_write(component, WM8753_PCM, voice);
 	return 0;
 }
 
 /*
  * Set's PCM dai fmt and BCLK.
  */
-static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_pcm_set_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
 	u16 voice, ioctl;
 
-	voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
-	ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
+	voice = snd_soc_component_read32(component, WM8753_PCM) & 0x011f;
+	ioctl = snd_soc_component_read32(component, WM8753_IOCTL) & 0x015d;
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1018,29 +1018,29 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8753_PCM, voice);
-	snd_soc_write(codec, WM8753_IOCTL, ioctl);
+	snd_soc_component_write(component, WM8753_PCM, voice);
+	snd_soc_component_write(component, WM8753_IOCTL, ioctl);
 	return 0;
 }
 
 static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
 	switch (div_id) {
 	case WM8753_PCMDIV:
-		reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
-		snd_soc_write(codec, WM8753_CLOCK, reg | div);
+		reg = snd_soc_component_read32(component, WM8753_CLOCK) & 0x003f;
+		snd_soc_component_write(component, WM8753_CLOCK, reg | div);
 		break;
 	case WM8753_BCLKDIV:
-		reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
-		snd_soc_write(codec, WM8753_SRATE2, reg | div);
+		reg = snd_soc_component_read32(component, WM8753_SRATE2) & 0x01c7;
+		snd_soc_component_write(component, WM8753_SRATE2, reg | div);
 		break;
 	case WM8753_VXCLKDIV:
-		reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
-		snd_soc_write(codec, WM8753_SRATE2, reg | div);
+		reg = snd_soc_component_read32(component, WM8753_SRATE2) & 0x003f;
+		snd_soc_component_write(component, WM8753_SRATE2, reg | div);
 		break;
 	default:
 		return -EINVAL;
@@ -1051,10 +1051,10 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 /*
  * Set's HiFi DAC format.
  */
-static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_hdac_set_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
-	u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
+	u16 hifi = snd_soc_component_read32(component, WM8753_HIFI) & 0x01e0;
 
 	/* interface format */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1076,20 +1076,20 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8753_HIFI, hifi);
+	snd_soc_component_write(component, WM8753_HIFI, hifi);
 	return 0;
 }
 
 /*
  * Set's I2S DAI format.
  */
-static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_i2s_set_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
 	u16 ioctl, hifi;
 
-	hifi = snd_soc_read(codec, WM8753_HIFI) & 0x013f;
-	ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
+	hifi = snd_soc_component_read32(component, WM8753_HIFI) & 0x013f;
+	ioctl = snd_soc_component_read32(component, WM8753_IOCTL) & 0x00ae;
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1143,8 +1143,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8753_HIFI, hifi);
-	snd_soc_write(codec, WM8753_IOCTL, ioctl);
+	snd_soc_component_write(component, WM8753_HIFI, hifi);
+	snd_soc_component_write(component, WM8753_IOCTL, ioctl);
 	return 0;
 }
 
@@ -1155,10 +1155,10 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-	u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
-	u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
+	struct snd_soc_component *component = dai->component;
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
+	u16 srate = snd_soc_component_read32(component, WM8753_SRATE1) & 0x01c0;
+	u16 hifi = snd_soc_component_read32(component, WM8753_HIFI) & 0x01f3;
 	int coeff;
 
 	/* is digital filter coefficient valid ? */
@@ -1167,7 +1167,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
 		printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
 		return coeff;
 	}
-	snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
+	snd_soc_component_write(component, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
 		coeff_div[coeff].usb);
 
 	/* bit size */
@@ -1185,70 +1185,70 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8753_HIFI, hifi);
+	snd_soc_component_write(component, WM8753_HIFI, hifi);
 	return 0;
 }
 
-static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_mode1v_set_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
 	u16 clock;
 
 	/* set clk source as pcmclk */
-	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
-	snd_soc_write(codec, WM8753_CLOCK, clock);
+	clock = snd_soc_component_read32(component, WM8753_CLOCK) & 0xfffb;
+	snd_soc_component_write(component, WM8753_CLOCK, clock);
 
-	return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
+	return wm8753_vdac_adc_set_dai_fmt(component, fmt);
 }
 
-static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_mode1h_set_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
-	return wm8753_hdac_set_dai_fmt(codec, fmt);
+	return wm8753_hdac_set_dai_fmt(component, fmt);
 }
 
-static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_mode2_set_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
 	u16 clock;
 
 	/* set clk source as pcmclk */
-	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
-	snd_soc_write(codec, WM8753_CLOCK, clock);
+	clock = snd_soc_component_read32(component, WM8753_CLOCK) & 0xfffb;
+	snd_soc_component_write(component, WM8753_CLOCK, clock);
 
-	return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
+	return wm8753_vdac_adc_set_dai_fmt(component, fmt);
 }
 
-static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
 	u16 clock;
 
 	/* set clk source as mclk */
-	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
-	snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
+	clock = snd_soc_component_read32(component, WM8753_CLOCK) & 0xfffb;
+	snd_soc_component_write(component, WM8753_CLOCK, clock | 0x4);
 
-	if (wm8753_hdac_set_dai_fmt(codec, fmt) < 0)
+	if (wm8753_hdac_set_dai_fmt(component, fmt) < 0)
 		return -EINVAL;
-	return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
+	return wm8753_vdac_adc_set_dai_fmt(component, fmt);
 }
 
-static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_hifi_write_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	switch (wm8753->dai_func) {
 	case 0:
-		ret = wm8753_mode1h_set_dai_fmt(codec, fmt);
+		ret = wm8753_mode1h_set_dai_fmt(component, fmt);
 		break;
 	case 1:
-		ret = wm8753_mode2_set_dai_fmt(codec, fmt);
+		ret = wm8753_mode2_set_dai_fmt(component, fmt);
 		break;
 	case 2:
 	case 3:
-		ret = wm8753_mode3_4_set_dai_fmt(codec, fmt);
+		ret = wm8753_mode3_4_set_dai_fmt(component, fmt);
 		break;
 	default:
 		 break;
@@ -1256,33 +1256,33 @@ static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
 	if (ret)
 		return ret;
 
-	return wm8753_i2s_set_dai_fmt(codec, fmt);
+	return wm8753_i2s_set_dai_fmt(component, fmt);
 }
 
 static int wm8753_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
 	wm8753->hifi_fmt = fmt;
 
-	return wm8753_hifi_write_dai_fmt(codec, fmt);
+	return wm8753_hifi_write_dai_fmt(component, fmt);
 };
 
-static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_voice_write_dai_fmt(struct snd_soc_component *component,
 		unsigned int fmt)
 {
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	if (wm8753->dai_func != 0)
 		return 0;
 
-	ret = wm8753_mode1v_set_dai_fmt(codec, fmt);
+	ret = wm8753_mode1v_set_dai_fmt(component, fmt);
 	if (ret)
 		return ret;
-	ret = wm8753_pcm_set_dai_fmt(codec, fmt);
+	ret = wm8753_pcm_set_dai_fmt(component, fmt);
 	if (ret)
 		return ret;
 
@@ -1292,30 +1292,30 @@ static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
 static int wm8753_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
 	wm8753->voice_fmt = fmt;
 
-	return wm8753_voice_write_dai_fmt(codec, fmt);
+	return wm8753_voice_write_dai_fmt(component, fmt);
 };
 
 static int wm8753_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8753_DAC) & 0xfff7;
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
 	/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
 	 * make sure we check if they are not both active when we mute */
 	if (mute && wm8753->dai_func == 1) {
-		if (!snd_soc_codec_is_active(codec))
-			snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
+		if (!snd_soc_component_is_active(component))
+			snd_soc_component_write(component, WM8753_DAC, mute_reg | 0x8);
 	} else {
 		if (mute)
-			snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
+			snd_soc_component_write(component, WM8753_DAC, mute_reg | 0x8);
 		else
-			snd_soc_write(codec, WM8753_DAC, mute_reg);
+			snd_soc_component_write(component, WM8753_DAC, mute_reg);
 	}
 
 	return 0;
@@ -1330,35 +1330,35 @@ static void wm8753_charge_work(struct work_struct *work)
 	regmap_update_bits(wm8753->regmap, WM8753_PWR1, 0x0180, 0x0100);
 }
 
-static int wm8753_set_bias_level(struct snd_soc_codec *codec,
+static int wm8753_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-	u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
+	u16 pwr_reg = snd_soc_component_read32(component, WM8753_PWR1) & 0xfe3e;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		/* set vmid to 50k and unmute dac */
-		snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
+		snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x00c0);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		/* Wait until fully charged */
 		flush_delayed_work(&wm8753->charge_work);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* set vmid to 5k for quick power up */
-			snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+			snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x01c1);
 			schedule_delayed_work(&wm8753->charge_work,
 				msecs_to_jiffies(caps_charge));
 		} else {
 			/* mute dac and set vmid to 500k, enable VREF */
-			snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+			snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x0141);
 		}
 		break;
 	case SND_SOC_BIAS_OFF:
 		cancel_delayed_work_sync(&wm8753->charge_work);
-		snd_soc_write(codec, WM8753_PWR1, 0x0001);
+		snd_soc_component_write(component, WM8753_PWR1, 0x0001);
 		break;
 	}
 	return 0;
@@ -1440,59 +1440,60 @@ static struct snd_soc_dai_driver wm8753_dai[] = {
 },
 };
 
-static int wm8753_resume(struct snd_soc_codec *codec)
+static int wm8753_resume(struct snd_soc_component *component)
 {
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
 	regcache_sync(wm8753->regmap);
 
 	return 0;
 }
 
-static int wm8753_probe(struct snd_soc_codec *codec)
+static int wm8753_probe(struct snd_soc_component *component)
 {
-	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+	struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	INIT_DELAYED_WORK(&wm8753->charge_work, wm8753_charge_work);
 
-	ret = wm8753_reset(codec);
+	ret = wm8753_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+		dev_err(component->dev, "Failed to issue reset: %d\n", ret);
 		return ret;
 	}
 
 	wm8753->dai_func = 0;
 
 	/* set the update bits */
-	snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_LADC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_RADC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_LDAC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_RDAC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_LADC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_RADC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_LOUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_ROUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_LOUT2V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_ROUT2V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_LINVOL, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8753_RINVOL, 0x0100, 0x0100);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
-	.probe =	wm8753_probe,
-	.resume =	wm8753_resume,
-	.set_bias_level = wm8753_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8753_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8753_snd_controls),
-		.dapm_widgets		= wm8753_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8753_dapm_widgets),
-		.dapm_routes		= wm8753_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8753_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8753 = {
+	.probe			= wm8753_probe,
+	.resume			= wm8753_resume,
+	.set_bias_level		= wm8753_set_bias_level,
+	.controls		= wm8753_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8753_snd_controls),
+	.dapm_widgets		= wm8753_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8753_dapm_widgets),
+	.dapm_routes		= wm8753_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8753_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8753_of_match[] = {
@@ -1534,7 +1535,7 @@ static int wm8753_spi_probe(struct spi_device *spi)
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753,
+	ret = devm_snd_soc_register_component(&spi->dev, &soc_component_dev_wm8753,
 				     wm8753_dai, ARRAY_SIZE(wm8753_dai));
 	if (ret != 0)
 		dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
@@ -1542,19 +1543,12 @@ static int wm8753_spi_probe(struct spi_device *spi)
 	return ret;
 }
 
-static int wm8753_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver wm8753_spi_driver = {
 	.driver = {
 		.name	= "wm8753",
 		.of_match_table = wm8753_of_match,
 	},
 	.probe		= wm8753_spi_probe,
-	.remove		= wm8753_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -1580,7 +1574,7 @@ static int wm8753_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753,
+	ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_wm8753,
 				     wm8753_dai, ARRAY_SIZE(wm8753_dai));
 	if (ret != 0)
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
@@ -1588,12 +1582,6 @@ static int wm8753_i2c_probe(struct i2c_client *i2c,
 	return ret;
 }
 
-static int wm8753_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8753_i2c_id[] = {
 	{ "wm8753", 0 },
 	{ }
@@ -1606,7 +1594,6 @@ static struct i2c_driver wm8753_i2c_driver = {
 		.of_match_table = wm8753_of_match,
 	},
 	.probe =    wm8753_i2c_probe,
-	.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 d6edcbb..806245c 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -84,7 +84,7 @@ struct wm8770_priv {
 	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES];
 	struct notifier_block disable_nb[WM8770_NUM_SUPPLIES];
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	int sysclk;
 };
 
@@ -308,14 +308,14 @@ static const struct snd_soc_dapm_route wm8770_intercon[] = {
 static int vout12supply_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0);
+		snd_soc_component_update_bits(component, WM8770_OUTMUX1, 0x180, 0);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180);
+		snd_soc_component_update_bits(component, WM8770_OUTMUX1, 0x180, 0x180);
 		break;
 	}
 
@@ -325,31 +325,31 @@ static int vout12supply_event(struct snd_soc_dapm_widget *w,
 static int vout34supply_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0);
+		snd_soc_component_update_bits(component, WM8770_OUTMUX2, 0x180, 0);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180);
+		snd_soc_component_update_bits(component, WM8770_OUTMUX2, 0x180, 0x180);
 		break;
 	}
 
 	return 0;
 }
 
-static int wm8770_reset(struct snd_soc_codec *codec)
+static int wm8770_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, WM8770_RESET, 0);
+	return snd_soc_component_write(component, WM8770_RESET, 0);
 }
 
 static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	int iface, master;
 
-	codec = dai->codec;
+	component = dai->component;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -392,8 +392,8 @@ static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface);
-	snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master);
+	snd_soc_component_update_bits(component, WM8770_IFACECTRL, 0xf, iface);
+	snd_soc_component_update_bits(component, WM8770_MSTRCTRL, 0x100, master);
 
 	return 0;
 }
@@ -411,15 +411,15 @@ static int wm8770_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm8770_priv *wm8770;
 	int i;
 	int iface;
 	int shift;
 	int ratio;
 
-	codec = dai->codec;
-	wm8770 = snd_soc_codec_get_drvdata(codec);
+	component = dai->component;
+	wm8770 = snd_soc_component_get_drvdata(component);
 
 	iface = 0;
 	switch (params_width(params)) {
@@ -450,7 +450,7 @@ static int wm8770_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* Only need to set MCLK/LRCLK ratio if we're master */
-	if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) {
+	if (snd_soc_component_read32(component, WM8770_MSTRCTRL) & 0x100) {
 		for (; i < ARRAY_SIZE(mclk_ratios); ++i) {
 			ratio = wm8770->sysclk / params_rate(params);
 			if (ratio == mclk_ratios[i])
@@ -458,51 +458,51 @@ static int wm8770_hw_params(struct snd_pcm_substream *substream,
 		}
 
 		if (i == ARRAY_SIZE(mclk_ratios)) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Unable to configure MCLK ratio %d/%d\n",
 				wm8770->sysclk, params_rate(params));
 			return -EINVAL;
 		}
 
-		dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
+		dev_dbg(component->dev, "MCLK is %dfs\n", mclk_ratios[i]);
 
-		snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift,
+		snd_soc_component_update_bits(component, WM8770_MSTRCTRL, 0x7 << shift,
 				    i << shift);
 	}
 
-	snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface);
+	snd_soc_component_update_bits(component, WM8770_IFACECTRL, 0x30, iface);
 
 	return 0;
 }
 
 static int wm8770_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 
-	codec = dai->codec;
-	return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10,
+	component = dai->component;
+	return snd_soc_component_update_bits(component, WM8770_DACMUTE, 0x10,
 				   !!mute << 4);
 }
 
 static int wm8770_set_sysclk(struct snd_soc_dai *dai,
 			     int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm8770_priv *wm8770;
 
-	codec = dai->codec;
-	wm8770 = snd_soc_codec_get_drvdata(codec);
+	component = dai->component;
+	wm8770 = snd_soc_component_get_drvdata(component);
 	wm8770->sysclk = freq;
 	return 0;
 }
 
-static int wm8770_set_bias_level(struct snd_soc_codec *codec,
+static int wm8770_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	int ret;
 	struct wm8770_priv *wm8770;
 
-	wm8770 = snd_soc_codec_get_drvdata(codec);
+	wm8770 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -510,11 +510,11 @@ static int wm8770_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
 						    wm8770->supplies);
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n",
 					ret);
 				return ret;
@@ -523,12 +523,12 @@ static int wm8770_set_bias_level(struct snd_soc_codec *codec,
 			regcache_sync(wm8770->regmap);
 
 			/* global powerup */
-			snd_soc_write(codec, WM8770_PWDNCTRL, 0);
+			snd_soc_component_write(component, WM8770_PWDNCTRL, 0);
 		}
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* global powerdown */
-		snd_soc_write(codec, WM8770_PWDNCTRL, 1);
+		snd_soc_component_write(component, WM8770_PWDNCTRL, 1);
 		regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies),
 				       wm8770->supplies);
 		break;
@@ -567,60 +567,59 @@ static struct snd_soc_dai_driver wm8770_dai = {
 	.symmetric_rates = 1
 };
 
-static int wm8770_probe(struct snd_soc_codec *codec)
+static int wm8770_probe(struct snd_soc_component *component)
 {
 	struct wm8770_priv *wm8770;
 	int ret;
 
-	wm8770 = snd_soc_codec_get_drvdata(codec);
-	wm8770->codec = codec;
+	wm8770 = snd_soc_component_get_drvdata(component);
+	wm8770->component = component;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
 				    wm8770->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		return ret;
 	}
 
-	ret = wm8770_reset(codec);
+	ret = wm8770_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+		dev_err(component->dev, "Failed to issue reset: %d\n", ret);
 		goto err_reg_enable;
 	}
 
 	/* latch the volume update bits */
-	snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_MSDIGVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_MSALGVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_VOUT1RVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_VOUT2RVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_VOUT3RVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_VOUT4RVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_DAC1RVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_DAC2RVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_DAC3RVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8770_DAC4RVOL, 0x100, 0x100);
 
 	/* mute all DACs */
-	snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
+	snd_soc_component_update_bits(component, WM8770_DACMUTE, 0x10, 0x10);
 
 err_reg_enable:
 	regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
 	return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
-	.probe = wm8770_probe,
-	.set_bias_level = wm8770_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.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 snd_soc_component_driver soc_component_dev_wm8770 = {
+	.probe			= wm8770_probe,
+	.set_bias_level		= wm8770_set_bias_level,
+	.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),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8770_of_match[] = {
@@ -682,8 +681,8 @@ static int wm8770_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8770);
 
-	ret = snd_soc_register_codec(&spi->dev,
-				     &soc_codec_dev_wm8770, &wm8770_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+				     &soc_component_dev_wm8770, &wm8770_dai, 1);
 
 	return ret;
 }
@@ -697,8 +696,6 @@ static int wm8770_spi_remove(struct spi_device *spi)
 		regulator_unregister_notifier(wm8770->supplies[i].consumer,
 					      &wm8770->disable_nb[i]);
 
-	snd_soc_unregister_codec(&spi->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index ae30480..fb357e2 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -78,9 +78,9 @@ static bool wm8776_volatile(struct device *dev, unsigned int reg)
 	}
 }
 
-static int wm8776_reset(struct snd_soc_codec *codec)
+static int wm8776_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, WM8776_RESET, 0);
+	return snd_soc_component_write(component, WM8776_RESET, 0);
 }
 
 static const DECLARE_TLV_DB_SCALE(hp_tlv, -12100, 100, 1);
@@ -166,7 +166,7 @@ static const struct snd_soc_dapm_route routes[] = {
 
 static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int reg, iface, master;
 
 	switch (dai->driver->id) {
@@ -224,8 +224,8 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	}
 
 	/* Finally, write out the values */
-	snd_soc_update_bits(codec, reg, 0xf, iface);
-	snd_soc_update_bits(codec, WM8776_MSTRCTRL, 0x180, master);
+	snd_soc_component_update_bits(component, reg, 0xf, iface);
+	snd_soc_component_update_bits(component, WM8776_MSTRCTRL, 0x180, master);
 
 	return 0;
 }
@@ -243,8 +243,8 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8776_priv *wm8776 = snd_soc_component_get_drvdata(component);
 	int iface_reg, iface;
 	int ratio_shift, master;
 	int i;
@@ -279,13 +279,13 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
 		iface = 0x30;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported sample size: %i\n",
+		dev_err(component->dev, "Unsupported sample size: %i\n",
 			params_width(params));
 		return -EINVAL;
 	}
 
 	/* Only need to set MCLK/LRCLK ratio if we're master */
-	if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) {
+	if (snd_soc_component_read32(component, WM8776_MSTRCTRL) & master) {
 		for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) {
 			if (wm8776->sysclk[dai->driver->id] / params_rate(params)
 			    == mclk_ratios[i])
@@ -293,37 +293,37 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
 		}
 
 		if (i == ARRAY_SIZE(mclk_ratios)) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Unable to configure MCLK ratio %d/%d\n",
 				wm8776->sysclk[dai->driver->id], params_rate(params));
 			return -EINVAL;
 		}
 
-		dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
+		dev_dbg(component->dev, "MCLK is %dfs\n", mclk_ratios[i]);
 
-		snd_soc_update_bits(codec, WM8776_MSTRCTRL,
+		snd_soc_component_update_bits(component, WM8776_MSTRCTRL,
 				    0x7 << ratio_shift, i << ratio_shift);
 	} else {
-		dev_dbg(codec->dev, "DAI in slave mode\n");
+		dev_dbg(component->dev, "DAI in slave mode\n");
 	}
 
-	snd_soc_update_bits(codec, iface_reg, 0x30, iface);
+	snd_soc_component_update_bits(component, iface_reg, 0x30, iface);
 
 	return 0;
 }
 
 static int wm8776_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	return snd_soc_write(codec, WM8776_DACMUTE, !!mute);
+	return snd_soc_component_write(component, WM8776_DACMUTE, !!mute);
 }
 
 static int wm8776_set_sysclk(struct snd_soc_dai *dai,
 			     int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8776_priv *wm8776 = snd_soc_component_get_drvdata(component);
 
 	if (WARN_ON(dai->driver->id >= ARRAY_SIZE(wm8776->sysclk)))
 		return -EINVAL;
@@ -333,10 +333,10 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai,
 	return 0;
 }
 
-static int wm8776_set_bias_level(struct snd_soc_codec *codec,
+static int wm8776_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
+	struct wm8776_priv *wm8776 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -344,16 +344,16 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_sync(wm8776->regmap);
 
 			/* Disable the global powerdown; DAPM does the rest */
-			snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
+			snd_soc_component_update_bits(component, WM8776_PWRDOWN, 1, 0);
 		}
 
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 1);
+		snd_soc_component_update_bits(component, WM8776_PWRDOWN, 1, 1);
 		break;
 	}
 
@@ -407,37 +407,38 @@ static struct snd_soc_dai_driver wm8776_dai[] = {
 	},
 };
 
-static int wm8776_probe(struct snd_soc_codec *codec)
+static int wm8776_probe(struct snd_soc_component *component)
 {
 	int ret = 0;
 
-	ret = wm8776_reset(codec);
+	ret = wm8776_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+		dev_err(component->dev, "Failed to issue reset: %d\n", ret);
 		return ret;
 	}
 
 	/* Latch the update bits; right channel only since we always
 	 * update both. */
-	snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8776_HPRVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8776_DACRVOL, 0x100, 0x100);
 
 	return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
-	.probe = 	wm8776_probe,
-	.set_bias_level = wm8776_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8776_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8776_snd_controls),
-		.dapm_widgets		= wm8776_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8776_dapm_widgets),
-		.dapm_routes		= routes,
-		.num_dapm_routes	= ARRAY_SIZE(routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8776 = {
+	.probe			= wm8776_probe,
+	.set_bias_level		= wm8776_set_bias_level,
+	.controls		= wm8776_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8776_snd_controls),
+	.dapm_widgets		= wm8776_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8776_dapm_widgets),
+	.dapm_routes		= routes,
+	.num_dapm_routes	= ARRAY_SIZE(routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct of_device_id wm8776_of_match[] = {
@@ -475,25 +476,18 @@ static int wm8776_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8776);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
 
 	return ret;
 }
 
-static int wm8776_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver wm8776_spi_driver = {
 	.driver = {
 		.name	= "wm8776",
 		.of_match_table = wm8776_of_match,
 	},
 	.probe		= wm8776_spi_probe,
-	.remove		= wm8776_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -515,18 +509,12 @@ static int wm8776_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8776);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
 
 	return ret;
 }
 
-static int wm8776_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8776_i2c_id[] = {
 	{ "wm8775", WM8775 },
 	{ "wm8776", WM8776 },
@@ -540,7 +528,6 @@ static struct i2c_driver wm8776_i2c_driver = {
 		.of_match_table = wm8776_of_match,
 	},
 	.probe =    wm8776_i2c_probe,
-	.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 bcda210..7949703 100644
--- a/sound/soc/codecs/wm8782.c
+++ b/sound/soc/codecs/wm8782.c
@@ -50,25 +50,21 @@ static struct snd_soc_dai_driver wm8782_dai = {
 	},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8782 = {
-	.component_driver = {
-		.dapm_widgets		= wm8782_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8782_dapm_widgets),
-		.dapm_routes		= wm8782_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8782_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8782 = {
+	.dapm_widgets		= wm8782_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8782_dapm_widgets),
+	.dapm_routes		= wm8782_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8782_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8782_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_wm8782, &wm8782_dai, 1);
-}
-
-static int wm8782_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_wm8782, &wm8782_dai, 1);
 }
 
 static struct platform_driver wm8782_codec_driver = {
@@ -76,7 +72,6 @@ static struct platform_driver wm8782_codec_driver = {
 		.name = "wm8782",
 	},
 	.probe = wm8782_probe,
-	.remove = wm8782_remove,
 };
 
 module_platform_driver(wm8782_codec_driver);
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index fc69b87..89f1324 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -137,21 +137,21 @@ static const struct snd_soc_dapm_route wm8804_dapm_routes[] = {
 static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8804_priv *wm8804 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		/* power up the aif */
 		if (!wm8804->aif_pwr)
-			snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0x0);
+			snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x0);
 		wm8804->aif_pwr++;
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		/* power down only both paths are disabled */
 		wm8804->aif_pwr--;
 		if (!wm8804->aif_pwr)
-			snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0x10);
+			snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x10);
 		break;
 	}
 
@@ -161,8 +161,8 @@ static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
 static int txsrc_put(struct snd_kcontrol *kcontrol,
 		     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l;
 	unsigned int mask = 1 << e->shift_l;
@@ -173,18 +173,18 @@ static int txsrc_put(struct snd_kcontrol *kcontrol,
 
 	snd_soc_dapm_mutex_lock(dapm);
 
-	if (snd_soc_test_bits(codec, e->reg, mask, val)) {
+	if (snd_soc_component_test_bits(component, e->reg, mask, val)) {
 		/* save the current power state of the transmitter */
-		txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4;
+		txpwr = snd_soc_component_read32(component, WM8804_PWRDN) & 0x4;
 
 		/* power down the transmitter */
-		snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4);
+		snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, 0x4);
 
 		/* set the tx source */
-		snd_soc_update_bits(codec, e->reg, mask, val);
+		snd_soc_component_update_bits(component, e->reg, mask, val);
 
 		/* restore the transmitter's configuration */
-		snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
+		snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, txpwr);
 	}
 
 	snd_soc_dapm_mutex_unlock(dapm);
@@ -218,10 +218,10 @@ static int wm8804_soft_reset(struct wm8804_priv *wm8804)
 
 static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	u16 format, master, bcp, lrp;
 
-	codec = dai->codec;
+	component = dai->component;
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
@@ -243,8 +243,8 @@ static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	}
 
 	/* set data format */
-	snd_soc_update_bits(codec, WM8804_AIFTX, 0x3, format);
-	snd_soc_update_bits(codec, WM8804_AIFRX, 0x3, format);
+	snd_soc_component_update_bits(component, WM8804_AIFTX, 0x3, format);
+	snd_soc_component_update_bits(component, WM8804_AIFRX, 0x3, format);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -259,7 +259,7 @@ static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	}
 
 	/* set master/slave mode */
-	snd_soc_update_bits(codec, WM8804_AIFRX, 0x40, master << 6);
+	snd_soc_component_update_bits(component, WM8804_AIFRX, 0x40, master << 6);
 
 	bcp = lrp = 0;
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -280,9 +280,9 @@ static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	}
 
 	/* set frame inversion */
-	snd_soc_update_bits(codec, WM8804_AIFTX, 0x10 | 0x20,
+	snd_soc_component_update_bits(component, WM8804_AIFTX, 0x10 | 0x20,
 			    (bcp << 4) | (lrp << 5));
-	snd_soc_update_bits(codec, WM8804_AIFRX, 0x10 | 0x20,
+	snd_soc_component_update_bits(component, WM8804_AIFRX, 0x10 | 0x20,
 			    (bcp << 4) | (lrp << 5));
 	return 0;
 }
@@ -291,10 +291,10 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	u16 blen;
 
-	codec = dai->codec;
+	component = dai->component;
 
 	switch (params_width(params)) {
 	case 16:
@@ -313,8 +313,8 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* set word length */
-	snd_soc_update_bits(codec, WM8804_AIFTX, 0xc, blen << 2);
-	snd_soc_update_bits(codec, WM8804_AIFRX, 0xc, blen << 2);
+	snd_soc_component_update_bits(component, WM8804_AIFTX, 0xc, blen << 2);
+	snd_soc_component_update_bits(component, WM8804_AIFRX, 0xc, blen << 2);
 
 	return 0;
 }
@@ -405,8 +405,8 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
 			  int source, unsigned int freq_in,
 			  unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8804_priv *wm8804 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component);
 	bool change;
 
 	if (!freq_in || !freq_out) {
@@ -431,18 +431,18 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
 			pm_runtime_get_sync(wm8804->dev);
 
 		/* set PLLN and PRESCALE */
-		snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10,
+		snd_soc_component_update_bits(component, WM8804_PLL4, 0xf | 0x10,
 				    pll_div.n | (pll_div.prescale << 4));
 		/* set mclkdiv and freqmode */
-		snd_soc_update_bits(codec, WM8804_PLL5, 0x3 | 0x8,
+		snd_soc_component_update_bits(component, WM8804_PLL5, 0x3 | 0x8,
 				    pll_div.freqmode | (pll_div.mclkdiv << 3));
 		/* set PLLK */
-		snd_soc_write(codec, WM8804_PLL1, pll_div.k & 0xff);
-		snd_soc_write(codec, WM8804_PLL2, (pll_div.k >> 8) & 0xff);
-		snd_soc_write(codec, WM8804_PLL3, pll_div.k >> 16);
+		snd_soc_component_write(component, WM8804_PLL1, pll_div.k & 0xff);
+		snd_soc_component_write(component, WM8804_PLL2, (pll_div.k >> 8) & 0xff);
+		snd_soc_component_write(component, WM8804_PLL3, pll_div.k >> 16);
 
 		/* power up the PLL */
-		snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0);
+		snd_soc_component_update_bits(component, WM8804_PWRDN, 0x1, 0);
 	}
 
 	return 0;
@@ -451,15 +451,15 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
 static int wm8804_set_sysclk(struct snd_soc_dai *dai,
 			     int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 
-	codec = dai->codec;
+	component = dai->component;
 
 	switch (clk_id) {
 	case WM8804_TX_CLKSRC_MCLK:
 		if ((freq >= 10000000 && freq <= 14400000)
 				|| (freq >= 16280000 && freq <= 27000000))
-			snd_soc_update_bits(codec, WM8804_PLL6, 0x80, 0x80);
+			snd_soc_component_update_bits(component, WM8804_PLL6, 0x80, 0x80);
 		else {
 			dev_err(dai->dev, "OSCCLOCK is not within the "
 				"recommended range: %uHz\n", freq);
@@ -467,13 +467,13 @@ static int wm8804_set_sysclk(struct snd_soc_dai *dai,
 		}
 		break;
 	case WM8804_TX_CLKSRC_PLL:
-		snd_soc_update_bits(codec, WM8804_PLL6, 0x80, 0);
+		snd_soc_component_update_bits(component, WM8804_PLL6, 0x80, 0);
 		break;
 	case WM8804_CLKOUT_SRC_CLK1:
-		snd_soc_update_bits(codec, WM8804_PLL6, 0x8, 0);
+		snd_soc_component_update_bits(component, WM8804_PLL6, 0x8, 0);
 		break;
 	case WM8804_CLKOUT_SRC_OSCCLK:
-		snd_soc_update_bits(codec, WM8804_PLL6, 0x8, 0x8);
+		snd_soc_component_update_bits(component, WM8804_PLL6, 0x8, 0x8);
 		break;
 	default:
 		dev_err(dai->dev, "Unknown clock source: %d\n", clk_id);
@@ -486,17 +486,17 @@ static int wm8804_set_sysclk(struct snd_soc_dai *dai,
 static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
 			     int div_id, int div)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm8804_priv *wm8804;
 
-	codec = dai->codec;
+	component = dai->component;
 	switch (div_id) {
 	case WM8804_CLKOUT_DIV:
-		snd_soc_update_bits(codec, WM8804_PLL5, 0x30,
+		snd_soc_component_update_bits(component, WM8804_PLL5, 0x30,
 				    (div & 0x3) << 4);
 		break;
 	case WM8804_MCLK_DIV:
-		wm8804 = snd_soc_codec_get_drvdata(codec);
+		wm8804 = snd_soc_component_get_drvdata(component);
 		wm8804->mclk_div = div;
 		break;
 	default:
@@ -542,15 +542,14 @@ static struct snd_soc_dai_driver wm8804_dai = {
 	.symmetric_rates = 1
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.dapm_widgets		= wm8804_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8804_dapm_widgets),
-		.dapm_routes		= wm8804_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8804_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8804 = {
+	.dapm_widgets		= wm8804_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8804_dapm_widgets),
+	.dapm_routes		= wm8804_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8804_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 const struct regmap_config wm8804_regmap_config = {
@@ -661,7 +660,7 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
 		}
 	}
 
-	ret = snd_soc_register_codec(dev, &soc_codec_dev_wm8804,
+	ret = devm_snd_soc_register_component(dev, &soc_component_dev_wm8804,
 				     &wm8804_dai, 1);
 	if (ret < 0) {
 		dev_err(dev, "Failed to register CODEC: %d\n", ret);
@@ -683,7 +682,6 @@ EXPORT_SYMBOL_GPL(wm8804_probe);
 void wm8804_remove(struct device *dev)
 {
 	pm_runtime_disable(dev);
-	snd_soc_unregister_codec(dev);
 }
 EXPORT_SYMBOL_GPL(wm8804_remove);
 
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index c77b49a..1a14e90 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -216,23 +216,23 @@ static bool wm8900_volatile_register(struct device *dev, unsigned int reg)
 	}
 }
 
-static void wm8900_reset(struct snd_soc_codec *codec)
+static void wm8900_reset(struct snd_soc_component *component)
 {
-	snd_soc_write(codec, WM8900_REG_RESET, 0);
+	snd_soc_component_write(component, WM8900_REG_RESET, 0);
 }
 
 static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	u16 hpctl1 = snd_soc_component_read32(component, WM8900_REG_HPCTL1);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		/* Clamp headphone outputs */
 		hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
 			WM8900_REG_HPCTL1_HP_CLAMP_OP;
-		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, hpctl1);
 		break;
 
 	case SND_SOC_DAPM_POST_PMU:
@@ -241,41 +241,41 @@ static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
 		hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
 			WM8900_REG_HPCTL1_HP_SHORT2 |
 			WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
-		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, hpctl1);
 
 		msleep(400);
 
 		/* Enable the output stage */
 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
 		hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
-		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, hpctl1);
 
 		/* Remove the shorts */
 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
-		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, hpctl1);
 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
-		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, hpctl1);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
 		/* Short the output */
 		hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
-		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, hpctl1);
 
 		/* Disable the output stage */
 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
-		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, hpctl1);
 
 		/* Clamp the outputs and power down input */
 		hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
 			WM8900_REG_HPCTL1_HP_CLAMP_OP;
 		hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
-		snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, hpctl1);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
 		/* Disable everything */
-		snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, 0);
 		break;
 
 	default:
@@ -635,10 +635,10 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 reg;
 
-	reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
+	reg = snd_soc_component_read32(component, WM8900_REG_AUDIO1) & ~0x60;
 
 	switch (params_width(params)) {
 	case 16:
@@ -656,17 +656,17 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8900_REG_AUDIO1, reg);
+	snd_soc_component_write(component, WM8900_REG_AUDIO1, reg);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
+		reg = snd_soc_component_read32(component, WM8900_REG_DACCTRL);
 
 		if (params_rate(params) <= 24000)
 			reg |= WM8900_REG_DACCTRL_DAC_SB_FILT;
 		else
 			reg &= ~WM8900_REG_DACCTRL_DAC_SB_FILT;
 
-		snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
+		snd_soc_component_write(component, WM8900_REG_DACCTRL, reg);
 	}
 
 	return 0;
@@ -751,24 +751,24 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 	return 0;
 }
 
-static int wm8900_set_fll(struct snd_soc_codec *codec,
+static int wm8900_set_fll(struct snd_soc_component *component,
 	int fll_id, unsigned int freq_in, unsigned int freq_out)
 {
-	struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
+	struct wm8900_priv *wm8900 = snd_soc_component_get_drvdata(component);
 	struct _fll_div fll_div;
 
 	if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out)
 		return 0;
 
 	/* The digital side should be disabled during any change. */
-	snd_soc_update_bits(codec, WM8900_REG_POWER1,
+	snd_soc_component_update_bits(component, WM8900_REG_POWER1,
 			    WM8900_REG_POWER1_FLL_ENA, 0);
 
 	/* Disable the FLL? */
 	if (!freq_in || !freq_out) {
-		snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
+		snd_soc_component_update_bits(component, WM8900_REG_CLOCKING1,
 				    WM8900_REG_CLOCKING1_MCLK_SRC, 0);
-		snd_soc_update_bits(codec, WM8900_REG_FLLCTL1,
+		snd_soc_component_update_bits(component, WM8900_REG_FLLCTL1,
 				    WM8900_REG_FLLCTL1_OSC_ENA, 0);
 		wm8900->fll_in = freq_in;
 		wm8900->fll_out = freq_out;
@@ -784,32 +784,32 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
 
 	/* The osclilator *MUST* be enabled before we enable the
 	 * digital circuit. */
-	snd_soc_write(codec, WM8900_REG_FLLCTL1,
+	snd_soc_component_write(component, WM8900_REG_FLLCTL1,
 		     fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA);
 
-	snd_soc_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
-	snd_soc_write(codec, WM8900_REG_FLLCTL5,
+	snd_soc_component_write(component, WM8900_REG_FLLCTL4, fll_div.n >> 5);
+	snd_soc_component_write(component, WM8900_REG_FLLCTL5,
 		     (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f));
 
 	if (fll_div.k) {
-		snd_soc_write(codec, WM8900_REG_FLLCTL2,
+		snd_soc_component_write(component, WM8900_REG_FLLCTL2,
 			     (fll_div.k >> 8) | 0x100);
-		snd_soc_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
+		snd_soc_component_write(component, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
 	} else
-		snd_soc_write(codec, WM8900_REG_FLLCTL2, 0);
+		snd_soc_component_write(component, WM8900_REG_FLLCTL2, 0);
 
 	if (fll_div.fll_slow_lock_ref)
-		snd_soc_write(codec, WM8900_REG_FLLCTL6,
+		snd_soc_component_write(component, WM8900_REG_FLLCTL6,
 			     WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF);
 	else
-		snd_soc_write(codec, WM8900_REG_FLLCTL6, 0);
+		snd_soc_component_write(component, WM8900_REG_FLLCTL6, 0);
 
-	snd_soc_update_bits(codec, WM8900_REG_POWER1,
+	snd_soc_component_update_bits(component, WM8900_REG_POWER1,
 			    WM8900_REG_POWER1_FLL_ENA,
 			    WM8900_REG_POWER1_FLL_ENA);
 
 reenable:
-	snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
+	snd_soc_component_update_bits(component, WM8900_REG_CLOCKING1,
 			    WM8900_REG_CLOCKING1_MCLK_SRC,
 			    WM8900_REG_CLOCKING1_MCLK_SRC);
 	return 0;
@@ -818,41 +818,41 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
 static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
+	return wm8900_set_fll(codec_dai->component, pll_id, freq_in, freq_out);
 }
 
 static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 				 int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	switch (div_id) {
 	case WM8900_BCLK_DIV:
-		snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
+		snd_soc_component_update_bits(component, WM8900_REG_CLOCKING1,
 				    WM8900_REG_CLOCKING1_BCLK_MASK, div);
 		break;
 	case WM8900_OPCLK_DIV:
-		snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
+		snd_soc_component_update_bits(component, WM8900_REG_CLOCKING1,
 				    WM8900_REG_CLOCKING1_OPCLK_MASK, div);
 		break;
 	case WM8900_DAC_LRCLK:
-		snd_soc_update_bits(codec, WM8900_REG_AUDIO4,
+		snd_soc_component_update_bits(component, WM8900_REG_AUDIO4,
 				    WM8900_LRC_MASK, div);
 		break;
 	case WM8900_ADC_LRCLK:
-		snd_soc_update_bits(codec, WM8900_REG_AUDIO3,
+		snd_soc_component_update_bits(component, WM8900_REG_AUDIO3,
 				    WM8900_LRC_MASK, div);
 		break;
 	case WM8900_DAC_CLKDIV:
-		snd_soc_update_bits(codec, WM8900_REG_CLOCKING2,
+		snd_soc_component_update_bits(component, WM8900_REG_CLOCKING2,
 				    WM8900_REG_CLOCKING2_DAC_CLKDIV, div);
 		break;
 	case WM8900_ADC_CLKDIV:
-		snd_soc_update_bits(codec, WM8900_REG_CLOCKING2,
+		snd_soc_component_update_bits(component, WM8900_REG_CLOCKING2,
 				    WM8900_REG_CLOCKING2_ADC_CLKDIV, div);
 		break;
 	case WM8900_LRCLK_MODE:
-		snd_soc_update_bits(codec, WM8900_REG_DACCTRL,
+		snd_soc_component_update_bits(component, WM8900_REG_DACCTRL,
 				    WM8900_REG_DACCTRL_AIF_LRCLKRATE, div);
 		break;
 	default:
@@ -866,13 +866,13 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int clocking1, aif1, aif3, aif4;
 
-	clocking1 = snd_soc_read(codec, WM8900_REG_CLOCKING1);
-	aif1 = snd_soc_read(codec, WM8900_REG_AUDIO1);
-	aif3 = snd_soc_read(codec, WM8900_REG_AUDIO3);
-	aif4 = snd_soc_read(codec, WM8900_REG_AUDIO4);
+	clocking1 = snd_soc_component_read32(component, WM8900_REG_CLOCKING1);
+	aif1 = snd_soc_component_read32(component, WM8900_REG_AUDIO1);
+	aif3 = snd_soc_component_read32(component, WM8900_REG_AUDIO3);
+	aif4 = snd_soc_component_read32(component, WM8900_REG_AUDIO4);
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -968,27 +968,27 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8900_REG_CLOCKING1, clocking1);
-	snd_soc_write(codec, WM8900_REG_AUDIO1, aif1);
-	snd_soc_write(codec, WM8900_REG_AUDIO3, aif3);
-	snd_soc_write(codec, WM8900_REG_AUDIO4, aif4);
+	snd_soc_component_write(component, WM8900_REG_CLOCKING1, clocking1);
+	snd_soc_component_write(component, WM8900_REG_AUDIO1, aif1);
+	snd_soc_component_write(component, WM8900_REG_AUDIO3, aif3);
+	snd_soc_component_write(component, WM8900_REG_AUDIO4, aif4);
 
 	return 0;
 }
 
 static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
-	reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
+	reg = snd_soc_component_read32(component, WM8900_REG_DACCTRL);
 
 	if (mute)
 		reg |= WM8900_REG_DACCTRL_MUTE;
 	else
 		reg &= ~WM8900_REG_DACCTRL_MUTE;
 
-	snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
+	snd_soc_component_write(component, WM8900_REG_DACCTRL, reg);
 
 	return 0;
 }
@@ -1028,7 +1028,7 @@ static struct snd_soc_dai_driver wm8900_dai = {
 	.ops = &wm8900_dai_ops,
 };
 
-static int wm8900_set_bias_level(struct snd_soc_codec *codec,
+static int wm8900_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	u16 reg;
@@ -1036,10 +1036,10 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		/* Enable thermal shutdown */
-		snd_soc_update_bits(codec, WM8900_REG_GPIO,
+		snd_soc_component_update_bits(component, WM8900_REG_GPIO,
 				    WM8900_REG_GPIO_TEMP_ENA,
 				    WM8900_REG_GPIO_TEMP_ENA);
-		snd_soc_update_bits(codec, WM8900_REG_ADDCTL,
+		snd_soc_component_update_bits(component, WM8900_REG_ADDCTL,
 				    WM8900_REG_ADDCTL_TEMP_SD,
 				    WM8900_REG_ADDCTL_TEMP_SD);
 		break;
@@ -1049,113 +1049,113 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_STANDBY:
 		/* Charge capacitors if initial power up */
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* STARTUP_BIAS_ENA on */
-			snd_soc_write(codec, WM8900_REG_POWER1,
+			snd_soc_component_write(component, WM8900_REG_POWER1,
 				     WM8900_REG_POWER1_STARTUP_BIAS_ENA);
 
 			/* Startup bias mode */
-			snd_soc_write(codec, WM8900_REG_ADDCTL,
+			snd_soc_component_write(component, WM8900_REG_ADDCTL,
 				     WM8900_REG_ADDCTL_BIAS_SRC |
 				     WM8900_REG_ADDCTL_VMID_SOFTST);
 
 			/* VMID 2x50k */
-			snd_soc_write(codec, WM8900_REG_POWER1,
+			snd_soc_component_write(component, WM8900_REG_POWER1,
 				     WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1);
 
 			/* Allow capacitors to charge */
 			schedule_timeout_interruptible(msecs_to_jiffies(400));
 
 			/* Enable bias */
-			snd_soc_write(codec, WM8900_REG_POWER1,
+			snd_soc_component_write(component, WM8900_REG_POWER1,
 				     WM8900_REG_POWER1_STARTUP_BIAS_ENA |
 				     WM8900_REG_POWER1_BIAS_ENA | 0x1);
 
-			snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
+			snd_soc_component_write(component, WM8900_REG_ADDCTL, 0);
 
-			snd_soc_write(codec, WM8900_REG_POWER1,
+			snd_soc_component_write(component, WM8900_REG_POWER1,
 				     WM8900_REG_POWER1_BIAS_ENA | 0x1);
 		}
 
-		reg = snd_soc_read(codec, WM8900_REG_POWER1);
-		snd_soc_write(codec, WM8900_REG_POWER1,
+		reg = snd_soc_component_read32(component, WM8900_REG_POWER1);
+		snd_soc_component_write(component, WM8900_REG_POWER1,
 			     (reg & WM8900_REG_POWER1_FLL_ENA) |
 			     WM8900_REG_POWER1_BIAS_ENA | 0x1);
-		snd_soc_write(codec, WM8900_REG_POWER2,
+		snd_soc_component_write(component, WM8900_REG_POWER2,
 			     WM8900_REG_POWER2_SYSCLK_ENA);
-		snd_soc_write(codec, WM8900_REG_POWER3, 0);
+		snd_soc_component_write(component, WM8900_REG_POWER3, 0);
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* Startup bias enable */
-		reg = snd_soc_read(codec, WM8900_REG_POWER1);
-		snd_soc_write(codec, WM8900_REG_POWER1,
+		reg = snd_soc_component_read32(component, WM8900_REG_POWER1);
+		snd_soc_component_write(component, WM8900_REG_POWER1,
 			     reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA);
-		snd_soc_write(codec, WM8900_REG_ADDCTL,
+		snd_soc_component_write(component, WM8900_REG_ADDCTL,
 			     WM8900_REG_ADDCTL_BIAS_SRC |
 			     WM8900_REG_ADDCTL_VMID_SOFTST);
 
 		/* Discharge caps */
-		snd_soc_write(codec, WM8900_REG_POWER1,
+		snd_soc_component_write(component, WM8900_REG_POWER1,
 			     WM8900_REG_POWER1_STARTUP_BIAS_ENA);
 		schedule_timeout_interruptible(msecs_to_jiffies(500));
 
 		/* Remove clamp */
-		snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
+		snd_soc_component_write(component, WM8900_REG_HPCTL1, 0);
 
 		/* Power down */
-		snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
-		snd_soc_write(codec, WM8900_REG_POWER1, 0);
-		snd_soc_write(codec, WM8900_REG_POWER2, 0);
-		snd_soc_write(codec, WM8900_REG_POWER3, 0);
+		snd_soc_component_write(component, WM8900_REG_ADDCTL, 0);
+		snd_soc_component_write(component, WM8900_REG_POWER1, 0);
+		snd_soc_component_write(component, WM8900_REG_POWER2, 0);
+		snd_soc_component_write(component, WM8900_REG_POWER3, 0);
 
 		/* Need to let things settle before stopping the clock
 		 * to ensure that restart works, see "Stopping the
 		 * master clock" in the datasheet. */
 		schedule_timeout_interruptible(msecs_to_jiffies(1));
-		snd_soc_write(codec, WM8900_REG_POWER2,
+		snd_soc_component_write(component, WM8900_REG_POWER2,
 			     WM8900_REG_POWER2_SYSCLK_ENA);
 		break;
 	}
 	return 0;
 }
 
-static int wm8900_suspend(struct snd_soc_codec *codec)
+static int wm8900_suspend(struct snd_soc_component *component)
 {
-	struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
+	struct wm8900_priv *wm8900 = snd_soc_component_get_drvdata(component);
 	int fll_out = wm8900->fll_out;
 	int fll_in  = wm8900->fll_in;
 	int ret;
 
 	/* Stop the FLL in an orderly fashion */
-	ret = wm8900_set_fll(codec, 0, 0, 0);
+	ret = wm8900_set_fll(component, 0, 0, 0);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to stop FLL\n");
+		dev_err(component->dev, "Failed to stop FLL\n");
 		return ret;
 	}
 
 	wm8900->fll_out = fll_out;
 	wm8900->fll_in = fll_in;
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
 	return 0;
 }
 
-static int wm8900_resume(struct snd_soc_codec *codec)
+static int wm8900_resume(struct snd_soc_component *component)
 {
-	struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
+	struct wm8900_priv *wm8900 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	wm8900_reset(codec);
+	wm8900_reset(component);
 
 	ret = regcache_sync(wm8900->regmap);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to restore cache: %d\n", ret);
+		dev_err(component->dev, "Failed to restore cache: %d\n", ret);
 		return ret;
 	}
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	/* Restart the FLL? */
 	if (wm8900->fll_out) {
@@ -1165,9 +1165,9 @@ static int wm8900_resume(struct snd_soc_codec *codec)
 		wm8900->fll_in = 0;
 		wm8900->fll_out = 0;
 
-		ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
+		ret = wm8900_set_fll(component, 0, fll_in, fll_out);
 		if (ret != 0) {
-			dev_err(codec->dev, "Failed to restart FLL\n");
+			dev_err(component->dev, "Failed to restart FLL\n");
 			return ret;
 		}
 	}
@@ -1175,53 +1175,54 @@ static int wm8900_resume(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int wm8900_probe(struct snd_soc_codec *codec)
+static int wm8900_probe(struct snd_soc_component *component)
 {
 	int reg;
 
-	reg = snd_soc_read(codec, WM8900_REG_ID);
+	reg = snd_soc_component_read32(component, WM8900_REG_ID);
 	if (reg != 0x8900) {
-		dev_err(codec->dev, "Device is not a WM8900 - ID %x\n", reg);
+		dev_err(component->dev, "Device is not a WM8900 - ID %x\n", reg);
 		return -ENODEV;
 	}
 
-	wm8900_reset(codec);
+	wm8900_reset(component);
 
 	/* Turn the chip on */
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	/* Latch the volume update bits */
-	snd_soc_update_bits(codec, WM8900_REG_LINVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_RINVOL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_LOUT1CTL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_ROUT1CTL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_LOUT2CTL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_ROUT2CTL, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_LDAC_DV, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_RDAC_DV, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_LADC_DV, 0x100, 0x100);
-	snd_soc_update_bits(codec, WM8900_REG_RADC_DV, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_LINVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_RINVOL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_LOUT1CTL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_ROUT1CTL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_LOUT2CTL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_ROUT2CTL, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_LDAC_DV, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_RDAC_DV, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_LADC_DV, 0x100, 0x100);
+	snd_soc_component_update_bits(component, WM8900_REG_RADC_DV, 0x100, 0x100);
 
 	/* Set the DAC and mixer output bias */
-	snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
+	snd_soc_component_write(component, WM8900_REG_OUTBIASCTL, 0x81);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
-	.probe =	wm8900_probe,
-	.suspend =	wm8900_suspend,
-	.resume =	wm8900_resume,
-	.set_bias_level = wm8900_set_bias_level,
-
-	.component_driver = {
-		.controls		= wm8900_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8900_snd_controls),
-		.dapm_widgets		= wm8900_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8900_dapm_widgets),
-		.dapm_routes		= wm8900_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8900_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8900 = {
+	.probe			= wm8900_probe,
+	.suspend		= wm8900_suspend,
+	.resume			= wm8900_resume,
+	.set_bias_level		= wm8900_set_bias_level,
+	.controls		= wm8900_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8900_snd_controls),
+	.dapm_widgets		= wm8900_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8900_dapm_widgets),
+	.dapm_routes		= wm8900_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8900_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8900_regmap = {
@@ -1253,15 +1254,14 @@ static int wm8900_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8900);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8900, &wm8900_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8900, &wm8900_dai, 1);
 
 	return ret;
 }
 
 static int wm8900_spi_remove(struct spi_device *spi)
 {
-	snd_soc_unregister_codec(&spi->dev);
 	return 0;
 }
 
@@ -1292,15 +1292,14 @@ static int wm8900_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8900);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8900, &wm8900_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8900, &wm8900_dai, 1);
 
 	return ret;
 }
 
 static int wm8900_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index cba90f2..7b8b6ef 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -270,15 +270,15 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
 static int wm8903_dcs_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		wm8903->dcs_pending |= 1 << w->shift;
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
+		snd_soc_component_update_bits(component, WM8903_DC_SERVO_0,
 				    1 << w->shift, 0);
 		break;
 	}
@@ -289,17 +289,16 @@ static int wm8903_dcs_event(struct snd_soc_dapm_widget *w,
 #define WM8903_DCS_MODE_WRITE_STOP 0
 #define WM8903_DCS_MODE_START_STOP 2
 
-static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
+static void wm8903_seq_notifier(struct snd_soc_component *component,
 				enum snd_soc_dapm_type event, int subseq)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 	int dcs_mode = WM8903_DCS_MODE_WRITE_STOP;
 	int i, val;
 
 	/* Complete any pending DC servo starts */
 	if (wm8903->dcs_pending) {
-		dev_dbg(codec->dev, "Starting DC servo for %x\n",
+		dev_dbg(component->dev, "Starting DC servo for %x\n",
 			wm8903->dcs_pending);
 
 		/* If we've no cached values then we need to do startup */
@@ -308,14 +307,14 @@ static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
 				continue;
 
 			if (wm8903->dcs_cache[i]) {
-				dev_dbg(codec->dev,
+				dev_dbg(component->dev,
 					"Restore DC servo %d value %x\n",
 					3 - i, wm8903->dcs_cache[i]);
 
-				snd_soc_write(codec, WM8903_DC_SERVO_4 + i,
+				snd_soc_component_write(component, WM8903_DC_SERVO_4 + i,
 					      wm8903->dcs_cache[i] & 0xff);
 			} else {
-				dev_dbg(codec->dev,
+				dev_dbg(component->dev,
 					"Calibrate DC servo %d\n", 3 - i);
 				dcs_mode = WM8903_DCS_MODE_START_STOP;
 			}
@@ -325,10 +324,10 @@ static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
 		if (wm8903->class_w_users)
 			dcs_mode = WM8903_DCS_MODE_START_STOP;
 
-		snd_soc_update_bits(codec, WM8903_DC_SERVO_2,
+		snd_soc_component_update_bits(component, WM8903_DC_SERVO_2,
 				    WM8903_DCS_MODE_MASK, dcs_mode);
 
-		snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
+		snd_soc_component_update_bits(component, WM8903_DC_SERVO_0,
 				    WM8903_DCS_ENA_MASK, wm8903->dcs_pending);
 
 		switch (dcs_mode) {
@@ -346,9 +345,9 @@ static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
 				if (!(wm8903->dcs_pending & (1 << i)))
 					continue;
 
-				val = snd_soc_read(codec,
+				val = snd_soc_component_read32(component,
 						   WM8903_DC_SERVO_READBACK_1 + i);
-				dev_dbg(codec->dev, "DC servo %d: %x\n",
+				dev_dbg(component->dev, "DC servo %d: %x\n",
 					3 - i, val);
 				wm8903->dcs_cache[i] = val;
 			}
@@ -374,18 +373,18 @@ static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
 static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 	u16 reg;
 	int ret;
 
-	reg = snd_soc_read(codec, WM8903_CLASS_W_0);
+	reg = snd_soc_component_read32(component, WM8903_CLASS_W_0);
 
 	/* Turn it off if we're about to enable bypass */
 	if (ucontrol->value.integer.value[0]) {
 		if (wm8903->class_w_users == 0) {
-			dev_dbg(codec->dev, "Disabling Class W\n");
-			snd_soc_write(codec, WM8903_CLASS_W_0, reg &
+			dev_dbg(component->dev, "Disabling Class W\n");
+			snd_soc_component_write(component, WM8903_CLASS_W_0, reg &
 				     ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
 		}
 		wm8903->class_w_users++;
@@ -397,14 +396,14 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
 	/* If we've just disabled the last bypass path turn Class W on */
 	if (!ucontrol->value.integer.value[0]) {
 		if (wm8903->class_w_users == 1) {
-			dev_dbg(codec->dev, "Enabling Class W\n");
-			snd_soc_write(codec, WM8903_CLASS_W_0, reg |
+			dev_dbg(component->dev, "Enabling Class W\n");
+			snd_soc_component_write(component, WM8903_CLASS_W_0, reg |
 				     WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
 		}
 		wm8903->class_w_users--;
 	}
 
-	dev_dbg(codec->dev, "Bypass use count now %d\n",
+	dev_dbg(component->dev, "Bypass use count now %d\n",
 		wm8903->class_w_users);
 
 	return ret;
@@ -417,9 +416,9 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
 
 static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
 
-static int wm8903_set_deemph(struct snd_soc_codec *codec)
+static int wm8903_set_deemph(struct snd_soc_component *component)
 {
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 	int val, i, best;
 
 	/* If we're using deemphasis select the nearest available sample
@@ -439,18 +438,18 @@ static int wm8903_set_deemph(struct snd_soc_codec *codec)
 		val = 0;
 	}
 
-	dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
+	dev_dbg(component->dev, "Set deemphasis %d (%dHz)\n",
 		best, wm8903_deemph[best]);
 
-	return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
+	return snd_soc_component_update_bits(component, WM8903_DAC_DIGITAL_1,
 				   WM8903_DEEMPH_MASK, val);
 }
 
 static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = wm8903->deemph;
 
@@ -460,8 +459,8 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
 static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 	unsigned int deemph = ucontrol->value.integer.value[0];
 	int ret = 0;
 
@@ -472,7 +471,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
 	if (wm8903->deemph != deemph) {
 		wm8903->deemph = deemph;
 
-		wm8903_set_deemph(codec);
+		wm8903_set_deemph(component);
 
 		ret = 1;
 	}
@@ -1101,7 +1100,7 @@ static const struct snd_soc_dapm_route wm8903_intercon[] = {
 	{ "Right Line Output PGA", NULL, "Charge Pump" },
 };
 
-static int wm8903_set_bias_level(struct snd_soc_codec *codec,
+static int wm8903_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
@@ -1109,14 +1108,14 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_VMID_CONTROL_0,
 				    WM8903_VMID_RES_MASK,
 				    WM8903_VMID_RES_50K);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_update_bits(component, WM8903_BIAS_CONTROL_0,
 					    WM8903_POBCTRL | WM8903_ISEL_MASK |
 					    WM8903_STARTUP_BIAS_ENA |
 					    WM8903_BIAS_ENA,
@@ -1124,22 +1123,22 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
 					    (2 << WM8903_ISEL_SHIFT) |
 					    WM8903_STARTUP_BIAS_ENA);
 
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					    WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
 					    WM8903_SPK_DISCHARGE,
 					    WM8903_SPK_DISCHARGE);
 
 			msleep(33);
 
-			snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
+			snd_soc_component_update_bits(component, WM8903_POWER_MANAGEMENT_5,
 					    WM8903_SPKL_ENA | WM8903_SPKR_ENA,
 					    WM8903_SPKL_ENA | WM8903_SPKR_ENA);
 
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					    WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
 					    WM8903_SPK_DISCHARGE, 0);
 
-			snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
+			snd_soc_component_update_bits(component, WM8903_VMID_CONTROL_0,
 					    WM8903_VMID_TIE_ENA |
 					    WM8903_BUFIO_ENA |
 					    WM8903_VMID_IO_ENA |
@@ -1155,57 +1154,57 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
 
 			msleep(129);
 
-			snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
+			snd_soc_component_update_bits(component, WM8903_POWER_MANAGEMENT_5,
 					    WM8903_SPKL_ENA | WM8903_SPKR_ENA,
 					    0);
 
-			snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
+			snd_soc_component_update_bits(component, WM8903_VMID_CONTROL_0,
 					    WM8903_VMID_SOFT_MASK, 0);
 
-			snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
+			snd_soc_component_update_bits(component, WM8903_VMID_CONTROL_0,
 					    WM8903_VMID_RES_MASK,
 					    WM8903_VMID_RES_50K);
 
-			snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
+			snd_soc_component_update_bits(component, WM8903_BIAS_CONTROL_0,
 					    WM8903_BIAS_ENA | WM8903_POBCTRL,
 					    WM8903_BIAS_ENA);
 
 			/* By default no bypass paths are enabled so
 			 * enable Class W support.
 			 */
-			dev_dbg(codec->dev, "Enabling Class W\n");
-			snd_soc_update_bits(codec, WM8903_CLASS_W_0,
+			dev_dbg(component->dev, "Enabling Class W\n");
+			snd_soc_component_update_bits(component, WM8903_CLASS_W_0,
 					    WM8903_CP_DYN_FREQ |
 					    WM8903_CP_DYN_V,
 					    WM8903_CP_DYN_FREQ |
 					    WM8903_CP_DYN_V);
 		}
 
-		snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_VMID_CONTROL_0,
 				    WM8903_VMID_RES_MASK,
 				    WM8903_VMID_RES_250K);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_BIAS_CONTROL_0,
 				    WM8903_BIAS_ENA, 0);
 
-		snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_VMID_CONTROL_0,
 				    WM8903_VMID_SOFT_MASK,
 				    2 << WM8903_VMID_SOFT_SHIFT);
 
-		snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_VMID_CONTROL_0,
 				    WM8903_VMID_BUF_ENA, 0);
 
 		msleep(290);
 
-		snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_VMID_CONTROL_0,
 				    WM8903_VMID_TIE_ENA | WM8903_BUFIO_ENA |
 				    WM8903_VMID_IO_ENA | WM8903_VMID_RES_MASK |
 				    WM8903_VMID_SOFT_MASK |
 				    WM8903_VMID_BUF_ENA, 0);
 
-		snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_BIAS_CONTROL_0,
 				    WM8903_STARTUP_BIAS_ENA, 0);
 		break;
 	}
@@ -1216,8 +1215,8 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
 static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 
 	wm8903->sysclk = freq;
 
@@ -1227,8 +1226,8 @@ static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
+	struct snd_soc_component *component = codec_dai->component;
+	u16 aif1 = snd_soc_component_read32(component, WM8903_AUDIO_INTERFACE_1);
 
 	aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK |
 		  WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV);
@@ -1306,24 +1305,24 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
+	snd_soc_component_write(component, WM8903_AUDIO_INTERFACE_1, aif1);
 
 	return 0;
 }
 
 static int wm8903_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
-	reg = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
+	reg = snd_soc_component_read32(component, WM8903_DAC_DIGITAL_1);
 
 	if (mute)
 		reg |= WM8903_DAC_MUTE;
 	else
 		reg &= ~WM8903_DAC_MUTE;
 
-	snd_soc_write(codec, WM8903_DAC_DIGITAL_1, reg);
+	snd_soc_component_write(component, WM8903_DAC_DIGITAL_1, reg);
 
 	return 0;
 }
@@ -1443,8 +1442,8 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 	int fs = params_rate(params);
 	int bclk;
 	int bclk_div;
@@ -1455,12 +1454,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
 	int cur_val;
 	int clk_sys;
 
-	u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
-	u16 aif2 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_2);
-	u16 aif3 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_3);
-	u16 clock0 = snd_soc_read(codec, WM8903_CLOCK_RATES_0);
-	u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
-	u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
+	u16 aif1 = snd_soc_component_read32(component, WM8903_AUDIO_INTERFACE_1);
+	u16 aif2 = snd_soc_component_read32(component, WM8903_AUDIO_INTERFACE_2);
+	u16 aif3 = snd_soc_component_read32(component, WM8903_AUDIO_INTERFACE_3);
+	u16 clock0 = snd_soc_component_read32(component, WM8903_CLOCK_RATES_0);
+	u16 clock1 = snd_soc_component_read32(component, WM8903_CLOCK_RATES_1);
+	u16 dac_digital1 = snd_soc_component_read32(component, WM8903_DAC_DIGITAL_1);
 
 	/* Enable sloping stopband filter for low sample rates */
 	if (fs <= 24000)
@@ -1479,7 +1478,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 
-	dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
+	dev_dbg(component->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
 	clock1 &= ~WM8903_SAMPLE_RATE_MASK;
 	clock1 |= sample_rates[dsp_config].value;
 
@@ -1505,7 +1504,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "MCLK = %dHz, target sample rate = %dHz\n",
+	dev_dbg(component->dev, "MCLK = %dHz, target sample rate = %dHz\n",
 		wm8903->sysclk, fs);
 
 	/* We may not have an MCLK which allows us to generate exactly
@@ -1540,12 +1539,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
 	clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
 	clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
 
-	dev_dbg(codec->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
+	dev_dbg(component->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
 		clk_sys_ratios[clk_config].rate,
 		clk_sys_ratios[clk_config].mode,
 		clk_sys_ratios[clk_config].div);
 
-	dev_dbg(codec->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
+	dev_dbg(component->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
 
 	/* We may not get quite the right frequency if using
 	 * approximate clocks so look for the closest match that is
@@ -1567,7 +1566,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
 	aif2 &= ~WM8903_BCLK_DIV_MASK;
 	aif3 &= ~WM8903_LRCLK_RATE_MASK;
 
-	dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
+	dev_dbg(component->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
 		bclk_divs[bclk_div].ratio / 10, bclk,
 		(clk_sys * 10) / bclk_divs[bclk_div].ratio);
 
@@ -1575,14 +1574,14 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
 	aif3 |= bclk / fs;
 
 	wm8903->fs = params_rate(params);
-	wm8903_set_deemph(codec);
+	wm8903_set_deemph(component);
 
-	snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
-	snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
-	snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
-	snd_soc_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
-	snd_soc_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
-	snd_soc_write(codec, WM8903_DAC_DIGITAL_1, dac_digital1);
+	snd_soc_component_write(component, WM8903_CLOCK_RATES_0, clock0);
+	snd_soc_component_write(component, WM8903_CLOCK_RATES_1, clock1);
+	snd_soc_component_write(component, WM8903_AUDIO_INTERFACE_1, aif1);
+	snd_soc_component_write(component, WM8903_AUDIO_INTERFACE_2, aif2);
+	snd_soc_component_write(component, WM8903_AUDIO_INTERFACE_3, aif3);
+	snd_soc_component_write(component, WM8903_DAC_DIGITAL_1, dac_digital1);
 
 	return 0;
 }
@@ -1590,7 +1589,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
 /**
  * wm8903_mic_detect - Enable microphone detection via the WM8903 IRQ
  *
- * @codec:  WM8903 codec
+ * @component:  WM8903 component
  * @jack:   jack to report detection events on
  * @det:    value to report for presence detection
  * @shrt:   value to report for short detection
@@ -1604,13 +1603,13 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
  * micdet_cfg in the platform data.  Using this function will force on
  * the microphone bias for the device.
  */
-int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+int wm8903_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,
 		      int det, int shrt)
 {
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 	int irq_mask = WM8903_MICDET_EINT | WM8903_MICSHRT_EINT;
 
-	dev_dbg(codec->dev, "Enabling microphone detection: %x %x\n",
+	dev_dbg(component->dev, "Enabling microphone detection: %x %x\n",
 		det, shrt);
 
 	/* Store the configuration */
@@ -1624,19 +1623,19 @@ int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 	if (shrt)
 		irq_mask &= ~WM8903_MICSHRT_EINT;
 
-	snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
+	snd_soc_component_update_bits(component, WM8903_INTERRUPT_STATUS_1_MASK,
 			    WM8903_MICDET_EINT | WM8903_MICSHRT_EINT,
 			    irq_mask);
 
 	if (det || shrt) {
 		/* Enable mic detection, this may not have been set through
 		 * platform data (eg, if the defaults are OK). */
-		snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
+		snd_soc_component_update_bits(component, WM8903_WRITE_SEQUENCER_0,
 				    WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
-		snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_MIC_BIAS_CONTROL_0,
 				    WM8903_MICDET_ENA, WM8903_MICDET_ENA);
 	} else {
-		snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8903_MIC_BIAS_CONTROL_0,
 				    WM8903_MICDET_ENA, 0);
 	}
 
@@ -1766,9 +1765,9 @@ static struct snd_soc_dai_driver wm8903_dai = {
 	.symmetric_rates = 1,
 };
 
-static int wm8903_resume(struct snd_soc_codec *codec)
+static int wm8903_resume(struct snd_soc_component *component)
 {
-	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+	struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component);
 
 	regcache_sync(wm8903->regmap);
 
@@ -1884,20 +1883,21 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903)
 }
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
-	.resume =	wm8903_resume,
-	.set_bias_level = wm8903_set_bias_level,
-	.seq_notifier = wm8903_seq_notifier,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8903_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8903_snd_controls),
-		.dapm_widgets		= wm8903_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8903_dapm_widgets),
-		.dapm_routes		= wm8903_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(wm8903_intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8903 = {
+	.resume			= wm8903_resume,
+	.set_bias_level		= wm8903_set_bias_level,
+	.seq_notifier		= wm8903_seq_notifier,
+	.controls		= wm8903_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8903_snd_controls),
+	.dapm_widgets		= wm8903_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8903_dapm_widgets),
+	.dapm_routes		= wm8903_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(wm8903_intercon),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8903_regmap = {
@@ -2176,8 +2176,8 @@ static int wm8903_i2c_probe(struct i2c_client *i2c,
 			   WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
 			   WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8903, &wm8903_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8903, &wm8903_dai, 1);
 	if (ret != 0)
 		goto err;
 
@@ -2197,7 +2197,6 @@ static int wm8903_i2c_remove(struct i2c_client *client)
 	if (client->irq)
 		free_irq(client->irq, wm8903);
 	wm8903_free_gpio(wm8903);
-	snd_soc_unregister_codec(&client->dev);
 
 	return 0;
 }
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index 0bb4a64..1301aa9 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -15,7 +15,7 @@
 
 #include <linux/i2c.h>
 
-extern int wm8903_mic_detect(struct snd_soc_codec *codec,
+extern int wm8903_mic_detect(struct snd_soc_component *component,
 			     struct snd_soc_jack *jack,
 			     int det, int shrt);
 
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 4fd350e8..20fdcae 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -316,31 +316,31 @@ static bool wm8904_readable_register(struct device *dev, unsigned int reg)
 	}
 }
 
-static int wm8904_configure_clocking(struct snd_soc_codec *codec)
+static int wm8904_configure_clocking(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	unsigned int clock0, clock2, rate;
 
 	/* Gate the clock while we're updating to avoid misclocking */
-	clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
-	snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
+	clock2 = snd_soc_component_read32(component, WM8904_CLOCK_RATES_2);
+	snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_2,
 			    WM8904_SYSCLK_SRC, 0);
 
 	/* This should be done on init() for bypass paths */
 	switch (wm8904->sysclk_src) {
 	case WM8904_CLK_MCLK:
-		dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
+		dev_dbg(component->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
 
 		clock2 &= ~WM8904_SYSCLK_SRC;
 		rate = wm8904->mclk_rate;
 
 		/* Ensure the FLL is stopped */
-		snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 				    WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
 		break;
 
 	case WM8904_CLK_FLL:
-		dev_dbg(codec->dev, "Using %dHz FLL clock\n",
+		dev_dbg(component->dev, "Using %dHz FLL clock\n",
 			wm8904->fll_fout);
 
 		clock2 |= WM8904_SYSCLK_SRC;
@@ -348,7 +348,7 @@ static int wm8904_configure_clocking(struct snd_soc_codec *codec)
 		break;
 
 	default:
-		dev_err(codec->dev, "System clock not configured\n");
+		dev_err(component->dev, "System clock not configured\n");
 		return -EINVAL;
 	}
 
@@ -361,40 +361,40 @@ static int wm8904_configure_clocking(struct snd_soc_codec *codec)
 		wm8904->sysclk_rate = rate;
 	}
 
-	snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
+	snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
 			    clock0);
 
-	snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
+	snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_2,
 			    WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2);
 
-	dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
+	dev_dbg(component->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
 
 	return 0;
 }
 
-static void wm8904_set_drc(struct snd_soc_codec *codec)
+static void wm8904_set_drc(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	struct wm8904_pdata *pdata = wm8904->pdata;
 	int save, i;
 
 	/* Save any enables; the configuration should clear them. */
-	save = snd_soc_read(codec, WM8904_DRC_0);
+	save = snd_soc_component_read32(component, WM8904_DRC_0);
 
 	for (i = 0; i < WM8904_DRC_REGS; i++)
-		snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff,
+		snd_soc_component_update_bits(component, WM8904_DRC_0 + i, 0xffff,
 				    pdata->drc_cfgs[wm8904->drc_cfg].regs[i]);
 
 	/* Reenable the DRC */
-	snd_soc_update_bits(codec, WM8904_DRC_0,
+	snd_soc_component_update_bits(component, WM8904_DRC_0,
 			    WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save);
 }
 
 static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	struct wm8904_pdata *pdata = wm8904->pdata;
 	int value = ucontrol->value.enumerated.item[0];
 
@@ -403,7 +403,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
 
 	wm8904->drc_cfg = value;
 
-	wm8904_set_drc(codec);
+	wm8904_set_drc(component);
 
 	return 0;
 }
@@ -411,17 +411,17 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
 static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
 
 	return 0;
 }
 
-static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
+static void wm8904_set_retune_mobile(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	struct wm8904_pdata *pdata = wm8904->pdata;
 	int best, best_val, save, i, cfg;
 
@@ -444,7 +444,7 @@ static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
 		}
 	}
 
-	dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
+	dev_dbg(component->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
 		pdata->retune_mobile_cfgs[best].name,
 		pdata->retune_mobile_cfgs[best].rate,
 		wm8904->fs);
@@ -452,20 +452,20 @@ static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
 	/* The EQ will be disabled while reconfiguring it, remember the
 	 * current configuration. 
 	 */
-	save = snd_soc_read(codec, WM8904_EQ1);
+	save = snd_soc_component_read32(component, WM8904_EQ1);
 
 	for (i = 0; i < WM8904_EQ_REGS; i++)
-		snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff,
+		snd_soc_component_update_bits(component, WM8904_EQ1 + i, 0xffff,
 				pdata->retune_mobile_cfgs[best].regs[i]);
 
-	snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save);
+	snd_soc_component_update_bits(component, WM8904_EQ1, WM8904_EQ_ENA, save);
 }
 
 static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	struct wm8904_pdata *pdata = wm8904->pdata;
 	int value = ucontrol->value.enumerated.item[0];
 
@@ -474,7 +474,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 
 	wm8904->retune_mobile_cfg = value;
 
-	wm8904_set_retune_mobile(codec);
+	wm8904_set_retune_mobile(component);
 
 	return 0;
 }
@@ -482,8 +482,8 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
 
@@ -492,9 +492,9 @@ static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 
 static int deemph_settings[] = { 0, 32000, 44100, 48000 };
 
-static int wm8904_set_deemph(struct snd_soc_codec *codec)
+static int wm8904_set_deemph(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	int val, i, best;
 
 	/* If we're using deemphasis select the nearest available sample 
@@ -513,17 +513,17 @@ static int wm8904_set_deemph(struct snd_soc_codec *codec)
 		val = 0;
 	}
 
-	dev_dbg(codec->dev, "Set deemphasis %d\n", val);
+	dev_dbg(component->dev, "Set deemphasis %d\n", val);
 
-	return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
+	return snd_soc_component_update_bits(component, WM8904_DAC_DIGITAL_1,
 				   WM8904_DEEMPH_MASK, val);
 }
 
 static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = wm8904->deemph;
 	return 0;
@@ -532,8 +532,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
 static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	unsigned int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
@@ -541,7 +541,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
 
 	wm8904->deemph = deemph;
 
-	return wm8904_set_deemph(codec);
+	return wm8904_set_deemph(component);
 }
 
 static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
@@ -572,7 +572,7 @@ static SOC_ENUM_SINGLE_DECL(hpf_mode, WM8904_ADC_DIGITAL_0, 5,
 static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int val;
 	int ret;
 
@@ -585,7 +585,7 @@ static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol,
 	else
 		val = WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5;
 
-	snd_soc_update_bits(codec, WM8904_ADC_TEST_0,
+	snd_soc_component_update_bits(component, WM8904_ADC_TEST_0,
 			    WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5,
 			    val);
 
@@ -673,8 +673,8 @@ static int cp_event(struct snd_soc_dapm_widget *w,
 static int sysclk_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -685,11 +685,11 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
 		 */
 		switch (wm8904->sysclk_src) {
 		case WM8904_CLK_FLL:
-			snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+			snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 					    WM8904_FLL_OSC_ENA,
 					    WM8904_FLL_OSC_ENA);
 
-			snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+			snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 					    WM8904_FLL_ENA,
 					    WM8904_FLL_ENA);
 			break;
@@ -700,7 +700,7 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 				    WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
 		break;
 	}
@@ -711,8 +711,8 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
 static int out_pga_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	int reg, val;
 	int dcs_mask;
 	int dcs_l, dcs_r;
@@ -751,43 +751,43 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		/* Power on the PGAs */
-		snd_soc_update_bits(codec, pwr_reg,
+		snd_soc_component_update_bits(component, pwr_reg,
 				    WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
 				    WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA);
 
 		/* Power on the amplifier */
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 				    WM8904_HPL_ENA | WM8904_HPR_ENA,
 				    WM8904_HPL_ENA | WM8904_HPR_ENA);
 
 
 		/* Enable the first stage */
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 				    WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
 				    WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);
 
 		/* Power up the DC servo */
-		snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
+		snd_soc_component_update_bits(component, WM8904_DC_SERVO_0,
 				    dcs_mask, dcs_mask);
 
 		/* Either calibrate the DC servo or restore cached state
 		 * if we have that.
 		 */
 		if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
-			dev_dbg(codec->dev, "Restoring DC servo state\n");
+			dev_dbg(component->dev, "Restoring DC servo state\n");
 
-			snd_soc_write(codec, dcs_l_reg,
+			snd_soc_component_write(component, dcs_l_reg,
 				      wm8904->dcs_state[dcs_l]);
-			snd_soc_write(codec, dcs_r_reg,
+			snd_soc_component_write(component, dcs_r_reg,
 				      wm8904->dcs_state[dcs_r]);
 
-			snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);
+			snd_soc_component_write(component, WM8904_DC_SERVO_1, dcs_mask);
 
 			timeout = 20;
 		} else {
-			dev_dbg(codec->dev, "Calibrating DC servo\n");
+			dev_dbg(component->dev, "Calibrating DC servo\n");
 
-			snd_soc_write(codec, WM8904_DC_SERVO_1,
+			snd_soc_component_write(component, WM8904_DC_SERVO_1,
 				dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);
 
 			timeout = 500;
@@ -796,7 +796,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 		/* Wait for DC servo to complete */
 		dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
 		do {
-			val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
+			val = snd_soc_component_read32(component, WM8904_DC_SERVO_READBACK_0);
 			if ((val & dcs_mask) == dcs_mask)
 				break;
 
@@ -804,19 +804,19 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 		} while (--timeout);
 
 		if ((val & dcs_mask) != dcs_mask)
-			dev_warn(codec->dev, "DC servo timed out\n");
+			dev_warn(component->dev, "DC servo timed out\n");
 		else
-			dev_dbg(codec->dev, "DC servo ready\n");
+			dev_dbg(component->dev, "DC servo ready\n");
 
 		/* Enable the output stage */
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 				    WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
 				    WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
 		break;
 
 	case SND_SOC_DAPM_POST_PMU:
 		/* Unshort the output itself */
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 				    WM8904_HPL_RMV_SHORT |
 				    WM8904_HPR_RMV_SHORT,
 				    WM8904_HPL_RMV_SHORT |
@@ -826,7 +826,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 
 	case SND_SOC_DAPM_PRE_PMD:
 		/* Short the output */
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 				    WM8904_HPL_RMV_SHORT |
 				    WM8904_HPR_RMV_SHORT, 0);
 		break;
@@ -834,21 +834,21 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_POST_PMD:
 		/* Cache the DC servo configuration; this will be
 		 * invalidated if we change the configuration. */
-		wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg);
-		wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg);
+		wm8904->dcs_state[dcs_l] = snd_soc_component_read32(component, dcs_l_reg);
+		wm8904->dcs_state[dcs_r] = snd_soc_component_read32(component, dcs_r_reg);
 
-		snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
+		snd_soc_component_update_bits(component, WM8904_DC_SERVO_0,
 				    dcs_mask, 0);
 
 		/* Disable the amplifier input and output stages */
-		snd_soc_update_bits(codec, reg,
+		snd_soc_component_update_bits(component, reg,
 				    WM8904_HPL_ENA | WM8904_HPR_ENA |
 				    WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY |
 				    WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
 				    0);
 
 		/* PGAs too */
-		snd_soc_update_bits(codec, pwr_reg,
+		snd_soc_component_update_bits(component, pwr_reg,
 				    WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
 				    0);
 		break;
@@ -1165,10 +1165,10 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = {
 	{ "LINER PGA", NULL, "DACR" },
 };
 
-static int wm8904_add_widgets(struct snd_soc_codec *codec)
+static int wm8904_add_widgets(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets,
 				  ARRAY_SIZE(wm8904_core_dapm_widgets));
@@ -1177,11 +1177,11 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
 
 	switch (wm8904->devtype) {
 	case WM8904:
-		snd_soc_add_codec_controls(codec, wm8904_adc_snd_controls,
+		snd_soc_add_component_controls(component, wm8904_adc_snd_controls,
 				     ARRAY_SIZE(wm8904_adc_snd_controls));
-		snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
+		snd_soc_add_component_controls(component, wm8904_dac_snd_controls,
 				     ARRAY_SIZE(wm8904_dac_snd_controls));
-		snd_soc_add_codec_controls(codec, wm8904_snd_controls,
+		snd_soc_add_component_controls(component, wm8904_snd_controls,
 				     ARRAY_SIZE(wm8904_snd_controls));
 
 		snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
@@ -1200,7 +1200,7 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
 		break;
 
 	case WM8912:
-		snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
+		snd_soc_add_component_controls(component, wm8904_dac_snd_controls,
 				     ARRAY_SIZE(wm8904_dac_snd_controls));
 
 		snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
@@ -1278,8 +1278,8 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	int ret, i, best, best_val, cur_val;
 	unsigned int aif1 = 0;
 	unsigned int aif2 = 0;
@@ -1290,7 +1290,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
 	/* What BCLK do we need? */
 	wm8904->fs = params_rate(params);
 	if (wm8904->tdm_slots) {
-		dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
+		dev_dbg(component->dev, "Configuring for %d %d bit TDM slots\n",
 			wm8904->tdm_slots, wm8904->tdm_width);
 		wm8904->bclk = snd_soc_calc_bclk(wm8904->fs,
 						 wm8904->tdm_width, 2,
@@ -1316,9 +1316,9 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
 	}
 
 
-	dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk);
+	dev_dbg(component->dev, "Target BCLK is %dHz\n", wm8904->bclk);
 
-	ret = wm8904_configure_clocking(codec);
+	ret = wm8904_configure_clocking(component);
 	if (ret != 0)
 		return ret;
 
@@ -1334,7 +1334,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
 			best_val = cur_val;
 		}
 	}
-	dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
+	dev_dbg(component->dev, "Selected CLK_SYS_RATIO of %d\n",
 		clk_sys_rates[best].ratio);
 	clock1 |= (clk_sys_rates[best].clk_sys_rate
 		   << WM8904_CLK_SYS_RATE_SHIFT);
@@ -1350,7 +1350,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
 			best_val = cur_val;
 		}
 	}
-	dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
+	dev_dbg(component->dev, "Selected SAMPLE_RATE of %dHz\n",
 		sample_rates[best].rate);
 	clock1 |= (sample_rates[best].sample_rate
 		   << WM8904_SAMPLE_RATE_SHIFT);
@@ -1373,30 +1373,30 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 	wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div;
-	dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
+	dev_dbg(component->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
 		bclk_divs[best].div, wm8904->bclk);
 	aif2 |= bclk_divs[best].bclk_div;
 
 	/* LRCLK is a simple fraction of BCLK */
-	dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
+	dev_dbg(component->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
 	aif3 |= wm8904->bclk / wm8904->fs;
 
 	/* Apply the settings */
-	snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
+	snd_soc_component_update_bits(component, WM8904_DAC_DIGITAL_1,
 			    WM8904_DAC_SB_FILT, dac_digital1);
-	snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
+	snd_soc_component_update_bits(component, WM8904_AUDIO_INTERFACE_1,
 			    WM8904_AIF_WL_MASK, aif1);
-	snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2,
+	snd_soc_component_update_bits(component, WM8904_AUDIO_INTERFACE_2,
 			    WM8904_BCLK_DIV_MASK, aif2);
-	snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
+	snd_soc_component_update_bits(component, WM8904_AUDIO_INTERFACE_3,
 			    WM8904_LRCLK_RATE_MASK, aif3);
-	snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1,
+	snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_1,
 			    WM8904_SAMPLE_RATE_MASK |
 			    WM8904_CLK_SYS_RATE_MASK, clock1);
 
 	/* Update filters for the new settings */
-	wm8904_set_retune_mobile(codec);
-	wm8904_set_deemph(codec);
+	wm8904_set_retune_mobile(component);
+	wm8904_set_deemph(component);
 
 	return 0;
 }
@@ -1405,8 +1405,8 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
 static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 			     unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8904_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8904_priv *priv = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case WM8904_CLK_MCLK:
@@ -1424,14 +1424,14 @@ static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 
 	dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
 
-	wm8904_configure_clocking(codec);
+	wm8904_configure_clocking(component);
 
 	return 0;
 }
 
 static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	unsigned int aif1 = 0;
 	unsigned int aif3 = 0;
 
@@ -1508,10 +1508,10 @@ static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
+	snd_soc_component_update_bits(component, WM8904_AUDIO_INTERFACE_1,
 			    WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV |
 			    WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1);
-	snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
+	snd_soc_component_update_bits(component, WM8904_AUDIO_INTERFACE_3,
 			    WM8904_LRCLK_DIR, aif3);
 
 	return 0;
@@ -1521,8 +1521,8 @@ static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			       unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	int aif1 = 0;
 
 	/* Don't need to validate anything if we're turning off TDM */
@@ -1560,7 +1560,7 @@ static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	wm8904->tdm_width = slot_width;
 	wm8904->tdm_slots = slots / 2;
 
-	snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
+	snd_soc_component_update_bits(component, WM8904_AUDIO_INTERFACE_1,
 			    WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN |
 			    WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1);
 
@@ -1678,8 +1678,8 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
 			  unsigned int Fref, unsigned int Fout)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	struct _fll_div fll_div;
 	int ret, val;
 	int clock2, fll1;
@@ -1689,19 +1689,19 @@ static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
 	    Fout == wm8904->fll_fout)
 		return 0;
 
-	clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
+	clock2 = snd_soc_component_read32(component, WM8904_CLOCK_RATES_2);
 
 	if (Fout == 0) {
-		dev_dbg(codec->dev, "FLL disabled\n");
+		dev_dbg(component->dev, "FLL disabled\n");
 
 		wm8904->fll_fref = 0;
 		wm8904->fll_fout = 0;
 
 		/* Gate SYSCLK to avoid glitches */
-		snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
+		snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_2,
 				    WM8904_CLK_SYS_ENA, 0);
 
-		snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 				    WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
 
 		goto out;
@@ -1718,7 +1718,7 @@ static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
 		break;
 
 	case WM8904_FLL_FREE_RUNNING:
-		dev_dbg(codec->dev, "Using free running FLL\n");
+		dev_dbg(component->dev, "Using free running FLL\n");
 		/* Force 12MHz and output/4 for now */
 		Fout = 12000000;
 		Fref = 12000000;
@@ -1728,20 +1728,20 @@ static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
 		break;
 
 	default:
-		dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
+		dev_err(component->dev, "Unknown FLL ID %d\n", fll_id);
 		return -EINVAL;
 	}
 
 	/* Save current state then disable the FLL and SYSCLK to avoid
 	 * misclocking */
-	fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1);
-	snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
+	fll1 = snd_soc_component_read32(component, WM8904_FLL_CONTROL_1);
+	snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_2,
 			    WM8904_CLK_SYS_ENA, 0);
-	snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+	snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 			    WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
 
 	/* Unlock forced oscilator control to switch it on/off */
-	snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
+	snd_soc_component_update_bits(component, WM8904_CONTROL_INTERFACE_TEST_1,
 			    WM8904_USER_KEY, WM8904_USER_KEY);
 
 	if (fll_id == WM8904_FLL_FREE_RUNNING) {
@@ -1750,24 +1750,24 @@ static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
 		val = 0;
 	}
 
-	snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
+	snd_soc_component_update_bits(component, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
 			    val);
-	snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
+	snd_soc_component_update_bits(component, WM8904_CONTROL_INTERFACE_TEST_1,
 			    WM8904_USER_KEY, 0);
 
 	switch (fll_id) {
 	case WM8904_FLL_MCLK:
-		snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
+		snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_5,
 				    WM8904_FLL_CLK_REF_SRC_MASK, 0);
 		break;
 
 	case WM8904_FLL_LRCLK:
-		snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
+		snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_5,
 				    WM8904_FLL_CLK_REF_SRC_MASK, 1);
 		break;
 
 	case WM8904_FLL_BCLK:
-		snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
+		snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_5,
 				    WM8904_FLL_CLK_REF_SRC_MASK, 2);
 		break;
 	}
@@ -1776,39 +1776,39 @@ static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
 		val = WM8904_FLL_FRACN_ENA;
 	else
 		val = 0;
-	snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+	snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 			    WM8904_FLL_FRACN_ENA, val);
 
-	snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2,
+	snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_2,
 			    WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK,
 			    (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) |
 			    (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT));
 
-	snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k);
+	snd_soc_component_write(component, WM8904_FLL_CONTROL_3, fll_div.k);
 
-	snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
+	snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
 			    fll_div.n << WM8904_FLL_N_SHIFT);
 
-	snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
+	snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_5,
 			    WM8904_FLL_CLK_REF_DIV_MASK,
 			    fll_div.fll_clk_ref_div 
 			    << WM8904_FLL_CLK_REF_DIV_SHIFT);
 
-	dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
+	dev_dbg(component->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
 
 	wm8904->fll_fref = Fref;
 	wm8904->fll_fout = Fout;
 	wm8904->fll_src = source;
 
 	/* Enable the FLL if it was previously active */
-	snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+	snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 			    WM8904_FLL_OSC_ENA, fll1);
-	snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
+	snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
 			    WM8904_FLL_ENA, fll1);
 
 out:
 	/* Reenable SYSCLK if it was previously active */
-	snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
+	snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_2,
 			    WM8904_CLK_SYS_ENA, clock2);
 
 	return 0;
@@ -1816,7 +1816,7 @@ static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
 
 static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int val;
 
 	if (mute)
@@ -1824,15 +1824,15 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 	else
 		val = 0;
 
-	snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
+	snd_soc_component_update_bits(component, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
 
 	return 0;
 }
 
-static int wm8904_set_bias_level(struct snd_soc_codec *codec,
+static int wm8904_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1844,21 +1844,21 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID resistance 2*50k */
-		snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8904_VMID_CONTROL_0,
 				    WM8904_VMID_RES_MASK,
 				    0x1 << WM8904_VMID_RES_SHIFT);
 
 		/* Normal bias current */
-		snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8904_BIAS_CONTROL_0,
 				    WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
 						    wm8904->supplies);
 			if (ret != 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n",
 					ret);
 				return ret;
@@ -1868,11 +1868,11 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
 			regcache_sync(wm8904->regmap);
 
 			/* Enable bias */
-			snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
+			snd_soc_component_update_bits(component, WM8904_BIAS_CONTROL_0,
 					    WM8904_BIAS_ENA, WM8904_BIAS_ENA);
 
 			/* Enable VMID, VMID buffering, 2*5k resistance */
-			snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
+			snd_soc_component_update_bits(component, WM8904_VMID_CONTROL_0,
 					    WM8904_VMID_ENA |
 					    WM8904_VMID_RES_MASK,
 					    WM8904_VMID_ENA |
@@ -1883,22 +1883,22 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
 		}
 
 		/* Maintain VMID with 2*250k */
-		snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8904_VMID_CONTROL_0,
 				    WM8904_VMID_RES_MASK,
 				    0x2 << WM8904_VMID_RES_SHIFT);
 
 		/* Bias current *0.5 */
-		snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8904_BIAS_CONTROL_0,
 				    WM8904_ISEL_MASK, 0);
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* Turn off VMID */
-		snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8904_VMID_CONTROL_0,
 				    WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0);
 
 		/* Stop bias generation */
-		snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
+		snd_soc_component_update_bits(component, WM8904_BIAS_CONTROL_0,
 				    WM8904_BIAS_ENA, 0);
 
 		regcache_cache_only(wm8904->regmap, true);
@@ -1946,9 +1946,9 @@ static struct snd_soc_dai_driver wm8904_dai = {
 	.symmetric_rates = 1,
 };
 
-static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
+static void wm8904_handle_retune_mobile_pdata(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	struct wm8904_pdata *pdata = wm8904->pdata;
 	struct snd_kcontrol_new control =
 		SOC_ENUM_EXT("EQ Mode",
@@ -1991,31 +1991,31 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
 		wm8904->retune_mobile_texts = t;
 	}
 
-	dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
+	dev_dbg(component->dev, "Allocated %d unique ReTune Mobile names\n",
 		wm8904->num_retune_mobile_texts);
 
 	wm8904->retune_mobile_enum.items = wm8904->num_retune_mobile_texts;
 	wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
 
-	ret = snd_soc_add_codec_controls(codec, &control, 1);
+	ret = snd_soc_add_component_controls(component, &control, 1);
 	if (ret != 0)
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Failed to add ReTune Mobile control: %d\n", ret);
 }
 
-static void wm8904_handle_pdata(struct snd_soc_codec *codec)
+static void wm8904_handle_pdata(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	struct wm8904_pdata *pdata = wm8904->pdata;
 	int ret, i;
 
 	if (!pdata) {
-		snd_soc_add_codec_controls(codec, wm8904_eq_controls,
+		snd_soc_add_component_controls(component, wm8904_eq_controls,
 				     ARRAY_SIZE(wm8904_eq_controls));
 		return;
 	}
 
-	dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
+	dev_dbg(component->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
 
 	if (pdata->num_drc_cfgs) {
 		struct snd_kcontrol_new control =
@@ -2034,28 +2034,28 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
 		wm8904->drc_enum.items = pdata->num_drc_cfgs;
 		wm8904->drc_enum.texts = wm8904->drc_texts;
 
-		ret = snd_soc_add_codec_controls(codec, &control, 1);
+		ret = snd_soc_add_component_controls(component, &control, 1);
 		if (ret != 0)
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to add DRC mode control: %d\n", ret);
 
-		wm8904_set_drc(codec);
+		wm8904_set_drc(component);
 	}
 
-	dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
+	dev_dbg(component->dev, "%d ReTune Mobile configurations\n",
 		pdata->num_retune_mobile_cfgs);
 
 	if (pdata->num_retune_mobile_cfgs)
-		wm8904_handle_retune_mobile_pdata(codec);
+		wm8904_handle_retune_mobile_pdata(component);
 	else
-		snd_soc_add_codec_controls(codec, wm8904_eq_controls,
+		snd_soc_add_component_controls(component, wm8904_eq_controls,
 				     ARRAY_SIZE(wm8904_eq_controls));
 }
 
 
-static int wm8904_probe(struct snd_soc_codec *codec)
+static int wm8904_probe(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 
 	switch (wm8904->devtype) {
 	case WM8904:
@@ -2064,33 +2064,33 @@ static int wm8904_probe(struct snd_soc_codec *codec)
 		memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture));
 		break;
 	default:
-		dev_err(codec->dev, "Unknown device type %d\n",
+		dev_err(component->dev, "Unknown device type %d\n",
 			wm8904->devtype);
 		return -EINVAL;
 	}
 
-	wm8904_handle_pdata(codec);
+	wm8904_handle_pdata(component);
 
-	wm8904_add_widgets(codec);
+	wm8904_add_widgets(component);
 
 	return 0;
 }
 
-static int wm8904_remove(struct snd_soc_codec *codec)
+static void wm8904_remove(struct snd_soc_component *component)
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 
 	kfree(wm8904->retune_mobile_texts);
 	kfree(wm8904->drc_texts);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
-	.probe =	wm8904_probe,
-	.remove =	wm8904_remove,
-	.set_bias_level = wm8904_set_bias_level,
-	.idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_wm8904 = {
+	.probe			= wm8904_probe,
+	.remove			= wm8904_remove,
+	.set_bias_level		= wm8904_set_bias_level,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8904_regmap = {
@@ -2265,8 +2265,8 @@ static int wm8904_i2c_probe(struct i2c_client *i2c,
 	regcache_cache_only(wm8904->regmap, true);
 	regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8904, &wm8904_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8904, &wm8904_dai, 1);
 	if (ret != 0)
 		return ret;
 
@@ -2277,12 +2277,6 @@ static int wm8904_i2c_probe(struct i2c_client *i2c,
 	return ret;
 }
 
-static int wm8904_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8904_i2c_id[] = {
 	{ "wm8904", WM8904 },
 	{ "wm8912", WM8912 },
@@ -2297,7 +2291,6 @@ static struct i2c_driver wm8904_i2c_driver = {
 		.of_match_table = of_match_ptr(wm8904_of_match),
 	},
 	.probe =    wm8904_i2c_probe,
-	.remove =   wm8904_i2c_remove,
 	.id_table = wm8904_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index b593562..be4fce0 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -334,14 +334,14 @@ static const struct snd_soc_dapm_route wm8940_dapm_routes[] = {
 	{"ADC", NULL, "Boost Mixer"},
 };
 
-#define wm8940_reset(c) snd_soc_write(c, WM8940_SOFTRESET, 0);
+#define wm8940_reset(c) snd_soc_component_write(c, WM8940_SOFTRESET, 0);
 
 static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFE67;
-	u16 clk = snd_soc_read(codec, WM8940_CLOCK) & 0x1fe;
+	struct snd_soc_component *component = codec_dai->component;
+	u16 iface = snd_soc_component_read32(component, WM8940_IFACE) & 0xFE67;
+	u16 clk = snd_soc_component_read32(component, WM8940_CLOCK) & 0x1fe;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM:
@@ -352,7 +352,7 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	default:
 		return -EINVAL;
 	}
-	snd_soc_write(codec, WM8940_CLOCK, clk);
+	snd_soc_component_write(component, WM8940_CLOCK, clk);
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
@@ -385,7 +385,7 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		break;
 	}
 
-	snd_soc_write(codec, WM8940_IFACE, iface);
+	snd_soc_component_write(component, WM8940_IFACE, iface);
 
 	return 0;
 }
@@ -394,10 +394,10 @@ static int wm8940_i2s_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;
-	u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
-	u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
-	u16 companding =  snd_soc_read(codec,
+	struct snd_soc_component *component = dai->component;
+	u16 iface = snd_soc_component_read32(component, WM8940_IFACE) & 0xFD9F;
+	u16 addcntrl = snd_soc_component_read32(component, WM8940_ADDCNTRL) & 0xFFF1;
+	u16 companding =  snd_soc_component_read32(component,
 						WM8940_COMPANDINGCTL) & 0xFFDF;
 	int ret;
 
@@ -426,7 +426,7 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
 	case 48000:
 		break;
 	}
-	ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
+	ret = snd_soc_component_write(component, WM8940_ADDCNTRL, addcntrl);
 	if (ret)
 		goto error_ret;
 
@@ -446,10 +446,10 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
 		iface |= (3 << 5);
 		break;
 	}
-	ret = snd_soc_write(codec, WM8940_COMPANDINGCTL, companding);
+	ret = snd_soc_component_write(component, WM8940_COMPANDINGCTL, companding);
 	if (ret)
 		goto error_ret;
-	ret = snd_soc_write(codec, WM8940_IFACE, iface);
+	ret = snd_soc_component_write(component, WM8940_IFACE, iface);
 
 error_ret:
 	return ret;
@@ -457,21 +457,21 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8940_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8940_DAC) & 0xffbf;
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8940_DAC) & 0xffbf;
 
 	if (mute)
 		mute_reg |= 0x40;
 
-	return snd_soc_write(codec, WM8940_DAC, mute_reg);
+	return snd_soc_component_write(component, WM8940_DAC, mute_reg);
 }
 
-static int wm8940_set_bias_level(struct snd_soc_codec *codec,
+static int wm8940_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
+	struct wm8940_priv *wm8940 = snd_soc_component_get_drvdata(component);
 	u16 val;
-	u16 pwr_reg = snd_soc_read(codec, WM8940_POWER1) & 0x1F0;
+	u16 pwr_reg = snd_soc_component_read32(component, WM8940_POWER1) & 0x1F0;
 	int ret = 0;
 
 	switch (level) {
@@ -479,23 +479,23 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
 		/* ensure bufioen and biasen */
 		pwr_reg |= (1 << 2) | (1 << 3);
 		/* Enable thermal shutdown */
-		val = snd_soc_read(codec, WM8940_OUTPUTCTL);
-		ret = snd_soc_write(codec, WM8940_OUTPUTCTL, val | 0x2);
+		val = snd_soc_component_read32(component, WM8940_OUTPUTCTL);
+		ret = snd_soc_component_write(component, WM8940_OUTPUTCTL, val | 0x2);
 		if (ret)
 			break;
 		/* set vmid to 75k */
-		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
+		ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg | 0x1);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		/* ensure bufioen and biasen */
 		pwr_reg |= (1 << 2) | (1 << 3);
-		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
+		ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg | 0x1);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regcache_sync(wm8940->regmap);
 			if (ret < 0) {
-				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				dev_err(component->dev, "Failed to sync cache: %d\n", ret);
 				return ret;
 			}
 		}
@@ -503,10 +503,10 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
 		/* ensure bufioen and biasen */
 		pwr_reg |= (1 << 2) | (1 << 3);
 		/* set vmid to 300k for standby */
-		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x2);
+		ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg | 0x2);
 		break;
 	case SND_SOC_BIAS_OFF:
-		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg);
+		ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg);
 		break;
 	}
 
@@ -576,40 +576,40 @@ static void pll_factors(unsigned int target, unsigned int source)
 static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
 	/* Turn off PLL */
-	reg = snd_soc_read(codec, WM8940_POWER1);
-	snd_soc_write(codec, WM8940_POWER1, reg & 0x1df);
+	reg = snd_soc_component_read32(component, WM8940_POWER1);
+	snd_soc_component_write(component, WM8940_POWER1, reg & 0x1df);
 
 	if (freq_in == 0 || freq_out == 0) {
 		/* Clock CODEC directly from MCLK */
-		reg = snd_soc_read(codec, WM8940_CLOCK);
-		snd_soc_write(codec, WM8940_CLOCK, reg & 0x0ff);
+		reg = snd_soc_component_read32(component, WM8940_CLOCK);
+		snd_soc_component_write(component, WM8940_CLOCK, reg & 0x0ff);
 		/* Pll power down */
-		snd_soc_write(codec, WM8940_PLLN, (1 << 7));
+		snd_soc_component_write(component, WM8940_PLLN, (1 << 7));
 		return 0;
 	}
 
 	/* Pll is followed by a frequency divide by 4 */
 	pll_factors(freq_out*4, freq_in);
 	if (pll_div.k)
-		snd_soc_write(codec, WM8940_PLLN,
+		snd_soc_component_write(component, WM8940_PLLN,
 			     (pll_div.pre_scale << 4) | pll_div.n | (1 << 6));
 	else /* No factional component */
-		snd_soc_write(codec, WM8940_PLLN,
+		snd_soc_component_write(component, WM8940_PLLN,
 			     (pll_div.pre_scale << 4) | pll_div.n);
-	snd_soc_write(codec, WM8940_PLLK1, pll_div.k >> 18);
-	snd_soc_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
-	snd_soc_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff);
+	snd_soc_component_write(component, WM8940_PLLK1, pll_div.k >> 18);
+	snd_soc_component_write(component, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
+	snd_soc_component_write(component, WM8940_PLLK3, pll_div.k & 0x1ff);
 	/* Enable the PLL */
-	reg = snd_soc_read(codec, WM8940_POWER1);
-	snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
+	reg = snd_soc_component_read32(component, WM8940_POWER1);
+	snd_soc_component_write(component, WM8940_POWER1, reg | 0x020);
 
 	/* Run CODEC from PLL instead of MCLK */
-	reg = snd_soc_read(codec, WM8940_CLOCK);
-	snd_soc_write(codec, WM8940_CLOCK, reg | 0x100);
+	reg = snd_soc_component_read32(component, WM8940_CLOCK);
+	snd_soc_component_write(component, WM8940_CLOCK, reg | 0x100);
 
 	return 0;
 }
@@ -617,8 +617,8 @@ static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8940_priv *wm8940 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case 11289600:
@@ -635,22 +635,22 @@ static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 				 int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 	int ret = 0;
 
 	switch (div_id) {
 	case WM8940_BCLKDIV:
-		reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3;
-		ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2));
+		reg = snd_soc_component_read32(component, WM8940_CLOCK) & 0xFFE3;
+		ret = snd_soc_component_write(component, WM8940_CLOCK, reg | (div << 2));
 		break;
 	case WM8940_MCLKDIV:
-		reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFF1F;
-		ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
+		reg = snd_soc_component_read32(component, WM8940_CLOCK) & 0xFF1F;
+		ret = snd_soc_component_write(component, WM8940_CLOCK, reg | (div << 5));
 		break;
 	case WM8940_OPCLKDIV:
-		reg = snd_soc_read(codec, WM8940_GPIO) & 0xFFCF;
-		ret = snd_soc_write(codec, WM8940_GPIO, reg | (div << 4));
+		reg = snd_soc_component_read32(component, WM8940_GPIO) & 0xFFCF;
+		ret = snd_soc_component_write(component, WM8940_GPIO, reg | (div << 4));
 		break;
 	}
 	return ret;
@@ -693,29 +693,29 @@ static struct snd_soc_dai_driver wm8940_dai = {
 	.symmetric_rates = 1,
 };
 
-static int wm8940_probe(struct snd_soc_codec *codec)
+static int wm8940_probe(struct snd_soc_component *component)
 {
-	struct wm8940_setup_data *pdata = codec->dev->platform_data;
+	struct wm8940_setup_data *pdata = component->dev->platform_data;
 	int ret;
 	u16 reg;
 
-	ret = wm8940_reset(codec);
+	ret = wm8940_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
+		dev_err(component->dev, "Failed to issue reset\n");
 		return ret;
 	}
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
-	ret = snd_soc_write(codec, WM8940_POWER1, 0x180);
+	ret = snd_soc_component_write(component, WM8940_POWER1, 0x180);
 	if (ret < 0)
 		return ret;
 
 	if (!pdata)
-		dev_warn(codec->dev, "No platform data supplied\n");
+		dev_warn(component->dev, "No platform data supplied\n");
 	else {
-		reg = snd_soc_read(codec, WM8940_OUTPUTCTL);
-		ret = snd_soc_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi);
+		reg = snd_soc_component_read32(component, WM8940_OUTPUTCTL);
+		ret = snd_soc_component_write(component, WM8940_OUTPUTCTL, reg | pdata->vroi);
 		if (ret < 0)
 			return ret;
 	}
@@ -723,19 +723,20 @@ static int wm8940_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
-	.probe =	wm8940_probe,
-	.set_bias_level = wm8940_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8940_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8940_snd_controls),
-		.dapm_widgets		= wm8940_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8940_dapm_widgets),
-		.dapm_routes		= wm8940_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8940_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8940 = {
+	.probe			= wm8940_probe,
+	.set_bias_level		= wm8940_set_bias_level,
+	.controls		= wm8940_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8940_snd_controls),
+	.dapm_widgets		= wm8940_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8940_dapm_widgets),
+	.dapm_routes		= wm8940_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8940_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8940_regmap = {
@@ -768,19 +769,12 @@ static int wm8940_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8940);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8940, &wm8940_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8940, &wm8940_dai, 1);
 
 	return ret;
 }
 
-static int wm8940_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm8940_i2c_id[] = {
 	{ "wm8940", 0 },
 	{ }
@@ -792,7 +786,6 @@ static struct i2c_driver wm8940_i2c_driver = {
 		.name = "wm8940",
 	},
 	.probe =    wm8940_i2c_probe,
-	.remove =   wm8940_i2c_remove,
 	.id_table = wm8940_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 1edc7b1..ba44e3d 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -128,9 +128,9 @@ static bool wm8955_volatile(struct device *dev, unsigned int reg)
 	}
 }
 
-static int wm8955_reset(struct snd_soc_codec *codec)
+static int wm8955_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, WM8955_RESET, 0);
+	return snd_soc_component_write(component, WM8955_RESET, 0);
 }
 
 struct pll_factors {
@@ -242,9 +242,9 @@ static struct {
 	{ 11289600, 88200, 0, 31, },
 };
 
-static int wm8955_configure_clocking(struct snd_soc_codec *codec)
+static int wm8955_configure_clocking(struct snd_soc_component *component)
 {
-	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+	struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component);
 	int i, ret, val;
 	int clocking = 0;
 	int srate = 0;
@@ -267,7 +267,7 @@ static int wm8955_configure_clocking(struct snd_soc_codec *codec)
 
 	/* We should never get here with an unsupported sample rate */
 	if (sr == -1) {
-		dev_err(codec->dev, "Sample rate %dHz unsupported\n",
+		dev_err(component->dev, "Sample rate %dHz unsupported\n",
 			wm8955->fs);
 		WARN_ON(sr == -1);
 		return -EINVAL;
@@ -282,30 +282,30 @@ static int wm8955_configure_clocking(struct snd_soc_codec *codec)
 
 		/* Use the last divider configuration we saw for the
 		 * sample rate. */
-		ret = wm8995_pll_factors(codec->dev, wm8955->mclk_rate,
+		ret = wm8995_pll_factors(component->dev, wm8955->mclk_rate,
 					 clock_cfgs[sr].mclk, &pll);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Unable to generate %dHz from %dHz MCLK\n",
 				wm8955->fs, wm8955->mclk_rate);
 			return -EINVAL;
 		}
 
-		snd_soc_update_bits(codec, WM8955_PLL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8955_PLL_CONTROL_1,
 				    WM8955_N_MASK | WM8955_K_21_18_MASK,
 				    (pll.n << WM8955_N_SHIFT) |
 				    pll.k >> 18);
-		snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
+		snd_soc_component_update_bits(component, WM8955_PLL_CONTROL_2,
 				    WM8955_K_17_9_MASK,
 				    (pll.k >> 9) & WM8955_K_17_9_MASK);
-		snd_soc_update_bits(codec, WM8955_PLL_CONTROL_3,
+		snd_soc_component_update_bits(component, WM8955_PLL_CONTROL_3,
 				    WM8955_K_8_0_MASK,
 				    pll.k & WM8955_K_8_0_MASK);
 		if (pll.k)
-			snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
+			snd_soc_component_update_bits(component, WM8955_PLL_CONTROL_4,
 					    WM8955_KEN, WM8955_KEN);
 		else
-			snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
+			snd_soc_component_update_bits(component, WM8955_PLL_CONTROL_4,
 					    WM8955_KEN, 0);
 
 		if (pll.outdiv)
@@ -314,17 +314,17 @@ static int wm8955_configure_clocking(struct snd_soc_codec *codec)
 			val = WM8955_PLL_RB;
 
 		/* Now start the PLL running */
-		snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
+		snd_soc_component_update_bits(component, WM8955_CLOCKING_PLL,
 				    WM8955_PLL_RB | WM8955_PLLOUTDIV2, val);
-		snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
+		snd_soc_component_update_bits(component, WM8955_CLOCKING_PLL,
 				    WM8955_PLLEN, WM8955_PLLEN);
 	}
 
 	srate = clock_cfgs[sr].usb | (clock_cfgs[sr].sr << WM8955_SR_SHIFT);
 
-	snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
+	snd_soc_component_update_bits(component, WM8955_SAMPLE_RATE,
 			    WM8955_USB | WM8955_SR_MASK, srate);
-	snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
+	snd_soc_component_update_bits(component, WM8955_CLOCKING_PLL,
 			    WM8955_MCLKSEL, clocking);
 
 	return 0;
@@ -333,22 +333,22 @@ static int wm8955_configure_clocking(struct snd_soc_codec *codec)
 static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	int ret = 0;
 
 	/* Always disable the clocks - if we're doing reconfiguration this
 	 * avoids misclocking.
 	 */
-	snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
+	snd_soc_component_update_bits(component, WM8955_POWER_MANAGEMENT_1,
 			    WM8955_DIGENB, 0);
-	snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
+	snd_soc_component_update_bits(component, WM8955_CLOCKING_PLL,
 			    WM8955_PLL_RB | WM8955_PLLEN, 0);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMD:
 		break;
 	case SND_SOC_DAPM_PRE_PMU:
-		ret = wm8955_configure_clocking(codec);
+		ret = wm8955_configure_clocking(component);
 		break;
 	default:
 		ret = -EINVAL;
@@ -360,9 +360,9 @@ static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
 
 static int deemph_settings[] = { 0, 32000, 44100, 48000 };
 
-static int wm8955_set_deemph(struct snd_soc_codec *codec)
+static int wm8955_set_deemph(struct snd_soc_component *component)
 {
-	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+	struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component);
 	int val, i, best;
 
 	/* If we're using deemphasis select the nearest available sample
@@ -381,17 +381,17 @@ static int wm8955_set_deemph(struct snd_soc_codec *codec)
 		val = 0;
 	}
 
-	dev_dbg(codec->dev, "Set deemphasis %d\n", val);
+	dev_dbg(component->dev, "Set deemphasis %d\n", val);
 
-	return snd_soc_update_bits(codec, WM8955_DAC_CONTROL,
+	return snd_soc_component_update_bits(component, WM8955_DAC_CONTROL,
 				   WM8955_DEEMPH_MASK, val);
 }
 
 static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = wm8955->deemph;
 	return 0;
@@ -400,8 +400,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
 static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component);
 	unsigned int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
@@ -409,7 +409,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
 
 	wm8955->deemph = deemph;
 
-	return wm8955_set_deemph(codec);
+	return wm8955_set_deemph(component);
 }
 
 static const char *bass_mode_text[] = {
@@ -592,8 +592,8 @@ static int wm8955_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component);
 	int ret;
 	int wl;
 
@@ -613,25 +613,25 @@ static int wm8955_hw_params(struct snd_pcm_substream *substream,
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8955_AUDIO_INTERFACE,
 			    WM8955_WL_MASK, wl);
 
 	wm8955->fs = params_rate(params);
-	wm8955_set_deemph(codec);
+	wm8955_set_deemph(component);
 
 	/* If the chip is clocked then disable the clocks and force a
 	 * reconfiguration, otherwise DAPM will power up the
 	 * clocks for us later. */
-	ret = snd_soc_read(codec, WM8955_POWER_MANAGEMENT_1);
+	ret = snd_soc_component_read32(component, WM8955_POWER_MANAGEMENT_1);
 	if (ret < 0)
 		return ret;
 	if (ret & WM8955_DIGENB) {
-		snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8955_POWER_MANAGEMENT_1,
 				    WM8955_DIGENB, 0);
-		snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
+		snd_soc_component_update_bits(component, WM8955_CLOCKING_PLL,
 				    WM8955_PLL_RB | WM8955_PLLEN, 0);
 
-		wm8955_configure_clocking(codec);
+		wm8955_configure_clocking(component);
 	}
 
 	return 0;
@@ -641,8 +641,8 @@ static int wm8955_hw_params(struct snd_pcm_substream *substream,
 static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 			     unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8955_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8955_priv *priv = snd_soc_component_get_drvdata(component);
 	int div;
 
 	switch (clk_id) {
@@ -655,7 +655,7 @@ static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 			div = 0;
 		}
 
-		snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
+		snd_soc_component_update_bits(component, WM8955_SAMPLE_RATE,
 				    WM8955_MCLKDIV2, div);
 		break;
 
@@ -670,7 +670,7 @@ static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 
 static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 aif = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -739,7 +739,7 @@ static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8955_AUDIO_INTERFACE,
 			    WM8955_MS | WM8955_FORMAT_MASK | WM8955_BCLKINV |
 			    WM8955_LRP, aif);
 
@@ -749,7 +749,7 @@ static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int val;
 
 	if (mute)
@@ -757,15 +757,15 @@ static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 	else
 		val = 0;
 
-	snd_soc_update_bits(codec, WM8955_DAC_CONTROL, WM8955_DACMU, val);
+	snd_soc_component_update_bits(component, WM8955_DAC_CONTROL, WM8955_DACMU, val);
 
 	return 0;
 }
 
-static int wm8955_set_bias_level(struct snd_soc_codec *codec,
+static int wm8955_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+	struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -774,22 +774,22 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID resistance 2*50k */
-		snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8955_POWER_MANAGEMENT_1,
 				    WM8955_VMIDSEL_MASK,
 				    0x1 << WM8955_VMIDSEL_SHIFT);
 
 		/* Default bias current */
-		snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8955_ADDITIONAL_CONTROL_1,
 				    WM8955_VSEL_MASK,
 				    0x2 << WM8955_VSEL_SHIFT);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
 						    wm8955->supplies);
 			if (ret != 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n",
 					ret);
 				return ret;
@@ -798,7 +798,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
 			regcache_sync(wm8955->regmap);
 
 			/* Enable VREF and VMID */
-			snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8955_POWER_MANAGEMENT_1,
 					    WM8955_VREF |
 					    WM8955_VMIDSEL_MASK,
 					    WM8955_VREF |
@@ -808,29 +808,29 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
 			msleep(500);
 
 			/* High resistance VROI to maintain outputs */
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					    WM8955_ADDITIONAL_CONTROL_3,
 					    WM8955_VROI, WM8955_VROI);
 		}
 
 		/* Maintain VMID with 2*250k */
-		snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8955_POWER_MANAGEMENT_1,
 				    WM8955_VMIDSEL_MASK,
 				    0x2 << WM8955_VMIDSEL_SHIFT);
 
 		/* Minimum bias current */
-		snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8955_ADDITIONAL_CONTROL_1,
 				    WM8955_VSEL_MASK, 0);
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* Low resistance VROI to help discharge */
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 				    WM8955_ADDITIONAL_CONTROL_3,
 				    WM8955_VROI, 0);
 
 		/* Turn off VMID and VREF */
-		snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8955_POWER_MANAGEMENT_1,
 				    WM8955_VREF |
 				    WM8955_VMIDSEL_MASK, 0);
 
@@ -865,70 +865,70 @@ static struct snd_soc_dai_driver wm8955_dai = {
 	.ops = &wm8955_dai_ops,
 };
 
-static int wm8955_probe(struct snd_soc_codec *codec)
+static int wm8955_probe(struct snd_soc_component *component)
 {
-	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
-	struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
+	struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component);
+	struct wm8955_pdata *pdata = dev_get_platdata(component->dev);
 	int ret, i;
 
 	for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
 		wm8955->supplies[i].supply = wm8955_supply_names[i];
 
-	ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies),
+	ret = devm_regulator_bulk_get(component->dev, ARRAY_SIZE(wm8955->supplies),
 				 wm8955->supplies);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to request supplies: %d\n", ret);
 		return ret;
 	}
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
 				    wm8955->supplies);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		return ret;
 	}
 
-	ret = wm8955_reset(codec);
+	ret = wm8955_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+		dev_err(component->dev, "Failed to issue reset: %d\n", ret);
 		goto err_enable;
 	}
 
 	/* Change some default settings - latch VU and enable ZC */
-	snd_soc_update_bits(codec, WM8955_LEFT_DAC_VOLUME,
+	snd_soc_component_update_bits(component, WM8955_LEFT_DAC_VOLUME,
 			    WM8955_LDVU, WM8955_LDVU);
-	snd_soc_update_bits(codec, WM8955_RIGHT_DAC_VOLUME,
+	snd_soc_component_update_bits(component, WM8955_RIGHT_DAC_VOLUME,
 			    WM8955_RDVU, WM8955_RDVU);
-	snd_soc_update_bits(codec, WM8955_LOUT1_VOLUME,
+	snd_soc_component_update_bits(component, WM8955_LOUT1_VOLUME,
 			    WM8955_LO1VU | WM8955_LO1ZC,
 			    WM8955_LO1VU | WM8955_LO1ZC);
-	snd_soc_update_bits(codec, WM8955_ROUT1_VOLUME,
+	snd_soc_component_update_bits(component, WM8955_ROUT1_VOLUME,
 			    WM8955_RO1VU | WM8955_RO1ZC,
 			    WM8955_RO1VU | WM8955_RO1ZC);
-	snd_soc_update_bits(codec, WM8955_LOUT2_VOLUME,
+	snd_soc_component_update_bits(component, WM8955_LOUT2_VOLUME,
 			    WM8955_LO2VU | WM8955_LO2ZC,
 			    WM8955_LO2VU | WM8955_LO2ZC);
-	snd_soc_update_bits(codec, WM8955_ROUT2_VOLUME,
+	snd_soc_component_update_bits(component, WM8955_ROUT2_VOLUME,
 			    WM8955_RO2VU | WM8955_RO2ZC,
 			    WM8955_RO2VU | WM8955_RO2ZC);
-	snd_soc_update_bits(codec, WM8955_MONOOUT_VOLUME,
+	snd_soc_component_update_bits(component, WM8955_MONOOUT_VOLUME,
 			    WM8955_MOZC, WM8955_MOZC);
 
 	/* Also enable adaptive bass boost by default */
-	snd_soc_update_bits(codec, WM8955_BASS_CONTROL, WM8955_BB, WM8955_BB);
+	snd_soc_component_update_bits(component, WM8955_BASS_CONTROL, WM8955_BB, WM8955_BB);
 
 	/* Set platform data values */
 	if (pdata) {
 		if (pdata->out2_speaker)
-			snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_2,
+			snd_soc_component_update_bits(component, WM8955_ADDITIONAL_CONTROL_2,
 					    WM8955_ROUT2INV, WM8955_ROUT2INV);
 
 		if (pdata->monoin_diff)
-			snd_soc_update_bits(codec, WM8955_MONO_OUT_MIX_1,
+			snd_soc_component_update_bits(component, WM8955_MONO_OUT_MIX_1,
 					    WM8955_DMEN, WM8955_DMEN);
 	}
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	/* Bias level configuration will have done an extra enable */
 	regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
@@ -940,19 +940,20 @@ static int wm8955_probe(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
-	.probe =	wm8955_probe,
-	.set_bias_level = wm8955_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8955_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8955_snd_controls),
-		.dapm_widgets		= wm8955_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8955_dapm_widgets),
-		.dapm_routes		= wm8955_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8955_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8955 = {
+	.probe			= wm8955_probe,
+	.set_bias_level		= wm8955_set_bias_level,
+	.controls		= wm8955_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8955_snd_controls),
+	.dapm_widgets		= wm8955_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8955_dapm_widgets),
+	.dapm_routes		= wm8955_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8955_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8955_regmap = {
@@ -989,19 +990,12 @@ static int wm8955_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8955);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8955, &wm8955_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8955, &wm8955_dai, 1);
 
 	return ret;
 }
 
-static int wm8955_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm8955_i2c_id[] = {
 	{ "wm8955", 0 },
 	{ }
@@ -1013,7 +1007,6 @@ static struct i2c_driver wm8955_i2c_driver = {
 		.name = "wm8955",
 	},
 	.probe =    wm8955_i2c_probe,
-	.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 6b864c0..8d49522 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -39,10 +39,10 @@
 #define WM_FW_BLOCK_A    0x08
 #define WM_FW_BLOCK_C    0x0c
 
-static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
+static int wm8958_dsp2_fw(struct snd_soc_component *component, const char *name,
 			  const struct firmware *fw, bool check)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	u64 data64;
 	u32 data32;
 	const u8 *data;
@@ -55,7 +55,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 		return 0;
 
 	if (fw->size < 32) {
-		dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n",
+		dev_err(component->dev, "%s: firmware too short (%zd bytes)\n",
 			name, fw->size);
 		goto err;
 	}
@@ -63,7 +63,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 	if (memcmp(fw->data, "WMFW", 4) != 0) {
 		memcpy(&data32, fw->data, sizeof(data32));
 		data32 = be32_to_cpu(data32);
-		dev_err(codec->dev, "%s: firmware has bad file magic %08x\n",
+		dev_err(component->dev, "%s: firmware has bad file magic %08x\n",
 			name, data32);
 		goto err;
 	}
@@ -74,35 +74,35 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 	memcpy(&data32, fw->data + 8, sizeof(data32));
 	data32 = be32_to_cpu(data32);
 	if ((data32 >> 24) & 0xff) {
-		dev_err(codec->dev, "%s: unsupported firmware version %d\n",
+		dev_err(component->dev, "%s: unsupported firmware version %d\n",
 			name, (data32 >> 24) & 0xff);
 		goto err;
 	}
 	if ((data32 & 0xffff) != 8958) {
-		dev_err(codec->dev, "%s: unsupported target device %d\n",
+		dev_err(component->dev, "%s: unsupported target device %d\n",
 			name, data32 & 0xffff);
 		goto err;
 	}
 	if (((data32 >> 16) & 0xff) != 0xc) {
-		dev_err(codec->dev, "%s: unsupported target core %d\n",
+		dev_err(component->dev, "%s: unsupported target core %d\n",
 			name, (data32 >> 16) & 0xff);
 		goto err;
 	}
 
 	if (check) {
 		memcpy(&data64, fw->data + 24, sizeof(u64));
-		dev_info(codec->dev, "%s timestamp %llx\n",
+		dev_info(component->dev, "%s timestamp %llx\n",
 			 name, be64_to_cpu(data64));
 	} else {
-		snd_soc_write(codec, 0x102, 0x2);
-		snd_soc_write(codec, 0x900, 0x2);
+		snd_soc_component_write(component, 0x102, 0x2);
+		snd_soc_component_write(component, 0x900, 0x2);
 	}
 
 	data = fw->data + len;
 	len = fw->size - len;
 	while (len) {
 		if (len < 12) {
-			dev_err(codec->dev, "%s short data block of %zd\n",
+			dev_err(component->dev, "%s short data block of %zd\n",
 				name, len);
 			goto err;
 		}
@@ -110,12 +110,12 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 		memcpy(&data32, data + 4, sizeof(data32));
 		block_len = be32_to_cpu(data32);
 		if (block_len + 8 > len) {
-			dev_err(codec->dev, "%zd byte block longer than file\n",
+			dev_err(component->dev, "%zd byte block longer than file\n",
 				block_len);
 			goto err;
 		}
 		if (block_len == 0) {
-			dev_err(codec->dev, "Zero length block\n");
+			dev_err(component->dev, "Zero length block\n");
 			goto err;
 		}
 
@@ -131,10 +131,10 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 			str = kzalloc(block_len + 1, GFP_KERNEL);
 			if (str) {
 				memcpy(str, data + 8, block_len);
-				dev_info(codec->dev, "%s: %s\n", name, str);
+				dev_info(component->dev, "%s: %s\n", name, str);
 				kfree(str);
 			} else {
-				dev_err(codec->dev, "Out of memory\n");
+				dev_err(component->dev, "Out of memory\n");
 			}
 			break;
 		case WM_FW_BLOCK_PM:
@@ -144,7 +144,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 		case WM_FW_BLOCK_I:
 		case WM_FW_BLOCK_A:
 		case WM_FW_BLOCK_C:
-			dev_dbg(codec->dev, "%s: %zd bytes of %x@%x\n", name,
+			dev_dbg(component->dev, "%s: %zd bytes of %x@%x\n", name,
 				block_len, (data32 >> 24) & 0xff,
 				data32 & 0xffffff);
 
@@ -160,7 +160,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 
 			break;
 		default:
-			dev_warn(codec->dev, "%s: unknown block type %d\n",
+			dev_warn(component->dev, "%s: unknown block type %d\n",
 				 name, (data32 >> 24) & 0xff);
 			break;
 		}
@@ -173,10 +173,10 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 	}
 
 	if (!check) {
-		dev_dbg(codec->dev, "%s: download done\n", name);
+		dev_dbg(component->dev, "%s: download done\n", name);
 		wm8994->cur_fw = fw;
 	} else {
-		dev_info(codec->dev, "%s: got firmware\n", name);
+		dev_info(component->dev, "%s: got firmware\n", name);
 	}
 
 	goto ok;
@@ -185,28 +185,28 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
 	ret = -EINVAL;
 ok:
 	if (!check) {
-		snd_soc_write(codec, 0x900, 0x0);
-		snd_soc_write(codec, 0x102, 0x0);
+		snd_soc_component_write(component, 0x900, 0x0);
+		snd_soc_component_write(component, 0x102, 0x0);
 	}
 
 	return ret;
 }
 
-static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
+static void wm8958_dsp_start_mbc(struct snd_soc_component *component, int path)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int i;
 
 	/* If the DSP is already running then noop */
-	if (snd_soc_read(codec, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA)
+	if (snd_soc_component_read32(component, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA)
 		return;
 
 	/* If we have MBC firmware download it */
 	if (wm8994->mbc)
-		wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false);
+		wm8958_dsp2_fw(component, "MBC", wm8994->mbc, false);
 
-	snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
+	snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM,
 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
 
 	/* If we've got user supplied MBC settings use them */
@@ -215,37 +215,37 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
 			= &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,
+			snd_soc_component_write(component, i + WM8958_MBC_BAND_1_K_1,
 				      cfg->coeff_regs[i]);
 
 		for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
-			snd_soc_write(codec,
+			snd_soc_component_write(component,
 				      i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
 				      cfg->cutoff_regs[i]);
 	}
 
 	/* Run the DSP */
-	snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
+	snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL,
 		      WM8958_DSP2_RUNR);
 
 	/* And we're off! */
-	snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
+	snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG,
 			    WM8958_MBC_ENA |
 			    WM8958_MBC_SEL_MASK,
 			    path << WM8958_MBC_SEL_SHIFT |
 			    WM8958_MBC_ENA);
 }
 
-static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
+static void wm8958_dsp_start_vss(struct snd_soc_component *component, int path)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int i, ena;
 
 	if (wm8994->mbc_vss)
-		wm8958_dsp2_fw(codec, "MBC+VSS", wm8994->mbc_vss, false);
+		wm8958_dsp2_fw(component, "MBC+VSS", wm8994->mbc_vss, false);
 
-	snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
+	snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM,
 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
 
 	/* If we've got user supplied settings use them */
@@ -254,7 +254,7 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
 			= &control->pdata.mbc_cfgs[wm8994->mbc_cfg];
 
 		for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
-			snd_soc_write(codec, i + 0x2800,
+			snd_soc_component_write(component, i + 0x2800,
 				      cfg->combined_regs[i]);
 	}
 
@@ -263,7 +263,7 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
 			= &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]);
+			snd_soc_component_write(component, i + 0x2600, cfg->regs[i]);
 	}
 
 	if (control->pdata.num_vss_hpf_cfgs) {
@@ -271,11 +271,11 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
 			= &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]);
+			snd_soc_component_write(component, i + 0x2400, cfg->regs[i]);
 	}
 
 	/* Run the DSP */
-	snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
+	snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL,
 		      WM8958_DSP2_RUNR);
 
 	/* Enable the algorithms we've selected */
@@ -289,23 +289,23 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
 	if (wm8994->vss_ena[path])
 		ena |= 0x1;
 
-	snd_soc_write(codec, 0x2201, ena);
+	snd_soc_component_write(component, 0x2201, ena);
 
 	/* Switch the DSP into the data path */
-	snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
+	snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG,
 			    WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
 			    path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
 }
 
-static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
+static void wm8958_dsp_start_enh_eq(struct snd_soc_component *component, int path)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int i;
 
-	wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false);
+	wm8958_dsp2_fw(component, "ENH_EQ", wm8994->enh_eq, false);
 
-	snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
+	snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM,
 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
 
 	/* If we've got user supplied settings use them */
@@ -314,24 +314,24 @@ static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
 			= &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg];
 
 		for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
-			snd_soc_write(codec, i + 0x2200,
+			snd_soc_component_write(component, i + 0x2200,
 				      cfg->regs[i]);
 	}
 
 	/* Run the DSP */
-	snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
+	snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL,
 		      WM8958_DSP2_RUNR);
 
 	/* Switch the DSP into the data path */
-	snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
+	snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG,
 			    WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
 			    path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
 }
 
-static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
+static void wm8958_dsp_apply(struct snd_soc_component *component, int path, int start)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
+	int pwr_reg = snd_soc_component_read32(component, WM8994_POWER_MANAGEMENT_5);
 	int ena, reg, aif;
 
 	switch (path) {
@@ -359,9 +359,9 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
 	if (!pwr_reg)
 		ena = 0;
 
-	reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
+	reg = snd_soc_component_read32(component, WM8958_DSP2_PROGRAM);
 
-	dev_dbg(codec->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n",
+	dev_dbg(component->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n",
 		path, wm8994->dsp_active, start, pwr_reg, reg);
 
 	if (start && ena) {
@@ -370,29 +370,29 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
 			return;
 
 		/* If either AIFnCLK is not yet enabled postpone */
-		if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
+		if (!(snd_soc_component_read32(component, WM8994_AIF1_CLOCKING_1)
 		      & WM8994_AIF1CLK_ENA_MASK) &&
-		    !(snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
+		    !(snd_soc_component_read32(component, WM8994_AIF2_CLOCKING_1)
 		      & WM8994_AIF2CLK_ENA_MASK))
 			return;
 
 		/* Switch the clock over to the appropriate AIF */
-		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+		snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
 				    WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
 				    aif << WM8958_DSP2CLK_SRC_SHIFT |
 				    WM8958_DSP2CLK_ENA);
 
 		if (wm8994->enh_eq_ena[path])
-			wm8958_dsp_start_enh_eq(codec, path);
+			wm8958_dsp_start_enh_eq(component, path);
 		else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] ||
 		    wm8994->hpf2_ena[path])
-			wm8958_dsp_start_vss(codec, path);
+			wm8958_dsp_start_vss(component, path);
 		else if (wm8994->mbc_ena[path])
-			wm8958_dsp_start_mbc(codec, path);
+			wm8958_dsp_start_mbc(component, path);
 
 		wm8994->dsp_active = path;
 
-		dev_dbg(codec->dev, "DSP running in path %d\n", path);
+		dev_dbg(component->dev, "DSP running in path %d\n", path);
 	}
 
 	if (!start && wm8994->dsp_active == path) {
@@ -400,37 +400,37 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
 		if (!(reg & WM8958_DSP2_ENA))
 			return;
 
-		snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
+		snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG,
 				    WM8958_MBC_ENA, 0);	
-		snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
+		snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL,
 			      WM8958_DSP2_STOP);
-		snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
+		snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM,
 				    WM8958_DSP2_ENA, 0);
-		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+		snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
 				    WM8958_DSP2CLK_ENA, 0);
 
 		wm8994->dsp_active = -1;
 
-		dev_dbg(codec->dev, "DSP stopped\n");
+		dev_dbg(component->dev, "DSP stopped\n");
 	}
 }
 
 int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
 		  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	int i;
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 	case SND_SOC_DAPM_PRE_PMU:
 		for (i = 0; i < 3; i++)
-			wm8958_dsp_apply(codec, i, 1);
+			wm8958_dsp_apply(component, i, 1);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 	case SND_SOC_DAPM_PRE_PMD:
 		for (i = 0; i < 3; i++)
-			wm8958_dsp_apply(codec, i, 0);
+			wm8958_dsp_apply(component, i, 0);
 		break;
 	}
 
@@ -456,14 +456,14 @@ static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif)
 static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
-	reg = snd_soc_read(codec, WM8994_CLOCKING_1);
+	reg = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
 		return -EBUSY;
 
@@ -478,8 +478,8 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
 static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
 
@@ -500,8 +500,8 @@ static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
 	int mbc = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
 
@@ -512,8 +512,8 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
 	int mbc = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0])
 		return 0;
@@ -522,7 +522,7 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
 		return -EINVAL;
 
 	if (wm8958_dsp2_busy(wm8994, mbc)) {
-		dev_dbg(codec->dev, "DSP2 active on %d already\n", mbc);
+		dev_dbg(component->dev, "DSP2 active on %d already\n", mbc);
 		return -EBUSY;
 	}
 
@@ -531,7 +531,7 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
 
 	wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
 
-	wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]);
+	wm8958_dsp_apply(component, mbc, wm8994->mbc_ena[mbc]);
 
 	return 0;
 }
@@ -546,14 +546,14 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
 static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
-	reg = snd_soc_read(codec, WM8994_CLOCKING_1);
+	reg = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
 		return -EBUSY;
 
@@ -568,8 +568,8 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
 static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = wm8994->vss_cfg;
 
@@ -579,14 +579,14 @@ static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol,
 static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
-	reg = snd_soc_read(codec, WM8994_CLOCKING_1);
+	reg = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
 		return -EBUSY;
 
@@ -601,8 +601,8 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
 static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg;
 
@@ -623,8 +623,8 @@ static int wm8958_vss_get(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
 	int vss = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = wm8994->vss_ena[vss];
 
@@ -635,8 +635,8 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
 	int vss = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0])
 		return 0;
@@ -648,7 +648,7 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
 		return -ENODEV;
 
 	if (wm8958_dsp2_busy(wm8994, vss)) {
-		dev_dbg(codec->dev, "DSP2 active on %d already\n", vss);
+		dev_dbg(component->dev, "DSP2 active on %d already\n", vss);
 		return -EBUSY;
 	}
 
@@ -657,7 +657,7 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
 
 	wm8994->vss_ena[vss] = ucontrol->value.integer.value[0];
 
-	wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]);
+	wm8958_dsp_apply(component, vss, wm8994->vss_ena[vss]);
 
 	return 0;
 }
@@ -684,8 +684,8 @@ static int wm8958_hpf_get(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
 	int hpf = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	if (hpf < 3)
 		ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3];
@@ -699,8 +699,8 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
 	int hpf = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	if (hpf < 3) {
 		if (wm8994->hpf1_ena[hpf % 3] ==
@@ -719,7 +719,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
 		return -ENODEV;
 
 	if (wm8958_dsp2_busy(wm8994, hpf % 3)) {
-		dev_dbg(codec->dev, "DSP2 active on %d already\n", hpf);
+		dev_dbg(component->dev, "DSP2 active on %d already\n", hpf);
 		return -EBUSY;
 	}
 
@@ -731,7 +731,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
 	else
 		wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0];
 
-	wm8958_dsp_apply(codec, hpf % 3, ucontrol->value.integer.value[0]);
+	wm8958_dsp_apply(component, hpf % 3, ucontrol->value.integer.value[0]);
 
 	return 0;
 }
@@ -746,14 +746,14 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
 static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
-	reg = snd_soc_read(codec, WM8994_CLOCKING_1);
+	reg = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
 		return -EBUSY;
 
@@ -768,8 +768,8 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
 static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg;
 
@@ -790,8 +790,8 @@ static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
 	int eq = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq];
 
@@ -802,8 +802,8 @@ static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
 	int eq = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0])
 		return 0;
@@ -815,7 +815,7 @@ static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
 		return -ENODEV;
 
 	if (wm8958_dsp2_busy(wm8994, eq)) {
-		dev_dbg(codec->dev, "DSP2 active on %d already\n", eq);
+		dev_dbg(component->dev, "DSP2 active on %d already\n", eq);
 		return -EBUSY;
 	}
 
@@ -825,7 +825,7 @@ static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
 
 	wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0];
 
-	wm8958_dsp_apply(codec, eq, ucontrol->value.integer.value[0]);
+	wm8958_dsp_apply(component, eq, ucontrol->value.integer.value[0]);
 
 	return 0;
 }
@@ -863,10 +863,10 @@ WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2),
 
 static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context)
 {
-	struct snd_soc_codec *codec = context;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = context;
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
-	if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) {
+	if (fw && (wm8958_dsp2_fw(component, "ENH_EQ", fw, true) == 0)) {
 		mutex_lock(&wm8994->fw_lock);
 		wm8994->enh_eq = fw;
 		mutex_unlock(&wm8994->fw_lock);
@@ -875,10 +875,10 @@ static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context)
 
 static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
 {
-	struct snd_soc_codec *codec = context;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = context;
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
-	if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) {
+	if (fw && (wm8958_dsp2_fw(component, "MBC+VSS", fw, true) == 0)) {
 		mutex_lock(&wm8994->fw_lock);
 		wm8994->mbc_vss = fw;
 		mutex_unlock(&wm8994->fw_lock);
@@ -887,43 +887,43 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
 
 static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
 {
-	struct snd_soc_codec *codec = context;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = context;
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
-	if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) {
+	if (fw && (wm8958_dsp2_fw(component, "MBC", fw, true) == 0)) {
 		mutex_lock(&wm8994->fw_lock);
 		wm8994->mbc = fw;
 		mutex_unlock(&wm8994->fw_lock);
 	}
 }
 
-void wm8958_dsp2_init(struct snd_soc_codec *codec)
+void wm8958_dsp2_init(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int ret, i;
 
 	wm8994->dsp_active = -1;
 
-	snd_soc_add_codec_controls(codec, wm8958_mbc_snd_controls,
+	snd_soc_add_component_controls(component, wm8958_mbc_snd_controls,
 			     ARRAY_SIZE(wm8958_mbc_snd_controls));
-	snd_soc_add_codec_controls(codec, wm8958_vss_snd_controls,
+	snd_soc_add_component_controls(component, wm8958_vss_snd_controls,
 			     ARRAY_SIZE(wm8958_vss_snd_controls));
-	snd_soc_add_codec_controls(codec, wm8958_enh_eq_snd_controls,
+	snd_soc_add_component_controls(component, wm8958_enh_eq_snd_controls,
 			     ARRAY_SIZE(wm8958_enh_eq_snd_controls));
 
 
 	/* We don't *require* firmware and don't want to delay boot */
 	request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
-				"wm8958_mbc.wfw", codec->dev, GFP_KERNEL,
-				codec, wm8958_mbc_loaded);
+				"wm8958_mbc.wfw", component->dev, GFP_KERNEL,
+				component, wm8958_mbc_loaded);
 	request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
-				"wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
-				codec, wm8958_mbc_vss_loaded);
+				"wm8958_mbc_vss.wfw", component->dev, GFP_KERNEL,
+				component, 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);
+				"wm8958_enh_eq.wfw", component->dev, GFP_KERNEL,
+				component, wm8958_enh_eq_loaded);
 
 	if (pdata->num_mbc_cfgs) {
 		struct snd_kcontrol_new control[] = {
@@ -943,10 +943,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 		wm8994->mbc_enum.items = pdata->num_mbc_cfgs;
 		wm8994->mbc_enum.texts = wm8994->mbc_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+		ret = snd_soc_add_component_controls(wm8994->hubs.component,
 						 control, 1);
 		if (ret != 0)
-			dev_err(wm8994->hubs.codec->dev,
+			dev_err(wm8994->hubs.component->dev,
 				"Failed to add MBC mode controls: %d\n", ret);
 	}
 
@@ -968,10 +968,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 		wm8994->vss_enum.items = pdata->num_vss_cfgs;
 		wm8994->vss_enum.texts = wm8994->vss_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+		ret = snd_soc_add_component_controls(wm8994->hubs.component,
 						 control, 1);
 		if (ret != 0)
-			dev_err(wm8994->hubs.codec->dev,
+			dev_err(wm8994->hubs.component->dev,
 				"Failed to add VSS mode controls: %d\n", ret);
 	}
 
@@ -994,10 +994,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 		wm8994->vss_hpf_enum.items = pdata->num_vss_hpf_cfgs;
 		wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+		ret = snd_soc_add_component_controls(wm8994->hubs.component,
 						 control, 1);
 		if (ret != 0)
-			dev_err(wm8994->hubs.codec->dev,
+			dev_err(wm8994->hubs.component->dev,
 				"Failed to add VSS HPFmode controls: %d\n",
 				ret);
 	}
@@ -1021,10 +1021,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 		wm8994->enh_eq_enum.items = pdata->num_enh_eq_cfgs;
 		wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+		ret = snd_soc_add_component_controls(wm8994->hubs.component,
 						 control, 1);
 		if (ret != 0)
-			dev_err(wm8994->hubs.codec->dev,
+			dev_err(wm8994->hubs.component->dev,
 				"Failed to add enhanced EQ controls: %d\n",
 				ret);
 	}
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 9ed4557..c30f5aa 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -49,7 +49,7 @@
 #define WM8960_DRES_MASK 0x30
 
 static bool is_pll_freq_available(unsigned int source, unsigned int target);
-static int wm8960_set_pll(struct snd_soc_codec *codec,
+static int wm8960_set_pll(struct snd_soc_component *component,
 		unsigned int freq_in, unsigned int freq_out);
 /*
  * wm8960 register cache
@@ -123,7 +123,7 @@ static bool wm8960_volatile(struct device *dev, unsigned int reg)
 struct wm8960_priv {
 	struct clk *mclk;
 	struct regmap *regmap;
-	int (*set_bias_level)(struct snd_soc_codec *,
+	int (*set_bias_level)(struct snd_soc_component *,
 			      enum snd_soc_bias_level level);
 	struct snd_soc_dapm_widget *lout1;
 	struct snd_soc_dapm_widget *rout1;
@@ -168,9 +168,9 @@ static const struct soc_enum wm8960_enum[] = {
 
 static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
 
-static int wm8960_set_deemph(struct snd_soc_codec *codec)
+static int wm8960_set_deemph(struct snd_soc_component *component)
 {
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 	int val, i, best;
 
 	/* If we're using deemphasis select the nearest available sample
@@ -189,17 +189,17 @@ static int wm8960_set_deemph(struct snd_soc_codec *codec)
 		val = 0;
 	}
 
-	dev_dbg(codec->dev, "Set deemphasis %d\n", val);
+	dev_dbg(component->dev, "Set deemphasis %d\n", val);
 
-	return snd_soc_update_bits(codec, WM8960_DACCTL1,
+	return snd_soc_component_update_bits(component, WM8960_DACCTL1,
 				   0x6, val);
 }
 
 static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = wm8960->deemph;
 	return 0;
@@ -208,8 +208,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
 static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 	unsigned int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
@@ -217,7 +217,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
 
 	wm8960->deemph = deemph;
 
-	return wm8960_set_deemph(codec);
+	return wm8960_set_deemph(component);
 }
 
 static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
@@ -470,11 +470,11 @@ static const struct snd_soc_dapm_route audio_paths_capless[] = {
 	{ "OUT3 VMID", NULL, "Right Output Mixer" },
 };
 
-static int wm8960_add_widgets(struct snd_soc_codec *codec)
+static int wm8960_add_widgets(struct snd_soc_component *component)
 {
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 	struct wm8960_data *pdata = &wm8960->pdata;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct snd_soc_dapm_widget *w;
 
 	snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,
@@ -504,7 +504,7 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
 	 * list each time to find the desired power state do so now
 	 * and save the result.
 	 */
-	list_for_each_entry(w, &codec->component.card->widgets, list) {
+	list_for_each_entry(w, &component->card->widgets, list) {
 		if (w->dapm != dapm)
 			continue;
 		if (strcmp(w->name, "LOUT1 PGA") == 0)
@@ -521,7 +521,7 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
 static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
 
 	/* set master/slave audio interface */
@@ -573,7 +573,7 @@ static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	}
 
 	/* set iface */
-	snd_soc_write(codec, WM8960_IFACE1, iface);
+	snd_soc_component_write(component, WM8960_IFACE1, iface);
 	return 0;
 }
 
@@ -683,7 +683,7 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
  * 	triplet, we relax the bclk such that bclk is chosen as the
  * 	closest available frequency greater than expected bclk.
  *
- * @codec: codec structure
+ * @component: component structure
  * @freq_in: input frequency used to derive freq out via PLL
  * @sysclk_idx: sysclk_divs index for found sysclk
  * @dac_idx: dac_divs index for found lrclk
@@ -695,10 +695,10 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
  *      (@sysclk_idx, @dac_idx, @bclk_idx) dividers
  */
 static
-int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
+int wm8960_configure_pll(struct snd_soc_component *component, int freq_in,
 			 int *sysclk_idx, int *dac_idx, int *bclk_idx)
 {
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 	int sysclk, bclk, lrclk, freq_out;
 	int diff, closest, best_freq_out;
 	int i, j, k;
@@ -741,22 +741,22 @@ int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
 
 	return best_freq_out;
 }
-static int wm8960_configure_clocking(struct snd_soc_codec *codec)
+static int wm8960_configure_clocking(struct snd_soc_component *component)
 {
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 	int freq_out, freq_in;
-	u16 iface1 = snd_soc_read(codec, WM8960_IFACE1);
+	u16 iface1 = snd_soc_component_read32(component, WM8960_IFACE1);
 	int i, j, k;
 	int ret;
 
 	if (!(iface1 & (1<<6))) {
-		dev_dbg(codec->dev,
+		dev_dbg(component->dev,
 			"Codec is slave mode, no need to configure clock\n");
 		return 0;
 	}
 
 	if (wm8960->clk_id != WM8960_SYSCLK_MCLK && !wm8960->freq_in) {
-		dev_err(codec->dev, "No MCLK configured\n");
+		dev_err(component->dev, "No MCLK configured\n");
 		return -EINVAL;
 	}
 
@@ -769,12 +769,12 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
 	 */
 	if (wm8960->clk_id == WM8960_SYSCLK_AUTO) {
 		/* disable the PLL and using MCLK to provide sysclk */
-		wm8960_set_pll(codec, 0, 0);
+		wm8960_set_pll(component, 0, 0);
 		freq_out = freq_in;
 	} else if (wm8960->sysclk) {
 		freq_out = wm8960->sysclk;
 	} else {
-		dev_err(codec->dev, "No SYSCLK configured\n");
+		dev_err(component->dev, "No SYSCLK configured\n");
 		return -EINVAL;
 	}
 
@@ -783,28 +783,28 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
 		if (ret >= 0) {
 			goto configure_clock;
 		} else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) {
-			dev_err(codec->dev, "failed to configure clock\n");
+			dev_err(component->dev, "failed to configure clock\n");
 			return -EINVAL;
 		}
 	}
 
-	freq_out = wm8960_configure_pll(codec, freq_in, &i, &j, &k);
+	freq_out = wm8960_configure_pll(component, freq_in, &i, &j, &k);
 	if (freq_out < 0) {
-		dev_err(codec->dev, "failed to configure clock via PLL\n");
+		dev_err(component->dev, "failed to configure clock via PLL\n");
 		return freq_out;
 	}
-	wm8960_set_pll(codec, freq_in, freq_out);
+	wm8960_set_pll(component, freq_in, freq_out);
 
 configure_clock:
 	/* configure sysclk clock */
-	snd_soc_update_bits(codec, WM8960_CLOCK1, 3 << 1, i << 1);
+	snd_soc_component_update_bits(component, WM8960_CLOCK1, 3 << 1, i << 1);
 
 	/* configure frame clock */
-	snd_soc_update_bits(codec, WM8960_CLOCK1, 0x7 << 3, j << 3);
-	snd_soc_update_bits(codec, WM8960_CLOCK1, 0x7 << 6, j << 6);
+	snd_soc_component_update_bits(component, WM8960_CLOCK1, 0x7 << 3, j << 3);
+	snd_soc_component_update_bits(component, WM8960_CLOCK1, 0x7 << 6, j << 6);
 
 	/* configure bit clock */
-	snd_soc_update_bits(codec, WM8960_CLOCK2, 0xf, k);
+	snd_soc_component_update_bits(component, WM8960_CLOCK2, 0xf, k);
 
 	return 0;
 }
@@ -813,9 +813,9 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
+	struct snd_soc_component *component = dai->component;
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
+	u16 iface = snd_soc_component_read32(component, WM8960_IFACE1) & 0xfff3;
 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 	int i;
 
@@ -840,7 +840,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
 			break;
 		}
 	default:
-		dev_err(codec->dev, "unsupported width %d\n",
+		dev_err(component->dev, "unsupported width %d\n",
 			params_width(params));
 		return -EINVAL;
 	}
@@ -848,23 +848,23 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
 	wm8960->lrclk = params_rate(params);
 	/* Update filters for the new rate */
 	if (tx) {
-		wm8960_set_deemph(codec);
+		wm8960_set_deemph(component);
 	} else {
 		for (i = 0; i < ARRAY_SIZE(alc_rates); i++)
 			if (alc_rates[i].rate == params_rate(params))
-				snd_soc_update_bits(codec,
+				snd_soc_component_update_bits(component,
 						    WM8960_ADDCTL3, 0x7,
 						    alc_rates[i].val);
 	}
 
 	/* set iface */
-	snd_soc_write(codec, WM8960_IFACE1, iface);
+	snd_soc_component_write(component, WM8960_IFACE1, iface);
 
 	wm8960->is_stream_in_use[tx] = true;
 
-	if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON &&
+	if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON &&
 	    !wm8960->is_stream_in_use[!tx])
-		return wm8960_configure_clocking(codec);
+		return wm8960_configure_clocking(component);
 
 	return 0;
 }
@@ -872,8 +872,8 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
 static int wm8960_hw_free(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
 	wm8960->is_stream_in_use[tx] = false;
@@ -883,20 +883,20 @@ static int wm8960_hw_free(struct snd_pcm_substream *substream,
 
 static int wm8960_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	if (mute)
-		snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0x8);
+		snd_soc_component_update_bits(component, WM8960_DACCTL1, 0x8, 0x8);
 	else
-		snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0);
+		snd_soc_component_update_bits(component, WM8960_DACCTL1, 0x8, 0);
 	return 0;
 }
 
-static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
+static int wm8960_set_bias_level_out3(struct snd_soc_component *component,
 				      enum snd_soc_bias_level level)
 {
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	u16 pm2 = snd_soc_read(codec, WM8960_POWER2);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
+	u16 pm2 = snd_soc_component_read32(component, WM8960_POWER2);
 	int ret;
 
 	switch (level) {
@@ -904,24 +904,24 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
-		switch (snd_soc_codec_get_bias_level(codec)) {
+		switch (snd_soc_component_get_bias_level(component)) {
 		case SND_SOC_BIAS_STANDBY:
 			if (!IS_ERR(wm8960->mclk)) {
 				ret = clk_prepare_enable(wm8960->mclk);
 				if (ret) {
-					dev_err(codec->dev,
+					dev_err(component->dev,
 						"Failed to enable MCLK: %d\n",
 						ret);
 					return ret;
 				}
 			}
 
-			ret = wm8960_configure_clocking(codec);
+			ret = wm8960_configure_clocking(component);
 			if (ret)
 				return ret;
 
 			/* Set VMID to 2x50k */
-			snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
+			snd_soc_component_update_bits(component, WM8960_POWER1, 0x180, 0x80);
 			break;
 
 		case SND_SOC_BIAS_ON:
@@ -930,7 +930,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 			 * disable the pll
 			 */
 			if (wm8960->clk_id == WM8960_SYSCLK_AUTO && (pm2 & 0x1))
-				wm8960_set_pll(codec, 0, 0);
+				wm8960_set_pll(component, 0, 0);
 
 			if (!IS_ERR(wm8960->mclk))
 				clk_disable_unprepare(wm8960->mclk);
@@ -943,38 +943,38 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_sync(wm8960->regmap);
 
 			/* Enable anti-pop features */
-			snd_soc_write(codec, WM8960_APOP1,
+			snd_soc_component_write(component, WM8960_APOP1,
 				      WM8960_POBCTRL | WM8960_SOFT_ST |
 				      WM8960_BUFDCOPEN | WM8960_BUFIOEN);
 
 			/* Enable & ramp VMID at 2x50k */
-			snd_soc_update_bits(codec, WM8960_POWER1, 0x80, 0x80);
+			snd_soc_component_update_bits(component, WM8960_POWER1, 0x80, 0x80);
 			msleep(100);
 
 			/* Enable VREF */
-			snd_soc_update_bits(codec, WM8960_POWER1, WM8960_VREF,
+			snd_soc_component_update_bits(component, WM8960_POWER1, WM8960_VREF,
 					    WM8960_VREF);
 
 			/* Disable anti-pop features */
-			snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
+			snd_soc_component_write(component, WM8960_APOP1, WM8960_BUFIOEN);
 		}
 
 		/* Set VMID to 2x250k */
-		snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100);
+		snd_soc_component_update_bits(component, WM8960_POWER1, 0x180, 0x100);
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* Enable anti-pop features */
-		snd_soc_write(codec, WM8960_APOP1,
+		snd_soc_component_write(component, WM8960_APOP1,
 			     WM8960_POBCTRL | WM8960_SOFT_ST |
 			     WM8960_BUFDCOPEN | WM8960_BUFIOEN);
 
 		/* Disable VMID and VREF, let them discharge */
-		snd_soc_write(codec, WM8960_POWER1, 0);
+		snd_soc_component_write(component, WM8960_POWER1, 0);
 		msleep(600);
 		break;
 	}
@@ -982,11 +982,11 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
+static int wm8960_set_bias_level_capless(struct snd_soc_component *component,
 					 enum snd_soc_bias_level level)
 {
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	u16 pm2 = snd_soc_read(codec, WM8960_POWER2);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
+	u16 pm2 = snd_soc_component_read32(component, WM8960_POWER2);
 	int reg, ret;
 
 	switch (level) {
@@ -994,10 +994,10 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
-		switch (snd_soc_codec_get_bias_level(codec)) {
+		switch (snd_soc_component_get_bias_level(component)) {
 		case SND_SOC_BIAS_STANDBY:
 			/* Enable anti pop mode */
-			snd_soc_update_bits(codec, WM8960_APOP1,
+			snd_soc_component_update_bits(component, WM8960_APOP1,
 					    WM8960_POBCTRL | WM8960_SOFT_ST |
 					    WM8960_BUFDCOPEN,
 					    WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -1011,20 +1011,20 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 				reg |= WM8960_PWR2_ROUT1;
 			if (wm8960->out3 && wm8960->out3->power)
 				reg |= WM8960_PWR2_OUT3;
-			snd_soc_update_bits(codec, WM8960_POWER2,
+			snd_soc_component_update_bits(component, WM8960_POWER2,
 					    WM8960_PWR2_LOUT1 |
 					    WM8960_PWR2_ROUT1 |
 					    WM8960_PWR2_OUT3, reg);
 
 			/* Enable VMID at 2*50k */
-			snd_soc_update_bits(codec, WM8960_POWER1,
+			snd_soc_component_update_bits(component, WM8960_POWER1,
 					    WM8960_VMID_MASK, 0x80);
 
 			/* Ramp */
 			msleep(100);
 
 			/* Enable VREF */
-			snd_soc_update_bits(codec, WM8960_POWER1,
+			snd_soc_component_update_bits(component, WM8960_POWER1,
 					    WM8960_VREF, WM8960_VREF);
 
 			msleep(100);
@@ -1032,14 +1032,14 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 			if (!IS_ERR(wm8960->mclk)) {
 				ret = clk_prepare_enable(wm8960->mclk);
 				if (ret) {
-					dev_err(codec->dev,
+					dev_err(component->dev,
 						"Failed to enable MCLK: %d\n",
 						ret);
 					return ret;
 				}
 			}
 
-			ret = wm8960_configure_clocking(codec);
+			ret = wm8960_configure_clocking(component);
 			if (ret)
 				return ret;
 
@@ -1051,20 +1051,20 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 			 * disable the pll
 			 */
 			if (wm8960->clk_id == WM8960_SYSCLK_AUTO && (pm2 & 0x1))
-				wm8960_set_pll(codec, 0, 0);
+				wm8960_set_pll(component, 0, 0);
 
 			if (!IS_ERR(wm8960->mclk))
 				clk_disable_unprepare(wm8960->mclk);
 
 			/* Enable anti-pop mode */
-			snd_soc_update_bits(codec, WM8960_APOP1,
+			snd_soc_component_update_bits(component, WM8960_APOP1,
 					    WM8960_POBCTRL | WM8960_SOFT_ST |
 					    WM8960_BUFDCOPEN,
 					    WM8960_POBCTRL | WM8960_SOFT_ST |
 					    WM8960_BUFDCOPEN);
 
 			/* Disable VMID and VREF */
-			snd_soc_update_bits(codec, WM8960_POWER1,
+			snd_soc_component_update_bits(component, WM8960_POWER1,
 					    WM8960_VREF | WM8960_VMID_MASK, 0);
 			break;
 
@@ -1077,15 +1077,15 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		switch (snd_soc_codec_get_bias_level(codec)) {
+		switch (snd_soc_component_get_bias_level(component)) {
 		case SND_SOC_BIAS_PREPARE:
 			/* Disable HP discharge */
-			snd_soc_update_bits(codec, WM8960_APOP2,
+			snd_soc_component_update_bits(component, WM8960_APOP2,
 					    WM8960_DISOP | WM8960_DRES_MASK,
 					    0);
 
 			/* Disable anti-pop features */
-			snd_soc_update_bits(codec, WM8960_APOP1,
+			snd_soc_component_update_bits(component, WM8960_APOP1,
 					    WM8960_POBCTRL | WM8960_SOFT_ST |
 					    WM8960_BUFDCOPEN,
 					    WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -1184,7 +1184,7 @@ static int pll_factors(unsigned int source, unsigned int target,
 	return 0;
 }
 
-static int wm8960_set_pll(struct snd_soc_codec *codec,
+static int wm8960_set_pll(struct snd_soc_component *component,
 		unsigned int freq_in, unsigned int freq_out)
 {
 	u16 reg;
@@ -1199,29 +1199,29 @@ static int wm8960_set_pll(struct snd_soc_codec *codec,
 
 	/* Disable the PLL: even if we are changing the frequency the
 	 * PLL needs to be disabled while we do so. */
-	snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0);
-	snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0);
+	snd_soc_component_update_bits(component, WM8960_CLOCK1, 0x1, 0);
+	snd_soc_component_update_bits(component, WM8960_POWER2, 0x1, 0);
 
 	if (!freq_in || !freq_out)
 		return 0;
 
-	reg = snd_soc_read(codec, WM8960_PLL1) & ~0x3f;
+	reg = snd_soc_component_read32(component, WM8960_PLL1) & ~0x3f;
 	reg |= pll_div.pre_div << 4;
 	reg |= pll_div.n;
 
 	if (pll_div.k) {
 		reg |= 0x20;
 
-		snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
-		snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
-		snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
+		snd_soc_component_write(component, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
+		snd_soc_component_write(component, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
+		snd_soc_component_write(component, WM8960_PLL4, pll_div.k & 0xff);
 	}
-	snd_soc_write(codec, WM8960_PLL1, reg);
+	snd_soc_component_write(component, WM8960_PLL1, reg);
 
 	/* Turn it on */
-	snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0x1);
+	snd_soc_component_update_bits(component, WM8960_POWER2, 0x1, 0x1);
 	msleep(250);
-	snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0x1);
+	snd_soc_component_update_bits(component, WM8960_CLOCK1, 0x1, 0x1);
 
 	return 0;
 }
@@ -1229,43 +1229,43 @@ static int wm8960_set_pll(struct snd_soc_codec *codec,
 static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 
 	wm8960->freq_in = freq_in;
 
 	if (pll_id == WM8960_SYSCLK_AUTO)
 		return 0;
 
-	return wm8960_set_pll(codec, freq_in, freq_out);
+	return wm8960_set_pll(component, freq_in, freq_out);
 }
 
 static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
 	switch (div_id) {
 	case WM8960_SYSCLKDIV:
-		reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9;
-		snd_soc_write(codec, WM8960_CLOCK1, reg | div);
+		reg = snd_soc_component_read32(component, WM8960_CLOCK1) & 0x1f9;
+		snd_soc_component_write(component, WM8960_CLOCK1, reg | div);
 		break;
 	case WM8960_DACDIV:
-		reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1c7;
-		snd_soc_write(codec, WM8960_CLOCK1, reg | div);
+		reg = snd_soc_component_read32(component, WM8960_CLOCK1) & 0x1c7;
+		snd_soc_component_write(component, WM8960_CLOCK1, reg | div);
 		break;
 	case WM8960_OPCLKDIV:
-		reg = snd_soc_read(codec, WM8960_PLL1) & 0x03f;
-		snd_soc_write(codec, WM8960_PLL1, reg | div);
+		reg = snd_soc_component_read32(component, WM8960_PLL1) & 0x03f;
+		snd_soc_component_write(component, WM8960_PLL1, reg | div);
 		break;
 	case WM8960_DCLKDIV:
-		reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
-		snd_soc_write(codec, WM8960_CLOCK2, reg | div);
+		reg = snd_soc_component_read32(component, WM8960_CLOCK2) & 0x03f;
+		snd_soc_component_write(component, WM8960_CLOCK2, reg | div);
 		break;
 	case WM8960_TOCLKSEL:
-		reg = snd_soc_read(codec, WM8960_ADDCTL1) & 0x1fd;
-		snd_soc_write(codec, WM8960_ADDCTL1, reg | div);
+		reg = snd_soc_component_read32(component, WM8960_ADDCTL1) & 0x1fd;
+		snd_soc_component_write(component, WM8960_ADDCTL1, reg | div);
 		break;
 	default:
 		return -EINVAL;
@@ -1274,27 +1274,27 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 	return 0;
 }
 
-static int wm8960_set_bias_level(struct snd_soc_codec *codec,
+static int wm8960_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 
-	return wm8960->set_bias_level(codec, level);
+	return wm8960->set_bias_level(component, level);
 }
 
 static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 					unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case WM8960_SYSCLK_MCLK:
-		snd_soc_update_bits(codec, WM8960_CLOCK1,
+		snd_soc_component_update_bits(component, WM8960_CLOCK1,
 					0x1, WM8960_SYSCLK_MCLK);
 		break;
 	case WM8960_SYSCLK_PLL:
-		snd_soc_update_bits(codec, WM8960_CLOCK1,
+		snd_soc_component_update_bits(component, WM8960_CLOCK1,
 					0x1, WM8960_SYSCLK_PLL);
 		break;
 	case WM8960_SYSCLK_AUTO:
@@ -1343,9 +1343,9 @@ static struct snd_soc_dai_driver wm8960_dai = {
 	.symmetric_rates = 1,
 };
 
-static int wm8960_probe(struct snd_soc_codec *codec)
+static int wm8960_probe(struct snd_soc_component *component)
 {
-	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
 	struct wm8960_data *pdata = &wm8960->pdata;
 
 	if (pdata->capless)
@@ -1353,17 +1353,21 @@ static int wm8960_probe(struct snd_soc_codec *codec)
 	else
 		wm8960->set_bias_level = wm8960_set_bias_level_out3;
 
-	snd_soc_add_codec_controls(codec, wm8960_snd_controls,
+	snd_soc_add_component_controls(component, wm8960_snd_controls,
 				     ARRAY_SIZE(wm8960_snd_controls));
-	wm8960_add_widgets(codec);
+	wm8960_add_widgets(component);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
-	.probe =	wm8960_probe,
-	.set_bias_level = wm8960_set_bias_level,
-	.suspend_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_wm8960 = {
+	.probe			= wm8960_probe,
+	.set_bias_level		= wm8960_set_bias_level,
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8960_regmap = {
@@ -1447,15 +1451,14 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8960);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8960, &wm8960_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8960, &wm8960_dai, 1);
 
 	return ret;
 }
 
 static int wm8960_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index e23ceac..f70f563 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -194,89 +194,89 @@ static bool wm8961_readable(struct device *dev, unsigned int reg)
 static int wm8961_hp_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0);
-	u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1);
-	u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
-	u16 dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	u16 hp_reg = snd_soc_component_read32(component, WM8961_ANALOGUE_HP_0);
+	u16 cp_reg = snd_soc_component_read32(component, WM8961_CHARGE_PUMP_1);
+	u16 pwr_reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_2);
+	u16 dcs_reg = snd_soc_component_read32(component, WM8961_DC_SERVO_1);
 	int timeout = 500;
 
 	if (event & SND_SOC_DAPM_POST_PMU) {
 		/* Make sure the output is shorted */
 		hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
-		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
+		snd_soc_component_write(component, WM8961_ANALOGUE_HP_0, hp_reg);
 
 		/* Enable the charge pump */
 		cp_reg |= WM8961_CP_ENA;
-		snd_soc_write(codec, WM8961_CHARGE_PUMP_1, cp_reg);
+		snd_soc_component_write(component, WM8961_CHARGE_PUMP_1, cp_reg);
 		mdelay(5);
 
 		/* Enable the PGA */
 		pwr_reg |= WM8961_LOUT1_PGA | WM8961_ROUT1_PGA;
-		snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
+		snd_soc_component_write(component, WM8961_PWR_MGMT_2, pwr_reg);
 
 		/* Enable the amplifier */
 		hp_reg |= WM8961_HPR_ENA | WM8961_HPL_ENA;
-		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
+		snd_soc_component_write(component, WM8961_ANALOGUE_HP_0, hp_reg);
 
 		/* Second stage enable */
 		hp_reg |= WM8961_HPR_ENA_DLY | WM8961_HPL_ENA_DLY;
-		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
+		snd_soc_component_write(component, WM8961_ANALOGUE_HP_0, hp_reg);
 
 		/* Enable the DC servo & trigger startup */
 		dcs_reg |=
 			WM8961_DCS_ENA_CHAN_HPR | WM8961_DCS_TRIG_STARTUP_HPR |
 			WM8961_DCS_ENA_CHAN_HPL | WM8961_DCS_TRIG_STARTUP_HPL;
-		dev_dbg(codec->dev, "Enabling DC servo\n");
+		dev_dbg(component->dev, "Enabling DC servo\n");
 
-		snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
+		snd_soc_component_write(component, WM8961_DC_SERVO_1, dcs_reg);
 		do {
 			msleep(1);
-			dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
+			dcs_reg = snd_soc_component_read32(component, WM8961_DC_SERVO_1);
 		} while (--timeout &&
 			 dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
 				WM8961_DCS_TRIG_STARTUP_HPL));
 		if (dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
 			       WM8961_DCS_TRIG_STARTUP_HPL))
-			dev_err(codec->dev, "DC servo timed out\n");
+			dev_err(component->dev, "DC servo timed out\n");
 		else
-			dev_dbg(codec->dev, "DC servo startup complete\n");
+			dev_dbg(component->dev, "DC servo startup complete\n");
 
 		/* Enable the output stage */
 		hp_reg |= WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP;
-		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
+		snd_soc_component_write(component, WM8961_ANALOGUE_HP_0, hp_reg);
 
 		/* Remove the short on the output stage */
 		hp_reg |= WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT;
-		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
+		snd_soc_component_write(component, WM8961_ANALOGUE_HP_0, hp_reg);
 	}
 
 	if (event & SND_SOC_DAPM_PRE_PMD) {
 		/* Short the output */
 		hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
-		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
+		snd_soc_component_write(component, WM8961_ANALOGUE_HP_0, hp_reg);
 
 		/* Disable the output stage */
 		hp_reg &= ~(WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP);
-		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
+		snd_soc_component_write(component, WM8961_ANALOGUE_HP_0, hp_reg);
 
 		/* Disable DC offset cancellation */
 		dcs_reg &= ~(WM8961_DCS_ENA_CHAN_HPR |
 			     WM8961_DCS_ENA_CHAN_HPL);
-		snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
+		snd_soc_component_write(component, WM8961_DC_SERVO_1, dcs_reg);
 
 		/* Finish up */
 		hp_reg &= ~(WM8961_HPR_ENA_DLY | WM8961_HPR_ENA |
 			    WM8961_HPL_ENA_DLY | WM8961_HPL_ENA);
-		snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
+		snd_soc_component_write(component, WM8961_ANALOGUE_HP_0, hp_reg);
 
 		/* Disable the PGA */
 		pwr_reg &= ~(WM8961_LOUT1_PGA | WM8961_ROUT1_PGA);
-		snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
+		snd_soc_component_write(component, WM8961_PWR_MGMT_2, pwr_reg);
 
 		/* Disable the charge pump */
-		dev_dbg(codec->dev, "Disabling charge pump\n");
-		snd_soc_write(codec, WM8961_CHARGE_PUMP_1,
+		dev_dbg(component->dev, "Disabling charge pump\n");
+		snd_soc_component_write(component, WM8961_CHARGE_PUMP_1,
 			     cp_reg & ~WM8961_CP_ENA);
 	}
 
@@ -286,28 +286,28 @@ static int wm8961_hp_event(struct snd_soc_dapm_widget *w,
 static int wm8961_spk_event(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
-	u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	u16 pwr_reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_2);
+	u16 spk_reg = snd_soc_component_read32(component, WM8961_CLASS_D_CONTROL_1);
 
 	if (event & SND_SOC_DAPM_POST_PMU) {
 		/* Enable the PGA */
 		pwr_reg |= WM8961_SPKL_PGA | WM8961_SPKR_PGA;
-		snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
+		snd_soc_component_write(component, WM8961_PWR_MGMT_2, pwr_reg);
 
 		/* Enable the amplifier */
 		spk_reg |= WM8961_SPKL_ENA | WM8961_SPKR_ENA;
-		snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
+		snd_soc_component_write(component, WM8961_CLASS_D_CONTROL_1, spk_reg);
 	}
 
 	if (event & SND_SOC_DAPM_PRE_PMD) {
 		/* Disable the amplifier */
 		spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA);
-		snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
+		snd_soc_component_write(component, WM8961_CLASS_D_CONTROL_1, spk_reg);
 
 		/* Disable the PGA */
 		pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA);
-		snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
+		snd_soc_component_write(component, WM8961_PWR_MGMT_2, pwr_reg);
 	}
 
 	return 0;
@@ -505,15 +505,15 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8961_priv *wm8961 = snd_soc_component_get_drvdata(component);
 	int i, best, target, fs;
 	u16 reg;
 
 	fs = params_rate(params);
 
 	if (!wm8961->sysclk) {
-		dev_err(codec->dev, "MCLK has not been specified\n");
+		dev_err(component->dev, "MCLK has not been specified\n");
 		return -EINVAL;
 	}
 
@@ -524,23 +524,23 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
 		    abs(wm8961_srate[best].rate - fs))
 			best = i;
 	}
-	reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_3);
+	reg = snd_soc_component_read32(component, WM8961_ADDITIONAL_CONTROL_3);
 	reg &= ~WM8961_SAMPLE_RATE_MASK;
 	reg |= wm8961_srate[best].val;
-	snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_3, reg);
-	dev_dbg(codec->dev, "Selected SRATE %dHz for %dHz\n",
+	snd_soc_component_write(component, WM8961_ADDITIONAL_CONTROL_3, reg);
+	dev_dbg(component->dev, "Selected SRATE %dHz for %dHz\n",
 		wm8961_srate[best].rate, fs);
 
 	/* Select a CLK_SYS/fs ratio equal to or higher than required */
 	target = wm8961->sysclk / fs;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && target < 64) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"SYSCLK must be at least 64*fs for DAC\n");
 		return -EINVAL;
 	}
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && target < 256) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"SYSCLK must be at least 256*fs for ADC\n");
 		return -EINVAL;
 	}
@@ -550,19 +550,19 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
 			break;
 	}
 	if (i == ARRAY_SIZE(wm8961_clk_sys_ratio)) {
-		dev_err(codec->dev, "Unable to generate CLK_SYS_RATE\n");
+		dev_err(component->dev, "Unable to generate CLK_SYS_RATE\n");
 		return -EINVAL;
 	}
-	dev_dbg(codec->dev, "Selected CLK_SYS_RATE of %d for %d/%d=%d\n",
+	dev_dbg(component->dev, "Selected CLK_SYS_RATE of %d for %d/%d=%d\n",
 		wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs,
 		wm8961->sysclk / fs);
 
-	reg = snd_soc_read(codec, WM8961_CLOCKING_4);
+	reg = snd_soc_component_read32(component, WM8961_CLOCKING_4);
 	reg &= ~WM8961_CLK_SYS_RATE_MASK;
 	reg |= wm8961_clk_sys_ratio[i].val << WM8961_CLK_SYS_RATE_SHIFT;
-	snd_soc_write(codec, WM8961_CLOCKING_4, reg);
+	snd_soc_component_write(component, WM8961_CLOCKING_4, reg);
 
-	reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
+	reg = snd_soc_component_read32(component, WM8961_AUDIO_INTERFACE_0);
 	reg &= ~WM8961_WL_MASK;
 	switch (params_width(params)) {
 	case 16:
@@ -579,15 +579,15 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
 	default:
 		return -EINVAL;
 	}
-	snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, reg);
+	snd_soc_component_write(component, WM8961_AUDIO_INTERFACE_0, reg);
 
 	/* Sloping stop-band filter is recommended for <= 24kHz */
-	reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
+	reg = snd_soc_component_read32(component, WM8961_ADC_DAC_CONTROL_2);
 	if (fs <= 24000)
 		reg |= WM8961_DACSLOPE;
 	else
 		reg &= ~WM8961_DACSLOPE;
-	snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
+	snd_soc_component_write(component, WM8961_ADC_DAC_CONTROL_2, reg);
 
 	return 0;
 }
@@ -596,25 +596,25 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 			     unsigned int freq,
 			     int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
-	u16 reg = snd_soc_read(codec, WM8961_CLOCKING1);
+	struct snd_soc_component *component = dai->component;
+	struct wm8961_priv *wm8961 = snd_soc_component_get_drvdata(component);
+	u16 reg = snd_soc_component_read32(component, WM8961_CLOCKING1);
 
 	if (freq > 33000000) {
-		dev_err(codec->dev, "MCLK must be <33MHz\n");
+		dev_err(component->dev, "MCLK must be <33MHz\n");
 		return -EINVAL;
 	}
 
 	if (freq > 16500000) {
-		dev_dbg(codec->dev, "Using MCLK/2 for %dHz MCLK\n", freq);
+		dev_dbg(component->dev, "Using MCLK/2 for %dHz MCLK\n", freq);
 		reg |= WM8961_MCLKDIV;
 		freq /= 2;
 	} else {
-		dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
+		dev_dbg(component->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
 		reg &= ~WM8961_MCLKDIV;
 	}
 
-	snd_soc_write(codec, WM8961_CLOCKING1, reg);
+	snd_soc_component_write(component, WM8961_CLOCKING1, reg);
 
 	wm8961->sysclk = freq;
 
@@ -623,8 +623,8 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 
 static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 aif = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
+	struct snd_soc_component *component = dai->component;
+	u16 aif = snd_soc_component_read32(component, WM8961_AUDIO_INTERFACE_0);
 
 	aif &= ~(WM8961_BCLKINV | WM8961_LRP |
 		 WM8961_MS | WM8961_FORMAT_MASK);
@@ -684,26 +684,26 @@ static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	return snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, aif);
+	return snd_soc_component_write(component, WM8961_AUDIO_INTERFACE_0, aif);
 }
 
 static int wm8961_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_2);
+	struct snd_soc_component *component = dai->component;
+	u16 reg = snd_soc_component_read32(component, WM8961_ADDITIONAL_CONTROL_2);
 
 	if (tristate)
 		reg |= WM8961_TRIS;
 	else
 		reg &= ~WM8961_TRIS;
 
-	return snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_2, reg);
+	return snd_soc_component_write(component, WM8961_ADDITIONAL_CONTROL_2, reg);
 }
 
 static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_1);
+	struct snd_soc_component *component = dai->component;
+	u16 reg = snd_soc_component_read32(component, WM8961_ADC_DAC_CONTROL_1);
 
 	if (mute)
 		reg |= WM8961_DACMU;
@@ -712,27 +712,27 @@ static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute)
 
 	msleep(17);
 
-	return snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_1, reg);
+	return snd_soc_component_write(component, WM8961_ADC_DAC_CONTROL_1, reg);
 }
 
 static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 reg;
 
 	switch (div_id) {
 	case WM8961_BCLK:
-		reg = snd_soc_read(codec, WM8961_CLOCKING2);
+		reg = snd_soc_component_read32(component, WM8961_CLOCKING2);
 		reg &= ~WM8961_BCLKDIV_MASK;
 		reg |= div;
-		snd_soc_write(codec, WM8961_CLOCKING2, reg);
+		snd_soc_component_write(component, WM8961_CLOCKING2, reg);
 		break;
 
 	case WM8961_LRCLK:
-		reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_2);
+		reg = snd_soc_component_read32(component, WM8961_AUDIO_INTERFACE_2);
 		reg &= ~WM8961_LRCLK_RATE_MASK;
 		reg |= div;
-		snd_soc_write(codec, WM8961_AUDIO_INTERFACE_2, reg);
+		snd_soc_component_write(component, WM8961_AUDIO_INTERFACE_2, reg);
 		break;
 
 	default:
@@ -742,7 +742,7 @@ static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
 	return 0;
 }
 
-static int wm8961_set_bias_level(struct snd_soc_codec *codec,
+static int wm8961_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	u16 reg;
@@ -757,36 +757,36 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
 			/* Enable bias generation */
-			reg = snd_soc_read(codec, WM8961_ANTI_POP);
+			reg = snd_soc_component_read32(component, WM8961_ANTI_POP);
 			reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN;
-			snd_soc_write(codec, WM8961_ANTI_POP, reg);
+			snd_soc_component_write(component, WM8961_ANTI_POP, reg);
 
 			/* VMID=2*50k, VREF */
-			reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
+			reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_1);
 			reg &= ~WM8961_VMIDSEL_MASK;
 			reg |= (1 << WM8961_VMIDSEL_SHIFT) | WM8961_VREF;
-			snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
+			snd_soc_component_write(component, WM8961_PWR_MGMT_1, reg);
 		}
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) {
 			/* VREF off */
-			reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
+			reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_1);
 			reg &= ~WM8961_VREF;
-			snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
+			snd_soc_component_write(component, WM8961_PWR_MGMT_1, reg);
 
 			/* Bias generation off */
-			reg = snd_soc_read(codec, WM8961_ANTI_POP);
+			reg = snd_soc_component_read32(component, WM8961_ANTI_POP);
 			reg &= ~(WM8961_BUFIOEN | WM8961_BUFDCOPEN);
-			snd_soc_write(codec, WM8961_ANTI_POP, reg);
+			snd_soc_component_write(component, WM8961_ANTI_POP, reg);
 
 			/* VMID off */
-			reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
+			reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_1);
 			reg &= ~WM8961_VMIDSEL_MASK;
-			snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
+			snd_soc_component_write(component, WM8961_PWR_MGMT_1, reg);
 		}
 		break;
 
@@ -830,51 +830,51 @@ static struct snd_soc_dai_driver wm8961_dai = {
 	.ops = &wm8961_dai_ops,
 };
 
-static int wm8961_probe(struct snd_soc_codec *codec)
+static int wm8961_probe(struct snd_soc_component *component)
 {
 	u16 reg;
 
 	/* Enable class W */
-	reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
+	reg = snd_soc_component_read32(component, WM8961_CHARGE_PUMP_B);
 	reg |= WM8961_CP_DYN_PWR_MASK;
-	snd_soc_write(codec, WM8961_CHARGE_PUMP_B, reg);
+	snd_soc_component_write(component, WM8961_CHARGE_PUMP_B, reg);
 
 	/* Latch volume update bits (right channel only, we always
 	 * write both out) and default ZC on. */
-	reg = snd_soc_read(codec, WM8961_ROUT1_VOLUME);
-	snd_soc_write(codec, WM8961_ROUT1_VOLUME,
+	reg = snd_soc_component_read32(component, WM8961_ROUT1_VOLUME);
+	snd_soc_component_write(component, WM8961_ROUT1_VOLUME,
 		     reg | WM8961_LO1ZC | WM8961_OUT1VU);
-	snd_soc_write(codec, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC);
-	reg = snd_soc_read(codec, WM8961_ROUT2_VOLUME);
-	snd_soc_write(codec, WM8961_ROUT2_VOLUME,
+	snd_soc_component_write(component, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC);
+	reg = snd_soc_component_read32(component, WM8961_ROUT2_VOLUME);
+	snd_soc_component_write(component, WM8961_ROUT2_VOLUME,
 		     reg | WM8961_SPKRZC | WM8961_SPKVU);
-	snd_soc_write(codec, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC);
+	snd_soc_component_write(component, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC);
 
-	reg = snd_soc_read(codec, WM8961_RIGHT_ADC_VOLUME);
-	snd_soc_write(codec, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU);
-	reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
-	snd_soc_write(codec, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU);
+	reg = snd_soc_component_read32(component, WM8961_RIGHT_ADC_VOLUME);
+	snd_soc_component_write(component, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU);
+	reg = snd_soc_component_read32(component, WM8961_RIGHT_INPUT_VOLUME);
+	snd_soc_component_write(component, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU);
 
 	/* Use soft mute by default */
-	reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
+	reg = snd_soc_component_read32(component, WM8961_ADC_DAC_CONTROL_2);
 	reg |= WM8961_DACSMM;
-	snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
+	snd_soc_component_write(component, WM8961_ADC_DAC_CONTROL_2, reg);
 
 	/* Use automatic clocking mode by default; for now this is all
 	 * we support.
 	 */
-	reg = snd_soc_read(codec, WM8961_CLOCKING_3);
+	reg = snd_soc_component_read32(component, WM8961_CLOCKING_3);
 	reg &= ~WM8961_MANUAL_MODE;
-	snd_soc_write(codec, WM8961_CLOCKING_3, reg);
+	snd_soc_component_write(component, WM8961_CLOCKING_3, reg);
 
 	return 0;
 }
 
 #ifdef CONFIG_PM
 
-static int wm8961_resume(struct snd_soc_codec *codec)
+static int wm8961_resume(struct snd_soc_component *component)
 {
-	snd_soc_cache_sync(codec);
+	snd_soc_component_cache_sync(component);
 
 	return 0;
 }
@@ -882,20 +882,21 @@ static int wm8961_resume(struct snd_soc_codec *codec)
 #define wm8961_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
-	.probe =	wm8961_probe,
-	.resume =	wm8961_resume,
-	.set_bias_level = wm8961_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8961_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8961_snd_controls),
-		.dapm_widgets		= wm8961_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8961_dapm_widgets),
-		.dapm_routes		= audio_paths,
-		.num_dapm_routes	= ARRAY_SIZE(audio_paths),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8961 = {
+	.probe			= wm8961_probe,
+	.resume			= wm8961_resume,
+	.set_bias_level		= wm8961_set_bias_level,
+	.controls		= wm8961_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8961_snd_controls),
+	.dapm_widgets		= wm8961_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8961_dapm_widgets),
+	.dapm_routes		= audio_paths,
+	.num_dapm_routes	= ARRAY_SIZE(audio_paths),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8961_regmap = {
@@ -961,19 +962,12 @@ static int wm8961_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8961);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8961, &wm8961_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8961, &wm8961_dai, 1);
 
 	return ret;
 }
 
-static int wm8961_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm8961_i2c_id[] = {
 	{ "wm8961", 0 },
 	{ }
@@ -985,7 +979,6 @@ static struct i2c_driver wm8961_i2c_driver = {
 		.name = "wm8961",
 	},
 	.probe =    wm8961_i2c_probe,
-	.remove =   wm8961_i2c_remove,
 	.id_table = wm8961_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index fd2731d..a11e9d6 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -55,7 +55,7 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
 struct wm8962_priv {
 	struct wm8962_pdata pdata;
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 
 	int sysclk;
 	int sysclk_rate;
@@ -1475,55 +1475,55 @@ static const DECLARE_TLV_DB_RANGE(classd_tlv,
 );
 static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
 
-static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
+static int wm8962_dsp2_write_config(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 
 	return regcache_sync_region(wm8962->regmap,
 				    WM8962_HDBASS_AI_1, WM8962_MAX_REGISTER);
 }
 
-static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
+static int wm8962_dsp2_set_enable(struct snd_soc_component *component, u16 val)
 {
-	u16 adcl = snd_soc_read(codec, WM8962_LEFT_ADC_VOLUME);
-	u16 adcr = snd_soc_read(codec, WM8962_RIGHT_ADC_VOLUME);
-	u16 dac = snd_soc_read(codec, WM8962_ADC_DAC_CONTROL_1);
+	u16 adcl = snd_soc_component_read32(component, WM8962_LEFT_ADC_VOLUME);
+	u16 adcr = snd_soc_component_read32(component, WM8962_RIGHT_ADC_VOLUME);
+	u16 dac = snd_soc_component_read32(component, WM8962_ADC_DAC_CONTROL_1);
 
 	/* Mute the ADCs and DACs */
-	snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, 0);
-	snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU);
-	snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
+	snd_soc_component_write(component, WM8962_LEFT_ADC_VOLUME, 0);
+	snd_soc_component_write(component, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU);
+	snd_soc_component_update_bits(component, WM8962_ADC_DAC_CONTROL_1,
 			    WM8962_DAC_MUTE, WM8962_DAC_MUTE);
 
-	snd_soc_write(codec, WM8962_SOUNDSTAGE_ENABLES_0, val);
+	snd_soc_component_write(component, WM8962_SOUNDSTAGE_ENABLES_0, val);
 
 	/* Restore the ADCs and DACs */
-	snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, adcl);
-	snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, adcr);
-	snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
+	snd_soc_component_write(component, WM8962_LEFT_ADC_VOLUME, adcl);
+	snd_soc_component_write(component, WM8962_RIGHT_ADC_VOLUME, adcr);
+	snd_soc_component_update_bits(component, WM8962_ADC_DAC_CONTROL_1,
 			    WM8962_DAC_MUTE, dac);
 
 	return 0;
 }
 
-static int wm8962_dsp2_start(struct snd_soc_codec *codec)
+static int wm8962_dsp2_start(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 
-	wm8962_dsp2_write_config(codec);
+	wm8962_dsp2_write_config(component);
 
-	snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR);
+	snd_soc_component_write(component, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR);
 
-	wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
+	wm8962_dsp2_set_enable(component, wm8962->dsp2_ena);
 
 	return 0;
 }
 
-static int wm8962_dsp2_stop(struct snd_soc_codec *codec)
+static int wm8962_dsp2_stop(struct snd_soc_component *component)
 {
-	wm8962_dsp2_set_enable(codec, 0);
+	wm8962_dsp2_set_enable(component, 0);
 
-	snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP);
+	snd_soc_component_write(component, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP);
 
 	return 0;
 }
@@ -1550,8 +1550,8 @@ static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	int shift = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift);
 
@@ -1562,11 +1562,11 @@ static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	int shift = kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	int old = wm8962->dsp2_ena;
 	int ret = 0;
-	int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) &
+	int dsp2_running = snd_soc_component_read32(component, WM8962_DSP2_POWER_MANAGEMENT) &
 		WM8962_DSP2_ENA;
 
 	mutex_lock(&wm8962->dsp2_ena_lock);
@@ -1583,9 +1583,9 @@ static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
 
 	if (dsp2_running) {
 		if (wm8962->dsp2_ena)
-			wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
+			wm8962_dsp2_set_enable(component, wm8962->dsp2_ena);
 		else
-			wm8962_dsp2_stop(codec);
+			wm8962_dsp2_stop(component);
 	}
 
 out:
@@ -1600,7 +1600,7 @@ static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
 static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
 			    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int ret;
 
 	/* Apply the update (if any) */
@@ -1609,17 +1609,17 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
 		return 0;
 
 	/* If the left PGA is enabled hit that VU bit... */
-	ret = snd_soc_read(codec, WM8962_PWR_MGMT_2);
+	ret = snd_soc_component_read32(component, WM8962_PWR_MGMT_2);
 	if (ret & WM8962_HPOUTL_PGA_ENA) {
-		snd_soc_write(codec, WM8962_HPOUTL_VOLUME,
-			      snd_soc_read(codec, WM8962_HPOUTL_VOLUME));
+		snd_soc_component_write(component, WM8962_HPOUTL_VOLUME,
+			      snd_soc_component_read32(component, WM8962_HPOUTL_VOLUME));
 		return 1;
 	}
 
 	/* ...otherwise the right.  The VU is stereo. */
 	if (ret & WM8962_HPOUTR_PGA_ENA)
-		snd_soc_write(codec, WM8962_HPOUTR_VOLUME,
-			      snd_soc_read(codec, WM8962_HPOUTR_VOLUME));
+		snd_soc_component_write(component, WM8962_HPOUTR_VOLUME,
+			      snd_soc_component_read32(component, WM8962_HPOUTR_VOLUME));
 
 	return 1;
 }
@@ -1630,7 +1630,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
 static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
 			    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int ret;
 
 	/* Apply the update (if any) */
@@ -1639,17 +1639,17 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
 		return 0;
 
 	/* If the left PGA is enabled hit that VU bit... */
-	ret = snd_soc_read(codec, WM8962_PWR_MGMT_2);
+	ret = snd_soc_component_read32(component, WM8962_PWR_MGMT_2);
 	if (ret & WM8962_SPKOUTL_PGA_ENA) {
-		snd_soc_write(codec, WM8962_SPKOUTL_VOLUME,
-			      snd_soc_read(codec, WM8962_SPKOUTL_VOLUME));
+		snd_soc_component_write(component, WM8962_SPKOUTL_VOLUME,
+			      snd_soc_component_read32(component, WM8962_SPKOUTL_VOLUME));
 		return 1;
 	}
 
 	/* ...otherwise the right.  The VU is stereo. */
 	if (ret & WM8962_SPKOUTR_PGA_ENA)
-		snd_soc_write(codec, WM8962_SPKOUTR_VOLUME,
-			      snd_soc_read(codec, WM8962_SPKOUTR_VOLUME));
+		snd_soc_component_write(component, WM8962_SPKOUTR_VOLUME,
+			      snd_soc_component_read32(component, WM8962_SPKOUTR_VOLUME));
 
 	return 1;
 }
@@ -1863,7 +1863,7 @@ static int cp_event(struct snd_soc_dapm_widget *w,
 static int hp_event(struct snd_soc_dapm_widget *w,
 		    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	int timeout;
 	int reg;
 	int expected = (WM8962_DCS_STARTUP_DONE_HP1L |
@@ -1871,17 +1871,17 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
+		snd_soc_component_update_bits(component, WM8962_ANALOGUE_HP_0,
 				    WM8962_HP1L_ENA | WM8962_HP1R_ENA,
 				    WM8962_HP1L_ENA | WM8962_HP1R_ENA);
 		udelay(20);
 
-		snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
+		snd_soc_component_update_bits(component, WM8962_ANALOGUE_HP_0,
 				    WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY,
 				    WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY);
 
 		/* Start the DC servo */
-		snd_soc_update_bits(codec, WM8962_DC_SERVO_1,
+		snd_soc_component_update_bits(component, WM8962_DC_SERVO_1,
 				    WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
 				    WM8962_HP1L_DCS_STARTUP |
 				    WM8962_HP1R_DCS_STARTUP,
@@ -1893,30 +1893,30 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 		timeout = 0;
 		do {
 			msleep(1);
-			reg = snd_soc_read(codec, WM8962_DC_SERVO_6);
+			reg = snd_soc_component_read32(component, WM8962_DC_SERVO_6);
 			if (reg < 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to read DCS status: %d\n",
 					reg);
 				continue;
 			}
-			dev_dbg(codec->dev, "DCS status: %x\n", reg);
+			dev_dbg(component->dev, "DCS status: %x\n", reg);
 		} while (++timeout < 200 && (reg & expected) != expected);
 
 		if ((reg & expected) != expected)
-			dev_err(codec->dev, "DC servo timed out\n");
+			dev_err(component->dev, "DC servo timed out\n");
 		else
-			dev_dbg(codec->dev, "DC servo complete after %dms\n",
+			dev_dbg(component->dev, "DC servo complete after %dms\n",
 				timeout);
 
-		snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
+		snd_soc_component_update_bits(component, WM8962_ANALOGUE_HP_0,
 				    WM8962_HP1L_ENA_OUTP |
 				    WM8962_HP1R_ENA_OUTP,
 				    WM8962_HP1L_ENA_OUTP |
 				    WM8962_HP1R_ENA_OUTP);
 		udelay(20);
 
-		snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
+		snd_soc_component_update_bits(component, WM8962_ANALOGUE_HP_0,
 				    WM8962_HP1L_RMV_SHORT |
 				    WM8962_HP1R_RMV_SHORT,
 				    WM8962_HP1L_RMV_SHORT |
@@ -1924,19 +1924,19 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
+		snd_soc_component_update_bits(component, WM8962_ANALOGUE_HP_0,
 				    WM8962_HP1L_RMV_SHORT |
 				    WM8962_HP1R_RMV_SHORT, 0);
 
 		udelay(20);
 
-		snd_soc_update_bits(codec, WM8962_DC_SERVO_1,
+		snd_soc_component_update_bits(component, WM8962_DC_SERVO_1,
 				    WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
 				    WM8962_HP1L_DCS_STARTUP |
 				    WM8962_HP1R_DCS_STARTUP,
 				    0);
 
-		snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
+		snd_soc_component_update_bits(component, WM8962_ANALOGUE_HP_0,
 				    WM8962_HP1L_ENA | WM8962_HP1R_ENA |
 				    WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY |
 				    WM8962_HP1L_ENA_OUTP |
@@ -1957,7 +1957,7 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 static int out_pga_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	int reg;
 
 	switch (w->shift) {
@@ -1980,7 +1980,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		return snd_soc_write(codec, reg, snd_soc_read(codec, reg));
+		return snd_soc_component_write(component, reg, snd_soc_component_read32(component, reg));
 	default:
 		WARN(1, "Invalid event %d\n", event);
 		return -EINVAL;
@@ -1990,18 +1990,18 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 static int dsp2_event(struct snd_soc_dapm_widget *w,
 		      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		if (wm8962->dsp2_ena)
-			wm8962_dsp2_start(codec);
+			wm8962_dsp2_start(component);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
 		if (wm8962->dsp2_ena)
-			wm8962_dsp2_stop(codec);
+			wm8962_dsp2_stop(component);
 		break;
 
 	default:
@@ -2354,19 +2354,19 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
 	{ "SPKOUTR", NULL, "SPKOUTR Output" },
 };
 
-static int wm8962_add_widgets(struct snd_soc_codec *codec)
+static int wm8962_add_widgets(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	struct wm8962_pdata *pdata = &wm8962->pdata;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-	snd_soc_add_codec_controls(codec, wm8962_snd_controls,
+	snd_soc_add_component_controls(component, wm8962_snd_controls,
 			     ARRAY_SIZE(wm8962_snd_controls));
 	if (pdata->spk_mono)
-		snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls,
+		snd_soc_add_component_controls(component, wm8962_spk_mono_controls,
 				     ARRAY_SIZE(wm8962_spk_mono_controls));
 	else
-		snd_soc_add_codec_controls(codec, wm8962_spk_stereo_controls,
+		snd_soc_add_component_controls(component, wm8962_spk_stereo_controls,
 				     ARRAY_SIZE(wm8962_spk_stereo_controls));
 
 
@@ -2403,21 +2403,21 @@ static const int sysclk_rates[] = {
 	64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 3072, 6144
 };
 
-static void wm8962_configure_bclk(struct snd_soc_codec *codec)
+static void wm8962_configure_bclk(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	int dspclk, i;
 	int clocking2 = 0;
 	int clocking4 = 0;
 	int aif2 = 0;
 
 	if (!wm8962->sysclk_rate) {
-		dev_dbg(codec->dev, "No SYSCLK configured\n");
+		dev_dbg(component->dev, "No SYSCLK configured\n");
 		return;
 	}
 
 	if (!wm8962->bclk || !wm8962->lrclk) {
-		dev_dbg(codec->dev, "No audio clocks configured\n");
+		dev_dbg(component->dev, "No audio clocks configured\n");
 		return;
 	}
 
@@ -2429,32 +2429,32 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
 	}
 
 	if (i == ARRAY_SIZE(sysclk_rates)) {
-		dev_err(codec->dev, "Unsupported sysclk ratio %d\n",
+		dev_err(component->dev, "Unsupported sysclk ratio %d\n",
 			wm8962->sysclk_rate / wm8962->lrclk);
 		return;
 	}
 
-	dev_dbg(codec->dev, "Selected sysclk ratio %d\n", sysclk_rates[i]);
+	dev_dbg(component->dev, "Selected sysclk ratio %d\n", sysclk_rates[i]);
 
-	snd_soc_update_bits(codec, WM8962_CLOCKING_4,
+	snd_soc_component_update_bits(component, WM8962_CLOCKING_4,
 			    WM8962_SYSCLK_RATE_MASK, clocking4);
 
 	/* DSPCLK_DIV can be only generated correctly after enabling SYSCLK.
 	 * So we here provisionally enable it and then disable it afterward
 	 * if current bias_level hasn't reached SND_SOC_BIAS_ON.
 	 */
-	if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_ON)
-		snd_soc_update_bits(codec, WM8962_CLOCKING2,
+	if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
+		snd_soc_component_update_bits(component, WM8962_CLOCKING2,
 				WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA);
 
-	dspclk = snd_soc_read(codec, WM8962_CLOCKING1);
+	dspclk = snd_soc_component_read32(component, WM8962_CLOCKING1);
 
-	if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_ON)
-		snd_soc_update_bits(codec, WM8962_CLOCKING2,
+	if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
+		snd_soc_component_update_bits(component, WM8962_CLOCKING2,
 				WM8962_SYSCLK_ENA_MASK, 0);
 
 	if (dspclk < 0) {
-		dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
+		dev_err(component->dev, "Failed to read DSPCLK: %d\n", dspclk);
 		return;
 	}
 
@@ -2470,11 +2470,11 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
 		dspclk = wm8962->sysclk_rate / 4;
 		break;
 	default:
-		dev_warn(codec->dev, "Unknown DSPCLK divisor read back\n");
+		dev_warn(component->dev, "Unknown DSPCLK divisor read back\n");
 		dspclk = wm8962->sysclk_rate;
 	}
 
-	dev_dbg(codec->dev, "DSPCLK is %dHz, BCLK %d\n", dspclk, wm8962->bclk);
+	dev_dbg(component->dev, "DSPCLK is %dHz, BCLK %d\n", dspclk, wm8962->bclk);
 
 	/* We're expecting an exact match */
 	for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
@@ -2482,29 +2482,29 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
 			continue;
 
 		if (dspclk / bclk_divs[i] == wm8962->bclk) {
-			dev_dbg(codec->dev, "Selected BCLK_DIV %d for %dHz\n",
+			dev_dbg(component->dev, "Selected BCLK_DIV %d for %dHz\n",
 				bclk_divs[i], wm8962->bclk);
 			clocking2 |= i;
 			break;
 		}
 	}
 	if (i == ARRAY_SIZE(bclk_divs)) {
-		dev_err(codec->dev, "Unsupported BCLK ratio %d\n",
+		dev_err(component->dev, "Unsupported BCLK ratio %d\n",
 			dspclk / wm8962->bclk);
 		return;
 	}
 
 	aif2 |= wm8962->bclk / wm8962->lrclk;
-	dev_dbg(codec->dev, "Selected LRCLK divisor %d for %dHz\n",
+	dev_dbg(component->dev, "Selected LRCLK divisor %d for %dHz\n",
 		wm8962->bclk / wm8962->lrclk, wm8962->lrclk);
 
-	snd_soc_update_bits(codec, WM8962_CLOCKING2,
+	snd_soc_component_update_bits(component, WM8962_CLOCKING2,
 			    WM8962_BCLK_DIV_MASK, clocking2);
-	snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_2,
+	snd_soc_component_update_bits(component, WM8962_AUDIO_INTERFACE_2,
 			    WM8962_AIF_RATE_MASK, aif2);
 }
 
-static int wm8962_set_bias_level(struct snd_soc_codec *codec,
+static int wm8962_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
@@ -2513,18 +2513,18 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID 2*50k */
-		snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
+		snd_soc_component_update_bits(component, WM8962_PWR_MGMT_1,
 				    WM8962_VMID_SEL_MASK, 0x80);
 
-		wm8962_configure_bclk(codec);
+		wm8962_configure_bclk(component);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
 		/* VMID 2*250k */
-		snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
+		snd_soc_component_update_bits(component, WM8962_PWR_MGMT_1,
 				    WM8962_VMID_SEL_MASK, 0x100);
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 			msleep(100);
 		break;
 
@@ -2556,8 +2556,8 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	int i;
 	int aif0 = 0;
 	int adctl3 = 0;
@@ -2575,7 +2575,7 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 	if (i == ARRAY_SIZE(sr_vals)) {
-		dev_err(codec->dev, "Unsupported rate %dHz\n", wm8962->lrclk);
+		dev_err(component->dev, "Unsupported rate %dHz\n", wm8962->lrclk);
 		return -EINVAL;
 	}
 
@@ -2598,17 +2598,17 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_0,
+	snd_soc_component_update_bits(component, WM8962_AUDIO_INTERFACE_0,
 			    WM8962_WL_MASK, aif0);
-	snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_3,
+	snd_soc_component_update_bits(component, WM8962_ADDITIONAL_CONTROL_3,
 			    WM8962_SAMPLE_RATE_INT_MODE |
 			    WM8962_SAMPLE_RATE_MASK, adctl3);
 
-	dev_dbg(codec->dev, "hw_params set BCLK %dHz LRCLK %dHz\n",
+	dev_dbg(component->dev, "hw_params set BCLK %dHz LRCLK %dHz\n",
 		wm8962->bclk, wm8962->lrclk);
 
-	if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON)
-		wm8962_configure_bclk(codec);
+	if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON)
+		wm8962_configure_bclk(component);
 
 	return 0;
 }
@@ -2616,8 +2616,8 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
 static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 				 unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	int src;
 
 	switch (clk_id) {
@@ -2633,7 +2633,7 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_SRC_MASK,
+	snd_soc_component_update_bits(component, WM8962_CLOCKING2, WM8962_SYSCLK_SRC_MASK,
 			    src);
 
 	wm8962->sysclk_rate = freq;
@@ -2643,7 +2643,7 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 
 static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int aif0 = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -2699,7 +2699,7 @@ static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_0,
+	snd_soc_component_update_bits(component, WM8962_AUDIO_INTERFACE_0,
 			    WM8962_FMT_MASK | WM8962_BCLK_INV | WM8962_MSTR |
 			    WM8962_LRCLK_INV, aif0);
 
@@ -2809,10 +2809,10 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 	return 0;
 }
 
-static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+static int wm8962_set_fll(struct snd_soc_component *component, int fll_id, int source,
 			  unsigned int Fref, unsigned int Fout)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	struct _fll_div fll_div;
 	unsigned long timeout;
 	int ret;
@@ -2824,15 +2824,15 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		return 0;
 
 	if (Fout == 0) {
-		dev_dbg(codec->dev, "FLL disabled\n");
+		dev_dbg(component->dev, "FLL disabled\n");
 
 		wm8962->fll_fref = 0;
 		wm8962->fll_fout = 0;
 
-		snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_1,
 				    WM8962_FLL_ENA, 0);
 
-		pm_runtime_put(codec->dev);
+		pm_runtime_put(component->dev);
 
 		return 0;
 	}
@@ -2842,7 +2842,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		return ret;
 
 	/* Parameters good, disable so we can reprogram */
-	snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
+	snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
 
 	switch (fll_id) {
 	case WM8962_FLL_MCLK:
@@ -2851,13 +2851,13 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		fll1 |= (fll_id - 1) << WM8962_FLL_REFCLK_SRC_SHIFT;
 		break;
 	case WM8962_FLL_INT:
-		snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_1,
 				    WM8962_FLL_OSC_ENA, WM8962_FLL_OSC_ENA);
-		snd_soc_update_bits(codec, WM8962_FLL_CONTROL_5,
+		snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_5,
 				    WM8962_FLL_FRC_NCO, WM8962_FLL_FRC_NCO);
 		break;
 	default:
-		dev_err(codec->dev, "Unknown FLL source %d\n", ret);
+		dev_err(component->dev, "Unknown FLL source %d\n", ret);
 		return -EINVAL;
 	}
 
@@ -2865,34 +2865,34 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		fll1 |= WM8962_FLL_FRAC;
 
 	/* Stop the FLL while we reconfigure */
-	snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
+	snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
 
-	snd_soc_update_bits(codec, WM8962_FLL_CONTROL_2,
+	snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_2,
 			    WM8962_FLL_OUTDIV_MASK |
 			    WM8962_FLL_REFCLK_DIV_MASK,
 			    (fll_div.fll_outdiv << WM8962_FLL_OUTDIV_SHIFT) |
 			    (fll_div.fll_refclk_div));
 
-	snd_soc_update_bits(codec, WM8962_FLL_CONTROL_3,
+	snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_3,
 			    WM8962_FLL_FRATIO_MASK, fll_div.fll_fratio);
 
-	snd_soc_write(codec, WM8962_FLL_CONTROL_6, fll_div.theta);
-	snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda);
-	snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n);
+	snd_soc_component_write(component, WM8962_FLL_CONTROL_6, fll_div.theta);
+	snd_soc_component_write(component, WM8962_FLL_CONTROL_7, fll_div.lambda);
+	snd_soc_component_write(component, WM8962_FLL_CONTROL_8, fll_div.n);
 
 	reinit_completion(&wm8962->fll_lock);
 
-	ret = pm_runtime_get_sync(codec->dev);
+	ret = pm_runtime_get_sync(component->dev);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to resume device: %d\n", ret);
+		dev_err(component->dev, "Failed to resume device: %d\n", ret);
 		return ret;
 	}
 
-	snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
+	snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_1,
 			    WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
 			    WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA);
 
-	dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
+	dev_dbg(component->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
 
 	/* This should be a massive overestimate but go even
 	 * higher if we'll error out
@@ -2906,10 +2906,10 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 					      timeout);
 
 	if (timeout == 0 && wm8962->irq) {
-		dev_err(codec->dev, "FLL lock timed out");
-		snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
+		dev_err(component->dev, "FLL lock timed out");
+		snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_1,
 				    WM8962_FLL_ENA, 0);
-		pm_runtime_put(codec->dev);
+		pm_runtime_put(component->dev);
 		return -ETIMEDOUT;
 	}
 
@@ -2922,7 +2922,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 
 static int wm8962_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int val, ret;
 
 	if (mute)
@@ -2934,12 +2934,12 @@ static int wm8962_mute(struct snd_soc_dai *dai, int mute)
 	 * The DAC mute bit is mirrored in two registers, update both to keep
 	 * the register cache consistent.
 	 */
-	ret = snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_1,
+	ret = snd_soc_component_update_bits(component, WM8962_CLASS_D_CONTROL_1,
 				  WM8962_DAC_MUTE_ALT, val);
 	if (ret < 0)
 		return ret;
 
-	return snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
+	return snd_soc_component_update_bits(component, WM8962_ADC_DAC_CONTROL_1,
 				   WM8962_DAC_MUTE, val);
 }
 
@@ -2981,12 +2981,12 @@ static void wm8962_mic_work(struct work_struct *work)
 	struct wm8962_priv *wm8962 = container_of(work,
 						  struct wm8962_priv,
 						  mic_work.work);
-	struct snd_soc_codec *codec = wm8962->codec;
+	struct snd_soc_component *component = wm8962->component;
 	int status = 0;
 	int irq_pol = 0;
 	int reg;
 
-	reg = snd_soc_read(codec, WM8962_ADDITIONAL_CONTROL_4);
+	reg = snd_soc_component_read32(component, WM8962_ADDITIONAL_CONTROL_4);
 
 	if (reg & WM8962_MICDET_STS) {
 		status |= SND_JACK_MICROPHONE;
@@ -3001,7 +3001,7 @@ static void wm8962_mic_work(struct work_struct *work)
 	snd_soc_jack_report(wm8962->jack, status,
 			    SND_JACK_MICROPHONE | SND_JACK_BTN_0);
 
-	snd_soc_update_bits(codec, WM8962_MICINT_SOURCE_POL,
+	snd_soc_component_update_bits(component, WM8962_MICINT_SOURCE_POL,
 			    WM8962_MICSCD_IRQ_POL |
 			    WM8962_MICD_IRQ_POL, irq_pol);
 }
@@ -3099,7 +3099,7 @@ static irqreturn_t wm8962_irq(int irq, void *data)
 /**
  * wm8962_mic_detect - Enable microphone detection via the WM8962 IRQ
  *
- * @codec:  WM8962 codec
+ * @component:  WM8962 component
  * @jack:   jack to report detection events on
  *
  * Enable microphone detection via IRQ on the WM8962.  If GPIOs are
@@ -3109,10 +3109,10 @@ static irqreturn_t wm8962_irq(int irq, void *data)
  *
  * If no jack is supplied detection will be disabled.
  */
-int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int wm8962_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int irq_mask, enable;
 
 	wm8962->jack = jack;
@@ -3124,9 +3124,9 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 		enable = 0;
 	}
 
-	snd_soc_update_bits(codec, WM8962_INTERRUPT_STATUS_2_MASK,
+	snd_soc_component_update_bits(component, WM8962_INTERRUPT_STATUS_2_MASK,
 			    WM8962_MICD_EINT | WM8962_MICSCD_EINT, irq_mask);
-	snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4,
+	snd_soc_component_update_bits(component, WM8962_ADDITIONAL_CONTROL_4,
 			    WM8962_MICDET_ENA, enable);
 
 	/* Send an initial empty report */
@@ -3157,8 +3157,8 @@ static void wm8962_beep_work(struct work_struct *work)
 {
 	struct wm8962_priv *wm8962 =
 		container_of(work, struct wm8962_priv, beep_work);
-	struct snd_soc_codec *codec = wm8962->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = wm8962->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int i;
 	int reg = 0;
 	int best = 0;
@@ -3170,18 +3170,18 @@ static void wm8962_beep_work(struct work_struct *work)
 				best = i;
 		}
 
-		dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
+		dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
 			beep_rates[best], wm8962->beep_rate);
 
 		reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT);
 
 		snd_soc_dapm_enable_pin(dapm, "Beep");
 	} else {
-		dev_dbg(codec->dev, "Disabling beep\n");
+		dev_dbg(component->dev, "Disabling beep\n");
 		snd_soc_dapm_disable_pin(dapm, "Beep");
 	}
 
-	snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1,
+	snd_soc_component_update_bits(component, WM8962_BEEP_GENERATOR_1,
 			    WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg);
 
 	snd_soc_dapm_sync(dapm);
@@ -3193,10 +3193,10 @@ static void wm8962_beep_work(struct work_struct *work)
 static int wm8962_beep_event(struct input_dev *dev, unsigned int type,
 			     unsigned int code, int hz)
 {
-	struct snd_soc_codec *codec = input_get_drvdata(dev);
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = input_get_drvdata(dev);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 
-	dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
+	dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
 
 	switch (code) {
 	case SND_BELL:
@@ -3233,14 +3233,14 @@ static ssize_t wm8962_beep_set(struct device *dev,
 
 static DEVICE_ATTR(beep, 0200, NULL, wm8962_beep_set);
 
-static void wm8962_init_beep(struct snd_soc_codec *codec)
+static void wm8962_init_beep(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	wm8962->beep = devm_input_allocate_device(codec->dev);
+	wm8962->beep = devm_input_allocate_device(component->dev);
 	if (!wm8962->beep) {
-		dev_err(codec->dev, "Failed to allocate beep device\n");
+		dev_err(component->dev, "Failed to allocate beep device\n");
 		return;
 	}
 
@@ -3248,37 +3248,37 @@ static void wm8962_init_beep(struct snd_soc_codec *codec)
 	wm8962->beep_rate = 0;
 
 	wm8962->beep->name = "WM8962 Beep Generator";
-	wm8962->beep->phys = dev_name(codec->dev);
+	wm8962->beep->phys = dev_name(component->dev);
 	wm8962->beep->id.bustype = BUS_I2C;
 
 	wm8962->beep->evbit[0] = BIT_MASK(EV_SND);
 	wm8962->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	wm8962->beep->event = wm8962_beep_event;
-	wm8962->beep->dev.parent = codec->dev;
-	input_set_drvdata(wm8962->beep, codec);
+	wm8962->beep->dev.parent = component->dev;
+	input_set_drvdata(wm8962->beep, component);
 
 	ret = input_register_device(wm8962->beep);
 	if (ret != 0) {
 		wm8962->beep = NULL;
-		dev_err(codec->dev, "Failed to register beep device\n");
+		dev_err(component->dev, "Failed to register beep device\n");
 	}
 
-	ret = device_create_file(codec->dev, &dev_attr_beep);
+	ret = device_create_file(component->dev, &dev_attr_beep);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to create keyclick file: %d\n",
+		dev_err(component->dev, "Failed to create keyclick file: %d\n",
 			ret);
 	}
 }
 
-static void wm8962_free_beep(struct snd_soc_codec *codec)
+static void wm8962_free_beep(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 
-	device_remove_file(codec->dev, &dev_attr_beep);
+	device_remove_file(component->dev, &dev_attr_beep);
 	cancel_work_sync(&wm8962->beep_work);
 	wm8962->beep = NULL;
 
-	snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA,0);
+	snd_soc_component_update_bits(component, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA,0);
 }
 
 static void wm8962_set_gpio_mode(struct wm8962_priv *wm8962, int gpio)
@@ -3333,9 +3333,9 @@ static int wm8962_gpio_request(struct gpio_chip *chip, unsigned offset)
 static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct wm8962_priv *wm8962 = gpiochip_get_data(chip);
-	struct snd_soc_codec *codec = wm8962->codec;
+	struct snd_soc_component *component = wm8962->component;
 
-	snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
+	snd_soc_component_update_bits(component, WM8962_GPIO_BASE + offset,
 			    WM8962_GP2_LVL, !!value << WM8962_GP2_LVL_SHIFT);
 }
 
@@ -3343,13 +3343,13 @@ static int wm8962_gpio_direction_out(struct gpio_chip *chip,
 				     unsigned offset, int value)
 {
 	struct wm8962_priv *wm8962 = gpiochip_get_data(chip);
-	struct snd_soc_codec *codec = wm8962->codec;
+	struct snd_soc_component *component = wm8962->component;
 	int ret, val;
 
 	/* Force function 1 (logic output) */
 	val = (1 << WM8962_GP2_FN_SHIFT) | (value << WM8962_GP2_LVL_SHIFT);
 
-	ret = snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
+	ret = snd_soc_component_update_bits(component, WM8962_GPIO_BASE + offset,
 				  WM8962_GP2_FN_MASK | WM8962_GP2_LVL, val);
 	if (ret < 0)
 		return ret;
@@ -3366,15 +3366,15 @@ static const struct gpio_chip wm8962_template_chip = {
 	.can_sleep		= 1,
 };
 
-static void wm8962_init_gpio(struct snd_soc_codec *codec)
+static void wm8962_init_gpio(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	struct wm8962_pdata *pdata = &wm8962->pdata;
 	int ret;
 
 	wm8962->gpio_chip = wm8962_template_chip;
 	wm8962->gpio_chip.ngpio = WM8962_MAX_GPIO;
-	wm8962->gpio_chip.parent = codec->dev;
+	wm8962->gpio_chip.parent = component->dev;
 
 	if (pdata->gpio_base)
 		wm8962->gpio_chip.base = pdata->gpio_base;
@@ -3383,34 +3383,34 @@ static void wm8962_init_gpio(struct snd_soc_codec *codec)
 
 	ret = gpiochip_add_data(&wm8962->gpio_chip, wm8962);
 	if (ret != 0)
-		dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+		dev_err(component->dev, "Failed to add GPIOs: %d\n", ret);
 }
 
-static void wm8962_free_gpio(struct snd_soc_codec *codec)
+static void wm8962_free_gpio(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 
 	gpiochip_remove(&wm8962->gpio_chip);
 }
 #else
-static void wm8962_init_gpio(struct snd_soc_codec *codec)
+static void wm8962_init_gpio(struct snd_soc_component *component)
 {
 }
 
-static void wm8962_free_gpio(struct snd_soc_codec *codec)
+static void wm8962_free_gpio(struct snd_soc_component *component)
 {
 }
 #endif
 
-static int wm8962_probe(struct snd_soc_codec *codec)
+static int wm8962_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int ret;
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	int i;
 	bool dmicclk, dmicdat;
 
-	wm8962->codec = codec;
+	wm8962->component = component;
 
 	wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0;
 	wm8962->disable_nb[1].notifier_call = wm8962_regulator_event_1;
@@ -3426,19 +3426,19 @@ static int wm8962_probe(struct snd_soc_codec *codec)
 		ret = regulator_register_notifier(wm8962->supplies[i].consumer,
 						  &wm8962->disable_nb[i]);
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to register regulator notifier: %d\n",
 				ret);
 		}
 	}
 
-	wm8962_add_widgets(codec);
+	wm8962_add_widgets(component);
 
 	/* Save boards having to disable DMIC when not in use */
 	dmicclk = false;
 	dmicdat = false;
 	for (i = 0; i < WM8962_MAX_GPIO; i++) {
-		switch (snd_soc_read(codec, WM8962_GPIO_BASE + i)
+		switch (snd_soc_component_read32(component, WM8962_GPIO_BASE + i)
 			& WM8962_GP2_FN_MASK) {
 		case WM8962_GPIO_FN_DMICCLK:
 			dmicclk = true;
@@ -3451,40 +3451,40 @@ static int wm8962_probe(struct snd_soc_codec *codec)
 		}
 	}
 	if (!dmicclk || !dmicdat) {
-		dev_dbg(codec->dev, "DMIC not in use, disabling\n");
+		dev_dbg(component->dev, "DMIC not in use, disabling\n");
 		snd_soc_dapm_nc_pin(dapm, "DMICDAT");
 	}
 	if (dmicclk != dmicdat)
-		dev_warn(codec->dev, "DMIC GPIOs partially configured\n");
+		dev_warn(component->dev, "DMIC GPIOs partially configured\n");
 
-	wm8962_init_beep(codec);
-	wm8962_init_gpio(codec);
+	wm8962_init_beep(component);
+	wm8962_init_gpio(component);
 
 	return 0;
 }
 
-static int wm8962_remove(struct snd_soc_codec *codec)
+static void wm8962_remove(struct snd_soc_component *component)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	cancel_delayed_work_sync(&wm8962->mic_work);
 
-	wm8962_free_gpio(codec);
-	wm8962_free_beep(codec);
+	wm8962_free_gpio(component);
+	wm8962_free_beep(component);
 	for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
 		regulator_unregister_notifier(wm8962->supplies[i].consumer,
 					      &wm8962->disable_nb[i]);
-
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
-	.probe =	wm8962_probe,
-	.remove =	wm8962_remove,
-	.set_bias_level = wm8962_set_bias_level,
-	.set_pll = wm8962_set_fll,
-	.idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_wm8962 = {
+	.probe			= wm8962_probe,
+	.remove			= wm8962_remove,
+	.set_bias_level		= wm8962_set_bias_level,
+	.set_pll		= wm8962_set_fll,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /* Improve power consumption for IN4 DC measurement mode */
@@ -3751,8 +3751,8 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
 	pm_runtime_enable(&i2c->dev);
 	pm_request_idle(&i2c->dev);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-				     &soc_codec_dev_wm8962, &wm8962_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_wm8962, &wm8962_dai, 1);
 	if (ret < 0)
 		goto err_pm_runtime;
 
@@ -3773,7 +3773,6 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
 
 static int wm8962_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	pm_runtime_disable(&client->dev);
 	return 0;
 }
diff --git a/sound/soc/codecs/wm8962.h b/sound/soc/codecs/wm8962.h
index e63a318..a4a42d2 100644
--- a/sound/soc/codecs/wm8962.h
+++ b/sound/soc/codecs/wm8962.h
@@ -3779,6 +3779,6 @@
 #define WM8962_VSS_ENA_SHIFT                         0  /* VSS_ENA */
 #define WM8962_VSS_ENA_WIDTH                         1  /* VSS_ENA */
 
-int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int wm8962_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #endif
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 887d31c..a79f7a7 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -89,7 +89,7 @@ static const struct reg_default wm8971_reg_defaults[] = {
 	{ 42, 0x0079 },
 };
 
-#define wm8971_reset(c)	snd_soc_write(c, WM8971_RESET, 0)
+#define wm8971_reset(c)	snd_soc_component_write(c, WM8971_RESET, 0)
 
 /* WM8971 Controls */
 static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
@@ -433,8 +433,8 @@ static int get_coeff(int mclk, int rate)
 static int wm8971_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8971_priv *wm8971 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case 11289600:
@@ -451,7 +451,7 @@ static int wm8971_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
 
 	/* set master/slave audio interface */
@@ -502,7 +502,7 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8971_IFACE, iface);
+	snd_soc_component_write(component, WM8971_IFACE, iface);
 	return 0;
 }
 
@@ -510,10 +510,10 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params,
 	struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
-	u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
-	u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
+	struct snd_soc_component *component = dai->component;
+	struct wm8971_priv *wm8971 = snd_soc_component_get_drvdata(component);
+	u16 iface = snd_soc_component_read32(component, WM8971_IFACE) & 0x1f3;
+	u16 srate = snd_soc_component_read32(component, WM8971_SRATE) & 0x1c0;
 	int coeff = get_coeff(wm8971->sysclk, params_rate(params));
 
 	/* bit size */
@@ -532,9 +532,9 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* set iface & srate */
-	snd_soc_write(codec, WM8971_IFACE, iface);
+	snd_soc_component_write(component, WM8971_IFACE, iface);
 	if (coeff >= 0)
-		snd_soc_write(codec, WM8971_SRATE, srate |
+		snd_soc_component_write(component, WM8971_SRATE, srate |
 			(coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
 
 	return 0;
@@ -542,13 +542,13 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8971_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8971_ADCDAC) & 0xfff7;
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8971_ADCDAC) & 0xfff7;
 
 	if (mute)
-		snd_soc_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
+		snd_soc_component_write(component, WM8971_ADCDAC, mute_reg | 0x8);
 	else
-		snd_soc_write(codec, WM8971_ADCDAC, mute_reg);
+		snd_soc_component_write(component, WM8971_ADCDAC, mute_reg);
 	return 0;
 }
 
@@ -561,37 +561,37 @@ static void wm8971_charge_work(struct work_struct *work)
 	regmap_update_bits(wm8971->regmap, WM8971_PWR1, 0x0180, 0x0100);
 }
 
-static int wm8971_set_bias_level(struct snd_soc_codec *codec,
+static int wm8971_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
-	u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
+	struct wm8971_priv *wm8971 = snd_soc_component_get_drvdata(component);
+	u16 pwr_reg = snd_soc_component_read32(component, WM8971_PWR1) & 0xfe3e;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		/* set vmid to 50k and unmute dac */
-		snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
+		snd_soc_component_write(component, WM8971_PWR1, pwr_reg | 0x00c1);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		/* Wait until fully charged */
 		flush_delayed_work(&wm8971->charge_work);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			snd_soc_cache_sync(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			snd_soc_component_cache_sync(component);
 			/* charge output caps - set vmid to 5k for quick power up */
-			snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x01c0);
+			snd_soc_component_write(component, WM8971_PWR1, pwr_reg | 0x01c0);
 			queue_delayed_work(system_power_efficient_wq,
 				&wm8971->charge_work, msecs_to_jiffies(1000));
 		} else {
 			/* mute dac and set vmid to 500k, enable VREF */
-			snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
+			snd_soc_component_write(component, WM8971_PWR1, pwr_reg | 0x0140);
 		}
 
 		break;
 	case SND_SOC_BIAS_OFF:
 		cancel_delayed_work_sync(&wm8971->charge_work);
-		snd_soc_write(codec, WM8971_PWR1, 0x0001);
+		snd_soc_component_write(component, WM8971_PWR1, 0x0001);
 		break;
 	}
 	return 0;
@@ -628,40 +628,41 @@ static struct snd_soc_dai_driver wm8971_dai = {
 	.ops = &wm8971_dai_ops,
 };
 
-static int wm8971_probe(struct snd_soc_codec *codec)
+static int wm8971_probe(struct snd_soc_component *component)
 {
-	struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
+	struct wm8971_priv *wm8971 = snd_soc_component_get_drvdata(component);
 
 	INIT_DELAYED_WORK(&wm8971->charge_work, wm8971_charge_work);
 
-	wm8971_reset(codec);
+	wm8971_reset(component);
 
 	/* set the update bits */
-	snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8971_LOUT1V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8971_ROUT1V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8971_LOUT2V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8971_ROUT2V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8971_LDAC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8971_RDAC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8971_LOUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8971_ROUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8971_LOUT2V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8971_ROUT2V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8971_LINVOL, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8971_RINVOL, 0x0100, 0x0100);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
-	.probe =	wm8971_probe,
-	.set_bias_level = wm8971_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8971_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8971_snd_controls),
-		.dapm_widgets		= wm8971_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8971_dapm_widgets),
-		.dapm_routes		= wm8971_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8971_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8971 = {
+	.probe			= wm8971_probe,
+	.set_bias_level		= wm8971_set_bias_level,
+	.controls		= wm8971_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8971_snd_controls),
+	.dapm_widgets		= wm8971_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8971_dapm_widgets),
+	.dapm_routes		= wm8971_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8971_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8971_regmap = {
@@ -691,18 +692,12 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8971);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8971, &wm8971_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8971, &wm8971_dai, 1);
 
 	return ret;
 }
 
-static int wm8971_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8971_i2c_id[] = {
 	{ "wm8971", 0 },
 	{ }
@@ -714,7 +709,6 @@ static struct i2c_driver wm8971_i2c_driver = {
 		.name = "wm8971",
 	},
 	.probe =    wm8971_i2c_probe,
-	.remove =   wm8971_i2c_remove,
 	.id_table = wm8971_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index d414ddd..43edaf8 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -54,7 +54,7 @@ static const struct reg_default wm8974_reg_defaults[] = {
 #define WM8974_POWER1_BIASEN  0x08
 #define WM8974_POWER1_BUFIOEN 0x04
 
-#define wm8974_reset(c)	snd_soc_write(c, WM8974_RESET, 0)
+#define wm8974_reset(c)	snd_soc_component_write(c, WM8974_RESET, 0)
 
 static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
 static const char *wm8974_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz" };
@@ -324,33 +324,33 @@ static void pll_factors(struct pll_ *pll_div,
 static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	struct pll_ pll_div;
 	u16 reg;
 
 	if (freq_in == 0 || freq_out == 0) {
 		/* Clock CODEC directly from MCLK */
-		reg = snd_soc_read(codec, WM8974_CLOCK);
-		snd_soc_write(codec, WM8974_CLOCK, reg & 0x0ff);
+		reg = snd_soc_component_read32(component, WM8974_CLOCK);
+		snd_soc_component_write(component, WM8974_CLOCK, reg & 0x0ff);
 
 		/* Turn off PLL */
-		reg = snd_soc_read(codec, WM8974_POWER1);
-		snd_soc_write(codec, WM8974_POWER1, reg & 0x1df);
+		reg = snd_soc_component_read32(component, WM8974_POWER1);
+		snd_soc_component_write(component, WM8974_POWER1, reg & 0x1df);
 		return 0;
 	}
 
 	pll_factors(&pll_div, freq_out, freq_in);
 
-	snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
-	snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
-	snd_soc_write(codec, WM8974_PLLK2, (pll_div.k >> 9) & 0x1ff);
-	snd_soc_write(codec, WM8974_PLLK3, pll_div.k & 0x1ff);
-	reg = snd_soc_read(codec, WM8974_POWER1);
-	snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
+	snd_soc_component_write(component, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
+	snd_soc_component_write(component, WM8974_PLLK1, pll_div.k >> 18);
+	snd_soc_component_write(component, WM8974_PLLK2, (pll_div.k >> 9) & 0x1ff);
+	snd_soc_component_write(component, WM8974_PLLK3, pll_div.k & 0x1ff);
+	reg = snd_soc_component_read32(component, WM8974_POWER1);
+	snd_soc_component_write(component, WM8974_POWER1, reg | 0x020);
 
 	/* Run CODEC from PLL instead of MCLK */
-	reg = snd_soc_read(codec, WM8974_CLOCK);
-	snd_soc_write(codec, WM8974_CLOCK, reg | 0x100);
+	reg = snd_soc_component_read32(component, WM8974_CLOCK);
+	snd_soc_component_write(component, WM8974_CLOCK, reg | 0x100);
 
 	return 0;
 }
@@ -361,21 +361,21 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
 	switch (div_id) {
 	case WM8974_OPCLKDIV:
-		reg = snd_soc_read(codec, WM8974_GPIO) & 0x1cf;
-		snd_soc_write(codec, WM8974_GPIO, reg | div);
+		reg = snd_soc_component_read32(component, WM8974_GPIO) & 0x1cf;
+		snd_soc_component_write(component, WM8974_GPIO, reg | div);
 		break;
 	case WM8974_MCLKDIV:
-		reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
-		snd_soc_write(codec, WM8974_CLOCK, reg | div);
+		reg = snd_soc_component_read32(component, WM8974_CLOCK) & 0x11f;
+		snd_soc_component_write(component, WM8974_CLOCK, reg | div);
 		break;
 	case WM8974_BCLKDIV:
-		reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
-		snd_soc_write(codec, WM8974_CLOCK, reg | div);
+		reg = snd_soc_component_read32(component, WM8974_CLOCK) & 0x1e3;
+		snd_soc_component_write(component, WM8974_CLOCK, reg | div);
 		break;
 	default:
 		return -EINVAL;
@@ -418,8 +418,8 @@ static unsigned int wm8974_get_mclkdiv(unsigned int f_in, unsigned int f_out,
 
 static int wm8974_update_clocks(struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8974_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8974_priv *priv = snd_soc_component_get_drvdata(component);
 	unsigned int fs256;
 	unsigned int fpll = 0;
 	unsigned int f;
@@ -446,8 +446,8 @@ static int wm8974_update_clocks(struct snd_soc_dai *dai)
 static int wm8974_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 				 unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8974_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8974_priv *priv = snd_soc_component_get_drvdata(component);
 
 	if (dir != SND_SOC_CLOCK_IN)
 		return -EINVAL;
@@ -460,9 +460,9 @@ static int wm8974_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
-	u16 clk = snd_soc_read(codec, WM8974_CLOCK) & 0x1fe;
+	u16 clk = snd_soc_component_read32(component, WM8974_CLOCK) & 0x1fe;
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -509,8 +509,8 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8974_IFACE, iface);
-	snd_soc_write(codec, WM8974_CLOCK, clk);
+	snd_soc_component_write(component, WM8974_IFACE, iface);
+	snd_soc_component_write(component, WM8974_CLOCK, clk);
 	return 0;
 }
 
@@ -518,10 +518,10 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8974_priv *priv = snd_soc_codec_get_drvdata(codec);
-	u16 iface = snd_soc_read(codec, WM8974_IFACE) & 0x19f;
-	u16 adn = snd_soc_read(codec, WM8974_ADD) & 0x1f1;
+	struct snd_soc_component *component = dai->component;
+	struct wm8974_priv *priv = snd_soc_component_get_drvdata(component);
+	u16 iface = snd_soc_component_read32(component, WM8974_IFACE) & 0x19f;
+	u16 adn = snd_soc_component_read32(component, WM8974_ADD) & 0x1f1;
 	int err;
 
 	priv->fs = params_rate(params);
@@ -566,55 +566,55 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8974_IFACE, iface);
-	snd_soc_write(codec, WM8974_ADD, adn);
+	snd_soc_component_write(component, WM8974_IFACE, iface);
+	snd_soc_component_write(component, WM8974_ADD, adn);
 	return 0;
 }
 
 static int wm8974_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8974_DAC) & 0xffbf;
 
 	if (mute)
-		snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
+		snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
 	else
-		snd_soc_write(codec, WM8974_DAC, mute_reg);
+		snd_soc_component_write(component, WM8974_DAC, mute_reg);
 	return 0;
 }
 
 /* liam need to make this lower power with dapm */
-static int wm8974_set_bias_level(struct snd_soc_codec *codec,
+static int wm8974_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	u16 power1 = snd_soc_read(codec, WM8974_POWER1) & ~0x3;
+	u16 power1 = snd_soc_component_read32(component, WM8974_POWER1) & ~0x3;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		power1 |= 0x1;  /* VMID 50k */
-		snd_soc_write(codec, WM8974_POWER1, power1);
+		snd_soc_component_write(component, WM8974_POWER1, power1);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
 		power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-			regcache_sync(dev_get_regmap(codec->dev, NULL));
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+			regcache_sync(dev_get_regmap(component->dev, NULL));
 
 			/* Initial cap charge at VMID 5k */
-			snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
+			snd_soc_component_write(component, WM8974_POWER1, power1 | 0x3);
 			mdelay(100);
 		}
 
 		power1 |= 0x2;  /* VMID 500k */
-		snd_soc_write(codec, WM8974_POWER1, power1);
+		snd_soc_component_write(component, WM8974_POWER1, power1);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, WM8974_POWER1, 0);
-		snd_soc_write(codec, WM8974_POWER2, 0);
-		snd_soc_write(codec, WM8974_POWER3, 0);
+		snd_soc_component_write(component, WM8974_POWER1, 0);
+		snd_soc_component_write(component, WM8974_POWER2, 0);
+		snd_soc_component_write(component, WM8974_POWER3, 0);
 		break;
 	}
 
@@ -663,32 +663,33 @@ static const struct regmap_config wm8974_regmap = {
 	.cache_type = REGCACHE_FLAT,
 };
 
-static int wm8974_probe(struct snd_soc_codec *codec)
+static int wm8974_probe(struct snd_soc_component *component)
 {
 	int ret = 0;
 
-	ret = wm8974_reset(codec);
+	ret = wm8974_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
+		dev_err(component->dev, "Failed to issue reset\n");
 		return ret;
 	}
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
-	.probe = 	wm8974_probe,
-	.set_bias_level = wm8974_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8974_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8974_snd_controls),
-		.dapm_widgets		= wm8974_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8974_dapm_widgets),
-		.dapm_routes		= wm8974_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8974_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8974 = {
+	.probe			= wm8974_probe,
+	.set_bias_level		= wm8974_set_bias_level,
+	.controls		= wm8974_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8974_snd_controls),
+	.dapm_widgets		= wm8974_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8974_dapm_widgets),
+	.dapm_routes		= wm8974_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8974_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8974_i2c_probe(struct i2c_client *i2c,
@@ -708,19 +709,12 @@ static int wm8974_i2c_probe(struct i2c_client *i2c,
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8974, &wm8974_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8974, &wm8974_dai, 1);
 
 	return ret;
 }
 
-static int wm8974_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm8974_i2c_id[] = {
 	{ "wm8974", 0 },
 	{ }
@@ -739,7 +733,6 @@ static struct i2c_driver wm8974_i2c_driver = {
 		.of_match_table = wm8974_of_match,
 	},
 	.probe =    wm8974_i2c_probe,
-	.remove =   wm8974_i2c_remove,
 	.id_table = wm8974_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index cf761e2..bae4fe8 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -408,7 +408,7 @@ struct wm8978_pll_div {
 
 #define FIXED_PLL_SIZE (1 << 24)
 
-static void pll_factors(struct snd_soc_codec *codec,
+static void pll_factors(struct snd_soc_component *component,
 		struct wm8978_pll_div *pll_div, unsigned int target, unsigned int source)
 {
 	u64 k_part;
@@ -424,7 +424,7 @@ static void pll_factors(struct snd_soc_codec *codec,
 	}
 
 	if (n_div < 6 || n_div > 12)
-		dev_warn(codec->dev,
+		dev_warn(component->dev,
 			 "WM8978 N value exceeds recommended range! N = %u\n",
 			 n_div);
 
@@ -471,9 +471,9 @@ static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
  * Calculate internal frequencies and dividers, according to Figure 40
  * "PLL and Clock Select Circuit" in WM8978 datasheet Rev. 2.6
  */
-static int wm8978_configure_pll(struct snd_soc_codec *codec)
+static int wm8978_configure_pll(struct snd_soc_component *component)
 {
-	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+	struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component);
 	struct wm8978_pll_div pll_div;
 	unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
 		f_256fs = wm8978->f_256fs;
@@ -505,9 +505,9 @@ static int wm8978_configure_pll(struct snd_soc_codec *codec)
 		else
 			opclk_div = 1;
 
-		dev_dbg(codec->dev, "%s: OPCLKDIV=%d\n", __func__, opclk_div);
+		dev_dbg(component->dev, "%s: OPCLKDIV=%d\n", __func__, opclk_div);
 
-		snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 0x30,
+		snd_soc_component_update_bits(component, WM8978_GPIO_CONTROL, 0x30,
 				    (opclk_div - 1) << 4);
 
 		wm8978->f_pllout = f_opclk * opclk_div;
@@ -533,28 +533,28 @@ static int wm8978_configure_pll(struct snd_soc_codec *codec)
 
 	f2 = wm8978->f_pllout * 4;
 
-	dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
+	dev_dbg(component->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
 		wm8978->f_mclk, wm8978->f_pllout);
 
-	pll_factors(codec, &pll_div, f2, wm8978->f_mclk);
+	pll_factors(component, &pll_div, f2, wm8978->f_mclk);
 
-	dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
+	dev_dbg(component->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
 		__func__, pll_div.n, pll_div.k, pll_div.div2);
 
 	/* Turn PLL off for configuration... */
-	snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
+	snd_soc_component_update_bits(component, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
 
-	snd_soc_write(codec, WM8978_PLL_N, (pll_div.div2 << 4) | pll_div.n);
-	snd_soc_write(codec, WM8978_PLL_K1, pll_div.k >> 18);
-	snd_soc_write(codec, WM8978_PLL_K2, (pll_div.k >> 9) & 0x1ff);
-	snd_soc_write(codec, WM8978_PLL_K3, pll_div.k & 0x1ff);
+	snd_soc_component_write(component, WM8978_PLL_N, (pll_div.div2 << 4) | pll_div.n);
+	snd_soc_component_write(component, WM8978_PLL_K1, pll_div.k >> 18);
+	snd_soc_component_write(component, WM8978_PLL_K2, (pll_div.k >> 9) & 0x1ff);
+	snd_soc_component_write(component, WM8978_PLL_K3, pll_div.k & 0x1ff);
 
 	/* ...and on again */
-	snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
+	snd_soc_component_update_bits(component, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
 
 	if (f_opclk)
 		/* Output PLL (OPCLK) to GPIO1 */
-		snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 4);
+		snd_soc_component_update_bits(component, WM8978_GPIO_CONTROL, 7, 4);
 
 	return 0;
 }
@@ -565,8 +565,8 @@ static int wm8978_configure_pll(struct snd_soc_codec *codec)
 static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 				 int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	switch (div_id) {
@@ -588,18 +588,18 @@ static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 			 * find an exact MCLK divider configuration - it will
 			 * be equal to or double the OPCLK divisor.
 			 */
-			ret = wm8978_configure_pll(codec);
+			ret = wm8978_configure_pll(component);
 		break;
 	case WM8978_BCLKDIV:
 		if (div & ~0x1c)
 			return -EINVAL;
-		snd_soc_update_bits(codec, WM8978_CLOCKING, 0x1c, div);
+		snd_soc_component_update_bits(component, WM8978_CLOCKING, 0x1c, div);
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "%s: ID %d, value %u\n", __func__, div_id, div);
+	dev_dbg(component->dev, "%s: ID %d, value %u\n", __func__, div_id, div);
 
 	return ret;
 }
@@ -610,18 +610,18 @@ static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 				 unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
-	dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
+	dev_dbg(component->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
 
 	if (freq) {
 		wm8978->f_mclk = freq;
 
 		/* Even if MCLK is used for system clock, might have to drive OPCLK */
 		if (wm8978->f_opclk)
-			ret = wm8978_configure_pll(codec);
+			ret = wm8978_configure_pll(component);
 
 		/* Our sysclk is fixed to 256 * fs, will configure in .hw_params()  */
 
@@ -631,13 +631,13 @@ static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 
 	if (wm8978->sysclk == WM8978_PLL && (!freq || clk_id == WM8978_MCLK)) {
 		/* Clock CODEC directly from MCLK */
-		snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
+		snd_soc_component_update_bits(component, WM8978_CLOCKING, 0x100, 0);
 
 		/* GPIO1 into default mode as input - before configuring PLL */
-		snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
+		snd_soc_component_update_bits(component, WM8978_GPIO_CONTROL, 7, 0);
 
 		/* Turn off PLL */
-		snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
+		snd_soc_component_update_bits(component, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
 		wm8978->sysclk = WM8978_MCLK;
 		wm8978->f_pllout = 0;
 		wm8978->f_opclk = 0;
@@ -651,15 +651,15 @@ static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
  */
 static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	/*
 	 * BCLK polarity mask = 0x100, LRC clock polarity mask = 0x80,
 	 * Data Format mask = 0x18: all will be calculated anew
 	 */
-	u16 iface = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x198;
-	u16 clk = snd_soc_read(codec, WM8978_CLOCKING);
+	u16 iface = snd_soc_component_read32(component, WM8978_AUDIO_INTERFACE) & ~0x198;
+	u16 clk = snd_soc_component_read32(component, WM8978_CLOCKING);
 
-	dev_dbg(codec->dev, "%s\n", __func__);
+	dev_dbg(component->dev, "%s\n", __func__);
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -707,8 +707,8 @@ static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface);
-	snd_soc_write(codec, WM8978_CLOCKING, clk);
+	snd_soc_component_write(component, WM8978_AUDIO_INTERFACE, iface);
+	snd_soc_component_write(component, WM8978_CLOCKING, clk);
 
 	return 0;
 }
@@ -720,13 +720,13 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component);
 	/* Word length mask = 0x60 */
-	u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
+	u16 iface_ctl = snd_soc_component_read32(component, WM8978_AUDIO_INTERFACE) & ~0x60;
 	/* Sampling rate mask = 0xe (for filters) */
-	u16 add_ctl = snd_soc_read(codec, WM8978_ADDITIONAL_CONTROL) & ~0xe;
-	u16 clking = snd_soc_read(codec, WM8978_CLOCKING);
+	u16 add_ctl = snd_soc_component_read32(component, WM8978_ADDITIONAL_CONTROL) & ~0xe;
+	u16 clking = snd_soc_component_read32(component, WM8978_CLOCKING);
 	enum wm8978_sysclk_src current_clk_id = clking & 0x100 ?
 		WM8978_PLL : WM8978_MCLK;
 	unsigned int f_sel, diff, diff_best = INT_MAX;
@@ -781,7 +781,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
 	} else {
 		if (!wm8978->f_opclk) {
 			/* We only enter here, if OPCLK is not used */
-			int ret = wm8978_configure_pll(codec);
+			int ret = wm8978_configure_pll(component);
 			if (ret < 0)
 				return ret;
 		}
@@ -812,28 +812,28 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (diff)
-		dev_warn(codec->dev, "Imprecise sampling rate: %uHz%s\n",
+		dev_warn(component->dev, "Imprecise sampling rate: %uHz%s\n",
 			f_sel * mclk_denominator[best] / mclk_numerator[best] / 256,
 			wm8978->sysclk == WM8978_MCLK ?
 			", consider using PLL" : "");
 
-	dev_dbg(codec->dev, "%s: width %d, rate %u, MCLK divisor #%d\n", __func__,
+	dev_dbg(component->dev, "%s: width %d, rate %u, MCLK divisor #%d\n", __func__,
 		params_width(params), params_rate(params), best);
 
 	/* MCLK divisor mask = 0xe0 */
-	snd_soc_update_bits(codec, WM8978_CLOCKING, 0xe0, best << 5);
+	snd_soc_component_update_bits(component, WM8978_CLOCKING, 0xe0, best << 5);
 
-	snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface_ctl);
-	snd_soc_write(codec, WM8978_ADDITIONAL_CONTROL, add_ctl);
+	snd_soc_component_write(component, WM8978_AUDIO_INTERFACE, iface_ctl);
+	snd_soc_component_write(component, WM8978_ADDITIONAL_CONTROL, add_ctl);
 
 	if (wm8978->sysclk != current_clk_id) {
 		if (wm8978->sysclk == WM8978_PLL)
 			/* Run CODEC from PLL instead of MCLK */
-			snd_soc_update_bits(codec, WM8978_CLOCKING,
+			snd_soc_component_update_bits(component, WM8978_CLOCKING,
 					    0x100, 0x100);
 		else
 			/* Clock CODEC directly from MCLK */
-			snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
+			snd_soc_component_update_bits(component, WM8978_CLOCKING, 0x100, 0);
 	}
 
 	return 0;
@@ -841,52 +841,52 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8978_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	dev_dbg(codec->dev, "%s: %d\n", __func__, mute);
+	dev_dbg(component->dev, "%s: %d\n", __func__, mute);
 
 	if (mute)
-		snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0x40);
+		snd_soc_component_update_bits(component, WM8978_DAC_CONTROL, 0x40, 0x40);
 	else
-		snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0);
+		snd_soc_component_update_bits(component, WM8978_DAC_CONTROL, 0x40, 0);
 
 	return 0;
 }
 
-static int wm8978_set_bias_level(struct snd_soc_codec *codec,
+static int wm8978_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	u16 power1 = snd_soc_read(codec, WM8978_POWER_MANAGEMENT_1) & ~3;
+	u16 power1 = snd_soc_component_read32(component, WM8978_POWER_MANAGEMENT_1) & ~3;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		power1 |= 1;  /* VMID 75k */
-		snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
+		snd_soc_component_write(component, WM8978_POWER_MANAGEMENT_1, power1);
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* bit 3: enable bias, bit 2: enable I/O tie off buffer */
 		power1 |= 0xc;
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Initial cap charge at VMID 5k */
-			snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
+			snd_soc_component_write(component, WM8978_POWER_MANAGEMENT_1,
 				      power1 | 0x3);
 			mdelay(100);
 		}
 
 		power1 |= 0x2;  /* VMID 500k */
-		snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
+		snd_soc_component_write(component, WM8978_POWER_MANAGEMENT_1, power1);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* Preserve PLL - OPCLK may be used by someone */
-		snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
-		snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0);
-		snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0);
+		snd_soc_component_update_bits(component, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
+		snd_soc_component_write(component, WM8978_POWER_MANAGEMENT_2, 0);
+		snd_soc_component_write(component, WM8978_POWER_MANAGEMENT_3, 0);
 		break;
 	}
 
-	dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
+	dev_dbg(component->dev, "%s: %d, %x\n", __func__, level, power1);
 
 	return 0;
 }
@@ -923,31 +923,31 @@ static struct snd_soc_dai_driver wm8978_dai = {
 	.symmetric_rates = 1,
 };
 
-static int wm8978_suspend(struct snd_soc_codec *codec)
+static int wm8978_suspend(struct snd_soc_component *component)
 {
-	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+	struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 	/* Also switch PLL off */
-	snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
+	snd_soc_component_write(component, WM8978_POWER_MANAGEMENT_1, 0);
 
 	regcache_mark_dirty(wm8978->regmap);
 
 	return 0;
 }
 
-static int wm8978_resume(struct snd_soc_codec *codec)
+static int wm8978_resume(struct snd_soc_component *component)
 {
-	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+	struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component);
 
 	/* Sync reg_cache with the hardware */
 	regcache_sync(wm8978->regmap);
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	if (wm8978->f_pllout)
 		/* Switch PLL on */
-		snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
+		snd_soc_component_update_bits(component, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
 
 	return 0;
 }
@@ -971,9 +971,9 @@ static const int update_reg[] = {
 	WM8978_ROUT2_SPK_CONTROL,
 };
 
-static int wm8978_probe(struct snd_soc_codec *codec)
+static int wm8978_probe(struct snd_soc_component *component)
 {
-	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+	struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	/*
@@ -988,25 +988,26 @@ static int wm8978_probe(struct snd_soc_codec *codec)
 	 * written.
 	 */
 	for (i = 0; i < ARRAY_SIZE(update_reg); i++)
-		snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100);
+		snd_soc_component_update_bits(component, update_reg[i], 0x100, 0x100);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
-	.probe =	wm8978_probe,
-	.suspend =	wm8978_suspend,
-	.resume =	wm8978_resume,
-	.set_bias_level = wm8978_set_bias_level,
-
-	.component_driver = {
-		.controls		= wm8978_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8978_snd_controls),
-		.dapm_widgets		= wm8978_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8978_dapm_widgets),
-		.dapm_routes		= wm8978_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8978_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8978 = {
+	.probe			= wm8978_probe,
+	.suspend		= wm8978_suspend,
+	.resume			= wm8978_resume,
+	.set_bias_level		= wm8978_set_bias_level,
+	.controls		= wm8978_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8978_snd_controls),
+	.dapm_widgets		= wm8978_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8978_dapm_widgets),
+	.dapm_routes		= wm8978_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8978_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8978_regmap_config = {
@@ -1048,8 +1049,8 @@ static int wm8978_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8978, &wm8978_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8978, &wm8978_dai, 1);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
 		return ret;
@@ -1058,13 +1059,6 @@ static int wm8978_i2c_probe(struct i2c_client *i2c,
 	return 0;
 }
 
-static int wm8978_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm8978_i2c_id[] = {
 	{ "wm8978", 0 },
 	{ }
@@ -1083,7 +1077,6 @@ static struct i2c_driver wm8978_i2c_driver = {
 		.of_match_table = wm8978_of_match,
 	},
 	.probe =    wm8978_i2c_probe,
-	.remove =   wm8978_i2c_remove,
 	.id_table = wm8978_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index bfdbe72..9f35801a 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -492,10 +492,10 @@ static const struct snd_soc_dapm_route wm8983_audio_map[] = {
 static int eqmode_get(struct snd_kcontrol *kcontrol,
 		      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF);
+	reg = snd_soc_component_read32(component, WM8983_EQ1_LOW_SHELF);
 	if (reg & WM8983_EQ3DMODE)
 		ucontrol->value.enumerated.item[0] = 1;
 	else
@@ -507,7 +507,7 @@ static int eqmode_get(struct snd_kcontrol *kcontrol,
 static int eqmode_put(struct snd_kcontrol *kcontrol,
 		      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int regpwr2, regpwr3;
 	unsigned int reg_eq;
 
@@ -515,7 +515,7 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
 	    && ucontrol->value.enumerated.item[0] != 1)
 		return -EINVAL;
 
-	reg_eq = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF);
+	reg_eq = snd_soc_component_read32(component, WM8983_EQ1_LOW_SHELF);
 	switch ((reg_eq & WM8983_EQ3DMODE) >> WM8983_EQ3DMODE_SHIFT) {
 	case 0:
 		if (!ucontrol->value.enumerated.item[0])
@@ -527,21 +527,21 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
 		break;
 	}
 
-	regpwr2 = snd_soc_read(codec, WM8983_POWER_MANAGEMENT_2);
-	regpwr3 = snd_soc_read(codec, WM8983_POWER_MANAGEMENT_3);
+	regpwr2 = snd_soc_component_read32(component, WM8983_POWER_MANAGEMENT_2);
+	regpwr3 = snd_soc_component_read32(component, WM8983_POWER_MANAGEMENT_3);
 	/* disable the DACs and ADCs */
-	snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_2,
+	snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_2,
 			    WM8983_ADCENR_MASK | WM8983_ADCENL_MASK, 0);
-	snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_3,
+	snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_3,
 			    WM8983_DACENR_MASK | WM8983_DACENL_MASK, 0);
 	/* set the desired eqmode */
-	snd_soc_update_bits(codec, WM8983_EQ1_LOW_SHELF,
+	snd_soc_component_update_bits(component, WM8983_EQ1_LOW_SHELF,
 			    WM8983_EQ3DMODE_MASK,
 			    ucontrol->value.enumerated.item[0]
 			    << WM8983_EQ3DMODE_SHIFT);
 	/* restore DAC/ADC configuration */
-	snd_soc_write(codec, WM8983_POWER_MANAGEMENT_2, regpwr2);
-	snd_soc_write(codec, WM8983_POWER_MANAGEMENT_3, regpwr3);
+	snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_2, regpwr2);
+	snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_3, regpwr3);
 	return 0;
 }
 
@@ -562,16 +562,16 @@ static bool wm8983_writeable(struct device *dev, unsigned int reg)
 
 static int wm8983_dac_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	return snd_soc_update_bits(codec, WM8983_DAC_CONTROL,
+	return snd_soc_component_update_bits(component, WM8983_DAC_CONTROL,
 				   WM8983_SOFTMUTE_MASK,
 				   !!mute << WM8983_SOFTMUTE_SHIFT);
 }
 
 static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 format, master, bcp, lrp;
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -593,7 +593,7 @@ static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8983_AUDIO_INTERFACE,
 			    WM8983_FMT_MASK, format << WM8983_FMT_SHIFT);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -608,7 +608,7 @@ static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
+	snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,
 			    WM8983_MS_MASK, master << WM8983_MS_SHIFT);
 
 	/* FIXME: We don't currently support DSP A/B modes */
@@ -639,9 +639,9 @@ static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8983_AUDIO_INTERFACE,
 			    WM8983_LRCP_MASK, lrp << WM8983_LRCP_SHIFT);
-	snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8983_AUDIO_INTERFACE,
 			    WM8983_BCP_MASK, bcp << WM8983_BCP_SHIFT);
 	return 0;
 }
@@ -651,8 +651,8 @@ static int wm8983_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_soc_dai *dai)
 {
 	int i;
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8983_priv *wm8983 = snd_soc_component_get_drvdata(component);
 	u16 blen, srate_idx;
 	u32 tmp;
 	int srate_best;
@@ -660,7 +660,7 @@ static int wm8983_hw_params(struct snd_pcm_substream *substream,
 
 	ret = snd_soc_params_to_bclk(params);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to convert params to bclk: %d\n", ret);
+		dev_err(component->dev, "Failed to convert params to bclk: %d\n", ret);
 		return ret;
 	}
 
@@ -685,7 +685,7 @@ static int wm8983_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8983_AUDIO_INTERFACE,
 			    WM8983_WL_MASK, blen << WM8983_WL_SHIFT);
 
 	/*
@@ -702,7 +702,7 @@ static int wm8983_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]);
-	snd_soc_update_bits(codec, WM8983_ADDITIONAL_CONTROL,
+	snd_soc_component_update_bits(component, WM8983_ADDITIONAL_CONTROL,
 			    WM8983_SR_MASK, srate_idx << WM8983_SR_SHIFT);
 
 	dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8983->bclk);
@@ -721,7 +721,7 @@ static int wm8983_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio);
-	snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
+	snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,
 			    WM8983_MCLKDIV_MASK, i << WM8983_MCLKDIV_SHIFT);
 
 	/* select the appropriate bclk divider */
@@ -737,7 +737,7 @@ static int wm8983_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	dev_dbg(dai->dev, "BCLK div = %d\n", i);
-	snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
+	snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,
 			    WM8983_BCLKDIV_MASK, i << WM8983_BCLKDIV_SHIFT);
 
 	return 0;
@@ -789,13 +789,13 @@ static int wm8983_set_pll(struct snd_soc_dai *dai, int pll_id,
 			  unsigned int freq_out)
 {
 	int ret;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct pll_div pll_div;
 
-	codec = dai->codec;
+	component = dai->component;
 	if (!freq_in || !freq_out) {
 		/* disable the PLL */
-		snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,
 				    WM8983_PLLEN_MASK, 0);
 		return 0;
 	} else {
@@ -804,19 +804,19 @@ static int wm8983_set_pll(struct snd_soc_dai *dai, int pll_id,
 			return ret;
 
 		/* disable the PLL before re-programming it */
-		snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,
 				    WM8983_PLLEN_MASK, 0);
 
 		/* set PLLN and PRESCALE */
-		snd_soc_write(codec, WM8983_PLL_N,
+		snd_soc_component_write(component, WM8983_PLL_N,
 			(pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT)
 			| pll_div.n);
 		/* set PLLK */
-		snd_soc_write(codec, WM8983_PLL_K_3, pll_div.k & 0x1ff);
-		snd_soc_write(codec, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
-		snd_soc_write(codec, WM8983_PLL_K_1, (pll_div.k >> 18));
+		snd_soc_component_write(component, WM8983_PLL_K_3, pll_div.k & 0x1ff);
+		snd_soc_component_write(component, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
+		snd_soc_component_write(component, WM8983_PLL_K_1, (pll_div.k >> 18));
 		/* enable the PLL */
-		snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,
 					WM8983_PLLEN_MASK, WM8983_PLLEN);
 	}
 
@@ -826,16 +826,16 @@ static int wm8983_set_pll(struct snd_soc_dai *dai, int pll_id,
 static int wm8983_set_sysclk(struct snd_soc_dai *dai,
 			     int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8983_priv *wm8983 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case WM8983_CLKSRC_MCLK:
-		snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
+		snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,
 				    WM8983_CLKSEL_MASK, 0);
 		break;
 	case WM8983_CLKSRC_PLL:
-		snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
+		snd_soc_component_update_bits(component, WM8983_CLOCK_GEN_CONTROL,
 				    WM8983_CLKSEL_MASK, WM8983_CLKSEL);
 		break;
 	default:
@@ -847,100 +847,100 @@ static int wm8983_set_sysclk(struct snd_soc_dai *dai,
 	return 0;
 }
 
-static int wm8983_set_bias_level(struct snd_soc_codec *codec,
+static int wm8983_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
+	struct wm8983_priv *wm8983 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID at 100k */
-		snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,
 				    WM8983_VMIDSEL_MASK,
 				    1 << WM8983_VMIDSEL_SHIFT);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regcache_sync(wm8983->regmap);
 			if (ret < 0) {
-				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				dev_err(component->dev, "Failed to sync cache: %d\n", ret);
 				return ret;
 			}
 			/* enable anti-pop features */
-			snd_soc_update_bits(codec, WM8983_OUT4_TO_ADC,
+			snd_soc_component_update_bits(component, WM8983_OUT4_TO_ADC,
 					    WM8983_POBCTRL_MASK | WM8983_DELEN_MASK,
 					    WM8983_POBCTRL | WM8983_DELEN);
 			/* enable thermal shutdown */
-			snd_soc_update_bits(codec, WM8983_OUTPUT_CTRL,
+			snd_soc_component_update_bits(component, WM8983_OUTPUT_CTRL,
 					    WM8983_TSDEN_MASK, WM8983_TSDEN);
 			/* enable BIASEN */
-			snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,
 					    WM8983_BIASEN_MASK, WM8983_BIASEN);
 			/* VMID at 100k */
-			snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,
 					    WM8983_VMIDSEL_MASK,
 					    1 << WM8983_VMIDSEL_SHIFT);
 			msleep(250);
 			/* disable anti-pop features */
-			snd_soc_update_bits(codec, WM8983_OUT4_TO_ADC,
+			snd_soc_component_update_bits(component, WM8983_OUT4_TO_ADC,
 					    WM8983_POBCTRL_MASK |
 					    WM8983_DELEN_MASK, 0);
 		}
 
 		/* VMID at 500k */
-		snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,
 				    WM8983_VMIDSEL_MASK,
 				    2 << WM8983_VMIDSEL_SHIFT);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* disable thermal shutdown */
-		snd_soc_update_bits(codec, WM8983_OUTPUT_CTRL,
+		snd_soc_component_update_bits(component, WM8983_OUTPUT_CTRL,
 				    WM8983_TSDEN_MASK, 0);
 		/* disable VMIDSEL and BIASEN */
-		snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_1,
 				    WM8983_VMIDSEL_MASK | WM8983_BIASEN_MASK,
 				    0);
 		/* wait for VMID to discharge */
 		msleep(100);
-		snd_soc_write(codec, WM8983_POWER_MANAGEMENT_1, 0);
-		snd_soc_write(codec, WM8983_POWER_MANAGEMENT_2, 0);
-		snd_soc_write(codec, WM8983_POWER_MANAGEMENT_3, 0);
+		snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_1, 0);
+		snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_2, 0);
+		snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_3, 0);
 		break;
 	}
 
 	return 0;
 }
 
-static int wm8983_probe(struct snd_soc_codec *codec)
+static int wm8983_probe(struct snd_soc_component *component)
 {
 	int ret;
 	int i;
 
-	ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0);
+	ret = snd_soc_component_write(component, WM8983_SOFTWARE_RESET, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+		dev_err(component->dev, "Failed to issue reset: %d\n", ret);
 		return ret;
 	}
 
 	/* set the vol/gain update bits */
 	for (i = 0; i < ARRAY_SIZE(vol_update_regs); ++i)
-		snd_soc_update_bits(codec, vol_update_regs[i],
+		snd_soc_component_update_bits(component, vol_update_regs[i],
 				    0x100, 0x100);
 
 	/* mute all outputs and set PGAs to minimum gain */
 	for (i = WM8983_LOUT1_HP_VOLUME_CTRL;
 	     i <= WM8983_OUT4_MONO_MIX_CTRL; ++i)
-		snd_soc_update_bits(codec, i, 0x40, 0x40);
+		snd_soc_component_update_bits(component, i, 0x40, 0x40);
 
 	/* enable soft mute */
-	snd_soc_update_bits(codec, WM8983_DAC_CONTROL,
+	snd_soc_component_update_bits(component, WM8983_DAC_CONTROL,
 			    WM8983_SOFTMUTE_MASK,
 			    WM8983_SOFTMUTE);
 
 	/* enable BIASCUT */
-	snd_soc_update_bits(codec, WM8983_BIAS_CTRL,
+	snd_soc_component_update_bits(component, WM8983_BIAS_CTRL,
 			    WM8983_BIASCUT, WM8983_BIASCUT);
 	return 0;
 }
@@ -976,18 +976,20 @@ static struct snd_soc_dai_driver wm8983_dai = {
 	.symmetric_rates = 1
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8983 = {
-	.probe = wm8983_probe,
-	.set_bias_level = wm8983_set_bias_level,
-	.suspend_bias_off = true,
-	.component_driver = {
-		.controls		= wm8983_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8983_snd_controls),
-		.dapm_widgets		= wm8983_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8983_dapm_widgets),
-		.dapm_routes		= wm8983_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(wm8983_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8983 = {
+	.probe			= wm8983_probe,
+	.set_bias_level		= wm8983_set_bias_level,
+	.controls		= wm8983_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8983_snd_controls),
+	.dapm_widgets		= wm8983_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8983_dapm_widgets),
+	.dapm_routes		= wm8983_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(wm8983_audio_map),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8983_regmap = {
@@ -1021,23 +1023,16 @@ static int wm8983_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8983);
 
-	ret = snd_soc_register_codec(&spi->dev,
-				     &soc_codec_dev_wm8983, &wm8983_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+				&soc_component_dev_wm8983, &wm8983_dai, 1);
 	return ret;
 }
 
-static int wm8983_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver wm8983_spi_driver = {
 	.driver = {
 		.name = "wm8983",
 	},
 	.probe = wm8983_spi_probe,
-	.remove = wm8983_spi_remove
 };
 #endif
 
@@ -1061,18 +1056,12 @@ static int wm8983_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8983);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-				     &soc_codec_dev_wm8983, &wm8983_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				&soc_component_dev_wm8983, &wm8983_dai, 1);
 
 	return ret;
 }
 
-static int wm8983_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8983_i2c_id[] = {
 	{ "wm8983", 0 },
 	{ }
@@ -1084,7 +1073,6 @@ static struct i2c_driver wm8983_i2c_driver = {
 		.name = "wm8983",
 	},
 	.probe = wm8983_i2c_probe,
-	.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 05344f9..18b342c 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -564,10 +564,10 @@ static const struct snd_soc_dapm_route wm8985_aux_dapm_routes[] = {
 	{ "Left Boost Mixer", "AUXL Volume", "AUXL" },
 };
 
-static int wm8985_add_widgets(struct snd_soc_codec *codec)
+static int wm8985_add_widgets(struct snd_soc_component *component)
 {
-	struct wm8985_priv *wm8985 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm8985_priv *wm8985 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	switch (wm8985->dev_type) {
 	case WM8758:
@@ -576,7 +576,7 @@ static int wm8985_add_widgets(struct snd_soc_codec *codec)
 		break;
 
 	case WM8985:
-		snd_soc_add_codec_controls(codec, wm8985_specific_snd_controls,
+		snd_soc_add_component_controls(component, wm8985_specific_snd_controls,
 			ARRAY_SIZE(wm8985_specific_snd_controls));
 
 		snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
@@ -592,10 +592,10 @@ static int wm8985_add_widgets(struct snd_soc_codec *codec)
 static int eqmode_get(struct snd_kcontrol *kcontrol,
 		      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF);
+	reg = snd_soc_component_read32(component, WM8985_EQ1_LOW_SHELF);
 	if (reg & WM8985_EQ3DMODE)
 		ucontrol->value.enumerated.item[0] = 1;
 	else
@@ -607,7 +607,7 @@ static int eqmode_get(struct snd_kcontrol *kcontrol,
 static int eqmode_put(struct snd_kcontrol *kcontrol,
 		      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int regpwr2, regpwr3;
 	unsigned int reg_eq;
 
@@ -615,7 +615,7 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
 			&& ucontrol->value.enumerated.item[0] != 1)
 		return -EINVAL;
 
-	reg_eq = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF);
+	reg_eq = snd_soc_component_read32(component, WM8985_EQ1_LOW_SHELF);
 	switch ((reg_eq & WM8985_EQ3DMODE) >> WM8985_EQ3DMODE_SHIFT) {
 	case 0:
 		if (!ucontrol->value.enumerated.item[0])
@@ -627,46 +627,46 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
 		break;
 	}
 
-	regpwr2 = snd_soc_read(codec, WM8985_POWER_MANAGEMENT_2);
-	regpwr3 = snd_soc_read(codec, WM8985_POWER_MANAGEMENT_3);
+	regpwr2 = snd_soc_component_read32(component, WM8985_POWER_MANAGEMENT_2);
+	regpwr3 = snd_soc_component_read32(component, WM8985_POWER_MANAGEMENT_3);
 	/* disable the DACs and ADCs */
-	snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_2,
+	snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_2,
 			    WM8985_ADCENR_MASK | WM8985_ADCENL_MASK, 0);
-	snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_3,
+	snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_3,
 			    WM8985_DACENR_MASK | WM8985_DACENL_MASK, 0);
-	snd_soc_update_bits(codec, WM8985_ADDITIONAL_CONTROL,
+	snd_soc_component_update_bits(component, WM8985_ADDITIONAL_CONTROL,
 			    WM8985_M128ENB_MASK, WM8985_M128ENB);
 	/* set the desired eqmode */
-	snd_soc_update_bits(codec, WM8985_EQ1_LOW_SHELF,
+	snd_soc_component_update_bits(component, WM8985_EQ1_LOW_SHELF,
 			    WM8985_EQ3DMODE_MASK,
 			    ucontrol->value.enumerated.item[0]
 			    << WM8985_EQ3DMODE_SHIFT);
 	/* restore DAC/ADC configuration */
-	snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, regpwr2);
-	snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, regpwr3);
+	snd_soc_component_write(component, WM8985_POWER_MANAGEMENT_2, regpwr2);
+	snd_soc_component_write(component, WM8985_POWER_MANAGEMENT_3, regpwr3);
 	return 0;
 }
 
-static int wm8985_reset(struct snd_soc_codec *codec)
+static int wm8985_reset(struct snd_soc_component *component)
 {
-	return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0);
+	return snd_soc_component_write(component, WM8985_SOFTWARE_RESET, 0x0);
 }
 
 static int wm8985_dac_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
-	return snd_soc_update_bits(codec, WM8985_DAC_CONTROL,
+	return snd_soc_component_update_bits(component, WM8985_DAC_CONTROL,
 				   WM8985_SOFTMUTE_MASK,
 				   !!mute << WM8985_SOFTMUTE_SHIFT);
 }
 
 static int wm8985_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	u16 format, master, bcp, lrp;
 
-	codec = dai->codec;
+	component = dai->component;
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
@@ -687,7 +687,7 @@ static int wm8985_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8985_AUDIO_INTERFACE,
 			    WM8985_FMT_MASK, format << WM8985_FMT_SHIFT);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -702,7 +702,7 @@ static int wm8985_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
+	snd_soc_component_update_bits(component, WM8985_CLOCK_GEN_CONTROL,
 			    WM8985_MS_MASK, master << WM8985_MS_SHIFT);
 
 	/* frame inversion is not valid for dsp modes */
@@ -739,9 +739,9 @@ static int wm8985_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8985_AUDIO_INTERFACE,
 			    WM8985_LRP_MASK, lrp << WM8985_LRP_SHIFT);
-	snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8985_AUDIO_INTERFACE,
 			    WM8985_BCP_MASK, bcp << WM8985_BCP_SHIFT);
 	return 0;
 }
@@ -751,14 +751,14 @@ static int wm8985_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_soc_dai *dai)
 {
 	int i;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm8985_priv *wm8985;
 	u16 blen, srate_idx;
 	unsigned int tmp;
 	int srate_best;
 
-	codec = dai->codec;
-	wm8985 = snd_soc_codec_get_drvdata(codec);
+	component = dai->component;
+	wm8985 = snd_soc_component_get_drvdata(component);
 
 	wm8985->bclk = snd_soc_params_to_bclk(params);
 	if ((int)wm8985->bclk < 0)
@@ -783,7 +783,7 @@ static int wm8985_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
+	snd_soc_component_update_bits(component, WM8985_AUDIO_INTERFACE,
 			    WM8985_WL_MASK, blen << WM8985_WL_SHIFT);
 
 	/*
@@ -800,7 +800,7 @@ static int wm8985_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]);
-	snd_soc_update_bits(codec, WM8985_ADDITIONAL_CONTROL,
+	snd_soc_component_update_bits(component, WM8985_ADDITIONAL_CONTROL,
 			    WM8985_SR_MASK, srate_idx << WM8985_SR_SHIFT);
 
 	dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8985->bclk);
@@ -819,7 +819,7 @@ static int wm8985_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio);
-	snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
+	snd_soc_component_update_bits(component, WM8985_CLOCK_GEN_CONTROL,
 			    WM8985_MCLKDIV_MASK, i << WM8985_MCLKDIV_SHIFT);
 
 	/* select the appropriate bclk divider */
@@ -835,7 +835,7 @@ static int wm8985_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	dev_dbg(dai->dev, "BCLK div = %d\n", i);
-	snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
+	snd_soc_component_update_bits(component, WM8985_CLOCK_GEN_CONTROL,
 			    WM8985_BCLKDIV_MASK, i << WM8985_BCLKDIV_SHIFT);
 	return 0;
 }
@@ -887,13 +887,13 @@ static int wm8985_set_pll(struct snd_soc_dai *dai, int pll_id,
 			  unsigned int freq_out)
 {
 	int ret;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct pll_div pll_div;
 
-	codec = dai->codec;
+	component = dai->component;
 	if (!freq_in || !freq_out) {
 		/* disable the PLL */
-		snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_1,
 				    WM8985_PLLEN_MASK, 0);
 	} else {
 		ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
@@ -901,18 +901,18 @@ static int wm8985_set_pll(struct snd_soc_dai *dai, int pll_id,
 			return ret;
 
 		/* set PLLN and PRESCALE */
-		snd_soc_write(codec, WM8985_PLL_N,
+		snd_soc_component_write(component, WM8985_PLL_N,
 			      (pll_div.div2 << WM8985_PLL_PRESCALE_SHIFT)
 			      | pll_div.n);
 		/* set PLLK */
-		snd_soc_write(codec, WM8985_PLL_K_3, pll_div.k & 0x1ff);
-		snd_soc_write(codec, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
-		snd_soc_write(codec, WM8985_PLL_K_1, (pll_div.k >> 18));
+		snd_soc_component_write(component, WM8985_PLL_K_3, pll_div.k & 0x1ff);
+		snd_soc_component_write(component, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
+		snd_soc_component_write(component, WM8985_PLL_K_1, (pll_div.k >> 18));
 		/* set the source of the clock to be the PLL */
-		snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
+		snd_soc_component_update_bits(component, WM8985_CLOCK_GEN_CONTROL,
 				    WM8985_CLKSEL_MASK, WM8985_CLKSEL);
 		/* enable the PLL */
-		snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_1,
 				    WM8985_PLLEN_MASK, WM8985_PLLEN);
 	}
 	return 0;
@@ -921,21 +921,21 @@ static int wm8985_set_pll(struct snd_soc_dai *dai, int pll_id,
 static int wm8985_set_sysclk(struct snd_soc_dai *dai,
 			     int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm8985_priv *wm8985;
 
-	codec = dai->codec;
-	wm8985 = snd_soc_codec_get_drvdata(codec);
+	component = dai->component;
+	wm8985 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case WM8985_CLKSRC_MCLK:
-		snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
+		snd_soc_component_update_bits(component, WM8985_CLOCK_GEN_CONTROL,
 				    WM8985_CLKSEL_MASK, 0);
-		snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_1,
 				    WM8985_PLLEN_MASK, 0);
 		break;
 	case WM8985_CLKSRC_PLL:
-		snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
+		snd_soc_component_update_bits(component, WM8985_CLOCK_GEN_CONTROL,
 				    WM8985_CLKSEL_MASK, WM8985_CLKSEL);
 		break;
 	default:
@@ -947,27 +947,27 @@ static int wm8985_set_sysclk(struct snd_soc_dai *dai,
 	return 0;
 }
 
-static int wm8985_set_bias_level(struct snd_soc_codec *codec,
+static int wm8985_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	int ret;
 	struct wm8985_priv *wm8985;
 
-	wm8985 = snd_soc_codec_get_drvdata(codec);
+	wm8985 = snd_soc_component_get_drvdata(component);
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID at 75k */
-		snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_1,
 				    WM8985_VMIDSEL_MASK,
 				    1 << WM8985_VMIDSEL_SHIFT);
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
 						    wm8985->supplies);
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n",
 					ret);
 				return ret;
@@ -976,45 +976,45 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
 			regcache_sync(wm8985->regmap);
 
 			/* enable anti-pop features */
-			snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC,
+			snd_soc_component_update_bits(component, WM8985_OUT4_TO_ADC,
 					    WM8985_POBCTRL_MASK,
 					    WM8985_POBCTRL);
 			/* enable thermal shutdown */
-			snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
+			snd_soc_component_update_bits(component, WM8985_OUTPUT_CTRL0,
 					    WM8985_TSDEN_MASK, WM8985_TSDEN);
-			snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
+			snd_soc_component_update_bits(component, WM8985_OUTPUT_CTRL0,
 					    WM8985_TSOPCTRL_MASK,
 					    WM8985_TSOPCTRL);
 			/* enable BIASEN */
-			snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_1,
 					    WM8985_BIASEN_MASK, WM8985_BIASEN);
 			/* VMID at 75k */
-			snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_1,
 					    WM8985_VMIDSEL_MASK,
 					    1 << WM8985_VMIDSEL_SHIFT);
 			msleep(500);
 			/* disable anti-pop features */
-			snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC,
+			snd_soc_component_update_bits(component, WM8985_OUT4_TO_ADC,
 					    WM8985_POBCTRL_MASK, 0);
 		}
 		/* VMID at 300k */
-		snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_1,
 				    WM8985_VMIDSEL_MASK,
 				    2 << WM8985_VMIDSEL_SHIFT);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* disable thermal shutdown */
-		snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
+		snd_soc_component_update_bits(component, WM8985_OUTPUT_CTRL0,
 				    WM8985_TSOPCTRL_MASK, 0);
-		snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
+		snd_soc_component_update_bits(component, WM8985_OUTPUT_CTRL0,
 				    WM8985_TSDEN_MASK, 0);
 		/* disable VMIDSEL and BIASEN */
-		snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8985_POWER_MANAGEMENT_1,
 				    WM8985_VMIDSEL_MASK | WM8985_BIASEN_MASK,
 				    0);
-		snd_soc_write(codec, WM8985_POWER_MANAGEMENT_1, 0);
-		snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0);
-		snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0);
+		snd_soc_component_write(component, WM8985_POWER_MANAGEMENT_1, 0);
+		snd_soc_component_write(component, WM8985_POWER_MANAGEMENT_2, 0);
+		snd_soc_component_write(component, WM8985_POWER_MANAGEMENT_3, 0);
 
 		regcache_mark_dirty(wm8985->regmap);
 
@@ -1026,46 +1026,46 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int wm8985_probe(struct snd_soc_codec *codec)
+static int wm8985_probe(struct snd_soc_component *component)
 {
 	size_t i;
 	struct wm8985_priv *wm8985;
 	int ret;
 
-	wm8985 = snd_soc_codec_get_drvdata(codec);
+	wm8985 = snd_soc_component_get_drvdata(component);
 
 	for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++)
 		wm8985->supplies[i].supply = wm8985_supply_names[i];
 
-	ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8985->supplies),
+	ret = devm_regulator_bulk_get(component->dev, ARRAY_SIZE(wm8985->supplies),
 				 wm8985->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to request supplies: %d\n", ret);
 		return ret;
 	}
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
 				    wm8985->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		return ret;
 	}
 
-	ret = wm8985_reset(codec);
+	ret = wm8985_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+		dev_err(component->dev, "Failed to issue reset: %d\n", ret);
 		goto err_reg_enable;
 	}
 
 	/* latch volume update bits */
 	for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i)
-		snd_soc_update_bits(codec, volume_update_regs[i],
+		snd_soc_component_update_bits(component, volume_update_regs[i],
 				    0x100, 0x100);
 	/* enable BIASCUT */
-	snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT,
+	snd_soc_component_update_bits(component, WM8985_BIAS_CTRL, WM8985_BIASCUT,
 			    WM8985_BIASCUT);
 
-	wm8985_add_widgets(codec);
+	wm8985_add_widgets(component);
 
 	return 0;
 
@@ -1105,19 +1105,20 @@ static struct snd_soc_dai_driver wm8985_dai = {
 	.symmetric_rates = 1
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
-	.probe = wm8985_probe,
-	.set_bias_level = wm8985_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8985_common_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8985_common_snd_controls),
-		.dapm_widgets		= wm8985_common_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8985_common_dapm_widgets),
-		.dapm_routes		= wm8985_common_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8985_common_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8985 = {
+	.probe			= wm8985_probe,
+	.set_bias_level		= wm8985_set_bias_level,
+	.controls		= wm8985_common_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8985_common_snd_controls),
+	.dapm_widgets		= wm8985_common_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8985_common_dapm_widgets),
+	.dapm_routes		= wm8985_common_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8985_common_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8985_regmap = {
@@ -1154,23 +1155,16 @@ static int wm8985_spi_probe(struct spi_device *spi)
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&spi->dev,
-				     &soc_codec_dev_wm8985, &wm8985_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+				     &soc_component_dev_wm8985, &wm8985_dai, 1);
 	return ret;
 }
 
-static int wm8985_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver wm8985_spi_driver = {
 	.driver = {
 		.name = "wm8985",
 	},
 	.probe = wm8985_spi_probe,
-	.remove = wm8985_spi_remove
 };
 #endif
 
@@ -1197,17 +1191,11 @@ static int wm8985_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev,
-				     &soc_codec_dev_wm8985, &wm8985_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_wm8985, &wm8985_dai, 1);
 	return ret;
 }
 
-static int wm8985_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8985_i2c_id[] = {
 	{ "wm8985", WM8985 },
 	{ "wm8758", WM8758 },
@@ -1220,7 +1208,6 @@ static struct i2c_driver wm8985_i2c_driver = {
 		.name = "wm8985",
 	},
 	.probe = wm8985_i2c_probe,
-	.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 b0d0219..6220011 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -119,7 +119,7 @@ struct wm8988_priv {
 	const struct snd_pcm_hw_constraint_list *sysclk_constraints;
 };
 
-#define wm8988_reset(c)	snd_soc_write(c, WM8988_RESET, 0)
+#define wm8988_reset(c)	snd_soc_component_write(c, WM8988_RESET, 0)
 
 /*
  * WM8988 Controls
@@ -244,16 +244,16 @@ SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V,
 static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	u16 adctl2 = snd_soc_read(codec, WM8988_ADCTL2);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	u16 adctl2 = snd_soc_component_read32(component, WM8988_ADCTL2);
 
 	/* Use the DAC to gate LRC if active, otherwise use ADC */
-	if (snd_soc_read(codec, WM8988_PWR2) & 0x180)
+	if (snd_soc_component_read32(component, WM8988_PWR2) & 0x180)
 		adctl2 &= ~0x4;
 	else
 		adctl2 |= 0x4;
 
-	return snd_soc_write(codec, WM8988_ADCTL2, adctl2);
+	return snd_soc_component_write(component, WM8988_ADCTL2, adctl2);
 }
 
 static const char *wm8988_line_texts[] = {
@@ -555,8 +555,8 @@ static const struct snd_pcm_hw_constraint_list constraints_12 = {
 static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
 
 	switch (freq) {
 	case 11289600:
@@ -587,7 +587,7 @@ static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 iface = 0;
 
 	/* set master/slave audio interface */
@@ -638,21 +638,21 @@ static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8988_IFACE, iface);
+	snd_soc_component_write(component, WM8988_IFACE, iface);
 	return 0;
 }
 
 static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
 			      struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
 
 	/* The set of sample rates that can be supported depends on the
 	 * MCLK supplied to the CODEC - enforce this.
 	 */
 	if (!wm8988->sysclk) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"No MCLK configured, call set_sysclk() on init\n");
 		return -EINVAL;
 	}
@@ -668,10 +668,10 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
-	u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
-	u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
+	struct snd_soc_component *component = dai->component;
+	struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
+	u16 iface = snd_soc_component_read32(component, WM8988_IFACE) & 0x1f3;
+	u16 srate = snd_soc_component_read32(component, WM8988_SRATE) & 0x180;
 	int coeff;
 
 	coeff = get_coeff(wm8988->sysclk, params_rate(params));
@@ -680,7 +680,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
 		srate |= 0x40;
 	}
 	if (coeff < 0) {
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Unable to configure sample rate %dHz with %dHz MCLK\n",
 			params_rate(params), wm8988->sysclk);
 		return coeff;
@@ -702,9 +702,9 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* set iface & srate */
-	snd_soc_write(codec, WM8988_IFACE, iface);
+	snd_soc_component_write(component, WM8988_IFACE, iface);
 	if (coeff >= 0)
-		snd_soc_write(codec, WM8988_SRATE, srate |
+		snd_soc_component_write(component, WM8988_SRATE, srate |
 			(coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
 
 	return 0;
@@ -712,21 +712,21 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8988_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = snd_soc_read(codec, WM8988_ADCDAC) & 0xfff7;
+	struct snd_soc_component *component = dai->component;
+	u16 mute_reg = snd_soc_component_read32(component, WM8988_ADCDAC) & 0xfff7;
 
 	if (mute)
-		snd_soc_write(codec, WM8988_ADCDAC, mute_reg | 0x8);
+		snd_soc_component_write(component, WM8988_ADCDAC, mute_reg | 0x8);
 	else
-		snd_soc_write(codec, WM8988_ADCDAC, mute_reg);
+		snd_soc_component_write(component, WM8988_ADCDAC, mute_reg);
 	return 0;
 }
 
-static int wm8988_set_bias_level(struct snd_soc_codec *codec,
+static int wm8988_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
-	u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
+	struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
+	u16 pwr_reg = snd_soc_component_read32(component, WM8988_PWR1) & ~0x1c1;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -734,26 +734,26 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VREF, VMID=2x50k, digital enabled */
-		snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x00c0);
+		snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x00c0);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_sync(wm8988->regmap);
 
 			/* VREF, VMID=2x5k */
-			snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
+			snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x1c1);
 
 			/* Charge caps */
 			msleep(100);
 		}
 
 		/* VREF, VMID=2*500k, digital stopped */
-		snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x0141);
+		snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x0141);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_write(codec, WM8988_PWR1, 0x0000);
+		snd_soc_component_write(component, WM8988_PWR1, 0x0000);
 		break;
 	}
 	return 0;
@@ -792,39 +792,40 @@ static struct snd_soc_dai_driver wm8988_dai = {
 	.symmetric_rates = 1,
 };
 
-static int wm8988_probe(struct snd_soc_codec *codec)
+static int wm8988_probe(struct snd_soc_component *component)
 {
 	int ret = 0;
 
-	ret = wm8988_reset(codec);
+	ret = wm8988_reset(component);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
+		dev_err(component->dev, "Failed to issue reset\n");
 		return ret;
 	}
 
 	/* set the update bits (we always update left then right) */
-	snd_soc_update_bits(codec, WM8988_RADC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8988_RDAC, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8988_ROUT1V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8988_ROUT2V, 0x0100, 0x0100);
-	snd_soc_update_bits(codec, WM8988_RINVOL, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8988_RADC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8988_RDAC, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8988_ROUT1V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8988_ROUT2V, 0x0100, 0x0100);
+	snd_soc_component_update_bits(component, WM8988_RINVOL, 0x0100, 0x0100);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
-	.probe =	wm8988_probe,
-	.set_bias_level = wm8988_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8988_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8988_snd_controls),
-		.dapm_widgets		= wm8988_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8988_dapm_widgets),
-		.dapm_routes		= wm8988_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8988_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8988 = {
+	.probe			= wm8988_probe,
+	.set_bias_level		= wm8988_set_bias_level,
+	.controls		= wm8988_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8988_snd_controls),
+	.dapm_widgets		= wm8988_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8988_dapm_widgets),
+	.dapm_routes		= wm8988_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8988_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8988_regmap = {
@@ -859,23 +860,16 @@ static int wm8988_spi_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, wm8988);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8988, &wm8988_dai, 1);
+	ret = devm_snd_soc_register_component(&spi->dev,
+			&soc_component_dev_wm8988, &wm8988_dai, 1);
 	return ret;
 }
 
-static int wm8988_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver wm8988_spi_driver = {
 	.driver = {
 		.name	= "wm8988",
 	},
 	.probe		= wm8988_spi_probe,
-	.remove		= wm8988_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -900,17 +894,11 @@ static int wm8988_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8988, &wm8988_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8988, &wm8988_dai, 1);
 	return ret;
 }
 
-static int wm8988_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8988_i2c_id[] = {
 	{ "wm8988", 0 },
 	{ }
@@ -922,7 +910,6 @@ static struct i2c_driver wm8988_i2c_driver = {
 		.name = "wm8988",
 	},
 	.probe =    wm8988_i2c_probe,
-	.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 a894500..411b9ee 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -111,7 +111,7 @@ static const struct reg_default wm8990_reg_defaults[] = {
 	{ 62, 0x0026 },     /* R62 - PLL3 */
 };
 
-#define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0)
+#define wm8990_reset(c) snd_soc_component_write(c, WM8990_RESET, 0)
 
 static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0);
 
@@ -132,7 +132,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0);
 static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	int reg = mc->reg;
@@ -144,8 +144,8 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
 		return ret;
 
 	/* now hit the volume update bits (always bit 8) */
-	val = snd_soc_read(codec, reg);
-	return snd_soc_write(codec, reg, val | 0x0100);
+	val = snd_soc_component_read32(component, reg);
+	return snd_soc_component_write(component, reg, val | 0x0100);
 }
 
 #define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
@@ -374,14 +374,14 @@ SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
 static int outmixer_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	u32 reg_shift = kcontrol->private_value & 0xfff;
 	int ret = 0;
 	u16 reg;
 
 	switch (reg_shift) {
 	case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) :
-		reg = snd_soc_read(codec, WM8990_OUTPUT_MIXER1);
+		reg = snd_soc_component_read32(component, WM8990_OUTPUT_MIXER1);
 		if (reg & WM8990_LDLO) {
 			printk(KERN_WARNING
 			"Cannot set as Output Mixer 1 LDLO Set\n");
@@ -389,7 +389,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
 		}
 		break;
 	case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8):
-		reg = snd_soc_read(codec, WM8990_OUTPUT_MIXER2);
+		reg = snd_soc_component_read32(component, WM8990_OUTPUT_MIXER2);
 		if (reg & WM8990_RDRO) {
 			printk(KERN_WARNING
 			"Cannot set as Output Mixer 2 RDRO Set\n");
@@ -397,7 +397,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
 		}
 		break;
 	case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8):
-		reg = snd_soc_read(codec, WM8990_SPEAKER_MIXER);
+		reg = snd_soc_component_read32(component, WM8990_SPEAKER_MIXER);
 		if (reg & WM8990_LDSPK) {
 			printk(KERN_WARNING
 			"Cannot set as Speaker Mixer LDSPK Set\n");
@@ -405,7 +405,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
 		}
 		break;
 	case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8):
-		reg = snd_soc_read(codec, WM8990_SPEAKER_MIXER);
+		reg = snd_soc_component_read32(component, WM8990_SPEAKER_MIXER);
 		if (reg & WM8990_RDSPK) {
 			printk(KERN_WARNING
 			"Cannot set as Speaker Mixer RDSPK Set\n");
@@ -934,28 +934,28 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
 static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	struct _pll_div pll_div;
 
 	if (freq_in && freq_out) {
 		pll_factors(&pll_div, freq_out * 4, freq_in);
 
 		/* Turn on PLL */
-		snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
+		snd_soc_component_update_bits(component, WM8990_POWER_MANAGEMENT_2,
 				    WM8990_PLL_ENA, WM8990_PLL_ENA);
 
 		/* sysclk comes from PLL */
-		snd_soc_update_bits(codec, WM8990_CLOCKING_2,
+		snd_soc_component_update_bits(component, WM8990_CLOCKING_2,
 				    WM8990_SYSCLK_SRC, WM8990_SYSCLK_SRC);
 
 		/* set up N , fractional mode and pre-divisor if necessary */
-		snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
+		snd_soc_component_write(component, WM8990_PLL1, pll_div.n | WM8990_SDM |
 			(pll_div.div2?WM8990_PRESCALE:0));
-		snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
-		snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
+		snd_soc_component_write(component, WM8990_PLL2, (u8)(pll_div.k>>8));
+		snd_soc_component_write(component, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
 	} else {
 		/* Turn off PLL */
-		snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
+		snd_soc_component_update_bits(component, WM8990_POWER_MANAGEMENT_2,
 				    WM8990_PLL_ENA, 0);
 	}
 	return 0;
@@ -967,8 +967,8 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm8990_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8990_priv *wm8990 = snd_soc_component_get_drvdata(component);
 
 	wm8990->sysclk = freq;
 	return 0;
@@ -980,11 +980,11 @@ static int wm8990_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 audio1, audio3;
 
-	audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
-	audio3 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_3);
+	audio1 = snd_soc_component_read32(component, WM8990_AUDIO_INTERFACE_1);
+	audio3 = snd_soc_component_read32(component, WM8990_AUDIO_INTERFACE_3);
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1025,31 +1025,31 @@ static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
-	snd_soc_write(codec, WM8990_AUDIO_INTERFACE_3, audio3);
+	snd_soc_component_write(component, WM8990_AUDIO_INTERFACE_1, audio1);
+	snd_soc_component_write(component, WM8990_AUDIO_INTERFACE_3, audio3);
 	return 0;
 }
 
 static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	switch (div_id) {
 	case WM8990_MCLK_DIV:
-		snd_soc_update_bits(codec, WM8990_CLOCKING_2,
+		snd_soc_component_update_bits(component, WM8990_CLOCKING_2,
 				    WM8990_MCLK_DIV_MASK, div);
 		break;
 	case WM8990_DACCLK_DIV:
-		snd_soc_update_bits(codec, WM8990_CLOCKING_2,
+		snd_soc_component_update_bits(component, WM8990_CLOCKING_2,
 				    WM8990_DAC_CLKDIV_MASK, div);
 		break;
 	case WM8990_ADCCLK_DIV:
-		snd_soc_update_bits(codec, WM8990_CLOCKING_2,
+		snd_soc_component_update_bits(component, WM8990_CLOCKING_2,
 				    WM8990_ADC_CLKDIV_MASK, div);
 		break;
 	case WM8990_BCLK_DIV:
-		snd_soc_update_bits(codec, WM8990_CLOCKING_1,
+		snd_soc_component_update_bits(component, WM8990_CLOCKING_1,
 				    WM8990_BCLK_DIV_MASK, div);
 		break;
 	default:
@@ -1066,8 +1066,8 @@ static int wm8990_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;
-	u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
+	struct snd_soc_component *component = dai->component;
+	u16 audio1 = snd_soc_component_read32(component, WM8990_AUDIO_INTERFACE_1);
 
 	audio1 &= ~WM8990_AIF_WL_MASK;
 	/* bit size */
@@ -1085,29 +1085,29 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
+	snd_soc_component_write(component, WM8990_AUDIO_INTERFACE_1, audio1);
 	return 0;
 }
 
 static int wm8990_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 val;
 
-	val  = snd_soc_read(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE;
+	val  = snd_soc_component_read32(component, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE;
 
 	if (mute)
-		snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
+		snd_soc_component_write(component, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
 	else
-		snd_soc_write(codec, WM8990_DAC_CTRL, val);
+		snd_soc_component_write(component, WM8990_DAC_CTRL, val);
 
 	return 0;
 }
 
-static int wm8990_set_bias_level(struct snd_soc_codec *codec,
+static int wm8990_set_bias_level(struct snd_soc_component *component,
 	enum snd_soc_bias_level level)
 {
-	struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec);
+	struct wm8990_priv *wm8990 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1116,26 +1116,26 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID=2*50k */
-		snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8990_POWER_MANAGEMENT_1,
 				    WM8990_VMID_MODE_MASK, 0x2);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regcache_sync(wm8990->regmap);
 			if (ret < 0) {
-				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				dev_err(component->dev, "Failed to sync cache: %d\n", ret);
 				return ret;
 			}
 
 			/* Enable all output discharge bits */
-			snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
+			snd_soc_component_write(component, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
 				WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
 				WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
 				WM8990_DIS_ROUT);
 
 			/* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
-			snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+			snd_soc_component_write(component, WM8990_ANTIPOP2, WM8990_SOFTST |
 				     WM8990_BUFDCOPEN | WM8990_POBCTRL |
 				     WM8990_VMIDTOG);
 
@@ -1143,82 +1143,82 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
 			msleep(300);
 
 			/* Disable VMIDTOG */
-			snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+			snd_soc_component_write(component, WM8990_ANTIPOP2, WM8990_SOFTST |
 				     WM8990_BUFDCOPEN | WM8990_POBCTRL);
 
 			/* disable all output discharge bits */
-			snd_soc_write(codec, WM8990_ANTIPOP1, 0);
+			snd_soc_component_write(component, WM8990_ANTIPOP1, 0);
 
 			/* Enable outputs */
-			snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00);
+			snd_soc_component_write(component, WM8990_POWER_MANAGEMENT_1, 0x1b00);
 
 			msleep(50);
 
 			/* Enable VMID at 2x50k */
-			snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02);
+			snd_soc_component_write(component, WM8990_POWER_MANAGEMENT_1, 0x1f02);
 
 			msleep(100);
 
 			/* Enable VREF */
-			snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
+			snd_soc_component_write(component, WM8990_POWER_MANAGEMENT_1, 0x1f03);
 
 			msleep(600);
 
 			/* Enable BUFIOEN */
-			snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+			snd_soc_component_write(component, WM8990_ANTIPOP2, WM8990_SOFTST |
 				     WM8990_BUFDCOPEN | WM8990_POBCTRL |
 				     WM8990_BUFIOEN);
 
 			/* Disable outputs */
-			snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3);
+			snd_soc_component_write(component, WM8990_POWER_MANAGEMENT_1, 0x3);
 
 			/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
-			snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
+			snd_soc_component_write(component, WM8990_ANTIPOP2, WM8990_BUFIOEN);
 
 			/* Enable workaround for ADC clocking issue. */
-			snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
-			snd_soc_write(codec, WM8990_EXT_CTL1, 0xa003);
-			snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0);
+			snd_soc_component_write(component, WM8990_EXT_ACCESS_ENA, 0x2);
+			snd_soc_component_write(component, WM8990_EXT_CTL1, 0xa003);
+			snd_soc_component_write(component, WM8990_EXT_ACCESS_ENA, 0);
 		}
 
 		/* VMID=2*250k */
-		snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8990_POWER_MANAGEMENT_1,
 				    WM8990_VMID_MODE_MASK, 0x4);
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* Enable POBCTRL and SOFT_ST */
-		snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+		snd_soc_component_write(component, WM8990_ANTIPOP2, WM8990_SOFTST |
 			WM8990_POBCTRL | WM8990_BUFIOEN);
 
 		/* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
-		snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
+		snd_soc_component_write(component, WM8990_ANTIPOP2, WM8990_SOFTST |
 			WM8990_BUFDCOPEN | WM8990_POBCTRL |
 			WM8990_BUFIOEN);
 
 		/* mute DAC */
-		snd_soc_update_bits(codec, WM8990_DAC_CTRL,
+		snd_soc_component_update_bits(component, WM8990_DAC_CTRL,
 				    WM8990_DAC_MUTE, WM8990_DAC_MUTE);
 
 		/* Enable any disabled outputs */
-		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
+		snd_soc_component_write(component, WM8990_POWER_MANAGEMENT_1, 0x1f03);
 
 		/* Disable VMID */
-		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01);
+		snd_soc_component_write(component, WM8990_POWER_MANAGEMENT_1, 0x1f01);
 
 		msleep(300);
 
 		/* Enable all output discharge bits */
-		snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
+		snd_soc_component_write(component, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
 			WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
 			WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
 			WM8990_DIS_ROUT);
 
 		/* Disable VREF */
-		snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0);
+		snd_soc_component_write(component, WM8990_POWER_MANAGEMENT_1, 0x0);
 
 		/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
-		snd_soc_write(codec, WM8990_ANTIPOP2, 0x0);
+		snd_soc_component_write(component, WM8990_ANTIPOP2, 0x0);
 
 		regcache_mark_dirty(wm8990->regmap);
 		break;
@@ -1272,41 +1272,42 @@ static struct snd_soc_dai_driver wm8990_dai = {
  * initialise the WM8990 driver
  * register the mixer and dsp interfaces with the kernel
  */
-static int wm8990_probe(struct snd_soc_codec *codec)
+static int wm8990_probe(struct snd_soc_component *component)
 {
-	wm8990_reset(codec);
+	wm8990_reset(component);
 
 	/* charge output caps */
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
-	snd_soc_update_bits(codec, WM8990_AUDIO_INTERFACE_4,
+	snd_soc_component_update_bits(component, WM8990_AUDIO_INTERFACE_4,
 			    WM8990_ALRCGPIO1, WM8990_ALRCGPIO1);
 
-	snd_soc_update_bits(codec, WM8990_GPIO1_GPIO2,
+	snd_soc_component_update_bits(component, WM8990_GPIO1_GPIO2,
 			    WM8990_GPIO1_SEL_MASK, 1);
 
-	snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
+	snd_soc_component_update_bits(component, WM8990_POWER_MANAGEMENT_2,
 			    WM8990_OPCLK_ENA, WM8990_OPCLK_ENA);
 
-	snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
-	snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
+	snd_soc_component_write(component, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
+	snd_soc_component_write(component, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
-	.probe =	wm8990_probe,
-	.set_bias_level = wm8990_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8990_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8990_snd_controls),
-		.dapm_widgets		= wm8990_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8990_dapm_widgets),
-		.dapm_routes		= wm8990_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8990_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8990 = {
+	.probe			= wm8990_probe,
+	.set_bias_level		= wm8990_set_bias_level,
+	.controls		= wm8990_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8990_snd_controls),
+	.dapm_widgets		= wm8990_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8990_dapm_widgets),
+	.dapm_routes		= wm8990_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8990_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8990_regmap = {
@@ -1333,19 +1334,12 @@ static int wm8990_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm8990);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8990, &wm8990_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8990, &wm8990_dai, 1);
 
 	return ret;
 }
 
-static int wm8990_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm8990_i2c_id[] = {
 	{ "wm8990", 0 },
 	{ }
@@ -1357,7 +1351,6 @@ static struct i2c_driver wm8990_i2c_driver = {
 		.name = "wm8990",
 	},
 	.probe =    wm8990_i2c_probe,
-	.remove =   wm8990_i2c_remove,
 	.id_table = wm8990_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 802c0694..76a639d 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -133,7 +133,7 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_sidetone_tlv,
 static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
 				      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int ret;
 	u16 val;
@@ -143,8 +143,8 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
 		return ret;
 
 	/* now hit the volume update bits (always bit 8) */
-	val = snd_soc_read(codec, reg);
-	return snd_soc_write(codec, reg, val | 0x0100);
+	val = snd_soc_component_read32(component, reg);
+	return snd_soc_component_write(component, reg, val | 0x0100);
 }
 
 static const char *wm8991_digital_sidetone[] =
@@ -361,14 +361,14 @@ static const struct snd_kcontrol_new wm8991_snd_controls[] = {
 static int outmixer_event(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	u32 reg_shift = kcontrol->private_value & 0xfff;
 	int ret = 0;
 	u16 reg;
 
 	switch (reg_shift) {
 	case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8):
-		reg = snd_soc_read(codec, WM8991_OUTPUT_MIXER1);
+		reg = snd_soc_component_read32(component, WM8991_OUTPUT_MIXER1);
 		if (reg & WM8991_LDLO) {
 			printk(KERN_WARNING
 			       "Cannot set as Output Mixer 1 LDLO Set\n");
@@ -377,7 +377,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
 		break;
 
 	case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8):
-		reg = snd_soc_read(codec, WM8991_OUTPUT_MIXER2);
+		reg = snd_soc_component_read32(component, WM8991_OUTPUT_MIXER2);
 		if (reg & WM8991_RDRO) {
 			printk(KERN_WARNING
 			       "Cannot set as Output Mixer 2 RDRO Set\n");
@@ -386,7 +386,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
 		break;
 
 	case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8):
-		reg = snd_soc_read(codec, WM8991_SPEAKER_MIXER);
+		reg = snd_soc_component_read32(component, WM8991_SPEAKER_MIXER);
 		if (reg & WM8991_LDSPK) {
 			printk(KERN_WARNING
 			       "Cannot set as Speaker Mixer LDSPK Set\n");
@@ -395,7 +395,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
 		break;
 
 	case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8):
-		reg = snd_soc_read(codec, WM8991_SPEAKER_MIXER);
+		reg = snd_soc_component_read32(component, WM8991_SPEAKER_MIXER);
 		if (reg & WM8991_RDSPK) {
 			printk(KERN_WARNING
 			       "Cannot set as Speaker Mixer RDSPK Set\n");
@@ -927,31 +927,31 @@ static int wm8991_set_dai_pll(struct snd_soc_dai *codec_dai,
 			      int pll_id, int src, unsigned int freq_in, unsigned int freq_out)
 {
 	u16 reg;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	struct _pll_div pll_div;
 
 	if (freq_in && freq_out) {
 		pll_factors(&pll_div, freq_out * 4, freq_in);
 
 		/* Turn on PLL */
-		reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
+		reg = snd_soc_component_read32(component, WM8991_POWER_MANAGEMENT_2);
 		reg |= WM8991_PLL_ENA;
-		snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
+		snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_2, reg);
 
 		/* sysclk comes from PLL */
-		reg = snd_soc_read(codec, WM8991_CLOCKING_2);
-		snd_soc_write(codec, WM8991_CLOCKING_2, reg | WM8991_SYSCLK_SRC);
+		reg = snd_soc_component_read32(component, WM8991_CLOCKING_2);
+		snd_soc_component_write(component, WM8991_CLOCKING_2, reg | WM8991_SYSCLK_SRC);
 
 		/* set up N , fractional mode and pre-divisor if necessary */
-		snd_soc_write(codec, WM8991_PLL1, pll_div.n | WM8991_SDM |
+		snd_soc_component_write(component, WM8991_PLL1, pll_div.n | WM8991_SDM |
 			      (pll_div.div2 ? WM8991_PRESCALE : 0));
-		snd_soc_write(codec, WM8991_PLL2, (u8)(pll_div.k>>8));
-		snd_soc_write(codec, WM8991_PLL3, (u8)(pll_div.k & 0xFF));
+		snd_soc_component_write(component, WM8991_PLL2, (u8)(pll_div.k>>8));
+		snd_soc_component_write(component, WM8991_PLL3, (u8)(pll_div.k & 0xFF));
 	} else {
 		/* Turn on PLL */
-		reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
+		reg = snd_soc_component_read32(component, WM8991_POWER_MANAGEMENT_2);
 		reg &= ~WM8991_PLL_ENA;
-		snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
+		snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_2, reg);
 	}
 	return 0;
 }
@@ -962,11 +962,11 @@ static int wm8991_set_dai_pll(struct snd_soc_dai *codec_dai,
 static int wm8991_set_dai_fmt(struct snd_soc_dai *codec_dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 audio1, audio3;
 
-	audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
-	audio3 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_3);
+	audio1 = snd_soc_component_read32(component, WM8991_AUDIO_INTERFACE_1);
+	audio3 = snd_soc_component_read32(component, WM8991_AUDIO_INTERFACE_3);
 
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1007,37 +1007,37 @@ static int wm8991_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
-	snd_soc_write(codec, WM8991_AUDIO_INTERFACE_3, audio3);
+	snd_soc_component_write(component, WM8991_AUDIO_INTERFACE_1, audio1);
+	snd_soc_component_write(component, WM8991_AUDIO_INTERFACE_3, audio3);
 	return 0;
 }
 
 static int wm8991_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 				 int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	u16 reg;
 
 	switch (div_id) {
 	case WM8991_MCLK_DIV:
-		reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
+		reg = snd_soc_component_read32(component, WM8991_CLOCKING_2) &
 		      ~WM8991_MCLK_DIV_MASK;
-		snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
+		snd_soc_component_write(component, WM8991_CLOCKING_2, reg | div);
 		break;
 	case WM8991_DACCLK_DIV:
-		reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
+		reg = snd_soc_component_read32(component, WM8991_CLOCKING_2) &
 		      ~WM8991_DAC_CLKDIV_MASK;
-		snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
+		snd_soc_component_write(component, WM8991_CLOCKING_2, reg | div);
 		break;
 	case WM8991_ADCCLK_DIV:
-		reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
+		reg = snd_soc_component_read32(component, WM8991_CLOCKING_2) &
 		      ~WM8991_ADC_CLKDIV_MASK;
-		snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
+		snd_soc_component_write(component, WM8991_CLOCKING_2, reg | div);
 		break;
 	case WM8991_BCLK_DIV:
-		reg = snd_soc_read(codec, WM8991_CLOCKING_1) &
+		reg = snd_soc_component_read32(component, WM8991_CLOCKING_1) &
 		      ~WM8991_BCLK_DIV_MASK;
-		snd_soc_write(codec, WM8991_CLOCKING_1, reg | div);
+		snd_soc_component_write(component, WM8991_CLOCKING_1, reg | div);
 		break;
 	default:
 		return -EINVAL;
@@ -1053,8 +1053,8 @@ static int wm8991_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;
-	u16 audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
+	struct snd_soc_component *component = dai->component;
+	u16 audio1 = snd_soc_component_read32(component, WM8991_AUDIO_INTERFACE_1);
 
 	audio1 &= ~WM8991_AIF_WL_MASK;
 	/* bit size */
@@ -1072,27 +1072,27 @@ static int wm8991_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
+	snd_soc_component_write(component, WM8991_AUDIO_INTERFACE_1, audio1);
 	return 0;
 }
 
 static int wm8991_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	u16 val;
 
-	val  = snd_soc_read(codec, WM8991_DAC_CTRL) & ~WM8991_DAC_MUTE;
+	val  = snd_soc_component_read32(component, WM8991_DAC_CTRL) & ~WM8991_DAC_MUTE;
 	if (mute)
-		snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
+		snd_soc_component_write(component, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
 	else
-		snd_soc_write(codec, WM8991_DAC_CTRL, val);
+		snd_soc_component_write(component, WM8991_DAC_CTRL, val);
 	return 0;
 }
 
-static int wm8991_set_bias_level(struct snd_soc_codec *codec,
+static int wm8991_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8991_priv *wm8991 = snd_soc_codec_get_drvdata(codec);
+	struct wm8991_priv *wm8991 = snd_soc_component_get_drvdata(component);
 	u16 val;
 
 	switch (level) {
@@ -1101,22 +1101,22 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID=2*50k */
-		val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
+		val = snd_soc_component_read32(component, WM8991_POWER_MANAGEMENT_1) &
 		      ~WM8991_VMID_MODE_MASK;
-		snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x2);
+		snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, val | 0x2);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_sync(wm8991->regmap);
 			/* Enable all output discharge bits */
-			snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
+			snd_soc_component_write(component, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
 				      WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
 				      WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
 				      WM8991_DIS_ROUT);
 
 			/* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
-			snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
+			snd_soc_component_write(component, WM8991_ANTIPOP2, WM8991_SOFTST |
 				      WM8991_BUFDCOPEN | WM8991_POBCTRL |
 				      WM8991_VMIDTOG);
 
@@ -1124,78 +1124,78 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec,
 			msleep(300);
 
 			/* Disable VMIDTOG */
-			snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
+			snd_soc_component_write(component, WM8991_ANTIPOP2, WM8991_SOFTST |
 				      WM8991_BUFDCOPEN | WM8991_POBCTRL);
 
 			/* disable all output discharge bits */
-			snd_soc_write(codec, WM8991_ANTIPOP1, 0);
+			snd_soc_component_write(component, WM8991_ANTIPOP1, 0);
 
 			/* Enable outputs */
-			snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1b00);
+			snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, 0x1b00);
 
 			msleep(50);
 
 			/* Enable VMID at 2x50k */
-			snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f02);
+			snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, 0x1f02);
 
 			msleep(100);
 
 			/* Enable VREF */
-			snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
+			snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, 0x1f03);
 
 			msleep(600);
 
 			/* Enable BUFIOEN */
-			snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
+			snd_soc_component_write(component, WM8991_ANTIPOP2, WM8991_SOFTST |
 				      WM8991_BUFDCOPEN | WM8991_POBCTRL |
 				      WM8991_BUFIOEN);
 
 			/* Disable outputs */
-			snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x3);
+			snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, 0x3);
 
 			/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
-			snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_BUFIOEN);
+			snd_soc_component_write(component, WM8991_ANTIPOP2, WM8991_BUFIOEN);
 		}
 
 		/* VMID=2*250k */
-		val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
+		val = snd_soc_component_read32(component, WM8991_POWER_MANAGEMENT_1) &
 		      ~WM8991_VMID_MODE_MASK;
-		snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x4);
+		snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, val | 0x4);
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* Enable POBCTRL and SOFT_ST */
-		snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
+		snd_soc_component_write(component, WM8991_ANTIPOP2, WM8991_SOFTST |
 			      WM8991_POBCTRL | WM8991_BUFIOEN);
 
 		/* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
-		snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
+		snd_soc_component_write(component, WM8991_ANTIPOP2, WM8991_SOFTST |
 			      WM8991_BUFDCOPEN | WM8991_POBCTRL |
 			      WM8991_BUFIOEN);
 
 		/* mute DAC */
-		val = snd_soc_read(codec, WM8991_DAC_CTRL);
-		snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
+		val = snd_soc_component_read32(component, WM8991_DAC_CTRL);
+		snd_soc_component_write(component, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
 
 		/* Enable any disabled outputs */
-		snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
+		snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, 0x1f03);
 
 		/* Disable VMID */
-		snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f01);
+		snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, 0x1f01);
 
 		msleep(300);
 
 		/* Enable all output discharge bits */
-		snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
+		snd_soc_component_write(component, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
 			      WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
 			      WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
 			      WM8991_DIS_ROUT);
 
 		/* Disable VREF */
-		snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x0);
+		snd_soc_component_write(component, WM8991_POWER_MANAGEMENT_1, 0x0);
 
 		/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
-		snd_soc_write(codec, WM8991_ANTIPOP2, 0x0);
+		snd_soc_component_write(component, WM8991_ANTIPOP2, 0x0);
 		regcache_mark_dirty(wm8991->regmap);
 		break;
 	}
@@ -1242,18 +1242,19 @@ static struct snd_soc_dai_driver wm8991_dai = {
 	.ops = &wm8991_ops
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
-	.set_bias_level = wm8991_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8991_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8991_snd_controls),
-		.dapm_widgets		= wm8991_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8991_dapm_widgets),
-		.dapm_routes		= wm8991_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8991_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8991 = {
+	.set_bias_level		= wm8991_set_bias_level,
+	.controls		= wm8991_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8991_snd_controls),
+	.dapm_widgets		= wm8991_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8991_dapm_widgets),
+	.dapm_routes		= wm8991_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8991_dapm_routes),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8991_regmap = {
@@ -1319,19 +1320,12 @@ static int wm8991_i2c_probe(struct i2c_client *i2c,
 	regmap_write(wm8991->regmap, WM8991_RIGHT_OUTPUT_VOLUME,
 		     0x50 | (1<<8));
 
-	ret = snd_soc_register_codec(&i2c->dev,
-				     &soc_codec_dev_wm8991, &wm8991_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_wm8991, &wm8991_dai, 1);
 
 	return ret;
 }
 
-static int wm8991_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-
-	return 0;
-}
-
 static const struct i2c_device_id wm8991_i2c_id[] = {
 	{ "wm8991", 0 },
 	{ }
@@ -1343,7 +1337,6 @@ static struct i2c_driver wm8991_i2c_driver = {
 		.name = "wm8991",
 	},
 	.probe = wm8991_i2c_probe,
-	.remove = wm8991_i2c_remove,
 	.id_table = wm8991_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 830ffd80..2c61655 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -466,11 +466,11 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 	return 0;
 }
 
-static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+static int _wm8993_set_fll(struct snd_soc_component *component, int fll_id, int source,
 			  unsigned int Fref, unsigned int Fout)
 {
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
 	u16 reg1, reg4, reg5;
 	struct _fll_div fll_div;
 	unsigned int timeout;
@@ -482,13 +482,13 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 
 	/* Disable the FLL */
 	if (Fout == 0) {
-		dev_dbg(codec->dev, "FLL disabled\n");
+		dev_dbg(component->dev, "FLL disabled\n");
 		wm8993->fll_fref = 0;
 		wm8993->fll_fout = 0;
 
-		reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
+		reg1 = snd_soc_component_read32(component, WM8993_FLL_CONTROL_1);
 		reg1 &= ~WM8993_FLL_ENA;
-		snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
+		snd_soc_component_write(component, WM8993_FLL_CONTROL_1, reg1);
 
 		return 0;
 	}
@@ -497,7 +497,7 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	if (ret != 0)
 		return ret;
 
-	reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5);
+	reg5 = snd_soc_component_read32(component, WM8993_FLL_CONTROL_5);
 	reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
 
 	switch (fll_id) {
@@ -513,36 +513,36 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		break;
 
 	default:
-		dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
+		dev_err(component->dev, "Unknown FLL ID %d\n", fll_id);
 		return -EINVAL;
 	}
 
 	/* Any FLL configuration change requires that the FLL be
 	 * disabled first. */
-	reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
+	reg1 = snd_soc_component_read32(component, WM8993_FLL_CONTROL_1);
 	reg1 &= ~WM8993_FLL_ENA;
-	snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
+	snd_soc_component_write(component, WM8993_FLL_CONTROL_1, reg1);
 
 	/* Apply the configuration */
 	if (fll_div.k)
 		reg1 |= WM8993_FLL_FRAC_MASK;
 	else
 		reg1 &= ~WM8993_FLL_FRAC_MASK;
-	snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
+	snd_soc_component_write(component, WM8993_FLL_CONTROL_1, reg1);
 
-	snd_soc_write(codec, WM8993_FLL_CONTROL_2,
+	snd_soc_component_write(component, WM8993_FLL_CONTROL_2,
 		      (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
 		      (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
-	snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
+	snd_soc_component_write(component, WM8993_FLL_CONTROL_3, fll_div.k);
 
-	reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4);
+	reg4 = snd_soc_component_read32(component, WM8993_FLL_CONTROL_4);
 	reg4 &= ~WM8993_FLL_N_MASK;
 	reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
-	snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4);
+	snd_soc_component_write(component, WM8993_FLL_CONTROL_4, reg4);
 
 	reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
 	reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
-	snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
+	snd_soc_component_write(component, WM8993_FLL_CONTROL_5, reg5);
 
 	/* If we've got an interrupt wired up make sure we get it */
 	if (i2c->irq)
@@ -555,13 +555,13 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	try_wait_for_completion(&wm8993->fll_lock);
 
 	/* Enable the FLL */
-	snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
+	snd_soc_component_write(component, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
 
 	timeout = wait_for_completion_timeout(&wm8993->fll_lock, timeout);
 	if (i2c->irq && !timeout)
-		dev_warn(codec->dev, "Timed out waiting for FLL\n");
+		dev_warn(component->dev, "Timed out waiting for FLL\n");
 
-	dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
+	dev_dbg(component->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
 
 	wm8993->fll_fref = Fref;
 	wm8993->fll_fout = Fout;
@@ -573,20 +573,20 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
 			  unsigned int Fref, unsigned int Fout)
 {
-	return _wm8993_set_fll(dai->codec, fll_id, source, Fref, Fout);
+	return _wm8993_set_fll(dai->component, fll_id, source, Fref, Fout);
 }
 
-static int configure_clock(struct snd_soc_codec *codec)
+static int configure_clock(struct snd_soc_component *component)
 {
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
 	unsigned int reg;
 
 	/* This should be done on init() for bypass paths */
 	switch (wm8993->sysclk_source) {
 	case WM8993_SYSCLK_MCLK:
-		dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
+		dev_dbg(component->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
 
-		reg = snd_soc_read(codec, WM8993_CLOCKING_2);
+		reg = snd_soc_component_read32(component, WM8993_CLOCKING_2);
 		reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
 		if (wm8993->mclk_rate > 13500000) {
 			reg |= WM8993_MCLK_DIV;
@@ -595,14 +595,14 @@ static int configure_clock(struct snd_soc_codec *codec)
 			reg &= ~WM8993_MCLK_DIV;
 			wm8993->sysclk_rate = wm8993->mclk_rate;
 		}
-		snd_soc_write(codec, WM8993_CLOCKING_2, reg);
+		snd_soc_component_write(component, WM8993_CLOCKING_2, reg);
 		break;
 
 	case WM8993_SYSCLK_FLL:
-		dev_dbg(codec->dev, "Using %dHz FLL clock\n",
+		dev_dbg(component->dev, "Using %dHz FLL clock\n",
 			wm8993->fll_fout);
 
-		reg = snd_soc_read(codec, WM8993_CLOCKING_2);
+		reg = snd_soc_component_read32(component, WM8993_CLOCKING_2);
 		reg |= WM8993_SYSCLK_SRC;
 		if (wm8993->fll_fout > 13500000) {
 			reg |= WM8993_MCLK_DIV;
@@ -611,15 +611,15 @@ static int configure_clock(struct snd_soc_codec *codec)
 			reg &= ~WM8993_MCLK_DIV;
 			wm8993->sysclk_rate = wm8993->fll_fout;
 		}
-		snd_soc_write(codec, WM8993_CLOCKING_2, reg);
+		snd_soc_component_write(component, WM8993_CLOCKING_2, reg);
 		break;
 
 	default:
-		dev_err(codec->dev, "System clock not configured\n");
+		dev_err(component->dev, "System clock not configured\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8993->sysclk_rate);
+	dev_dbg(component->dev, "CLK_SYS is %dHz\n", wm8993->sysclk_rate);
 
 	return 0;
 }
@@ -809,11 +809,11 @@ SOC_SINGLE_TLV("EQ5 Volume", WM8993_EQ6, 0, 24, 0, eq_tlv),
 static int clk_sys_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		return configure_clock(codec);
+		return configure_clock(component);
 
 	case SND_SOC_DAPM_POST_PMD:
 		break;
@@ -972,26 +972,26 @@ static const struct snd_soc_dapm_route routes[] = {
 	{ "Right Headphone Mux", "DAC", "DACR" },
 };
 
-static int wm8993_set_bias_level(struct snd_soc_codec *codec,
+static int wm8993_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	wm_hubs_set_bias_level(codec, level);
+	wm_hubs_set_bias_level(component, level);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID=2*40k */
-		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_1,
 				    WM8993_VMID_SEL_MASK, 0x2);
-		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
+		snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_2,
 				    WM8993_TSHUT_ENA, WM8993_TSHUT_ENA);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
 						    wm8993->supplies);
 			if (ret != 0)
@@ -1000,10 +1000,10 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
 			regcache_cache_only(wm8993->regmap, false);
 			regcache_sync(wm8993->regmap);
 
-			wm_hubs_vmid_ena(codec);
+			wm_hubs_vmid_ena(component);
 
 			/* Bring up VMID with fast soft start */
-			snd_soc_update_bits(codec, WM8993_ANTIPOP2,
+			snd_soc_component_update_bits(component, WM8993_ANTIPOP2,
 					    WM8993_STARTUP_BIAS_ENA |
 					    WM8993_VMID_BUF_ENA |
 					    WM8993_VMID_RAMP_MASK |
@@ -1017,40 +1017,40 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
 			 * need the VMID buffer */
 			if (!wm8993->pdata.lineout1_diff ||
 			    !wm8993->pdata.lineout2_diff)
-				snd_soc_update_bits(codec, WM8993_ANTIPOP1,
+				snd_soc_component_update_bits(component, WM8993_ANTIPOP1,
 						 WM8993_LINEOUT_VMID_BUF_ENA,
 						 WM8993_LINEOUT_VMID_BUF_ENA);
 
 			/* VMID=2*40k */
-			snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_1,
 					    WM8993_VMID_SEL_MASK |
 					    WM8993_BIAS_ENA,
 					    WM8993_BIAS_ENA | 0x2);
 			msleep(32);
 
 			/* Switch to normal bias */
-			snd_soc_update_bits(codec, WM8993_ANTIPOP2,
+			snd_soc_component_update_bits(component, WM8993_ANTIPOP2,
 					    WM8993_BIAS_SRC |
 					    WM8993_STARTUP_BIAS_ENA, 0);
 		}
 
 		/* VMID=2*240k */
-		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_1,
 				    WM8993_VMID_SEL_MASK, 0x4);
 
-		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
+		snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_2,
 				    WM8993_TSHUT_ENA, 0);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, WM8993_ANTIPOP1,
+		snd_soc_component_update_bits(component, WM8993_ANTIPOP1,
 				    WM8993_LINEOUT_VMID_BUF_ENA, 0);
 
-		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_1,
 				    WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
 				    0);
 
-		snd_soc_update_bits(codec, WM8993_ANTIPOP2,
+		snd_soc_component_update_bits(component, WM8993_ANTIPOP2,
 				    WM8993_STARTUP_BIAS_ENA |
 				    WM8993_VMID_BUF_ENA |
 				    WM8993_VMID_RAMP_MASK |
@@ -1070,8 +1070,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
 static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
 			     int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = codec_dai->component;
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case WM8993_SYSCLK_MCLK:
@@ -1091,10 +1091,10 @@ static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
-	unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
-	unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
+	struct snd_soc_component *component = dai->component;
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
+	unsigned int aif1 = snd_soc_component_read32(component, WM8993_AUDIO_INTERFACE_1);
+	unsigned int aif4 = snd_soc_component_read32(component, WM8993_AUDIO_INTERFACE_4);
 
 	aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
 		  WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
@@ -1178,8 +1178,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
-	snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
+	snd_soc_component_write(component, WM8993_AUDIO_INTERFACE_1, aif1);
+	snd_soc_component_write(component, WM8993_AUDIO_INTERFACE_4, aif4);
 
 	return 0;
 }
@@ -1188,28 +1188,28 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
 	int ret, i, best, best_val, cur_val;
 	unsigned int clocking1, clocking3, aif1, aif4;
 
-	clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
+	clocking1 = snd_soc_component_read32(component, WM8993_CLOCKING_1);
 	clocking1 &= ~WM8993_BCLK_DIV_MASK;
 
-	clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
+	clocking3 = snd_soc_component_read32(component, WM8993_CLOCKING_3);
 	clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
 
-	aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
+	aif1 = snd_soc_component_read32(component, WM8993_AUDIO_INTERFACE_1);
 	aif1 &= ~WM8993_AIF_WL_MASK;
 
-	aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
+	aif4 = snd_soc_component_read32(component, WM8993_AUDIO_INTERFACE_4);
 	aif4 &= ~WM8993_LRCLK_RATE_MASK;
 
 	/* What BCLK do we need? */
 	wm8993->fs = params_rate(params);
 	wm8993->bclk = 2 * wm8993->fs;
 	if (wm8993->tdm_slots) {
-		dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
+		dev_dbg(component->dev, "Configuring for %d %d bit TDM slots\n",
 			wm8993->tdm_slots, wm8993->tdm_width);
 		wm8993->bclk *= wm8993->tdm_width * wm8993->tdm_slots;
 	} else {
@@ -1234,9 +1234,9 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 
-	dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8993->bclk);
+	dev_dbg(component->dev, "Target BCLK is %dHz\n", wm8993->bclk);
 
-	ret = configure_clock(codec);
+	ret = configure_clock(component);
 	if (ret != 0)
 		return ret;
 
@@ -1252,7 +1252,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
 			best_val = cur_val;
 		}
 	}
-	dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
+	dev_dbg(component->dev, "Selected CLK_SYS_RATIO of %d\n",
 		clk_sys_rates[best].ratio);
 	clocking3 |= (clk_sys_rates[best].clk_sys_rate
 		      << WM8993_CLK_SYS_RATE_SHIFT);
@@ -1268,7 +1268,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
 			best_val = cur_val;
 		}
 	}
-	dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
+	dev_dbg(component->dev, "Selected SAMPLE_RATE of %dHz\n",
 		sample_rates[best].rate);
 	clocking3 |= (sample_rates[best].sample_rate
 		      << WM8993_SAMPLE_RATE_SHIFT);
@@ -1287,22 +1287,22 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 	wm8993->bclk = (wm8993->sysclk_rate * 10) / bclk_divs[best].div;
-	dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
+	dev_dbg(component->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
 		bclk_divs[best].div, wm8993->bclk);
 	clocking1 |= bclk_divs[best].bclk_div << WM8993_BCLK_DIV_SHIFT;
 
 	/* LRCLK is a simple fraction of BCLK */
-	dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
+	dev_dbg(component->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
 	aif4 |= wm8993->bclk / wm8993->fs;
 
-	snd_soc_write(codec, WM8993_CLOCKING_1, clocking1);
-	snd_soc_write(codec, WM8993_CLOCKING_3, clocking3);
-	snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
-	snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
+	snd_soc_component_write(component, WM8993_CLOCKING_1, clocking1);
+	snd_soc_component_write(component, WM8993_CLOCKING_3, clocking3);
+	snd_soc_component_write(component, WM8993_AUDIO_INTERFACE_1, aif1);
+	snd_soc_component_write(component, WM8993_AUDIO_INTERFACE_4, aif4);
 
 	/* ReTune Mobile? */
 	if (wm8993->pdata.num_retune_configs) {
-		u16 eq1 = snd_soc_read(codec, WM8993_EQ1);
+		u16 eq1 = snd_soc_component_read32(component, WM8993_EQ1);
 		struct wm8993_retune_mobile_setting *s;
 
 		best = 0;
@@ -1318,16 +1318,16 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
 		}
 		s = &wm8993->pdata.retune_configs[best];
 
-		dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
+		dev_dbg(component->dev, "ReTune Mobile %s tuned for %dHz\n",
 			s->name, s->rate);
 
 		/* Disable EQ while we reconfigure */
-		snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
+		snd_soc_component_update_bits(component, WM8993_EQ1, WM8993_EQ_ENA, 0);
 
 		for (i = 1; i < ARRAY_SIZE(s->config); i++)
-			snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]);
+			snd_soc_component_write(component, WM8993_EQ1 + i, s->config[i]);
 
-		snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
+		snd_soc_component_update_bits(component, WM8993_EQ1, WM8993_EQ_ENA, eq1);
 	}
 
 	return 0;
@@ -1335,17 +1335,17 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, WM8993_DAC_CTRL);
+	reg = snd_soc_component_read32(component, WM8993_DAC_CTRL);
 
 	if (mute)
 		reg |= WM8993_DAC_MUTE;
 	else
 		reg &= ~WM8993_DAC_MUTE;
 
-	snd_soc_write(codec, WM8993_DAC_CTRL, reg);
+	snd_soc_component_write(component, WM8993_DAC_CTRL, reg);
 
 	return 0;
 }
@@ -1353,8 +1353,8 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			       unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
 	int aif1 = 0;
 	int aif2 = 0;
 
@@ -1396,9 +1396,9 @@ static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 	wm8993->tdm_width = slot_width;
 	wm8993->tdm_slots = slots / 2;
 
-	snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_1,
+	snd_soc_component_update_bits(component, WM8993_AUDIO_INTERFACE_1,
 			    WM8993_AIFADC_TDM | WM8993_AIFADC_TDM_CHAN, aif1);
-	snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_2,
+	snd_soc_component_update_bits(component, WM8993_AUDIO_INTERFACE_2,
 			    WM8993_AIFDAC_TDM | WM8993_AIFDAC_TDM_CHAN, aif2);
 
 	return 0;
@@ -1481,10 +1481,10 @@ static struct snd_soc_dai_driver wm8993_dai = {
 	.symmetric_rates = 1,
 };
 
-static int wm8993_probe(struct snd_soc_codec *codec)
+static int wm8993_probe(struct snd_soc_component *component)
 {
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	wm8993->hubs_data.hp_startup_mode = 1;
 	wm8993->hubs_data.dcs_codes_l = -2;
@@ -1492,20 +1492,20 @@ static int wm8993_probe(struct snd_soc_codec *codec)
 	wm8993->hubs_data.series_startup = 1;
 
 	/* Latch volume update bits and default ZC on */
-	snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
 			    WM8993_DAC_VU, WM8993_DAC_VU);
-	snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
 			    WM8993_ADC_VU, WM8993_ADC_VU);
 
 	/* Manualy manage the HPOUT sequencing for independent stereo
 	 * control. */
-	snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
+	snd_soc_component_update_bits(component, WM8993_ANALOGUE_HP_0,
 			    WM8993_HPOUT1_AUTO_PU, 0);
 
 	/* Use automatic clock configuration */
-	snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
+	snd_soc_component_update_bits(component, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
 
-	wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
+	wm_hubs_handle_analogue_pdata(component, wm8993->pdata.lineout1_diff,
 				      wm8993->pdata.lineout2_diff,
 				      wm8993->pdata.lineout1fb,
 				      wm8993->pdata.lineout2fb,
@@ -1516,22 +1516,22 @@ static int wm8993_probe(struct snd_soc_codec *codec)
 				      wm8993->pdata.micbias1_lvl,
 				      wm8993->pdata.micbias2_lvl);
 
-	snd_soc_add_codec_controls(codec, wm8993_snd_controls,
+	snd_soc_add_component_controls(component, wm8993_snd_controls,
 			     ARRAY_SIZE(wm8993_snd_controls));
 	if (wm8993->pdata.num_retune_configs != 0) {
-		dev_dbg(codec->dev, "Using ReTune Mobile\n");
+		dev_dbg(component->dev, "Using ReTune Mobile\n");
 	} else {
-		dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n");
-		snd_soc_add_codec_controls(codec, wm8993_eq_controls,
+		dev_dbg(component->dev, "No ReTune Mobile, using normal EQ\n");
+		snd_soc_add_component_controls(component, wm8993_eq_controls,
 				     ARRAY_SIZE(wm8993_eq_controls));
 	}
 
 	snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets,
 				  ARRAY_SIZE(wm8993_dapm_widgets));
-	wm_hubs_add_analogue_controls(codec);
+	wm_hubs_add_analogue_controls(component);
 
 	snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
-	wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
+	wm_hubs_add_analogue_routes(component, wm8993->pdata.lineout1_diff,
 				    wm8993->pdata.lineout2_diff);
 
 	/* If the line outputs are differential then we aren't presenting
@@ -1545,34 +1545,34 @@ static int wm8993_probe(struct snd_soc_codec *codec)
 }
 
 #ifdef CONFIG_PM
-static int wm8993_suspend(struct snd_soc_codec *codec)
+static int wm8993_suspend(struct snd_soc_component *component)
 {
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
 	int fll_fout = wm8993->fll_fout;
 	int fll_fref  = wm8993->fll_fref;
 	int ret;
 
 	/* Stop the FLL in an orderly fashion */
-	ret = _wm8993_set_fll(codec, 0, 0, 0, 0);
+	ret = _wm8993_set_fll(component, 0, 0, 0, 0);
 	if (ret != 0) {
-		dev_err(codec->dev, "Failed to stop FLL\n");
+		dev_err(component->dev, "Failed to stop FLL\n");
 		return ret;
 	}
 
 	wm8993->fll_fout = fll_fout;
 	wm8993->fll_fref = fll_fref;
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
 	return 0;
 }
 
-static int wm8993_resume(struct snd_soc_codec *codec)
+static int wm8993_resume(struct snd_soc_component *component)
 {
-	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+	struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component);
 	int ret;
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	/* Restart the FLL? */
 	if (wm8993->fll_fout) {
@@ -1582,10 +1582,10 @@ static int wm8993_resume(struct snd_soc_codec *codec)
 		wm8993->fll_fref = 0;
 		wm8993->fll_fout = 0;
 
-		ret = _wm8993_set_fll(codec, 0, wm8993->fll_src,
+		ret = _wm8993_set_fll(component, 0, wm8993->fll_src,
 				     fll_fref, fll_fout);
 		if (ret != 0)
-			dev_err(codec->dev, "Failed to restart FLL\n");
+			dev_err(component->dev, "Failed to restart FLL\n");
 	}
 
 	return 0;
@@ -1615,11 +1615,15 @@ static const struct regmap_config wm8993_regmap = {
 	.num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults),
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
-	.probe = 	wm8993_probe,
-	.suspend =	wm8993_suspend,
-	.resume =	wm8993_resume,
-	.set_bias_level = wm8993_set_bias_level,
+static const struct snd_soc_component_driver soc_component_dev_wm8993 = {
+	.probe			= wm8993_probe,
+	.suspend		= wm8993_suspend,
+	.resume			= wm8993_resume,
+	.set_bias_level		= wm8993_set_bias_level,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8993_i2c_probe(struct i2c_client *i2c,
@@ -1705,8 +1709,8 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
 
 	regcache_cache_only(wm8993->regmap, true);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8993, &wm8993_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm8993, &wm8993_dai, 1);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
 		goto err_irq;
@@ -1726,7 +1730,6 @@ 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);
 	regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 21ffd64..6e9e32a 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -106,9 +106,9 @@ static const struct wm8958_micd_rate jackdet_rates[] = {
 	{ 44100 * 256, false, 7, 8 },
 };
 
-static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
+static void wm8958_micd_set_rate(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int best, i, sysclk, val;
 	bool idle;
@@ -117,7 +117,7 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
 
 	idle = !wm8994->jack_mic;
 
-	sysclk = snd_soc_read(codec, WM8994_CLOCKING_1);
+	sysclk = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 	if (sysclk & WM8994_SYSCLK_SRC)
 		sysclk = wm8994->aifclk[1];
 	else
@@ -148,18 +148,18 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
 	val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT
 		| rates[best].rate << WM8958_MICD_RATE_SHIFT;
 
-	dev_dbg(codec->dev, "MICD rate %d,%d for %dHz %s\n",
+	dev_dbg(component->dev, "MICD rate %d,%d for %dHz %s\n",
 		rates[best].start, rates[best].rate, sysclk,
 		idle ? "idle" : "active");
 
-	snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+	snd_soc_component_update_bits(component, WM8958_MIC_DETECT_1,
 			    WM8958_MICD_BIAS_STARTTIME_MASK |
 			    WM8958_MICD_RATE_MASK, val);
 }
 
-static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
+static int configure_aif_clock(struct snd_soc_component *component, int aif)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	int rate;
 	int reg1 = 0;
 	int offset;
@@ -197,28 +197,28 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
 		rate /= 2;
 		reg1 |= WM8994_AIF1CLK_DIV;
 
-		dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
+		dev_dbg(component->dev, "Dividing AIF%d clock to %dHz\n",
 			aif + 1, rate);
 	}
 
 	wm8994->aifclk[aif] = rate;
 
-	snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
+	snd_soc_component_update_bits(component, WM8994_AIF1_CLOCKING_1 + offset,
 			    WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
 			    reg1);
 
 	return 0;
 }
 
-static int configure_clock(struct snd_soc_codec *codec)
+static int configure_clock(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	int change, new;
 
 	/* Bring up the AIF clocks first */
-	configure_aif_clock(codec, 0);
-	configure_aif_clock(codec, 1);
+	configure_aif_clock(component, 0);
+	configure_aif_clock(component, 1);
 
 	/* Then switch CLK_SYS over to the higher of them; a change
 	 * can only happen as a result of a clocking change which can
@@ -228,7 +228,7 @@ static int configure_clock(struct snd_soc_codec *codec)
 
 	/* If they're equal it doesn't matter which is used */
 	if (wm8994->aifclk[0] == wm8994->aifclk[1]) {
-		wm8958_micd_set_rate(codec);
+		wm8958_micd_set_rate(component);
 		return 0;
 	}
 
@@ -237,12 +237,12 @@ static int configure_clock(struct snd_soc_codec *codec)
 	else
 		new = 0;
 
-	change = snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+	change = snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
 				     WM8994_SYSCLK_SRC, new);
 	if (change)
 		snd_soc_dapm_sync(dapm);
 
-	wm8958_micd_set_rate(codec);
+	wm8958_micd_set_rate(component);
 
 	return 0;
 }
@@ -250,8 +250,8 @@ static int configure_clock(struct snd_soc_codec *codec)
 static int check_clk_sys(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-	int reg = snd_soc_read(codec, WM8994_CLOCKING_1);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+	int reg = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 	const char *clk;
 
 	/* Check what we're currently using for CLK_SYS */
@@ -300,7 +300,7 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
 {
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	int mask, ret;
 
 	/* Can't enable both ADC and DAC paths simultaneously */
@@ -310,7 +310,7 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
 	else
 		mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
 
-	ret = snd_soc_read(codec, mc->reg);
+	ret = snd_soc_component_read32(component, mc->reg);
 	if (ret < 0)
 		return ret;
 	if (ret & mask)
@@ -319,9 +319,9 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
 	return snd_soc_put_volsw(kcontrol, ucontrol);
 }
 
-static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
+static void wm8994_set_drc(struct snd_soc_component *component, int drc)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int base = wm8994_drc_base[drc];
@@ -329,15 +329,15 @@ static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
 	int save, i;
 
 	/* Save any enables; the configuration should clear them. */
-	save = snd_soc_read(codec, base);
+	save = snd_soc_component_read32(component, base);
 	save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
 		WM8994_AIF1ADC1R_DRC_ENA;
 
 	for (i = 0; i < WM8994_DRC_REGS; i++)
-		snd_soc_update_bits(codec, base + i, 0xffff,
+		snd_soc_component_update_bits(component, base + i, 0xffff,
 				    pdata->drc_cfgs[cfg].regs[i]);
 
-	snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA |
+	snd_soc_component_update_bits(component, base, WM8994_AIF1DAC1_DRC_ENA |
 			     WM8994_AIF1ADC1L_DRC_ENA |
 			     WM8994_AIF1ADC1R_DRC_ENA, save);
 }
@@ -357,8 +357,8 @@ static int wm8994_get_drc(const char *name)
 static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int drc = wm8994_get_drc(kcontrol->id.name);
@@ -372,7 +372,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
 
 	wm8994->drc_cfg[drc] = value;
 
-	wm8994_set_drc(codec, drc);
+	wm8994_set_drc(component, drc);
 
 	return 0;
 }
@@ -380,8 +380,8 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
 static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	int drc = wm8994_get_drc(kcontrol->id.name);
 
 	if (drc < 0)
@@ -391,9 +391,9 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
+static void wm8994_set_retune_mobile(struct snd_soc_component *component, int block)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int base = wm8994_retune_mobile_base[block];
@@ -430,7 +430,7 @@ static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
 		}
 	}
 
-	dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
+	dev_dbg(component->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
 		block,
 		pdata->retune_mobile_cfgs[best].name,
 		pdata->retune_mobile_cfgs[best].rate,
@@ -439,14 +439,14 @@ static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
 	/* The EQ will be disabled while reconfiguring it, remember the
 	 * current configuration.
 	 */
-	save = snd_soc_read(codec, base);
+	save = snd_soc_component_read32(component, base);
 	save &= WM8994_AIF1DAC1_EQ_ENA;
 
 	for (i = 0; i < WM8994_EQ_REGS; i++)
-		snd_soc_update_bits(codec, base + i, 0xffff,
+		snd_soc_component_update_bits(component, base + i, 0xffff,
 				pdata->retune_mobile_cfgs[best].regs[i]);
 
-	snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save);
+	snd_soc_component_update_bits(component, base, WM8994_AIF1DAC1_EQ_ENA, save);
 }
 
 /* Icky as hell but saves code duplication */
@@ -464,8 +464,8 @@ static int wm8994_get_retune_mobile_block(const char *name)
 static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
@@ -479,7 +479,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 
 	wm8994->retune_mobile_cfg[block] = value;
 
-	wm8994_set_retune_mobile(codec, block);
+	wm8994_set_retune_mobile(component, block);
 
 	return 0;
 }
@@ -487,8 +487,8 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
 
 	if (block < 0)
@@ -740,9 +740,9 @@ SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
 };
 
 /* We run all mode setting through a function to enforce audio mode */
-static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
+static void wm1811_jackdet_set_mode(struct snd_soc_component *component, u16 mode)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	if (!wm8994->jackdet || !wm8994->micdet[0].jack)
 		return;
@@ -759,37 +759,37 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
 	if (mode != WM1811_JACKDET_MODE_NONE)
 		mode = WM1811_JACKDET_MODE_AUDIO;
 
-	snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+	snd_soc_component_update_bits(component, WM8994_ANTIPOP_2,
 			    WM1811_JACKDET_MODE_MASK, mode);
 }
 
-static void active_reference(struct snd_soc_codec *codec)
+static void active_reference(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	mutex_lock(&wm8994->accdet_lock);
 
 	wm8994->active_refcount++;
 
-	dev_dbg(codec->dev, "Active refcount incremented, now %d\n",
+	dev_dbg(component->dev, "Active refcount incremented, now %d\n",
 		wm8994->active_refcount);
 
 	/* If we're using jack detection go into audio mode */
-	wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_AUDIO);
+	wm1811_jackdet_set_mode(component, WM1811_JACKDET_MODE_AUDIO);
 
 	mutex_unlock(&wm8994->accdet_lock);
 }
 
-static void active_dereference(struct snd_soc_codec *codec)
+static void active_dereference(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	u16 mode;
 
 	mutex_lock(&wm8994->accdet_lock);
 
 	wm8994->active_refcount--;
 
-	dev_dbg(codec->dev, "Active refcount decremented, now %d\n",
+	dev_dbg(component->dev, "Active refcount decremented, now %d\n",
 		wm8994->active_refcount);
 
 	if (wm8994->active_refcount == 0) {
@@ -799,7 +799,7 @@ static void active_dereference(struct snd_soc_codec *codec)
 		else
 			mode = WM1811_JACKDET_MODE_JACK;
 
-		wm1811_jackdet_set_mode(codec, mode);
+		wm1811_jackdet_set_mode(component, mode);
 	}
 
 	mutex_unlock(&wm8994->accdet_lock);
@@ -808,12 +808,12 @@ static void active_dereference(struct snd_soc_codec *codec)
 static int clk_sys_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		return configure_clock(codec);
+		return configure_clock(component);
 
 	case SND_SOC_DAPM_POST_PMU:
 		/*
@@ -832,30 +832,30 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		configure_clock(codec);
+		configure_clock(component);
 		break;
 	}
 
 	return 0;
 }
 
-static void vmid_reference(struct snd_soc_codec *codec)
+static void vmid_reference(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
 	wm8994->vmid_refcount++;
 
-	dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
+	dev_dbg(component->dev, "Referencing VMID, refcount is now %d\n",
 		wm8994->vmid_refcount);
 
 	if (wm8994->vmid_refcount == 1) {
-		snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+		snd_soc_component_update_bits(component, WM8994_ANTIPOP_1,
 				    WM8994_LINEOUT1_DISCH |
 				    WM8994_LINEOUT2_DISCH, 0);
 
-		wm_hubs_vmid_ena(codec);
+		wm_hubs_vmid_ena(component);
 
 		switch (wm8994->vmid_mode) {
 		default:
@@ -863,7 +863,7 @@ static void vmid_reference(struct snd_soc_codec *codec)
 			/* fall through */
 		case WM8994_VMID_NORMAL:
 			/* Startup bias, VMID ramp & buffer */
-			snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+			snd_soc_component_update_bits(component, WM8994_ANTIPOP_2,
 					    WM8994_BIAS_SRC |
 					    WM8994_VMID_DISCH |
 					    WM8994_STARTUP_BIAS_ENA |
@@ -875,14 +875,14 @@ static void vmid_reference(struct snd_soc_codec *codec)
 					    (0x2 << WM8994_VMID_RAMP_SHIFT));
 
 			/* Main bias enable, VMID=2x40k */
-			snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_1,
 					    WM8994_BIAS_ENA |
 					    WM8994_VMID_SEL_MASK,
 					    WM8994_BIAS_ENA | 0x2);
 
 			msleep(300);
 
-			snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+			snd_soc_component_update_bits(component, WM8994_ANTIPOP_2,
 					    WM8994_VMID_RAMP_MASK |
 					    WM8994_BIAS_SRC,
 					    0);
@@ -890,7 +890,7 @@ static void vmid_reference(struct snd_soc_codec *codec)
 
 		case WM8994_VMID_FORCE:
 			/* Startup bias, slow VMID ramp & buffer */
-			snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+			snd_soc_component_update_bits(component, WM8994_ANTIPOP_2,
 					    WM8994_BIAS_SRC |
 					    WM8994_VMID_DISCH |
 					    WM8994_STARTUP_BIAS_ENA |
@@ -902,14 +902,14 @@ static void vmid_reference(struct snd_soc_codec *codec)
 					    (0x2 << WM8994_VMID_RAMP_SHIFT));
 
 			/* Main bias enable, VMID=2x40k */
-			snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_1,
 					    WM8994_BIAS_ENA |
 					    WM8994_VMID_SEL_MASK,
 					    WM8994_BIAS_ENA | 0x2);
 
 			msleep(400);
 
-			snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+			snd_soc_component_update_bits(component, WM8994_ANTIPOP_2,
 					    WM8994_VMID_RAMP_MASK |
 					    WM8994_BIAS_SRC,
 					    0);
@@ -918,120 +918,120 @@ static void vmid_reference(struct snd_soc_codec *codec)
 	}
 }
 
-static void vmid_dereference(struct snd_soc_codec *codec)
+static void vmid_dereference(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	wm8994->vmid_refcount--;
 
-	dev_dbg(codec->dev, "Dereferencing VMID, refcount is now %d\n",
+	dev_dbg(component->dev, "Dereferencing VMID, refcount is now %d\n",
 		wm8994->vmid_refcount);
 
 	if (wm8994->vmid_refcount == 0) {
 		if (wm8994->hubs.lineout1_se)
-			snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
+			snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_3,
 					    WM8994_LINEOUT1N_ENA |
 					    WM8994_LINEOUT1P_ENA,
 					    WM8994_LINEOUT1N_ENA |
 					    WM8994_LINEOUT1P_ENA);
 
 		if (wm8994->hubs.lineout2_se)
-			snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
+			snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_3,
 					    WM8994_LINEOUT2N_ENA |
 					    WM8994_LINEOUT2P_ENA,
 					    WM8994_LINEOUT2N_ENA |
 					    WM8994_LINEOUT2P_ENA);
 
 		/* Start discharging VMID */
-		snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+		snd_soc_component_update_bits(component, WM8994_ANTIPOP_2,
 				    WM8994_BIAS_SRC |
 				    WM8994_VMID_DISCH,
 				    WM8994_BIAS_SRC |
 				    WM8994_VMID_DISCH);
 
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_1,
 				    WM8994_VMID_SEL_MASK, 0);
 
 		msleep(400);
 
 		/* Active discharge */
-		snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+		snd_soc_component_update_bits(component, WM8994_ANTIPOP_1,
 				    WM8994_LINEOUT1_DISCH |
 				    WM8994_LINEOUT2_DISCH,
 				    WM8994_LINEOUT1_DISCH |
 				    WM8994_LINEOUT2_DISCH);
 
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_3,
 				    WM8994_LINEOUT1N_ENA |
 				    WM8994_LINEOUT1P_ENA |
 				    WM8994_LINEOUT2N_ENA |
 				    WM8994_LINEOUT2P_ENA, 0);
 
 		/* Switch off startup biases */
-		snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+		snd_soc_component_update_bits(component, WM8994_ANTIPOP_2,
 				    WM8994_BIAS_SRC |
 				    WM8994_STARTUP_BIAS_ENA |
 				    WM8994_VMID_BUF_ENA |
 				    WM8994_VMID_RAMP_MASK, 0);
 
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_1,
 				    WM8994_VMID_SEL_MASK, 0);
 	}
 
-	pm_runtime_put(codec->dev);
+	pm_runtime_put(component->dev);
 }
 
 static int vmid_event(struct snd_soc_dapm_widget *w,
 		      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		vmid_reference(codec);
+		vmid_reference(component);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		vmid_dereference(codec);
+		vmid_dereference(component);
 		break;
 	}
 
 	return 0;
 }
 
-static bool wm8994_check_class_w_digital(struct snd_soc_codec *codec)
+static bool wm8994_check_class_w_digital(struct snd_soc_component *component)
 {
 	int source = 0;  /* GCC flow analysis can't track enable */
 	int reg, reg_r;
 
 	/* We also need the same AIF source for L/R and only one path */
-	reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+	reg = snd_soc_component_read32(component, WM8994_DAC1_LEFT_MIXER_ROUTING);
 	switch (reg) {
 	case WM8994_AIF2DACL_TO_DAC1L:
-		dev_vdbg(codec->dev, "Class W source AIF2DAC\n");
+		dev_vdbg(component->dev, "Class W source AIF2DAC\n");
 		source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
 		break;
 	case WM8994_AIF1DAC2L_TO_DAC1L:
-		dev_vdbg(codec->dev, "Class W source AIF1DAC2\n");
+		dev_vdbg(component->dev, "Class W source AIF1DAC2\n");
 		source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
 		break;
 	case WM8994_AIF1DAC1L_TO_DAC1L:
-		dev_vdbg(codec->dev, "Class W source AIF1DAC1\n");
+		dev_vdbg(component->dev, "Class W source AIF1DAC1\n");
 		source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
 		break;
 	default:
-		dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg);
+		dev_vdbg(component->dev, "DAC mixer setting: %x\n", reg);
 		return false;
 	}
 
-	reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+	reg_r = snd_soc_component_read32(component, WM8994_DAC1_RIGHT_MIXER_ROUTING);
 	if (reg_r != reg) {
-		dev_vdbg(codec->dev, "Left and right DAC mixers different\n");
+		dev_vdbg(component->dev, "Left and right DAC mixers different\n");
 		return false;
 	}
 
 	/* Set the source up */
-	snd_soc_update_bits(codec, WM8994_CLASS_W_1,
+	snd_soc_component_update_bits(component, WM8994_CLASS_W_1,
 			    WM8994_CP_DYN_SRC_SEL_MASK, source);
 
 	return true;
@@ -1040,8 +1040,8 @@ static bool wm8994_check_class_w_digital(struct snd_soc_codec *codec)
 static int aif1clk_ev(struct snd_soc_dapm_widget *w,
 		      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
 	int i;
@@ -1064,7 +1064,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
 		if (wm8994->channels[0] <= 2)
 			mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
 
-		val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1);
+		val = snd_soc_component_read32(component, WM8994_AIF1_CONTROL_1);
 		if ((val & WM8994_AIF1ADCL_SRC) &&
 		    (val & WM8994_AIF1ADCR_SRC))
 			adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA;
@@ -1075,7 +1075,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
 			adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA |
 				WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA;
 
-		val = snd_soc_read(codec, WM8994_AIF1_CONTROL_2);
+		val = snd_soc_component_read32(component, WM8994_AIF1_CONTROL_2);
 		if ((val & WM8994_AIF1DACL_SRC) &&
 		    (val & WM8994_AIF1DACR_SRC))
 			dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA;
@@ -1086,21 +1086,21 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
 			dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA |
 				WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA;
 
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4,
 				    mask, adc);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_5,
 				    mask, dac);
-		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+		snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
 				    WM8994_AIF1DSPCLK_ENA |
 				    WM8994_SYSDSPCLK_ENA,
 				    WM8994_AIF1DSPCLK_ENA |
 				    WM8994_SYSDSPCLK_ENA);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, mask,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4, mask,
 				    WM8994_AIF1ADC1R_ENA |
 				    WM8994_AIF1ADC1L_ENA |
 				    WM8994_AIF1ADC2R_ENA |
 				    WM8994_AIF1ADC2L_ENA);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, mask,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_5, mask,
 				    WM8994_AIF1DAC1R_ENA |
 				    WM8994_AIF1DAC1L_ENA |
 				    WM8994_AIF1DAC2R_ENA |
@@ -1109,24 +1109,24 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
 
 	case SND_SOC_DAPM_POST_PMU:
 		for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
-			snd_soc_write(codec, wm8994_vu_bits[i].reg,
-				      snd_soc_read(codec,
+			snd_soc_component_write(component, wm8994_vu_bits[i].reg,
+				      snd_soc_component_read32(component,
 						   wm8994_vu_bits[i].reg));
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_5,
 				    mask, 0);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4,
 				    mask, 0);
 
-		val = snd_soc_read(codec, WM8994_CLOCKING_1);
+		val = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 		if (val & WM8994_AIF2DSPCLK_ENA)
 			val = WM8994_SYSDSPCLK_ENA;
 		else
 			val = 0;
-		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+		snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
 				    WM8994_SYSDSPCLK_ENA |
 				    WM8994_AIF1DSPCLK_ENA, val);
 		break;
@@ -1138,7 +1138,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
 static int aif2clk_ev(struct snd_soc_dapm_widget *w,
 		      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	int i;
 	int dac;
 	int adc;
@@ -1146,7 +1146,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		val = snd_soc_read(codec, WM8994_AIF2_CONTROL_1);
+		val = snd_soc_component_read32(component, WM8994_AIF2_CONTROL_1);
 		if ((val & WM8994_AIF2ADCL_SRC) &&
 		    (val & WM8994_AIF2ADCR_SRC))
 			adc = WM8994_AIF2ADCR_ENA;
@@ -1157,7 +1157,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
 			adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA;
 
 
-		val = snd_soc_read(codec, WM8994_AIF2_CONTROL_2);
+		val = snd_soc_component_read32(component, WM8994_AIF2_CONTROL_2);
 		if ((val & WM8994_AIF2DACL_SRC) &&
 		    (val & WM8994_AIF2DACR_SRC))
 			dac = WM8994_AIF2DACR_ENA;
@@ -1167,23 +1167,23 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
 		else
 			dac = WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA;
 
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4,
 				    WM8994_AIF2ADCL_ENA |
 				    WM8994_AIF2ADCR_ENA, adc);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_5,
 				    WM8994_AIF2DACL_ENA |
 				    WM8994_AIF2DACR_ENA, dac);
-		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+		snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
 				    WM8994_AIF2DSPCLK_ENA |
 				    WM8994_SYSDSPCLK_ENA,
 				    WM8994_AIF2DSPCLK_ENA |
 				    WM8994_SYSDSPCLK_ENA);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4,
 				    WM8994_AIF2ADCL_ENA |
 				    WM8994_AIF2ADCR_ENA,
 				    WM8994_AIF2ADCL_ENA |
 				    WM8994_AIF2ADCR_ENA);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_5,
 				    WM8994_AIF2DACL_ENA |
 				    WM8994_AIF2DACR_ENA,
 				    WM8994_AIF2DACL_ENA |
@@ -1192,26 +1192,26 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
 
 	case SND_SOC_DAPM_POST_PMU:
 		for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
-			snd_soc_write(codec, wm8994_vu_bits[i].reg,
-				      snd_soc_read(codec,
+			snd_soc_component_write(component, wm8994_vu_bits[i].reg,
+				      snd_soc_component_read32(component,
 						   wm8994_vu_bits[i].reg));
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_5,
 				    WM8994_AIF2DACL_ENA |
 				    WM8994_AIF2DACR_ENA, 0);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+		snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4,
 				    WM8994_AIF2ADCL_ENA |
 				    WM8994_AIF2ADCR_ENA, 0);
 
-		val = snd_soc_read(codec, WM8994_CLOCKING_1);
+		val = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 		if (val & WM8994_AIF1DSPCLK_ENA)
 			val = WM8994_SYSDSPCLK_ENA;
 		else
 			val = 0;
-		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+		snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
 				    WM8994_SYSDSPCLK_ENA |
 				    WM8994_AIF2DSPCLK_ENA, val);
 		break;
@@ -1223,8 +1223,8 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
 static int aif1clk_late_ev(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -1241,8 +1241,8 @@ static int aif1clk_late_ev(struct snd_soc_dapm_widget *w,
 static int aif2clk_late_ev(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -1259,14 +1259,14 @@ static int aif2clk_late_ev(struct snd_soc_dapm_widget *w,
 static int late_enable_ev(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		if (wm8994->aif1clk_enable) {
 			aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU);
-			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
+			snd_soc_component_update_bits(component, WM8994_AIF1_CLOCKING_1,
 					    WM8994_AIF1CLK_ENA_MASK,
 					    WM8994_AIF1CLK_ENA);
 			aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU);
@@ -1274,7 +1274,7 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
 		}
 		if (wm8994->aif2clk_enable) {
 			aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU);
-			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
+			snd_soc_component_update_bits(component, WM8994_AIF2_CLOCKING_1,
 					    WM8994_AIF2CLK_ENA_MASK,
 					    WM8994_AIF2CLK_ENA);
 			aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU);
@@ -1292,21 +1292,21 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
 static int late_disable_ev(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMD:
 		if (wm8994->aif1clk_disable) {
 			aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD);
-			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
+			snd_soc_component_update_bits(component, WM8994_AIF1_CLOCKING_1,
 					    WM8994_AIF1CLK_ENA_MASK, 0);
 			aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD);
 			wm8994->aif1clk_disable = 0;
 		}
 		if (wm8994->aif2clk_disable) {
 			aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD);
-			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
+			snd_soc_component_update_bits(component, WM8994_AIF2_CLOCKING_1,
 					    WM8994_AIF2CLK_ENA_MASK, 0);
 			aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD);
 			wm8994->aif2clk_disable = 0;
@@ -1334,10 +1334,10 @@ static int micbias_ev(struct snd_soc_dapm_widget *w,
 static int dac_ev(struct snd_soc_dapm_widget *w,
 		  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int mask = 1 << w->shift;
 
-	snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+	snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_5,
 			    mask, mask);
 	return 0;
 }
@@ -1375,9 +1375,9 @@ SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
 static int post_ev(struct snd_soc_dapm_widget *w,
 	    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	dev_dbg(codec->dev, "SRC status: %x\n",
-		snd_soc_read(codec,
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	dev_dbg(component->dev, "SRC status: %x\n",
+		snd_soc_component_read32(component,
 			     WM8994_RATE_STATUS));
 	return 0;
 }
@@ -1443,12 +1443,12 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
 static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
 	int ret;
 
 	ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
 
-	wm_hubs_update_class_w(codec);
+	wm_hubs_update_class_w(component);
 
 	return ret;
 }
@@ -2130,10 +2130,10 @@ static int wm8994_get_fll_config(struct wm8994 *control, struct fll_div *fll,
 	return 0;
 }
 
-static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
+static int _wm8994_set_fll(struct snd_soc_component *component, int id, int src,
 			  unsigned int freq_in, unsigned int freq_out)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int reg_offset, ret;
 	struct fll_div fll;
@@ -2156,7 +2156,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 		return -EINVAL;
 	}
 
-	reg = snd_soc_read(codec, WM8994_FLL1_CONTROL_1 + reg_offset);
+	reg = snd_soc_component_read32(component, WM8994_FLL1_CONTROL_1 + reg_offset);
 	was_enabled = reg & WM8994_FLL1_ENA;
 
 	switch (src) {
@@ -2197,57 +2197,57 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 		return ret;
 
 	/* Make sure that we're not providing SYSCLK right now */
-	clk1 = snd_soc_read(codec, WM8994_CLOCKING_1);
+	clk1 = snd_soc_component_read32(component, WM8994_CLOCKING_1);
 	if (clk1 & WM8994_SYSCLK_SRC)
 		aif_reg = WM8994_AIF2_CLOCKING_1;
 	else
 		aif_reg = WM8994_AIF1_CLOCKING_1;
-	reg = snd_soc_read(codec, aif_reg);
+	reg = snd_soc_component_read32(component, aif_reg);
 
 	if ((reg & WM8994_AIF1CLK_ENA) &&
 	    (reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) {
-		dev_err(codec->dev, "FLL%d is currently providing SYSCLK\n",
+		dev_err(component->dev, "FLL%d is currently providing SYSCLK\n",
 			id + 1);
 		return -EBUSY;
 	}
 
 	/* We always need to disable the FLL while reconfiguring */
-	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
+	snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_1 + reg_offset,
 			    WM8994_FLL1_ENA, 0);
 
 	if (wm8994->fll_byp && src == WM8994_FLL_SRC_BCLK &&
 	    freq_in == freq_out && freq_out) {
-		dev_dbg(codec->dev, "Bypassing FLL%d\n", id + 1);
-		snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
+		dev_dbg(component->dev, "Bypassing FLL%d\n", id + 1);
+		snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_5 + reg_offset,
 				    WM8958_FLL1_BYP, WM8958_FLL1_BYP);
 		goto out;
 	}
 
 	reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
 		(fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
-	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
+	snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_2 + reg_offset,
 			    WM8994_FLL1_OUTDIV_MASK |
 			    WM8994_FLL1_FRATIO_MASK, reg);
 
-	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_3 + reg_offset,
+	snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_3 + reg_offset,
 			    WM8994_FLL1_K_MASK, fll.k);
 
-	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
+	snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_4 + reg_offset,
 			    WM8994_FLL1_N_MASK,
 			    fll.n << WM8994_FLL1_N_SHIFT);
 
 	if (fll.lambda) {
-		snd_soc_update_bits(codec, WM8958_FLL1_EFS_1 + reg_offset,
+		snd_soc_component_update_bits(component, WM8958_FLL1_EFS_1 + reg_offset,
 				    WM8958_FLL1_LAMBDA_MASK,
 				    fll.lambda);
-		snd_soc_update_bits(codec, WM8958_FLL1_EFS_2 + reg_offset,
+		snd_soc_component_update_bits(component, WM8958_FLL1_EFS_2 + reg_offset,
 				    WM8958_FLL1_EFS_ENA, WM8958_FLL1_EFS_ENA);
 	} else {
-		snd_soc_update_bits(codec, WM8958_FLL1_EFS_2 + reg_offset,
+		snd_soc_component_update_bits(component, WM8958_FLL1_EFS_2 + reg_offset,
 				    WM8958_FLL1_EFS_ENA, 0);
 	}
 
-	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
+	snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_5 + reg_offset,
 			    WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP |
 			    WM8994_FLL1_REFCLK_DIV_MASK |
 			    WM8994_FLL1_REFCLK_SRC_MASK,
@@ -2263,15 +2263,15 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 	if (freq_out) {
 		/* Enable VMID if we need it */
 		if (!was_enabled) {
-			active_reference(codec);
+			active_reference(component);
 
 			switch (control->type) {
 			case WM8994:
-				vmid_reference(codec);
+				vmid_reference(component);
 				break;
 			case WM8958:
 				if (control->revision < 1)
-					vmid_reference(codec);
+					vmid_reference(component);
 				break;
 			default:
 				break;
@@ -2285,7 +2285,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 		if (src == WM8994_FLL_SRC_INTERNAL)
 			reg |= WM8994_FLL1_OSC_ENA;
 
-		snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
+		snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_1 + reg_offset,
 				    WM8994_FLL1_ENA | WM8994_FLL1_OSC_ENA |
 				    WM8994_FLL1_FRAC, reg);
 
@@ -2293,7 +2293,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 			timeout = wait_for_completion_timeout(&wm8994->fll_locked[id],
 							      msecs_to_jiffies(10));
 			if (timeout == 0)
-				dev_warn(codec->dev,
+				dev_warn(component->dev,
 					 "Timed out waiting for FLL lock\n");
 		} else {
 			msleep(5);
@@ -2302,17 +2302,17 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 		if (was_enabled) {
 			switch (control->type) {
 			case WM8994:
-				vmid_dereference(codec);
+				vmid_dereference(component);
 				break;
 			case WM8958:
 				if (control->revision < 1)
-					vmid_dereference(codec);
+					vmid_dereference(component);
 				break;
 			default:
 				break;
 			}
 
-			active_dereference(codec);
+			active_dereference(component);
 		}
 	}
 
@@ -2321,29 +2321,29 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 	wm8994->fll[id].out = freq_out;
 	wm8994->fll[id].src = src;
 
-	configure_clock(codec);
+	configure_clock(component);
 
 	/*
 	 * 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");
+		dev_dbg(component->dev, "Configuring AIFs for 128fs\n");
 
-		wm8994->aifdiv[0] = snd_soc_read(codec, WM8994_AIF1_RATE)
+		wm8994->aifdiv[0] = snd_soc_component_read32(component, WM8994_AIF1_RATE)
 			& WM8994_AIF1CLK_RATE_MASK;
-		wm8994->aifdiv[1] = snd_soc_read(codec, WM8994_AIF2_RATE)
+		wm8994->aifdiv[1] = snd_soc_component_read32(component, WM8994_AIF2_RATE)
 			& WM8994_AIF1CLK_RATE_MASK;
 
-		snd_soc_update_bits(codec, WM8994_AIF1_RATE,
+		snd_soc_component_update_bits(component, WM8994_AIF1_RATE,
 				    WM8994_AIF1CLK_RATE_MASK, 0x1);
-		snd_soc_update_bits(codec, WM8994_AIF2_RATE,
+		snd_soc_component_update_bits(component, WM8994_AIF2_RATE,
 				    WM8994_AIF2CLK_RATE_MASK, 0x1);
 	} else if (wm8994->aifdiv[0]) {
-		snd_soc_update_bits(codec, WM8994_AIF1_RATE,
+		snd_soc_component_update_bits(component, WM8994_AIF1_RATE,
 				    WM8994_AIF1CLK_RATE_MASK,
 				    wm8994->aifdiv[0]);
-		snd_soc_update_bits(codec, WM8994_AIF2_RATE,
+		snd_soc_component_update_bits(component, WM8994_AIF2_RATE,
 				    WM8994_AIF2CLK_RATE_MASK,
 				    wm8994->aifdiv[1]);
 
@@ -2368,14 +2368,14 @@ static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
 static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
 			  unsigned int freq_in, unsigned int freq_out)
 {
-	return _wm8994_set_fll(dai->codec, id, src, freq_in, freq_out);
+	return _wm8994_set_fll(dai->component, id, src, freq_in, freq_out);
 }
 
 static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	int i;
 
 	switch (dai->id) {
@@ -2424,12 +2424,12 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
 					break;
 			if (i == ARRAY_SIZE(opclk_divs))
 				return -EINVAL;
-			snd_soc_update_bits(codec, WM8994_CLOCKING_2,
+			snd_soc_component_update_bits(component, WM8994_CLOCKING_2,
 					    WM8994_OPCLK_DIV_MASK, i);
-			snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
+			snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_2,
 					    WM8994_OPCLK_ENA, WM8994_OPCLK_ENA);
 		} else {
-			snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
+			snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_2,
 					    WM8994_OPCLK_ENA, 0);
 		}
 
@@ -2437,29 +2437,29 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
 		return -EINVAL;
 	}
 
-	configure_clock(codec);
+	configure_clock(component);
 
 	/*
 	 * 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");
+		dev_dbg(component->dev, "Configuring AIFs for 128fs\n");
 
-		wm8994->aifdiv[0] = snd_soc_read(codec, WM8994_AIF1_RATE)
+		wm8994->aifdiv[0] = snd_soc_component_read32(component, WM8994_AIF1_RATE)
 			& WM8994_AIF1CLK_RATE_MASK;
-		wm8994->aifdiv[1] = snd_soc_read(codec, WM8994_AIF2_RATE)
+		wm8994->aifdiv[1] = snd_soc_component_read32(component, WM8994_AIF2_RATE)
 			& WM8994_AIF1CLK_RATE_MASK;
 
-		snd_soc_update_bits(codec, WM8994_AIF1_RATE,
+		snd_soc_component_update_bits(component, WM8994_AIF1_RATE,
 				    WM8994_AIF1CLK_RATE_MASK, 0x1);
-		snd_soc_update_bits(codec, WM8994_AIF2_RATE,
+		snd_soc_component_update_bits(component, WM8994_AIF2_RATE,
 				    WM8994_AIF2CLK_RATE_MASK, 0x1);
 	} else if (wm8994->aifdiv[0]) {
-		snd_soc_update_bits(codec, WM8994_AIF1_RATE,
+		snd_soc_component_update_bits(component, WM8994_AIF1_RATE,
 				    WM8994_AIF1CLK_RATE_MASK,
 				    wm8994->aifdiv[0]);
-		snd_soc_update_bits(codec, WM8994_AIF2_RATE,
+		snd_soc_component_update_bits(component, WM8994_AIF2_RATE,
 				    WM8994_AIF2CLK_RATE_MASK,
 				    wm8994->aifdiv[1]);
 
@@ -2470,13 +2470,13 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
 	return 0;
 }
 
-static int wm8994_set_bias_level(struct snd_soc_codec *codec,
+static int wm8994_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 
-	wm_hubs_set_bias_level(codec, level);
+	wm_hubs_set_bias_level(component, level);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -2487,26 +2487,26 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
 		switch (control->type) {
 		case WM8958:
 		case WM1811:
-			snd_soc_update_bits(codec, WM8958_MICBIAS1,
+			snd_soc_component_update_bits(component, WM8958_MICBIAS1,
 					    WM8958_MICB1_MODE, 0);
-			snd_soc_update_bits(codec, WM8958_MICBIAS2,
+			snd_soc_component_update_bits(component, WM8958_MICBIAS2,
 					    WM8958_MICB2_MODE, 0);
 			break;
 		default:
 			break;
 		}
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY)
-			active_reference(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY)
+			active_reference(component);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			switch (control->type) {
 			case WM8958:
 				if (control->revision == 0) {
 					/* Optimise performance for rev A */
-					snd_soc_update_bits(codec,
+					snd_soc_component_update_bits(component,
 							    WM8958_CHARGE_PUMP_2,
 							    WM8958_CP_DISCH,
 							    WM8958_CP_DISCH);
@@ -2518,24 +2518,24 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
 			}
 
 			/* Discharge LINEOUT1 & 2 */
-			snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+			snd_soc_component_update_bits(component, WM8994_ANTIPOP_1,
 					    WM8994_LINEOUT1_DISCH |
 					    WM8994_LINEOUT2_DISCH,
 					    WM8994_LINEOUT1_DISCH |
 					    WM8994_LINEOUT2_DISCH);
 		}
 
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE)
-			active_dereference(codec);
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE)
+			active_dereference(component);
 
 		/* MICBIAS into bypass mode on newer devices */
 		switch (control->type) {
 		case WM8958:
 		case WM1811:
-			snd_soc_update_bits(codec, WM8958_MICBIAS1,
+			snd_soc_component_update_bits(component, WM8958_MICBIAS1,
 					    WM8958_MICB1_MODE,
 					    WM8958_MICB1_MODE);
-			snd_soc_update_bits(codec, WM8958_MICBIAS2,
+			snd_soc_component_update_bits(component, WM8958_MICBIAS2,
 					    WM8958_MICB2_MODE,
 					    WM8958_MICB2_MODE);
 			break;
@@ -2545,7 +2545,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY)
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY)
 			wm8994->cur_fw = NULL;
 		break;
 	}
@@ -2553,10 +2553,10 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode)
+int wm8994_vmid_mode(struct snd_soc_component *component, enum wm8994_vmid_mode mode)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	switch (mode) {
 	case WM8994_VMID_NORMAL:
@@ -2613,8 +2613,8 @@ int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode)
 
 static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int ms_reg;
 	int aif1_reg;
@@ -2717,7 +2717,7 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	case WM1811:
 	case WM8958:
 		if (dai->id == 2)
-			snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
+			snd_soc_component_update_bits(component, WM8958_AIF3_CONTROL_1,
 					    WM8994_AIF1_LRCLK_INV |
 					    WM8958_AIF3_FMT_MASK, aif1);
 		break;
@@ -2726,15 +2726,15 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		break;
 	}
 
-	snd_soc_update_bits(codec, aif1_reg,
+	snd_soc_component_update_bits(component, aif1_reg,
 			    WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
 			    WM8994_AIF1_FMT_MASK,
 			    aif1);
-	snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
+	snd_soc_component_update_bits(component, ms_reg, WM8994_AIF1_MSTR,
 			    ms);
-	snd_soc_update_bits(codec, dac_reg,
+	snd_soc_component_update_bits(component, dac_reg,
 			    WM8958_AIF1_LRCLK_INV, lrclk);
-	snd_soc_update_bits(codec, adc_reg,
+	snd_soc_component_update_bits(component, adc_reg,
 			    WM8958_AIF1_LRCLK_INV, lrclk);
 
 	return 0;
@@ -2769,8 +2769,8 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int aif1_reg;
@@ -2798,7 +2798,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 			lrclk_reg = WM8994_AIF1DAC_LRCLK;
 		} else {
 			lrclk_reg = WM8994_AIF1ADC_LRCLK;
-			dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
+			dev_dbg(component->dev, "AIF1 using split LRCLK\n");
 		}
 		break;
 	case 2:
@@ -2811,7 +2811,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 			lrclk_reg = WM8994_AIF2DAC_LRCLK;
 		} else {
 			lrclk_reg = WM8994_AIF2ADC_LRCLK;
-			dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
+			dev_dbg(component->dev, "AIF2 using split LRCLK\n");
 		}
 		break;
 	default:
@@ -2870,7 +2870,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 		dai->id, wm8994->aifclk[id], bclk_rate);
 
 	if (wm8994->channels[id] == 1 &&
-	    (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18)
+	    (snd_soc_component_read32(component, aif1_reg) & 0x18) == 0x18)
 		aif2 |= WM8994_AIF1_MONO;
 
 	if (wm8994->aifclk[id] == 0) {
@@ -2920,24 +2920,24 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 	dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
 		lrclk, bclk_rate / lrclk);
 
-	snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
-	snd_soc_update_bits(codec, aif2_reg, WM8994_AIF1_MONO, aif2);
-	snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
-	snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
+	snd_soc_component_update_bits(component, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
+	snd_soc_component_update_bits(component, aif2_reg, WM8994_AIF1_MONO, aif2);
+	snd_soc_component_update_bits(component, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
+	snd_soc_component_update_bits(component, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
 			    lrclk);
-	snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK |
+	snd_soc_component_update_bits(component, rate_reg, WM8994_AIF1_SR_MASK |
 			    WM8994_AIF1CLK_RATE_MASK, rate_val);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		switch (dai->id) {
 		case 1:
 			wm8994->dac_rates[0] = params_rate(params);
-			wm8994_set_retune_mobile(codec, 0);
-			wm8994_set_retune_mobile(codec, 1);
+			wm8994_set_retune_mobile(component, 0);
+			wm8994_set_retune_mobile(component, 1);
 			break;
 		case 2:
 			wm8994->dac_rates[1] = params_rate(params);
-			wm8994_set_retune_mobile(codec, 2);
+			wm8994_set_retune_mobile(component, 2);
 			break;
 		}
 	}
@@ -2949,8 +2949,8 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int aif1_reg;
 	int aif1 = 0;
@@ -2986,12 +2986,12 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
+	return snd_soc_component_update_bits(component, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
 }
 
 static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int mute_reg;
 	int reg;
 
@@ -3011,14 +3011,14 @@ static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
 	else
 		reg = 0;
 
-	snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
+	snd_soc_component_update_bits(component, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
 
 	return 0;
 }
 
 static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int reg, val, mask;
 
 	switch (codec_dai->id) {
@@ -3039,19 +3039,19 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
 	else
 		val = 0;
 
-	return snd_soc_update_bits(codec, reg, mask, val);
+	return snd_soc_component_update_bits(component, reg, mask, val);
 }
 
 static int wm8994_aif2_probe(struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	/* Disable the pulls on the AIF if we're using it to save power. */
-	snd_soc_update_bits(codec, WM8994_GPIO_3,
+	snd_soc_component_update_bits(component, WM8994_GPIO_3,
 			    WM8994_GPN_PU | WM8994_GPN_PD, 0);
-	snd_soc_update_bits(codec, WM8994_GPIO_4,
+	snd_soc_component_update_bits(component, WM8994_GPIO_4,
 			    WM8994_GPN_PU | WM8994_GPN_PD, 0);
-	snd_soc_update_bits(codec, WM8994_GPIO_5,
+	snd_soc_component_update_bits(component, WM8994_GPIO_5,
 			    WM8994_GPN_PU | WM8994_GPN_PD, 0);
 
 	return 0;
@@ -3152,53 +3152,53 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 };
 
 #ifdef CONFIG_PM
-static int wm8994_codec_suspend(struct snd_soc_codec *codec)
+static int wm8994_component_suspend(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	int i, ret;
 
 	for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
 		memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
 		       sizeof(struct wm8994_fll_config));
-		ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0);
+		ret = _wm8994_set_fll(component, i + 1, 0, 0, 0);
 		if (ret < 0)
-			dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
+			dev_warn(component->dev, "Failed to stop FLL%d: %d\n",
 				 i + 1, ret);
 	}
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
 	return 0;
 }
 
-static int wm8994_codec_resume(struct snd_soc_codec *codec)
+static int wm8994_component_resume(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	int i, ret;
 
 	for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
 		if (!wm8994->fll_suspend[i].out)
 			continue;
 
-		ret = _wm8994_set_fll(codec, i + 1,
+		ret = _wm8994_set_fll(component, i + 1,
 				     wm8994->fll_suspend[i].src,
 				     wm8994->fll_suspend[i].in,
 				     wm8994->fll_suspend[i].out);
 		if (ret < 0)
-			dev_warn(codec->dev, "Failed to restore FLL%d: %d\n",
+			dev_warn(component->dev, "Failed to restore FLL%d: %d\n",
 				 i + 1, ret);
 	}
 
 	return 0;
 }
 #else
-#define wm8994_codec_suspend NULL
-#define wm8994_codec_resume NULL
+#define wm8994_component_suspend NULL
+#define wm8994_component_resume NULL
 #endif
 
 static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
 {
-	struct snd_soc_codec *codec = wm8994->hubs.codec;
+	struct snd_soc_component *component = wm8994->hubs.component;
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	struct snd_kcontrol_new controls[] = {
@@ -3251,22 +3251,22 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
 		wm8994->retune_mobile_texts = t;
 	}
 
-	dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
+	dev_dbg(component->dev, "Allocated %d unique ReTune Mobile names\n",
 		wm8994->num_retune_mobile_texts);
 
 	wm8994->retune_mobile_enum.items = wm8994->num_retune_mobile_texts;
 	wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
 
-	ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
+	ret = snd_soc_add_component_controls(wm8994->hubs.component, controls,
 				   ARRAY_SIZE(controls));
 	if (ret != 0)
-		dev_err(wm8994->hubs.codec->dev,
+		dev_err(wm8994->hubs.component->dev,
 			"Failed to add ReTune Mobile controls: %d\n", ret);
 }
 
 static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 {
-	struct snd_soc_codec *codec = wm8994->hubs.codec;
+	struct snd_soc_component *component = wm8994->hubs.component;
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int ret, i;
@@ -3274,7 +3274,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 	if (!pdata)
 		return;
 
-	wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff,
+	wm_hubs_handle_analogue_pdata(component, pdata->lineout1_diff,
 				      pdata->lineout2_diff,
 				      pdata->lineout1fb,
 				      pdata->lineout2fb,
@@ -3285,7 +3285,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 				      pdata->micbias1_lvl,
 				      pdata->micbias2_lvl);
 
-	dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
+	dev_dbg(component->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
 
 	if (pdata->num_drc_cfgs) {
 		struct snd_kcontrol_new controls[] = {
@@ -3298,7 +3298,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 		};
 
 		/* We need an array of texts for the enum API */
-		wm8994->drc_texts = devm_kzalloc(wm8994->hubs.codec->dev,
+		wm8994->drc_texts = devm_kzalloc(wm8994->hubs.component->dev,
 			    sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL);
 		if (!wm8994->drc_texts)
 			return;
@@ -3309,33 +3309,33 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 		wm8994->drc_enum.items = pdata->num_drc_cfgs;
 		wm8994->drc_enum.texts = wm8994->drc_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
+		ret = snd_soc_add_component_controls(wm8994->hubs.component, controls,
 					   ARRAY_SIZE(controls));
 		for (i = 0; i < WM8994_NUM_DRC; i++)
-			wm8994_set_drc(codec, i);
+			wm8994_set_drc(component, i);
 	} else {
-		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+		ret = snd_soc_add_component_controls(wm8994->hubs.component,
 						 wm8994_drc_controls,
 						 ARRAY_SIZE(wm8994_drc_controls));
 	}
 
 	if (ret != 0)
-		dev_err(wm8994->hubs.codec->dev,
+		dev_err(wm8994->hubs.component->dev,
 			"Failed to add DRC mode controls: %d\n", ret);
 
 
-	dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
+	dev_dbg(component->dev, "%d ReTune Mobile configurations\n",
 		pdata->num_retune_mobile_cfgs);
 
 	if (pdata->num_retune_mobile_cfgs)
 		wm8994_handle_retune_mobile_pdata(wm8994);
 	else
-		snd_soc_add_codec_controls(wm8994->hubs.codec, wm8994_eq_controls,
+		snd_soc_add_component_controls(wm8994->hubs.component, wm8994_eq_controls,
 				     ARRAY_SIZE(wm8994_eq_controls));
 
 	for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
 		if (pdata->micbias[i]) {
-			snd_soc_write(codec, WM8958_MICBIAS1 + i,
+			snd_soc_component_write(component, WM8958_MICBIAS1 + i,
 				pdata->micbias[i] & 0xffff);
 		}
 	}
@@ -3344,7 +3344,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 /**
  * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ
  *
- * @codec:   WM8994 codec
+ * @component:   WM8994 component
  * @jack:    jack to report detection events on
  * @micbias: microphone bias to detect on
  *
@@ -3356,17 +3356,17 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
  * Configuration of detection levels is available via the micbias1_lvl
  * and micbias2_lvl platform data members.
  */
-int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,
 		      int micbias)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994_micdet *micdet;
 	struct wm8994 *control = wm8994->wm8994;
 	int reg, ret;
 
 	if (control->type != WM8994) {
-		dev_warn(codec->dev, "Not a WM8994\n");
+		dev_warn(component->dev, "Not a WM8994\n");
 		return -EINVAL;
 	}
 
@@ -3386,15 +3386,15 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 			ret = snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
 		break;
 	default:
-		dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias);
+		dev_warn(component->dev, "Invalid MICBIAS %d\n", micbias);
 		return -EINVAL;
 	}
 
 	if (ret != 0)
-		dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n",
+		dev_warn(component->dev, "Failed to configure MICBIAS%d: %d\n",
 			 micbias, ret);
 
-	dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n",
+	dev_dbg(component->dev, "Configuring microphone detection on %d %p\n",
 		micbias, jack);
 
 	/* Store the configuration */
@@ -3407,10 +3407,10 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 	else
 		reg = 0;
 
-	snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
+	snd_soc_component_update_bits(component, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
 
 	/* enable MICDET and MICSHRT deboune */
-	snd_soc_update_bits(codec, WM8994_IRQ_DEBOUNCE,
+	snd_soc_component_update_bits(component, WM8994_IRQ_DEBOUNCE,
 			    WM8994_MIC1_DET_DB_MASK | WM8994_MIC1_SHRT_DB_MASK |
 			    WM8994_MIC2_DET_DB_MASK | WM8994_MIC2_SHRT_DB_MASK,
 			    WM8994_MIC1_DET_DB | WM8994_MIC1_SHRT_DB);
@@ -3488,13 +3488,13 @@ static void wm8994_mic_work(struct work_struct *work)
 static irqreturn_t wm8994_mic_irq(int irq, void *data)
 {
 	struct wm8994_priv *priv = data;
-	struct snd_soc_codec *codec = priv->hubs.codec;
+	struct snd_soc_component *component = priv->hubs.component;
 
 #ifndef CONFIG_SND_SOC_WM8994_MODULE
-	trace_snd_soc_jack_irq(dev_name(codec->dev));
+	trace_snd_soc_jack_irq(dev_name(component->dev));
 #endif
 
-	pm_wakeup_event(codec->dev, 300);
+	pm_wakeup_event(component->dev, 300);
 
 	queue_delayed_work(system_power_efficient_wq,
 			   &priv->mic_work, msecs_to_jiffies(250));
@@ -3503,25 +3503,25 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
 }
 
 /* Should be called with accdet_lock held */
-static void wm1811_micd_stop(struct snd_soc_codec *codec)
+static void wm1811_micd_stop(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	if (!wm8994->jackdet)
 		return;
 
-	snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0);
+	snd_soc_component_update_bits(component, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0);
 
-	wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK);
+	wm1811_jackdet_set_mode(component, WM1811_JACKDET_MODE_JACK);
 
 	if (wm8994->wm8994->pdata.jd_ext_cap)
 		snd_soc_dapm_disable_pin(dapm, "MICBIAS2");
 }
 
-static void wm8958_button_det(struct snd_soc_codec *codec, u16 status)
+static void wm8958_button_det(struct snd_soc_component *component, u16 status)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	int report;
 
 	report = 0;
@@ -3556,14 +3556,14 @@ static void wm8958_open_circuit_work(struct work_struct *work)
 
 	mutex_lock(&wm8994->accdet_lock);
 
-	wm1811_micd_stop(wm8994->hubs.codec);
+	wm1811_micd_stop(wm8994->hubs.component);
 
 	dev_dbg(dev, "Reporting open circuit\n");
 
 	wm8994->jack_mic = false;
 	wm8994->mic_detecting = true;
 
-	wm8958_micd_set_rate(wm8994->hubs.codec);
+	wm8958_micd_set_rate(wm8994->hubs.component);
 
 	snd_soc_jack_report(wm8994->micdet[0].jack, 0,
 			    wm8994->btn_mask |
@@ -3574,13 +3574,13 @@ static void wm8958_open_circuit_work(struct work_struct *work)
 
 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);
+	struct snd_soc_component *component = data;
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 
 	/* Either nothing present or just starting detection */
 	if (!(status & WM8958_MICD_STS)) {
 		/* If nothing present then clear our statuses */
-		dev_dbg(codec->dev, "Detected open circuit\n");
+		dev_dbg(component->dev, "Detected open circuit\n");
 
 		queue_delayed_work(system_power_efficient_wq,
 				   &wm8994->open_circuit_work,
@@ -3592,12 +3592,12 @@ static void wm8958_mic_id(void *data, u16 status)
 	 * microphone.
 	 */
 	if (status & 0x600) {
-		dev_dbg(codec->dev, "Detected microphone\n");
+		dev_dbg(component->dev, "Detected microphone\n");
 
 		wm8994->mic_detecting = false;
 		wm8994->jack_mic = true;
 
-		wm8958_micd_set_rate(codec);
+		wm8958_micd_set_rate(component);
 
 		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET,
 				    SND_JACK_HEADSET);
@@ -3605,13 +3605,13 @@ static void wm8958_mic_id(void *data, u16 status)
 
 
 	if (status & 0xfc) {
-		dev_dbg(codec->dev, "Detected headphone\n");
+		dev_dbg(component->dev, "Detected headphone\n");
 		wm8994->mic_detecting = false;
 
-		wm8958_micd_set_rate(codec);
+		wm8958_micd_set_rate(component);
 
 		/* If we have jackdet that will detect removal */
-		wm1811_micd_stop(codec);
+		wm1811_micd_stop(component);
 
 		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
 				    SND_JACK_HEADSET);
@@ -3624,10 +3624,10 @@ 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;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = wm8994->hubs.component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
 	/* If required for an external cap force MICBIAS on */
 	if (control->pdata.jd_ext_cap) {
@@ -3637,7 +3637,7 @@ static void wm1811_mic_work(struct work_struct *work)
 
 	mutex_lock(&wm8994->accdet_lock);
 
-	dev_dbg(codec->dev, "Starting mic detection\n");
+	dev_dbg(component->dev, "Starting mic detection\n");
 
 	/* Use a user-supplied callback if we have one */
 	if (wm8994->micd_cb) {
@@ -3648,54 +3648,54 @@ static void wm1811_mic_work(struct work_struct *work)
 		 * what's actually there.
 		 */
 		wm8994->mic_detecting = true;
-		wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
+		wm1811_jackdet_set_mode(component, WM1811_JACKDET_MODE_MIC);
 
-		snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+		snd_soc_component_update_bits(component, WM8958_MIC_DETECT_1,
 				    WM8958_MICD_ENA, WM8958_MICD_ENA);
 	}
 
 	mutex_unlock(&wm8994->accdet_lock);
 
-	pm_runtime_put(codec->dev);
+	pm_runtime_put(component->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;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = wm8994->hubs.component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int reg, delay;
 	bool present;
 
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
 	cancel_delayed_work_sync(&wm8994->mic_complete_work);
 
 	mutex_lock(&wm8994->accdet_lock);
 
-	reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
+	reg = snd_soc_component_read32(component, WM1811_JACKDET_CTRL);
 	if (reg < 0) {
-		dev_err(codec->dev, "Failed to read jack status: %d\n", reg);
+		dev_err(component->dev, "Failed to read jack status: %d\n", reg);
 		mutex_unlock(&wm8994->accdet_lock);
-		pm_runtime_put(codec->dev);
+		pm_runtime_put(component->dev);
 		return IRQ_NONE;
 	}
 
-	dev_dbg(codec->dev, "JACKDET %x\n", reg);
+	dev_dbg(component->dev, "JACKDET %x\n", reg);
 
 	present = reg & WM1811_JACKDET_LVL;
 
 	if (present) {
-		dev_dbg(codec->dev, "Jack detected\n");
+		dev_dbg(component->dev, "Jack detected\n");
 
-		wm8958_micd_set_rate(codec);
+		wm8958_micd_set_rate(component);
 
-		snd_soc_update_bits(codec, WM8958_MICBIAS2,
+		snd_soc_component_update_bits(component, WM8958_MICBIAS2,
 				    WM8958_MICB2_DISCH, 0);
 
 		/* Disable debounce while inserted */
-		snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
+		snd_soc_component_update_bits(component, WM1811_JACKDET_CTRL,
 				    WM1811_JACKDET_DB, 0);
 
 		delay = control->pdata.micdet_delay;
@@ -3703,22 +3703,22 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
 				   &wm8994->mic_work,
 				   msecs_to_jiffies(delay));
 	} else {
-		dev_dbg(codec->dev, "Jack not detected\n");
+		dev_dbg(component->dev, "Jack not detected\n");
 
 		cancel_delayed_work_sync(&wm8994->mic_work);
 
-		snd_soc_update_bits(codec, WM8958_MICBIAS2,
+		snd_soc_component_update_bits(component, WM8958_MICBIAS2,
 				    WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
 
 		/* Enable debounce while removed */
-		snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
+		snd_soc_component_update_bits(component, WM1811_JACKDET_CTRL,
 				    WM1811_JACKDET_DB, WM1811_JACKDET_DB);
 
 		wm8994->mic_detecting = false;
 		wm8994->jack_mic = false;
-		snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+		snd_soc_component_update_bits(component, WM8958_MIC_DETECT_1,
 				    WM8958_MICD_ENA, 0);
-		wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK);
+		wm1811_jackdet_set_mode(component, WM1811_JACKDET_MODE_JACK);
 	}
 
 	mutex_unlock(&wm8994->accdet_lock);
@@ -3739,7 +3739,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
 	 * avoid bootstrapping issues with the core. */
 	snd_soc_jack_report(wm8994->micdet[0].jack, 0, 0);
 
-	pm_runtime_put(codec->dev);
+	pm_runtime_put(component->dev);
 	return IRQ_HANDLED;
 }
 
@@ -3754,7 +3754,7 @@ static void wm1811_jackdet_bootstrap(struct work_struct *work)
 /**
  * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
  *
- * @codec:   WM8958 codec
+ * @component:   WM8958 component
  * @jack:    jack to report detection events on
  *
  * Enable microphone detection functionality for the WM8958.  By
@@ -3767,12 +3767,12 @@ static void wm1811_jackdet_bootstrap(struct work_struct *work)
  * flexiblity a callback is provided which allows a completely custom
  * detection algorithm.
  */
-int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,
 		      wm1811_micdet_cb det_cb, void *det_cb_data,
 		      wm1811_mic_id_cb id_cb, void *id_cb_data)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	u16 micd_lvl_sel;
 
@@ -3803,10 +3803,10 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 			wm8994->mic_id_cb_data = id_cb_data;
 		} else {
 			wm8994->mic_id_cb = wm8958_mic_id;
-			wm8994->mic_id_cb_data = codec;
+			wm8994->mic_id_cb_data = component;
 		}
 
-		wm8958_micd_set_rate(codec);
+		wm8958_micd_set_rate(component);
 
 		/* Detect microphones and short circuits by default */
 		if (control->pdata.micd_lvl_sel)
@@ -3818,10 +3818,10 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 			SND_JACK_BTN_2 | SND_JACK_BTN_3 |
 			SND_JACK_BTN_4 | SND_JACK_BTN_5;
 
-		snd_soc_update_bits(codec, WM8958_MIC_DETECT_2,
+		snd_soc_component_update_bits(component, WM8958_MIC_DETECT_2,
 				    WM8958_MICD_LVL_SEL_MASK, micd_lvl_sel);
 
-		WARN_ON(snd_soc_codec_get_bias_level(codec) > SND_SOC_BIAS_STANDBY);
+		WARN_ON(snd_soc_component_get_bias_level(component) > SND_SOC_BIAS_STANDBY);
 
 		/*
 		 * If we can use jack detection start off with that,
@@ -3829,25 +3829,25 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 		 */
 		if (wm8994->jackdet) {
 			/* Disable debounce for the initial detect */
-			snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
+			snd_soc_component_update_bits(component, WM1811_JACKDET_CTRL,
 					    WM1811_JACKDET_DB, 0);
 
-			snd_soc_update_bits(codec, WM8958_MICBIAS2,
+			snd_soc_component_update_bits(component, WM8958_MICBIAS2,
 					    WM8958_MICB2_DISCH,
 					    WM8958_MICB2_DISCH);
-			snd_soc_update_bits(codec, WM8994_LDO_1,
+			snd_soc_component_update_bits(component, WM8994_LDO_1,
 					    WM8994_LDO1_DISCH, 0);
-			wm1811_jackdet_set_mode(codec,
+			wm1811_jackdet_set_mode(component,
 						WM1811_JACKDET_MODE_JACK);
 		} else {
-			snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+			snd_soc_component_update_bits(component, WM8958_MIC_DETECT_1,
 					    WM8958_MICD_ENA, WM8958_MICD_ENA);
 		}
 
 	} else {
-		snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+		snd_soc_component_update_bits(component, WM8958_MIC_DETECT_1,
 				    WM8958_MICD_ENA, 0);
-		wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_NONE);
+		wm1811_jackdet_set_mode(component, WM1811_JACKDET_MODE_NONE);
 		snd_soc_dapm_disable_pin(dapm, "CLK_SYS");
 		snd_soc_dapm_sync(dapm);
 	}
@@ -3861,9 +3861,9 @@ static void wm8958_mic_work(struct work_struct *work)
 	struct wm8994_priv *wm8994 = container_of(work,
 						  struct wm8994_priv,
 						  mic_complete_work.work);
-	struct snd_soc_codec *codec = wm8994->hubs.codec;
+	struct snd_soc_component *component = wm8994->hubs.component;
 
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
 	mutex_lock(&wm8994->accdet_lock);
 
@@ -3871,13 +3871,13 @@ static void wm8958_mic_work(struct work_struct *work)
 
 	mutex_unlock(&wm8994->accdet_lock);
 
-	pm_runtime_put(codec->dev);
+	pm_runtime_put(component->dev);
 }
 
 static irqreturn_t wm8958_mic_irq(int irq, void *data)
 {
 	struct wm8994_priv *wm8994 = data;
-	struct snd_soc_codec *codec = wm8994->hubs.codec;
+	struct snd_soc_component *component = wm8994->hubs.component;
 	int reg, count, ret, id_delay;
 
 	/*
@@ -3885,30 +3885,30 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
 	 * with an update of the MICDET status; if so it will have
 	 * stopped detection and we can ignore this interrupt.
 	 */
-	if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
+	if (!(snd_soc_component_read32(component, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
 		return IRQ_HANDLED;
 
 	cancel_delayed_work_sync(&wm8994->mic_complete_work);
 	cancel_delayed_work_sync(&wm8994->open_circuit_work);
 
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
 	/* We may occasionally read a detection without an impedence
 	 * range being provided - if that happens loop again.
 	 */
 	count = 10;
 	do {
-		reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
+		reg = snd_soc_component_read32(component, WM8958_MIC_DETECT_3);
 		if (reg < 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to read mic detect status: %d\n",
 				reg);
-			pm_runtime_put(codec->dev);
+			pm_runtime_put(component->dev);
 			return IRQ_NONE;
 		}
 
 		if (!(reg & WM8958_MICD_VALID)) {
-			dev_dbg(codec->dev, "Mic detect data not valid\n");
+			dev_dbg(component->dev, "Mic detect data not valid\n");
 			goto out;
 		}
 
@@ -3919,20 +3919,20 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
 	} while (count--);
 
 	if (count == 0)
-		dev_warn(codec->dev, "No impedance range reported for jack\n");
+		dev_warn(component->dev, "No impedance range reported for jack\n");
 
 #ifndef CONFIG_SND_SOC_WM8994_MODULE
-	trace_snd_soc_jack_irq(dev_name(codec->dev));
+	trace_snd_soc_jack_irq(dev_name(component->dev));
 #endif
 
 	/* Avoid a transient report when the accessory is being removed */
 	if (wm8994->jackdet) {
-		ret = snd_soc_read(codec, WM1811_JACKDET_CTRL);
+		ret = snd_soc_component_read32(component, WM1811_JACKDET_CTRL);
 		if (ret < 0) {
-			dev_err(codec->dev, "Failed to read jack status: %d\n",
+			dev_err(component->dev, "Failed to read jack status: %d\n",
 				ret);
 		} else if (!(ret & WM1811_JACKDET_LVL)) {
-			dev_dbg(codec->dev, "Ignoring removed jack\n");
+			dev_dbg(component->dev, "Ignoring removed jack\n");
 			goto out;
 		}
 	} else if (!(reg & WM8958_MICD_STS)) {
@@ -3951,51 +3951,51 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
 				   &wm8994->mic_complete_work,
 				   msecs_to_jiffies(id_delay));
 	else
-		wm8958_button_det(codec, reg);
+		wm8958_button_det(component, reg);
 
 out:
-	pm_runtime_put(codec->dev);
+	pm_runtime_put(component->dev);
 	return IRQ_HANDLED;
 }
 
 static irqreturn_t wm8994_fifo_error(int irq, void *data)
 {
-	struct snd_soc_codec *codec = data;
+	struct snd_soc_component *component = data;
 
-	dev_err(codec->dev, "FIFO error\n");
+	dev_err(component->dev, "FIFO error\n");
 
 	return IRQ_HANDLED;
 }
 
 static irqreturn_t wm8994_temp_warn(int irq, void *data)
 {
-	struct snd_soc_codec *codec = data;
+	struct snd_soc_component *component = data;
 
-	dev_err(codec->dev, "Thermal warning\n");
+	dev_err(component->dev, "Thermal warning\n");
 
 	return IRQ_HANDLED;
 }
 
 static irqreturn_t wm8994_temp_shut(int irq, void *data)
 {
-	struct snd_soc_codec *codec = data;
+	struct snd_soc_component *component = data;
 
-	dev_crit(codec->dev, "Thermal shutdown\n");
+	dev_crit(component->dev, "Thermal shutdown\n");
 
 	return IRQ_HANDLED;
 }
 
-static int wm8994_codec_probe(struct snd_soc_codec *codec)
+static int wm8994_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct wm8994 *control = dev_get_drvdata(codec->dev->parent);
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8994 *control = dev_get_drvdata(component->dev->parent);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	unsigned int reg;
 	int ret, i;
 
-	snd_soc_codec_init_regmap(codec, control->regmap);
+	snd_soc_component_init_regmap(component, control->regmap);
 
-	wm8994->hubs.codec = codec;
+	wm8994->hubs.component = component;
 
 	mutex_init(&wm8994->accdet_lock);
 	INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
@@ -4070,7 +4070,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		wm8994->hubs.dcs_codes_l = -9;
 		wm8994->hubs.dcs_codes_r = -7;
 
-		snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1,
+		snd_soc_component_update_bits(component, WM8994_ANALOGUE_HP_1,
 				    WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN);
 		break;
 
@@ -4079,11 +4079,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 	}
 
 	wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR,
-			   wm8994_fifo_error, "FIFO error", codec);
+			   wm8994_fifo_error, "FIFO error", component);
 	wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN,
-			   wm8994_temp_warn, "Thermal warning", codec);
+			   wm8994_temp_warn, "Thermal warning", component);
 	wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT,
-			   wm8994_temp_shut, "Thermal shutdown", codec);
+			   wm8994_temp_shut, "Thermal shutdown", component);
 
 	switch (control->type) {
 	case WM8994:
@@ -4101,7 +4101,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 					wm8994);
 
 		if (ret != 0)
-			dev_warn(codec->dev,
+			dev_warn(component->dev,
 				 "Failed to request Mic1 detect IRQ: %d\n",
 				 ret);
 
@@ -4111,7 +4111,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 					 wm8994_mic_irq, "Mic 1 short",
 					 wm8994);
 		if (ret != 0)
-			dev_warn(codec->dev,
+			dev_warn(component->dev,
 				 "Failed to request Mic1 short IRQ: %d\n",
 				 ret);
 
@@ -4120,7 +4120,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 					 wm8994_mic_irq, "Mic 2 detect",
 					 wm8994);
 		if (ret != 0)
-			dev_warn(codec->dev,
+			dev_warn(component->dev,
 				 "Failed to request Mic2 detect IRQ: %d\n",
 				 ret);
 
@@ -4129,7 +4129,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 					 wm8994_mic_irq, "Mic 2 short",
 					 wm8994);
 		if (ret != 0)
-			dev_warn(codec->dev,
+			dev_warn(component->dev,
 				 "Failed to request Mic2 short IRQ: %d\n",
 				 ret);
 		break;
@@ -4144,7 +4144,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 						   "Mic detect",
 						   wm8994);
 			if (ret != 0)
-				dev_warn(codec->dev,
+				dev_warn(component->dev,
 					 "Failed to request Mic detect IRQ: %d\n",
 					 ret);
 		} else {
@@ -4180,7 +4180,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 	}
 
 	/* Make sure we can read from the GPIOs if they're inputs */
-	pm_runtime_get_sync(codec->dev);
+	pm_runtime_get_sync(component->dev);
 
 	/* Remember if AIFnLRCLK is configured as a GPIO.  This should be
 	 * configured on init - if a system wants to do this dynamically
@@ -4188,7 +4188,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 	 */
 	ret = regmap_read(control->regmap, WM8994_GPIO_1, &reg);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
+		dev_err(component->dev, "Failed to read GPIO1 state: %d\n", ret);
 		goto err_irq;
 	}
 	if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
@@ -4200,7 +4200,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 
 	ret = regmap_read(control->regmap, WM8994_GPIO_6, &reg);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
+		dev_err(component->dev, "Failed to read GPIO6 state: %d\n", ret);
 		goto err_irq;
 	}
 	if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
@@ -4210,22 +4210,22 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		wm8994->lrclk_shared[1] = 0;
 	}
 
-	pm_runtime_put(codec->dev);
+	pm_runtime_put(component->dev);
 
 	/* Latch volume update bits */
 	for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
-		snd_soc_update_bits(codec, wm8994_vu_bits[i].reg,
+		snd_soc_component_update_bits(component, wm8994_vu_bits[i].reg,
 				    wm8994_vu_bits[i].mask,
 				    wm8994_vu_bits[i].mask);
 
 	/* Set the low bit of the 3D stereo depth so TLV matches */
-	snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
+	snd_soc_component_update_bits(component, WM8994_AIF1_DAC1_FILTERS_2,
 			    1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
 			    1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
-	snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2,
+	snd_soc_component_update_bits(component, WM8994_AIF1_DAC2_FILTERS_2,
 			    1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
 			    1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
-	snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2,
+	snd_soc_component_update_bits(component, WM8994_AIF2_DAC_FILTERS_2,
 			    1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
 			    1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
 
@@ -4235,7 +4235,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 	switch (control->type) {
 	case WM8994:
 	case WM8958:
-		snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8994_AIF1_CONTROL_1,
 				    WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM);
 		break;
 	default:
@@ -4246,9 +4246,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 	switch (control->type) {
 	case WM8958:
 	case WM1811:
-		snd_soc_update_bits(codec, WM8958_MICBIAS1,
+		snd_soc_component_update_bits(component, WM8958_MICBIAS1,
 				    WM8958_MICB1_MODE, WM8958_MICB1_MODE);
-		snd_soc_update_bits(codec, WM8958_MICBIAS2,
+		snd_soc_component_update_bits(component, WM8958_MICBIAS2,
 				    WM8958_MICB2_MODE, WM8958_MICB2_MODE);
 		break;
 	default:
@@ -4256,12 +4256,12 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 	}
 
 	wm8994->hubs.check_class_w_digital = wm8994_check_class_w_digital;
-	wm_hubs_update_class_w(codec);
+	wm_hubs_update_class_w(component);
 
 	wm8994_handle_pdata(wm8994);
 
-	wm_hubs_add_analogue_controls(codec);
-	snd_soc_add_codec_controls(codec, wm8994_snd_controls,
+	wm_hubs_add_analogue_controls(component);
+	snd_soc_add_component_controls(component, wm8994_snd_controls,
 			     ARRAY_SIZE(wm8994_snd_controls));
 	snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
 				  ARRAY_SIZE(wm8994_dapm_widgets));
@@ -4287,7 +4287,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		}
 		break;
 	case WM8958:
-		snd_soc_add_codec_controls(codec, wm8958_snd_controls,
+		snd_soc_add_component_controls(component, wm8958_snd_controls,
 				     ARRAY_SIZE(wm8958_snd_controls));
 		snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
 					  ARRAY_SIZE(wm8958_dapm_widgets));
@@ -4309,7 +4309,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		break;
 
 	case WM1811:
-		snd_soc_add_codec_controls(codec, wm8958_snd_controls,
+		snd_soc_add_component_controls(component, wm8958_snd_controls,
 				     ARRAY_SIZE(wm8958_snd_controls));
 		snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
 					  ARRAY_SIZE(wm8958_dapm_widgets));
@@ -4322,7 +4322,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		break;
 	}
 
-	wm_hubs_add_analogue_routes(codec, 0, 0);
+	wm_hubs_add_analogue_routes(component, 0, 0);
 	ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
 				 wm_hubs_dcs_done, "DC servo done",
 				 &wm8994->hubs);
@@ -4360,7 +4360,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 						ARRAY_SIZE(wm8958_intercon));
 		}
 
-		wm8958_dsp2_init(codec);
+		wm8958_dsp2_init(component);
 		break;
 	case WM1811:
 		snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
@@ -4385,16 +4385,16 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 				&wm8994->fll_locked[i]);
 	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
 			&wm8994->hubs);
-	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec);
-	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec);
-	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec);
+	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, component);
+	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, component);
+	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, component);
 
 	return ret;
 }
 
-static int wm8994_codec_remove(struct snd_soc_codec *codec)
+static void wm8994_component_remove(struct snd_soc_component *component)
 {
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
 	struct wm8994 *control = wm8994->wm8994;
 	int i;
 
@@ -4404,9 +4404,9 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
 
 	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
 			&wm8994->hubs);
-	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec);
-	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec);
-	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec);
+	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, component);
+	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, component);
+	wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, component);
 
 	if (wm8994->jackdet)
 		wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994);
@@ -4433,15 +4433,18 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
 	release_firmware(wm8994->mbc_vss);
 	release_firmware(wm8994->enh_eq);
 	kfree(wm8994->retune_mobile_texts);
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
-	.probe =	wm8994_codec_probe,
-	.remove =	wm8994_codec_remove,
-	.suspend =	wm8994_codec_suspend,
-	.resume =	wm8994_codec_resume,
-	.set_bias_level = wm8994_set_bias_level,
+static const struct snd_soc_component_driver soc_component_dev_wm8994 = {
+	.probe			= wm8994_component_probe,
+	.remove			= wm8994_component_remove,
+	.suspend		= wm8994_component_suspend,
+	.resume			= wm8994_component_resume,
+	.set_bias_level		= wm8994_set_bias_level,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8994_probe(struct platform_device *pdev)
@@ -4461,13 +4464,12 @@ static int wm8994_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_idle(&pdev->dev);
 
-	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
+	return devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wm8994,
 			wm8994_dai, ARRAY_SIZE(wm8994_dai));
 }
 
 static int wm8994_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index dd73387..a72efb0 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -43,18 +43,18 @@ enum wm8994_vmid_mode {
 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 wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,
 		      int micbias);
-int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,
 		      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);
+int wm8994_vmid_mode(struct snd_soc_component *component, enum wm8994_vmid_mode mode);
 
 int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
 		  struct snd_kcontrol *kcontrol, int event);
 
-void wm8958_dsp2_init(struct snd_soc_codec *codec);
+void wm8958_dsp2_init(struct snd_soc_component *component);
 
 struct wm8994_micdet {
 	struct snd_soc_jack *jack;
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 19b08a5..60e2278 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -385,7 +385,7 @@ struct wm8995_priv {
 	struct fll_config fll[2], fll_suspend[2];
 	struct regulator_bulk_data supplies[WM8995_NUM_SUPPLIES];
 	struct notifier_block disable_nb[WM8995_NUM_SUPPLIES];
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 };
 
 /*
@@ -485,48 +485,48 @@ static const struct snd_kcontrol_new wm8995_snd_controls[] = {
 		WM8995_AIF2_ADC_RIGHT_VOLUME, 0, 96, 0, digital_tlv)
 };
 
-static void wm8995_update_class_w(struct snd_soc_codec *codec)
+static void wm8995_update_class_w(struct snd_soc_component *component)
 {
 	int enable = 1;
 	int source = 0;  /* GCC flow analysis can't track enable */
 	int reg, reg_r;
 
 	/* We also need the same setting for L/R and only one path */
-	reg = snd_soc_read(codec, WM8995_DAC1_LEFT_MIXER_ROUTING);
+	reg = snd_soc_component_read32(component, WM8995_DAC1_LEFT_MIXER_ROUTING);
 	switch (reg) {
 	case WM8995_AIF2DACL_TO_DAC1L:
-		dev_dbg(codec->dev, "Class W source AIF2DAC\n");
+		dev_dbg(component->dev, "Class W source AIF2DAC\n");
 		source = 2 << WM8995_CP_DYN_SRC_SEL_SHIFT;
 		break;
 	case WM8995_AIF1DAC2L_TO_DAC1L:
-		dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
+		dev_dbg(component->dev, "Class W source AIF1DAC2\n");
 		source = 1 << WM8995_CP_DYN_SRC_SEL_SHIFT;
 		break;
 	case WM8995_AIF1DAC1L_TO_DAC1L:
-		dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
+		dev_dbg(component->dev, "Class W source AIF1DAC1\n");
 		source = 0 << WM8995_CP_DYN_SRC_SEL_SHIFT;
 		break;
 	default:
-		dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
+		dev_dbg(component->dev, "DAC mixer setting: %x\n", reg);
 		enable = 0;
 		break;
 	}
 
-	reg_r = snd_soc_read(codec, WM8995_DAC1_RIGHT_MIXER_ROUTING);
+	reg_r = snd_soc_component_read32(component, WM8995_DAC1_RIGHT_MIXER_ROUTING);
 	if (reg_r != reg) {
-		dev_dbg(codec->dev, "Left and right DAC mixers different\n");
+		dev_dbg(component->dev, "Left and right DAC mixers different\n");
 		enable = 0;
 	}
 
 	if (enable) {
-		dev_dbg(codec->dev, "Class W enabled\n");
-		snd_soc_update_bits(codec, WM8995_CLASS_W_1,
+		dev_dbg(component->dev, "Class W enabled\n");
+		snd_soc_component_update_bits(component, WM8995_CLASS_W_1,
 				    WM8995_CP_DYN_PWR_MASK |
 				    WM8995_CP_DYN_SRC_SEL_MASK,
 				    source | WM8995_CP_DYN_PWR);
 	} else {
-		dev_dbg(codec->dev, "Class W disabled\n");
-		snd_soc_update_bits(codec, WM8995_CLASS_W_1,
+		dev_dbg(component->dev, "Class W disabled\n");
+		snd_soc_component_update_bits(component, WM8995_CLASS_W_1,
 				    WM8995_CP_DYN_PWR_MASK, 0);
 	}
 }
@@ -534,11 +534,11 @@ static void wm8995_update_class_w(struct snd_soc_codec *codec)
 static int check_clk_sys(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
 	unsigned int reg;
 	const char *clk;
 
-	reg = snd_soc_read(codec, WM8995_CLOCKING_1);
+	reg = snd_soc_component_read32(component, WM8995_CLOCKING_1);
 	/* Check what we're currently using for CLK_SYS */
 	if (reg & WM8995_SYSCLK_SRC)
 		clk = "AIF2CLK";
@@ -550,37 +550,37 @@ static int check_clk_sys(struct snd_soc_dapm_widget *source,
 static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
 	int ret;
 
 	ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
-	wm8995_update_class_w(codec);
+	wm8995_update_class_w(component);
 	return ret;
 }
 
 static int hp_supply_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		/* Enable the headphone amp */
-		snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8995_POWER_MANAGEMENT_1,
 				    WM8995_HPOUT1L_ENA_MASK |
 				    WM8995_HPOUT1R_ENA_MASK,
 				    WM8995_HPOUT1L_ENA |
 				    WM8995_HPOUT1R_ENA);
 
 		/* Enable the second stage */
-		snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
+		snd_soc_component_update_bits(component, WM8995_ANALOGUE_HP_1,
 				    WM8995_HPOUT1L_DLY_MASK |
 				    WM8995_HPOUT1R_DLY_MASK,
 				    WM8995_HPOUT1L_DLY |
 				    WM8995_HPOUT1R_DLY);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, WM8995_CHARGE_PUMP_1,
 				    WM8995_CP_ENA_MASK, 0);
 		break;
 	}
@@ -588,41 +588,41 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static void dc_servo_cmd(struct snd_soc_codec *codec,
+static void dc_servo_cmd(struct snd_soc_component *component,
 			 unsigned int reg, unsigned int val, unsigned int mask)
 {
 	int timeout = 10;
 
-	dev_dbg(codec->dev, "%s: reg = %#x, val = %#x, mask = %#x\n",
+	dev_dbg(component->dev, "%s: reg = %#x, val = %#x, mask = %#x\n",
 		__func__, reg, val, mask);
 
-	snd_soc_write(codec, reg, val);
+	snd_soc_component_write(component, reg, val);
 	while (timeout--) {
 		msleep(10);
-		val = snd_soc_read(codec, WM8995_DC_SERVO_READBACK_0);
+		val = snd_soc_component_read32(component, WM8995_DC_SERVO_READBACK_0);
 		if ((val & mask) == mask)
 			return;
 	}
 
-	dev_err(codec->dev, "Timed out waiting for DC Servo\n");
+	dev_err(component->dev, "Timed out waiting for DC Servo\n");
 }
 
 static int hp_event(struct snd_soc_dapm_widget *w,
 		    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1);
+	reg = snd_soc_component_read32(component, WM8995_ANALOGUE_HP_1);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, WM8995_CHARGE_PUMP_1,
 				    WM8995_CP_ENA_MASK, WM8995_CP_ENA);
 
 		msleep(5);
 
-		snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8995_POWER_MANAGEMENT_1,
 				    WM8995_HPOUT1L_ENA_MASK |
 				    WM8995_HPOUT1R_ENA_MASK,
 				    WM8995_HPOUT1L_ENA | WM8995_HPOUT1R_ENA);
@@ -630,12 +630,12 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 		udelay(20);
 
 		reg |= WM8995_HPOUT1L_DLY | WM8995_HPOUT1R_DLY;
-		snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
+		snd_soc_component_write(component, WM8995_ANALOGUE_HP_1, reg);
 
-		snd_soc_write(codec, WM8995_DC_SERVO_1, WM8995_DCS_ENA_CHAN_0 |
+		snd_soc_component_write(component, WM8995_DC_SERVO_1, WM8995_DCS_ENA_CHAN_0 |
 			      WM8995_DCS_ENA_CHAN_1);
 
-		dc_servo_cmd(codec, WM8995_DC_SERVO_2,
+		dc_servo_cmd(component, WM8995_DC_SERVO_2,
 			     WM8995_DCS_TRIG_STARTUP_0 |
 			     WM8995_DCS_TRIG_STARTUP_1,
 			     WM8995_DCS_TRIG_DAC_WR_0 |
@@ -643,23 +643,23 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 
 		reg |= WM8995_HPOUT1R_OUTP | WM8995_HPOUT1R_RMV_SHORT |
 		       WM8995_HPOUT1L_OUTP | WM8995_HPOUT1L_RMV_SHORT;
-		snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
+		snd_soc_component_write(component, WM8995_ANALOGUE_HP_1, reg);
 
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
+		snd_soc_component_update_bits(component, WM8995_ANALOGUE_HP_1,
 				    WM8995_HPOUT1L_OUTP_MASK |
 				    WM8995_HPOUT1R_OUTP_MASK |
 				    WM8995_HPOUT1L_RMV_SHORT_MASK |
 				    WM8995_HPOUT1R_RMV_SHORT_MASK, 0);
 
-		snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
+		snd_soc_component_update_bits(component, WM8995_ANALOGUE_HP_1,
 				    WM8995_HPOUT1L_DLY_MASK |
 				    WM8995_HPOUT1R_DLY_MASK, 0);
 
-		snd_soc_write(codec, WM8995_DC_SERVO_1, 0);
+		snd_soc_component_write(component, WM8995_DC_SERVO_1, 0);
 
-		snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8995_POWER_MANAGEMENT_1,
 				    WM8995_HPOUT1L_ENA_MASK |
 				    WM8995_HPOUT1R_ENA_MASK,
 				    0);
@@ -669,14 +669,14 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
+static int configure_aif_clock(struct snd_soc_component *component, int aif)
 {
 	struct wm8995_priv *wm8995;
 	int rate;
 	int reg1 = 0;
 	int offset;
 
-	wm8995 = snd_soc_codec_get_drvdata(codec);
+	wm8995 = snd_soc_component_get_drvdata(component);
 
 	if (aif)
 		offset = 4;
@@ -707,29 +707,29 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
 		rate /= 2;
 		reg1 |= WM8995_AIF1CLK_DIV;
 
-		dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
+		dev_dbg(component->dev, "Dividing AIF%d clock to %dHz\n",
 			aif + 1, rate);
 	}
 
 	wm8995->aifclk[aif] = rate;
 
-	snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1 + offset,
+	snd_soc_component_update_bits(component, WM8995_AIF1_CLOCKING_1 + offset,
 			    WM8995_AIF1CLK_SRC_MASK | WM8995_AIF1CLK_DIV_MASK,
 			    reg1);
 	return 0;
 }
 
-static int configure_clock(struct snd_soc_codec *codec)
+static int configure_clock(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct wm8995_priv *wm8995;
 	int change, new;
 
-	wm8995 = snd_soc_codec_get_drvdata(codec);
+	wm8995 = snd_soc_component_get_drvdata(component);
 
 	/* Bring up the AIF clocks first */
-	configure_aif_clock(codec, 0);
-	configure_aif_clock(codec, 1);
+	configure_aif_clock(component, 0);
+	configure_aif_clock(component, 1);
 
 	/*
 	 * Then switch CLK_SYS over to the higher of them; a change
@@ -747,7 +747,7 @@ static int configure_clock(struct snd_soc_codec *codec)
 	else
 		new = 0;
 
-	change = snd_soc_update_bits(codec, WM8995_CLOCKING_1,
+	change = snd_soc_component_update_bits(component, WM8995_CLOCKING_1,
 				     WM8995_SYSCLK_SRC_MASK, new);
 	if (!change)
 		return 0;
@@ -760,14 +760,14 @@ static int configure_clock(struct snd_soc_codec *codec)
 static int clk_sys_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		return configure_clock(codec);
+		return configure_clock(component);
 
 	case SND_SOC_DAPM_POST_PMD:
-		configure_clock(codec);
+		configure_clock(component);
 		break;
 	}
 
@@ -1422,7 +1422,7 @@ static bool wm8995_volatile(struct device *dev, unsigned int reg)
 
 static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int mute_reg;
 
 	switch (dai->id) {
@@ -1436,18 +1436,18 @@ static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, mute_reg, WM8995_AIF1DAC1_MUTE_MASK,
+	snd_soc_component_update_bits(component, mute_reg, WM8995_AIF1DAC1_MUTE_MASK,
 			    !!mute << WM8995_AIF1DAC1_MUTE_SHIFT);
 	return 0;
 }
 
 static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	int master;
 	int aif;
 
-	codec = dai->codec;
+	component = dai->component;
 
 	master = 0;
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1519,11 +1519,11 @@ static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, WM8995_AIF1_CONTROL_1,
+	snd_soc_component_update_bits(component, WM8995_AIF1_CONTROL_1,
 			    WM8995_AIF1_BCLK_INV_MASK |
 			    WM8995_AIF1_LRCLK_INV_MASK |
 			    WM8995_AIF1_FMT_MASK, aif);
-	snd_soc_update_bits(codec, WM8995_AIF1_MASTER_SLAVE,
+	snd_soc_component_update_bits(component, WM8995_AIF1_MASTER_SLAVE,
 			    WM8995_AIF1_MSTR_MASK, master);
 	return 0;
 }
@@ -1546,7 +1546,7 @@ static int wm8995_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm8995_priv *wm8995;
 	int aif1_reg;
 	int bclk_reg;
@@ -1557,8 +1557,8 @@ static int wm8995_hw_params(struct snd_pcm_substream *substream,
 	int lrclk, bclk;
 	int i, rate_val, best, best_val, cur_val;
 
-	codec = dai->codec;
-	wm8995 = snd_soc_codec_get_drvdata(codec);
+	component = dai->component;
+	wm8995 = snd_soc_component_get_drvdata(component);
 
 	switch (dai->id) {
 	case 0:
@@ -1570,7 +1570,7 @@ static int wm8995_hw_params(struct snd_pcm_substream *substream,
 			lrclk_reg = WM8995_AIF1DAC_LRCLK;
 		} else {
 			lrclk_reg = WM8995_AIF1ADC_LRCLK;
-			dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
+			dev_dbg(component->dev, "AIF1 using split LRCLK\n");
 		}
 		break;
 	case 1:
@@ -1582,7 +1582,7 @@ static int wm8995_hw_params(struct snd_pcm_substream *substream,
 			lrclk_reg = WM8995_AIF2DAC_LRCLK;
 		} else {
 			lrclk_reg = WM8995_AIF2ADC_LRCLK;
-			dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
+			dev_dbg(component->dev, "AIF2 using split LRCLK\n");
 		}
 		break;
 	default:
@@ -1668,13 +1668,13 @@ static int wm8995_hw_params(struct snd_pcm_substream *substream,
 	dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
 		lrclk, bclk_rate / lrclk);
 
-	snd_soc_update_bits(codec, aif1_reg,
+	snd_soc_component_update_bits(component, aif1_reg,
 			    WM8995_AIF1_WL_MASK, aif1);
-	snd_soc_update_bits(codec, bclk_reg,
+	snd_soc_component_update_bits(component, bclk_reg,
 			    WM8995_AIF1_BCLK_DIV_MASK, bclk);
-	snd_soc_update_bits(codec, lrclk_reg,
+	snd_soc_component_update_bits(component, lrclk_reg,
 			    WM8995_AIF1DAC_RATE_MASK, lrclk);
-	snd_soc_update_bits(codec, rate_reg,
+	snd_soc_component_update_bits(component, rate_reg,
 			    WM8995_AIF1_SR_MASK |
 			    WM8995_AIF1CLK_RATE_MASK, rate_val);
 	return 0;
@@ -1682,7 +1682,7 @@ static int wm8995_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	int reg, val, mask;
 
 	switch (codec_dai->id) {
@@ -1707,7 +1707,7 @@ static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
 	else
 		val = 0;
 
-	return snd_soc_update_bits(codec, reg, mask, val);
+	return snd_soc_component_update_bits(component, reg, mask, val);
 }
 
 /* The size in bits of the FLL divide multiplied by 10
@@ -1797,19 +1797,19 @@ static int wm8995_set_fll(struct snd_soc_dai *dai, int id,
 			  int src, unsigned int freq_in,
 			  unsigned int freq_out)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm8995_priv *wm8995;
 	int reg_offset, ret;
 	struct fll_div fll;
 	u16 reg, aif1, aif2;
 
-	codec = dai->codec;
-	wm8995 = snd_soc_codec_get_drvdata(codec);
+	component = dai->component;
+	wm8995 = snd_soc_component_get_drvdata(component);
 
-	aif1 = snd_soc_read(codec, WM8995_AIF1_CLOCKING_1)
+	aif1 = snd_soc_component_read32(component, WM8995_AIF1_CLOCKING_1)
 	       & WM8995_AIF1CLK_ENA;
 
-	aif2 = snd_soc_read(codec, WM8995_AIF2_CLOCKING_1)
+	aif2 = snd_soc_component_read32(component, WM8995_AIF2_CLOCKING_1)
 	       & WM8995_AIF2CLK_ENA;
 
 	switch (id) {
@@ -1858,35 +1858,35 @@ static int wm8995_set_fll(struct snd_soc_dai *dai, int id,
 		return ret;
 
 	/* Gate the AIF clocks while we reclock */
-	snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
+	snd_soc_component_update_bits(component, WM8995_AIF1_CLOCKING_1,
 			    WM8995_AIF1CLK_ENA_MASK, 0);
-	snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
+	snd_soc_component_update_bits(component, WM8995_AIF2_CLOCKING_1,
 			    WM8995_AIF2CLK_ENA_MASK, 0);
 
 	/* We always need to disable the FLL while reconfiguring */
-	snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
+	snd_soc_component_update_bits(component, WM8995_FLL1_CONTROL_1 + reg_offset,
 			    WM8995_FLL1_ENA_MASK, 0);
 
 	reg = (fll.outdiv << WM8995_FLL1_OUTDIV_SHIFT) |
 	      (fll.fll_fratio << WM8995_FLL1_FRATIO_SHIFT);
-	snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_2 + reg_offset,
+	snd_soc_component_update_bits(component, WM8995_FLL1_CONTROL_2 + reg_offset,
 			    WM8995_FLL1_OUTDIV_MASK |
 			    WM8995_FLL1_FRATIO_MASK, reg);
 
-	snd_soc_write(codec, WM8995_FLL1_CONTROL_3 + reg_offset, fll.k);
+	snd_soc_component_write(component, WM8995_FLL1_CONTROL_3 + reg_offset, fll.k);
 
-	snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_4 + reg_offset,
+	snd_soc_component_update_bits(component, WM8995_FLL1_CONTROL_4 + reg_offset,
 			    WM8995_FLL1_N_MASK,
 			    fll.n << WM8995_FLL1_N_SHIFT);
 
-	snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_5 + reg_offset,
+	snd_soc_component_update_bits(component, WM8995_FLL1_CONTROL_5 + reg_offset,
 			    WM8995_FLL1_REFCLK_DIV_MASK |
 			    WM8995_FLL1_REFCLK_SRC_MASK,
 			    (fll.clk_ref_div << WM8995_FLL1_REFCLK_DIV_SHIFT) |
 			    (src - 1));
 
 	if (freq_out)
-		snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
+		snd_soc_component_update_bits(component, WM8995_FLL1_CONTROL_1 + reg_offset,
 				    WM8995_FLL1_ENA_MASK, WM8995_FLL1_ENA);
 
 	wm8995->fll[id].in = freq_in;
@@ -1894,12 +1894,12 @@ static int wm8995_set_fll(struct snd_soc_dai *dai, int id,
 	wm8995->fll[id].src = src;
 
 	/* Enable any gated AIF clocks */
-	snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
+	snd_soc_component_update_bits(component, WM8995_AIF1_CLOCKING_1,
 			    WM8995_AIF1CLK_ENA_MASK, aif1);
-	snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
+	snd_soc_component_update_bits(component, WM8995_AIF2_CLOCKING_1,
 			    WM8995_AIF2CLK_ENA_MASK, aif2);
 
-	configure_clock(codec);
+	configure_clock(component);
 
 	return 0;
 }
@@ -1907,11 +1907,11 @@ static int wm8995_set_fll(struct snd_soc_dai *dai, int id,
 static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai,
 				 int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct wm8995_priv *wm8995;
 
-	codec = dai->codec;
-	wm8995 = snd_soc_codec_get_drvdata(codec);
+	component = dai->component;
+	wm8995 = snd_soc_component_get_drvdata(component);
 
 	switch (dai->id) {
 	case 0:
@@ -1949,24 +1949,24 @@ static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai,
 		return -EINVAL;
 	}
 
-	configure_clock(codec);
+	configure_clock(component);
 
 	return 0;
 }
 
-static int wm8995_set_bias_level(struct snd_soc_codec *codec,
+static int wm8995_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	struct wm8995_priv *wm8995;
 	int ret;
 
-	wm8995 = snd_soc_codec_get_drvdata(codec);
+	wm8995 = snd_soc_component_get_drvdata(component);
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
 						    wm8995->supplies);
 			if (ret)
@@ -1974,17 +1974,17 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
 
 			ret = regcache_sync(wm8995->regmap);
 			if (ret) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to sync cache: %d\n", ret);
 				return ret;
 			}
 
-			snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8995_POWER_MANAGEMENT_1,
 					    WM8995_BG_ENA_MASK, WM8995_BG_ENA);
 		}
 		break;
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8995_POWER_MANAGEMENT_1,
 				    WM8995_BG_ENA_MASK, 0);
 		regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies),
 				       wm8995->supplies);
@@ -1994,37 +1994,36 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int wm8995_remove(struct snd_soc_codec *codec)
+static void wm8995_remove(struct snd_soc_component *component)
 {
 	struct wm8995_priv *wm8995;
 	int i;
 
-	wm8995 = snd_soc_codec_get_drvdata(codec);
+	wm8995 = snd_soc_component_get_drvdata(component);
 
 	for (i = 0; i < ARRAY_SIZE(wm8995->supplies); ++i)
 		regulator_unregister_notifier(wm8995->supplies[i].consumer,
 					      &wm8995->disable_nb[i]);
 
 	regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
-	return 0;
 }
 
-static int wm8995_probe(struct snd_soc_codec *codec)
+static int wm8995_probe(struct snd_soc_component *component)
 {
 	struct wm8995_priv *wm8995;
 	int i;
 	int ret;
 
-	wm8995 = snd_soc_codec_get_drvdata(codec);
-	wm8995->codec = codec;
+	wm8995 = snd_soc_component_get_drvdata(component);
+	wm8995->component = component;
 
 	for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++)
 		wm8995->supplies[i].supply = wm8995_supply_names[i];
 
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8995->supplies),
+	ret = regulator_bulk_get(component->dev, ARRAY_SIZE(wm8995->supplies),
 				 wm8995->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to request supplies: %d\n", ret);
 		return ret;
 	}
 
@@ -2042,7 +2041,7 @@ static int wm8995_probe(struct snd_soc_codec *codec)
 		ret = regulator_register_notifier(wm8995->supplies[i].consumer,
 						  &wm8995->disable_nb[i]);
 		if (ret) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to register regulator notifier: %d\n",
 				ret);
 		}
@@ -2051,49 +2050,49 @@ static int wm8995_probe(struct snd_soc_codec *codec)
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
 				    wm8995->supplies);
 	if (ret) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 		goto err_reg_get;
 	}
 
-	ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET);
+	ret = snd_soc_component_read32(component, WM8995_SOFTWARE_RESET);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to read device ID: %d\n", ret);
+		dev_err(component->dev, "Failed to read device ID: %d\n", ret);
 		goto err_reg_enable;
 	}
 
 	if (ret != 0x8995) {
-		dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
+		dev_err(component->dev, "Invalid device ID: %#x\n", ret);
 		ret = -EINVAL;
 		goto err_reg_enable;
 	}
 
-	ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0);
+	ret = snd_soc_component_write(component, WM8995_SOFTWARE_RESET, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+		dev_err(component->dev, "Failed to issue reset: %d\n", ret);
 		goto err_reg_enable;
 	}
 
 	/* Latch volume updates (right only; we always do left then right). */
-	snd_soc_update_bits(codec, WM8995_AIF1_DAC1_RIGHT_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_AIF1_DAC1_RIGHT_VOLUME,
 			    WM8995_AIF1DAC1_VU_MASK, WM8995_AIF1DAC1_VU);
-	snd_soc_update_bits(codec, WM8995_AIF1_DAC2_RIGHT_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_AIF1_DAC2_RIGHT_VOLUME,
 			    WM8995_AIF1DAC2_VU_MASK, WM8995_AIF1DAC2_VU);
-	snd_soc_update_bits(codec, WM8995_AIF2_DAC_RIGHT_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_AIF2_DAC_RIGHT_VOLUME,
 			    WM8995_AIF2DAC_VU_MASK, WM8995_AIF2DAC_VU);
-	snd_soc_update_bits(codec, WM8995_AIF1_ADC1_RIGHT_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_AIF1_ADC1_RIGHT_VOLUME,
 			    WM8995_AIF1ADC1_VU_MASK, WM8995_AIF1ADC1_VU);
-	snd_soc_update_bits(codec, WM8995_AIF1_ADC2_RIGHT_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_AIF1_ADC2_RIGHT_VOLUME,
 			    WM8995_AIF1ADC2_VU_MASK, WM8995_AIF1ADC2_VU);
-	snd_soc_update_bits(codec, WM8995_AIF2_ADC_RIGHT_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_AIF2_ADC_RIGHT_VOLUME,
 			    WM8995_AIF2ADC_VU_MASK, WM8995_AIF1ADC2_VU);
-	snd_soc_update_bits(codec, WM8995_DAC1_RIGHT_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_DAC1_RIGHT_VOLUME,
 			    WM8995_DAC1_VU_MASK, WM8995_DAC1_VU);
-	snd_soc_update_bits(codec, WM8995_DAC2_RIGHT_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_DAC2_RIGHT_VOLUME,
 			    WM8995_DAC2_VU_MASK, WM8995_DAC2_VU);
-	snd_soc_update_bits(codec, WM8995_RIGHT_LINE_INPUT_1_VOLUME,
+	snd_soc_component_update_bits(component, WM8995_RIGHT_LINE_INPUT_1_VOLUME,
 			    WM8995_IN1_VU_MASK, WM8995_IN1_VU);
 
-	wm8995_update_class_w(codec);
+	wm8995_update_class_w(component);
 
 	return 0;
 
@@ -2186,20 +2185,19 @@ static struct snd_soc_dai_driver wm8995_dai[] = {
 	}
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
-	.probe = wm8995_probe,
-	.remove = wm8995_remove,
-	.set_bias_level = wm8995_set_bias_level,
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm8995_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8995_snd_controls),
-		.dapm_widgets		= wm8995_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8995_dapm_widgets),
-		.dapm_routes		= wm8995_intercon,
-		.num_dapm_routes	= ARRAY_SIZE(wm8995_intercon),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8995 = {
+	.probe			= wm8995_probe,
+	.remove			= wm8995_remove,
+	.set_bias_level		= wm8995_set_bias_level,
+	.controls		= wm8995_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8995_snd_controls),
+	.dapm_widgets		= wm8995_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8995_dapm_widgets),
+	.dapm_routes		= wm8995_intercon,
+	.num_dapm_routes	= ARRAY_SIZE(wm8995_intercon),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm8995_regmap = {
@@ -2233,24 +2231,17 @@ static int wm8995_spi_probe(struct spi_device *spi)
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&spi->dev,
-				     &soc_codec_dev_wm8995, wm8995_dai,
+	ret = devm_snd_soc_register_component(&spi->dev,
+				     &soc_component_dev_wm8995, wm8995_dai,
 				     ARRAY_SIZE(wm8995_dai));
 	return ret;
 }
 
-static int wm8995_spi_remove(struct spi_device *spi)
-{
-	snd_soc_unregister_codec(&spi->dev);
-	return 0;
-}
-
 static struct spi_driver wm8995_spi_driver = {
 	.driver = {
 		.name = "wm8995",
 	},
 	.probe = wm8995_spi_probe,
-	.remove = wm8995_spi_remove
 };
 #endif
 
@@ -2274,8 +2265,8 @@ static int wm8995_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = snd_soc_register_codec(&i2c->dev,
-				     &soc_codec_dev_wm8995, wm8995_dai,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_wm8995, wm8995_dai,
 				     ARRAY_SIZE(wm8995_dai));
 	if (ret < 0)
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
@@ -2283,12 +2274,6 @@ static int wm8995_i2c_probe(struct i2c_client *i2c,
 	return ret;
 }
 
-static int wm8995_i2c_remove(struct i2c_client *client)
-{
-	snd_soc_unregister_codec(&client->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm8995_i2c_id[] = {
 	{"wm8995", 0},
 	{}
@@ -2301,7 +2286,6 @@ static struct i2c_driver wm8995_i2c_driver = {
 		.name = "wm8995",
 	},
 	.probe = wm8995_i2c_probe,
-	.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 8affa49..d9d2060 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -53,7 +53,7 @@ static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
 struct wm8996_priv {
 	struct device *dev;
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 
 	int ldo1ena;
 
@@ -335,9 +335,9 @@ static SOC_ENUM_SINGLE_DECL(dsp1tx_hpf_cutoff,
 static SOC_ENUM_SINGLE_DECL(dsp2tx_hpf_cutoff,
 			    WM8996_DSP2_TX_FILTERS, 0, hpf_cutoff_text);
 
-static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block)
+static void wm8996_set_retune_mobile(struct snd_soc_component *component, int block)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	struct wm8996_pdata *pdata = &wm8996->pdata;
 	int base, best, best_val, save, i, cfg, iface;
 
@@ -347,7 +347,7 @@ static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block)
 	switch (block) {
 	case 0:
 		base = WM8996_DSP1_RX_EQ_GAINS_1;
-		if (snd_soc_read(codec, WM8996_POWER_MANAGEMENT_8) &
+		if (snd_soc_component_read32(component, WM8996_POWER_MANAGEMENT_8) &
 		    WM8996_DSP1RX_SRC)
 			iface = 1;
 		else
@@ -355,7 +355,7 @@ static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block)
 		break;
 	case 1:
 		base = WM8996_DSP1_RX_EQ_GAINS_2;
-		if (snd_soc_read(codec, WM8996_POWER_MANAGEMENT_8) &
+		if (snd_soc_component_read32(component, WM8996_POWER_MANAGEMENT_8) &
 		    WM8996_DSP2RX_SRC)
 			iface = 1;
 		else
@@ -381,7 +381,7 @@ static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block)
 		}
 	}
 
-	dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
+	dev_dbg(component->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
 		block,
 		pdata->retune_mobile_cfgs[best].name,
 		pdata->retune_mobile_cfgs[best].rate,
@@ -390,14 +390,14 @@ static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block)
 	/* The EQ will be disabled while reconfiguring it, remember the
 	 * current configuration. 
 	 */
-	save = snd_soc_read(codec, base);
+	save = snd_soc_component_read32(component, base);
 	save &= WM8996_DSP1RX_EQ_ENA;
 
 	for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)
-		snd_soc_update_bits(codec, base + i, 0xffff,
+		snd_soc_component_update_bits(component, base + i, 0xffff,
 				    pdata->retune_mobile_cfgs[best].regs[i]);
 
-	snd_soc_update_bits(codec, base, WM8996_DSP1RX_EQ_ENA, save);
+	snd_soc_component_update_bits(component, base, WM8996_DSP1RX_EQ_ENA, save);
 }
 
 /* Icky as hell but saves code duplication */
@@ -413,8 +413,8 @@ static int wm8996_get_retune_mobile_block(const char *name)
 static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	struct wm8996_pdata *pdata = &wm8996->pdata;
 	int block = wm8996_get_retune_mobile_block(kcontrol->id.name);
 	int value = ucontrol->value.enumerated.item[0];
@@ -427,7 +427,7 @@ static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 
 	wm8996->retune_mobile_cfg[block] = value;
 
-	wm8996_set_retune_mobile(codec, block);
+	wm8996_set_retune_mobile(component, block);
 
 	return 0;
 }
@@ -435,8 +435,8 @@ static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int block = wm8996_get_retune_mobile_block(kcontrol->id.name);
 
 	if (block < 0)
@@ -575,40 +575,40 @@ SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
 	       eq_tlv),
 };
 
-static void wm8996_bg_enable(struct snd_soc_codec *codec)
+static void wm8996_bg_enable(struct snd_soc_component *component)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 
 	wm8996->bg_ena++;
 	if (wm8996->bg_ena == 1) {
-		snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8996_POWER_MANAGEMENT_1,
 				    WM8996_BG_ENA, WM8996_BG_ENA);
 		msleep(2);
 	}
 }
 
-static void wm8996_bg_disable(struct snd_soc_codec *codec)
+static void wm8996_bg_disable(struct snd_soc_component *component)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 
 	wm8996->bg_ena--;
 	if (!wm8996->bg_ena)
-		snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8996_POWER_MANAGEMENT_1,
 				    WM8996_BG_ENA, 0);
 }
 
 static int bg_event(struct snd_soc_dapm_widget *w,
 		    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	int ret = 0;
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		wm8996_bg_enable(codec);
+		wm8996_bg_enable(component);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		wm8996_bg_disable(codec);
+		wm8996_bg_disable(component);
 		break;
 	default:
 		WARN(1, "Invalid event %d\n", event);
@@ -635,8 +635,8 @@ static int cp_event(struct snd_soc_dapm_widget *w,
 static int rmv_short_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 
 	/* Record which outputs we enabled */
 	switch (event) {
@@ -654,14 +654,14 @@ static int rmv_short_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
+static void wait_for_dc_servo(struct snd_soc_component *component, u16 mask)
 {
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int ret;
 	unsigned long timeout = 200;
 
-	snd_soc_write(codec, WM8996_DC_SERVO_2, mask);
+	snd_soc_component_write(component, WM8996_DC_SERVO_2, mask);
 
 	/* Use the interrupt if possible */
 	do {
@@ -669,44 +669,43 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
 			timeout = wait_for_completion_timeout(&wm8996->dcs_done,
 							      msecs_to_jiffies(200));
 			if (timeout == 0)
-				dev_err(codec->dev, "DC servo timed out\n");
+				dev_err(component->dev, "DC servo timed out\n");
 
 		} else {
 			msleep(1);
 			timeout--;
 		}
 
-		ret = snd_soc_read(codec, WM8996_DC_SERVO_2);
-		dev_dbg(codec->dev, "DC servo state: %x\n", ret);
+		ret = snd_soc_component_read32(component, WM8996_DC_SERVO_2);
+		dev_dbg(component->dev, "DC servo state: %x\n", ret);
 	} while (timeout && ret & mask);
 
 	if (timeout == 0)
-		dev_err(codec->dev, "DC servo timed out for %x\n", mask);
+		dev_err(component->dev, "DC servo timed out for %x\n", mask);
 	else
-		dev_dbg(codec->dev, "DC servo complete for %x\n", mask);
+		dev_dbg(component->dev, "DC servo complete for %x\n", mask);
 }
 
-static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
+static void wm8996_seq_notifier(struct snd_soc_component *component,
 				enum snd_soc_dapm_type event, int subseq)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	u16 val, mask;
 
 	/* Complete any pending DC servo starts */
 	if (wm8996->dcs_pending) {
-		dev_dbg(codec->dev, "Starting DC servo for %x\n",
+		dev_dbg(component->dev, "Starting DC servo for %x\n",
 			wm8996->dcs_pending);
 
 		/* Trigger a startup sequence */
-		wait_for_dc_servo(codec, wm8996->dcs_pending
+		wait_for_dc_servo(component, wm8996->dcs_pending
 				         << WM8996_DCS_TRIG_STARTUP_0_SHIFT);
 
 		wm8996->dcs_pending = 0;
 	}
 
 	if (wm8996->hpout_pending != wm8996->hpout_ena) {
-		dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n",
+		dev_dbg(component->dev, "Applying RMV_SHORTs %x->%x\n",
 			wm8996->hpout_ena, wm8996->hpout_pending);
 
 		val = 0;
@@ -729,7 +728,7 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
 				WM8996_HPOUT1R_DLY;
 		}
 
-		snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1, mask, val);
+		snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_1, mask, val);
 
 		val = 0;
 		mask = 0;
@@ -751,7 +750,7 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
 				WM8996_HPOUT2R_DLY;
 		}
 
-		snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_2, mask, val);
+		snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_2, mask, val);
 
 		wm8996->hpout_ena = wm8996->hpout_pending;
 	}
@@ -760,8 +759,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
 static int dcs_start(struct snd_soc_dapm_widget *w,
 		     struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
@@ -1533,9 +1532,9 @@ static const int bclk_divs[] = {
 	1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
 };
 
-static void wm8996_update_bclk(struct snd_soc_codec *codec)
+static void wm8996_update_bclk(struct snd_soc_component *component)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int aif, best, cur_val, bclk_rate, bclk_reg, i;
 
 	/* Don't bother if we're in a low frequency idle mode that
@@ -1565,18 +1564,18 @@ static void wm8996_update_bclk(struct snd_soc_codec *codec)
 			best = i;
 		}
 		bclk_rate = wm8996->sysclk / bclk_divs[best];
-		dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
+		dev_dbg(component->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
 			bclk_divs[best], bclk_rate);
 
-		snd_soc_update_bits(codec, bclk_reg,
+		snd_soc_component_update_bits(component, bclk_reg,
 				    WM8996_AIF1_BCLK_DIV_MASK, best);
 	}
 }
 
-static int wm8996_set_bias_level(struct snd_soc_codec *codec,
+static int wm8996_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	switch (level) {
@@ -1584,18 +1583,18 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		/* Put the MICBIASes into regulating mode */
-		snd_soc_update_bits(codec, WM8996_MICBIAS_1,
+		snd_soc_component_update_bits(component, WM8996_MICBIAS_1,
 				    WM8996_MICB1_MODE, 0);
-		snd_soc_update_bits(codec, WM8996_MICBIAS_2,
+		snd_soc_component_update_bits(component, WM8996_MICBIAS_2,
 				    WM8996_MICB2_MODE, 0);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
 						    wm8996->supplies);
 			if (ret != 0) {
-				dev_err(codec->dev,
+				dev_err(component->dev,
 					"Failed to enable supplies: %d\n",
 					ret);
 				return ret;
@@ -1612,9 +1611,9 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
 		}
 
 		/* Bypass the MICBIASes for lowest power */
-		snd_soc_update_bits(codec, WM8996_MICBIAS_1,
+		snd_soc_component_update_bits(component, WM8996_MICBIAS_1,
 				    WM8996_MICB1_MODE, WM8996_MICB1_MODE);
-		snd_soc_update_bits(codec, WM8996_MICBIAS_2,
+		snd_soc_component_update_bits(component, WM8996_MICBIAS_2,
 				    WM8996_MICB2_MODE, WM8996_MICB2_MODE);
 		break;
 
@@ -1634,7 +1633,7 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
 
 static int wm8996_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int aifctrl = 0;
 	int bclk = 0;
 	int lrclk_tx = 0;
@@ -1711,15 +1710,15 @@ static int wm8996_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	snd_soc_update_bits(codec, aifctrl_reg, WM8996_AIF1_FMT_MASK, aifctrl);
-	snd_soc_update_bits(codec, bclk_reg,
+	snd_soc_component_update_bits(component, aifctrl_reg, WM8996_AIF1_FMT_MASK, aifctrl);
+	snd_soc_component_update_bits(component, bclk_reg,
 			    WM8996_AIF1_BCLK_INV | WM8996_AIF1_BCLK_MSTR,
 			    bclk);
-	snd_soc_update_bits(codec, lrclk_tx_reg,
+	snd_soc_component_update_bits(component, lrclk_tx_reg,
 			    WM8996_AIF1TX_LRCLK_INV |
 			    WM8996_AIF1TX_LRCLK_MSTR,
 			    lrclk_tx);
-	snd_soc_update_bits(codec, lrclk_rx_reg,
+	snd_soc_component_update_bits(component, lrclk_rx_reg,
 			    WM8996_AIF1RX_LRCLK_INV |
 			    WM8996_AIF1RX_LRCLK_MSTR,
 			    lrclk_rx);
@@ -1735,8 +1734,8 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int bits, i, bclk_rate, best;
 	int aifdata = 0;
 	int lrclk = 0;
@@ -1746,7 +1745,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
 	switch (dai->id) {
 	case 0:
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
-		    (snd_soc_read(codec, WM8996_GPIO_1)) & WM8996_GP1_FN_MASK) {
+		    (snd_soc_component_read32(component, WM8996_GPIO_1)) & WM8996_GP1_FN_MASK) {
 			aifdata_reg = WM8996_AIF1RX_DATA_CONFIGURATION;
 			lrclk_reg = WM8996_AIF1_RX_LRCLK_1;
 		} else {
@@ -1757,7 +1756,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
 		break;
 	case 1:
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
-		    (snd_soc_read(codec, WM8996_GPIO_2)) & WM8996_GP2_FN_MASK) {
+		    (snd_soc_component_read32(component, WM8996_GPIO_2)) & WM8996_GP2_FN_MASK) {
 			aifdata_reg = WM8996_AIF2RX_DATA_CONFIGURATION;
 			lrclk_reg = WM8996_AIF2_RX_LRCLK_1;
 		} else {
@@ -1773,7 +1772,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
 
 	bclk_rate = snd_soc_params_to_bclk(params);
 	if (bclk_rate < 0) {
-		dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
+		dev_err(component->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
 		return bclk_rate;
 	}
 
@@ -1794,19 +1793,19 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
 	}
 	dsp |= i << dsp_shift;
 
-	wm8996_update_bclk(codec);
+	wm8996_update_bclk(component);
 
 	lrclk = bclk_rate / params_rate(params);
 	dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
 		lrclk, bclk_rate / lrclk);
 
-	snd_soc_update_bits(codec, aifdata_reg,
+	snd_soc_component_update_bits(component, aifdata_reg,
 			    WM8996_AIF1TX_WL_MASK |
 			    WM8996_AIF1TX_SLOT_LEN_MASK,
 			    aifdata);
-	snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK,
+	snd_soc_component_update_bits(component, lrclk_reg, WM8996_AIF1RX_RATE_MASK,
 			    lrclk);
-	snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2,
+	snd_soc_component_update_bits(component, WM8996_AIF_CLOCKING_2,
 			    WM8996_DSP1_DIV_MASK << dsp_shift, dsp);
 
 	return 0;
@@ -1815,8 +1814,8 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
 static int wm8996_set_sysclk(struct snd_soc_dai *dai,
 		int clk_id, unsigned int freq, int dir)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int lfclk = 0;
 	int ratediv = 0;
 	int sync = WM8996_REG_SYNC;
@@ -1827,8 +1826,8 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
 		return 0;
 
 	/* Disable SYSCLK while we reconfigure */
-	old = snd_soc_read(codec, WM8996_AIF_CLOCKING_1) & WM8996_SYSCLK_ENA;
-	snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
+	old = snd_soc_component_read32(component, WM8996_AIF_CLOCKING_1) & WM8996_SYSCLK_ENA;
+	snd_soc_component_update_bits(component, WM8996_AIF_CLOCKING_1,
 			    WM8996_SYSCLK_ENA, 0);
 
 	switch (clk_id) {
@@ -1845,14 +1844,14 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
 		src = 2;
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported clock source %d\n", clk_id);
+		dev_err(component->dev, "Unsupported clock source %d\n", clk_id);
 		return -EINVAL;
 	}
 
 	switch (wm8996->sysclk) {
 	case 5644800:
 	case 6144000:
-		snd_soc_update_bits(codec, WM8996_AIF_RATE,
+		snd_soc_component_update_bits(component, WM8996_AIF_RATE,
 				    WM8996_SYSCLK_RATE, 0);
 		break;
 	case 22579200:
@@ -1861,7 +1860,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
 		wm8996->sysclk /= 2;
 	case 11289600:
 	case 12288000:
-		snd_soc_update_bits(codec, WM8996_AIF_RATE,
+		snd_soc_component_update_bits(component, WM8996_AIF_RATE,
 				    WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE);
 		break;
 	case 32000:
@@ -1870,20 +1869,20 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
 		sync = 0;
 		break;
 	default:
-		dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
+		dev_warn(component->dev, "Unsupported clock rate %dHz\n",
 			 wm8996->sysclk);
 		return -EINVAL;
 	}
 
-	wm8996_update_bclk(codec);
+	wm8996_update_bclk(component);
 
-	snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
+	snd_soc_component_update_bits(component, WM8996_AIF_CLOCKING_1,
 			    WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK,
 			    src << WM8996_SYSCLK_SRC_SHIFT | ratediv);
-	snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk);
-	snd_soc_update_bits(codec, WM8996_CONTROL_INTERFACE_1,
+	snd_soc_component_update_bits(component, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk);
+	snd_soc_component_update_bits(component, WM8996_CONTROL_INTERFACE_1,
 			    WM8996_REG_SYNC, sync);
-	snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
+	snd_soc_component_update_bits(component, WM8996_AIF_CLOCKING_1,
 			    WM8996_SYSCLK_ENA, old);
 
 	wm8996->sysclk_src = clk_id;
@@ -2002,11 +2001,11 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 	return 0;
 }
 
-static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+static int wm8996_set_fll(struct snd_soc_component *component, int fll_id, int source,
 			  unsigned int Fref, unsigned int Fout)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
 	struct _fll_div fll_div;
 	unsigned long timeout, time_left;
 	int ret, reg, retry;
@@ -2017,15 +2016,15 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		return 0;
 
 	if (Fout == 0) {
-		dev_dbg(codec->dev, "FLL disabled\n");
+		dev_dbg(component->dev, "FLL disabled\n");
 
 		wm8996->fll_fref = 0;
 		wm8996->fll_fout = 0;
 
-		snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
+		snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_1,
 				    WM8996_FLL_ENA, 0);
 
-		wm8996_bg_disable(codec);
+		wm8996_bg_disable(component);
 
 		return 0;
 	}
@@ -2048,14 +2047,14 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		reg = 3;
 		break;
 	default:
-		dev_err(codec->dev, "Unknown FLL source %d\n", ret);
+		dev_err(component->dev, "Unknown FLL source %d\n", ret);
 		return -EINVAL;
 	}
 
 	reg |= fll_div.fll_refclk_div << WM8996_FLL_REFCLK_DIV_SHIFT;
 	reg |= fll_div.fll_ref_freq << WM8996_FLL_REF_FREQ_SHIFT;
 
-	snd_soc_update_bits(codec, WM8996_FLL_CONTROL_5,
+	snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_5,
 			    WM8996_FLL_REFCLK_DIV_MASK | WM8996_FLL_REF_FREQ |
 			    WM8996_FLL_REFCLK_SRC_MASK, reg);
 
@@ -2064,38 +2063,38 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		reg |= WM8996_FLL_EFS_ENA | (3 << WM8996_FLL_LFSR_SEL_SHIFT);
 	else
 		reg |= 1 << WM8996_FLL_LFSR_SEL_SHIFT;
-	snd_soc_write(codec, WM8996_FLL_EFS_2, reg);
+	snd_soc_component_write(component, WM8996_FLL_EFS_2, reg);
 
-	snd_soc_update_bits(codec, WM8996_FLL_CONTROL_2,
+	snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_2,
 			    WM8996_FLL_OUTDIV_MASK |
 			    WM8996_FLL_FRATIO_MASK,
 			    (fll_div.fll_outdiv << WM8996_FLL_OUTDIV_SHIFT) |
 			    (fll_div.fll_fratio));
 
-	snd_soc_write(codec, WM8996_FLL_CONTROL_3, fll_div.theta);
+	snd_soc_component_write(component, WM8996_FLL_CONTROL_3, fll_div.theta);
 
-	snd_soc_update_bits(codec, WM8996_FLL_CONTROL_4,
+	snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_4,
 			    WM8996_FLL_N_MASK | WM8996_FLL_LOOP_GAIN_MASK,
 			    (fll_div.n << WM8996_FLL_N_SHIFT) |
 			    fll_div.fll_loop_gain);
 
-	snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
+	snd_soc_component_write(component, WM8996_FLL_EFS_1, fll_div.lambda);
 
 	/* Enable the bandgap if it's not already enabled */
-	ret = snd_soc_read(codec, WM8996_FLL_CONTROL_1);
+	ret = snd_soc_component_read32(component, WM8996_FLL_CONTROL_1);
 	if (!(ret & WM8996_FLL_ENA))
-		wm8996_bg_enable(codec);
+		wm8996_bg_enable(component);
 
 	/* Clear any pending completions (eg, from failed startups) */
 	try_wait_for_completion(&wm8996->fll_lock);
 
-	snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
+	snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_1,
 			    WM8996_FLL_ENA, WM8996_FLL_ENA);
 
 	/* The FLL supports live reconfiguration - kick that in case we were
 	 * already enabled.
 	 */
-	snd_soc_write(codec, WM8996_FLL_CONTROL_6, WM8996_FLL_SWITCH_CLK);
+	snd_soc_component_write(component, WM8996_FLL_CONTROL_6, WM8996_FLL_SWITCH_CLK);
 
 	/* Wait for the FLL to lock, using the interrupt if possible */
 	if (Fref > 1000000)
@@ -2121,16 +2120,16 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 			break;
 		}
 
-		ret = snd_soc_read(codec, WM8996_INTERRUPT_RAW_STATUS_2);
+		ret = snd_soc_component_read32(component, WM8996_INTERRUPT_RAW_STATUS_2);
 		if (ret & WM8996_FLL_LOCK_STS)
 			break;
 	}
 	if (retry == 10) {
-		dev_err(codec->dev, "Timed out waiting for FLL\n");
+		dev_err(component->dev, "Timed out waiting for FLL\n");
 		ret = -ETIMEDOUT;
 	}
 
-	dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
+	dev_dbg(component->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
 
 	wm8996->fll_fref = Fref;
 	wm8996->fll_fout = Fout;
@@ -2237,11 +2236,11 @@ static void wm8996_free_gpio(struct wm8996_priv *wm8996)
  * will also detect inverted microphone ground connections and update
  * the polarity of the connections.
  */
-int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+int wm8996_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,
 		  wm8996_polarity_fn polarity_cb)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	wm8996->jack = jack;
 	wm8996->detecting = true;
@@ -2249,12 +2248,12 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 	wm8996->jack_flips = 0;
 
 	if (wm8996->polarity_cb)
-		wm8996->polarity_cb(codec, 0);
+		wm8996->polarity_cb(component, 0);
 
 	/* Clear discarge to avoid noise during detection */
-	snd_soc_update_bits(codec, WM8996_MICBIAS_1,
+	snd_soc_component_update_bits(component, WM8996_MICBIAS_1,
 			    WM8996_MICB1_DISCH, 0);
-	snd_soc_update_bits(codec, WM8996_MICBIAS_2,
+	snd_soc_component_update_bits(component, WM8996_MICBIAS_2,
 			    WM8996_MICB2_DISCH, 0);
 
 	/* LDO2 powers the microphones, SYSCLK clocks detection */
@@ -2268,26 +2267,26 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 	/* We start off just enabling microphone detection - even a
 	 * plain headphone will trigger detection.
 	 */
-	snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+	snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,
 			    WM8996_MICD_ENA, WM8996_MICD_ENA);
 
 	/* Slowest detection rate, gives debounce for initial detection */
-	snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+	snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,
 			    WM8996_MICD_RATE_MASK,
 			    WM8996_MICD_RATE_MASK);
 
 	/* Enable interrupts and we're off */
-	snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK,
+	snd_soc_component_update_bits(component, WM8996_INTERRUPT_STATUS_2_MASK,
 			    WM8996_IM_MICD_EINT | WM8996_HP_DONE_EINT, 0);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(wm8996_detect);
 
-static void wm8996_hpdet_irq(struct snd_soc_codec *codec)
+static void wm8996_hpdet_irq(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int val, reg, report;
 
 	/* Assume headphone in error conditions; we need to report
@@ -2295,20 +2294,20 @@ static void wm8996_hpdet_irq(struct snd_soc_codec *codec)
 	 */
 	report = SND_JACK_HEADPHONE;
 
-	reg = snd_soc_read(codec, WM8996_HEADPHONE_DETECT_2);
+	reg = snd_soc_component_read32(component, WM8996_HEADPHONE_DETECT_2);
 	if (reg < 0) {
-		dev_err(codec->dev, "Failed to read HPDET status\n");
+		dev_err(component->dev, "Failed to read HPDET status\n");
 		goto out;
 	}
 
 	if (!(reg & WM8996_HP_DONE)) {
-		dev_err(codec->dev, "Got HPDET IRQ but HPDET is busy\n");
+		dev_err(component->dev, "Got HPDET IRQ but HPDET is busy\n");
 		goto out;
 	}
 
 	val = reg & WM8996_HP_LVL_MASK;
 
-	dev_dbg(codec->dev, "HPDET measured %d ohms\n", val);
+	dev_dbg(component->dev, "HPDET measured %d ohms\n", val);
 
 	/* If we've got high enough impedence then report as line,
 	 * otherwise assume headphone.
@@ -2328,28 +2327,28 @@ static void wm8996_hpdet_irq(struct snd_soc_codec *codec)
 	wm8996->detecting = false;
 
 	/* If the output isn't running re-clamp it */
-	if (!(snd_soc_read(codec, WM8996_POWER_MANAGEMENT_1) &
+	if (!(snd_soc_component_read32(component, WM8996_POWER_MANAGEMENT_1) &
 	      (WM8996_HPOUT1L_ENA | WM8996_HPOUT1R_RMV_SHORT)))
-		snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
+		snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_1,
 				    WM8996_HPOUT1L_RMV_SHORT |
 				    WM8996_HPOUT1R_RMV_SHORT, 0);
 
 	/* Go back to looking at the microphone */
-	snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
+	snd_soc_component_update_bits(component, WM8996_ACCESSORY_DETECT_MODE_1,
 			    WM8996_JD_MODE_MASK, 0);
-	snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA,
+	snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1, WM8996_MICD_ENA,
 			    WM8996_MICD_ENA);
 
 	snd_soc_dapm_disable_pin(dapm, "Bandgap");
 	snd_soc_dapm_sync(dapm);
 }
 
-static void wm8996_hpdet_start(struct snd_soc_codec *codec)
+static void wm8996_hpdet_start(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	/* Unclamp the output, we can't measure while we're shorting it */
-	snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
+	snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_1,
 			    WM8996_HPOUT1L_RMV_SHORT |
 			    WM8996_HPOUT1R_RMV_SHORT,
 			    WM8996_HPOUT1L_RMV_SHORT |
@@ -2360,45 +2359,45 @@ static void wm8996_hpdet_start(struct snd_soc_codec *codec)
 	snd_soc_dapm_sync(dapm);
 
 	/* Go into headphone detect left mode */
-	snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0);
-	snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
+	snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0);
+	snd_soc_component_update_bits(component, WM8996_ACCESSORY_DETECT_MODE_1,
 			    WM8996_JD_MODE_MASK, 1);
 
 	/* Trigger a measurement */
-	snd_soc_update_bits(codec, WM8996_HEADPHONE_DETECT_1,
+	snd_soc_component_update_bits(component, WM8996_HEADPHONE_DETECT_1,
 			    WM8996_HP_POLL, WM8996_HP_POLL);
 }
 
-static void wm8996_report_headphone(struct snd_soc_codec *codec)
+static void wm8996_report_headphone(struct snd_soc_component *component)
 {
-	dev_dbg(codec->dev, "Headphone detected\n");
-	wm8996_hpdet_start(codec);
+	dev_dbg(component->dev, "Headphone detected\n");
+	wm8996_hpdet_start(component);
 
 	/* Increase the detection rate a bit for responsiveness. */
-	snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+	snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,
 			    WM8996_MICD_RATE_MASK |
 			    WM8996_MICD_BIAS_STARTTIME_MASK,
 			    7 << WM8996_MICD_RATE_SHIFT |
 			    7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
 }
 
-static void wm8996_micd(struct snd_soc_codec *codec)
+static void wm8996_micd(struct snd_soc_component *component)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int val, reg;
 
-	val = snd_soc_read(codec, WM8996_MIC_DETECT_3);
+	val = snd_soc_component_read32(component, WM8996_MIC_DETECT_3);
 
-	dev_dbg(codec->dev, "Microphone event: %x\n", val);
+	dev_dbg(component->dev, "Microphone event: %x\n", val);
 
 	if (!(val & WM8996_MICD_VALID)) {
-		dev_warn(codec->dev, "Microphone detection state invalid\n");
+		dev_warn(component->dev, "Microphone detection state invalid\n");
 		return;
 	}
 
 	/* No accessory, reset everything and report removal */
 	if (!(val & WM8996_MICD_STS)) {
-		dev_dbg(codec->dev, "Jack removal detected\n");
+		dev_dbg(component->dev, "Jack removal detected\n");
 		wm8996->jack_mic = false;
 		wm8996->detecting = true;
 		wm8996->jack_flips = 0;
@@ -2406,7 +2405,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
 				    SND_JACK_LINEOUT | SND_JACK_HEADSET |
 				    SND_JACK_BTN_0);
 
-		snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+		snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,
 				    WM8996_MICD_RATE_MASK |
 				    WM8996_MICD_BIAS_STARTTIME_MASK,
 				    WM8996_MICD_RATE_MASK |
@@ -2420,19 +2419,19 @@ static void wm8996_micd(struct snd_soc_codec *codec)
 	 */
 	if (val & 0x400) {
 		if (wm8996->detecting) {
-			dev_dbg(codec->dev, "Microphone detected\n");
+			dev_dbg(component->dev, "Microphone detected\n");
 			wm8996->jack_mic = true;
-			wm8996_hpdet_start(codec);
+			wm8996_hpdet_start(component);
 
 			/* Increase poll rate to give better responsiveness
 			 * for buttons */
-			snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+			snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,
 					    WM8996_MICD_RATE_MASK |
 					    WM8996_MICD_BIAS_STARTTIME_MASK,
 					    5 << WM8996_MICD_RATE_SHIFT |
 					    7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
 		} else {
-			dev_dbg(codec->dev, "Mic button up\n");
+			dev_dbg(component->dev, "Mic button up\n");
 			snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0);
 		}
 
@@ -2449,22 +2448,22 @@ static void wm8996_micd(struct snd_soc_codec *codec)
 		wm8996->jack_flips++;
 
 		if (wm8996->jack_flips > 1) {
-			wm8996_report_headphone(codec);
+			wm8996_report_headphone(component);
 			return;
 		}
 
-		reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2);
+		reg = snd_soc_component_read32(component, WM8996_ACCESSORY_DETECT_MODE_2);
 		reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
 			WM8996_MICD_BIAS_SRC;
-		snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
+		snd_soc_component_update_bits(component, WM8996_ACCESSORY_DETECT_MODE_2,
 				    WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
 				    WM8996_MICD_BIAS_SRC, reg);
 
 		if (wm8996->polarity_cb)
-			wm8996->polarity_cb(codec,
+			wm8996->polarity_cb(component,
 					    (reg & WM8996_MICD_SRC) != 0);
 
-		dev_dbg(codec->dev, "Set microphone polarity to %d\n",
+		dev_dbg(component->dev, "Set microphone polarity to %d\n",
 			(reg & WM8996_MICD_SRC) != 0);
 
 		return;
@@ -2475,52 +2474,52 @@ static void wm8996_micd(struct snd_soc_codec *codec)
 	 */
 	if (val & 0x3fc) {
 		if (wm8996->jack_mic) {
-			dev_dbg(codec->dev, "Mic button detected\n");
+			dev_dbg(component->dev, "Mic button detected\n");
 			snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
 					    SND_JACK_BTN_0);
 		} else if (wm8996->detecting) {
-			wm8996_report_headphone(codec);
+			wm8996_report_headphone(component);
 		}
 	}
 }
 
 static irqreturn_t wm8996_irq(int irq, void *data)
 {
-	struct snd_soc_codec *codec = data;
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = data;
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	int irq_val;
 
-	irq_val = snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2);
+	irq_val = snd_soc_component_read32(component, WM8996_INTERRUPT_STATUS_2);
 	if (irq_val < 0) {
-		dev_err(codec->dev, "Failed to read IRQ status: %d\n",
+		dev_err(component->dev, "Failed to read IRQ status: %d\n",
 			irq_val);
 		return IRQ_NONE;
 	}
-	irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK);
+	irq_val &= ~snd_soc_component_read32(component, WM8996_INTERRUPT_STATUS_2_MASK);
 
 	if (!irq_val)
 		return IRQ_NONE;
 
-	snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val);
+	snd_soc_component_write(component, WM8996_INTERRUPT_STATUS_2, irq_val);
 
 	if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {
-		dev_dbg(codec->dev, "DC servo IRQ\n");
+		dev_dbg(component->dev, "DC servo IRQ\n");
 		complete(&wm8996->dcs_done);
 	}
 
 	if (irq_val & WM8996_FIFOS_ERR_EINT)
-		dev_err(codec->dev, "Digital core FIFO error\n");
+		dev_err(component->dev, "Digital core FIFO error\n");
 
 	if (irq_val & WM8996_FLL_LOCK_EINT) {
-		dev_dbg(codec->dev, "FLL locked\n");
+		dev_dbg(component->dev, "FLL locked\n");
 		complete(&wm8996->fll_lock);
 	}
 
 	if (irq_val & WM8996_MICD_EINT)
-		wm8996_micd(codec);
+		wm8996_micd(component);
 
 	if (irq_val & WM8996_HP_DONE_EINT)
-		wm8996_hpdet_irq(codec);
+		wm8996_hpdet_irq(component);
 
 	return IRQ_HANDLED;
 }
@@ -2539,9 +2538,9 @@ static irqreturn_t wm8996_edge_irq(int irq, void *data)
 	return ret;
 }
 
-static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
+static void wm8996_retune_mobile_pdata(struct snd_soc_component *component)
 {
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
 	struct wm8996_pdata *pdata = &wm8996->pdata;
 
 	struct snd_kcontrol_new controls[] = {
@@ -2590,15 +2589,15 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
 		wm8996->retune_mobile_texts = t;
 	}
 
-	dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
+	dev_dbg(component->dev, "Allocated %d unique ReTune Mobile names\n",
 		wm8996->num_retune_mobile_texts);
 
 	wm8996->retune_mobile_enum.items = wm8996->num_retune_mobile_texts;
 	wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts;
 
-	ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
+	ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));
 	if (ret != 0)
-		dev_err(codec->dev,
+		dev_err(component->dev,
 			"Failed to add ReTune Mobile controls: %d\n", ret);
 }
 
@@ -2614,22 +2613,22 @@ static const struct regmap_config wm8996_regmap = {
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int wm8996_probe(struct snd_soc_codec *codec)
+static int wm8996_probe(struct snd_soc_component *component)
 {
 	int ret;
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
+	struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
 	int irq_flags;
 
-	wm8996->codec = codec;
+	wm8996->component = component;
 
 	init_completion(&wm8996->dcs_done);
 	init_completion(&wm8996->fll_lock);
 
 	if (wm8996->pdata.num_retune_mobile_cfgs)
-		wm8996_retune_mobile_pdata(codec);
+		wm8996_retune_mobile_pdata(component);
 	else
-		snd_soc_add_codec_controls(codec, wm8996_eq_controls,
+		snd_soc_add_component_controls(component, wm8996_eq_controls,
 				     ARRAY_SIZE(wm8996_eq_controls));
 
 	if (i2c->irq) {
@@ -2643,18 +2642,18 @@ static int wm8996_probe(struct snd_soc_codec *codec)
 		if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
 			ret = request_threaded_irq(i2c->irq, NULL,
 						   wm8996_edge_irq,
-						   irq_flags, "wm8996", codec);
+						   irq_flags, "wm8996", component);
 		else
 			ret = request_threaded_irq(i2c->irq, NULL, wm8996_irq,
-						   irq_flags, "wm8996", codec);
+						   irq_flags, "wm8996", component);
 
 		if (ret == 0) {
 			/* Unmask the interrupt */
-			snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
+			snd_soc_component_update_bits(component, WM8996_INTERRUPT_CONTROL,
 					    WM8996_IM_IRQ, 0);
 
 			/* Enable error reporting and DC servo status */
-			snd_soc_update_bits(codec,
+			snd_soc_component_update_bits(component,
 					    WM8996_INTERRUPT_STATUS_2_MASK,
 					    WM8996_IM_DCS_DONE_23_EINT |
 					    WM8996_IM_DCS_DONE_01_EINT |
@@ -2662,7 +2661,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
 					    WM8996_IM_FIFOS_ERR_EINT,
 					    0);
 		} else {
-			dev_err(codec->dev, "Failed to request IRQ: %d\n",
+			dev_err(component->dev, "Failed to request IRQ: %d\n",
 				ret);
 			return ret;
 		}
@@ -2671,34 +2670,33 @@ static int wm8996_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int wm8996_remove(struct snd_soc_codec *codec)
+static void wm8996_remove(struct snd_soc_component *component)
 {
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
+	struct i2c_client *i2c = to_i2c_client(component->dev);
 
-	snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
+	snd_soc_component_update_bits(component, WM8996_INTERRUPT_CONTROL,
 			    WM8996_IM_IRQ, WM8996_IM_IRQ);
 
 	if (i2c->irq)
-		free_irq(i2c->irq, codec);
-
-	return 0;
+		free_irq(i2c->irq, component);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
-	.probe =	wm8996_probe,
-	.remove =	wm8996_remove,
-	.set_bias_level = wm8996_set_bias_level,
-	.idle_bias_off	= true,
-	.seq_notifier = wm8996_seq_notifier,
-	.component_driver = {
-		.controls		= wm8996_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8996_snd_controls),
-		.dapm_widgets		= wm8996_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8996_dapm_widgets),
-		.dapm_routes		= wm8996_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8996_dapm_routes),
-	},
-	.set_pll = wm8996_set_fll,
+static const struct snd_soc_component_driver soc_component_dev_wm8996 = {
+	.probe			= wm8996_probe,
+	.remove			= wm8996_remove,
+	.set_bias_level		= wm8996_set_bias_level,
+	.seq_notifier		= wm8996_seq_notifier,
+	.controls		= wm8996_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8996_snd_controls),
+	.dapm_widgets		= wm8996_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8996_dapm_widgets),
+	.dapm_routes		= wm8996_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8996_dapm_routes),
+	.set_pll		= wm8996_set_fll,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+
 };
 
 #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
@@ -3046,8 +3044,8 @@ static int wm8996_i2c_probe(struct i2c_client *i2c,
 
 	wm8996_init_gpio(wm8996);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-				     &soc_codec_dev_wm8996, wm8996_dai,
+	ret = devm_snd_soc_register_component(&i2c->dev,
+				     &soc_component_dev_wm8996, wm8996_dai,
 				     ARRAY_SIZE(wm8996_dai));
 	if (ret < 0)
 		goto err_gpiolib;
@@ -3074,7 +3072,6 @@ static int wm8996_i2c_remove(struct i2c_client *client)
 	struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
 	int i;
 
-	snd_soc_unregister_codec(&client->dev);
 	wm8996_free_gpio(wm8996);
 	if (wm8996->pdata.ldo_ena > 0) {
 		gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
diff --git a/sound/soc/codecs/wm8996.h b/sound/soc/codecs/wm8996.h
index de9ac3e..b387699 100644
--- a/sound/soc/codecs/wm8996.h
+++ b/sound/soc/codecs/wm8996.h
@@ -22,9 +22,9 @@
 #define WM8996_FLL_DACLRCLK1  3
 #define WM8996_FLL_BCLK1      4
 
-typedef void (*wm8996_polarity_fn)(struct snd_soc_codec *codec, int polarity);
+typedef void (*wm8996_polarity_fn)(struct snd_soc_component *component, int polarity);
 
-int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+int wm8996_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,
 		  wm8996_polarity_fn polarity_cb);
 
 /*
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index cac9b3e..df5b36b 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -84,8 +84,8 @@ static const struct reg_default wm8997_sysclk_reva_patch[] = {
 static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
 			    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 	struct regmap *regmap = arizona->regmap;
 	const struct reg_default *patch = NULL;
 	int i, patch_size;
@@ -118,7 +118,7 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
 	return arizona_dvfs_sysclk_ev(w, kcontrol, event);
 }
 
-static const char *wm8997_osr_text[] = {
+static const char * const wm8997_osr_text[] = {
 	"Low power", "Normal", "High performance",
 };
 
@@ -609,8 +609,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
 		    ARIZONA_SLIMRX8_ENA_SHIFT, 0),
 
 SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-		       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-		       &wm8997_aec_loopback_mux),
+		 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm8997_aec_loopback_mux),
 
 SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
 		   ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
@@ -927,10 +926,10 @@ static const struct snd_soc_dapm_route wm8997_dapm_routes[] = {
 	{ "MICSUPP", NULL, "SYSCLK" },
 };
 
-static int wm8997_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-			  unsigned int Fref, unsigned int Fout)
+static int wm8997_set_fll(struct snd_soc_component *component, int fll_id,
+			  int source, unsigned int Fref, unsigned int Fout)
 {
-	struct wm8997_priv *wm8997 = snd_soc_codec_get_drvdata(codec);
+	struct wm8997_priv *wm8997 = snd_soc_component_get_drvdata(component);
 
 	switch (fll_id) {
 	case WM8997_FLL1:
@@ -1057,17 +1056,16 @@ static struct snd_soc_dai_driver wm8997_dai[] = {
 	},
 };
 
-static int wm8997_codec_probe(struct snd_soc_codec *codec)
+static int wm8997_component_probe(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-	struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8997_priv *priv = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = priv->core.arizona;
 	int ret;
 
-	snd_soc_codec_init_regmap(codec, arizona->regmap);
+	snd_soc_component_init_regmap(component, arizona->regmap);
 
-	ret = arizona_init_spk(codec);
+	ret = arizona_init_spk(component);
 	if (ret < 0)
 		return ret;
 
@@ -1078,13 +1076,11 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int wm8997_codec_remove(struct snd_soc_codec *codec)
+static void wm8997_component_remove(struct snd_soc_component *component)
 {
-	struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct wm8997_priv *priv = snd_soc_component_get_drvdata(component);
 
 	priv->core.arizona->dapm = NULL;
-
-	return 0;
 }
 
 #define WM8997_DIG_VU 0x0200
@@ -1098,23 +1094,20 @@ static unsigned int wm8997_digital_vu[] = {
 	ARIZONA_DAC_DIGITAL_VOLUME_5R,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8997 = {
-	.probe = wm8997_codec_probe,
-	.remove = wm8997_codec_remove,
-
-	.idle_bias_off = true,
-
-	.set_sysclk = arizona_set_sysclk,
-	.set_pll = wm8997_set_fll,
-
-	.component_driver = {
-		.controls		= wm8997_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8997_snd_controls),
-		.dapm_widgets		= wm8997_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8997_dapm_widgets),
-		.dapm_routes		= wm8997_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8997_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8997 = {
+	.probe			= wm8997_component_probe,
+	.remove			= wm8997_component_remove,
+	.set_sysclk		= arizona_set_sysclk,
+	.set_pll		= wm8997_set_fll,
+	.controls		= wm8997_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8997_snd_controls),
+	.dapm_widgets		= wm8997_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8997_dapm_widgets),
+	.dapm_routes		= wm8997_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8997_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8997_probe(struct platform_device *pdev)
@@ -1178,10 +1171,12 @@ static int wm8997_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
-	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8997,
-				     wm8997_dai, ARRAY_SIZE(wm8997_dai));
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &soc_component_dev_wm8997,
+					      wm8997_dai,
+					      ARRAY_SIZE(wm8997_dai));
 	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
 		goto err_spk_irqs;
 	}
 
@@ -1196,7 +1191,6 @@ static int wm8997_remove(struct platform_device *pdev)
 	struct wm8997_priv *wm8997 = platform_get_drvdata(pdev);
 	struct arizona *arizona = wm8997->core.arizona;
 
-	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 	arizona_free_spk_irqs(arizona);
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 1288e1f..61294c7 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -41,12 +41,12 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol,
 			  int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 	unsigned int val;
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		val = snd_soc_read(codec, ARIZONA_ASRC_RATE1);
+		val = snd_soc_component_read32(component, ARIZONA_ASRC_RATE1);
 		val &= ARIZONA_ASRC_RATE1_MASK;
 		val >>= ARIZONA_ASRC_RATE1_SHIFT;
 
@@ -54,23 +54,23 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
 		case 0:
 		case 1:
 		case 2:
-			val = snd_soc_read(codec,
+			val = snd_soc_component_read32(component,
 					   ARIZONA_SAMPLE_RATE_1 + val);
 			if (val >= 0x11) {
-				dev_warn(codec->dev,
+				dev_warn(component->dev,
 					 "Unsupported ASRC rate1 (%s)\n",
 					 arizona_sample_rate_val_to_name(val));
 			return -EINVAL;
 			}
 			break;
 		default:
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Illegal ASRC rate1 selector (0x%x)\n",
 				val);
 			return -EINVAL;
 		}
 
-		val = snd_soc_read(codec, ARIZONA_ASRC_RATE2);
+		val = snd_soc_component_read32(component, ARIZONA_ASRC_RATE2);
 		val &= ARIZONA_ASRC_RATE2_MASK;
 		val >>= ARIZONA_ASRC_RATE2_SHIFT;
 
@@ -78,17 +78,17 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
 		case 8:
 		case 9:
 			val -= 0x8;
-			val = snd_soc_read(codec,
+			val = snd_soc_component_read32(component,
 					   ARIZONA_ASYNC_SAMPLE_RATE_1 + val);
 			if (val >= 0x11) {
-				dev_warn(codec->dev,
+				dev_warn(component->dev,
 					 "Unsupported ASRC rate2 (%s)\n",
 					 arizona_sample_rate_val_to_name(val));
 				return -EINVAL;
 			}
 			break;
 		default:
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Illegal ASRC rate2 selector (0x%x)\n",
 				val);
 			return -EINVAL;
@@ -104,9 +104,9 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
 static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
 			    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8998_priv *wm8998 = snd_soc_component_get_drvdata(component);
 	struct arizona *arizona = wm8998->core.arizona;
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int mode_reg, mode_index;
@@ -137,11 +137,13 @@ static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
 	if (inmode & ARIZONA_INMODE_SE)
 		src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
 
-	snd_soc_update_bits(codec, mode_reg, ARIZONA_IN1_MODE_MASK, mode_val);
+	snd_soc_component_update_bits(component, mode_reg,
+				      ARIZONA_IN1_MODE_MASK, mode_val);
 
-	snd_soc_update_bits(codec, e->reg,
-			    ARIZONA_IN1L_SRC_MASK | ARIZONA_IN1L_SRC_SE_MASK,
-			    src_val);
+	snd_soc_component_update_bits(component, e->reg,
+				      ARIZONA_IN1L_SRC_MASK |
+				      ARIZONA_IN1L_SRC_SE_MASK,
+				      src_val);
 
 	return snd_soc_dapm_mux_update_power(dapm, kcontrol,
 					     ucontrol->value.enumerated.item[0],
@@ -322,7 +324,7 @@ SOC_DOUBLE_R("HPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
 SOC_DOUBLE_R("LINEOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
 	     ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
 SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
-	     ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
+	   ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
 	     ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("SPKDAT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
@@ -335,7 +337,7 @@ SOC_DOUBLE_R_TLV("LINEOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
 		 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
 		 0xbf, 0, digital_tlv),
 SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
-		 ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
+	       ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
 SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
 		 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
 		 0xbf, 0, digital_tlv),
@@ -615,12 +617,12 @@ SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
 		 ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("AEC1 Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-		       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-		       &wm8998_aec_loopback_mux[0]),
+		 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
+		 &wm8998_aec_loopback_mux[0]),
 
 SND_SOC_DAPM_MUX("AEC2 Loopback", ARIZONA_DAC_AEC_CONTROL_2,
-		       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-		       &wm8998_aec_loopback_mux[1]),
+		 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
+		 &wm8998_aec_loopback_mux[1]),
 
 SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
 		     ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
@@ -739,9 +741,9 @@ SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
 
 SND_SOC_DAPM_PGA("SPD1TX1", ARIZONA_SPD1_TX_CONTROL,
-		   ARIZONA_SPD1_VAL1_SHIFT, 0, NULL, 0),
+		 ARIZONA_SPD1_VAL1_SHIFT, 0, NULL, 0),
 SND_SOC_DAPM_PGA("SPD1TX2", ARIZONA_SPD1_TX_CONTROL,
-		   ARIZONA_SPD1_VAL2_SHIFT, 0, NULL, 0),
+		 ARIZONA_SPD1_VAL2_SHIFT, 0, NULL, 0),
 SND_SOC_DAPM_OUT_DRV("SPD1", ARIZONA_SPD1_TX_CONTROL,
 		     ARIZONA_SPD1_ENA_SHIFT, 0, NULL, 0),
 
@@ -1249,10 +1251,10 @@ static struct snd_soc_dai_driver wm8998_dai[] = {
 	},
 };
 
-static int wm8998_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-			  unsigned int Fref, unsigned int Fout)
+static int wm8998_set_fll(struct snd_soc_component *component, int fll_id,
+			  int source, unsigned int Fref, unsigned int Fout)
 {
-	struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
+	struct wm8998_priv *wm8998 = snd_soc_component_get_drvdata(component);
 
 	switch (fll_id) {
 	case WM8998_FLL1:
@@ -1270,35 +1272,32 @@ static int wm8998_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	}
 }
 
-static int wm8998_codec_probe(struct snd_soc_codec *codec)
+static int wm8998_component_probe(struct snd_soc_component *component)
 {
-	struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+	struct wm8998_priv *priv = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct arizona *arizona = priv->core.arizona;
 	int ret;
 
 	arizona->dapm = dapm;
-	snd_soc_codec_init_regmap(codec, arizona->regmap);
+	snd_soc_component_init_regmap(component, arizona->regmap);
 
-	ret = arizona_init_spk(codec);
+	ret = arizona_init_spk(component);
 	if (ret < 0)
 		return ret;
 
-	arizona_init_gpio(codec);
+	arizona_init_gpio(component);
 
 	snd_soc_component_disable_pin(component, "HAPTICS");
 
 	return 0;
 }
 
-static int wm8998_codec_remove(struct snd_soc_codec *codec)
+static void wm8998_component_remove(struct snd_soc_component *component)
 {
-	struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct wm8998_priv *priv = snd_soc_component_get_drvdata(component);
 
 	priv->core.arizona->dapm = NULL;
-
-	return 0;
 }
 
 #define WM8998_DIG_VU 0x0200
@@ -1315,23 +1314,20 @@ static unsigned int wm8998_digital_vu[] = {
 	ARIZONA_DAC_DIGITAL_VOLUME_5R,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
-	.probe = wm8998_codec_probe,
-	.remove = wm8998_codec_remove,
-
-	.idle_bias_off = true,
-
-	.set_sysclk = arizona_set_sysclk,
-	.set_pll = wm8998_set_fll,
-
-	.component_driver = {
-		.controls		= wm8998_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm8998_snd_controls),
-		.dapm_widgets		= wm8998_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm8998_dapm_widgets),
-		.dapm_routes		= wm8998_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(wm8998_dapm_routes),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm8998 = {
+	.probe			= wm8998_component_probe,
+	.remove			= wm8998_component_remove,
+	.set_sysclk		= arizona_set_sysclk,
+	.set_pll		= wm8998_set_fll,
+	.controls		= wm8998_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm8998_snd_controls),
+	.dapm_widgets		= wm8998_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm8998_dapm_widgets),
+	.dapm_routes		= wm8998_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(wm8998_dapm_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm8998_probe(struct platform_device *pdev)
@@ -1384,10 +1380,12 @@ static int wm8998_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
-	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8998,
-				     wm8998_dai, ARRAY_SIZE(wm8998_dai));
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &soc_component_dev_wm8998,
+					      wm8998_dai,
+					      ARRAY_SIZE(wm8998_dai));
 	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
+		dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
 		goto err_spk_irqs;
 	}
 
@@ -1404,7 +1402,6 @@ static int wm8998_remove(struct platform_device *pdev)
 	struct wm8998_priv *wm8998 = platform_get_drvdata(pdev);
 	struct arizona *arizona = wm8998->core.arizona;
 
-	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 	arizona_free_spk_irqs(arizona);
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 6febef3..5a0ea7b 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -339,10 +339,10 @@ static SOC_ENUM_SINGLE_DECL(speaker_mode, WM9081_ANALOGUE_SPEAKER_2, 6,
 static int speaker_mode_get(struct snd_kcontrol *kcontrol,
 			    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2);
+	reg = snd_soc_component_read32(component, WM9081_ANALOGUE_SPEAKER_2);
 	if (reg & WM9081_SPK_MODE)
 		ucontrol->value.enumerated.item[0] = 1;
 	else
@@ -360,9 +360,9 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol,
 static int speaker_mode_put(struct snd_kcontrol *kcontrol,
 			    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	unsigned int reg_pwr = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
-	unsigned int reg2 = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	unsigned int reg_pwr = snd_soc_component_read32(component, WM9081_POWER_MANAGEMENT);
+	unsigned int reg2 = snd_soc_component_read32(component, WM9081_ANALOGUE_SPEAKER_2);
 
 	/* Are we changing anything? */
 	if (ucontrol->value.enumerated.item[0] ==
@@ -383,7 +383,7 @@ static int speaker_mode_put(struct snd_kcontrol *kcontrol,
 		reg2 &= ~WM9081_SPK_MODE;
 	}
 
-	snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_2, reg2);
+	snd_soc_component_write(component, WM9081_ANALOGUE_SPEAKER_2, reg2);
 
 	return 0;
 }
@@ -546,10 +546,10 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 	return 0;
 }
 
-static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
+static int wm9081_set_fll(struct snd_soc_component *component, int fll_id,
 			  unsigned int Fref, unsigned int Fout)
 {
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
 	u16 reg1, reg4, reg5;
 	struct _fll_div fll_div;
 	int ret;
@@ -561,7 +561,7 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
 
 	/* Disable the FLL */
 	if (Fout == 0) {
-		dev_dbg(codec->dev, "FLL disabled\n");
+		dev_dbg(component->dev, "FLL disabled\n");
 		wm9081->fll_fref = 0;
 		wm9081->fll_fout = 0;
 
@@ -572,7 +572,7 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
 	if (ret != 0)
 		return ret;
 
-	reg5 = snd_soc_read(codec, WM9081_FLL_CONTROL_5);
+	reg5 = snd_soc_component_read32(component, WM9081_FLL_CONTROL_5);
 	reg5 &= ~WM9081_FLL_CLK_SRC_MASK;
 
 	switch (fll_id) {
@@ -581,55 +581,55 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
 		break;
 
 	default:
-		dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
+		dev_err(component->dev, "Unknown FLL ID %d\n", fll_id);
 		return -EINVAL;
 	}
 
 	/* Disable CLK_SYS while we reconfigure */
-	clk_sys_reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
+	clk_sys_reg = snd_soc_component_read32(component, WM9081_CLOCK_CONTROL_3);
 	if (clk_sys_reg & WM9081_CLK_SYS_ENA)
-		snd_soc_write(codec, WM9081_CLOCK_CONTROL_3,
+		snd_soc_component_write(component, WM9081_CLOCK_CONTROL_3,
 			     clk_sys_reg & ~WM9081_CLK_SYS_ENA);
 
 	/* Any FLL configuration change requires that the FLL be
 	 * disabled first. */
-	reg1 = snd_soc_read(codec, WM9081_FLL_CONTROL_1);
+	reg1 = snd_soc_component_read32(component, WM9081_FLL_CONTROL_1);
 	reg1 &= ~WM9081_FLL_ENA;
-	snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1);
+	snd_soc_component_write(component, WM9081_FLL_CONTROL_1, reg1);
 
 	/* Apply the configuration */
 	if (fll_div.k)
 		reg1 |= WM9081_FLL_FRAC_MASK;
 	else
 		reg1 &= ~WM9081_FLL_FRAC_MASK;
-	snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1);
+	snd_soc_component_write(component, WM9081_FLL_CONTROL_1, reg1);
 
-	snd_soc_write(codec, WM9081_FLL_CONTROL_2,
+	snd_soc_component_write(component, WM9081_FLL_CONTROL_2,
 		     (fll_div.fll_outdiv << WM9081_FLL_OUTDIV_SHIFT) |
 		     (fll_div.fll_fratio << WM9081_FLL_FRATIO_SHIFT));
-	snd_soc_write(codec, WM9081_FLL_CONTROL_3, fll_div.k);
+	snd_soc_component_write(component, WM9081_FLL_CONTROL_3, fll_div.k);
 
-	reg4 = snd_soc_read(codec, WM9081_FLL_CONTROL_4);
+	reg4 = snd_soc_component_read32(component, WM9081_FLL_CONTROL_4);
 	reg4 &= ~WM9081_FLL_N_MASK;
 	reg4 |= fll_div.n << WM9081_FLL_N_SHIFT;
-	snd_soc_write(codec, WM9081_FLL_CONTROL_4, reg4);
+	snd_soc_component_write(component, WM9081_FLL_CONTROL_4, reg4);
 
 	reg5 &= ~WM9081_FLL_CLK_REF_DIV_MASK;
 	reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
-	snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
+	snd_soc_component_write(component, WM9081_FLL_CONTROL_5, reg5);
 
 	/* Set gain to the recommended value */
-	snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4,
+	snd_soc_component_update_bits(component, WM9081_FLL_CONTROL_4,
 			    WM9081_FLL_GAIN_MASK, 0);
 
 	/* Enable the FLL */
-	snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
+	snd_soc_component_write(component, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
 
 	/* Then bring CLK_SYS up again if it was disabled */
 	if (clk_sys_reg & WM9081_CLK_SYS_ENA)
-		snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, clk_sys_reg);
+		snd_soc_component_write(component, WM9081_CLOCK_CONTROL_3, clk_sys_reg);
 
-	dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
+	dev_dbg(component->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
 
 	wm9081->fll_fref = Fref;
 	wm9081->fll_fout = Fout;
@@ -637,9 +637,9 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
 	return 0;
 }
 
-static int configure_clock(struct snd_soc_codec *codec)
+static int configure_clock(struct snd_soc_component *component)
 {
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
 	int new_sysclk, i, target;
 	unsigned int reg;
 	int ret = 0;
@@ -654,7 +654,7 @@ static int configure_clock(struct snd_soc_codec *codec)
 		} else {
 			wm9081->sysclk_rate = wm9081->mclk_rate;
 		}
-		wm9081_set_fll(codec, WM9081_SYSCLK_FLL_MCLK, 0, 0);
+		wm9081_set_fll(component, WM9081_SYSCLK_FLL_MCLK, 0, 0);
 		break;
 
 	case WM9081_SYSCLK_FLL_MCLK:
@@ -695,7 +695,7 @@ static int configure_clock(struct snd_soc_codec *codec)
 			new_sysclk = 12288000;
 		}
 
-		ret = wm9081_set_fll(codec, WM9081_SYSCLK_FLL_MCLK,
+		ret = wm9081_set_fll(component, WM9081_SYSCLK_FLL_MCLK,
 				     wm9081->mclk_rate, new_sysclk);
 		if (ret == 0) {
 			wm9081->sysclk_rate = new_sysclk;
@@ -711,21 +711,21 @@ static int configure_clock(struct snd_soc_codec *codec)
 		return -EINVAL;
 	}
 
-	reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_1);
+	reg = snd_soc_component_read32(component, WM9081_CLOCK_CONTROL_1);
 	if (mclkdiv)
 		reg |= WM9081_MCLKDIV2;
 	else
 		reg &= ~WM9081_MCLKDIV2;
-	snd_soc_write(codec, WM9081_CLOCK_CONTROL_1, reg);
+	snd_soc_component_write(component, WM9081_CLOCK_CONTROL_1, reg);
 
-	reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
+	reg = snd_soc_component_read32(component, WM9081_CLOCK_CONTROL_3);
 	if (fll)
 		reg |= WM9081_CLK_SRC_SEL;
 	else
 		reg &= ~WM9081_CLK_SRC_SEL;
-	snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, reg);
+	snd_soc_component_write(component, WM9081_CLOCK_CONTROL_3, reg);
 
-	dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate);
+	dev_dbg(component->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate);
 
 	return ret;
 }
@@ -733,31 +733,31 @@ static int configure_clock(struct snd_soc_codec *codec)
 static int clk_sys_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
 
 	/* This should be done on init() for bypass paths */
 	switch (wm9081->sysclk_source) {
 	case WM9081_SYSCLK_MCLK:
-		dev_dbg(codec->dev, "Using %dHz MCLK\n", wm9081->mclk_rate);
+		dev_dbg(component->dev, "Using %dHz MCLK\n", wm9081->mclk_rate);
 		break;
 	case WM9081_SYSCLK_FLL_MCLK:
-		dev_dbg(codec->dev, "Using %dHz MCLK with FLL\n",
+		dev_dbg(component->dev, "Using %dHz MCLK with FLL\n",
 			wm9081->mclk_rate);
 		break;
 	default:
-		dev_err(codec->dev, "System clock not configured\n");
+		dev_err(component->dev, "System clock not configured\n");
 		return -EINVAL;
 	}
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		configure_clock(codec);
+		configure_clock(component);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
 		/* Disable the FLL if it's running */
-		wm9081_set_fll(codec, 0, 0, 0);
+		wm9081_set_fll(component, 0, 0, 0);
 		break;
 	}
 
@@ -816,10 +816,10 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
 	{ "SPKP", NULL, "Speaker" },
 };
 
-static int wm9081_set_bias_level(struct snd_soc_codec *codec,
+static int wm9081_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -827,31 +827,31 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_PREPARE:
 		/* VMID=2*40k */
-		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+		snd_soc_component_update_bits(component, WM9081_VMID_CONTROL,
 				    WM9081_VMID_SEL_MASK, 0x2);
 
 		/* Normal bias current */
-		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+		snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1,
 				    WM9081_STBY_BIAS_ENA, 0);
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
 		/* Initial cold start */
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			regcache_cache_only(wm9081->regmap, false);
 			regcache_sync(wm9081->regmap);
 
 			/* Disable LINEOUT discharge */
-			snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
+			snd_soc_component_update_bits(component, WM9081_ANTI_POP_CONTROL,
 					    WM9081_LINEOUT_DISCH, 0);
 
 			/* Select startup bias source */
-			snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+			snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1,
 					    WM9081_BIAS_SRC | WM9081_BIAS_ENA,
 					    WM9081_BIAS_SRC | WM9081_BIAS_ENA);
 
 			/* VMID 2*4k; Soft VMID ramp enable */
-			snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+			snd_soc_component_update_bits(component, WM9081_VMID_CONTROL,
 					    WM9081_VMID_RAMP |
 					    WM9081_VMID_SEL_MASK,
 					    WM9081_VMID_RAMP | 0x6);
@@ -859,37 +859,37 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
 			mdelay(100);
 
 			/* Normal bias enable & soft start off */
-			snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+			snd_soc_component_update_bits(component, WM9081_VMID_CONTROL,
 					    WM9081_VMID_RAMP, 0);
 
 			/* Standard bias source */
-			snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+			snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1,
 					    WM9081_BIAS_SRC, 0);
 		}
 
 		/* VMID 2*240k */
-		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+		snd_soc_component_update_bits(component, WM9081_VMID_CONTROL,
 				    WM9081_VMID_SEL_MASK, 0x04);
 
 		/* Standby bias current on */
-		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+		snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1,
 				    WM9081_STBY_BIAS_ENA,
 				    WM9081_STBY_BIAS_ENA);
 		break;
 
 	case SND_SOC_BIAS_OFF:
 		/* Startup bias source and disable bias */
-		snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+		snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1,
 				    WM9081_BIAS_SRC | WM9081_BIAS_ENA,
 				    WM9081_BIAS_SRC);
 
 		/* Disable VMID with soft ramping */
-		snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+		snd_soc_component_update_bits(component, WM9081_VMID_CONTROL,
 				    WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK,
 				    WM9081_VMID_RAMP);
 
 		/* Actively discharge LINEOUT */
-		snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
+		snd_soc_component_update_bits(component, WM9081_ANTI_POP_CONTROL,
 				    WM9081_LINEOUT_DISCH,
 				    WM9081_LINEOUT_DISCH);
 
@@ -903,9 +903,9 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
 static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
 			      unsigned int fmt)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
-	unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
+	struct snd_soc_component *component = dai->component;
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
+	unsigned int aif2 = snd_soc_component_read32(component, WM9081_AUDIO_INTERFACE_2);
 
 	aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV |
 		  WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK);
@@ -986,7 +986,7 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);
+	snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_2, aif2);
 
 	return 0;
 }
@@ -995,23 +995,23 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = dai->component;
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
 	int ret, i, best, best_val, cur_val;
 	unsigned int clk_ctrl2, aif1, aif2, aif3, aif4;
 
-	clk_ctrl2 = snd_soc_read(codec, WM9081_CLOCK_CONTROL_2);
+	clk_ctrl2 = snd_soc_component_read32(component, WM9081_CLOCK_CONTROL_2);
 	clk_ctrl2 &= ~(WM9081_CLK_SYS_RATE_MASK | WM9081_SAMPLE_RATE_MASK);
 
-	aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
+	aif1 = snd_soc_component_read32(component, WM9081_AUDIO_INTERFACE_1);
 
-	aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
+	aif2 = snd_soc_component_read32(component, WM9081_AUDIO_INTERFACE_2);
 	aif2 &= ~WM9081_AIF_WL_MASK;
 
-	aif3 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_3);
+	aif3 = snd_soc_component_read32(component, WM9081_AUDIO_INTERFACE_3);
 	aif3 &= ~WM9081_BCLK_DIV_MASK;
 
-	aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4);
+	aif4 = snd_soc_component_read32(component, WM9081_AUDIO_INTERFACE_4);
 	aif4 &= ~WM9081_LRCLK_RATE_MASK;
 
 	wm9081->fs = params_rate(params);
@@ -1047,9 +1047,9 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 
-	dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk);
+	dev_dbg(component->dev, "Target BCLK is %dHz\n", wm9081->bclk);
 
-	ret = configure_clock(codec);
+	ret = configure_clock(component);
 	if (ret != 0)
 		return ret;
 
@@ -1065,7 +1065,7 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
 			best_val = cur_val;
 		}
 	}
-	dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
+	dev_dbg(component->dev, "Selected CLK_SYS_RATIO of %d\n",
 		clk_sys_rates[best].ratio);
 	clk_ctrl2 |= (clk_sys_rates[best].clk_sys_rate
 		      << WM9081_CLK_SYS_RATE_SHIFT);
@@ -1081,7 +1081,7 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
 			best_val = cur_val;
 		}
 	}
-	dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
+	dev_dbg(component->dev, "Selected SAMPLE_RATE of %dHz\n",
 		sample_rates[best].rate);
 	clk_ctrl2 |= (sample_rates[best].sample_rate
 			<< WM9081_SAMPLE_RATE_SHIFT);
@@ -1100,12 +1100,12 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 	wm9081->bclk = (wm9081->sysclk_rate * 10) / bclk_divs[best].div;
-	dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
+	dev_dbg(component->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
 		bclk_divs[best].div, wm9081->bclk);
 	aif3 |= bclk_divs[best].bclk_div;
 
 	/* LRCLK is a simple fraction of BCLK */
-	dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm9081->bclk / wm9081->fs);
+	dev_dbg(component->dev, "LRCLK_RATE is %d\n", wm9081->bclk / wm9081->fs);
 	aif4 |= wm9081->bclk / wm9081->fs;
 
 	/* Apply a ReTune Mobile configuration if it's in use */
@@ -1126,51 +1126,51 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
 		}
 		s = &pdata->retune_configs[best];
 
-		dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
+		dev_dbg(component->dev, "ReTune Mobile %s tuned for %dHz\n",
 			s->name, s->rate);
 
 		/* If the EQ is enabled then disable it while we write out */
-		eq1 = snd_soc_read(codec, WM9081_EQ_1) & WM9081_EQ_ENA;
+		eq1 = snd_soc_component_read32(component, WM9081_EQ_1) & WM9081_EQ_ENA;
 		if (eq1 & WM9081_EQ_ENA)
-			snd_soc_write(codec, WM9081_EQ_1, 0);
+			snd_soc_component_write(component, WM9081_EQ_1, 0);
 
 		/* Write out the other values */
 		for (i = 1; i < ARRAY_SIZE(s->config); i++)
-			snd_soc_write(codec, WM9081_EQ_1 + i, s->config[i]);
+			snd_soc_component_write(component, WM9081_EQ_1 + i, s->config[i]);
 
 		eq1 |= (s->config[0] & ~WM9081_EQ_ENA);
-		snd_soc_write(codec, WM9081_EQ_1, eq1);
+		snd_soc_component_write(component, WM9081_EQ_1, eq1);
 	}
 
-	snd_soc_write(codec, WM9081_CLOCK_CONTROL_2, clk_ctrl2);
-	snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);
-	snd_soc_write(codec, WM9081_AUDIO_INTERFACE_3, aif3);
-	snd_soc_write(codec, WM9081_AUDIO_INTERFACE_4, aif4);
+	snd_soc_component_write(component, WM9081_CLOCK_CONTROL_2, clk_ctrl2);
+	snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_2, aif2);
+	snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_3, aif3);
+	snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_4, aif4);
 
 	return 0;
 }
 
 static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	unsigned int reg;
 
-	reg = snd_soc_read(codec, WM9081_DAC_DIGITAL_2);
+	reg = snd_soc_component_read32(component, WM9081_DAC_DIGITAL_2);
 
 	if (mute)
 		reg |= WM9081_DAC_MUTE;
 	else
 		reg &= ~WM9081_DAC_MUTE;
 
-	snd_soc_write(codec, WM9081_DAC_DIGITAL_2, reg);
+	snd_soc_component_write(component, WM9081_DAC_DIGITAL_2, reg);
 
 	return 0;
 }
 
-static int wm9081_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int wm9081_set_sysclk(struct snd_soc_component *component, int clk_id,
 			     int source, unsigned int freq, int dir)
 {
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
 
 	switch (clk_id) {
 	case WM9081_SYSCLK_MCLK:
@@ -1189,9 +1189,9 @@ static int wm9081_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
 	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-	struct snd_soc_codec *codec = dai->codec;
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
-	unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
+	struct snd_soc_component *component = dai->component;
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
+	unsigned int aif1 = snd_soc_component_read32(component, WM9081_AUDIO_INTERFACE_1);
 
 	aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK);
 
@@ -1221,7 +1221,7 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
 		return -EINVAL;
 	}
 
-	snd_soc_write(codec, WM9081_AUDIO_INTERFACE_1, aif1);
+	snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_1, aif1);
 
 	return 0;
 }
@@ -1254,42 +1254,39 @@ static struct snd_soc_dai_driver wm9081_dai = {
 	.ops = &wm9081_dai_ops,
 };
 
-static int wm9081_probe(struct snd_soc_codec *codec)
+static int wm9081_probe(struct snd_soc_component *component)
 {
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+	struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component);
 
 	/* Enable zero cross by default */
-	snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
+	snd_soc_component_update_bits(component, WM9081_ANALOGUE_LINEOUT,
 			    WM9081_LINEOUTZC, WM9081_LINEOUTZC);
-	snd_soc_update_bits(codec, WM9081_ANALOGUE_SPEAKER_PGA,
+	snd_soc_component_update_bits(component, WM9081_ANALOGUE_SPEAKER_PGA,
 			    WM9081_SPKPGAZC, WM9081_SPKPGAZC);
 
 	if (!wm9081->pdata.num_retune_configs) {
-		dev_dbg(codec->dev,
+		dev_dbg(component->dev,
 			"No ReTune Mobile data, using normal EQ\n");
-		snd_soc_add_codec_controls(codec, wm9081_eq_controls,
+		snd_soc_add_component_controls(component, wm9081_eq_controls,
 				     ARRAY_SIZE(wm9081_eq_controls));
 	}
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
-	.probe = 	wm9081_probe,
-
-	.set_sysclk = wm9081_set_sysclk,
-	.set_bias_level = wm9081_set_bias_level,
-
-	.idle_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm9081_snd_controls,
-		.num_controls		= ARRAY_SIZE(wm9081_snd_controls),
-		.dapm_widgets		= wm9081_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm9081_dapm_widgets),
-		.dapm_routes		= wm9081_audio_paths,
-		.num_dapm_routes	= ARRAY_SIZE(wm9081_audio_paths),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm9081 = {
+	.probe			= wm9081_probe,
+	.set_sysclk		= wm9081_set_sysclk,
+	.set_bias_level		= wm9081_set_bias_level,
+	.controls		= wm9081_snd_controls,
+	.num_controls		= ARRAY_SIZE(wm9081_snd_controls),
+	.dapm_widgets		= wm9081_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm9081_dapm_widgets),
+	.dapm_routes		= wm9081_audio_paths,
+	.num_dapm_routes	= ARRAY_SIZE(wm9081_audio_paths),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm9081_regmap = {
@@ -1355,8 +1352,8 @@ static int wm9081_i2c_probe(struct i2c_client *i2c,
 
 	regcache_cache_only(wm9081->regmap, true);
 
-	ret = snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm9081, &wm9081_dai, 1);
+	ret = devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm9081, &wm9081_dai, 1);
 	if (ret < 0)
 		return ret;
 
@@ -1365,7 +1362,6 @@ static int wm9081_i2c_probe(struct i2c_client *i2c,
 
 static int wm9081_i2c_remove(struct i2c_client *client)
 {
-	snd_soc_unregister_codec(&client->dev);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 5a13138..a9f1a03 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -143,23 +143,23 @@ static bool wm9090_readable(struct device *dev, unsigned int reg)
 	}
 }
 
-static void wait_for_dc_servo(struct snd_soc_codec *codec)
+static void wait_for_dc_servo(struct snd_soc_component *component)
 {
 	unsigned int reg;
 	int count = 0;
 
-	dev_dbg(codec->dev, "Waiting for DC servo...\n");
+	dev_dbg(component->dev, "Waiting for DC servo...\n");
 	do {
 		count++;
 		msleep(1);
-		reg = snd_soc_read(codec, WM9090_DC_SERVO_READBACK_0);
-		dev_dbg(codec->dev, "DC servo status: %x\n", reg);
+		reg = snd_soc_component_read32(component, WM9090_DC_SERVO_READBACK_0);
+		dev_dbg(component->dev, "DC servo status: %x\n", reg);
 	} while ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
 		 != WM9090_DCS_CAL_COMPLETE_MASK && count < 1000);
 
 	if ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
 	    != WM9090_DCS_CAL_COMPLETE_MASK)
-		dev_err(codec->dev, "Timed out waiting for DC Servo\n");
+		dev_err(component->dev, "Timed out waiting for DC Servo\n");
 }
 
 static const DECLARE_TLV_DB_RANGE(in_tlv,
@@ -251,22 +251,22 @@ SOC_SINGLE_TLV("MIXOUTR IN2B Volume", WM9090_OUTPUT_MIXER4, 0, 3, 1,
 static int hp_ev(struct snd_soc_dapm_widget *w,
 		 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	unsigned int reg = snd_soc_read(codec, WM9090_ANALOGUE_HP_0);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	unsigned int reg = snd_soc_component_read32(component, WM9090_ANALOGUE_HP_0);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, WM9090_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, WM9090_CHARGE_PUMP_1,
 				    WM9090_CP_ENA, WM9090_CP_ENA);
 
 		msleep(5);
 
-		snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
 				    WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
 				    WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA);
 
 		reg |= WM9090_HPOUT1L_DLY | WM9090_HPOUT1R_DLY;
-		snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
+		snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
 
 		/* Start the DC servo.  We don't currently use the
 		 * ability to save the state since we don't have full
@@ -274,16 +274,16 @@ static int hp_ev(struct snd_soc_dapm_widget *w,
 		 * DC offsets; see the WM8904 driver for an example of
 		 * doing so.
 		 */
-		snd_soc_write(codec, WM9090_DC_SERVO_0,
+		snd_soc_component_write(component, WM9090_DC_SERVO_0,
 			      WM9090_DCS_ENA_CHAN_0 |
 			      WM9090_DCS_ENA_CHAN_1 |
 			      WM9090_DCS_TRIG_STARTUP_1 |
 			      WM9090_DCS_TRIG_STARTUP_0);
-		wait_for_dc_servo(codec);
+		wait_for_dc_servo(component);
 
 		reg |= WM9090_HPOUT1R_OUTP | WM9090_HPOUT1R_RMV_SHORT |
 			WM9090_HPOUT1L_OUTP | WM9090_HPOUT1L_RMV_SHORT;
-		snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
+		snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
@@ -294,15 +294,15 @@ static int hp_ev(struct snd_soc_dapm_widget *w,
 			 WM9090_HPOUT1R_DLY |
 			 WM9090_HPOUT1R_OUTP);
 
-		snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
+		snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
 
-		snd_soc_write(codec, WM9090_DC_SERVO_0, 0);
+		snd_soc_component_write(component, WM9090_DC_SERVO_0, 0);
 
-		snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
 				    WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
 				    0);
 
-		snd_soc_update_bits(codec, WM9090_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, WM9090_CHARGE_PUMP_1,
 				    WM9090_CP_ENA, 0);
 		break;
 	}
@@ -419,10 +419,10 @@ static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
 	{ "IN2A PGA", NULL, "IN2-" },	
 };
 
-static int wm9090_add_controls(struct snd_soc_codec *codec)
+static int wm9090_add_controls(struct snd_soc_component *component)
 {
-	struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int i;
 
 	snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets,
@@ -430,7 +430,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
 
 	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
 
-	snd_soc_add_codec_controls(codec, wm9090_controls,
+	snd_soc_add_component_controls(component, wm9090_controls,
 			     ARRAY_SIZE(wm9090_controls));
 
 	if (wm9090->pdata.lin1_diff) {
@@ -439,7 +439,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
 	} else {
 		snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
 					ARRAY_SIZE(audio_map_in1_se));
-		snd_soc_add_codec_controls(codec, wm9090_in1_se_controls,
+		snd_soc_add_component_controls(component, wm9090_in1_se_controls,
 				     ARRAY_SIZE(wm9090_in1_se_controls));
 	}
 
@@ -449,18 +449,18 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
 	} else {
 		snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
 					ARRAY_SIZE(audio_map_in2_se));
-		snd_soc_add_codec_controls(codec, wm9090_in2_se_controls,
+		snd_soc_add_component_controls(component, wm9090_in2_se_controls,
 				     ARRAY_SIZE(wm9090_in2_se_controls));
 	}
 
 	if (wm9090->pdata.agc_ena) {
 		for (i = 0; i < ARRAY_SIZE(wm9090->pdata.agc); i++)
-			snd_soc_write(codec, WM9090_AGC_CONTROL_0 + i,
+			snd_soc_component_write(component, WM9090_AGC_CONTROL_0 + i,
 				      wm9090->pdata.agc[i]);
-		snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_3,
+		snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_3,
 				    WM9090_AGC_ENA, WM9090_AGC_ENA);
 	} else {
-		snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_3,
+		snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_3,
 				    WM9090_AGC_ENA, 0);
 	}
 
@@ -472,19 +472,19 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
  * The machine driver should call this from their set_bias_level; if there
  * isn't one then this can just be set as the set_bias_level function.
  */
-static int wm9090_set_bias_level(struct snd_soc_codec *codec,
+static int wm9090_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
-	struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
+	struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
 
 	case SND_SOC_BIAS_PREPARE:
-		snd_soc_update_bits(codec, WM9090_ANTIPOP2, WM9090_VMID_ENA,
+		snd_soc_component_update_bits(component, WM9090_ANTIPOP2, WM9090_VMID_ENA,
 				    WM9090_VMID_ENA);
-		snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
 				    WM9090_BIAS_ENA |
 				    WM9090_VMID_RES_MASK,
 				    WM9090_BIAS_ENA |
@@ -493,7 +493,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 			/* Restore the register cache */
 			regcache_sync(wm9090->regmap);
 		}
@@ -502,9 +502,9 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
 		 * ground referenced outputs and class D speaker mean that
 		 * latency is not an issue.
 		 */
-		snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
 				    WM9090_BIAS_ENA | WM9090_VMID_RES_MASK, 0);
-		snd_soc_update_bits(codec, WM9090_ANTIPOP2,
+		snd_soc_component_update_bits(component, WM9090_ANTIPOP2,
 				    WM9090_VMID_ENA, 0);
 		break;
 
@@ -515,45 +515,49 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-static int wm9090_probe(struct snd_soc_codec *codec)
+static int wm9090_probe(struct snd_soc_component *component)
 {
 	/* Configure some defaults; they will be written out when we
 	 * bring the bias up.
 	 */
-	snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_A_VOLUME,
+	snd_soc_component_update_bits(component, WM9090_IN1_LINE_INPUT_A_VOLUME,
 			    WM9090_IN1_VU | WM9090_IN1A_ZC,
 			    WM9090_IN1_VU | WM9090_IN1A_ZC);
-	snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_B_VOLUME,
+	snd_soc_component_update_bits(component, WM9090_IN1_LINE_INPUT_B_VOLUME,
 			    WM9090_IN1_VU | WM9090_IN1B_ZC,
 			    WM9090_IN1_VU | WM9090_IN1B_ZC);
-	snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_A_VOLUME,
+	snd_soc_component_update_bits(component, WM9090_IN2_LINE_INPUT_A_VOLUME,
 			    WM9090_IN2_VU | WM9090_IN2A_ZC,
 			    WM9090_IN2_VU | WM9090_IN2A_ZC);
-	snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_B_VOLUME,
+	snd_soc_component_update_bits(component, WM9090_IN2_LINE_INPUT_B_VOLUME,
 			    WM9090_IN2_VU | WM9090_IN2B_ZC,
 			    WM9090_IN2_VU | WM9090_IN2B_ZC);
-	snd_soc_update_bits(codec, WM9090_SPEAKER_VOLUME_LEFT,
+	snd_soc_component_update_bits(component, WM9090_SPEAKER_VOLUME_LEFT,
 			    WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC,
 			    WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC);
-	snd_soc_update_bits(codec, WM9090_LEFT_OUTPUT_VOLUME,
+	snd_soc_component_update_bits(component, WM9090_LEFT_OUTPUT_VOLUME,
 			    WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC,
 			    WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC);
-	snd_soc_update_bits(codec, WM9090_RIGHT_OUTPUT_VOLUME,
+	snd_soc_component_update_bits(component, WM9090_RIGHT_OUTPUT_VOLUME,
 			    WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC,
 			    WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC);
 
-	snd_soc_update_bits(codec, WM9090_CLOCKING_1,
+	snd_soc_component_update_bits(component, WM9090_CLOCKING_1,
 			    WM9090_TOCLK_ENA, WM9090_TOCLK_ENA);
 
-	wm9090_add_controls(codec);
+	wm9090_add_controls(component);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
-	.probe = 	wm9090_probe,
-	.set_bias_level = wm9090_set_bias_level,
-	.suspend_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_wm9090 = {
+	.probe			= wm9090_probe,
+	.set_bias_level		= wm9090_set_bias_level,
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config wm9090_regmap = {
@@ -607,8 +611,8 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, wm9090);
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm9090,  NULL, 0);
+	ret =  devm_snd_soc_register_component(&i2c->dev,
+			&soc_component_dev_wm9090,  NULL, 0);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
 		return ret;
@@ -617,12 +621,6 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
 	return 0;
 }
 
-static int wm9090_i2c_remove(struct i2c_client *i2c)
-{
-	snd_soc_unregister_codec(&i2c->dev);
-	return 0;
-}
-
 static const struct i2c_device_id wm9090_id[] = {
 	{ "wm9090", 0 },
 	{ "wm9093", 0 },
@@ -635,7 +633,6 @@ static struct i2c_driver wm9090_i2c_driver = {
 		.name = "wm9090",
 	},
 	.probe = wm9090_i2c_probe,
-	.remove = wm9090_i2c_remove,
 	.id_table = wm9090_id,
 };
 
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 2c09f71..ccdf088 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -235,17 +235,17 @@ static const struct snd_soc_dapm_route wm9705_audio_map[] = {
 static int ac97_prepare(struct snd_pcm_substream *substream,
 			struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int reg;
 
-	snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x1, 0x1);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x1, 0x1);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		reg = AC97_PCM_FRONT_DAC_RATE;
 	else
 		reg = AC97_PCM_LR_ADC_RATE;
 
-	return snd_soc_write(codec, reg, substream->runtime->rate);
+	return snd_soc_component_write(component, reg, substream->runtime->rate);
 }
 
 #define WM9705_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
@@ -289,18 +289,18 @@ static struct snd_soc_dai_driver wm9705_dai[] = {
 };
 
 #ifdef CONFIG_PM
-static int wm9705_soc_suspend(struct snd_soc_codec *codec)
+static int wm9705_soc_suspend(struct snd_soc_component *component)
 {
-	regcache_cache_bypass(codec->component.regmap, true);
-	snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
-	regcache_cache_bypass(codec->component.regmap, false);
+	regcache_cache_bypass(component->regmap, true);
+	snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
+	regcache_cache_bypass(component->regmap, false);
 
 	return 0;
 }
 
-static int wm9705_soc_resume(struct snd_soc_codec *codec)
+static int wm9705_soc_resume(struct snd_soc_component *component)
 {
-	struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
+	struct wm9705_priv *wm9705 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = snd_ac97_reset(wm9705->ac97, true, WM9705_VENDOR_ID,
@@ -308,7 +308,7 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
 	if (ret < 0)
 		return ret;
 
-	regcache_sync(codec->component.regmap);
+	snd_soc_component_cache_sync(component);
 
 	return 0;
 }
@@ -317,9 +317,9 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
 #define wm9705_soc_resume NULL
 #endif
 
-static int wm9705_soc_probe(struct snd_soc_codec *codec)
+static int wm9705_soc_probe(struct snd_soc_component *component)
 {
-	struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
+	struct wm9705_priv *wm9705 = snd_soc_component_get_drvdata(component);
 	struct regmap *regmap;
 
 	if (wm9705->mfd_pdata) {
@@ -327,54 +327,54 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
 		regmap = wm9705->mfd_pdata->regmap;
 	} else {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-		wm9705->ac97 = snd_soc_new_ac97_codec(codec, WM9705_VENDOR_ID,
+		wm9705->ac97 = snd_soc_new_ac97_component(component, WM9705_VENDOR_ID,
 						      WM9705_VENDOR_ID_MASK);
 		if (IS_ERR(wm9705->ac97)) {
-			dev_err(codec->dev, "Failed to register AC97 codec\n");
+			dev_err(component->dev, "Failed to register AC97 codec\n");
 			return PTR_ERR(wm9705->ac97);
 		}
 
 		regmap = regmap_init_ac97(wm9705->ac97, &wm9705_regmap_config);
 		if (IS_ERR(regmap)) {
-			snd_soc_free_ac97_codec(wm9705->ac97);
+			snd_soc_free_ac97_component(wm9705->ac97);
 			return PTR_ERR(regmap);
 		}
 #endif
 	}
 
-	snd_soc_codec_set_drvdata(codec, wm9705->ac97);
-	snd_soc_codec_init_regmap(codec, regmap);
+	snd_soc_component_set_drvdata(component, wm9705->ac97);
+	snd_soc_component_init_regmap(component, regmap);
 
 	return 0;
 }
 
-static int wm9705_soc_remove(struct snd_soc_codec *codec)
+static void wm9705_soc_remove(struct snd_soc_component *component)
 {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-	struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
+	struct wm9705_priv *wm9705 = snd_soc_component_get_drvdata(component);
 
 	if (!wm9705->mfd_pdata) {
-		snd_soc_codec_exit_regmap(codec);
-		snd_soc_free_ac97_codec(wm9705->ac97);
+		snd_soc_component_exit_regmap(component);
+		snd_soc_free_ac97_component(wm9705->ac97);
 	}
 #endif
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
-	.probe = 	wm9705_soc_probe,
-	.remove = 	wm9705_soc_remove,
-	.suspend =	wm9705_soc_suspend,
-	.resume =	wm9705_soc_resume,
-
-	.component_driver = {
-		.controls		= wm9705_snd_ac97_controls,
-		.num_controls		= ARRAY_SIZE(wm9705_snd_ac97_controls),
-		.dapm_widgets		= wm9705_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm9705_dapm_widgets),
-		.dapm_routes		= wm9705_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(wm9705_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm9705 = {
+	.probe			= wm9705_soc_probe,
+	.remove			= wm9705_soc_remove,
+	.suspend		= wm9705_soc_suspend,
+	.resume			= wm9705_soc_resume,
+	.controls		= wm9705_snd_ac97_controls,
+	.num_controls		= ARRAY_SIZE(wm9705_snd_ac97_controls),
+	.dapm_widgets		= wm9705_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm9705_dapm_widgets),
+	.dapm_routes		= wm9705_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(wm9705_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm9705_probe(struct platform_device *pdev)
@@ -388,14 +388,8 @@ static int wm9705_probe(struct platform_device *pdev)
 	wm9705->mfd_pdata = dev_get_platdata(&pdev->dev);
 	platform_set_drvdata(pdev, wm9705);
 
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
-}
-
-static int wm9705_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
 }
 
 static struct platform_driver wm9705_codec_driver = {
@@ -404,7 +398,6 @@ static struct platform_driver wm9705_codec_driver = {
 	},
 
 	.probe = wm9705_probe,
-	.remove = wm9705_remove,
 };
 
 module_platform_driver(wm9705_codec_driver);
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 4f6d1a4..953d94d 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -220,13 +220,13 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-	struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+	struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
 	unsigned int val = ucontrol->value.integer.value[0];
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int mixer, mask, shift, old;
-	struct snd_soc_dapm_update update = { 0 };
+	struct snd_soc_dapm_update update = {};
 	bool change;
 
 	mixer = mc->shift >> 8;
@@ -264,8 +264,8 @@ static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-	struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+	struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int shift, mixer;
@@ -527,33 +527,33 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = {
 static int ac97_prepare(struct snd_pcm_substream *substream,
 			struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	int reg;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
-	snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x1, 0x1);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x1, 0x1);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		reg = AC97_PCM_FRONT_DAC_RATE;
 	else
 		reg = AC97_PCM_LR_ADC_RATE;
 
-	return snd_soc_write(codec, reg, runtime->rate);
+	return snd_soc_component_write(component, reg, runtime->rate);
 }
 
 static int ac97_aux_prepare(struct snd_pcm_substream *substream,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
-	snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x1, 0x1);
-	snd_soc_update_bits(codec, AC97_PCI_SID, 0x8000, 0x8000);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x1, 0x1);
+	snd_soc_component_update_bits(component, AC97_PCI_SID, 0x8000, 0x8000);
 
 	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
 		return -ENODEV;
 
-	return snd_soc_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
+	return snd_soc_component_write(component, AC97_PCM_SURR_DAC_RATE, runtime->rate);
 }
 
 #define WM9712_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
@@ -597,7 +597,7 @@ static struct snd_soc_dai_driver wm9712_dai[] = {
 }
 };
 
-static int wm9712_set_bias_level(struct snd_soc_codec *codec,
+static int wm9712_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
@@ -605,20 +605,20 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
-		snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
+		snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* disable everything including AC link */
-		snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
-		snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
+		snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
+		snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
 		break;
 	}
 	return 0;
 }
 
-static int wm9712_soc_resume(struct snd_soc_codec *codec)
+static int wm9712_soc_resume(struct snd_soc_component *component)
 {
-	struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+	struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = snd_ac97_reset(wm9712->ac97, true, WM9712_VENDOR_ID,
@@ -626,17 +626,17 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec)
 	if (ret < 0)
 		return ret;
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	if (ret == 0)
-		regcache_sync(codec->component.regmap);
+		snd_soc_component_cache_sync(component);
 
 	return ret;
 }
 
-static int wm9712_soc_probe(struct snd_soc_codec *codec)
+static int wm9712_soc_probe(struct snd_soc_component *component)
 {
-	struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+	struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
 	struct regmap *regmap;
 	int ret;
 
@@ -645,59 +645,59 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
 		regmap = wm9712->mfd_pdata->regmap;
 	} else {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-		wm9712->ac97 = snd_soc_new_ac97_codec(codec, WM9712_VENDOR_ID,
+		wm9712->ac97 = snd_soc_new_ac97_component(component, WM9712_VENDOR_ID,
 						      WM9712_VENDOR_ID_MASK);
 		if (IS_ERR(wm9712->ac97)) {
 			ret = PTR_ERR(wm9712->ac97);
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to register AC97 codec: %d\n", ret);
 			return ret;
 		}
 
 		regmap = regmap_init_ac97(wm9712->ac97, &wm9712_regmap_config);
 		if (IS_ERR(regmap)) {
-			snd_soc_free_ac97_codec(wm9712->ac97);
+			snd_soc_free_ac97_component(wm9712->ac97);
 			return PTR_ERR(regmap);
 		}
 #endif
 	}
 
-	snd_soc_codec_init_regmap(codec, regmap);
+	snd_soc_component_init_regmap(component, regmap);
 
 	/* set alc mux to none */
-	snd_soc_update_bits(codec, AC97_VIDEO, 0x3000, 0x3000);
+	snd_soc_component_update_bits(component, AC97_VIDEO, 0x3000, 0x3000);
 
 	return 0;
 }
 
-static int wm9712_soc_remove(struct snd_soc_codec *codec)
+static void wm9712_soc_remove(struct snd_soc_component *component)
 {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-	struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+	struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
 
 	if (!wm9712->mfd_pdata) {
-		snd_soc_codec_exit_regmap(codec);
-		snd_soc_free_ac97_codec(wm9712->ac97);
+		snd_soc_component_exit_regmap(component);
+		snd_soc_free_ac97_component(wm9712->ac97);
 	}
 #endif
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
-	.probe = 	wm9712_soc_probe,
-	.remove = 	wm9712_soc_remove,
-	.resume =	wm9712_soc_resume,
-	.set_bias_level = wm9712_set_bias_level,
-	.suspend_bias_off = true,
-
-	.component_driver = {
-		.controls		= wm9712_snd_ac97_controls,
-		.num_controls		= ARRAY_SIZE(wm9712_snd_ac97_controls),
-		.dapm_widgets		= wm9712_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm9712_dapm_widgets),
-		.dapm_routes		= wm9712_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(wm9712_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm9712 = {
+	.probe			= wm9712_soc_probe,
+	.remove			= wm9712_soc_remove,
+	.resume			= wm9712_soc_resume,
+	.set_bias_level		= wm9712_set_bias_level,
+	.controls		= wm9712_snd_ac97_controls,
+	.num_controls		= ARRAY_SIZE(wm9712_snd_ac97_controls),
+	.dapm_widgets		= wm9712_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm9712_dapm_widgets),
+	.dapm_routes		= wm9712_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(wm9712_audio_map),
+	.suspend_bias_off	= 1,
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm9712_probe(struct platform_device *pdev)
@@ -713,26 +713,19 @@ static int wm9712_probe(struct platform_device *pdev)
 	wm9712->mfd_pdata = dev_get_platdata(&pdev->dev);
 	platform_set_drvdata(pdev, wm9712);
 
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
 }
 
-static int wm9712_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
-}
-
-static struct platform_driver wm9712_codec_driver = {
+static struct platform_driver wm9712_component_driver = {
 	.driver = {
-		.name = "wm9712-codec",
+		.name = "wm9712-component",
 	},
 
 	.probe = wm9712_probe,
-	.remove = wm9712_remove,
 };
 
-module_platform_driver(wm9712_codec_driver);
+module_platform_driver(wm9712_component_driver);
 
 MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
 MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index df72206..643863b 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -196,16 +196,16 @@ SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
 static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
 				 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
 	if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD))
 		return -EINVAL;
 
 	/* Gracefully shut down the voice interface. */
-	snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0200);
+	snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, 0x0200);
 	schedule_timeout_interruptible(msecs_to_jiffies(1));
-	snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0f00);
-	snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x1000, 0x1000);
+	snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, 0x0f00);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x1000, 0x1000);
 
 	return 0;
 }
@@ -229,13 +229,13 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+	struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
 	unsigned int val = ucontrol->value.integer.value[0];
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int mixer, mask, shift, old;
-	struct snd_soc_dapm_update update = { 0 };
+	struct snd_soc_dapm_update update = {};
 	bool change;
 
 	mixer = mc->shift >> 8;
@@ -273,8 +273,8 @@ static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+	struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int mixer, shift;
@@ -753,7 +753,7 @@ struct _pll_div {
  * to allow rounding later */
 #define FIXED_PLL_SIZE ((1 << 22) * 10)
 
-static void pll_factors(struct snd_soc_codec *codec,
+static void pll_factors(struct snd_soc_component *component,
 	struct _pll_div *pll_div, unsigned int source)
 {
 	u64 Kpart;
@@ -789,7 +789,7 @@ static void pll_factors(struct snd_soc_codec *codec,
 
 	Ndiv = target / source;
 	if ((Ndiv < 5) || (Ndiv > 12))
-		dev_warn(codec->dev,
+		dev_warn(component->dev,
 			"WM9713 PLL N value %u out of recommended range!\n",
 			Ndiv);
 
@@ -815,28 +815,28 @@ static void pll_factors(struct snd_soc_codec *codec,
  * Please note that changing the PLL input frequency may require
  * resynchronisation with the AC97 controller.
  */
-static int wm9713_set_pll(struct snd_soc_codec *codec,
+static int wm9713_set_pll(struct snd_soc_component *component,
 	int pll_id, unsigned int freq_in, unsigned int freq_out)
 {
-	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+	struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
 	u16 reg, reg2;
 	struct _pll_div pll_div;
 
 	/* turn PLL off ? */
 	if (freq_in == 0) {
 		/* disable PLL power and select ext source */
-		snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0080, 0x0080);
-		snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x0200, 0x0200);
+		snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0080, 0x0080);
+		snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x0200, 0x0200);
 		wm9713->pll_in = 0;
 		return 0;
 	}
 
-	pll_factors(codec, &pll_div, freq_in);
+	pll_factors(component, &pll_div, freq_in);
 
 	if (pll_div.k == 0) {
 		reg = (pll_div.n << 12) | (pll_div.lf << 11) |
 			(pll_div.divsel << 9) | (pll_div.divctl << 8);
-		snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+		snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 	} else {
 		/* write the fractional k to the reg 0x46 pages */
 		reg2 = (pll_div.n << 12) | (pll_div.lf << 11) | (1 << 10) |
@@ -844,31 +844,31 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
 
 		/* K [21:20] */
 		reg = reg2 | (0x5 << 4) | (pll_div.k >> 20);
-		snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+		snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
 		/* K [19:16] */
 		reg = reg2 | (0x4 << 4) | ((pll_div.k >> 16) & 0xf);
-		snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+		snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
 		/* K [15:12] */
 		reg = reg2 | (0x3 << 4) | ((pll_div.k >> 12) & 0xf);
-		snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+		snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
 		/* K [11:8] */
 		reg = reg2 | (0x2 << 4) | ((pll_div.k >> 8) & 0xf);
-		snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+		snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
 		/* K [7:4] */
 		reg = reg2 | (0x1 << 4) | ((pll_div.k >> 4) & 0xf);
-		snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+		snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
 		reg = reg2 | (0x0 << 4) | (pll_div.k & 0xf); /* K [3:0] */
-		snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+		snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 	}
 
 	/* turn PLL on and select as source */
-	snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x0200, 0x0000);
-	snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0080, 0x0000);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x0200, 0x0000);
+	snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0080, 0x0000);
 	wm9713->pll_in = freq_in;
 
 	/* wait 10ms AC97 link frames for the link to stabilise */
@@ -879,8 +879,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
 static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
+	struct snd_soc_component *component = codec_dai->component;
+	return wm9713_set_pll(component, pll_id, freq_in, freq_out);
 }
 
 /*
@@ -890,10 +890,10 @@ static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
 	int tristate)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	if (tristate)
-		snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
+		snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
 				    0x6000, 0x0000);
 
 	return 0;
@@ -906,30 +906,30 @@ static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
 static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 		int div_id, int div)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
 	switch (div_id) {
 	case WM9713_PCMCLK_DIV:
-		snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, div);
+		snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, div);
 		break;
 	case WM9713_CLKA_MULT:
-		snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0002, div);
+		snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0002, div);
 		break;
 	case WM9713_CLKB_MULT:
-		snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0004, div);
+		snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0004, div);
 		break;
 	case WM9713_HIFI_DIV:
-		snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x7000, div);
+		snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x7000, div);
 		break;
 	case WM9713_PCMBCLK_DIV:
-		snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER, 0x0e00, div);
+		snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER, 0x0e00, div);
 		break;
 	case WM9713_PCMCLK_PLL_DIV:
-		snd_soc_update_bits(codec, AC97_LINE1_LEVEL,
+		snd_soc_component_update_bits(component, AC97_LINE1_LEVEL,
 				    0x007f, div | 0x60);
 		break;
 	case WM9713_HIFI_PLL_DIV:
-		snd_soc_update_bits(codec, AC97_LINE1_LEVEL,
+		snd_soc_component_update_bits(component, AC97_LINE1_LEVEL,
 				    0x007f, div | 0x70);
 		break;
 	default:
@@ -942,8 +942,8 @@ static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 {
-	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 gpio = snd_soc_read(codec, AC97_GPIO_CFG) & 0xffc5;
+	struct snd_soc_component *component = codec_dai->component;
+	u16 gpio = snd_soc_component_read32(component, AC97_GPIO_CFG) & 0xffc5;
 	u16 reg = 0x8000;
 
 	/* clock masters */
@@ -996,8 +996,8 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		break;
 	}
 
-	snd_soc_write(codec, AC97_GPIO_CFG, gpio);
-	snd_soc_write(codec, AC97_CENTER_LFE_MASTER, reg);
+	snd_soc_component_write(component, AC97_GPIO_CFG, gpio);
+	snd_soc_component_write(component, AC97_CENTER_LFE_MASTER, reg);
 	return 0;
 }
 
@@ -1005,22 +1005,22 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 
 	/* enable PCM interface in master mode */
 	switch (params_width(params)) {
 	case 16:
 		break;
 	case 20:
-		snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
+		snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
 				    0x000c, 0x0004);
 		break;
 	case 24:
-		snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
+		snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
 				    0x000c, 0x0008);
 		break;
 	case 32:
-		snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
+		snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
 				    0x000c, 0x000c);
 		break;
 	}
@@ -1030,33 +1030,33 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
 static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
 			     struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int reg;
 
-	snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		reg = AC97_PCM_FRONT_DAC_RATE;
 	else
 		reg = AC97_PCM_LR_ADC_RATE;
 
-	return snd_soc_write(codec, reg, runtime->rate);
+	return snd_soc_component_write(component, reg, runtime->rate);
 }
 
 static int ac97_aux_prepare(struct snd_pcm_substream *substream,
 			    struct snd_soc_dai *dai)
 {
-	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_component *component = dai->component;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
-	snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
-	snd_soc_update_bits(codec, AC97_PCI_SID, 0x8000, 0x8000);
+	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
+	snd_soc_component_update_bits(component, AC97_PCI_SID, 0x8000, 0x8000);
 
 	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
 		return -ENODEV;
 
-	return snd_soc_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
+	return snd_soc_component_write(component, AC97_PCM_SURR_DAC_RATE, runtime->rate);
 }
 
 #define WM9713_RATES (SNDRV_PCM_RATE_8000  |	\
@@ -1142,48 +1142,48 @@ static struct snd_soc_dai_driver wm9713_dai[] = {
 	},
 };
 
-static int wm9713_set_bias_level(struct snd_soc_codec *codec,
+static int wm9713_set_bias_level(struct snd_soc_component *component,
 				 enum snd_soc_bias_level level)
 {
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		/* enable thermal shutdown */
-		snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0xe400, 0x0000);
+		snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0xe400, 0x0000);
 		break;
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* enable master bias and vmid */
-		snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0xc400, 0x0000);
-		snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
+		snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0xc400, 0x0000);
+		snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
 		break;
 	case SND_SOC_BIAS_OFF:
 		/* disable everything including AC link */
-		snd_soc_write(codec, AC97_EXTENDED_MID, 0xffff);
-		snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
-		snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
+		snd_soc_component_write(component, AC97_EXTENDED_MID, 0xffff);
+		snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
+		snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
 		break;
 	}
 	return 0;
 }
 
-static int wm9713_soc_suspend(struct snd_soc_codec *codec)
+static int wm9713_soc_suspend(struct snd_soc_component *component)
 {
 	/* Disable everything except touchpanel - that will be handled
 	 * by the touch driver and left disabled if touch is not in
 	 * use. */
-	snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x7fff,
+	snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x7fff,
 				 0x7fff);
-	snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
-	snd_soc_write(codec, AC97_POWERDOWN, 0x6f00);
-	snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
+	snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
+	snd_soc_component_write(component, AC97_POWERDOWN, 0x6f00);
+	snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
 
 	return 0;
 }
 
-static int wm9713_soc_resume(struct snd_soc_codec *codec)
+static int wm9713_soc_resume(struct snd_soc_component *component)
 {
-	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+	struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID,
@@ -1191,24 +1191,24 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
 	if (ret < 0)
 		return ret;
 
-	snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
 	/* do we need to re-start the PLL ? */
 	if (wm9713->pll_in)
-		wm9713_set_pll(codec, 0, wm9713->pll_in, 0);
+		wm9713_set_pll(component, 0, wm9713->pll_in, 0);
 
 	/* only synchronise the codec if warm reset failed */
 	if (ret == 0) {
-		regcache_mark_dirty(codec->component.regmap);
-		snd_soc_cache_sync(codec);
+		regcache_mark_dirty(component->regmap);
+		snd_soc_component_cache_sync(component);
 	}
 
 	return ret;
 }
 
-static int wm9713_soc_probe(struct snd_soc_codec *codec)
+static int wm9713_soc_probe(struct snd_soc_component *component)
 {
-	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+	struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
 	struct regmap *regmap = NULL;
 
 	if (wm9713->mfd_pdata) {
@@ -1216,54 +1216,54 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
 		regmap = wm9713->mfd_pdata->regmap;
 	} else {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-		wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID,
+		wm9713->ac97 = snd_soc_new_ac97_component(component, WM9713_VENDOR_ID,
 						      WM9713_VENDOR_ID_MASK);
 		if (IS_ERR(wm9713->ac97))
 			return PTR_ERR(wm9713->ac97);
 		regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
 		if (IS_ERR(regmap)) {
-			snd_soc_free_ac97_codec(wm9713->ac97);
+			snd_soc_free_ac97_component(wm9713->ac97);
 			return PTR_ERR(regmap);
 		}
 #endif
 	}
 
-	snd_soc_codec_init_regmap(codec, regmap);
+	snd_soc_component_init_regmap(component, regmap);
 
 	/* unmute the adc - move to kcontrol */
-	snd_soc_update_bits(codec, AC97_CD, 0x7fff, 0x0000);
+	snd_soc_component_update_bits(component, AC97_CD, 0x7fff, 0x0000);
 
 	return 0;
 }
 
-static int wm9713_soc_remove(struct snd_soc_codec *codec)
+static void wm9713_soc_remove(struct snd_soc_component *component)
 {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+	struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
 
 	if (!wm9713->mfd_pdata) {
-		snd_soc_codec_exit_regmap(codec);
-		snd_soc_free_ac97_codec(wm9713->ac97);
+		snd_soc_component_exit_regmap(component);
+		snd_soc_free_ac97_component(wm9713->ac97);
 	}
 #endif
-	return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
-	.probe = 	wm9713_soc_probe,
-	.remove = 	wm9713_soc_remove,
-	.suspend =	wm9713_soc_suspend,
-	.resume = 	wm9713_soc_resume,
-	.set_bias_level = wm9713_set_bias_level,
-
-	.component_driver = {
-		.controls		= wm9713_snd_ac97_controls,
-		.num_controls		= ARRAY_SIZE(wm9713_snd_ac97_controls),
-		.dapm_widgets		= wm9713_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(wm9713_dapm_widgets),
-		.dapm_routes		= wm9713_audio_map,
-		.num_dapm_routes	= ARRAY_SIZE(wm9713_audio_map),
-	},
+static const struct snd_soc_component_driver soc_component_dev_wm9713 = {
+	.probe			= wm9713_soc_probe,
+	.remove			= wm9713_soc_remove,
+	.suspend		= wm9713_soc_suspend,
+	.resume			= wm9713_soc_resume,
+	.set_bias_level		= wm9713_set_bias_level,
+	.controls		= wm9713_snd_ac97_controls,
+	.num_controls		= ARRAY_SIZE(wm9713_snd_ac97_controls),
+	.dapm_widgets		= wm9713_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(wm9713_dapm_widgets),
+	.dapm_routes		= wm9713_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(wm9713_audio_map),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int wm9713_probe(struct platform_device *pdev)
@@ -1279,14 +1279,8 @@ static int wm9713_probe(struct platform_device *pdev)
 	wm9713->mfd_pdata = dev_get_platdata(&pdev->dev);
 	platform_set_drvdata(pdev, wm9713);
 
-	return snd_soc_register_codec(&pdev->dev,
-			&soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
-}
-
-static int wm9713_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_codec(&pdev->dev);
-	return 0;
+	return devm_snd_soc_register_component(&pdev->dev,
+			&soc_component_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
 }
 
 static struct platform_driver wm9713_codec_driver = {
@@ -1295,7 +1289,6 @@ static struct platform_driver wm9713_codec_driver = {
 	},
 
 	.probe = wm9713_probe,
-	.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
index 989d093..82b0927 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -605,13 +605,13 @@ static const struct {
 };
 
 static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
-				  struct snd_soc_codec *codec)
+				  struct snd_soc_component *component)
 {
 	struct dentry *root = NULL;
 	char *root_name;
 	int i;
 
-	if (!codec->component.debugfs_root) {
+	if (!component->debugfs_root) {
 		adsp_err(dsp, "No codec debugfs root\n");
 		goto err;
 	}
@@ -621,7 +621,7 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
 		goto err;
 
 	snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num);
-	root = debugfs_create_dir(root_name, codec->component.debugfs_root);
+	root = debugfs_create_dir(root_name, component->debugfs_root);
 	kfree(root_name);
 
 	if (!root)
@@ -662,7 +662,7 @@ static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
 }
 #else
 static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
-					 struct snd_soc_codec *codec)
+					 struct snd_soc_component *component)
 {
 }
 
@@ -688,9 +688,9 @@ static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
 static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-	struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+	struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw;
 
@@ -700,9 +700,9 @@ static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
 static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-	struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+	struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
 	int ret = 0;
 
 	if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw)
@@ -1215,7 +1215,7 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl)
 		break;
 	}
 
-	ret = snd_soc_add_codec_controls(dsp->codec, kcontrol, 1);
+	ret = snd_soc_add_component_controls(dsp->component, kcontrol, 1);
 	if (ret < 0)
 		goto err_kcontrol;
 
@@ -1239,9 +1239,16 @@ static int wm_coeff_init_control_caches(struct wm_adsp *dsp)
 		if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
 			continue;
 
-		ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
-		if (ret < 0)
-			return ret;
+		/*
+		 * For readable controls populate the cache from the DSP memory.
+		 * For non-readable controls the cache was zero-filled when
+		 * created so we don't need to do anything.
+		 */
+		if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) {
+			ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
+			if (ret < 0)
+				return ret;
+		}
 	}
 
 	return 0;
@@ -2398,14 +2405,14 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol,
 		   int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
 	struct wm_adsp *dsp = &dsps[w->shift];
 	struct wm_coeff_ctl *ctl;
 	int ret;
 	unsigned int val;
 
-	dsp->codec = codec;
+	dsp->component = component;
 
 	mutex_lock(&dsp->pwr_lock);
 
@@ -2635,8 +2642,8 @@ static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
 int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
 			   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = dsp->preloaded;
 
@@ -2647,9 +2654,9 @@ EXPORT_SYMBOL_GPL(wm_adsp2_preloader_get);
 int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
 			   struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	char preload[32];
@@ -2685,8 +2692,8 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event,
 			 unsigned int freq)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
 	struct wm_adsp *dsp = &dsps[w->shift];
 	struct wm_coeff_ctl *ctl;
 
@@ -2728,8 +2735,8 @@ EXPORT_SYMBOL_GPL(wm_adsp2_early_event);
 int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
 	struct wm_adsp *dsp = &dsps[w->shift];
 	int ret;
 
@@ -2843,31 +2850,31 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(wm_adsp2_event);
 
-int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec)
+int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	char preload[32];
 
 	snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num);
 	snd_soc_dapm_disable_pin(dapm, preload);
 
-	wm_adsp2_init_debugfs(dsp, codec);
+	wm_adsp2_init_debugfs(dsp, component);
 
-	dsp->codec = codec;
+	dsp->component = component;
 
-	return snd_soc_add_codec_controls(codec,
+	return snd_soc_add_component_controls(component,
 					  &wm_adsp_fw_controls[dsp->num - 1],
 					  1);
 }
-EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe);
+EXPORT_SYMBOL_GPL(wm_adsp2_component_probe);
 
-int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec)
+int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component)
 {
 	wm_adsp2_cleanup_debugfs(dsp);
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove);
+EXPORT_SYMBOL_GPL(wm_adsp2_component_remove);
 
 int wm_adsp2_init(struct wm_adsp *dsp)
 {
@@ -3253,6 +3260,13 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
 	return 0;
 }
 
+static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf)
+{
+	buf->irq_count = 0xFFFFFFFF;
+	buf->read_index = -1;
+	buf->avail = 0;
+}
+
 static int wm_adsp_buffer_init(struct wm_adsp *dsp)
 {
 	struct wm_adsp_compr_buf *buf;
@@ -3263,8 +3277,8 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp)
 		return -ENOMEM;
 
 	buf->dsp = dsp;
-	buf->read_index = -1;
-	buf->irq_count = 0xFFFFFFFF;
+
+	wm_adsp_buffer_clear(buf);
 
 	ret = wm_adsp_buffer_locate(buf);
 	if (ret < 0) {
@@ -3322,16 +3336,17 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		if (wm_adsp_compr_attached(compr))
-			break;
-
-		ret = wm_adsp_compr_attach(compr);
-		if (ret < 0) {
-			adsp_err(dsp, "Failed to link buffer and stream: %d\n",
-				 ret);
-			break;
+		if (!wm_adsp_compr_attached(compr)) {
+			ret = wm_adsp_compr_attach(compr);
+			if (ret < 0) {
+				adsp_err(dsp, "Failed to link buffer and stream: %d\n",
+					 ret);
+				break;
+			}
 		}
 
+		wm_adsp_buffer_clear(compr->buf);
+
 		/* Trigger the IRQ at one fragment of data */
 		ret = wm_adsp_buffer_write(compr->buf,
 					   HOST_BUFFER_FIELD(high_water_mark),
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 41cc11c..bc6d359 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -62,12 +62,12 @@ struct wm_adsp {
 	int type;
 	struct device *dev;
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 
-	int base;
-	int sysclk_reg;
-	int sysclk_mask;
-	int sysclk_shift;
+	unsigned int base;
+	unsigned int sysclk_reg;
+	unsigned int sysclk_mask;
+	unsigned int sysclk_shift;
 
 	struct list_head alg_regions;
 
@@ -126,8 +126,8 @@ extern const struct snd_kcontrol_new wm_adsp_fw_controls[];
 int wm_adsp1_init(struct wm_adsp *dsp);
 int wm_adsp2_init(struct wm_adsp *dsp);
 void wm_adsp2_remove(struct wm_adsp *dsp);
-int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec);
-int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec);
+int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component);
+int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component);
 int wm_adsp1_event(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol, int event);
 int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 63b2745..fed6ea9 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -60,9 +60,9 @@ static const char *speaker_mode_text[] = {
 static SOC_ENUM_SINGLE_DECL(speaker_mode,
 			    WM8993_SPKMIXR_ATTENUATION, 8, speaker_mode_text);
 
-static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
+static void wait_for_dc_servo(struct snd_soc_component *component, unsigned int op)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	unsigned int reg;
 	int count = 0;
 	int timeout;
@@ -71,9 +71,9 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 	val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
 
 	/* Trigger the command */
-	snd_soc_write(codec, WM8993_DC_SERVO_0, val);
+	snd_soc_component_write(component, WM8993_DC_SERVO_0, val);
 
-	dev_dbg(codec->dev, "Waiting for DC servo...\n");
+	dev_dbg(component->dev, "Waiting for DC servo...\n");
 
 	if (hubs->dcs_done_irq)
 		timeout = 4;
@@ -89,12 +89,12 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 		else
 			msleep(1);
 
-		reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
-		dev_dbg(codec->dev, "DC servo: %x\n", reg);
+		reg = snd_soc_component_read32(component, WM8993_DC_SERVO_0);
+		dev_dbg(component->dev, "DC servo: %x\n", reg);
 	} while (reg & op && count < timeout);
 
 	if (reg & op)
-		dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
+		dev_err(component->dev, "Timed out waiting for DC Servo %x\n",
 			op);
 }
 
@@ -108,35 +108,35 @@ irqreturn_t wm_hubs_dcs_done(int irq, void *data)
 }
 EXPORT_SYMBOL_GPL(wm_hubs_dcs_done);
 
-static bool wm_hubs_dac_hp_direct(struct snd_soc_codec *codec)
+static bool wm_hubs_dac_hp_direct(struct snd_soc_component *component)
 {
 	int reg;
 
 	/* If we're going via the mixer we'll need to do additional checks */
-	reg = snd_soc_read(codec, WM8993_OUTPUT_MIXER1);
+	reg = snd_soc_component_read32(component, WM8993_OUTPUT_MIXER1);
 	if (!(reg & WM8993_DACL_TO_HPOUT1L)) {
 		if (reg & ~WM8993_DACL_TO_MIXOUTL) {
-			dev_vdbg(codec->dev, "Analogue paths connected: %x\n",
+			dev_vdbg(component->dev, "Analogue paths connected: %x\n",
 				 reg & ~WM8993_DACL_TO_HPOUT1L);
 			return false;
 		} else {
-			dev_vdbg(codec->dev, "HPL connected to mixer\n");
+			dev_vdbg(component->dev, "HPL connected to mixer\n");
 		}
 	} else {
-		dev_vdbg(codec->dev, "HPL connected to DAC\n");
+		dev_vdbg(component->dev, "HPL connected to DAC\n");
 	}
 
-	reg = snd_soc_read(codec, WM8993_OUTPUT_MIXER2);
+	reg = snd_soc_component_read32(component, WM8993_OUTPUT_MIXER2);
 	if (!(reg & WM8993_DACR_TO_HPOUT1R)) {
 		if (reg & ~WM8993_DACR_TO_MIXOUTR) {
-			dev_vdbg(codec->dev, "Analogue paths connected: %x\n",
+			dev_vdbg(component->dev, "Analogue paths connected: %x\n",
 				 reg & ~WM8993_DACR_TO_HPOUT1R);
 			return false;
 		} else {
-			dev_vdbg(codec->dev, "HPR connected to mixer\n");
+			dev_vdbg(component->dev, "HPR connected to mixer\n");
 		}
 	} else {
-		dev_vdbg(codec->dev, "HPR connected to DAC\n");
+		dev_vdbg(component->dev, "HPR connected to DAC\n");
 	}
 
 	return true;
@@ -149,17 +149,17 @@ struct wm_hubs_dcs_cache {
 	u16 dcs_cfg;
 };
 
-static bool wm_hubs_dcs_cache_get(struct snd_soc_codec *codec,
+static bool wm_hubs_dcs_cache_get(struct snd_soc_component *component,
 				  struct wm_hubs_dcs_cache **entry)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	struct wm_hubs_dcs_cache *cache;
 	unsigned int left, right;
 
-	left = snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME);
+	left = snd_soc_component_read32(component, WM8993_LEFT_OUTPUT_VOLUME);
 	left &= WM8993_HPOUT1L_VOL_MASK;
 
-	right = snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME);
+	right = snd_soc_component_read32(component, WM8993_RIGHT_OUTPUT_VOLUME);
 	right &= WM8993_HPOUT1R_VOL_MASK;
 
 	list_for_each_entry(cache, &hubs->dcs_cache, list) {
@@ -173,22 +173,22 @@ static bool wm_hubs_dcs_cache_get(struct snd_soc_codec *codec,
 	return false;
 }
 
-static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg)
+static void wm_hubs_dcs_cache_set(struct snd_soc_component *component, u16 dcs_cfg)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	struct wm_hubs_dcs_cache *cache;
 
 	if (hubs->no_cache_dac_hp_direct)
 		return;
 
-	cache = devm_kzalloc(codec->dev, sizeof(*cache), GFP_KERNEL);
+	cache = devm_kzalloc(component->dev, sizeof(*cache), GFP_KERNEL);
 	if (!cache)
 		return;
 
-	cache->left = snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME);
+	cache->left = snd_soc_component_read32(component, WM8993_LEFT_OUTPUT_VOLUME);
 	cache->left &= WM8993_HPOUT1L_VOL_MASK;
 
-	cache->right = snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME);
+	cache->right = snd_soc_component_read32(component, WM8993_RIGHT_OUTPUT_VOLUME);
 	cache->right &= WM8993_HPOUT1R_VOL_MASK;
 
 	cache->dcs_cfg = dcs_cfg;
@@ -196,10 +196,10 @@ static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg)
 	list_add_tail(&cache->list, &hubs->dcs_cache);
 }
 
-static int wm_hubs_read_dc_servo(struct snd_soc_codec *codec,
+static int wm_hubs_read_dc_servo(struct snd_soc_component *component,
 				  u16 *reg_l, u16 *reg_r)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	u16 dcs_reg, reg;
 	int ret = 0;
 
@@ -220,14 +220,14 @@ static int wm_hubs_read_dc_servo(struct snd_soc_codec *codec,
 	 */
 	switch (hubs->dcs_readback_mode) {
 	case 0:
-		*reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+		*reg_l = snd_soc_component_read32(component, WM8993_DC_SERVO_READBACK_1)
 			& WM8993_DCS_INTEG_CHAN_0_MASK;
-		*reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+		*reg_r = snd_soc_component_read32(component, WM8993_DC_SERVO_READBACK_2)
 			& WM8993_DCS_INTEG_CHAN_1_MASK;
 		break;
 	case 2:
 	case 1:
-		reg = snd_soc_read(codec, dcs_reg);
+		reg = snd_soc_component_read32(component, dcs_reg);
 		*reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
 			>> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
 		*reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
@@ -242,9 +242,9 @@ static int wm_hubs_read_dc_servo(struct snd_soc_codec *codec,
 /*
  * Startup calibration of the DC servo
  */
-static void enable_dc_servo(struct snd_soc_codec *codec)
+static void enable_dc_servo(struct snd_soc_component *component)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	struct wm_hubs_dcs_cache *cache;
 	s8 offset;
 	u16 reg_l, reg_r, dcs_cfg, dcs_reg;
@@ -260,12 +260,12 @@ static void enable_dc_servo(struct snd_soc_codec *codec)
 
 	/* If we're using a digital only path and have a previously
 	 * callibrated DC servo offset stored then use that. */
-	if (wm_hubs_dac_hp_direct(codec) &&
-	    wm_hubs_dcs_cache_get(codec, &cache)) {
-		dev_dbg(codec->dev, "Using cached DCS offset %x for %d,%d\n",
+	if (wm_hubs_dac_hp_direct(component) &&
+	    wm_hubs_dcs_cache_get(component, &cache)) {
+		dev_dbg(component->dev, "Using cached DCS offset %x for %d,%d\n",
 			cache->dcs_cfg, cache->left, cache->right);
-		snd_soc_write(codec, dcs_reg, cache->dcs_cfg);
-		wait_for_dc_servo(codec,
+		snd_soc_component_write(component, dcs_reg, cache->dcs_cfg);
+		wait_for_dc_servo(component,
 				  WM8993_DCS_TRIG_DAC_WR_0 |
 				  WM8993_DCS_TRIG_DAC_WR_1);
 		return;
@@ -273,48 +273,48 @@ static void enable_dc_servo(struct snd_soc_codec *codec)
 
 	if (hubs->series_startup) {
 		/* Set for 32 series updates */
-		snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
+		snd_soc_component_update_bits(component, WM8993_DC_SERVO_1,
 				    WM8993_DCS_SERIES_NO_01_MASK,
 				    32 << WM8993_DCS_SERIES_NO_01_SHIFT);
-		wait_for_dc_servo(codec,
+		wait_for_dc_servo(component,
 				  WM8993_DCS_TRIG_SERIES_0 |
 				  WM8993_DCS_TRIG_SERIES_1);
 	} else {
-		wait_for_dc_servo(codec,
+		wait_for_dc_servo(component,
 				  WM8993_DCS_TRIG_STARTUP_0 |
 				  WM8993_DCS_TRIG_STARTUP_1);
 	}
 
-	if (wm_hubs_read_dc_servo(codec, &reg_l, &reg_r) < 0)
+	if (wm_hubs_read_dc_servo(component, &reg_l, &reg_r) < 0)
 		return;
 
-	dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
+	dev_dbg(component->dev, "DCS input: %x %x\n", reg_l, reg_r);
 
 	/* Apply correction to DC servo result */
 	if (hubs->dcs_codes_l || hubs->dcs_codes_r) {
-		dev_dbg(codec->dev,
+		dev_dbg(component->dev,
 			"Applying %d/%d code DC servo correction\n",
 			hubs->dcs_codes_l, hubs->dcs_codes_r);
 
 		/* HPOUT1R */
 		offset = (s8)reg_r;
-		dev_dbg(codec->dev, "DCS right %d->%d\n", offset,
+		dev_dbg(component->dev, "DCS right %d->%d\n", offset,
 			offset + hubs->dcs_codes_r);
 		offset += hubs->dcs_codes_r;
 		dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
 
 		/* HPOUT1L */
 		offset = (s8)reg_l;
-		dev_dbg(codec->dev, "DCS left %d->%d\n", offset,
+		dev_dbg(component->dev, "DCS left %d->%d\n", offset,
 			offset + hubs->dcs_codes_l);
 		offset += hubs->dcs_codes_l;
 		dcs_cfg |= (u8)offset;
 
-		dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
+		dev_dbg(component->dev, "DCS result: %x\n", dcs_cfg);
 
 		/* Do it */
-		snd_soc_write(codec, dcs_reg, dcs_cfg);
-		wait_for_dc_servo(codec,
+		snd_soc_component_write(component, dcs_reg, dcs_cfg);
+		wait_for_dc_servo(component,
 				  WM8993_DCS_TRIG_DAC_WR_0 |
 				  WM8993_DCS_TRIG_DAC_WR_1);
 	} else {
@@ -324,8 +324,8 @@ static void enable_dc_servo(struct snd_soc_codec *codec)
 
 	/* Save the callibrated offset if we're in class W mode and
 	 * therefore don't have any analogue signal mixed in. */
-	if (wm_hubs_dac_hp_direct(codec))
-		wm_hubs_dcs_cache_set(codec, dcs_cfg);
+	if (wm_hubs_dac_hp_direct(component))
+		wm_hubs_dcs_cache_set(component, dcs_cfg);
 }
 
 /*
@@ -334,8 +334,8 @@ static void enable_dc_servo(struct snd_soc_codec *codec)
 static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = snd_soc_put_volsw(kcontrol, ucontrol);
@@ -346,9 +346,9 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
 		return ret;
 
 	/* Only need to do this if the outputs are active */
-	if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
+	if (snd_soc_component_read32(component, WM8993_POWER_MANAGEMENT_1)
 	    & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
-		snd_soc_update_bits(codec,
+		snd_soc_component_update_bits(component,
 				    WM8993_DC_SERVO_0,
 				    WM8993_DCS_TRIG_SINGLE_0 |
 				    WM8993_DCS_TRIG_SINGLE_1,
@@ -499,8 +499,8 @@ SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
 static int hp_supply_event(struct snd_soc_dapm_widget *w,
 			   struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -509,28 +509,28 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w,
 			break;
 		case 1:
 			/* Enable the headphone amp */
-			snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
+			snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_1,
 					    WM8993_HPOUT1L_ENA |
 					    WM8993_HPOUT1R_ENA,
 					    WM8993_HPOUT1L_ENA |
 					    WM8993_HPOUT1R_ENA);
 
 			/* Enable the second stage */
-			snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
+			snd_soc_component_update_bits(component, WM8993_ANALOGUE_HP_0,
 					    WM8993_HPOUT1L_DLY |
 					    WM8993_HPOUT1R_DLY,
 					    WM8993_HPOUT1L_DLY |
 					    WM8993_HPOUT1R_DLY);
 			break;
 		default:
-			dev_err(codec->dev, "Unknown HP startup mode %d\n",
+			dev_err(component->dev, "Unknown HP startup mode %d\n",
 				hubs->hp_startup_mode);
 			break;
 		}
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, WM8993_CHARGE_PUMP_1,
 				    WM8993_CP_ENA, 0);
 		break;
 	}
@@ -541,47 +541,47 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w,
 static int hp_event(struct snd_soc_dapm_widget *w,
 		    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	unsigned int reg = snd_soc_read(codec, WM8993_ANALOGUE_HP_0);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	unsigned int reg = snd_soc_component_read32(component, WM8993_ANALOGUE_HP_0);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
+		snd_soc_component_update_bits(component, WM8993_CHARGE_PUMP_1,
 				    WM8993_CP_ENA, WM8993_CP_ENA);
 
 		msleep(5);
 
-		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_1,
 				    WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
 				    WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA);
 
 		reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
-		snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
+		snd_soc_component_write(component, WM8993_ANALOGUE_HP_0, reg);
 
-		snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
+		snd_soc_component_update_bits(component, WM8993_DC_SERVO_1,
 				    WM8993_DCS_TIMER_PERIOD_01_MASK, 0);
 
-		enable_dc_servo(codec);
+		enable_dc_servo(component);
 
 		reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
 			WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
-		snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
+		snd_soc_component_write(component, WM8993_ANALOGUE_HP_0, reg);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
+		snd_soc_component_update_bits(component, WM8993_ANALOGUE_HP_0,
 				    WM8993_HPOUT1L_OUTP |
 				    WM8993_HPOUT1R_OUTP |
 				    WM8993_HPOUT1L_RMV_SHORT |
 				    WM8993_HPOUT1R_RMV_SHORT, 0);
 
-		snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
+		snd_soc_component_update_bits(component, WM8993_ANALOGUE_HP_0,
 				    WM8993_HPOUT1L_DLY |
 				    WM8993_HPOUT1R_DLY, 0);
 
-		snd_soc_write(codec, WM8993_DC_SERVO_0, 0);
+		snd_soc_component_write(component, WM8993_DC_SERVO_0, 0);
 
-		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
+		snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_1,
 				    WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
 				    0);
 		break;
@@ -593,18 +593,18 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 static int earpiece_event(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *control, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	u16 reg = snd_soc_read(codec, WM8993_ANTIPOP1) & ~WM8993_HPOUT2_IN_ENA;
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	u16 reg = snd_soc_component_read32(component, WM8993_ANTIPOP1) & ~WM8993_HPOUT2_IN_ENA;
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		reg |= WM8993_HPOUT2_IN_ENA;
-		snd_soc_write(codec, WM8993_ANTIPOP1, reg);
+		snd_soc_component_write(component, WM8993_ANTIPOP1, reg);
 		udelay(50);
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
-		snd_soc_write(codec, WM8993_ANTIPOP1, reg);
+		snd_soc_component_write(component, WM8993_ANTIPOP1, reg);
 		break;
 
 	default:
@@ -618,8 +618,8 @@ static int earpiece_event(struct snd_soc_dapm_widget *w,
 static int lineout_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *control, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	bool *flag;
 
 	switch (w->shift) {
@@ -648,8 +648,8 @@ static int lineout_event(struct snd_soc_dapm_widget *w,
 static int micbias_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 
 	switch (w->shift) {
 	case WM8993_MICB1_ENA_SHIFT:
@@ -667,26 +667,26 @@ static int micbias_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-void wm_hubs_update_class_w(struct snd_soc_codec *codec)
+void wm_hubs_update_class_w(struct snd_soc_component *component)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	int enable = WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ;
 
-	if (!wm_hubs_dac_hp_direct(codec))
+	if (!wm_hubs_dac_hp_direct(component))
 		enable = false;
 
-	if (hubs->check_class_w_digital && !hubs->check_class_w_digital(codec))
+	if (hubs->check_class_w_digital && !hubs->check_class_w_digital(component))
 		enable = false;
 
-	dev_vdbg(codec->dev, "Class W %s\n", enable ? "enabled" : "disabled");
+	dev_vdbg(component->dev, "Class W %s\n", enable ? "enabled" : "disabled");
 
-	snd_soc_update_bits(codec, WM8993_CLASS_W_0,
+	snd_soc_component_update_bits(component, WM8993_CLASS_W_0,
 			    WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ, enable);
 
-	snd_soc_write(codec, WM8993_LEFT_OUTPUT_VOLUME,
-		      snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME));
-	snd_soc_write(codec, WM8993_RIGHT_OUTPUT_VOLUME,
-		      snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME));
+	snd_soc_component_write(component, WM8993_LEFT_OUTPUT_VOLUME,
+		      snd_soc_component_read32(component, WM8993_LEFT_OUTPUT_VOLUME));
+	snd_soc_component_write(component, WM8993_RIGHT_OUTPUT_VOLUME,
+		      snd_soc_component_read32(component, WM8993_RIGHT_OUTPUT_VOLUME));
 }
 EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
 
@@ -697,12 +697,12 @@ EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
 static int class_w_put_volsw(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
 	int ret;
 
 	ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
 
-	wm_hubs_update_class_w(codec);
+	wm_hubs_update_class_w(component);
 
 	return ret;
 }
@@ -717,12 +717,12 @@ static int class_w_put_volsw(struct snd_kcontrol *kcontrol,
 static int class_w_put_double(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
 	int ret;
 
 	ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
 
-	wm_hubs_update_class_w(codec);
+	wm_hubs_update_class_w(component);
 
 	return ret;
 }
@@ -1113,40 +1113,40 @@ static const struct snd_soc_dapm_route lineout2_se_routes[] = {
 	{ "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" },
 };
 
-int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
+int wm_hubs_add_analogue_controls(struct snd_soc_component *component)
 {
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
 	/* Latch volume update bits & default ZC on */
-	snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
 			    WM8993_IN1_VU, WM8993_IN1_VU);
-	snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_1_2_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_RIGHT_LINE_INPUT_1_2_VOLUME,
 			    WM8993_IN1_VU, WM8993_IN1_VU);
-	snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_3_4_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_LEFT_LINE_INPUT_3_4_VOLUME,
 			    WM8993_IN2_VU, WM8993_IN2_VU);
-	snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME,
 			    WM8993_IN2_VU, WM8993_IN2_VU);
 
-	snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_LEFT,
+	snd_soc_component_update_bits(component, WM8993_SPEAKER_VOLUME_LEFT,
 			    WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
-	snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT,
+	snd_soc_component_update_bits(component, WM8993_SPEAKER_VOLUME_RIGHT,
 			    WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
 
-	snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_LEFT_OUTPUT_VOLUME,
 			    WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC,
 			    WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC);
-	snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_RIGHT_OUTPUT_VOLUME,
 			    WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC,
 			    WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC);
 
-	snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_LEFT_OPGA_VOLUME,
 			    WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU,
 			    WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU);
-	snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME,
+	snd_soc_component_update_bits(component, WM8993_RIGHT_OPGA_VOLUME,
 			    WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
 			    WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
 
-	snd_soc_add_codec_controls(codec, analogue_snd_controls,
+	snd_soc_add_component_controls(component, analogue_snd_controls,
 			     ARRAY_SIZE(analogue_snd_controls));
 
 	snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
@@ -1155,13 +1155,13 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
 
-int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
+int wm_hubs_add_analogue_routes(struct snd_soc_component *component,
 				int lineout1_diff, int lineout2_diff)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-	hubs->codec = codec;
+	hubs->component = component;
 
 	INIT_LIST_HEAD(&hubs->dcs_cache);
 	init_completion(&hubs->dcs_done);
@@ -1191,14 +1191,14 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
 
-int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
+int wm_hubs_handle_analogue_pdata(struct snd_soc_component *component,
 				  int lineout1_diff, int lineout2_diff,
 				  int lineout1fb, int lineout2fb,
 				  int jd_scthr, int jd_thr,
 				  int micbias1_delay, int micbias2_delay,
 				  int micbias1_lvl, int micbias2_lvl)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 
 	hubs->lineout1_se = !lineout1_diff;
 	hubs->lineout2_se = !lineout2_diff;
@@ -1206,28 +1206,28 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
 	hubs->micb2_delay = micbias2_delay;
 
 	if (!lineout1_diff)
-		snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
+		snd_soc_component_update_bits(component, WM8993_LINE_MIXER1,
 				    WM8993_LINEOUT1_MODE,
 				    WM8993_LINEOUT1_MODE);
 	if (!lineout2_diff)
-		snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
+		snd_soc_component_update_bits(component, WM8993_LINE_MIXER2,
 				    WM8993_LINEOUT2_MODE,
 				    WM8993_LINEOUT2_MODE);
 
 	if (!lineout1_diff && !lineout2_diff)
-		snd_soc_update_bits(codec, WM8993_ANTIPOP1,
+		snd_soc_component_update_bits(component, WM8993_ANTIPOP1,
 				    WM8993_LINEOUT_VMID_BUF_ENA,
 				    WM8993_LINEOUT_VMID_BUF_ENA);
 
 	if (lineout1fb)
-		snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
+		snd_soc_component_update_bits(component, WM8993_ADDITIONAL_CONTROL,
 				    WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
 
 	if (lineout2fb)
-		snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
+		snd_soc_component_update_bits(component, WM8993_ADDITIONAL_CONTROL,
 				    WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
 
-	snd_soc_update_bits(codec, WM8993_MICBIAS,
+	snd_soc_component_update_bits(component, WM8993_MICBIAS,
 			    WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
 			    WM8993_MICB1_LVL | WM8993_MICB2_LVL,
 			    jd_scthr << WM8993_JD_SCTHR_SHIFT |
@@ -1239,9 +1239,9 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
 
-void wm_hubs_vmid_ena(struct snd_soc_codec *codec)
+void wm_hubs_vmid_ena(struct snd_soc_component *component)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	int val = 0;
 
 	if (hubs->lineout1_se)
@@ -1251,20 +1251,20 @@ void wm_hubs_vmid_ena(struct snd_soc_codec *codec)
 		val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
 
 	/* Enable the line outputs while we power up */
-	snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val);
+	snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_3, val, val);
 }
 EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena);
 
-void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
+void wm_hubs_set_bias_level(struct snd_soc_component *component,
 			    enum snd_soc_bias_level level)
 {
-	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
 	int mask, val;
 
 	switch (level) {
 	case SND_SOC_BIAS_STANDBY:
 		/* Clamp the inputs to VMID while we ramp to charge caps */
-		snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
+		snd_soc_component_update_bits(component, WM8993_INPUTS_CLAMP_REG,
 				    WM8993_INPUTS_CLAMP, WM8993_INPUTS_CLAMP);
 		break;
 
@@ -1291,11 +1291,11 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
 		if (hubs->lineout2_se && hubs->lineout2p_ena)
 			val |= WM8993_LINEOUT2P_ENA;
 
-		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3,
+		snd_soc_component_update_bits(component, WM8993_POWER_MANAGEMENT_3,
 				    mask, val);
 
 		/* Remove the input clamps */
-		snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
+		snd_soc_component_update_bits(component, WM8993_INPUTS_CLAMP_REG,
 				    WM8993_INPUTS_CLAMP, 0);
 		break;
 
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 24c763d..ee339ad 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -19,7 +19,7 @@
 #include <linux/list.h>
 #include <sound/control.h>
 
-struct snd_soc_codec;
+struct snd_soc_component;
 
 extern const unsigned int wm_hubs_spkmix_tlv[];
 
@@ -34,7 +34,7 @@ struct wm_hubs_data {
 
 	bool no_cache_dac_hp_direct;
 	struct list_head dcs_cache;
-	bool (*check_class_w_digital)(struct snd_soc_codec *);
+	bool (*check_class_w_digital)(struct snd_soc_component *);
 
 	int micb1_delay;
 	int micb2_delay;
@@ -50,12 +50,12 @@ struct wm_hubs_data {
 	bool dcs_done_irq;
 	struct completion dcs_done;
 
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 };
 
-extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
-extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
-extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
+extern int wm_hubs_add_analogue_controls(struct snd_soc_component *);
+extern int wm_hubs_add_analogue_routes(struct snd_soc_component *, int, int);
+extern int wm_hubs_handle_analogue_pdata(struct snd_soc_component *,
 					 int lineout1_diff, int lineout2_diff,
 					 int lineout1fb, int lineout2fb,
 					 int jd_scthr, int jd_thr,
@@ -63,10 +63,10 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
 					 int micbias1_lvl, int micbias2_lvl);
 
 extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
-extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec);
-extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
+extern void wm_hubs_vmid_ena(struct snd_soc_component *component);
+extern void wm_hubs_set_bias_level(struct snd_soc_component *component,
 				   enum snd_soc_bias_level level);
-extern void wm_hubs_update_class_w(struct snd_soc_codec *codec);
+extern void wm_hubs_update_class_w(struct snd_soc_component *component);
 
 extern const struct snd_kcontrol_new wm_hubs_hpl_mux;
 extern const struct snd_kcontrol_new wm_hubs_hpr_mux;
diff --git a/sound/soc/codecs/zx_aud96p22.c b/sound/soc/codecs/zx_aud96p22.c
index ca1932d..7a2d6ea 100644
--- a/sound/soc/codecs/zx_aud96p22.c
+++ b/sound/soc/codecs/zx_aud96p22.c
@@ -57,8 +57,8 @@ struct aud96p22_priv {
 static int aud96p22_adc_event(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct aud96p22_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct aud96p22_priv *priv = snd_soc_component_get_drvdata(component);
 	struct regmap *regmap = priv->regmap;
 
 	if (event != SND_SOC_DAPM_POST_PMU)
@@ -74,8 +74,8 @@ static int aud96p22_adc_event(struct snd_soc_dapm_widget *w,
 static int aud96p22_dac_event(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-	struct aud96p22_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct aud96p22_priv *priv = snd_soc_component_get_drvdata(component);
 	struct regmap *regmap = priv->regmap;
 
 	if (event != SND_SOC_DAPM_POST_PMU)
@@ -261,20 +261,22 @@ static const struct snd_soc_dapm_route aud96p22_dapm_routes[] = {
 	{ "LINEOUTMN", NULL, "LD2" },
 };
 
-static const struct snd_soc_codec_driver aud96p22_driver = {
-	.component_driver = {
-		.controls = aud96p22_snd_controls,
-		.num_controls = ARRAY_SIZE(aud96p22_snd_controls),
-		.dapm_widgets = aud96p22_dapm_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(aud96p22_dapm_widgets),
-		.dapm_routes = aud96p22_dapm_routes,
-		.num_dapm_routes = ARRAY_SIZE(aud96p22_dapm_routes),
-	},
+static const struct snd_soc_component_driver aud96p22_driver = {
+	.controls		= aud96p22_snd_controls,
+	.num_controls		= ARRAY_SIZE(aud96p22_snd_controls),
+	.dapm_widgets		= aud96p22_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(aud96p22_dapm_widgets),
+	.dapm_routes		= aud96p22_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(aud96p22_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int aud96p22_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct aud96p22_priv *priv = snd_soc_codec_get_drvdata(dai->codec);
+	struct aud96p22_priv *priv = snd_soc_component_get_drvdata(dai->component);
 	struct regmap *regmap = priv->regmap;
 	unsigned int val;
 
@@ -367,9 +369,9 @@ static int aud96p22_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, priv);
 
-	ret = snd_soc_register_codec(dev, &aud96p22_driver, &aud96p22_dai, 1);
+	ret = devm_snd_soc_register_component(dev, &aud96p22_driver, &aud96p22_dai, 1);
 	if (ret) {
-		dev_err(dev, "failed to register codec: %d\n", ret);
+		dev_err(dev, "failed to register component: %d\n", ret);
 		return ret;
 	}
 
@@ -378,7 +380,6 @@ static int aud96p22_i2c_probe(struct i2c_client *i2c,
 
 static int aud96p22_i2c_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&i2c->dev);
 	return 0;
 }
 
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 3849616..807040b 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -34,6 +34,7 @@
 #include "edma-pcm.h"
 #include "davinci-i2s.h"
 
+#define DRV_NAME "davinci-i2s"
 
 /*
  * NOTE:  terminology here is confusing.
@@ -190,7 +191,7 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
 		struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_platform *platform = rtd->platform;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 	int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 	u32 spcr;
 	u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
@@ -211,8 +212,8 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
 	if (playback) {
 		/* Stop the DMA to avoid data loss */
 		/* while the transmitter is out of reset to handle XSYNCERR */
-		if (platform->driver->ops->trigger) {
-			int ret = platform->driver->ops->trigger(substream,
+		if (component->driver->ops->trigger) {
+			int ret = component->driver->ops->trigger(substream,
 				SNDRV_PCM_TRIGGER_STOP);
 			if (ret < 0)
 				printk(KERN_DEBUG "Playback DMA stop failed\n");
@@ -233,8 +234,8 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
 		toggle_clock(dev, playback);
 
 		/* Restart the DMA */
-		if (platform->driver->ops->trigger) {
-			int ret = platform->driver->ops->trigger(substream,
+		if (component->driver->ops->trigger) {
+			int ret = component->driver->ops->trigger(substream,
 				SNDRV_PCM_TRIGGER_START);
 			if (ret < 0)
 				printk(KERN_DEBUG "Playback DMA start failed\n");
@@ -651,7 +652,7 @@ static struct snd_soc_dai_driver davinci_i2s_dai = {
 };
 
 static const struct snd_soc_component_driver davinci_i2s_component = {
-	.name		= "davinci-i2s",
+	.name		= DRV_NAME,
 };
 
 static int davinci_i2s_probe(struct platform_device *pdev)
diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
index e27e21f..65112b9 100644
--- a/sound/soc/dwc/dwc-i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
@@ -491,6 +491,10 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
 			dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
 		comp1 = comp1 & ~BIT(5);
 
+	if (dev->capability & DWC_I2S_PLAY &&
+			dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
+		comp1 = comp1 & ~BIT(6);
+
 	if (COMP1_TX_ENABLED(comp1)) {
 		dev_dbg(dev->dev, " designware: play supported\n");
 		idx = COMP1_TX_WORDSIZE_0(comp1);
diff --git a/sound/soc/dwc/dwc-pcm.c b/sound/soc/dwc/dwc-pcm.c
index 406fd867..2cc9632 100644
--- a/sound/soc/dwc/dwc-pcm.c
+++ b/sound/soc/dwc/dwc-pcm.c
@@ -269,7 +269,7 @@ static const struct snd_pcm_ops dw_pcm_ops = {
 	.pointer = dw_pcm_pointer,
 };
 
-static const struct snd_soc_platform_driver dw_pcm_platform = {
+static const struct snd_soc_component_driver dw_pcm_component = {
 	.pcm_new = dw_pcm_new,
 	.pcm_free = dw_pcm_free,
 	.ops = &dw_pcm_ops,
@@ -277,5 +277,6 @@ static const struct snd_soc_platform_driver dw_pcm_platform = {
 
 int dw_pcm_register(struct platform_device *pdev)
 {
-	return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform);
+	return devm_snd_soc_register_component(&pdev->dev, &dw_pcm_component,
+					       NULL, 0);
 }
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 37f9b62..6ec19fb 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -231,17 +231,6 @@
 	  Enable I2S based access to the TLV320AIC23B codec attached
 	  to the SSI interface
 
-config SND_SOC_IMX_WM8962
-	tristate "SoC Audio support for i.MX boards with wm8962"
-	depends on OF && I2C && INPUT
-	select SND_SOC_WM8962
-	select SND_SOC_IMX_PCM_DMA
-	select SND_SOC_IMX_AUDMUX
-	select SND_SOC_FSL_SSI
-	help
-	  Say Y if you want to add support for SoC audio on an i.MX board with
-	  a wm8962 codec.
-
 config SND_SOC_IMX_ES8328
 	tristate "SoC Audio support for i.MX boards with the ES8328 codec"
 	depends on OF && (I2C || SPI)
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index c67bf11..de94fa0 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -55,7 +55,6 @@
 snd-soc-wm1133-ev1-objs := wm1133-ev1.o
 snd-soc-imx-es8328-objs := imx-es8328.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
-snd-soc-imx-wm8962-objs := imx-wm8962.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
 
@@ -65,6 +64,5 @@
 obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
 obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
-obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 989be51..4a6750a 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -91,9 +91,9 @@ struct fsl_asoc_card_priv {
 	struct cpu_priv cpu_priv;
 	struct snd_soc_card card;
 	u32 sample_rate;
-	u32 sample_format;
+	snd_pcm_format_t sample_format;
 	u32 asrc_rate;
-	u32 asrc_format;
+	snd_pcm_format_t asrc_format;
 	u32 dai_fmt;
 	char name[32];
 };
@@ -199,7 +199,7 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 
 	mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 	snd_mask_none(mask);
-	snd_mask_set(mask, priv->asrc_format);
+	snd_mask_set(mask, (__force int)priv->asrc_format);
 
 	return 0;
 }
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 806d399..adfb813 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -582,10 +582,6 @@ static struct snd_soc_dai_driver fsl_asrc_dai = {
 	.ops = &fsl_asrc_dai_ops,
 };
 
-static const struct snd_soc_component_driver fsl_asrc_component = {
-	.name = "fsl-asrc-dai",
-};
-
 static bool fsl_asrc_readable_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
@@ -927,12 +923,6 @@ static int fsl_asrc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = devm_snd_soc_register_platform(&pdev->dev, &fsl_asrc_platform);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register ASoC platform\n");
-		return ret;
-	}
-
 	return 0;
 }
 
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 2c5856a..d558dd5 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -462,6 +462,7 @@ struct fsl_asrc {
 	u32 regcache_cfg;
 };
 
-extern struct snd_soc_platform_driver fsl_asrc_platform;
+#define DRV_NAME "fsl-asrc-dai"
+extern struct snd_soc_component_driver fsl_asrc_component;
 struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir);
 #endif /* _FSL_ASRC_H */
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index e1b97e5..565e16d8 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -64,7 +64,8 @@ static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct fsl_asrc_pair *pair = runtime->private_data;
-	struct device *dev = rtd->platform->dev;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct device *dev = component->dev;
 	unsigned long flags = DMA_CTRL_ACK;
 
 	/* Prepare and submit Front-End DMA channel */
@@ -137,12 +138,13 @@ static int fsl_asrc_dma_hw_params(struct snd_pcm_substream *substream,
 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 	struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL;
 	struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct fsl_asrc_pair *pair = runtime->private_data;
 	struct fsl_asrc *asrc_priv = pair->asrc_priv;
 	struct dma_slave_config config_fe, config_be;
 	enum asrc_pair_index index = pair->index;
-	struct device *dev = rtd->platform->dev;
+	struct device *dev = component->dev;
 	int stream = substream->stream;
 	struct imx_dma_data *tmp_data;
 	struct snd_soc_dpcm *dpcm;
@@ -274,7 +276,8 @@ static int fsl_asrc_dma_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct device *dev = rtd->platform->dev;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct device *dev = component->dev;
 	struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
 	struct fsl_asrc_pair *pair;
 
@@ -381,9 +384,10 @@ static void fsl_asrc_dma_pcm_free(struct snd_pcm *pcm)
 	}
 }
 
-struct snd_soc_platform_driver fsl_asrc_platform = {
+struct snd_soc_component_driver fsl_asrc_component = {
+	.name		= DRV_NAME,
 	.ops		= &fsl_asrc_dma_pcm_ops,
 	.pcm_new	= fsl_asrc_dma_pcm_new,
 	.pcm_free	= fsl_asrc_dma_pcm_free,
 };
-EXPORT_SYMBOL_GPL(fsl_asrc_platform);
+EXPORT_SYMBOL_GPL(fsl_asrc_component);
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 8c2981b..78871de 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -37,6 +37,8 @@
 #include "fsl_dma.h"
 #include "fsl_ssi.h"	/* For the offset of stx0 and srx0 */
 
+#define DRV_NAME "fsl_dma"
+
 /*
  * The formats that the DMA controller supports, which is anything
  * that is 8, 16, or 32 bits.
@@ -56,7 +58,7 @@
 			    SNDRV_PCM_FMTBIT_U32_LE     | \
 			    SNDRV_PCM_FMTBIT_U32_BE)
 struct dma_object {
-	struct snd_soc_platform_driver dai;
+	struct snd_soc_component_driver dai;
 	dma_addr_t ssi_stx_phys;
 	dma_addr_t ssi_srx_phys;
 	unsigned int ssi_fifo_depth;
@@ -203,7 +205,8 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
 	struct fsl_dma_private *dma_private = dev_id;
 	struct snd_pcm_substream *substream = dma_private->substream;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct device *dev = rtd->platform->dev;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct device *dev = component->dev;
 	struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
 	irqreturn_t ret = IRQ_NONE;
 	u32 sr, sr2 = 0;
@@ -385,9 +388,10 @@ static int fsl_dma_open(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct device *dev = rtd->platform->dev;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct device *dev = component->dev;
 	struct dma_object *dma =
-		container_of(rtd->platform->driver, struct dma_object, dai);
+		container_of(component->driver, struct dma_object, dai);
 	struct fsl_dma_private *dma_private;
 	struct ccsr_dma_channel __iomem *dma_channel;
 	dma_addr_t ld_buf_phys;
@@ -539,7 +543,8 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct fsl_dma_private *dma_private = runtime->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct device *dev = rtd->platform->dev;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct device *dev = component->dev;
 
 	/* Number of bits per sample */
 	unsigned int sample_bits =
@@ -702,7 +707,8 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct fsl_dma_private *dma_private = runtime->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct device *dev = rtd->platform->dev;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct device *dev = component->dev;
 	struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
 	dma_addr_t position;
 	snd_pcm_uframes_t frames;
@@ -799,9 +805,10 @@ static int fsl_dma_close(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct fsl_dma_private *dma_private = runtime->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct device *dev = rtd->platform->dev;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct device *dev = component->dev;
 	struct dma_object *dma =
-		container_of(rtd->platform->driver, struct dma_object, dai);
+		container_of(component->driver, struct dma_object, dai);
 
 	if (dma_private) {
 		if (dma_private->irq)
@@ -879,7 +886,7 @@ static const struct snd_pcm_ops fsl_dma_ops = {
 };
 
 static int fsl_soc_dma_probe(struct platform_device *pdev)
- {
+{
 	struct dma_object *dma;
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *ssi_np;
@@ -908,6 +915,7 @@ static int fsl_soc_dma_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	dma->dai.name = DRV_NAME;
 	dma->dai.ops = &fsl_dma_ops;
 	dma->dai.pcm_new = fsl_dma_new;
 	dma->dai.pcm_free = fsl_dma_free_dma_buffers;
@@ -925,7 +933,7 @@ static int fsl_soc_dma_probe(struct platform_device *pdev)
 
 	of_node_put(ssi_np);
 
-	ret = snd_soc_register_platform(&pdev->dev, &dma->dai);
+	ret = devm_snd_soc_register_component(&pdev->dev, &dma->dai, NULL, 0);
 	if (ret) {
 		dev_err(&pdev->dev, "could not register platform\n");
 		kfree(dma);
@@ -944,7 +952,6 @@ static int fsl_soc_dma_remove(struct platform_device *pdev)
 {
 	struct dma_object *dma = dev_get_drvdata(&pdev->dev);
 
-	snd_soc_unregister_platform(&pdev->dev);
 	iounmap(dma->channel);
 	irq_dispose_mapping(dma->irq);
 	kfree(dma);
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index cef79a1..40a7004 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -788,7 +788,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	struct fsl_esai *esai_priv;
 	struct resource *res;
-	const uint32_t *iprop;
+	const __be32 *iprop;
 	void __iomem *regs;
 	int irq, ret;
 
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index aecd00f..0823b08 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -56,6 +56,10 @@
 #include "fsl_ssi.h"
 #include "imx-pcm.h"
 
+/* Define RX and TX to index ssi->regvals array; Can be 0 or 1 only */
+#define RX 0
+#define TX 1
+
 /**
  * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
  *
@@ -86,6 +90,16 @@
 	 SNDRV_PCM_FMTBIT_S24_LE)
 #endif
 
+/*
+ * In AC97 mode, TXDIR bit is forced to 0 and TFDIR bit is forced to 1:
+ *  - SSI inputs external bit clock and outputs frame sync clock -- CBM_CFS
+ *  - Also have NB_NF to mark these two clocks will not be inverted
+ */
+#define FSLSSI_AC97_DAIFMT \
+	(SND_SOC_DAIFMT_AC97 | \
+	 SND_SOC_DAIFMT_CBM_CFS | \
+	 SND_SOC_DAIFMT_NB_NF)
+
 #define FSLSSI_SIER_DBG_RX_FLAGS \
 	(SSI_SIER_RFF0_EN | \
 	 SSI_SIER_RLS_EN | \
@@ -201,7 +215,9 @@ struct fsl_ssi_soc_data {
  * @cpu_dai_drv: CPU DAI driver for this device
  *
  * @dai_fmt: DAI configuration this device is currently used with
+ * @streams: Mask of current active streams: BIT(TX) and BIT(RX)
  * @i2s_net: I2S and Network mode configurations of SCR register
+ * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
  * @use_dma: DMA is used or FIQ with stream filter
  * @use_dual_fifo: DMA with support for dual FIFO mode
  * @has_ipg_clk_name: If "ipg" is in the clock name list of device tree
@@ -223,8 +239,12 @@ struct fsl_ssi_soc_data {
  *
  * @fiq_params: FIQ stream filtering parameters
  *
- * @pdev: Pointer to pdev when using fsl-ssi as sound card (ppc only)
- *        TODO: Should be replaced with simple-sound-card
+ * @card_pdev: Platform_device pointer to register a sound card for PowerPC or
+ *             to register a CODEC platform device for AC97
+ * @card_name: Platform_device name to register a sound card for PowerPC or
+ *             to register a CODEC platform device for AC97
+ * @card_idx: The index of SSI to register a sound card for PowerPC or
+ *            to register a CODEC platform device for AC97
  *
  * @dbg_stats: Debugging statistics
  *
@@ -245,7 +265,9 @@ struct fsl_ssi {
 	struct snd_soc_dai_driver cpu_dai_drv;
 
 	unsigned int dai_fmt;
+	u8 streams;
 	u8 i2s_net;
+	bool synchronous;
 	bool use_dma;
 	bool use_dual_fifo;
 	bool has_ipg_clk_name;
@@ -267,7 +289,9 @@ struct fsl_ssi {
 
 	struct imx_pcm_fiq_params fiq_params;
 
-	struct platform_device *pdev;
+	struct platform_device *card_pdev;
+	char card_name[32];
+	u32 card_idx;
 
 	struct fsl_ssi_dbg dbg_stats;
 
@@ -376,181 +400,172 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 }
 
 /**
- * Enable or disable all rx/tx config flags at once
+ * Set SCR, SIER, STCR and SRCR registers with cached values in regvals
+ *
+ * Notes:
+ * 1) For offline_config SoCs, enable all necessary bits of both streams
+ *    when 1st stream starts, even if the opposite stream will not start
+ * 2) It also clears FIFO before setting regvals; SOR is safe to set online
  */
-static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable)
+static void fsl_ssi_config_enable(struct fsl_ssi *ssi, bool tx)
 {
-	struct regmap *regs = ssi->regs;
 	struct fsl_ssi_regvals *vals = ssi->regvals;
+	int dir = tx ? TX : RX;
+	u32 sier, srcr, stcr;
 
-	if (enable) {
-		regmap_update_bits(regs, REG_SSI_SIER,
-				   vals[RX].sier | vals[TX].sier,
-				   vals[RX].sier | vals[TX].sier);
-		regmap_update_bits(regs, REG_SSI_SRCR,
-				   vals[RX].srcr | vals[TX].srcr,
-				   vals[RX].srcr | vals[TX].srcr);
-		regmap_update_bits(regs, REG_SSI_STCR,
-				   vals[RX].stcr | vals[TX].stcr,
-				   vals[RX].stcr | vals[TX].stcr);
-	} else {
-		regmap_update_bits(regs, REG_SSI_SRCR,
-				   vals[RX].srcr | vals[TX].srcr, 0);
-		regmap_update_bits(regs, REG_SSI_STCR,
-				   vals[RX].stcr | vals[TX].stcr, 0);
-		regmap_update_bits(regs, REG_SSI_SIER,
-				   vals[RX].sier | vals[TX].sier, 0);
-	}
-}
-
-/**
- * Clear remaining data in the FIFO to avoid dirty data or channel slipping
- */
-static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx)
-{
-	bool tx = !is_rx;
-
+	/* Clear dirty data in the FIFO; It also prevents channel slipping */
 	regmap_update_bits(ssi->regs, REG_SSI_SOR,
 			   SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
-}
-
-/**
- * Calculate the bits that have to be disabled for the current stream that is
- * getting disabled. This keeps the bits enabled that are necessary for the
- * second stream to work if 'stream_active' is true.
- *
- * Detailed calculation:
- * These are the values that need to be active after disabling. For non-active
- * second stream, this is 0:
- *	vals_stream * !!stream_active
- *
- * The following computes the overall differences between the setup for the
- * to-disable stream and the active stream, a simple XOR:
- *	vals_disable ^ (vals_stream * !!(stream_active))
- *
- * The full expression adds a mask on all values we care about
- */
-#define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \
-	((vals_disable) & \
-	 ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active))))
-
-/**
- * Enable or disable SSI configuration.
- */
-static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
-			   struct fsl_ssi_regvals *vals)
-{
-	struct regmap *regs = ssi->regs;
-	struct fsl_ssi_regvals *avals;
-	int nr_active_streams;
-	u32 scr;
-	int keep_active;
-
-	regmap_read(regs, REG_SSI_SCR, &scr);
-
-	nr_active_streams = !!(scr & SSI_SCR_TE) + !!(scr & SSI_SCR_RE);
-
-	if (nr_active_streams - 1 > 0)
-		keep_active = 1;
-	else
-		keep_active = 0;
-
-	/* Get the opposite direction to keep its values untouched */
-	if (&ssi->regvals[RX] == vals)
-		avals = &ssi->regvals[TX];
-	else
-		avals = &ssi->regvals[RX];
-
-	if (!enable) {
-		/*
-		 * To keep the other stream safe, exclude shared bits between
-		 * both streams, and get safe bits to disable current stream
-		 */
-		u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr,
-					      keep_active);
-		/* Safely disable SCR register for the stream */
-		regmap_update_bits(regs, REG_SSI_SCR, scr, 0);
-	}
 
 	/*
-	 * For cases where online configuration is not supported,
-	 * 1) Enable all necessary bits of both streams when 1st stream starts
-	 *    even if the opposite stream will not start
-	 * 2) Disable all remaining bits of both streams when last stream ends
+	 * On offline_config SoCs, SxCR and SIER are already configured when
+	 * the previous stream started. So skip all SxCR and SIER settings
+	 * to prevent online reconfigurations, then jump to set SCR directly
 	 */
-	if (ssi->soc->offline_config) {
-		if ((enable && !nr_active_streams) || (!enable && !keep_active))
-			fsl_ssi_rxtx_config(ssi, enable);
+	if (ssi->soc->offline_config && ssi->streams)
+		goto enable_scr;
 
-		goto config_done;
+	if (ssi->soc->offline_config) {
+		/*
+		 * Online reconfiguration not supported, so enable all bits for
+		 * both streams at once to avoid necessity of reconfigurations
+		 */
+		srcr = vals[RX].srcr | vals[TX].srcr;
+		stcr = vals[RX].stcr | vals[TX].stcr;
+		sier = vals[RX].sier | vals[TX].sier;
+	} else {
+		/* Otherwise, only set bits for the current stream */
+		srcr = vals[dir].srcr;
+		stcr = vals[dir].stcr;
+		sier = vals[dir].sier;
 	}
 
-	/* Online configure single direction while SSI is running */
-	if (enable) {
-		fsl_ssi_fifo_clear(ssi, vals->scr & SSI_SCR_RE);
+	/* Configure SRCR, STCR and SIER at once */
+	regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, srcr);
+	regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, stcr);
+	regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, sier);
 
-		regmap_update_bits(regs, REG_SSI_SRCR, vals->srcr, vals->srcr);
-		regmap_update_bits(regs, REG_SSI_STCR, vals->stcr, vals->stcr);
-		regmap_update_bits(regs, REG_SSI_SIER, vals->sier, vals->sier);
+enable_scr:
+	/*
+	 * Start DMA before setting TE to avoid FIFO underrun
+	 * which may cause a channel slip or a channel swap
+	 *
+	 * TODO: FIQ cases might also need this upon testing
+	 */
+	if (ssi->use_dma && tx) {
+		int try = 100;
+		u32 sfcsr;
+
+		/* Enable SSI first to send TX DMA request */
+		regmap_update_bits(ssi->regs, REG_SSI_SCR,
+				   SSI_SCR_SSIEN, SSI_SCR_SSIEN);
+
+		/* Busy wait until TX FIFO not empty -- DMA working */
+		do {
+			regmap_read(ssi->regs, REG_SSI_SFCSR, &sfcsr);
+			if (SSI_SFCSR_TFCNT0(sfcsr))
+				break;
+		} while (--try);
+
+		/* FIFO still empty -- something might be wrong */
+		if (!SSI_SFCSR_TFCNT0(sfcsr))
+			dev_warn(ssi->dev, "Timeout waiting TX FIFO filling\n");
+	}
+	/* Enable all remaining bits in SCR */
+	regmap_update_bits(ssi->regs, REG_SSI_SCR,
+			   vals[dir].scr, vals[dir].scr);
+
+	/* Log the enabled stream to the mask */
+	ssi->streams |= BIT(dir);
+}
+
+/**
+ * Exclude bits that are used by the opposite stream
+ *
+ * When both streams are active, disabling some bits for the current stream
+ * might break the other stream if these bits are used by it.
+ *
+ * @vals : regvals of the current stream
+ * @avals: regvals of the opposite stream
+ * @aactive: active state of the opposite stream
+ *
+ *  1) XOR vals and avals to get the differences if the other stream is active;
+ *     Otherwise, return current vals if the other stream is not active
+ *  2) AND the result of 1) with the current vals
+ */
+#define _ssi_xor_shared_bits(vals, avals, aactive) \
+	((vals) ^ ((avals) * (aactive)))
+
+#define ssi_excl_shared_bits(vals, avals, aactive) \
+	((vals) & _ssi_xor_shared_bits(vals, avals, aactive))
+
+/**
+ * Unset SCR, SIER, STCR and SRCR registers with cached values in regvals
+ *
+ * Notes:
+ * 1) For offline_config SoCs, to avoid online reconfigurations, disable all
+ *    bits of both streams at once when the last stream is abort to end
+ * 2) It also clears FIFO after unsetting regvals; SOR is safe to set online
+ */
+static void fsl_ssi_config_disable(struct fsl_ssi *ssi, bool tx)
+{
+	struct fsl_ssi_regvals *vals, *avals;
+	u32 sier, srcr, stcr, scr;
+	int adir = tx ? RX : TX;
+	int dir = tx ? TX : RX;
+	bool aactive;
+
+	/* Check if the opposite stream is active */
+	aactive = ssi->streams & BIT(adir);
+
+	vals = &ssi->regvals[dir];
+
+	/* Get regvals of the opposite stream to keep opposite stream safe */
+	avals = &ssi->regvals[adir];
+
+	/*
+	 * To keep the other stream safe, exclude shared bits between
+	 * both streams, and get safe bits to disable current stream
+	 */
+	scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive);
+
+	/* Disable safe bits of SCR register for the current stream */
+	regmap_update_bits(ssi->regs, REG_SSI_SCR, scr, 0);
+
+	/* Log the disabled stream to the mask */
+	ssi->streams &= ~BIT(dir);
+
+	/*
+	 * On offline_config SoCs, if the other stream is active, skip
+	 * SxCR and SIER settings to prevent online reconfigurations
+	 */
+	if (ssi->soc->offline_config && aactive)
+		goto fifo_clear;
+
+	if (ssi->soc->offline_config) {
+		/* Now there is only current stream active, disable all bits */
+		srcr = vals->srcr | avals->srcr;
+		stcr = vals->stcr | avals->stcr;
+		sier = vals->sier | avals->sier;
 	} else {
-		u32 sier;
-		u32 srcr;
-		u32 stcr;
-
 		/*
 		 * To keep the other stream safe, exclude shared bits between
 		 * both streams, and get safe bits to disable current stream
 		 */
-		sier = fsl_ssi_disable_val(vals->sier, avals->sier,
-					   keep_active);
-		srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr,
-					   keep_active);
-		stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr,
-					   keep_active);
-
-		/* Safely disable other control registers for the stream */
-		regmap_update_bits(regs, REG_SSI_SRCR, srcr, 0);
-		regmap_update_bits(regs, REG_SSI_STCR, stcr, 0);
-		regmap_update_bits(regs, REG_SSI_SIER, sier, 0);
+		sier = ssi_excl_shared_bits(vals->sier, avals->sier, aactive);
+		srcr = ssi_excl_shared_bits(vals->srcr, avals->srcr, aactive);
+		stcr = ssi_excl_shared_bits(vals->stcr, avals->stcr, aactive);
 	}
 
-config_done:
-	/* Enabling of subunits is done after configuration */
-	if (enable) {
-		/*
-		 * Start DMA before setting TE to avoid FIFO underrun
-		 * which may cause a channel slip or a channel swap
-		 *
-		 * TODO: FIQ cases might also need this upon testing
-		 */
-		if (ssi->use_dma && (vals->scr & SSI_SCR_TE)) {
-			int i;
-			int max_loop = 100;
+	/* Clear configurations of SRCR, STCR and SIER at once */
+	regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, 0);
+	regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, 0);
+	regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, 0);
 
-			/* Enable SSI first to send TX DMA request */
-			regmap_update_bits(regs, REG_SSI_SCR,
-					   SSI_SCR_SSIEN, SSI_SCR_SSIEN);
-
-			/* Busy wait until TX FIFO not empty -- DMA working */
-			for (i = 0; i < max_loop; i++) {
-				u32 sfcsr;
-				regmap_read(regs, REG_SSI_SFCSR, &sfcsr);
-				if (SSI_SFCSR_TFCNT0(sfcsr))
-					break;
-			}
-			if (i == max_loop) {
-				dev_err(ssi->dev,
-					"Timeout waiting TX FIFO filling\n");
-			}
-		}
-		/* Enable all remaining bits */
-		regmap_update_bits(regs, REG_SSI_SCR, vals->scr, vals->scr);
-	}
-}
-
-static void fsl_ssi_rx_config(struct fsl_ssi *ssi, bool enable)
-{
-	fsl_ssi_config(ssi, enable, &ssi->regvals[RX]);
+fifo_clear:
+	/* Clear remaining data in the FIFO */
+	regmap_update_bits(ssi->regs, REG_SSI_SOR,
+			   SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
 }
 
 static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
@@ -566,21 +581,6 @@ static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
 	}
 }
 
-static void fsl_ssi_tx_config(struct fsl_ssi *ssi, bool enable)
-{
-	/*
-	 * SACCST might be modified via AC Link by a CODEC if it sends
-	 * extra bits in their SLOTREQ requests, which'll accidentally
-	 * send valid data to slots other than normal playback slots.
-	 *
-	 * To be safe, configure SACCST right before TX starts.
-	 */
-	if (enable && fsl_ssi_is_ac97(ssi))
-		fsl_ssi_tx_ac97_saccst_setup(ssi);
-
-	fsl_ssi_config(ssi, enable, &ssi->regvals[TX]);
-}
-
 /**
  * Cache critical bits of SIER, SRCR, STCR and SCR to later set them safely
  */
@@ -588,17 +588,20 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
 {
 	struct fsl_ssi_regvals *vals = ssi->regvals;
 
-	vals[RX].sier = SSI_SIER_RFF0_EN;
+	vals[RX].sier = SSI_SIER_RFF0_EN | FSLSSI_SIER_DBG_RX_FLAGS;
 	vals[RX].srcr = SSI_SRCR_RFEN0;
-	vals[RX].scr = 0;
-	vals[TX].sier = SSI_SIER_TFE0_EN;
+	vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE;
+	vals[TX].sier = SSI_SIER_TFE0_EN | FSLSSI_SIER_DBG_TX_FLAGS;
 	vals[TX].stcr = SSI_STCR_TFEN0;
-	vals[TX].scr = 0;
+	vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE;
 
 	/* AC97 has already enabled SSIEN, RE and TE, so ignore them */
-	if (!fsl_ssi_is_ac97(ssi)) {
-		vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE;
-		vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE;
+	if (fsl_ssi_is_ac97(ssi))
+		vals[RX].scr = vals[TX].scr = 0;
+
+	if (ssi->use_dual_fifo) {
+		vals[RX].srcr |= SSI_SRCR_RFEN1;
+		vals[TX].stcr |= SSI_STCR_TFEN1;
 	}
 
 	if (ssi->use_dma) {
@@ -608,9 +611,6 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
 		vals[RX].sier |= SSI_SIER_RIE;
 		vals[TX].sier |= SSI_SIER_TIE;
 	}
-
-	vals[RX].sier |= FSLSSI_SIER_DBG_RX_FLAGS;
-	vals[TX].sier |= FSLSSI_SIER_DBG_TX_FLAGS;
 }
 
 static void fsl_ssi_setup_ac97(struct fsl_ssi *ssi)
@@ -681,7 +681,6 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
 	bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
 	struct regmap *regs = ssi->regs;
-	int synchronous = ssi->cpu_dai_drv.symmetric_rates, ret;
 	u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
 	unsigned long clkrate, baudrate, tmprate;
 	unsigned int slots = params_channels(hw_params);
@@ -689,6 +688,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
 	u64 sub, savesub = 100000;
 	unsigned int freq;
 	bool baudclk_is_used;
+	int ret;
 
 	/* Override slots and slot_width if being specifically set... */
 	if (ssi->slots)
@@ -767,7 +767,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
 	mask = SSI_SxCCR_PM_MASK | SSI_SxCCR_DIV2 | SSI_SxCCR_PSR;
 
 	/* STCCR is used for RX in synchronous mode */
-	tx2 = tx || synchronous;
+	tx2 = tx || ssi->synchronous;
 	regmap_update_bits(regs, REG_SSI_SxCCR(tx2), mask, stccr);
 
 	if (!baudclk_is_used) {
@@ -803,11 +803,6 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 	unsigned int sample_size = params_width(hw_params);
 	u32 wl = SSI_SxCCR_WL(sample_size);
 	int ret;
-	u32 scr;
-	int enabled;
-
-	regmap_read(regs, REG_SSI_SCR, &scr);
-	enabled = scr & SSI_SCR_SSIEN;
 
 	/*
 	 * SSI is properly configured if it is enabled and running in
@@ -815,7 +810,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 	 * that should set separate configurations for STCCR and SRCCR
 	 * despite running in the synchronous mode.
 	 */
-	if (enabled && ssi->cpu_dai_drv.symmetric_rates)
+	if (ssi->streams && ssi->synchronous)
 		return 0;
 
 	if (fsl_ssi_is_i2s_master(ssi)) {
@@ -834,20 +829,20 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (!fsl_ssi_is_ac97(ssi)) {
-		u8 i2s_net;
 		/* Normal + Network mode to send 16-bit data in 32-bit frames */
 		if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
-			i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
-		else
-			i2s_net = ssi->i2s_net;
+			ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
+
+		/* Use Normal mode to send mono data at 1st slot of 2 slots */
+		if (channels == 1)
+			ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL;
 
 		regmap_update_bits(regs, REG_SSI_SCR,
-				   SSI_SCR_I2S_NET_MASK,
-				   channels == 1 ? 0 : i2s_net);
+				   SSI_SCR_I2S_NET_MASK, ssi->i2s_net);
 	}
 
 	/* In synchronous mode, the SSI uses STCCR for capture */
-	tx2 = tx || ssi->cpu_dai_drv.symmetric_rates;
+	tx2 = tx || ssi->synchronous;
 	regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl);
 
 	return 0;
@@ -868,45 +863,31 @@ static int fsl_ssi_hw_free(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static int _fsl_ssi_set_dai_fmt(struct device *dev,
-				struct fsl_ssi *ssi, unsigned int fmt)
+static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt)
 {
-	struct regmap *regs = ssi->regs;
-	u32 strcr = 0, stcr, srcr, scr, mask;
-	u8 wm;
+	u32 strcr = 0, scr = 0, stcr, srcr, mask;
 
 	ssi->dai_fmt = fmt;
 
-	if (fsl_ssi_is_i2s_master(ssi) && IS_ERR(ssi->baudclk)) {
-		dev_err(dev, "missing baudclk for master mode\n");
-		return -EINVAL;
-	}
-
-	fsl_ssi_setup_regvals(ssi);
-
-	regmap_read(regs, REG_SSI_SCR, &scr);
-	scr &= ~(SSI_SCR_SYN | SSI_SCR_I2S_MODE_MASK);
 	/* Synchronize frame sync clock for TE to avoid data slipping */
 	scr |= SSI_SCR_SYNC_TX_FS;
 
-	mask = SSI_STCR_TXBIT0 | SSI_STCR_TFDIR | SSI_STCR_TXDIR |
-	       SSI_STCR_TSCKP | SSI_STCR_TFSI | SSI_STCR_TFSL | SSI_STCR_TEFS;
-	regmap_read(regs, REG_SSI_STCR, &stcr);
-	regmap_read(regs, REG_SSI_SRCR, &srcr);
-	stcr &= ~mask;
-	srcr &= ~mask;
+	/* Set to default shifting settings: LSB_ALIGNED */
+	strcr |= SSI_STCR_TXBIT0;
 
 	/* Use Network mode as default */
 	ssi->i2s_net = SSI_SCR_NET;
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		regmap_update_bits(regs, REG_SSI_STCCR,
-				   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
-		regmap_update_bits(regs, REG_SSI_SRCCR,
-				   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
 		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-		case SND_SOC_DAIFMT_CBM_CFS:
 		case SND_SOC_DAIFMT_CBS_CFS:
+			if (IS_ERR(ssi->baudclk)) {
+				dev_err(ssi->dev,
+					"missing baudclk for master mode\n");
+				return -EINVAL;
+			}
+			/* fall through */
+		case SND_SOC_DAIFMT_CBM_CFS:
 			ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER;
 			break;
 		case SND_SOC_DAIFMT_CBM_CFM:
@@ -916,30 +897,34 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
 			return -EINVAL;
 		}
 
+		regmap_update_bits(ssi->regs, REG_SSI_STCCR,
+				   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
+		regmap_update_bits(ssi->regs, REG_SSI_SRCCR,
+				   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
+
 		/* Data on rising edge of bclk, frame low, 1clk before data */
-		strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP |
-			 SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
+		strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP | SSI_STCR_TEFS;
 		break;
 	case SND_SOC_DAIFMT_LEFT_J:
 		/* Data on rising edge of bclk, frame high */
-		strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP;
+		strcr |= SSI_STCR_TSCKP;
 		break;
 	case SND_SOC_DAIFMT_DSP_A:
 		/* Data on rising edge of bclk, frame high, 1clk before data */
-		strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP |
-			 SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
+		strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP | SSI_STCR_TEFS;
 		break;
 	case SND_SOC_DAIFMT_DSP_B:
 		/* Data on rising edge of bclk, frame high */
-		strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP | SSI_STCR_TXBIT0;
+		strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP;
 		break;
 	case SND_SOC_DAIFMT_AC97:
 		/* Data on falling edge of bclk, frame high, 1clk before data */
-		ssi->i2s_net |= SSI_SCR_I2S_MODE_NORMAL;
+		strcr |= SSI_STCR_TEFS;
 		break;
 	default:
 		return -EINVAL;
 	}
+
 	scr |= ssi->i2s_net;
 
 	/* DAI clock inversion */
@@ -973,49 +958,33 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
 		break;
 	case SND_SOC_DAIFMT_CBM_CFM:
 		/* Input bit or frame sync clocks */
-		scr &= ~SSI_SCR_SYS_CLK_EN;
 		break;
 	case SND_SOC_DAIFMT_CBM_CFS:
 		/* Input bit clock but output frame sync clock */
-		strcr &= ~SSI_STCR_TXDIR;
 		strcr |= SSI_STCR_TFDIR;
-		scr &= ~SSI_SCR_SYS_CLK_EN;
 		break;
 	default:
-		if (!fsl_ssi_is_ac97(ssi))
-			return -EINVAL;
+		return -EINVAL;
 	}
 
-	stcr |= strcr;
-	srcr |= strcr;
+	stcr = strcr;
+	srcr = strcr;
 
 	/* Set SYN mode and clear RXDIR bit when using SYN or AC97 mode */
-	if (ssi->cpu_dai_drv.symmetric_rates || fsl_ssi_is_ac97(ssi)) {
+	if (ssi->synchronous || fsl_ssi_is_ac97(ssi)) {
 		srcr &= ~SSI_SRCR_RXDIR;
 		scr |= SSI_SCR_SYN;
 	}
 
-	regmap_write(regs, REG_SSI_STCR, stcr);
-	regmap_write(regs, REG_SSI_SRCR, srcr);
-	regmap_write(regs, REG_SSI_SCR, scr);
+	mask = SSI_STCR_TFDIR | SSI_STCR_TXDIR | SSI_STCR_TSCKP |
+	       SSI_STCR_TFSL | SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
 
-	wm = ssi->fifo_watermark;
+	regmap_update_bits(ssi->regs, REG_SSI_STCR, mask, stcr);
+	regmap_update_bits(ssi->regs, REG_SSI_SRCR, mask, srcr);
 
-	regmap_write(regs, REG_SSI_SFCSR,
-		     SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) |
-		     SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm));
-
-	if (ssi->use_dual_fifo) {
-		regmap_update_bits(regs, REG_SSI_SRCR,
-				   SSI_SRCR_RFEN1, SSI_SRCR_RFEN1);
-		regmap_update_bits(regs, REG_SSI_STCR,
-				   SSI_STCR_TFEN1, SSI_STCR_TFEN1);
-		regmap_update_bits(regs, REG_SSI_SCR,
-				   SSI_SCR_TCH_EN, SSI_SCR_TCH_EN);
-	}
-
-	if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97)
-		fsl_ssi_setup_ac97(ssi);
+	mask = SSI_SCR_SYNC_TX_FS | SSI_SCR_I2S_MODE_MASK |
+	       SSI_SCR_SYS_CLK_EN | SSI_SCR_SYN;
+	regmap_update_bits(ssi->regs, REG_SSI_SCR, mask, scr);
 
 	return 0;
 }
@@ -1031,7 +1000,7 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	if (fsl_ssi_is_ac97(ssi))
 		return 0;
 
-	return _fsl_ssi_set_dai_fmt(dai->dev, ssi, fmt);
+	return _fsl_ssi_set_dai_fmt(ssi, fmt);
 }
 
 /**
@@ -1051,9 +1020,7 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
 	}
 
 	/* The slot number should be >= 2 if using Network mode or I2S mode */
-	regmap_read(regs, REG_SSI_SCR, &val);
-	val &= SSI_SCR_I2S_MODE_MASK | SSI_SCR_NET;
-	if (val && slots < 2) {
+	if (ssi->i2s_net && slots < 2) {
 		dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n");
 		return -EINVAL;
 	}
@@ -1063,9 +1030,8 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
 	regmap_update_bits(regs, REG_SSI_SRCCR,
 			   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots));
 
-	/* Save SSIEN bit of the SCR register */
+	/* Save the SCR register value */
 	regmap_read(regs, REG_SSI_SCR, &val);
-	val &= SSI_SCR_SSIEN;
 	/* Temporarily enable SSI to allow SxMSKs to be configurable */
 	regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, SSI_SCR_SSIEN);
 
@@ -1092,39 +1058,34 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
-	struct regmap *regs = ssi->regs;
+	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			fsl_ssi_tx_config(ssi, true);
-		else
-			fsl_ssi_rx_config(ssi, true);
+		/*
+		 * SACCST might be modified via AC Link by a CODEC if it sends
+		 * extra bits in their SLOTREQ requests, which'll accidentally
+		 * send valid data to slots other than normal playback slots.
+		 *
+		 * To be safe, configure SACCST right before TX starts.
+		 */
+		if (tx && fsl_ssi_is_ac97(ssi))
+			fsl_ssi_tx_ac97_saccst_setup(ssi);
+		fsl_ssi_config_enable(ssi, tx);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			fsl_ssi_tx_config(ssi, false);
-		else
-			fsl_ssi_rx_config(ssi, false);
+		fsl_ssi_config_disable(ssi, tx);
 		break;
 
 	default:
 		return -EINVAL;
 	}
 
-	/* Clear corresponding FIFO */
-	if (fsl_ssi_is_ac97(ssi)) {
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			regmap_write(regs, REG_SSI_SOR, SSI_SOR_TX_CLR);
-		else
-			regmap_write(regs, REG_SSI_SOR, SSI_SOR_RX_CLR);
-	}
-
 	return 0;
 }
 
@@ -1132,10 +1093,9 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
 {
 	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
 
-	if (ssi->soc->imx && ssi->use_dma) {
-		dai->playback_dma_data = &ssi->dma_params_tx;
-		dai->capture_dma_data = &ssi->dma_params_rx;
-	}
+	if (ssi->soc->imx && ssi->use_dma)
+		snd_soc_dai_init_dma_data(dai, &ssi->dma_params_tx,
+					  &ssi->dma_params_rx);
 
 	return 0;
 }
@@ -1175,6 +1135,7 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
 
 static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
 	.bus_control = true,
+	.symmetric_channels = 1,
 	.probe = fsl_ssi_dai_probe,
 	.playback = {
 		.stream_name = "AC97 Playback",
@@ -1272,6 +1233,53 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
 };
 
 /**
+ * Initialize SSI registers
+ */
+static int fsl_ssi_hw_init(struct fsl_ssi *ssi)
+{
+	u32 wm = ssi->fifo_watermark;
+
+	/* Initialize regvals */
+	fsl_ssi_setup_regvals(ssi);
+
+	/* Set watermarks */
+	regmap_write(ssi->regs, REG_SSI_SFCSR,
+		     SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) |
+		     SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm));
+
+	/* Enable Dual FIFO mode */
+	if (ssi->use_dual_fifo)
+		regmap_update_bits(ssi->regs, REG_SSI_SCR,
+				   SSI_SCR_TCH_EN, SSI_SCR_TCH_EN);
+
+	/* AC97 should start earlier to communicate with CODECs */
+	if (fsl_ssi_is_ac97(ssi)) {
+		_fsl_ssi_set_dai_fmt(ssi, ssi->dai_fmt);
+		fsl_ssi_setup_ac97(ssi);
+	}
+
+	return 0;
+}
+
+/**
+ * Clear SSI registers
+ */
+static void fsl_ssi_hw_clean(struct fsl_ssi *ssi)
+{
+	/* Disable registers for AC97 */
+	if (fsl_ssi_is_ac97(ssi)) {
+		/* Disable TE and RE bits first */
+		regmap_update_bits(ssi->regs, REG_SSI_SCR,
+				   SSI_SCR_TE | SSI_SCR_RE, 0);
+		/* Disable AC97 mode */
+		regmap_write(ssi->regs, REG_SSI_SACNT, 0);
+		/* Unset WAIT bits */
+		regmap_write(ssi->regs, REG_SSI_SOR, 0);
+		/* Disable SSI -- software reset */
+		regmap_update_bits(ssi->regs, REG_SSI_SCR, SSI_SCR_SSIEN, 0);
+	}
+}
+/**
  * Make every character in a string lower-case
  */
 static void make_lowercase(char *s)
@@ -1285,9 +1293,7 @@ static void make_lowercase(char *s)
 static int fsl_ssi_imx_probe(struct platform_device *pdev,
 			     struct fsl_ssi *ssi, void __iomem *iomem)
 {
-	struct device_node *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
-	u32 dmas[4];
 	int ret;
 
 	/* Backward compatible for a DT without ipg clock name assigned */
@@ -1321,14 +1327,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 	ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0;
 	ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0;
 
-	/* Set to dual FIFO mode according to the SDMA sciprt */
-	ret = of_property_read_u32_array(np, "dmas", dmas, 4);
-	if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
-		ssi->use_dual_fifo = true;
-		/*
-		 * Use even numbers to avoid channel swap due to SDMA
-		 * script design
-		 */
+	/* Use even numbers to avoid channel swap due to SDMA script design */
+	if (ssi->use_dual_fifo) {
 		ssi->dma_params_tx.maxburst &= ~0x1;
 		ssi->dma_params_rx.maxburst &= ~0x1;
 	}
@@ -1369,41 +1369,109 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev, struct fsl_ssi *ssi)
 		clk_disable_unprepare(ssi->clk);
 }
 
-static int fsl_ssi_probe(struct platform_device *pdev)
+static int fsl_ssi_probe_from_dt(struct fsl_ssi *ssi)
 {
-	struct fsl_ssi *ssi;
-	int ret = 0;
-	struct device_node *np = pdev->dev.of_node;
-	struct device *dev = &pdev->dev;
+	struct device *dev = ssi->dev;
+	struct device_node *np = dev->of_node;
 	const struct of_device_id *of_id;
 	const char *p, *sprop;
-	const uint32_t *iprop;
-	struct resource *res;
-	void __iomem *iomem;
-	char name[64];
-	struct regmap_config regconfig = fsl_ssi_regconfig;
+	const __be32 *iprop;
+	u32 dmas[4];
+	int ret;
 
 	of_id = of_match_device(fsl_ssi_ids, dev);
 	if (!of_id || !of_id->data)
 		return -EINVAL;
 
-	ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL);
-	if (!ssi)
-		return -ENOMEM;
-
 	ssi->soc = of_id->data;
-	ssi->dev = dev;
+
+	ret = of_property_match_string(np, "clock-names", "ipg");
+	/* Get error code if not found */
+	ssi->has_ipg_clk_name = ret >= 0;
 
 	/* Check if being used in AC97 mode */
 	sprop = of_get_property(np, "fsl,mode", NULL);
-	if (sprop) {
-		if (!strcmp(sprop, "ac97-slave"))
-			ssi->dai_fmt = SND_SOC_DAIFMT_AC97;
+	if (sprop && !strcmp(sprop, "ac97-slave")) {
+		ssi->dai_fmt = FSLSSI_AC97_DAIFMT;
+
+		ret = of_property_read_u32(np, "cell-index", &ssi->card_idx);
+		if (ret) {
+			dev_err(dev, "failed to get SSI index property\n");
+			return -EINVAL;
+		}
+		strcpy(ssi->card_name, "ac97-codec");
+	} else if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
+		/*
+		 * In synchronous mode, STCK and STFS ports are used by RX
+		 * as well. So the software should limit the sample rates,
+		 * sample bits and channels to be symmetric.
+		 *
+		 * This is exclusive with FSLSSI_AC97_FORMATS as AC97 runs
+		 * in the SSI synchronous mode however it does not have to
+		 * limit symmetric sample rates and sample bits.
+		 */
+		ssi->synchronous = true;
 	}
 
 	/* Select DMA or FIQ */
 	ssi->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter");
 
+	/* Fetch FIFO depth; Set to 8 for older DT without this property */
+	iprop = of_get_property(np, "fsl,fifo-depth", NULL);
+	if (iprop)
+		ssi->fifo_depth = be32_to_cpup(iprop);
+	else
+		ssi->fifo_depth = 8;
+
+	/* Use dual FIFO mode depending on the support from SDMA script */
+	ret = of_property_read_u32_array(np, "dmas", dmas, 4);
+	if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL)
+		ssi->use_dual_fifo = true;
+
+	/*
+	 * Backward compatible for older bindings by manually triggering the
+	 * machine driver's probe(). Use /compatible property, including the
+	 * address of CPU DAI driver structure, as the name of machine driver
+	 *
+	 * If card_name is set by AC97 earlier, bypass here since it uses a
+	 * different name to register the device.
+	 */
+	if (!ssi->card_name[0] && of_get_property(np, "codec-handle", NULL)) {
+		sprop = of_get_property(of_find_node_by_path("/"),
+					"compatible", NULL);
+		/* Strip "fsl," in the compatible name if applicable */
+		p = strrchr(sprop, ',');
+		if (p)
+			sprop = p + 1;
+		snprintf(ssi->card_name, sizeof(ssi->card_name),
+			 "snd-soc-%s", sprop);
+		make_lowercase(ssi->card_name);
+		ssi->card_idx = 0;
+	}
+
+	return 0;
+}
+
+static int fsl_ssi_probe(struct platform_device *pdev)
+{
+	struct regmap_config regconfig = fsl_ssi_regconfig;
+	struct device *dev = &pdev->dev;
+	struct fsl_ssi *ssi;
+	struct resource *res;
+	void __iomem *iomem;
+	int ret = 0;
+
+	ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL);
+	if (!ssi)
+		return -ENOMEM;
+
+	ssi->dev = dev;
+
+	/* Probe from DT */
+	ret = fsl_ssi_probe_from_dt(ssi);
+	if (ret)
+		return ret;
+
 	if (fsl_ssi_is_ac97(ssi)) {
 		memcpy(&ssi->cpu_dai_drv, &fsl_ssi_ac97_dai,
 		       sizeof(fsl_ssi_ac97_dai));
@@ -1427,15 +1495,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 			REG_SSI_SRMSK / sizeof(uint32_t) + 1;
 	}
 
-	ret = of_property_match_string(np, "clock-names", "ipg");
-	if (ret < 0) {
-		ssi->has_ipg_clk_name = false;
-		ssi->regs = devm_regmap_init_mmio(dev, iomem, &regconfig);
-	} else {
-		ssi->has_ipg_clk_name = true;
+	if (ssi->has_ipg_clk_name)
 		ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem,
 						      &regconfig);
-	}
+	else
+		ssi->regs = devm_regmap_init_mmio(dev, iomem, &regconfig);
 	if (IS_ERR(ssi->regs)) {
 		dev_err(dev, "failed to init register map\n");
 		return PTR_ERR(ssi->regs);
@@ -1447,23 +1511,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		return ssi->irq;
 	}
 
-	/* Set software limitations for synchronous mode */
-	if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
-		if (!fsl_ssi_is_ac97(ssi)) {
-			ssi->cpu_dai_drv.symmetric_rates = 1;
-			ssi->cpu_dai_drv.symmetric_samplebits = 1;
-		}
-
+	/* Set software limitations for synchronous mode except AC97 */
+	if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) {
+		ssi->cpu_dai_drv.symmetric_rates = 1;
 		ssi->cpu_dai_drv.symmetric_channels = 1;
+		ssi->cpu_dai_drv.symmetric_samplebits = 1;
 	}
 
-	/* Fetch FIFO depth; Set to 8 for older DT without this property */
-	iprop = of_get_property(np, "fsl,fifo-depth", NULL);
-	if (iprop)
-		ssi->fifo_depth = be32_to_cpup(iprop);
-	else
-		ssi->fifo_depth = 8;
-
 	/*
 	 * Configure TX and RX DMA watermarks -- when to send a DMA request
 	 *
@@ -1528,50 +1582,27 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	if (ret)
 		goto error_asoc_register;
 
-	/* Bypass it if using newer DT bindings of ASoC machine drivers */
-	if (!of_get_property(np, "codec-handle", NULL))
-		goto done;
+	/* Initially configures SSI registers */
+	fsl_ssi_hw_init(ssi);
 
-	/*
-	 * Backward compatible for older bindings by manually triggering the
-	 * machine driver's probe(). Use /compatible property, including the
-	 * address of CPU DAI driver structure, as the name of machine driver.
-	 */
-	sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
-	/* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
-	p = strrchr(sprop, ',');
-	if (p)
-		sprop = p + 1;
-	snprintf(name, sizeof(name), "snd-soc-%s", sprop);
-	make_lowercase(name);
+	/* Register a platform device for older bindings or AC97 */
+	if (ssi->card_name[0]) {
+		struct device *parent = dev;
+		/*
+		 * Do not set SSI dev as the parent of AC97 CODEC device since
+		 * it does not have a DT node. Otherwise ASoC core will assume
+		 * CODEC has the same DT node as the SSI, so it may bypass the
+		 * dai_probe() of SSI and then cause NULL DMA data pointers.
+		 */
+		if (fsl_ssi_is_ac97(ssi))
+			parent = NULL;
 
-	ssi->pdev = platform_device_register_data(dev, name, 0, NULL, 0);
-	if (IS_ERR(ssi->pdev)) {
-		ret = PTR_ERR(ssi->pdev);
-		dev_err(dev, "failed to register platform: %d\n", ret);
-		goto error_sound_card;
-	}
-
-done:
-	if (ssi->dai_fmt)
-		_fsl_ssi_set_dai_fmt(dev, ssi, ssi->dai_fmt);
-
-	if (fsl_ssi_is_ac97(ssi)) {
-		u32 ssi_idx;
-
-		ret = of_property_read_u32(np, "cell-index", &ssi_idx);
-		if (ret) {
-			dev_err(dev, "failed to get SSI index property\n");
-			goto error_sound_card;
-		}
-
-		ssi->pdev = platform_device_register_data(NULL, "ac97-codec",
-							  ssi_idx, NULL, 0);
-		if (IS_ERR(ssi->pdev)) {
-			ret = PTR_ERR(ssi->pdev);
-			dev_err(dev,
-				"failed to register AC97 codec platform: %d\n",
-				ret);
+		ssi->card_pdev = platform_device_register_data(parent,
+				ssi->card_name, ssi->card_idx, NULL, 0);
+		if (IS_ERR(ssi->card_pdev)) {
+			ret = PTR_ERR(ssi->card_pdev);
+			dev_err(dev, "failed to register %s: %d\n",
+				ssi->card_name, ret);
 			goto error_sound_card;
 		}
 	}
@@ -1599,8 +1630,11 @@ static int fsl_ssi_remove(struct platform_device *pdev)
 
 	fsl_ssi_debugfs_remove(&ssi->dbg_stats);
 
-	if (ssi->pdev)
-		platform_device_unregister(ssi->pdev);
+	if (ssi->card_pdev)
+		platform_device_unregister(ssi->card_pdev);
+
+	/* Clean up SSI registers */
+	fsl_ssi_hw_clean(ssi);
 
 	if (ssi->soc->imx)
 		fsl_ssi_imx_clean(pdev, ssi);
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index de2fdc5..18f8dd5 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -12,9 +12,6 @@
 #ifndef _MPC8610_I2S_H
 #define _MPC8610_I2S_H
 
-#define RX 0
-#define TX 1
-
 /* -- SSI Register Map -- */
 
 /* SSI Transmit Data Register 0 */
diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c
index b9e42b5..7592b04 100644
--- a/sound/soc/fsl/fsl_utils.c
+++ b/sound/soc/fsl/fsl_utils.c
@@ -36,7 +36,7 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np,
 {
 	struct resource res;
 	struct device_node *dma_channel_np, *dma_np;
-	const u32 *iprop;
+	const __be32 *iprop;
 	int ret;
 
 	dma_channel_np = of_parse_phandle(ssi_np, name, 0);
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 4e5fefe..0578f34 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -341,7 +341,7 @@ static void imx_pcm_fiq_free(struct snd_pcm *pcm)
 	imx_pcm_free(pcm);
 }
 
-static const struct snd_soc_platform_driver imx_soc_platform_fiq = {
+static const struct snd_soc_component_driver imx_soc_component_fiq = {
 	.ops		= &imx_pcm_ops,
 	.pcm_new	= imx_pcm_fiq_new,
 	.pcm_free	= imx_pcm_fiq_free,
@@ -368,7 +368,8 @@ int imx_pcm_fiq_init(struct platform_device *pdev,
 	params->dma_params_tx->maxburst = 4;
 	params->dma_params_rx->maxburst = 6;
 
-	ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
+	ret = devm_snd_soc_register_component(&pdev->dev, &imx_soc_component_fiq,
+					      NULL, 0);
 	if (ret)
 		goto failed_register;
 
@@ -384,7 +385,6 @@ EXPORT_SYMBOL_GPL(imx_pcm_fiq_init);
 
 void imx_pcm_fiq_exit(struct platform_device *pdev)
 {
-	snd_soc_unregister_platform(&pdev->dev);
 }
 EXPORT_SYMBOL_GPL(imx_pcm_fiq_exit);
 
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
deleted file mode 100644
index 206b898..0000000
--- a/sound/soc/fsl/imx-wm8962.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright 2013 Freescale Semiconductor, Inc.
- *
- * Based on imx-sgtl5000.c
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Copyright 2012 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
- */
-
-#include <linux/module.h>
-#include <linux/of_platform.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
-#include <linux/pinctrl/consumer.h>
-
-#include "../codecs/wm8962.h"
-#include "imx-audmux.h"
-
-#define DAI_NAME_SIZE	32
-
-struct imx_wm8962_data {
-	struct snd_soc_dai_link dai;
-	struct snd_soc_card card;
-	char codec_dai_name[DAI_NAME_SIZE];
-	char platform_name[DAI_NAME_SIZE];
-	unsigned int clk_frequency;
-};
-
-struct imx_priv {
-	struct platform_device *pdev;
-	int sample_rate;
-	snd_pcm_format_t sample_format;
-};
-
-static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
-	SND_SOC_DAPM_HP("Headphone Jack", NULL),
-	SND_SOC_DAPM_SPK("Ext Spk", NULL),
-	SND_SOC_DAPM_MIC("AMIC", NULL),
-	SND_SOC_DAPM_MIC("DMIC", NULL),
-};
-
-static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
-		struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct imx_priv *priv = snd_soc_card_get_drvdata(rtd->card);
-
-	priv->sample_rate = params_rate(params);
-	priv->sample_format = params_format(params);
-
-	return 0;
-}
-
-static const struct snd_soc_ops imx_hifi_ops = {
-	.hw_params = imx_hifi_hw_params,
-};
-
-static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
-					struct snd_soc_dapm_context *dapm,
-					enum snd_soc_bias_level level)
-{
-	struct snd_soc_pcm_runtime *rtd;
-	struct snd_soc_dai *codec_dai;
-	struct imx_priv *priv = snd_soc_card_get_drvdata(card);
-	struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
-	struct device *dev = &priv->pdev->dev;
-	unsigned int pll_out;
-	int ret;
-
-	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-	codec_dai = rtd->codec_dai;
-	if (dapm->dev != codec_dai->dev)
-		return 0;
-
-	switch (level) {
-	case SND_SOC_BIAS_PREPARE:
-		if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
-			if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
-				pll_out = priv->sample_rate * 384;
-			else
-				pll_out = priv->sample_rate * 256;
-
-			ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
-					WM8962_FLL_MCLK, data->clk_frequency,
-					pll_out);
-			if (ret < 0) {
-				dev_err(dev, "failed to start FLL: %d\n", ret);
-				return ret;
-			}
-
-			ret = snd_soc_dai_set_sysclk(codec_dai,
-					WM8962_SYSCLK_FLL, pll_out,
-					SND_SOC_CLOCK_IN);
-			if (ret < 0) {
-				dev_err(dev, "failed to set SYSCLK: %d\n", ret);
-				return ret;
-			}
-		}
-		break;
-
-	case SND_SOC_BIAS_STANDBY:
-		if (dapm->bias_level == SND_SOC_BIAS_PREPARE) {
-			ret = snd_soc_dai_set_sysclk(codec_dai,
-					WM8962_SYSCLK_MCLK, data->clk_frequency,
-					SND_SOC_CLOCK_IN);
-			if (ret < 0) {
-				dev_err(dev,
-					"failed to switch away from FLL: %d\n",
-					ret);
-				return ret;
-			}
-
-			ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
-					0, 0, 0);
-			if (ret < 0) {
-				dev_err(dev, "failed to stop FLL: %d\n", ret);
-				return ret;
-			}
-		}
-		break;
-
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-static int imx_wm8962_late_probe(struct snd_soc_card *card)
-{
-	struct snd_soc_pcm_runtime *rtd;
-	struct snd_soc_dai *codec_dai;
-	struct imx_priv *priv = snd_soc_card_get_drvdata(card);
-	struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
-	struct device *dev = &priv->pdev->dev;
-	int ret;
-
-	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-	codec_dai = rtd->codec_dai;
-	ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
-			data->clk_frequency, SND_SOC_CLOCK_IN);
-	if (ret < 0)
-		dev_err(dev, "failed to set sysclk in %s\n", __func__);
-
-	return ret;
-}
-
-static int imx_wm8962_probe(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	struct device_node *ssi_np, *codec_np;
-	struct platform_device *ssi_pdev;
-	struct i2c_client *codec_dev;
-	struct imx_wm8962_data *data;
-	struct imx_priv *priv;
-	struct clk *codec_clk;
-	int int_port, ext_port;
-	int ret;
-
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	priv->pdev = pdev;
-	priv->sample_rate = 44100;
-	priv->sample_format = SNDRV_PCM_FORMAT_S16_LE;
-
-	ret = of_property_read_u32(np, "mux-int-port", &int_port);
-	if (ret) {
-		dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
-		return ret;
-	}
-	ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
-	if (ret) {
-		dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
-		return ret;
-	}
-
-	/*
-	 * The port numbering in the hardware manual starts at 1, while
-	 * the audmux API expects it starts at 0.
-	 */
-	int_port--;
-	ext_port--;
-	ret = imx_audmux_v2_configure_port(int_port,
-			IMX_AUDMUX_V2_PTCR_SYN |
-			IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
-			IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
-			IMX_AUDMUX_V2_PTCR_TFSDIR |
-			IMX_AUDMUX_V2_PTCR_TCLKDIR,
-			IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
-	if (ret) {
-		dev_err(&pdev->dev, "audmux internal port setup failed\n");
-		return ret;
-	}
-	ret = imx_audmux_v2_configure_port(ext_port,
-			IMX_AUDMUX_V2_PTCR_SYN,
-			IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
-	if (ret) {
-		dev_err(&pdev->dev, "audmux external port setup failed\n");
-		return ret;
-	}
-
-	ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
-	codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
-	if (!ssi_np || !codec_np) {
-		dev_err(&pdev->dev, "phandle missing or invalid\n");
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	ssi_pdev = of_find_device_by_node(ssi_np);
-	if (!ssi_pdev) {
-		dev_err(&pdev->dev, "failed to find SSI platform device\n");
-		ret = -EINVAL;
-		goto fail;
-	}
-	codec_dev = of_find_i2c_device_by_node(codec_np);
-	if (!codec_dev || !codec_dev->dev.driver) {
-		dev_err(&pdev->dev, "failed to find codec platform device\n");
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-	if (!data) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	codec_clk = clk_get(&codec_dev->dev, NULL);
-	if (IS_ERR(codec_clk)) {
-		ret = PTR_ERR(codec_clk);
-		dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
-		goto fail;
-	}
-
-	data->clk_frequency = clk_get_rate(codec_clk);
-	clk_put(codec_clk);
-
-	data->dai.name = "HiFi";
-	data->dai.stream_name = "HiFi";
-	data->dai.codec_dai_name = "wm8962";
-	data->dai.codec_of_node = codec_np;
-	data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
-	data->dai.platform_of_node = ssi_np;
-	data->dai.ops = &imx_hifi_ops;
-	data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-			    SND_SOC_DAIFMT_CBM_CFM;
-
-	data->card.dev = &pdev->dev;
-	ret = snd_soc_of_parse_card_name(&data->card, "model");
-	if (ret)
-		goto fail;
-	ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
-	if (ret)
-		goto fail;
-	data->card.num_links = 1;
-	data->card.owner = THIS_MODULE;
-	data->card.dai_link = &data->dai;
-	data->card.dapm_widgets = imx_wm8962_dapm_widgets;
-	data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets);
-
-	data->card.late_probe = imx_wm8962_late_probe;
-	data->card.set_bias_level = imx_wm8962_set_bias_level;
-
-	platform_set_drvdata(pdev, &data->card);
-	snd_soc_card_set_drvdata(&data->card, data);
-
-	ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
-	if (ret) {
-		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
-		goto fail;
-	}
-
-fail:
-	of_node_put(ssi_np);
-	of_node_put(codec_np);
-
-	return ret;
-}
-
-static const struct of_device_id imx_wm8962_dt_ids[] = {
-	{ .compatible = "fsl,imx-audio-wm8962", },
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_wm8962_dt_ids);
-
-static struct platform_driver imx_wm8962_driver = {
-	.driver = {
-		.name = "imx-wm8962",
-		.pm = &snd_soc_pm_ops,
-		.of_match_table = imx_wm8962_dt_ids,
-	},
-	.probe = imx_wm8962_probe,
-};
-module_platform_driver(imx_wm8962_driver);
-
-MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-MODULE_DESCRIPTION("Freescale i.MX WM8962 ASoC machine driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:imx-wm8962");
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index e63029f..c1a4544 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -22,6 +22,8 @@
 
 #include "mpc5200_dma.h"
 
+#define DRV_NAME "mpc5200_dma"
+
 /*
  * Interrupt handlers
  */
@@ -300,12 +302,13 @@ static const struct snd_pcm_ops psc_dma_ops = {
 static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_card *card = rtd->card->snd_card;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 	struct snd_soc_dai *dai = rtd->cpu_dai;
 	struct snd_pcm *pcm = rtd->pcm;
 	size_t size = psc_dma_hardware.buffer_bytes_max;
 	int rc;
 
-	dev_dbg(rtd->platform->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
+	dev_dbg(component->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
 		card, dai, pcm);
 
 	rc = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
@@ -341,10 +344,11 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
 static void psc_dma_free(struct snd_pcm *pcm)
 {
 	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 	struct snd_pcm_substream *substream;
 	int stream;
 
-	dev_dbg(rtd->platform->dev, "psc_dma_free(pcm=%p)\n", pcm);
+	dev_dbg(component->dev, "psc_dma_free(pcm=%p)\n", pcm);
 
 	for (stream = 0; stream < 2; stream++) {
 		substream = pcm->streams[stream].substream;
@@ -356,7 +360,8 @@ static void psc_dma_free(struct snd_pcm *pcm)
 	}
 }
 
-static const struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
+static const struct snd_soc_component_driver mpc5200_audio_dma_component = {
+	.name		= DRV_NAME,
 	.ops		= &psc_dma_ops,
 	.pcm_new	= &psc_dma_new,
 	.pcm_free	= &psc_dma_free,
@@ -468,7 +473,8 @@ int mpc5200_audio_dma_create(struct platform_device *op)
 	dev_set_drvdata(&op->dev, psc_dma);
 
 	/* Tell the ASoC OF helpers about it */
-	return snd_soc_register_platform(&op->dev, &mpc5200_audio_dma_platform);
+	return devm_snd_soc_register_component(&op->dev,
+					&mpc5200_audio_dma_component, NULL, 0);
 out_irq:
 	free_irq(psc_dma->irq, psc_dma);
 	free_irq(psc_dma->capture.irq, &psc_dma->capture);
@@ -487,8 +493,6 @@ int mpc5200_audio_dma_destroy(struct platform_device *op)
 
 	dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n");
 
-	snd_soc_unregister_platform(&op->dev);
-
 	bcom_gen_bd_rx_release(psc_dma->capture.bcom_task);
 	bcom_gen_bd_tx_release(psc_dma->playback.bcom_task);
 
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index cdaf163..2f80b21 100644
--- a/sound/soc/fsl/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
@@ -201,18 +201,18 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
 
 static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 
 	/* Headphone jack detection */
 	snd_soc_card_jack_new(rtd->card, "Headphone", SND_JACK_HEADPHONE,
 			      &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins));
-	wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
+	wm8350_hp_jack_detect(component, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
 
 	/* Microphone jack detection */
 	snd_soc_card_jack_new(rtd->card, "Microphone",
 			      SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack,
 			      mic_jack_pins, ARRAY_SIZE(mic_jack_pins));
-	wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
+	wm8350_mic_jack_detect(component, &mic_jack, SND_JACK_MICROPHONE,
 			       SND_JACK_BTN_0);
 
 	snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias");
diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c
index 53e11c6..915b894 100644
--- a/sound/soc/img/pistachio-internal-dac.c
+++ b/sound/soc/img/pistachio-internal-dac.c
@@ -122,26 +122,26 @@ static struct snd_soc_dai_driver pistachio_internal_dac_dais[] = {
 	},
 };
 
-static int pistachio_internal_dac_codec_probe(struct snd_soc_codec *codec)
+static int pistachio_internal_dac_codec_probe(struct snd_soc_component *component)
 {
-	struct pistachio_internal_dac *dac = snd_soc_codec_get_drvdata(codec);
+	struct pistachio_internal_dac *dac = snd_soc_component_get_drvdata(component);
 
-	snd_soc_codec_init_regmap(codec, dac->regmap);
+	snd_soc_component_init_regmap(component, dac->regmap);
 
 	return 0;
 }
 
-static const struct snd_soc_codec_driver pistachio_internal_dac_driver = {
-	.probe = pistachio_internal_dac_codec_probe,
-	.idle_bias_off = true,
-	.component_driver = {
-		.controls		= pistachio_internal_dac_snd_controls,
-		.num_controls		= ARRAY_SIZE(pistachio_internal_dac_snd_controls),
-		.dapm_widgets		= pistachio_internal_dac_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(pistachio_internal_dac_widgets),
-		.dapm_routes		= pistachio_internal_dac_routes,
-		.num_dapm_routes	= ARRAY_SIZE(pistachio_internal_dac_routes),
-	},
+static const struct snd_soc_component_driver pistachio_internal_dac_driver = {
+	.probe			= pistachio_internal_dac_codec_probe,
+	.controls		= pistachio_internal_dac_snd_controls,
+	.num_controls		= ARRAY_SIZE(pistachio_internal_dac_snd_controls),
+	.dapm_widgets		= pistachio_internal_dac_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(pistachio_internal_dac_widgets),
+	.dapm_routes		= pistachio_internal_dac_routes,
+	.num_dapm_routes	= ARRAY_SIZE(pistachio_internal_dac_routes),
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static int pistachio_internal_dac_probe(struct platform_device *pdev)
@@ -202,11 +202,12 @@ static int pistachio_internal_dac_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_idle(dev);
 
-	ret = snd_soc_register_codec(dev, &pistachio_internal_dac_driver,
+	ret = devm_snd_soc_register_component(dev,
+			&pistachio_internal_dac_driver,
 			pistachio_internal_dac_dais,
 			ARRAY_SIZE(pistachio_internal_dac_dais));
 	if (ret) {
-		dev_err(dev, "failed to register codec: %d\n", ret);
+		dev_err(dev, "failed to register component: %d\n", ret);
 		goto err_pwr;
 	}
 
@@ -225,7 +226,6 @@ static int pistachio_internal_dac_remove(struct platform_device *pdev)
 {
 	struct pistachio_internal_dac *dac = dev_get_drvdata(&pdev->dev);
 
-	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	pistachio_internal_dac_pwr_off(dac);
 	regulator_disable(dac->supply);
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
index 0f3604b..3672d36 100644
--- a/sound/soc/intel/atom/sst-atom-controls.c
+++ b/sound/soc/intel/atom/sst-atom-controls.c
@@ -1414,11 +1414,11 @@ static int sst_fill_module_list(struct snd_kcontrol *kctl,
  * name. First part of control name contains the pipe name (widget name).
  */
 static int sst_fill_widget_module_info(struct snd_soc_dapm_widget *w,
-	struct snd_soc_platform *platform)
+	struct snd_soc_component *component)
 {
 	struct snd_kcontrol *kctl;
 	int index, ret = 0;
-	struct snd_card *card = platform->component.card->snd_card;
+	struct snd_card *card = component->card->snd_card;
 	char *idx;
 
 	down_read(&card->controls_rwsem);
@@ -1468,13 +1468,13 @@ static int sst_fill_widget_module_info(struct snd_soc_dapm_widget *w,
 /**
  * sst_fill_linked_widgets - fill the parent pointer for the linked widget
  */
-static void sst_fill_linked_widgets(struct snd_soc_platform *platform,
+static void sst_fill_linked_widgets(struct snd_soc_component *component,
 						struct sst_ids *ids)
 {
 	struct snd_soc_dapm_widget *w;
 	unsigned int len = strlen(ids->parent_wname);
 
-	list_for_each_entry(w, &platform->component.card->widgets, list) {
+	list_for_each_entry(w, &component->card->widgets, list) {
 		if (!strncmp(ids->parent_wname, w->name, len)) {
 			ids->parent_w = w;
 			break;
@@ -1485,41 +1485,41 @@ static void sst_fill_linked_widgets(struct snd_soc_platform *platform,
 /**
  * sst_map_modules_to_pipe - fill algo/gains list for all pipes
  */
-static int sst_map_modules_to_pipe(struct snd_soc_platform *platform)
+static int sst_map_modules_to_pipe(struct snd_soc_component *component)
 {
 	struct snd_soc_dapm_widget *w;
 	int ret = 0;
 
-	list_for_each_entry(w, &platform->component.card->widgets, list) {
+	list_for_each_entry(w, &component->card->widgets, list) {
 		if (is_sst_dapm_widget(w) && (w->priv)) {
 			struct sst_ids *ids = w->priv;
 
-			dev_dbg(platform->dev, "widget type=%d name=%s\n",
+			dev_dbg(component->dev, "widget type=%d name=%s\n",
 					w->id, w->name);
 			INIT_LIST_HEAD(&ids->algo_list);
 			INIT_LIST_HEAD(&ids->gain_list);
-			ret = sst_fill_widget_module_info(w, platform);
+			ret = sst_fill_widget_module_info(w, component);
 
 			if (ret < 0)
 				return ret;
 
 			/* fill linked widgets */
 			if (ids->parent_wname !=  NULL)
-				sst_fill_linked_widgets(platform, ids);
+				sst_fill_linked_widgets(component, ids);
 		}
 	}
 	return 0;
 }
 
-int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform)
+int sst_dsp_init_v2_dpcm(struct snd_soc_component *component)
 {
 	int i, ret = 0;
 	struct snd_soc_dapm_context *dapm =
-			snd_soc_component_get_dapm(&platform->component);
-	struct sst_data *drv = snd_soc_platform_get_drvdata(platform);
+			snd_soc_component_get_dapm(component);
+	struct sst_data *drv = snd_soc_component_get_drvdata(component);
 	unsigned int gains = ARRAY_SIZE(sst_gain_controls)/3;
 
-	drv->byte_stream = devm_kzalloc(platform->dev,
+	drv->byte_stream = devm_kzalloc(component->dev,
 					SST_MAX_BIN_BYTES, GFP_KERNEL);
 	if (!drv->byte_stream)
 		return -ENOMEM;
@@ -1537,26 +1537,26 @@ int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform)
 		sst_gains[i].ramp_duration = SST_GAIN_RAMP_DURATION_DEFAULT;
 	}
 
-	ret = snd_soc_add_platform_controls(platform, sst_gain_controls,
+	ret = snd_soc_add_component_controls(component, sst_gain_controls,
 			ARRAY_SIZE(sst_gain_controls));
 	if (ret)
 		return ret;
 
 	/* Initialize algo control params */
-	ret = sst_algo_control_init(platform->dev);
+	ret = sst_algo_control_init(component->dev);
 	if (ret)
 		return ret;
-	ret = snd_soc_add_platform_controls(platform, sst_algo_controls,
+	ret = snd_soc_add_component_controls(component, sst_algo_controls,
 			ARRAY_SIZE(sst_algo_controls));
 	if (ret)
 		return ret;
 
-	ret = snd_soc_add_platform_controls(platform, sst_slot_controls,
+	ret = snd_soc_add_component_controls(component, sst_slot_controls,
 			ARRAY_SIZE(sst_slot_controls));
 	if (ret)
 		return ret;
 
-	ret = sst_map_modules_to_pipe(platform);
+	ret = sst_map_modules_to_pipe(component);
 
 	return ret;
 }
diff --git a/sound/soc/intel/atom/sst-mfld-platform-compress.c b/sound/soc/intel/atom/sst-mfld-platform-compress.c
index 1dbcab5..6a44b19 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-compress.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-compress.c
@@ -107,8 +107,8 @@ static int sst_platform_compr_set_params(struct snd_compr_stream *cstream,
 	struct snd_sst_params str_params;
 	struct sst_compress_cb cb;
 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
-	struct snd_soc_platform *platform = rtd->platform;
-	struct sst_data *ctx = snd_soc_platform_get_drvdata(platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_data *ctx = snd_soc_component_get_drvdata(component);
 
 	stream = cstream->runtime->private_data;
 	/* construct fw structure for this*/
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 43e7fdd..6c36da5 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -697,26 +697,22 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	return retval;
 }
 
-static int sst_soc_probe(struct snd_soc_platform *platform)
+static int sst_soc_probe(struct snd_soc_component *component)
 {
-	struct sst_data *drv = dev_get_drvdata(platform->dev);
+	struct sst_data *drv = dev_get_drvdata(component->dev);
 
-	drv->soc_card = platform->component.card;
-	return sst_dsp_init_v2_dpcm(platform);
+	drv->soc_card = component->card;
+	return sst_dsp_init_v2_dpcm(component);
 }
 
-static const struct snd_soc_platform_driver sst_soc_platform_drv  = {
+static const struct snd_soc_component_driver sst_soc_platform_drv  = {
+	.name		= DRV_NAME,
 	.probe		= sst_soc_probe,
 	.ops		= &sst_platform_ops,
 	.compr_ops	= &sst_platform_compr_ops,
 	.pcm_new	= sst_pcm_new,
 };
 
-static const struct snd_soc_component_driver sst_component = {
-	.name		= "sst",
-};
-
-
 static int sst_platform_probe(struct platform_device *pdev)
 {
 	struct sst_data *drv;
@@ -740,26 +736,16 @@ static int sst_platform_probe(struct platform_device *pdev)
 	mutex_init(&drv->lock);
 	dev_set_drvdata(&pdev->dev, drv);
 
-	ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
-	if (ret) {
-		dev_err(&pdev->dev, "registering soc platform failed\n");
-		return ret;
-	}
-
-	ret = snd_soc_register_component(&pdev->dev, &sst_component,
+	ret = devm_snd_soc_register_component(&pdev->dev, &sst_soc_platform_drv,
 				sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
-	if (ret) {
+	if (ret)
 		dev_err(&pdev->dev, "registering cpu dais failed\n");
-		snd_soc_unregister_platform(&pdev->dev);
-	}
+
 	return ret;
 }
 
 static int sst_platform_remove(struct platform_device *pdev)
 {
-
-	snd_soc_unregister_component(&pdev->dev);
-	snd_soc_unregister_platform(&pdev->dev);
 	dev_dbg(&pdev->dev, "sst_platform_remove success\n");
 	return 0;
 }
diff --git a/sound/soc/intel/atom/sst-mfld-platform.h b/sound/soc/intel/atom/sst-mfld-platform.h
index 31a58c2..5f729df 100644
--- a/sound/soc/intel/atom/sst-mfld-platform.h
+++ b/sound/soc/intel/atom/sst-mfld-platform.h
@@ -27,6 +27,8 @@
 extern struct sst_device *sst;
 extern const struct snd_compr_ops sst_platform_compr_ops;
 
+#define DRV_NAME "sst"
+
 #define SST_MONO		1
 #define SST_STEREO		2
 #define SST_MAX_CAP		5
@@ -155,7 +157,7 @@ struct sst_device {
 
 struct sst_data;
 
-int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform);
+int sst_dsp_init_v2_dpcm(struct snd_soc_component *component);
 int sst_send_pipe_gains(struct snd_soc_dai *dai, int stream, int mute);
 int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable);
 int sst_handle_vb_timer(struct snd_soc_dai *dai, bool enable);
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
index 8afdff4..0962bc9 100644
--- a/sound/soc/intel/atom/sst/sst.c
+++ b/sound/soc/intel/atom/sst/sst.c
@@ -449,6 +449,13 @@ static int intel_sst_suspend(struct device *dev)
 			dev_err(dev, "stream %d is running, can't suspend, abort\n", i);
 			return -EBUSY;
 		}
+
+		if (ctx->pdata->streams_lost_on_suspend) {
+			stream->resume_status = stream->status;
+			stream->resume_prev = stream->prev;
+			if (stream->status != STREAM_UN_INIT)
+				sst_free_stream(ctx, i);
+		}
 	}
 	synchronize_irq(ctx->irq_num);
 	flush_workqueue(ctx->post_msg_wq);
@@ -509,8 +516,8 @@ static int intel_sst_resume(struct device *dev)
 {
 	struct intel_sst_drv *ctx = dev_get_drvdata(dev);
 	struct sst_fw_save *fw_save = ctx->fw_save;
-	int ret = 0;
 	struct sst_block *block;
+	int i, ret = 0;
 
 	if (!fw_save)
 		return 0;
@@ -550,6 +557,21 @@ static int intel_sst_resume(struct device *dev)
 		sst_set_fw_state_locked(ctx, SST_FW_RUNNING);
 	}
 
+	if (ctx->pdata->streams_lost_on_suspend) {
+		for (i = 1; i <= ctx->info.max_streams; i++) {
+			struct stream_info *stream = &ctx->streams[i];
+
+			if (stream->resume_status != STREAM_UN_INIT) {
+				dev_dbg(ctx->dev, "Re-allocing stream %d status %d prev %d\n",
+					i, stream->resume_status,
+					stream->resume_prev);
+				sst_realloc_stream(ctx, i);
+				stream->status = stream->resume_status;
+				stream->prev = stream->resume_prev;
+			}
+		}
+	}
+
 	sst_free_block(ctx, block);
 	return ret;
 }
diff --git a/sound/soc/intel/atom/sst/sst.h b/sound/soc/intel/atom/sst/sst.h
index e02e2b4..b2a705d 100644
--- a/sound/soc/intel/atom/sst/sst.h
+++ b/sound/soc/intel/atom/sst/sst.h
@@ -65,9 +65,7 @@ enum sst_stream_states {
 	STREAM_UN_INIT	= 0,	/* Freed/Not used stream */
 	STREAM_RUNNING	= 1,	/* Running */
 	STREAM_PAUSED	= 2,	/* Paused stream */
-	STREAM_DECODE	= 3,	/* stream is in decoding only state */
-	STREAM_INIT	= 4,	/* stream init, waiting for data */
-	STREAM_RESET	= 5,	/* force reset on recovery */
+	STREAM_INIT	= 3,	/* stream init, waiting for data */
 };
 
 enum sst_ram_type {
@@ -181,22 +179,22 @@ struct sst_block {
  *
  * @status : stream current state
  * @prev : stream prev state
- * @ops : stream operation pb/cp/drm...
- * @bufs: stream buffer list
+ * @resume_status : stream current state to restore on resume
+ * @resume_prev : stream prev state to restore on resume
  * @lock : stream mutex for protecting state
+ * @alloc_param : parameters used for stream (re-)allocation
  * @pcm_substream : PCM substream
  * @period_elapsed : PCM period elapsed callback
  * @sfreq : stream sampling freq
- * @str_type : stream type
  * @cumm_bytes : cummulative bytes decoded
- * @str_type : stream type
- * @src : stream source
  */
 struct stream_info {
 	unsigned int		status;
 	unsigned int		prev;
-	unsigned int		ops;
+	unsigned int		resume_status;
+	unsigned int		resume_prev;
 	struct mutex		lock;
+	struct snd_sst_alloc_mrfld alloc_param;
 
 	void			*pcm_substream;
 	void (*period_elapsed)(void *pcm_substream);
@@ -212,7 +210,6 @@ struct stream_info {
 
 	unsigned int		num_ch;
 	unsigned int		pipe_id;
-	unsigned int		str_id;
 	unsigned int		task_id;
 };
 
@@ -438,6 +435,7 @@ struct intel_sst_ops {
 	void (*post_download)(struct intel_sst_drv *sst);
 };
 
+int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);
 int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int id);
 int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int id);
 int sst_drop_stream(struct intel_sst_drv *sst_drv_ctx, int id);
@@ -501,8 +499,6 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst,
 
 void sst_process_pending_msg(struct work_struct *work);
 int sst_assign_pvt_id(struct intel_sst_drv *sst_drv_ctx);
-void sst_init_stream(struct stream_info *stream,
-		int codec, int sst_id, int ops, u8 slot);
 int sst_validate_strid(struct intel_sst_drv *sst_drv_ctx, int str_id);
 struct stream_info *get_stream_info(struct intel_sst_drv *sst_drv_ctx,
 		int str_id);
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 6cd481b..c90b04c 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -143,10 +143,11 @@ static struct sst_platform_info byt_rvp_platform_data = {
 	.lib_info = &byt_lib_dnld_info,
 	.res_info = &byt_rvp_res_info,
 	.platform = "sst-mfld-platform",
+	.streams_lost_on_suspend = true,
 };
 
 /* Cherryview (Cherrytrail and Braswell) uses same mrfld dpcm fw as Baytrail,
- * so pdata is same as Baytrail.
+ * so pdata is same as Baytrail, minus the streams_lost_on_suspend quirk.
  */
 static struct sst_platform_info chv_platform_data = {
 	.probe_data = &byt_fwparse_info,
diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c
index 71af544..6a8b253 100644
--- a/sound/soc/intel/atom/sst/sst_drv_interface.c
+++ b/sound/soc/intel/atom/sst/sst_drv_interface.c
@@ -238,16 +238,7 @@ static int sst_cdev_close(struct device *dev, unsigned int str_id)
 		return -EINVAL;
 	}
 
-	if (stream->status == STREAM_RESET) {
-		dev_dbg(dev, "stream in reset state...\n");
-		stream->status = STREAM_UN_INIT;
-
-		retval = 0;
-		goto put;
-	}
-
 	retval = sst_free_stream(ctx, str_id);
-put:
 	stream->compr_cb_param = NULL;
 	stream->compr_cb = NULL;
 
@@ -256,7 +247,6 @@ static int sst_cdev_close(struct device *dev, unsigned int str_id)
 
 	dev_dbg(dev, "End\n");
 	return retval;
-
 }
 
 static int sst_cdev_ack(struct device *dev, unsigned int str_id,
@@ -486,16 +476,7 @@ static int sst_close_pcm_stream(struct device *dev, unsigned int str_id)
 		return -EINVAL;
 	}
 
-	if (stream->status == STREAM_RESET) {
-		/* silently fail here as we have cleaned the stream earlier */
-		dev_dbg(ctx->dev, "stream in reset state...\n");
-
-		retval = 0;
-		goto put;
-	}
-
 	retval = free_stream_context(ctx, str_id);
-put:
 	stream->pcm_substream = NULL;
 	stream->status = STREAM_UN_INIT;
 	stream->period_elapsed = NULL;
diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c
index b1e6b8f..af93244 100644
--- a/sound/soc/intel/atom/sst/sst_pvt.c
+++ b/sound/soc/intel/atom/sst/sst_pvt.c
@@ -360,14 +360,6 @@ int sst_assign_pvt_id(struct intel_sst_drv *drv)
 	return local;
 }
 
-void sst_init_stream(struct stream_info *stream,
-		int codec, int sst_id, int ops, u8 slot)
-{
-	stream->status = STREAM_INIT;
-	stream->prev = STREAM_UN_INIT;
-	stream->ops = ops;
-}
-
 int sst_validate_strid(
 		struct intel_sst_drv *sst_drv_ctx, int str_id)
 {
diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c
index 7ee6aeb..107271f 100644
--- a/sound/soc/intel/atom/sst/sst_stream.c
+++ b/sound/soc/intel/atom/sst/sst_stream.c
@@ -35,29 +35,31 @@
 
 int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
 {
-	struct snd_sst_alloc_mrfld alloc_param;
+	struct snd_pcm_params *pcm_params;
 	struct snd_sst_params *str_params;
 	struct snd_sst_tstamp fw_tstamp;
 	struct stream_info *str_info;
-	struct snd_sst_alloc_response *response;
-	unsigned int str_id, pipe_id, task_id;
-	int i, num_ch, ret = 0;
-	void *data = NULL;
+	int i, num_ch, str_id;
 
 	dev_dbg(sst_drv_ctx->dev, "Enter\n");
 
 	str_params = (struct snd_sst_params *)params;
-	memset(&alloc_param, 0, sizeof(alloc_param));
-	alloc_param.operation = str_params->ops;
-	alloc_param.codec_type = str_params->codec;
-	alloc_param.sg_count = str_params->aparams.sg_count;
-	alloc_param.ring_buf_info[0].addr =
-		str_params->aparams.ring_buf_info[0].addr;
-	alloc_param.ring_buf_info[0].size =
-		str_params->aparams.ring_buf_info[0].size;
-	alloc_param.frag_size = str_params->aparams.frag_size;
+	str_id = str_params->stream_id;
+	str_info = get_stream_info(sst_drv_ctx, str_id);
+	if (!str_info)
+		return -EINVAL;
 
-	memcpy(&alloc_param.codec_params, &str_params->sparams,
+	memset(&str_info->alloc_param, 0, sizeof(str_info->alloc_param));
+	str_info->alloc_param.operation = str_params->ops;
+	str_info->alloc_param.codec_type = str_params->codec;
+	str_info->alloc_param.sg_count = str_params->aparams.sg_count;
+	str_info->alloc_param.ring_buf_info[0].addr =
+		str_params->aparams.ring_buf_info[0].addr;
+	str_info->alloc_param.ring_buf_info[0].size =
+		str_params->aparams.ring_buf_info[0].size;
+	str_info->alloc_param.frag_size = str_params->aparams.frag_size;
+
+	memcpy(&str_info->alloc_param.codec_params, &str_params->sparams,
 			sizeof(struct snd_sst_stream_params));
 
 	/*
@@ -67,47 +69,62 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
 	 * Currently hardcoding as per FW reqm.
 	 */
 	num_ch = sst_get_num_channel(str_params);
+	pcm_params = &str_info->alloc_param.codec_params.uc.pcm_params;
 	for (i = 0; i < 8; i++) {
 		if (i < num_ch)
-			alloc_param.codec_params.uc.pcm_params.channel_map[i] = i;
+			pcm_params->channel_map[i] = i;
 		else
-			alloc_param.codec_params.uc.pcm_params.channel_map[i] = 0xFF;
+			pcm_params->channel_map[i] = 0xff;
 	}
 
-	str_id = str_params->stream_id;
-	str_info = get_stream_info(sst_drv_ctx, str_id);
-	if (str_info == NULL) {
-		dev_err(sst_drv_ctx->dev, "get stream info returned null\n");
-		return -EINVAL;
-	}
-
-	pipe_id = str_params->device_type;
-	task_id = str_params->task;
-	sst_drv_ctx->streams[str_id].pipe_id = pipe_id;
-	sst_drv_ctx->streams[str_id].task_id = task_id;
+	sst_drv_ctx->streams[str_id].status = STREAM_INIT;
+	sst_drv_ctx->streams[str_id].prev = STREAM_UN_INIT;
+	sst_drv_ctx->streams[str_id].pipe_id = str_params->device_type;
+	sst_drv_ctx->streams[str_id].task_id = str_params->task;
 	sst_drv_ctx->streams[str_id].num_ch = num_ch;
 
 	if (sst_drv_ctx->info.lpe_viewpt_rqd)
-		alloc_param.ts = sst_drv_ctx->info.mailbox_start +
+		str_info->alloc_param.ts = sst_drv_ctx->info.mailbox_start +
 			sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp));
 	else
-		alloc_param.ts = sst_drv_ctx->mailbox_add +
+		str_info->alloc_param.ts = sst_drv_ctx->mailbox_add +
 			sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp));
 
 	dev_dbg(sst_drv_ctx->dev, "alloc tstamp location = 0x%x\n",
-			alloc_param.ts);
+			str_info->alloc_param.ts);
 	dev_dbg(sst_drv_ctx->dev, "assigned pipe id 0x%x to task %d\n",
-			pipe_id, task_id);
+			str_info->pipe_id, str_info->task_id);
 
-	/* allocate device type context */
-	sst_init_stream(&sst_drv_ctx->streams[str_id], alloc_param.codec_type,
-			str_id, alloc_param.operation, 0);
+	return sst_realloc_stream(sst_drv_ctx, str_id);
+}
+
+/**
+ * sst_realloc_stream - Send msg for (re-)allocating a stream using the
+ * @sst_drv_ctx  intel_sst_drv context pointer
+ * @str_id:	 stream ID
+ *
+ * Send a msg for (re-)allocating a stream using the parameters previously
+ * passed to sst_alloc_stream_mrfld() for the same stream ID.
+ * Return: 0 or negative errno value.
+ */
+int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
+{
+	struct snd_sst_alloc_response *response;
+	struct stream_info *str_info;
+	void *data = NULL;
+	int ret;
+
+	str_info = get_stream_info(sst_drv_ctx, str_id);
+	if (!str_info)
+		return -EINVAL;
 
 	dev_dbg(sst_drv_ctx->dev, "Alloc for str %d pipe %#x\n",
-			str_id, pipe_id);
-	ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD,
-			IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param),
-			&alloc_param, &data, true, true, false, true);
+		str_id, str_info->pipe_id);
+
+	ret = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, IPC_CMD,
+			IPC_IA_ALLOC_STREAM_MRFLD, str_info->pipe_id,
+			sizeof(str_info->alloc_param), &str_info->alloc_param,
+			&data, true, true, false, true);
 
 	if (ret < 0) {
 		dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret);
@@ -253,7 +270,7 @@ int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
 		if (retval == 0) {
 			str_info->prev = str_info->status;
 			str_info->status = STREAM_PAUSED;
-		} else if (retval == SST_ERR_INVALID_STREAM_ID) {
+		} else if (retval == -SST_ERR_INVALID_STREAM_ID) {
 			retval = -EINVAL;
 			mutex_lock(&sst_drv_ctx->sst_lock);
 			sst_clean_stream(str_info);
@@ -285,7 +302,29 @@ int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
 		return -EINVAL;
 	if (str_info->status == STREAM_RUNNING)
 		return 0;
-	if (str_info->status == STREAM_PAUSED) {
+
+	if (str_info->resume_status == STREAM_PAUSED &&
+	    str_info->resume_prev == STREAM_RUNNING) {
+		/*
+		 * Stream was running before suspend and re-created on resume,
+		 * start it to get back to running state.
+		 */
+		dev_dbg(sst_drv_ctx->dev, "restart recreated stream after resume\n");
+		str_info->status = STREAM_RUNNING;
+		str_info->prev = STREAM_PAUSED;
+		retval = sst_start_stream(sst_drv_ctx, str_id);
+		str_info->resume_status = STREAM_UN_INIT;
+	} else if (str_info->resume_status == STREAM_PAUSED &&
+		   str_info->resume_prev == STREAM_INIT) {
+		/*
+		 * Stream was idle before suspend and re-created on resume,
+		 * keep it as is.
+		 */
+		dev_dbg(sst_drv_ctx->dev, "leaving recreated stream idle after resume\n");
+		str_info->status = STREAM_INIT;
+		str_info->prev = STREAM_PAUSED;
+		str_info->resume_status = STREAM_UN_INIT;
+	} else if (str_info->status == STREAM_PAUSED) {
 		retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id,
 				IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD,
 				str_info->pipe_id, 0, NULL, NULL,
diff --git a/sound/soc/intel/baytrail/sst-baytrail-pcm.c b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
index c545293..aabb35b 100644
--- a/sound/soc/intel/baytrail/sst-baytrail-pcm.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
@@ -23,6 +23,7 @@
 #include "../common/sst-dsp-priv.h"
 #include "../common/sst-dsp.h"
 
+#define DRV_NAME "byt-dai"
 #define BYT_PCM_COUNT		2
 
 static const struct snd_pcm_hardware sst_byt_pcm_hardware = {
@@ -69,8 +70,8 @@ static int sst_byt_pcm_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sst_byt_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
 	struct sst_byt *byt = pdata->byt;
 	u32 rate, bits;
@@ -141,8 +142,8 @@ static int sst_byt_pcm_hw_free(struct snd_pcm_substream *substream)
 static int sst_byt_pcm_restore_stream_context(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sst_byt_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
 	struct sst_byt *byt = pdata->byt;
 	int ret;
@@ -174,8 +175,8 @@ static void sst_byt_pcm_work(struct work_struct *work)
 static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sst_byt_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
 	struct sst_byt *byt = pdata->byt;
 
@@ -216,8 +217,8 @@ static u32 byt_notify_pointer(struct sst_byt_stream *stream, void *data)
 	struct snd_pcm_substream *substream = pcm_data->substream;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sst_byt_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_byt *byt = pdata->byt;
 	u32 pos, hw_pos;
 
@@ -238,8 +239,8 @@ static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct sst_byt_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
 
 	dev_dbg(rtd->dev, "PCM: DMA pointer %u bytes\n", pcm_data->hw_ptr);
@@ -250,8 +251,8 @@ static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream
 static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sst_byt_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
 	struct sst_byt *byt = pdata->byt;
 
@@ -278,8 +279,8 @@ static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
 static int sst_byt_pcm_close(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct sst_byt_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
 	struct sst_byt *byt = pdata->byt;
 	int ret;
@@ -324,8 +325,8 @@ static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_pcm *pcm = rtd->pcm;
 	size_t size;
-	struct snd_soc_platform *platform = rtd->platform;
-	struct sst_pdata *pdata = dev_get_platdata(platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_pdata *pdata = dev_get_platdata(component->dev);
 	int ret = 0;
 
 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
@@ -366,21 +367,21 @@ static struct snd_soc_dai_driver byt_dais[] = {
 	},
 };
 
-static int sst_byt_pcm_probe(struct snd_soc_platform *platform)
+static int sst_byt_pcm_probe(struct snd_soc_component *component)
 {
-	struct sst_pdata *plat_data = dev_get_platdata(platform->dev);
+	struct sst_pdata *plat_data = dev_get_platdata(component->dev);
 	struct sst_byt_priv_data *priv_data;
 	int i;
 
 	if (!plat_data)
 		return -ENODEV;
 
-	priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data),
+	priv_data = devm_kzalloc(component->dev, sizeof(*priv_data),
 				 GFP_KERNEL);
 	if (!priv_data)
 		return -ENOMEM;
 	priv_data->byt = plat_data->dsp;
-	snd_soc_platform_set_drvdata(platform, priv_data);
+	snd_soc_component_set_drvdata(component, priv_data);
 
 	for (i = 0; i < BYT_PCM_COUNT; i++) {
 		mutex_init(&priv_data->pcm[i].mutex);
@@ -390,22 +391,13 @@ static int sst_byt_pcm_probe(struct snd_soc_platform *platform)
 	return 0;
 }
 
-static int sst_byt_pcm_remove(struct snd_soc_platform *platform)
-{
-	return 0;
-}
-
-static const struct snd_soc_platform_driver byt_soc_platform = {
+static const struct snd_soc_component_driver byt_dai_component = {
+	.name		= DRV_NAME,
 	.probe		= sst_byt_pcm_probe,
-	.remove		= sst_byt_pcm_remove,
 	.ops		= &sst_byt_pcm_ops,
 	.pcm_new	= sst_byt_pcm_new,
 };
 
-static const struct snd_soc_component_driver byt_dai_component = {
-	.name		= "byt-dai",
-};
-
 #ifdef CONFIG_PM
 static int sst_byt_pcm_dev_suspend_late(struct device *dev)
 {
@@ -461,19 +453,13 @@ static int sst_byt_pcm_dev_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return -ENODEV;
 
-	ret = snd_soc_register_platform(&pdev->dev, &byt_soc_platform);
+	ret = devm_snd_soc_register_component(&pdev->dev, &byt_dai_component,
+					 byt_dais, ARRAY_SIZE(byt_dais));
 	if (ret < 0)
 		goto err_plat;
 
-	ret = snd_soc_register_component(&pdev->dev, &byt_dai_component,
-					 byt_dais, ARRAY_SIZE(byt_dais));
-	if (ret < 0)
-		goto err_comp;
-
 	return 0;
 
-err_comp:
-	snd_soc_unregister_platform(&pdev->dev);
 err_plat:
 	sst_byt_dsp_free(&pdev->dev, sst_pdata);
 	return ret;
@@ -483,8 +469,6 @@ static int sst_byt_pcm_dev_remove(struct platform_device *pdev)
 {
 	struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
 
-	snd_soc_unregister_platform(&pdev->dev);
-	snd_soc_unregister_component(&pdev->dev);
 	sst_byt_dsp_free(&pdev->dev, sst_pdata);
 
 	return 0;
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index fefb1ee..2479748 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -125,6 +125,17 @@
 	  Say Y or m if you have such a device. This is a recommended option.
 	  If unsure select "N".
 
+config SND_SOC_INTEL_CHT_BSW_NAU8824_MACH
+	tristate "Cherrytrail & Braswell with NAU88L24 codec"
+	depends on X86_INTEL_LPSS && I2C && ACPI
+	select SND_SOC_ACPI
+	select SND_SOC_NAU8824
+	help
+	  This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
+	  platforms with NAU88L24 audio codec.
+	  Say Y or m if you have such a device. This is a recommended option.
+	  If unsure select "N".
+
 config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
 	tristate "Baytrail & Cherrytrail with DA7212/7213 codec"
 	depends on X86_INTEL_LPSS && I2C && ACPI
@@ -256,6 +267,20 @@
           create an alsa sound card for RT5663 + RT5514 + MAX98927.
           Say Y or m if you have such a device. This is a recommended option.
           If unsure select "N".
+
+config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH
+	tristate "KBL with DA7219 and MAX98357A in I2S Mode"
+	depends on MFD_INTEL_LPSS && I2C && ACPI
+	select SND_SOC_DA7219
+	select SND_SOC_MAX98357A
+	select SND_SOC_DMIC
+	select SND_SOC_HDAC_HDMI
+	help
+	  This adds support for ASoC Onboard Codec I2S machine driver. This will
+	  create an alsa sound card for DA7219 + MAX98357A I2S audio codec.
+	  Say Y if you have such a device.
+	  If unsure select "N".
+
 endif ## SND_SOC_INTEL_SKYLAKE
 
 endif ## SND_SOC_INTEL_MACH
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 69d2dfa..92b5507 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -11,9 +11,11 @@
 snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
 snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
 snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
+snd-soc-sst-cht-bsw-nau8824-objs := cht_bsw_nau8824.o
 snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o
 snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o
 snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o
+snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o
 snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o
 snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
 snd-soc-skl_rt286-objs := skl_rt286.o
@@ -32,9 +34,11 @@
 obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
 obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
 obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
+obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH) += snd-soc-sst-cht-bsw-nau8824.o
 obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) += snd-soc-sst-byt-cht-da7213.o
 obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH) += snd-soc-sst-byt-cht-es8316.o
 obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) += snd-soc-sst-byt-cht-nocodec.o
+obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH) += snd-soc-kbl_da7219_max98357a.o
 obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH) += snd-soc-kbl_rt5663_max98927.o
 obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH) += snd-soc-kbl_rt5663_rt5514_max98927.o
 obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
index 058b8cc..6ea360f 100644
--- a/sound/soc/intel/boards/bdw-rt5677.c
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -34,7 +34,7 @@
 
 struct bdw_rt5677_priv {
 	struct gpio_desc *gpio_hp_en;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 };
 
 static int bdw_rt5677_event_hp(struct snd_soc_dapm_widget *w,
@@ -183,7 +183,8 @@ static const struct snd_soc_ops bdw_rt5677_ops = {
 
 static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_pdata *pdata = dev_get_platdata(component->dev);
 	struct sst_hsw *broadwell = pdata->dsp;
 	int ret;
 
@@ -203,26 +204,26 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct bdw_rt5677_priv *bdw_rt5677 =
 			snd_soc_card_get_drvdata(rtd->card);
-	struct snd_soc_codec *codec = rtd->codec;
-	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct snd_soc_component *component = rtd->codec_dai->component;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	int ret;
 
-	ret = devm_acpi_dev_add_driver_gpios(codec->dev, bdw_rt5677_gpios);
+	ret = devm_acpi_dev_add_driver_gpios(component->dev, bdw_rt5677_gpios);
 	if (ret)
-		dev_warn(codec->dev, "Failed to add driver gpios\n");
+		dev_warn(component->dev, "Failed to add driver gpios\n");
 
 	/* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1.
 	 * The ASRC clock source is clk_i2s1_asrc.
 	 */
-	rt5677_sel_asrc_clk_src(codec, RT5677_DA_STEREO_FILTER |
+	rt5677_sel_asrc_clk_src(component, RT5677_DA_STEREO_FILTER |
 			RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
 			RT5677_CLK_SEL_I2S1_ASRC);
 
 	/* Request rt5677 GPIO for headphone amp control */
-	bdw_rt5677->gpio_hp_en = devm_gpiod_get(codec->dev, "headphone-enable",
+	bdw_rt5677->gpio_hp_en = devm_gpiod_get(component->dev, "headphone-enable",
 						GPIOD_OUT_LOW);
 	if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
-		dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n");
+		dev_err(component->dev, "Can't find HP_AMP_SHDN_L gpio\n");
 		return PTR_ERR(bdw_rt5677->gpio_hp_en);
 	}
 
@@ -230,25 +231,25 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
 	if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack",
 			SND_JACK_HEADPHONE, &headphone_jack,
 			&headphone_jack_pin, 1)) {
-		headphone_jack_gpio.gpiod_dev = codec->dev;
+		headphone_jack_gpio.gpiod_dev = component->dev;
 		if (snd_soc_jack_add_gpios(&headphone_jack, 1,
 				&headphone_jack_gpio))
-			dev_err(codec->dev, "Can't add headphone jack gpio\n");
+			dev_err(component->dev, "Can't add headphone jack gpio\n");
 	} else {
-		dev_err(codec->dev, "Can't create headphone jack\n");
+		dev_err(component->dev, "Can't create headphone jack\n");
 	}
 
 	/* Create and initialize mic jack */
 	if (!snd_soc_card_jack_new(rtd->card, "Mic Jack",
 			SND_JACK_MICROPHONE, &mic_jack,
 			&mic_jack_pin, 1)) {
-		mic_jack_gpio.gpiod_dev = codec->dev;
+		mic_jack_gpio.gpiod_dev = component->dev;
 		if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio))
-			dev_err(codec->dev, "Can't add mic jack gpio\n");
+			dev_err(component->dev, "Can't add mic jack gpio\n");
 	} else {
-		dev_err(codec->dev, "Can't create mic jack\n");
+		dev_err(component->dev, "Can't create mic jack\n");
 	}
-	bdw_rt5677->codec = codec;
+	bdw_rt5677->component = component;
 
 	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
 	return 0;
@@ -301,8 +302,8 @@ static int bdw_rt5677_suspend_pre(struct snd_soc_card *card)
 	struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
 	struct snd_soc_dapm_context *dapm;
 
-	if (bdw_rt5677->codec) {
-		dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec);
+	if (bdw_rt5677->component) {
+		dapm = snd_soc_component_get_dapm(bdw_rt5677->component);
 		snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
 	}
 	return 0;
@@ -313,8 +314,8 @@ static int bdw_rt5677_resume_post(struct snd_soc_card *card)
 	struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
 	struct snd_soc_dapm_context *dapm;
 
-	if (bdw_rt5677->codec) {
-		dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec);
+	if (bdw_rt5677->component) {
+		dapm = snd_soc_component_get_dapm(bdw_rt5677->component);
 		snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
 	}
 	return 0;
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index 6dcbbce..7b0ee67 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -78,7 +78,7 @@ static const struct snd_soc_dapm_route broadwell_rt286_map[] = {
 
 static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	int ret = 0;
 	ret = snd_soc_card_jack_new(rtd->card, "Headset",
 		SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset,
@@ -86,7 +86,7 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
 	if (ret)
 		return ret;
 
-	rt286_mic_detect(codec, &broadwell_headset);
+	rt286_mic_detect(component, &broadwell_headset);
 	return 0;
 }
 
@@ -132,7 +132,8 @@ static const struct snd_soc_ops broadwell_rt286_ops = {
 
 static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_pdata *pdata = dev_get_platdata(component->dev);
 	struct sst_hsw *broadwell = pdata->dsp;
 	int ret;
 
@@ -224,10 +225,9 @@ static int broadwell_suspend(struct snd_soc_card *card){
 
 	list_for_each_entry(component, &card->component_dev_list, card_list) {
 		if (!strcmp(component->name, "i2c-INT343A:00")) {
-			struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-			dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
-			rt286_mic_detect(codec, NULL);
+			dev_dbg(component->dev, "disabling jack detect before going to suspend.\n");
+			rt286_mic_detect(component, NULL);
 			break;
 		}
 	}
@@ -239,10 +239,9 @@ static int broadwell_resume(struct snd_soc_card *card){
 
 	list_for_each_entry(component, &card->component_dev_list, card_list) {
 		if (!strcmp(component->name, "i2c-INT343A:00")) {
-			struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-			dev_dbg(codec->dev, "enabling jack detect for resume.\n");
-			rt286_mic_detect(codec, &broadwell_headset);
+			dev_dbg(component->dev, "enabling jack detect for resume.\n");
+			rt286_mic_detect(component, &broadwell_headset);
 			break;
 		}
 	}
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index f8a91a6..668c093 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -169,7 +169,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 
 	/* Configure sysclk for codec */
 	ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000,
@@ -192,7 +192,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
 		return ret;
 	}
 
-	da7219_aad_jack_det(codec, &broxton_headset);
+	da7219_aad_jack_det(component, &broxton_headset);
 
 	snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -522,12 +522,12 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
 {
 	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
 	struct bxt_hdmi_pcm *pcm;
-	struct snd_soc_codec *codec = NULL;
+	struct snd_soc_component *component = NULL;
 	int err, i = 0;
 	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-		codec = pcm->codec_dai->codec;
+		component = pcm->codec_dai->component;
 		snprintf(jack_name, sizeof(jack_name),
 			"HDMI/DP, pcm=%d Jack", pcm->device);
 		err = snd_soc_card_jack_new(card, jack_name,
@@ -545,10 +545,10 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
 		i++;
 	}
 
-	if (!codec)
+	if (!component)
 		return -EINVAL;
 
-	return hdac_hdmi_jack_port_init(codec, &card->dapm);
+	return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* broxton audio machine driver for SPT + da7219 */
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index 7843104..c7e9024 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -146,6 +146,9 @@ static const struct snd_soc_dapm_route geminilake_rt298_map[] = {
 	{ "dmic01_hifi", NULL, "DMIC01 Rx" },
 	{ "DMIC01 Rx", NULL, "Capture" },
 
+	{ "dmic_voice", NULL, "DMIC16k Rx" },
+	{ "DMIC16k Rx", NULL, "Capture" },
+
 	{ "hifi3", NULL, "iDisp3 Tx"},
 	{ "iDisp3 Tx", NULL, "iDisp3_out"},
 	{ "hifi2", NULL, "iDisp2 Tx"},
@@ -167,7 +170,7 @@ static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd)
 
 static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	int ret = 0;
 
 	ret = snd_soc_card_jack_new(rtd->card, "Headset",
@@ -178,7 +181,7 @@ static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
 	if (ret)
 		return ret;
 
-	rt298_mic_detect(codec, &broxton_headset);
+	rt298_mic_detect(component, &broxton_headset);
 
 	snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -457,6 +460,18 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
 		.no_pcm = 1,
 	},
 	{
+		.name = "dmic16k",
+		.id = 2,
+		.cpu_dai_name = "DMIC16k Pin",
+		.codec_name = "dmic-codec",
+		.codec_dai_name = "dmic-hifi",
+		.platform_name = "0000:00:0e.0",
+		.be_hw_params_fixup = broxton_dmic_fixup,
+		.ignore_suspend = 1,
+		.dpcm_capture = 1,
+		.no_pcm = 1,
+	},
+	{
 		.name = "iDisp1",
 		.id = 3,
 		.cpu_dai_name = "iDisp1 Pin",
@@ -496,12 +511,12 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
 {
 	struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
 	struct bxt_hdmi_pcm *pcm;
-	struct snd_soc_codec *codec = NULL;
+	struct snd_soc_component *component = NULL;
 	int err, i = 0;
 	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-		codec = pcm->codec_dai->codec;
+		component = pcm->codec_dai->component;
 		snprintf(jack_name, sizeof(jack_name),
 			"HDMI/DP, pcm=%d Jack", pcm->device);
 		err = snd_soc_card_jack_new(card, jack_name,
@@ -519,10 +534,10 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
 		i++;
 	}
 
-	if (!codec)
+	if (!component)
 		return -EINVAL;
 
-	return hdac_hdmi_jack_port_init(codec, &card->dapm);
+	return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 
diff --git a/sound/soc/intel/boards/byt-rt5640.c b/sound/soc/intel/boards/byt-rt5640.c
index de9788a..df902d8 100644
--- a/sound/soc/intel/boards/byt-rt5640.c
+++ b/sound/soc/intel/boards/byt-rt5640.c
@@ -131,7 +131,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 {
 	int ret;
-	struct snd_soc_codec *codec = runtime->codec;
+	struct snd_soc_component *component = runtime->codec_dai->component;
 	struct snd_soc_card *card = runtime->card;
 	const struct snd_soc_dapm_route *custom_map;
 	int num_routes;
@@ -165,7 +165,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 
 	if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
-		ret = rt5640_dmic_enable(codec, 0, 0);
+		ret = rt5640_dmic_enable(component, 0, 0);
 		if (ret)
 			return ret;
 	}
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index b6a1cfe..a8d8bff 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -444,14 +444,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
 	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
-	struct snd_soc_codec *codec = runtime->codec;
+	struct snd_soc_component *component = runtime->codec_dai->component;
 	const struct snd_soc_dapm_route *custom_map;
 	int num_routes;
 	int ret;
 
 	card->dapm.idle_bias_off = true;
 
-	rt5640_sel_asrc_clk_src(codec,
+	rt5640_sel_asrc_clk_src(component,
 				RT5640_DA_STEREO_FILTER |
 				RT5640_DA_MONO_L_FILTER	|
 				RT5640_DA_MONO_R_FILTER	|
@@ -522,12 +522,12 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 
 	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
-		snd_soc_update_bits(codec,  RT5640_IN1_IN2, RT5640_IN_DF1,
+		snd_soc_component_update_bits(component,  RT5640_IN1_IN2, RT5640_IN_DF1,
 				    RT5640_IN_DF1);
 	}
 
 	if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
-		ret = rt5640_dmic_enable(codec, 0, 0);
+		ret = rt5640_dmic_enable(component, 0, 0);
 		if (ret)
 			return ret;
 	}
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index 456526a..1b1997f 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -18,13 +18,16 @@
  */
 
 #include <linux/init.h>
+#include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <asm/cpu_device_id.h>
 #include <asm/platform_sst_audio.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -39,22 +42,55 @@ enum {
 	BYT_RT5651_IN1_MAP,
 	BYT_RT5651_IN2_MAP,
 	BYT_RT5651_IN1_IN2_MAP,
-	BYT_RT5651_IN3_MAP,
+	BYT_RT5651_IN1_HS_IN3_MAP,
+	BYT_RT5651_IN2_HS_IN3_MAP,
 };
 
-#define BYT_RT5651_MAP(quirk)	((quirk) & GENMASK(7, 0))
-#define BYT_RT5651_DMIC_EN	BIT(16)
-#define BYT_RT5651_MCLK_EN	BIT(17)
-#define BYT_RT5651_MCLK_25MHZ	BIT(18)
+enum {
+	BYT_RT5651_JD_NULL	= (RT5651_JD_NULL << 4),
+	BYT_RT5651_JD1_1	= (RT5651_JD1_1 << 4),
+	BYT_RT5651_JD1_2	= (RT5651_JD1_2 << 4),
+	BYT_RT5651_JD2		= (RT5651_JD2 << 4),
+};
+
+enum {
+	BYT_RT5651_OVCD_TH_600UA  = (6 << 8),
+	BYT_RT5651_OVCD_TH_1500UA = (15 << 8),
+	BYT_RT5651_OVCD_TH_2000UA = (20 << 8),
+};
+
+enum {
+	BYT_RT5651_OVCD_SF_0P5	= (RT5651_OVCD_SF_0P5 << 13),
+	BYT_RT5651_OVCD_SF_0P75	= (RT5651_OVCD_SF_0P75 << 13),
+	BYT_RT5651_OVCD_SF_1P0	= (RT5651_OVCD_SF_1P0 << 13),
+	BYT_RT5651_OVCD_SF_1P5	= (RT5651_OVCD_SF_1P5 << 13),
+};
+
+#define BYT_RT5651_MAP(quirk)		((quirk) & GENMASK(3, 0))
+#define BYT_RT5651_JDSRC(quirk)		(((quirk) & GENMASK(7, 4)) >> 4)
+#define BYT_RT5651_OVCD_TH(quirk)	(((quirk) & GENMASK(12, 8)) >> 8)
+#define BYT_RT5651_OVCD_SF(quirk)	(((quirk) & GENMASK(14, 13)) >> 13)
+#define BYT_RT5651_DMIC_EN		BIT(16)
+#define BYT_RT5651_MCLK_EN		BIT(17)
+#define BYT_RT5651_MCLK_25MHZ		BIT(18)
+#define BYT_RT5651_SSP2_AIF2		BIT(19) /* default is using AIF1  */
+#define BYT_RT5651_SSP0_AIF1		BIT(20)
+#define BYT_RT5651_SSP0_AIF2		BIT(21)
+
+/* jack-detect-source + dmic-en + ovcd-th + -sf + terminating empty entry */
+#define MAX_NO_PROPS 5
 
 struct byt_rt5651_private {
 	struct clk *mclk;
 	struct snd_soc_jack jack;
 };
 
-static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC_MAP |
-					BYT_RT5651_DMIC_EN |
-					BYT_RT5651_MCLK_EN;
+/* Default: jack-detect on JD1_1, internal mic on in2, headsetmic on in3 */
+static unsigned long byt_rt5651_quirk = BYT_RT5651_MCLK_EN |
+					BYT_RT5651_JD1_1 |
+					BYT_RT5651_OVCD_TH_2000UA |
+					BYT_RT5651_OVCD_SF_0P75 |
+					BYT_RT5651_IN2_HS_IN3_MAP;
 
 static void log_quirks(struct device *dev)
 {
@@ -64,17 +100,66 @@ static void log_quirks(struct device *dev)
 		dev_info(dev, "quirk IN1_MAP enabled");
 	if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP)
 		dev_info(dev, "quirk IN2_MAP enabled");
-	if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN3_MAP)
-		dev_info(dev, "quirk IN3_MAP enabled");
+	if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_HS_IN3_MAP)
+		dev_info(dev, "quirk IN1_HS_IN3_MAP enabled");
+	if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_HS_IN3_MAP)
+		dev_info(dev, "quirk IN2_HS_IN3_MAP enabled");
+	if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) {
+		dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
+			 BYT_RT5651_JDSRC(byt_rt5651_quirk));
+		dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
+			 BYT_RT5651_OVCD_TH(byt_rt5651_quirk) * 100);
+		dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
+			 BYT_RT5651_OVCD_SF(byt_rt5651_quirk));
+	}
 	if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
 		dev_info(dev, "quirk DMIC enabled");
 	if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
 		dev_info(dev, "quirk MCLK_EN enabled");
 	if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
 		dev_info(dev, "quirk MCLK_25MHZ enabled");
+	if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2)
+		dev_info(dev, "quirk SSP2_AIF2 enabled\n");
+	if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1)
+		dev_info(dev, "quirk SSP0_AIF1 enabled\n");
+	if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)
+		dev_info(dev, "quirk SSP0_AIF2 enabled\n");
 }
 
 #define BYT_CODEC_DAI1	"rt5651-aif1"
+#define BYT_CODEC_DAI2	"rt5651-aif2"
+
+static int byt_rt5651_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
+					      int rate, int bclk_ratio)
+{
+	int clk_id, clk_freq, ret;
+
+	/* Configure the PLL before selecting it */
+	if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
+		clk_id = RT5651_PLL1_S_BCLK1,
+		clk_freq = rate * bclk_ratio;
+	} else {
+		clk_id = RT5651_PLL1_S_MCLK;
+		if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
+			clk_freq = 25000000;
+		else
+			clk_freq = 19200000;
+	}
+	ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, rate * 512);
+	if (ret < 0) {
+		dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
+				     rate * 512, SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
 
 static int platform_clock_control(struct snd_soc_dapm_widget *w,
 				  struct snd_kcontrol *k, int  event)
@@ -86,6 +171,8 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
 	int ret;
 
 	codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
+	if (!codec_dai)
+		codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
 	if (!codec_dai) {
 		dev_err(card->dev,
 			"Codec dai not found; Unable to set platform clock\n");
@@ -101,9 +188,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
 				return ret;
 			}
 		}
-		ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
-					     48000 * 512,
-					     SND_SOC_CLOCK_IN);
+		ret = byt_rt5651_prepare_and_enable_pll1(codec_dai, 48000, 50);
 	} else {
 		/*
 		 * Set codec clock source to internal clock before
@@ -145,13 +230,6 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
 	{"Speaker", NULL, "Platform Clock"},
 	{"Line In", NULL, "Platform Clock"},
 
-	{"AIF1 Playback", NULL, "ssp2 Tx"},
-	{"ssp2 Tx", NULL, "codec_out0"},
-	{"ssp2 Tx", NULL, "codec_out1"},
-	{"codec_in0", NULL, "ssp2 Rx"},
-	{"codec_in1", NULL, "ssp2 Rx"},
-	{"ssp2 Rx", NULL, "AIF1 Capture"},
-
 	{"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
@@ -170,8 +248,8 @@ static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = {
 
 static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
 	{"Internal Mic", NULL, "micbias1"},
-	{"IN2P", NULL, "Headset Mic"},
 	{"IN1P", NULL, "Internal Mic"},
+	{"IN2P", NULL, "Headset Mic"},
 };
 
 static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = {
@@ -187,10 +265,52 @@ static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_in2_map[] = {
 	{"IN3P", NULL, "Headset Mic"},
 };
 
-static const struct snd_soc_dapm_route byt_rt5651_intmic_in3_map[] = {
+static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_hs_in3_map[] = {
 	{"Internal Mic", NULL, "micbias1"},
-	{"IN3P", NULL, "Headset Mic"},
 	{"IN1P", NULL, "Internal Mic"},
+	{"IN3P", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_hs_in3_map[] = {
+	{"Internal Mic", NULL, "micbias1"},
+	{"IN2P", NULL, "Internal Mic"},
+	{"IN3P", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif1_map[] = {
+	{"ssp0 Tx", NULL, "modem_out"},
+	{"modem_in", NULL, "ssp0 Rx"},
+
+	{"AIF1 Playback", NULL, "ssp0 Tx"},
+	{"ssp0 Rx", NULL, "AIF1 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif2_map[] = {
+	{"ssp0 Tx", NULL, "modem_out"},
+	{"modem_in", NULL, "ssp0 Rx"},
+
+	{"AIF2 Playback", NULL, "ssp0 Tx"},
+	{"ssp0 Rx", NULL, "AIF2 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif1_map[] = {
+	{"ssp2 Tx", NULL, "codec_out0"},
+	{"ssp2 Tx", NULL, "codec_out1"},
+	{"codec_in0", NULL, "ssp2 Rx"},
+	{"codec_in1", NULL, "ssp2 Rx"},
+
+	{"AIF1 Playback", NULL, "ssp2 Tx"},
+	{"ssp2 Rx", NULL, "AIF1 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif2_map[] = {
+	{"ssp2 Tx", NULL, "codec_out0"},
+	{"ssp2 Tx", NULL, "codec_out1"},
+	{"codec_in0", NULL, "ssp2 Rx"},
+	{"codec_in1", NULL, "ssp2 Rx"},
+
+	{"AIF2 Playback", NULL, "ssp2 Tx"},
+	{"ssp2 Rx", NULL, "AIF2 Capture"},
 };
 
 static const struct snd_kcontrol_new byt_rt5651_controls[] = {
@@ -217,44 +337,16 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
+	snd_pcm_format_t format = params_format(params);
+	int rate = params_rate(params);
+	int bclk_ratio;
 
-	snd_soc_dai_set_bclk_ratio(codec_dai, 50);
+	if (format == SNDRV_PCM_FORMAT_S16_LE)
+		bclk_ratio = 32;
+	else
+		bclk_ratio = 50;
 
-	ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
-				     params_rate(params) * 512,
-				     SND_SOC_CLOCK_IN);
-	if (ret < 0) {
-		dev_err(rtd->dev, "can't set codec clock %d\n", ret);
-		return ret;
-	}
-
-	if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
-		/* 2x25 bit slots on SSP2 */
-		ret = snd_soc_dai_set_pll(codec_dai, 0,
-					RT5651_PLL1_S_BCLK1,
-					params_rate(params) * 50,
-					params_rate(params) * 512);
-	} else {
-		if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) {
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5651_PLL1_S_MCLK,
-						25000000,
-						params_rate(params) * 512);
-		} else {
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5651_PLL1_S_MCLK,
-						19200000,
-						params_rate(params) * 512);
-		}
-	}
-
-	if (ret < 0) {
-		dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
+	return byt_rt5651_prepare_and_enable_pll1(codec_dai, rate, bclk_ratio);
 }
 
 static int byt_rt5651_quirk_cb(const struct dmi_system_id *id)
@@ -270,7 +362,7 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
 		},
-		.driver_data = (void *)(BYT_RT5651_IN3_MAP),
+		.driver_data = (void *)(BYT_RT5651_IN1_HS_IN3_MAP),
 	},
 	{
 		.callback = byt_rt5651_quirk_cb,
@@ -279,7 +371,7 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Turbot"),
 		},
 		.driver_data = (void *)(BYT_RT5651_MCLK_EN |
-					BYT_RT5651_IN3_MAP),
+					BYT_RT5651_IN1_HS_IN3_MAP),
 	},
 	{
 		.callback = byt_rt5651_quirk_cb,
@@ -288,15 +380,76 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
 		},
 		.driver_data = (void *)(BYT_RT5651_MCLK_EN |
+					BYT_RT5651_JD1_1 |
+					BYT_RT5651_OVCD_TH_2000UA |
+					BYT_RT5651_OVCD_SF_0P75 |
+					BYT_RT5651_IN1_IN2_MAP),
+	},
+	{
+		/* Chuwi Vi8 Plus (CWI519) */
+		.callback = byt_rt5651_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "D2D3_Vi8A1"),
+		},
+		.driver_data = (void *)(BYT_RT5651_MCLK_EN |
+					BYT_RT5651_JD1_1 |
+					BYT_RT5651_OVCD_TH_2000UA |
+					BYT_RT5651_OVCD_SF_0P75 |
+					BYT_RT5651_IN2_HS_IN3_MAP),
+	},
+	{
+		/* VIOS LTH17 */
+		.callback = byt_rt5651_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "VIOS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LTH17"),
+		},
+		.driver_data = (void *)(BYT_RT5651_MCLK_EN |
+					BYT_RT5651_JD1_1 |
+					BYT_RT5651_OVCD_TH_2000UA |
+					BYT_RT5651_OVCD_SF_1P0 |
 					BYT_RT5651_IN1_IN2_MAP),
 	},
 	{}
 };
 
+/*
+ * Note this MUST be called before snd_soc_register_card(), so that the props
+ * are in place before the codec component driver's probe function parses them.
+ */
+static int byt_rt5651_add_codec_device_props(const char *i2c_dev_name)
+{
+	struct property_entry props[MAX_NO_PROPS] = {};
+	struct device *i2c_dev;
+	int ret, cnt = 0;
+
+	i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
+	if (!i2c_dev)
+		return -EPROBE_DEFER;
+
+	props[cnt++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source",
+				BYT_RT5651_JDSRC(byt_rt5651_quirk));
+
+	props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-threshold-microamp",
+				BYT_RT5651_OVCD_TH(byt_rt5651_quirk) * 100);
+
+	props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-scale-factor",
+				BYT_RT5651_OVCD_SF(byt_rt5651_quirk));
+
+	if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
+		props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,dmic-en");
+
+	ret = device_add_properties(i2c_dev, props);
+	put_device(i2c_dev);
+
+	return ret;
+}
+
 static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
-	struct snd_soc_codec *codec = runtime->codec;
+	struct snd_soc_component *codec = runtime->codec_dai->component;
 	struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
 	const struct snd_soc_dapm_route *custom_map;
 	int num_routes;
@@ -304,6 +457,11 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
 
 	card->dapm.idle_bias_off = true;
 
+	/* Start with RC clk for jack-detect (we disable MCLK below) */
+	if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
+		snd_soc_component_update_bits(codec, RT5651_GLB_CLK,
+			RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_RCCLK);
+
 	switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
 	case BYT_RT5651_IN1_MAP:
 		custom_map = byt_rt5651_intmic_in1_map;
@@ -317,9 +475,13 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
 		custom_map = byt_rt5651_intmic_in1_in2_map;
 		num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map);
 		break;
-	case BYT_RT5651_IN3_MAP:
-		custom_map = byt_rt5651_intmic_in3_map;
-		num_routes = ARRAY_SIZE(byt_rt5651_intmic_in3_map);
+	case BYT_RT5651_IN1_HS_IN3_MAP:
+		custom_map = byt_rt5651_intmic_in1_hs_in3_map;
+		num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_hs_in3_map);
+		break;
+	case BYT_RT5651_IN2_HS_IN3_MAP:
+		custom_map = byt_rt5651_intmic_in2_hs_in3_map;
+		num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_hs_in3_map);
 		break;
 	default:
 		custom_map = byt_rt5651_intmic_dmic_map;
@@ -329,6 +491,26 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
 	if (ret)
 		return ret;
 
+	if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) {
+		ret = snd_soc_dapm_add_routes(&card->dapm,
+					byt_rt5651_ssp2_aif2_map,
+					ARRAY_SIZE(byt_rt5651_ssp2_aif2_map));
+	} else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) {
+		ret = snd_soc_dapm_add_routes(&card->dapm,
+					byt_rt5651_ssp0_aif1_map,
+					ARRAY_SIZE(byt_rt5651_ssp0_aif1_map));
+	} else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2) {
+		ret = snd_soc_dapm_add_routes(&card->dapm,
+					byt_rt5651_ssp0_aif2_map,
+					ARRAY_SIZE(byt_rt5651_ssp0_aif2_map));
+	} else {
+		ret = snd_soc_dapm_add_routes(&card->dapm,
+					byt_rt5651_ssp2_aif1_map,
+					ARRAY_SIZE(byt_rt5651_ssp2_aif1_map));
+	}
+	if (ret)
+		return ret;
+
 	ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
 					ARRAY_SIZE(byt_rt5651_controls));
 	if (ret) {
@@ -362,17 +544,21 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
 			dev_err(card->dev, "unable to set MCLK rate\n");
 	}
 
-	ret = snd_soc_card_jack_new(runtime->card, "Headset",
+	if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) {
+		ret = snd_soc_card_jack_new(runtime->card, "Headset",
 				    SND_JACK_HEADSET, &priv->jack,
 				    bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins));
-	if (ret) {
-		dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
-		return ret;
+		if (ret) {
+			dev_err(runtime->dev, "jack creation failed %d\n", ret);
+			return ret;
+		}
+
+		ret = snd_soc_component_set_jack(codec, &priv->jack, NULL);
+		if (ret)
+			return ret;
 	}
 
-	rt5651_set_jack_detect(codec, &priv->jack);
-
-	return ret;
+	return 0;
 }
 
 static const struct snd_soc_pcm_stream byt_rt5651_dai_params = {
@@ -390,18 +576,26 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 			SNDRV_PCM_HW_PARAM_RATE);
 	struct snd_interval *channels = hw_param_interval(params,
 						SNDRV_PCM_HW_PARAM_CHANNELS);
-	int ret;
+	int ret, bits;
 
-	/* The DSP will covert the FE rate to 48k, stereo, 24bits */
+	/* The DSP will covert the FE rate to 48k, stereo */
 	rate->min = rate->max = 48000;
 	channels->min = channels->max = 2;
 
-	/* set SSP2 to 24-bit */
-	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+	if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
+	    (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
+		/* set SSP0 to 16-bit */
+		params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+		bits = 16;
+	} else {
+		/* set SSP2 to 24-bit */
+		params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+		bits = 24;
+	}
 
 	/*
 	 * Default mode for SSP configuration is TDM 4 slot, override config
-	 * with explicit setting to I2S 2ch 24-bit. The word length is set with
+	 * with explicit setting to I2S 2ch. The word length is set with
 	 * dai_set_tdm_slot() since there is no other API exposed
 	 */
 	ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
@@ -415,7 +609,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 		return ret;
 	}
 
-	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits);
 	if (ret < 0) {
 		dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
 		return ret;
@@ -510,12 +704,32 @@ static struct snd_soc_card byt_rt5651_card = {
 };
 
 static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN];
+static char byt_rt5651_codec_aif_name[12]; /*  = "rt5651-aif[1|2]" */
+static char byt_rt5651_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
+
+static bool is_valleyview(void)
+{
+	static const struct x86_cpu_id cpu_ids[] = {
+		{ X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
+		{}
+	};
+
+	if (!x86_match_cpu(cpu_ids))
+		return false;
+	return true;
+}
+
+struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
+	u64 aif_value;       /* 1: AIF1, 2: AIF2 */
+	u64 mclock_value;    /* usually 25MHz (0x17d7940), ignored */
+};
 
 static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
 {
 	struct byt_rt5651_private *priv;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
+	bool is_bytcr = false;
 	int ret_val = 0;
 	int dai_index = 0;
 	int i;
@@ -540,17 +754,105 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
 
 	/* fixup codec name based on HID */
 	i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
-	if (i2c_name) {
-		snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
-			"%s%s", "i2c-", i2c_name);
+	if (!i2c_name) {
+		dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
+		return -ENODEV;
+	}
+	snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
+		"%s%s", "i2c-", i2c_name);
+	byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
 
-		byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
+	/*
+	 * swap SSP0 if bytcr is detected
+	 * (will be overridden if DMI quirk is detected)
+	 */
+	if (is_valleyview()) {
+		struct sst_platform_info *p_info = mach->pdata;
+		const struct sst_res_info *res_info = p_info->res_info;
+
+		if (res_info->acpi_ipc_irq_index == 0)
+			is_bytcr = true;
+	}
+
+	if (is_bytcr) {
+		/*
+		 * Baytrail CR platforms may have CHAN package in BIOS, try
+		 * to find relevant routing quirk based as done on Windows
+		 * platforms. We have to read the information directly from the
+		 * BIOS, at this stage the card is not created and the links
+		 * with the codec driver/pdata are non-existent
+		 */
+
+		struct acpi_chan_package chan_package;
+
+		/* format specified: 2 64-bit integers */
+		struct acpi_buffer format = {sizeof("NN"), "NN"};
+		struct acpi_buffer state = {0, NULL};
+		struct snd_soc_acpi_package_context pkg_ctx;
+		bool pkg_found = false;
+
+		state.length = sizeof(chan_package);
+		state.pointer = &chan_package;
+
+		pkg_ctx.name = "CHAN";
+		pkg_ctx.length = 2;
+		pkg_ctx.format = &format;
+		pkg_ctx.state = &state;
+		pkg_ctx.data_valid = false;
+
+		pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
+							       &pkg_ctx);
+		if (pkg_found) {
+			if (chan_package.aif_value == 1) {
+				dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
+				byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF1;
+			} else  if (chan_package.aif_value == 2) {
+				dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
+				byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
+			} else {
+				dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
+				pkg_found = false;
+			}
+		}
+
+		if (!pkg_found) {
+			/* no BIOS indications, assume SSP0-AIF2 connection */
+			byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
+		}
 	}
 
 	/* check quirks before creating card */
 	dmi_check_system(byt_rt5651_quirk_table);
+
+	/* Must be called before register_card, also see declaration comment. */
+	ret_val = byt_rt5651_add_codec_device_props(byt_rt5651_codec_name);
+	if (ret_val)
+		return ret_val;
+
 	log_quirks(&pdev->dev);
 
+	if ((byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) ||
+	    (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
+		/* fixup codec aif name */
+		snprintf(byt_rt5651_codec_aif_name,
+			sizeof(byt_rt5651_codec_aif_name),
+			"%s", "rt5651-aif2");
+
+		byt_rt5651_dais[dai_index].codec_dai_name =
+			byt_rt5651_codec_aif_name;
+	}
+
+	if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
+	    (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
+		/* fixup cpu dai name name */
+		snprintf(byt_rt5651_cpu_dai_name,
+			sizeof(byt_rt5651_cpu_dai_name),
+			"%s", "ssp0-port");
+
+		byt_rt5651_dais[dai_index].cpu_dai_name =
+			byt_rt5651_cpu_dai_name;
+	}
+
 	if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
 		priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
 		if (IS_ERR(priv->mclk)) {
diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c
new file mode 100644
index 0000000..680f2b3
--- /dev/null
+++ b/sound/soc/intel/boards/cht_bsw_nau8824.c
@@ -0,0 +1,282 @@
+/*
+ *  cht-bsw-nau8824.c - ASoc Machine driver for Intel Cherryview-based
+ *          platforms Cherrytrail and Braswell, with nau8824 codec.
+ *
+ *  Copyright (C) 2018 Intel Corp
+ *  Copyright (C) 2018 Nuvoton Technology Corp
+ *
+ *  Author: Wang, Joseph C <joequant@gmail.com>
+ *  Co-author: John Hsu <KCHSU0@nuvoton.com>
+ *  This file is based on cht_bsw_rt5672.c and cht-bsw-max98090.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <linux/input.h>
+#include "../atom/sst-atom-controls.h"
+#include "../../codecs/nau8824.h"
+
+struct cht_mc_private {
+	struct snd_soc_jack jack;
+};
+
+static struct snd_soc_jack_pin cht_bsw_jack_pins[] = {
+	{
+		.pin = "Headphone",
+		.mask = SND_JACK_HEADPHONE,
+	},
+	{
+		.pin = "Headset Mic",
+		.mask = SND_JACK_MICROPHONE,
+	},
+};
+
+static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+	SND_SOC_DAPM_MIC("Int Mic", NULL),
+	SND_SOC_DAPM_SPK("Ext Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route cht_audio_map[] = {
+	{"Ext Spk", NULL, "SPKOUTL"},
+	{"Ext Spk", NULL, "SPKOUTR"},
+	{"Headphone", NULL, "HPOL"},
+	{"Headphone", NULL, "HPOR"},
+	{"MIC1", NULL, "Int Mic"},
+	{"MIC2", NULL, "Int Mic"},
+	{"HSMIC1", NULL, "Headset Mic"},
+	{"HSMIC2", NULL, "Headset Mic"},
+	{"Playback", NULL, "ssp2 Tx"},
+	{"ssp2 Tx", NULL, "codec_out0"},
+	{"ssp2 Tx", NULL, "codec_out1"},
+	{"codec_in0", NULL, "ssp2 Rx" },
+	{"codec_in1", NULL, "ssp2 Rx" },
+	{"ssp2 Rx", NULL, "Capture"},
+};
+
+static const struct snd_kcontrol_new cht_mc_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Headphone"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
+	SOC_DAPM_PIN_SWITCH("Int Mic"),
+	SOC_DAPM_PIN_SWITCH("Ext Spk"),
+};
+
+static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	int ret;
+
+	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8824_CLK_FLL_FS, 0,
+		SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		dev_err(codec_dai->dev, "can't set FS clock %d\n", ret);
+		return ret;
+	}
+	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),
+		params_rate(params) * 256);
+	if (ret < 0) {
+		dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
+{
+	struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
+	struct snd_soc_jack *jack = &ctx->jack;
+	struct snd_soc_dai *codec_dai = runtime->codec_dai;
+	struct snd_soc_component *component = codec_dai->component;
+	int ret, jack_type;
+
+	/* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
+	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xf, 0x1, 4, 24);
+	if (ret < 0) {
+		dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret);
+		return ret;
+	}
+
+	/* NAU88L24 supports 4 butons headset detection
+	 * KEY_MEDIA
+	 * KEY_VOICECOMMAND
+	 * KEY_VOLUMEUP
+	 * KEY_VOLUMEDOWN
+	 */
+	jack_type = SND_JACK_HEADPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+		SND_JACK_BTN_2 | SND_JACK_BTN_3;
+	ret = snd_soc_card_jack_new(runtime->card, "Headset", jack_type, jack,
+		cht_bsw_jack_pins, ARRAY_SIZE(cht_bsw_jack_pins));
+	if (ret) {
+		dev_err(runtime->dev,
+			"Headset Jack creation failed %d\n", ret);
+		return ret;
+	}
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+	nau8824_enable_jack_detect(component, jack);
+
+	return ret;
+}
+
+static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+		SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *channels = hw_param_interval(params,
+		SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_mask *fmt =
+		hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+	/* The DSP will covert the FE rate to 48k, stereo, 24bits */
+	rate->min = rate->max = 48000;
+	channels->min = channels->max = 2;
+
+	/* set SSP2 to 24-bit */
+	snd_mask_none(fmt);
+	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+	return 0;
+}
+
+static int cht_aif1_startup(struct snd_pcm_substream *substream)
+{
+	return snd_pcm_hw_constraint_single(substream->runtime,
+		SNDRV_PCM_HW_PARAM_RATE, 48000);
+}
+
+static const struct snd_soc_ops cht_aif1_ops = {
+	.startup = cht_aif1_startup,
+};
+
+static const struct snd_soc_ops cht_be_ssp2_ops = {
+	.hw_params = cht_aif1_hw_params,
+};
+
+static struct snd_soc_dai_link cht_dailink[] = {
+	/* Front End DAI links */
+	[MERR_DPCM_AUDIO] = {
+		.name = "Audio Port",
+		.stream_name = "Audio",
+		.cpu_dai_name = "media-cpu-dai",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.platform_name = "sst-mfld-platform",
+		.nonatomic = true,
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.dpcm_capture = 1,
+		.ops = &cht_aif1_ops,
+	},
+	[MERR_DPCM_DEEP_BUFFER] = {
+		.name = "Deep-Buffer Audio Port",
+		.stream_name = "Deep-Buffer Audio",
+		.cpu_dai_name = "deepbuffer-cpu-dai",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.platform_name = "sst-mfld-platform",
+		.nonatomic = true,
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &cht_aif1_ops,
+	},
+	[MERR_DPCM_COMPR] = {
+		.name = "Compressed Port",
+		.stream_name = "Compress",
+		.cpu_dai_name = "compress-cpu-dai",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.platform_name = "sst-mfld-platform",
+	},
+	/* Back End DAI links */
+	{
+		/* SSP2 - Codec */
+		.name = "SSP2-Codec",
+		.id = 1,
+		.cpu_dai_name = "ssp2-port",
+		.platform_name = "sst-mfld-platform",
+		.no_pcm = 1,
+		.codec_dai_name = NAU8824_CODEC_DAI,
+		.codec_name = "i2c-10508824:00",
+		.dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF
+			| SND_SOC_DAIFMT_CBS_CFS,
+		.init = cht_codec_init,
+		.be_hw_params_fixup = cht_codec_fixup,
+		.dpcm_playback = 1,
+		.dpcm_capture = 1,
+		.ops = &cht_be_ssp2_ops,
+	},
+};
+
+/* SoC card */
+static struct snd_soc_card snd_soc_card_cht = {
+	.name = "chtnau8824",
+	.owner = THIS_MODULE,
+	.dai_link = cht_dailink,
+	.num_links = ARRAY_SIZE(cht_dailink),
+	.dapm_widgets = cht_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
+	.dapm_routes = cht_audio_map,
+	.num_dapm_routes = ARRAY_SIZE(cht_audio_map),
+	.controls = cht_mc_controls,
+	.num_controls = ARRAY_SIZE(cht_mc_controls),
+};
+
+static int snd_cht_mc_probe(struct platform_device *pdev)
+{
+	struct cht_mc_private *drv;
+	int ret_val;
+
+	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
+	if (!drv)
+		return -ENOMEM;
+	snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
+
+	/* register the soc card */
+	snd_soc_card_cht.dev = &pdev->dev;
+	ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
+	if (ret_val) {
+		dev_err(&pdev->dev,
+			"snd_soc_register_card failed %d\n", ret_val);
+		return ret_val;
+	}
+	platform_set_drvdata(pdev, &snd_soc_card_cht);
+
+	return ret_val;
+}
+
+static struct platform_driver snd_cht_mc_driver = {
+	.driver = {
+		.name = "cht-bsw-nau8824",
+	},
+	.probe = snd_cht_mc_probe,
+};
+
+module_platform_driver(snd_cht_mc_driver);
+
+MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
+MODULE_AUTHOR("Wang, Joseph C <joequant@gmail.com>");
+MODULE_AUTHOR("John Hsu <KCHSU0@nuvoton.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:cht-bsw-nau8824");
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 31641aa..49ba1a9 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -252,14 +252,14 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
 	struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
-	struct snd_soc_codec *codec = runtime->codec;
+	struct snd_soc_component *component = runtime->codec_dai->component;
 	int jack_type;
 	int ret;
 
 	if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) ||
 	    (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
 		/* Select clk_i2s2_asrc as ASRC clock source */
-		rt5645_sel_asrc_clk_src(codec,
+		rt5645_sel_asrc_clk_src(component,
 					RT5645_DA_STEREO_FILTER |
 					RT5645_DA_MONO_L_FILTER |
 					RT5645_DA_MONO_R_FILTER |
@@ -267,7 +267,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 					RT5645_CLK_SEL_I2S2_ASRC);
 	} else {
 		/* Select clk_i2s1_asrc as ASRC clock source */
-		rt5645_sel_asrc_clk_src(codec,
+		rt5645_sel_asrc_clk_src(component,
 					RT5645_DA_STEREO_FILTER |
 					RT5645_DA_MONO_L_FILTER |
 					RT5645_DA_MONO_R_FILTER |
@@ -310,7 +310,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
-	rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack);
+	rt5645_set_jack_detect(component, &ctx->jack, &ctx->jack, &ctx->jack);
 
 
 	/*
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index c14a52d..e68ec32 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -183,10 +183,10 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 {
 	int ret;
 	struct snd_soc_dai *codec_dai = runtime->codec_dai;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
 
-	if (devm_acpi_dev_add_driver_gpios(codec->dev, cht_rt5672_gpios))
+	if (devm_acpi_dev_add_driver_gpios(component->dev, cht_rt5672_gpios))
 		dev_warn(runtime->dev, "Unable to add GPIO mapping table\n");
 
 	/* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
@@ -201,7 +201,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 	 * be supported by RT5672. Otherwise, ASRC will be disabled and cause
 	 * noise.
 	 */
-	rt5670_sel_asrc_clk_src(codec,
+	rt5670_sel_asrc_clk_src(component,
 				RT5670_DA_STEREO_FILTER
 				| RT5670_DA_MONO_L_FILTER
 				| RT5670_DA_MONO_R_FILTER
@@ -219,7 +219,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
         if (ret)
                 return ret;
 
-	rt5670_set_jack_detect(codec, &ctx->headset);
+	rt5670_set_jack_detect(component, &ctx->headset);
 	if (ctx->mclk) {
 		/*
 		 * The firmware might enable the clock at
@@ -333,10 +333,9 @@ static int cht_suspend_pre(struct snd_soc_card *card)
 	list_for_each_entry(component, &card->component_dev_list, card_list) {
 		if (!strncmp(component->name,
 			     ctx->codec_name, sizeof(ctx->codec_name))) {
-			struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-			dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
-			rt5670_jack_suspend(codec);
+			dev_dbg(component->dev, "disabling jack detect before going to suspend.\n");
+			rt5670_jack_suspend(component);
 			break;
 		}
 	}
@@ -351,10 +350,9 @@ static int cht_resume_post(struct snd_soc_card *card)
 	list_for_each_entry(component, &card->component_dev_list, card_list) {
 		if (!strncmp(component->name,
 			     ctx->codec_name, sizeof(ctx->codec_name))) {
-			struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-			dev_dbg(codec->dev, "enabling jack detect for resume.\n");
-			rt5670_jack_resume(codec);
+			dev_dbg(component->dev, "enabling jack detect for resume.\n");
+			rt5670_jack_resume(component);
 			break;
 		}
 	}
diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/haswell.c
index 3c516077..eab1f43 100644
--- a/sound/soc/intel/boards/haswell.c
+++ b/sound/soc/intel/boards/haswell.c
@@ -87,7 +87,8 @@ static const struct snd_soc_ops haswell_rt5640_ops = {
 
 static int haswell_rtd_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_pdata *pdata = dev_get_platdata(component->dev);
 	struct sst_hsw *haswell = pdata->dsp;
 	int ret;
 
diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c
new file mode 100644
index 0000000..e84baaf
--- /dev/null
+++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
@@ -0,0 +1,613 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2017-18 Intel Corporation.
+
+/*
+ * Intel Kabylake I2S Machine Driver with MAX98357A & DA7219 Codecs
+ *
+ * Modified from:
+ *   Intel Kabylake I2S Machine driver supporting MAXIM98927 and
+ *   RT5663 codecs
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include "../../codecs/da7219.h"
+#include "../../codecs/hdac_hdmi.h"
+#include "../skylake/skl.h"
+#include "../../codecs/da7219-aad.h"
+
+#define KBL_DIALOG_CODEC_DAI "da7219-hifi"
+#define KBL_MAXIM_CODEC_DAI "HiFi"
+#define MAXIM_DEV0_NAME "MX98357A:00"
+#define DUAL_CHANNEL 2
+#define QUAD_CHANNEL 4
+
+static struct snd_soc_card *kabylake_audio_card;
+static struct snd_soc_jack skylake_hdmi[3];
+
+struct kbl_hdmi_pcm {
+	struct list_head head;
+	struct snd_soc_dai *codec_dai;
+	int device;
+};
+
+struct kbl_codec_private {
+	struct snd_soc_jack kabylake_headset;
+	struct list_head hdmi_pcm_list;
+};
+
+enum {
+	KBL_DPCM_AUDIO_PB = 0,
+	KBL_DPCM_AUDIO_CP,
+	KBL_DPCM_AUDIO_DMIC_CP,
+	KBL_DPCM_AUDIO_HDMI1_PB,
+	KBL_DPCM_AUDIO_HDMI2_PB,
+	KBL_DPCM_AUDIO_HDMI3_PB,
+};
+
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+					struct snd_kcontrol *k, int  event)
+{
+	struct snd_soc_dapm_context *dapm = w->dapm;
+	struct snd_soc_card *card = dapm->card;
+	struct snd_soc_dai *codec_dai;
+	int ret = 0;
+
+	codec_dai = snd_soc_card_get_codec_dai(card, KBL_DIALOG_CODEC_DAI);
+	if (!codec_dai) {
+		dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
+		return -EIO;
+	}
+
+	/* Configure sysclk for codec */
+	ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24576000,
+				     SND_SOC_CLOCK_IN);
+	if (ret) {
+		dev_err(card->dev, "can't set codec sysclk configuration\n");
+		return ret;
+	}
+
+	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		ret = snd_soc_dai_set_pll(codec_dai, 0,
+				     DA7219_SYSCLK_MCLK, 0, 0);
+		if (ret)
+			dev_err(card->dev, "failed to stop PLL: %d\n", ret);
+	} else if (SND_SOC_DAPM_EVENT_ON(event)) {
+		ret = snd_soc_dai_set_pll(codec_dai, 0,	DA7219_SYSCLK_PLL_SRM,
+				     0, DA7219_PLL_FREQ_OUT_98304);
+		if (ret)
+			dev_err(card->dev, "failed to start PLL: %d\n", ret);
+	}
+
+	return ret;
+}
+
+static const struct snd_kcontrol_new kabylake_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
+	SOC_DAPM_PIN_SWITCH("Spk"),
+};
+
+static const struct snd_soc_dapm_widget kabylake_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+	SND_SOC_DAPM_SPK("Spk", NULL),
+	SND_SOC_DAPM_MIC("SoC DMIC", NULL),
+	SND_SOC_DAPM_SPK("DP", NULL),
+	SND_SOC_DAPM_SPK("HDMI", NULL),
+	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+			platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route kabylake_map[] = {
+	{ "Headphone Jack", NULL, "HPL" },
+	{ "Headphone Jack", NULL, "HPR" },
+
+	/* speaker */
+	{ "Spk", NULL, "Speaker" },
+
+	/* other jacks */
+	{ "MIC", NULL, "Headset Mic" },
+	{ "DMic", NULL, "SoC DMIC" },
+
+	{ "HDMI", NULL, "hif5 Output" },
+	{ "DP", NULL, "hif6 Output" },
+
+	/* CODEC BE connections */
+	{ "HiFi Playback", NULL, "ssp0 Tx" },
+	{ "ssp0 Tx", NULL, "codec0_out" },
+
+	{ "Playback", NULL, "ssp1 Tx" },
+	{ "ssp1 Tx", NULL, "codec1_out" },
+
+	{ "codec0_in", NULL, "ssp1 Rx" },
+	{ "ssp1 Rx", NULL, "Capture" },
+
+	/* DMIC */
+	{ "dmic01_hifi", NULL, "DMIC01 Rx" },
+	{ "DMIC01 Rx", NULL, "DMIC AIF" },
+
+	{ "hifi1", NULL, "iDisp1 Tx" },
+	{ "iDisp1 Tx", NULL, "iDisp1_out" },
+	{ "hifi2", NULL, "iDisp2 Tx" },
+	{ "iDisp2 Tx", NULL, "iDisp2_out" },
+	{ "hifi3", NULL, "iDisp3 Tx"},
+	{ "iDisp3 Tx", NULL, "iDisp3_out"},
+
+	{ "Headphone Jack", NULL, "Platform Clock" },
+	{ "Headset Mic", NULL, "Platform Clock" },
+};
+
+static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
+			struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+			SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *channels = hw_param_interval(params,
+			SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+	/* The ADSP will convert the FE rate to 48k, stereo */
+	rate->min = rate->max = 48000;
+	channels->min = channels->max = DUAL_CHANNEL;
+
+	/* set SSP to 24 bit */
+	snd_mask_none(fmt);
+	snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
+
+	return 0;
+}
+
+static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_component *component = rtd->codec_dai->component;
+	struct snd_soc_jack *jack;
+	int ret;
+
+	/*
+	 * Headset buttons map to the google Reference headset.
+	 * These can be configured by userspace.
+	 */
+	ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack",
+			SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+			SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
+			&ctx->kabylake_headset, NULL, 0);
+	if (ret) {
+		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+		return ret;
+	}
+
+	jack = &ctx->kabylake_headset;
+
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+	da7219_aad_jack_det(component, &ctx->kabylake_headset);
+
+	ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
+	if (ret)
+		dev_err(rtd->dev, "SoC DMIC - Ignore suspend failed %d\n", ret);
+
+	return ret;
+}
+
+static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device)
+{
+	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_dai *dai = rtd->codec_dai;
+	struct kbl_hdmi_pcm *pcm;
+
+	pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
+	if (!pcm)
+		return -ENOMEM;
+
+	pcm->device = device;
+	pcm->codec_dai = dai;
+
+	list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
+
+	return 0;
+}
+
+static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
+{
+	return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB);
+}
+
+static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
+{
+	return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB);
+}
+
+static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
+{
+	return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB);
+}
+
+static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_dapm_context *dapm;
+	struct snd_soc_component *component = rtd->cpu_dai->component;
+
+	dapm = snd_soc_component_get_dapm(component);
+	snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
+
+	return 0;
+}
+
+static const unsigned int rates[] = {
+	48000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_rates = {
+	.count = ARRAY_SIZE(rates),
+	.list  = rates,
+	.mask = 0,
+};
+
+static const unsigned int channels[] = {
+	DUAL_CHANNEL,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+	.count = ARRAY_SIZE(channels),
+	.list = channels,
+	.mask = 0,
+};
+
+static unsigned int channels_quad[] = {
+	QUAD_CHANNEL,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
+	.count = ARRAY_SIZE(channels_quad),
+	.list = channels_quad,
+	.mask = 0,
+};
+
+static int kbl_fe_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	/*
+	 * On this platform for PCM device we support,
+	 * 48Khz
+	 * stereo
+	 * 16 bit audio
+	 */
+
+	runtime->hw.channels_max = DUAL_CHANNEL;
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+					   &constraints_channels);
+
+	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
+	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
+
+	snd_pcm_hw_constraint_list(runtime, 0,
+				SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
+
+	return 0;
+}
+
+static const struct snd_soc_ops kabylake_da7219_fe_ops = {
+	.startup = kbl_fe_startup,
+};
+
+static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
+		struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *channels = hw_param_interval(params,
+				SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	/*
+	 * set BE channel constraint as user FE channels
+	 */
+
+	if (params_channels(params) == 2)
+		channels->min = channels->max = 2;
+	else
+		channels->min = channels->max = 4;
+
+	return 0;
+}
+
+static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+			&constraints_channels_quad);
+
+	return snd_pcm_hw_constraint_list(substream->runtime, 0,
+			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
+}
+
+static struct snd_soc_ops kabylake_dmic_ops = {
+	.startup = kabylake_dmic_startup,
+};
+
+static const unsigned int rates_16000[] = {
+	16000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_16000 = {
+	.count = ARRAY_SIZE(rates_16000),
+	.list  = rates_16000,
+};
+
+static const unsigned int ch_mono[] = {
+	1,
+};
+
+/* kabylake digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link kabylake_dais[] = {
+	/* Front End DAI links */
+	[KBL_DPCM_AUDIO_PB] = {
+		.name = "Kbl Audio Port",
+		.stream_name = "Audio",
+		.cpu_dai_name = "System Pin",
+		.platform_name = "0000:00:1f.3",
+		.dynamic = 1,
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.nonatomic = 1,
+		.init = kabylake_da7219_fe_init,
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+		.dpcm_playback = 1,
+		.ops = &kabylake_da7219_fe_ops,
+	},
+	[KBL_DPCM_AUDIO_CP] = {
+		.name = "Kbl Audio Capture Port",
+		.stream_name = "Audio Record",
+		.cpu_dai_name = "System Pin",
+		.platform_name = "0000:00:1f.3",
+		.dynamic = 1,
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.nonatomic = 1,
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+		.dpcm_capture = 1,
+	},
+	[KBL_DPCM_AUDIO_DMIC_CP] = {
+		.name = "Kbl Audio DMIC cap",
+		.stream_name = "dmiccap",
+		.cpu_dai_name = "DMIC Pin",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.platform_name = "0000:00:1f.3",
+		.init = NULL,
+		.dpcm_capture = 1,
+		.nonatomic = 1,
+		.dynamic = 1,
+		.ops = &kabylake_dmic_ops,
+	},
+	[KBL_DPCM_AUDIO_HDMI1_PB] = {
+		.name = "Kbl HDMI Port1",
+		.stream_name = "Hdmi1",
+		.cpu_dai_name = "HDMI1 Pin",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.platform_name = "0000:00:1f.3",
+		.dpcm_playback = 1,
+		.init = NULL,
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+		.nonatomic = 1,
+		.dynamic = 1,
+	},
+	[KBL_DPCM_AUDIO_HDMI2_PB] = {
+		.name = "Kbl HDMI Port2",
+		.stream_name = "Hdmi2",
+		.cpu_dai_name = "HDMI2 Pin",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.platform_name = "0000:00:1f.3",
+		.dpcm_playback = 1,
+		.init = NULL,
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+		.nonatomic = 1,
+		.dynamic = 1,
+	},
+	[KBL_DPCM_AUDIO_HDMI3_PB] = {
+		.name = "Kbl HDMI Port3",
+		.stream_name = "Hdmi3",
+		.cpu_dai_name = "HDMI3 Pin",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.platform_name = "0000:00:1f.3",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+		.dpcm_playback = 1,
+		.init = NULL,
+		.nonatomic = 1,
+		.dynamic = 1,
+	},
+
+	/* Back End DAI links */
+	{
+		/* SSP0 - Codec */
+		.name = "SSP0-Codec",
+		.id = 0,
+		.cpu_dai_name = "SSP0 Pin",
+		.platform_name = "0000:00:1f.3",
+		.no_pcm = 1,
+		.codec_name = MAXIM_DEV0_NAME,
+		.codec_dai_name = KBL_MAXIM_CODEC_DAI,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.ignore_pmdown_time = 1,
+		.be_hw_params_fixup = kabylake_ssp_fixup,
+		.dpcm_playback = 1,
+	},
+	{
+		/* SSP1 - Codec */
+		.name = "SSP1-Codec",
+		.id = 1,
+		.cpu_dai_name = "SSP1 Pin",
+		.platform_name = "0000:00:1f.3",
+		.no_pcm = 1,
+		.codec_name = "i2c-DLGS7219:00",
+		.codec_dai_name = KBL_DIALOG_CODEC_DAI,
+		.init = kabylake_da7219_codec_init,
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.ignore_pmdown_time = 1,
+		.be_hw_params_fixup = kabylake_ssp_fixup,
+		.dpcm_playback = 1,
+		.dpcm_capture = 1,
+	},
+	{
+		.name = "dmic01",
+		.id = 2,
+		.cpu_dai_name = "DMIC01 Pin",
+		.codec_name = "dmic-codec",
+		.codec_dai_name = "dmic-hifi",
+		.platform_name = "0000:00:1f.3",
+		.be_hw_params_fixup = kabylake_dmic_fixup,
+		.ignore_suspend = 1,
+		.dpcm_capture = 1,
+		.no_pcm = 1,
+	},
+	{
+		.name = "iDisp1",
+		.id = 3,
+		.cpu_dai_name = "iDisp1 Pin",
+		.codec_name = "ehdaudio0D2",
+		.codec_dai_name = "intel-hdmi-hifi1",
+		.platform_name = "0000:00:1f.3",
+		.dpcm_playback = 1,
+		.init = kabylake_hdmi1_init,
+		.no_pcm = 1,
+	},
+	{
+		.name = "iDisp2",
+		.id = 4,
+		.cpu_dai_name = "iDisp2 Pin",
+		.codec_name = "ehdaudio0D2",
+		.codec_dai_name = "intel-hdmi-hifi2",
+		.platform_name = "0000:00:1f.3",
+		.init = kabylake_hdmi2_init,
+		.dpcm_playback = 1,
+		.no_pcm = 1,
+	},
+	{
+		.name = "iDisp3",
+		.id = 5,
+		.cpu_dai_name = "iDisp3 Pin",
+		.codec_name = "ehdaudio0D2",
+		.codec_dai_name = "intel-hdmi-hifi3",
+		.platform_name = "0000:00:1f.3",
+		.init = kabylake_hdmi3_init,
+		.dpcm_playback = 1,
+		.no_pcm = 1,
+	},
+};
+
+#define NAME_SIZE	32
+static int kabylake_card_late_probe(struct snd_soc_card *card)
+{
+	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
+	struct kbl_hdmi_pcm *pcm;
+	struct snd_soc_component *component = NULL;
+	int err, i = 0;
+	char jack_name[NAME_SIZE];
+
+	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
+		component = pcm->codec_dai->component;
+		snprintf(jack_name, sizeof(jack_name),
+			"HDMI/DP, pcm=%d Jack", pcm->device);
+		err = snd_soc_card_jack_new(card, jack_name,
+					SND_JACK_AVOUT, &skylake_hdmi[i],
+					NULL, 0);
+
+		if (err)
+			return err;
+
+		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
+				&skylake_hdmi[i]);
+		if (err < 0)
+			return err;
+
+		i++;
+
+	}
+
+	if (!component)
+		return -EINVAL;
+
+	return hdac_hdmi_jack_port_init(component, &card->dapm);
+}
+
+/* kabylake audio machine driver for SPT + DA7219 */
+static struct snd_soc_card kabylake_audio_card_da7219_m98357a = {
+	.name = "kblda7219max",
+	.owner = THIS_MODULE,
+	.dai_link = kabylake_dais,
+	.num_links = ARRAY_SIZE(kabylake_dais),
+	.controls = kabylake_controls,
+	.num_controls = ARRAY_SIZE(kabylake_controls),
+	.dapm_widgets = kabylake_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(kabylake_widgets),
+	.dapm_routes = kabylake_map,
+	.num_dapm_routes = ARRAY_SIZE(kabylake_map),
+	.fully_routed = true,
+	.late_probe = kabylake_card_late_probe,
+};
+
+static int kabylake_audio_probe(struct platform_device *pdev)
+{
+	struct kbl_codec_private *ctx;
+
+	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
+	if (!ctx)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
+
+	kabylake_audio_card =
+		(struct snd_soc_card *)pdev->id_entry->driver_data;
+
+	kabylake_audio_card->dev = &pdev->dev;
+	snd_soc_card_set_drvdata(kabylake_audio_card, ctx);
+	return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card);
+}
+
+static const struct platform_device_id kbl_board_ids[] = {
+	{
+		.name = "kbl_da7219_max98357a",
+		.driver_data =
+			(kernel_ulong_t)&kabylake_audio_card_da7219_m98357a,
+	},
+	{ }
+};
+
+static struct platform_driver kabylake_audio = {
+	.probe = kabylake_audio_probe,
+	.driver = {
+		.name = "kbl_da7219_max98357a",
+		.pm = &snd_soc_pm_ops,
+	},
+	.id_table = kbl_board_ids,
+};
+
+module_platform_driver(kabylake_audio)
+
+/* Module information */
+MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode");
+MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:kbl_da7219_max98357a");
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index f5df6bc..0e6b7e7 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -204,13 +204,18 @@ static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = {
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 	SND_SOC_DAPM_SPK("DP", NULL),
 	SND_SOC_DAPM_SPK("HDMI", NULL),
+	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+			platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_route kabylake_5663_map[] = {
+	{ "Headphone Jack", NULL, "Platform Clock" },
 	{ "Headphone Jack", NULL, "HPOL" },
 	{ "Headphone Jack", NULL, "HPOR" },
 
 	/* other jacks */
+	{ "Headset Mic", NULL, "Platform Clock" },
 	{ "IN1P", NULL, "Headset Mic" },
 	{ "IN1N", NULL, "Headset Mic" },
 
@@ -272,7 +277,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
 	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card);
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	struct snd_soc_jack *jack;
 
 	/*
@@ -294,7 +299,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 
-	rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
+	rt5663_set_jack_detect(component, &ctx->kabylake_headset);
 	return ret;
 }
 
@@ -448,7 +453,7 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
 	int ret;
 
 	/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
-	rt5663_sel_asrc_clk_src(codec_dai->codec,
+	rt5663_sel_asrc_clk_src(codec_dai->component,
 			RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
 			RT5663_CLK_SEL_I2S1_ASRC);
 
@@ -898,12 +903,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
 	struct kbl_hdmi_pcm *pcm;
-	struct snd_soc_codec *codec = NULL;
+	struct snd_soc_component *component = NULL;
 	int err, i = 0;
 	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-		codec = pcm->codec_dai->codec;
+		component = pcm->codec_dai->component;
 		snprintf(jack_name, sizeof(jack_name),
 			"HDMI/DP, pcm=%d Jack", pcm->device);
 		err = snd_soc_card_jack_new(card, jack_name,
@@ -921,10 +926,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 		i++;
 	}
 
-	if (!codec)
+	if (!component)
 		return -EINVAL;
 
-	return hdac_hdmi_jack_port_init(codec, &card->dapm);
+	return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* kabylake audio machine driver for SPT + RT5663 */
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index 90ea98f..69c3d84 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -178,7 +178,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
 	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	struct snd_soc_jack *jack;
 
 	/*
@@ -200,7 +200,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 
-	rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
+	rt5663_set_jack_detect(component, &ctx->kabylake_headset);
 
 	ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC");
 	if (ret)
@@ -333,7 +333,7 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
 	int ret;
 
 	/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
-	rt5663_sel_asrc_clk_src(codec_dai->codec,
+	rt5663_sel_asrc_clk_src(codec_dai->component,
 			RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
 			RT5663_CLK_SEL_I2S1_ASRC);
 
@@ -599,12 +599,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
 	struct kbl_hdmi_pcm *pcm;
-	struct snd_soc_codec *codec = NULL;
+	struct snd_soc_component *component = NULL;
 	int err, i = 0;
 	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-		codec = pcm->codec_dai->codec;
+		component = pcm->codec_dai->component;
 		snprintf(jack_name, sizeof(jack_name),
 			"HDMI/DP,pcm=%d Jack", pcm->device);
 		err = snd_soc_card_jack_new(card, jack_name,
@@ -620,10 +620,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 		i++;
 	}
 
-	if (!codec)
+	if (!component)
 		return -EINVAL;
 
-	return hdac_hdmi_jack_port_init(codec, &card->dapm);
+	return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /*
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index 1b5a689..9a7a064 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -165,7 +165,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
 static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 
 	/*
 	 * Headset buttons map to the google Reference headset.
@@ -180,7 +180,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
 		return ret;
 	}
 
-	nau8825_enable_jack_detect(codec, &skylake_headset);
+	nau8825_enable_jack_detect(component, &skylake_headset);
 
 	snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -592,12 +592,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
 	struct skl_hdmi_pcm *pcm;
-	struct snd_soc_codec *codec = NULL;
+	struct snd_soc_component *component = NULL;
 	int err, i = 0;
 	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-		codec = pcm->codec_dai->codec;
+		component = pcm->codec_dai->component;
 		snprintf(jack_name, sizeof(jack_name),
 			"HDMI/DP, pcm=%d Jack", pcm->device);
 		err = snd_soc_card_jack_new(card, jack_name,
@@ -616,10 +616,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 		i++;
 	}
 
-	if (!codec)
+	if (!component)
 		return -EINVAL;
 
-	return hdac_hdmi_jack_port_init(codec, &card->dapm);
+	return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* skylake audio machine driver for SPT + NAU88L25 */
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index 7bea4bc..212ac89 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -195,7 +195,7 @@ static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd)
 static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 
 	/*
 	 * 4 buttons here map to the google Reference headset
@@ -210,7 +210,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
 		return ret;
 	}
 
-	nau8825_enable_jack_detect(codec, &skylake_headset);
+	nau8825_enable_jack_detect(component, &skylake_headset);
 
 	snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -643,12 +643,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
 	struct skl_hdmi_pcm *pcm;
-	struct snd_soc_codec *codec = NULL;
+	struct snd_soc_component *component = NULL;
 	int err, i = 0;
 	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-		codec = pcm->codec_dai->codec;
+		component = pcm->codec_dai->component;
 		snprintf(jack_name, sizeof(jack_name),
 			"HDMI/DP, pcm=%d Jack", pcm->device);
 		err = snd_soc_card_jack_new(card, jack_name,
@@ -667,10 +667,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 		i++;
 	}
 
-	if (!codec)
+	if (!component)
 		return -EINVAL;
 
-	return hdac_hdmi_jack_port_init(codec, &card->dapm);
+	return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* skylake audio machine driver for SPT + NAU88L25 */
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index 2bc4cfc..737d561 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -130,7 +130,7 @@ static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd)
 
 static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	int ret;
 
 	ret = snd_soc_card_jack_new(rtd->card, "Headset",
@@ -141,7 +141,7 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
 	if (ret)
 		return ret;
 
-	rt286_mic_detect(codec, &skylake_headset);
+	rt286_mic_detect(component, &skylake_headset);
 
 	snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -478,12 +478,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
 	struct skl_hdmi_pcm *pcm;
-	struct snd_soc_codec *codec = NULL;
+	struct snd_soc_component *component = NULL;
 	int err, i = 0;
 	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-		codec = pcm->codec_dai->codec;
+		component = pcm->codec_dai->component;
 		snprintf(jack_name, sizeof(jack_name),
 			"HDMI/DP, pcm=%d Jack", pcm->device);
 		err = snd_soc_card_jack_new(card, jack_name,
@@ -501,10 +501,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 		i++;
 	}
 
-	if (!codec)
+	if (!component)
 		return -EINVAL;
 
-	return hdac_hdmi_jack_port_init(codec, &card->dapm);
+	return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* skylake audio machine driver for SPT + RT286S */
diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c
index b50a0d5..ad1eb2d 100644
--- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c
@@ -118,6 +118,15 @@ struct snd_soc_acpi_mach  snd_soc_acpi_intel_cherrytrail_machines[] = {
 		.asoc_plat_name = "sst-mfld-platform",
 	},
 	{
+		.id = "10508824",
+		.drv_name = "cht-bsw-nau8824",
+		.fw_filename = "intel/fw_sst_22a8.bin",
+		.board = "cht-bsw",
+		.sof_fw_filename = "intel/reef-cht.ri",
+		.sof_tplg_filename = "intel/reef-cht-nau8824.tplg",
+		.asoc_plat_name = "sst-mfld-platform",
+	},
+	{
 		.id = "DLGS7212",
 		.drv_name = "bytcht_da7213",
 		.fw_filename = "intel/fw_sst_22a8.bin",
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.h b/sound/soc/intel/haswell/sst-haswell-ipc.h
index 06d71ae..fbc14df 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.h
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.h
@@ -22,6 +22,8 @@
 #include <linux/platform_device.h>
 #include <sound/asound.h>
 
+#define DRV_NAME "haswell-dai"
+
 #define SST_HSW_NO_CHANNELS		4
 #define SST_HSW_MAX_DX_REGIONS		14
 #define SST_HSW_DX_CONTEXT_SIZE        (640 * 1024)
diff --git a/sound/soc/intel/haswell/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c
index c044400..fe2c826 100644
--- a/sound/soc/intel/haswell/sst-haswell-pcm.c
+++ b/sound/soc/intel/haswell/sst-haswell-pcm.c
@@ -181,11 +181,11 @@ static inline unsigned int hsw_ipc_to_mixer(u32 value)
 static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	struct hsw_priv_data *pdata =
-		snd_soc_platform_get_drvdata(platform);
+		snd_soc_component_get_drvdata(component);
 	struct hsw_pcm_data *pcm_data;
 	struct sst_hsw *hsw = pdata->hsw;
 	u32 volume;
@@ -230,11 +230,11 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
 static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	struct hsw_priv_data *pdata =
-		snd_soc_platform_get_drvdata(platform);
+		snd_soc_component_get_drvdata(component);
 	struct hsw_pcm_data *pcm_data;
 	struct sst_hsw *hsw = pdata->hsw;
 	u32 volume;
@@ -273,8 +273,8 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
 static int hsw_volume_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-	struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_hsw *hsw = pdata->hsw;
 	u32 volume;
 
@@ -302,8 +302,8 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol,
 static int hsw_volume_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-	struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_hsw *hsw = pdata->hsw;
 	unsigned int volume = 0;
 
@@ -322,8 +322,8 @@ static int hsw_volume_get(struct snd_kcontrol *kcontrol,
 static int hsw_waves_switch_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-	struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_hsw *hsw = pdata->hsw;
 	enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
 
@@ -336,8 +336,8 @@ static int hsw_waves_switch_get(struct snd_kcontrol *kcontrol,
 static int hsw_waves_switch_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-	struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_hsw *hsw = pdata->hsw;
 	int ret = 0;
 	enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
@@ -370,8 +370,8 @@ static int hsw_waves_switch_put(struct snd_kcontrol *kcontrol,
 static int hsw_waves_param_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-	struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_hsw *hsw = pdata->hsw;
 
 	/* return a matching line from param buffer */
@@ -381,8 +381,8 @@ static int hsw_waves_param_get(struct snd_kcontrol *kcontrol,
 static int hsw_waves_param_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-	struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_hsw *hsw = pdata->hsw;
 	int ret;
 	enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
@@ -472,8 +472,8 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct hsw_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct hsw_pcm_data *pcm_data;
 	struct sst_hsw *hsw = pdata->hsw;
 	struct sst_module *module_data;
@@ -674,8 +674,8 @@ static int hsw_pcm_hw_free(struct snd_pcm_substream *substream)
 static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct hsw_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct hsw_pcm_data *pcm_data;
 	struct sst_hsw_stream *sst_stream;
 	struct sst_hsw *hsw = pdata->hsw;
@@ -718,8 +718,8 @@ static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data)
 	struct snd_pcm_substream *substream = pcm_data->substream;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct hsw_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct sst_hsw *hsw = pdata->hsw;
 	u32 pos;
 	snd_pcm_uframes_t position = bytes_to_frames(runtime,
@@ -783,8 +783,8 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct hsw_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct hsw_pcm_data *pcm_data;
 	struct sst_hsw *hsw = pdata->hsw;
 	snd_pcm_uframes_t offset;
@@ -807,8 +807,8 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
 static int hsw_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct hsw_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct hsw_pcm_data *pcm_data;
 	struct sst_hsw *hsw = pdata->hsw;
 	int dai;
@@ -840,8 +840,8 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
 static int hsw_pcm_close(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct hsw_priv_data *pdata =
-		snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
 	struct hsw_pcm_data *pcm_data;
 	struct sst_hsw *hsw = pdata->hsw;
 	int ret, dai;
@@ -942,9 +942,9 @@ static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
 static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_pcm *pcm = rtd->pcm;
-	struct snd_soc_platform *platform = rtd->platform;
-	struct sst_pdata *pdata = dev_get_platdata(platform->dev);
-	struct hsw_priv_data *priv_data = dev_get_drvdata(platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct sst_pdata *pdata = dev_get_platdata(component->dev);
+	struct hsw_priv_data *priv_data = dev_get_drvdata(component->dev);
 	struct device *dev = pdata->dma_dev;
 	int ret = 0;
 
@@ -1052,23 +1052,23 @@ static const struct snd_soc_dapm_route graph[] = {
 	{"Analog Capture", NULL, "SSP0 CODEC IN"},
 };
 
-static int hsw_pcm_probe(struct snd_soc_platform *platform)
+static int hsw_pcm_probe(struct snd_soc_component *component)
 {
-	struct hsw_priv_data *priv_data = snd_soc_platform_get_drvdata(platform);
-	struct sst_pdata *pdata = dev_get_platdata(platform->dev);
+	struct hsw_priv_data *priv_data = snd_soc_component_get_drvdata(component);
+	struct sst_pdata *pdata = dev_get_platdata(component->dev);
 	struct device *dma_dev, *dev;
 	int i, ret = 0;
 
 	if (!pdata)
 		return -ENODEV;
 
-	dev = platform->dev;
+	dev = component->dev;
 	dma_dev = pdata->dma_dev;
 
 	priv_data->hsw = pdata->dsp;
-	priv_data->dev = platform->dev;
+	priv_data->dev = dev;
 	priv_data->pm_state = HSW_PM_STATE_D0;
-	priv_data->soc_card = platform->component.card;
+	priv_data->soc_card = component->card;
 
 	/* allocate DSP buffer page tables */
 	for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
@@ -1098,11 +1098,10 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
 		goto err;
 
 	/* enable runtime PM with auto suspend */
-	pm_runtime_set_autosuspend_delay(platform->dev,
-		SST_RUNTIME_SUSPEND_DELAY);
-	pm_runtime_use_autosuspend(platform->dev);
-	pm_runtime_enable(platform->dev);
-	pm_runtime_idle(platform->dev);
+	pm_runtime_set_autosuspend_delay(dev, SST_RUNTIME_SUSPEND_DELAY);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
 
 	return 0;
 
@@ -1116,13 +1115,13 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
 	return ret;
 }
 
-static int hsw_pcm_remove(struct snd_soc_platform *platform)
+static void hsw_pcm_remove(struct snd_soc_component *component)
 {
 	struct hsw_priv_data *priv_data =
-		snd_soc_platform_get_drvdata(platform);
+		snd_soc_component_get_drvdata(component);
 	int i;
 
-	pm_runtime_disable(platform->dev);
+	pm_runtime_disable(component->dev);
 	hsw_pcm_free_modules(priv_data);
 
 	for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
@@ -1131,24 +1130,19 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform)
 		if (hsw_dais[i].capture.channels_min)
 			snd_dma_free_pages(&priv_data->dmab[i][1]);
 	}
-
-	return 0;
 }
 
-static const struct snd_soc_platform_driver hsw_soc_platform = {
+static const struct snd_soc_component_driver hsw_dai_component = {
+	.name		= DRV_NAME,
 	.probe		= hsw_pcm_probe,
 	.remove		= hsw_pcm_remove,
 	.ops		= &hsw_pcm_ops,
 	.pcm_new	= hsw_pcm_new,
-};
-
-static const struct snd_soc_component_driver hsw_dai_component = {
-	.name = "haswell-dai",
-	.controls = hsw_volume_controls,
-	.num_controls = ARRAY_SIZE(hsw_volume_controls),
-	.dapm_widgets = widgets,
+	.controls	= hsw_volume_controls,
+	.num_controls	= ARRAY_SIZE(hsw_volume_controls),
+	.dapm_widgets	= widgets,
 	.num_dapm_widgets = ARRAY_SIZE(widgets),
-	.dapm_routes = graph,
+	.dapm_routes	= graph,
 	.num_dapm_routes = ARRAY_SIZE(graph),
 };
 
@@ -1172,19 +1166,13 @@ static int hsw_pcm_dev_probe(struct platform_device *pdev)
 	priv_data->hsw = sst_pdata->dsp;
 	platform_set_drvdata(pdev, priv_data);
 
-	ret = snd_soc_register_platform(&pdev->dev, &hsw_soc_platform);
+	ret = devm_snd_soc_register_component(&pdev->dev, &hsw_dai_component,
+		hsw_dais, ARRAY_SIZE(hsw_dais));
 	if (ret < 0)
 		goto err_plat;
 
-	ret = snd_soc_register_component(&pdev->dev, &hsw_dai_component,
-		hsw_dais, ARRAY_SIZE(hsw_dais));
-	if (ret < 0)
-		goto err_comp;
-
 	return 0;
 
-err_comp:
-	snd_soc_unregister_platform(&pdev->dev);
 err_plat:
 	sst_hsw_dsp_free(&pdev->dev, sst_pdata);
 	return 0;
@@ -1194,8 +1182,6 @@ static int hsw_pcm_dev_remove(struct platform_device *pdev)
 {
 	struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
 
-	snd_soc_unregister_platform(&pdev->dev);
-	snd_soc_unregister_component(&pdev->dev);
 	sst_hsw_dsp_free(&pdev->dev, sst_pdata);
 
 	return 0;
diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c
index dc20d91..a016455 100644
--- a/sound/soc/intel/skylake/skl-debug.c
+++ b/sound/soc/intel/skylake/skl-debug.c
@@ -231,7 +231,7 @@ struct skl_debug *skl_debugfs_init(struct skl *skl)
 
 	/* create the debugfs dir with platform component's debugfs as parent */
 	d->fs = debugfs_create_dir("dsp",
-				   skl->platform->component.debugfs_root);
+				   skl->component->debugfs_root);
 	if (IS_ERR(d->fs) || !d->fs) {
 		dev_err(&skl->pci->dev, "debugfs root creation failed\n");
 		return NULL;
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 60d76ad..57d4a58 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -417,11 +417,16 @@ int skl_resume_dsp(struct skl *skl)
 	if (skl->skl_sst->is_first_boot == true)
 		return 0;
 
-	/* disable dynamic clock gating during fw and lib download */
+	/*
+	 * Disable dynamic clock and power gating during firmware
+	 * and library download
+	 */
 	ctx->enable_miscbdcge(ctx->dev, false);
+	ctx->clock_power_gating(ctx->dev, false);
 
 	ret = skl_dsp_wake(ctx->dsp);
 	ctx->enable_miscbdcge(ctx->dev, true);
+	ctx->clock_power_gating(ctx->dev, true);
 	if (ret < 0)
 		return ret;
 
@@ -1210,7 +1215,7 @@ int skl_bind_modules(struct skl_sst *ctx,
 static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
 	enum skl_ipc_pipeline_state state)
 {
-	dev_dbg(ctx->dev, "%s: pipe_satate = %d\n", __func__, state);
+	dev_dbg(ctx->dev, "%s: pipe_state = %d\n", __func__, state);
 
 	return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state);
 }
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index e468285..15cb8ac 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -959,6 +959,17 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
 	},
 },
 {
+	.name = "DMIC16k Pin",
+	.ops = &skl_dmic_dai_ops,
+	.capture = {
+		.stream_name = "DMIC16k Rx",
+		.channels_min = HDA_MONO,
+		.channels_max = HDA_QUAD,
+		.rates = SNDRV_PCM_RATE_16000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+},
+{
 	.name = "HD-Codec Pin",
 	.ops = &skl_link_dai_ops,
 	.playback = {
@@ -1307,29 +1318,31 @@ static int skl_populate_modules(struct skl *skl)
 					"query module info failed\n");
 				return ret;
 			}
+
+			skl_tplg_add_moduleid_in_bind_params(skl, w);
 		}
 	}
 
 	return ret;
 }
 
-static int skl_platform_soc_probe(struct snd_soc_platform *platform)
+static int skl_platform_soc_probe(struct snd_soc_component *component)
 {
-	struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
+	struct hdac_ext_bus *ebus = dev_get_drvdata(component->dev);
 	struct skl *skl = ebus_to_skl(ebus);
 	const struct skl_dsp_ops *ops;
 	int ret;
 
-	pm_runtime_get_sync(platform->dev);
+	pm_runtime_get_sync(component->dev);
 	if ((ebus_to_hbus(ebus))->ppcap) {
-		skl->platform = platform;
+		skl->component = component;
 
 		/* init debugfs */
 		skl->debugfs = skl_debugfs_init(skl);
 
-		ret = skl_tplg_init(platform, ebus);
+		ret = skl_tplg_init(component, ebus);
 		if (ret < 0) {
-			dev_err(platform->dev, "Failed to init topology!\n");
+			dev_err(component->dev, "Failed to init topology!\n");
 			return ret;
 		}
 
@@ -1339,17 +1352,22 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
 			return -EIO;
 
 		if (skl->skl_sst->is_first_boot == false) {
-			dev_err(platform->dev, "DSP reports first boot done!!!\n");
+			dev_err(component->dev, "DSP reports first boot done!!!\n");
 			return -EIO;
 		}
 
-		/* disable dynamic clock gating during fw and lib download */
-		skl->skl_sst->enable_miscbdcge(platform->dev, false);
+		/*
+		 * Disable dynamic clock and power gating during firmware
+		 * and library download
+		 */
+		skl->skl_sst->enable_miscbdcge(component->dev, false);
+		skl->skl_sst->clock_power_gating(component->dev, false);
 
-		ret = ops->init_fw(platform->dev, skl->skl_sst);
-		skl->skl_sst->enable_miscbdcge(platform->dev, true);
+		ret = ops->init_fw(component->dev, skl->skl_sst);
+		skl->skl_sst->enable_miscbdcge(component->dev, true);
+		skl->skl_sst->clock_power_gating(component->dev, true);
 		if (ret < 0) {
-			dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
+			dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
 			return ret;
 		}
 		skl_populate_modules(skl);
@@ -1362,22 +1380,20 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
 					skl->cfg.astate_cfg);
 		}
 	}
-	pm_runtime_mark_last_busy(platform->dev);
-	pm_runtime_put_autosuspend(platform->dev);
+	pm_runtime_mark_last_busy(component->dev);
+	pm_runtime_put_autosuspend(component->dev);
 
 	return 0;
 }
-static const struct snd_soc_platform_driver skl_platform_drv  = {
+
+static const struct snd_soc_component_driver skl_component  = {
+	.name		= "pcm",
 	.probe		= skl_platform_soc_probe,
 	.ops		= &skl_platform_ops,
 	.pcm_new	= skl_pcm_new,
 	.pcm_free	= skl_pcm_free,
 };
 
-static const struct snd_soc_component_driver skl_component = {
-	.name           = "pcm",
-};
-
 int skl_platform_register(struct device *dev)
 {
 	int ret;
@@ -1389,12 +1405,6 @@ int skl_platform_register(struct device *dev)
 	INIT_LIST_HEAD(&skl->ppl_list);
 	INIT_LIST_HEAD(&skl->bind_list);
 
-	ret = snd_soc_register_platform(dev, &skl_platform_drv);
-	if (ret) {
-		dev_err(dev, "soc platform registration failed %d\n", ret);
-		return ret;
-	}
-
 	skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
 			    GFP_KERNEL);
 	if (!skl->dais) {
@@ -1416,18 +1426,12 @@ int skl_platform_register(struct device *dev)
 		num_dais += ARRAY_SIZE(skl_fe_dai);
 	}
 
-	ret = snd_soc_register_component(dev, &skl_component,
+	ret = devm_snd_soc_register_component(dev, &skl_component,
 					 skl->dais, num_dais);
-	if (ret) {
+	if (ret)
 		dev_err(dev, "soc component registration failed %d\n", ret);
-		goto err;
-	}
-
-	return 0;
 err:
-	snd_soc_unregister_platform(dev);
 	return ret;
-
 }
 
 int skl_platform_unregister(struct device *dev)
@@ -1443,8 +1447,6 @@ int skl_platform_unregister(struct device *dev)
 		}
 	}
 
-	snd_soc_unregister_component(dev);
-	snd_soc_unregister_platform(dev);
 	kfree(skl->dais);
 
 	return 0;
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c
index 7fbddf5..cda1b5f 100644
--- a/sound/soc/intel/skylake/skl-ssp-clk.c
+++ b/sound/soc/intel/skylake/skl-ssp-clk.c
@@ -247,8 +247,8 @@ static unsigned long skl_clk_recalc_rate(struct clk_hw *hw,
 }
 
 /* Not supported by clk driver. Implemented to satisfy clk fw */
-long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
-				unsigned long *parent_rate)
+static long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *parent_rate)
 {
 	return rate;
 }
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 55f2d2c..f74f040 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -118,6 +118,9 @@ struct skl_sst {
 	struct skl_d0i3_data d0i3;
 
 	const struct skl_dsp_ops *dsp_ops;
+
+	/* Callback to update dynamic clock and power gating registers */
+	void (*clock_power_gating)(struct device *dev, bool enable);
 };
 
 struct skl_ipc_init_instance_msg {
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 73af6e1..3b1dca4 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -94,8 +94,12 @@ void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps)
  * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
  * ignore. This helpers checks if the SKL driver handles this widget type
  */
-static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
+static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w,
+				  struct device *dev)
 {
+	if (w->dapm->dev != dev)
+		return false;
+
 	switch (w->id) {
 	case snd_soc_dapm_dai_link:
 	case snd_soc_dapm_dai_in:
@@ -826,7 +830,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
 	if (mcfg->m_type == SKL_MODULE_TYPE_KPB) {
 		struct skl_kpb_params *kpb_params =
 				(struct skl_kpb_params *)params;
-		struct skl_mod_inst_map *inst = kpb_params->map;
+		struct skl_mod_inst_map *inst = kpb_params->u.map;
 
 		for (i = 0; i < kpb_params->num_modules; i++) {
 			pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id,
@@ -911,6 +915,87 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
+static int skl_get_module_id(struct skl_sst *ctx, uuid_le *uuid)
+{
+	struct uuid_module *module;
+
+	list_for_each_entry(module, &ctx->uuid_list, list) {
+		if (uuid_le_cmp(*uuid, module->uuid) == 0)
+			return module->id;
+	}
+
+	return -EINVAL;
+}
+
+static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
+					const struct snd_kcontrol_new *k)
+{
+	struct soc_bytes_ext *sb = (void *) k->private_value;
+	struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
+	struct skl_kpb_params *uuid_params, *params;
+	struct hdac_bus *bus = ebus_to_hbus(skl_to_ebus(skl));
+	int i, size, module_id;
+
+	if (bc->set_params == SKL_PARAM_BIND && bc->max) {
+		uuid_params = (struct skl_kpb_params *)bc->params;
+		size = uuid_params->num_modules *
+			sizeof(struct skl_mod_inst_map) +
+			sizeof(uuid_params->num_modules);
+
+		params = devm_kzalloc(bus->dev, size, GFP_KERNEL);
+		if (!params)
+			return -ENOMEM;
+
+		params->num_modules = uuid_params->num_modules;
+
+		for (i = 0; i < uuid_params->num_modules; i++) {
+			module_id = skl_get_module_id(skl->skl_sst,
+				&uuid_params->u.map_uuid[i].mod_uuid);
+			if (module_id < 0) {
+				devm_kfree(bus->dev, params);
+				return -EINVAL;
+			}
+
+			params->u.map[i].mod_id = module_id;
+			params->u.map[i].inst_id =
+				uuid_params->u.map_uuid[i].inst_id;
+		}
+
+		devm_kfree(bus->dev, bc->params);
+		bc->params = (char *)params;
+		bc->max = size;
+	}
+
+	return 0;
+}
+
+/*
+ * Retrieve the module id from UUID mentioned in the
+ * post bind params
+ */
+void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
+				struct snd_soc_dapm_widget *w)
+{
+	struct skl_module_cfg *mconfig = w->priv;
+	int i;
+
+	/*
+	 * Post bind params are used for only for KPB
+	 * to set copier instances to drain the data
+	 * in fast mode
+	 */
+	if (mconfig->m_type != SKL_MODULE_TYPE_KPB)
+		return;
+
+	for (i = 0; i < w->num_kcontrols; i++)
+		if ((w->kcontrol_news[i].access &
+			SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
+			(skl_tplg_find_moduleid_from_uuid(skl,
+			&w->kcontrol_news[i]) < 0))
+			dev_err(skl->skl_sst->dev,
+				"%s: invalid kpb post bind params\n",
+				__func__);
+}
 
 static int skl_tplg_module_add_deferred_bind(struct skl *skl,
 	struct skl_module_cfg *src, struct skl_module_cfg *dst)
@@ -969,7 +1054,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
 
 		next_sink = p->sink;
 
-		if (!is_skl_dsp_widget_type(p->sink))
+		if (!is_skl_dsp_widget_type(p->sink, ctx->dev))
 			return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
 
 		/*
@@ -978,7 +1063,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
 		 * they are ones used for SKL so check that first
 		 */
 		if ((p->sink->priv != NULL) &&
-					is_skl_dsp_widget_type(p->sink)) {
+				is_skl_dsp_widget_type(p->sink, ctx->dev)) {
 
 			sink = p->sink;
 			sink_mconfig = sink->priv;
@@ -1092,7 +1177,7 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
 		 * ones used for SKL so check that first
 		 */
 		if ((p->source->priv != NULL) &&
-					is_skl_dsp_widget_type(p->source)) {
+				is_skl_dsp_widget_type(p->source, ctx->dev)) {
 			return p->source;
 		}
 	}
@@ -1654,7 +1739,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
 		w = dai->playback_widget;
 		snd_soc_dapm_widget_for_each_sink_path(w, p) {
 			if (p->connect && p->sink->power &&
-					!is_skl_dsp_widget_type(p->sink))
+				!is_skl_dsp_widget_type(p->sink, dai->dev))
 				continue;
 
 			if (p->sink->priv) {
@@ -1667,7 +1752,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
 		w = dai->capture_widget;
 		snd_soc_dapm_widget_for_each_source_path(w, p) {
 			if (p->connect && p->source->power &&
-					!is_skl_dsp_widget_type(p->source))
+				!is_skl_dsp_widget_type(p->source, dai->dev))
 				continue;
 
 			if (p->source->priv) {
@@ -1819,7 +1904,7 @@ static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
 	int ret = -EIO;
 
 	snd_soc_dapm_widget_for_each_source_path(w, p) {
-		if (p->connect && is_skl_dsp_widget_type(p->source) &&
+		if (p->connect && is_skl_dsp_widget_type(p->source, dai->dev) &&
 						p->source->priv) {
 
 			ret = skl_tplg_be_fill_pipe_params(dai,
@@ -1844,7 +1929,7 @@ static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
 	int ret = -EIO;
 
 	snd_soc_dapm_widget_for_each_sink_path(w, p) {
-		if (p->connect && is_skl_dsp_widget_type(p->sink) &&
+		if (p->connect && is_skl_dsp_widget_type(p->sink, dai->dev) &&
 						p->sink->priv) {
 
 			ret = skl_tplg_be_fill_pipe_params(dai,
@@ -2710,15 +2795,15 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
 	return 0;
 }
 
-static void skl_clear_pin_config(struct snd_soc_platform *platform,
+static void skl_clear_pin_config(struct snd_soc_component *component,
 				struct snd_soc_dapm_widget *w)
 {
 	int i;
 	struct skl_module_cfg *mconfig;
 	struct skl_pipe *pipe;
 
-	if (!strncmp(w->dapm->component->name, platform->component.name,
-					strlen(platform->component.name))) {
+	if (!strncmp(w->dapm->component->name, component->name,
+					strlen(component->name))) {
 		mconfig = w->priv;
 		pipe = mconfig->pipe;
 		for (i = 0; i < mconfig->module->max_input_pins; i++) {
@@ -2737,14 +2822,14 @@ static void skl_clear_pin_config(struct snd_soc_platform *platform,
 void skl_cleanup_resources(struct skl *skl)
 {
 	struct skl_sst *ctx = skl->skl_sst;
-	struct snd_soc_platform *soc_platform = skl->platform;
+	struct snd_soc_component *soc_component = skl->component;
 	struct snd_soc_dapm_widget *w;
 	struct snd_soc_card *card;
 
-	if (soc_platform == NULL)
+	if (soc_component == NULL)
 		return;
 
-	card = soc_platform->component.card;
+	card = soc_component->card;
 	if (!card || !card->instantiated)
 		return;
 
@@ -2752,8 +2837,8 @@ void skl_cleanup_resources(struct skl *skl)
 	skl->resource.mcps = 0;
 
 	list_for_each_entry(w, &card->widgets, list) {
-		if (is_skl_dsp_widget_type(w) && (w->priv != NULL))
-			skl_clear_pin_config(soc_platform, w);
+		if (is_skl_dsp_widget_type(w, ctx->dev) && w->priv != NULL)
+			skl_clear_pin_config(soc_component, w);
 	}
 
 	skl_clear_module_cnt(ctx->dsp);
@@ -3400,19 +3485,19 @@ static struct snd_soc_tplg_ops skl_tplg_ops  = {
  * widgets in a pipelines, so this helper - skl_tplg_create_pipe_widget_list()
  * helps to get the SKL type widgets in that pipeline
  */
-static int skl_tplg_create_pipe_widget_list(struct snd_soc_platform *platform)
+static int skl_tplg_create_pipe_widget_list(struct snd_soc_component *component)
 {
 	struct snd_soc_dapm_widget *w;
 	struct skl_module_cfg *mcfg = NULL;
 	struct skl_pipe_module *p_module = NULL;
 	struct skl_pipe *pipe;
 
-	list_for_each_entry(w, &platform->component.card->widgets, list) {
-		if (is_skl_dsp_widget_type(w) && w->priv != NULL) {
+	list_for_each_entry(w, &component->card->widgets, list) {
+		if (is_skl_dsp_widget_type(w, component->dev) && w->priv) {
 			mcfg = w->priv;
 			pipe = mcfg->pipe;
 
-			p_module = devm_kzalloc(platform->dev,
+			p_module = devm_kzalloc(component->dev,
 						sizeof(*p_module), GFP_KERNEL);
 			if (!p_module)
 				return -ENOMEM;
@@ -3455,7 +3540,7 @@ static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe)
 /*
  * SKL topology init routine
  */
-int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
+int skl_tplg_init(struct snd_soc_component *component, struct hdac_ext_bus *ebus)
 {
 	int ret;
 	const struct firmware *fw;
@@ -3479,7 +3564,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
 	 * The complete tplg for SKL is loaded as index 0, we don't use
 	 * any other index
 	 */
-	ret = snd_soc_tplg_component_load(&platform->component,
+	ret = snd_soc_tplg_component_load(component,
 					&skl_tplg_ops, fw, 0);
 	if (ret < 0) {
 		dev_err(bus->dev, "tplg component load failed%d\n", ret);
@@ -3491,7 +3576,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
 	skl->resource.max_mem = SKL_FW_MAX_MEM;
 
 	skl->tplg = fw;
-	ret = skl_tplg_create_pipe_widget_list(platform);
+	ret = skl_tplg_create_pipe_widget_list(component);
 	if (ret < 0)
 		return ret;
 
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index b649651..b1e0667 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -221,9 +221,18 @@ struct skl_mod_inst_map {
 	u16 inst_id;
 };
 
+struct skl_uuid_inst_map {
+	u16 inst_id;
+	u16 reserved;
+	uuid_le mod_uuid;
+} __packed;
+
 struct skl_kpb_params {
 	u32 num_modules;
-	struct skl_mod_inst_map map[0];
+	union {
+		struct skl_mod_inst_map map[0];
+		struct skl_uuid_inst_map map_uuid[0];
+	} u;
 };
 
 struct skl_module_inst_id {
@@ -460,7 +469,7 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
 			u32 caps_size, u32 node_id);
 void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
 	struct skl_pipe_params *params, int stream);
-int skl_tplg_init(struct snd_soc_platform *platform,
+int skl_tplg_init(struct snd_soc_component *component,
 				struct hdac_ext_bus *ebus);
 struct skl_module_cfg *skl_tplg_fe_get_cpr_module(
 		struct snd_soc_dai *dai, int stream);
@@ -505,4 +514,6 @@ int skl_pcm_link_dma_prepare(struct device *dev,
 
 int skl_dai_load(struct snd_soc_component *cmp,
 		 struct snd_soc_dai_driver *pcm_dai);
+void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
+				struct snd_soc_dapm_widget *w);
 #endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 32ce64c..abf3247 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -94,6 +94,32 @@ static void skl_enable_miscbdcge(struct device *dev, bool enable)
 	update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, val);
 }
 
+/**
+ * skl_clock_power_gating: Enable/Disable clock and power gating
+ *
+ * @dev: Device pointer
+ * @enable: Enable/Disable flag
+ */
+static void skl_clock_power_gating(struct device *dev, bool enable)
+{
+	struct pci_dev *pci = to_pci_dev(dev);
+	struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
+	struct hdac_bus *bus = ebus_to_hbus(ebus);
+	u32 val;
+
+	/* Update PDCGE bit of CGCTL register */
+	val = enable ? AZX_CGCTL_ADSPDCGE : 0;
+	update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_ADSPDCGE, val);
+
+	/* Update L1SEN bit of EM2 register */
+	val = enable ? AZX_REG_VS_EM2_L1SEN : 0;
+	snd_hdac_chip_updatel(bus, VS_EM2, AZX_REG_VS_EM2_L1SEN, val);
+
+	/* Update ADSPPGD bit of PGCTL register */
+	val = enable ? 0 : AZX_PGCTL_ADSPPGD;
+	update_pci_dword(pci, AZX_PCIREG_PGCTL, AZX_PGCTL_ADSPPGD, val);
+}
+
 /*
  * While performing reset, controller may not come back properly causing
  * issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
@@ -916,6 +942,7 @@ static int skl_probe(struct pci_dev *pci,
 			goto out_nhlt_free;
 		}
 		skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
+		skl->skl_sst->clock_power_gating = skl_clock_power_gating;
 	}
 	if (bus->mlcap)
 		snd_hdac_ext_bus_get_ml_capabilities(ebus);
@@ -1017,6 +1044,11 @@ static struct snd_soc_acpi_codecs kbl_5663_5514_codecs = {
 	.codecs = {"10EC5663", "10EC5514"}
 };
 
+static struct snd_soc_acpi_codecs kbl_7219_98357_codecs = {
+	.num_codecs = 1,
+	.codecs = {"MX98357A"}
+};
+
 static struct skl_machine_pdata cnl_pdata = {
 	.use_tplg_pcm = true,
 };
@@ -1105,6 +1137,14 @@ static struct snd_soc_acpi_mach sst_kbl_devdata[] = {
 		.drv_name = "kbl_rt5663",
 		.fw_filename = "intel/dsp_fw_kbl.bin",
 	},
+	{
+		.id = "DLGS7219",
+		.drv_name = "kbl_da7219_max98357a",
+		.fw_filename = "intel/dsp_fw_kbl.bin",
+		.machine_quirk = snd_soc_acpi_codec_list,
+		.quirk_data = &kbl_7219_98357_codecs,
+		.pdata = &skl_dmic_data
+	},
 
 	{}
 };
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 2d13f3f..0d5375c 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -33,8 +33,10 @@
 
 #define AZX_PCIREG_PGCTL		0x44
 #define AZX_PGCTL_LSRMD_MASK		(1 << 4)
+#define AZX_PGCTL_ADSPPGD		BIT(2)
 #define AZX_PCIREG_CGCTL		0x48
 #define AZX_CGCTL_MISCBDCGE_MASK	(1 << 6)
+#define AZX_CGCTL_ADSPDCGE		BIT(1)
 /* D0I3C Register fields */
 #define AZX_REG_VS_D0I3C_CIP      0x1 /* Command in progress */
 #define AZX_REG_VS_D0I3C_I3       0x4 /* D0i3 enable */
@@ -43,6 +45,8 @@
 #define DMA_TRANSMITION_START	2
 #define DMA_TRANSMITION_STOP	3
 
+#define AZX_REG_VS_EM2_L1SEN		BIT(13)
+
 struct skl_dsp_resource {
 	u32 max_mcps;
 	u32 max_mem;
@@ -74,7 +78,7 @@ struct skl {
 	struct platform_device *dmic_dev;
 	struct platform_device *i2s_dev;
 	struct platform_device *clk_dev;
-	struct snd_soc_platform *platform;
+	struct snd_soc_component *component;
 	struct snd_soc_dai_driver *dais;
 
 	struct nhlt_acpi_table *nhlt; /* nhlt ptr */
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index 505b0ff..c6a5852 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -318,7 +318,8 @@ static void kirkwood_dma_free_dma_buffers(struct snd_pcm *pcm)
 	}
 }
 
-const struct snd_soc_platform_driver kirkwood_soc_platform = {
+const struct snd_soc_component_driver kirkwood_soc_component = {
+	.name		= DRV_NAME,
 	.ops		= &kirkwood_dma_ops,
 	.pcm_new	= kirkwood_dma_new,
 	.pcm_free	= kirkwood_dma_free_dma_buffers,
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 105a73c..9a2777b 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -26,8 +26,6 @@
 
 #include "kirkwood.h"
 
-#define DRV_NAME	"mvebu-audio"
-
 #define KIRKWOOD_I2S_FORMATS \
 	(SNDRV_PCM_FMTBIT_S16_LE | \
 	 SNDRV_PCM_FMTBIT_S24_LE | \
@@ -524,10 +522,6 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
     },
 };
 
-static const struct snd_soc_component_driver kirkwood_i2s_component = {
-	.name		= DRV_NAME,
-};
-
 static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 {
 	struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
@@ -601,24 +595,17 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
 	}
 
-	err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
+	err = devm_snd_soc_register_component(&pdev->dev, &kirkwood_soc_component,
 					 soc_dai, 2);
 	if (err) {
 		dev_err(&pdev->dev, "snd_soc_register_component failed\n");
 		goto err_component;
 	}
 
-	err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
-	if (err) {
-		dev_err(&pdev->dev, "snd_soc_register_platform failed\n");
-		goto err_platform;
-	}
-
 	kirkwood_i2s_init(priv);
 
 	return 0;
- err_platform:
-	snd_soc_unregister_component(&pdev->dev);
+
  err_component:
 	if (!IS_ERR(priv->extclk))
 		clk_disable_unprepare(priv->extclk);
@@ -631,9 +618,6 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
 {
 	struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
 
-	snd_soc_unregister_platform(&pdev->dev);
-	snd_soc_unregister_component(&pdev->dev);
-
 	if (!IS_ERR(priv->extclk))
 		clk_disable_unprepare(priv->extclk);
 	clk_disable_unprepare(priv->clk);
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h
index 783cb1a4..c13ee5f 100644
--- a/sound/soc/kirkwood/kirkwood.h
+++ b/sound/soc/kirkwood/kirkwood.h
@@ -12,6 +12,8 @@
 #ifndef _KIRKWOOD_AUDIO_H
 #define _KIRKWOOD_AUDIO_H
 
+#define DRV_NAME	"mvebu-audio"
+
 #define KIRKWOOD_RECORD_WIN			0
 #define KIRKWOOD_PLAYBACK_WIN			1
 #define KIRKWOOD_MAX_AUDIO_WIN			2
@@ -143,6 +145,6 @@ struct kirkwood_dma_data {
 	int burst;
 };
 
-extern const struct snd_soc_platform_driver kirkwood_soc_platform;
+extern const struct snd_soc_component_driver kirkwood_soc_component;
 
 #endif
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
index ac231d3..c91e5f4 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -18,6 +18,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <sound/soc.h>
+#include "mtk-afe-platform-driver.h"
 #include "mtk-afe-fe-dai.h"
 #include "mtk-base-afe.h"
 
@@ -43,7 +44,8 @@ int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
 		       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int memif_num = rtd->cpu_dai->id;
 	struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
@@ -105,7 +107,8 @@ void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
 			 struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
 	int irq_id;
 
@@ -128,7 +131,8 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
 			 struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
 	int msb_at_bit33 = 0;
 	int ret, fs = 0;
@@ -192,7 +196,8 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime * const runtime = substream->runtime;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
 	struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage];
 	const struct mtk_base_irq_data *irq_data = irqs->irq_data;
@@ -255,7 +260,8 @@ int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
 		       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd  = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
 	int hd_audio = 0;
 
diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
index 82d439c..53215b5 100644
--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
@@ -25,7 +25,8 @@ static snd_pcm_uframes_t mtk_afe_pcm_pointer
 			 (struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
 	const struct mtk_base_memif_data *memif_data = memif->data;
 	struct regmap *regmap = afe->regmap;
@@ -65,7 +66,8 @@ static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	size_t size;
 	struct snd_card *card = rtd->card->snd_card;
 	struct snd_pcm *pcm = rtd->pcm;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
 	size = afe->mtk_afe_hardware->buffer_bytes_max;
 	return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
@@ -77,7 +79,8 @@ static void mtk_afe_pcm_free(struct snd_pcm *pcm)
 	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
-const struct snd_soc_platform_driver mtk_afe_pcm_platform = {
+const struct snd_soc_component_driver mtk_afe_pcm_platform = {
+	.name = AFE_PCM_NAME,
 	.ops = &mtk_afe_pcm_ops,
 	.pcm_new = mtk_afe_pcm_new,
 	.pcm_free = mtk_afe_pcm_free,
diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.h b/sound/soc/mediatek/common/mtk-afe-platform-driver.h
index a973fc9..8dcdbed 100644
--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.h
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.h
@@ -17,7 +17,8 @@
 #ifndef _MTK_AFE_PLATFORM_DRIVER_H_
 #define _MTK_AFE_PLATFORM_DRIVER_H_
 
-extern const struct snd_soc_platform_driver mtk_afe_pcm_platform;
+#define AFE_PCM_NAME "mtk-afe-pcm"
+extern const struct snd_soc_component_driver mtk_afe_pcm_platform;
 
 #endif
 
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index d68b53f..73cce33 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -93,7 +93,8 @@ static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
 				  struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
 
 	if (i2s_num < 0)
@@ -108,7 +109,8 @@ static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
 					int dir_invert)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
 	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
 	const struct mt2701_i2s_data *i2s_data;
@@ -144,7 +146,8 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
 				    struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
 	struct mt2701_i2s_path *i2s_path;
@@ -176,7 +179,8 @@ static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
 					  int dir_invert)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
 	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
 	const struct mt2701_i2s_data *i2s_data;
@@ -247,7 +251,8 @@ static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
 {
 	int clk_domain;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
 	struct mt2701_i2s_path *i2s_path;
@@ -312,7 +317,8 @@ static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
 				struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
 	int ret;
 
@@ -329,14 +335,15 @@ static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
 				  struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	int stream_fs;
 	u32 val, msk;
 
 	stream_fs = params_rate(params);
 
 	if ((stream_fs != 8000) && (stream_fs != 16000)) {
-		dev_err(afe->dev, "%s() btmgr not supprt this stream_fs %d\n",
+		dev_err(afe->dev, "%s() btmgr not support this stream_fs %d\n",
 			__func__, stream_fs);
 		return -EINVAL;
 	}
@@ -372,7 +379,8 @@ static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
 				  struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
 
 	/* if the other direction stream is not occupied */
@@ -392,7 +400,8 @@ static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
 				    struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	int stream_dir = substream->stream;
 	int memif_num = rtd->cpu_dai->id;
 	struct mtk_base_afe_memif *memif_tmp;
@@ -414,7 +423,8 @@ static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream,
 				      struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	int stream_dir = substream->stream;
 
 	/* single DL use PAIR_INTERLEAVE */
@@ -431,7 +441,8 @@ static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,
 				 struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mtk_base_afe_memif *memif_tmp;
 	const struct mtk_base_memif_data *memif_data;
 	int i;
@@ -458,7 +469,8 @@ static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,
 				   struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	const struct mtk_base_memif_data *memif_data;
 	int i;
 
@@ -477,7 +489,8 @@ static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	int channels = params_channels(params);
 
 	regmap_update_bits(afe->regmap,
@@ -500,7 +513,8 @@ static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream,
 				 int cmd, struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1];
 
 	switch (cmd) {
@@ -1517,7 +1531,8 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
 	}
 	pm_runtime_get_sync(dev);
 
-	ret = snd_soc_register_platform(dev, &mtk_afe_pcm_platform);
+	ret = devm_snd_soc_register_component(&pdev->dev, &mtk_afe_pcm_platform,
+					      NULL, 0);
 	if (ret) {
 		dev_warn(dev, "err_platform\n");
 		goto err_platform;
@@ -1526,13 +1541,11 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
 	ret = mt2701_afe_add_component(afe);
 	if (ret) {
 		dev_warn(dev, "err_dai_component\n");
-		goto err_dai_component;
+		goto err_platform;
 	}
 
 	return 0;
 
-err_dai_component:
-	snd_soc_unregister_platform(dev);
 err_platform:
 	pm_runtime_put_sync(dev);
 err_pm_disable:
@@ -1548,9 +1561,6 @@ static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
 	if (!pm_runtime_status_suspended(&pdev->dev))
 		mt2701_afe_runtime_suspend(&pdev->dev);
 
-	snd_soc_unregister_component(&pdev->dev);
-	snd_soc_unregister_platform(&pdev->dev);
-
 	return 0;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index c7f7f8a..65d1433 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -304,7 +304,8 @@ static int mt8173_afe_i2s_startup(struct snd_pcm_substream *substream,
 				  struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
 	if (dai->active)
 		return 0;
@@ -318,7 +319,8 @@ static void mt8173_afe_i2s_shutdown(struct snd_pcm_substream *substream,
 				    struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
 	if (dai->active)
 		return;
@@ -334,7 +336,8 @@ static int mt8173_afe_i2s_prepare(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime * const runtime = substream->runtime;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt8173_afe_private *afe_priv = afe->platform_priv;
 	int ret;
 
@@ -356,7 +359,8 @@ static int mt8173_afe_hdmi_startup(struct snd_pcm_substream *substream,
 				   struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt8173_afe_private *afe_priv = afe->platform_priv;
 
 	if (dai->active)
@@ -371,7 +375,8 @@ static void mt8173_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
 				     struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt8173_afe_private *afe_priv = afe->platform_priv;
 
 	if (dai->active)
@@ -386,7 +391,8 @@ static int mt8173_afe_hdmi_prepare(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime * const runtime = substream->runtime;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mt8173_afe_private *afe_priv = afe->platform_priv;
 
 	unsigned int val;
@@ -449,7 +455,8 @@ static int mt8173_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
 				   struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
 	dev_info(afe->dev, "%s cmd=%d %s\n", __func__, cmd, dai->name);
 
@@ -498,7 +505,8 @@ static int mt8173_memif_fs(struct snd_pcm_substream *substream,
 			   unsigned int rate)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 	struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
 	int fs;
 
@@ -1172,31 +1180,29 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
 	afe->runtime_resume = mt8173_afe_runtime_resume;
 	afe->runtime_suspend = mt8173_afe_runtime_suspend;
 
-	ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform);
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					 &mtk_afe_pcm_platform,
+					 NULL, 0);
 	if (ret)
 		goto err_pm_disable;
 
-	ret = snd_soc_register_component(&pdev->dev,
+	ret = devm_snd_soc_register_component(&pdev->dev,
 					 &mt8173_afe_pcm_dai_component,
 					 mt8173_afe_pcm_dais,
 					 ARRAY_SIZE(mt8173_afe_pcm_dais));
 	if (ret)
-		goto err_platform;
+		goto err_pm_disable;
 
-	ret = snd_soc_register_component(&pdev->dev,
+	ret = devm_snd_soc_register_component(&pdev->dev,
 					 &mt8173_afe_hdmi_dai_component,
 					 mt8173_afe_hdmi_dais,
 					 ARRAY_SIZE(mt8173_afe_hdmi_dais));
 	if (ret)
-		goto err_comp;
+		goto err_pm_disable;
 
 	dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
 	return 0;
 
-err_comp:
-	snd_soc_unregister_component(&pdev->dev);
-err_platform:
-	snd_soc_unregister_platform(&pdev->dev);
 err_pm_disable:
 	pm_runtime_disable(&pdev->dev);
 	return ret;
@@ -1207,8 +1213,6 @@ static int mt8173_afe_pcm_dev_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 	if (!pm_runtime_status_suspended(&pdev->dev))
 		mt8173_afe_runtime_suspend(&pdev->dev);
-	snd_soc_unregister_component(&pdev->dev);
-	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index e0c2b23..b49b527 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -75,7 +75,7 @@ static int mt8173_max98090_init(struct snd_soc_pcm_runtime *runtime)
 {
 	int ret;
 	struct snd_soc_card *card = runtime->card;
-	struct snd_soc_codec *codec = runtime->codec;
+	struct snd_soc_component *component = runtime->codec_dai->component;
 
 	/* enable jack detection */
 	ret = snd_soc_card_jack_new(card, "Headphone", SND_JACK_HEADPHONE,
@@ -87,7 +87,7 @@ static int mt8173_max98090_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
-	return max98090_mic_detect(codec, &mt8173_max98090_jack);
+	return max98090_mic_detect(component, &mt8173_max98090_jack);
 }
 
 /* Digital audio interface glue - connects codec <---> CPU */
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 5a9a548..904f3ee 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -82,10 +82,10 @@ static struct snd_soc_jack mt8173_rt5650_rt5514_jack;
 static int mt8173_rt5650_rt5514_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
-	struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
+	struct snd_soc_component *component = runtime->codec_dais[0]->component;
 	int ret;
 
-	rt5645_sel_asrc_clk_src(codec,
+	rt5645_sel_asrc_clk_src(component,
 				RT5645_DA_STEREO_FILTER |
 				RT5645_AD_STEREO_FILTER,
 				RT5645_CLK_SEL_I2S1_ASRC);
@@ -101,7 +101,7 @@ static int mt8173_rt5650_rt5514_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
-	return rt5645_set_jack_detect(codec,
+	return rt5645_set_jack_detect(component,
 				      &mt8173_rt5650_rt5514_jack,
 				      &mt8173_rt5650_rt5514_jack,
 				      &mt8173_rt5650_rt5514_jack);
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index b724808..9c61b8c 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -86,19 +86,19 @@ static struct snd_soc_jack mt8173_rt5650_rt5676_jack;
 static int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
-	struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
-	struct snd_soc_codec *codec_sub = runtime->codec_dais[1]->codec;
+	struct snd_soc_component *component = runtime->codec_dais[0]->component;
+	struct snd_soc_component *component_sub = runtime->codec_dais[1]->component;
 	int ret;
 
-	rt5645_sel_asrc_clk_src(codec,
+	rt5645_sel_asrc_clk_src(component,
 				RT5645_DA_STEREO_FILTER |
 				RT5645_AD_STEREO_FILTER,
 				RT5645_CLK_SEL_I2S1_ASRC);
-	rt5677_sel_asrc_clk_src(codec_sub,
+	rt5677_sel_asrc_clk_src(component_sub,
 				RT5677_DA_STEREO_FILTER |
 				RT5677_AD_STEREO1_FILTER,
 				RT5677_CLK_SEL_I2S1_ASRC);
-	rt5677_sel_asrc_clk_src(codec_sub,
+	rt5677_sel_asrc_clk_src(component_sub,
 				RT5677_AD_STEREO2_FILTER |
 				RT5677_I2S2_SOURCE,
 				RT5677_CLK_SEL_I2S2_ASRC);
@@ -114,7 +114,7 @@ static int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
-	return rt5645_set_jack_detect(codec,
+	return rt5645_set_jack_detect(component,
 				      &mt8173_rt5650_rt5676_jack,
 				      &mt8173_rt5650_rt5676_jack,
 				      &mt8173_rt5650_rt5676_jack);
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index 679fc8b..84aa09d 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -112,26 +112,26 @@ static struct snd_soc_jack mt8173_rt5650_jack;
 static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
-	struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
+	struct snd_soc_component *component = runtime->codec_dais[0]->component;
 	const char *codec_capture_dai = runtime->codec_dais[1]->name;
 	int ret;
 
-	rt5645_sel_asrc_clk_src(codec,
+	rt5645_sel_asrc_clk_src(component,
 				RT5645_DA_STEREO_FILTER,
 				RT5645_CLK_SEL_I2S1_ASRC);
 
 	if (!strcmp(codec_capture_dai, "rt5645-aif1")) {
-		rt5645_sel_asrc_clk_src(codec,
+		rt5645_sel_asrc_clk_src(component,
 					RT5645_AD_STEREO_FILTER,
 					RT5645_CLK_SEL_I2S1_ASRC);
 	} else if (!strcmp(codec_capture_dai, "rt5645-aif2")) {
-		rt5645_sel_asrc_clk_src(codec,
+		rt5645_sel_asrc_clk_src(component,
 					RT5645_AD_STEREO_FILTER,
 					RT5645_CLK_SEL_I2S2_ASRC);
 	} else {
 		dev_warn(card->dev,
 			 "Only one dai codec found in DTS, enabled rt5645 AD filter\n");
-		rt5645_sel_asrc_clk_src(codec,
+		rt5645_sel_asrc_clk_src(component,
 					RT5645_AD_STEREO_FILTER,
 					RT5645_CLK_SEL_I2S1_ASRC);
 	}
@@ -147,7 +147,7 @@ static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
-	return rt5645_set_jack_detect(codec,
+	return rt5645_set_jack_detect(component,
 				      &mt8173_rt5650_jack,
 				      &mt8173_rt5650_jack,
 				      &mt8173_rt5650_jack);
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index bd6dfa2..ad8392a 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -299,14 +299,15 @@ static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
 	return 0;
 }
 
-static const struct snd_soc_platform_driver nuc900_soc_platform = {
+static const struct snd_soc_component_driver nuc900_soc_component = {
 	.ops		= &nuc900_dma_ops,
 	.pcm_new	= nuc900_dma_new,
 };
 
 static int nuc900_soc_platform_probe(struct platform_device *pdev)
 {
-	return devm_snd_soc_register_platform(&pdev->dev, &nuc900_soc_platform);
+	return devm_snd_soc_register_component(&pdev->dev, &nuc900_soc_component,
+					       NULL, 0);
 }
 
 static struct platform_driver nuc900_pcm_driver = {
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index cb72c1e..77a30f0 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -93,7 +93,7 @@ static unsigned short ams_delta_audio_agc;
  * Used for passing a codec structure pointer
  * from the board initialization code to the tty line discipline.
  */
-static struct snd_soc_codec *cx20442_codec;
+static struct snd_soc_component *cx20442_codec;
 
 static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
 					struct snd_ctl_elem_value *ucontrol)
@@ -105,7 +105,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
 	int pin, changed = 0;
 
 	/* Refuse any mode changes if we are not able to control the codec. */
-	if (!cx20442_codec->component.card->pop_time)
+	if (!cx20442_codec->card->pop_time)
 		return -EUNATCH;
 
 	if (ucontrol->value.enumerated.item[0] >= control->items)
@@ -300,15 +300,15 @@ static int cx81801_open(struct tty_struct *tty)
 /* Line discipline .close() */
 static void cx81801_close(struct tty_struct *tty)
 {
-	struct snd_soc_codec *codec = tty->disc_data;
-	struct snd_soc_dapm_context *dapm = &codec->component.card->dapm;
+	struct snd_soc_component *component = tty->disc_data;
+	struct snd_soc_dapm_context *dapm = &component->card->dapm;
 
 	del_timer_sync(&cx81801_timer);
 
 	/* Prevent the hook switch from further changing the DAPM pins */
 	INIT_LIST_HEAD(&ams_delta_hook_switch.pins);
 
-	if (!codec)
+	if (!component)
 		return;
 
 	v253_ops.close(tty);
@@ -338,14 +338,14 @@ static int cx81801_hangup(struct tty_struct *tty)
 static void cx81801_receive(struct tty_struct *tty,
 				const unsigned char *cp, char *fp, int count)
 {
-	struct snd_soc_codec *codec = tty->disc_data;
+	struct snd_soc_component *component = tty->disc_data;
 	const unsigned char *c;
 	int apply, ret;
 
-	if (!codec)
+	if (!component)
 		return;
 
-	if (!codec->component.card->pop_time) {
+	if (!component->card->pop_time) {
 		/* First modem response, complete setup procedure */
 
 		/* Initialize timer used for config pulse generation */
@@ -358,7 +358,7 @@ static void cx81801_receive(struct tty_struct *tty,
 					ARRAY_SIZE(ams_delta_hook_switch_pins),
 					ams_delta_hook_switch_pins);
 		if (ret)
-			dev_warn(codec->dev,
+			dev_warn(component->dev,
 				"Failed to link hook switch to DAPM pins, "
 				"will continue with hook switch unlinked.\n");
 
@@ -467,7 +467,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
 	/* Codec is ready, now add/activate board specific controls */
 
 	/* Store a pointer to the codec structure for tty ldisc use */
-	cx20442_codec = rtd->codec;
+	cx20442_codec = rtd->codec_dai->component;
 
 	/* Set up digital mute if not provided by the codec */
 	if (!codec_dai->driver->ops) {
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 614b18d..15ccbf4 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -52,7 +52,7 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream,
 	int clk_id, freq;
 	int ret;
 
-	clk_id = twl6040_get_clk_id(rtd->codec);
+	clk_id = twl6040_get_clk_id(codec_dai->component);
 	if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
 		freq = priv->mclk_freq;
 	else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
@@ -166,7 +166,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
 
 static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	struct snd_soc_card *card = rtd->card;
 	struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
 	int hs_trim;
@@ -176,7 +176,7 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
 	 * Configure McPDM offset cancellation based on the HSOTRIM value from
 	 * twl6040.
 	 */
-	hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
+	hs_trim = twl6040_get_trim_value(component, TWL6040_TRIM_HSOTRIM);
 	omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
 					TWL6040_HSF_TRIM_RIGHT(hs_trim));
 
@@ -189,7 +189,7 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
 		if (ret)
 			return ret;
 
-		twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
+		twl6040_hs_jack_detect(component, &hs_jack, SND_JACK_HEADSET);
 	}
 
 	return 0;
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index aca2c43..778cc8f 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -243,7 +243,7 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	return ret;
 }
 
-static const struct snd_soc_platform_driver omap_soc_platform = {
+static const struct snd_soc_component_driver omap_soc_component = {
 	.ops		= &omap_pcm_ops,
 	.pcm_new	= omap_pcm_new,
 	.pcm_free	= omap_pcm_free_dma_buffers,
@@ -252,7 +252,8 @@ static const struct snd_soc_platform_driver omap_soc_platform = {
 int omap_pcm_platform_register(struct device *dev)
 {
 	omap_pcm_limit_supported_formats();
-	return devm_snd_soc_register_platform(dev, &omap_soc_platform);
+	return devm_snd_soc_register_component(dev, &omap_soc_component,
+					       NULL, 0);
 }
 EXPORT_SYMBOL_GPL(omap_pcm_platform_register);
 
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index c4c6fbe..47052fe 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -58,20 +58,20 @@
 #define AC97_GPIO_PULL		0x58
 
 /* Use GPIO8 for rear speaker amplifier */
-static int rear_amp_power(struct snd_soc_codec *codec, int power)
+static int rear_amp_power(struct snd_soc_component *component, int power)
 {
 	unsigned short reg;
 
 	if (power) {
-		reg = snd_soc_read(codec, AC97_GPIO_CFG);
-		snd_soc_write(codec, AC97_GPIO_CFG, reg | 0x0100);
-		reg = snd_soc_read(codec, AC97_GPIO_PULL);
-		snd_soc_write(codec, AC97_GPIO_PULL, reg | (1<<15));
+		reg = snd_soc_component_read32(component, AC97_GPIO_CFG);
+		snd_soc_component_write(component, AC97_GPIO_CFG, reg | 0x0100);
+		reg = snd_soc_component_read32(component, AC97_GPIO_PULL);
+		snd_soc_component_write(component, AC97_GPIO_PULL, reg | (1<<15));
 	} else {
-		reg = snd_soc_read(codec, AC97_GPIO_CFG);
-		snd_soc_write(codec, AC97_GPIO_CFG, reg & ~0x0100);
-		reg = snd_soc_read(codec, AC97_GPIO_PULL);
-		snd_soc_write(codec, AC97_GPIO_PULL, reg & ~(1<<15));
+		reg = snd_soc_component_read32(component, AC97_GPIO_CFG);
+		snd_soc_component_write(component, AC97_GPIO_CFG, reg & ~0x0100);
+		reg = snd_soc_component_read32(component, AC97_GPIO_PULL);
+		snd_soc_component_write(component, AC97_GPIO_PULL, reg & ~(1<<15));
 	}
 
 	return 0;
@@ -82,11 +82,11 @@ static int rear_amp_event(struct snd_soc_dapm_widget *widget,
 {
 	struct snd_soc_card *card = widget->dapm->card;
 	struct snd_soc_pcm_runtime *rtd;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 
 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-	codec = rtd->codec;
-	return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event));
+	component = rtd->codec_dai->component;
+	return rear_amp_power(component, SND_SOC_DAPM_EVENT_ON(event));
 }
 
 /* mioa701 machine dapm widgets */
@@ -129,13 +129,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
 
 static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 
 	/* Prepare GPIO8 for rear speaker amplifier */
-	snd_soc_update_bits(codec, AC97_GPIO_CFG, 0x100, 0x100);
+	snd_soc_component_update_bits(component, AC97_GPIO_CFG, 0x100, 0x100);
 
 	/* Prepare MIC input */
-	snd_soc_update_bits(codec, AC97_3D_CONTROL, 0xc000, 0xc000);
+	snd_soc_component_update_bits(component, AC97_3D_CONTROL, 0xc000, 0xc000);
 
 	return 0;
 }
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
index 624d9bd..d2d4652 100644
--- a/sound/soc/pxa/mmp-pcm.c
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -25,6 +25,8 @@
 #include <sound/soc.h>
 #include <sound/dmaengine_pcm.h>
 
+#define DRV_NAME "mmp-pcm"
+
 struct mmp_dma_data {
 	int ssp_id;
 	struct resource *dma_res;
@@ -100,7 +102,8 @@ static bool filter(struct dma_chan *chan, void *param)
 static int mmp_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct platform_device *pdev = to_platform_device(rtd->platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct platform_device *pdev = to_platform_device(component->dev);
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct mmp_dma_data dma_data;
 	struct resource *r;
@@ -211,7 +214,8 @@ static int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	return ret;
 }
 
-static const struct snd_soc_platform_driver mmp_soc_platform = {
+static const struct snd_soc_component_driver mmp_soc_component = {
+	.name		= DRV_NAME,
 	.ops		= &mmp_pcm_ops,
 	.pcm_new	= mmp_pcm_new,
 	.pcm_free	= mmp_pcm_free_dma_buffers,
@@ -231,7 +235,8 @@ static int mmp_pcm_probe(struct platform_device *pdev)
 		mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].period_bytes_max =
 						pdata->period_max_capture;
 	}
-	return devm_snd_soc_register_platform(&pdev->dev, &mmp_soc_platform);
+	return devm_snd_soc_register_component(&pdev->dev, &mmp_soc_component,
+					       NULL, 0);
 }
 
 static struct platform_driver mmp_pcm_driver = {
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index 64b85e3..7c998ea 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -377,7 +377,6 @@ static int mmp_sspa_probe(struct snd_soc_dai *dai)
 #define MMP_SSPA_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
 		SNDRV_PCM_FMTBIT_S16_LE | \
 		SNDRV_PCM_FMTBIT_S24_LE | \
-		SNDRV_PCM_FMTBIT_S24_LE | \
 		SNDRV_PCM_FMTBIT_S32_LE)
 
 static const struct snd_soc_dai_ops mmp_sspa_dai_ops = {
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index e64958d..8b6a70e 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -84,7 +84,7 @@ static int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	return ret;
 }
 
-static const struct snd_soc_platform_driver pxa2xx_soc_platform = {
+static const struct snd_soc_component_driver pxa2xx_soc_platform = {
 	.ops		= &pxa2xx_pcm_ops,
 	.pcm_new	= pxa2xx_soc_pcm_new,
 	.pcm_free	= pxa2xx_pcm_free_dma_buffers,
@@ -92,7 +92,8 @@ static const struct snd_soc_platform_driver pxa2xx_soc_platform = {
 
 static int pxa2xx_soc_platform_probe(struct platform_device *pdev)
 {
-	return devm_snd_soc_register_platform(&pdev->dev, &pxa2xx_soc_platform);
+	return devm_snd_soc_register_component(&pdev->dev, &pxa2xx_soc_platform,
+					       NULL, 0);
 }
 
 #ifdef CONFIG_OF
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c
index 65c20f7..5d6e61a 100644
--- a/sound/soc/pxa/ttc-dkb.c
+++ b/sound/soc/pxa/ttc-dkb.c
@@ -75,7 +75,7 @@ static const struct snd_soc_dapm_route ttc_audio_map[] = {
 
 static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 
 	/* Headset jack detection */
 	snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE |
@@ -86,9 +86,9 @@ static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
 			      ARRAY_SIZE(mic_jack_pins));
 
 	/* headphone, microphone detection & headset short detection */
-	pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
+	pm860x_hs_jack_detect(component, &hs_jack, SND_JACK_HEADPHONE,
 			      SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
-	pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
+	pm860x_mic_jack_detect(component, &hs_jack, SND_JACK_MICROPHONE);
 
 	return 0;
 }
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
index caf71aa..31fe78a 100644
--- a/sound/soc/qcom/lpass-platform.c
+++ b/sound/soc/qcom/lpass-platform.c
@@ -24,6 +24,8 @@
 #include "lpass-lpaif-reg.h"
 #include "lpass.h"
 
+#define DRV_NAME "lpass-platform"
+
 struct lpass_pcm_data {
 	int dma_ch;
 	int i2s_port;
@@ -61,8 +63,8 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
 	struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
-	struct lpass_data *drvdata =
-		snd_soc_platform_get_drvdata(soc_runtime->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
 	struct lpass_variant *v = drvdata->variant;
 	int ret, dma_ch, dir = substream->stream;
 	struct lpass_pcm_data *data;
@@ -115,8 +117,8 @@ static int lpass_platform_pcmops_close(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-	struct lpass_data *drvdata =
-		snd_soc_platform_get_drvdata(soc_runtime->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
 	struct lpass_variant *v = drvdata->variant;
 	struct lpass_pcm_data *data;
 
@@ -132,8 +134,8 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-	struct lpass_data *drvdata =
-		snd_soc_platform_get_drvdata(soc_runtime->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
 	struct snd_pcm_runtime *rt = substream->runtime;
 	struct lpass_pcm_data *pcm_data = rt->private_data;
 	struct lpass_variant *v = drvdata->variant;
@@ -225,8 +227,8 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
 static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-	struct lpass_data *drvdata =
-		snd_soc_platform_get_drvdata(soc_runtime->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
 	struct snd_pcm_runtime *rt = substream->runtime;
 	struct lpass_pcm_data *pcm_data = rt->private_data;
 	struct lpass_variant *v = drvdata->variant;
@@ -246,8 +248,8 @@ static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-	struct lpass_data *drvdata =
-		snd_soc_platform_get_drvdata(soc_runtime->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
 	struct snd_pcm_runtime *rt = substream->runtime;
 	struct lpass_pcm_data *pcm_data = rt->private_data;
 	struct lpass_variant *v = drvdata->variant;
@@ -298,8 +300,8 @@ static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
 		int cmd)
 {
 	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-	struct lpass_data *drvdata =
-		snd_soc_platform_get_drvdata(soc_runtime->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
 	struct snd_pcm_runtime *rt = substream->runtime;
 	struct lpass_pcm_data *pcm_data = rt->private_data;
 	struct lpass_variant *v = drvdata->variant;
@@ -372,8 +374,8 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
 		struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-	struct lpass_data *drvdata =
-			snd_soc_platform_get_drvdata(soc_runtime->platform);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
 	struct snd_pcm_runtime *rt = substream->runtime;
 	struct lpass_pcm_data *pcm_data = rt->private_data;
 	struct lpass_variant *v = drvdata->variant;
@@ -509,13 +511,14 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
 {
 	struct snd_pcm *pcm = soc_runtime->pcm;
 	struct snd_pcm_substream *psubstream, *csubstream;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
 	int ret = -EINVAL;
 	size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
 
 	psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
 	if (psubstream) {
 		ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
-					soc_runtime->platform->dev,
+					component->dev,
 					size, &psubstream->dma_buffer);
 		if (ret) {
 			dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
@@ -526,7 +529,7 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
 	csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
 	if (csubstream) {
 		ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
-					soc_runtime->platform->dev,
+					component->dev,
 					size, &csubstream->dma_buffer);
 		if (ret) {
 			dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
@@ -555,7 +558,8 @@ static void lpass_platform_pcm_free(struct snd_pcm *pcm)
 	}
 }
 
-static const struct snd_soc_platform_driver lpass_platform_driver = {
+static const struct snd_soc_component_driver lpass_component_driver = {
+	.name		= DRV_NAME,
 	.pcm_new	= lpass_platform_pcm_new,
 	.pcm_free	= lpass_platform_pcm_free,
 	.ops		= &lpass_platform_pcm_ops,
@@ -591,8 +595,8 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
 	}
 
 
-	return devm_snd_soc_register_platform(&pdev->dev,
-			&lpass_platform_driver);
+	return devm_snd_soc_register_component(&pdev->dev,
+			&lpass_component_driver, NULL, 0);
 }
 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register);
 
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index b082537..957046a 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -56,6 +56,9 @@
 	depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
 	select SND_SOC_ROCKCHIP_I2S
 	select SND_SOC_HDMI_CODEC
+	select SND_SOC_ES8328_I2C
+	select SND_SOC_ES8328_SPI if SPI_MASTER
+	select DRM_DW_HDMI_I2S_AUDIO if DRM_DW_HDMI
 	help
 	  Say Y or M here if you want to add support for SoC audio on Rockchip
 	  RK3288 boards using an analog output and the built-in HDMI audio.
diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c
index fa44e39..929b3fe 100644
--- a/sound/soc/rockchip/rk3288_hdmi_analog.c
+++ b/sound/soc/rockchip/rk3288_hdmi_analog.c
@@ -155,7 +155,7 @@ static struct snd_soc_dai_link_component rk_codecs[] = {
 	{ },
 	{
 		.name = "hdmi-audio-codec.2.auto",
-		.dai_name = "hdmi-hifi.0",
+		.dai_name = "i2s-hifi",
 	},
 };
 
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index 214bfc7..9a10181 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -176,7 +176,7 @@ static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
 
 static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec_dais[0]->codec;
+	struct snd_soc_component *component = rtd->codec_dais[0]->component;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	int ret;
 
@@ -215,7 +215,7 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
 	snd_jack_set_key(
 		rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
 
-	da7219_aad_jack_det(codec, &rockchip_sound_jack);
+	da7219_aad_jack_det(component, &rockchip_sound_jack);
 
 	return 0;
 }
diff --git a/sound/soc/rockchip/rockchip_rt5645.c b/sound/soc/rockchip/rockchip_rt5645.c
index 9e0c178..4db4fd5 100644
--- a/sound/soc/rockchip/rockchip_rt5645.c
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -29,16 +29,12 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include "rockchip_i2s.h"
+#include "../codecs/rt5645.h"
 
 #define DRV_NAME "rockchip-snd-rt5645"
 
 static struct snd_soc_jack headset_jack;
 
-/* Jack detect via rt5645 driver. */
-extern int rt5645_set_jack_detect(struct snd_soc_codec *codec,
-	struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
-	struct snd_soc_jack *btn_jack);
-
 static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
 	SND_SOC_DAPM_HP("Headphones", NULL),
 	SND_SOC_DAPM_SPK("Speakers", NULL),
@@ -129,7 +125,7 @@ static int rk_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
-	return rt5645_set_jack_detect(runtime->codec,
+	return rt5645_set_jack_detect(runtime->codec_dai->component,
 				     &headset_jack,
 				     &headset_jack,
 				     &headset_jack);
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 030949e..c3b7603 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -21,8 +21,6 @@
 # S3C24XX Machine Support
 snd-soc-jive-wm8750-objs := jive_wm8750.o
 snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
-snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
-snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
 snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
 snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
 snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
@@ -32,7 +30,6 @@
 snd-soc-smdk-wm8580-objs := smdk_wm8580.o
 snd-soc-smdk-wm8994-objs := smdk_wm8994.o
 snd-soc-snow-objs := snow.o
-snd-soc-smdk-wm9713-objs := smdk_wm9713.o
 snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
 snd-soc-smdk-spdif-objs := smdk_spdif.o
 snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o
diff --git a/sound/soc/samsung/i2s-regs.h b/sound/soc/samsung/i2s-regs.h
index fe69140..964985e 100644
--- a/sound/soc/samsung/i2s-regs.h
+++ b/sound/soc/samsung/i2s-regs.h
@@ -65,11 +65,12 @@
 #define CON_RXDMA_ACTIVE	(1 << 1)
 #define CON_ACTIVE		(1 << 0)
 
-#define MOD_OPCLK_CDCLK_OUT	(0 << 30)
-#define MOD_OPCLK_CDCLK_IN	(1 << 30)
-#define MOD_OPCLK_BCLK_OUT	(2 << 30)
-#define MOD_OPCLK_PCLK		(3 << 30)
-#define MOD_OPCLK_MASK		(3 << 30)
+#define MOD_OPCLK_SHIFT		30
+#define MOD_OPCLK_CDCLK_OUT	(0 << MOD_OPCLK_SHIFT)
+#define MOD_OPCLK_CDCLK_IN	(1 << MOD_OPCLK_SHIFT)
+#define MOD_OPCLK_BCLK_OUT	(2 << MOD_OPCLK_SHIFT)
+#define MOD_OPCLK_PCLK		(3 << MOD_OPCLK_SHIFT)
+#define MOD_OPCLK_MASK		(3 << MOD_OPCLK_SHIFT)
 #define MOD_TXS_IDMA		(1 << 28) /* Sec_TXFIFO use I-DMA */
 
 #define MOD_BLCS_SHIFT		26
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 233f1c9..f914ed4 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -489,7 +489,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
 	switch (clk_id) {
 	case SAMSUNG_I2S_OPCLK:
 		mask = MOD_OPCLK_MASK;
-		val = dir;
+		val = (dir << MOD_OPCLK_SHIFT) & MOD_OPCLK_MASK;
 		break;
 	case SAMSUNG_I2S_CDCLK:
 		mask = 1 << i2s_regs->cdclkcon_off;
@@ -656,8 +656,12 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
 		tmp |= mod_slave;
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
-		/* Set default source clock in Master mode */
-		if (i2s->rclk_srcrate == 0)
+		/*
+		 * Set default source clock in Master mode, only when the
+		 * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any
+		 * clock configuration assigned in DT is not overwritten.
+		 */
+		if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL)
 			i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
 							0, SND_SOC_CLOCK_IN);
 		break;
@@ -881,6 +885,11 @@ static int config_setup(struct i2s_dai *i2s)
 		return 0;
 
 	if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
+		struct clk *rclksrc = i2s->clk_table[CLK_I2S_RCLK_SRC];
+
+		if (rclksrc && !IS_ERR(rclksrc))
+			i2s->rclk_srcrate = clk_get_rate(rclksrc);
+
 		psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
 		writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
 		dev_dbg(&i2s->pdev->dev,
@@ -1184,11 +1193,13 @@ static void i2s_unregister_clock_provider(struct platform_device *pdev)
 
 static int i2s_register_clock_provider(struct platform_device *pdev)
 {
-	struct device *dev = &pdev->dev;
-	struct i2s_dai *i2s = dev_get_drvdata(dev);
+	const char * const i2s_clk_desc[] = { "cdclk", "rclk_src", "prescaler" };
 	const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" };
 	const char *p_names[2] = { NULL };
+	struct device *dev = &pdev->dev;
+	struct i2s_dai *i2s = dev_get_drvdata(dev);
 	const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs;
+	const char *i2s_clk_name[ARRAY_SIZE(i2s_clk_desc)];
 	struct clk *rclksrc;
 	int ret, i;
 
@@ -1205,30 +1216,38 @@ static int i2s_register_clock_provider(struct platform_device *pdev)
 		clk_put(rclksrc);
 	}
 
+	for (i = 0; i < ARRAY_SIZE(i2s_clk_desc); i++) {
+		i2s_clk_name[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%s",
+						dev_name(dev), i2s_clk_desc[i]);
+		if (!i2s_clk_name[i])
+			return -ENOMEM;
+	}
+
 	if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
 		/* Activate the prescaler */
 		u32 val = readl(i2s->addr + I2SPSR);
 		writel(val | PSR_PSREN, i2s->addr + I2SPSR);
 
 		i2s->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
-				"i2s_rclksrc", p_names, ARRAY_SIZE(p_names),
+				i2s_clk_name[CLK_I2S_RCLK_SRC], p_names,
+				ARRAY_SIZE(p_names),
 				CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
 				i2s->addr + I2SMOD, reg_info->rclksrc_off,
 				1, 0, i2s->lock);
 
 		i2s->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
-				"i2s_presc", "i2s_rclksrc",
+				i2s_clk_name[CLK_I2S_RCLK_PSR],
+				i2s_clk_name[CLK_I2S_RCLK_SRC],
 				CLK_SET_RATE_PARENT,
 				i2s->addr + I2SPSR, 8, 6, 0, i2s->lock);
 
-		p_names[0] = "i2s_presc";
+		p_names[0] = i2s_clk_name[CLK_I2S_RCLK_PSR];
 		i2s->clk_data.clk_num = 2;
 	}
-	of_property_read_string_index(dev->of_node,
-				"clock-output-names", 0, &clk_name[0]);
 
-	i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev, clk_name[0],
-				p_names[0], CLK_SET_RATE_PARENT,
+	i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev,
+				i2s_clk_name[CLK_I2S_CDCLK], p_names[0],
+				CLK_SET_RATE_PARENT,
 				i2s->addr + I2SMOD, reg_info->cdclkcon_off,
 				CLK_GATE_SET_TO_DISABLE, i2s->lock);
 
@@ -1385,9 +1404,14 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 
 	ret = i2s_register_clock_provider(pdev);
-	if (!ret)
-		return 0;
+	if (ret < 0)
+		goto err_disable_pm;
 
+	pri_dai->op_clk = clk_get_parent(pri_dai->clk_table[CLK_I2S_RCLK_SRC]);
+
+	return 0;
+
+err_disable_pm:
 	pm_runtime_disable(&pdev->dev);
 err_disable_clk:
 	clk_disable_unprepare(pri_dai->clk);
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
index 79781de..a9832a9 100644
--- a/sound/soc/samsung/i2s.h
+++ b/sound/soc/samsung/i2s.h
@@ -16,11 +16,16 @@
 #define SAMSUNG_I2S_DAI        "samsung-i2s"
 #define SAMSUNG_I2S_DAI_SEC    "samsung-i2s-sec"
 
-#define SAMSUNG_I2S_DIV_BCLK	1
+#define SAMSUNG_I2S_DIV_BCLK		1
 
-#define SAMSUNG_I2S_RCLKSRC_0	0
-#define SAMSUNG_I2S_RCLKSRC_1	1
+#define SAMSUNG_I2S_RCLKSRC_0		0
+#define SAMSUNG_I2S_RCLKSRC_1		1
 #define SAMSUNG_I2S_CDCLK		2
+/* Operation clock for IIS logic */
 #define SAMSUNG_I2S_OPCLK		3
+#define  SAMSUNG_I2S_OPCLK_CDCLK_OUT	0	/* CODEC clock out */
+#define  SAMSUNG_I2S_OPCLK_CDCLK_IN	1	/* CODEC clock in */
+#define  SAMSUNG_I2S_OPCLK_BCLK_OUT	2	/* Bit clock out */
+#define  SAMSUNG_I2S_OPCLK_PCLK		3	/* Audio bus clock */
 
 #endif /* __SND_SOC_SAMSUNG_I2S_H */
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c
index a635df6..b1f09b9 100644
--- a/sound/soc/samsung/idma.c
+++ b/sound/soc/samsung/idma.c
@@ -399,7 +399,7 @@ void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr)
 }
 EXPORT_SYMBOL_GPL(idma_reg_addr_init);
 
-static const struct snd_soc_platform_driver asoc_idma_platform = {
+static const struct snd_soc_component_driver asoc_idma_platform = {
 	.ops = &idma_ops,
 	.pcm_new = idma_new,
 	.pcm_free = idma_free,
@@ -411,7 +411,8 @@ static int asoc_idma_platform_probe(struct platform_device *pdev)
 	if (idma_irq < 0)
 		return idma_irq;
 
-	return devm_snd_soc_register_platform(&pdev->dev, &asoc_idma_platform);
+	return devm_snd_soc_register_component(&pdev->dev, &asoc_idma_platform,
+					       NULL, 0);
 }
 
 static struct platform_driver asoc_idma_driver = {
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index 7cb204e..087f8d7 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -258,13 +258,13 @@ static struct snd_soc_jack littlemill_headset;
 static int littlemill_late_probe(struct snd_soc_card *card)
 {
 	struct snd_soc_pcm_runtime *rtd;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct snd_soc_dai *aif1_dai;
 	struct snd_soc_dai *aif2_dai;
 	int ret;
 
 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-	codec = rtd->codec;
+	component = rtd->codec_dai->component;
 	aif1_dai = rtd->codec_dai;
 
 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
@@ -290,10 +290,10 @@ static int littlemill_late_probe(struct snd_soc_card *card)
 		return ret;
 
 	/* This will check device compatibility itself */
-	wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL, NULL, NULL);
+	wm8958_mic_detect(component, &littlemill_headset, NULL, NULL, NULL, NULL);
 
 	/* As will this */
-	wm8994_mic_detect(codec, &littlemill_headset, 1);
+	wm8994_mic_detect(component, &littlemill_headset, 1);
 
 	return 0;
 }
diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c
index 0d0f582..c9081f4 100644
--- a/sound/soc/samsung/lowland.c
+++ b/sound/soc/samsung/lowland.c
@@ -37,10 +37,10 @@ static struct snd_soc_jack_pin lowland_headset_pins[] = {
 
 static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	int ret;
 
-	ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_SYSCLK,
+	ret = snd_soc_component_set_sysclk(component, WM5100_CLK_SYSCLK,
 				       WM5100_CLKSRC_MCLK1, MCLK1_RATE,
 				       SND_SOC_CLOCK_IN);
 	if (ret < 0) {
@@ -49,7 +49,7 @@ static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
 	}
 
 	/* Clock OPCLK, used by the other audio components. */
-	ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_OPCLK, 0,
+	ret = snd_soc_component_set_sysclk(component, WM5100_CLK_OPCLK, 0,
 				       CLKOUT_RATE, 0);
 	if (ret < 0) {
 		pr_err("Failed to set OPCLK rate: %d\n", ret);
@@ -63,19 +63,19 @@ static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
 	if (ret)
 		return ret;
 
-	wm5100_detect(codec, &lowland_headset);
+	wm5100_detect(component, &lowland_headset);
 
 	return 0;
 }
 
 static int lowland_wm9081_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 
 	snd_soc_dapm_nc_pin(&rtd->card->dapm, "LINEOUT");
 
 	/* At any time the WM9081 is active it will have this clock */
-	return snd_soc_codec_set_sysclk(codec, WM9081_SYSCLK_MCLK, 0,
+	return snd_soc_component_set_sysclk(component, WM9081_SYSCLK_MCLK, 0,
 					CLKOUT_RATE, 0);
 }
 
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c
index 44b6de5..e7b371b 100644
--- a/sound/soc/samsung/odroid.c
+++ b/sound/soc/samsung/odroid.c
@@ -36,23 +36,24 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card);
-	unsigned int pll_freq, rclk_freq;
+	unsigned int pll_freq, rclk_freq, rfs;
 	int ret;
 
 	switch (params_rate(params)) {
-	case 32000:
 	case 64000:
-		pll_freq = 131072006U;
+		pll_freq = 196608001U;
+		rfs = 384;
 		break;
 	case 44100:
 	case 88200:
-	case 176400:
 		pll_freq = 180633609U;
+		rfs = 512;
 		break;
+	case 32000:
 	case 48000:
 	case 96000:
-	case 192000:
 		pll_freq = 196608001U;
+		rfs = 512;
 		break;
 	default:
 		return -EINVAL;
@@ -67,7 +68,7 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream,
 	 *  frequency values due to the EPLL output frequency not being exact
 	 *  multiple of the audio sampling rate.
 	 */
-	rclk_freq = params_rate(params) * 256 + 1;
+	rclk_freq = params_rate(params) * rfs + 1;
 
 	ret = clk_set_rate(priv->sclk_i2s, rclk_freq);
 	if (ret < 0)
@@ -90,18 +91,6 @@ static const struct snd_soc_ops odroid_card_ops = {
 	.hw_params = odroid_card_hw_params,
 };
 
-static void odroid_put_codec_of_nodes(struct snd_soc_dai_link *link)
-{
-	struct snd_soc_dai_link_component *component = link->codecs;
-	int i;
-
-	for (i = 0; i < link->num_codecs; i++, component++) {
-		if (!component->of_node)
-			break;
-		of_node_put(component->of_node);
-	}
-}
-
 static int odroid_audio_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -196,7 +185,7 @@ static int odroid_audio_probe(struct platform_device *pdev)
 err_put_i2s_n:
 	of_node_put(link->cpu_of_node);
 err_put_codec_n:
-	odroid_put_codec_of_nodes(link);
+	snd_soc_of_put_dai_link_codecs(link);
 	return ret;
 }
 
@@ -205,7 +194,7 @@ static int odroid_audio_remove(struct platform_device *pdev)
 	struct odroid_priv *priv = platform_get_drvdata(pdev);
 
 	of_node_put(priv->dai_link.cpu_of_node);
-	odroid_put_codec_of_nodes(&priv->dai_link);
+	snd_soc_of_put_dai_link_codecs(&priv->dai_link);
 	clk_put(priv->sclk_i2s);
 	clk_put(priv->clk_i2s_bus);
 
@@ -213,8 +202,10 @@ static int odroid_audio_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id odroid_audio_of_match[] = {
+	{ .compatible	= "hardkernel,odroid-xu3-audio" },
+	{ .compatible	= "hardkernel,odroid-xu4-audio" },
 	{ .compatible	= "samsung,odroid-xu3-audio" },
-	{ .compatible	= "samsung,odroid-xu4-audio"},
+	{ .compatible	= "samsung,odroid-xu4-audio" },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, odroid_audio_of_match);
diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c
index d8ac907..5d8efc2 100644
--- a/sound/soc/samsung/snow.c
+++ b/sound/soc/samsung/snow.c
@@ -11,97 +11,207 @@
  * General Public License for more details.
  */
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-
+#include <sound/pcm_params.h>
 #include <sound/soc.h>
 
 #include "i2s.h"
 
 #define FIN_PLL_RATE		24000000
 
-static struct snd_soc_dai_link snow_dai[] = {
-	{
-		.name = "Primary",
-		.stream_name = "Primary",
-		.codec_dai_name = "HiFi",
-		.dai_fmt = SND_SOC_DAIFMT_I2S |
-				SND_SOC_DAIFMT_NB_NF |
-				SND_SOC_DAIFMT_CBS_CFS,
-	},
+struct snow_priv {
+	struct snd_soc_dai_link dai_link;
+	struct clk *clk_i2s_bus;
+};
+
+static int snow_card_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params)
+{
+	static const unsigned int pll_rate[] = {
+		73728000U, 67737602U, 49152000U, 45158401U, 32768001U
+	};
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snow_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+	int bfs, psr, rfs, bitwidth;
+	unsigned long int rclk;
+	long int freq = -EINVAL;
+	int ret, i;
+
+	bitwidth = snd_pcm_format_width(params_format(params));
+	if (bitwidth < 0) {
+		dev_err(rtd->card->dev, "Invalid bit-width: %d\n", bitwidth);
+		return bitwidth;
+	}
+
+	if (bitwidth != 16 && bitwidth != 24) {
+		dev_err(rtd->card->dev, "Unsupported bit-width: %d\n", bitwidth);
+		return -EINVAL;
+	}
+
+	bfs = 2 * bitwidth;
+
+	switch (params_rate(params)) {
+	case 16000:
+	case 22050:
+	case 24000:
+	case 32000:
+	case 44100:
+	case 48000:
+	case 88200:
+	case 96000:
+		rfs = 8 * bfs;
+		break;
+	case 64000:
+		rfs = 384;
+		break;
+	case 8000:
+	case 11025:
+	case 12000:
+		rfs = 16 * bfs;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	rclk = params_rate(params) * rfs;
+
+	for (psr = 8; psr > 0; psr /= 2) {
+		for (i = 0; i < ARRAY_SIZE(pll_rate); i++) {
+			if ((pll_rate[i] - rclk * psr) <= 2) {
+				freq = pll_rate[i];
+				break;
+			}
+		}
+	}
+	if (freq < 0) {
+		dev_err(rtd->card->dev, "Unsupported RCLK rate: %lu\n", rclk);
+		return -EINVAL;
+	}
+
+	ret = clk_set_rate(priv->clk_i2s_bus, freq);
+	if (ret < 0) {
+		dev_err(rtd->card->dev, "I2S bus clock rate set failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops snow_card_ops = {
+	.hw_params = snow_card_hw_params,
 };
 
 static int snow_late_probe(struct snd_soc_card *card)
 {
 	struct snd_soc_pcm_runtime *rtd;
 	struct snd_soc_dai *codec_dai;
-	struct snd_soc_dai *cpu_dai;
-	int ret;
 
 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-	codec_dai = rtd->codec_dai;
-	cpu_dai = rtd->cpu_dai;
+
+	/* In the multi-codec case codec_dais 0 is MAX98095 and 1 is HDMI. */
+	if (rtd->num_codecs > 1)
+		codec_dai = rtd->codec_dais[0];
+	else
+		codec_dai = rtd->codec_dai;
 
 	/* Set the MCLK rate for the codec */
-	ret = snd_soc_dai_set_sysclk(codec_dai, 0,
-					FIN_PLL_RATE, SND_SOC_CLOCK_IN);
-	if (ret < 0)
-		return ret;
-
-	/* Select I2S Bus clock to set RCLK and BCLK */
-	ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
-					0, SND_SOC_CLOCK_IN);
-	if (ret < 0)
-		return ret;
-
-	return 0;
+	return snd_soc_dai_set_sysclk(codec_dai, 0,
+				FIN_PLL_RATE, SND_SOC_CLOCK_IN);
 }
 
 static struct snd_soc_card snow_snd = {
 	.name = "Snow-I2S",
 	.owner = THIS_MODULE,
-	.dai_link = snow_dai,
-	.num_links = ARRAY_SIZE(snow_dai),
-
 	.late_probe = snow_late_probe,
 };
 
 static int snow_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct snd_soc_card *card = &snow_snd;
-	struct device_node *i2s_node, *codec_node;
-	int i, ret;
+	struct device_node *cpu, *codec;
+	struct snd_soc_dai_link *link;
+	struct snow_priv *priv;
+	int ret;
 
-	i2s_node = of_parse_phandle(pdev->dev.of_node,
-				    "samsung,i2s-controller", 0);
-	if (!i2s_node) {
-		dev_err(&pdev->dev,
-			"Property 'i2s-controller' missing or invalid\n");
-		return -EINVAL;
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	link = &priv->dai_link;
+
+	link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS;
+
+	link->name = "Primary";
+	link->stream_name = link->name;
+
+	card->dai_link = link;
+	card->num_links = 1;
+	card->dev = dev;
+
+	/* Try new DT bindings with HDMI support first. */
+	cpu = of_get_child_by_name(dev->of_node, "cpu");
+
+	if (cpu) {
+		link->ops = &snow_card_ops;
+
+		link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
+		of_node_put(cpu);
+
+		if (!link->cpu_of_node) {
+			dev_err(dev, "Failed parsing cpu/sound-dai property\n");
+			return -EINVAL;
+		}
+
+		codec = of_get_child_by_name(dev->of_node, "codec");
+		ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
+		of_node_put(codec);
+
+		if (ret < 0) {
+			of_node_put(link->cpu_of_node);
+			dev_err(dev, "Failed parsing codec node\n");
+			return ret;
+		}
+
+		priv->clk_i2s_bus = of_clk_get_by_name(link->cpu_of_node,
+						       "i2s_opclk0");
+		if (IS_ERR(priv->clk_i2s_bus)) {
+			snd_soc_of_put_dai_link_codecs(link);
+			of_node_put(link->cpu_of_node);
+			return PTR_ERR(priv->clk_i2s_bus);
+		}
+	} else {
+		link->codec_dai_name = "HiFi",
+
+		link->cpu_of_node = of_parse_phandle(dev->of_node,
+						"samsung,i2s-controller", 0);
+		if (!link->cpu_of_node) {
+			dev_err(dev, "i2s-controller property parse error\n");
+			return -EINVAL;
+		}
+
+		link->codec_of_node = of_parse_phandle(dev->of_node,
+						"samsung,audio-codec", 0);
+		if (!link->codec_of_node) {
+			of_node_put(link->cpu_of_node);
+			dev_err(dev, "audio-codec property parse error\n");
+			return -EINVAL;
+		}
 	}
 
-	codec_node = of_parse_phandle(pdev->dev.of_node,
-				      "samsung,audio-codec", 0);
-	if (!codec_node) {
-		dev_err(&pdev->dev,
-			"Property 'audio-codec' missing or invalid\n");
-		return -EINVAL;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(snow_dai); i++) {
-		snow_dai[i].codec_of_node = codec_node;
-		snow_dai[i].cpu_of_node = i2s_node;
-		snow_dai[i].platform_of_node = i2s_node;
-	}
-
-	card->dev = &pdev->dev;
+	link->platform_of_node = link->cpu_of_node;
 
 	/* Update card-name if provided through DT, else use default name */
 	snd_soc_of_parse_card_name(card, "samsung,model");
 
-	ret = devm_snd_soc_register_card(&pdev->dev, card);
+	snd_soc_card_set_drvdata(card, priv);
+
+	ret = devm_snd_soc_register_card(dev, card);
 	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
 		return ret;
@@ -110,6 +220,20 @@ static int snow_probe(struct platform_device *pdev)
 	return ret;
 }
 
+static int snow_remove(struct platform_device *pdev)
+{
+	struct snow_priv *priv = platform_get_drvdata(pdev);
+	struct snd_soc_dai_link *link = &priv->dai_link;
+
+	of_node_put(link->cpu_of_node);
+	of_node_put(link->codec_of_node);
+	snd_soc_of_put_dai_link_codecs(link);
+
+	clk_put(priv->clk_i2s_bus);
+
+	return 0;
+}
+
 static const struct of_device_id snow_of_match[] = {
 	{ .compatible = "google,snow-audio-max98090", },
 	{ .compatible = "google,snow-audio-max98091", },
@@ -125,6 +249,7 @@ static struct platform_driver snow_driver = {
 		.of_match_table = snow_of_match,
 	},
 	.probe = snow_probe,
+	.remove = snow_remove,
 };
 
 module_platform_driver(snow_driver);
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 083ef5e..4b4147d 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -124,14 +124,14 @@ static int speyside_get_micbias(struct snd_soc_dapm_widget *source,
 	return 0;
 }
 
-static void speyside_set_polarity(struct snd_soc_codec *codec,
+static void speyside_set_polarity(struct snd_soc_component *component,
 				  int polarity)
 {
 	speyside_jack_polarity = !polarity;
 	gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
 
 	/* Re-run DAPM to make sure we're using the correct mic bias */
-	snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
+	snd_soc_dapm_sync(snd_soc_component_get_dapm(component));
 }
 
 static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd)
@@ -149,7 +149,7 @@ static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd)
 static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_dai *dai = rtd->codec_dai;
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = dai->component;
 	int ret;
 
 	ret = snd_soc_dai_set_sysclk(dai, WM8996_SYSCLK_MCLK2, 32768, 0);
@@ -168,7 +168,7 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
 	if (ret)
 		return ret;
 
-	wm8996_detect(codec, &speyside_headset, speyside_set_polarity);
+	wm8996_detect(component, &speyside_headset, speyside_set_polarity);
 
 	return 0;
 }
@@ -232,10 +232,8 @@ static struct snd_soc_dai_link speyside_dai[] = {
 
 static int speyside_wm9081_init(struct snd_soc_component *component)
 {
-	struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
-
 	/* At any time the WM9081 is active it will have this clock */
-	return snd_soc_codec_set_sysclk(codec, WM9081_SYSCLK_MCLK, 0,
+	return snd_soc_component_set_sysclk(component, WM9081_SYSCLK_MCLK, 0,
 					MCLK_AUDIO_RATE, 0);
 }
 
diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c
index a55d187..43332c3 100644
--- a/sound/soc/samsung/tm2_wm5110.c
+++ b/sound/soc/samsung/tm2_wm5110.c
@@ -31,7 +31,7 @@
 #define TM2_DAI_AIF2	1
 
 struct tm2_machine_priv {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	unsigned int sysclk_rate;
 	struct gpio_desc *gpio_mic_bias;
 };
@@ -39,33 +39,33 @@ struct tm2_machine_priv {
 static int tm2_start_sysclk(struct snd_soc_card *card)
 {
 	struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
-	struct snd_soc_codec *codec = priv->codec;
+	struct snd_soc_component *component = priv->component;
 	int ret;
 
-	ret = snd_soc_codec_set_pll(codec, WM5110_FLL1_REFCLK,
+	ret = snd_soc_component_set_pll(component, WM5110_FLL1_REFCLK,
 				    ARIZONA_FLL_SRC_MCLK1,
 				    MCLK_RATE,
 				    priv->sysclk_rate);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set FLL1 source: %d\n", ret);
+		dev_err(component->dev, "Failed to set FLL1 source: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_codec_set_pll(codec, WM5110_FLL1,
+	ret = snd_soc_component_set_pll(component, WM5110_FLL1,
 				    ARIZONA_FLL_SRC_MCLK1,
 				    MCLK_RATE,
 				    priv->sysclk_rate);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to start FLL1: %d\n", ret);
+		dev_err(component->dev, "Failed to start FLL1: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
+	ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_SYSCLK,
 				       ARIZONA_CLK_SRC_FLL1,
 				       priv->sysclk_rate,
 				       SND_SOC_CLOCK_IN);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set SYSCLK source: %d\n", ret);
+		dev_err(component->dev, "Failed to set SYSCLK source: %d\n", ret);
 		return ret;
 	}
 
@@ -75,19 +75,19 @@ static int tm2_start_sysclk(struct snd_soc_card *card)
 static int tm2_stop_sysclk(struct snd_soc_card *card)
 {
 	struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
-	struct snd_soc_codec *codec = priv->codec;
+	struct snd_soc_component *component = priv->component;
 	int ret;
 
-	ret = snd_soc_codec_set_pll(codec, WM5110_FLL1, 0, 0, 0);
+	ret = snd_soc_component_set_pll(component, WM5110_FLL1, 0, 0, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to stop FLL1: %d\n", ret);
+		dev_err(component->dev, "Failed to stop FLL1: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
+	ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_SYSCLK,
 				       ARIZONA_CLK_SRC_FLL1, 0, 0);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to stop SYSCLK: %d\n", ret);
+		dev_err(component->dev, "Failed to stop SYSCLK: %d\n", ret);
 		return ret;
 	}
 
@@ -98,7 +98,7 @@ static int tm2_aif1_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(rtd->card);
 
 	switch (params_rate(params)) {
@@ -123,7 +123,7 @@ static int tm2_aif1_hw_params(struct snd_pcm_substream *substream,
 		priv->sysclk_rate = 135475200U;
 		break;
 	default:
-		dev_err(codec->dev, "Not supported sample rate: %d\n",
+		dev_err(component->dev, "Not supported sample rate: %d\n",
 			params_rate(params));
 		return -EINVAL;
 	}
@@ -139,7 +139,7 @@ static int tm2_aif2_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	unsigned int asyncclk_rate;
 	int ret;
 
@@ -155,35 +155,35 @@ static int tm2_aif2_hw_params(struct snd_pcm_substream *substream,
 		asyncclk_rate = 45158400U;
 		break;
 	default:
-		dev_err(codec->dev, "Not supported sample rate: %d\n",
+		dev_err(component->dev, "Not supported sample rate: %d\n",
 			params_rate(params));
 		return -EINVAL;
 	}
 
-	ret = snd_soc_codec_set_pll(codec, WM5110_FLL2_REFCLK,
+	ret = snd_soc_component_set_pll(component, WM5110_FLL2_REFCLK,
 				    ARIZONA_FLL_SRC_MCLK1,
 				    MCLK_RATE,
 				    asyncclk_rate);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set FLL2 source: %d\n", ret);
+		dev_err(component->dev, "Failed to set FLL2 source: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_codec_set_pll(codec, WM5110_FLL2,
+	ret = snd_soc_component_set_pll(component, WM5110_FLL2,
 				    ARIZONA_FLL_SRC_MCLK1,
 				    MCLK_RATE,
 				    asyncclk_rate);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to start FLL2: %d\n", ret);
+		dev_err(component->dev, "Failed to start FLL2: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK,
+	ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_ASYNCCLK,
 				       ARIZONA_CLK_SRC_FLL2,
 				       asyncclk_rate,
 				       SND_SOC_CLOCK_IN);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set ASYNCCLK source: %d\n", ret);
+		dev_err(component->dev, "Failed to set ASYNCCLK source: %d\n", ret);
 		return ret;
 	}
 
@@ -193,14 +193,14 @@ static int tm2_aif2_hw_params(struct snd_pcm_substream *substream,
 static int tm2_aif2_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->codec_dai->component;
 	int ret;
 
 	/* disable FLL2 */
-	ret = snd_soc_codec_set_pll(codec, WM5110_FLL2, ARIZONA_FLL_SRC_MCLK1,
+	ret = snd_soc_component_set_pll(component, WM5110_FLL2, ARIZONA_FLL_SRC_MCLK1,
 				    0, 0);
 	if (ret < 0)
-		dev_err(codec->dev, "Failed to stop FLL2: %d\n", ret);
+		dev_err(component->dev, "Failed to stop FLL2: %d\n", ret);
 
 	return ret;
 }
@@ -210,6 +210,59 @@ static struct snd_soc_ops tm2_aif2_ops = {
 	.hw_free = tm2_aif2_hw_free,
 };
 
+static int tm2_hdmi_hw_params(struct snd_pcm_substream *substream,
+			      struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	unsigned int bfs;
+	int bitwidth, ret;
+
+	bitwidth = snd_pcm_format_width(params_format(params));
+	if (bitwidth < 0) {
+		dev_err(rtd->card->dev, "Invalid bit-width: %d\n", bitwidth);
+		return bitwidth;
+	}
+
+	switch (bitwidth) {
+	case 48:
+		bfs = 64;
+		break;
+	case 16:
+		bfs = 32;
+		break;
+	default:
+		dev_err(rtd->card->dev, "Unsupported bit-width: %d\n", bitwidth);
+		return -EINVAL;
+	}
+
+	switch (params_rate(params)) {
+	case 48000:
+	case 96000:
+	case 192000:
+		break;
+	default:
+		dev_err(rtd->card->dev, "Unsupported sample rate: %d\n",
+			params_rate(params));
+		return -EINVAL;
+	}
+
+	ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_OPCLK,
+					0, SAMSUNG_I2S_OPCLK_PCLK);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct snd_soc_ops tm2_hdmi_ops = {
+	.hw_params = tm2_hdmi_hw_params,
+};
+
 static int tm2_mic_bias(struct snd_soc_dapm_widget *w,
 				struct snd_kcontrol *kcontrol, int event)
 {
@@ -269,7 +322,7 @@ static int tm2_late_probe(struct snd_soc_card *card)
 
 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[TM2_DAI_AIF1].name);
 	aif1_dai = rtd->codec_dai;
-	priv->codec = rtd->codec;
+	priv->component = rtd->codec_dai->component;
 
 	ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0);
 	if (ret < 0) {
@@ -405,6 +458,12 @@ static struct snd_soc_dai_link tm2_dai_links[] = {
 		.dai_fmt	= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 				  SND_SOC_DAIFMT_CBM_CFM,
 		.ignore_suspend = 1,
+	}, {
+		.name		= "HDMI",
+		.stream_name	= "i2s1",
+		.ops		= &tm2_hdmi_ops,
+		.dai_fmt	= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+				  SND_SOC_DAIFMT_CBS_CFS,
 	}
 };
 
@@ -412,7 +471,6 @@ static struct snd_soc_card tm2_card = {
 	.owner			= THIS_MODULE,
 
 	.dai_link		= tm2_dai_links,
-	.num_links		= ARRAY_SIZE(tm2_dai_links),
 	.controls		= tm2_controls,
 	.num_controls		= ARRAY_SIZE(tm2_controls),
 	.dapm_widgets		= tm2_dapm_widgets,
@@ -426,11 +484,14 @@ static struct snd_soc_card tm2_card = {
 
 static int tm2_probe(struct platform_device *pdev)
 {
+	struct device_node *cpu_dai_node[2] = {};
+	struct device_node *codec_dai_node[2] = {};
+	const char *cells_name = NULL;
 	struct device *dev = &pdev->dev;
 	struct snd_soc_card *card = &tm2_card;
 	struct tm2_machine_priv *priv;
-	struct device_node *cpu_dai_node, *codec_dai_node;
-	int ret, i;
+	struct of_phandle_args args;
+	int num_codecs, ret, i;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -464,47 +525,92 @@ static int tm2_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	cpu_dai_node = of_parse_phandle(dev->of_node, "i2s-controller", 0);
-	if (!cpu_dai_node) {
-		dev_err(dev, "i2s-controllers property invalid or missing\n");
-		ret = -EINVAL;
-		goto amp_node_put;
+	num_codecs = of_count_phandle_with_args(dev->of_node, "audio-codec",
+						 NULL);
+
+	/* Skip the HDMI link if not specified in DT */
+	if (num_codecs > 1) {
+		card->num_links = ARRAY_SIZE(tm2_dai_links);
+		cells_name = "#sound-dai-cells";
+	} else {
+		card->num_links = ARRAY_SIZE(tm2_dai_links) - 1;
 	}
 
-	codec_dai_node = of_parse_phandle(dev->of_node, "audio-codec", 0);
-	if (!codec_dai_node) {
-		dev_err(dev, "audio-codec property invalid or missing\n");
-		ret = -EINVAL;
-		goto cpu_dai_node_put;
+	for (i = 0; i < num_codecs; i++) {
+		struct of_phandle_args args;
+
+		ret = of_parse_phandle_with_args(dev->of_node, "i2s-controller",
+						 cells_name, i, &args);
+		if (!args.np) {
+			dev_err(dev, "i2s-controller property parse error: %d\n", i);
+			ret = -EINVAL;
+			goto dai_node_put;
+		}
+		cpu_dai_node[i] = args.np;
+
+		codec_dai_node[i] = of_parse_phandle(dev->of_node,
+						     "audio-codec", i);
+		if (!codec_dai_node[i]) {
+			dev_err(dev, "audio-codec property parse error\n");
+			ret = -EINVAL;
+			goto dai_node_put;
+		}
 	}
 
+	/* Initialize WM5110 - I2S and HDMI - I2S1 DAI links */
 	for (i = 0; i < card->num_links; i++) {
+		unsigned int dai_index = 0; /* WM5110 */
+
 		card->dai_link[i].cpu_name = NULL;
 		card->dai_link[i].platform_name = NULL;
-		card->dai_link[i].codec_of_node = codec_dai_node;
-		card->dai_link[i].cpu_of_node = cpu_dai_node;
-		card->dai_link[i].platform_of_node = cpu_dai_node;
+
+		if (num_codecs > 1 && i == card->num_links - 1)
+			dai_index = 1; /* HDMI */
+
+		card->dai_link[i].codec_of_node = codec_dai_node[dai_index];
+		card->dai_link[i].cpu_of_node = cpu_dai_node[dai_index];
+		card->dai_link[i].platform_of_node = cpu_dai_node[dai_index];
+	}
+
+	if (num_codecs > 1) {
+		/* HDMI DAI link (I2S1) */
+		i = card->num_links - 1;
+
+		ret = of_parse_phandle_with_fixed_args(dev->of_node,
+						"audio-codec", 0, 1, &args);
+		if (ret) {
+			dev_err(dev, "audio-codec property parse error\n");
+			goto dai_node_put;
+		}
+
+		ret = snd_soc_get_dai_name(&args, &card->dai_link[i].codec_dai_name);
+		if (ret) {
+			dev_err(dev, "Unable to get codec_dai_name\n");
+			goto dai_node_put;
+		}
 	}
 
 	ret = devm_snd_soc_register_component(dev, &tm2_component,
 				tm2_ext_dai, ARRAY_SIZE(tm2_ext_dai));
 	if (ret < 0) {
 		dev_err(dev, "Failed to register component: %d\n", ret);
-		goto codec_dai_node_put;
+		goto dai_node_put;
 	}
 
 	ret = devm_snd_soc_register_card(dev, card);
 	if (ret < 0) {
 		dev_err(dev, "Failed to register card: %d\n", ret);
-		goto codec_dai_node_put;
+		goto dai_node_put;
 	}
 
-codec_dai_node_put:
-	of_node_put(codec_dai_node);
-cpu_dai_node_put:
-	of_node_put(cpu_dai_node);
-amp_node_put:
+dai_node_put:
+	for (i = 0; i < num_codecs; i++) {
+		of_node_put(codec_dai_node[i]);
+		of_node_put(cpu_dai_node[i]);
+	}
+
 	of_node_put(card->aux_dev[0].codec_of_node);
+
 	return ret;
 }
 
diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c
index 3310eda..998727c 100644
--- a/sound/soc/samsung/tobermory.c
+++ b/sound/soc/samsung/tobermory.c
@@ -179,12 +179,12 @@ static struct snd_soc_jack_pin tobermory_headset_pins[] = {
 static int tobermory_late_probe(struct snd_soc_card *card)
 {
 	struct snd_soc_pcm_runtime *rtd;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	struct snd_soc_dai *codec_dai;
 	int ret;
 
 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-	codec = rtd->codec;
+	component = rtd->codec_dai->component;
 	codec_dai = rtd->codec_dai;
 
 	ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
@@ -199,7 +199,7 @@ static int tobermory_late_probe(struct snd_soc_card *card)
 	if (ret)
 		return ret;
 
-	wm8962_mic_detect(codec, &tobermory_headset);
+	wm8962_mic_detect(component, &tobermory_headset);
 
 	return 0;
 }
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 1e7d417..2dc3b76 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -320,14 +320,15 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	return 0;
 }
 
-static const struct snd_soc_platform_driver sh7760_soc_platform = {
+static const struct snd_soc_component_driver sh7760_soc_component = {
 	.ops		= &camelot_pcm_ops,
 	.pcm_new	= camelot_pcm_new,
 };
 
 static int sh7760_soc_platform_probe(struct platform_device *pdev)
 {
-	return devm_snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform);
+	return devm_snd_soc_register_component(&pdev->dev, &sh7760_soc_component,
+					       NULL, 0);
 }
 
 static struct platform_driver sh7760_pcm_driver = {
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index c3aaf47..3bae06d 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1764,7 +1764,7 @@ static const struct snd_pcm_ops fsi_pcm_ops = {
 };
 
 /*
- *		snd_soc_platform
+ *		snd_soc_component
  */
 
 #define PREALLOC_BUFFER		(32 * 1024)
@@ -1818,13 +1818,10 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = {
 	},
 };
 
-static const struct snd_soc_platform_driver fsi_soc_platform = {
-	.ops		= &fsi_pcm_ops,
-	.pcm_new	= fsi_pcm_new,
-};
-
 static const struct snd_soc_component_driver fsi_soc_component = {
 	.name		= "fsi",
+	.ops		= &fsi_pcm_ops,
+	.pcm_new	= fsi_pcm_new,
 };
 
 /*
@@ -2007,23 +2004,15 @@ static int fsi_probe(struct platform_device *pdev)
 		goto exit_fsib;
 	}
 
-	ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "cannot snd soc register\n");
-		goto exit_fsib;
-	}
-
-	ret = snd_soc_register_component(&pdev->dev, &fsi_soc_component,
+	ret = devm_snd_soc_register_component(&pdev->dev, &fsi_soc_component,
 				    fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
 	if (ret < 0) {
 		dev_err(&pdev->dev, "cannot snd component register\n");
-		goto exit_snd_soc;
+		goto exit_fsib;
 	}
 
 	return ret;
 
-exit_snd_soc:
-	snd_soc_unregister_platform(&pdev->dev);
 exit_fsib:
 	pm_runtime_disable(&pdev->dev);
 	fsi_stream_remove(&master->fsib);
@@ -2041,9 +2030,6 @@ static int fsi_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
-	snd_soc_unregister_component(&pdev->dev);
-	snd_soc_unregister_platform(&pdev->dev);
-
 	fsi_stream_remove(&master->fsia);
 	fsi_stream_remove(&master->fsib);
 
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 64d5ecb..6a76688 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -93,6 +93,15 @@
  *  [mod]->fn() -> [mod]->fn() -> [mod]->fn()...
  *
  */
+
+/*
+ * you can enable below define if you don't need
+ * DAI status debug message when debugging
+ * see rsnd_dbg_dai_call()
+ *
+ * #define RSND_DEBUG_NO_DAI_CALL 1
+ */
+
 #include <linux/pm_runtime.h>
 #include "rsnd.h"
 
@@ -468,7 +477,7 @@ static int rsnd_status_update(u32 *status,
 						__rsnd_mod_shift_##fn,	\
 						__rsnd_mod_add_##fn,	\
 						__rsnd_mod_call_##fn);	\
-		dev_dbg(dev, "%s[%d]\t0x%08x %s\n",			\
+		rsnd_dbg_dai_call(dev, "%s[%d]\t0x%08x %s\n",		\
 			rsnd_mod_name(mod), rsnd_mod_id(mod), *status,	\
 			(func_call && (mod)->ops->fn) ? #fn : "");	\
 		if (func_call && (mod)->ops->fn)			\
@@ -1337,7 +1346,7 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
 }
 
 /*
- *		snd_soc_platform
+ *		snd_soc_component
  */
 
 #define PREALLOC_BUFFER		(32 * 1024)
@@ -1364,12 +1373,9 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
 		PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
 }
 
-static const struct snd_soc_platform_driver rsnd_soc_platform = {
+static const struct snd_soc_component_driver rsnd_soc_component = {
 	.ops		= &rsnd_pcm_ops,
 	.pcm_new	= rsnd_pcm_new,
-};
-
-static const struct snd_soc_component_driver rsnd_soc_component = {
 	.name		= "rsnd",
 };
 
@@ -1478,17 +1484,11 @@ static int rsnd_probe(struct platform_device *pdev)
 	/*
 	 *	asoc register
 	 */
-	ret = snd_soc_register_platform(dev, &rsnd_soc_platform);
-	if (ret < 0) {
-		dev_err(dev, "cannot snd soc register\n");
-		return ret;
-	}
-
-	ret = snd_soc_register_component(dev, &rsnd_soc_component,
+	ret = devm_snd_soc_register_component(dev, &rsnd_soc_component,
 					 priv->daidrv, rsnd_rdai_nr(priv));
 	if (ret < 0) {
 		dev_err(dev, "cannot snd dai register\n");
-		goto exit_snd_soc;
+		goto exit_snd_probe;
 	}
 
 	pm_runtime_enable(dev);
@@ -1496,8 +1496,6 @@ static int rsnd_probe(struct platform_device *pdev)
 	dev_info(dev, "probed\n");
 	return ret;
 
-exit_snd_soc:
-	snd_soc_unregister_platform(dev);
 exit_snd_probe:
 	for_each_rsnd_dai(rdai, priv, i) {
 		rsnd_dai_call(remove, &rdai->playback, priv);
@@ -1535,9 +1533,6 @@ static int rsnd_remove(struct platform_device *pdev)
 	for (i = 0; i < ARRAY_SIZE(remove_func); i++)
 		remove_func[i](priv);
 
-	snd_soc_unregister_component(&pdev->dev);
-	snd_soc_unregister_platform(&pdev->dev);
-
 	return ret;
 }
 
@@ -1560,8 +1555,7 @@ static int rsnd_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops rsnd_pm_ops = {
-	.suspend		= rsnd_suspend,
-	.resume			= rsnd_resume,
+	SET_SYSTEM_SLEEP_PM_OPS(rsnd_suspend, rsnd_resume)
 };
 
 static struct platform_driver rsnd_driver = {
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index ad65235..172c8d6 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -788,4 +788,24 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
 #define rsnd_mod_confirm_dvc(mdvc)
 #endif
 
+/*
+ * If you don't need interrupt status debug message,
+ * define RSND_DEBUG_NO_IRQ_STATUS as 1 on top of src.c/ssi.c
+ *
+ * #define RSND_DEBUG_NO_IRQ_STATUS 1
+ */
+#define rsnd_dbg_irq_status(dev, param...)		\
+	if (!IS_BUILTIN(RSND_DEBUG_NO_IRQ_STATUS))	\
+		dev_dbg(dev, param)
+
+/*
+ * If you don't need rsnd_dai_call debug message,
+ * define RSND_DEBUG_NO_DAI_CALL as 1 on top of core.c
+ *
+ * #define RSND_DEBUG_NO_DAI_CALL 1
+ */
+#define rsnd_dbg_dai_call(dev, param...)		\
+	if (!IS_BUILTIN(RSND_DEBUG_NO_DAI_CALL))	\
+		dev_dbg(dev, param)
+
 #endif
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 510b68a..a727e71 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -8,6 +8,15 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+/*
+ * you can enable below define if you don't need
+ * SSI interrupt status debug message when debugging
+ * see rsnd_dbg_irq_status()
+ *
+ * #define RSND_DEBUG_NO_IRQ_STATUS 1
+ */
+
 #include "rsnd.h"
 
 #define SRC_NAME "src"
@@ -325,7 +334,10 @@ static void rsnd_src_status_clear(struct rsnd_mod *mod)
 
 static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
 {
+	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+	struct device *dev = rsnd_priv_to_dev(priv);
 	u32 val0, val1;
+	u32 status0, status1;
 	bool ret = false;
 
 	val0 = val1 = OUF_SRC(rsnd_mod_id(mod));
@@ -338,9 +350,15 @@ static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
 	if (rsnd_src_sync_is_enabled(mod))
 		val0 = val0 & 0xffff;
 
-	if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val0) ||
-	    (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1))
+	status0 = rsnd_mod_read(mod, SCU_SYS_STATUS0);
+	status1 = rsnd_mod_read(mod, SCU_SYS_STATUS1);
+	if ((status0 & val0) || (status1 & val1)) {
+		rsnd_dbg_irq_status(dev, "%s[%d] err status : 0x%08x, 0x%08x\n",
+			rsnd_mod_name(mod), rsnd_mod_id(mod),
+			status0, status1);
+
 		ret = true;
+	}
 
 	return ret;
 }
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 97a9db8..333b802 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -11,6 +11,15 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+/*
+ * you can enable below define if you don't need
+ * SSI interrupt status debug message when debugging
+ * see rsnd_dbg_irq_status()
+ *
+ * #define RSND_DEBUG_NO_IRQ_STATUS 1
+ */
+
 #include <sound/simple_card_utils.h>
 #include <linux/delay.h>
 #include "rsnd.h"
@@ -603,6 +612,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 				 struct rsnd_dai_stream *io)
 {
 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+	struct device *dev = rsnd_priv_to_dev(priv);
 	int is_dma = rsnd_ssi_is_dma_mode(mod);
 	u32 status;
 	bool elapsed = false;
@@ -621,8 +631,12 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 		elapsed = rsnd_ssi_pio_interrupt(mod, io);
 
 	/* DMA only */
-	if (is_dma && (status & (UIRQ | OIRQ)))
+	if (is_dma && (status & (UIRQ | OIRQ))) {
+		rsnd_dbg_irq_status(dev, "%s[%d] err status : 0x%08x\n",
+			rsnd_mod_name(mod), rsnd_mod_id(mod), status);
+
 		stop = true;
+	}
 
 	rsnd_ssi_status_clear(mod);
 rsnd_ssi_interrupt_out:
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 83c3430..6088d62 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -183,7 +183,7 @@ static inline u32 siu_read32(u32 __iomem *addr)
 #define SIU_BRGBSEL	(0x108 / sizeof(u32))
 #define SIU_BRRB	(0x10c / sizeof(u32))
 
-extern struct snd_soc_platform_driver siu_platform;
+extern struct snd_soc_component_driver siu_component;
 extern struct siu_info *siu_i2s_data;
 
 int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index 1605029..ee22116 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -727,10 +727,6 @@ static struct snd_soc_dai_driver siu_i2s_dai = {
 	.ops = &siu_dai_ops,
 };
 
-static const struct snd_soc_component_driver siu_i2s_component = {
-	.name		= "siu-i2s",
-};
-
 static int siu_probe(struct platform_device *pdev)
 {
 	const struct firmware *fw_entry;
@@ -786,15 +782,11 @@ static int siu_probe(struct platform_device *pdev)
 	dev_set_drvdata(&pdev->dev, info);
 
 	/* register using ARRAY version so we can keep dai name */
-	ret = devm_snd_soc_register_component(&pdev->dev, &siu_i2s_component,
+	ret = devm_snd_soc_register_component(&pdev->dev, &siu_component,
 					      &siu_i2s_dai, 1);
 	if (ret < 0)
 		return ret;
 
-	ret = devm_snd_soc_register_platform(&pdev->dev, &siu_platform);
-	if (ret < 0)
-		return ret;
-
 	pm_runtime_enable(&pdev->dev);
 
 	return 0;
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index 3118cb0e..1729095 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -35,6 +35,7 @@
 
 #include "siu.h"
 
+#define DRV_NAME "siu-i2s"
 #define GET_MAX_PERIODS(buf_bytes, period_bytes) \
 				((buf_bytes) / (period_bytes))
 #define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \
@@ -340,7 +341,8 @@ static int siu_pcm_open(struct snd_pcm_substream *ss)
 {
 	/* Playback / Capture */
 	struct snd_soc_pcm_runtime *rtd = ss->private_data;
-	struct siu_platform *pdata = rtd->platform->dev->platform_data;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct siu_platform *pdata = component->dev->platform_data;
 	struct siu_info *info = siu_i2s_data;
 	struct siu_port *port_info = siu_port_info(ss);
 	struct siu_stream *siu_stream;
@@ -604,9 +606,10 @@ static const struct snd_pcm_ops siu_pcm_ops = {
 	.pointer	= siu_pcm_pointer_dma,
 };
 
-struct snd_soc_platform_driver siu_platform = {
+struct snd_soc_component_driver siu_component = {
+	.name		= DRV_NAME,
 	.ops			= &siu_pcm_ops,
 	.pcm_new	= siu_pcm_new,
 	.pcm_free	= siu_pcm_free,
 };
-EXPORT_SYMBOL_GPL(siu_platform);
+EXPORT_SYMBOL_GPL(siu_component);
diff --git a/sound/soc/sirf/sirf-usp.h b/sound/soc/sirf/sirf-usp.h
index bf0201c..e22e13a 100644
--- a/sound/soc/sirf/sirf-usp.h
+++ b/sound/soc/sirf/sirf-usp.h
@@ -154,7 +154,7 @@
 					USP_RX_IO_DMA_INT|\
 					USP_RXFIFO_FULL_INT|\
 					USP_RXFIFO_THD_INT|\
-					USP_RXFIFO_THD_INT|USP_RX_TIMEOUT_INT)
+					USP_RX_TIMEOUT_INT)
 
 #define USP_INT_ALL        0x1FFF
 
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c
index 36dae41..3f424f2 100644
--- a/sound/soc/soc-ac97.c
+++ b/sound/soc/soc-ac97.c
@@ -44,7 +44,7 @@ struct snd_ac97_gpio_priv {
 	struct gpio_chip gpio_chip;
 #endif
 	unsigned int gpios_set;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 };
 
 static struct snd_ac97_bus soc_ac97_bus = {
@@ -57,11 +57,11 @@ static void soc_ac97_device_release(struct device *dev)
 }
 
 #ifdef CONFIG_GPIOLIB
-static inline struct snd_soc_codec *gpio_to_codec(struct gpio_chip *chip)
+static inline struct snd_soc_component *gpio_to_component(struct gpio_chip *chip)
 {
 	struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
 
-	return gpio_priv->codec;
+	return gpio_priv->component;
 }
 
 static int snd_soc_ac97_gpio_request(struct gpio_chip *chip, unsigned offset)
@@ -75,20 +75,22 @@ static int snd_soc_ac97_gpio_request(struct gpio_chip *chip, unsigned offset)
 static int snd_soc_ac97_gpio_direction_in(struct gpio_chip *chip,
 					  unsigned offset)
 {
-	struct snd_soc_codec *codec = gpio_to_codec(chip);
+	struct snd_soc_component *component = gpio_to_component(chip);
 
-	dev_dbg(codec->dev, "set gpio %d to output\n", offset);
-	return snd_soc_update_bits(codec, AC97_GPIO_CFG,
+	dev_dbg(component->dev, "set gpio %d to output\n", offset);
+	return snd_soc_component_update_bits(component, AC97_GPIO_CFG,
 				   1 << offset, 1 << offset);
 }
 
 static int snd_soc_ac97_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	struct snd_soc_codec *codec = gpio_to_codec(chip);
+	struct snd_soc_component *component = gpio_to_component(chip);
 	int ret;
 
-	ret = snd_soc_read(codec, AC97_GPIO_STATUS);
-	dev_dbg(codec->dev, "get gpio %d : %d\n", offset,
+	if (snd_soc_component_read(component, AC97_GPIO_STATUS, &ret) < 0)
+		ret = -1;
+
+	dev_dbg(component->dev, "get gpio %d : %d\n", offset,
 		ret < 0 ? ret : ret & (1 << offset));
 
 	return ret < 0 ? ret : !!(ret & (1 << offset));
@@ -98,22 +100,24 @@ static void snd_soc_ac97_gpio_set(struct gpio_chip *chip, unsigned offset,
 				  int value)
 {
 	struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
-	struct snd_soc_codec *codec = gpio_to_codec(chip);
+	struct snd_soc_component *component = gpio_to_component(chip);
 
 	gpio_priv->gpios_set &= ~(1 << offset);
 	gpio_priv->gpios_set |= (!!value) << offset;
-	snd_soc_write(codec, AC97_GPIO_STATUS, gpio_priv->gpios_set);
-	dev_dbg(codec->dev, "set gpio %d to %d\n", offset, !!value);
+	snd_soc_component_write(component, AC97_GPIO_STATUS,
+				gpio_priv->gpios_set);
+	dev_dbg(component->dev, "set gpio %d to %d\n", offset, !!value);
 }
 
 static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip,
 				     unsigned offset, int value)
 {
-	struct snd_soc_codec *codec = gpio_to_codec(chip);
+	struct snd_soc_component *component = gpio_to_component(chip);
 
-	dev_dbg(codec->dev, "set gpio %d to output\n", offset);
+	dev_dbg(component->dev, "set gpio %d to output\n", offset);
 	snd_soc_ac97_gpio_set(chip, offset, value);
-	return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0);
+	return snd_soc_component_update_bits(component, AC97_GPIO_CFG,
+					     1 << offset, 0);
 }
 
 static const struct gpio_chip snd_soc_ac97_gpio_chip = {
@@ -128,24 +132,24 @@ static const struct gpio_chip snd_soc_ac97_gpio_chip = {
 };
 
 static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
-				  struct snd_soc_codec *codec)
+				  struct snd_soc_component *component)
 {
 	struct snd_ac97_gpio_priv *gpio_priv;
 	int ret;
 
-	gpio_priv = devm_kzalloc(codec->dev, sizeof(*gpio_priv), GFP_KERNEL);
+	gpio_priv = devm_kzalloc(component->dev, sizeof(*gpio_priv), GFP_KERNEL);
 	if (!gpio_priv)
 		return -ENOMEM;
 	ac97->gpio_priv = gpio_priv;
-	gpio_priv->codec = codec;
+	gpio_priv->component = component;
 	gpio_priv->gpio_chip = snd_soc_ac97_gpio_chip;
 	gpio_priv->gpio_chip.ngpio = AC97_NUM_GPIOS;
-	gpio_priv->gpio_chip.parent = codec->dev;
+	gpio_priv->gpio_chip.parent = component->dev;
 	gpio_priv->gpio_chip.base = -1;
 
 	ret = gpiochip_add_data(&gpio_priv->gpio_chip, gpio_priv);
 	if (ret != 0)
-		dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+		dev_err(component->dev, "Failed to add GPIOs: %d\n", ret);
 	return ret;
 }
 
@@ -155,7 +159,7 @@ static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
 }
 #else
 static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
-				  struct snd_soc_codec *codec)
+				  struct snd_soc_component *component)
 {
 	return 0;
 }
@@ -166,8 +170,8 @@ static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
 #endif
 
 /**
- * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device
- * @codec: The CODEC for which to create the AC'97 device
+ * snd_soc_alloc_ac97_component() - Allocate new a AC'97 device
+ * @component: The COMPONENT for which to create the AC'97 device
  *
  * Allocated a new snd_ac97 device and intializes it, but does not yet register
  * it. The caller is responsible to either call device_add(&ac97->dev) to
@@ -175,7 +179,7 @@ static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
  *
  * Returns: A snd_ac97 device or a PTR_ERR in case of an error.
  */
-struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec)
+struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component)
 {
 	struct snd_ac97 *ac97;
 
@@ -187,26 +191,26 @@ struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec)
 	ac97->num = 0;
 
 	ac97->dev.bus = &ac97_bus_type;
-	ac97->dev.parent = codec->component.card->dev;
+	ac97->dev.parent = component->card->dev;
 	ac97->dev.release = soc_ac97_device_release;
 
 	dev_set_name(&ac97->dev, "%d-%d:%s",
-		     codec->component.card->snd_card->number, 0,
-		     codec->component.name);
+		     component->card->snd_card->number, 0,
+		     component->name);
 
 	device_initialize(&ac97->dev);
 
 	return ac97;
 }
-EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);
+EXPORT_SYMBOL(snd_soc_alloc_ac97_component);
 
 /**
- * snd_soc_new_ac97_codec - initailise AC97 device
- * @codec: audio codec
+ * snd_soc_new_ac97_component - initailise AC97 device
+ * @component: audio component
  * @id: The expected device ID
  * @id_mask: Mask that is applied to the device ID before comparing with @id
  *
- * Initialises AC97 codec resources for use by ad-hoc devices only.
+ * Initialises AC97 component resources for use by ad-hoc devices only.
  *
  * If @id is not 0 this function will reset the device, then read the ID from
  * the device and check if it matches the expected ID. If it doesn't match an
@@ -214,20 +218,20 @@ EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);
  *
  * Returns: A PTR_ERR() on failure or a valid snd_ac97 struct on success.
  */
-struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
 	unsigned int id, unsigned int id_mask)
 {
 	struct snd_ac97 *ac97;
 	int ret;
 
-	ac97 = snd_soc_alloc_ac97_codec(codec);
+	ac97 = snd_soc_alloc_ac97_component(component);
 	if (IS_ERR(ac97))
 		return ac97;
 
 	if (id) {
 		ret = snd_ac97_reset(ac97, false, id, id_mask);
 		if (ret < 0) {
-			dev_err(codec->dev, "Failed to reset AC97 device: %d\n",
+			dev_err(component->dev, "Failed to reset AC97 device: %d\n",
 				ret);
 			goto err_put_device;
 		}
@@ -237,7 +241,7 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
 	if (ret)
 		goto err_put_device;
 
-	ret = snd_soc_ac97_init_gpio(ac97, codec);
+	ret = snd_soc_ac97_init_gpio(ac97, component);
 	if (ret)
 		goto err_put_device;
 
@@ -247,22 +251,22 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
 	put_device(&ac97->dev);
 	return ERR_PTR(ret);
 }
-EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
+EXPORT_SYMBOL_GPL(snd_soc_new_ac97_component);
 
 /**
- * snd_soc_free_ac97_codec - free AC97 codec device
+ * snd_soc_free_ac97_component - free AC97 component device
  * @ac97: snd_ac97 device to be freed
  *
- * Frees AC97 codec device resources.
+ * Frees AC97 component device resources.
  */
-void snd_soc_free_ac97_codec(struct snd_ac97 *ac97)
+void snd_soc_free_ac97_component(struct snd_ac97 *ac97)
 {
 	snd_soc_ac97_free_gpio(ac97);
 	device_del(&ac97->dev);
 	ac97->bus = NULL;
 	put_device(&ac97->dev);
 }
-EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
+EXPORT_SYMBOL_GPL(snd_soc_free_ac97_component);
 
 static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 96c44f6..bf7ca32a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -221,14 +221,14 @@ static const struct attribute_group soc_dapm_dev_group = {
 	.is_visible = soc_dev_attr_is_visible,
 };
 
-static const struct attribute_group soc_dev_roup = {
+static const struct attribute_group soc_dev_group = {
 	.attrs = soc_dev_attrs,
 	.is_visible = soc_dev_attr_is_visible,
 };
 
 static const struct attribute_group *soc_dev_attr_groups[] = {
 	&soc_dapm_dev_group,
-	&soc_dev_roup,
+	&soc_dev_group,
 	NULL
 };
 
@@ -349,7 +349,7 @@ static void soc_init_codec_debugfs(struct snd_soc_component *component)
 			"ASoC: Failed to create codec register debugfs file\n");
 }
 
-static int codec_list_seq_show(struct seq_file *m, void *v)
+static int codec_list_show(struct seq_file *m, void *v)
 {
 	struct snd_soc_codec *codec;
 
@@ -362,20 +362,9 @@ static int codec_list_seq_show(struct seq_file *m, void *v)
 
 	return 0;
 }
+DEFINE_SHOW_ATTRIBUTE(codec_list);
 
-static int codec_list_seq_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, codec_list_seq_show, NULL);
-}
-
-static const struct file_operations codec_list_fops = {
-	.open = codec_list_seq_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int dai_list_seq_show(struct seq_file *m, void *v)
+static int dai_list_show(struct seq_file *m, void *v)
 {
 	struct snd_soc_component *component;
 	struct snd_soc_dai *dai;
@@ -390,20 +379,9 @@ static int dai_list_seq_show(struct seq_file *m, void *v)
 
 	return 0;
 }
+DEFINE_SHOW_ATTRIBUTE(dai_list);
 
-static int dai_list_seq_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, dai_list_seq_show, NULL);
-}
-
-static const struct file_operations dai_list_fops = {
-	.open = dai_list_seq_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int platform_list_seq_show(struct seq_file *m, void *v)
+static int platform_list_show(struct seq_file *m, void *v)
 {
 	struct snd_soc_platform *platform;
 
@@ -416,18 +394,7 @@ static int platform_list_seq_show(struct seq_file *m, void *v)
 
 	return 0;
 }
-
-static int platform_list_seq_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, platform_list_seq_show, NULL);
-}
-
-static const struct file_operations platform_list_fops = {
-	.open = platform_list_seq_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(platform_list);
 
 static void soc_init_card_debugfs(struct snd_soc_card *card)
 {
@@ -1100,8 +1067,8 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 	cpu_dai_component.dai_name = dai_link->cpu_dai_name;
 	rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);
 	if (!rtd->cpu_dai) {
-		dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
-			dai_link->cpu_dai_name);
+		dev_info(card->dev, "ASoC: CPU DAI %s not registered\n",
+			 dai_link->cpu_dai_name);
 		goto _err_defer;
 	}
 	snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component);
@@ -1162,11 +1129,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 
 		rtd->platform = platform;
 	}
-	if (!rtd->platform) {
-		dev_err(card->dev, "ASoC: platform %s not registered\n",
-			dai_link->platform_name);
-		goto _err_defer;
-	}
 
 	soc_add_pcm_runtime(card, rtd);
 	return 0;
@@ -1624,22 +1586,21 @@ static int soc_probe_link_components(struct snd_soc_card *card,
 
 static int soc_probe_dai(struct snd_soc_dai *dai, int order)
 {
-	int ret;
+	if (dai->probed ||
+	    dai->driver->probe_order != order)
+		return 0;
 
-	if (!dai->probed && dai->driver->probe_order == order) {
-		if (dai->driver->probe) {
-			ret = dai->driver->probe(dai);
-			if (ret < 0) {
-				dev_err(dai->dev,
-					"ASoC: failed to probe DAI %s: %d\n",
-					dai->name, ret);
-				return ret;
-			}
+	if (dai->driver->probe) {
+		int ret = dai->driver->probe(dai);
+		if (ret < 0) {
+			dev_err(dai->dev, "ASoC: failed to probe DAI %s: %d\n",
+				dai->name, ret);
+			return ret;
 		}
-
-		dai->probed = 1;
 	}
 
+	dai->probed = 1;
+
 	return 0;
 }
 
@@ -3459,7 +3420,6 @@ int snd_soc_add_component(struct device *dev,
 err_cleanup:
 	snd_soc_component_cleanup(component);
 err_free:
-	kfree(component);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_add_component);
@@ -3471,7 +3431,7 @@ int snd_soc_register_component(struct device *dev,
 {
 	struct snd_soc_component *component;
 
-	component = kzalloc(sizeof(*component), GFP_KERNEL);
+	component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL);
 	if (!component)
 		return -ENOMEM;
 
@@ -3506,7 +3466,6 @@ static int __snd_soc_unregister_component(struct device *dev)
 
 	if (found) {
 		snd_soc_component_cleanup(component);
-		kfree(component);
 	}
 
 	return found;
@@ -4398,6 +4357,26 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
 EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
 
 /*
+ * snd_soc_of_put_dai_link_codecs - Dereference device nodes in the codecs array
+ * @dai_link: DAI link
+ *
+ * Dereference device nodes acquired by snd_soc_of_get_dai_link_codecs().
+ */
+void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link)
+{
+	struct snd_soc_dai_link_component *component = dai_link->codecs;
+	int index;
+
+	for (index = 0; index < dai_link->num_codecs; index++, component++) {
+		if (!component->of_node)
+			break;
+		of_node_put(component->of_node);
+		component->of_node = NULL;
+	}
+}
+EXPORT_SYMBOL_GPL(snd_soc_of_put_dai_link_codecs);
+
+/*
  * snd_soc_of_get_dai_link_codecs - Parse a list of CODECs in the devicetree
  * @dev: Card device
  * @of_node: Device node
@@ -4406,7 +4385,8 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
  * Builds an array of CODEC DAI components from the DAI link property
  * 'sound-dai'.
  * The array is set in the DAI link and the number of DAIs is set accordingly.
- * The device nodes in the array (of_node) must be dereferenced by the caller.
+ * The device nodes in the array (of_node) must be dereferenced by calling
+ * snd_soc_of_put_dai_link_codecs() on @dai_link.
  *
  * Returns 0 for success
  */
@@ -4454,14 +4434,7 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev,
 	}
 	return 0;
 err:
-	for (index = 0, component = dai_link->codecs;
-	     index < dai_link->num_codecs;
-	     index++, component++) {
-		if (!component->of_node)
-			break;
-		of_node_put(component->of_node);
-		component->of_node = NULL;
-	}
+	snd_soc_of_put_dai_link_codecs(dai_link);
 	dai_link->codecs = NULL;
 	dai_link->num_codecs = 0;
 	return ret;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 92894d9..2d97091 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -35,6 +35,7 @@
 #include <linux/debugfs.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -72,6 +73,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
 static int dapm_up_seq[] = {
 	[snd_soc_dapm_pre] = 0,
 	[snd_soc_dapm_regulator_supply] = 1,
+	[snd_soc_dapm_pinctrl] = 1,
 	[snd_soc_dapm_clock_supply] = 1,
 	[snd_soc_dapm_supply] = 2,
 	[snd_soc_dapm_micbias] = 3,
@@ -121,6 +123,7 @@ static int dapm_down_seq[] = {
 	[snd_soc_dapm_dai_link] = 11,
 	[snd_soc_dapm_supply] = 12,
 	[snd_soc_dapm_clock_supply] = 13,
+	[snd_soc_dapm_pinctrl] = 13,
 	[snd_soc_dapm_regulator_supply] = 13,
 	[snd_soc_dapm_post] = 14,
 };
@@ -1290,6 +1293,31 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
 EXPORT_SYMBOL_GPL(dapm_regulator_event);
 
 /*
+ * Handler for pinctrl widget.
+ */
+int dapm_pinctrl_event(struct snd_soc_dapm_widget *w,
+		       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_dapm_pinctrl_priv *priv = w->priv;
+	struct pinctrl *p = w->pinctrl;
+	struct pinctrl_state *s;
+
+	if (!p || !priv)
+		return -EIO;
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		s = pinctrl_lookup_state(p, priv->active_state);
+	else
+		s = pinctrl_lookup_state(p, priv->sleep_state);
+
+	if (IS_ERR(s))
+		return PTR_ERR(s);
+
+	return pinctrl_select_state(p, s);
+}
+EXPORT_SYMBOL_GPL(dapm_pinctrl_event);
+
+/*
  * Handler for clock supply widget.
  */
 int dapm_clock_event(struct snd_soc_dapm_widget *w,
@@ -1902,6 +1930,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
 				break;
 			case snd_soc_dapm_supply:
 			case snd_soc_dapm_regulator_supply:
+			case snd_soc_dapm_pinctrl:
 			case snd_soc_dapm_clock_supply:
 			case snd_soc_dapm_micbias:
 				if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
@@ -2315,6 +2344,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt,
 		case snd_soc_dapm_mixer_named_ctl:
 		case snd_soc_dapm_supply:
 		case snd_soc_dapm_regulator_supply:
+		case snd_soc_dapm_pinctrl:
 		case snd_soc_dapm_clock_supply:
 			if (w->name)
 				count += sprintf(buf + count, "%s: %s\n",
@@ -3165,7 +3195,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 	unsigned int invert = mc->invert;
 	unsigned int val, rval = 0;
 	int connect, rconnect = -1, change, reg_change = 0;
-	struct snd_soc_dapm_update update = { NULL };
+	struct snd_soc_dapm_update update = {};
 	int ret = 0;
 
 	val = (ucontrol->value.integer.value[0] & mask);
@@ -3292,7 +3322,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
 	unsigned int *item = ucontrol->value.enumerated.item;
 	unsigned int val, change, reg_change = 0;
 	unsigned int mask;
-	struct snd_soc_dapm_update update = { NULL };
+	struct snd_soc_dapm_update update = {};
 	int ret = 0;
 
 	if (item[0] >= e->items)
@@ -3464,6 +3494,17 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
 					 w->name, ret);
 		}
 		break;
+	case snd_soc_dapm_pinctrl:
+		w->pinctrl = devm_pinctrl_get(dapm->dev);
+		if (IS_ERR_OR_NULL(w->pinctrl)) {
+			ret = PTR_ERR(w->pinctrl);
+			if (ret == -EPROBE_DEFER)
+				return ERR_PTR(ret);
+			dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
+				w->name, ret);
+			return NULL;
+		}
+		break;
 	case snd_soc_dapm_clock_supply:
 #ifdef CONFIG_CLKDEV_LOOKUP
 		w->clk = devm_clk_get(dapm->dev, w->name);
@@ -3543,6 +3584,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
 		break;
 	case snd_soc_dapm_supply:
 	case snd_soc_dapm_regulator_supply:
+	case snd_soc_dapm_pinctrl:
 	case snd_soc_dapm_clock_supply:
 	case snd_soc_dapm_kcontrol:
 		w->is_supply = 1;
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index d537864..56a541b 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -33,13 +33,13 @@
 struct dmaengine_pcm {
 	struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
 	const struct snd_dmaengine_pcm_config *config;
-	struct snd_soc_platform platform;
+	struct snd_soc_component component;
 	unsigned int flags;
 };
 
-static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p)
+static struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
 {
-	return container_of(p, struct dmaengine_pcm, platform);
+	return container_of(p, struct dmaengine_pcm, component);
 }
 
 static struct device *dmaengine_dma_dev(struct dmaengine_pcm *pcm,
@@ -88,7 +88,9 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+	struct snd_soc_component *component =
+		snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
 	struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
 	int (*prepare_slave_config)(struct snd_pcm_substream *substream,
 			struct snd_pcm_hw_params *params,
@@ -119,7 +121,9 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream,
 static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+	struct snd_soc_component *component =
+		snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
 	struct device *dma_dev = dmaengine_dma_dev(pcm, substream);
 	struct dma_chan *chan = pcm->chan[substream->stream];
 	struct snd_dmaengine_dai_dma_data *dma_data;
@@ -128,7 +132,8 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
 	u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
 			  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
 			  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
-	int i, ret;
+	snd_pcm_format_t i;
+	int ret;
 
 	if (pcm->config && pcm->config->pcm_hardware)
 		return snd_soc_set_runtime_hwparams(substream,
@@ -178,7 +183,7 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
 		 * default assumption is that it supports 1, 2 and 4 bytes
 		 * widths.
 		 */
-		for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+		for (i = SNDRV_PCM_FORMAT_FIRST; i <= SNDRV_PCM_FORMAT_LAST; i++) {
 			int bits = snd_pcm_format_physical_width(i);
 
 			/*
@@ -206,7 +211,9 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
 static int dmaengine_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+	struct snd_soc_component *component =
+		snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
 	struct dma_chan *chan = pcm->chan[substream->stream];
 	int ret;
 
@@ -221,7 +228,9 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel(
 	struct snd_soc_pcm_runtime *rtd,
 	struct snd_pcm_substream *substream)
 {
-	struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+	struct snd_soc_component *component =
+		snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
 	struct snd_dmaengine_dai_dma_data *dma_data;
 	dma_filter_fn fn = NULL;
 
@@ -260,9 +269,11 @@ static bool dmaengine_pcm_can_report_residue(struct device *dev,
 
 static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
-	struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+	struct snd_soc_component *component =
+		snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
 	const struct snd_dmaengine_pcm_config *config = pcm->config;
-	struct device *dev = rtd->platform->dev;
+	struct device *dev = component->dev;
 	struct snd_dmaengine_dai_dma_data *dma_data;
 	struct snd_pcm_substream *substream;
 	size_t prealloc_buffer_size;
@@ -296,7 +307,7 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
 		}
 
 		if (!pcm->chan[i]) {
-			dev_err(rtd->platform->dev,
+			dev_err(component->dev,
 				"Missing dma channel for stream: %d\n", i);
 			return -EINVAL;
 		}
@@ -320,7 +331,9 @@ static snd_pcm_uframes_t dmaengine_pcm_pointer(
 	struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+	struct snd_soc_component *component =
+		snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
 
 	if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
 		return snd_dmaengine_pcm_pointer_no_residue(substream);
@@ -328,6 +341,41 @@ static snd_pcm_uframes_t dmaengine_pcm_pointer(
 		return snd_dmaengine_pcm_pointer(substream);
 }
 
+static int dmaengine_copy_user(struct snd_pcm_substream *substream,
+			       int channel, unsigned long hwoff,
+			       void *buf, unsigned long bytes)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_component *component =
+		snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
+	int (*process)(struct snd_pcm_substream *substream,
+		       int channel, unsigned long hwoff,
+		       void *buf, unsigned long bytes) = pcm->config->process;
+	bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	void *dma_ptr = runtime->dma_area + hwoff +
+			channel * (runtime->dma_bytes / runtime->channels);
+	int ret;
+
+	if (is_playback)
+		if (copy_from_user(dma_ptr, (void __user *)buf, bytes))
+			return -EFAULT;
+
+	if (process) {
+		ret = process(substream, channel, hwoff,
+			      (void __user *)buf, bytes);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (!is_playback)
+		if (copy_to_user((void __user *)buf, dma_ptr, bytes))
+			return -EFAULT;
+
+	return 0;
+}
+
 static const struct snd_pcm_ops dmaengine_pcm_ops = {
 	.open		= dmaengine_pcm_open,
 	.close		= snd_dmaengine_pcm_close,
@@ -338,14 +386,31 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = {
 	.pointer	= dmaengine_pcm_pointer,
 };
 
-static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
-	.component_driver = {
-		.probe_order = SND_SOC_COMP_ORDER_LATE,
-	},
+static const struct snd_pcm_ops dmaengine_pcm_process_ops = {
+	.open		= dmaengine_pcm_open,
+	.close		= snd_dmaengine_pcm_close,
+	.ioctl		= snd_pcm_lib_ioctl,
+	.hw_params	= dmaengine_pcm_hw_params,
+	.hw_free	= snd_pcm_lib_free_pages,
+	.trigger	= snd_dmaengine_pcm_trigger,
+	.pointer	= dmaengine_pcm_pointer,
+	.copy_user	= dmaengine_copy_user,
+};
+
+static const struct snd_soc_component_driver dmaengine_pcm_component = {
+	.name		= SND_DMAENGINE_PCM_DRV_NAME,
+	.probe_order	= SND_SOC_COMP_ORDER_LATE,
 	.ops		= &dmaengine_pcm_ops,
 	.pcm_new	= dmaengine_pcm_new,
 };
 
+static const struct snd_soc_component_driver dmaengine_pcm_component_process = {
+	.name		= SND_DMAENGINE_PCM_DRV_NAME,
+	.probe_order	= SND_SOC_COMP_ORDER_LATE,
+	.ops		= &dmaengine_pcm_process_ops,
+	.pcm_new	= dmaengine_pcm_new,
+};
+
 static const char * const dmaengine_pcm_dma_channel_names[] = {
 	[SNDRV_PCM_STREAM_PLAYBACK] = "tx",
 	[SNDRV_PCM_STREAM_CAPTURE] = "rx",
@@ -431,6 +496,9 @@ int snd_dmaengine_pcm_register(struct device *dev,
 	if (!pcm)
 		return -ENOMEM;
 
+#ifdef CONFIG_DEBUG_FS
+	pcm->component.debugfs_prefix = "dma";
+#endif
 	pcm->config = config;
 	pcm->flags = flags;
 
@@ -438,8 +506,13 @@ int snd_dmaengine_pcm_register(struct device *dev,
 	if (ret)
 		goto err_free_dma;
 
-	ret = snd_soc_add_platform(dev, &pcm->platform,
-		&dmaengine_pcm_platform);
+	if (config && config->process)
+		ret = snd_soc_add_component(dev, &pcm->component,
+					    &dmaengine_pcm_component_process,
+					    NULL, 0);
+	else
+		ret = snd_soc_add_component(dev, &pcm->component,
+					    &dmaengine_pcm_component, NULL, 0);
 	if (ret)
 		goto err_free_dma;
 
@@ -461,16 +534,16 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);
  */
 void snd_dmaengine_pcm_unregister(struct device *dev)
 {
-	struct snd_soc_platform *platform;
+	struct snd_soc_component *component;
 	struct dmaengine_pcm *pcm;
 
-	platform = snd_soc_lookup_platform(dev);
-	if (!platform)
+	component = snd_soc_lookup_component(dev, SND_DMAENGINE_PCM_DRV_NAME);
+	if (!component)
 		return;
 
-	pcm = soc_platform_to_pcm(platform);
+	pcm = soc_component_to_pcm(component);
 
-	snd_soc_remove_platform(platform);
+	snd_soc_unregister_component(dev);
 	dmaengine_pcm_release_chan(pcm);
 	kfree(pcm);
 }
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 2bc1c4c..d36a192 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -88,19 +88,16 @@ static int snd_soc_component_update_bits_legacy(
 	unsigned int old, new;
 	int ret;
 
-	if (!component->read || !component->write)
-		return -EIO;
-
 	mutex_lock(&component->io_mutex);
 
-	ret = component->read(component, reg, &old);
+	ret = snd_soc_component_read(component, reg, &old);
 	if (ret < 0)
 		goto out_unlock;
 
 	new = (old & ~mask) | (val & mask);
 	*change = old != new;
 	if (*change)
-		ret = component->write(component, reg, new);
+		ret = snd_soc_component_write(component, reg, new);
 out_unlock:
 	mutex_unlock(&component->io_mutex);
 
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 0841254..68d9dc9 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1392,12 +1392,18 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
 	struct snd_soc_pcm_runtime *be;
 	int i;
 
+	dev_dbg(card->dev, "ASoC: find BE for widget %s\n", widget->name);
+
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		list_for_each_entry(be, &card->rtd_list, list) {
 
 			if (!be->dai_link->no_pcm)
 				continue;
 
+			dev_dbg(card->dev, "ASoC: try BE : %s\n",
+				be->cpu_dai->playback_widget ?
+				be->cpu_dai->playback_widget->name : "(not set)");
+
 			if (be->cpu_dai->playback_widget == widget)
 				return be;
 
@@ -1414,6 +1420,10 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
 			if (!be->dai_link->no_pcm)
 				continue;
 
+			dev_dbg(card->dev, "ASoC: try BE %s\n",
+				be->cpu_dai->capture_widget ?
+				be->cpu_dai->capture_widget->name : "(not set)");
+
 			if (be->cpu_dai->capture_widget == widget)
 				return be;
 
@@ -1425,6 +1435,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
 		}
 	}
 
+	/* dai link name and stream name set correctly ? */
 	dev_err(card->dev, "ASoC: can't get %s BE for %s\n",
 		stream ? "capture" : "playback", widget->name);
 	return NULL;
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 01a5041..fa27d0f 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -504,6 +504,9 @@ static void remove_widget(struct snd_soc_component *comp,
 	if (dobj->ops && dobj->ops->widget_unload)
 		dobj->ops->widget_unload(comp, dobj);
 
+	if (!w->kcontrols)
+		goto free_news;
+
 	/*
 	 * Dynamic Widgets either have 1..N enum kcontrols or mixers.
 	 * The enum may either have an array of values or strings.
@@ -523,8 +526,8 @@ static void remove_widget(struct snd_soc_component *comp,
 				kfree(se->dobj.control.dtexts[j]);
 
 			kfree(se);
+			kfree(w->kcontrol_news[i].name);
 		}
-		kfree(w->kcontrol_news);
 	} else {
 		/* volume mixer or bytes controls */
 		for (i = 0; i < w->num_kcontrols; i++) {
@@ -540,9 +543,13 @@ static void remove_widget(struct snd_soc_component *comp,
 			 */
 			kfree((void *)kcontrol->private_value);
 			snd_ctl_remove(card, kcontrol);
+			kfree(w->kcontrol_news[i].name);
 		}
-		kfree(w->kcontrol_news);
 	}
+
+free_news:
+	kfree(w->kcontrol_news);
+
 	/* widget w is freed by soc-dapm.c */
 }
 
@@ -1233,7 +1240,9 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
 		dev_dbg(tplg->dev, " adding DAPM widget mixer control %s at %d\n",
 			mc->hdr.name, i);
 
-		kc[i].name = mc->hdr.name;
+		kc[i].name = kstrdup(mc->hdr.name, GFP_KERNEL);
+		if (kc[i].name == NULL)
+			goto err_str;
 		kc[i].private_value = (long)sm;
 		kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 		kc[i].access = mc->hdr.access;
@@ -1272,14 +1281,19 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
 			kfree(sm);
 			continue;
 		}
+
+		/* create any TLV data */
+		soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr);
 	}
 	return kc;
 
 err_str:
 	kfree(sm);
 err:
-	for (--i; i >= 0; i--)
+	for (--i; i >= 0; i--) {
 		kfree((void *)kc[i].private_value);
+		kfree(kc[i].name);
+	}
 	kfree(kc);
 	return NULL;
 }
@@ -1310,7 +1324,9 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
 		dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n",
 			ec->hdr.name);
 
-		kc[i].name = ec->hdr.name;
+		kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL);
+		if (kc[i].name == NULL)
+			goto err_se;
 		kc[i].private_value = (long)se;
 		kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 		kc[i].access = ec->hdr.access;
@@ -1386,6 +1402,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
 			kfree(se->dobj.control.dtexts[j]);
 
 		kfree(se);
+		kfree(kc[i].name);
 	}
 err:
 	kfree(kc);
@@ -1424,7 +1441,9 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
 			"ASoC: adding bytes kcontrol %s with access 0x%x\n",
 			be->hdr.name, be->hdr.access);
 
-		kc[i].name = be->hdr.name;
+		kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL);
+		if (kc[i].name == NULL)
+			goto err;
 		kc[i].private_value = (long)sbe;
 		kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 		kc[i].access = be->hdr.access;
@@ -1454,8 +1473,10 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
 	return kc;
 
 err:
-	for (--i; i >= 0; i--)
+	for (--i; i >= 0; i--) {
 		kfree((void *)kc[i].private_value);
+		kfree(kc[i].name);
+	}
 
 	kfree(kc);
 	return NULL;
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index bcd3da2..2d9e98b 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -284,11 +284,16 @@ static const struct snd_pcm_ops dummy_dma_ops = {
 	.ioctl		= snd_pcm_lib_ioctl,
 };
 
-static const struct snd_soc_platform_driver dummy_platform = {
+static const struct snd_soc_component_driver dummy_platform = {
 	.ops = &dummy_dma_ops,
 };
 
-static const struct snd_soc_codec_driver dummy_codec;
+static const struct snd_soc_component_driver dummy_codec = {
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
 
 #define STUB_RATES	SNDRV_PCM_RATE_8000_192000
 #define STUB_FORMATS	(SNDRV_PCM_FMTBIT_S8 | \
@@ -338,33 +343,22 @@ static int snd_soc_dummy_probe(struct platform_device *pdev)
 {
 	int ret;
 
-	ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1);
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &dummy_codec, &dummy_dai, 1);
 	if (ret < 0)
 		return ret;
 
-	ret = snd_soc_register_platform(&pdev->dev, &dummy_platform);
-	if (ret < 0) {
-		snd_soc_unregister_codec(&pdev->dev);
-		return ret;
-	}
+	ret = devm_snd_soc_register_component(&pdev->dev, &dummy_platform,
+					      NULL, 0);
 
 	return ret;
 }
 
-static int snd_soc_dummy_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_platform(&pdev->dev);
-	snd_soc_unregister_codec(&pdev->dev);
-
-	return 0;
-}
-
 static struct platform_driver soc_dummy_driver = {
 	.driver = {
 		.name = "snd-soc-dummy",
 	},
 	.probe = snd_soc_dummy_probe,
-	.remove = snd_soc_dummy_remove,
 };
 
 static struct platform_device *soc_dummy_dev;
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
index 7306e3e..db73fef 100644
--- a/sound/soc/stm/stm32_adfsdm.c
+++ b/sound/soc/stm/stm32_adfsdm.c
@@ -281,7 +281,7 @@ static void stm32_adfsdm_pcm_free(struct snd_pcm *pcm)
 	}
 }
 
-static struct snd_soc_platform_driver stm32_adfsdm_soc_platform = {
+static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
 	.ops		= &stm32_adfsdm_pcm_ops,
 	.pcm_new	= stm32_adfsdm_pcm_new,
 	.pcm_free	= stm32_adfsdm_pcm_free,
@@ -322,8 +322,9 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
 	if (IS_ERR(priv->iio_cb))
 		return PTR_ERR(priv->iio_cb);
 
-	ret = devm_snd_soc_register_platform(&pdev->dev,
-					     &stm32_adfsdm_soc_platform);
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &stm32_adfsdm_soc_platform,
+					      NULL, 0);
 	if (ret < 0)
 		dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
 			__func__);
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
index d743b7d..f226542 100644
--- a/sound/soc/stm/stm32_sai.c
+++ b/sound/soc/stm/stm32_sai.c
@@ -30,10 +30,12 @@
 
 static const struct stm32_sai_conf stm32_sai_conf_f4 = {
 	.version = SAI_STM32F4,
+	.has_spdif = false,
 };
 
 static const struct stm32_sai_conf stm32_sai_conf_h7 = {
 	.version = SAI_STM32H7,
+	.has_spdif = true,
 };
 
 static const struct of_device_id stm32_sai_ids[] = {
diff --git a/sound/soc/stm/stm32_sai.h b/sound/soc/stm/stm32_sai.h
index bb062e7..f254221 100644
--- a/sound/soc/stm/stm32_sai.h
+++ b/sound/soc/stm/stm32_sai.h
@@ -248,9 +248,11 @@ enum stm32_sai_version {
 /**
  * struct stm32_sai_conf - SAI configuration
  * @version: SAI version
+ * @has_spdif: SAI S/PDIF support flag
  */
 struct stm32_sai_conf {
 	int version;
+	bool has_spdif;
 };
 
 /**
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 08583b9..cfeb219 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -23,6 +23,7 @@
 #include <linux/of_platform.h>
 #include <linux/regmap.h>
 
+#include <sound/asoundef.h>
 #include <sound/core.h>
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm_params.h>
@@ -30,6 +31,7 @@
 #include "stm32_sai.h"
 
 #define SAI_FREE_PROTOCOL	0x0
+#define SAI_SPDIF_PROTOCOL	0x1
 
 #define SAI_SLOT_SIZE_AUTO	0x0
 #define SAI_SLOT_SIZE_16	0x1
@@ -59,8 +61,13 @@
 #define SAI_SYNC_INTERNAL	0x1
 #define SAI_SYNC_EXTERNAL	0x2
 
+#define STM_SAI_PROTOCOL_IS_SPDIF(ip)	((ip)->spdif)
+#define STM_SAI_HAS_SPDIF(x)	((x)->pdata->conf->has_spdif)
 #define STM_SAI_HAS_EXT_SYNC(x) (!STM_SAI_IS_F4(sai->pdata))
 
+#define SAI_IEC60958_BLOCK_FRAMES	192
+#define SAI_IEC60958_STATUS_BYTES	24
+
 /**
  * struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
  * @pdev: device data pointer
@@ -78,6 +85,7 @@
  * @id: SAI sub block id corresponding to sub-block A or B
  * @dir: SAI block direction (playback or capture). set at init
  * @master: SAI block mode flag. (true=master, false=slave) set at init
+ * @spdif: SAI S/PDIF iec60958 mode flag. set at init
  * @fmt: SAI block format. relevant only for custom protocols. set at init
  * @sync: SAI block synchronization mode. (none, internal or external)
  * @synco: SAI block ext sync source (provider setting). (none, sub-block A/B)
@@ -87,6 +95,8 @@
  * @slot_width: rx or tx slot width in bits
  * @slot_mask: rx or tx active slots mask. set at init or at runtime
  * @data_size: PCM data width. corresponds to PCM substream width.
+ * @spdif_frm_cnt: S/PDIF playback frame counter
+ * @spdif_status_bits: S/PDIF status bits
  */
 struct stm32_sai_sub_data {
 	struct platform_device *pdev;
@@ -104,6 +114,7 @@ struct stm32_sai_sub_data {
 	unsigned int id;
 	int dir;
 	bool master;
+	bool spdif;
 	int fmt;
 	int sync;
 	int synco;
@@ -113,6 +124,8 @@ struct stm32_sai_sub_data {
 	int slot_width;
 	int slot_mask;
 	int data_size;
+	unsigned int spdif_frm_cnt;
+	unsigned char spdif_status_bits[SAI_IEC60958_STATUS_BYTES];
 };
 
 enum stm32_sai_fifo_th {
@@ -171,6 +184,10 @@ static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg)
 	}
 }
 
+static const unsigned char default_status_bits[SAI_IEC60958_STATUS_BYTES] = {
+	0, 0, 0, IEC958_AES3_CON_FS_48000,
+};
+
 static const struct regmap_config stm32_sai_sub_regmap_config_f4 = {
 	.reg_bits = 32,
 	.reg_stride = 4,
@@ -277,6 +294,11 @@ static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
 	struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
 	int slotr, slotr_mask, slot_size;
 
+	if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+		dev_warn(cpu_dai->dev, "Slot setting relevant only for TDM\n");
+		return 0;
+	}
+
 	dev_dbg(cpu_dai->dev, "Masks tx/rx:%#x/%#x, slots:%d, width:%d\n",
 		tx_mask, rx_mask, slots, slot_width);
 
@@ -326,8 +348,17 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 
 	dev_dbg(cpu_dai->dev, "fmt %x\n", fmt);
 
-	cr1_mask = SAI_XCR1_PRTCFG_MASK;
-	cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
+	/* Do not generate master by default */
+	cr1 = SAI_XCR1_NODIV;
+	cr1_mask = SAI_XCR1_NODIV;
+
+	cr1_mask |= SAI_XCR1_PRTCFG_MASK;
+	if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+		cr1 |= SAI_XCR1_PRTCFG_SET(SAI_SPDIF_PROTOCOL);
+		goto conf_update;
+	}
+
+	cr1 |= SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	/* SCK active high for all protocols */
@@ -409,10 +440,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 
 	cr1_mask |= SAI_XCR1_SLAVE;
 
-	/* do not generate master by default */
-	cr1 |= SAI_XCR1_NODIV;
-	cr1_mask |= SAI_XCR1_NODIV;
-
+conf_update:
 	ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
 	if (ret < 0) {
 		dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
@@ -478,6 +506,12 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
 			   SAI_XCR2_FFLUSH |
 			   SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
 
+	/* DS bits in CR1 not set for SPDIF (size forced to 24 bits).*/
+	if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+		sai->spdif_frm_cnt = 0;
+		return 0;
+	}
+
 	/* Mode, data format and channel config */
 	cr1_mask = SAI_XCR1_DS_MASK;
 	switch (params_format(params)) {
@@ -592,13 +626,14 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
 	int cr1, mask, div = 0;
 	int sai_clk_rate, mclk_ratio, den, ret;
 	int version = sai->pdata->conf->version;
+	unsigned int rate = params_rate(params);
 
 	if (!sai->mclk_rate) {
 		dev_err(cpu_dai->dev, "Mclk rate is null\n");
 		return -EINVAL;
 	}
 
-	if (!(params_rate(params) % 11025))
+	if (!(rate % 11025))
 		clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k);
 	else
 		clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k);
@@ -623,24 +658,28 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
 		 *      MCKDIV = sai_ck / (frl x ws)	(NOMCK=1)
 		 * Note: NOMCK/NODIV correspond to same bit.
 		 */
-		if (sai->mclk_rate) {
-			mclk_ratio = sai->mclk_rate / params_rate(params);
-			if (mclk_ratio != 256) {
+		if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+			div = DIV_ROUND_CLOSEST(sai_clk_rate,
+						(params_rate(params) * 128));
+		} else {
+			if (sai->mclk_rate) {
+				mclk_ratio = sai->mclk_rate / rate;
 				if (mclk_ratio == 512) {
 					mask = SAI_XCR1_OSR;
 					cr1 = SAI_XCR1_OSR;
-				} else {
+				} else if (mclk_ratio != 256) {
 					dev_err(cpu_dai->dev,
 						"Wrong mclk ratio %d\n",
 						mclk_ratio);
 					return -EINVAL;
 				}
+				div = DIV_ROUND_CLOSEST(sai_clk_rate,
+							sai->mclk_rate);
+			} else {
+				/* mclk-fs not set, master clock not active */
+				den = sai->fs_length * params_rate(params);
+				div = DIV_ROUND_CLOSEST(sai_clk_rate, den);
 			}
-			div = DIV_ROUND_CLOSEST(sai_clk_rate, sai->mclk_rate);
-		} else {
-			/* mclk-fs not set, master clock not active. NOMCK=1 */
-			den = sai->fs_length * params_rate(params);
-			div = DIV_ROUND_CLOSEST(sai_clk_rate, den);
 		}
 	}
 
@@ -670,10 +709,12 @@ static int stm32_sai_hw_params(struct snd_pcm_substream *substream,
 
 	sai->data_size = params_width(params);
 
-	ret = stm32_sai_set_slots(cpu_dai);
-	if (ret < 0)
-		return ret;
-	stm32_sai_set_frame(cpu_dai);
+	if (!STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+		ret = stm32_sai_set_slots(cpu_dai);
+		if (ret < 0)
+			return ret;
+		stm32_sai_set_frame(cpu_dai);
+	}
 
 	ret = stm32_sai_set_config(cpu_dai, substream, params);
 	if (ret)
@@ -723,6 +764,9 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 					 (unsigned int)~SAI_XCR1_DMAEN);
 		if (ret < 0)
 			dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
+
+		if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
+			sai->spdif_frm_cnt = 0;
 		break;
 	default:
 		return -EINVAL;
@@ -776,6 +820,10 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
 				     sai->synco, sai->synci);
 	}
 
+	if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
+		memcpy(sai->spdif_status_bits, default_status_bits,
+		       sizeof(default_status_bits));
+
 	cr1_mask |= SAI_XCR1_SYNCEN_MASK;
 	cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync);
 
@@ -792,6 +840,42 @@ static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
 	.shutdown	= stm32_sai_shutdown,
 };
 
+static int stm32_sai_pcm_process_spdif(struct snd_pcm_substream *substream,
+				       int channel, unsigned long hwoff,
+				       void *buf, unsigned long bytes)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
+	int *ptr = (int *)(runtime->dma_area + hwoff +
+			   channel * (runtime->dma_bytes / runtime->channels));
+	ssize_t cnt = bytes_to_samples(runtime, bytes);
+	unsigned int frm_cnt = sai->spdif_frm_cnt;
+	unsigned int byte;
+	unsigned int mask;
+
+	do {
+		*ptr = ((*ptr >> 8) & 0x00ffffff);
+
+		/* Set channel status bit */
+		byte = frm_cnt >> 3;
+		mask = 1 << (frm_cnt - (byte << 3));
+		if (sai->spdif_status_bits[byte] & mask)
+			*ptr |= 0x04000000;
+		ptr++;
+
+		if (!(cnt % 2))
+			frm_cnt++;
+
+		if (frm_cnt == SAI_IEC60958_BLOCK_FRAMES)
+			frm_cnt = 0;
+	} while (--cnt);
+	sai->spdif_frm_cnt = frm_cnt;
+
+	return 0;
+}
+
 static const struct snd_pcm_hardware stm32_sai_pcm_hw = {
 	.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,
 	.buffer_bytes_max = 8 * PAGE_SIZE,
@@ -842,8 +926,14 @@ static struct snd_soc_dai_driver stm32_sai_capture_dai[] = {
 };
 
 static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config = {
-	.pcm_hardware	= &stm32_sai_pcm_hw,
-	.prepare_slave_config	= snd_dmaengine_pcm_prepare_slave_config,
+	.pcm_hardware = &stm32_sai_pcm_hw,
+	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+};
+
+static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config_spdif = {
+	.pcm_hardware = &stm32_sai_pcm_hw,
+	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+	.process = stm32_sai_pcm_process_spdif,
 };
 
 static const struct snd_soc_component_driver stm32_component = {
@@ -900,6 +990,18 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
+	/* Get spdif iec60958 property */
+	sai->spdif = false;
+	if (of_get_property(np, "st,iec60958", NULL)) {
+		if (!STM_SAI_HAS_SPDIF(sai) ||
+		    sai->dir == SNDRV_PCM_STREAM_CAPTURE) {
+			dev_err(&pdev->dev, "S/PDIF IEC60958 not supported\n");
+			return -EINVAL;
+		}
+		sai->spdif = true;
+		sai->master = true;
+	}
+
 	/* Get synchronization property */
 	args.np = NULL;
 	ret = of_parse_phandle_with_fixed_args(np, "st,sync", 1, 0, &args);
@@ -999,6 +1101,7 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
 {
 	struct stm32_sai_sub_data *sai;
 	const struct of_device_id *of_id;
+	const struct snd_dmaengine_pcm_config *conf = &stm32_sai_pcm_config;
 	int ret;
 
 	sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
@@ -1039,8 +1142,10 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
-					      &stm32_sai_pcm_config, 0);
+	if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
+		conf = &stm32_sai_pcm_config_spdif;
+
+	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, conf, 0);
 	if (ret) {
 		dev_err(&pdev->dev, "Could not register pcm dma\n");
 		return ret;
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
index b9bdefc..373df4f 100644
--- a/sound/soc/stm/stm32_spdifrx.c
+++ b/sound/soc/stm/stm32_spdifrx.c
@@ -819,7 +819,6 @@ static const struct snd_soc_dai_ops stm32_spdifrx_pcm_dai_ops = {
 
 static struct snd_soc_dai_driver stm32_spdifrx_dai[] = {
 	{
-		.name = "spdifrx-capture-cpu-dai",
 		.probe = stm32_spdifrx_dai_probe,
 		.capture = {
 			.stream_name = "CPU-Capture",
@@ -858,8 +857,8 @@ static const struct of_device_id stm32_spdifrx_ids[] = {
 	{}
 };
 
-static int stm_spdifrx_parse_of(struct platform_device *pdev,
-				struct stm32_spdifrx_data *spdifrx)
+static int stm32_spdifrx_parse_of(struct platform_device *pdev,
+				  struct stm32_spdifrx_data *spdifrx)
 {
 	struct device_node *np = pdev->dev.of_node;
 	const struct of_device_id *of_id;
@@ -914,7 +913,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, spdifrx);
 
-	ret = stm_spdifrx_parse_of(pdev, spdifrx);
+	ret = stm32_spdifrx_parse_of(pdev, spdifrx);
 	if (ret)
 		return ret;
 
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 8862816..9a3cb77 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -792,15 +792,17 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
 	{ "Mic1", NULL, "VMIC" },
 };
 
-static const struct snd_soc_codec_driver sun4i_codec_codec = {
-	.component_driver = {
-		.controls		= sun4i_codec_controls,
-		.num_controls		= ARRAY_SIZE(sun4i_codec_controls),
-		.dapm_widgets		= sun4i_codec_codec_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
-		.dapm_routes		= sun4i_codec_codec_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
-	},
+static const struct snd_soc_component_driver sun4i_codec_codec = {
+	.controls		= sun4i_codec_controls,
+	.num_controls		= ARRAY_SIZE(sun4i_codec_controls),
+	.dapm_widgets		= sun4i_codec_codec_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
+	.dapm_routes		= sun4i_codec_codec_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /*** sun6i Codec ***/
@@ -1098,15 +1100,17 @@ static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
 	{ "Right ADC", NULL, "Right ADC Mixer" },
 };
 
-static const struct snd_soc_codec_driver sun6i_codec_codec = {
-	.component_driver = {
-		.controls		= sun6i_codec_codec_widgets,
-		.num_controls		= ARRAY_SIZE(sun6i_codec_codec_widgets),
-		.dapm_widgets		= sun6i_codec_codec_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
-		.dapm_routes		= sun6i_codec_codec_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
-	},
+static const struct snd_soc_component_driver sun6i_codec_codec = {
+	.controls		= sun6i_codec_codec_widgets,
+	.num_controls		= ARRAY_SIZE(sun6i_codec_codec_widgets),
+	.dapm_widgets		= sun6i_codec_codec_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
+	.dapm_routes		= sun6i_codec_codec_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 /* sun8i A23 codec */
@@ -1126,13 +1130,15 @@ static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = {
 
 };
 
-static const struct snd_soc_codec_driver sun8i_a23_codec_codec = {
-	.component_driver = {
-		.controls		= sun8i_a23_codec_codec_controls,
-		.num_controls		= ARRAY_SIZE(sun8i_a23_codec_codec_controls),
-		.dapm_widgets		= sun8i_a23_codec_codec_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
-	},
+static const struct snd_soc_component_driver sun8i_a23_codec_codec = {
+	.controls		= sun8i_a23_codec_codec_controls,
+	.num_controls		= ARRAY_SIZE(sun8i_a23_codec_codec_controls),
+	.dapm_widgets		= sun8i_a23_codec_codec_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct snd_soc_component_driver sun4i_codec_component = {
@@ -1450,7 +1456,7 @@ static const struct regmap_config sun8i_v3s_codec_regmap_config = {
 
 struct sun4i_codec_quirks {
 	const struct regmap_config *regmap_config;
-	const struct snd_soc_codec_driver *codec;
+	const struct snd_soc_component_driver *codec;
 	struct snd_soc_card * (*create_card)(struct device *dev);
 	struct reg_field reg_adc_fifoc;	/* used for regmap_field */
 	unsigned int reg_dac_txdata;	/* TX FIFO offset for DMA config */
@@ -1657,7 +1663,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	scodec->capture_dma_data.maxburst = 8;
 	scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 
-	ret = snd_soc_register_codec(&pdev->dev, quirks->codec,
+	ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec,
 				     &sun4i_codec_dai, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register our codec\n");
@@ -1669,20 +1675,20 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 					      &dummy_cpu_dai, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register our DAI\n");
-		goto err_unregister_codec;
+		goto err_assert_reset;
 	}
 
 	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
-		goto err_unregister_codec;
+		goto err_assert_reset;
 	}
 
 	card = quirks->create_card(&pdev->dev);
 	if (IS_ERR(card)) {
 		ret = PTR_ERR(card);
 		dev_err(&pdev->dev, "Failed to create our card\n");
-		goto err_unregister_codec;
+		goto err_assert_reset;
 	}
 
 	snd_soc_card_set_drvdata(card, scodec);
@@ -1690,13 +1696,11 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	ret = snd_soc_register_card(card);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register our card\n");
-		goto err_unregister_codec;
+		goto err_assert_reset;
 	}
 
 	return 0;
 
-err_unregister_codec:
-	snd_soc_unregister_codec(&pdev->dev);
 err_assert_reset:
 	if (scodec->rst)
 		reset_control_assert(scodec->rst);
@@ -1711,7 +1715,6 @@ static int sun4i_codec_remove(struct platform_device *pdev)
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
 
 	snd_soc_unregister_card(card);
-	snd_soc_unregister_codec(&pdev->dev);
 	if (scodec->rst)
 		reset_control_assert(scodec->rst);
 	clk_disable_unprepare(scodec->clk_apb);
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 7a15df9..fb37dd9 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -184,7 +184,7 @@ static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
 
 static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
+	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(dai->component);
 	u32 value;
 
 	/* clock masters */
@@ -304,7 +304,7 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
 				 struct snd_soc_dai *dai)
 {
-	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
+	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(dai->component);
 	int sample_rate;
 	u8 bclk_div;
 
@@ -500,13 +500,15 @@ static struct snd_soc_dai_driver sun8i_codec_dai = {
 	.ops = &sun8i_codec_dai_ops,
 };
 
-static const struct snd_soc_codec_driver sun8i_soc_codec = {
-	.component_driver = {
-		.dapm_widgets		= sun8i_codec_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
-		.dapm_routes		= sun8i_codec_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
-	},
+static const struct snd_soc_component_driver sun8i_soc_component = {
+	.dapm_widgets		= sun8i_codec_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
+	.dapm_routes		= sun8i_codec_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static const struct regmap_config sun8i_codec_regmap_config = {
@@ -566,7 +568,7 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 			goto err_pm_disable;
 	}
 
-	ret = snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec,
+	ret = devm_snd_soc_register_component(&pdev->dev, &sun8i_soc_component,
 				     &sun8i_codec_dai, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register codec\n");
@@ -594,7 +596,6 @@ static int sun8i_codec_remove(struct platform_device *pdev)
 	if (!pm_runtime_status_suspended(&pdev->dev))
 		sun8i_codec_runtime_suspend(&pdev->dev);
 
-	snd_soc_unregister_codec(&pdev->dev);
 	clk_disable_unprepare(scodec->clk_module);
 	clk_disable_unprepare(scodec->clk_bus);
 
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 18bdae5..69bc946 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -170,7 +170,7 @@ static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
 static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 	struct snd_soc_card *card = rtd->card;
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
 
@@ -189,7 +189,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 			      &tegra_wm8903_mic_jack,
 			      tegra_wm8903_mic_jack_pins,
 			      ARRAY_SIZE(tegra_wm8903_mic_jack_pins));
-	wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
+	wm8903_mic_detect(component, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
 				0);
 
 	snd_soc_dapm_force_enable_pin(&card->dapm, "MICBIAS");
@@ -202,9 +202,9 @@ static int tegra_wm8903_remove(struct snd_soc_card *card)
 	struct snd_soc_pcm_runtime *rtd =
 		snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_component *component = codec_dai->component;
 
-	wm8903_mic_detect(codec, NULL, 0, 0);
+	wm8903_mic_detect(component, NULL, 0, 0);
 
 	return 0;
 }
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index a2bb68f..8d31fe6 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -23,6 +23,8 @@
 #include <sound/soc.h>
 #include "txx9aclc.h"
 
+#define DRV_NAME "txx9aclc"
+
 static struct txx9aclc_soc_device {
 	struct txx9aclc_dmadata dmadata[2];
 } txx9aclc_soc_device;
@@ -53,6 +55,7 @@ static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 	struct txx9aclc_dmadata *dmadata = runtime->private_data;
 	int ret;
 
@@ -60,13 +63,13 @@ static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream,
 	if (ret < 0)
 		return ret;
 
-	dev_dbg(rtd->platform->dev,
+	dev_dbg(component->dev,
 		"runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd "
 		"runtime->min_align %ld\n",
 		(unsigned long)runtime->dma_area,
 		(unsigned long)runtime->dma_addr, runtime->dma_bytes,
 		runtime->min_align);
-	dev_dbg(rtd->platform->dev,
+	dev_dbg(component->dev,
 		"periods %d period_bytes %d stream %d\n",
 		params_periods(params), params_period_bytes(params),
 		substream->stream);
@@ -287,7 +290,8 @@ static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	struct snd_card *card = rtd->card->snd_card;
 	struct snd_soc_dai *dai = rtd->cpu_dai;
 	struct snd_pcm *pcm = rtd->pcm;
-	struct platform_device *pdev = to_platform_device(rtd->platform->dev);
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+	struct platform_device *pdev = to_platform_device(component->dev);
 	struct txx9aclc_soc_device *dev;
 	struct resource *r;
 	int i;
@@ -371,15 +375,15 @@ static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
 	return 0;
 }
 
-static int txx9aclc_pcm_probe(struct snd_soc_platform *platform)
+static int txx9aclc_pcm_probe(struct snd_soc_component *component)
 {
-	snd_soc_platform_set_drvdata(platform, &txx9aclc_soc_device);
+	snd_soc_component_set_drvdata(component, &txx9aclc_soc_device);
 	return 0;
 }
 
-static int txx9aclc_pcm_remove(struct snd_soc_platform *platform)
+static void txx9aclc_pcm_remove(struct snd_soc_component *component)
 {
-	struct txx9aclc_soc_device *dev = snd_soc_platform_get_drvdata(platform);
+	struct txx9aclc_soc_device *dev = snd_soc_component_get_drvdata(component);
 	struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
 	void __iomem *base = drvdata->base;
 	int i;
@@ -400,10 +404,10 @@ static int txx9aclc_pcm_remove(struct snd_soc_platform *platform)
 		}
 		dev->dmadata[i].dma_chan = NULL;
 	}
-	return 0;
 }
 
-static const struct snd_soc_platform_driver txx9aclc_soc_platform = {
+static const struct snd_soc_component_driver txx9aclc_soc_component = {
+	.name		= DRV_NAME,
 	.probe		= txx9aclc_pcm_probe,
 	.remove		= txx9aclc_pcm_remove,
 	.ops		= &txx9aclc_pcm_ops,
@@ -412,8 +416,8 @@ static const struct snd_soc_platform_driver txx9aclc_soc_platform = {
 
 static int txx9aclc_soc_platform_probe(struct platform_device *pdev)
 {
-	return devm_snd_soc_register_platform(&pdev->dev,
-					      &txx9aclc_soc_platform);
+	return devm_snd_soc_register_component(&pdev->dev,
+					&txx9aclc_soc_component, NULL, 0);
 }
 
 static struct platform_driver txx9aclc_pcm_driver = {
diff --git a/sound/soc/uniphier/Kconfig b/sound/soc/uniphier/Kconfig
index 02886a4..aa3592e 100644
--- a/sound/soc/uniphier/Kconfig
+++ b/sound/soc/uniphier/Kconfig
@@ -8,6 +8,39 @@
 	  audio interfaces to support below.
 	  If unsure select "N".
 
+config SND_SOC_UNIPHIER_AIO
+	tristate "UniPhier AIO DAI Driver"
+	select REGMAP_MMIO
+	select SND_SOC_COMPRESS
+	depends on SND_SOC_UNIPHIER
+	help
+	  This adds ASoC driver support for Socionext UniPhier
+	  'AIO' Audio Input/Output subsystem.
+	  Select Y if you use such device.
+	  If unsure select "N".
+
+config SND_SOC_UNIPHIER_LD11
+	tristate "UniPhier LD11/LD20 Device Driver"
+	depends on SND_SOC_UNIPHIER
+	select SND_SOC_UNIPHIER_AIO
+	select SND_SOC_UNIPHIER_AIO_DMA
+	help
+	  This adds ASoC driver for Socionext UniPhier LD11/LD20
+	  input and output that can be used with other codecs.
+	  Select Y if you use such device.
+	  If unsure select "N".
+
+config SND_SOC_UNIPHIER_PXS2
+	tristate "UniPhier PXs2 Device Driver"
+	depends on SND_SOC_UNIPHIER
+	select SND_SOC_UNIPHIER_AIO
+	select SND_SOC_UNIPHIER_AIO_DMA
+	help
+	  This adds ASoC driver for Socionext UniPhier PXs2
+	  input and output that can be used with other codecs.
+	  Select Y if you use such device.
+	  If unsure select "N".
+
 config SND_SOC_UNIPHIER_EVEA_CODEC
 	tristate "UniPhier SoC internal audio codec"
 	depends on SND_SOC_UNIPHIER
diff --git a/sound/soc/uniphier/Makefile b/sound/soc/uniphier/Makefile
index 3be00d7..8816939 100644
--- a/sound/soc/uniphier/Makefile
+++ b/sound/soc/uniphier/Makefile
@@ -1,3 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0
+snd-soc-uniphier-aio-cpu-objs := aio-core.o aio-dma.o aio-cpu.o aio-compress.o
+snd-soc-uniphier-aio-ld11-objs := aio-ld11.o
+snd-soc-uniphier-aio-pxs2-objs := aio-pxs2.o
+
+obj-$(CONFIG_SND_SOC_UNIPHIER_AIO) += snd-soc-uniphier-aio-cpu.o
+obj-$(CONFIG_SND_SOC_UNIPHIER_LD11) += snd-soc-uniphier-aio-ld11.o
+obj-$(CONFIG_SND_SOC_UNIPHIER_PXS2) += snd-soc-uniphier-aio-pxs2.o
+
 snd-soc-uniphier-evea-objs := evea.o
 obj-$(CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC) += snd-soc-uniphier-evea.o
diff --git a/sound/soc/uniphier/aio-compress.c b/sound/soc/uniphier/aio-compress.c
new file mode 100644
index 0000000..4c1027a
--- /dev/null
+++ b/sound/soc/uniphier/aio-compress.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO Compress Audio driver.
+//
+// Copyright (c) 2017-2018 Socionext 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; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+#include <linux/bitfield.h>
+#include <linux/circ_buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "aio.h"
+
+static int uniphier_aio_compr_prepare(struct snd_compr_stream *cstream);
+static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream);
+
+static int uniphier_aio_comprdma_new(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_compr *compr = rtd->compr;
+	struct device *dev = compr->card->dev;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
+	size_t size = AUD_RING_SIZE;
+	int dma_dir = DMA_FROM_DEVICE, ret;
+
+	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));
+	if (ret)
+		return ret;
+
+	sub->compr_area = kzalloc(size, GFP_KERNEL);
+	if (!sub->compr_area)
+		return -ENOMEM;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT)
+		dma_dir = DMA_TO_DEVICE;
+
+	sub->compr_addr = dma_map_single(dev, sub->compr_area, size, dma_dir);
+	if (dma_mapping_error(dev, sub->compr_addr)) {
+		kfree(sub->compr_area);
+		sub->compr_area = NULL;
+
+		return -ENOMEM;
+	}
+
+	sub->compr_bytes = size;
+
+	return 0;
+}
+
+static int uniphier_aio_comprdma_free(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_compr *compr = rtd->compr;
+	struct device *dev = compr->card->dev;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
+	int dma_dir = DMA_FROM_DEVICE;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT)
+		dma_dir = DMA_TO_DEVICE;
+
+	dma_unmap_single(dev, sub->compr_addr, sub->compr_bytes, dma_dir);
+	kfree(sub->compr_area);
+	sub->compr_area = NULL;
+
+	return 0;
+}
+
+static int uniphier_aio_compr_open(struct snd_compr_stream *cstream)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+	int ret;
+
+	if (sub->cstream)
+		return -EBUSY;
+
+	sub->cstream = cstream;
+	sub->pass_through = 1;
+	sub->use_mmap = false;
+
+	ret = uniphier_aio_comprdma_new(rtd);
+	if (ret)
+		return ret;
+
+	ret = aio_init(sub);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int uniphier_aio_compr_free(struct snd_compr_stream *cstream)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+	int ret;
+
+	ret = uniphier_aio_compr_hw_free(cstream);
+	if (ret)
+		return ret;
+	ret = uniphier_aio_comprdma_free(rtd);
+	if (ret)
+		return ret;
+
+	sub->cstream = NULL;
+
+	return 0;
+}
+
+static int uniphier_aio_compr_get_params(struct snd_compr_stream *cstream,
+					 struct snd_codec *params)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+
+	*params = sub->cparams.codec;
+
+	return 0;
+}
+
+static int uniphier_aio_compr_set_params(struct snd_compr_stream *cstream,
+					 struct snd_compr_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+	struct device *dev = &aio->chip->pdev->dev;
+	int ret;
+
+	if (params->codec.id != SND_AUDIOCODEC_IEC61937) {
+		dev_err(dev, "Codec ID is not supported(%d)\n",
+			params->codec.id);
+		return -EINVAL;
+	}
+	if (params->codec.profile != SND_AUDIOPROFILE_IEC61937_SPDIF) {
+		dev_err(dev, "Codec profile is not supported(%d)\n",
+			params->codec.profile);
+		return -EINVAL;
+	}
+
+	/* IEC frame type will be changed after received valid data */
+	sub->iec_pc = IEC61937_PC_AAC;
+
+	sub->cparams = *params;
+	sub->setting = 1;
+
+	aio_port_reset(sub);
+	aio_src_reset(sub);
+
+	ret = uniphier_aio_compr_prepare(cstream);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+
+	sub->setting = 0;
+
+	return 0;
+}
+
+static int uniphier_aio_compr_prepare(struct snd_compr_stream *cstream)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_compr_runtime *runtime = cstream->runtime;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+	int bytes = runtime->fragment_size;
+	unsigned long flags;
+	int ret;
+
+	ret = aiodma_ch_set_param(sub);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&sub->lock, flags);
+	ret = aiodma_rb_set_buffer(sub, sub->compr_addr,
+				   sub->compr_addr + sub->compr_bytes,
+				   bytes);
+	spin_unlock_irqrestore(&sub->lock, flags);
+	if (ret)
+		return ret;
+
+	ret = aio_port_set_param(sub, sub->pass_through, &sub->params);
+	if (ret)
+		return ret;
+	ret = aio_oport_set_stream_type(sub, sub->iec_pc);
+	if (ret)
+		return ret;
+	aio_port_set_enable(sub, 1);
+
+	ret = aio_if_set_param(sub, sub->pass_through);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int uniphier_aio_compr_trigger(struct snd_compr_stream *cstream,
+				      int cmd)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_compr_runtime *runtime = cstream->runtime;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+	struct device *dev = &aio->chip->pdev->dev;
+	int bytes = runtime->fragment_size, ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sub->lock, flags);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
+		aiodma_ch_set_enable(sub, 1);
+		sub->running = 1;
+
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		sub->running = 0;
+		aiodma_ch_set_enable(sub, 0);
+
+		break;
+	default:
+		dev_warn(dev, "Unknown trigger(%d)\n", cmd);
+		ret = -EINVAL;
+	}
+	spin_unlock_irqrestore(&sub->lock, flags);
+
+	return ret;
+}
+
+static int uniphier_aio_compr_pointer(struct snd_compr_stream *cstream,
+				      struct snd_compr_tstamp *tstamp)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_compr_runtime *runtime = cstream->runtime;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+	int bytes = runtime->fragment_size;
+	unsigned long flags;
+	u32 pos;
+
+	spin_lock_irqsave(&sub->lock, flags);
+
+	aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		pos = sub->rd_offs;
+		/* Size of AIO output format is double of IEC61937 */
+		tstamp->copied_total = sub->rd_total / 2;
+	} else {
+		pos = sub->wr_offs;
+		tstamp->copied_total = sub->rd_total;
+	}
+	tstamp->byte_offset = pos;
+
+	spin_unlock_irqrestore(&sub->lock, flags);
+
+	return 0;
+}
+
+static int aio_compr_send_to_hw(struct uniphier_aio_sub *sub,
+				char __user *buf, size_t dstsize)
+{
+	u32 __user *srcbuf = (u32 __user *)buf;
+	u32 *dstbuf = (u32 *)(sub->compr_area + sub->wr_offs);
+	int src = 0, dst = 0, ret;
+	u32 frm, frm_a, frm_b;
+
+	while (dstsize > 0) {
+		ret = get_user(frm, srcbuf + src);
+		if (ret)
+			return ret;
+		src++;
+
+		frm_a = frm & 0xffff;
+		frm_b = (frm >> 16) & 0xffff;
+
+		if (frm == IEC61937_HEADER_SIGN) {
+			frm_a |= 0x01000000;
+
+			/* Next data is Pc and Pd */
+			sub->iec_header = true;
+		} else {
+			u16 pc = be16_to_cpu((__be16)frm_a);
+
+			if (sub->iec_header && sub->iec_pc != pc) {
+				/* Force overwrite IEC frame type */
+				sub->iec_pc = pc;
+				ret = aio_oport_set_stream_type(sub, pc);
+				if (ret)
+					return ret;
+			}
+			sub->iec_header = false;
+		}
+		dstbuf[dst++] = frm_a;
+		dstbuf[dst++] = frm_b;
+
+		dstsize -= sizeof(u32) * 2;
+	}
+
+	return 0;
+}
+
+static int uniphier_aio_compr_copy(struct snd_compr_stream *cstream,
+				   char __user *buf, size_t count)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_compr_runtime *runtime = cstream->runtime;
+	struct device *carddev = rtd->compr->card->dev;
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+	size_t cnt = min_t(size_t, count, aio_rb_space_to_end(sub) / 2);
+	int bytes = runtime->fragment_size;
+	unsigned long flags;
+	size_t s;
+	int ret;
+
+	if (cnt < sizeof(u32))
+		return 0;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		dma_addr_t dmapos = sub->compr_addr + sub->wr_offs;
+
+		/* Size of AIO output format is double of IEC61937 */
+		s = cnt * 2;
+
+		dma_sync_single_for_cpu(carddev, dmapos, s, DMA_TO_DEVICE);
+		ret = aio_compr_send_to_hw(sub, buf, s);
+		dma_sync_single_for_device(carddev, dmapos, s, DMA_TO_DEVICE);
+	} else {
+		dma_addr_t dmapos = sub->compr_addr + sub->rd_offs;
+
+		s = cnt;
+
+		dma_sync_single_for_cpu(carddev, dmapos, s, DMA_FROM_DEVICE);
+		ret = copy_to_user(buf, sub->compr_area + sub->rd_offs, s);
+		dma_sync_single_for_device(carddev, dmapos, s, DMA_FROM_DEVICE);
+	}
+	if (ret)
+		return -EFAULT;
+
+	spin_lock_irqsave(&sub->lock, flags);
+
+	sub->threshold = 2 * bytes;
+	aiodma_rb_set_threshold(sub, sub->compr_bytes, 2 * bytes);
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		sub->wr_offs += s;
+		if (sub->wr_offs >= sub->compr_bytes)
+			sub->wr_offs -= sub->compr_bytes;
+	} else {
+		sub->rd_offs += s;
+		if (sub->rd_offs >= sub->compr_bytes)
+			sub->rd_offs -= sub->compr_bytes;
+	}
+	aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
+
+	spin_unlock_irqrestore(&sub->lock, flags);
+
+	return cnt;
+}
+
+static int uniphier_aio_compr_get_caps(struct snd_compr_stream *cstream,
+				       struct snd_compr_caps *caps)
+{
+	caps->num_codecs = 1;
+	caps->min_fragment_size = AUD_MIN_FRAGMENT_SIZE;
+	caps->max_fragment_size = AUD_MAX_FRAGMENT_SIZE;
+	caps->min_fragments = AUD_MIN_FRAGMENT;
+	caps->max_fragments = AUD_MAX_FRAGMENT;
+	caps->codecs[0] = SND_AUDIOCODEC_IEC61937;
+
+	return 0;
+}
+
+static const struct snd_compr_codec_caps caps_iec = {
+	.num_descriptors = 1,
+	.descriptor[0].max_ch = 8,
+	.descriptor[0].num_sample_rates = 0,
+	.descriptor[0].num_bitrates = 0,
+	.descriptor[0].profiles = SND_AUDIOPROFILE_IEC61937_SPDIF,
+	.descriptor[0].modes = SND_AUDIOMODE_IEC_AC3 |
+				SND_AUDIOMODE_IEC_MPEG1 |
+				SND_AUDIOMODE_IEC_MP3 |
+				SND_AUDIOMODE_IEC_DTS,
+	.descriptor[0].formats = 0,
+};
+
+static int uniphier_aio_compr_get_codec_caps(struct snd_compr_stream *stream,
+					     struct snd_compr_codec_caps *codec)
+{
+	if (codec->codec == SND_AUDIOCODEC_IEC61937)
+		*codec = caps_iec;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+const struct snd_compr_ops uniphier_aio_compr_ops = {
+	.open           = uniphier_aio_compr_open,
+	.free           = uniphier_aio_compr_free,
+	.get_params     = uniphier_aio_compr_get_params,
+	.set_params     = uniphier_aio_compr_set_params,
+	.trigger        = uniphier_aio_compr_trigger,
+	.pointer        = uniphier_aio_compr_pointer,
+	.copy           = uniphier_aio_compr_copy,
+	.get_caps       = uniphier_aio_compr_get_caps,
+	.get_codec_caps = uniphier_aio_compr_get_codec_caps,
+};
diff --git a/sound/soc/uniphier/aio-core.c b/sound/soc/uniphier/aio-core.c
new file mode 100644
index 0000000..6d50042
--- /dev/null
+++ b/sound/soc/uniphier/aio-core.c
@@ -0,0 +1,1138 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO ALSA common driver.
+//
+// Copyright (c) 2016-2018 Socionext 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; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+#include <linux/bitfield.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "aio.h"
+#include "aio-reg.h"
+
+static u64 rb_cnt(u64 wr, u64 rd, u64 len)
+{
+	if (rd <= wr)
+		return wr - rd;
+	else
+		return len - (rd - wr);
+}
+
+static u64 rb_cnt_to_end(u64 wr, u64 rd, u64 len)
+{
+	if (rd <= wr)
+		return wr - rd;
+	else
+		return len - rd;
+}
+
+static u64 rb_space(u64 wr, u64 rd, u64 len)
+{
+	if (rd <= wr)
+		return len - (wr - rd) - 8;
+	else
+		return rd - wr - 8;
+}
+
+static u64 rb_space_to_end(u64 wr, u64 rd, u64 len)
+{
+	if (rd > wr)
+		return rd - wr - 8;
+	else if (rd > 0)
+		return len - wr;
+	else
+		return len - wr - 8;
+}
+
+u64 aio_rb_cnt(struct uniphier_aio_sub *sub)
+{
+	return rb_cnt(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
+}
+
+u64 aio_rbt_cnt_to_end(struct uniphier_aio_sub *sub)
+{
+	return rb_cnt_to_end(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
+}
+
+u64 aio_rb_space(struct uniphier_aio_sub *sub)
+{
+	return rb_space(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
+}
+
+u64 aio_rb_space_to_end(struct uniphier_aio_sub *sub)
+{
+	return rb_space_to_end(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
+}
+
+/**
+ * aio_iecout_set_enable - setup IEC output via SoC glue
+ * @chip: the AIO chip pointer
+ * @enable: false to stop the output, true to start
+ *
+ * Set enabled or disabled S/PDIF signal output to out of SoC via AOnIEC pins.
+ * This function need to call at driver startup.
+ *
+ * The regmap of SoC glue is specified by 'socionext,syscon' optional property
+ * of DT. This function has no effect if no property.
+ */
+void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable)
+{
+	struct regmap *r = chip->regmap_sg;
+
+	if (!r)
+		return;
+
+	regmap_write(r, SG_AOUTEN, (enable) ? ~0 : 0);
+}
+
+/**
+ * aio_chip_set_pll - set frequency to audio PLL
+ * @chip  : the AIO chip pointer
+ * @source: PLL
+ * @freq  : frequency in Hz, 0 is ignored
+ *
+ * Sets frequency of audio PLL. This function can be called anytime,
+ * but it takes time till PLL is locked.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_chip_set_pll(struct uniphier_aio_chip *chip, int pll_id,
+		     unsigned int freq)
+{
+	struct device *dev = &chip->pdev->dev;
+	struct regmap *r = chip->regmap;
+	int shift;
+	u32 v;
+
+	/* Not change */
+	if (freq == 0)
+		return 0;
+
+	switch (pll_id) {
+	case AUD_PLL_A1:
+		shift = 0;
+		break;
+	case AUD_PLL_F1:
+		shift = 1;
+		break;
+	case AUD_PLL_A2:
+		shift = 2;
+		break;
+	case AUD_PLL_F2:
+		shift = 3;
+		break;
+	default:
+		dev_err(dev, "PLL(%d) not supported\n", pll_id);
+		return -EINVAL;
+	}
+
+	switch (freq) {
+	case 36864000:
+		v = A2APLLCTR1_APLLX_36MHZ;
+		break;
+	case 33868800:
+		v = A2APLLCTR1_APLLX_33MHZ;
+		break;
+	default:
+		dev_err(dev, "PLL frequency not supported(%d)\n", freq);
+		return -EINVAL;
+	}
+	chip->plls[pll_id].freq = freq;
+
+	regmap_update_bits(r, A2APLLCTR1, A2APLLCTR1_APLLX_MASK << shift,
+			   v << shift);
+
+	return 0;
+}
+
+/**
+ * aio_chip_init - initialize AIO whole settings
+ * @chip: the AIO chip pointer
+ *
+ * Sets AIO fixed and whole device settings to AIO.
+ * This function need to call once at driver startup.
+ *
+ * The register area that is changed by this function is shared by all
+ * modules of AIO. But there is not race condition since this function
+ * has always set the same initialize values.
+ */
+void aio_chip_init(struct uniphier_aio_chip *chip)
+{
+	struct regmap *r = chip->regmap;
+
+	regmap_update_bits(r, A2APLLCTR0,
+			   A2APLLCTR0_APLLXPOW_MASK,
+			   A2APLLCTR0_APLLXPOW_PWON);
+
+	regmap_update_bits(r, A2EXMCLKSEL0,
+			   A2EXMCLKSEL0_EXMCLK_MASK,
+			   A2EXMCLKSEL0_EXMCLK_OUTPUT);
+
+	regmap_update_bits(r, A2AIOINPUTSEL, A2AIOINPUTSEL_RXSEL_MASK,
+			   A2AIOINPUTSEL_RXSEL_PCMI1_HDMIRX1 |
+			   A2AIOINPUTSEL_RXSEL_PCMI2_SIF |
+			   A2AIOINPUTSEL_RXSEL_PCMI3_EVEA |
+			   A2AIOINPUTSEL_RXSEL_IECI1_HDMIRX1);
+
+	if (chip->chip_spec->addr_ext)
+		regmap_update_bits(r, CDA2D_TEST, CDA2D_TEST_DDR_MODE_MASK,
+				   CDA2D_TEST_DDR_MODE_EXTON0);
+	else
+		regmap_update_bits(r, CDA2D_TEST, CDA2D_TEST_DDR_MODE_MASK,
+				   CDA2D_TEST_DDR_MODE_EXTOFF1);
+}
+
+/**
+ * aio_init - initialize AIO substream
+ * @sub: the AIO substream pointer
+ *
+ * Sets fixed settings of each AIO substreams.
+ * This function need to call once at substream startup.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_init(struct uniphier_aio_sub *sub)
+{
+	struct device *dev = &sub->aio->chip->pdev->dev;
+	struct regmap *r = sub->aio->chip->regmap;
+
+	regmap_write(r, A2RBNMAPCTR0(sub->swm->rb.hw),
+		     MAPCTR0_EN | sub->swm->rb.map);
+	regmap_write(r, A2CHNMAPCTR0(sub->swm->ch.hw),
+		     MAPCTR0_EN | sub->swm->ch.map);
+
+	switch (sub->swm->type) {
+	case PORT_TYPE_I2S:
+	case PORT_TYPE_SPDIF:
+	case PORT_TYPE_EVE:
+		if (sub->swm->dir == PORT_DIR_INPUT) {
+			regmap_write(r, A2IIFNMAPCTR0(sub->swm->iif.hw),
+				     MAPCTR0_EN | sub->swm->iif.map);
+			regmap_write(r, A2IPORTNMAPCTR0(sub->swm->iport.hw),
+				     MAPCTR0_EN | sub->swm->iport.map);
+		} else {
+			regmap_write(r, A2OIFNMAPCTR0(sub->swm->oif.hw),
+				     MAPCTR0_EN | sub->swm->oif.map);
+			regmap_write(r, A2OPORTNMAPCTR0(sub->swm->oport.hw),
+				     MAPCTR0_EN | sub->swm->oport.map);
+		}
+		break;
+	case PORT_TYPE_CONV:
+		regmap_write(r, A2OIFNMAPCTR0(sub->swm->oif.hw),
+			     MAPCTR0_EN | sub->swm->oif.map);
+		regmap_write(r, A2OPORTNMAPCTR0(sub->swm->oport.hw),
+			     MAPCTR0_EN | sub->swm->oport.map);
+		regmap_write(r, A2CHNMAPCTR0(sub->swm->och.hw),
+			     MAPCTR0_EN | sub->swm->och.map);
+		regmap_write(r, A2IIFNMAPCTR0(sub->swm->iif.hw),
+			     MAPCTR0_EN | sub->swm->iif.map);
+		break;
+	default:
+		dev_err(dev, "Unknown port type %d.\n", sub->swm->type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * aio_port_reset - reset AIO port block
+ * @sub: the AIO substream pointer
+ *
+ * Resets the digital signal input/output port block of AIO.
+ */
+void aio_port_reset(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		regmap_write(r, AOUTRSTCTR0, BIT(sub->swm->oport.map));
+		regmap_write(r, AOUTRSTCTR1, BIT(sub->swm->oport.map));
+	} else {
+		regmap_update_bits(r, IPORTMXRSTCTR(sub->swm->iport.map),
+				   IPORTMXRSTCTR_RSTPI_MASK,
+				   IPORTMXRSTCTR_RSTPI_RESET);
+		regmap_update_bits(r, IPORTMXRSTCTR(sub->swm->iport.map),
+				   IPORTMXRSTCTR_RSTPI_MASK,
+				   IPORTMXRSTCTR_RSTPI_RELEASE);
+	}
+}
+
+/**
+ * aio_port_set_rate - set sampling rate of LPCM
+ * @sub: the AIO substream pointer, PCM substream only
+ * @rate: Sampling rate in Hz.
+ *
+ * Set suitable I2S format settings to input/output port block of AIO.
+ * Parameter is specified by hw_params().
+ *
+ * This function may return error if non-PCM substream.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	struct device *dev = &sub->aio->chip->pdev->dev;
+	u32 v;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		switch (rate) {
+		case 8000:
+			v = OPORTMXCTR1_FSSEL_8;
+			break;
+		case 11025:
+			v = OPORTMXCTR1_FSSEL_11_025;
+			break;
+		case 12000:
+			v = OPORTMXCTR1_FSSEL_12;
+			break;
+		case 16000:
+			v = OPORTMXCTR1_FSSEL_16;
+			break;
+		case 22050:
+			v = OPORTMXCTR1_FSSEL_22_05;
+			break;
+		case 24000:
+			v = OPORTMXCTR1_FSSEL_24;
+			break;
+		case 32000:
+			v = OPORTMXCTR1_FSSEL_32;
+			break;
+		case 44100:
+			v = OPORTMXCTR1_FSSEL_44_1;
+			break;
+		case 48000:
+			v = OPORTMXCTR1_FSSEL_48;
+			break;
+		case 88200:
+			v = OPORTMXCTR1_FSSEL_88_2;
+			break;
+		case 96000:
+			v = OPORTMXCTR1_FSSEL_96;
+			break;
+		case 176400:
+			v = OPORTMXCTR1_FSSEL_176_4;
+			break;
+		case 192000:
+			v = OPORTMXCTR1_FSSEL_192;
+			break;
+		default:
+			dev_err(dev, "Rate not supported(%d)\n", rate);
+			return -EINVAL;
+		}
+
+		regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map),
+				   OPORTMXCTR1_FSSEL_MASK, v);
+	} else {
+		switch (rate) {
+		case 8000:
+			v = IPORTMXCTR1_FSSEL_8;
+			break;
+		case 11025:
+			v = IPORTMXCTR1_FSSEL_11_025;
+			break;
+		case 12000:
+			v = IPORTMXCTR1_FSSEL_12;
+			break;
+		case 16000:
+			v = IPORTMXCTR1_FSSEL_16;
+			break;
+		case 22050:
+			v = IPORTMXCTR1_FSSEL_22_05;
+			break;
+		case 24000:
+			v = IPORTMXCTR1_FSSEL_24;
+			break;
+		case 32000:
+			v = IPORTMXCTR1_FSSEL_32;
+			break;
+		case 44100:
+			v = IPORTMXCTR1_FSSEL_44_1;
+			break;
+		case 48000:
+			v = IPORTMXCTR1_FSSEL_48;
+			break;
+		case 88200:
+			v = IPORTMXCTR1_FSSEL_88_2;
+			break;
+		case 96000:
+			v = IPORTMXCTR1_FSSEL_96;
+			break;
+		case 176400:
+			v = IPORTMXCTR1_FSSEL_176_4;
+			break;
+		case 192000:
+			v = IPORTMXCTR1_FSSEL_192;
+			break;
+		default:
+			dev_err(dev, "Rate not supported(%d)\n", rate);
+			return -EINVAL;
+		}
+
+		regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map),
+				   IPORTMXCTR1_FSSEL_MASK, v);
+	}
+
+	return 0;
+}
+
+/**
+ * aio_port_set_fmt - set format of I2S data
+ * @sub: the AIO substream pointer, PCM substream only
+ * This parameter has no effect if substream is I2S or PCM.
+ *
+ * Set suitable I2S format settings to input/output port block of AIO.
+ * Parameter is specified by set_fmt().
+ *
+ * This function may return error if non-PCM substream.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_port_set_fmt(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	struct device *dev = &sub->aio->chip->pdev->dev;
+	u32 v;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		switch (sub->aio->fmt) {
+		case SND_SOC_DAIFMT_LEFT_J:
+			v = OPORTMXCTR1_I2SLRSEL_LEFT;
+			break;
+		case SND_SOC_DAIFMT_RIGHT_J:
+			v = OPORTMXCTR1_I2SLRSEL_RIGHT;
+			break;
+		case SND_SOC_DAIFMT_I2S:
+			v = OPORTMXCTR1_I2SLRSEL_I2S;
+			break;
+		default:
+			dev_err(dev, "Format is not supported(%d)\n",
+				sub->aio->fmt);
+			return -EINVAL;
+		}
+
+		v |= OPORTMXCTR1_OUTBITSEL_24;
+		regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map),
+				   OPORTMXCTR1_I2SLRSEL_MASK |
+				   OPORTMXCTR1_OUTBITSEL_MASK, v);
+	} else {
+		switch (sub->aio->fmt) {
+		case SND_SOC_DAIFMT_LEFT_J:
+			v = IPORTMXCTR1_LRSEL_LEFT;
+			break;
+		case SND_SOC_DAIFMT_RIGHT_J:
+			v = IPORTMXCTR1_LRSEL_RIGHT;
+			break;
+		case SND_SOC_DAIFMT_I2S:
+			v = IPORTMXCTR1_LRSEL_I2S;
+			break;
+		default:
+			dev_err(dev, "Format is not supported(%d)\n",
+				sub->aio->fmt);
+			return -EINVAL;
+		}
+
+		v |= IPORTMXCTR1_OUTBITSEL_24 |
+			IPORTMXCTR1_CHSEL_ALL;
+		regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map),
+				   IPORTMXCTR1_LRSEL_MASK |
+				   IPORTMXCTR1_OUTBITSEL_MASK |
+				   IPORTMXCTR1_CHSEL_MASK, v);
+	}
+
+	return 0;
+}
+
+/**
+ * aio_port_set_clk - set clock and divider of AIO port block
+ * @sub: the AIO substream pointer
+ *
+ * Set suitable PLL clock divider and relational settings to
+ * input/output port block of AIO. Parameters are specified by
+ * set_sysclk() and set_pll().
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_port_set_clk(struct uniphier_aio_sub *sub)
+{
+	struct uniphier_aio_chip *chip = sub->aio->chip;
+	struct device *dev = &sub->aio->chip->pdev->dev;
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 v_pll[] = {
+		OPORTMXCTR2_ACLKSEL_A1, OPORTMXCTR2_ACLKSEL_F1,
+		OPORTMXCTR2_ACLKSEL_A2, OPORTMXCTR2_ACLKSEL_F2,
+		OPORTMXCTR2_ACLKSEL_A2PLL,
+		OPORTMXCTR2_ACLKSEL_RX1,
+	};
+	u32 v_div[] = {
+		OPORTMXCTR2_DACCKSEL_1_2, OPORTMXCTR2_DACCKSEL_1_3,
+		OPORTMXCTR2_DACCKSEL_1_1, OPORTMXCTR2_DACCKSEL_2_3,
+	};
+	u32 v;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		if (sub->swm->type == PORT_TYPE_I2S) {
+			if (sub->aio->pll_out >= ARRAY_SIZE(v_pll)) {
+				dev_err(dev, "PLL(%d) is invalid\n",
+					sub->aio->pll_out);
+				return -EINVAL;
+			}
+			if (sub->aio->plldiv >= ARRAY_SIZE(v_div)) {
+				dev_err(dev, "PLL divider(%d) is invalid\n",
+					sub->aio->plldiv);
+				return -EINVAL;
+			}
+
+			v = v_pll[sub->aio->pll_out] |
+				OPORTMXCTR2_MSSEL_MASTER |
+				v_div[sub->aio->plldiv];
+
+			switch (chip->plls[sub->aio->pll_out].freq) {
+			case 0:
+			case 36864000:
+			case 33868800:
+				v |= OPORTMXCTR2_EXTLSIFSSEL_36;
+				break;
+			default:
+				v |= OPORTMXCTR2_EXTLSIFSSEL_24;
+				break;
+			}
+		} else if (sub->swm->type == PORT_TYPE_EVE) {
+			v = OPORTMXCTR2_ACLKSEL_A2PLL |
+				OPORTMXCTR2_MSSEL_MASTER |
+				OPORTMXCTR2_EXTLSIFSSEL_36 |
+				OPORTMXCTR2_DACCKSEL_1_2;
+		} else if (sub->swm->type == PORT_TYPE_SPDIF) {
+			if (sub->aio->pll_out >= ARRAY_SIZE(v_pll)) {
+				dev_err(dev, "PLL(%d) is invalid\n",
+					sub->aio->pll_out);
+				return -EINVAL;
+			}
+			v = v_pll[sub->aio->pll_out] |
+				OPORTMXCTR2_MSSEL_MASTER |
+				OPORTMXCTR2_DACCKSEL_1_2;
+
+			switch (chip->plls[sub->aio->pll_out].freq) {
+			case 0:
+			case 36864000:
+			case 33868800:
+				v |= OPORTMXCTR2_EXTLSIFSSEL_36;
+				break;
+			default:
+				v |= OPORTMXCTR2_EXTLSIFSSEL_24;
+				break;
+			}
+		} else {
+			v = OPORTMXCTR2_ACLKSEL_A1 |
+				OPORTMXCTR2_MSSEL_MASTER |
+				OPORTMXCTR2_EXTLSIFSSEL_36 |
+				OPORTMXCTR2_DACCKSEL_1_2;
+		}
+		regmap_write(r, OPORTMXCTR2(sub->swm->oport.map), v);
+	} else {
+		v = IPORTMXCTR2_ACLKSEL_A1 |
+			IPORTMXCTR2_MSSEL_SLAVE |
+			IPORTMXCTR2_EXTLSIFSSEL_36 |
+			IPORTMXCTR2_DACCKSEL_1_2;
+		regmap_write(r, IPORTMXCTR2(sub->swm->iport.map), v);
+	}
+
+	return 0;
+}
+
+/**
+ * aio_port_set_param - set parameters of AIO port block
+ * @sub: the AIO substream pointer
+ * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
+ * This parameter has no effect if substream is I2S or PCM.
+ * @params: hardware parameters of ALSA
+ *
+ * Set suitable setting to input/output port block of AIO to process the
+ * specified in params.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through,
+		       const struct snd_pcm_hw_params *params)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	unsigned int rate;
+	u32 v;
+	int ret;
+
+	if (!pass_through) {
+		if (sub->swm->type == PORT_TYPE_EVE ||
+		    sub->swm->type == PORT_TYPE_CONV) {
+			rate = 48000;
+		} else {
+			rate = params_rate(params);
+		}
+
+		ret = aio_port_set_rate(sub, rate);
+		if (ret)
+			return ret;
+
+		ret = aio_port_set_fmt(sub);
+		if (ret)
+			return ret;
+	}
+
+	ret = aio_port_set_clk(sub);
+	if (ret)
+		return ret;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		if (pass_through)
+			v = OPORTMXCTR3_SRCSEL_STREAM |
+				OPORTMXCTR3_VALID_STREAM;
+		else
+			v = OPORTMXCTR3_SRCSEL_PCM |
+				OPORTMXCTR3_VALID_PCM;
+
+		v |= OPORTMXCTR3_IECTHUR_IECOUT |
+			OPORTMXCTR3_PMSEL_PAUSE |
+			OPORTMXCTR3_PMSW_MUTE_OFF;
+		regmap_write(r, OPORTMXCTR3(sub->swm->oport.map), v);
+	} else {
+		regmap_write(r, IPORTMXACLKSEL0EX(sub->swm->iport.map),
+			     IPORTMXACLKSEL0EX_ACLKSEL0EX_INTERNAL);
+		regmap_write(r, IPORTMXEXNOE(sub->swm->iport.map),
+			     IPORTMXEXNOE_PCMINOE_INPUT);
+	}
+
+	return 0;
+}
+
+/**
+ * aio_port_set_enable - start or stop of AIO port block
+ * @sub: the AIO substream pointer
+ * @enable: zero to stop the block, otherwise to start
+ *
+ * Start or stop the signal input/output port block of AIO.
+ */
+void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		regmap_write(r, OPORTMXPATH(sub->swm->oport.map),
+			     sub->swm->oif.map);
+
+		regmap_update_bits(r, OPORTMXMASK(sub->swm->oport.map),
+				   OPORTMXMASK_IUDXMSK_MASK |
+				   OPORTMXMASK_IUXCKMSK_MASK |
+				   OPORTMXMASK_DXMSK_MASK |
+				   OPORTMXMASK_XCKMSK_MASK,
+				   OPORTMXMASK_IUDXMSK_OFF |
+				   OPORTMXMASK_IUXCKMSK_OFF |
+				   OPORTMXMASK_DXMSK_OFF |
+				   OPORTMXMASK_XCKMSK_OFF);
+
+		if (enable)
+			regmap_write(r, AOUTENCTR0, BIT(sub->swm->oport.map));
+		else
+			regmap_write(r, AOUTENCTR1, BIT(sub->swm->oport.map));
+	} else {
+		regmap_update_bits(r, IPORTMXMASK(sub->swm->iport.map),
+				   IPORTMXMASK_IUXCKMSK_MASK |
+				   IPORTMXMASK_XCKMSK_MASK,
+				   IPORTMXMASK_IUXCKMSK_OFF |
+				   IPORTMXMASK_XCKMSK_OFF);
+
+		if (enable)
+			regmap_update_bits(r,
+					   IPORTMXCTR2(sub->swm->iport.map),
+					   IPORTMXCTR2_REQEN_MASK,
+					   IPORTMXCTR2_REQEN_ENABLE);
+		else
+			regmap_update_bits(r,
+					   IPORTMXCTR2(sub->swm->iport.map),
+					   IPORTMXCTR2_REQEN_MASK,
+					   IPORTMXCTR2_REQEN_DISABLE);
+	}
+}
+
+/**
+ * aio_if_set_param - set parameters of AIO DMA I/F block
+ * @sub: the AIO substream pointer
+ * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
+ * This parameter has no effect if substream is I2S or PCM.
+ *
+ * Set suitable setting to DMA interface block of AIO to process the
+ * specified in settings.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 v;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		if (pass_through)
+			v = PBOUTMXCTR0_ENDIAN_0123 |
+				PBOUTMXCTR0_MEMFMT_STREAM;
+		else
+			v = PBOUTMXCTR0_ENDIAN_3210 |
+				PBOUTMXCTR0_MEMFMT_2CH;
+
+		regmap_write(r, PBOUTMXCTR0(sub->swm->oif.map), v);
+		regmap_write(r, PBOUTMXCTR1(sub->swm->oif.map), 0);
+	} else {
+		regmap_write(r, PBINMXCTR(sub->swm->iif.map),
+			     PBINMXCTR_NCONNECT_CONNECT |
+			     PBINMXCTR_INOUTSEL_IN |
+			     (sub->swm->iport.map << PBINMXCTR_PBINSEL_SHIFT) |
+			     PBINMXCTR_ENDIAN_3210 |
+			     PBINMXCTR_MEMFMT_D0);
+	}
+
+	return 0;
+}
+
+/**
+ * aio_oport_set_stream_type - set parameters of AIO playback port block
+ * @sub: the AIO substream pointer
+ * @pc: Pc type of IEC61937
+ *
+ * Set special setting to output port block of AIO to output the stream
+ * via S/PDIF.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_oport_set_stream_type(struct uniphier_aio_sub *sub,
+			      enum IEC61937_PC pc)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 repet = 0, pause = OPORTMXPAUDAT_PAUSEPC_CMN;
+
+	switch (pc) {
+	case IEC61937_PC_AC3:
+		repet = OPORTMXREPET_STRLENGTH_AC3 |
+			OPORTMXREPET_PMLENGTH_AC3;
+		pause |= OPORTMXPAUDAT_PAUSEPD_AC3;
+		break;
+	case IEC61937_PC_MPA:
+		repet = OPORTMXREPET_STRLENGTH_MPA |
+			OPORTMXREPET_PMLENGTH_MPA;
+		pause |= OPORTMXPAUDAT_PAUSEPD_MPA;
+		break;
+	case IEC61937_PC_MP3:
+		repet = OPORTMXREPET_STRLENGTH_MP3 |
+			OPORTMXREPET_PMLENGTH_MP3;
+		pause |= OPORTMXPAUDAT_PAUSEPD_MP3;
+		break;
+	case IEC61937_PC_DTS1:
+		repet = OPORTMXREPET_STRLENGTH_DTS1 |
+			OPORTMXREPET_PMLENGTH_DTS1;
+		pause |= OPORTMXPAUDAT_PAUSEPD_DTS1;
+		break;
+	case IEC61937_PC_DTS2:
+		repet = OPORTMXREPET_STRLENGTH_DTS2 |
+			OPORTMXREPET_PMLENGTH_DTS2;
+		pause |= OPORTMXPAUDAT_PAUSEPD_DTS2;
+		break;
+	case IEC61937_PC_DTS3:
+		repet = OPORTMXREPET_STRLENGTH_DTS3 |
+			OPORTMXREPET_PMLENGTH_DTS3;
+		pause |= OPORTMXPAUDAT_PAUSEPD_DTS3;
+		break;
+	case IEC61937_PC_AAC:
+		repet = OPORTMXREPET_STRLENGTH_AAC |
+			OPORTMXREPET_PMLENGTH_AAC;
+		pause |= OPORTMXPAUDAT_PAUSEPD_AAC;
+		break;
+	case IEC61937_PC_PAUSE:
+		/* Do nothing */
+		break;
+	}
+
+	regmap_write(r, OPORTMXREPET(sub->swm->oport.map), repet);
+	regmap_write(r, OPORTMXPAUDAT(sub->swm->oport.map), pause);
+
+	return 0;
+}
+
+/**
+ * aio_src_reset - reset AIO SRC block
+ * @sub: the AIO substream pointer
+ *
+ * Resets the digital signal input/output port with sampling rate converter
+ * block of AIO.
+ * This function has no effect if substream is not supported rate converter.
+ */
+void aio_src_reset(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+
+	if (sub->swm->dir != PORT_DIR_OUTPUT)
+		return;
+
+	regmap_write(r, AOUTSRCRSTCTR0, BIT(sub->swm->oport.map));
+	regmap_write(r, AOUTSRCRSTCTR1, BIT(sub->swm->oport.map));
+}
+
+/**
+ * aio_src_set_param - set parameters of AIO SRC block
+ * @sub: the AIO substream pointer
+ * @params: hardware parameters of ALSA
+ *
+ * Set suitable setting to input/output port with sampling rate converter
+ * block of AIO to process the specified in params.
+ * This function has no effect if substream is not supported rate converter.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_src_set_param(struct uniphier_aio_sub *sub,
+		      const struct snd_pcm_hw_params *params)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 v;
+
+	if (sub->swm->dir != PORT_DIR_OUTPUT)
+		return 0;
+
+	regmap_write(r, OPORTMXSRC1CTR(sub->swm->oport.map),
+		     OPORTMXSRC1CTR_THMODE_SRC |
+		     OPORTMXSRC1CTR_SRCPATH_CALC |
+		     OPORTMXSRC1CTR_SYNC_ASYNC |
+		     OPORTMXSRC1CTR_FSIIPSEL_INNER |
+		     OPORTMXSRC1CTR_FSISEL_ACLK);
+
+	switch (params_rate(params)) {
+	default:
+	case 48000:
+		v = OPORTMXRATE_I_ACLKSEL_APLLA1 |
+			OPORTMXRATE_I_MCKSEL_36 |
+			OPORTMXRATE_I_FSSEL_48;
+		break;
+	case 44100:
+		v = OPORTMXRATE_I_ACLKSEL_APLLA2 |
+			OPORTMXRATE_I_MCKSEL_33 |
+			OPORTMXRATE_I_FSSEL_44_1;
+		break;
+	case 32000:
+		v = OPORTMXRATE_I_ACLKSEL_APLLA1 |
+			OPORTMXRATE_I_MCKSEL_36 |
+			OPORTMXRATE_I_FSSEL_32;
+		break;
+	}
+
+	regmap_write(r, OPORTMXRATE_I(sub->swm->oport.map),
+		     v | OPORTMXRATE_I_ACLKSRC_APLL |
+		     OPORTMXRATE_I_LRCKSTP_STOP);
+	regmap_update_bits(r, OPORTMXRATE_I(sub->swm->oport.map),
+			   OPORTMXRATE_I_LRCKSTP_MASK,
+			   OPORTMXRATE_I_LRCKSTP_START);
+
+	return 0;
+}
+
+int aio_srcif_set_param(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+
+	regmap_write(r, PBINMXCTR(sub->swm->iif.map),
+		     PBINMXCTR_NCONNECT_CONNECT |
+		     PBINMXCTR_INOUTSEL_OUT |
+		     (sub->swm->oport.map << PBINMXCTR_PBINSEL_SHIFT) |
+		     PBINMXCTR_ENDIAN_3210 |
+		     PBINMXCTR_MEMFMT_D0);
+
+	return 0;
+}
+
+int aio_srcch_set_param(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+
+	regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->och.map),
+		     CDA2D_CHMXCTRL1_INDSIZE_INFINITE);
+
+	regmap_write(r, CDA2D_CHMXSRCAMODE(sub->swm->och.map),
+		     CDA2D_CHMXAMODE_ENDIAN_3210 |
+		     CDA2D_CHMXAMODE_AUPDT_FIX |
+		     CDA2D_CHMXAMODE_TYPE_NORMAL);
+
+	regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->och.map),
+		     CDA2D_CHMXAMODE_ENDIAN_3210 |
+		     CDA2D_CHMXAMODE_AUPDT_INC |
+		     CDA2D_CHMXAMODE_TYPE_RING |
+		     (sub->swm->och.map << CDA2D_CHMXAMODE_RSSEL_SHIFT));
+
+	return 0;
+}
+
+void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 v;
+
+	if (enable)
+		v = CDA2D_STRT0_STOP_START;
+	else
+		v = CDA2D_STRT0_STOP_STOP;
+
+	regmap_write(r, CDA2D_STRT0,
+		     v | BIT(sub->swm->och.map));
+}
+
+int aiodma_ch_set_param(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 v;
+
+	regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->ch.map),
+		     CDA2D_CHMXCTRL1_INDSIZE_INFINITE);
+
+	v = CDA2D_CHMXAMODE_ENDIAN_3210 |
+		CDA2D_CHMXAMODE_AUPDT_INC |
+		CDA2D_CHMXAMODE_TYPE_NORMAL |
+		(sub->swm->rb.map << CDA2D_CHMXAMODE_RSSEL_SHIFT);
+	if (sub->swm->dir == PORT_DIR_OUTPUT)
+		regmap_write(r, CDA2D_CHMXSRCAMODE(sub->swm->ch.map), v);
+	else
+		regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->ch.map), v);
+
+	return 0;
+}
+
+void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+
+	if (enable) {
+		regmap_write(r, CDA2D_STRT0,
+			     CDA2D_STRT0_STOP_START | BIT(sub->swm->ch.map));
+
+		regmap_update_bits(r, INTRBIM(0),
+				   BIT(sub->swm->rb.map),
+				   BIT(sub->swm->rb.map));
+	} else {
+		regmap_write(r, CDA2D_STRT0,
+			     CDA2D_STRT0_STOP_STOP | BIT(sub->swm->ch.map));
+
+		regmap_update_bits(r, INTRBIM(0),
+				   BIT(sub->swm->rb.map),
+				   0);
+	}
+}
+
+static u64 aiodma_rb_get_rp(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 pos_u, pos_l;
+	int i;
+
+	regmap_write(r, CDA2D_RDPTRLOAD,
+		     CDA2D_RDPTRLOAD_LSFLAG_STORE | BIT(sub->swm->rb.map));
+	/* Wait for setup */
+	for (i = 0; i < 6; i++)
+		regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &pos_l);
+
+	regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &pos_l);
+	regmap_read(r, CDA2D_RBMXRDPTRU(sub->swm->rb.map), &pos_u);
+	pos_u = FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK, pos_u);
+
+	return ((u64)pos_u << 32) | pos_l;
+}
+
+static void aiodma_rb_set_rp(struct uniphier_aio_sub *sub, u64 pos)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 tmp;
+	int i;
+
+	regmap_write(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), (u32)pos);
+	regmap_write(r, CDA2D_RBMXRDPTRU(sub->swm->rb.map), (u32)(pos >> 32));
+	regmap_write(r, CDA2D_RDPTRLOAD, BIT(sub->swm->rb.map));
+	/* Wait for setup */
+	for (i = 0; i < 6; i++)
+		regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &tmp);
+}
+
+static u64 aiodma_rb_get_wp(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 pos_u, pos_l;
+	int i;
+
+	regmap_write(r, CDA2D_WRPTRLOAD,
+		     CDA2D_WRPTRLOAD_LSFLAG_STORE | BIT(sub->swm->rb.map));
+	/* Wait for setup */
+	for (i = 0; i < 6; i++)
+		regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &pos_l);
+
+	regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &pos_l);
+	regmap_read(r, CDA2D_RBMXWRPTRU(sub->swm->rb.map), &pos_u);
+	pos_u = FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK, pos_u);
+
+	return ((u64)pos_u << 32) | pos_l;
+}
+
+static void aiodma_rb_set_wp(struct uniphier_aio_sub *sub, u64 pos)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 tmp;
+	int i;
+
+	regmap_write(r, CDA2D_RBMXWRPTR(sub->swm->rb.map),
+		     lower_32_bits(pos));
+	regmap_write(r, CDA2D_RBMXWRPTRU(sub->swm->rb.map),
+		     upper_32_bits(pos));
+	regmap_write(r, CDA2D_WRPTRLOAD, BIT(sub->swm->rb.map));
+	/* Wait for setup */
+	for (i = 0; i < 6; i++)
+		regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &tmp);
+}
+
+int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+
+	if (size <= th)
+		return -EINVAL;
+
+	regmap_write(r, CDA2D_RBMXBTH(sub->swm->rb.map), th);
+	regmap_write(r, CDA2D_RBMXRTH(sub->swm->rb.map), th);
+
+	return 0;
+}
+
+int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end,
+			 int period)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u64 size = end - start;
+	int ret;
+
+	if (end < start || period < 0)
+		return -EINVAL;
+
+	regmap_write(r, CDA2D_RBMXCNFG(sub->swm->rb.map), 0);
+	regmap_write(r, CDA2D_RBMXBGNADRS(sub->swm->rb.map),
+		     lower_32_bits(start));
+	regmap_write(r, CDA2D_RBMXBGNADRSU(sub->swm->rb.map),
+		     upper_32_bits(start));
+	regmap_write(r, CDA2D_RBMXENDADRS(sub->swm->rb.map),
+		     lower_32_bits(end));
+	regmap_write(r, CDA2D_RBMXENDADRSU(sub->swm->rb.map),
+		     upper_32_bits(end));
+
+	regmap_write(r, CDA2D_RBADRSLOAD, BIT(sub->swm->rb.map));
+
+	ret = aiodma_rb_set_threshold(sub, size, 2 * period);
+	if (ret)
+		return ret;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		aiodma_rb_set_rp(sub, start);
+		aiodma_rb_set_wp(sub, end - period);
+
+		regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map),
+				   CDA2D_RBMXIX_SPACE,
+				   CDA2D_RBMXIX_SPACE);
+	} else {
+		aiodma_rb_set_rp(sub, end - period);
+		aiodma_rb_set_wp(sub, start);
+
+		regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map),
+				   CDA2D_RBMXIX_REMAIN,
+				   CDA2D_RBMXIX_REMAIN);
+	}
+
+	sub->threshold = 2 * period;
+	sub->rd_offs = 0;
+	sub->wr_offs = 0;
+	sub->rd_org = 0;
+	sub->wr_org = 0;
+	sub->rd_total = 0;
+	sub->wr_total = 0;
+
+	return 0;
+}
+
+void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size,
+		    int period)
+{
+	if (sub->swm->dir == PORT_DIR_OUTPUT) {
+		sub->rd_offs = aiodma_rb_get_rp(sub) - start;
+
+		if (sub->use_mmap) {
+			sub->threshold = 2 * period;
+			aiodma_rb_set_threshold(sub, size, 2 * period);
+
+			sub->wr_offs = sub->rd_offs - period;
+			if (sub->rd_offs < period)
+				sub->wr_offs += size;
+		}
+		aiodma_rb_set_wp(sub, sub->wr_offs + start);
+	} else {
+		sub->wr_offs = aiodma_rb_get_wp(sub) - start;
+
+		if (sub->use_mmap) {
+			sub->threshold = 2 * period;
+			aiodma_rb_set_threshold(sub, size, 2 * period);
+
+			sub->rd_offs = sub->wr_offs - period;
+			if (sub->wr_offs < period)
+				sub->rd_offs += size;
+		}
+		aiodma_rb_set_rp(sub, sub->rd_offs + start);
+	}
+
+	sub->rd_total += sub->rd_offs - sub->rd_org;
+	if (sub->rd_offs < sub->rd_org)
+		sub->rd_total += size;
+	sub->wr_total += sub->wr_offs - sub->wr_org;
+	if (sub->wr_offs < sub->wr_org)
+		sub->wr_total += size;
+
+	sub->rd_org = sub->rd_offs;
+	sub->wr_org = sub->wr_offs;
+}
+
+bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+	u32 ir;
+
+	regmap_read(r, CDA2D_RBMXIR(sub->swm->rb.map), &ir);
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT)
+		return !!(ir & CDA2D_RBMXIX_SPACE);
+	else
+		return !!(ir & CDA2D_RBMXIX_REMAIN);
+}
+
+void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub)
+{
+	struct regmap *r = sub->aio->chip->regmap;
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT)
+		regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map),
+			     CDA2D_RBMXIX_SPACE);
+	else
+		regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map),
+			     CDA2D_RBMXIX_REMAIN);
+}
diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
new file mode 100644
index 0000000..1e5eb8e
--- /dev/null
+++ b/sound/soc/uniphier/aio-cpu.c
@@ -0,0 +1,578 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO ALSA CPU DAI driver.
+//
+// Copyright (c) 2016-2018 Socionext 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; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "aio.h"
+
+static bool is_valid_pll(struct uniphier_aio_chip *chip, int pll_id)
+{
+	struct device *dev = &chip->pdev->dev;
+
+	if (pll_id < 0 || chip->num_plls <= pll_id) {
+		dev_err(dev, "PLL(%d) is not supported\n", pll_id);
+		return false;
+	}
+
+	return chip->plls[pll_id].enable;
+}
+
+static bool match_spec(const struct uniphier_aio_spec *spec,
+		       const char *name, int dir)
+{
+	if (dir == SNDRV_PCM_STREAM_PLAYBACK &&
+	    spec->swm.dir != PORT_DIR_OUTPUT) {
+		return false;
+	}
+
+	if (dir == SNDRV_PCM_STREAM_CAPTURE &&
+	    spec->swm.dir != PORT_DIR_INPUT) {
+		return false;
+	}
+
+	if (spec->name && strcmp(spec->name, name) == 0)
+		return true;
+
+	if (spec->gname && strcmp(spec->gname, name) == 0)
+		return true;
+
+	return false;
+}
+
+/**
+ * find_spec - find HW specification info by name
+ * @aio: the AIO device pointer
+ * @name: name of device
+ * @direction: the direction of substream, SNDRV_PCM_STREAM_*
+ *
+ * Find hardware specification information from list by device name. This
+ * information is used for telling the difference of SoCs to driver.
+ *
+ * Specification list is array of 'struct uniphier_aio_spec' which is defined
+ * in each drivers (see: aio-i2s.c).
+ *
+ * Return: The pointer of hardware specification of AIO if successful,
+ * otherwise NULL on error.
+ */
+static const struct uniphier_aio_spec *find_spec(struct uniphier_aio *aio,
+						 const char *name,
+						 int direction)
+{
+	const struct uniphier_aio_chip_spec *chip_spec = aio->chip->chip_spec;
+	int i;
+
+	for (i = 0; i < chip_spec->num_specs; i++) {
+		const struct uniphier_aio_spec *spec = &chip_spec->specs[i];
+
+		if (match_spec(spec, name, direction))
+			return spec;
+	}
+
+	return NULL;
+}
+
+/**
+ * find_divider - find clock divider by frequency
+ * @aio: the AIO device pointer
+ * @pll_id: PLL ID, should be AUD_PLL_XX
+ * @freq: required frequency
+ *
+ * Find suitable clock divider by frequency.
+ *
+ * Return: The ID of PLL if successful, otherwise negative error value.
+ */
+static int find_divider(struct uniphier_aio *aio, int pll_id, unsigned int freq)
+{
+	struct uniphier_aio_pll *pll;
+	int mul[] = { 1, 1, 1, 2, };
+	int div[] = { 2, 3, 1, 3, };
+	int i;
+
+	if (!is_valid_pll(aio->chip, pll_id))
+		return -EINVAL;
+
+	pll = &aio->chip->plls[pll_id];
+	for (i = 0; i < ARRAY_SIZE(mul); i++)
+		if (pll->freq * mul[i] / div[i] == freq)
+			return i;
+
+	return -ENOTSUPP;
+}
+
+static int uniphier_aio_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+				   unsigned int freq, int dir)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	struct device *dev = &aio->chip->pdev->dev;
+	bool pll_auto = false;
+	int pll_id, div_id;
+
+	switch (clk_id) {
+	case AUD_CLK_IO:
+		return -ENOTSUPP;
+	case AUD_CLK_A1:
+		pll_id = AUD_PLL_A1;
+		break;
+	case AUD_CLK_F1:
+		pll_id = AUD_PLL_F1;
+		break;
+	case AUD_CLK_A2:
+		pll_id = AUD_PLL_A2;
+		break;
+	case AUD_CLK_F2:
+		pll_id = AUD_PLL_F2;
+		break;
+	case AUD_CLK_A:
+		pll_id = AUD_PLL_A1;
+		pll_auto = true;
+		break;
+	case AUD_CLK_F:
+		pll_id = AUD_PLL_F1;
+		pll_auto = true;
+		break;
+	case AUD_CLK_APLL:
+		pll_id = AUD_PLL_APLL;
+		break;
+	case AUD_CLK_RX0:
+		pll_id = AUD_PLL_RX0;
+		break;
+	case AUD_CLK_USB0:
+		pll_id = AUD_PLL_USB0;
+		break;
+	case AUD_CLK_HSC0:
+		pll_id = AUD_PLL_HSC0;
+		break;
+	default:
+		dev_err(dev, "Sysclk(%d) is not supported\n", clk_id);
+		return -EINVAL;
+	}
+
+	if (pll_auto) {
+		for (pll_id = 0; pll_id < aio->chip->num_plls; pll_id++) {
+			div_id = find_divider(aio, pll_id, freq);
+			if (div_id >= 0) {
+				aio->plldiv = div_id;
+				break;
+			}
+		}
+		if (pll_id == aio->chip->num_plls) {
+			dev_err(dev, "Sysclk frequency is not supported(%d)\n",
+				freq);
+			return -EINVAL;
+		}
+	}
+
+	if (dir == SND_SOC_CLOCK_OUT)
+		aio->pll_out = pll_id;
+	else
+		aio->pll_in = pll_id;
+
+	return 0;
+}
+
+static int uniphier_aio_set_pll(struct snd_soc_dai *dai, int pll_id,
+				int source, unsigned int freq_in,
+				unsigned int freq_out)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	struct device *dev = &aio->chip->pdev->dev;
+	int ret;
+
+	if (!is_valid_pll(aio->chip, pll_id))
+		return -EINVAL;
+	if (!aio->chip->plls[pll_id].enable) {
+		dev_err(dev, "PLL(%d) is not implemented\n", pll_id);
+		return -ENOTSUPP;
+	}
+
+	ret = aio_chip_set_pll(aio->chip, pll_id, freq_out);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int uniphier_aio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	struct device *dev = &aio->chip->pdev->dev;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_LEFT_J:
+	case SND_SOC_DAIFMT_RIGHT_J:
+	case SND_SOC_DAIFMT_I2S:
+		aio->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+		break;
+	default:
+		dev_err(dev, "Format is not supported(%d)\n",
+			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int uniphier_aio_startup(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+	int ret;
+
+	sub->substream = substream;
+	sub->pass_through = 0;
+	sub->use_mmap = true;
+
+	ret = aio_init(sub);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void uniphier_aio_shutdown(struct snd_pcm_substream *substream,
+				  struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+
+	sub->substream = NULL;
+}
+
+static int uniphier_aio_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+	struct device *dev = &aio->chip->pdev->dev;
+	int freq, ret;
+
+	switch (params_rate(params)) {
+	case 48000:
+	case 32000:
+	case 24000:
+		freq = 12288000;
+		break;
+	case 44100:
+	case 22050:
+		freq = 11289600;
+		break;
+	default:
+		dev_err(dev, "Rate is not supported(%d)\n",
+			params_rate(params));
+		return -EINVAL;
+	}
+	ret = snd_soc_dai_set_sysclk(dai, AUD_CLK_A,
+				     freq, SND_SOC_CLOCK_OUT);
+	if (ret)
+		return ret;
+
+	sub->params = *params;
+	sub->setting = 1;
+
+	aio_port_reset(sub);
+	aio_src_reset(sub);
+
+	return 0;
+}
+
+static int uniphier_aio_hw_free(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+
+	sub->setting = 0;
+
+	return 0;
+}
+
+static int uniphier_aio_prepare(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+	int ret;
+
+	ret = aio_port_set_param(sub, sub->pass_through, &sub->params);
+	if (ret)
+		return ret;
+	ret = aio_src_set_param(sub, &sub->params);
+	if (ret)
+		return ret;
+	aio_port_set_enable(sub, 1);
+
+	ret = aio_if_set_param(sub, sub->pass_through);
+	if (ret)
+		return ret;
+
+	if (sub->swm->type == PORT_TYPE_CONV) {
+		ret = aio_srcif_set_param(sub);
+		if (ret)
+			return ret;
+		ret = aio_srcch_set_param(sub);
+		if (ret)
+			return ret;
+		aio_srcch_set_enable(sub, 1);
+	}
+
+	return 0;
+}
+
+const struct snd_soc_dai_ops uniphier_aio_i2s_ops = {
+	.set_sysclk  = uniphier_aio_set_sysclk,
+	.set_pll     = uniphier_aio_set_pll,
+	.set_fmt     = uniphier_aio_set_fmt,
+	.startup     = uniphier_aio_startup,
+	.shutdown    = uniphier_aio_shutdown,
+	.hw_params   = uniphier_aio_hw_params,
+	.hw_free     = uniphier_aio_hw_free,
+	.prepare     = uniphier_aio_prepare,
+};
+EXPORT_SYMBOL_GPL(uniphier_aio_i2s_ops);
+
+const struct snd_soc_dai_ops uniphier_aio_spdif_ops = {
+	.set_sysclk  = uniphier_aio_set_sysclk,
+	.set_pll     = uniphier_aio_set_pll,
+	.startup     = uniphier_aio_startup,
+	.shutdown    = uniphier_aio_shutdown,
+	.hw_params   = uniphier_aio_hw_params,
+	.hw_free     = uniphier_aio_hw_free,
+	.prepare     = uniphier_aio_prepare,
+};
+EXPORT_SYMBOL_GPL(uniphier_aio_spdif_ops);
+
+int uniphier_aio_dai_probe(struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(aio->sub); i++) {
+		struct uniphier_aio_sub *sub = &aio->sub[i];
+		const struct uniphier_aio_spec *spec;
+
+		spec = find_spec(aio, dai->name, i);
+		if (!spec)
+			continue;
+
+		sub->swm = &spec->swm;
+		sub->spec = spec;
+	}
+
+	aio_iecout_set_enable(aio->chip, true);
+	aio_chip_init(aio->chip);
+	aio->chip->active = 1;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_dai_probe);
+
+int uniphier_aio_dai_remove(struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+
+	aio->chip->active = 0;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_dai_remove);
+
+int uniphier_aio_dai_suspend(struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+
+	reset_control_assert(aio->chip->rst);
+	clk_disable_unprepare(aio->chip->clk);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_dai_suspend);
+
+int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
+{
+	struct uniphier_aio *aio = uniphier_priv(dai);
+	int ret, i;
+
+	if (!aio->chip->active)
+		return 0;
+
+	ret = clk_prepare_enable(aio->chip->clk);
+	if (ret)
+		return ret;
+
+	ret = reset_control_deassert(aio->chip->rst);
+	if (ret)
+		goto err_out_clock;
+
+	aio_iecout_set_enable(aio->chip, true);
+	aio_chip_init(aio->chip);
+
+	for (i = 0; i < ARRAY_SIZE(aio->sub); i++) {
+		struct uniphier_aio_sub *sub = &aio->sub[i];
+
+		if (!sub->spec || !sub->substream)
+			continue;
+
+		ret = aio_init(sub);
+		if (ret)
+			goto err_out_clock;
+
+		if (!sub->setting)
+			continue;
+
+		aio_port_reset(sub);
+		aio_src_reset(sub);
+	}
+
+	return 0;
+
+err_out_clock:
+	clk_disable_unprepare(aio->chip->clk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_dai_resume);
+
+static const struct snd_soc_component_driver uniphier_aio_component = {
+	.name = "uniphier-aio",
+};
+
+int uniphier_aio_probe(struct platform_device *pdev)
+{
+	struct uniphier_aio_chip *chip;
+	struct device *dev = &pdev->dev;
+	int ret, i, j;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->chip_spec = of_device_get_match_data(dev);
+	if (!chip->chip_spec)
+		return -EINVAL;
+
+	chip->regmap_sg = syscon_regmap_lookup_by_phandle(dev->of_node,
+							  "socionext,syscon");
+	if (IS_ERR(chip->regmap_sg)) {
+		if (PTR_ERR(chip->regmap_sg) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		chip->regmap_sg = NULL;
+	}
+
+	chip->clk = devm_clk_get(dev, "aio");
+	if (IS_ERR(chip->clk))
+		return PTR_ERR(chip->clk);
+
+	chip->rst = devm_reset_control_get_shared(dev, "aio");
+	if (IS_ERR(chip->rst))
+		return PTR_ERR(chip->rst);
+
+	chip->num_aios = chip->chip_spec->num_dais;
+	chip->aios = devm_kzalloc(dev,
+				  sizeof(struct uniphier_aio) * chip->num_aios,
+				  GFP_KERNEL);
+	if (!chip->aios)
+		return -ENOMEM;
+
+	chip->num_plls = chip->chip_spec->num_plls;
+	chip->plls = devm_kzalloc(dev, sizeof(struct uniphier_aio_pll) *
+				  chip->num_plls, GFP_KERNEL);
+	if (!chip->plls)
+		return -ENOMEM;
+	memcpy(chip->plls, chip->chip_spec->plls,
+	       sizeof(struct uniphier_aio_pll) * chip->num_plls);
+
+	for (i = 0; i < chip->num_aios; i++) {
+		struct uniphier_aio *aio = &chip->aios[i];
+
+		aio->chip = chip;
+		aio->fmt = SND_SOC_DAIFMT_I2S;
+
+		for (j = 0; j < ARRAY_SIZE(aio->sub); j++) {
+			struct uniphier_aio_sub *sub = &aio->sub[j];
+
+			sub->aio = aio;
+			spin_lock_init(&sub->lock);
+		}
+	}
+
+	chip->pdev = pdev;
+	platform_set_drvdata(pdev, chip);
+
+	ret = clk_prepare_enable(chip->clk);
+	if (ret)
+		return ret;
+
+	ret = reset_control_deassert(chip->rst);
+	if (ret)
+		goto err_out_clock;
+
+	ret = devm_snd_soc_register_component(dev, &uniphier_aio_component,
+					      chip->chip_spec->dais,
+					      chip->chip_spec->num_dais);
+	if (ret) {
+		dev_err(dev, "Register component failed.\n");
+		goto err_out_reset;
+	}
+
+	ret = uniphier_aiodma_soc_register_platform(pdev);
+	if (ret) {
+		dev_err(dev, "Register platform failed.\n");
+		goto err_out_reset;
+	}
+
+	return 0;
+
+err_out_reset:
+	reset_control_assert(chip->rst);
+
+err_out_clock:
+	clk_disable_unprepare(chip->clk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_probe);
+
+int uniphier_aio_remove(struct platform_device *pdev)
+{
+	struct uniphier_aio_chip *chip = platform_get_drvdata(pdev);
+
+	reset_control_assert(chip->rst);
+	clk_disable_unprepare(chip->clk);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_remove);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("UniPhier AIO CPU DAI driver.");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/uniphier/aio-dma.c b/sound/soc/uniphier/aio-dma.c
new file mode 100644
index 0000000..ef7bafa
--- /dev/null
+++ b/sound/soc/uniphier/aio-dma.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO DMA driver.
+//
+// Copyright (c) 2016-2018 Socionext 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; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "aio.h"
+
+static struct snd_pcm_hardware uniphier_aiodma_hw = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_INTERLEAVED,
+	.period_bytes_min = 256,
+	.period_bytes_max = 4096,
+	.periods_min      = 4,
+	.periods_max      = 1024,
+	.buffer_bytes_max = 128 * 1024,
+};
+
+static void aiodma_pcm_irq(struct uniphier_aio_sub *sub)
+{
+	struct snd_pcm_runtime *runtime = sub->substream->runtime;
+	int bytes = runtime->period_size *
+		runtime->channels * samples_to_bytes(runtime, 1);
+	int ret;
+
+	spin_lock(&sub->lock);
+	ret = aiodma_rb_set_threshold(sub, runtime->dma_bytes,
+				      sub->threshold + bytes);
+	if (!ret)
+		sub->threshold += bytes;
+
+	aiodma_rb_sync(sub, runtime->dma_addr, runtime->dma_bytes, bytes);
+	aiodma_rb_clear_irq(sub);
+	spin_unlock(&sub->lock);
+
+	snd_pcm_period_elapsed(sub->substream);
+}
+
+static void aiodma_compr_irq(struct uniphier_aio_sub *sub)
+{
+	struct snd_compr_runtime *runtime = sub->cstream->runtime;
+	int bytes = runtime->fragment_size;
+	int ret;
+
+	spin_lock(&sub->lock);
+	ret = aiodma_rb_set_threshold(sub, sub->compr_bytes,
+				      sub->threshold + bytes);
+	if (!ret)
+		sub->threshold += bytes;
+
+	aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
+	aiodma_rb_clear_irq(sub);
+	spin_unlock(&sub->lock);
+
+	snd_compr_fragment_elapsed(sub->cstream);
+}
+
+static irqreturn_t aiodma_irq(int irq, void *p)
+{
+	struct platform_device *pdev = p;
+	struct uniphier_aio_chip *chip = platform_get_drvdata(pdev);
+	irqreturn_t ret = IRQ_NONE;
+	int i, j;
+
+	for (i = 0; i < chip->num_aios; i++) {
+		struct uniphier_aio *aio = &chip->aios[i];
+
+		for (j = 0; j < ARRAY_SIZE(aio->sub); j++) {
+			struct uniphier_aio_sub *sub = &aio->sub[j];
+
+			/* Skip channel that does not trigger */
+			if (!sub->running || !aiodma_rb_is_irq(sub))
+				continue;
+
+			if (sub->substream)
+				aiodma_pcm_irq(sub);
+			if (sub->cstream)
+				aiodma_compr_irq(sub);
+
+			ret = IRQ_HANDLED;
+		}
+	}
+
+	return ret;
+}
+
+static int uniphier_aiodma_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	snd_soc_set_runtime_hwparams(substream, &uniphier_aiodma_hw);
+
+	return snd_pcm_hw_constraint_step(runtime, 0,
+		SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256);
+}
+
+static int uniphier_aiodma_hw_params(struct snd_pcm_substream *substream,
+				     struct snd_pcm_hw_params *params)
+{
+	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+	substream->runtime->dma_bytes = params_buffer_bytes(params);
+
+	return 0;
+}
+
+static int uniphier_aiodma_hw_free(struct snd_pcm_substream *substream)
+{
+	snd_pcm_set_runtime_buffer(substream, NULL);
+	substream->runtime->dma_bytes = 0;
+
+	return 0;
+}
+
+static int uniphier_aiodma_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+	int bytes = runtime->period_size *
+		runtime->channels * samples_to_bytes(runtime, 1);
+	unsigned long flags;
+	int ret;
+
+	ret = aiodma_ch_set_param(sub);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&sub->lock, flags);
+	ret = aiodma_rb_set_buffer(sub, runtime->dma_addr,
+				   runtime->dma_addr + runtime->dma_bytes,
+				   bytes);
+	spin_unlock_irqrestore(&sub->lock, flags);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int uniphier_aiodma_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+	struct device *dev = &aio->chip->pdev->dev;
+	int bytes = runtime->period_size *
+		runtime->channels * samples_to_bytes(runtime, 1);
+	unsigned long flags;
+
+	spin_lock_irqsave(&sub->lock, flags);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		aiodma_rb_sync(sub, runtime->dma_addr, runtime->dma_bytes,
+			       bytes);
+		aiodma_ch_set_enable(sub, 1);
+		sub->running = 1;
+
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		sub->running = 0;
+		aiodma_ch_set_enable(sub, 0);
+
+		break;
+	default:
+		dev_warn(dev, "Unknown trigger(%d) ignored\n", cmd);
+		break;
+	}
+	spin_unlock_irqrestore(&sub->lock, flags);
+
+	return 0;
+}
+
+static snd_pcm_uframes_t uniphier_aiodma_pointer(
+					struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+	struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+	struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+	int bytes = runtime->period_size *
+		runtime->channels * samples_to_bytes(runtime, 1);
+	unsigned long flags;
+	snd_pcm_uframes_t pos;
+
+	spin_lock_irqsave(&sub->lock, flags);
+	aiodma_rb_sync(sub, runtime->dma_addr, runtime->dma_bytes, bytes);
+
+	if (sub->swm->dir == PORT_DIR_OUTPUT)
+		pos = bytes_to_frames(runtime, sub->rd_offs);
+	else
+		pos = bytes_to_frames(runtime, sub->wr_offs);
+	spin_unlock_irqrestore(&sub->lock, flags);
+
+	return pos;
+}
+
+static int uniphier_aiodma_mmap(struct snd_pcm_substream *substream,
+				struct vm_area_struct *vma)
+{
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+	return remap_pfn_range(vma, vma->vm_start,
+			       substream->dma_buffer.addr >> PAGE_SHIFT,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
+static const struct snd_pcm_ops uniphier_aiodma_ops = {
+	.open      = uniphier_aiodma_open,
+	.ioctl     = snd_pcm_lib_ioctl,
+	.hw_params = uniphier_aiodma_hw_params,
+	.hw_free   = uniphier_aiodma_hw_free,
+	.prepare   = uniphier_aiodma_prepare,
+	.trigger   = uniphier_aiodma_trigger,
+	.pointer   = uniphier_aiodma_pointer,
+	.mmap      = uniphier_aiodma_mmap,
+};
+
+static int uniphier_aiodma_new(struct snd_soc_pcm_runtime *rtd)
+{
+	struct device *dev = rtd->card->snd_card->dev;
+	struct snd_pcm *pcm = rtd->pcm;
+	int ret;
+
+	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));
+	if (ret)
+		return ret;
+
+	return snd_pcm_lib_preallocate_pages_for_all(pcm,
+		SNDRV_DMA_TYPE_DEV, dev,
+		uniphier_aiodma_hw.buffer_bytes_max,
+		uniphier_aiodma_hw.buffer_bytes_max);
+}
+
+static void uniphier_aiodma_free(struct snd_pcm *pcm)
+{
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static const struct snd_soc_component_driver uniphier_soc_platform = {
+	.pcm_new   = uniphier_aiodma_new,
+	.pcm_free  = uniphier_aiodma_free,
+	.ops       = &uniphier_aiodma_ops,
+	.compr_ops = &uniphier_aio_compr_ops,
+};
+
+static const struct regmap_config aiodma_regmap_config = {
+	.reg_bits      = 32,
+	.reg_stride    = 4,
+	.val_bits      = 32,
+	.max_register  = 0x7fffc,
+	.cache_type    = REGCACHE_NONE,
+};
+
+/**
+ * uniphier_aiodma_soc_register_platform - register the AIO DMA
+ * @pdev: the platform device
+ *
+ * Register and setup the DMA of AIO to transfer the sound data to device.
+ * This function need to call once at driver startup and need NOT to call
+ * unregister function.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int uniphier_aiodma_soc_register_platform(struct platform_device *pdev)
+{
+	struct uniphier_aio_chip *chip = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	void __iomem *preg;
+	int irq, ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	preg = devm_ioremap_resource(dev, res);
+	if (IS_ERR(preg))
+		return PTR_ERR(preg);
+
+	chip->regmap = devm_regmap_init_mmio(dev, preg,
+					     &aiodma_regmap_config);
+	if (IS_ERR(chip->regmap))
+		return PTR_ERR(chip->regmap);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "Could not get irq.\n");
+		return irq;
+	}
+
+	ret = devm_request_irq(dev, irq, aiodma_irq,
+			       IRQF_SHARED, dev_name(dev), pdev);
+	if (ret)
+		return ret;
+
+	return devm_snd_soc_register_component(dev, &uniphier_soc_platform,
+					       NULL, 0);
+}
+EXPORT_SYMBOL_GPL(uniphier_aiodma_soc_register_platform);
diff --git a/sound/soc/uniphier/aio-ld11.c b/sound/soc/uniphier/aio-ld11.c
new file mode 100644
index 0000000..4c4dd3d
--- /dev/null
+++ b/sound/soc/uniphier/aio-ld11.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO ALSA driver for LD11/LD20.
+//
+// Copyright (c) 2016-2018 Socionext 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; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+#include <linux/module.h>
+
+#include "aio.h"
+
+static const struct uniphier_aio_spec uniphier_aio_ld11[] = {
+	/* for HDMI PCM In, Pin:AI1Dx */
+	{
+		.name = AUD_NAME_PCMIN1,
+		.gname = AUD_GNAME_HDMI,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_INPUT,
+			.rb    = { 21, 14, },
+			.ch    = { 21, 14, },
+			.iif   = { 5, 3, },
+			.iport = { 0, AUD_HW_PCMIN1, },
+		},
+	},
+
+	/* for SIF In, Pin:AI2Dx */
+	{
+		.name = AUD_NAME_PCMIN2,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_INPUT,
+			.rb    = { 22, 15, },
+			.ch    = { 22, 15, },
+			.iif   = { 6, 4, },
+			.iport = { 1, AUD_HW_PCMIN2, },
+		},
+	},
+
+	/* for Line In, Pin:AI3Dx */
+	{
+		.name = AUD_NAME_PCMIN3,
+		.gname = AUD_GNAME_LINE,
+		.swm = {
+			.type  = PORT_TYPE_EVE,
+			.dir   = PORT_DIR_INPUT,
+			.rb    = { 23, 16, },
+			.ch    = { 23, 16, },
+			.iif   = { 7, 5, },
+			.iport = { 2, AUD_HW_PCMIN3, },
+		},
+	},
+
+	/* for S/PDIF In, Pin:AI1IEC */
+	{
+		.name = AUD_NAME_IECIN1,
+		.gname = AUD_GNAME_IEC,
+		.swm = {
+			.type  = PORT_TYPE_SPDIF,
+			.dir   = PORT_DIR_INPUT,
+			.rb    = { 26, 17, },
+			.ch    = { 26, 17, },
+			.iif   = { 10, 6, },
+			.iport = { 3, AUD_HW_IECIN1, },
+		},
+	},
+
+	/* for Speaker, Pin:AO1Dx */
+	{
+		.name = AUD_NAME_HPCMOUT1,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 0, 0, },
+			.ch    = { 0, 0, },
+			.oif   = { 0, 0, },
+			.oport = { 0, AUD_HW_HPCMOUT1, },
+		},
+	},
+
+	/* for HDMI PCM, Pin:AO2Dx */
+	{
+		.name = AUD_NAME_PCMOUT1,
+		.gname = AUD_GNAME_HDMI,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 0, 0, },
+			.ch    = { 0, 0, },
+			.oif   = { 0, 0, },
+			.oport = { 3, AUD_HW_PCMOUT1, },
+		},
+	},
+
+	/* for Line Out, Pin:LO2_x */
+	{
+		.name = AUD_NAME_PCMOUT2,
+		.gname = AUD_GNAME_LINE,
+		.swm = {
+			.type  = PORT_TYPE_EVE,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 2, 2, },
+			.ch    = { 2, 2, },
+			.oif   = { 2, 2, },
+			.oport = { 1, AUD_HW_PCMOUT2, },
+		},
+	},
+
+	/* for Headphone, Pin:HP1_x */
+	{
+		.name = AUD_NAME_PCMOUT3,
+		.swm = {
+			.type  = PORT_TYPE_EVE,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 3, 3, },
+			.ch    = { 3, 3, },
+			.oif   = { 3, 3, },
+			.oport = { 2, AUD_HW_PCMOUT3, },
+		},
+	},
+
+	/* for HW Sampling Rate Converter */
+	{
+		.name = AUD_NAME_EPCMOUT2,
+		.swm = {
+			.type  = PORT_TYPE_CONV,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 7, 5, },
+			.ch    = { 7, 5, },
+			.oif   = { 7, 5, },
+			.oport = { 6, AUD_HW_EPCMOUT2, },
+			.och   = { 17, 12, },
+			.iif   = { 1, 1, },
+		},
+	},
+
+	/* for HW Sampling Rate Converter 2 */
+	{
+		.name = AUD_NAME_EPCMOUT3,
+		.swm = {
+			.type  = PORT_TYPE_CONV,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 8, 6, },
+			.ch    = { 8, 6, },
+			.oif   = { 8, 6, },
+			.oport = { 7, AUD_HW_EPCMOUT3, },
+			.och   = { 18, 13, },
+			.iif   = { 2, 2, },
+		},
+	},
+
+	/* for S/PDIF Out, Pin:AO1IEC */
+	{
+		.name = AUD_NAME_HIECOUT1,
+		.gname = AUD_GNAME_IEC,
+		.swm = {
+			.type  = PORT_TYPE_SPDIF,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 1, 1, },
+			.ch    = { 1, 1, },
+			.oif   = { 1, 1, },
+			.oport = { 12, AUD_HW_HIECOUT1, },
+		},
+	},
+
+	/* for S/PDIF Out, Pin:AO1IEC, Compress */
+	{
+		.name = AUD_NAME_HIECCOMPOUT1,
+		.gname = AUD_GNAME_IEC,
+		.swm = {
+			.type  = PORT_TYPE_SPDIF,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 1, 1, },
+			.ch    = { 1, 1, },
+			.oif   = { 1, 1, },
+			.oport = { 12, AUD_HW_HIECOUT1, },
+		},
+	},
+};
+
+static const struct uniphier_aio_pll uniphier_aio_pll_ld11[] = {
+	[AUD_PLL_A1]   = { .enable = true, },
+	[AUD_PLL_F1]   = { .enable = true, },
+	[AUD_PLL_A2]   = { .enable = true, },
+	[AUD_PLL_F2]   = { .enable = true, },
+	[AUD_PLL_APLL] = { .enable = true, },
+	[AUD_PLL_RX0]  = { .enable = true, },
+	[AUD_PLL_USB0] = { .enable = true, },
+	[AUD_PLL_HSC0] = { .enable = true, },
+};
+
+static int uniphier_aio_ld11_probe(struct snd_soc_dai *dai)
+{
+	int ret;
+
+	ret = uniphier_aio_dai_probe(dai);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
+	if (ret < 0)
+		return ret;
+	ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
+	if (ret < 0)
+		return ret;
+	ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct snd_soc_dai_driver uniphier_aio_dai_ld11[] = {
+	{
+		.name    = AUD_GNAME_HDMI,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_PCMOUT1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.capture = {
+			.stream_name = AUD_NAME_PCMIN1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000 |
+				SNDRV_PCM_RATE_44100 |
+				SNDRV_PCM_RATE_32000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_NAME_PCMIN2,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.capture = {
+			.stream_name = AUD_NAME_PCMIN2,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_GNAME_LINE,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_PCMOUT2,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.capture = {
+			.stream_name = AUD_NAME_PCMIN3,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_NAME_HPCMOUT1,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_HPCMOUT1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_NAME_PCMOUT3,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_PCMOUT3,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_NAME_HIECOUT1,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_HIECOUT1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_spdif_ops,
+	},
+	{
+		.name    = AUD_NAME_EPCMOUT2,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_EPCMOUT2,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000 |
+				SNDRV_PCM_RATE_44100 |
+				SNDRV_PCM_RATE_32000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_NAME_EPCMOUT3,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_EPCMOUT3,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000 |
+				SNDRV_PCM_RATE_44100 |
+				SNDRV_PCM_RATE_32000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_NAME_HIECCOMPOUT1,
+		.probe   = uniphier_aio_ld11_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.compress_new = snd_soc_new_compress,
+		.playback = {
+			.stream_name = AUD_NAME_HIECCOMPOUT1,
+			.channels_min = 1,
+			.channels_max = 1,
+		},
+		.ops = &uniphier_aio_spdif_ops,
+	},
+};
+
+static const struct uniphier_aio_chip_spec uniphier_aio_ld11_spec = {
+	.specs     = uniphier_aio_ld11,
+	.num_specs = ARRAY_SIZE(uniphier_aio_ld11),
+	.dais      = uniphier_aio_dai_ld11,
+	.num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
+	.plls      = uniphier_aio_pll_ld11,
+	.num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
+	.addr_ext  = 0,
+};
+
+static const struct uniphier_aio_chip_spec uniphier_aio_ld20_spec = {
+	.specs     = uniphier_aio_ld11,
+	.num_specs = ARRAY_SIZE(uniphier_aio_ld11),
+	.dais      = uniphier_aio_dai_ld11,
+	.num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
+	.plls      = uniphier_aio_pll_ld11,
+	.num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
+	.addr_ext  = 1,
+};
+
+static const struct of_device_id uniphier_aio_of_match[] = {
+	{
+		.compatible = "socionext,uniphier-ld11-aio",
+		.data = &uniphier_aio_ld11_spec,
+	},
+	{
+		.compatible = "socionext,uniphier-ld20-aio",
+		.data = &uniphier_aio_ld20_spec,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
+
+static struct platform_driver uniphier_aio_driver = {
+	.driver = {
+		.name = "snd-uniphier-aio-ld11",
+		.of_match_table = of_match_ptr(uniphier_aio_of_match),
+	},
+	.probe    = uniphier_aio_probe,
+	.remove   = uniphier_aio_remove,
+};
+module_platform_driver(uniphier_aio_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("UniPhier LD11/LD20 AIO driver.");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/uniphier/aio-pxs2.c b/sound/soc/uniphier/aio-pxs2.c
new file mode 100644
index 0000000..69cd5b0
--- /dev/null
+++ b/sound/soc/uniphier/aio-pxs2.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO ALSA driver for PXs2.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/module.h>
+
+#include "aio.h"
+
+static const struct uniphier_aio_spec uniphier_aio_pxs2[] = {
+	/* for Line PCM In, Pin:AI1Dx */
+	{
+		.name = AUD_NAME_PCMIN1,
+		.gname = AUD_GNAME_LINE,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_INPUT,
+			.rb    = { 16, 11, },
+			.ch    = { 16, 11, },
+			.iif   = { 0, 0, },
+			.iport = { 0, AUD_HW_PCMIN1, },
+		},
+	},
+
+	/* for Speaker/Headphone/Mic PCM In, Pin:AI2Dx */
+	{
+		.name = AUD_NAME_PCMIN2,
+		.gname = AUD_GNAME_AUX,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_INPUT,
+			.rb    = { 17, 12, },
+			.ch    = { 17, 12, },
+			.iif   = { 1, 1, },
+			.iport = { 1, AUD_HW_PCMIN2, },
+		},
+	},
+
+	/* for HDMI PCM Out, Pin:AO1Dx (inner) */
+	{
+		.name = AUD_NAME_HPCMOUT1,
+		.gname = AUD_GNAME_HDMI,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 0, 0, },
+			.ch    = { 0, 0, },
+			.oif   = { 0, 0, },
+			.oport = { 3, AUD_HW_HPCMOUT1, },
+		},
+	},
+
+	/* for Line PCM Out, Pin:AO2Dx */
+	{
+		.name = AUD_NAME_PCMOUT1,
+		.gname = AUD_GNAME_LINE,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 1, 1, },
+			.ch    = { 1, 1, },
+			.oif   = { 1, 1, },
+			.oport = { 0, AUD_HW_PCMOUT1, },
+		},
+	},
+
+	/* for Speaker/Headphone/Mic PCM Out, Pin:AO3Dx */
+	{
+		.name = AUD_NAME_PCMOUT2,
+		.gname = AUD_GNAME_AUX,
+		.swm = {
+			.type  = PORT_TYPE_I2S,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 2, 2, },
+			.ch    = { 2, 2, },
+			.oif   = { 2, 2, },
+			.oport = { 1, AUD_HW_PCMOUT2, },
+		},
+	},
+
+	/* for HDMI Out, Pin:AO1IEC */
+	{
+		.name = AUD_NAME_HIECOUT1,
+		.swm = {
+			.type  = PORT_TYPE_SPDIF,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 6, 4, },
+			.ch    = { 6, 4, },
+			.oif   = { 6, 4, },
+			.oport = { 12, AUD_HW_HIECOUT1, },
+		},
+	},
+
+	/* for HDMI Out, Pin:AO1IEC, Compress */
+	{
+		.name = AUD_NAME_HIECCOMPOUT1,
+		.swm = {
+			.type  = PORT_TYPE_SPDIF,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 6, 4, },
+			.ch    = { 6, 4, },
+			.oif   = { 6, 4, },
+			.oport = { 12, AUD_HW_HIECOUT1, },
+		},
+	},
+
+	/* for S/PDIF Out, Pin:AO2IEC */
+	{
+		.name = AUD_NAME_IECOUT1,
+		.swm = {
+			.type  = PORT_TYPE_SPDIF,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 7, 5, },
+			.ch    = { 7, 5, },
+			.oif   = { 7, 5, },
+			.oport = { 13, AUD_HW_IECOUT1, },
+		},
+	},
+
+	/* for S/PDIF Out, Pin:AO2IEC */
+	{
+		.name = AUD_NAME_IECCOMPOUT1,
+		.swm = {
+			.type  = PORT_TYPE_SPDIF,
+			.dir   = PORT_DIR_OUTPUT,
+			.rb    = { 7, 5, },
+			.ch    = { 7, 5, },
+			.oif   = { 7, 5, },
+			.oport = { 13, AUD_HW_IECOUT1, },
+		},
+	},
+};
+
+static const struct uniphier_aio_pll uniphier_aio_pll_pxs2[] = {
+	[AUD_PLL_A1]   = { .enable = true, },
+	[AUD_PLL_F1]   = { .enable = true, },
+	[AUD_PLL_A2]   = { .enable = true, },
+	[AUD_PLL_F2]   = { .enable = true, },
+	[AUD_PLL_APLL] = { .enable = true, },
+	[AUD_PLL_HSC0] = { .enable = true, },
+};
+
+static int uniphier_aio_pxs2_probe(struct snd_soc_dai *dai)
+{
+	int ret;
+
+	ret = uniphier_aio_dai_probe(dai);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
+	if (ret < 0)
+		return ret;
+	ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
+	if (ret < 0)
+		return ret;
+	ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct snd_soc_dai_driver uniphier_aio_dai_pxs2[] = {
+	{
+		.name    = AUD_GNAME_HDMI,
+		.probe   = uniphier_aio_pxs2_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_HPCMOUT1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_GNAME_LINE,
+		.probe   = uniphier_aio_pxs2_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_PCMOUT1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.capture = {
+			.stream_name = AUD_NAME_PCMIN1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_GNAME_AUX,
+		.probe   = uniphier_aio_pxs2_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_PCMOUT2,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.capture = {
+			.stream_name = AUD_NAME_PCMIN2,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_i2s_ops,
+	},
+	{
+		.name    = AUD_NAME_HIECOUT1,
+		.probe   = uniphier_aio_pxs2_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_HIECOUT1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_spdif_ops,
+	},
+	{
+		.name    = AUD_NAME_IECOUT1,
+		.probe   = uniphier_aio_pxs2_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.playback = {
+			.stream_name = AUD_NAME_IECOUT1,
+			.formats     = SNDRV_PCM_FMTBIT_S32_LE,
+			.rates       = SNDRV_PCM_RATE_48000,
+			.channels_min = 2,
+			.channels_max = 2,
+		},
+		.ops = &uniphier_aio_spdif_ops,
+	},
+	{
+		.name    = AUD_NAME_HIECCOMPOUT1,
+		.probe   = uniphier_aio_pxs2_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.compress_new = snd_soc_new_compress,
+		.playback = {
+			.stream_name = AUD_NAME_HIECCOMPOUT1,
+			.channels_min = 1,
+			.channels_max = 1,
+		},
+		.ops = &uniphier_aio_spdif_ops,
+	},
+	{
+		.name    = AUD_NAME_IECCOMPOUT1,
+		.probe   = uniphier_aio_pxs2_probe,
+		.remove  = uniphier_aio_dai_remove,
+		.suspend = uniphier_aio_dai_suspend,
+		.resume  = uniphier_aio_dai_resume,
+		.compress_new = snd_soc_new_compress,
+		.playback = {
+			.stream_name = AUD_NAME_IECCOMPOUT1,
+			.channels_min = 1,
+			.channels_max = 1,
+		},
+		.ops = &uniphier_aio_spdif_ops,
+	},
+};
+
+static const struct uniphier_aio_chip_spec uniphier_aio_pxs2_spec = {
+	.specs     = uniphier_aio_pxs2,
+	.num_specs = ARRAY_SIZE(uniphier_aio_pxs2),
+	.dais      = uniphier_aio_dai_pxs2,
+	.num_dais  = ARRAY_SIZE(uniphier_aio_dai_pxs2),
+	.plls      = uniphier_aio_pll_pxs2,
+	.num_plls  = ARRAY_SIZE(uniphier_aio_pll_pxs2),
+	.addr_ext  = 0,
+};
+
+static const struct of_device_id uniphier_aio_of_match[] = {
+	{
+		.compatible = "socionext,uniphier-pxs2-aio",
+		.data = &uniphier_aio_pxs2_spec,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
+
+static struct platform_driver uniphier_aio_driver = {
+	.driver = {
+		.name = "snd-uniphier-aio-pxs2",
+		.of_match_table = of_match_ptr(uniphier_aio_of_match),
+	},
+	.probe    = uniphier_aio_probe,
+	.remove   = uniphier_aio_remove,
+};
+module_platform_driver(uniphier_aio_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("UniPhier PXs2 AIO driver.");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/uniphier/aio-reg.h b/sound/soc/uniphier/aio-reg.h
new file mode 100644
index 0000000..136d356
--- /dev/null
+++ b/sound/soc/uniphier/aio-reg.h
@@ -0,0 +1,465 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Socionext UniPhier AIO ALSA driver.
+ *
+ * Copyright (c) 2016-2018 Socionext 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; version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SND_UNIPHIER_AIO_REG_H__
+#define SND_UNIPHIER_AIO_REG_H__
+
+#include <linux/bitops.h>
+
+/* soc-glue */
+#define SG_AOUTEN                       0x1c04
+
+/* SW view */
+#define A2CHNMAPCTR0(n)                 (0x00000 + 0x40 * (n))
+#define A2RBNMAPCTR0(n)                 (0x01000 + 0x40 * (n))
+#define A2IPORTNMAPCTR0(n)              (0x02000 + 0x40 * (n))
+#define A2IPORTNMAPCTR1(n)              (0x02004 + 0x40 * (n))
+#define A2IIFNMAPCTR0(n)                (0x03000 + 0x40 * (n))
+#define A2OPORTNMAPCTR0(n)              (0x04000 + 0x40 * (n))
+#define A2OPORTNMAPCTR1(n)              (0x04004 + 0x40 * (n))
+#define A2OPORTNMAPCTR2(n)              (0x04008 + 0x40 * (n))
+#define A2OIFNMAPCTR0(n)                (0x05000 + 0x40 * (n))
+#define A2ATNMAPCTR0(n)                 (0x06000 + 0x40 * (n))
+
+#define MAPCTR0_EN                      0x80000000
+
+/* CTL */
+#define A2APLLCTR0                      0x07000
+#define   A2APLLCTR0_APLLXPOW_MASK        GENMASK(3, 0)
+#define   A2APLLCTR0_APLLXPOW_PWOFF       (0x0 << 0)
+#define   A2APLLCTR0_APLLXPOW_PWON        (0xf << 0)
+#define A2APLLCTR1                      0x07004
+#define   A2APLLCTR1_APLLX_MASK           0x00010101
+#define   A2APLLCTR1_APLLX_36MHZ          0x00000000
+#define   A2APLLCTR1_APLLX_33MHZ          0x00000001
+#define A2EXMCLKSEL0                    0x07030
+#define   A2EXMCLKSEL0_EXMCLK_MASK        GENMASK(2, 0)
+#define   A2EXMCLKSEL0_EXMCLK_OUTPUT      (0x0 << 0)
+#define   A2EXMCLKSEL0_EXMCLK_INPUT       (0x7 << 0)
+#define A2SSIFSW                        0x07050
+#define A2CH22_2CTR                     0x07054
+#define A2AIOINPUTSEL                   0x070e0
+#define   A2AIOINPUTSEL_RXSEL_PCMI1_MASK      GENMASK(2, 0)
+#define   A2AIOINPUTSEL_RXSEL_PCMI1_HDMIRX1   (0x2 << 0)
+#define   A2AIOINPUTSEL_RXSEL_PCMI2_MASK      GENMASK(6, 4)
+#define   A2AIOINPUTSEL_RXSEL_PCMI2_SIF       (0x7 << 4)
+#define   A2AIOINPUTSEL_RXSEL_PCMI3_MASK      GENMASK(10, 8)
+#define   A2AIOINPUTSEL_RXSEL_PCMI3_EVEA      (0x1 << 8)
+#define   A2AIOINPUTSEL_RXSEL_IECI1_MASK      GENMASK(14, 12)
+#define   A2AIOINPUTSEL_RXSEL_IECI1_HDMIRX1   (0x2 << 12)
+#define   A2AIOINPUTSEL_RXSEL_MASK        (A2AIOINPUTSEL_RXSEL_PCMI1_MASK | \
+					   A2AIOINPUTSEL_RXSEL_PCMI2_MASK | \
+					   A2AIOINPUTSEL_RXSEL_PCMI3_MASK | \
+					   A2AIOINPUTSEL_RXSEL_IECI1_HDMIRX1)
+
+/* INTC */
+#define INTCHIM(m)                       (0x9028 + 0x80 * (m))
+#define INTRBIM(m)                       (0x9030 + 0x80 * (m))
+#define INTCHID(m)                       (0xa028 + 0x80 * (m))
+#define INTRBID(m)                       (0xa030 + 0x80 * (m))
+
+/* AIN(PCMINN) */
+#define IPORTMXCTR1(n)                   (0x22000 + 0x400 * (n))
+#define   IPORTMXCTR1_LRSEL_MASK           GENMASK(11, 10)
+#define   IPORTMXCTR1_LRSEL_RIGHT          (0x0 << 10)
+#define   IPORTMXCTR1_LRSEL_LEFT           (0x1 << 10)
+#define   IPORTMXCTR1_LRSEL_I2S            (0x2 << 10)
+#define   IPORTMXCTR1_OUTBITSEL_MASK       (0x800003U << 8)
+#define   IPORTMXCTR1_OUTBITSEL_32         (0x800000U << 8)
+#define   IPORTMXCTR1_OUTBITSEL_24         (0x000000U << 8)
+#define   IPORTMXCTR1_OUTBITSEL_20         (0x000001U << 8)
+#define   IPORTMXCTR1_OUTBITSEL_16         (0x000002U << 8)
+#define   IPORTMXCTR1_CHSEL_MASK           GENMASK(6, 4)
+#define   IPORTMXCTR1_CHSEL_ALL            (0x0 << 4)
+#define   IPORTMXCTR1_CHSEL_D0_D2          (0x1 << 4)
+#define   IPORTMXCTR1_CHSEL_D0             (0x2 << 4)
+#define   IPORTMXCTR1_CHSEL_D1             (0x3 << 4)
+#define   IPORTMXCTR1_CHSEL_D2             (0x4 << 4)
+#define   IPORTMXCTR1_CHSEL_DMIX           (0x5 << 4)
+#define   IPORTMXCTR1_FSSEL_MASK           GENMASK(3, 0)
+#define   IPORTMXCTR1_FSSEL_48             (0x0 << 0)
+#define   IPORTMXCTR1_FSSEL_96             (0x1 << 0)
+#define   IPORTMXCTR1_FSSEL_192            (0x2 << 0)
+#define   IPORTMXCTR1_FSSEL_32             (0x3 << 0)
+#define   IPORTMXCTR1_FSSEL_44_1           (0x4 << 0)
+#define   IPORTMXCTR1_FSSEL_88_2           (0x5 << 0)
+#define   IPORTMXCTR1_FSSEL_176_4          (0x6 << 0)
+#define   IPORTMXCTR1_FSSEL_16             (0x8 << 0)
+#define   IPORTMXCTR1_FSSEL_22_05          (0x9 << 0)
+#define   IPORTMXCTR1_FSSEL_24             (0xa << 0)
+#define   IPORTMXCTR1_FSSEL_8              (0xb << 0)
+#define   IPORTMXCTR1_FSSEL_11_025         (0xc << 0)
+#define   IPORTMXCTR1_FSSEL_12             (0xd << 0)
+#define IPORTMXCTR2(n)                   (0x22004 + 0x400 * (n))
+#define   IPORTMXCTR2_ACLKSEL_MASK         GENMASK(19, 16)
+#define   IPORTMXCTR2_ACLKSEL_A1           (0x0 << 16)
+#define   IPORTMXCTR2_ACLKSEL_F1           (0x1 << 16)
+#define   IPORTMXCTR2_ACLKSEL_A2           (0x2 << 16)
+#define   IPORTMXCTR2_ACLKSEL_F2           (0x3 << 16)
+#define   IPORTMXCTR2_ACLKSEL_A2PLL        (0x4 << 16)
+#define   IPORTMXCTR2_ACLKSEL_RX1          (0x5 << 16)
+#define   IPORTMXCTR2_ACLKSEL_RX2          (0x6 << 16)
+#define   IPORTMXCTR2_MSSEL_MASK           BIT(15)
+#define   IPORTMXCTR2_MSSEL_SLAVE          (0x0 << 15)
+#define   IPORTMXCTR2_MSSEL_MASTER         (0x1 << 15)
+#define   IPORTMXCTR2_EXTLSIFSSEL_MASK     BIT(14)
+#define   IPORTMXCTR2_EXTLSIFSSEL_36       (0x0 << 14)
+#define   IPORTMXCTR2_EXTLSIFSSEL_24       (0x1 << 14)
+#define   IPORTMXCTR2_DACCKSEL_MASK        GENMASK(9, 8)
+#define   IPORTMXCTR2_DACCKSEL_1_2         (0x0 << 8)
+#define   IPORTMXCTR2_DACCKSEL_1_3         (0x1 << 8)
+#define   IPORTMXCTR2_DACCKSEL_1_1         (0x2 << 8)
+#define   IPORTMXCTR2_DACCKSEL_2_3         (0x3 << 8)
+#define   IPORTMXCTR2_REQEN_MASK           BIT(0)
+#define   IPORTMXCTR2_REQEN_DISABLE        (0x0 << 0)
+#define   IPORTMXCTR2_REQEN_ENABLE         (0x1 << 0)
+#define IPORTMXCNTCTR(n)                 (0x22010 + 0x400 * (n))
+#define IPORTMXCOUNTER(n)                (0x22014 + 0x400 * (n))
+#define IPORTMXCNTMONI(n)                (0x22018 + 0x400 * (n))
+#define IPORTMXACLKSEL0EX(n)             (0x22020 + 0x400 * (n))
+#define   IPORTMXACLKSEL0EX_ACLKSEL0EX_MASK        GENMASK(3, 0)
+#define   IPORTMXACLKSEL0EX_ACLKSEL0EX_INTERNAL    (0x0 << 0)
+#define   IPORTMXACLKSEL0EX_ACLKSEL0EX_EXTERNAL    (0xf << 0)
+#define IPORTMXEXNOE(n)                  (0x22070 + 0x400 * (n))
+#define   IPORTMXEXNOE_PCMINOE_MASK        BIT(0)
+#define   IPORTMXEXNOE_PCMINOE_OUTPUT      (0x0 << 0)
+#define   IPORTMXEXNOE_PCMINOE_INPUT       (0x1 << 0)
+#define IPORTMXMASK(n)                   (0x22078 + 0x400 * (n))
+#define   IPORTMXMASK_IUXCKMSK_MASK        GENMASK(18, 16)
+#define   IPORTMXMASK_IUXCKMSK_ON          (0x0 << 16)
+#define   IPORTMXMASK_IUXCKMSK_OFF         (0x7 << 16)
+#define   IPORTMXMASK_XCKMSK_MASK          GENMASK(2, 0)
+#define   IPORTMXMASK_XCKMSK_ON            (0x0 << 0)
+#define   IPORTMXMASK_XCKMSK_OFF           (0x7 << 0)
+#define IPORTMXRSTCTR(n)                 (0x2207c + 0x400 * (n))
+#define   IPORTMXRSTCTR_RSTPI_MASK         BIT(7)
+#define   IPORTMXRSTCTR_RSTPI_RELEASE      (0x0 << 7)
+#define   IPORTMXRSTCTR_RSTPI_RESET        (0x1 << 7)
+
+/* AIN(PBinMX) */
+#define PBINMXCTR(n)                     (0x20200 + 0x40 * (n))
+#define   PBINMXCTR_NCONNECT_MASK          BIT(15)
+#define   PBINMXCTR_NCONNECT_CONNECT       (0x0 << 15)
+#define   PBINMXCTR_NCONNECT_DISCONNECT    (0x1 << 15)
+#define   PBINMXCTR_INOUTSEL_MASK          BIT(14)
+#define   PBINMXCTR_INOUTSEL_IN            (0x0 << 14)
+#define   PBINMXCTR_INOUTSEL_OUT           (0x1 << 14)
+#define   PBINMXCTR_PBINSEL_SHIFT          (8)
+#define   PBINMXCTR_ENDIAN_MASK            GENMASK(5, 4)
+#define   PBINMXCTR_ENDIAN_3210            (0x0 << 4)
+#define   PBINMXCTR_ENDIAN_0123            (0x1 << 4)
+#define   PBINMXCTR_ENDIAN_1032            (0x2 << 4)
+#define   PBINMXCTR_ENDIAN_2301            (0x3 << 4)
+#define   PBINMXCTR_MEMFMT_MASK            GENMASK(3, 0)
+#define   PBINMXCTR_MEMFMT_D0              (0x0 << 0)
+#define   PBINMXCTR_MEMFMT_5_1CH_DMIX      (0x1 << 0)
+#define   PBINMXCTR_MEMFMT_6CH             (0x2 << 0)
+#define   PBINMXCTR_MEMFMT_4CH             (0x3 << 0)
+#define   PBINMXCTR_MEMFMT_DMIX            (0x4 << 0)
+#define   PBINMXCTR_MEMFMT_1CH             (0x5 << 0)
+#define   PBINMXCTR_MEMFMT_16LR            (0x6 << 0)
+#define   PBINMXCTR_MEMFMT_7_1CH           (0x7 << 0)
+#define   PBINMXCTR_MEMFMT_7_1CH_DMIX      (0x8 << 0)
+#define   PBINMXCTR_MEMFMT_STREAM          (0xf << 0)
+#define PBINMXPAUSECTR0(n)               (0x20204 + 0x40 * (n))
+#define PBINMXPAUSECTR1(n)               (0x20208 + 0x40 * (n))
+
+/* AOUT */
+#define AOUTENCTR0                       0x40040
+#define AOUTENCTR1                       0x40044
+#define AOUTENCTR2                       0x40048
+#define AOUTRSTCTR0                      0x40060
+#define AOUTRSTCTR1                      0x40064
+#define AOUTRSTCTR2                      0x40068
+#define AOUTSRCRSTCTR0                   0x400c0
+#define AOUTSRCRSTCTR1                   0x400c4
+#define AOUTSRCRSTCTR2                   0x400c8
+
+/* AOUT(PCMOUTN) */
+#define OPORTMXCTR1(n)                   (0x42000 + 0x400 * (n))
+#define   OPORTMXCTR1_I2SLRSEL_MASK        (0x11 << 10)
+#define   OPORTMXCTR1_I2SLRSEL_RIGHT       (0x00 << 10)
+#define   OPORTMXCTR1_I2SLRSEL_LEFT        (0x01 << 10)
+#define   OPORTMXCTR1_I2SLRSEL_I2S         (0x11 << 10)
+#define   OPORTMXCTR1_OUTBITSEL_MASK       (0x800003U << 8)
+#define   OPORTMXCTR1_OUTBITSEL_32         (0x800000U << 8)
+#define   OPORTMXCTR1_OUTBITSEL_24         (0x000000U << 8)
+#define   OPORTMXCTR1_OUTBITSEL_20         (0x000001U << 8)
+#define   OPORTMXCTR1_OUTBITSEL_16         (0x000002U << 8)
+#define   OPORTMXCTR1_FSSEL_MASK           GENMASK(3, 0)
+#define   OPORTMXCTR1_FSSEL_48             (0x0 << 0)
+#define   OPORTMXCTR1_FSSEL_96             (0x1 << 0)
+#define   OPORTMXCTR1_FSSEL_192            (0x2 << 0)
+#define   OPORTMXCTR1_FSSEL_32             (0x3 << 0)
+#define   OPORTMXCTR1_FSSEL_44_1           (0x4 << 0)
+#define   OPORTMXCTR1_FSSEL_88_2           (0x5 << 0)
+#define   OPORTMXCTR1_FSSEL_176_4          (0x6 << 0)
+#define   OPORTMXCTR1_FSSEL_16             (0x8 << 0)
+#define   OPORTMXCTR1_FSSEL_22_05          (0x9 << 0)
+#define   OPORTMXCTR1_FSSEL_24             (0xa << 0)
+#define   OPORTMXCTR1_FSSEL_8              (0xb << 0)
+#define   OPORTMXCTR1_FSSEL_11_025         (0xc << 0)
+#define   OPORTMXCTR1_FSSEL_12             (0xd << 0)
+#define OPORTMXCTR2(n)                   (0x42004 + 0x400 * (n))
+#define   OPORTMXCTR2_ACLKSEL_MASK         GENMASK(19, 16)
+#define   OPORTMXCTR2_ACLKSEL_A1           (0x0 << 16)
+#define   OPORTMXCTR2_ACLKSEL_F1           (0x1 << 16)
+#define   OPORTMXCTR2_ACLKSEL_A2           (0x2 << 16)
+#define   OPORTMXCTR2_ACLKSEL_F2           (0x3 << 16)
+#define   OPORTMXCTR2_ACLKSEL_A2PLL        (0x4 << 16)
+#define   OPORTMXCTR2_ACLKSEL_RX1          (0x5 << 16)
+#define   OPORTMXCTR2_ACLKSEL_RX2          (0x6 << 16)
+#define   OPORTMXCTR2_MSSEL_MASK           BIT(15)
+#define   OPORTMXCTR2_MSSEL_SLAVE          (0x0 << 15)
+#define   OPORTMXCTR2_MSSEL_MASTER         (0x1 << 15)
+#define   OPORTMXCTR2_EXTLSIFSSEL_MASK     BIT(14)
+#define   OPORTMXCTR2_EXTLSIFSSEL_36       (0x0 << 14)
+#define   OPORTMXCTR2_EXTLSIFSSEL_24       (0x1 << 14)
+#define   OPORTMXCTR2_DACCKSEL_MASK        GENMASK(9, 8)
+#define   OPORTMXCTR2_DACCKSEL_1_2         (0x0 << 8)
+#define   OPORTMXCTR2_DACCKSEL_1_3         (0x1 << 8)
+#define   OPORTMXCTR2_DACCKSEL_1_1         (0x2 << 8)
+#define   OPORTMXCTR2_DACCKSEL_2_3         (0x3 << 8)
+#define OPORTMXCTR3(n)                   (0x42008 + 0x400 * (n))
+#define   OPORTMXCTR3_IECTHUR_MASK         BIT(19)
+#define   OPORTMXCTR3_IECTHUR_IECOUT       (0x0 << 19)
+#define   OPORTMXCTR3_IECTHUR_IECIN        (0x1 << 19)
+#define   OPORTMXCTR3_SRCSEL_MASK          GENMASK(18, 16)
+#define   OPORTMXCTR3_SRCSEL_PCM           (0x0 << 16)
+#define   OPORTMXCTR3_SRCSEL_STREAM        (0x1 << 16)
+#define   OPORTMXCTR3_SRCSEL_CDDTS         (0x2 << 16)
+#define   OPORTMXCTR3_VALID_MASK           BIT(12)
+#define   OPORTMXCTR3_VALID_PCM            (0x0 << 12)
+#define   OPORTMXCTR3_VALID_STREAM         (0x1 << 12)
+#define   OPORTMXCTR3_PMSEL_MASK           BIT(3)
+#define   OPORTMXCTR3_PMSEL_MUTE           (0x0 << 3)
+#define   OPORTMXCTR3_PMSEL_PAUSE          (0x1 << 3)
+#define   OPORTMXCTR3_PMSW_MASK            BIT(2)
+#define   OPORTMXCTR3_PMSW_MUTE_OFF        (0x0 << 2)
+#define   OPORTMXCTR3_PMSW_MUTE_ON         (0x1 << 2)
+#define OPORTMXSRC1CTR(n)                (0x4200c + 0x400 * (n))
+#define   OPORTMXSRC1CTR_FSIIPNUM_SHIFT    (24)
+#define   OPORTMXSRC1CTR_THMODE_MASK       BIT(23)
+#define   OPORTMXSRC1CTR_THMODE_SRC        (0x0 << 23)
+#define   OPORTMXSRC1CTR_THMODE_BYPASS     (0x1 << 23)
+#define   OPORTMXSRC1CTR_LOCK_MASK         BIT(16)
+#define   OPORTMXSRC1CTR_LOCK_UNLOCK       (0x0 << 16)
+#define   OPORTMXSRC1CTR_LOCK_LOCK         (0x1 << 16)
+#define   OPORTMXSRC1CTR_SRCPATH_MASK      BIT(15)
+#define   OPORTMXSRC1CTR_SRCPATH_BYPASS    (0x0 << 15)
+#define   OPORTMXSRC1CTR_SRCPATH_CALC      (0x1 << 15)
+#define   OPORTMXSRC1CTR_SYNC_MASK         BIT(14)
+#define   OPORTMXSRC1CTR_SYNC_ASYNC        (0x0 << 14)
+#define   OPORTMXSRC1CTR_SYNC_SYNC         (0x1 << 14)
+#define   OPORTMXSRC1CTR_FSOCK_MASK        GENMASK(11, 10)
+#define   OPORTMXSRC1CTR_FSOCK_44_1        (0x0 << 10)
+#define   OPORTMXSRC1CTR_FSOCK_48          (0x1 << 10)
+#define   OPORTMXSRC1CTR_FSOCK_32          (0x2 << 10)
+#define   OPORTMXSRC1CTR_FSICK_MASK        GENMASK(9, 8)
+#define   OPORTMXSRC1CTR_FSICK_44_1        (0x0 << 8)
+#define   OPORTMXSRC1CTR_FSICK_48          (0x1 << 8)
+#define   OPORTMXSRC1CTR_FSICK_32          (0x2 << 8)
+#define   OPORTMXSRC1CTR_FSIIPSEL_MASK     GENMASK(5, 4)
+#define   OPORTMXSRC1CTR_FSIIPSEL_INNER    (0x0 << 4)
+#define   OPORTMXSRC1CTR_FSIIPSEL_OUTER    (0x1 << 4)
+#define   OPORTMXSRC1CTR_FSISEL_MASK       GENMASK(3, 0)
+#define   OPORTMXSRC1CTR_FSISEL_ACLK       (0x0 << 0)
+#define   OPORTMXSRC1CTR_FSISEL_DD         (0x1 << 0)
+#define OPORTMXDSDMUTEDAT(n)             (0x42020 + 0x400 * (n))
+#define OPORTMXDXDFREQMODE(n)            (0x42024 + 0x400 * (n))
+#define OPORTMXDSDSEL(n)                 (0x42028 + 0x400 * (n))
+#define OPORTMXDSDPORT(n)                (0x4202c + 0x400 * (n))
+#define OPORTMXACLKSEL0EX(n)             (0x42030 + 0x400 * (n))
+#define OPORTMXPATH(n)                   (0x42040 + 0x400 * (n))
+#define OPORTMXSYNC(n)                   (0x42044 + 0x400 * (n))
+#define OPORTMXREPET(n)                  (0x42050 + 0x400 * (n))
+#define   OPORTMXREPET_STRLENGTH_AC3       SBF_(IEC61937_FRM_STR_AC3, 16)
+#define   OPORTMXREPET_STRLENGTH_MPA       SBF_(IEC61937_FRM_STR_MPA, 16)
+#define   OPORTMXREPET_STRLENGTH_MP3       SBF_(IEC61937_FRM_STR_MP3, 16)
+#define   OPORTMXREPET_STRLENGTH_DTS1      SBF_(IEC61937_FRM_STR_DTS1, 16)
+#define   OPORTMXREPET_STRLENGTH_DTS2      SBF_(IEC61937_FRM_STR_DTS2, 16)
+#define   OPORTMXREPET_STRLENGTH_DTS3      SBF_(IEC61937_FRM_STR_DTS3, 16)
+#define   OPORTMXREPET_STRLENGTH_AAC       SBF_(IEC61937_FRM_STR_AAC, 16)
+#define   OPORTMXREPET_PMLENGTH_AC3        SBF_(IEC61937_FRM_PAU_AC3, 0)
+#define   OPORTMXREPET_PMLENGTH_MPA        SBF_(IEC61937_FRM_PAU_MPA, 0)
+#define   OPORTMXREPET_PMLENGTH_MP3        SBF_(IEC61937_FRM_PAU_MP3, 0)
+#define   OPORTMXREPET_PMLENGTH_DTS1       SBF_(IEC61937_FRM_PAU_DTS1, 0)
+#define   OPORTMXREPET_PMLENGTH_DTS2       SBF_(IEC61937_FRM_PAU_DTS2, 0)
+#define   OPORTMXREPET_PMLENGTH_DTS3       SBF_(IEC61937_FRM_PAU_DTS3, 0)
+#define   OPORTMXREPET_PMLENGTH_AAC        SBF_(IEC61937_FRM_PAU_AAC, 0)
+#define OPORTMXPAUDAT(n)                 (0x42054 + 0x400 * (n))
+#define   OPORTMXPAUDAT_PAUSEPC_CMN        (IEC61937_PC_PAUSE << 16)
+#define   OPORTMXPAUDAT_PAUSEPD_AC3        (IEC61937_FRM_PAU_AC3 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_MPA        (IEC61937_FRM_PAU_MPA * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_MP3        (IEC61937_FRM_PAU_MP3 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_DTS1       (IEC61937_FRM_PAU_DTS1 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_DTS2       (IEC61937_FRM_PAU_DTS2 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_DTS3       (IEC61937_FRM_PAU_DTS3 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_AAC        (IEC61937_FRM_PAU_AAC * 4)
+#define OPORTMXRATE_I(n)                 (0x420e4 + 0x400 * (n))
+#define   OPORTMXRATE_I_EQU_MASK           BIT(31)
+#define   OPORTMXRATE_I_EQU_NOTEQUAL       (0x0 << 31)
+#define   OPORTMXRATE_I_EQU_EQUAL          (0x1 << 31)
+#define   OPORTMXRATE_I_SRCBPMD_MASK       BIT(29)
+#define   OPORTMXRATE_I_SRCBPMD_BYPASS     (0x0 << 29)
+#define   OPORTMXRATE_I_SRCBPMD_SRC        (0x1 << 29)
+#define   OPORTMXRATE_I_LRCKSTP_MASK       BIT(24)
+#define   OPORTMXRATE_I_LRCKSTP_START      (0x0 << 24)
+#define   OPORTMXRATE_I_LRCKSTP_STOP       (0x1 << 24)
+#define   OPORTMXRATE_I_ACLKSRC_MASK       GENMASK(15, 12)
+#define   OPORTMXRATE_I_ACLKSRC_APLL       (0x0 << 12)
+#define   OPORTMXRATE_I_ACLKSRC_USB        (0x1 << 12)
+#define   OPORTMXRATE_I_ACLKSRC_HSC        (0x3 << 12)
+/* if OPORTMXRATE_I_ACLKSRC_APLL */
+#define   OPORTMXRATE_I_ACLKSEL_MASK       GENMASK(11, 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLLA1     (0x0 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLLF1     (0x1 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLLA2     (0x2 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLLF2     (0x3 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLL       (0x4 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_HDMI1      (0x5 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_HDMI2      (0x6 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_AI1ADCCK   (0xc << 8)
+#define   OPORTMXRATE_I_ACLKSEL_AI2ADCCK   (0xd << 8)
+#define   OPORTMXRATE_I_ACLKSEL_AI3ADCCK   (0xe << 8)
+#define   OPORTMXRATE_I_MCKSEL_MASK        GENMASK(7, 4)
+#define   OPORTMXRATE_I_MCKSEL_36          (0x0 << 4)
+#define   OPORTMXRATE_I_MCKSEL_33          (0x1 << 4)
+#define   OPORTMXRATE_I_MCKSEL_HSC27       (0xb << 4)
+#define   OPORTMXRATE_I_FSSEL_MASK         GENMASK(3, 0)
+#define   OPORTMXRATE_I_FSSEL_48           (0x0 << 0)
+#define   OPORTMXRATE_I_FSSEL_96           (0x1 << 0)
+#define   OPORTMXRATE_I_FSSEL_192          (0x2 << 0)
+#define   OPORTMXRATE_I_FSSEL_32           (0x3 << 0)
+#define   OPORTMXRATE_I_FSSEL_44_1         (0x4 << 0)
+#define   OPORTMXRATE_I_FSSEL_88_2         (0x5 << 0)
+#define   OPORTMXRATE_I_FSSEL_176_4        (0x6 << 0)
+#define   OPORTMXRATE_I_FSSEL_16           (0x8 << 0)
+#define   OPORTMXRATE_I_FSSEL_22_05        (0x9 << 0)
+#define   OPORTMXRATE_I_FSSEL_24           (0xa << 0)
+#define   OPORTMXRATE_I_FSSEL_8            (0xb << 0)
+#define   OPORTMXRATE_I_FSSEL_11_025       (0xc << 0)
+#define   OPORTMXRATE_I_FSSEL_12           (0xd << 0)
+#define OPORTMXEXNOE(n)                  (0x420f0 + 0x400 * (n))
+#define OPORTMXMASK(n)                   (0x420f8 + 0x400 * (n))
+#define   OPORTMXMASK_IUDXMSK_MASK         GENMASK(28, 24)
+#define   OPORTMXMASK_IUDXMSK_ON           (0x00 << 24)
+#define   OPORTMXMASK_IUDXMSK_OFF          (0x1f << 24)
+#define   OPORTMXMASK_IUXCKMSK_MASK        GENMASK(18, 16)
+#define   OPORTMXMASK_IUXCKMSK_ON          (0x0 << 16)
+#define   OPORTMXMASK_IUXCKMSK_OFF         (0x7 << 16)
+#define   OPORTMXMASK_DXMSK_MASK           GENMASK(12, 8)
+#define   OPORTMXMASK_DXMSK_ON             (0x00 << 8)
+#define   OPORTMXMASK_DXMSK_OFF            (0x1f << 8)
+#define   OPORTMXMASK_XCKMSK_MASK          GENMASK(2, 0)
+#define   OPORTMXMASK_XCKMSK_ON            (0x0 << 0)
+#define   OPORTMXMASK_XCKMSK_OFF           (0x7 << 0)
+#define OPORTMXDEBUG(n)                  (0x420fc + 0x400 * (n))
+#define OPORTMXT0RSTCTR(n)               (0x4211c + 0x400 * (n))
+#define OPORTMXT1RSTCTR(n)               (0x4213c + 0x400 * (n))
+#define OPORTMXT2RSTCTR(n)               (0x4215c + 0x400 * (n))
+#define OPORTMXT3RSTCTR(n)               (0x4217c + 0x400 * (n))
+#define OPORTMXT4RSTCTR(n)               (0x4219c + 0x400 * (n))
+
+#define SBF_(frame, shift)    (((frame) * 2 - 1) << shift)
+
+/* AOUT(PBoutMX) */
+#define PBOUTMXCTR0(n)                   (0x40200 + 0x40 * (n))
+#define   PBOUTMXCTR0_ENDIAN_MASK         GENMASK(5, 4)
+#define   PBOUTMXCTR0_ENDIAN_3210         (0x0 << 4)
+#define   PBOUTMXCTR0_ENDIAN_0123         (0x1 << 4)
+#define   PBOUTMXCTR0_ENDIAN_1032         (0x2 << 4)
+#define   PBOUTMXCTR0_ENDIAN_2301         (0x3 << 4)
+#define   PBOUTMXCTR0_MEMFMT_MASK         GENMASK(3, 0)
+#define   PBOUTMXCTR0_MEMFMT_10CH         (0x0 << 0)
+#define   PBOUTMXCTR0_MEMFMT_8CH          (0x1 << 0)
+#define   PBOUTMXCTR0_MEMFMT_6CH          (0x2 << 0)
+#define   PBOUTMXCTR0_MEMFMT_4CH          (0x3 << 0)
+#define   PBOUTMXCTR0_MEMFMT_2CH          (0x4 << 0)
+#define   PBOUTMXCTR0_MEMFMT_STREAM       (0x5 << 0)
+#define   PBOUTMXCTR0_MEMFMT_1CH          (0x6 << 0)
+#define PBOUTMXCTR1(n)                   (0x40204 + 0x40 * (n))
+#define PBOUTMXINTCTR(n)                 (0x40208 + 0x40 * (n))
+
+/* A2D(subsystem) */
+#define CDA2D_STRT0                      0x10000
+#define   CDA2D_STRT0_STOP_MASK            BIT(31)
+#define   CDA2D_STRT0_STOP_START           (0x0 << 31)
+#define   CDA2D_STRT0_STOP_STOP            (0x1 << 31)
+#define CDA2D_STAT0                      0x10020
+#define CDA2D_TEST                       0x100a0
+#define   CDA2D_TEST_DDR_MODE_MASK         GENMASK(3, 2)
+#define   CDA2D_TEST_DDR_MODE_EXTON0       (0x0 << 2)
+#define   CDA2D_TEST_DDR_MODE_EXTOFF1      (0x3 << 2)
+#define CDA2D_STRTADRSLOAD               0x100b0
+
+#define CDA2D_CHMXCTRL1(n)               (0x12000 + 0x80 * (n))
+#define   CDA2D_CHMXCTRL1_INDSIZE_MASK     BIT(0)
+#define   CDA2D_CHMXCTRL1_INDSIZE_FINITE   (0x0 << 0)
+#define   CDA2D_CHMXCTRL1_INDSIZE_INFINITE (0x1 << 0)
+#define CDA2D_CHMXCTRL2(n)               (0x12004 + 0x80 * (n))
+#define CDA2D_CHMXSRCAMODE(n)            (0x12020 + 0x80 * (n))
+#define CDA2D_CHMXDSTAMODE(n)            (0x12024 + 0x80 * (n))
+#define   CDA2D_CHMXAMODE_ENDIAN_MASK      GENMASK(17, 16)
+#define   CDA2D_CHMXAMODE_ENDIAN_3210      (0x0 << 16)
+#define   CDA2D_CHMXAMODE_ENDIAN_0123      (0x1 << 16)
+#define   CDA2D_CHMXAMODE_ENDIAN_1032      (0x2 << 16)
+#define   CDA2D_CHMXAMODE_ENDIAN_2301      (0x3 << 16)
+#define   CDA2D_CHMXAMODE_RSSEL_SHIFT      (8)
+#define   CDA2D_CHMXAMODE_AUPDT_MASK       GENMASK(5, 4)
+#define   CDA2D_CHMXAMODE_AUPDT_INC        (0x0 << 4)
+#define   CDA2D_CHMXAMODE_AUPDT_FIX        (0x2 << 4)
+#define   CDA2D_CHMXAMODE_TYPE_MASK        GENMASK(3, 2)
+#define   CDA2D_CHMXAMODE_TYPE_NORMAL      (0x0 << 2)
+#define   CDA2D_CHMXAMODE_TYPE_RING        (0x1 << 2)
+#define CDA2D_CHMXSRCSTRTADRS(n)         (0x12030 + 0x80 * (n))
+#define CDA2D_CHMXSRCSTRTADRSU(n)        (0x12034 + 0x80 * (n))
+#define CDA2D_CHMXDSTSTRTADRS(n)         (0x12038 + 0x80 * (n))
+#define CDA2D_CHMXDSTSTRTADRSU(n)        (0x1203c + 0x80 * (n))
+
+/* A2D(ring buffer) */
+#define CDA2D_RBFLUSH0                   0x10040
+#define CDA2D_RBADRSLOAD                 0x100b4
+#define CDA2D_RDPTRLOAD                  0x100b8
+#define   CDA2D_RDPTRLOAD_LSFLAG_LOAD      (0x0 << 31)
+#define   CDA2D_RDPTRLOAD_LSFLAG_STORE     (0x1 << 31)
+#define CDA2D_WRPTRLOAD                  0x100bc
+#define   CDA2D_WRPTRLOAD_LSFLAG_LOAD      (0x0 << 31)
+#define   CDA2D_WRPTRLOAD_LSFLAG_STORE     (0x1 << 31)
+
+#define CDA2D_RBMXBGNADRS(n)             (0x14000 + 0x80 * (n))
+#define CDA2D_RBMXBGNADRSU(n)            (0x14004 + 0x80 * (n))
+#define CDA2D_RBMXENDADRS(n)             (0x14008 + 0x80 * (n))
+#define CDA2D_RBMXENDADRSU(n)            (0x1400c + 0x80 * (n))
+#define CDA2D_RBMXBTH(n)                 (0x14038 + 0x80 * (n))
+#define CDA2D_RBMXRTH(n)                 (0x1403c + 0x80 * (n))
+#define CDA2D_RBMXRDPTR(n)               (0x14020 + 0x80 * (n))
+#define CDA2D_RBMXRDPTRU(n)              (0x14024 + 0x80 * (n))
+#define CDA2D_RBMXWRPTR(n)               (0x14028 + 0x80 * (n))
+#define CDA2D_RBMXWRPTRU(n)              (0x1402c + 0x80 * (n))
+#define   CDA2D_RBMXPTRU_PTRU_MASK         GENMASK(1, 0)
+#define CDA2D_RBMXCNFG(n)                (0x14030 + 0x80 * (n))
+#define CDA2D_RBMXIR(n)                  (0x14014 + 0x80 * (n))
+#define CDA2D_RBMXIE(n)                  (0x14018 + 0x80 * (n))
+#define CDA2D_RBMXID(n)                  (0x1401c + 0x80 * (n))
+#define   CDA2D_RBMXIX_SPACE               BIT(3)
+#define   CDA2D_RBMXIX_REMAIN              BIT(4)
+
+#endif /* SND_UNIPHIER_AIO_REG_H__ */
diff --git a/sound/soc/uniphier/aio.h b/sound/soc/uniphier/aio.h
new file mode 100644
index 0000000..8cab4a5
--- /dev/null
+++ b/sound/soc/uniphier/aio.h
@@ -0,0 +1,359 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Socionext UniPhier AIO ALSA driver.
+ *
+ * Copyright (c) 2016-2018 Socionext 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; version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SND_UNIPHIER_AIO_H__
+#define SND_UNIPHIER_AIO_H__
+
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+struct platform_device;
+
+enum ID_PORT_TYPE {
+	PORT_TYPE_UNKNOWN,
+	PORT_TYPE_I2S,
+	PORT_TYPE_SPDIF,
+	PORT_TYPE_EVE,
+	PORT_TYPE_CONV,
+};
+
+enum ID_PORT_DIR {
+	PORT_DIR_OUTPUT,
+	PORT_DIR_INPUT,
+};
+
+enum IEC61937_PC {
+	IEC61937_PC_AC3   = 0x0001,
+	IEC61937_PC_PAUSE = 0x0003,
+	IEC61937_PC_MPA   = 0x0004,
+	IEC61937_PC_MP3   = 0x0005,
+	IEC61937_PC_DTS1  = 0x000b,
+	IEC61937_PC_DTS2  = 0x000c,
+	IEC61937_PC_DTS3  = 0x000d,
+	IEC61937_PC_AAC   = 0x0007,
+};
+
+/* IEC61937 Repetition period of data-burst in IEC60958 frames */
+#define IEC61937_FRM_STR_AC3       1536
+#define IEC61937_FRM_STR_MPA       1152
+#define IEC61937_FRM_STR_MP3       1152
+#define IEC61937_FRM_STR_DTS1      512
+#define IEC61937_FRM_STR_DTS2      1024
+#define IEC61937_FRM_STR_DTS3      2048
+#define IEC61937_FRM_STR_AAC       1024
+
+/* IEC61937 Repetition period of Pause data-burst in IEC60958 frames */
+#define IEC61937_FRM_PAU_AC3       3
+#define IEC61937_FRM_PAU_MPA       32
+#define IEC61937_FRM_PAU_MP3       32
+#define IEC61937_FRM_PAU_DTS1      3
+#define IEC61937_FRM_PAU_DTS2      3
+#define IEC61937_FRM_PAU_DTS3      3
+#define IEC61937_FRM_PAU_AAC       32
+
+/* IEC61937 Pa and Pb */
+#define IEC61937_HEADER_SIGN       0x1f4e72f8
+
+#define AUD_HW_PCMIN1    0
+#define AUD_HW_PCMIN2    1
+#define AUD_HW_PCMIN3    2
+#define AUD_HW_IECIN1    3
+#define AUD_HW_DIECIN1   4
+
+#define AUD_NAME_PCMIN1     "aio-pcmin1"
+#define AUD_NAME_PCMIN2     "aio-pcmin2"
+#define AUD_NAME_PCMIN3     "aio-pcmin3"
+#define AUD_NAME_IECIN1     "aio-iecin1"
+#define AUD_NAME_DIECIN1    "aio-diecin1"
+
+#define AUD_HW_HPCMOUT1    0
+#define AUD_HW_PCMOUT1     1
+#define AUD_HW_PCMOUT2     2
+#define AUD_HW_PCMOUT3     3
+#define AUD_HW_EPCMOUT1    4
+#define AUD_HW_EPCMOUT2    5
+#define AUD_HW_EPCMOUT3    6
+#define AUD_HW_EPCMOUT6    9
+#define AUD_HW_HIECOUT1    10
+#define AUD_HW_IECOUT1     11
+#define AUD_HW_CMASTER     31
+
+#define AUD_NAME_HPCMOUT1        "aio-hpcmout1"
+#define AUD_NAME_PCMOUT1         "aio-pcmout1"
+#define AUD_NAME_PCMOUT2         "aio-pcmout2"
+#define AUD_NAME_PCMOUT3         "aio-pcmout3"
+#define AUD_NAME_EPCMOUT1        "aio-epcmout1"
+#define AUD_NAME_EPCMOUT2        "aio-epcmout2"
+#define AUD_NAME_EPCMOUT3        "aio-epcmout3"
+#define AUD_NAME_EPCMOUT6        "aio-epcmout6"
+#define AUD_NAME_HIECOUT1        "aio-hiecout1"
+#define AUD_NAME_IECOUT1         "aio-iecout1"
+#define AUD_NAME_CMASTER         "aio-cmaster"
+#define AUD_NAME_HIECCOMPOUT1    "aio-hieccompout1"
+#define AUD_NAME_IECCOMPOUT1     "aio-ieccompout1"
+
+#define AUD_GNAME_HDMI    "aio-hdmi"
+#define AUD_GNAME_LINE    "aio-line"
+#define AUD_GNAME_AUX     "aio-aux"
+#define AUD_GNAME_IEC     "aio-iec"
+
+#define AUD_CLK_IO        0
+#define AUD_CLK_A1        1
+#define AUD_CLK_F1        2
+#define AUD_CLK_A2        3
+#define AUD_CLK_F2        4
+#define AUD_CLK_A         5
+#define AUD_CLK_F         6
+#define AUD_CLK_APLL      7
+#define AUD_CLK_RX0       8
+#define AUD_CLK_USB0      9
+#define AUD_CLK_HSC0      10
+
+#define AUD_PLL_A1        0
+#define AUD_PLL_F1        1
+#define AUD_PLL_A2        2
+#define AUD_PLL_F2        3
+#define AUD_PLL_APLL      4
+#define AUD_PLL_RX0       5
+#define AUD_PLL_USB0      6
+#define AUD_PLL_HSC0      7
+
+#define AUD_PLLDIV_1_2    0
+#define AUD_PLLDIV_1_3    1
+#define AUD_PLLDIV_1_1    2
+#define AUD_PLLDIV_2_3    3
+
+#define AUD_RING_SIZE            (128 * 1024)
+
+#define AUD_MIN_FRAGMENT         4
+#define AUD_MAX_FRAGMENT         8
+#define AUD_MIN_FRAGMENT_SIZE    (4 * 1024)
+#define AUD_MAX_FRAGMENT_SIZE    (16 * 1024)
+
+/*
+ * This is a selector for virtual register map of AIO.
+ *
+ * map:  Specify the index of virtual register map.
+ * hw :  Specify the ID of real register map, selector uses this value.
+ *       A meaning of this value depends specification of SoC.
+ */
+struct uniphier_aio_selector {
+	int map;
+	int hw;
+};
+
+/**
+ * 'SoftWare MAPping' setting of UniPhier AIO registers.
+ *
+ * We have to setup 'virtual' register maps to access 'real' registers of AIO.
+ * This feature is legacy and meaningless but AIO needs this to work.
+ *
+ * Each hardware blocks have own virtual register maps as following:
+ *
+ * Address Virtual                      Real
+ * ------- ---------                    ---------------
+ * 0x12000 DMAC map0 --> [selector] --> DMAC hardware 3
+ * 0x12080 DMAC map1 --> [selector] --> DMAC hardware 1
+ * ...
+ * 0x42000 Port map0 --> [selector] --> Port hardware 1
+ * 0x42400 Port map1 --> [selector] --> Port hardware 2
+ * ...
+ *
+ * ch   : Input or output channel of DMAC
+ * rb   : Ring buffer
+ * iport: PCM input port
+ * iif  : Input interface
+ * oport: PCM output port
+ * oif  : Output interface
+ * och  : Output channel of DMAC for sampling rate converter
+ *
+ * These are examples for sound data paths:
+ *
+ * For caputure device:
+ *   (outer of AIO) -> iport -> iif -> ch -> rb -> (CPU)
+ * For playback device:
+ *   (CPU) -> rb -> ch -> oif -> oport -> (outer of AIO)
+ * For sampling rate converter device:
+ *   (CPU) -> rb -> ch -> oif -> (HW SRC) -> iif -> och -> orb -> (CPU)
+ */
+struct uniphier_aio_swmap {
+	int type;
+	int dir;
+
+	struct uniphier_aio_selector ch;
+	struct uniphier_aio_selector rb;
+	struct uniphier_aio_selector iport;
+	struct uniphier_aio_selector iif;
+	struct uniphier_aio_selector oport;
+	struct uniphier_aio_selector oif;
+	struct uniphier_aio_selector och;
+};
+
+struct uniphier_aio_spec {
+	const char *name;
+	const char *gname;
+	struct uniphier_aio_swmap swm;
+};
+
+struct uniphier_aio_pll {
+	bool enable;
+	unsigned int freq;
+};
+
+struct uniphier_aio_chip_spec {
+	const struct uniphier_aio_spec *specs;
+	int num_specs;
+	const struct uniphier_aio_pll *plls;
+	int num_plls;
+	struct snd_soc_dai_driver *dais;
+	int num_dais;
+
+	/* DMA access mode, this is workaround for DMA hungup */
+	int addr_ext;
+};
+
+struct uniphier_aio_sub {
+	struct uniphier_aio *aio;
+
+	/* Guard sub->rd_offs and wr_offs from IRQ handler. */
+	spinlock_t lock;
+
+	const struct uniphier_aio_swmap *swm;
+	const struct uniphier_aio_spec *spec;
+
+	/* For PCM audio */
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_hw_params params;
+
+	/* For compress audio */
+	struct snd_compr_stream *cstream;
+	struct snd_compr_params cparams;
+	unsigned char *compr_area;
+	dma_addr_t compr_addr;
+	size_t compr_bytes;
+	int pass_through;
+	enum IEC61937_PC iec_pc;
+	bool iec_header;
+
+	/* Both PCM and compress audio */
+	bool use_mmap;
+	int setting;
+	int running;
+	u64 rd_offs;
+	u64 wr_offs;
+	u32 threshold;
+	u64 rd_org;
+	u64 wr_org;
+	u64 rd_total;
+	u64 wr_total;
+};
+
+struct uniphier_aio {
+	struct uniphier_aio_chip *chip;
+
+	struct uniphier_aio_sub sub[2];
+
+	unsigned int fmt;
+	/* Set one of AUD_CLK_X */
+	int clk_in;
+	int clk_out;
+	/* Set one of AUD_PLL_X */
+	int pll_in;
+	int pll_out;
+	/* Set one of AUD_PLLDIV_X */
+	int plldiv;
+};
+
+struct uniphier_aio_chip {
+	struct platform_device *pdev;
+	const struct uniphier_aio_chip_spec *chip_spec;
+
+	struct uniphier_aio *aios;
+	int num_aios;
+	struct uniphier_aio_pll *plls;
+	int num_plls;
+
+	struct clk *clk;
+	struct reset_control *rst;
+	struct regmap *regmap;
+	struct regmap *regmap_sg;
+	int active;
+};
+
+static inline struct uniphier_aio *uniphier_priv(struct snd_soc_dai *dai)
+{
+	struct uniphier_aio_chip *chip = snd_soc_dai_get_drvdata(dai);
+
+	return &chip->aios[dai->id];
+}
+
+int uniphier_aiodma_soc_register_platform(struct platform_device *pdev);
+extern const struct snd_compr_ops uniphier_aio_compr_ops;
+
+int uniphier_aio_dai_probe(struct snd_soc_dai *dai);
+int uniphier_aio_dai_remove(struct snd_soc_dai *dai);
+int uniphier_aio_dai_suspend(struct snd_soc_dai *dai);
+int uniphier_aio_dai_resume(struct snd_soc_dai *dai);
+int uniphier_aio_probe(struct platform_device *pdev);
+int uniphier_aio_remove(struct platform_device *pdev);
+extern const struct snd_soc_dai_ops uniphier_aio_i2s_ops;
+extern const struct snd_soc_dai_ops uniphier_aio_spdif_ops;
+
+u64 aio_rb_cnt(struct uniphier_aio_sub *sub);
+u64 aio_rbt_cnt_to_end(struct uniphier_aio_sub *sub);
+u64 aio_rb_space(struct uniphier_aio_sub *sub);
+u64 aio_rb_space_to_end(struct uniphier_aio_sub *sub);
+
+void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable);
+int aio_chip_set_pll(struct uniphier_aio_chip *chip, int pll_id,
+		     unsigned int freq);
+void aio_chip_init(struct uniphier_aio_chip *chip);
+int aio_init(struct uniphier_aio_sub *sub);
+void aio_port_reset(struct uniphier_aio_sub *sub);
+int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate);
+int aio_port_set_fmt(struct uniphier_aio_sub *sub);
+int aio_port_set_clk(struct uniphier_aio_sub *sub);
+int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through,
+		       const struct snd_pcm_hw_params *params);
+void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable);
+int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through);
+int aio_oport_set_stream_type(struct uniphier_aio_sub *sub,
+			      enum IEC61937_PC pc);
+void aio_src_reset(struct uniphier_aio_sub *sub);
+int aio_src_set_param(struct uniphier_aio_sub *sub,
+		      const struct snd_pcm_hw_params *params);
+int aio_srcif_set_param(struct uniphier_aio_sub *sub);
+int aio_srcch_set_param(struct uniphier_aio_sub *sub);
+void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable);
+
+int aiodma_ch_set_param(struct uniphier_aio_sub *sub);
+void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable);
+int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th);
+int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end,
+			 int period);
+void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size,
+		    int period);
+bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub);
+void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub);
+
+#endif /* SND_UNIPHIER_AIO_H__ */
diff --git a/sound/soc/uniphier/evea.c b/sound/soc/uniphier/evea.c
index 0cc9eff..73fd673 100644
--- a/sound/soc/uniphier/evea.c
+++ b/sound/soc/uniphier/evea.c
@@ -1,22 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
-/*
- * Socionext UniPhier EVEA ADC/DAC codec driver.
- *
- * Copyright (c) 2016-2017 Socionext 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; version 2
- * of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
+//
+// Socionext UniPhier EVEA ADC/DAC codec driver.
+//
+// Copyright (c) 2016-2017 Socionext Inc.
 
 #include <linux/clk.h>
 #include <linux/module.h>
@@ -32,6 +18,8 @@
 
 #define AADCPOW(n)                           (0x0078 + 0x04 * (n))
 #define   AADCPOW_AADC_POWD                   BIT(0)
+#define ALINSW1                              0x0088
+#define   ALINSW1_SEL1_SHIFT                  3
 #define AHPOUTPOW                            0x0098
 #define   AHPOUTPOW_HP_ON                     BIT(4)
 #define ALINEPOW                             0x009c
@@ -220,8 +208,8 @@ static void evea_update_switch_all(struct evea_priv *evea)
 static int evea_get_switch_lin(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = evea->switch_lin;
 
@@ -231,8 +219,8 @@ static int evea_get_switch_lin(struct snd_kcontrol *kcontrol,
 static int evea_set_switch_lin(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
 	if (evea->switch_lin == ucontrol->value.integer.value[0])
 		return 0;
@@ -245,8 +233,8 @@ static int evea_set_switch_lin(struct snd_kcontrol *kcontrol,
 static int evea_get_switch_lo(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = evea->switch_lo;
 
@@ -256,8 +244,8 @@ static int evea_get_switch_lo(struct snd_kcontrol *kcontrol,
 static int evea_set_switch_lo(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
 	if (evea->switch_lo == ucontrol->value.integer.value[0])
 		return 0;
@@ -270,8 +258,8 @@ static int evea_set_switch_lo(struct snd_kcontrol *kcontrol,
 static int evea_get_switch_hp(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = evea->switch_hp;
 
@@ -281,8 +269,8 @@ static int evea_get_switch_hp(struct snd_kcontrol *kcontrol,
 static int evea_set_switch_hp(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
 	if (evea->switch_hp == ucontrol->value.integer.value[0])
 		return 0;
@@ -292,7 +280,16 @@ static int evea_set_switch_hp(struct snd_kcontrol *kcontrol,
 	return evea_update_switch_hp(evea);
 }
 
-static const struct snd_kcontrol_new eva_controls[] = {
+static const char * const linsw1_sel1_text[] = {
+	"LIN1", "LIN2", "LIN3"
+};
+
+static SOC_ENUM_SINGLE_DECL(linsw1_sel1_enum,
+	ALINSW1, ALINSW1_SEL1_SHIFT,
+	linsw1_sel1_text);
+
+static const struct snd_kcontrol_new evea_controls[] = {
+	SOC_ENUM("Line Capture Source", linsw1_sel1_enum),
 	SOC_SINGLE_BOOL_EXT("Line Capture Switch", 0,
 			    evea_get_switch_lin, evea_set_switch_lin),
 	SOC_SINGLE_BOOL_EXT("Line Playback Switch", 0,
@@ -301,9 +298,9 @@ static const struct snd_kcontrol_new eva_controls[] = {
 			    evea_get_switch_hp, evea_set_switch_hp),
 };
 
-static int evea_codec_probe(struct snd_soc_codec *codec)
+static int evea_codec_probe(struct snd_soc_component *component)
 {
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
 	evea->switch_lin = 1;
 	evea->switch_lo = 1;
@@ -315,9 +312,9 @@ static int evea_codec_probe(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int evea_codec_suspend(struct snd_soc_codec *codec)
+static int evea_codec_suspend(struct snd_soc_component *component)
 {
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
 	evea_set_power_state_off(evea);
 
@@ -331,9 +328,9 @@ static int evea_codec_suspend(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int evea_codec_resume(struct snd_soc_codec *codec)
+static int evea_codec_resume(struct snd_soc_component *component)
 {
-	struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+	struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	ret = clk_prepare_enable(evea->clk);
@@ -376,19 +373,20 @@ static int evea_codec_resume(struct snd_soc_codec *codec)
 	return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_evea = {
-	.probe   = evea_codec_probe,
-	.suspend = evea_codec_suspend,
-	.resume  = evea_codec_resume,
-
-	.component_driver = {
-		.dapm_widgets = evea_widgets,
-		.num_dapm_widgets = ARRAY_SIZE(evea_widgets),
-		.dapm_routes = evea_routes,
-		.num_dapm_routes = ARRAY_SIZE(evea_routes),
-		.controls = eva_controls,
-		.num_controls = ARRAY_SIZE(eva_controls),
-	},
+static struct snd_soc_component_driver soc_codec_evea = {
+	.probe			= evea_codec_probe,
+	.suspend		= evea_codec_suspend,
+	.resume			= evea_codec_resume,
+	.dapm_widgets		= evea_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(evea_widgets),
+	.dapm_routes		= evea_routes,
+	.num_dapm_routes	= ARRAY_SIZE(evea_routes),
+	.controls		= evea_controls,
+	.num_controls		= ARRAY_SIZE(evea_controls),
+	.idle_bias_on		= 1,
+	.use_pmdown_time	= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
 };
 
 static struct snd_soc_dai_driver soc_dai_evea[] = {
@@ -505,7 +503,7 @@ static int evea_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, evea);
 
-	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_evea,
+	ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_evea,
 				     soc_dai_evea, ARRAY_SIZE(soc_dai_evea));
 	if (ret)
 		goto err_out_reset_adamv;
@@ -534,8 +532,6 @@ static int evea_remove(struct platform_device *pdev)
 {
 	struct evea_priv *evea = platform_get_drvdata(pdev);
 
-	snd_soc_unregister_codec(&pdev->dev);
-
 	reset_control_assert(evea->rst_adamv);
 	reset_control_assert(evea->rst_exiv);
 	reset_control_assert(evea->rst);
diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c
index 2472144..5035609 100644
--- a/sound/soc/xtensa/xtfpga-i2s.c
+++ b/sound/soc/xtensa/xtfpga-i2s.c
@@ -483,13 +483,10 @@ static const struct snd_pcm_ops xtfpga_pcm_ops = {
 	.pointer	= xtfpga_pcm_pointer,
 };
 
-static const struct snd_soc_platform_driver xtfpga_soc_platform = {
-	.pcm_new	= xtfpga_pcm_new,
-	.ops		= &xtfpga_pcm_ops,
-};
-
 static const struct snd_soc_component_driver xtfpga_i2s_component = {
 	.name		= DRV_NAME,
+	.pcm_new	= xtfpga_pcm_new,
+	.ops		= &xtfpga_pcm_ops,
 };
 
 static const struct snd_soc_dai_ops xtfpga_i2s_dai_ops = {
@@ -591,18 +588,13 @@ static int xtfpga_i2s_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	err = snd_soc_register_platform(&pdev->dev, &xtfpga_soc_platform);
-	if (err < 0) {
-		dev_err(&pdev->dev, "couldn't register platform\n");
-		goto err;
-	}
 	err = devm_snd_soc_register_component(&pdev->dev,
 					      &xtfpga_i2s_component,
 					      xtfpga_i2s_dai,
 					      ARRAY_SIZE(xtfpga_i2s_dai));
 	if (err < 0) {
 		dev_err(&pdev->dev, "couldn't register component\n");
-		goto err_unregister_platform;
+		goto err;
 	}
 
 	pm_runtime_enable(&pdev->dev);
@@ -615,8 +607,6 @@ static int xtfpga_i2s_probe(struct platform_device *pdev)
 
 err_pm_disable:
 	pm_runtime_disable(&pdev->dev);
-err_unregister_platform:
-	snd_soc_unregister_platform(&pdev->dev);
 err:
 	dev_err(&pdev->dev, "%s: err = %d\n", __func__, err);
 	return err;
@@ -626,7 +616,6 @@ static int xtfpga_i2s_remove(struct platform_device *pdev)
 {
 	struct xtfpga_i2s *i2s = dev_get_drvdata(&pdev->dev);
 
-	snd_soc_unregister_platform(&pdev->dev);
 	if (i2s->regmap && !IS_ERR(i2s->regmap)) {
 		regmap_write(i2s->regmap, XTFPGA_I2S_CONFIG, 0);
 		regmap_write(i2s->regmap, XTFPGA_I2S_INT_MASK, 0);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 8018d56..4a1c6bb 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -7,6 +7,7 @@
  *	    Alan Cox (alan@lxorguk.ukuu.org.uk)
  *	    Thomas Sailer (sailer@ife.ee.ethz.ch)
  *
+ *   Audio Class 3.0 support by Ruslan Bilovol <ruslan.bilovol@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
@@ -44,6 +45,7 @@
 #include <linux/mutex.h>
 #include <linux/usb/audio.h>
 #include <linux/usb/audio-v2.h>
+#include <linux/usb/audio-v3.h>
 #include <linux/module.h>
 
 #include <sound/control.h>
@@ -281,7 +283,8 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
 		break;
 	}
 
-	case UAC_VERSION_2: {
+	case UAC_VERSION_2:
+	case UAC_VERSION_3: {
 		struct usb_interface_assoc_descriptor *assoc =
 			usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
 
@@ -301,7 +304,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
 		}
 
 		if (!assoc) {
-			dev_err(&dev->dev, "Audio class v2 interfaces need an interface association\n");
+			dev_err(&dev->dev, "Audio class v2/v3 interfaces need an interface association\n");
 			return -EINVAL;
 		}
 
diff --git a/sound/usb/card.h b/sound/usb/card.h
index ed87cc8..1406292 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -22,7 +22,7 @@ struct audioformat {
 	unsigned char endpoint;		/* endpoint */
 	unsigned char ep_attr;		/* endpoint attributes */
 	unsigned char datainterval;	/* log_2 of data packet interval */
-	unsigned char protocol;		/* UAC_VERSION_1/2 */
+	unsigned char protocol;		/* UAC_VERSION_1/2/3 */
 	unsigned int maxpacksize;	/* max. packet size */
 	unsigned int rates;		/* rate bitmasks */
 	unsigned int rate_min, rate_max;	/* min/max rates */
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index eb3396f..ab39ccb 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -23,6 +23,7 @@
 #include <linux/usb.h>
 #include <linux/usb/audio.h>
 #include <linux/usb/audio-v2.h>
+#include <linux/usb/audio-v3.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
@@ -50,6 +51,22 @@ static struct uac_clock_source_descriptor *
 	return NULL;
 }
 
+static struct uac3_clock_source_descriptor *
+	snd_usb_find_clock_source_v3(struct usb_host_interface *ctrl_iface,
+				  int clock_id)
+{
+	struct uac3_clock_source_descriptor *cs = NULL;
+
+	while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
+					     ctrl_iface->extralen,
+					     cs, UAC3_CLOCK_SOURCE))) {
+		if (cs->bClockID == clock_id)
+			return cs;
+	}
+
+	return NULL;
+}
+
 static struct uac_clock_selector_descriptor *
 	snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface,
 				    int clock_id)
@@ -69,6 +86,22 @@ static struct uac_clock_selector_descriptor *
 	return NULL;
 }
 
+static struct uac3_clock_selector_descriptor *
+	snd_usb_find_clock_selector_v3(struct usb_host_interface *ctrl_iface,
+				    int clock_id)
+{
+	struct uac3_clock_selector_descriptor *cs = NULL;
+
+	while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
+					     ctrl_iface->extralen,
+					     cs, UAC3_CLOCK_SELECTOR))) {
+		if (cs->bClockID == clock_id)
+			return cs;
+	}
+
+	return NULL;
+}
+
 static struct uac_clock_multiplier_descriptor *
 	snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface,
 				      int clock_id)
@@ -85,6 +118,22 @@ static struct uac_clock_multiplier_descriptor *
 	return NULL;
 }
 
+static struct uac3_clock_multiplier_descriptor *
+	snd_usb_find_clock_multiplier_v3(struct usb_host_interface *ctrl_iface,
+				      int clock_id)
+{
+	struct uac3_clock_multiplier_descriptor *cs = NULL;
+
+	while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
+					     ctrl_iface->extralen,
+					     cs, UAC3_CLOCK_MULTIPLIER))) {
+		if (cs->bClockID == clock_id)
+			return cs;
+	}
+
+	return NULL;
+}
+
 static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
 {
 	unsigned char buf;
@@ -138,20 +187,34 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_i
 	return ret;
 }
 
-static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
+static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
+				      int protocol,
+				      int source_id)
 {
 	int err;
 	unsigned char data;
 	struct usb_device *dev = chip->dev;
-	struct uac_clock_source_descriptor *cs_desc =
-		snd_usb_find_clock_source(chip->ctrl_intf, source_id);
+	u32 bmControls;
 
-	if (!cs_desc)
-		return 0;
+	if (protocol == UAC_VERSION_3) {
+		struct uac3_clock_source_descriptor *cs_desc =
+			snd_usb_find_clock_source_v3(chip->ctrl_intf, source_id);
+
+		if (!cs_desc)
+			return 0;
+		bmControls = le32_to_cpu(cs_desc->bmControls);
+	} else { /* UAC_VERSION_1/2 */
+		struct uac_clock_source_descriptor *cs_desc =
+			snd_usb_find_clock_source(chip->ctrl_intf, source_id);
+
+		if (!cs_desc)
+			return 0;
+		bmControls = cs_desc->bmControls;
+	}
 
 	/* If a clock source can't tell us whether it's valid, we assume it is */
-	if (!uac2_control_is_readable(cs_desc->bmControls,
-				      UAC2_CS_CONTROL_CLOCK_VALID - 1))
+	if (!uac_v2v3_control_is_readable(bmControls,
+				      UAC2_CS_CONTROL_CLOCK_VALID))
 		return 1;
 
 	err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
@@ -170,9 +233,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
 	return !!data;
 }
 
-static int __uac_clock_find_source(struct snd_usb_audio *chip,
-				   int entity_id, unsigned long *visited,
-				   bool validate)
+static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id,
+				   unsigned long *visited, bool validate)
 {
 	struct uac_clock_source_descriptor *source;
 	struct uac_clock_selector_descriptor *selector;
@@ -191,7 +253,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
 	source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
 	if (source) {
 		entity_id = source->bClockID;
-		if (validate && !uac_clock_source_is_valid(chip, entity_id)) {
+		if (validate && !uac_clock_source_is_valid(chip, UAC_VERSION_2,
+								entity_id)) {
 			usb_audio_err(chip,
 				"clock source %d is not valid, cannot use\n",
 				entity_id);
@@ -260,6 +323,97 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
 	return -EINVAL;
 }
 
+static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id,
+				   unsigned long *visited, bool validate)
+{
+	struct uac3_clock_source_descriptor *source;
+	struct uac3_clock_selector_descriptor *selector;
+	struct uac3_clock_multiplier_descriptor *multiplier;
+
+	entity_id &= 0xff;
+
+	if (test_and_set_bit(entity_id, visited)) {
+		usb_audio_warn(chip,
+			 "%s(): recursive clock topology detected, id %d.\n",
+			 __func__, entity_id);
+		return -EINVAL;
+	}
+
+	/* first, see if the ID we're looking for is a clock source already */
+	source = snd_usb_find_clock_source_v3(chip->ctrl_intf, entity_id);
+	if (source) {
+		entity_id = source->bClockID;
+		if (validate && !uac_clock_source_is_valid(chip, UAC_VERSION_3,
+								entity_id)) {
+			usb_audio_err(chip,
+				"clock source %d is not valid, cannot use\n",
+				entity_id);
+			return -ENXIO;
+		}
+		return entity_id;
+	}
+
+	selector = snd_usb_find_clock_selector_v3(chip->ctrl_intf, entity_id);
+	if (selector) {
+		int ret, i, cur;
+
+		/* the entity ID we are looking for is a selector.
+		 * find out what it currently selects */
+		ret = uac_clock_selector_get_val(chip, selector->bClockID);
+		if (ret < 0)
+			return ret;
+
+		/* Selector values are one-based */
+
+		if (ret > selector->bNrInPins || ret < 1) {
+			usb_audio_err(chip,
+				"%s(): selector reported illegal value, id %d, ret %d\n",
+				__func__, selector->bClockID, ret);
+
+			return -EINVAL;
+		}
+
+		cur = ret;
+		ret = __uac3_clock_find_source(chip, selector->baCSourceID[ret - 1],
+					       visited, validate);
+		if (!validate || ret > 0 || !chip->autoclock)
+			return ret;
+
+		/* The current clock source is invalid, try others. */
+		for (i = 1; i <= selector->bNrInPins; i++) {
+			int err;
+
+			if (i == cur)
+				continue;
+
+			ret = __uac3_clock_find_source(chip, selector->baCSourceID[i - 1],
+				visited, true);
+			if (ret < 0)
+				continue;
+
+			err = uac_clock_selector_set_val(chip, entity_id, i);
+			if (err < 0)
+				continue;
+
+			usb_audio_info(chip,
+				 "found and selected valid clock source %d\n",
+				 ret);
+			return ret;
+		}
+
+		return -ENXIO;
+	}
+
+	/* FIXME: multipliers only act as pass-thru element for now */
+	multiplier = snd_usb_find_clock_multiplier_v3(chip->ctrl_intf,
+						      entity_id);
+	if (multiplier)
+		return __uac3_clock_find_source(chip, multiplier->bCSourceID,
+						visited, validate);
+
+	return -EINVAL;
+}
+
 /*
  * For all kinds of sample rate settings and other device queries,
  * the clock source (end-leaf) must be used. However, clock selectors,
@@ -271,12 +425,22 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
  *
  * Returns the clock source UnitID (>=0) on success, or an error.
  */
-int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id,
-			      bool validate)
+int snd_usb_clock_find_source(struct snd_usb_audio *chip, int protocol,
+			      int entity_id, bool validate)
 {
 	DECLARE_BITMAP(visited, 256);
 	memset(visited, 0, sizeof(visited));
-	return __uac_clock_find_source(chip, entity_id, visited, validate);
+
+	switch (protocol) {
+	case UAC_VERSION_2:
+		return __uac_clock_find_source(chip, entity_id, visited,
+					       validate);
+	case UAC_VERSION_3:
+		return __uac3_clock_find_source(chip, entity_id, visited,
+					       validate);
+	default:
+		return -EINVAL;
+	}
 }
 
 static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
@@ -335,7 +499,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
 	return 0;
 }
 
-static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface,
+static int get_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
 			      int altsetting, int clock)
 {
 	struct usb_device *dev = chip->dev;
@@ -348,7 +512,7 @@ static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface,
 			      snd_usb_ctrl_intf(chip) | (clock << 8),
 			      &data, sizeof(data));
 	if (err < 0) {
-		dev_warn(&dev->dev, "%d:%d: cannot get freq (v2): err %d\n",
+		dev_warn(&dev->dev, "%d:%d: cannot get freq (v2/v3): err %d\n",
 			 iface, altsetting, err);
 		return 0;
 	}
@@ -356,7 +520,7 @@ static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface,
 	return le32_to_cpu(data);
 }
 
-static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
+static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
 			      struct usb_host_interface *alts,
 			      struct audioformat *fmt, int rate)
 {
@@ -365,18 +529,31 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
 	int err, cur_rate, prev_rate;
 	int clock;
 	bool writeable;
-	struct uac_clock_source_descriptor *cs_desc;
+	u32 bmControls;
 
-	clock = snd_usb_clock_find_source(chip, fmt->clock, true);
+	clock = snd_usb_clock_find_source(chip, fmt->protocol,
+					  fmt->clock, true);
 	if (clock < 0)
 		return clock;
 
-	prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock);
+	prev_rate = get_sample_rate_v2v3(chip, iface, fmt->altsetting, clock);
 	if (prev_rate == rate)
 		return 0;
 
-	cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock);
-	writeable = uac2_control_is_writeable(cs_desc->bmControls, UAC2_CS_CONTROL_SAM_FREQ - 1);
+	if (fmt->protocol == UAC_VERSION_3) {
+		struct uac3_clock_source_descriptor *cs_desc;
+
+		cs_desc = snd_usb_find_clock_source_v3(chip->ctrl_intf, clock);
+		bmControls = le32_to_cpu(cs_desc->bmControls);
+	} else {
+		struct uac_clock_source_descriptor *cs_desc;
+
+		cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock);
+		bmControls = cs_desc->bmControls;
+	}
+
+	writeable = uac_v2v3_control_is_writeable(bmControls,
+						  UAC2_CS_CONTROL_SAM_FREQ);
 	if (writeable) {
 		data = cpu_to_le32(rate);
 		err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
@@ -386,12 +563,13 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
 				      &data, sizeof(data));
 		if (err < 0) {
 			usb_audio_err(chip,
-				"%d:%d: cannot set freq %d (v2): err %d\n",
+				"%d:%d: cannot set freq %d (v2/v3): err %d\n",
 				iface, fmt->altsetting, rate, err);
 			return err;
 		}
 
-		cur_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock);
+		cur_rate = get_sample_rate_v2v3(chip, iface,
+						fmt->altsetting, clock);
 	} else {
 		cur_rate = prev_rate;
 	}
@@ -430,7 +608,8 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
 		return set_sample_rate_v1(chip, iface, alts, fmt, rate);
 
 	case UAC_VERSION_2:
-		return set_sample_rate_v2(chip, iface, alts, fmt, rate);
+	case UAC_VERSION_3:
+		return set_sample_rate_v2v3(chip, iface, alts, fmt, rate);
 	}
 }
 
diff --git a/sound/usb/clock.h b/sound/usb/clock.h
index 87557ca..076e31b 100644
--- a/sound/usb/clock.h
+++ b/sound/usb/clock.h
@@ -6,7 +6,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
 			     struct usb_host_interface *alts,
 			     struct audioformat *fmt, int rate);
 
-int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id,
-			     bool validate);
+int snd_usb_clock_find_source(struct snd_usb_audio *chip, int protocol,
+			     int entity_id, bool validate);
 
 #endif /* __USBAUDIO_CLOCK_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 2c44386..49e7ec6 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -20,6 +20,7 @@
 #include <linux/usb.h>
 #include <linux/usb/audio.h>
 #include <linux/usb/audio-v2.h>
+#include <linux/usb/audio-v3.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -39,11 +40,11 @@
  * @dev: usb device
  * @fp: audioformat record
  * @format: the format tag (wFormatTag)
- * @fmt: the format type descriptor
+ * @fmt: the format type descriptor (v1/v2) or AudioStreaming descriptor (v3)
  */
 static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
 				     struct audioformat *fp,
-				     unsigned int format, void *_fmt)
+				     u64 format, void *_fmt)
 {
 	int sample_width, sample_bytes;
 	u64 pcm_formats = 0;
@@ -54,7 +55,7 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
 		struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
 		sample_width = fmt->bBitResolution;
 		sample_bytes = fmt->bSubframeSize;
-		format = 1 << format;
+		format = 1ULL << format;
 		break;
 	}
 
@@ -69,6 +70,18 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
 		format <<= 1;
 		break;
 	}
+	case UAC_VERSION_3: {
+		struct uac3_as_header_descriptor *as = _fmt;
+
+		sample_width = as->bBitResolution;
+		sample_bytes = as->bSubslotSize;
+
+		if (format & UAC3_FORMAT_TYPE_I_RAW_DATA)
+			pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL;
+
+		format <<= 1;
+		break;
+	}
 	}
 
 	if ((pcm_formats == 0) &&
@@ -137,7 +150,7 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
 	}
 	if (format & ~0x3f) {
 		usb_audio_info(chip,
-			 "%u:%d : unsupported format bits %#x\n",
+			 "%u:%d : unsupported format bits %#llx\n",
 			 fp->iface, fp->altsetting, format);
 	}
 
@@ -281,15 +294,16 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,
 
 /*
  * parse the format descriptor and stores the possible sample rates
- * on the audioformat table (audio class v2).
+ * on the audioformat table (audio class v2 and v3).
  */
-static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
+static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,
 				       struct audioformat *fp)
 {
 	struct usb_device *dev = chip->dev;
 	unsigned char tmp[2], *data;
 	int nr_triplets, data_size, ret = 0;
-	int clock = snd_usb_clock_find_source(chip, fp->clock, false);
+	int clock = snd_usb_clock_find_source(chip, fp->protocol,
+					      fp->clock, false);
 
 	if (clock < 0) {
 		dev_err(&dev->dev,
@@ -368,13 +382,30 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
  * parse the format type I and III descriptors
  */
 static int parse_audio_format_i(struct snd_usb_audio *chip,
-				struct audioformat *fp, unsigned int format,
-				struct uac_format_type_i_continuous_descriptor *fmt)
+				struct audioformat *fp, u64 format,
+				void *_fmt)
 {
 	snd_pcm_format_t pcm_format;
+	unsigned int fmt_type;
 	int ret;
 
-	if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
+	switch (fp->protocol) {
+	default:
+	case UAC_VERSION_1:
+	case UAC_VERSION_2: {
+		struct uac_format_type_i_continuous_descriptor *fmt = _fmt;
+
+		fmt_type = fmt->bFormatType;
+		break;
+	}
+	case UAC_VERSION_3: {
+		/* fp->fmt_type is already set in this case */
+		fmt_type = fp->fmt_type;
+		break;
+	}
+	}
+
+	if (fmt_type == UAC_FORMAT_TYPE_III) {
 		/* FIXME: the format type is really IECxxx
 		 *        but we give normal PCM format to get the existing
 		 *        apps working...
@@ -393,7 +424,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
 		}
 		fp->formats = pcm_format_to_bits(pcm_format);
 	} else {
-		fp->formats = parse_audio_format_i_type(chip, fp, format, fmt);
+		fp->formats = parse_audio_format_i_type(chip, fp, format, _fmt);
 		if (!fp->formats)
 			return -EINVAL;
 	}
@@ -405,15 +436,20 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
 	 */
 	switch (fp->protocol) {
 	default:
-	case UAC_VERSION_1:
+	case UAC_VERSION_1: {
+		struct uac_format_type_i_continuous_descriptor *fmt = _fmt;
+
 		fp->channels = fmt->bNrChannels;
 		ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
 		break;
+	}
 	case UAC_VERSION_2:
+	case UAC_VERSION_3: {
 		/* fp->channels is already set in this case */
-		ret = parse_audio_format_rates_v2(chip, fp);
+		ret = parse_audio_format_rates_v2v3(chip, fp);
 		break;
 	}
+	}
 
 	if (fp->channels < 1) {
 		usb_audio_err(chip,
@@ -430,7 +466,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
  */
 static int parse_audio_format_ii(struct snd_usb_audio *chip,
 				 struct audioformat *fp,
-				 int format, void *_fmt)
+				 u64 format, void *_fmt)
 {
 	int brate, framesize, ret;
 
@@ -445,7 +481,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
 		break;
 	default:
 		usb_audio_info(chip,
-			 "%u:%d : unknown format tag %#x is detected.  processed as MPEG.\n",
+			 "%u:%d : unknown format tag %#llx is detected.  processed as MPEG.\n",
 			 fp->iface, fp->altsetting, format);
 		fp->formats = SNDRV_PCM_FMTBIT_MPEG;
 		break;
@@ -470,7 +506,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
 		framesize = le16_to_cpu(fmt->wSamplesPerFrame);
 		usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
 		fp->frame_size = framesize;
-		ret = parse_audio_format_rates_v2(chip, fp);
+		ret = parse_audio_format_rates_v2v3(chip, fp);
 		break;
 	}
 	}
@@ -479,7 +515,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
 }
 
 int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
-			       struct audioformat *fp, unsigned int format,
+			       struct audioformat *fp, u64 format,
 			       struct uac_format_type_i_continuous_descriptor *fmt,
 			       int stream)
 {
@@ -520,3 +556,26 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
 	return 0;
 }
 
+int snd_usb_parse_audio_format_v3(struct snd_usb_audio *chip,
+			       struct audioformat *fp,
+			       struct uac3_as_header_descriptor *as,
+			       int stream)
+{
+	u64 format = le64_to_cpu(as->bmFormats);
+	int err;
+
+	/*
+	 * Type I format bits are D0..D6
+	 * This test works because type IV is not supported
+	 */
+	if (format & 0x7f)
+		fp->fmt_type = UAC_FORMAT_TYPE_I;
+	else
+		fp->fmt_type = UAC_FORMAT_TYPE_III;
+
+	err = parse_audio_format_i(chip, fp, format, as);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
diff --git a/sound/usb/format.h b/sound/usb/format.h
index 8c3ff9c..e701718 100644
--- a/sound/usb/format.h
+++ b/sound/usb/format.h
@@ -3,8 +3,12 @@
 #define __USBAUDIO_FORMAT_H
 
 int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
-			       struct audioformat *fp, unsigned int format,
+			       struct audioformat *fp, u64 format,
 			       struct uac_format_type_i_continuous_descriptor *fmt,
 			       int stream);
 
+int snd_usb_parse_audio_format_v3(struct snd_usb_audio *chip,
+			       struct audioformat *fp,
+			       struct uac3_as_header_descriptor *as,
+			       int stream);
 #endif /*  __USBAUDIO_FORMAT_H */
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 06b2262..301ad61 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -51,6 +51,7 @@
 #include <linux/usb.h>
 #include <linux/usb/audio.h>
 #include <linux/usb/audio-v2.h>
+#include <linux/usb/audio-v3.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -189,7 +190,7 @@ static void *find_audio_control_unit(struct mixer_build *state,
 					USB_DT_CS_INTERFACE)) != NULL) {
 		if (hdr->bLength >= 4 &&
 		    hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL &&
-		    hdr->bDescriptorSubtype <= UAC2_SAMPLE_RATE_CONVERTER &&
+		    hdr->bDescriptorSubtype <= UAC3_SAMPLE_RATE_CONVERTER &&
 		    hdr->bUnitID == unit)
 			return hdr;
 	}
@@ -468,9 +469,10 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
 
 	validx += cval->idx_off;
 
+
 	if (cval->head.mixer->protocol == UAC_VERSION_1) {
 		val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
-	} else { /* UAC_VERSION_2 */
+	} else { /* UAC_VERSION_2/3 */
 		val_len = uac2_ctl_value_size(cval->val_type);
 
 		/* FIXME */
@@ -723,6 +725,7 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
 static int check_input_term(struct mixer_build *state, int id,
 			    struct usb_audio_term *term)
 {
+	int protocol = state->mixer->protocol;
 	int err;
 	void *p1;
 
@@ -730,16 +733,104 @@ static int check_input_term(struct mixer_build *state, int id,
 	while ((p1 = find_audio_control_unit(state, id)) != NULL) {
 		unsigned char *hdr = p1;
 		term->id = id;
-		switch (hdr[2]) {
-		case UAC_INPUT_TERMINAL:
-			if (state->mixer->protocol == UAC_VERSION_1) {
-				struct uac_input_terminal_descriptor *d = p1;
-				term->type = le16_to_cpu(d->wTerminalType);
-				term->channels = d->bNrChannels;
-				term->chconfig = le16_to_cpu(d->wChannelConfig);
-				term->name = d->iTerminal;
-			} else { /* UAC_VERSION_2 */
-				struct uac2_input_terminal_descriptor *d = p1;
+
+		if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
+			switch (hdr[2]) {
+			case UAC_INPUT_TERMINAL:
+				if (protocol == UAC_VERSION_1) {
+					struct uac_input_terminal_descriptor *d = p1;
+
+					term->type = le16_to_cpu(d->wTerminalType);
+					term->channels = d->bNrChannels;
+					term->chconfig = le16_to_cpu(d->wChannelConfig);
+					term->name = d->iTerminal;
+				} else { /* UAC_VERSION_2 */
+					struct uac2_input_terminal_descriptor *d = p1;
+
+					/* call recursively to verify that the
+					 * referenced clock entity is valid */
+					err = check_input_term(state, d->bCSourceID, term);
+					if (err < 0)
+						return err;
+
+					/* save input term properties after recursion,
+					 * to ensure they are not overriden by the
+					 * recursion calls */
+					term->id = id;
+					term->type = le16_to_cpu(d->wTerminalType);
+					term->channels = d->bNrChannels;
+					term->chconfig = le32_to_cpu(d->bmChannelConfig);
+					term->name = d->iTerminal;
+				}
+				return 0;
+			case UAC_FEATURE_UNIT: {
+				/* the header is the same for v1 and v2 */
+				struct uac_feature_unit_descriptor *d = p1;
+
+				id = d->bSourceID;
+				break; /* continue to parse */
+			}
+			case UAC_MIXER_UNIT: {
+				struct uac_mixer_unit_descriptor *d = p1;
+
+				term->type = d->bDescriptorSubtype << 16; /* virtual type */
+				term->channels = uac_mixer_unit_bNrChannels(d);
+				term->chconfig = uac_mixer_unit_wChannelConfig(d, protocol);
+				term->name = uac_mixer_unit_iMixer(d);
+				return 0;
+			}
+			case UAC_SELECTOR_UNIT:
+			case UAC2_CLOCK_SELECTOR: {
+				struct uac_selector_unit_descriptor *d = p1;
+				/* call recursively to retrieve the channel info */
+				err = check_input_term(state, d->baSourceID[0], term);
+				if (err < 0)
+					return err;
+				term->type = d->bDescriptorSubtype << 16; /* virtual type */
+				term->id = id;
+				term->name = uac_selector_unit_iSelector(d);
+				return 0;
+			}
+			case UAC1_PROCESSING_UNIT:
+			case UAC1_EXTENSION_UNIT:
+			/* UAC2_PROCESSING_UNIT_V2 */
+			/* UAC2_EFFECT_UNIT */
+			case UAC2_EXTENSION_UNIT_V2: {
+				struct uac_processing_unit_descriptor *d = p1;
+
+				if (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 */
+				}
+				term->type = d->bDescriptorSubtype << 16; /* virtual type */
+				term->channels = uac_processing_unit_bNrChannels(d);
+				term->chconfig = uac_processing_unit_wChannelConfig(d, protocol);
+				term->name = uac_processing_unit_iProcessing(d, protocol);
+				return 0;
+			}
+			case UAC2_CLOCK_SOURCE: {
+				struct uac_clock_source_descriptor *d = p1;
+
+				term->type = d->bDescriptorSubtype << 16; /* virtual type */
+				term->id = id;
+				term->name = d->iClockSource;
+				return 0;
+			}
+			default:
+				return -ENODEV;
+			}
+		} else { /* UAC_VERSION_3 */
+			switch (hdr[2]) {
+			case UAC_INPUT_TERMINAL: {
+				struct uac3_input_terminal_descriptor *d = p1;
 
 				/* call recursively to verify that the
 				 * referenced clock entity is valid */
@@ -752,71 +843,31 @@ static int check_input_term(struct mixer_build *state, int id,
 				 * recursion calls */
 				term->id = id;
 				term->type = le16_to_cpu(d->wTerminalType);
-				term->channels = d->bNrChannels;
-				term->chconfig = le32_to_cpu(d->bmChannelConfig);
-				term->name = d->iTerminal;
-			}
-			return 0;
-		case UAC_FEATURE_UNIT: {
-			/* the header is the same for v1 and v2 */
-			struct uac_feature_unit_descriptor *d = p1;
-			id = d->bSourceID;
-			break; /* continue to parse */
-		}
-		case UAC_MIXER_UNIT: {
-			struct uac_mixer_unit_descriptor *d = p1;
-			term->type = d->bDescriptorSubtype << 16; /* virtual type */
-			term->channels = uac_mixer_unit_bNrChannels(d);
-			term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->protocol);
-			term->name = uac_mixer_unit_iMixer(d);
-			return 0;
-		}
-		case UAC_SELECTOR_UNIT:
-		case UAC2_CLOCK_SELECTOR: {
-			struct uac_selector_unit_descriptor *d = p1;
-			/* call recursively to retrieve the channel info */
-			err = check_input_term(state, d->baSourceID[0], term);
-			if (err < 0)
-				return err;
-			term->type = d->bDescriptorSubtype << 16; /* virtual type */
-			term->id = id;
-			term->name = uac_selector_unit_iSelector(d);
-			return 0;
-		}
-		case UAC1_PROCESSING_UNIT:
-		case UAC1_EXTENSION_UNIT:
-		/* UAC2_PROCESSING_UNIT_V2 */
-		/* UAC2_EFFECT_UNIT */
-		case UAC2_EXTENSION_UNIT_V2: {
-			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.
-				 */
+				/* REVISIT: UAC3 IT doesn't have channels/cfg */
+				term->channels = 0;
+				term->chconfig = 0;
+
+				term->name = le16_to_cpu(d->wTerminalDescrStr);
 				return 0;
 			}
+			case UAC3_FEATURE_UNIT: {
+				struct uac3_feature_unit_descriptor *d = p1;
 
-			if (d->bNrInPins) {
-				id = d->baSourceID[0];
+				id = d->bSourceID;
 				break; /* continue to parse */
 			}
-			term->type = d->bDescriptorSubtype << 16; /* virtual type */
-			term->channels = uac_processing_unit_bNrChannels(d);
-			term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol);
-			term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol);
-			return 0;
-		}
-		case UAC2_CLOCK_SOURCE: {
-			struct uac_clock_source_descriptor *d = p1;
-			term->type = d->bDescriptorSubtype << 16; /* virtual type */
-			term->id = id;
-			term->name = d->iClockSource;
-			return 0;
-		}
-		default:
-			return -ENODEV;
+			case UAC3_CLOCK_SOURCE: {
+				struct uac3_clock_source_descriptor *d = p1;
+
+				term->type = d->bDescriptorSubtype << 16; /* virtual type */
+				term->id = id;
+				term->name = le16_to_cpu(d->wClockSourceStr);
+				return 0;
+			}
+			default:
+				return -ENODEV;
+			}
 		}
 	}
 	return -ENODEV;
@@ -828,26 +879,27 @@ static int check_input_term(struct mixer_build *state, int id,
 
 /* feature unit control information */
 struct usb_feature_control_info {
+	int control;
 	const char *name;
 	int type;	/* data type for uac1 */
 	int type_uac2;	/* data type for uac2 if different from uac1, else -1 */
 };
 
 static struct usb_feature_control_info audio_feature_info[] = {
-	{ "Mute",			USB_MIXER_INV_BOOLEAN, -1 },
-	{ "Volume",			USB_MIXER_S16, -1 },
-	{ "Tone Control - Bass",	USB_MIXER_S8, -1 },
-	{ "Tone Control - Mid",		USB_MIXER_S8, -1 },
-	{ "Tone Control - Treble",	USB_MIXER_S8, -1 },
-	{ "Graphic Equalizer",		USB_MIXER_S8, -1 }, /* FIXME: not implemeted yet */
-	{ "Auto Gain Control",		USB_MIXER_BOOLEAN, -1 },
-	{ "Delay Control",		USB_MIXER_U16, USB_MIXER_U32 },
-	{ "Bass Boost",			USB_MIXER_BOOLEAN, -1 },
-	{ "Loudness",			USB_MIXER_BOOLEAN, -1 },
+	{ UAC_FU_MUTE,			"Mute",			USB_MIXER_INV_BOOLEAN, -1 },
+	{ UAC_FU_VOLUME,		"Volume",		USB_MIXER_S16, -1 },
+	{ UAC_FU_BASS,			"Tone Control - Bass",	USB_MIXER_S8, -1 },
+	{ UAC_FU_MID,			"Tone Control - Mid",	USB_MIXER_S8, -1 },
+	{ UAC_FU_TREBLE,		"Tone Control - Treble", USB_MIXER_S8, -1 },
+	{ UAC_FU_GRAPHIC_EQUALIZER,	"Graphic Equalizer",	USB_MIXER_S8, -1 }, /* FIXME: not implemented yet */
+	{ UAC_FU_AUTOMATIC_GAIN,	"Auto Gain Control",	USB_MIXER_BOOLEAN, -1 },
+	{ UAC_FU_DELAY,			"Delay Control",	USB_MIXER_U16, USB_MIXER_U32 },
+	{ UAC_FU_BASS_BOOST,		"Bass Boost",		USB_MIXER_BOOLEAN, -1 },
+	{ UAC_FU_LOUDNESS,		"Loudness",		USB_MIXER_BOOLEAN, -1 },
 	/* UAC2 specific */
-	{ "Input Gain Control",		USB_MIXER_S16, -1 },
-	{ "Input Gain Pad Control",	USB_MIXER_S16, -1 },
-	{ "Phase Inverter Control",	USB_MIXER_BOOLEAN, -1 },
+	{ UAC2_FU_INPUT_GAIN,		"Input Gain Control",	USB_MIXER_S16, -1 },
+	{ UAC2_FU_INPUT_GAIN_PAD,	"Input Gain Pad Control", USB_MIXER_S16, -1 },
+	{ UAC2_FU_PHASE_INVERTER,	 "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 },
 };
 
 /* private_free callback */
@@ -1183,6 +1235,21 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,
 	return changed;
 }
 
+/* get the boolean value from the master channel of a UAC control */
+static int mixer_ctl_master_bool_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
+	int val, err;
+
+	err = snd_usb_get_cur_mix_value(cval, 0, 0, &val);
+	if (err < 0)
+		return filter_error(cval, err);
+	val = (val != 0);
+	ucontrol->value.integer.value[0] = val;
+	return 0;
+}
+
 static struct snd_kcontrol_new usb_feature_unit_ctl = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "", /* will be filled later manually */
@@ -1201,6 +1268,19 @@ static const struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
 };
 
 /*
+ * A control which shows the boolean value from reading a UAC control on
+ * the master channel.
+ */
+static struct snd_kcontrol_new usb_bool_master_control_ctl_ro = {
+	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+	.name = "", /* will be filled later manually */
+	.access = SNDRV_CTL_ELEM_ACCESS_READ,
+	.info = snd_ctl_boolean_mono_info,
+	.get = mixer_ctl_master_bool_get,
+	.put = NULL,
+};
+
+/*
  * This symbol is exported in order to allow the mixer quirks to
  * hook up to the standard feature unit control mechanism
  */
@@ -1242,6 +1322,17 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
 	strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
 }
 
+static struct usb_feature_control_info *get_feature_control_info(int control)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(audio_feature_info); ++i) {
+		if (audio_feature_info[i].control == control)
+			return &audio_feature_info[i];
+	}
+	return NULL;
+}
+
 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,
@@ -1257,8 +1348,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
 	const struct usbmix_name_map *map;
 	unsigned int range;
 
-	control++; /* change from zero-based to 1-based value */
-
 	if (control == UAC_FU_GRAPHIC_EQUALIZER) {
 		/* FIXME: not supported yet */
 		return;
@@ -1274,7 +1363,12 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
 	snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid);
 	cval->control = control;
 	cval->cmask = ctl_mask;
-	ctl_info = &audio_feature_info[control-1];
+
+	ctl_info = get_feature_control_info(control);
+	if (!ctl_info) {
+		kfree(cval);
+		return;
+	}
 	if (state->mixer->protocol == UAC_VERSION_1)
 		cval->val_type = ctl_info->type;
 	else /* UAC_VERSION_2 */
@@ -1400,6 +1494,60 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
 	snd_usb_mixer_add_control(&cval->head, kctl);
 }
 
+static void get_connector_control_name(struct mixer_build *state,
+				       struct usb_audio_term *term,
+				       bool is_input, char *name, int name_size)
+{
+	int name_len = get_term_name(state, term, name, name_size, 0);
+
+	if (name_len == 0)
+		strlcpy(name, "Unknown", name_size);
+
+	/*
+	 *  sound/core/ctljack.c has a convention of naming jack controls
+	 * by ending in " Jack".  Make it slightly more useful by
+	 * indicating Input or Output after the terminal name.
+	 */
+	if (is_input)
+		strlcat(name, " - Input Jack", name_size);
+	else
+		strlcat(name, " - Output Jack", name_size);
+}
+
+/* Build a mixer control for a UAC connector control (jack-detect) */
+static void build_connector_control(struct mixer_build *state,
+				    struct usb_audio_term *term, bool is_input)
+{
+	struct snd_kcontrol *kctl;
+	struct usb_mixer_elem_info *cval;
+
+	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
+	if (!cval)
+		return;
+	snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id);
+	/*
+	 * The first byte from reading the UAC2_TE_CONNECTOR control returns the
+	 * number of channels connected.  This boolean ctl will simply report
+	 * if any channels are connected or not.
+	 * (Audio20_final.pdf Table 5-10: Connector Control CUR Parameter Block)
+	 */
+	cval->control = UAC2_TE_CONNECTOR;
+	cval->val_type = USB_MIXER_BOOLEAN;
+	cval->channels = 1; /* report true if any channel is connected */
+	cval->min = 0;
+	cval->max = 1;
+	kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval);
+	if (!kctl) {
+		usb_audio_err(state->chip, "cannot malloc kcontrol\n");
+		kfree(cval);
+		return;
+	}
+	get_connector_control_name(state, term, is_input, kctl->id.name,
+				   sizeof(kctl->id.name));
+	kctl->private_free = snd_usb_mixer_elem_free;
+	snd_usb_mixer_add_control(&cval->head, kctl);
+}
+
 static int parse_clock_source_unit(struct mixer_build *state, int unitid,
 				   void *_ftr)
 {
@@ -1423,8 +1571,8 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid,
 	 * The only property of this unit we are interested in is the
 	 * clock source validity. If that isn't readable, just bail out.
 	 */
-	if (!uac2_control_is_readable(hdr->bmControls,
-				      ilog2(UAC2_CS_CONTROL_CLOCK_VALID)))
+	if (!uac_v2v3_control_is_readable(hdr->bmControls,
+				      UAC2_CS_CONTROL_CLOCK_VALID))
 		return 0;
 
 	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -1439,13 +1587,9 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid,
 	cval->val_type = USB_MIXER_BOOLEAN;
 	cval->control = UAC2_CS_CONTROL_CLOCK_VALID;
 
-	if (uac2_control_is_writeable(hdr->bmControls,
-				      ilog2(UAC2_CS_CONTROL_CLOCK_VALID)))
-		kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
-	else {
-		cval->master_readonly = 1;
-		kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
-	}
+	cval->master_readonly = 1;
+	/* From UAC2 5.2.5.1.2 "Only the get request is supported." */
+	kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval);
 
 	if (!kctl) {
 		kfree(cval);
@@ -1502,7 +1646,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
 				      unitid);
 			return -EINVAL;
 		}
-	} else {
+	} else if (state->mixer->protocol == UAC_VERSION_2) {
 		struct uac2_feature_unit_descriptor *ftr = _ftr;
 		if (hdr->bLength < 6) {
 			usb_audio_err(state->chip,
@@ -1519,6 +1663,24 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
 				      unitid);
 			return -EINVAL;
 		}
+	} else { /* UAC_VERSION_3 */
+		struct uac3_feature_unit_descriptor *ftr = _ftr;
+
+		if (hdr->bLength < 7) {
+			usb_audio_err(state->chip,
+				      "unit %u: invalid UAC3_FEATURE_UNIT descriptor\n",
+				      unitid);
+			return -EINVAL;
+		}
+		csize = 4;
+		channels = (ftr->bLength - 7) / 4 - 1;
+		bmaControls = ftr->bmaControls;
+		if (hdr->bLength < 7 + csize) {
+			usb_audio_err(state->chip,
+				      "unit %u: invalid UAC3_FEATURE_UNIT descriptor\n",
+				      unitid);
+			return -EINVAL;
+		}
 	}
 
 	/* parse the source unit */
@@ -1556,6 +1718,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
 		/* check all control types */
 		for (i = 0; i < 10; i++) {
 			unsigned int ch_bits = 0;
+			int control = audio_feature_info[i].control;
+
 			for (j = 0; j < channels; j++) {
 				unsigned int mask;
 
@@ -1571,25 +1735,26 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
 			 * (for ease of programming).
 			 */
 			if (ch_bits & 1)
-				build_feature_ctl(state, _ftr, ch_bits, i,
+				build_feature_ctl(state, _ftr, ch_bits, control,
 						  &iterm, unitid, 0);
 			if (master_bits & (1 << i))
-				build_feature_ctl(state, _ftr, 0, i, &iterm,
-						  unitid, 0);
+				build_feature_ctl(state, _ftr, 0, control,
+						  &iterm, unitid, 0);
 		}
-	} else { /* UAC_VERSION_2 */
+	} else { /* UAC_VERSION_2/3 */
 		for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
 			unsigned int ch_bits = 0;
 			unsigned int ch_read_only = 0;
+			int control = audio_feature_info[i].control;
 
 			for (j = 0; j < channels; j++) {
 				unsigned int mask;
 
 				mask = snd_usb_combine_bytes(bmaControls +
 							     csize * (j+1), csize);
-				if (uac2_control_is_readable(mask, i)) {
+				if (uac_v2v3_control_is_readable(mask, control)) {
 					ch_bits |= (1 << j);
-					if (!uac2_control_is_writeable(mask, i))
+					if (!uac_v2v3_control_is_writeable(mask, control))
 						ch_read_only |= (1 << j);
 				}
 			}
@@ -1608,11 +1773,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
 			 * (for ease of programming).
 			 */
 			if (ch_bits & 1)
-				build_feature_ctl(state, _ftr, ch_bits, i,
+				build_feature_ctl(state, _ftr, ch_bits, control,
 						  &iterm, unitid, ch_read_only);
-			if (uac2_control_is_readable(master_bits, i))
+			if (uac_v2v3_control_is_readable(master_bits, control))
 				build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
-						  !uac2_control_is_writeable(master_bits, i));
+						  !uac_v2v3_control_is_writeable(master_bits,
+										 control));
 		}
 	}
 
@@ -1684,6 +1850,23 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
 	snd_usb_mixer_add_control(&cval->head, kctl);
 }
 
+static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
+				      void *raw_desc)
+{
+	struct usb_audio_term iterm;
+	struct uac2_input_terminal_descriptor *d = raw_desc;
+
+	check_input_term(state, d->bTerminalID, &iterm);
+	if (state->mixer->protocol == UAC_VERSION_2) {
+		/* Check for jack detection. */
+		if (uac_v2v3_control_is_readable(d->bmControls,
+						 UAC2_TE_CONNECTOR)) {
+			build_connector_control(state, &iterm, true);
+		}
+	}
+	return 0;
+}
+
 /*
  * parse a mixer unit
  */
@@ -2220,6 +2403,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
 static int parse_audio_unit(struct mixer_build *state, int unitid)
 {
 	unsigned char *p1;
+	int protocol = state->mixer->protocol;
 
 	if (test_and_set_bit(unitid, state->unitbitmap))
 		return 0; /* the unit already visited */
@@ -2230,36 +2414,61 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
 		return -EINVAL;
 	}
 
-	switch (p1[2]) {
-	case UAC_INPUT_TERMINAL:
-		return 0; /* NOP */
-	case UAC_MIXER_UNIT:
-		return parse_audio_mixer_unit(state, unitid, p1);
-	case UAC2_CLOCK_SOURCE:
-		return parse_clock_source_unit(state, unitid, p1);
-	case UAC_SELECTOR_UNIT:
-	case UAC2_CLOCK_SELECTOR:
-		return parse_audio_selector_unit(state, unitid, p1);
-	case UAC_FEATURE_UNIT:
-		return parse_audio_feature_unit(state, unitid, p1);
-	case UAC1_PROCESSING_UNIT:
-	/*   UAC2_EFFECT_UNIT has the same value */
-		if (state->mixer->protocol == UAC_VERSION_1)
-			return parse_audio_processing_unit(state, unitid, p1);
-		else
-			return 0; /* FIXME - effect units not implemented yet */
-	case UAC1_EXTENSION_UNIT:
-	/*   UAC2_PROCESSING_UNIT_V2 has the same value */
-		if (state->mixer->protocol == UAC_VERSION_1)
+	if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
+		switch (p1[2]) {
+		case UAC_INPUT_TERMINAL:
+			return parse_audio_input_terminal(state, unitid, p1);
+		case UAC_MIXER_UNIT:
+			return parse_audio_mixer_unit(state, unitid, p1);
+		case UAC2_CLOCK_SOURCE:
+			return parse_clock_source_unit(state, unitid, p1);
+		case UAC_SELECTOR_UNIT:
+		case UAC2_CLOCK_SELECTOR:
+			return parse_audio_selector_unit(state, unitid, p1);
+		case UAC_FEATURE_UNIT:
+			return parse_audio_feature_unit(state, unitid, p1);
+		case UAC1_PROCESSING_UNIT:
+		/*   UAC2_EFFECT_UNIT has the same value */
+			if (protocol == UAC_VERSION_1)
+				return parse_audio_processing_unit(state, unitid, p1);
+			else
+				return 0; /* FIXME - effect units not implemented yet */
+		case UAC1_EXTENSION_UNIT:
+		/*   UAC2_PROCESSING_UNIT_V2 has the same value */
+			if (protocol == UAC_VERSION_1)
+				return parse_audio_extension_unit(state, unitid, p1);
+			else /* UAC_VERSION_2 */
+				return parse_audio_processing_unit(state, unitid, p1);
+		case UAC2_EXTENSION_UNIT_V2:
 			return parse_audio_extension_unit(state, unitid, p1);
-		else /* UAC_VERSION_2 */
+		default:
+			usb_audio_err(state->chip,
+				"unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
+			return -EINVAL;
+		}
+	} else { /* UAC_VERSION_3 */
+		switch (p1[2]) {
+		case UAC_INPUT_TERMINAL:
+			return 0; /* NOP */
+		case UAC3_MIXER_UNIT:
+			return parse_audio_mixer_unit(state, unitid, p1);
+		case UAC3_CLOCK_SOURCE:
+			return parse_clock_source_unit(state, unitid, p1);
+		case UAC3_CLOCK_SELECTOR:
+			return parse_audio_selector_unit(state, unitid, p1);
+		case UAC3_FEATURE_UNIT:
+			return parse_audio_feature_unit(state, unitid, p1);
+		case UAC3_EFFECT_UNIT:
+			return 0; /* FIXME - effect units not implemented yet */
+		case UAC3_PROCESSING_UNIT:
 			return parse_audio_processing_unit(state, unitid, p1);
-	case UAC2_EXTENSION_UNIT_V2:
-		return parse_audio_extension_unit(state, unitid, p1);
-	default:
-		usb_audio_err(state->chip,
-			"unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
-		return -EINVAL;
+		case UAC3_EXTENSION_UNIT:
+			return parse_audio_extension_unit(state, unitid, p1);
+		default:
+			usb_audio_err(state->chip,
+				"unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
+			return -EINVAL;
+		}
 	}
 }
 
@@ -2330,7 +2539,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
 			err = parse_audio_unit(&state, desc->bSourceID);
 			if (err < 0 && err != -EINVAL)
 				return err;
-		} else { /* UAC_VERSION_2 */
+		} else if (mixer->protocol == UAC_VERSION_2) {
 			struct uac2_output_terminal_descriptor *desc = p;
 
 			if (desc->bLength < sizeof(*desc))
@@ -2351,6 +2560,33 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
 			err = parse_audio_unit(&state, desc->bCSourceID);
 			if (err < 0 && err != -EINVAL)
 				return err;
+
+			if (uac_v2v3_control_is_readable(desc->bmControls,
+							 UAC2_TE_CONNECTOR)) {
+				build_connector_control(&state, &state.oterm,
+							false);
+			}
+		} else {  /* UAC_VERSION_3 */
+			struct uac3_output_terminal_descriptor *desc = p;
+
+			if (desc->bLength < sizeof(*desc))
+				continue; /* invalid descriptor? */
+			/* mark terminal ID as visited */
+			set_bit(desc->bTerminalID, state.unitbitmap);
+			state.oterm.id = desc->bTerminalID;
+			state.oterm.type = le16_to_cpu(desc->wTerminalType);
+			state.oterm.name = le16_to_cpu(desc->wTerminalDescrStr);
+			err = parse_audio_unit(&state, desc->bSourceID);
+			if (err < 0 && err != -EINVAL)
+				return err;
+
+			/*
+			 * For UAC3, use the same approach to also add the
+			 * clock selectors
+			 */
+			err = parse_audio_unit(&state, desc->bCSourceID);
+			if (err < 0 && err != -EINVAL)
+				return err;
 		}
 	}
 
@@ -2597,6 +2833,9 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
 	case UAC_VERSION_2:
 		mixer->protocol = UAC_VERSION_2;
 		break;
+	case UAC_VERSION_3:
+		mixer->protocol = UAC_VERSION_3;
+		break;
 	}
 
 	if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 794224e1..acbeb52 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1149,27 +1149,17 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
 	return false;
 }
 
-/* Marantz/Denon USB DACs need a vendor cmd to switch
+/* ITF-USB DSD based DACs need a vendor cmd to switch
  * between PCM and native DSD mode
  */
-static bool is_marantz_denon_dac(unsigned int id)
+static bool is_itf_usb_dsd_dac(unsigned int id)
 {
 	switch (id) {
 	case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */
 	case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */
 	case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */
-		return true;
-	}
-	return false;
-}
-
-/* TEAC UD-501/UD-503/NT-503 USB DACs need a vendor cmd to switch
- * between PCM/DOP and native DSD mode
- */
-static bool is_teac_dsd_dac(unsigned int id)
-{
-	switch (id) {
-	case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */
+	case USB_ID(0x1852, 0x5065): /* Luxman DA-06 */
+	case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-501V2/UD-503/NT-503 */
 	case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */
 	case USB_ID(0x0644, 0x804a): /* TEAC UD-301 */
 		return true;
@@ -1183,7 +1173,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs,
 	struct usb_device *dev = subs->dev;
 	int err;
 
-	if (is_marantz_denon_dac(subs->stream->chip->usb_id)) {
+	if (is_itf_usb_dsd_dac(subs->stream->chip->usb_id)) {
 		/* First switch to alt set 0, otherwise the mode switch cmd
 		 * will not be accepted by the DAC
 		 */
@@ -1193,37 +1183,26 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs,
 
 		mdelay(20); /* Delay needed after setting the interface */
 
-		switch (fmt->altsetting) {
-		case 2: /* DSD mode requested */
-		case 1: /* PCM mode requested */
-			err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
-					      USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
-					      fmt->altsetting - 1, 1, NULL, 0);
-			if (err < 0)
-				return err;
-			break;
-		}
-		mdelay(20);
-	} else if (is_teac_dsd_dac(subs->stream->chip->usb_id)) {
 		/* Vendor mode switch cmd is required. */
-		switch (fmt->altsetting) {
-		case 3: /* DSD mode (DSD_U32) requested */
+		if (fmt->formats & SNDRV_PCM_FMTBIT_DSD_U32_BE) {
+			/* DSD mode (DSD_U32) requested */
 			err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
 					      USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
 					      1, 1, NULL, 0);
 			if (err < 0)
 				return err;
-			break;
 
-		case 2: /* PCM or DOP mode (S32) requested */
-		case 1: /* PCM mode (S16) requested */
+		} else {
+			/* PCM or DOP mode (S32) requested */
+			/* PCM mode (S16) requested */
 			err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
 					      USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
 					      0, 1, NULL, 0);
 			if (err < 0)
 				return err;
-			break;
+
 		}
+		mdelay(20);
 	}
 	return 0;
 }
@@ -1300,10 +1279,10 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
 	    (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
 		mdelay(20);
 
-	/* Marantz/Denon devices with USB DAC functionality need a delay
+	/* ITF-USB DSD based DACs functionality need a delay
 	 * after each class compliant request
 	 */
-	if (is_marantz_denon_dac(chip->usb_id)
+	if (is_itf_usb_dsd_dac(chip->usb_id)
 	    && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
 		mdelay(20);
 
@@ -1329,6 +1308,8 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
 					struct audioformat *fp,
 					unsigned int sample_bytes)
 {
+	struct usb_interface *iface;
+
 	/* Playback Designs */
 	if (USB_ID_VENDOR(chip->usb_id) == 0x23ba) {
 		switch (fp->altsetting) {
@@ -1390,17 +1371,52 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
 		break;
 	}
 
-	/* Denon/Marantz devices with USB DAC functionality */
-	if (is_marantz_denon_dac(chip->usb_id)) {
-		if (fp->altsetting == 2)
-			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
-	}
+	/* ITF-USB DSD based DACs */
+	if (is_itf_usb_dsd_dac(chip->usb_id)) {
+		iface = usb_ifnum_to_if(chip->dev, fp->iface);
 
-	/* TEAC devices with USB DAC functionality */
-	if (is_teac_dsd_dac(chip->usb_id)) {
-		if (fp->altsetting == 3)
+		/* Altsetting 2 support native DSD if the num of altsets is
+		 * three (0-2),
+		 * Altsetting 3 support native DSD if the num of altsets is
+		 * four (0-3).
+		 */
+		if (fp->altsetting == iface->num_altsetting - 1)
 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
 	}
 
 	return 0;
 }
+
+void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
+					  struct audioformat *fp,
+					  int stream)
+{
+	switch (chip->usb_id) {
+	case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
+		/* Optoplay sets the sample rate attribute although
+		 * it seems not supporting it in fact.
+		 */
+		fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
+		break;
+	case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
+	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
+		/* doesn't set the sample rate attribute, but supports it */
+		fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
+		break;
+	case USB_ID(0x0763, 0x2001):  /* M-Audio Quattro USB */
+	case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
+	case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
+	case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
+					an older model 77d:223) */
+	/*
+	 * plantronics headset and Griffin iMic have set adaptive-in
+	 * although it's really not...
+	 */
+		fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
+		else
+			fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
+		break;
+	}
+}
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
index b90c8b7..a80e0dd 100644
--- a/sound/usb/quirks.h
+++ b/sound/usb/quirks.h
@@ -42,4 +42,8 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
 					struct audioformat *fp,
 					unsigned int sample_bytes);
 
+void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
+					  struct audioformat *fp,
+					  int stream);
+
 #endif /* __USBAUDIO_QUIRKS_H */
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index d1776e5..6a8f584 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -20,6 +20,7 @@
 #include <linux/usb.h>
 #include <linux/usb/audio.h>
 #include <linux/usb/audio-v2.h>
+#include <linux/usb/audio-v3.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -311,6 +312,153 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,
 	return chmap;
 }
 
+/* UAC3 device stores channels information in Cluster Descriptors */
+static struct
+snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
+								*cluster)
+{
+	unsigned int channels = cluster->bNrChannels;
+	struct snd_pcm_chmap_elem *chmap;
+	void *p = cluster;
+	int len, c;
+
+	if (channels > ARRAY_SIZE(chmap->map))
+		return NULL;
+
+	chmap = kzalloc(sizeof(*chmap), GFP_KERNEL);
+	if (!chmap)
+		return NULL;
+
+	len = le16_to_cpu(cluster->wLength);
+	c = 0;
+	p += sizeof(struct uac3_cluster_header_descriptor);
+
+	while (((p - (void *)cluster) < len) && (c < channels)) {
+		struct uac3_cluster_segment_descriptor *cs_desc = p;
+		u16 cs_len;
+		u8 cs_type;
+
+		cs_len = le16_to_cpu(cs_desc->wLength);
+		cs_type = cs_desc->bSegmentType;
+
+		if (cs_type == UAC3_CHANNEL_INFORMATION) {
+			struct uac3_cluster_information_segment_descriptor *is = p;
+			unsigned char map;
+
+			/*
+			 * TODO: this conversion is not complete, update it
+			 * after adding UAC3 values to asound.h
+			 */
+			switch (is->bChPurpose) {
+			case UAC3_CH_MONO:
+				map = SNDRV_CHMAP_MONO;
+				break;
+			case UAC3_CH_LEFT:
+			case UAC3_CH_FRONT_LEFT:
+			case UAC3_CH_HEADPHONE_LEFT:
+				map = SNDRV_CHMAP_FL;
+				break;
+			case UAC3_CH_RIGHT:
+			case UAC3_CH_FRONT_RIGHT:
+			case UAC3_CH_HEADPHONE_RIGHT:
+				map = SNDRV_CHMAP_FR;
+				break;
+			case UAC3_CH_FRONT_CENTER:
+				map = SNDRV_CHMAP_FC;
+				break;
+			case UAC3_CH_FRONT_LEFT_OF_CENTER:
+				map = SNDRV_CHMAP_FLC;
+				break;
+			case UAC3_CH_FRONT_RIGHT_OF_CENTER:
+				map = SNDRV_CHMAP_FRC;
+				break;
+			case UAC3_CH_SIDE_LEFT:
+				map = SNDRV_CHMAP_SL;
+				break;
+			case UAC3_CH_SIDE_RIGHT:
+				map = SNDRV_CHMAP_SR;
+				break;
+			case UAC3_CH_BACK_LEFT:
+				map = SNDRV_CHMAP_RL;
+				break;
+			case UAC3_CH_BACK_RIGHT:
+				map = SNDRV_CHMAP_RR;
+				break;
+			case UAC3_CH_BACK_CENTER:
+				map = SNDRV_CHMAP_RC;
+				break;
+			case UAC3_CH_BACK_LEFT_OF_CENTER:
+				map = SNDRV_CHMAP_RLC;
+				break;
+			case UAC3_CH_BACK_RIGHT_OF_CENTER:
+				map = SNDRV_CHMAP_RRC;
+				break;
+			case UAC3_CH_TOP_CENTER:
+				map = SNDRV_CHMAP_TC;
+				break;
+			case UAC3_CH_TOP_FRONT_LEFT:
+				map = SNDRV_CHMAP_TFL;
+				break;
+			case UAC3_CH_TOP_FRONT_RIGHT:
+				map = SNDRV_CHMAP_TFR;
+				break;
+			case UAC3_CH_TOP_FRONT_CENTER:
+				map = SNDRV_CHMAP_TFC;
+				break;
+			case UAC3_CH_TOP_FRONT_LOC:
+				map = SNDRV_CHMAP_TFLC;
+				break;
+			case UAC3_CH_TOP_FRONT_ROC:
+				map = SNDRV_CHMAP_TFRC;
+				break;
+			case UAC3_CH_TOP_SIDE_LEFT:
+				map = SNDRV_CHMAP_TSL;
+				break;
+			case UAC3_CH_TOP_SIDE_RIGHT:
+				map = SNDRV_CHMAP_TSR;
+				break;
+			case UAC3_CH_TOP_BACK_LEFT:
+				map = SNDRV_CHMAP_TRL;
+				break;
+			case UAC3_CH_TOP_BACK_RIGHT:
+				map = SNDRV_CHMAP_TRR;
+				break;
+			case UAC3_CH_TOP_BACK_CENTER:
+				map = SNDRV_CHMAP_TRC;
+				break;
+			case UAC3_CH_BOTTOM_CENTER:
+				map = SNDRV_CHMAP_BC;
+				break;
+			case UAC3_CH_LOW_FREQUENCY_EFFECTS:
+				map = SNDRV_CHMAP_LFE;
+				break;
+			case UAC3_CH_LFE_LEFT:
+				map = SNDRV_CHMAP_LLFE;
+				break;
+			case UAC3_CH_LFE_RIGHT:
+				map = SNDRV_CHMAP_RLFE;
+				break;
+			case UAC3_CH_RELATIONSHIP_UNDEFINED:
+			default:
+				map = SNDRV_CHMAP_UNKNOWN;
+				break;
+			}
+			chmap->map[c++] = map;
+		}
+		p += cs_len;
+	}
+
+	if (channels < c)
+		pr_err("%s: channel number mismatch\n", __func__);
+
+	chmap->channels = channels;
+
+	for (; c < channels; c++)
+		chmap->map[c] = SNDRV_CHMAP_UNKNOWN;
+
+	return chmap;
+}
+
 /*
  * add this endpoint to the chip instance.
  * if a stream with the same endpoint already exists, append to it.
@@ -461,10 +609,11 @@ snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
 	return NULL;
 }
 
-static struct uac2_output_terminal_descriptor *
-	snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
-						int terminal_id)
+static void *
+snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
+					int terminal_id)
 {
+	/* OK to use with both UAC2 and UAC3 */
 	struct uac2_output_terminal_descriptor *term = NULL;
 
 	while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
@@ -484,10 +633,12 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
 	struct usb_host_interface *alts;
 	struct usb_interface_descriptor *altsd;
 	int i, altno, err, stream;
-	unsigned int format = 0, num_channels = 0;
+	u64 format = 0;
+	unsigned int num_channels = 0;
 	struct audioformat *fp = NULL;
 	int num, protocol, clock = 0;
-	struct uac_format_type_i_continuous_descriptor *fmt;
+	struct uac_format_type_i_continuous_descriptor *fmt = NULL;
+	struct snd_pcm_chmap_elem *chmap_v3 = NULL;
 	unsigned int chconfig;
 
 	dev = chip->dev;
@@ -624,38 +775,158 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
 				iface_no, altno, as->bTerminalLink);
 			continue;
 		}
-		}
 
-		/* get format type */
-		fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
-		if (!fmt) {
+		case UAC_VERSION_3: {
+			struct uac3_input_terminal_descriptor *input_term;
+			struct uac3_output_terminal_descriptor *output_term;
+			struct uac3_as_header_descriptor *as;
+			struct uac3_cluster_header_descriptor *cluster;
+			struct uac3_hc_descriptor_header hc_header;
+			u16 cluster_id, wLength;
+
+			as = snd_usb_find_csint_desc(alts->extra,
+							alts->extralen,
+							NULL, UAC_AS_GENERAL);
+
+			if (!as) {
+				dev_err(&dev->dev,
+					"%u:%d : UAC_AS_GENERAL descriptor not found\n",
+					iface_no, altno);
+				continue;
+			}
+
+			if (as->bLength < sizeof(*as)) {
+				dev_err(&dev->dev,
+					"%u:%d : invalid UAC_AS_GENERAL desc\n",
+					iface_no, altno);
+				continue;
+			}
+
+			cluster_id = le16_to_cpu(as->wClusterDescrID);
+			if (!cluster_id) {
+				dev_err(&dev->dev,
+					"%u:%d : no cluster descriptor\n",
+					iface_no, altno);
+				continue;
+			}
+
+			/*
+			 * Get number of channels and channel map through
+			 * High Capability Cluster Descriptor
+			 *
+			 * First step: get High Capability header and
+			 * read size of Cluster Descriptor
+			 */
+			err = snd_usb_ctl_msg(chip->dev,
+					usb_rcvctrlpipe(chip->dev, 0),
+					UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
+					USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+					cluster_id,
+					snd_usb_ctrl_intf(chip),
+					&hc_header, sizeof(hc_header));
+			if (err < 0)
+				return err;
+			else if (err != sizeof(hc_header)) {
+				dev_err(&dev->dev,
+					"%u:%d : can't get High Capability descriptor\n",
+					iface_no, altno);
+				return -EIO;
+			}
+
+			/*
+			 * Second step: allocate needed amount of memory
+			 * and request Cluster Descriptor
+			 */
+			wLength = le16_to_cpu(hc_header.wLength);
+			cluster = kzalloc(wLength, GFP_KERNEL);
+			if (!cluster)
+				return -ENOMEM;
+			err = snd_usb_ctl_msg(chip->dev,
+					usb_rcvctrlpipe(chip->dev, 0),
+					UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
+					USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+					cluster_id,
+					snd_usb_ctrl_intf(chip),
+					cluster, wLength);
+			if (err < 0) {
+				kfree(cluster);
+				return err;
+			} else if (err != wLength) {
+				dev_err(&dev->dev,
+					"%u:%d : can't get Cluster Descriptor\n",
+					iface_no, altno);
+				kfree(cluster);
+				return -EIO;
+			}
+
+			num_channels = cluster->bNrChannels;
+			chmap_v3 = convert_chmap_v3(cluster);
+
+			kfree(cluster);
+
+			format = le64_to_cpu(as->bmFormats);
+
+			/* lookup the terminal associated to this interface
+			 * to extract the clock */
+			input_term = snd_usb_find_input_terminal_descriptor(
+							chip->ctrl_intf,
+							as->bTerminalLink);
+
+			if (input_term) {
+				clock = input_term->bCSourceID;
+				break;
+			}
+
+			output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
+									      as->bTerminalLink);
+			if (output_term) {
+				clock = output_term->bCSourceID;
+				break;
+			}
+
 			dev_err(&dev->dev,
-				"%u:%d : no UAC_FORMAT_TYPE desc\n",
-				iface_no, altno);
+				"%u:%d : bogus bTerminalLink %d\n",
+				iface_no, altno, as->bTerminalLink);
 			continue;
 		}
-		if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
-		    ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) {
-			dev_err(&dev->dev,
-				"%u:%d : invalid UAC_FORMAT_TYPE desc\n",
-				iface_no, altno);
-			continue;
 		}
 
-		/*
-		 * Blue Microphones workaround: The last altsetting is identical
-		 * with the previous one, except for a larger packet size, but
-		 * is actually a mislabeled two-channel setting; ignore it.
-		 */
-		if (fmt->bNrChannels == 1 &&
-		    fmt->bSubframeSize == 2 &&
-		    altno == 2 && num == 3 &&
-		    fp && fp->altsetting == 1 && fp->channels == 1 &&
-		    fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
-		    protocol == UAC_VERSION_1 &&
-		    le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
+		if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
+			/* get format type */
+			fmt = snd_usb_find_csint_desc(alts->extra,
+						      alts->extralen,
+						      NULL, UAC_FORMAT_TYPE);
+			if (!fmt) {
+				dev_err(&dev->dev,
+					"%u:%d : no UAC_FORMAT_TYPE desc\n",
+					iface_no, altno);
+				continue;
+			}
+			if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8))
+					|| ((protocol == UAC_VERSION_2) &&
+							(fmt->bLength < 6))) {
+				dev_err(&dev->dev,
+					"%u:%d : invalid UAC_FORMAT_TYPE desc\n",
+					iface_no, altno);
+				continue;
+			}
+
+			/*
+			 * Blue Microphones workaround: The last altsetting is
+			 * identical with the previous one, except for a larger
+			 * packet size, but is actually a mislabeled two-channel
+			 * setting; ignore it.
+			 */
+			if (fmt->bNrChannels == 1 &&
+			    fmt->bSubframeSize == 2 &&
+			    altno == 2 && num == 3 &&
+			    fp && fp->altsetting == 1 && fp->channels == 1 &&
+			    fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
+			    protocol == UAC_VERSION_1 &&
+			    le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
 							fp->maxpacksize * 2)
-			continue;
+				continue;
+		}
 
 		fp = kzalloc(sizeof(*fp), GFP_KERNEL);
 		if (!fp)
@@ -678,48 +949,42 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
 		INIT_LIST_HEAD(&fp->list);
 
 		/* some quirks for attributes here */
-
-		switch (chip->usb_id) {
-		case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
-			/* Optoplay sets the sample rate attribute although
-			 * it seems not supporting it in fact.
-			 */
-			fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
-			break;
-		case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
-		case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
-			/* doesn't set the sample rate attribute, but supports it */
-			fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
-			break;
-		case USB_ID(0x0763, 0x2001):  /* M-Audio Quattro USB */
-		case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
-		case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
-		case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
-						an older model 77d:223) */
-		/*
-		 * plantronics headset and Griffin iMic have set adaptive-in
-		 * although it's really not...
-		 */
-			fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
-			if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-				fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
-			else
-				fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
-			break;
-		}
+		snd_usb_audioformat_attributes_quirk(chip, fp, stream);
 
 		/* ok, let's parse further... */
-		if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream) < 0) {
-			kfree(fp->rate_table);
-			kfree(fp);
-			fp = NULL;
-			continue;
+		if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
+			if (snd_usb_parse_audio_format(chip, fp, format,
+							fmt, stream) < 0) {
+				kfree(fp->rate_table);
+				kfree(fp);
+				fp = NULL;
+				continue;
+			}
+		} else {
+			struct uac3_as_header_descriptor *as;
+
+			as = snd_usb_find_csint_desc(alts->extra,
+						     alts->extralen,
+						     NULL, UAC_AS_GENERAL);
+
+			if (snd_usb_parse_audio_format_v3(chip, fp, as,
+								stream) < 0) {
+				kfree(fp->rate_table);
+				kfree(fp);
+				fp = NULL;
+				continue;
+			}
 		}
 
 		/* Create chmap */
 		if (fp->channels != num_channels)
 			chconfig = 0;
-		fp->chmap = convert_chmap(fp->channels, chconfig, protocol);
+
+		if (protocol == UAC_VERSION_3)
+			fp->chmap = chmap_v3;
+		else
+			fp->chmap = convert_chmap(fp->channels, chconfig,
+						  protocol);
 
 		dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);
 		err = snd_usb_add_audio_stream(chip, stream, fp);
diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
index dac4d41..c864544 100644
--- a/tools/gpio/gpio-event-mon.c
+++ b/tools/gpio/gpio-event-mon.c
@@ -99,7 +99,7 @@ int monitor_device(const char *device_name,
 			ret = -EIO;
 			break;
 		}
-		fprintf(stdout, "GPIO EVENT %" PRIu64 ": ", event.timestamp);
+		fprintf(stdout, "GPIO EVENT %llu: ", event.timestamp);
 		switch (event.id) {
 		case GPIOEVENT_EVENT_RISING_EDGE:
 			fprintf(stdout, "rising edge");
diff --git a/tools/thermal/tmon/sysfs.c b/tools/thermal/tmon/sysfs.c
index 1c12536..18f5235 100644
--- a/tools/thermal/tmon/sysfs.c
+++ b/tools/thermal/tmon/sysfs.c
@@ -486,6 +486,7 @@ int zone_instance_to_index(int zone_inst)
 int update_thermal_data()
 {
 	int i;
+	int next_thermal_record = cur_thermal_record + 1;
 	char tz_name[256];
 	static unsigned long samples;
 
@@ -495,9 +496,9 @@ int update_thermal_data()
 	}
 
 	/* circular buffer for keeping historic data */
-	if (cur_thermal_record >= NR_THERMAL_RECORDS)
-		cur_thermal_record = 0;
-	gettimeofday(&trec[cur_thermal_record].tv, NULL);
+	if (next_thermal_record >= NR_THERMAL_RECORDS)
+		next_thermal_record = 0;
+	gettimeofday(&trec[next_thermal_record].tv, NULL);
 	if (tmon_log) {
 		fprintf(tmon_log, "%lu ", ++samples);
 		fprintf(tmon_log, "%3.1f ", p_param.t_target);
@@ -507,11 +508,12 @@ int update_thermal_data()
 		snprintf(tz_name, 256, "%s/%s%d", THERMAL_SYSFS, TZONE,
 			ptdata.tzi[i].instance);
 		sysfs_get_ulong(tz_name, "temp",
-				&trec[cur_thermal_record].temp[i]);
+				&trec[next_thermal_record].temp[i]);
 		if (tmon_log)
 			fprintf(tmon_log, "%lu ",
-				trec[cur_thermal_record].temp[i]/1000);
+				trec[next_thermal_record].temp[i] / 1000);
 	}
+	cur_thermal_record = next_thermal_record;
 	for (i = 0; i < ptdata.nr_cooling_dev; i++) {
 		char cdev_name[256];
 		unsigned long val;
diff --git a/tools/thermal/tmon/tmon.c b/tools/thermal/tmon/tmon.c
index 9aa1965..b43138f 100644
--- a/tools/thermal/tmon/tmon.c
+++ b/tools/thermal/tmon/tmon.c
@@ -336,7 +336,6 @@ int main(int argc, char **argv)
 			show_data_w();
 			show_cooling_device();
 		}
-		cur_thermal_record++;
 		time_elapsed += ticktime;
 		controller_handler(trec[0].temp[target_tz_index] / 1000,
 				&yk);